diff --git a/src/dehacked.c b/src/dehacked.c index 814f7d65a..3a40b64a5 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1783,7 +1783,6 @@ static actionpointer_t actionpointers[] = {{A_CapeChase}, "A_CAPECHASE"}, {{A_RotateSpikeBall}, "A_ROTATESPIKEBALL"}, {{A_SlingAppear}, "A_SLINGAPPEAR"}, - {{A_MaceRotate}, "A_MACEROTATE"}, {{A_UnidusBall}, "A_UNIDUSBALL"}, {{A_RockSpawn}, "A_ROCKSPAWN"}, {{A_SetFuse}, "A_SETFUSE"}, @@ -4958,18 +4957,62 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_SLING1", "S_SLING2", - // CEZ Small Mace Chain + // CEZ maces and chains "S_SMALLMACECHAIN", - - // CEZ Big Mace Chain "S_BIGMACECHAIN", - - // CEZ Small Mace "S_SMALLMACE", - - // CEZ Big Mace "S_BIGMACE", + // Yellow spring on a ball + "S_YELLOWSPRINGBALL", + "S_YELLOWSPRINGBALL2", + "S_YELLOWSPRINGBALL3", + "S_YELLOWSPRINGBALL4", + "S_YELLOWSPRINGBALL5", + + // Red spring on a ball + "S_REDSPRINGBALL", + "S_REDSPRINGBALL2", + "S_REDSPRINGBALL3", + "S_REDSPRINGBALL4", + "S_REDSPRINGBALL5", + + // Small Firebar + "S_SMALLFIREBAR1", + "S_SMALLFIREBAR2", + "S_SMALLFIREBAR3", + "S_SMALLFIREBAR4", + "S_SMALLFIREBAR5", + "S_SMALLFIREBAR6", + "S_SMALLFIREBAR7", + "S_SMALLFIREBAR8", + "S_SMALLFIREBAR9", + "S_SMALLFIREBAR10", + "S_SMALLFIREBAR11", + "S_SMALLFIREBAR12", + "S_SMALLFIREBAR13", + "S_SMALLFIREBAR14", + "S_SMALLFIREBAR15", + "S_SMALLFIREBAR16", + + // Big Firebar + "S_BIGFIREBAR1", + "S_BIGFIREBAR2", + "S_BIGFIREBAR3", + "S_BIGFIREBAR4", + "S_BIGFIREBAR5", + "S_BIGFIREBAR6", + "S_BIGFIREBAR7", + "S_BIGFIREBAR8", + "S_BIGFIREBAR9", + "S_BIGFIREBAR10", + "S_BIGFIREBAR11", + "S_BIGFIREBAR12", + "S_BIGFIREBAR13", + "S_BIGFIREBAR14", + "S_BIGFIREBAR15", + "S_BIGFIREBAR16", + "S_CEZFLOWER1", // Big Tumbleweed @@ -6304,14 +6347,20 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_FLAMEPARTICLE", "MT_EGGSTATUE", // Eggman Statue "MT_MACEPOINT", // Mace rotation point - "MT_SWINGMACEPOINT", // Mace swinging point - "MT_HANGMACEPOINT", // Hangable mace chain - "MT_SPINMACEPOINT", // Spin/Controllable mace chain + "MT_CHAINMACEPOINT", // Combination of chains and maces point + "MT_SPRINGBALLPOINT", // Spring ball point + "MT_CHAINPOINT", // Mace chain "MT_HIDDEN_SLING", // Spin mace chain (activatable) + "MT_FIREBARPOINT", // Firebar + "MT_CUSTOMMACEPOINT", // Custom mace "MT_SMALLMACECHAIN", // Small Mace Chain "MT_BIGMACECHAIN", // Big Mace Chain "MT_SMALLMACE", // Small Mace "MT_BIGMACE", // Big Mace + "MT_YELLOWSPRINGBALL", // Yellow spring on a ball + "MT_REDSPRINGBALL", // Red spring on a ball + "MT_SMALLFIREBAR", // Small Firebar + "MT_BIGFIREBAR", // Big Firebar "MT_CEZFLOWER", // Arid Canyon Scenery @@ -6664,6 +6713,7 @@ static const char *const MOBJFLAG2_LIST[] = { "AMBUSH", // Alternate behaviour typically set by MTF_AMBUSH "LINKDRAW", // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position) "SHIELD", // Thinker calls P_AddShield/P_ShieldLook (must be partnered with MF_SCENERY to use) + "MACEROTATE", // Thinker calls P_MaceRotate around tracer NULL }; diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index cf9b1c536..267666749 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -323,6 +323,10 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_BMCH &lspr[NOLIGHT], // SPR_SMCE &lspr[NOLIGHT], // SPR_BMCE + &lspr[NOLIGHT], // SPR_YSPB + &lspr[NOLIGHT], // SPR_RSPB + &lspr[REDBALL_L], // SPR_SFBR + &lspr[REDBALL_L], // SPR_BFBR // Arid Canyon Scenery &lspr[NOLIGHT], // SPR_BTBL diff --git a/src/info.c b/src/info.c index 90bd817f4..1f5b394ab 100644 --- a/src/info.c +++ b/src/info.c @@ -211,6 +211,10 @@ char sprnames[NUMSPRITES + 1][5] = "BMCH", // Big Mace Chain "SMCE", // Small Mace "BMCE", // Big Mace + "YSPB", // Yellow spring on a ball + "RSPB", // Red spring on a ball + "SFBR", // Small Firebar + "BFBR", // Big Firebar // Arid Canyon Scenery "BTBL", // Big tumbleweed @@ -1830,13 +1834,13 @@ state_t states[NUMSTATES] = {SPR_CHAN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CEZCHAIN // Flame - {SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20, 3, {A_FlameParticle}, 3, 0, S_FLAME2}, // S_FLAME1 - {SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|1, 3, {NULL}, 0, 0, S_FLAME3}, // S_FLAME2 - {SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|2, 3, {A_FlameParticle}, 3, 0, S_FLAME4}, // S_FLAME3 - {SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|3, 3, {NULL}, 0, 0, S_FLAME5}, // S_FLAME4 - {SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|4, 3, {A_FlameParticle}, 3, 0, S_FLAME6}, // S_FLAME5 - {SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|5, 3, {NULL}, 0, 0, S_FLAME1}, // S_FLAME6 - {SPR_FLAM, FF_FULLBRIGHT|FF_TRANS10|6, 24, {NULL}, 0, 0, S_NULL}, // S_FLAMEPARTICLE + {SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20, 3, {A_FlameParticle}, 3, FRACUNIT/2, S_FLAME2}, // S_FLAME1 + {SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|1, 3, {NULL}, 0, 0 , S_FLAME3}, // S_FLAME2 + {SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|2, 3, {A_FlameParticle}, 3, FRACUNIT/2, S_FLAME4}, // S_FLAME3 + {SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|3, 3, {NULL}, 0, 0 , S_FLAME5}, // S_FLAME4 + {SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|4, 3, {A_FlameParticle}, 3, FRACUNIT/2, S_FLAME6}, // S_FLAME5 + {SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|5, 3, {NULL}, 0, 0 , S_FLAME1}, // S_FLAME6 + {SPR_FLAM, FF_FULLBRIGHT|FF_TRANS10|6, 24, {NULL}, 0, 0 , S_NULL}, // S_FLAMEPARTICLE {SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|FF_ANIMATE, -1, {NULL}, 5, 3, S_FLAME2}, // S_FLAMEREST @@ -1847,31 +1851,75 @@ state_t states[NUMSTATES] = {SPR_NULL, 0, -1, {NULL}, 0, 0, S_SLING2}, // S_SLING1 {SPR_NULL, 0, -1, {A_SlingAppear}, 0, 0, S_NULL}, // S_SLING2 - // Small Mace Chain - {SPR_SMCH, 0, 1, {A_MaceRotate}, 0, 0, S_SMALLMACECHAIN}, // S_SMALLMACECHAIN + // CEZ maces and chains + {SPR_SMCH, 0, -1, {NULL}, 0, 0, S_SMALLMACECHAIN}, // S_SMALLMACECHAIN + {SPR_BMCH, 0, -1, {NULL}, 0, 0, S_BIGMACECHAIN}, // S_BIGMACECHAIN + {SPR_SMCE, 0, -1, {NULL}, 0, 0, S_SMALLMACE}, // S_SMALLMACE + {SPR_BMCE, 0, -1, {NULL}, 0, 0, S_BIGMACE}, // S_BIGMACE - // Big Mace Chain - {SPR_BMCH, 0, 1, {A_MaceRotate}, 0, 0, S_BIGMACECHAIN}, // S_BIGMACECHAIN + // Yellow spring on a ball + {SPR_YSPB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_YELLOWSPRINGBALL + {SPR_YSPB, 4, 4, {A_Pain}, 0, 0, S_YELLOWSPRINGBALL3}, // S_YELLOWSPRINGBALL2 + {SPR_YSPB, 3, 1, {NULL}, 0, 0, S_YELLOWSPRINGBALL4}, // S_YELLOWSPRINGBALL3 + {SPR_YSPB, 2, 1, {NULL}, 0, 0, S_YELLOWSPRINGBALL5}, // S_YELLOWSPRINGBALL4 + {SPR_YSPB, 1, 1, {NULL}, 0, 0, S_YELLOWSPRINGBALL}, // S_YELLOWSPRINGBALL5 - // Small Mace - {SPR_SMCE, 0, 1, {A_MaceRotate}, 0, 0, S_SMALLMACE}, // S_SMALLMACE + // Red spring on a ball + {SPR_RSPB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_REDSPRINGBALL + {SPR_RSPB, 4, 4, {A_Pain}, 0, 0, S_REDSPRINGBALL3}, // S_REDSPRINGBALL2 + {SPR_RSPB, 3, 1, {NULL}, 0, 0, S_REDSPRINGBALL4}, // S_REDSPRINGBALL3 + {SPR_RSPB, 2, 1, {NULL}, 0, 0, S_REDSPRINGBALL5}, // S_REDSPRINGBALL4 + {SPR_RSPB, 1, 1, {NULL}, 0, 0, S_REDSPRINGBALL}, // S_REDSPRINGBALL5 - // Big Mace - {SPR_BMCE, 0, 1, {A_MaceRotate}, 0, 0, S_BIGMACE}, // S_BIGMACE + // Small Firebar + {SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20, 1, {A_FlameParticle}, 3, FRACUNIT/3, S_SMALLFIREBAR2}, // S_SMALLFIREBAR1 + {SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20| 1, 1, {NULL}, 0, 0, S_SMALLFIREBAR3}, // S_SMALLFIREBAR2 + {SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20| 2, 1, {A_FlameParticle}, 3, FRACUNIT/3, S_SMALLFIREBAR4}, // S_SMALLFIREBAR3 + {SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20| 3, 1, {NULL}, 0, 0, S_SMALLFIREBAR5}, // S_SMALLFIREBAR4 + {SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20| 4, 1, {A_FlameParticle}, 3, FRACUNIT/3, S_SMALLFIREBAR6}, // S_SMALLFIREBAR5 + {SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20| 5, 1, {NULL}, 0, 0, S_SMALLFIREBAR7}, // S_SMALLFIREBAR6 + {SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20| 6, 1, {A_FlameParticle}, 3, FRACUNIT/3, S_SMALLFIREBAR8}, // S_SMALLFIREBAR7 + {SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20| 7, 1, {NULL}, 0, 0, S_SMALLFIREBAR9}, // S_SMALLFIREBAR8 + {SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20| 8, 1, {A_FlameParticle}, 3, FRACUNIT/3, S_SMALLFIREBAR10}, // S_SMALLFIREBAR9 + {SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20| 9, 1, {NULL}, 0, 0, S_SMALLFIREBAR11}, // S_SMALLFIREBAR10 + {SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20|10, 1, {A_FlameParticle}, 3, FRACUNIT/3, S_SMALLFIREBAR12}, // S_SMALLFIREBAR11 + {SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20|11, 1, {NULL}, 0, 0, S_SMALLFIREBAR13}, // S_SMALLFIREBAR12 + {SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20|12, 1, {A_FlameParticle}, 3, FRACUNIT/3, S_SMALLFIREBAR14}, // S_SMALLFIREBAR13 + {SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20|13, 1, {NULL}, 0, 0, S_SMALLFIREBAR15}, // S_SMALLFIREBAR14 + {SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20|14, 1, {A_FlameParticle}, 3, FRACUNIT/3, S_SMALLFIREBAR16}, // S_SMALLFIREBAR15 + {SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20|15, 1, {NULL}, 0, 0, S_SMALLFIREBAR1}, // S_SMALLFIREBAR16 + + // Big Firebar + {SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20, 1, {A_FlameParticle}, 3, FRACUNIT/2, S_BIGFIREBAR2}, // S_BIGFIREBAR1 + {SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20| 1, 1, {NULL}, 0, 0, S_BIGFIREBAR3}, // S_BIGFIREBAR2 + {SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20| 2, 1, {A_FlameParticle}, 3, FRACUNIT/2, S_BIGFIREBAR4}, // S_BIGFIREBAR3 + {SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20| 3, 1, {NULL}, 0, 0, S_BIGFIREBAR5}, // S_BIGFIREBAR4 + {SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20| 4, 1, {A_FlameParticle}, 3, FRACUNIT/2, S_BIGFIREBAR6}, // S_BIGFIREBAR5 + {SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20| 5, 1, {NULL}, 0, 0, S_BIGFIREBAR7}, // S_BIGFIREBAR6 + {SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20| 6, 1, {A_FlameParticle}, 3, FRACUNIT/2, S_BIGFIREBAR8}, // S_BIGFIREBAR7 + {SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20| 7, 1, {NULL}, 0, 0, S_BIGFIREBAR9}, // S_BIGFIREBAR8 + {SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20| 8, 1, {A_FlameParticle}, 3, FRACUNIT/2, S_BIGFIREBAR10}, // S_BIGFIREBAR9 + {SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20| 9, 1, {NULL}, 0, 0, S_BIGFIREBAR11}, // S_BIGFIREBAR10 + {SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20|10, 1, {A_FlameParticle}, 3, FRACUNIT/2, S_BIGFIREBAR12}, // S_BIGFIREBAR11 + {SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20|11, 1, {NULL}, 0, 0, S_BIGFIREBAR13}, // S_BIGFIREBAR12 + {SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20|12, 1, {A_FlameParticle}, 3, FRACUNIT/2, S_BIGFIREBAR14}, // S_BIGFIREBAR13 + {SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20|13, 1, {NULL}, 0, 0, S_BIGFIREBAR15}, // S_BIGFIREBAR14 + {SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20|14, 1, {A_FlameParticle}, 3, FRACUNIT/2, S_BIGFIREBAR16}, // S_BIGFIREBAR15 + {SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20|15, 1, {NULL}, 0, 0, S_BIGFIREBAR1}, // S_BIGFIREBAR16 // CEZ Flower {SPR_FWR4, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CEZFLOWER1 // Big Tumbleweed - {SPR_BTBL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BIGTUMBLEWEED - {SPR_BTBL, 0, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL2}, // S_BIGTUMBLEWEED_ROLL1 - {SPR_BTBL, 1, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL3}, // S_BIGTUMBLEWEED_ROLL2 - {SPR_BTBL, 2, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL4}, // S_BIGTUMBLEWEED_ROLL3 - {SPR_BTBL, 3, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL5}, // S_BIGTUMBLEWEED_ROLL4 - {SPR_BTBL, 4, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL6}, // S_BIGTUMBLEWEED_ROLL5 - {SPR_BTBL, 5, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL7}, // S_BIGTUMBLEWEED_ROLL6 - {SPR_BTBL, 6, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL8}, // S_BIGTUMBLEWEED_ROLL7 - {SPR_BTBL, 7, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL1}, // S_BIGTUMBLEWEED_ROLL8 + {SPR_BTBL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BIGTUMBLEWEED + {SPR_BTBL, 0, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL2}, // S_BIGTUMBLEWEED_ROLL1 + {SPR_BTBL, 1, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL3}, // S_BIGTUMBLEWEED_ROLL2 + {SPR_BTBL, 2, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL4}, // S_BIGTUMBLEWEED_ROLL3 + {SPR_BTBL, 3, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL5}, // S_BIGTUMBLEWEED_ROLL4 + {SPR_BTBL, 4, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL6}, // S_BIGTUMBLEWEED_ROLL5 + {SPR_BTBL, 5, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL7}, // S_BIGTUMBLEWEED_ROLL6 + {SPR_BTBL, 6, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL8}, // S_BIGTUMBLEWEED_ROLL7 + {SPR_BTBL, 7, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL1}, // S_BIGTUMBLEWEED_ROLL8 // Little Tumbleweed {SPR_STBL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_LITTLETUMBLEWEED @@ -8822,7 +8870,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_SWINGMACEPOINT + { // MT_CHAINMACEPOINT 1105, // doomednum S_INVISIBLE, // spawnstate 1000, // spawnhealth @@ -8849,7 +8897,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_HANGMACEPOINT + { // MT_SPRINGBALLPOINT 1106, // doomednum S_INVISIBLE, // spawnstate 1000, // spawnhealth @@ -8876,7 +8924,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_SPINMACEPOINT + { // MT_CHAINPOINT 1107, // doomednum S_INVISIBLE, // spawnstate 1000, // spawnhealth @@ -8896,7 +8944,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 128*FRACUNIT, // radius 1*FRACUNIT, // height 0, // display offset - 200, // mass + 10000, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags @@ -8930,6 +8978,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_FIREBARPOINT + 1109, // doomednum + S_INVISIBLE, // spawnstate + 1000, // 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 + 10*FRACUNIT, // speed + 128*FRACUNIT, // radius + 1*FRACUNIT, // height + 0, // display offset + 200, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_CUSTOMMACEPOINT + 1111, // doomednum + S_INVISIBLE, // spawnstate + 1000, // 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 + 10*FRACUNIT, // speed + 128*FRACUNIT, // radius + 1*FRACUNIT, // height + 0, // display offset + 200, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + { // MT_SMALLMACECHAIN -1, // doomednum S_SMALLMACECHAIN, // spawnstate @@ -8953,7 +9055,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 1, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL|MF_NOCLIPHEIGHT, // flags + MF_SCENERY|MF_SPECIAL|MF_NOGRAVITY, // flags S_NULL // raisestate }, @@ -8980,7 +9082,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 1, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL|MF_NOCLIPHEIGHT, // flags + MF_SCENERY|MF_SPECIAL|MF_NOGRAVITY, // flags S_NULL // raisestate }, @@ -9003,11 +9105,11 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // speed 17*FRACUNIT, // radius 34*FRACUNIT, // height - 0, // display offset + 1, // display offset 100, // mass 1, // damage sfx_mswing, // activesound - MF_PAIN|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_SCENERY|MF_PAIN|MF_NOGRAVITY, // flags S_NULL // raisestate }, @@ -9030,11 +9132,119 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 48*FRACUNIT, // speed 34*FRACUNIT, // radius 68*FRACUNIT, // height - 0, // display offset + 1, // display offset 100, // mass 1, // damage sfx_mswing, // activesound - MF_PAIN|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_SCENERY|MF_PAIN|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_YELLOWSPRINGBALL + -1, // doomednum + S_YELLOWSPRINGBALL, // spawnstate + 1000, // spawnhealth + S_YELLOWSPRINGBALL2, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_spring, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 24*FRACUNIT, // speed + 17*FRACUNIT, // radius + 34*FRACUNIT, // height + 1, // display offset + 20*FRACUNIT, // mass + 0, // damage + sfx_mswing, // activesound + MF_SCENERY|MF_SOLID|MF_SPRING|MF_NOGRAVITY, // flags + S_YELLOWSPRINGBALL2 // raisestate + }, + + { // MT_REDSPRINGBALL + -1, // doomednum + S_REDSPRINGBALL, // spawnstate + 1000, // spawnhealth + S_REDSPRINGBALL2, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_spring, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 24*FRACUNIT, // speed + 17*FRACUNIT, // radius + 34*FRACUNIT, // height + 1, // display offset + 32*FRACUNIT, // mass + 0, // damage + sfx_mswing, // activesound + MF_SCENERY|MF_SOLID|MF_SPRING|MF_NOGRAVITY, // flags + S_REDSPRINGBALL2 // raisestate + }, + + { // MT_SMALLFIREBAR + -1, // doomednum + S_SMALLFIREBAR1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + MT_FLAMEPARTICLE, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 24*FRACUNIT, // speed + 17*FRACUNIT, // radius + 34*FRACUNIT, // height + 0, // display offset + 100, // mass + 1, // damage + sfx_None, // activesound + MF_SCENERY|MF_PAIN|MF_FIRE|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_BIGFIREBAR + -1, // doomednum + S_BIGFIREBAR1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + MT_FLAMEPARTICLE, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 48*FRACUNIT, // speed + 34*FRACUNIT, // radius + 68*FRACUNIT, // height + 1, // display offset + 100, // mass + 1, // damage + sfx_None, // activesound + MF_SCENERY|MF_PAIN|MF_FIRE|MF_NOGRAVITY, // flags S_NULL // raisestate }, diff --git a/src/info.h b/src/info.h index 540c2853b..63a4d893f 100644 --- a/src/info.h +++ b/src/info.h @@ -84,7 +84,6 @@ void A_DetonChase(); // Deton Chaser void A_CapeChase(); // Fake little Super Sonic cape void A_RotateSpikeBall(); // Spike ball rotation void A_SlingAppear(); -void A_MaceRotate(); void A_UnidusBall(); void A_RockSpawn(); void A_SetFuse(); @@ -417,6 +416,10 @@ typedef enum sprite SPR_BMCH, // Big Mace Chain SPR_SMCE, // Small Mace SPR_BMCE, // Big Mace + SPR_YSPB, // Yellow spring on a ball + SPR_RSPB, // Red spring on a ball + SPR_SFBR, // Small Firebar + SPR_BFBR, // Big Firebar // Arid Canyon Scenery SPR_BTBL, // Big tumbleweed @@ -2056,18 +2059,62 @@ typedef enum state S_SLING1, S_SLING2, - // CEZ Small Mace Chain + // CEZ maces and chains S_SMALLMACECHAIN, - - // CEZ Big Mace Chain S_BIGMACECHAIN, - - // CEZ Small Mace S_SMALLMACE, - - // CEZ Big Mace S_BIGMACE, + // Yellow spring on a ball + S_YELLOWSPRINGBALL, + S_YELLOWSPRINGBALL2, + S_YELLOWSPRINGBALL3, + S_YELLOWSPRINGBALL4, + S_YELLOWSPRINGBALL5, + + // Red spring on a ball + S_REDSPRINGBALL, + S_REDSPRINGBALL2, + S_REDSPRINGBALL3, + S_REDSPRINGBALL4, + S_REDSPRINGBALL5, + + // Small Firebar + S_SMALLFIREBAR1, + S_SMALLFIREBAR2, + S_SMALLFIREBAR3, + S_SMALLFIREBAR4, + S_SMALLFIREBAR5, + S_SMALLFIREBAR6, + S_SMALLFIREBAR7, + S_SMALLFIREBAR8, + S_SMALLFIREBAR9, + S_SMALLFIREBAR10, + S_SMALLFIREBAR11, + S_SMALLFIREBAR12, + S_SMALLFIREBAR13, + S_SMALLFIREBAR14, + S_SMALLFIREBAR15, + S_SMALLFIREBAR16, + + // Big Firebar + S_BIGFIREBAR1, + S_BIGFIREBAR2, + S_BIGFIREBAR3, + S_BIGFIREBAR4, + S_BIGFIREBAR5, + S_BIGFIREBAR6, + S_BIGFIREBAR7, + S_BIGFIREBAR8, + S_BIGFIREBAR9, + S_BIGFIREBAR10, + S_BIGFIREBAR11, + S_BIGFIREBAR12, + S_BIGFIREBAR13, + S_BIGFIREBAR14, + S_BIGFIREBAR15, + S_BIGFIREBAR16, + S_CEZFLOWER1, // Big Tumbleweed @@ -3421,14 +3468,20 @@ typedef enum mobj_type MT_FLAMEPARTICLE, MT_EGGSTATUE, // Eggman Statue MT_MACEPOINT, // Mace rotation point - MT_SWINGMACEPOINT, // Mace swinging point - MT_HANGMACEPOINT, // Hangable mace chain - MT_SPINMACEPOINT, // Spin/Controllable mace chain + MT_CHAINMACEPOINT, // Combination of chains and maces point + MT_SPRINGBALLPOINT, // Spring ball point + MT_CHAINPOINT, // Mace chain MT_HIDDEN_SLING, // Spin mace chain (activatable) + MT_FIREBARPOINT, // Firebar + MT_CUSTOMMACEPOINT, // Custom mace MT_SMALLMACECHAIN, // Small Mace Chain MT_BIGMACECHAIN, // Big Mace Chain MT_SMALLMACE, // Small Mace MT_BIGMACE, // Big Mace + MT_YELLOWSPRINGBALL, // Yellow spring on a ball + MT_REDSPRINGBALL, // Red spring on a ball + MT_SMALLFIREBAR, // Small Firebar + MT_BIGFIREBAR, // Big Firebar MT_CEZFLOWER, // Arid Canyon Scenery diff --git a/src/p_enemy.c b/src/p_enemy.c index 08c6eb306..c9a173616 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -137,7 +137,6 @@ void A_DetonChase(mobj_t *actor); void A_CapeChase(mobj_t *actor); void A_RotateSpikeBall(mobj_t *actor); void A_SlingAppear(mobj_t *actor); -void A_MaceRotate(mobj_t *actor); void A_UnidusBall(mobj_t *actor); void A_RockSpawn(mobj_t *actor); void A_SetFuse(mobj_t *actor); @@ -5145,15 +5144,12 @@ void A_SlingAppear(mobj_t *actor) actor->movefactor = actor->threshold; actor->friction = 128; - actor->flags |= MF_SLIDEME; - while (mlength > 0) { spawnee = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SMALLMACECHAIN); P_SetTarget(&spawnee->target, actor); - spawnee->movecount = 0; spawnee->threshold = 0; spawnee->reactiontime = mlength; @@ -5168,129 +5164,6 @@ void A_SlingAppear(mobj_t *actor) } } -// -// Function: A_MaceRotate -// -// Spins an object around its target, or, swings it from side to side. -// -// var1 = unused -// var2 = unused -// -// So NOBODY forgets: -// actor-> -// threshold - X tilt -// movecount - Z tilt -// reactiontime - link # in the chain (1 is closest) -// lastlook - speed -// friction - top speed -// movedir - current angle holder -// extravalue1 - smoothly move link into place -// -void A_MaceRotate(mobj_t *actor) -{ - TVector v; - TVector *res; - fixed_t radius; -#ifdef HAVE_BLUA - if (LUA_CallAction("A_MaceRotate", actor)) - return; -#endif - - // Target was removed. - if (!actor->target) - { - P_RemoveMobj(actor); - return; - } - - P_UnsetThingPosition(actor); - - // Radius of the link's rotation. - radius = FixedMul(actor->info->speed * actor->reactiontime, actor->target->scale); - - // Double the radius if the chain links are made up of maces. - if (actor->target->type == MT_AXIS && (actor->type == MT_SMALLMACE || actor->type == MT_BIGMACE)) - radius *= 2; - - // Axis offset for the axis. - radius += actor->target->extravalue1; - - // Smoothly move the link into position. - if (actor->extravalue1) - { - radius = FixedMul(radius, FixedDiv(actor->extravalue1, 100)); - actor->extravalue1 += 1; - if (actor->extravalue1 >= 100) - actor->extravalue1 = 0; - } - - actor->x = actor->target->x; - actor->y = actor->target->y; - actor->z = actor->target->z; - - // Cut the height to align the link with the axis. - if (actor->type == MT_SMALLMACECHAIN || actor->type == MT_BIGMACECHAIN) - actor->z -= actor->height/4; - else - actor->z -= actor->height/2; - - // Set the top speed for the link if it happens to be over that speed. - if (actor->target->lastlook > actor->target->friction) - actor->target->lastlook = actor->target->friction; - - // Swinging Chain. - if (actor->target->type == MT_HANGMACEPOINT || actor->target->type == MT_SWINGMACEPOINT) - { - actor->movecount += actor->target->lastlook; - actor->movecount &= FINEMASK; - - actor->threshold = FixedMul(FINECOSINE(actor->movecount), actor->target->lastlook << FRACBITS); - - v[0] = FRACUNIT; - v[1] = 0; - v[2] = -radius; - v[3] = FRACUNIT; - - // Calculate the angle matrixes for the link. - res = VectorMatrixMultiply(v, *RotateXMatrix(FixedAngle(actor->threshold))); - M_Memcpy(&v, res, sizeof(v)); - res = VectorMatrixMultiply(v, *RotateZMatrix(actor->target->health << ANGLETOFINESHIFT)); - M_Memcpy(&v, res, sizeof(v)); - } - // Rotating Chain. - else - { - angle_t fa; - - actor->threshold += actor->target->lastlook; - actor->threshold &= FINEMASK; - actor->target->health &= FINEMASK; - - fa = actor->threshold; - v[0] = FixedMul(FINECOSINE(fa), radius); - v[1] = 0; - v[2] = FixedMul(FINESINE(fa), radius); - v[3] = FRACUNIT; - - // Calculate the angle matrixes for the link. - res = VectorMatrixMultiply(v, *RotateXMatrix(actor->target->threshold << ANGLETOFINESHIFT)); - M_Memcpy(&v, res, sizeof(v)); - res = VectorMatrixMultiply(v, *RotateZMatrix(actor->target->health << ANGLETOFINESHIFT)); - M_Memcpy(&v, res, sizeof(v)); - } - - // Add on the appropriate distances to the actor's co-ordinates. - actor->x += v[0]; - actor->y += v[1]; - actor->z += v[2]; - - P_SetThingPosition(actor); - - if (!(actor->target->flags2 & MF2_BOSSNOTRAP) // flag that makes maces shut up on request - && !(leveltime & 63) && (actor->type == MT_BIGMACE || actor->type == MT_SMALLMACE) && actor->target->type == MT_MACEPOINT) - S_StartSound(actor, actor->info->activesound); -} - // Function: A_SetFuse // // Description: Sets the actor's fuse timer if not set already. May also change state when fuse reaches the last tic, otherwise by default the actor will die or disappear. (Replaces A_SnowBall) @@ -10794,26 +10667,33 @@ void A_FlickyFlutter(mobj_t *actor) // Description: Creates the mobj's painchance at a random position around the object's radius. // // var1 = momz of particle. +// var2 = chance of particle spawn // void A_FlameParticle(mobj_t *actor) { mobjtype_t type = (mobjtype_t)(mobjinfo[actor->type].painchance); + fixed_t rad, hei; + mobj_t *particle; INT32 locvar1 = var1; + INT32 locvar2 = var2; #ifdef HAVE_BLUA if (LUA_CallAction("A_FlameParticle", actor)) return; #endif - if (type) - { - fixed_t rad = 2*actor->radius>>FRACBITS; - fixed_t hei = actor->height>>FRACBITS; - mobj_t *particle = P_SpawnMobjFromMobj(actor, - P_RandomRange(rad, -rad)<radius>>FRACBITS; + hei = actor->height>>FRACBITS; + particle = P_SpawnMobjFromMobj(actor, + P_RandomRange(rad, -rad)<powers[pw_flashing]) return; + if (special->movefactor && special->tracer && (angle_t)special->tracer->health != ANGLE_90 && (angle_t)special->tracer->health != ANGLE_270) + { // I don't expect you to understand this, Mr Bond... + angle_t ang = R_PointToAngle2(special->x, special->y, toucher->x, toucher->y) - special->tracer->threshold; + if ((special->movefactor > 0) == ((angle_t)special->tracer->health > ANGLE_90 && (angle_t)special->tracer->health < ANGLE_270)) + ang += ANGLE_180; + if (ang < ANGLE_180) + return; // I expect you to die. + } + P_ResetPlayer(player); P_SetTarget(&toucher->tracer, special); - if (special->target && (special->target->type == MT_SPINMACEPOINT || special->target->type == MT_HIDDEN_SLING)) + if (special->tracer && !(special->tracer->flags2 & MF2_STRONGBOX)) { player->powers[pw_carry] = CR_MACESPIN; S_StartSound(toucher, sfx_spin); @@ -1483,6 +1492,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // Can't jump first frame player->pflags |= PF_JUMPSTASIS; + return; case MT_BIGMINE: case MT_BIGAIRMINE: diff --git a/src/p_mobj.c b/src/p_mobj.c index 60694996c..85c69fa73 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6454,6 +6454,128 @@ static void P_NightsItemChase(mobj_t *thing) P_Attract(thing, thing->tracer, true); } +// +// P_MaceRotate +// Spins an object around its target, or, swings it from side to side. +// +static void P_MaceRotate(mobj_t *mobj) +{ + TVector v; + TVector *res; + fixed_t radius, dist; + angle_t fa; + INT32 prevswing; + boolean donetwice = false; + + // Tracer was removed. + if (!mobj->health) + return; + else if (!mobj->tracer) + { + P_KillMobj(mobj, NULL, NULL, 0); + return; + } + + mobj->momx = mobj->momy = mobj->momz = 0; + + prevswing = mobj->threshold; + mobj->threshold += mobj->tracer->lastlook; + mobj->threshold &= FINEMASK; + + dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed); + + // Radius of the link's rotation. + radius = FixedMul(dist * mobj->movecount, mobj->tracer->scale) + mobj->tracer->extravalue1; + +maceretry: + + fa = (FixedAngle(mobj->tracer->movefactor*FRACUNIT) >> ANGLETOFINESHIFT); + radius = FixedMul(FINECOSINE(fa), radius); + v[1] = -FixedMul(FINESINE(fa), radius) + + FixedMul(dist * mobj->movefactor, mobj->tracer->scale); + v[3] = FRACUNIT; + + // Swinging Chain. + if (mobj->tracer->flags2 & MF2_STRONGBOX) + { + fixed_t swingmagnitude = FixedMul(FINECOSINE(mobj->threshold), mobj->tracer->lastlook << FRACBITS); + prevswing = FINECOSINE(prevswing); + + if (!donetwice + && (mobj->flags2 & MF2_BOSSNOTRAP) // at the end of the chain and can play a sound + && ((prevswing > 0) != (swingmagnitude > 0))) // just passed its lowest point + S_StartSound(mobj, mobj->info->activesound); + + fa = ((FixedAngle(swingmagnitude) >> ANGLETOFINESHIFT) + mobj->friction) & FINEMASK; + + v[0] = FixedMul(FINESINE(fa), -radius); + v[2] = FixedMul(FINECOSINE(fa), -radius); + } + // Rotating Chain. + else + { + prevswing = (prevswing + mobj->friction) & FINEMASK; + fa = (mobj->threshold + mobj->friction) & FINEMASK; + + if (!donetwice + && (mobj->flags2 & MF2_BOSSNOTRAP) // at the end of the chain and can play a sound + && (!(prevswing > (FINEMASK/2)) && (fa > (FINEMASK/2)))) // completed a full swing + S_StartSound(mobj, mobj->info->activesound); + + v[0] = FixedMul(FINECOSINE(fa), radius); + v[2] = FixedMul(FINESINE(fa), radius); + } + + // Calculate the angle matrixes for the link. + res = VectorMatrixMultiply(v, *RotateXMatrix(mobj->tracer->threshold << ANGLETOFINESHIFT)); + M_Memcpy(&v, res, sizeof(v)); + res = VectorMatrixMultiply(v, *RotateZMatrix(mobj->tracer->health << ANGLETOFINESHIFT)); + M_Memcpy(&v, res, sizeof(v)); + + // Cut the height to align the link with the axis. + if (mobj->type == MT_SMALLMACECHAIN || mobj->type == MT_BIGMACECHAIN) + v[2] -= P_MobjFlip(mobj)*mobj->height/4; + else + v[2] -= P_MobjFlip(mobj)*mobj->height/2; + + P_UnsetThingPosition(mobj); + + // Add on the appropriate distances to the center's co-ordinates. + mobj->x = mobj->tracer->x + v[0]; + mobj->y = mobj->tracer->y + v[1]; + mobj->z = mobj->tracer->z + v[2]; + + P_SetThingPosition(mobj); + + if (donetwice || P_MobjWasRemoved(mobj)) + return; + + if (mobj->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)) + return; + + if ((fa = ((mobj->tracer->threshold & (FINEMASK/2)) << ANGLETOFINESHIFT)) > ANGLE_45 && fa < ANGLE_135) // only move towards center when the motion is towards/away from the ground, rather than alongside it + return; + + if (mobj->subsector->sector->ffloors) + P_AdjustMobjFloorZ_FFloors(mobj, mobj->subsector->sector, 2); + + // Variable reuse + if (mobj->floorz > mobj->z) + dist = (mobj->floorz - mobj->tracer->z); + else if (mobj->ceilingz < mobj->z) + dist = (mobj->ceilingz - mobj->tracer->z); + else + return; + + if ((dist = FixedDiv(dist, v[2])) > FRACUNIT) + return; + + radius = FixedMul(radius, dist); + donetwice = true; + dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed); + goto maceretry; +} + static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) { if (!thing->target || thing->target->health <= 0 || !thing->target->player @@ -6811,6 +6933,13 @@ void P_MobjThinker(mobj_t *mobj) // fade out when nearing the end of fuse... mobj->frame = (mobj->frame & ~FF_TRANSMASK) | (((NUMTRANSMAPS-1) - mobj->fuse / 2) << FF_TRANSSHIFT); + if (mobj->flags2 & MF2_MACEROTATE) + { + P_MaceRotate(mobj); + if (P_MobjWasRemoved(mobj)) + return; + } + // Special thinker for scenery objects if (mobj->flags & MF_SCENERY) { @@ -7476,7 +7605,8 @@ void P_MobjThinker(mobj_t *mobj) } } break; - case MT_SPINMACEPOINT: + case MT_CHAINPOINT: + case MT_CHAINMACEPOINT: if (leveltime & 1) { if (mobj->lastlook > mobj->movecount) @@ -9813,15 +9943,20 @@ void P_SpawnMapThing(mapthing_t *mthing) mobj->movedir = mthing->extrainfo; break; case MT_MACEPOINT: - case MT_SWINGMACEPOINT: - case MT_HANGMACEPOINT: - case MT_SPINMACEPOINT: + case MT_CHAINMACEPOINT: + case MT_SPRINGBALLPOINT: + case MT_CHAINPOINT: + case MT_FIREBARPOINT: + case MT_CUSTOMMACEPOINT: { - fixed_t mlength, mspeed, mxspeed, mzspeed, mstartangle, mmaxspeed; - mobjtype_t chainlink = MT_SMALLMACECHAIN; - mobjtype_t macetype = MT_SMALLMACE; - boolean firsttime; + fixed_t mlength, mlengthset, mspeed, mphase, myaw, mpitch, mmaxspeed, mnumspokes, mnumspokesset, mpinch, mroll, mnumnospokes, mwidth, mmin, msound, radiusfactor; + angle_t mspokeangle; + mobjtype_t chainlink, macetype, firsttype, linktype; + boolean mdoall = true; mobj_t *spawnee; + mobjflag_t mflagsapply; + mobjflag2_t mflags2apply; + mobjeflag_t meflagsapply; INT32 line; const size_t mthingi = (size_t)(mthing - mapthings); @@ -9835,93 +9970,240 @@ void P_SpawnMapThing(mapthing_t *mthing) return; } /* -No deaf - small mace -Deaf - big mace +mapthing - +MTF_AMBUSH : + MT_SPRINGBALLPOINT - upgrade from yellow to red spring + anything else - bigger mace/chain theory +MTF_OBJECTSPECIAL - force silent +MTF_GRAVFLIP - flips objects, doesn't affect chain arrangements +Parameter value : number of "spokes" -ML_NOCLIMB : Direction not controllable +linedef - +ML_NOCLIMB : + MT_CHAINPOINT/MT_CHAINMACEPOINT with ML_EFFECT1 applied - Direction not controllable + anything else - no functionality +ML_EFFECT1 : Swings instead of spins +ML_EFFECT2 : Linktype is replaced with macetype for all spokes not ending in chains (inverted for MT_FIREBARPOINT) +ML_EFFECT3 : Spawn a bonus macetype at the hinge point +ML_EFFECT4 : Don't clip inside the ground */ mlength = abs(lines[line].dx >> FRACBITS); - mspeed = abs(lines[line].dy >> FRACBITS); - mxspeed = sides[lines[line].sidenum[0]].textureoffset >> FRACBITS; - mzspeed = sides[lines[line].sidenum[0]].rowoffset >> FRACBITS; - mstartangle = lines[line].frontsector->floorheight >> FRACBITS; - mmaxspeed = lines[line].frontsector->ceilingheight >> FRACBITS; + mspeed = abs(lines[line].dy >> (FRACBITS - 4)); + mphase = (sides[lines[line].sidenum[0]].textureoffset >> FRACBITS) % 360; + if ((mmaxspeed = sides[lines[line].sidenum[0]].rowoffset >> (FRACBITS - 4)) < mspeed) + mmaxspeed = mspeed << 1; + mpitch = (lines[line].frontsector->floorheight >> FRACBITS) % 360; + myaw = (lines[line].frontsector->ceilingheight >> FRACBITS) % 360; - mstartangle %= 360; - mxspeed %= 360; - mzspeed %= 360; + mnumspokes = mthing->extrainfo + 1; + mspokeangle = FixedAngle((360*FRACUNIT)/mnumspokes)>>ANGLETOFINESHIFT; - CONS_Debug(DBG_GAMELOGIC, "Mace Chain (mapthing #%s):\n" + if (lines[line].backsector) + { + mpinch = (lines[line].backsector->floorheight >> FRACBITS) % 360; + mroll = (lines[line].backsector->ceilingheight >> FRACBITS) % 360; + mnumnospokes = (sides[lines[line].sidenum[1]].textureoffset >> FRACBITS); + if ((mwidth = sides[lines[line].sidenum[1]].rowoffset >> FRACBITS) < 0) + mwidth = 0; + } + else + mpinch = mroll = mnumnospokes = mwidth = 0; + + CONS_Debug(DBG_GAMELOGIC, "Mace/Chain (mapthing #%s):\n" "Length is %d\n" "Speed is %d\n" - "Xspeed is %d\n" - "Zspeed is %d\n" - "startangle is %d\n" - "maxspeed is %d\n", - sizeu1(mthingi), mlength, mspeed, mxspeed, mzspeed, mstartangle, mmaxspeed); + "Phase is %d\n" + "Yaw is %d\n" + "Pitch is %d\n" + "Max. speed is %d\n" + "No. of spokes is %d\n" + "Pinch is %d\n" + "Roll is %d\n" + "No. of antispokes is %d\n" + "Width is %d\n", + sizeu1(mthingi), mlength, mspeed, mphase, myaw, mpitch, mmaxspeed, mnumspokes, mpinch, mroll, mnumnospokes, mwidth); - mobj->lastlook = mspeed << 4; + if (mnumnospokes > 0 && (mnumnospokes < mnumspokes)) + mnumnospokes = mnumspokes/mnumnospokes; + else + mnumnospokes = ((mobj->type == MT_CHAINMACEPOINT) ? (mnumspokes - 1) : 0); + + mobj->lastlook = mspeed; mobj->movecount = mobj->lastlook; - mobj->health = (FixedAngle(mzspeed*FRACUNIT)>>ANGLETOFINESHIFT) + (FixedAngle(mstartangle*FRACUNIT)>>ANGLETOFINESHIFT); - mobj->threshold = (FixedAngle(mxspeed*FRACUNIT)>>ANGLETOFINESHIFT) + (FixedAngle(mstartangle*FRACUNIT)>>ANGLETOFINESHIFT); - mobj->movefactor = mobj->threshold; + mobj->health = (FixedAngle(myaw*FRACUNIT)>>ANGLETOFINESHIFT); + mobj->threshold = (FixedAngle(mpitch*FRACUNIT)>>ANGLETOFINESHIFT); mobj->friction = mmaxspeed; + mobj->movefactor = mpinch; + // Mobjtype selection + switch(mobj->type) + { + case MT_SPRINGBALLPOINT: + macetype = ((mthing->options & MTF_AMBUSH) + ? MT_REDSPRINGBALL + : MT_YELLOWSPRINGBALL); + chainlink = MT_SMALLMACECHAIN; + break; + case MT_FIREBARPOINT: + macetype = ((mthing->options & MTF_AMBUSH) + ? MT_BIGFIREBAR + : MT_SMALLFIREBAR); + chainlink = MT_NULL; + break; + case MT_CUSTOMMACEPOINT: + macetype = (mobjtype_t)sides[lines[line].sidenum[0]].toptexture; + if (lines[line].backsector) + chainlink = (mobjtype_t)sides[lines[line].sidenum[1]].toptexture; + else + chainlink = MT_NULL; + break; + default: + if (mthing->options & MTF_AMBUSH) + { + macetype = MT_BIGMACE; + chainlink = MT_BIGMACECHAIN; + } + else + { + macetype = MT_SMALLMACE; + chainlink = MT_SMALLMACECHAIN; + } + break; + } + + if (!macetype) + break; + + if (mobj->type != MT_CHAINPOINT) + { + firsttype = macetype; + mlength++; + } + else + { + if (!mlength) + break; + firsttype = chainlink; + } + + // Adjustable direction if (lines[line].flags & ML_NOCLIMB) mobj->flags |= MF_SLIDEME; - mobj->reactiontime = 0; - - if (mthing->options & MTF_AMBUSH) + // Swinging + if (lines[line].flags & ML_EFFECT1) { - chainlink = MT_BIGMACECHAIN; - macetype = MT_BIGMACE; + mobj->flags2 |= MF2_STRONGBOX; + mmin = ((mnumnospokes > 1) ? 1 : 0); } - - if (mthing->options & MTF_OBJECTSPECIAL) - mobj->flags2 |= MF2_BOSSNOTRAP; // shut up maces. - - if (mobj->type == MT_HANGMACEPOINT || mobj->type == MT_SPINMACEPOINT) - firsttime = true; else + mmin = mnumspokes; + + // Make the links the same type as the end - repeated below + if ((mobj->type != MT_CHAINPOINT) && (!(lines[line].flags & ML_EFFECT2) == (mobj->type == MT_FIREBARPOINT))) // exclusive or { - firsttime = false; - - spawnee = P_SpawnMobj(mobj->x, mobj->y, mobj->z, macetype); - P_SetTarget(&spawnee->target, mobj); - - if (mobj->type == MT_SWINGMACEPOINT) - spawnee->movecount = FixedAngle(mstartangle*FRACUNIT)>>ANGLETOFINESHIFT; - else - spawnee->movecount = 0; - - spawnee->threshold = FixedAngle(mstartangle*FRACUNIT)>>ANGLETOFINESHIFT; - spawnee->reactiontime = mlength+1; + linktype = macetype; + radiusfactor = 2; // Double the radius. } + else + radiusfactor = (((linktype = chainlink) == MT_NULL) ? 2 : 1); - while (mlength > 0) + mflagsapply = ((lines[line].flags & ML_EFFECT4) ? 0 : (MF_NOCLIP|MF_NOCLIPHEIGHT)); + mflags2apply = (MF2_MACEROTATE|((mthing->options & MTF_OBJECTFLIP) ? MF2_OBJECTFLIP : 0)); + meflagsapply = ((mthing->options & MTF_OBJECTFLIP) ? MFE_VERTICALFLIP : 0); + + msound = ((firsttype == chainlink) ? 0 : (mwidth & 1)); + + // Quick and easy preparatory variable setting + mphase = (FixedAngle(mphase*FRACUNIT)>>ANGLETOFINESHIFT); + mroll = (FixedAngle(mroll*FRACUNIT)>>ANGLETOFINESHIFT); + +#define makemace(mobjtype, dist, moreflags2) P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobjtype);\ + P_SetTarget(&spawnee->tracer, mobj);\ + spawnee->threshold = mphase;\ + spawnee->friction = mroll;\ + spawnee->movefactor = mwidth;\ + spawnee->movecount = dist;\ + spawnee->angle = myaw;\ + spawnee->flags |= (MF_NOGRAVITY|mflagsapply);\ + spawnee->flags2 |= (mflags2apply|moreflags2);\ + spawnee->eflags |= meflagsapply + +domaceagain: + mnumspokesset = mnumspokes; + + if (mdoall && lines[line].flags & ML_EFFECT3) // Innermost mace/link + { spawnee = makemace(macetype, 0, MF2_AMBUSH); } + + // The actual spawning of spokes + while (mnumspokesset-- > 0) { - spawnee = P_SpawnMobj(mobj->x, mobj->y, mobj->z, chainlink); + // Offsets + if (lines[line].flags & ML_EFFECT1) // Swinging + mroll = (mroll - mspokeangle) & FINEMASK; + else // Spinning + mphase = (mphase - mspokeangle) & FINEMASK; - P_SetTarget(&spawnee->target, mobj); - - if (mobj->type == MT_HANGMACEPOINT || mobj->type == MT_SWINGMACEPOINT) - spawnee->movecount = FixedAngle(mstartangle*FRACUNIT)>>ANGLETOFINESHIFT; - else - spawnee->movecount = 0; - - spawnee->threshold = FixedAngle(mstartangle*FRACUNIT)>>ANGLETOFINESHIFT; - spawnee->reactiontime = mlength; - - if (firsttime) + if (mnumnospokes && !(mnumspokesset % mnumnospokes)) // Skipping a "missing" spoke { - // This is the outermost link in the chain - spawnee->flags2 |= MF2_AMBUSH; - firsttime = false; + if (mobj->type != MT_CHAINMACEPOINT) + continue; + + firsttype = linktype = chainlink; + mlengthset = 1 + (mlength - 1)*radiusfactor; + radiusfactor = 1; + } + else + { + if (mobj->type == MT_CHAINMACEPOINT) + { + // Make the links the same type as the end - repeated above + if (lines[line].flags & ML_EFFECT2) + { + linktype = macetype; + radiusfactor = 2; + } + else + { + linktype = chainlink; + radiusfactor = (((linktype = chainlink) == MT_NULL) ? 2 : 1); + } + + firsttype = macetype; + } + + mlengthset = mlength; } - mlength--; + // Outermost mace/link + spawnee = makemace(firsttype, radiusfactor*(mlengthset--), MF2_AMBUSH); + + if (mspeed && (mwidth == msound) && !(mthing->options & MTF_OBJECTSPECIAL) && mnumspokesset <= mmin) // Can it make a sound? + spawnee->flags2 |= MF2_BOSSNOTRAP; + + if (!mdoall || !linktype) + continue; + + // The rest of the links + while (mlengthset > 0) + { spawnee = makemace(linktype, radiusfactor*(mlengthset--), 0); } } + + if (mwidth > 0) + { + mwidth *= -1; + goto domaceagain; + } + else if (mwidth != 0) + { + if ((mwidth = -(mwidth + ((firsttype == chainlink) ? 1 : 2))) < 0) + break; + mdoall = false; + goto domaceagain; + } + +#undef makemace + break; } case MT_PARTICLEGEN: @@ -11294,4 +11576,4 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo newmobj->destscale = mobj->destscale; P_SetScale(newmobj, mobj->scale); return newmobj; -} +} \ No newline at end of file diff --git a/src/p_mobj.h b/src/p_mobj.h index f6ebd3cad..c6e1bfbf2 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -194,6 +194,7 @@ typedef enum MF2_AMBUSH = 1<<27, // Alternate behaviour typically set by MTF_AMBUSH MF2_LINKDRAW = 1<<28, // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position) MF2_SHIELD = 1<<29, // Thinker calls P_AddShield/P_ShieldLook (must be partnered with MF_SCENERY to use) + MF2_MACEROTATE = 1<<30, // Thinker calls P_MaceRotate around tracer // free: to and including 1<<31 } mobjflag2_t; diff --git a/src/p_setup.c b/src/p_setup.c index 1c2cb370a..3bae9379e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1594,6 +1594,7 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum) break; } + case 9: // Mace parameters case 14: // Bustable block parameters case 15: // Fan particle spawner parameters case 425: // Calls P_SetMobjState on calling mobj diff --git a/src/p_user.c b/src/p_user.c index 7eafdf8ef..eb8810acd 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9974,7 +9974,7 @@ void P_PlayerAfterThink(player_t *player) } } } - else if (player->powers[pw_carry] == CR_MACESPIN && player->mo->tracer && player->mo->tracer->target) + else if (player->powers[pw_carry] == CR_MACESPIN && player->mo->tracer && player->mo->tracer->tracer) { player->mo->height = P_GetPlayerSpinHeight(player); // tracer is what you're hanging onto.... @@ -9990,14 +9990,20 @@ void P_PlayerAfterThink(player_t *player) player->pflags &= ~PF_THOKKED; if (cmd->forwardmove > 0) - player->mo->tracer->target->lastlook += 2; - else if (cmd->forwardmove < 0 && player->mo->tracer->target->lastlook > player->mo->tracer->target->movecount) - player->mo->tracer->target->lastlook -= 2; + { + if ((player->mo->tracer->tracer->lastlook += 2) > player->mo->tracer->tracer->friction) + player->mo->tracer->tracer->lastlook = player->mo->tracer->tracer->friction; + } + else if (cmd->forwardmove < 0) + { + if ((player->mo->tracer->tracer->lastlook -= 2) < player->mo->tracer->tracer->movecount) + player->mo->tracer->tracer->lastlook = player->mo->tracer->tracer->movecount; + } - if (!(player->mo->tracer->target->flags & MF_SLIDEME) // Noclimb on chain parameters gives this + if ((player->mo->tracer->tracer->flags & MF_SLIDEME) // Noclimb on chain parameters gives this && !(twodlevel || player->mo->flags2 & MF2_TWOD)) // why on earth would you want to turn them in 2D mode? { - player->mo->tracer->target->health += cmd->sidemove; + player->mo->tracer->tracer->health += cmd->sidemove; player->mo->angle += cmd->sidemove< ANGLE_MAX if (!demoplayback || P_AnalogMove(player))