diff --git a/src/dehacked.c b/src/dehacked.c index 77663ccd..b8885be4 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6327,31 +6327,31 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ROCKETSNEAKER_RVIBRATE", //{ Eggman Monitor - "S_FAKEITEM1", - "S_FAKEITEM2", - "S_FAKEITEM3", - "S_FAKEITEM4", - "S_FAKEITEM5", - "S_FAKEITEM6", - "S_FAKEITEM7", - "S_FAKEITEM8", - "S_FAKEITEM9", - "S_FAKEITEM10", - "S_FAKEITEM11", - "S_FAKEITEM12", - "S_FAKEITEM13", - "S_FAKEITEM14", - "S_FAKEITEM15", - "S_FAKEITEM16", - "S_FAKEITEM17", - "S_FAKEITEM18", - "S_FAKEITEM19", - "S_FAKEITEM20", - "S_FAKEITEM21", - "S_FAKEITEM22", - "S_FAKEITEM23", - "S_FAKEITEM24", - "S_DEADFAKEITEM", + "S_EGGMANITEM1", + "S_EGGMANITEM2", + "S_EGGMANITEM3", + "S_EGGMANITEM4", + "S_EGGMANITEM5", + "S_EGGMANITEM6", + "S_EGGMANITEM7", + "S_EGGMANITEM8", + "S_EGGMANITEM9", + "S_EGGMANITEM10", + "S_EGGMANITEM11", + "S_EGGMANITEM12", + "S_EGGMANITEM13", + "S_EGGMANITEM14", + "S_EGGMANITEM15", + "S_EGGMANITEM16", + "S_EGGMANITEM17", + "S_EGGMANITEM18", + "S_EGGMANITEM19", + "S_EGGMANITEM20", + "S_EGGMANITEM21", + "S_EGGMANITEM22", + "S_EGGMANITEM23", + "S_EGGMANITEM24", + "S_EGGMANITEM_DEAD", //} // Banana @@ -6863,6 +6863,59 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_CDTREEASP", "S_CDTREEBSP", + // Daytona Speedway + "S_PINETREE", + "S_PINETREE_SIDE", + + // Egg Zeppelin + "S_EZZPROPELLER", + "S_EZZPROPELLER_BLADE", + + // Desert Palace + "S_DP_PALMTREE", + + // Aurora Atoll + "S_AAZTREE_SEG", + "S_AAZTREE_COCONUT", + "S_AAZTREE_LEAF", + + // Barren Badlands + "S_BBZDUST1", // Dust + "S_BBZDUST2", + "S_BBZDUST3", + "S_BBZDUST4", + "S_FROGGER", // Frog badniks + "S_FROGGER_ATTACK", + "S_FROGGER_JUMP", + "S_FROGTONGUE", + "S_FROGTONGUE_JOINT", + "S_ROBRA", // Black cobra badniks + "S_ROBRA_HEAD", + "S_ROBRA_JOINT", + "S_ROBRASHELL_INSIDE", + "S_ROBRASHELL_OUTSIDE", + "S_BLUEROBRA", // Blue cobra badniks + "S_BLUEROBRA_HEAD", + "S_BLUEROBRA_JOINT", + + // Eerie Grove + "S_EERIEFOG1", + "S_EERIEFOG2", + "S_EERIEFOG3", + "S_EERIEFOG4", + "S_EERIEFOG5", + + // SMK ports + "S_SMK_PIPE1", // Generic pipes + "S_SMK_PIPE2", + "S_SMK_MOLE", // Donut Plains Monty Moles + "S_SMK_THWOMP", // Bowser Castle Thwomps + "S_SMK_SNOWBALL", // Vanilla Lake snowballs + "S_SMK_ICEBLOCK", // Vanilla Lake breakable ice blocks + "S_SMK_ICEBLOCK2", + "S_SMK_ICEBLOCK_DEBRIS", + "S_SMK_ICEBLOCK_DEBRIS2", + #ifdef SEENAMES "S_NAMECHECK", #endif @@ -7397,8 +7450,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_ROCKETSNEAKER", // Rocket sneakers - "MT_FAKESHIELD", - "MT_FAKEITEM", + "MT_EGGMANITEM", // Eggman items + "MT_EGGMANITEM_SHIELD", "MT_BANANA", // Banana Stuff "MT_BANANA_SHIELD", @@ -7537,6 +7590,49 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_CDTREEA", "MT_CDTREEB", + // Daytona Speedway + "MT_PINETREE", + "MT_PINETREE_SIDE", + + // Egg Zeppelin + "MT_EZZPROPELLER", + "MT_EZZPROPELLER_BLADE", + + // Desert Palace + "MT_DP_PALMTREE", + + // Aurora Atoll + "MT_AAZTREE_HELPER", + "MT_AAZTREE_SEG", + "MT_AAZTREE_COCONUT", + "MT_AAZTREE_LEAF", + + // Barren Badlands + "MT_BBZDUST", + "MT_FROGGER", + "MT_FROGTONGUE", + "MT_FROGTONGUE_JOINT", + "MT_ROBRA", + "MT_ROBRA_HEAD", + "MT_ROBRA_JOINT", + "MT_BLUEROBRA", + "MT_BLUEROBRA_HEAD", + "MT_BLUEROBRA_JOINT", + + // Eerie Grove + "MT_EERIEFOG", + "MT_EERIEFOGGEN", + + // SMK ports + "MT_SMK_PIPE", + "MT_SMK_MOLESPAWNER", + "MT_SMK_MOLE", + "MT_SMK_THWOMP", + "MT_SMK_SNOWBALL", + "MT_SMK_ICEBLOCK", + "MT_SMK_ICEBLOCK_SIDE", + "MT_SMK_ICEBLOCK_DEBRIS", + #ifdef SEENAMES "MT_NAMECHECK", #endif diff --git a/src/doomstat.h b/src/doomstat.h index 4b0c6f60..f45651d1 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -460,6 +460,7 @@ extern tic_t wantedcalcdelay; extern tic_t indirectitemcooldown; extern tic_t mapreset; extern UINT8 nospectategrief; +extern boolean thwompsactive; extern boolean legitimateexit; extern boolean comebackshowninfo; diff --git a/src/g_game.c b/src/g_game.c index baf89d06..bbf6ebac 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -266,6 +266,7 @@ tic_t wantedcalcdelay; // Time before it recalculates WANTED tic_t indirectitemcooldown; // Cooldown before any more Shrink, SPB, or any other item that works indirectly is awarded tic_t mapreset; // Map reset delay when enough players have joined an empty game UINT8 nospectategrief; // How many players need to be in-game to eliminate last; for preventing spectate griefing +boolean thwompsactive; // Thwomps activate on lap 2 // Client-sided, unsynched variables (NEVER use in anything that needs to be synced with other players) boolean legitimateexit; // Did this client actually finish the match? diff --git a/src/info.c b/src/info.c index cde74cee..81fd5469 100644 --- a/src/info.c +++ b/src/info.c @@ -62,7 +62,8 @@ char sprnames[NUMSPRITES + 1][5] = "CRAB","SHAD","BRNG","BUMP","FLEN","CLAS","PSHW","ISTA","ISTB","ARRO", "ITEM","ITMO","ITMI","ITMN","WANT","PBOM","RETI","AIDU","KSPK","LZI1", "LZI2","KLIT","FZSM","FZBM","FPRT","SPTL","ENM1","GARU","MARR","REAP", - "JITB","CDMO","CDBU","VIEW" + "JITB","CDMO","CDBU","PINE","PPLR","DPPT","AATR","COCO","BDST","FROG", + "CBRA","HOLE","BBRA","EGFG","SMKP","MTYM","THWP","SNOB","ICEB","VIEW" }; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) @@ -2629,31 +2630,31 @@ state_t states[NUMSTATES] = {SPR_RSHE, 2, -1, {NULL}, 0, 0, S_NULL}, // S_ROCKETSNEAKER_LVIBRATE {SPR_RSHE, 3, -1, {NULL}, 0, 0, S_NULL}, // S_ROCKETSNEAKER_RVIBRATE - {SPR_FITM, FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM2}, // S_FAKEITEM1 - {SPR_FITM, 1|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM3}, // S_FAKEITEM2 - {SPR_FITM, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM4}, // S_FAKEITEM3 - {SPR_FITM, 3|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM5}, // S_FAKEITEM4 - {SPR_FITM, 4|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM6}, // S_FAKEITEM5 - {SPR_FITM, 5|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM7}, // S_FAKEITEM6 - {SPR_FITM, 6|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM8}, // S_FAKEITEM7 - {SPR_FITM, 7|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM9}, // S_FAKEITEM8 - {SPR_FITM, 8|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM10}, // S_FAKEITEM9 - {SPR_FITM, 9|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM11}, // S_FAKEITEM10 - {SPR_FITM, 10|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM12}, // S_FAKEITEM11 - {SPR_FITM, 11|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM13}, // S_FAKEITEM12 - {SPR_FITM, 12|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM14}, // S_FAKEITEM13 - {SPR_FITM, 13|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM15}, // S_FAKEITEM14 - {SPR_FITM, 14|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM16}, // S_FAKEITEM15 - {SPR_FITM, 15|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM17}, // S_FAKEITEM16 - {SPR_FITM, 16|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM18}, // S_FAKEITEM17 - {SPR_FITM, 17|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM19}, // S_FAKEITEM18 - {SPR_FITM, 18|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM20}, // S_FAKEITEM19 - {SPR_FITM, 19|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM21}, // S_FAKEITEM20 - {SPR_FITM, 20|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM22}, // S_FAKEITEM21 - {SPR_FITM, 21|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM23}, // S_FAKEITEM22 // ***** - {SPR_FITM, 22|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM24}, // S_FAKEITEM23 // ***** - {SPR_FITM, 23|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM1}, // S_FAKEITEM24 // ***** - {SPR_FITM, FF_FULLBRIGHT, 175, {NULL}, 0, 0, S_FAKEITEM1}, // S_DEADFAKEITEM + {SPR_FITM, FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM2}, // S_EGGMANITEM1 + {SPR_FITM, 1|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM3}, // S_EGGMANITEM2 + {SPR_FITM, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM4}, // S_EGGMANITEM3 + {SPR_FITM, 3|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM5}, // S_EGGMANITEM4 + {SPR_FITM, 4|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM6}, // S_EGGMANITEM5 + {SPR_FITM, 5|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM7}, // S_EGGMANITEM6 + {SPR_FITM, 6|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM8}, // S_EGGMANITEM7 + {SPR_FITM, 7|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM9}, // S_EGGMANITEM8 + {SPR_FITM, 8|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM10}, // S_EGGMANITEM9 + {SPR_FITM, 9|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM11}, // S_EGGMANITEM10 + {SPR_FITM, 10|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM12}, // S_EGGMANITEM11 + {SPR_FITM, 11|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM13}, // S_EGGMANITEM12 + {SPR_FITM, 12|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM14}, // S_EGGMANITEM13 + {SPR_FITM, 13|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM15}, // S_EGGMANITEM14 + {SPR_FITM, 14|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM16}, // S_EGGMANITEM15 + {SPR_FITM, 15|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM17}, // S_EGGMANITEM16 + {SPR_FITM, 16|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM18}, // S_EGGMANITEM17 + {SPR_FITM, 17|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM19}, // S_EGGMANITEM18 + {SPR_FITM, 18|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM20}, // S_EGGMANITEM19 + {SPR_FITM, 19|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM21}, // S_EGGMANITEM20 + {SPR_FITM, 20|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM22}, // S_EGGMANITEM21 + {SPR_FITM, 21|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM23}, // S_EGGMANITEM22 // ***** + {SPR_FITM, 22|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM24}, // S_EGGMANITEM23 // ***** + {SPR_FITM, 23|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM1}, // S_EGGMANITEM24 // ***** + {SPR_FITM, FF_FULLBRIGHT, 175, {NULL}, 0, 0, S_EGGMANITEM1}, // S_EGGMANITEM_DEAD {SPR_BANA, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BANANA {SPR_BANA, 0, 175, {NULL}, 0, 0, S_NULL}, // S_BANANA_DEAD @@ -3158,6 +3159,63 @@ state_t states[NUMSTATES] = {SPR_CDBU, 1, -1, {NULL}, 0, 0, S_CDTREEASP}, // S_CDTREEASP {SPR_CDBU, 2, -1, {NULL}, 0, 0, S_CDTREEBSP}, // S_CDTREEBSP + // Daytona Speedway + {SPR_PINE, 1, -1, {NULL}, 0, 0, S_NULL}, // S_PINETREE + {SPR_PINE, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_PINETREE_SIDE + + // Egg Zeppelin + {SPR_PPLR, 0, -1, {NULL}, 0, 0, S_EZZPROPELLER}, // S_EZZPROPELLER + {SPR_PPLR, FF_PAPERSPRITE|1, -1, {NULL}, 0, 0, S_EZZPROPELLER_BLADE}, // S_EZZPROPELLER_BLADE + + // Desert Palace + {SPR_DPPT, 0, -1, {NULL}, 0, 0, S_NULL}, // S_DP_PALMTREE + + // Aurora Atoll + {SPR_AATR, 0, -1, {NULL}, 0, 0, S_AAZTREE_SEG}, // S_AAZTREE_SEG + {SPR_COCO, 0, -1, {NULL}, 0, 0, S_AAZTREE_COCONUT}, // S_AAZTREE_COCONUT + {SPR_AATR, FF_PAPERSPRITE|1, -1, {NULL}, 0, 0, S_AAZTREE_LEAF}, // S_AAZTREE_LEAF + + // Barren Badlands + {SPR_BDST, FF_TRANS80, 35, {NULL}, 0, 0, S_BBZDUST2}, // S_BBZDUST1 + {SPR_BDST, FF_TRANS80|1, 12, {NULL}, 0, 0, S_BBZDUST3}, // S_BBZDUST2 + {SPR_BDST, FF_TRANS80|2, 11, {NULL}, 0, 0, S_BBZDUST4}, // S_BBZDUST3 + {SPR_BDST, FF_TRANS80|3, 10, {NULL}, 0, 0, S_NULL}, // S_BBZDUST4 + + {SPR_FROG, 0, -1, {NULL}, 0, 0, S_FROGGER}, // S_FROGGER + {SPR_FROG, 1, -1, {NULL}, 0, 0, S_FROGGER_ATTACK}, // S_FROGGER_ATTACK + {SPR_FROG, 2, -1, {NULL}, 0, 0, S_FROGGER_JUMP}, // S_FROGGER_JUMP + + {SPR_FROG, 3, 7*TICRATE/2, {NULL}, 0, 0, S_NULL}, // S_FROGTONGUE + {SPR_FROG, 4, 7*TICRATE/2, {NULL}, 0, 0, S_NULL}, // S_FROGTONGUE_JOINT + + {SPR_HOLE, 0, 1, {NULL}, 0, 0, S_ROBRA}, // S_ROBRA + {SPR_CBRA, 0, 1, {NULL}, 0, 0, S_ROBRA_HEAD}, // S_ROBRA_HEAD + {SPR_CBRA, 1, -1, {NULL}, 0, 0, S_ROBRA_JOINT}, // S_ROBRA_JOINT + {SPR_CBRA, 2, -1, {NULL}, 1, 0, S_ROBRASHELL_INSIDE}, // S_ROBRASHELL_INSIDE + {SPR_CBRA, 3, -1, {NULL}, 0, 0, S_ROBRASHELL_OUTSIDE}, // S_ROBRASHELL_OUTSIDE + + {SPR_HOLE, 0, 1, {NULL}, 0, 0, S_BLUEROBRA}, // S_BLUEROBRA + {SPR_BBRA, 0, 1, {NULL}, 0, 0, S_BLUEROBRA_HEAD}, // S_BLUEROBRA_HEAD + {SPR_BBRA, 1, -1, {NULL}, 0, 0, S_BLUEROBRA_JOINT}, // S_BLUEROBRA_JOINT + + // Eerie Grove + {SPR_EGFG, FF_TRANS90|FF_FULLBRIGHT, 7, {A_SetRandomTics}, 5, 9, S_EERIEFOG2}, // S_EERIEFOG1 + {SPR_EGFG, FF_TRANS90|FF_FULLBRIGHT|1, 7, {A_SetRandomTics}, 5, 9, S_EERIEFOG3}, // S_EERIEFOG2 + {SPR_EGFG, FF_TRANS90|FF_FULLBRIGHT|2, 7, {A_SetRandomTics}, 5, 9, S_EERIEFOG4}, // S_EERIEFOG3 + {SPR_EGFG, FF_TRANS90|FF_FULLBRIGHT|3, 7, {A_SetRandomTics}, 5, 9, S_EERIEFOG5}, // S_EERIEFOG4 + {SPR_EGFG, FF_TRANS90|FF_FULLBRIGHT|4, 7, {A_SetRandomTics}, 5, 9, S_EERIEFOG1}, // S_EERIEFOG5 + + // SMK ports + {SPR_SMKP, 0, -1, {NULL}, 0, 0, S_SMK_PIPE1}, // S_SMK_PIPE1 + {SPR_SMKP, 1, -1, {NULL}, 0, 0, S_SMK_PIPE2}, // S_SMK_PIPE2 + {SPR_MTYM, 0, -1, {NULL}, 0, 0, S_SMK_MOLE}, // S_SMK_MOLE + {SPR_THWP, 0, -1, {NULL}, 0, 0, S_SMK_THWOMP}, // S_SMK_THWOMP + {SPR_SNOB, 0, -1, {NULL}, 0, 0, S_SMK_SNOWBALL}, // S_SMK_SNOWBALL + {SPR_ICEB, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_SMK_ICEBLOCK + {SPR_ICEB, FF_PAPERSPRITE|1, -1, {NULL}, 0, 0, S_NULL}, // S_SMK_ICEBLOCK2 + {SPR_ICEB, 2, 10, {NULL}, 0, 0, S_SMK_ICEBLOCK_DEBRIS2}, // S_SMK_ICEBLOCK_DEBRIS + {SPR_ICEB, 3, 10, {NULL}, 0, 0, S_NULL}, // S_SMK_ICEBLOCK_DEBRIS2 + #ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK #endif @@ -14927,36 +14985,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_FAKESHIELD + { // MT_EGGMANITEM -1, // doomednum - S_FAKEITEM1, // 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_DEADFAKEITEM, // deathstate - S_NULL, // xdeathstate - sfx_kc2e, // deathsound - 8, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 100, // mass - 1, // damage - sfx_None, // activesound - MF_SPECIAL|MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags - S_NULL // raisestate - }, - - { // MT_FAKEITEM - -1, // doomednum - S_FAKEITEM1, // spawnstate + S_EGGMANITEM1, // spawnstate 2, // spawnhealth S_NULL, // seestate sfx_tossed, // seesound @@ -14967,7 +14998,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_DEADFAKEITEM, // deathstate + S_EGGMANITEM_DEAD, // deathstate S_NULL, // xdeathstate sfx_kc2e, // deathsound 0, // speed @@ -14981,6 +15012,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_EGGMANITEM_SHIELD + -1, // doomednum + S_EGGMANITEM1, // 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_EGGMANITEM_DEAD, // deathstate + S_NULL, // xdeathstate + sfx_kc2e, // deathsound + 8, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 1, // damage + sfx_None, // activesound + MF_SPECIAL|MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + { // MT_BANANA -1, // doomednum S_BANANA, // spawnstate @@ -17656,6 +17714,789 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_PINETREE + 3204, // doomednum + S_PINETREE, // 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 + 0, // speed + 32<mo->hnext; @@ -4659,7 +4659,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } else { - newitem = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_FAKEITEM); + newitem = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_EGGMANITEM); if (player->kartstuff[k_eggmanblame] >= 0 && player->kartstuff[k_eggmanblame] < MAXPLAYERS && playeringame[player->kartstuff[k_eggmanblame]] @@ -4685,7 +4685,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) // Eggman Monitor throwing else if (ATTACK_IS_DOWN && player->kartstuff[k_eggmanheld]) { - K_ThrowKartItem(player, false, MT_FAKEITEM, -1, 0); + K_ThrowKartItem(player, false, MT_EGGMANITEM, -1, 0); K_PlayAttackTaunt(player->mo); player->kartstuff[k_eggmanheld] = 0; K_UpdateHnextList(player, true); @@ -4811,7 +4811,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->kartstuff[k_itemamount]--; player->kartstuff[k_eggmanheld] = 1; S_StartSound(player->mo, sfx_s254); - mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_FAKESHIELD); + mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_EGGMANITEM_SHIELD); if (mo) { mo->flags |= MF_NOCLIPTHING; diff --git a/src/p_inter.c b/src/p_inter.c index af5dc5b1..f9c57432 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -324,48 +324,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; } - else if ((special->flags & MF_ENEMY) && !(special->flags & MF_MISSILE)) + else if ((special->flags & MF_ENEMY) && !(special->flags & MF_MISSILE) + && (special->type != MT_SPRINGSHELL)) // Kart: prevent random hits from these things { - //////////////////////////////////////////////////////// - /////ENEMIES!!////////////////////////////////////////// - //////////////////////////////////////////////////////// - /*if (special->type == MT_GSNAPPER && !(((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) - || player->powers[pw_invulnerability] || player->powers[pw_super]) - && toucher->z < special->z + special->height && toucher->z + toucher->height > special->z) - { - // Can only hit snapper from above - P_DamageMobj(toucher, special, special, 1); - } - else if (special->type == MT_SHARP - && ((special->state == &states[special->info->xdeathstate]) || (toucher->z > special->z + special->height/2))) - { - // Cannot hit sharp from above or when red and angry - P_DamageMobj(toucher, special, special, 1); - } - else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) - || (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)) - || player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object? - { - if (P_MobjFlip(toucher)*toucher->momz < 0) - toucher->momz = -toucher->momz; - - P_DamageMobj(special, toucher, toucher, 1); - } - else if (((toucher->z < special->z && !(toucher->eflags & MFE_VERTICALFLIP)) - || (toucher->z + toucher->height > special->z + special->height && (toucher->eflags & MFE_VERTICALFLIP))) // Flame is bad at logic - JTE - && player->charability == CA_FLY - && (player->powers[pw_tailsfly] - || (toucher->state >= &states[S_PLAY_SPC1] && toucher->state <= &states[S_PLAY_SPC4]))) // Tails can shred stuff with his propeller. - { - if (P_MobjFlip(toucher)*toucher->momz < 0) - toucher->momz = -toucher->momz/2; - - P_DamageMobj(special, toucher, toucher, 1); - } - // SRB2kart - Removed: No more fly states - else*/ - P_DamageMobj(toucher, special, special, 1); - + P_DamageMobj(toucher, special, special, 1); return; } else if (special->flags & MF_FIRE) @@ -424,8 +386,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_SetTarget(&special->target, toucher); P_KillMobj(special, toucher, toucher); break; - case MT_FAKESHIELD: // SRB2kart - case MT_FAKEITEM: + case MT_EGGMANITEM_SHIELD: // SRB2kart + case MT_EGGMANITEM: if ((special->target == toucher || special->target == toucher->target) && (special->threshold > 0)) return; @@ -618,7 +580,36 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } else K_SpinPlayer(player, special, 0, false); + return; + /*case MT_EERIEFOG: + special->frame &= ~FF_TRANS80; + special->frame |= FF_TRANS90; + return;*/ + case MT_SMK_MOLE: + if (special->target && !P_MobjWasRemoved(special->target)) + return; + if (special->health <= 0 || toucher->health <= 0) + return; + + if (!player->mo || player->spectator) + return; + + // kill + if (player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0) + { + P_KillMobj(special, toucher, toucher); + return; + } + + // no interaction + if (player->powers[pw_flashing] > 0 || player->kartstuff[k_hyudorotimer] > 0 + || player->kartstuff[k_squishedtimer] > 0 || player->kartstuff[k_spinouttimer] > 0) + return; + + // attach to player! + P_SetTarget(&special->target, toucher); + S_StartSound(special, sfx_s1a2); return; // ***************************************** // @@ -2044,7 +2035,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) && !(target->type == MT_ORBINAUT || target->type == MT_ORBINAUT_SHIELD || target->type == MT_JAWZ || target->type == MT_JAWZ_DUD || target->type == MT_JAWZ_SHIELD || target->type == MT_BANANA || target->type == MT_BANANA_SHIELD - || target->type == MT_FAKEITEM || target->type == MT_FAKESHIELD + || target->type == MT_EGGMANITEM || target->type == MT_EGGMANITEM_SHIELD || target->type == MT_BALLHOG || target->type == MT_SPB)) // kart dead items target->flags |= MF_NOGRAVITY; // Don't drop Tails 03-08-2000 else @@ -2068,7 +2059,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) // I wish I knew a better way to do this if (target->target && target->target->player && target->target->player->mo) { - if (target->target->player->kartstuff[k_eggmanheld] && target->type == MT_FAKESHIELD) + if (target->target->player->kartstuff[k_eggmanheld] && target->type == MT_EGGMANITEM_SHIELD) target->target->player->kartstuff[k_eggmanheld] = 0; if (target->target->player->kartstuff[k_itemheld]) @@ -2414,6 +2405,21 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) else P_PlayDeathSound(target); break; + + // SRB2Kart: + case MT_SMK_ICEBLOCK: + { + mobj_t *cur = target->hnext; + while (cur && !P_MobjWasRemoved(cur)) + { + P_SetMobjState(cur, S_SMK_ICEBLOCK2); + cur = cur->hnext; + } + target->fuse = 10; + S_StartSound(target, sfx_s3k80); + } + break; + default: break; } @@ -2474,6 +2480,41 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) target->z += P_MobjFlip(target)*20*target->scale; } + // kill tracer + if (target->type == MT_FROGGER) + { + if (target->tracer && !P_MobjWasRemoved(target->tracer)) + P_KillMobj(target->tracer, inflictor, source); + } + + + if (target->type == MT_FROGGER || target->type == MT_ROBRA_HEAD || target->type == MT_BLUEROBRA_HEAD) // clean hnext list + { + mobj_t *cur = target->hnext; + while (cur && !P_MobjWasRemoved(cur)) + { + P_KillMobj(cur, inflictor, source); + cur = cur->hnext; + } + } + + // Bounce up on death + if (target->type == MT_SMK_PIPE || target->type == MT_SMK_MOLE || target->type == MT_SMK_THWOMP) + { + target->flags &= (~MF_NOGRAVITY); + + if (target->eflags & MFE_VERTICALFLIP) + target->z -= target->height; + else + target->z += target->height; + + S_StartSound(target, target->info->deathsound); + + P_SetObjectMomZ(target, 8<x, inflictor->y, target->x, target->y)+ANGLE_90, 16<type == MT_SPIKE && inflictor && target->info->deathstate != S_NULL) { const fixed_t x=target->x,y=target->y,z=target->z; @@ -3250,7 +3291,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da { if (inflictor && (inflictor->type == MT_ORBINAUT || inflictor->type == MT_ORBINAUT_SHIELD || inflictor->type == MT_JAWZ || inflictor->type == MT_JAWZ_SHIELD || inflictor->type == MT_JAWZ_DUD - || inflictor->player)) + || inflictor->type == MT_SMK_THWOMP || inflictor->player)) { player->kartstuff[k_sneakertimer] = 0; K_SpinPlayer(player, source, 1, false); diff --git a/src/p_map.c b/src/p_map.c index 1d8a2daa..eba6ad8d 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -663,7 +663,38 @@ static boolean PIT_CheckThing(mobj_t *thing) } } - // SRB2kart 011617 - Colission code for kart items //{ + // SRB2kart 011617 - Colission[sic] code for kart items //{ + + if (thing->type == MT_SMK_ICEBLOCK) + { + // 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 + + if (!(tmthing->flags & MF_SOLID || tmthing->flags & MF_SHOOTABLE || tmthing->flags & MF_BOUNCE)) + return true; + + if (!(tmthing->health)) + return true; + + if (tmthing->type == MT_BANANA || tmthing->type == MT_BANANA_SHIELD + || tmthing->type == MT_EGGMANITEM || tmthing->type == MT_EGGMANITEM_SHIELD + || tmthing->type == MT_SSMINE || tmthing->type == MT_SSMINE_SHIELD + || tmthing->type == MT_ORBINAUT_SHIELD || tmthing->type == MT_JAWZ_SHIELD) + return false; + + if (thing->health) + P_KillMobj(thing, tmthing, tmthing); + + /*if (tmthing->player && (tmthing->player->kartstuff[k_invincibilitytimer] > 0 + || tmthing->player->kartstuff[k_growshrinktimer] > 0)) + return true;*/ + + K_KartBouncing(tmthing, thing, false, true); + return false; + } if (tmthing->type == MT_RANDOMITEM) return true; @@ -1539,6 +1570,106 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } + else if (thing->type == MT_BLUEROBRA_HEAD || thing->type == MT_BLUEROBRA_JOINT) + { + // 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 + + if (!thing->health) + return true; // dead + + if (tmthing->player->kartstuff[k_invincibilitytimer] > 0 + || tmthing->player->kartstuff[k_growshrinktimer] > 0) + { + if (thing->type == MT_BLUEROBRA_JOINT) + P_KillMobj(thing->target, tmthing, tmthing); + else + P_KillMobj(thing, tmthing, tmthing); + return true; + } + else + { + K_KartBouncing(tmthing, thing, false, true); + return false; + } + } + else if (thing->type == MT_SMK_PIPE) + { + // 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 + + if (!thing->health) + return true; // dead + + if (tmthing->player->kartstuff[k_invincibilitytimer] > 0 + || tmthing->player->kartstuff[k_growshrinktimer] > 0) + { + P_KillMobj(thing, tmthing, tmthing); + return true; // kill + } + + K_KartBouncing(tmthing, thing, false, true); + return false; + } + else if (thing->type == MT_SMK_THWOMP) + { + if (!thing->health) + return true; // dead + + if (!thwompsactive) + return true; // not active yet + + if ((tmthing->z < thing->z) && (thing->z >= thing->movefactor-(256<extravalue1 = 1; // purposely try to stomp on players early + //S_StartSound(thing, sfx_s1bb); + } + + // 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 + + // kill + if (tmthing->player->kartstuff[k_invincibilitytimer] > 0 + || tmthing->player->kartstuff[k_growshrinktimer] > 0) + { + P_KillMobj(thing, tmthing, tmthing); + return true; + } + + // continue to squish + if (tmthing->player->kartstuff[k_squishedtimer]) + { + tmthing->player->kartstuff[k_squishedtimer] = 2*TICRATE; + tmthing->player->powers[pw_flashing] = K_GetKartFlashing(tmthing->player); + return true; + } + + // no interaction + if (tmthing->player->powers[pw_flashing] > 0 || tmthing->player->kartstuff[k_hyudorotimer] > 0 + || tmthing->player->kartstuff[k_spinouttimer] > 0) //|| tmthing->player->kartstuff[k_squishedtimer] > 0 + return true; + + // collide + if (tmthing->z < thing->z && thing->momz < 0) + K_SquishPlayer(tmthing->player, thing); + else + { + if (thing->flags2 & MF2_AMBUSH) + P_DamageMobj(tmthing, thing, thing, 1); + K_KartBouncing(tmthing, thing, false, true); + } + + return false; + } else if (thing->flags & MF_SOLID) { // see if it went over / under @@ -1552,7 +1683,7 @@ static boolean PIT_CheckThing(mobj_t *thing) else K_KartBouncing(tmthing, thing, false, true); - return true; + return false; } // Are you touching the side of the object you're interacting with? else if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height diff --git a/src/p_mobj.c b/src/p_mobj.c index 5de7e246..91ba959a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1403,7 +1403,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) gravityadd >>= 1; break; case MT_BANANA: - case MT_FAKEITEM: + case MT_EGGMANITEM: case MT_SSMINE: gravityadd = FixedMul(gravityadd, 5*FRACUNIT/2); break; @@ -2345,7 +2345,7 @@ static boolean P_ZMovement(mobj_t *mo) case MT_SHELL: // SRB2kart stuff that should die in pits // Shouldn't stop moving along the Z if there's no speed though! - case MT_FAKEITEM: + case MT_EGGMANITEM: case MT_BANANA: case MT_ORBINAUT: case MT_JAWZ: @@ -6641,7 +6641,7 @@ void P_MobjThinker(mobj_t *mobj) case MT_JAWZ_SHIELD: case MT_BANANA_SHIELD: case MT_SSMINE_SHIELD: - case MT_FAKESHIELD: + case MT_EGGMANITEM_SHIELD: case MT_SINK_SHIELD: if ((mobj->health > 0 && (!mobj->target || !mobj->target->player || mobj->target->player->health <= 0 || mobj->target->player->spectator)) @@ -6838,7 +6838,8 @@ void P_MobjThinker(mobj_t *mobj) if (!mobj->tracer) { - mobj->tracer = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY); + mobj_t *overlay = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY); + P_SetTarget(&mobj->tracer, overlay); P_SetTarget(&mobj->tracer->target, mobj); P_SetMobjState(mobj->tracer, S_PLAYERARROW_ITEM); P_SetMobjState(mobj->tracer, S_ITEMICON); // null sprite and frame to be overwritten later @@ -7402,7 +7403,7 @@ void P_MobjThinker(mobj_t *mobj) //{ SRB2kart Items - Death States case MT_ORBINAUT: case MT_BANANA: - case MT_FAKEITEM: + case MT_EGGMANITEM: case MT_SPB: if (mobj->z <= mobj->floorz) { @@ -7412,7 +7413,7 @@ void P_MobjThinker(mobj_t *mobj) // fallthru case MT_ORBINAUT_SHIELD: case MT_BANANA_SHIELD: - case MT_FAKESHIELD: + case MT_EGGMANITEM_SHIELD: mobj->flags2 ^= MF2_DONTDRAW; break; case MT_JAWZ: @@ -7439,6 +7440,41 @@ void P_MobjThinker(mobj_t *mobj) case MT_MINEEXPLOSIONSOUND: P_RemoveMobj(mobj); return; + case MT_SMK_PIPE: + if (mobj->flags2 & MF2_AMBUSH) + P_SetMobjStateNF(mobj, mobj->info->seestate); + else + P_SetMobjStateNF(mobj, mobj->info->spawnstate); + /* FALLTHRU */ + case MT_SMK_MOLE: + mobj->flags2 ^= MF2_DONTDRAW; + if (mobj->z <= mobj->floorz) + { + P_RemoveMobj(mobj); + return; + } + break; + case MT_SMK_THWOMP: + if (mobj->flags2 & MF2_AMBUSH) + { + mobj->colorized = true; + mobj->color = (1 + (leveltime % (MAXSKINCOLORS-1))); + mobj->frame |= FF_FULLBRIGHT; + } + else + { + mobj->colorized = false; + mobj->color = SKINCOLOR_NONE; + mobj->frame &= (~FF_FULLBRIGHT); + } + + mobj->flags2 ^= MF2_DONTDRAW; + if (mobj->z <= mobj->floorz) + { + P_RemoveMobj(mobj); + return; + } + break; //} default: break; @@ -7881,50 +7917,6 @@ void P_MobjThinker(mobj_t *mobj) } break; //{ SRB2kart Items - case MT_POKEY: - if (mobj->threshold) - { - if (mobj->state == &states[S_POKEY1]) - mobj->health = 1; - else if (mobj->state == &states[S_POKEY2]) - mobj->health = 2; - else if (mobj->state == &states[S_POKEY3]) - mobj->health = 3; - else if (mobj->state == &states[S_POKEY4]) - mobj->health = 4; - else if (mobj->state == &states[S_POKEY5]) - mobj->health = 5; - else if (mobj->state == &states[S_POKEY6]) - mobj->health = 6; - else if (mobj->state == &states[S_POKEY7]) - mobj->health = 7; - else if (mobj->state == &states[S_POKEY8]) - mobj->health = 8; - - mobj->threshold++; - P_SetMobjState(mobj, S_POKEYIDLE); - } - if (mobj->state == &states[S_POKEYIDLE] && mobj->threshold >= 105) - { - if (mobj->health == 1) - P_SetMobjState(mobj, S_POKEY1); - else if (mobj->health == 2) - P_SetMobjState(mobj, S_POKEY2); - else if (mobj->health == 3) - P_SetMobjState(mobj, S_POKEY3); - else if (mobj->health == 4) - P_SetMobjState(mobj, S_POKEY4); - else if (mobj->health == 5) - P_SetMobjState(mobj, S_POKEY5); - else if (mobj->health == 6) - P_SetMobjState(mobj, S_POKEY6); - else if (mobj->health == 7) - P_SetMobjState(mobj, S_POKEY7); - else if (mobj->health == 8) - P_SetMobjState(mobj, S_POKEY8); - mobj->threshold = 0; - } - break; case MT_FLOATINGITEM: { if (mobj->flags & MF_NOCLIPTHING) @@ -8147,7 +8139,7 @@ void P_MobjThinker(mobj_t *mobj) break; } case MT_BANANA: - case MT_FAKEITEM: + case MT_EGGMANITEM: if (mobj->momx || mobj->momy) P_SpawnGhostMobj(mobj); if (mobj->z <= mobj->floorz && mobj->health > 1) @@ -8561,6 +8553,449 @@ void P_MobjThinker(mobj_t *mobj) } } break; + case MT_EZZPROPELLER: + if (mobj->hnext) + { + mobj_t *cur = mobj->hnext; + + while (cur && !P_MobjWasRemoved(cur)) + { + cur->angle += FixedAngle(mobj->info->speed); + P_TeleportMove(cur, mobj->x + FINECOSINE((cur->angle*8)>>ANGLETOFINESHIFT), + mobj->y + FINESINE((cur->angle*8)>>ANGLETOFINESHIFT), mobj->z); + //P_SpawnGhostMobj(cur)->tics = 2; + + cur = cur->hnext; + } + } + if (!S_SoundPlaying(mobj, mobj->info->seesound)) + S_StartSound(mobj, mobj->info->seesound); + break; + case MT_FROGGER: + { + statenum_t frogstate = (mobj->state-states); + + // FROG ATTACK VALUES: + // threshold: distance + // movecount: time + // lastlook: direction + // extravalue1: x step + // extravalue2: y step + // cusval: z step + + if (frogstate == S_FROGGER) + { + mobj->threshold = mobj->movecount = mobj->lastlook = 0; // clear tongue attack + mobj->extravalue1 = mobj->extravalue2 = mobj->cusval = 0; + if (mobj->hnext) // Clean hnext list + { + mobj_t *cur = mobj->hnext; + while (cur && !P_MobjWasRemoved(cur)) + { + mobj_t *next = cur->hnext; + P_RemoveMobj(cur); + cur = next; + } + } + + if (mobj->reactiontime) + mobj->reactiontime--; + else + { + if (mobj->flags2 & MF2_AMBUSH) + { + mobj->momz = P_RandomRange(12, 16)<x, mobj->y, mobj->z + (mobj->height/2), MT_FROGTONGUE); + P_SetTarget(&mobj->tracer, tongue); + P_SetMobjState(mobj, S_FROGGER_ATTACK); + } + } + } + else if (frogstate == S_FROGGER_ATTACK) + { + if (!mobj->tracer || P_MobjWasRemoved(mobj->tracer)) + { + mobj->reactiontime = mobj->info->reactiontime; + P_SetMobjState(mobj, S_FROGGER); + break; + } + + if (mobj->threshold == 0) + { + fixed_t targetz = mobj->tracer->z; //mobj->z + (mobj->height/2) + + mobj->threshold = 256; + mobj->movecount = 1; + mobj->lastlook = 1; + + mobj->tracer->angle = mobj->angle; + + mobj->extravalue1 = FixedMul(FixedMul((mobj->threshold/16)<>ANGLETOFINESHIFT)), + FINECOSINE(mobj->angle>>ANGLETOFINESHIFT)) >> FRACBITS; + + mobj->extravalue2 = FixedMul(FixedMul((mobj->threshold/16)<>ANGLETOFINESHIFT)), + FINESINE(mobj->angle>>ANGLETOFINESHIFT)) >> FRACBITS; + + mobj->cusval = FixedMul((mobj->threshold/16)<>ANGLETOFINESHIFT)) >> FRACBITS; + + S_StartSound(mobj, sfx_s3k8c); // Play that tongue-y sound. + } + + mobj->movecount += mobj->lastlook; + + if (!(P_TryMove(mobj->tracer, mobj->x + ((mobj->extravalue1<movecount), mobj->y + ((mobj->extravalue2<movecount), true)) + || (mobj->movecount >= 16) // maximum travel time + || (mobj->tracer->z <= mobj->tracer->floorz) // Through the floor + || ((mobj->tracer->z + mobj->tracer->height) >= mobj->tracer->ceilingz)) // Through the ceiling + { + mobj->lastlook = -1; // Reverse direction. + } + + if (mobj->movecount == 0) // It's back to its source, time to reset. + { + mobj->threshold = mobj->lastlook = 0; + + P_RemoveMobj(mobj->tracer); + + if (mobj->hnext) // Clean hnext list + { + mobj_t *cur = mobj->hnext; + while (cur && !P_MobjWasRemoved(cur)) + { + mobj_t *next = cur->hnext; + P_RemoveMobj(cur); + cur = next; + } + } + + mobj->reactiontime = mobj->info->reactiontime; + P_SetMobjState(mobj, S_FROGGER); + } + else + { + const UINT8 numjoints = 11; + UINT8 joint = numjoints; + mobj_t *cur = mobj->hnext, *prev = mobj; + + mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y); + + for (; joint > 0; joint--) + { + fixed_t wx = mobj->tracer->x + (joint * (mobj->x - mobj->tracer->x) / (numjoints+1)); + fixed_t wy = mobj->tracer->y + (joint * (mobj->y - mobj->tracer->y) / (numjoints+1)); + fixed_t wz = mobj->tracer->z + (joint * ((mobj->z + (mobj->height/2)) - mobj->tracer->z) / (numjoints+1)); + + if (cur && !P_MobjWasRemoved(cur)) + P_TeleportMove(cur, wx, wy, wz); + else + cur = P_SpawnMobj(wx, wy, wz, MT_FROGTONGUE_JOINT); + + P_SetTarget(&cur->target, mobj); + + P_SetTarget(&prev->hnext, cur); + P_SetTarget(&cur->hprev, prev); + + prev = cur; + cur = cur->hnext; + } + } + } + else if (frogstate == S_FROGGER_JUMP) + { + if (P_IsObjectOnGround(mobj)) + { + mobj->reactiontime = mobj->info->reactiontime; + P_SetMobjState(mobj, S_FROGGER); + } + } + } + break; + case MT_ROBRA: + case MT_BLUEROBRA: + if (mobj->health) + { + boolean blue = (mobj->type == MT_BLUEROBRA); + + if (blue) + { + if (mobj->spawnpoint) + mobj->extravalue2 = mobj->spawnpoint->angle; + else + mobj->extravalue2 = 128; + } + else + { + if (!mobj->extravalue2) + mobj->extravalue2 = P_RandomRange(64, 192); + } + + if (mobj->reactiontime) + mobj->reactiontime--; + else + { + if (!mobj->extravalue1) + { + mobj_t *head = P_SpawnMobj(mobj->x, mobj->y, mobj->z, (blue ? MT_BLUEROBRA_HEAD : MT_ROBRA_HEAD)); + P_SetTarget(&mobj->tracer, head); + + mobj->destscale = mapheaderinfo[gamemap-1]->mobj_scale; + P_SetTarget(&mobj->tracer->target, mobj->target); + P_SetTarget(&mobj->tracer->tracer, mobj); + mobj->tracer->extravalue2 = mobj->extravalue2; + + if (!blue) + mobj->tracer->angle = mobj->angle; + + mobj->extravalue1 = 1; + } + } + + if ((mobj->extravalue1) && !(mobj->tracer && !P_MobjWasRemoved(mobj->tracer))) + { + mobj->reactiontime = 20*mobj->info->reactiontime; + P_SetTarget(&mobj->target, NULL); + mobj->extravalue1 = 0; + } + + if ((mobj->tracer && !P_MobjWasRemoved(mobj->tracer)) && !(leveltime % 10)) + { + mobj_t *dust = P_SpawnMobj(mobj->x + (P_RandomRange(-4, 4)<y + (P_RandomRange(-4, 4)<z + (P_RandomRange(0, 2)<scale/2); + P_InstaThrust(dust, FixedAngle(P_RandomRange(0,359)<tracer->momz)/2); + + if (abs(mobj->tracer->momz) >= 2<health) + { + boolean blue = (mobj->type == MT_BLUEROBRA_HEAD); + UINT8 numsegs = abs(mobj->z - mobj->floorz) / (32 * mobj->scale); + UINT8 i; + mobj_t *cur = mobj->hnext, *prev = mobj; + + if (blue) + mobj->angle = (angle_t)mobj->extravalue1; + mobj->extravalue1 += (FixedAngle(2*mobj->momz) * (blue ? -1 : 1)); + + for (i = 0; i < numsegs*2; i++) // *2 to check for any extra segs still present + { + fixed_t segz = mobj->z - ((i+1) * (32 * mobj->scale)); + + if (cur && !P_MobjWasRemoved(cur)) + { + if (i >= numsegs) // Remove extras + { + mobj_t *next = cur->hnext; + P_RemoveMobj(cur); + cur = next; + continue; + } + else // Move into place + P_TeleportMove(cur, mobj->x, mobj->y, segz); + } + else + { + if (i >= numsegs) // We're done with this list + continue; //break; + else // Need another here! + cur = P_SpawnMobj(mobj->x, mobj->y, segz, (blue ? MT_BLUEROBRA_JOINT : MT_ROBRA_JOINT)); + } + + P_SetTarget(&cur->target, mobj); + P_SetScale(cur, (7*mobj->scale)/8); + + cur->angle = mobj->extravalue1; + mobj->extravalue1 += (FixedAngle(2*mobj->momz) * (blue ? -1 : 1)); + + P_SetTarget(&prev->hnext, cur); + P_SetTarget(&cur->hprev, prev); + + prev = cur; + cur = cur->hnext; + } + + { + //fixed_t ceilingheight = mobj->ceilingz - (72<floorz + (72<floorz + (mobj->extravalue2<z < targetheight) + { + mobj->momz += mobj->info->speed; + if ((mobj->z < floorheight) && (mobj->momz < 0)) + mobj->momz /= 2; + } + else + { + mobj->momz -= mobj->info->speed; + if ((mobj->z > (targetheight + (64<momz > 0)) + mobj->momz /= 2; + } + } + } + break; + case MT_ROBRA_JOINT: + case MT_BLUEROBRA_JOINT: + if (!mobj->target || P_MobjWasRemoved(mobj->target)) + { + P_RemoveMobj(mobj); + return; + } + break; + case MT_SMK_PIPE: + if (mobj->flags2 & MF2_AMBUSH) + P_SetMobjStateNF(mobj, mobj->info->seestate); + else + P_SetMobjStateNF(mobj, mobj->info->spawnstate); + break; + case MT_SMK_MOLESPAWNER: + if (!mobj->target || P_MobjWasRemoved(mobj->target)) + { + mobj_t *newmole = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SMK_MOLE); + P_SetTarget(&mobj->target, newmole); + return; + } + break; + case MT_SMK_MOLE: + if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player) + { + player_t *player = mobj->target->player; + + mobj->extravalue1 = 1; + player->kartstuff[k_offroad] += 2<mo->x + P_ReturnThrustX(NULL, player->mo->angle, player->mo->radius) + + P_ReturnThrustX(NULL, player->mo->angle+ANGLE_90, (mobj->threshold)<mo->y + P_ReturnThrustY(NULL, player->mo->angle, player->mo->radius) + + P_ReturnThrustY(NULL, player->mo->angle+ANGLE_90, (mobj->threshold)<mo->z + (player->mo->height/2 * P_MobjFlip(player->mo)) + + (P_RandomRange(-abs(mobj->threshold), abs(mobj->threshold))<threshold /= 2; + mobj->momz = 0; + + if (mobj->movecount > 8*TICRATE) + { + P_KillMobj(mobj, mobj->target, mobj->target); + break; + } + + if (abs(player->cmd.driftturn) > 100) + { + INT32 lastsign = 0; + if (mobj->lastlook > 0) + lastsign = 1; + else if (mobj->lastlook < 0) + lastsign = -1; + + if ((player->cmd.driftturn > 0 && lastsign < 0) + || (player->cmd.driftturn < 0 && lastsign > 0)) + { + mobj->movecount += (TICRATE/2); + mobj->threshold = 16*lastsign; + S_StartSound(mobj, sfx_s1ab); + } + + mobj->lastlook = player->cmd.driftturn; + } + + mobj->movecount++; + } + else if (mobj->extravalue1) // lost your player somehow, DIE + { + P_KillMobj(mobj, NULL, NULL); + break; + } + else + { + if (P_IsObjectOnGround(mobj)) + { + if (mobj->reactiontime) + mobj->reactiontime--; + else + { + mobj->momz = (mobj->info->speed * P_MobjFlip(mobj)); + mobj->reactiontime = mobj->info->reactiontime; + } + } + } + break; + case MT_SMK_THWOMP: + if (mobj->flags2 & MF2_AMBUSH) + { + mobj->colorized = true; + mobj->color = (1 + (leveltime % (MAXSKINCOLORS-1))); + mobj->frame |= FF_FULLBRIGHT; + } + else + { + mobj->colorized = false; + mobj->color = SKINCOLOR_NONE; + mobj->frame &= (~FF_FULLBRIGHT); + } + + if (!thwompsactive) + break; + + if (mobj->reactiontime) + mobj->reactiontime--; + else + { + if (mobj->extravalue1) + { + P_SpawnGhostMobj(mobj)->tics = 3; + + if (mobj->z == mobj->floorz) + { + UINT8 i; + + mobj->extravalue1 = 0; + mobj->reactiontime = mobj->info->reactiontime; + S_StartSound(mobj, sfx_s1bd); + + for (i = 0; i < 8; i++) + { + mobj_t *dust = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_DRIFTDUST); + P_InstaThrust(dust, FixedAngle(((360*FRACUNIT)/8) * i), mobj->info->speed/8); + dust->momz = P_MobjFlip(mobj) * (P_RandomRange(1,4)<scale = mobj->scale/2; + dust->destscale = mobj->scale*3; + } + } + else + mobj->momz = (-mobj->info->speed) * P_MobjFlip(mobj); + } + else + { + if (mobj->z > mobj->movefactor) + mobj->z = mobj->movefactor; + + if (mobj->z == mobj->movefactor) + { + mobj->extravalue1 = 1; + //S_StartSound(mobj, sfx_s1bb); + } + else + mobj->momz = (mobj->info->speed/16) * P_MobjFlip(mobj); + } + } + break; //} case MT_TURRET: P_MobjCheckWater(mobj); @@ -8855,6 +9290,31 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s return; case MT_PLAYER: break; // don't remove + case MT_SMK_ICEBLOCK: + { + mobj_t *cur = mobj->hnext, *next; + UINT8 i; + + for (i = 0; i < 5; i++) + { + mobj_t *debris = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SMK_ICEBLOCK_DEBRIS); + debris->angle = FixedAngle(P_RandomRange(0,360)<angle, P_RandomRange(3,18)*(FRACUNIT/4)); + debris->momz = P_RandomRange(4,8)<hnext; + P_RemoveMobj(cur); + cur = next; + } + + P_RemoveMobj(mobj); + return; + } default: P_SetMobjState(mobj, mobj->info->xdeathstate); // will remove the mobj if S_NULL. break; @@ -8862,7 +9322,7 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s if (P_MobjWasRemoved(mobj)) return; } - else if (((mobj->type == MT_RANDOMITEM && mobj->threshold == 69) || mobj->type == MT_FAKEITEM || mobj->type == MT_FALLINGROCK) && mobj->fuse <= TICRATE) + else if (((mobj->type == MT_RANDOMITEM && mobj->threshold == 69) || mobj->type == MT_EGGMANITEM || mobj->type == MT_FALLINGROCK) && mobj->fuse <= TICRATE) mobj->flags2 ^= MF2_DONTDRAW; } @@ -9363,7 +9823,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_BLUEBALL: nummaprings++; break; - case MT_KARMAHITBOX: // SRB2Kart + // SRB2Kart + case MT_KARMAHITBOX: { const fixed_t rad = FixedMul(mobjinfo[MT_PLAYER].radius, mobj->scale); mobj_t *cur, *prev = mobj; @@ -9430,6 +9891,103 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->color = SKINCOLOR_AQUA; break; } + case MT_PINETREE: + { + angle_t diff = FixedAngle((360/mobj->info->mass)*FRACUNIT); + UINT8 i; + + for (i = 0; i < mobj->info->mass; i++) + { + angle_t ang = i * diff; + mobj_t *side = P_SpawnMobj(mobj->x + FINECOSINE((ang>>ANGLETOFINESHIFT) & FINEMASK), + mobj->y + FINESINE((ang>>ANGLETOFINESHIFT) & FINEMASK), mobj->z, MT_PINETREE_SIDE); + side->angle = ang; + side->target = mobj; + side->threshold = i; + } + break; + } + case MT_EZZPROPELLER: + { + mobj_t *cur, *prev = mobj; + UINT8 i; + + for (i = 0; i < mobj->info->mass; i++) + { + mobj->angle = FixedAngle((i * (360/mobj->info->mass))<x + FINECOSINE(((mobj->angle*8)>>ANGLETOFINESHIFT) & FINEMASK), + mobj->y + FINESINE(((mobj->angle*8)>>ANGLETOFINESHIFT) & FINEMASK), mobj->z, MT_EZZPROPELLER_BLADE); + cur->angle = mobj->angle; + + P_SetTarget(&cur->hprev, prev); + P_SetTarget(&prev->hnext, cur); + + prev = cur; + } + break; + } + case MT_ROBRA: + case MT_BLUEROBRA: + P_SetScale(mobj, (mobj->destscale = 1)); + break; + case MT_ROBRA_HEAD: + { + mobj_t *shell; + + shell = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY); + P_SetTarget(&shell->target, mobj); + P_SetMobjState(shell, S_ROBRASHELL_INSIDE); + + shell = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY); + P_SetTarget(&shell->target, mobj); + P_SetMobjState(shell, S_ROBRASHELL_OUTSIDE); + } + break; + case MT_EERIEFOGGEN: + { + UINT16 i; + for (i = 0; i < mobj->info->mass; i++) + { + fixed_t newx = mobj->x + (P_RandomRange(-mobj->info->mass, mobj->info->mass)<y + (P_RandomRange(-mobj->info->mass, mobj->info->mass)<z, 8<z) + P_SpawnMobj(newx, newy, mobj->z, MT_EERIEFOG); + } + } + break; + case MT_SMK_MOLE: + mobj->reactiontime = P_RandomRange(0, 3*mobj->info->reactiontime/2); // Random delay on start of level + break; + case MT_SMK_THWOMP: + mobj->reactiontime = P_RandomRange(0, 3*mobj->info->reactiontime); // Random delay on start of level + if (mobj->z == mobj->floorz) + mobj->z += (256<movefactor = mobj->z + (256<flags2 |= MF2_STANDONME; + { + mobj_t *cur, *prev = mobj; + UINT8 i; + + for (i = 0; i < 4; i++) + { + cur = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SMK_ICEBLOCK_SIDE); + P_SetTarget(&cur->target, mobj); + cur->threshold = i; + P_TeleportMove(cur, cur->x + ((cur->radius>>FRACBITS) * FINECOSINE((FixedAngle((90*cur->threshold)<>ANGLETOFINESHIFT) & FINEMASK)), + cur->y + ((cur->radius>>FRACBITS) * FINESINE((FixedAngle((90*cur->threshold)<>ANGLETOFINESHIFT) & FINEMASK)), cur->z); + cur->angle = ANGLE_90*(cur->threshold+1); + + P_SetTarget(&cur->hprev, prev); + P_SetTarget(&prev->hnext, cur); + + prev = cur; + } + } + break; default: break; } @@ -9437,17 +9995,19 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) switch (mobj->type) { case MT_PLAYER: - case MT_BIGMACE: case MT_SMALLMACE: + case MT_SMALLMACE: case MT_BIGMACE: + case MT_PUMA: case MT_BIGPUMA: case MT_FALLINGROCK: + case MT_SMK_MOLE: case MT_SMK_THWOMP: //case MT_RANDOMITEM: case MT_FLOATINGITEM: case MT_BATTLEBUMPER: case MT_BANANA: case MT_BANANA_SHIELD: - //case MT_FAKEITEM: case MT_FAKESHIELD: + //case MT_EGGMANITEM: case MT_EGGMANSHIELD: case MT_ORBINAUT: case MT_ORBINAUT_SHIELD: - case MT_JAWZ: case MT_JAWZ_DUD: case MT_JAWZ_SHIELD: - case MT_SSMINE: case MT_SSMINE_SHIELD: - case MT_BALLHOG: case MT_SINK: + case MT_JAWZ: case MT_JAWZ_DUD: case MT_JAWZ_SHIELD: + case MT_SSMINE: case MT_SSMINE_SHIELD: + case MT_BALLHOG: case MT_SINK: case MT_THUNDERSHIELD: case MT_ROCKETSNEAKER: case MT_SPB: P_SpawnShadowMobj(mobj); @@ -11090,6 +11650,46 @@ ML_NOCLIMB : Direction not controllable case MT_TRAPGOYLELONG: if (mthing->angle >= 360) mobj->tics += 7*(mthing->angle / 360) + 1; // starting delay + break; + // SRB2Kart + case MT_AAZTREE_HELPER: + { + fixed_t top = mobj->z; + UINT8 numsegs = (mthing->extrainfo)+2; + UINT8 numleaves = max(3, (abs(mthing->angle+1) % 6) + 3); + UINT8 i; + mobj_t *coconut; + + // Spawn tree segments + for (i = 0; i < numsegs; i++) + { + P_SpawnMobj(mobj->x, mobj->y, top, MT_AAZTREE_SEG); + top += FixedMul(mobjinfo[MT_AAZTREE_SEG].height, mobj->scale); + } + + // Big coconut topper + coconut = P_SpawnMobj(mobj->x, mobj->y, top - (8<destscale = (2*mobj->scale))); + + // Spawn all of the papersprite leaves + for (i = 0; i < numleaves; i++) + { + mobj_t *leaf; + + mobj->angle = FixedAngle((i * (360/numleaves))<x + FINECOSINE((mobj->angle>>ANGLETOFINESHIFT) & FINEMASK), + mobj->y + FINESINE((mobj->angle>>ANGLETOFINESHIFT) & FINEMASK), top, MT_AAZTREE_LEAF); + leaf->angle = mobj->angle; + + // Small coconut for each leaf + P_SpawnMobj(mobj->x + (32 * FINECOSINE((mobj->angle>>ANGLETOFINESHIFT) & FINEMASK)), + mobj->y + (32 * FINESINE((mobj->angle>>ANGLETOFINESHIFT) & FINEMASK)), top - (24<starpostnum) { diff --git a/src/p_user.c b/src/p_user.c index 0f89f826..a286202a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7695,7 +7695,7 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) if (mo->type == MT_ORBINAUT || mo->type == MT_JAWZ || mo->type == MT_JAWZ_DUD || mo->type == MT_ORBINAUT_SHIELD || mo->type == MT_JAWZ_SHIELD || mo->type == MT_BANANA || mo->type == MT_BANANA_SHIELD - || mo->type == MT_FAKEITEM || mo->type == MT_FAKESHIELD + || mo->type == MT_EGGMANITEM || mo->type == MT_EGGMANITEM_SHIELD || mo->type == MT_BALLHOG || mo->type == MT_SPB) { if (mo->eflags & MFE_VERTICALFLIP)