diff --git a/src/blua/ldump.c b/src/blua/ldump.c index c9d3d4870..b69a12729 100644 --- a/src/blua/ldump.c +++ b/src/blua/ldump.c @@ -60,7 +60,7 @@ static void DumpVector(const void* b, int n, size_t size, DumpState* D) static void DumpString(const TString* s, DumpState* D) { - if (s==NULL || getstr(s)==NULL) + if (s==NULL) { size_t size=0; DumpVar(size,D); diff --git a/src/d_netfil.c b/src/d_netfil.c index 3c269f63a..041c7c35f 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -194,6 +194,12 @@ UINT8 *PutFileNeeded(UINT16 firstfile) filestatus = 1; // Importance - not really used any more, holds 1 by default for backwards compat with MS + /* don't send mainwads!! */ +#ifdef DEVELOP + if (i <= mainwads) + filestatus += (2 << 4); +#endif + // Store in the upper four bits if (!cv_downloading.value) filestatus += (2 << 4); // Won't send diff --git a/src/d_player.h b/src/d_player.h index 0e5fd613b..60ca7c4bd 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -437,6 +437,8 @@ typedef struct player_s UINT16 draftleeway; // Leniency timer before removing draft power SINT8 lastdraft; // (-1 to 15) - Last player being drafted + UINT16 tripwireLeniency; // When reaching a state that lets you go thru tripwire, you get an extra second leniency after it ends to still go through it. + UINT16 itemroulette; // Used for the roulette when deciding what item to give you (was "pw_kartitem") UINT8 roulettetype; // Used for the roulette, for deciding type (0 = normal, 1 = better, 2 = eggman mark) diff --git a/src/deh_tables.c b/src/deh_tables.c index a8fd4612c..c5acec7f8 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -129,7 +129,6 @@ actionpointer_t actionpointers[] = {{A_BossZoom}, "A_BOSSZOOM"}, {{A_BossScream}, "A_BOSSSCREAM"}, {{A_Boss2TakeDamage}, "A_BOSS2TAKEDAMAGE"}, - {{A_Boss7Chase}, "A_BOSS7CHASE"}, {{A_GoopSplat}, "A_GOOPSPLAT"}, {{A_Boss2PogoSFX}, "A_BOSS2POGOSFX"}, {{A_Boss2PogoTarget}, "A_BOSS2POGOTARGET"}, @@ -1094,236 +1093,6 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_FSGNC", "S_FSGND", - // Black Eggman (Boss 7) - "S_BLACKEGG_STND", - "S_BLACKEGG_STND2", - "S_BLACKEGG_WALK1", - "S_BLACKEGG_WALK2", - "S_BLACKEGG_WALK3", - "S_BLACKEGG_WALK4", - "S_BLACKEGG_WALK5", - "S_BLACKEGG_WALK6", - "S_BLACKEGG_SHOOT1", - "S_BLACKEGG_SHOOT2", - "S_BLACKEGG_PAIN1", - "S_BLACKEGG_PAIN2", - "S_BLACKEGG_PAIN3", - "S_BLACKEGG_PAIN4", - "S_BLACKEGG_PAIN5", - "S_BLACKEGG_PAIN6", - "S_BLACKEGG_PAIN7", - "S_BLACKEGG_PAIN8", - "S_BLACKEGG_PAIN9", - "S_BLACKEGG_PAIN10", - "S_BLACKEGG_PAIN11", - "S_BLACKEGG_PAIN12", - "S_BLACKEGG_PAIN13", - "S_BLACKEGG_PAIN14", - "S_BLACKEGG_PAIN15", - "S_BLACKEGG_PAIN16", - "S_BLACKEGG_PAIN17", - "S_BLACKEGG_PAIN18", - "S_BLACKEGG_PAIN19", - "S_BLACKEGG_PAIN20", - "S_BLACKEGG_PAIN21", - "S_BLACKEGG_PAIN22", - "S_BLACKEGG_PAIN23", - "S_BLACKEGG_PAIN24", - "S_BLACKEGG_PAIN25", - "S_BLACKEGG_PAIN26", - "S_BLACKEGG_PAIN27", - "S_BLACKEGG_PAIN28", - "S_BLACKEGG_PAIN29", - "S_BLACKEGG_PAIN30", - "S_BLACKEGG_PAIN31", - "S_BLACKEGG_PAIN32", - "S_BLACKEGG_PAIN33", - "S_BLACKEGG_PAIN34", - "S_BLACKEGG_PAIN35", - "S_BLACKEGG_HITFACE1", - "S_BLACKEGG_HITFACE2", - "S_BLACKEGG_HITFACE3", - "S_BLACKEGG_HITFACE4", - "S_BLACKEGG_DIE1", - "S_BLACKEGG_DIE2", - "S_BLACKEGG_DIE3", - "S_BLACKEGG_DIE4", - "S_BLACKEGG_DIE5", - "S_BLACKEGG_MISSILE1", - "S_BLACKEGG_MISSILE2", - "S_BLACKEGG_MISSILE3", - "S_BLACKEGG_GOOP", - "S_BLACKEGG_JUMP1", - "S_BLACKEGG_JUMP2", - "S_BLACKEGG_DESTROYPLAT1", - "S_BLACKEGG_DESTROYPLAT2", - "S_BLACKEGG_DESTROYPLAT3", - - "S_BLACKEGG_HELPER", // Collision helper - - "S_BLACKEGG_GOOP1", - "S_BLACKEGG_GOOP2", - "S_BLACKEGG_GOOP3", - "S_BLACKEGG_GOOP4", - "S_BLACKEGG_GOOP5", - "S_BLACKEGG_GOOP6", - "S_BLACKEGG_GOOP7", - - "S_BLACKEGG_MISSILE", - - // New Very-Last-Minute 2.1 Brak Eggman (Cy-Brak-demon) - "S_CYBRAKDEMON_IDLE", - "S_CYBRAKDEMON_WALK1", - "S_CYBRAKDEMON_WALK2", - "S_CYBRAKDEMON_WALK3", - "S_CYBRAKDEMON_WALK4", - "S_CYBRAKDEMON_WALK5", - "S_CYBRAKDEMON_WALK6", - "S_CYBRAKDEMON_CHOOSE_ATTACK1", - "S_CYBRAKDEMON_MISSILE_ATTACK1", // Aim - "S_CYBRAKDEMON_MISSILE_ATTACK2", // Fire - "S_CYBRAKDEMON_MISSILE_ATTACK3", // Aim - "S_CYBRAKDEMON_MISSILE_ATTACK4", // Fire - "S_CYBRAKDEMON_MISSILE_ATTACK5", // Aim - "S_CYBRAKDEMON_MISSILE_ATTACK6", // Fire - "S_CYBRAKDEMON_FLAME_ATTACK1", // Reset - "S_CYBRAKDEMON_FLAME_ATTACK2", // Aim - "S_CYBRAKDEMON_FLAME_ATTACK3", // Fire - "S_CYBRAKDEMON_FLAME_ATTACK4", // Loop - "S_CYBRAKDEMON_CHOOSE_ATTACK2", - "S_CYBRAKDEMON_VILE_ATTACK1", - "S_CYBRAKDEMON_VILE_ATTACK2", - "S_CYBRAKDEMON_VILE_ATTACK3", - "S_CYBRAKDEMON_VILE_ATTACK4", - "S_CYBRAKDEMON_VILE_ATTACK5", - "S_CYBRAKDEMON_VILE_ATTACK6", - "S_CYBRAKDEMON_NAPALM_ATTACK1", - "S_CYBRAKDEMON_NAPALM_ATTACK2", - "S_CYBRAKDEMON_NAPALM_ATTACK3", - "S_CYBRAKDEMON_FINISH_ATTACK1", // If just attacked, remove MF2_FRET w/out going back to spawnstate - "S_CYBRAKDEMON_FINISH_ATTACK2", // Force a delay between attacks so you don't get bombarded with them back-to-back - "S_CYBRAKDEMON_PAIN1", - "S_CYBRAKDEMON_PAIN2", - "S_CYBRAKDEMON_PAIN3", - "S_CYBRAKDEMON_DIE1", - "S_CYBRAKDEMON_DIE2", - "S_CYBRAKDEMON_DIE3", - "S_CYBRAKDEMON_DIE4", - "S_CYBRAKDEMON_DIE5", - "S_CYBRAKDEMON_DIE6", - "S_CYBRAKDEMON_DIE7", - "S_CYBRAKDEMON_DIE8", - "S_CYBRAKDEMON_DEINVINCIBLERIZE", - "S_CYBRAKDEMON_INVINCIBLERIZE", - - "S_CYBRAKDEMONMISSILE", - "S_CYBRAKDEMONMISSILE_EXPLODE1", - "S_CYBRAKDEMONMISSILE_EXPLODE2", - "S_CYBRAKDEMONMISSILE_EXPLODE3", - - "S_CYBRAKDEMONFLAMESHOT_FLY1", - "S_CYBRAKDEMONFLAMESHOT_FLY2", - "S_CYBRAKDEMONFLAMESHOT_FLY3", - "S_CYBRAKDEMONFLAMESHOT_DIE", - - "S_CYBRAKDEMONFLAMEREST", - - "S_CYBRAKDEMONELECTRICBARRIER_INIT1", - "S_CYBRAKDEMONELECTRICBARRIER_INIT2", - "S_CYBRAKDEMONELECTRICBARRIER_PLAYSOUND", - "S_CYBRAKDEMONELECTRICBARRIER1", - "S_CYBRAKDEMONELECTRICBARRIER2", - "S_CYBRAKDEMONELECTRICBARRIER3", - "S_CYBRAKDEMONELECTRICBARRIER4", - "S_CYBRAKDEMONELECTRICBARRIER5", - "S_CYBRAKDEMONELECTRICBARRIER6", - "S_CYBRAKDEMONELECTRICBARRIER7", - "S_CYBRAKDEMONELECTRICBARRIER8", - "S_CYBRAKDEMONELECTRICBARRIER9", - "S_CYBRAKDEMONELECTRICBARRIER10", - "S_CYBRAKDEMONELECTRICBARRIER11", - "S_CYBRAKDEMONELECTRICBARRIER12", - "S_CYBRAKDEMONELECTRICBARRIER13", - "S_CYBRAKDEMONELECTRICBARRIER14", - "S_CYBRAKDEMONELECTRICBARRIER15", - "S_CYBRAKDEMONELECTRICBARRIER16", - "S_CYBRAKDEMONELECTRICBARRIER17", - "S_CYBRAKDEMONELECTRICBARRIER18", - "S_CYBRAKDEMONELECTRICBARRIER19", - "S_CYBRAKDEMONELECTRICBARRIER20", - "S_CYBRAKDEMONELECTRICBARRIER21", - "S_CYBRAKDEMONELECTRICBARRIER22", - "S_CYBRAKDEMONELECTRICBARRIER23", - "S_CYBRAKDEMONELECTRICBARRIER24", - "S_CYBRAKDEMONELECTRICBARRIER_DIE1", - "S_CYBRAKDEMONELECTRICBARRIER_DIE2", - "S_CYBRAKDEMONELECTRICBARRIER_DIE3", - "S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMCHECK", - "S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMSUCCESS", - "S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMCHOOSE", - "S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM1", - "S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM2", - "S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM3", - "S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM4", - "S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM5", - "S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM6", - "S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM7", - "S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM8", - "S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM9", - "S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM10", - "S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM11", - "S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM12", - "S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMFAIL", - "S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMLOOP", - "S_CYBRAKDEMONELECTRICBARRIER_REVIVE1", - "S_CYBRAKDEMONELECTRICBARRIER_REVIVE2", - "S_CYBRAKDEMONELECTRICBARRIER_REVIVE3", - - "S_CYBRAKDEMONTARGETRETICULE1", - "S_CYBRAKDEMONTARGETRETICULE2", - "S_CYBRAKDEMONTARGETRETICULE3", - "S_CYBRAKDEMONTARGETRETICULE4", - "S_CYBRAKDEMONTARGETRETICULE5", - "S_CYBRAKDEMONTARGETRETICULE6", - "S_CYBRAKDEMONTARGETRETICULE7", - "S_CYBRAKDEMONTARGETRETICULE8", - "S_CYBRAKDEMONTARGETRETICULE9", - "S_CYBRAKDEMONTARGETRETICULE10", - "S_CYBRAKDEMONTARGETRETICULE11", - "S_CYBRAKDEMONTARGETRETICULE12", - "S_CYBRAKDEMONTARGETRETICULE13", - "S_CYBRAKDEMONTARGETRETICULE14", - - "S_CYBRAKDEMONTARGETDOT", - - "S_CYBRAKDEMONNAPALMBOMBLARGE_FLY1", - "S_CYBRAKDEMONNAPALMBOMBLARGE_FLY2", - "S_CYBRAKDEMONNAPALMBOMBLARGE_FLY3", - "S_CYBRAKDEMONNAPALMBOMBLARGE_FLY4", - "S_CYBRAKDEMONNAPALMBOMBLARGE_DIE1", // Explode - "S_CYBRAKDEMONNAPALMBOMBLARGE_DIE2", // Outer ring - "S_CYBRAKDEMONNAPALMBOMBLARGE_DIE3", // Center - "S_CYBRAKDEMONNAPALMBOMBLARGE_DIE4", // Sound - - "S_CYBRAKDEMONNAPALMBOMBSMALL", - "S_CYBRAKDEMONNAPALMBOMBSMALL_DIE1", // Explode - "S_CYBRAKDEMONNAPALMBOMBSMALL_DIE2", // Outer ring - "S_CYBRAKDEMONNAPALMBOMBSMALL_DIE3", // Inner ring - "S_CYBRAKDEMONNAPALMBOMBSMALL_DIE4", // Center - "S_CYBRAKDEMONNAPALMBOMBSMALL_DIE5", // Sound - - "S_CYBRAKDEMONNAPALMFLAME_FLY1", - "S_CYBRAKDEMONNAPALMFLAME_FLY2", - "S_CYBRAKDEMONNAPALMFLAME_FLY3", - "S_CYBRAKDEMONNAPALMFLAME_FLY4", - "S_CYBRAKDEMONNAPALMFLAME_FLY5", - "S_CYBRAKDEMONNAPALMFLAME_FLY6", - "S_CYBRAKDEMONNAPALMFLAME_DIE", - - "S_CYBRAKDEMONVILEEXPLOSION1", - "S_CYBRAKDEMONVILEEXPLOSION2", - "S_CYBRAKDEMONVILEEXPLOSION3", - // Metal Sonic (Race) "S_METALSONIC_RACE", // Metal Sonic (Battle) @@ -3538,6 +3307,10 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi // Brake drift sparks "S_BRAKEDRIFT", + // Brake dust + "S_BRAKEDUST1", + "S_BRAKEDUST2", + // Drift Smoke "S_DRIFTDUST1", "S_DRIFTDUST2", @@ -3784,8 +3557,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_SSMINE_DEPLOY12", "S_SSMINE_DEPLOY13", "S_SSMINE_EXPLODE", - "S_MINEEXPLOSION1", - "S_MINEEXPLOSION2", + "S_SSMINE_EXPLODE2", // New explosion "S_QUICKBOOM1", @@ -4540,6 +4312,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_EBARREL16", "S_EBARREL17", "S_EBARREL18", + "S_EBARREL19", "S_MERRYHORSE", "S_BLUEFRUIT", "S_ORANGEFRUIT", @@ -4816,25 +4589,6 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_FSGNB", "MT_FANGWAYPOINT", - // Black Eggman (Boss 7) - "MT_BLACKEGGMAN", - "MT_BLACKEGGMAN_HELPER", - "MT_BLACKEGGMAN_GOOPFIRE", - "MT_BLACKEGGMAN_MISSILE", - - // New Very-Last-Minute 2.1 Brak Eggman (Cy-Brak-demon) - "MT_CYBRAKDEMON", - "MT_CYBRAKDEMON_ELECTRIC_BARRIER", - "MT_CYBRAKDEMON_MISSILE", - "MT_CYBRAKDEMON_FLAMESHOT", - "MT_CYBRAKDEMON_FLAMEREST", - "MT_CYBRAKDEMON_TARGET_RETICULE", - "MT_CYBRAKDEMON_TARGET_DOT", - "MT_CYBRAKDEMON_NAPALM_BOMB_LARGE", - "MT_CYBRAKDEMON_NAPALM_BOMB_SMALL", - "MT_CYBRAKDEMON_NAPALM_FLAMES", - "MT_CYBRAKDEMON_VILE_EXPLOSION", - // Metal Sonic (Boss 9) "MT_METALSONIC_RACE", "MT_METALSONIC_BATTLE", @@ -5509,6 +5263,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_WIPEOUTTRAIL", "MT_DRIFTSPARK", "MT_BRAKEDRIFT", + "MT_BRAKEDUST", "MT_DRIFTDUST", "MT_DRIFTELECTRICITY", "MT_DRIFTELECTRICSPARK", @@ -5533,8 +5288,6 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_SSMINE_SHIELD", // Special Stage Mine stuff "MT_SSMINE", - "MT_MINEEXPLOSION", - "MT_MINEEXPLOSIONSOUND", "MT_SMOLDERING", // New explosion "MT_BOOMEXPLODE", @@ -6170,7 +5923,9 @@ const char *COLOR_ENUMS[] = { "CHAOSEMERALD4", "CHAOSEMERALD5", "CHAOSEMERALD6", - "CHAOSEMERALD7" + "CHAOSEMERALD7", + + "INVINCFLASH" }; const char *const KARTHUD_LIST[] = { diff --git a/src/doomdef.h b/src/doomdef.h index 7489e4688..4d16e5547 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -398,6 +398,8 @@ typedef enum SKINCOLOR_CHAOSEMERALD6, SKINCOLOR_CHAOSEMERALD7, + SKINCOLOR_INVINCFLASH, + SKINCOLOR_FIRSTFREESLOT, SKINCOLOR_LASTFREESLOT = SKINCOLOR_FIRSTFREESLOT + NUMCOLORFREESLOTS - 1, diff --git a/src/info.c b/src/info.c index 672c0401d..8d3b31f52 100644 --- a/src/info.c +++ b/src/info.c @@ -112,7 +112,6 @@ char sprnames[NUMSPRITES + 1][5] = "EGGR", // Boss 7 (Dark City) - "BRAK", "BGOO", // Goop "BMSL", @@ -543,6 +542,7 @@ char sprnames[NUMSPRITES + 1][5] = "WIPD", // Wipeout dust trail "DRIF", // Drift Sparks "BDRF", // Brake drift sparks + "BRAK", // Brake dust "DRWS", // Drift dust sparks "DREL", // Drift electricity "DRES", // Drift electric sparks @@ -1598,243 +1598,6 @@ state_t states[NUMSTATES] = {SPR_FSGN, 2|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_FSGNC {SPR_FSGN, 3|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_FSGND - // Black Eggman (Boss 7) - {SPR_BRAK, 0, 1, {A_SetReactionTime}, 0, 0, S_BLACKEGG_STND2}, // S_BLACKEGG_STND - {SPR_BRAK, 0, 7, {A_Look}, 1, 0, S_BLACKEGG_STND2}, // S_BLACKEGG_STND2 - {SPR_BRAK, 1, 7, {NULL}, 0, 0, S_BLACKEGG_WALK2}, // S_BLACKEGG_WALK1 - {SPR_BRAK, 2, 7, {NULL}, 0, 0, S_BLACKEGG_WALK3}, // S_BLACKEGG_WALK2 - {SPR_BRAK, 3, 7, {A_PlaySound}, sfx_bestep, 0, S_BLACKEGG_WALK4}, // S_BLACKEGG_WALK3 - {SPR_BRAK, 4, 7, {NULL}, 0, 0, S_BLACKEGG_WALK5}, // S_BLACKEGG_WALK4 - {SPR_BRAK, 5, 7, {NULL}, 0, 0, S_BLACKEGG_WALK6}, // S_BLACKEGG_WALK5 - {SPR_BRAK, 6, 7, {A_PlaySound}, sfx_bestp2, 0, S_BLACKEGG_WALK1}, // S_BLACKEGG_WALK6 - {SPR_BRAK, 7, 3, {NULL}, 0, 0, S_BLACKEGG_SHOOT2}, // S_BLACKEGG_SHOOT1 - {SPR_BRAK, 24, 1, {A_PlaySound}, sfx_befire, 0, S_BLACKEGG_SHOOT1}, // S_BLACKEGG_SHOOT2 - - {SPR_BRAK, 8, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN2}, // S_BLACKEGG_PAIN1 - {SPR_BRAK, 25, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN3}, // S_BLACKEGG_PAIN2 - {SPR_BRAK, 8, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN4}, // S_BLACKEGG_PAIN3 - {SPR_BRAK, 25, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN5}, // S_BLACKEGG_PAIN4 - {SPR_BRAK, 8, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN6}, // S_BLACKEGG_PAIN5 - {SPR_BRAK, 25, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN7}, // S_BLACKEGG_PAIN6 - {SPR_BRAK, 8, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN8}, // S_BLACKEGG_PAIN7 - {SPR_BRAK, 25, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN9}, // S_BLACKEGG_PAIN8 - {SPR_BRAK, 8, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN10}, // S_BLACKEGG_PAIN9 - {SPR_BRAK, 25, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN11}, // S_BLACKEGG_PAIN10 - {SPR_BRAK, 8, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN12}, // S_BLACKEGG_PAIN11 - {SPR_BRAK, 25, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN13}, // S_BLACKEGG_PAIN12 - {SPR_BRAK, 8, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN14}, // S_BLACKEGG_PAIN13 - {SPR_BRAK, 25, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN15}, // S_BLACKEGG_PAIN14 - {SPR_BRAK, 8, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN16}, // S_BLACKEGG_PAIN15 - {SPR_BRAK, 25, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN17}, // S_BLACKEGG_PAIN16 - {SPR_BRAK, 8, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN18}, // S_BLACKEGG_PAIN17 - {SPR_BRAK, 25, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN19}, // S_BLACKEGG_PAIN18 - {SPR_BRAK, 8, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN20}, // S_BLACKEGG_PAIN19 - {SPR_BRAK, 25, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN21}, // S_BLACKEGG_PAIN20 - {SPR_BRAK, 8, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN22}, // S_BLACKEGG_PAIN21 - {SPR_BRAK, 25, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN23}, // S_BLACKEGG_PAIN22 - {SPR_BRAK, 8, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN24}, // S_BLACKEGG_PAIN23 - {SPR_BRAK, 25, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN25}, // S_BLACKEGG_PAIN24 - {SPR_BRAK, 8, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN26}, // S_BLACKEGG_PAIN25 - {SPR_BRAK, 25, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN27}, // S_BLACKEGG_PAIN26 - {SPR_BRAK, 8, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN28}, // S_BLACKEGG_PAIN27 - {SPR_BRAK, 25, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN29}, // S_BLACKEGG_PAIN28 - {SPR_BRAK, 8, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN30}, // S_BLACKEGG_PAIN29 - {SPR_BRAK, 25, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN31}, // S_BLACKEGG_PAIN30 - {SPR_BRAK, 8, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN32}, // S_BLACKEGG_PAIN31 - {SPR_BRAK, 25, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN33}, // S_BLACKEGG_PAIN32 - {SPR_BRAK, 8, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN34}, // S_BLACKEGG_PAIN33 - {SPR_BRAK, 25, 1, {NULL}, 0, 0, S_BLACKEGG_PAIN35}, // S_BLACKEGG_PAIN34 - {SPR_BRAK, 8, 1, {NULL}, 0, 0, S_BLACKEGG_WALK1}, // S_BLACKEGG_PAIN35 - - {SPR_BRAK, 9, 20, {NULL}, 0, 0, S_BLACKEGG_HITFACE2}, // S_BLACKEGG_HITFACE1 - {SPR_BRAK, 10, 2, {NULL}, 0, 0, S_BLACKEGG_HITFACE3}, // S_BLACKEGG_HITFACE2 - {SPR_BRAK, 11, 2, {NULL}, 0, 0, S_BLACKEGG_HITFACE4}, // S_BLACKEGG_HITFACE3 - {SPR_BRAK, 12,14, {NULL}, 0, 0, S_BLACKEGG_PAIN1}, // S_BLACKEGG_HITFACE4 - - {SPR_BRAK, 13, 14, {NULL}, 0, 0, S_BLACKEGG_DIE2}, // S_BLACKEGG_DIE1 - {SPR_BRAK, 14, 7, {NULL}, 0, 0, S_BLACKEGG_DIE3}, // S_BLACKEGG_DIE2 - {SPR_BRAK, 15, 5, {NULL}, 0, 0, S_BLACKEGG_DIE4}, // S_BLACKEGG_DIE3 - {SPR_BRAK, 16, 3, {A_PlaySound}, sfx_bgxpld, 0, S_BLACKEGG_DIE5}, // S_BLACKEGG_DIE4 - {SPR_BRAK, 17, -1, {NULL}, 0, 0, S_BLACKEGG_DIE5}, // S_BLACKEGG_DIE5 - - {SPR_BRAK, 18, 14, {NULL}, 0, 0, S_BLACKEGG_MISSILE2}, // S_BLACKEGG_MISSILE1 - {SPR_BRAK, 19, 5, {NULL}, 0, 0, S_BLACKEGG_MISSILE3}, // S_BLACKEGG_MISSILE2 - {SPR_BRAK, 20, 35, {A_Boss7FireMissiles}, MT_BLACKEGGMAN_MISSILE, sfx_beshot, S_BLACKEGG_JUMP1}, // S_BLACKEGG_MISSILE3 - - {SPR_BRAK, 21, -1, {NULL}, 0, 0, S_BLACKEGG_STND}, // S_BLACKEGG_GOOP - - {SPR_BRAK, 22, 14, {A_PlaySound}, sfx_belnch, 0, S_BLACKEGG_JUMP2}, // S_BLACKEGG_JUMP1 - {SPR_BRAK, 23, -1, {NULL}, 0, 0, S_BLACKEGG_WALK1}, // S_BLACKEGG_JUMP2 - - {SPR_BRAK, 21, 3*TICRATE, {NULL}, 0, 0, S_BLACKEGG_DESTROYPLAT2}, // S_BLACKEGG_DESTROYPLAT1 - {SPR_BRAK, 21, 1, {A_PlaySound}, sfx_s3k54, 0, S_BLACKEGG_DESTROYPLAT3}, // S_BLACKEGG_DESTROYPLAT2 - {SPR_BRAK, 21, 14, {A_LinedefExecute}, LE_BRAKPLATFORM, 0, S_BLACKEGG_STND}, // S_BLACKEGG_DESTROYPLAT3 - - {SPR_NULL, 0, 1, {A_CapeChase}, (160 - 20) << 16, 0, S_BLACKEGG_HELPER}, // S_BLACKEGG_HELPER - - {SPR_BGOO, FF_TRANS50 , 2, {NULL}, 0, 0, S_BLACKEGG_GOOP2}, // S_BLACKEGG_GOOP1 - {SPR_BGOO, FF_TRANS50|1, 2, {NULL}, 0, 0, S_BLACKEGG_GOOP1}, // S_BLACKEGG_GOOP2 - {SPR_BGOO, FF_TRANS50|2, 6*TICRATE, {A_GoopSplat}, 0, 0, S_BLACKEGG_GOOP4}, // S_BLACKEGG_GOOP3 - {SPR_BGOO, FF_TRANS60|2, 4, {NULL}, 0, 0, S_BLACKEGG_GOOP5}, // S_BLACKEGG_GOOP4 - {SPR_BGOO, FF_TRANS70|2, 4, {NULL}, 0, 0, S_BLACKEGG_GOOP6}, // S_BLACKEGG_GOOP5 - {SPR_BGOO, FF_TRANS80|2, 4, {NULL}, 0, 0, S_BLACKEGG_GOOP7}, // S_BLACKEGG_GOOP6 - {SPR_BGOO, FF_TRANS90|2, 4, {NULL}, 0, 0, S_NULL}, // S_BLACKEGG_GOOP7 - - {SPR_BMSL, 0, 1, {NULL}, 0, 0, S_BLACKEGG_MISSILE}, // S_BLACKEGG_MISSILE - - // New Very-Last-Minute 2.1 Brak Eggman (Cy-Brak-demon) - {SPR_BRAK, 0, 10, {A_Look}, 0, 0, S_CYBRAKDEMON_IDLE}, // S_CYBRAKDEMON_IDLE - {SPR_BRAK, 1, 8, {A_BrakChase}, 3, 0, S_CYBRAKDEMON_WALK2}, // S_CYBRAKDEMON_WALK1 - {SPR_BRAK, 2, 8, {A_BrakChase}, 3, 0, S_CYBRAKDEMON_WALK3}, // S_CYBRAKDEMON_WALK2 - {SPR_BRAK, 3, 8, {A_BrakChase}, 3, sfx_bestep, S_CYBRAKDEMON_WALK4}, // S_CYBRAKDEMON_WALK3 - {SPR_BRAK, 4, 8, {A_BrakChase}, 3, 0, S_CYBRAKDEMON_WALK5}, // S_CYBRAKDEMON_WALK4 - {SPR_BRAK, 5, 8, {A_BrakChase}, 3, 0, S_CYBRAKDEMON_WALK6}, // S_CYBRAKDEMON_WALK5 - {SPR_BRAK, 6, 8, {A_BrakChase}, 3, sfx_bestp2, S_CYBRAKDEMON_WALK1}, // S_CYBRAKDEMON_WALK6 - {SPR_BRAK, 7, 6, {A_RandomState}, S_CYBRAKDEMON_MISSILE_ATTACK1, S_CYBRAKDEMON_FLAME_ATTACK1, S_CYBRAKDEMON_MISSILE_ATTACK1}, // S_CYBRAKDEMON_CHOOSE_ATTACK1 - {SPR_BRAK, 7, 6, {A_FaceTarget}, 0, 0, S_CYBRAKDEMON_MISSILE_ATTACK2}, // S_CYBRAKDEMON_MISSILE_ATTACK1 // Aim - {SPR_BRAK, 26 + FF_FULLBRIGHT, 12, {A_BrakFireShot}, MT_CYBRAKDEMON_MISSILE, 128, S_CYBRAKDEMON_MISSILE_ATTACK3}, // S_CYBRAKDEMON_MISSILE_ATTACK2 // Fire - {SPR_BRAK, 7, 12, {A_FaceTarget}, 0, 0, S_CYBRAKDEMON_MISSILE_ATTACK4}, // S_CYBRAKDEMON_MISSILE_ATTACK3 // Aim - {SPR_BRAK, 26 + FF_FULLBRIGHT, 12, {A_BrakFireShot}, MT_CYBRAKDEMON_MISSILE, 128, S_CYBRAKDEMON_MISSILE_ATTACK5}, // S_CYBRAKDEMON_MISSILE_ATTACK4 // Fire - {SPR_BRAK, 7, 12, {A_FaceTarget}, 0, 0, S_CYBRAKDEMON_MISSILE_ATTACK6}, // S_CYBRAKDEMON_MISSILE_ATTACK5 // Aim - {SPR_BRAK, 26 + FF_FULLBRIGHT, 12, {A_BrakFireShot}, MT_CYBRAKDEMON_MISSILE, 128, S_CYBRAKDEMON_FINISH_ATTACK1}, // S_CYBRAKDEMON_MISSILE_ATTACK6 // Fire - {SPR_BRAK, 7, 1, {A_Repeat}, 1, S_CYBRAKDEMON_FLAME_ATTACK1, S_CYBRAKDEMON_FLAME_ATTACK2}, // S_CYBRAKDEMON_FLAME_ATTACK1 // Reset - {SPR_BRAK, 7, 6, {A_FaceTarget}, 0, 0, S_CYBRAKDEMON_FLAME_ATTACK3}, // S_CYBRAKDEMON_FLAME_ATTACK2 // Aim - {SPR_BRAK, 26 + FF_FULLBRIGHT, 2, {A_BrakFireShot}, MT_CYBRAKDEMON_FLAMESHOT, 128, S_CYBRAKDEMON_FLAME_ATTACK4}, // S_CYBRAKDEMON_FLAME_ATTACK3 // Fire - {SPR_BRAK, 7, 1, {A_Repeat}, 30, S_CYBRAKDEMON_FLAME_ATTACK3, S_CYBRAKDEMON_FINISH_ATTACK1}, // S_CYBRAKDEMON_FLAME_ATTACK4 // Loop - {SPR_BRAK, 0, 6, {A_RandomState}, S_CYBRAKDEMON_VILE_ATTACK1, S_CYBRAKDEMON_NAPALM_ATTACK1, S_CYBRAKDEMON_MISSILE_ATTACK1}, // S_CYBRAKDEMON_CHOOSE_ATTACK2 - {SPR_BRAK, 20, 0, {A_LinedefExecute}, LE_BRAKVILEATACK, 0, S_CYBRAKDEMON_VILE_ATTACK2}, // S_CYBRAKDEMON_VILE_ATTACK1 - {SPR_BRAK, 20, 24, {A_VileTarget}, MT_CYBRAKDEMON_TARGET_RETICULE, 1, S_CYBRAKDEMON_VILE_ATTACK3}, // S_CYBRAKDEMON_VILE_ATTACK2 - {SPR_BRAK, 19, 8, {A_FaceTarget}, 0, 0, S_CYBRAKDEMON_VILE_ATTACK4}, // S_CYBRAKDEMON_VILE_ATTACK3 - {SPR_BRAK, 18, 8, {A_FaceTarget}, 0, 0, S_CYBRAKDEMON_VILE_ATTACK5}, // S_CYBRAKDEMON_VILE_ATTACK4 - {SPR_BRAK, 8, 32, {A_FaceTarget}, 0, 0, S_CYBRAKDEMON_VILE_ATTACK6}, // S_CYBRAKDEMON_VILE_ATTACK5 - {SPR_BRAK, 20 + FF_FULLBRIGHT, 28, {A_VileAttack}, sfx_brakrx, MT_CYBRAKDEMON_VILE_EXPLOSION + (1<<16), S_CYBRAKDEMON_FINISH_ATTACK1}, // S_CYBRAKDEMON_VILE_ATTACK6 - {SPR_BRAK, 0, 6, {A_FaceTarget}, 0, 0, S_CYBRAKDEMON_NAPALM_ATTACK2}, // S_CYBRAKDEMON_NAPALM_ATTACK1 - {SPR_BRAK, 21 + FF_FULLBRIGHT, 8, {A_BrakLobShot}, MT_CYBRAKDEMON_NAPALM_BOMB_LARGE, 96, S_CYBRAKDEMON_NAPALM_ATTACK3}, // S_CYBRAKDEMON_NAPALM_ATTACK2 - {SPR_BRAK, 0, 8, {A_FaceTarget}, 0, 0, S_CYBRAKDEMON_FINISH_ATTACK1}, // S_CYBRAKDEMON_NAPALM_ATTACK3 - {SPR_BRAK, 0, 0, {A_SetObjectFlags2}, MF2_FRET, 1, S_CYBRAKDEMON_FINISH_ATTACK2}, // S_CYBRAKDEMON_FINISH_ATTACK1 // If just attacked, remove MF2_FRET w/out going back to spawnstate - {SPR_BRAK, 0, 0, {A_SetReactionTime}, 0, 0, S_CYBRAKDEMON_WALK1}, // S_CYBRAKDEMON_FINISH_ATTACK2 // If just attacked, remove MF2_FRET w/out going back to spawnstate - {SPR_BRAK, 18, 24, {A_Pain}, 0, 0, S_CYBRAKDEMON_PAIN2}, // S_CYBRAKDEMON_PAIN1 - {SPR_BRAK, 18, 0, {A_CheckHealth}, 3, S_CYBRAKDEMON_PAIN3, S_CYBRAKDEMON_CHOOSE_ATTACK1}, // S_CYBRAKDEMON_PAIN2 - {SPR_BRAK, 18, 0, {A_LinedefExecute}, LE_PINCHPHASE, 0, S_CYBRAKDEMON_CHOOSE_ATTACK1}, // S_CYBRAKDEMON_PAIN3 - {SPR_BRAK, 18, 1, {A_Repeat}, 1, S_CYBRAKDEMON_DIE1, S_CYBRAKDEMON_DIE2}, // S_CYBRAKDEMON_DIE1 - {SPR_BRAK, 18, 2, {A_BossScream}, 2, 0, S_CYBRAKDEMON_DIE3}, // S_CYBRAKDEMON_DIE2 - {SPR_BRAK, 18, 0, {A_Repeat}, 52, S_CYBRAKDEMON_DIE2, S_CYBRAKDEMON_DIE4}, // S_CYBRAKDEMON_DIE3 - {SPR_BRAK, 13, 34, {A_BossDeath}, 0, 0, S_CYBRAKDEMON_DIE5}, // S_CYBRAKDEMON_DIE4 - {SPR_BRAK, 14, 34, {NULL}, 0, 0, S_CYBRAKDEMON_DIE6}, // S_CYBRAKDEMON_DIE5 - {SPR_BRAK, 15, 34, {NULL}, 0, 0, S_CYBRAKDEMON_DIE7}, // S_CYBRAKDEMON_DIE6 - {SPR_BRAK, 16, 34, {NULL}, 0, 0, S_CYBRAKDEMON_DIE8}, // S_CYBRAKDEMON_DIE7 - {SPR_BRAK, 17, 34, {NULL}, sfx_befall, 0, S_CYBRAKDEMON_DIE8}, // S_CYBRAKDEMON_DIE8 - {SPR_BRAK, 0, 0, {A_SetObjectFlags}, MF_SPECIAL|MF_SHOOTABLE, 2, S_CYBRAKDEMON_IDLE}, // S_CYBRAKDEMON_DEINVINCIBLERIZE - {SPR_BRAK, 0, 0, {A_SetObjectFlags}, MF_SPECIAL|MF_SHOOTABLE, 1, S_CYBRAKDEMON_IDLE}, // S_CYBRAKDEMON_INVINCIBLERIZE - - {SPR_RCKT, 0 + FF_FULLBRIGHT, 1, {A_SetObjectFlags2}, MF2_RAILRING, 2, S_CYBRAKDEMONMISSILE}, // S_CYBRAKDEMONMISSILE - {SPR_RCKT, 1 + FF_FULLBRIGHT, 8, {A_Explode}, 0, 0, S_CYBRAKDEMONMISSILE_EXPLODE2}, // S_CYBRAKDEMONMISSILE_EXPLODE1 //TODO: set missile mobj's "damage" to an appropriate radius - {SPR_RCKT, 2 + FF_FULLBRIGHT, 6, {A_NapalmScatter}, MT_CYBRAKDEMON_NAPALM_FLAMES + (6<<16), 32 + (16<<16), S_CYBRAKDEMONMISSILE_EXPLODE3}, // S_CYBRAKDEMONMISSILE_EXPLODE2 - {SPR_RCKT, 3 + FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_NULL}, // S_CYBRAKDEMONMISSILE_EXPLODE3 - - {SPR_FLME, FF_FULLBRIGHT , 15, {NULL}, 0, 0, S_CYBRAKDEMONFLAMESHOT_FLY2}, // S_CYBRAKDEMONFLAMESHOT_FLY1 - {SPR_FLME, FF_FULLBRIGHT|1, 15, {NULL}, 0, 0, S_CYBRAKDEMONFLAMESHOT_FLY3}, // S_CYBRAKDEMONFLAMESHOT_FLY2 - {SPR_FLME, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_CYBRAKDEMONFLAMESHOT_FLY3}, // S_CYBRAKDEMONFLAMESHOT_FLY3 - {SPR_FLME, FF_FULLBRIGHT|2, 0, {A_SpawnObjectRelative}, 0, MT_CYBRAKDEMON_FLAMEREST, S_NULL}, // S_CYBRAKDEMONFLAMESHOT_DIE - - {SPR_FLAM, FF_FULLBRIGHT, 1, {A_SetFuse}, 10*TICRATE, 0, S_FLAMEREST}, // S_CYBRAKDEMONFLAMEREST - - {SPR_ELEC, 0 + FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER_INIT2}, // S_CYBRAKDEMONELECTRICBARRIER_INIT1 - {SPR_ELEC, 0 + FF_FULLBRIGHT, 0, {A_RemoteAction}, -1, S_CYBRAKDEMON_INVINCIBLERIZE, S_CYBRAKDEMONELECTRICBARRIER_PLAYSOUND}, // S_CYBRAKDEMONELECTRICBARRIER_INIT2 - {SPR_ELEC, 0 + FF_FULLBRIGHT, 0, {A_PlayActiveSound}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER1}, // S_CYBRAKDEMONELECTRICBARRIER_PLAYSOUND - {SPR_ELEC, 0 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER2}, // S_CYBRAKDEMONELECTRICBARRIER1 - {SPR_ELEC, 0 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER3}, // S_CYBRAKDEMONELECTRICBARRIER2 - {SPR_ELEC, 1 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER4}, // S_CYBRAKDEMONELECTRICBARRIER3 - {SPR_ELEC, 1 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER5}, // S_CYBRAKDEMONELECTRICBARRIER4 - {SPR_ELEC, 2 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER6}, // S_CYBRAKDEMONELECTRICBARRIER5 - {SPR_ELEC, 2 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER7}, // S_CYBRAKDEMONELECTRICBARRIER6 - {SPR_ELEC, 3 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER8}, // S_CYBRAKDEMONELECTRICBARRIER7 - {SPR_ELEC, 3 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER9}, // S_CYBRAKDEMONELECTRICBARRIER8 - {SPR_ELEC, 4 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER10}, // S_CYBRAKDEMONELECTRICBARRIER9 - {SPR_ELEC, 4 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER11}, // S_CYBRAKDEMONELECTRICBARRIER10 - {SPR_ELEC, 5 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER12}, // S_CYBRAKDEMONELECTRICBARRIER11 - {SPR_ELEC, 5 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER13}, // S_CYBRAKDEMONELECTRICBARRIER12 - {SPR_ELEC, 6 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER14}, // S_CYBRAKDEMONELECTRICBARRIER13 - {SPR_ELEC, 6 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER15}, // S_CYBRAKDEMONELECTRICBARRIER14 - {SPR_ELEC, 7 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER16}, // S_CYBRAKDEMONELECTRICBARRIER15 - {SPR_ELEC, 7 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER17}, // S_CYBRAKDEMONELECTRICBARRIER16 - {SPR_ELEC, 8 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER18}, // S_CYBRAKDEMONELECTRICBARRIER17 - {SPR_ELEC, 8 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER19}, // S_CYBRAKDEMONELECTRICBARRIER18 - {SPR_ELEC, 9 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER20}, // S_CYBRAKDEMONELECTRICBARRIER19 - {SPR_ELEC, 9 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER21}, // S_CYBRAKDEMONELECTRICBARRIER20 - {SPR_ELEC, 10 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER22}, // S_CYBRAKDEMONELECTRICBARRIER21 - {SPR_ELEC, 10 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER23}, // S_CYBRAKDEMONELECTRICBARRIER22 - {SPR_ELEC, 11 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER24}, // S_CYBRAKDEMONELECTRICBARRIER23 - {SPR_ELEC, 11 + FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER_PLAYSOUND}, // S_CYBRAKDEMONELECTRICBARRIER24 - {SPR_NULL, 0, 0, {A_RemoteAction}, -1, S_CYBRAKDEMON_DEINVINCIBLERIZE, S_CYBRAKDEMONELECTRICBARRIER_DIE2}, // S_CYBRAKDEMONELECTRICBARRIER_DIE1 - {SPR_NULL, 0, 0, {A_SetObjectFlags}, MF_PUSHABLE|MF_PAIN, 1, S_CYBRAKDEMONELECTRICBARRIER_DIE3}, // S_CYBRAKDEMONELECTRICBARRIER_DIE2 - {SPR_NULL, 0, 20*TICRATE, {A_Scream}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMSUCCESS}, // S_CYBRAKDEMONELECTRICBARRIER_DIE3 - {SPR_NULL, 0, 0, {A_CheckRandom}, 10, S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMSUCCESS, S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMFAIL}, // S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMCHECK, - {SPR_NULL, 0, 0, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMCHOOSE}, // S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMSUCCESS, - {SPR_NULL, 0, 0, {A_RandomStateRange}, S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM1, S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM12, S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM1}, // S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMCHOOSE, - {SPR_ELEC, 0 + FF_FULLBRIGHT, 1, {A_PlaySound}, sfx_s3k5c, 1, S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMLOOP}, // S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM1, - {SPR_ELEC, 1 + FF_FULLBRIGHT, 1, {A_PlaySound}, sfx_s3k5c, 1, S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMLOOP}, // S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM2, - {SPR_ELEC, 2 + FF_FULLBRIGHT, 1, {A_PlaySound}, sfx_s3k5c, 1, S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMLOOP}, // S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM3, - {SPR_ELEC, 3 + FF_FULLBRIGHT, 1, {A_PlaySound}, sfx_s3k5c, 1, S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMLOOP}, // S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM4, - {SPR_ELEC, 4 + FF_FULLBRIGHT, 1, {A_PlaySound}, sfx_s3k5c, 1, S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMLOOP}, // S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM5, - {SPR_ELEC, 5 + FF_FULLBRIGHT, 1, {A_PlaySound}, sfx_s3k5c, 1, S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMLOOP}, // S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM6, - {SPR_ELEC, 6 + FF_FULLBRIGHT, 1, {A_PlaySound}, sfx_s3k5c, 1, S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMLOOP}, // S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM7, - {SPR_ELEC, 7 + FF_FULLBRIGHT, 1, {A_PlaySound}, sfx_s3k5c, 1, S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMLOOP}, // S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM8, - {SPR_ELEC, 8 + FF_FULLBRIGHT, 1, {A_PlaySound}, sfx_s3k5c, 1, S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMLOOP}, // S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM9, - {SPR_ELEC, 9 + FF_FULLBRIGHT, 1, {A_PlaySound}, sfx_s3k5c, 1, S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMLOOP}, // S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM10, - {SPR_ELEC, 10 + FF_FULLBRIGHT, 1, {A_PlaySound}, sfx_s3k5c, 1, S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMLOOP}, // S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM11, - {SPR_ELEC, 11 + FF_FULLBRIGHT, 1, {A_PlaySound}, sfx_s3k5c, 1, S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMLOOP}, // S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM12, - {SPR_NULL, 0, 1, {NULL}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMLOOP}, // S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMFAIL, - {SPR_NULL, 0, 0, {A_Repeat}, 5*TICRATE, S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMCHECK, S_CYBRAKDEMONELECTRICBARRIER_REVIVE1}, // S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMLOOP, - {SPR_NULL, 0, 0, {A_CapeChase}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER_REVIVE2}, // S_CYBRAKDEMONELECTRICBARRIER_REVIVE1 - {SPR_NULL, 0, 0, {A_SpawnFreshCopy}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER_REVIVE3}, // S_CYBRAKDEMONELECTRICBARRIER_REVIVE2 - {SPR_NULL, 0, TICRATE, {A_PlaySound}, sfx_s3k79, 0, S_NULL}, // S_CYBRAKDEMONELECTRICBARRIER_REVIVE3 - - {SPR_TARG, FF_TRANS50|FF_FULLBRIGHT , 1, {A_VileFire}, sfx_s3k9d, MT_CYBRAKDEMON_TARGET_DOT, S_CYBRAKDEMONTARGETRETICULE2}, // S_CYBRAKDEMONTARGETRETICULE1 - {SPR_TARG, FF_TRANS50|FF_FULLBRIGHT|6, 1, {A_VileFire}, 0, MT_CYBRAKDEMON_TARGET_DOT, S_CYBRAKDEMONTARGETRETICULE3}, // S_CYBRAKDEMONTARGETRETICULE2 - {SPR_TARG, FF_TRANS50|FF_FULLBRIGHT|1, 1, {A_VileFire}, 0, MT_CYBRAKDEMON_TARGET_DOT, S_CYBRAKDEMONTARGETRETICULE4}, // S_CYBRAKDEMONTARGETRETICULE3 - {SPR_TARG, FF_TRANS50|FF_FULLBRIGHT|6, 1, {A_VileFire}, 0, MT_CYBRAKDEMON_TARGET_DOT, S_CYBRAKDEMONTARGETRETICULE5}, // S_CYBRAKDEMONTARGETRETICULE4 - {SPR_TARG, FF_TRANS50|FF_FULLBRIGHT|2, 1, {A_VileFire}, 0, MT_CYBRAKDEMON_TARGET_DOT, S_CYBRAKDEMONTARGETRETICULE6}, // S_CYBRAKDEMONTARGETRETICULE5 - {SPR_TARG, FF_TRANS50|FF_FULLBRIGHT|6, 1, {A_VileFire}, 0, MT_CYBRAKDEMON_TARGET_DOT, S_CYBRAKDEMONTARGETRETICULE7}, // S_CYBRAKDEMONTARGETRETICULE6 - {SPR_TARG, FF_TRANS50|FF_FULLBRIGHT|3, 1, {A_VileFire}, 0, MT_CYBRAKDEMON_TARGET_DOT, S_CYBRAKDEMONTARGETRETICULE8}, // S_CYBRAKDEMONTARGETRETICULE7 - {SPR_TARG, FF_TRANS50|FF_FULLBRIGHT|6, 1, {A_VileFire}, 0, MT_CYBRAKDEMON_TARGET_DOT, S_CYBRAKDEMONTARGETRETICULE9}, // S_CYBRAKDEMONTARGETRETICULE8 - {SPR_TARG, FF_TRANS50|FF_FULLBRIGHT|4, 1, {A_VileFire}, 0, MT_CYBRAKDEMON_TARGET_DOT, S_CYBRAKDEMONTARGETRETICULE10}, // S_CYBRAKDEMONTARGETRETICULE9 - {SPR_TARG, FF_TRANS50|FF_FULLBRIGHT|6, 1, {A_VileFire}, 0, MT_CYBRAKDEMON_TARGET_DOT, S_CYBRAKDEMONTARGETRETICULE11}, // S_CYBRAKDEMONTARGETRETICULE10 - {SPR_TARG, FF_TRANS50|FF_FULLBRIGHT|5, 1, {A_VileFire}, 0, MT_CYBRAKDEMON_TARGET_DOT, S_CYBRAKDEMONTARGETRETICULE12}, // S_CYBRAKDEMONTARGETRETICULE11 - {SPR_TARG, FF_TRANS50|FF_FULLBRIGHT|6, 1, {A_VileFire}, 0, MT_CYBRAKDEMON_TARGET_DOT, S_CYBRAKDEMONTARGETRETICULE13}, // S_CYBRAKDEMONTARGETRETICULE12 - {SPR_TARG, FF_TRANS50|FF_FULLBRIGHT , 1, {A_VileFire}, 0, MT_CYBRAKDEMON_TARGET_DOT, S_CYBRAKDEMONTARGETRETICULE14}, // S_CYBRAKDEMONTARGETRETICULE13 - {SPR_TARG, FF_TRANS50|FF_FULLBRIGHT|6, 1, {A_Repeat}, 6, S_CYBRAKDEMONTARGETRETICULE2, S_NULL}, // S_CYBRAKDEMONTARGETRETICULE14 - - {SPR_HOOP, FF_TRANS50|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_CYBRAKDEMONTARGETDOT - - {SPR_NPLM, 0, 2, {NULL}, 0, 0, S_CYBRAKDEMONNAPALMBOMBLARGE_FLY2}, //S_CYBRAKDEMONNAPALMBOMBLARGE_FLY1, - {SPR_NPLM, 1, 2, {NULL}, 0, 0, S_CYBRAKDEMONNAPALMBOMBLARGE_FLY3}, //S_CYBRAKDEMONNAPALMBOMBLARGE_FLY2, - {SPR_NPLM, 2, 2, {NULL}, 0, 0, S_CYBRAKDEMONNAPALMBOMBLARGE_FLY4}, //S_CYBRAKDEMONNAPALMBOMBLARGE_FLY3, - {SPR_NPLM, 3, 2, {NULL}, 0, 0, S_CYBRAKDEMONNAPALMBOMBLARGE_FLY1}, //S_CYBRAKDEMONNAPALMBOMBLARGE_FLY4, - {SPR_NPLM, 0, 1, {A_Explode}, 0, 0, S_CYBRAKDEMONNAPALMBOMBLARGE_DIE2}, //S_CYBRAKDEMONNAPALMBOMBLARGE_DIE1, // Explode - {SPR_NPLM, 0, 1, {A_NapalmScatter}, MT_CYBRAKDEMON_NAPALM_BOMB_SMALL + (6<<16), 256 + (48<<16), S_CYBRAKDEMONNAPALMBOMBLARGE_DIE3}, //S_CYBRAKDEMONNAPALMBOMBLARGE_DIE2, // Outer ring - {SPR_NPLM, 0, 1, {A_NapalmScatter}, MT_CYBRAKDEMON_NAPALM_BOMB_SMALL + (1<<16), 32<<16, S_CYBRAKDEMONNAPALMBOMBLARGE_DIE4}, //S_CYBRAKDEMONNAPALMBOMBLARGE_DIE3, // Center - {SPR_NULL, 0, 81, {A_Scream}, 0, 0, S_NULL}, //S_CYBRAKDEMONNAPALMBOMBLARGE_DIE4, // Sound - - {SPR_MNPL, 0, 1, {NULL}, 0, 0, S_CYBRAKDEMONNAPALMBOMBSMALL}, //S_CYBRAKDEMONNAPALMBOMBSMALL, - {SPR_MNPL, 0, 1, {A_Explode}, 0, 0, S_CYBRAKDEMONNAPALMBOMBSMALL_DIE2}, //S_CYBRAKDEMONNAPALMBOMBSMALL_DIE1, // Explode - {SPR_MNPL, 0, 1, {A_NapalmScatter}, MT_CYBRAKDEMON_NAPALM_FLAMES + (12<<16), 128 + (40<<16), S_CYBRAKDEMONNAPALMBOMBSMALL_DIE3}, //S_CYBRAKDEMONNAPALMBOMBSMALL_DIE2, // Outer ring - {SPR_MNPL, 0, 1, {A_NapalmScatter}, MT_CYBRAKDEMON_NAPALM_FLAMES + (8<<16), 64 + (32<<16), S_CYBRAKDEMONNAPALMBOMBSMALL_DIE4}, //S_CYBRAKDEMONNAPALMBOMBSMALL_DIE3, // Inner ring - {SPR_MNPL, 0, 1, {A_NapalmScatter}, MT_CYBRAKDEMON_NAPALM_FLAMES + (1<<16), 24<<16, S_CYBRAKDEMONNAPALMBOMBSMALL_DIE5}, //S_CYBRAKDEMONNAPALMBOMBSMALL_DIE4, // Center - {SPR_NULL, 0, 24, {A_Scream}, 0, 0, S_NULL}, //S_CYBRAKDEMONNAPALMBOMBSMALL_DIE5, // Sound - - {SPR_SFLM, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_CYBRAKDEMONNAPALMFLAME_FLY2}, //S_CYBRAKDEMONNAPALMFLAME_FLY1, - {SPR_SFLM, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_CYBRAKDEMONNAPALMFLAME_FLY3}, //S_CYBRAKDEMONNAPALMFLAME_FLY2, - {SPR_SFLM, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_CYBRAKDEMONNAPALMFLAME_FLY4}, //S_CYBRAKDEMONNAPALMFLAME_FLY3, - {SPR_SFLM, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_CYBRAKDEMONNAPALMFLAME_FLY5}, //S_CYBRAKDEMONNAPALMFLAME_FLY4, - {SPR_SFLM, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_CYBRAKDEMONNAPALMFLAME_FLY6}, //S_CYBRAKDEMONNAPALMFLAME_FLY5, - {SPR_SFLM, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_CYBRAKDEMONNAPALMFLAME_FLY1}, //S_CYBRAKDEMONNAPALMFLAME_FLY6, - {SPR_SFLM, FF_FULLBRIGHT, 0, {A_SpawnObjectRelative}, 0, MT_CYBRAKDEMON_FLAMEREST, S_NULL}, //S_CYBRAKDEMONNAPALMFLAME_DIE, - - {SPR_NULL, 0, 1, {A_SetFuse}, TICRATE, 0, S_CYBRAKDEMONVILEEXPLOSION2}, //S_CYBRAKDEMONVILEEXPLOSION1, - {SPR_NULL, 0, 0, {A_ScoreRise}, 0, 0, S_CYBRAKDEMONVILEEXPLOSION3}, //S_CYBRAKDEMONVILEEXPLOSION2, - {SPR_NULL, 0, 1, {A_BossScream}, 0, 0, S_CYBRAKDEMONVILEEXPLOSION1}, //S_CYBRAKDEMONVILEEXPLOSION3, - // Metal Sonic {SPR_PLAY, SPR2_STIL, -1, {NULL}, 0, 0, S_METALSONIC_RACE}, // S_METALSONIC_RACE @@ -4121,6 +3884,9 @@ state_t states[NUMSTATES] = {SPR_BDRF, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE, -1, {NULL}, 5, 2, S_BRAKEDRIFT}, // S_BRAKEDRIFT + {SPR_BRAK, 0, 1, {NULL}, 0, 0, S_BRAKEDUST2}, // S_BRAKEDUST1 + {SPR_BRAK, FF_ANIMATE, 7, {NULL}, 6, 1, S_NULL}, // S_BRAKEDUST2 + {SPR_DUST, 0, 3, {NULL}, 0, 0, S_DRIFTDUST2}, // S_DRIFTDUST1 {SPR_DUST, 1, 3, {NULL}, 0, 0, S_DRIFTDUST3}, // S_DRIFTDUST2 {SPR_DUST, FF_TRANS20|2, 3, {NULL}, 0, 0, S_DRIFTDUST4}, // S_DRIFTDUST3 @@ -4232,10 +3998,10 @@ state_t states[NUMSTATES] = {SPR_KINB, FF_FULLBRIGHT|10, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULNB12}, // S_KARTINVULNB11 {SPR_KINB, FF_FULLBRIGHT|11, 1, {A_InvincSparkleRotate}, 0, 0, S_NULL}, // S_KARTINVULNB12 - {SPR_KINF, FF_FULLBRIGHT|FF_TRANS90, 1, {NULL}, 0, 0, S_INVULNFLASH2}, // S_INVULNFLASH1 - {SPR_NULL, FF_FULLBRIGHT|FF_TRANS90, 1, {NULL}, 0, 0, S_INVULNFLASH3}, // S_INVULNFLASH2 - {SPR_KINF, FF_FULLBRIGHT|FF_TRANS90|1, 1, {NULL}, 0, 0, S_INVULNFLASH4}, // S_INVULNFLASH3 - {SPR_NULL, FF_FULLBRIGHT|FF_TRANS90, 1, {NULL}, 0, 0, S_INVULNFLASH1}, // S_INVULNFLASH4 + {SPR_KINF, FF_FULLBRIGHT|FF_TRANS80|FF_ADD, 1, {NULL}, 0, 0, S_INVULNFLASH2}, // S_INVULNFLASH1 + {SPR_NULL, FF_FULLBRIGHT|FF_TRANS80|FF_ADD, 1, {NULL}, 0, 0, S_INVULNFLASH3}, // S_INVULNFLASH2 + {SPR_KINF, FF_FULLBRIGHT|FF_TRANS80|FF_ADD|1, 1, {NULL}, 0, 0, S_INVULNFLASH4}, // S_INVULNFLASH3 + {SPR_NULL, FF_FULLBRIGHT|FF_TRANS80|FF_ADD, 1, {NULL}, 0, 0, S_INVULNFLASH1}, // S_INVULNFLASH4 {SPR_INVI, FF_FULLBRIGHT|FF_PAPERSPRITE, 1, {NULL}, 0, 0, S_KARTINVLINES2}, // S_KARTINVLINES1 {SPR_INVI, FF_FULLBRIGHT|FF_PAPERSPRITE|1, 1, {NULL}, 0, 0, S_KARTINVLINES3}, // S_KARTINVLINES2 @@ -4349,10 +4115,8 @@ state_t states[NUMSTATES] = {SPR_SSMN, 12, 3, {NULL}, 0, 0, S_SSMINE_DEPLOY12}, // S_SSMINE_DEPLOY11 {SPR_SSMN, 13, 3, {NULL}, 0, 0, S_SSMINE_DEPLOY13}, // S_SSMINE_DEPLOY12 {SPR_SSMN, 14, 3, {NULL}, 0, 0, S_SSMINE1}, // S_SSMINE_DEPLOY13 - {SPR_SSMN, 3, 1, {A_SSMineExplode}, MT_MINEEXPLOSION, 0, S_NULL}, // S_SSMINE_EXPLODE - - {SPR_NULL, 0, 6, {NULL}, 0, 0, S_MINEEXPLOSION2}, // S_MINEEXPLOSION1 - {SPR_NULL, 1, 22, {A_ForceStop}, 0, 0, S_NULL}, // S_MINEEXPLOSION2 + {SPR_SSMN, 3, 1, {A_SSMineExplode}, 0, 0, S_SSMINE_EXPLODE2}, // S_SSMINE_EXPLODE + {SPR_NULL, 0, 12, {A_SSMineExplode}, 1, 0, S_NULL}, // S_SSMINE_EXPLODE2 {SPR_KRBM, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_QUICKBOOM2}, // S_QUICKBOOM1 {SPR_KRBM, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_QUICKBOOM3}, // S_QUICKBOOM2 @@ -5093,7 +4857,7 @@ state_t states[NUMSTATES] = {SPR_TOAH, 2, 3, {NULL}, 0, 0, S_TOADHIT4}, // S_TOADHIT3 {SPR_TOAH, 3, 3, {NULL}, 0, 0, S_EBARREL18}, // S_TOADHIT4 - {SPR_BRRL, 0, 1, {A_Look}, (96<<16)|1, 0, S_EBARRELIDLE}, // S_EBARRELIDLE + {SPR_BRRL, 0, 1, {A_Look}, (96<<16)|1, 0, S_EBARRELIDLE}, // S_EBARRELIDLE {SPR_BRRR, 0, 4, {NULL}, 0, 0, S_EBARREL2}, // S_EBARREL1 {SPR_BRRR, 1, 4, {NULL}, 0, 0, S_EBARREL3}, // S_EBARREL2 {SPR_BRRR, 2, 4, {NULL}, 0, 0, S_EBARREL4}, // S_EBARREL3 @@ -5111,7 +4875,8 @@ state_t states[NUMSTATES] = {SPR_BRRR, 14, 4, {NULL}, 0, 0, S_EBARREL16}, // S_EBARREL15 {SPR_BRRR, 15, 4, {NULL}, 0, 0, S_EBARREL17}, // S_EBARREL16 {SPR_BRRR, 16, 4, {NULL}, 0, 0, S_EBARREL18}, // S_EBARREL17 - {SPR_BRRR, 16, 0, {A_SSMineExplode}, MT_MINEEXPLOSION, 0, S_NULL}, // S_EBARREL18 + {SPR_BRRR, 16, 1, {A_SSMineExplode}, 0, 0, S_EBARREL19}, // S_EBARREL18 + {SPR_NULL, 0, 12, {A_SSMineExplode}, 1, 0, S_NULL}, // S_EBARREL19 {SPR_HRSE, 0, 230, {A_PlaySeeSound}, 0, 0, S_MERRYHORSE}, // S_MERRYHORSE @@ -5398,7 +5163,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 1, // speed - 16*FRACUNIT, // radius + 24*FRACUNIT, // radius 48*FRACUNIT, // height 0, // display offset 1000, // mass @@ -7675,412 +7440,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_BLACKEGGMAN - 206, // doomednum - S_BLACKEGG_STND, // spawnstate - 8, // spawnhealth - S_BLACKEGG_WALK1, // seestate - sfx_None, // seesound - 8*TICRATE, // reactiontime - sfx_None, // attacksound - S_BLACKEGG_PAIN1, // painstate - 0, // painchance - sfx_None, // painsound - S_BLACKEGG_HITFACE1, // meleestate - S_BLACKEGG_MISSILE1, // missilestate - S_BLACKEGG_DIE1, // deathstate - S_BLACKEGG_GOOP, // xdeathstate - sfx_None, // deathsound - 1, // speed - 48*FRACUNIT, // radius - 160*FRACUNIT, // height - 0, // display offset - 0, // mass - 3, // damage - sfx_None, // activesound - MF_SPECIAL|MF_BOSS,// flags - S_BLACKEGG_JUMP1 // raisestate - }, - - { // MT_BLACKEGGMAN_HELPER - -1, // doomednum - S_BLACKEGG_HELPER, // spawnstate - 8, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 0, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 1, // speed - 48*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 0, // mass - 1, // damage - sfx_None, // activesound - MF_SOLID|MF_NOGRAVITY, // flags - S_NULL // raisestate - }, - - { // MT_BLACKEGGMAN_GOOPFIRE - -1, // doomednum - S_BLACKEGG_GOOP1, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_BLACKEGG_GOOP3, // deathstate - S_NULL, // xdeathstate - sfx_ghit, // deathsound - 30*FRACUNIT, // speed - 11*FRACUNIT, // radius - 8*FRACUNIT, // height - 100, // display offset - 0, // mass - 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags - S_NULL // raisestate - }, - - { // MT_BLACKEGGMAN_MISSILE - -1, // doomednum - S_BLACKEGG_MISSILE, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_BOSSEXPLODE, // deathstate - S_NULL, // xdeathstate - sfx_bexpld, // deathsound - 10*FRACUNIT, // speed - 24*FRACUNIT, // radius - 24*FRACUNIT, // height - 0, // display offset - 0, // mass - 1, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags - S_NULL // raisestate - }, - - { // MT_CYBRAKDEMON - 209, // doomednum - S_CYBRAKDEMON_IDLE, // spawnstate - 12, // spawnhealth - S_CYBRAKDEMON_WALK1,// seestate - sfx_None, // seesound - 15, // reactiontime - sfx_None, // attacksound - S_CYBRAKDEMON_PAIN1,// painstate - 0, // painchance - sfx_behurt, // painsound - S_CYBRAKDEMON_CHOOSE_ATTACK2, // meleestate - S_CYBRAKDEMON_CHOOSE_ATTACK1, // missilestate - S_CYBRAKDEMON_DIE1, // deathstate - S_NULL, // xdeathstate - sfx_s3kb4, // deathsound - 40, // speed - 48*FRACUNIT, // radius - 160*FRACUNIT, // height - 0, // display offset - 100, // mass - 1, // damage - sfx_bewar1, // activesound - MF_SPECIAL|MF_BOSS|MF_SHOOTABLE, // flags - S_NULL // raisestate - }, - - { // MT_CYBRAKDEMON_ELECTRIC_BARRIER - -1, // doomednum - S_CYBRAKDEMONELECTRICBARRIER_INIT1, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_s3k79, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_CYBRAKDEMONELECTRICBARRIER_DIE1, // deathstate - S_NULL, // xdeathstate - sfx_fizzle, // deathsound - 10*FRACUNIT, // speed - 24*FRACUNIT, // radius - 80*FRACUNIT, // height - 0, // display offset - DMG_NORMAL, // mass - 1, // damage - sfx_beelec, // activesound - MF_PAIN|MF_NOGRAVITY|MF_PUSHABLE, // flags - S_NULL // raisestate - }, - - { // MT_CYBRAKDEMON_MISSILE - -1, // doomednum - S_CYBRAKDEMONMISSILE, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_brakrl, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_CYBRAKDEMONMISSILE_EXPLODE1, // deathstate - S_NULL, // xdeathstate - sfx_brakrx, // deathsound - 40*FRACUNIT, // speed - 11*FRACUNIT, // radius - 8*FRACUNIT, // height - 0, // display offset - 0, // mass - 32*FRACUNIT, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags - S_NULL // raisestate - }, - - { // MT_CYBRAKDEMON_FLAMESHOT - -1, // doomednum - S_CYBRAKDEMONFLAMESHOT_FLY1, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_s3kc2s, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_CYBRAKDEMONFLAMESHOT_DIE, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 20*FRACUNIT, // speed - 24*FRACUNIT, // radius - 24*FRACUNIT, // height - 0, // display offset - DMG_NORMAL, // mass - 1, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_PAIN|MF_NOGRAVITY, // flags - S_NULL // raisestate - }, - - { // MT_CYBRAKDEMON_FLAMEREST - -1, // doomednum - S_CYBRAKDEMONFLAMEREST, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_s3kc2s, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - MT_NULL, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 20*FRACUNIT, // speed - 24*FRACUNIT, // radius - 24*FRACUNIT, // height - 0, // display offset - DMG_NORMAL, // mass - 1, // damage - sfx_None, // activesound - MF_PAIN|MF_RUNSPAWNFUNC, // flags - S_NULL // raisestate - }, - - { // MT_CYBRAKDEMON_TARGET_RETICULE - -1, // doomednum - S_CYBRAKDEMONTARGETRETICULE1, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_BOSSEXPLODE, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 10*FRACUNIT, // speed - 32*FRACUNIT, // radius - 64*FRACUNIT, // height - 0, // display offset - 100, // mass - 1, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOGRAVITY|MF_RUNSPAWNFUNC, // flags - S_NULL // raisestate - }, - - { // MT_CYBRAKDEMON_TARGET_DOT - -1, // doomednum - S_CYBRAKDEMONTARGETDOT, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_BOSSEXPLODE, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 10*FRACUNIT, // speed - 32*FRACUNIT, // radius - 64*FRACUNIT, // height - 0, // display offset - 100, // mass - 1, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate - }, - - { // MT_CYBRAKDEMON_NAPALM_BOMB_LARGE - -1, // doomednum - S_CYBRAKDEMONNAPALMBOMBLARGE_FLY1, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_s3k81, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 20*TICRATE, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_CYBRAKDEMONNAPALMBOMBLARGE_DIE1, // deathstate - S_NULL, // xdeathstate - sfx_s3k4e, // deathsound - 10*FRACUNIT, // speed - 24*FRACUNIT, // radius - 24*FRACUNIT, // height - 0, // display offset - 0, // mass - 48*FRACUNIT, // damage - sfx_s3k5d, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_GRENADEBOUNCE, // flags - S_NULL // raisestate - }, - - { // MT_CYBRAKDEMON_NAPALM_BOMB_SMALL - -1, // doomednum - S_CYBRAKDEMONNAPALMBOMBSMALL, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_CYBRAKDEMONNAPALMBOMBSMALL_DIE1, // deathstate - S_NULL, // xdeathstate - sfx_s3k70, // deathsound - 10*FRACUNIT, // speed - 24*FRACUNIT, // radius - 24*FRACUNIT, // height - 0, // display offset - 0, // mass - 32*FRACUNIT, // damage - sfx_s3k99, // activesound - MF_NOBLOCKMAP|MF_MISSILE, // flags - S_NULL // raisestate - }, - - { // MT_CYBRAKDEMON_NAPALM_FLAMES - -1, // doomednum - S_CYBRAKDEMONNAPALMFLAME_FLY1, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_CYBRAKDEMONNAPALMFLAME_DIE, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 10*FRACUNIT, // speed - 24*FRACUNIT, // radius - 24*FRACUNIT, // height - 0, // display offset - 0, // mass - 1, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE, // flags - S_NULL // raisestate - }, - - { // MT_CYBRAKDEMON_VILE_EXPLOSION - -1, // doomednum - S_CYBRAKDEMONVILEEXPLOSION1, // spawnstate - 1, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_s3kb4, // deathsound - 1*FRACUNIT, // speed - 8*FRACUNIT, // radius - 8*FRACUNIT, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags - S_NULL // raisestate - }, - - { // MT_METALSONIC_RACE 207, // doomednum S_METALSONIC_RACE, // spawnstate @@ -23596,6 +22955,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_BRAKEDUST + -1, // doomednum + S_BRAKEDUST1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 8*FRACUNIT, // height + 1, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_DONTENCOREMAP|MF_NOSQUISH, // flags + S_NULL // raisestate + }, + { // MT_DRIFTDUST -1, // doomednum S_DRIFTDUST1, // spawnstate @@ -24055,60 +23441,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_MINEEXPLOSION - -1, // doomednum - S_MINEEXPLOSION1, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 8, // speed - 32*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - MF_SOLID|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags - S_NULL // raisestate - }, - - { // MT_MINEEXPLOSIONSOUND - -1, // doomednum - S_INVISIBLE, // spawnstate - 100, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 16*FRACUNIT, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY, // flags - S_NULL // raisestate - }, - { // MT_SMOLDERING -1, // doomednum S_INVISIBLE, // spawnstate @@ -29518,7 +28850,9 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Chaos Emerald 4", { 0, 144, 146, 147, 149, 165, 167, 169, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD4 {"Chaos Emerald 5", { 0, 1, 144, 4, 9, 170, 14, 21, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD5 {"Chaos Emerald 6", { 0, 208, 50, 32, 34, 37, 40, 44, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD6 - {"Chaos Emerald 7", { 0, 120, 121, 140, 133, 135, 149, 156, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false} // SKINCOLOR_CHAOSEMERALD7 + {"Chaos Emerald 7", { 0, 120, 121, 140, 133, 135, 149, 156, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD7 + + {"Invinc Flash", { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, SKINCOLOR_NONE, 0, 0, false} // SKINCOLOR_INVINCFLASH }; /** Patches the mobjinfo, state, and skincolor tables. diff --git a/src/info.h b/src/info.h index e64dae3de..5e4ef6418 100644 --- a/src/info.h +++ b/src/info.h @@ -404,7 +404,6 @@ void A_BossZoom(); //Unused void A_Boss1Chase(); void A_Boss2Chase(); void A_Boss2Pogo(); -void A_Boss7Chase(); void A_BossJetFume(); void A_SpawnObjectAbsolute(); void A_SpawnObjectRelative(); @@ -660,7 +659,6 @@ typedef enum sprite SPR_EGGR, // Boss 7 (Dark City) - SPR_BRAK, SPR_BGOO, // Goop SPR_BMSL, @@ -1091,6 +1089,7 @@ typedef enum sprite SPR_WIPD, // Wipeout dust trail SPR_DRIF, // Drift Sparks SPR_BDRF, // Brake drift sparks + SPR_BRAK, // Brake brak SPR_DRWS, // Drift dust sparks SPR_DREL, // Drift electricity SPR_DRES, // Drift electric sparks @@ -2077,236 +2076,6 @@ typedef enum state S_FSGNC, S_FSGND, - // Black Eggman (Boss 7) - S_BLACKEGG_STND, - S_BLACKEGG_STND2, - S_BLACKEGG_WALK1, - S_BLACKEGG_WALK2, - S_BLACKEGG_WALK3, - S_BLACKEGG_WALK4, - S_BLACKEGG_WALK5, - S_BLACKEGG_WALK6, - S_BLACKEGG_SHOOT1, - S_BLACKEGG_SHOOT2, - S_BLACKEGG_PAIN1, - S_BLACKEGG_PAIN2, - S_BLACKEGG_PAIN3, - S_BLACKEGG_PAIN4, - S_BLACKEGG_PAIN5, - S_BLACKEGG_PAIN6, - S_BLACKEGG_PAIN7, - S_BLACKEGG_PAIN8, - S_BLACKEGG_PAIN9, - S_BLACKEGG_PAIN10, - S_BLACKEGG_PAIN11, - S_BLACKEGG_PAIN12, - S_BLACKEGG_PAIN13, - S_BLACKEGG_PAIN14, - S_BLACKEGG_PAIN15, - S_BLACKEGG_PAIN16, - S_BLACKEGG_PAIN17, - S_BLACKEGG_PAIN18, - S_BLACKEGG_PAIN19, - S_BLACKEGG_PAIN20, - S_BLACKEGG_PAIN21, - S_BLACKEGG_PAIN22, - S_BLACKEGG_PAIN23, - S_BLACKEGG_PAIN24, - S_BLACKEGG_PAIN25, - S_BLACKEGG_PAIN26, - S_BLACKEGG_PAIN27, - S_BLACKEGG_PAIN28, - S_BLACKEGG_PAIN29, - S_BLACKEGG_PAIN30, - S_BLACKEGG_PAIN31, - S_BLACKEGG_PAIN32, - S_BLACKEGG_PAIN33, - S_BLACKEGG_PAIN34, - S_BLACKEGG_PAIN35, - S_BLACKEGG_HITFACE1, - S_BLACKEGG_HITFACE2, - S_BLACKEGG_HITFACE3, - S_BLACKEGG_HITFACE4, - S_BLACKEGG_DIE1, - S_BLACKEGG_DIE2, - S_BLACKEGG_DIE3, - S_BLACKEGG_DIE4, - S_BLACKEGG_DIE5, - S_BLACKEGG_MISSILE1, - S_BLACKEGG_MISSILE2, - S_BLACKEGG_MISSILE3, - S_BLACKEGG_GOOP, - S_BLACKEGG_JUMP1, - S_BLACKEGG_JUMP2, - S_BLACKEGG_DESTROYPLAT1, - S_BLACKEGG_DESTROYPLAT2, - S_BLACKEGG_DESTROYPLAT3, - - S_BLACKEGG_HELPER, // Collision helper - - S_BLACKEGG_GOOP1, - S_BLACKEGG_GOOP2, - S_BLACKEGG_GOOP3, - S_BLACKEGG_GOOP4, - S_BLACKEGG_GOOP5, - S_BLACKEGG_GOOP6, - S_BLACKEGG_GOOP7, - - S_BLACKEGG_MISSILE, - - // New Very-Last-Minute 2.1 Brak Eggman (Cy-Brak-demon) - S_CYBRAKDEMON_IDLE, - S_CYBRAKDEMON_WALK1, - S_CYBRAKDEMON_WALK2, - S_CYBRAKDEMON_WALK3, - S_CYBRAKDEMON_WALK4, - S_CYBRAKDEMON_WALK5, - S_CYBRAKDEMON_WALK6, - S_CYBRAKDEMON_CHOOSE_ATTACK1, - S_CYBRAKDEMON_MISSILE_ATTACK1, // Aim - S_CYBRAKDEMON_MISSILE_ATTACK2, // Fire - S_CYBRAKDEMON_MISSILE_ATTACK3, // Aim - S_CYBRAKDEMON_MISSILE_ATTACK4, // Fire - S_CYBRAKDEMON_MISSILE_ATTACK5, // Aim - S_CYBRAKDEMON_MISSILE_ATTACK6, // Fire - S_CYBRAKDEMON_FLAME_ATTACK1, // Reset - S_CYBRAKDEMON_FLAME_ATTACK2, // Aim - S_CYBRAKDEMON_FLAME_ATTACK3, // Fire - S_CYBRAKDEMON_FLAME_ATTACK4, // Loop - S_CYBRAKDEMON_CHOOSE_ATTACK2, - S_CYBRAKDEMON_VILE_ATTACK1, - S_CYBRAKDEMON_VILE_ATTACK2, - S_CYBRAKDEMON_VILE_ATTACK3, - S_CYBRAKDEMON_VILE_ATTACK4, - S_CYBRAKDEMON_VILE_ATTACK5, - S_CYBRAKDEMON_VILE_ATTACK6, - S_CYBRAKDEMON_NAPALM_ATTACK1, - S_CYBRAKDEMON_NAPALM_ATTACK2, - S_CYBRAKDEMON_NAPALM_ATTACK3, - S_CYBRAKDEMON_FINISH_ATTACK1, // If just attacked, remove MF2_FRET w/out going back to spawnstate - S_CYBRAKDEMON_FINISH_ATTACK2, // Force a delay between attacks so you don't get bombarded with them back-to-back - S_CYBRAKDEMON_PAIN1, - S_CYBRAKDEMON_PAIN2, - S_CYBRAKDEMON_PAIN3, - S_CYBRAKDEMON_DIE1, - S_CYBRAKDEMON_DIE2, - S_CYBRAKDEMON_DIE3, - S_CYBRAKDEMON_DIE4, - S_CYBRAKDEMON_DIE5, - S_CYBRAKDEMON_DIE6, - S_CYBRAKDEMON_DIE7, - S_CYBRAKDEMON_DIE8, - S_CYBRAKDEMON_DEINVINCIBLERIZE, - S_CYBRAKDEMON_INVINCIBLERIZE, - - S_CYBRAKDEMONMISSILE, - S_CYBRAKDEMONMISSILE_EXPLODE1, - S_CYBRAKDEMONMISSILE_EXPLODE2, - S_CYBRAKDEMONMISSILE_EXPLODE3, - - S_CYBRAKDEMONFLAMESHOT_FLY1, - S_CYBRAKDEMONFLAMESHOT_FLY2, - S_CYBRAKDEMONFLAMESHOT_FLY3, - S_CYBRAKDEMONFLAMESHOT_DIE, - - S_CYBRAKDEMONFLAMEREST, - - S_CYBRAKDEMONELECTRICBARRIER_INIT1, - S_CYBRAKDEMONELECTRICBARRIER_INIT2, - S_CYBRAKDEMONELECTRICBARRIER_PLAYSOUND, - S_CYBRAKDEMONELECTRICBARRIER1, - S_CYBRAKDEMONELECTRICBARRIER2, - S_CYBRAKDEMONELECTRICBARRIER3, - S_CYBRAKDEMONELECTRICBARRIER4, - S_CYBRAKDEMONELECTRICBARRIER5, - S_CYBRAKDEMONELECTRICBARRIER6, - S_CYBRAKDEMONELECTRICBARRIER7, - S_CYBRAKDEMONELECTRICBARRIER8, - S_CYBRAKDEMONELECTRICBARRIER9, - S_CYBRAKDEMONELECTRICBARRIER10, - S_CYBRAKDEMONELECTRICBARRIER11, - S_CYBRAKDEMONELECTRICBARRIER12, - S_CYBRAKDEMONELECTRICBARRIER13, - S_CYBRAKDEMONELECTRICBARRIER14, - S_CYBRAKDEMONELECTRICBARRIER15, - S_CYBRAKDEMONELECTRICBARRIER16, - S_CYBRAKDEMONELECTRICBARRIER17, - S_CYBRAKDEMONELECTRICBARRIER18, - S_CYBRAKDEMONELECTRICBARRIER19, - S_CYBRAKDEMONELECTRICBARRIER20, - S_CYBRAKDEMONELECTRICBARRIER21, - S_CYBRAKDEMONELECTRICBARRIER22, - S_CYBRAKDEMONELECTRICBARRIER23, - S_CYBRAKDEMONELECTRICBARRIER24, - S_CYBRAKDEMONELECTRICBARRIER_DIE1, - S_CYBRAKDEMONELECTRICBARRIER_DIE2, - S_CYBRAKDEMONELECTRICBARRIER_DIE3, - S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMCHECK, - S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMSUCCESS, - S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMCHOOSE, - S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM1, - S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM2, - S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM3, - S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM4, - S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM5, - S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM6, - S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM7, - S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM8, - S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM9, - S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM10, - S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM11, - S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOM12, - S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMFAIL, - S_CYBRAKDEMONELECTRICBARRIER_SPARK_RANDOMLOOP, - S_CYBRAKDEMONELECTRICBARRIER_REVIVE1, - S_CYBRAKDEMONELECTRICBARRIER_REVIVE2, - S_CYBRAKDEMONELECTRICBARRIER_REVIVE3, - - S_CYBRAKDEMONTARGETRETICULE1, - S_CYBRAKDEMONTARGETRETICULE2, - S_CYBRAKDEMONTARGETRETICULE3, - S_CYBRAKDEMONTARGETRETICULE4, - S_CYBRAKDEMONTARGETRETICULE5, - S_CYBRAKDEMONTARGETRETICULE6, - S_CYBRAKDEMONTARGETRETICULE7, - S_CYBRAKDEMONTARGETRETICULE8, - S_CYBRAKDEMONTARGETRETICULE9, - S_CYBRAKDEMONTARGETRETICULE10, - S_CYBRAKDEMONTARGETRETICULE11, - S_CYBRAKDEMONTARGETRETICULE12, - S_CYBRAKDEMONTARGETRETICULE13, - S_CYBRAKDEMONTARGETRETICULE14, - - S_CYBRAKDEMONTARGETDOT, - - S_CYBRAKDEMONNAPALMBOMBLARGE_FLY1, - S_CYBRAKDEMONNAPALMBOMBLARGE_FLY2, - S_CYBRAKDEMONNAPALMBOMBLARGE_FLY3, - S_CYBRAKDEMONNAPALMBOMBLARGE_FLY4, - S_CYBRAKDEMONNAPALMBOMBLARGE_DIE1, // Explode - S_CYBRAKDEMONNAPALMBOMBLARGE_DIE2, // Outer ring - S_CYBRAKDEMONNAPALMBOMBLARGE_DIE3, // Center - S_CYBRAKDEMONNAPALMBOMBLARGE_DIE4, // Sound - - S_CYBRAKDEMONNAPALMBOMBSMALL, - S_CYBRAKDEMONNAPALMBOMBSMALL_DIE1, // Explode - S_CYBRAKDEMONNAPALMBOMBSMALL_DIE2, // Outer ring - S_CYBRAKDEMONNAPALMBOMBSMALL_DIE3, // Inner ring - S_CYBRAKDEMONNAPALMBOMBSMALL_DIE4, // Center - S_CYBRAKDEMONNAPALMBOMBSMALL_DIE5, // Sound - - S_CYBRAKDEMONNAPALMFLAME_FLY1, - S_CYBRAKDEMONNAPALMFLAME_FLY2, - S_CYBRAKDEMONNAPALMFLAME_FLY3, - S_CYBRAKDEMONNAPALMFLAME_FLY4, - S_CYBRAKDEMONNAPALMFLAME_FLY5, - S_CYBRAKDEMONNAPALMFLAME_FLY6, - S_CYBRAKDEMONNAPALMFLAME_DIE, - - S_CYBRAKDEMONVILEEXPLOSION1, - S_CYBRAKDEMONVILEEXPLOSION2, - S_CYBRAKDEMONVILEEXPLOSION3, - // Metal Sonic (Race) S_METALSONIC_RACE, // Metal Sonic (Battle) @@ -4521,6 +4290,10 @@ typedef enum state // Brake drift sparks S_BRAKEDRIFT, + // Brake dust + S_BRAKEDUST1, + S_BRAKEDUST2, + // Drift Smoke S_DRIFTDUST1, S_DRIFTDUST2, @@ -4767,8 +4540,7 @@ typedef enum state S_SSMINE_DEPLOY12, S_SSMINE_DEPLOY13, S_SSMINE_EXPLODE, - S_MINEEXPLOSION1, - S_MINEEXPLOSION2, + S_SSMINE_EXPLODE2, // New explosion S_QUICKBOOM1, @@ -5532,6 +5304,7 @@ typedef enum state S_EBARREL16, S_EBARREL17, S_EBARREL18, + S_EBARREL19, S_MERRYHORSE, @@ -5836,25 +5609,6 @@ typedef enum mobj_type MT_FSGNB, MT_FANGWAYPOINT, - // Black Eggman (Boss 7) - MT_BLACKEGGMAN, - MT_BLACKEGGMAN_HELPER, - MT_BLACKEGGMAN_GOOPFIRE, - MT_BLACKEGGMAN_MISSILE, - - // New Very-Last-Minute 2.1 Brak Eggman (Cy-Brak-demon) - MT_CYBRAKDEMON, - MT_CYBRAKDEMON_ELECTRIC_BARRIER, - MT_CYBRAKDEMON_MISSILE, - MT_CYBRAKDEMON_FLAMESHOT, - MT_CYBRAKDEMON_FLAMEREST, - MT_CYBRAKDEMON_TARGET_RETICULE, - MT_CYBRAKDEMON_TARGET_DOT, - MT_CYBRAKDEMON_NAPALM_BOMB_LARGE, - MT_CYBRAKDEMON_NAPALM_BOMB_SMALL, - MT_CYBRAKDEMON_NAPALM_FLAMES, - MT_CYBRAKDEMON_VILE_EXPLOSION, - // Metal Sonic (Boss 9) MT_METALSONIC_RACE, MT_METALSONIC_BATTLE, @@ -6529,6 +6283,7 @@ typedef enum mobj_type MT_WIPEOUTTRAIL, MT_DRIFTSPARK, MT_BRAKEDRIFT, + MT_BRAKEDUST, MT_DRIFTDUST, MT_DRIFTELECTRICITY, MT_DRIFTELECTRICSPARK, @@ -6553,8 +6308,6 @@ typedef enum mobj_type MT_SSMINE, // Mine stuff MT_SSMINE_SHIELD, - MT_MINEEXPLOSION, - MT_MINEEXPLOSIONSOUND, MT_SMOLDERING, // New explosion MT_BOOMEXPLODE, diff --git a/src/k_bot.c b/src/k_bot.c index f31317546..9e1212b1f 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -279,7 +279,7 @@ boolean K_BotCanTakeCut(player_t *player) { if ( #if 1 - K_TripwirePass(player) == true + K_TripwirePassConditions(player) == true #else K_ApplyOffroad(player) == false #endif diff --git a/src/k_collide.c b/src/k_collide.c index f08f7a00b..665a3ff0a 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -296,6 +296,115 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2) return true; } +static mobj_t *grenade; +static fixed_t explodedist; +static boolean explodespin; + +static inline boolean PIT_SSMineChecks(mobj_t *thing) +{ + if (thing == grenade) // Don't explode yourself! Endless loop! + return true; + + if (thing->health <= 0) + return true; + + if (!(thing->flags & MF_SHOOTABLE) || (thing->flags & MF_SCENERY)) + return true; + + if (thing->player && thing->player->spectator) + return true; + + if (P_AproxDistance(P_AproxDistance(thing->x - grenade->x, thing->y - grenade->y), thing->z - grenade->z) > explodedist) + return true; // Too far away + + if (P_CheckSight(grenade, thing) == false) + return true; // Not in sight + + return false; +} + +static inline boolean PIT_SSMineSearch(mobj_t *thing) +{ + if (grenade == NULL || P_MobjWasRemoved(grenade)) + return false; // There's the possibility these can chain react onto themselves after they've already died if there are enough all in one spot + + if (grenade->flags2 & MF2_DEBRIS) // don't explode twice + return false; + + if (thing->type != MT_PLAYER) // Don't explode for anything but an actual player. + return true; + + if (thing == grenade->target && grenade->threshold != 0) // Don't blow up at your owner instantly. + return true; + + if (PIT_SSMineChecks(thing) == true) + return true; + + // Explode! + P_SetMobjState(grenade, grenade->info->deathstate); + return false; +} + +void K_DoMineSearch(mobj_t *actor, fixed_t size) +{ + INT32 bx, by, xl, xh, yl, yh; + + explodedist = FixedMul(size, actor->scale); + grenade = actor; + + yh = (unsigned)(actor->y + explodedist - bmaporgy)>>MAPBLOCKSHIFT; + yl = (unsigned)(actor->y - explodedist - bmaporgy)>>MAPBLOCKSHIFT; + xh = (unsigned)(actor->x + explodedist - bmaporgx)>>MAPBLOCKSHIFT; + xl = (unsigned)(actor->x - explodedist - bmaporgx)>>MAPBLOCKSHIFT; + + BMBOUNDFIX (xl, xh, yl, yh); + + for (by = yl; by <= yh; by++) + for (bx = xl; bx <= xh; bx++) + P_BlockThingsIterator(bx, by, PIT_SSMineSearch); +} + +static inline boolean PIT_SSMineExplode(mobj_t *thing) +{ + if (grenade == NULL || P_MobjWasRemoved(grenade)) + return false; // There's the possibility these can chain react onto themselves after they've already died if there are enough all in one spot + +#if 0 + if (grenade->flags2 & MF2_DEBRIS) // don't explode twice + return false; +#endif + + if (PIT_SSMineChecks(thing) == true) + return true; + + P_DamageMobj(thing, grenade, grenade->target, 1, (explodespin ? DMG_NORMAL : DMG_EXPLODE)); + return true; +} + +void K_MineExplodeAttack(mobj_t *actor, fixed_t size, boolean spin) +{ + INT32 bx, by, xl, xh, yl, yh; + + explodespin = spin; + explodedist = FixedMul(size, actor->scale); + grenade = actor; + + // Use blockmap to check for nearby shootables + yh = (unsigned)(actor->y + explodedist - bmaporgy)>>MAPBLOCKSHIFT; + yl = (unsigned)(actor->y - explodedist - bmaporgy)>>MAPBLOCKSHIFT; + xh = (unsigned)(actor->x + explodedist - bmaporgx)>>MAPBLOCKSHIFT; + xl = (unsigned)(actor->x - explodedist - bmaporgx)>>MAPBLOCKSHIFT; + + BMBOUNDFIX (xl, xh, yl, yh); + + for (by = yl; by <= yh; by++) + for (bx = xl; bx <= xh; bx++) + P_BlockThingsIterator(bx, by, PIT_SSMineExplode); + + // Set this flag to ensure that the inital action won't be triggered twice. + actor->flags2 |= MF2_DEBRIS; +} + boolean K_MineCollide(mobj_t *t1, mobj_t *t2) { if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0)) @@ -349,31 +458,6 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2) return true; } -boolean K_MineExplosionCollide(mobj_t *t1, mobj_t *t2) -{ - if (t2->player) - { - if (t2->player->flashing > 0 && t2->hitlag == 0) - return true; - - if (t1->state == &states[S_MINEEXPLOSION1]) - { - P_DamageMobj(t2, t1, t1->target, 1, DMG_EXPLODE); - } - else - { - P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL); - } - } - else if (t2->flags & MF_SHOOTABLE) - { - // Shootable damage - P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL); - } - - return true; -} - boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2) { if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0)) diff --git a/src/k_collide.h b/src/k_collide.h index 11af0502b..49cc3fa08 100644 --- a/src/k_collide.h +++ b/src/k_collide.h @@ -5,17 +5,27 @@ #include "p_mobj.h" angle_t K_GetCollideAngle(mobj_t *t1, mobj_t *t2); + boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2); + boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2); boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2); + +void K_DoMineSearch(mobj_t *actor, fixed_t size); +void K_MineExplodeAttack(mobj_t *actor, fixed_t size, boolean spin); boolean K_MineCollide(mobj_t *t1, mobj_t *t2); -boolean K_MineExplosionCollide(mobj_t *t1, mobj_t *t2); + boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2); + boolean K_DropTargetCollide(mobj_t *t1, mobj_t *t2); + boolean K_BubbleShieldCollide(mobj_t *t1, mobj_t *t2); + boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2); + boolean K_FallingRockCollide(mobj_t *t1, mobj_t *t2); boolean K_SMKIceBlockCollide(mobj_t *t1, mobj_t *t2); + boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2); #endif diff --git a/src/k_kart.c b/src/k_kart.c index 92fda8de3..1071f0371 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2029,6 +2029,17 @@ void K_SpawnDashDustRelease(player_t *player) } } +static fixed_t K_GetBrakeFXScale(player_t *player, fixed_t maxScale) +{ + fixed_t s = FixedDiv(player->speed, + K_GetKartSpeed(player, false)); + + s = max(s, FRACUNIT); + s = min(s, maxScale); + + return s; +} + static void K_SpawnBrakeDriftSparks(player_t *player) // Be sure to update the mobj thinker case too! { mobj_t *sparks; @@ -2041,11 +2052,84 @@ static void K_SpawnBrakeDriftSparks(player_t *player) // Be sure to update the m // This avoids needing to dupe code if we don't need it. sparks = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BRAKEDRIFT); P_SetTarget(&sparks->target, player->mo); - P_SetScale(sparks, (sparks->destscale = player->mo->scale)); + P_SetScale(sparks, (sparks->destscale = FixedMul(K_GetBrakeFXScale(player, 3*FRACUNIT), player->mo->scale))); K_MatchGenericExtraFlags(sparks, player->mo); sparks->renderflags |= RF_DONTDRAW; } +static void +spawn_brake_dust +( mobj_t * master, + angle_t aoff, + fixed_t rad, + fixed_t scale) +{ + const angle_t a = master->angle + aoff; + + mobj_t *spark = P_SpawnMobjFromMobj(master, + P_ReturnThrustX(NULL, a, rad), + P_ReturnThrustY(NULL, a, rad), 0, + MT_BRAKEDUST); + + spark->momx = master->momx; + spark->momy = master->momy; + spark->momz = P_GetMobjZMovement(master); + spark->angle = a - ANGLE_180; + spark->pitch = master->pitch; + spark->roll = master->roll; + + P_Thrust(spark, a, 16 * spark->scale); + + P_SetScale(spark, (spark->destscale = + FixedMul(scale, spark->scale))); +} + +static void K_SpawnBrakeVisuals(player_t *player) +{ + const fixed_t scale = + K_GetBrakeFXScale(player, 2*FRACUNIT); + + if (leveltime & 1) + { + angle_t aoff; + fixed_t radf; + + UINT8 wheel = 3; + + if (player->drift) + { + /* brake-drifting: dust flies from outer wheel */ + wheel ^= 1 << (player->drift < 0); + + aoff = 7 * ANG10; + radf = 32 * FRACUNIT; + } + else + { + aoff = ANG30; + radf = 24 * FRACUNIT; + } + + if (wheel & 1) + { + spawn_brake_dust(player->mo, + aoff, radf, scale); + } + + if (wheel & 2) + { + spawn_brake_dust(player->mo, + InvAngle(aoff), radf, scale); + } + } + + if (leveltime % 4 == 0) + S_StartSound(player->mo, sfx_s3k67); + + /* vertical shaking, scales with speed */ + player->mo->spriteyoffset = P_RandomFlip(2 * scale); +} + void K_SpawnDriftBoostClip(player_t *player) { mobj_t *clip; @@ -2104,32 +2188,61 @@ void K_SpawnNormalSpeedLines(player_t *player) K_MatchGenericExtraFlags(fast, player->mo); - // Make it red when you have the eggman speed boost + if (player->tripwireLeniency) + { + fast->destscale = fast->destscale * 2; + P_SetScale(fast, 3*fast->scale/2); + } + if (player->eggmanexplode) { + // Make it red when you have the eggman speed boost fast->color = SKINCOLOR_RED; fast->colorized = true; } + else if (player->invincibilitytimer) + { + const tic_t defaultTime = itemtime+(2*TICRATE); + if (player->invincibilitytimer > defaultTime) + { + fast->color = player->mo->color; + } + else + { + fast->color = SKINCOLOR_INVINCFLASH; + } + fast->colorized = true; + } + else if (player->tripwireLeniency) + { + // Make it pink+blue+big when you can go through tripwire + fast->color = (leveltime & 1) ? SKINCOLOR_LILAC : SKINCOLOR_JAWZ; + fast->colorized = true; + fast->renderflags |= RF_ADD; + } } void K_SpawnInvincibilitySpeedLines(mobj_t *mo) { mobj_t *fast = P_SpawnMobjFromMobj(mo, P_RandomRange(-48, 48) * FRACUNIT, - P_RandomRange(-48, 48) * FRACUNIT, - P_RandomRange(0, 64) * FRACUNIT, - MT_FASTLINE); + P_RandomRange(-48, 48) * FRACUNIT, + P_RandomRange(0, 64) * FRACUNIT, + MT_FASTLINE); + P_SetMobjState(fast, S_KARTINVLINES1); + + P_SetTarget(&fast->target, mo); + P_InitAngle(fast, K_MomentumAngle(mo)); fast->momx = 3*mo->momx/4; fast->momy = 3*mo->momy/4; fast->momz = 3*P_GetMobjZMovement(mo)/4; - P_SetTarget(&fast->target, mo); - P_InitAngle(fast, K_MomentumAngle(mo)); + K_MatchGenericExtraFlags(fast, mo); + fast->color = mo->color; fast->colorized = true; - K_MatchGenericExtraFlags(fast, mo); - P_SetMobjState(fast, S_KARTINVLINES1); + if (mo->player->invincibilitytimer < 10*TICRATE) fast->destscale = 6*((mo->player->invincibilitytimer/TICRATE)*FRACUNIT)/8; } @@ -2742,7 +2855,7 @@ boolean K_SlopeResistance(player_t *player) return false; } -boolean K_TripwirePass(player_t *player) +boolean K_TripwirePassConditions(player_t *player) { if ( player->invincibilitytimer || @@ -2755,6 +2868,11 @@ boolean K_TripwirePass(player_t *player) return false; } +boolean K_TripwirePass(player_t *player) +{ + return (K_TripwirePassConditions(player) || (player->tripwireLeniency > 0)); +} + boolean K_WaterRun(player_t *player) { if ( @@ -3695,88 +3813,6 @@ void K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount) K_HandleBumperChanges(victim, oldVictimBumpers); } -// source is the mobj that originally threw the bomb that exploded etc. -// Spawns the sphere around the explosion that handles spinout -void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit, mobj_t *source) -{ - mobj_t *mobj; - mobj_t *ghost = NULL; - INT32 i; - TVector v; - TVector *res; - fixed_t finalx, finaly, finalz, dist; - //mobj_t hoopcenter; - angle_t degrees, fa, closestangle; - fixed_t mobjx, mobjy, mobjz; - - //hoopcenter.x = x; - //hoopcenter.y = y; - //hoopcenter.z = z; - - //hoopcenter.z = z - mobjinfo[type].height/2; - - degrees = FINEANGLES/number; - - closestangle = 0; - - // Create the hoop! - for (i = 0; i < number; i++) - { - fa = (i*degrees); - v[0] = FixedMul(FINECOSINE(fa),radius); - v[1] = 0; - v[2] = FixedMul(FINESINE(fa),radius); - v[3] = FRACUNIT; - - res = VectorMatrixMultiply(v, *RotateXMatrix(rotangle)); - M_Memcpy(&v, res, sizeof (v)); - res = VectorMatrixMultiply(v, *RotateZMatrix(closestangle)); - M_Memcpy(&v, res, sizeof (v)); - - finalx = x + v[0]; - finaly = y + v[1]; - finalz = z + v[2]; - - mobj = P_SpawnMobj(finalx, finaly, finalz, type); - - mobj->z -= mobj->height>>1; - - // change angle - P_InitAngle(mobj, R_PointToAngle2(mobj->x, mobj->y, x, y)); - - // change slope - dist = P_AproxDistance(P_AproxDistance(x - mobj->x, y - mobj->y), z - mobj->z); - - if (dist < 1) - dist = 1; - - mobjx = mobj->x; - mobjy = mobj->y; - mobjz = mobj->z; - - if (ghostit) - { - ghost = P_SpawnGhostMobj(mobj); - P_SetMobjState(mobj, S_NULL); - mobj = ghost; - } - - if (spawncenter) - { - mobj->x = x; - mobj->y = y; - mobj->z = z; - } - - mobj->momx = FixedMul(FixedDiv(mobjx - x, dist), FixedDiv(dist, 6*FRACUNIT)); - mobj->momy = FixedMul(FixedDiv(mobjy - y, dist), FixedDiv(dist, 6*FRACUNIT)); - mobj->momz = FixedMul(FixedDiv(mobjz - z, dist), FixedDiv(dist, 6*FRACUNIT)); - - if (source && !P_MobjWasRemoved(source)) - P_SetTarget(&mobj->target, source); - } -} - #define MINEQUAKEDIST 4096 // Does the proximity screen flash and quake for explosions @@ -3822,6 +3858,8 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color) radius = source->radius>>FRACBITS; height = source->height>>FRACBITS; + S_StartSound(smoldering, sfx_s3k4e); + if (!color) color = SKINCOLOR_KETCHUP; @@ -4468,7 +4506,6 @@ void K_SpawnSparkleTrail(mobj_t *mo) { const INT32 rad = (mo->radius*3)/FRACUNIT; mobj_t *sparkle; - INT32 i; UINT8 invanimnum; // Current sparkle animation number INT32 invtime;// Invincibility time left, in seconds UINT8 index = 0; @@ -4477,13 +4514,6 @@ void K_SpawnSparkleTrail(mobj_t *mo) I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); - if ((mo->player->sneakertimer - || mo->player->ringboost || mo->player->driftboost - || mo->player->startboost || mo->player->eggmanexplode)) - { - return; - } - if (leveltime & 2) index = 1; @@ -4491,34 +4521,37 @@ void K_SpawnSparkleTrail(mobj_t *mo) //CONS_Printf("%d\n", index); - for (i = 0; i < 8; i++) - { - newx = mo->x + (P_RandomRange(-rad, rad)*FRACUNIT); - newy = mo->y + (P_RandomRange(-rad, rad)*FRACUNIT); - newz = mo->z + (P_RandomRange(0, mo->height>>FRACBITS)*FRACUNIT); + newx = mo->x + (P_RandomRange(-rad, rad)*FRACUNIT); + newy = mo->y + (P_RandomRange(-rad, rad)*FRACUNIT); + newz = mo->z + (P_RandomRange(0, mo->height>>FRACBITS)*FRACUNIT); - sparkle = P_SpawnMobj(newx, newy, newz, MT_SPARKLETRAIL); - P_InitAngle(sparkle, R_PointToAngle2(mo->x, mo->y, sparkle->x, sparkle->y)); - sparkle->movefactor = R_PointToDist2(mo->x, mo->y, sparkle->x, sparkle->y); // Save the distance we spawned away from the player. - //CONS_Printf("movefactor: %d\n", sparkle->movefactor/FRACUNIT); - sparkle->extravalue1 = (sparkle->z - mo->z); // Keep track of our Z position relative to the player's, I suppose. - sparkle->extravalue2 = P_RandomRange(0, 1) ? 1 : -1; // Rotation direction? - sparkle->cvmem = P_RandomRange(-25, 25)*mo->scale; // Vertical "angle" - K_FlipFromObject(sparkle, mo); + sparkle = P_SpawnMobj(newx, newy, newz, MT_SPARKLETRAIL); - //if (i == 0) - //P_SetMobjState(sparkle, S_KARTINVULN_LARGE1); + P_InitAngle(sparkle, R_PointToAngle2(mo->x, mo->y, sparkle->x, sparkle->y)); - P_SetTarget(&sparkle->target, mo); - sparkle->destscale = mo->destscale; - P_SetScale(sparkle, mo->scale); - } + sparkle->movefactor = R_PointToDist2(mo->x, mo->y, sparkle->x, sparkle->y); // Save the distance we spawned away from the player. + //CONS_Printf("movefactor: %d\n", sparkle->movefactor/FRACUNIT); + + sparkle->extravalue1 = (sparkle->z - mo->z); // Keep track of our Z position relative to the player's, I suppose. + sparkle->extravalue2 = P_RandomRange(0, 1) ? 1 : -1; // Rotation direction? + sparkle->cvmem = P_RandomRange(-25, 25)*mo->scale; // Vertical "angle" + + K_FlipFromObject(sparkle, mo); + P_SetTarget(&sparkle->target, mo); + + sparkle->destscale = mo->destscale; + P_SetScale(sparkle, mo->scale); invanimnum = (invtime >= 11) ? 11 : invtime; //CONS_Printf("%d\n", invanimnum); + P_SetMobjState(sparkle, K_SparkleTrailStartStates[invanimnum][index]); - sparkle->colorized = true; - sparkle->color = mo->color; + + if (mo->player->invincibilitytimer > itemtime+(2*TICRATE)) + { + sparkle->color = mo->color; + sparkle->colorized = true; + } } void K_SpawnWipeoutTrail(mobj_t *mo) @@ -4722,6 +4755,90 @@ void K_DriftDustHandling(mobj_t *spawner) } } +static void K_SpawnTripwireVFX(mobj_t *mo) +{ + tic_t t = leveltime; + angle_t ang, aoff; + SINT8 sign = 1; + boolean altColor = false; + mobj_t *dust; + boolean drifting = false; + UINT8 i; + + I_Assert(mo != NULL); + I_Assert(!P_MobjWasRemoved(mo)); + + if (!P_IsObjectOnGround(mo)) + return; + + if (mo->player) + { + ang = mo->player->drawangle; + + if (mo->player->drift != 0) + { + drifting = true; + ang += (mo->player->drift * ((ANGLE_270 + ANGLE_22h) / 5)); // -112.5 doesn't work. I fucking HATE SRB2 angles + if (mo->player->drift < 0) + sign = 1; + else + sign = -1; + } + } + else + ang = mo->angle; + + if (drifting == false) + { + i = (t & 1); + + if (i & 1) + sign = -1; + else + sign = 1; + } + else + { + if (t & 1) + { + return; + } + + t /= 2; + i = (t & 1); + } + + aoff = (ang + ANGLE_180) + (ANGLE_45 * sign); + + dust = P_SpawnMobj(mo->x + FixedMul(24*mo->scale, FINECOSINE(aoff>>ANGLETOFINESHIFT)), + mo->y + FixedMul(24*mo->scale, FINESINE(aoff>>ANGLETOFINESHIFT)), + mo->z, MT_DRIFTDUST); + + P_SetTarget(&dust->target, mo); + P_InitAngle(dust, ang - (ANGLE_90 * sign)); // point completely perpendicular from the player + P_SetScale(dust, mo->scale); + dust->destscale = mo->scale * 6; + dust->scalespeed = mo->scale/12; + K_FlipFromObject(dust, mo); + + altColor = (sign > 0); + + if ((t / 2) & 1) + { + dust->tics++; // "randomize" animation + altColor = !altColor; + } + + dust->colorized = true; + dust->color = altColor ? SKINCOLOR_BLOSSOM : SKINCOLOR_JAWZ; + + dust->momx = (4*mo->momx)/5; + dust->momy = (4*mo->momy)/5; + dust->momz = (4*P_GetMobjZMovement(mo))/5; + + P_Thrust(dust, dust->angle, 4*mo->scale); +} + void K_Squish(mobj_t *mo) { const fixed_t maxstretch = 4*FRACUNIT; @@ -6948,9 +7065,11 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) || player->driftboost || player->startboost || player->eggmanexplode || player->trickboost) { +#if 0 if (player->invincibilitytimer) K_SpawnInvincibilitySpeedLines(player->mo); else +#endif K_SpawnNormalSpeedLines(player); } @@ -7030,56 +7149,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) } } - if (player->playerstate == PST_DEAD || (player->respawn.state == RESPAWNST_MOVE)) // Ensure these are set correctly here - { - player->mo->colorized = (player->dye != 0); - player->mo->color = player->dye ? player->dye : player->skincolor; - } - else if (player->eggmanexplode) // You're gonna diiiiie - { - const INT32 flashtime = 4<<(player->eggmanexplode/TICRATE); - if (player->eggmanexplode == 1 || (player->eggmanexplode % (flashtime/2) != 0)) - { - player->mo->colorized = (player->dye != 0); - player->mo->color = player->dye ? player->dye : player->skincolor; - } - else if (player->eggmanexplode % flashtime == 0) - { - player->mo->colorized = true; - player->mo->color = SKINCOLOR_BLACK; - } - else - { - player->mo->colorized = true; - player->mo->color = SKINCOLOR_CRIMSON; - } - } - else if (player->invincibilitytimer) // setting players to use the star colormap and spawning afterimages - { - player->mo->colorized = true; - } - else if (player->growshrinktimer) // Ditto, for grow/shrink - { - if (player->growshrinktimer % 5 == 0) - { - player->mo->colorized = true; - player->mo->color = (player->growshrinktimer < 0 ? SKINCOLOR_CREAMSICLE : SKINCOLOR_PERIWINKLE); - } - else - { - player->mo->colorized = (player->dye != 0); - player->mo->color = player->dye ? player->dye : player->skincolor; - } - } - else if (player->ringboost && (leveltime & 1)) // ring boosting - { - player->mo->colorized = true; - } - else - { - player->mo->colorized = (player->dye != 0); - } - if (player->itemtype == KITEM_NONE) player->pflags &= ~PF_HOLDREADY; @@ -7307,6 +7376,17 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) K_HandleTumbleBounce(player); } + if (player->tripwireLeniency > 0) + { + player->tripwireLeniency--; + K_SpawnTripwireVFX(player->mo); + } + + if (K_TripwirePassConditions(player) == true) + { + player->tripwireLeniency = max(player->tripwireLeniency, TICRATE); + } + K_KartPlayerHUDUpdate(player); if (battleovertime.enabled && !(player->pflags & PF_ELIMINATED) && player->bumpers <= 0 && player->karmadelay <= 0) @@ -7422,13 +7502,101 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) } K_KartEbrakeVisuals(player); + + if (K_GetKartButtons(player) & BT_BRAKE && + P_IsObjectOnGround(player->mo) && + K_GetKartSpeed(player, false) / 2 <= player->speed) + { + K_SpawnBrakeVisuals(player); + } } void K_KartPlayerAfterThink(player_t *player) { - if (player->curshield - || player->invincibilitytimer - || (player->growshrinktimer != 0 && player->growshrinktimer % 5 == 4)) // 4 instead of 0 because this is afterthink! + boolean fullbright = false; + + if (player->playerstate == PST_DEAD || (player->respawn.state == RESPAWNST_MOVE)) // Ensure these are set correctly here + { + player->mo->colorized = (player->dye != 0); + player->mo->color = player->dye ? player->dye : player->skincolor; + } + else if (player->eggmanexplode) // You're gonna diiiiie + { + const INT32 flashtime = 4<<(player->eggmanexplode/TICRATE); + if (player->eggmanexplode == 1 || (player->eggmanexplode % (flashtime/2) != 0)) + { + player->mo->colorized = (player->dye != 0); + player->mo->color = player->dye ? player->dye : player->skincolor; + } + else if (player->eggmanexplode % flashtime == 0) + { + player->mo->colorized = true; + player->mo->color = SKINCOLOR_BLACK; + fullbright = true; + } + else + { + player->mo->colorized = true; + player->mo->color = SKINCOLOR_CRIMSON; + fullbright = true; + } + } + else if (player->invincibilitytimer) + { + const tic_t defaultTime = itemtime+(2*TICRATE); + tic_t flicker = 2; + + fullbright = true; + + if (player->invincibilitytimer > defaultTime) + { + player->mo->color = K_RainbowColor(leveltime / 2); + player->mo->colorized = true; + } + else + { + player->mo->color = player->skincolor; + player->mo->colorized = false; + + flicker += (defaultTime - player->invincibilitytimer) / TICRATE / 2; + } + + if (leveltime % flicker == 0) + { + player->mo->color = SKINCOLOR_INVINCFLASH; + player->mo->colorized = true; + } + } + else if (player->growshrinktimer) // Ditto, for grow/shrink + { + if (player->growshrinktimer % 5 == 0) + { + player->mo->colorized = true; + player->mo->color = (player->growshrinktimer < 0 ? SKINCOLOR_CREAMSICLE : SKINCOLOR_PERIWINKLE); + fullbright = true; + } + else + { + player->mo->colorized = (player->dye != 0); + player->mo->color = player->dye ? player->dye : player->skincolor; + } + } + else if (player->ringboost && (leveltime & 1)) // ring boosting + { + player->mo->colorized = true; + fullbright = true; + } + else + { + player->mo->colorized = (player->dye != 0); + } + + if (player->curshield) + { + fullbright = true; + } + + if (fullbright == true) { player->mo->frame |= FF_FULLBRIGHT; } @@ -9272,7 +9440,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) overlay->destscale = player->mo->scale; P_SetScale(overlay, player->mo->scale); } - player->invincibilitytimer = itemtime+(2*TICRATE); // 10 seconds + player->invincibilitytimer += itemtime+(2*TICRATE); // 10 seconds if (P_IsLocalPlayer(player) == true) { diff --git a/src/k_kart.h b/src/k_kart.h index 95e24d7cd..aef18b19e 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -75,7 +75,6 @@ void K_DebtStingPlayer(player_t *player, mobj_t *source); void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers); void K_DestroyBumpers(player_t *player, UINT8 amount); void K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount); -void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit, mobj_t *source); void K_MineFlashScreen(mobj_t *source); void K_SpawnMineExplosion(mobj_t *source, UINT8 color); void K_RunFinishLineBeam(void); @@ -116,6 +115,7 @@ void K_StripOther(player_t *player); void K_MomentumToFacing(player_t *player); boolean K_ApplyOffroad(player_t *player); boolean K_SlopeResistance(player_t *player); +boolean K_TripwirePassConditions(player_t *player); boolean K_TripwirePass(player_t *player); boolean K_WaterRun(player_t *player); void K_ApplyTripWire(player_t *player, tripwirestate_t state); diff --git a/src/k_race.c b/src/k_race.c index f459e7a80..fde4c9be2 100644 --- a/src/k_race.c +++ b/src/k_race.c @@ -125,7 +125,7 @@ boolean K_GenerateFinishBeamLine(void) mapthing_t *mt; INT64 bounds[4]; - angle_t angle; + angle_t angle = 0; boolean valid = false; size_t i; diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 04b37601f..decf683f4 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3550,25 +3550,6 @@ static int lib_kTakeBumpersFromPlayer(lua_State *L) return 0; } -static int lib_kSpawnKartExplosion(lua_State *L) -{ - fixed_t x = luaL_checkfixed(L, 1); - fixed_t y = luaL_checkfixed(L, 2); - fixed_t z = luaL_checkfixed(L, 3); - fixed_t radius = (fixed_t)luaL_optinteger(L, 4, 32*FRACUNIT); - INT32 number = (INT32)luaL_optinteger(L, 5, 32); - mobjtype_t type = luaL_optinteger(L, 6, MT_MINEEXPLOSION); - angle_t rotangle = luaL_optinteger(L, 7, 0); - boolean spawncenter = lua_opttrueboolean(L, 8); - boolean ghostit = lua_optboolean(L, 9); - mobj_t *source = NULL; - NOHUD - if (!lua_isnone(L, 10) && lua_isuserdata(L, 10)) - source = *((mobj_t **)luaL_checkudata(L, 10, META_MOBJ)); - K_SpawnKartExplosion(x, y, z, radius, number, type, rotangle, spawncenter, ghostit, source); - return 0; -} - static int lib_kSpawnMineExplosion(lua_State *L) { mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); @@ -4101,7 +4082,6 @@ static luaL_Reg lib[] = { {"K_TumblePlayer",lib_kTumblePlayer}, {"K_ExplodePlayer",lib_kExplodePlayer}, {"K_TakeBumpersFromPlayer",lib_kTakeBumpersFromPlayer}, - {"K_SpawnKartExplosion",lib_kSpawnKartExplosion}, {"K_SpawnMineExplosion",lib_kSpawnMineExplosion}, {"K_SpawnBoostTrail",lib_kSpawnBoostTrail}, {"K_SpawnSparkleTrail",lib_kSpawnSparkleTrail}, diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 6b297c240..3d05d9c15 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -288,6 +288,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->draftleeway); else if (fastcmp(field,"lastdraft")) lua_pushinteger(L, plr->lastdraft); + else if (fastcmp(field,"tripwireLeniency")) + lua_pushinteger(L, plr->tripwireLeniency); else if (fastcmp(field,"itemroulette")) lua_pushinteger(L, plr->itemroulette); else if (fastcmp(field,"roulettetype")) @@ -630,6 +632,8 @@ static int player_set(lua_State *L) plr->draftleeway = luaL_checkinteger(L, 3); else if (fastcmp(field,"lastdraft")) plr->lastdraft = luaL_checkinteger(L, 3); + else if (fastcmp(field,"tripwireLeniency")) + plr->tripwireLeniency = luaL_checkinteger(L, 3); else if (fastcmp(field,"itemroulette")) plr->itemroulette = luaL_checkinteger(L, 3); else if (fastcmp(field,"roulettetype")) diff --git a/src/m_menu.c b/src/m_menu.c index 1c5191127..c1c8c114d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6344,7 +6344,7 @@ static void M_RetryResponse(INT32 ch) if (ch != 'y' && ch != KEY_ENTER) return; - if (!&players[consoleplayer] || netgame || multiplayer) // Should never happen! + if (netgame || multiplayer) // Should never happen! return; M_ClearMenus(true); diff --git a/src/m_misc.c b/src/m_misc.c index cf5053078..8146cceec 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -851,7 +851,7 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png else snprintf(lvlttltext, 48, "Unknown"); - if (gamestate == GS_LEVEL && &players[g_localplayers[0]] && players[g_localplayers[0]].mo) + if (gamestate == GS_LEVEL && players[g_localplayers[0]].mo) snprintf(locationtxt, 40, "X:%d Y:%d Z:%d A:%d", players[g_localplayers[0]].mo->x>>FRACBITS, players[g_localplayers[0]].mo->y>>FRACBITS, diff --git a/src/p_enemy.c b/src/p_enemy.c index 0edfbb5e8..7b6d12983 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -25,10 +25,13 @@ #include "i_video.h" #include "z_zone.h" #include "lua_hook.h" -#include "k_kart.h" // SRB2kart + +// SRB2kart +#include "k_kart.h" #include "k_waypoint.h" #include "k_battle.h" #include "k_respawn.h" +#include "k_collide.h" #ifdef HW3SOUND #include "hardware/hw3sound.h" @@ -141,7 +144,6 @@ void A_RingExplode(mobj_t *actor); void A_OldRingExplode(mobj_t *actor); void A_MixUp(mobj_t *actor); void A_Boss2TakeDamage(mobj_t *actor); -void A_Boss7Chase(mobj_t *actor); void A_GoopSplat(mobj_t *actor); void A_Boss2PogoSFX(mobj_t *actor); void A_Boss2PogoTarget(mobj_t *actor); @@ -2490,26 +2492,15 @@ void A_LobShot(mobj_t *actor) if (actor->eflags & MFE_VERTICALFLIP) { z = actor->z + actor->height - FixedMul(locvar2*FRACUNIT, actor->scale); - if (actor->type == MT_BLACKEGGMAN) - z -= FixedMul(mobjinfo[locvar1].height, actor->scale/2); - else - z -= FixedMul(mobjinfo[locvar1].height, actor->scale); + z -= FixedMul(mobjinfo[locvar1].height, actor->scale); } else z = actor->z + FixedMul(locvar2*FRACUNIT, actor->scale); shot = P_SpawnMobj(actor->x, actor->y, z, locvar1); - if (actor->type == MT_BLACKEGGMAN) - { - shot->destscale = actor->scale/2; - P_SetScale(shot, actor->scale/2); - } - else - { - shot->destscale = actor->scale; - P_SetScale(shot, actor->scale); - } + shot->destscale = actor->scale; + P_SetScale(shot, actor->scale); // Keep track of where it's going to land hitspot = P_SpawnMobj(actor->target->x&(64*FRACUNIT-1), actor->target->y&(64*FRACUNIT-1), actor->target->subsector->sector->floorheight, MT_NULL); @@ -3576,28 +3567,6 @@ bossjustdie: // now do another switch case for escaping switch (mo->type) { - case MT_BLACKEGGMAN: - { - mo->flags |= MF_NOCLIP; - mo->flags &= ~MF_SPECIAL; - - S_StartSound(NULL, sfx_befall); - break; - } - case MT_CYBRAKDEMON: - { - mo->flags |= MF_NOCLIP; - mo->flags &= ~(MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT); - - S_StartSound(NULL, sfx_bedie2); - P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_CYBRAKDEMON_VILE_EXPLOSION); - mo->z += P_MobjFlip(mo); - P_SetObjectMomZ(mo, 12*FRACUNIT, false); - S_StartSound(mo, sfx_bgxpld); - if (mo->spawnpoint && !(mo->spawnpoint->options & MTF_EXTRA)) - P_InstaThrust(mo, R_PointToAngle2(0, 0, mo->x, mo->y), 14*FRACUNIT); - break; - } case MT_KOOPA: { // Initialize my junk @@ -4047,7 +4016,7 @@ void A_AttractChase(mobj_t *actor) } else { - fixed_t dist = (actor->target->radius/4) * (16 - actor->extravalue1); + fixed_t dist = (4*actor->target->scale) * (16 - actor->extravalue1); P_SetScale(actor, (actor->destscale = actor->target->scale - ((actor->target->scale/14) * actor->extravalue1))); actor->z = actor->target->z; @@ -6190,128 +6159,6 @@ void A_Boss2TakeDamage(mobj_t *actor) actor->movecount = locvar1; // become flashing invulnerable for this long. } -// Function: A_Boss7Chase -// -// Description: Like A_Chase, but for Black Eggman -// -// var1 = unused -// var2 = unused -// -void A_Boss7Chase(mobj_t *actor) -{ - INT32 delta; - INT32 i; - - if (LUA_CallAction(A_BOSS7CHASE, actor)) - return; - - if (actor->z != actor->floorz) - return; - - // Self-adjust if stuck on the edge - if (actor->tracer) - { - if (P_AproxDistance(actor->x - actor->tracer->x, actor->y - actor->tracer->y) > 128*FRACUNIT - actor->radius) - P_InstaThrust(actor, R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y), FRACUNIT); - } - - if (actor->flags2 & MF2_FRET) - { - P_SetMobjState(actor, S_BLACKEGG_DESTROYPLAT1); - S_StartSound(0, sfx_s3k53); - actor->flags2 &= ~MF2_FRET; - return; - } - - // turn towards movement direction if not there yet - if (actor->movedir < NUMDIRS) - { - actor->angle &= (7<<29); - delta = actor->angle - (actor->movedir << 29); - - if (delta > 0) - actor->angle -= ANGLE_45; - else if (delta < 0) - actor->angle += ANGLE_45; - } - - // Is a player on top of us? - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator) - continue; - - if (!players[i].mo) - continue; - - if (players[i].mo->health <= 0) - continue; - - if (P_AproxDistance(players[i].mo->x - actor->x, players[i].mo->y - actor->y) > actor->radius) - continue; - - if (players[i].mo->z > actor->z + actor->height - 2*FRACUNIT - && players[i].mo->z < actor->z + actor->height + 32*FRACUNIT) - { - // Punch him! - P_SetMobjState(actor, actor->info->meleestate); - S_StartSound(0, sfx_begrnd); // warning sound - return; - } - } - - if (actor->reactiontime) - actor->reactiontime--; - - if (actor->reactiontime <= 0 && actor->z == actor->floorz) - { - // Here, we'll call P_RandomByte() and decide what kind of attack to do - switch(actor->threshold) - { - case 0: // Lob cannon balls - if (actor->z < 1056*FRACUNIT) - { - A_FaceTarget(actor); - P_SetMobjState(actor, actor->info->xdeathstate); - actor->movecount = 7*TICRATE + P_RandomByte(); - break; - } - actor->threshold++; - /* FALLTHRU */ - case 1: // Chaingun Goop - A_FaceTarget(actor); - P_SetMobjState(actor, S_BLACKEGG_SHOOT1); - - if (actor->health > actor->info->damage) - actor->movecount = TICRATE + P_RandomByte()/3; - else - actor->movecount = TICRATE + P_RandomByte()/2; - break; - case 2: // Homing Missile - A_FaceTarget(actor); - P_SetMobjState(actor, actor->info->missilestate); - S_StartSound(0, sfx_beflap); - break; - } - - actor->threshold++; - actor->threshold %= 3; - return; - } - - // possibly choose another target - if (multiplayer && (actor->target->health <= 0 || !P_CheckSight(actor, actor->target)) - && P_BossTargetPlayer(actor, false)) - return; // got a new target - - if (leveltime & 1) - { - // chase towards player - if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) - P_NewChaseDir(actor); - } -} - // Function: A_GoopSplat // // Description: Black Eggman goop hits a target and sticks around for awhile. @@ -9846,7 +9693,7 @@ void A_VileTarget(mobj_t *actor) // Determine object to spawn if (locvar1 <= 0 || locvar1 >= NUMMOBJTYPES) - fogtype = MT_CYBRAKDEMON_TARGET_RETICULE; + return; else fogtype = (mobjtype_t)locvar1; @@ -10142,8 +9989,6 @@ void A_BrakChase(mobj_t *actor) if (actor->reactiontime) { actor->reactiontime--; - if (actor->reactiontime == 0 && actor->type == MT_CYBRAKDEMON) - S_StartSound(0, sfx_bewar1 + P_RandomKey(4)); } // modify target threshold @@ -10222,7 +10067,7 @@ void A_BrakChase(mobj_t *actor) S_StartSound(actor, (sfxenum_t)locvar2); // make active sound - if (actor->type != MT_CYBRAKDEMON && actor->info->activesound && P_RandomChance(3*FRACUNIT/256)) + if (actor->info->activesound && P_RandomChance(3*FRACUNIT/256)) { S_StartSound(actor, actor->info->activesound); } @@ -14050,55 +13895,9 @@ void A_SPBChase(mobj_t *actor) return; } -static mobj_t *grenade; -static fixed_t explodedist; - -static inline boolean PIT_SSMineSearch(mobj_t *thing) -{ - if (!grenade) - return false; - - if (grenade->flags2 & MF2_DEBRIS) - return false; - - if (thing->type != MT_PLAYER) // Don't explode for anything but an actual player. - return true; - - if (!(thing->flags & MF_SHOOTABLE)) - { - // didn't do any damage - return true; - } - - if (netgame && thing->player && thing->player->spectator) - return true; - - if (thing == grenade->target && grenade->threshold != 0) // Don't blow up at your owner. - return true; - - if (thing->player && (thing->player->hyudorotimer - || ((gametyperules & GTR_BUMPERS) && thing->player && thing->player->bumpers <= 0 && thing->player->karmadelay))) - return true; - - // see if it went over / under - if (grenade->z - explodedist > thing->z + thing->height) - return true; // overhead - if (grenade->z + grenade->height + explodedist < thing->z) - return true; // underneath - - if (P_AproxDistance(P_AproxDistance(thing->x - grenade->x, thing->y - grenade->y), - thing->z - grenade->z) > explodedist) - return true; // Too far away - - // Explode! - P_SetMobjState(grenade, grenade->info->deathstate); - return false; -} - void A_SSMineSearch(mobj_t *actor) { - INT32 bx, by, xl, xh, yl, yh; - explodedist = FixedMul(actor->info->painchance, mapobjectscale); + fixed_t dis = INT32_MAX; if (LUA_CallAction(A_SSMINESEARCH, actor)) return; @@ -14106,66 +13905,19 @@ void A_SSMineSearch(mobj_t *actor) if (actor->flags2 & MF2_DEBRIS) return; - if (actor->state == &states[S_SSMINE_DEPLOY8]) - explodedist = (3*explodedist)/2; - if (leveltime % 35 == 0) S_StartSound(actor, actor->info->activesound); - // Use blockmap to check for nearby shootables - yh = (unsigned)(actor->y + explodedist - bmaporgy)>>MAPBLOCKSHIFT; - yl = (unsigned)(actor->y - explodedist - bmaporgy)>>MAPBLOCKSHIFT; - xh = (unsigned)(actor->x + explodedist - bmaporgx)>>MAPBLOCKSHIFT; - xl = (unsigned)(actor->x - explodedist - bmaporgx)>>MAPBLOCKSHIFT; + dis = actor->info->painchance; + if (actor->state == &states[S_SSMINE_DEPLOY8]) + dis = (3*dis)>>1; - grenade = actor; - - for (by = yl; by <= yh; by++) - for (bx = xl; bx <= xh; bx++) - P_BlockThingsIterator(bx, by, PIT_SSMineSearch); -} - -static inline boolean PIT_MineExplode(mobj_t *thing) -{ - if (!grenade || P_MobjWasRemoved(grenade)) - return false; // There's the possibility these can chain react onto themselves after they've already died if there are enough all in one spot - - if (grenade->flags2 & MF2_DEBRIS) // don't explode twice - return false; - - if (thing == grenade || thing->type == MT_MINEEXPLOSIONSOUND) // Don't explode yourself! Endless loop! - return true; - - if (!(thing->flags & MF_SHOOTABLE) || (thing->flags & MF_SCENERY)) - return true; - - if (netgame && thing->player && thing->player->spectator) - return true; - - if ((gametyperules & GTR_BUMPERS) && grenade->target && grenade->target->player && grenade->target->player->bumpers <= 0 && thing == grenade->target) - return true; - - // see if it went over / under - if (grenade->z - explodedist > thing->z + thing->height) - return true; // overhead - if (grenade->z + grenade->height + explodedist < thing->z) - return true; // underneath - - if (P_AproxDistance(P_AproxDistance(thing->x - grenade->x, thing->y - grenade->y), - thing->z - grenade->z) > explodedist) - return true; // Too far away - - P_DamageMobj(thing, grenade, grenade->target, 1, DMG_EXPLODE); - return true; + K_DoMineSearch(actor, dis); } void A_SSMineExplode(mobj_t *actor) { - INT32 bx, by, xl, xh, yl, yh; - INT32 d; INT32 locvar1 = var1; - mobjtype_t type; - explodedist = FixedMul((3*actor->info->painchance)/2, actor->scale); if (LUA_CallAction(A_SSMINEEXPLODE, actor)) return; @@ -14173,33 +13925,8 @@ void A_SSMineExplode(mobj_t *actor) if (actor->flags2 & MF2_DEBRIS) return; - type = (mobjtype_t)locvar1; - - // Use blockmap to check for nearby shootables - yh = (unsigned)(actor->y + explodedist - bmaporgy)>>MAPBLOCKSHIFT; - yl = (unsigned)(actor->y - explodedist - bmaporgy)>>MAPBLOCKSHIFT; - xh = (unsigned)(actor->x + explodedist - bmaporgx)>>MAPBLOCKSHIFT; - xl = (unsigned)(actor->x - explodedist - bmaporgx)>>MAPBLOCKSHIFT; - - BMBOUNDFIX (xl, xh, yl, yh); - - grenade = actor; - - for (by = yl; by <= yh; by++) - for (bx = xl; bx <= xh; bx++) - P_BlockThingsIterator(bx, by, PIT_MineExplode); - - for (d = 0; d < 16; d++) - K_SpawnKartExplosion(actor->x, actor->y, actor->z, explodedist + 32*mapobjectscale, 32, type, d*(ANGLE_45/4), true, false, actor->target); // 32 <-> 64 - - if (actor->target && actor->target->player) - K_SpawnMineExplosion(actor, actor->target->player->skincolor); - else - K_SpawnMineExplosion(actor, SKINCOLOR_KETCHUP); - - P_SpawnMobj(actor->x, actor->y, actor->z, MT_MINEEXPLOSIONSOUND); - - actor->flags2 |= MF2_DEBRIS; // Set this flag to ensure that the explosion won't be effective more than 1 frame. + K_SpawnMineExplosion(actor, (actor->target && actor->target->player) ? actor->target->player->skincolor : SKINCOLOR_KETCHUP); + K_MineExplodeAttack(actor, (3*actor->info->painchance)>>1, (boolean)locvar1); } void A_LandMineExplode(mobj_t *actor) @@ -14748,6 +14475,7 @@ void A_FlameShieldPaper(mobj_t *actor) void A_InvincSparkleRotate(mobj_t *actor) { fixed_t sx, sy, sz; // Teleport dests. + mobj_t *ghost = NULL; if (LUA_CallAction(A_INVINCSPARKLEROTATE, actor)) return; @@ -14766,4 +14494,11 @@ void A_InvincSparkleRotate(mobj_t *actor) actor->momz = actor->target->momz; // Give momentum for eventual interp builds idk. actor->angle += ANG1*10*(actor->extravalue2); // Arbitrary value, change this if you want, I suppose. + + ghost = P_SpawnGhostMobj(actor); + if (ghost != NULL && P_MobjWasRemoved(ghost) == false) + { + ghost->frame |= FF_ADD; + ghost->fuse = 4; + } } diff --git a/src/p_map.c b/src/p_map.c index 6954d6e11..9d3df593b 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -892,27 +892,6 @@ static boolean PIT_CheckThing(mobj_t *thing) return K_MineCollide(thing, tmthing); } - if (tmthing->type == MT_MINEEXPLOSION) - { - // see if it went over / under - if (tmthing->z > thing->z + thing->height) - return true; // overhead - if (tmthing->z + tmthing->height < thing->z) - return true; // underneath - - return K_MineExplosionCollide(tmthing, thing); - } - else if (thing->type == MT_MINEEXPLOSION) - { - // see if it went over / under - if (tmthing->z > thing->z + thing->height) - return true; // overhead - if (tmthing->z + tmthing->height < thing->z) - return true; // underneath - - return K_MineExplosionCollide(thing, tmthing); - } - if (tmthing->type == MT_LANDMINE) { // see if it went over / under @@ -2490,8 +2469,10 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) // This makes sure that there are no freezes from computing extremely small movements. // Originally was MAXRADIUS/2, but that causes some inconsistencies for small players. - if (radius < mapobjectscale) - radius = mapobjectscale; + radius = max(radius, mapobjectscale); + + // And Big Large (tm) movements can skip over slopes. + radius = min(radius, 16*mapobjectscale); #if 0 if (thing->hitlag > 0) @@ -3922,7 +3903,7 @@ bounceback: tmxmove = FixedMul(mmomx, (FRACUNIT - (FRACUNIT>>6) - (FRACUNIT>>5))); tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>6) - (FRACUNIT>>5))); } - else if (mo->type == MT_THROWNGRENADE || mo->type == MT_CYBRAKDEMON_NAPALM_BOMB_LARGE) + else if (mo->type == MT_THROWNGRENADE) { // Quickly decay speed as it bounces tmxmove = FixedDiv(mmomx, 2*FRACUNIT); diff --git a/src/p_mobj.c b/src/p_mobj.c index 00744229f..c9f68b8f3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -42,6 +42,7 @@ #include "k_respawn.h" #include "k_bot.h" #include "k_terrain.h" +#include "k_collide.h" static CV_PossibleValue_t CV_BobSpeed[] = {{0, "MIN"}, {4*FRACUNIT, "MAX"}, {0, NULL}}; consvar_t cv_movebob = CVAR_INIT ("movebob", "1.0", CV_FLOAT|CV_SAVE, CV_BobSpeed, NULL); @@ -1171,7 +1172,6 @@ fixed_t P_GetMobjGravity(mobj_t *mo) } break; case MT_WATERDROP: - case MT_CYBRAKDEMON: case MT_BATTLEBUMPER: gravityadd /= 2; break; @@ -2342,10 +2342,6 @@ boolean P_ZMovement(mobj_t *mo) if (abs(mom.z) < mo->scale) { mom.x = mom.y = mom.z = 0; - - // Napalm hack - if (mo->type == MT_CYBRAKDEMON_NAPALM_BOMB_LARGE && mo->fuse) - mo->fuse = 1; } // Otherwise bounce up at half speed. else @@ -6281,9 +6277,6 @@ static boolean P_MobjDeadThink(mobj_t *mobj) return false; } break; - case MT_MINEEXPLOSIONSOUND: - P_RemoveMobj(mobj); - return false; case MT_CDUFO: if (mobj->fuse > TICRATE) mobj->renderflags ^= RF_DONTDRAW; // only by good fortune does this end with it having RF_DONTDRAW... don't touch! @@ -6972,34 +6965,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj) case MT_SPBEXPLOSION: mobj->health--; break; - case MT_MINEEXPLOSION: - if ((mobj->z < mobj->floorz - mobj->height) || (mobj->z > mobj->ceilingz + mobj->height)) - { - P_KillMobj(mobj, NULL, NULL, DMG_NORMAL); - break; - } - - if (mobj->tics != -1) - { - mobj->tics--; - - // you can cycle through multiple states in a tic - if (!mobj->tics) - if (!P_SetMobjState(mobj, mobj->state->nextstate)) - return false; // freed itself - } - - P_UnsetThingPosition(mobj); - mobj->x += mobj->momx; - mobj->y += mobj->momy; - mobj->z += mobj->momz; - P_SetThingPosition(mobj); - return false; - case MT_MINEEXPLOSIONSOUND: - if (mobj->health == 100) - S_StartSound(mobj, sfx_s3k4e); - mobj->health--; - break; case MT_EMERALD: { if (battleovertime.enabled >= 10*TICRATE) @@ -7175,15 +7140,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj) P_Thrust(smoke, mobj->angle+FixedAngle(P_RandomRange(135, 225)<target->scale); } break; - case MT_SPARKLETRAIL: - if (!mobj->target) - { - P_RemoveMobj(mobj); - return false; - } - mobj->color = mobj->target->color; - mobj->colorized = mobj->target->colorized; - break; case MT_INVULNFLASH: if (!mobj->target || !mobj->target->health || (mobj->target->player && !mobj->target->player->invincibilitytimer)) { @@ -7229,6 +7185,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->renderflags |= RF_DONTDRAW; } break; + case MT_BRAKEDUST: + //mobj->renderflags ^= RF_DONTDRAW; + break; case MT_JANKSPARK: if (!mobj->target) { @@ -8962,6 +8921,17 @@ static void P_FiringThink(mobj_t *mobj) mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); } +static void K_MineExplodeThink(mobj_t *mobj) +{ + if (mobj->state->action.acp1 == (actionf_p1)A_SSMineExplode) + { + if (mobj->state->tics > 1) + { + K_MineExplodeAttack(mobj, mobj->info->painchance, (boolean)mobj->state->var1); + } + } +} + static void P_MonitorFuseThink(mobj_t *mobj) { mobj_t *newmobj; @@ -9313,6 +9283,9 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->flags2 & MF2_FIRING) P_FiringThink(mobj); + if (mobj->flags2 & MF2_DEBRIS) + K_MineExplodeThink(mobj); + if (mobj->flags & MF_AMBIENT) { if (!(leveltime % mobj->health) && mobj->info->seesound) @@ -9649,6 +9622,8 @@ static void P_DefaultMobjShadowScale(mobj_t *thing) { case MT_PLAYER: case MT_KART_LEFTOVER: + thing->shadowscale = FRACUNIT; + break; case MT_SMALLMACE: case MT_BIGMACE: case MT_PUMA: @@ -9842,17 +9817,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_LOCKONINF: P_SetScale(mobj, (mobj->destscale = 3*mobj->scale)); break; - case MT_CYBRAKDEMON_NAPALM_BOMB_LARGE: - mobj->fuse = mobj->info->painchance; - break; - case MT_BLACKEGGMAN: - { - mobj_t *spawn = P_SpawnMobj(mobj->x, mobj->z, mobj->z+mobj->height-16*FRACUNIT, MT_BLACKEGGMAN_HELPER); - spawn->destscale = mobj->scale; - P_SetScale(spawn, mobj->scale); - P_SetTarget(&spawn->target, mobj); - } - break; case MT_FAKEMOBILE: case MT_EGGSHIELD: mobj->flags2 |= MF2_INVERTAIMABLE; diff --git a/src/p_saveg.c b/src/p_saveg.c index 92de0c486..bebc5c161 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -278,6 +278,8 @@ static void P_NetArchivePlayers(void) WRITEUINT16(save_p, players[i].draftleeway); WRITESINT8(save_p, players[i].lastdraft); + WRITEUINT16(save_p, players[i].tripwireLeniency); + WRITEUINT16(save_p, players[i].itemroulette); WRITEUINT8(save_p, players[i].roulettetype); @@ -546,6 +548,8 @@ static void P_NetUnArchivePlayers(void) players[i].draftleeway = READUINT16(save_p); players[i].lastdraft = READSINT8(save_p); + players[i].tripwireLeniency = READUINT16(save_p); + players[i].itemroulette = READUINT16(save_p); players[i].roulettetype = READUINT8(save_p); diff --git a/src/p_user.c b/src/p_user.c index 8cc74c837..51016d80e 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1672,15 +1672,15 @@ static void P_CheckInvincibilityTimer(player_t *player) if (!player->invincibilitytimer) return; - player->mo->color = K_RainbowColor(leveltime); - // Resume normal music stuff. if (player->invincibilitytimer == 1) { player->mo->color = player->skincolor; + player->mo->colorized = false; G_GhostAddColor((INT32) (player - players), GHC_NORMAL); P_RestoreMusic(player); + return; } } diff --git a/src/w_wad.c b/src/w_wad.c index df8df7928..e1cb6b1aa 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -637,8 +637,6 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp) lump_p->fullname = Z_Calloc(zentry.namelen + 1, PU_STATIC, NULL); strncpy(lump_p->fullname, fullname, zentry.namelen); - free(fullname); - switch(zentry.compression) { case 0: @@ -658,6 +656,8 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp) break; } + free(fullname); + // skip and ignore comments/extra fields if (fseek(handle, zentry.xtralen + zentry.commlen, SEEK_CUR) != 0) {