Hooh boy.

****
* MF2_MACEROTATE. Apply to any object. Replaces the indiscriminate spamming of A_MaceRotate each tic.
****
* Mace point mapthings have been slightly modified.
   - MTF_AMBUSH: bigger luke theory (has no effect on custom mace, different effect on spring mace)
   - MTF_OBJECTFLIP: flips the objects, but nothing else - just so it doesn't look out of place in gravflip sections
   - MTF_OBJECTSPECIAL: keeps it from attempting to play swinging sounds
   - angle: tag of controlling linedef
   - parameter: number of "spokes" minus one - for example, a parameter of 2 results in 3 equidistant maces rotating around the same point.
****
* Mace linedefs have been significantly revamped.
   - line dx: number of chain links
   - line dy: speed (in FU)
   - frontside floor height: Pitch (in degrees; how much it "tilts" over - Yaw influences the axis it's tilting on)
   - frontside ceiling height: Yaw (in degrees; rotation of entire thing on xy plane)
   - frontside x offset: Phase (in degrees; how far it is through the rotation cycle)
   - frontside y offset: Max speed (in FU; if less than speed, set to speed*2)
   - backside floor height: Pinch (in degrees; 0 if no backside; essentially makes rotation conical instead of wheel-like)
   - backside ceiling height: Roll (in degrees; 0 if no backside; rotates on the axis of the spinning - identical to Phase for spinning maces, but useful for rotating swinging maces as opposed to just offsetting them)
   - backside x offset: Number of "antispokes" (0 if no backside; makes that many spokes not exist so you can put another mace/chain type in there instead; for combo mace/chain instead turns them into chains directly)
   - backside y offset: Width (in number of extra chains per side; 0 if no backside; creates a "skiprope" arrangement)
   ----
   - ML_NOCLIMB: for chains and chain-mace combos, allow for player control of yaw through strafe keys
   - ML_EFFECT1: replacing the seperate mapthings, this makes a mace type swing instead of spin.
   - ML_EFFECT2: for all spokes of the mace wheel ending in maces, make the chains out of the mace type (inverted for firebars)
   - ML_EFFECT3: spawn a bonus mace type at the center(s) of rotation
   - ML_EFFECT4: don't clip inside ground
****
* Mapthing 1104 represents both spinning and swinging maces from prior versions of SRB2.
* Mapthing 1105 has gone from being a swinging mace variant to a combination of chains and maces in a single unit, provided the number of "spokes" is greater than one.
* Mapthing 1105 has gone from being a swinging chain variant to a vertical spring-on-a-ball-on-a-chain. Yellow by default, apply MTF_AMBUSH to turn into a red spring.
* Mapthing 1107 represents both spinning and swinging chains from prior versions of SRB2.
* Mapthing 1108 is completely untouched except to port over 2.1's functionality to the new backend.
* Mapthing 1109 is a Mario castle-level style firebar. This inverts the functionality of ML_EFFECT2 on the tagged linedef.
* Mapthing 1110 is a free slot should we want to implement another type of base-game mace.
* Mapthing 1111 is a custom mace. Use the linedef's frontside texture slots to identify a macetype mobjtype, then use the backside texture slots to identify a linktype mobjtype (defaults to MT_NULL if no backside).
****

Whooh. Requires new patch.dta for sprites.
This commit is contained in:
toasterbabe 2017-07-02 15:11:09 +01:00
parent a0fa548e8b
commit 370d9c3176
10 changed files with 753 additions and 273 deletions

View File

@ -1826,7 +1826,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"},
@ -5248,18 +5247,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
@ -6587,14 +6630,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
@ -6947,6 +6996,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
};

View File

@ -316,6 +316,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

View File

@ -204,6 +204,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
@ -1804,13 +1808,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
@ -1821,31 +1825,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
@ -8504,7 +8552,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_SWINGMACEPOINT
{ // MT_CHAINMACEPOINT
1105, // doomednum
S_INVISIBLE, // spawnstate
1000, // spawnhealth
@ -8531,7 +8579,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_HANGMACEPOINT
{ // MT_SPRINGBALLPOINT
1106, // doomednum
S_INVISIBLE, // spawnstate
1000, // spawnhealth
@ -8558,7 +8606,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_SPINMACEPOINT
{ // MT_CHAINPOINT
1107, // doomednum
S_INVISIBLE, // spawnstate
1000, // spawnhealth
@ -8578,7 +8626,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
@ -8612,6 +8660,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
@ -8635,7 +8737,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
},
@ -8662,7 +8764,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
},
@ -8685,11 +8787,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
},
@ -8712,11 +8814,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
},

View File

@ -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();
@ -410,6 +409,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
@ -2029,18 +2032,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
@ -3387,14 +3434,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

View File

@ -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);
@ -5142,15 +5141,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;
@ -5165,134 +5161,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;
INT32 prevswing;
#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->threshold += actor->target->lastlook;
actor->threshold &= FINEMASK;
prevswing = actor->movecount;
actor->movecount = FixedMul(FINECOSINE(actor->threshold), actor->target->lastlook << FRACBITS);
if ((actor->flags2 & MF2_AMBUSH) // at the end of the chain
&& !(actor->target->flags2 & MF2_BOSSNOTRAP) // flag that makes 'em shut up on request
&& ((prevswing > 0) != (actor->movecount > 0))) // just passed its lowest point
S_StartSound(actor, actor->info->activesound);
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->movecount)));
M_Memcpy(&v, res, sizeof(v));
res = VectorMatrixMultiply(v, *RotateZMatrix(actor->target->health << ANGLETOFINESHIFT));
M_Memcpy(&v, res, sizeof(v));
}
// Rotating Chain.
else
{
prevswing = actor->threshold;
actor->threshold += actor->target->lastlook;
actor->threshold &= FINEMASK;
if ((actor->flags2 & MF2_AMBUSH) // at the end of the chain
&& !(actor->target->flags2 & MF2_BOSSNOTRAP) // flag that makes 'em shut up on request
&& (!(prevswing > (FINEMASK/2)) && (actor->threshold > (FINEMASK/2)))) // completed a full swing
S_StartSound(actor, actor->info->activesound);
v[0] = FixedMul(FINECOSINE((angle_t)actor->threshold), radius);
v[1] = 0;
v[2] = FixedMul(FINESINE((angle_t)actor->threshold), 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);
}
// 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)
@ -10796,26 +10664,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)<<FRACBITS,
P_RandomRange(rad, -rad)<<FRACBITS,
P_RandomRange(hei/2, hei)<<FRACBITS,
type);
P_SetObjectMomZ(particle, locvar1<<FRACBITS, false);
}
if (!P_RandomChance(locvar2))
return;
if (!type)
return;
rad = 2*actor->radius>>FRACBITS;
hei = actor->height>>FRACBITS;
particle = P_SpawnMobjFromMobj(actor,
P_RandomRange(rad, -rad)<<FRACBITS,
P_RandomRange(rad, -rad)<<FRACBITS,
P_RandomRange(hei/2, hei)<<FRACBITS,
type);
P_SetObjectMomZ(particle, locvar1<<FRACBITS, false);
}

View File

@ -1474,7 +1474,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
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);
@ -1485,6 +1485,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:

View File

@ -6453,6 +6453,132 @@ 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:
// Set the top speed for the link if it happens to be over that speed.
if (mobj->tracer->lastlook > mobj->tracer->friction)
mobj->tracer->lastlook = mobj->tracer->friction;
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)
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
@ -6810,6 +6936,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)
{
@ -7456,7 +7589,7 @@ void P_MobjThinker(mobj_t *mobj)
}
}
break;
case MT_SPINMACEPOINT:
case MT_FIREBARPOINT:
if (leveltime & 1)
{
if (mobj->lastlook > mobj->movecount)
@ -9771,16 +9904,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, thresholdset, radiusfactor = 1;
mobjtype_t chainlink = MT_SMALLMACECHAIN;
mobjtype_t macetype = MT_SMALLMACE;
mobjtype_t firsttype;
const boolean hazard = (mobj->type == MT_MACEPOINT || mobj->type == MT_SWINGMACEPOINT);
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);
@ -9794,91 +9931,239 @@ void P_SpawnMapThing(mapthing_t *mthing)
return;
}
/*
No deaf - small
Deaf - big
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"
linedef -
ML_NOCLIMB :
SPINMACEPOINT - Direction not controllable
MACEPOINT, SWINGMACEPOINT - Chain links are replaced with maces
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) < 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;
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"
"Phase is %d\n"
"Angle is %d\n"
"Tilt is %d\n"
"Max. speed is %d\n",
sizeu1(mthingi), mlength, mspeed, mxspeed, mzspeed, mstartangle, mmaxspeed);
"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);
mobj->threshold = (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;
if (mthing->options & MTF_AMBUSH)
// Mobjtype selection
switch(mobj->type)
{
chainlink = MT_BIGMACECHAIN;
macetype = MT_BIGMACE;
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 (lines[line].flags & ML_NOCLIMB)
{
if (hazard)
{
chainlink = macetype;
radiusfactor = 2; // Double the radius.
}
else
mobj->flags |= MF_SLIDEME;
}
if (!macetype)
break;
mobj->reactiontime = 0;
if (!mspeed || mthing->options & MTF_OBJECTSPECIAL)
mobj->flags2 |= MF2_BOSSNOTRAP; // shut up maces.
thresholdset = FixedAngle(mxspeed*FRACUNIT)>>ANGLETOFINESHIFT;
if (hazard) // outermost mace
if (mobj->type != MT_CHAINPOINT)
{
firsttype = macetype;
mlength++;
}
else
{
if (!mlength)
break;
firsttype = chainlink;
if (mlength) // outermost mace/link
{
spawnee = P_SpawnMobj(mobj->x, mobj->y, mobj->z, firsttype);
P_SetTarget(&spawnee->target, mobj);
spawnee->threshold = thresholdset;
spawnee->reactiontime = radiusfactor*(mlength--);
spawnee->flags2 |= MF2_AMBUSH;
}
while (mlength > 0)
{
spawnee = P_SpawnMobj(mobj->x, mobj->y, mobj->z, chainlink);
P_SetTarget(&spawnee->target, mobj);
// Adjustable direction
if (lines[line].flags & ML_NOCLIMB)
mobj->flags |= MF_SLIDEME;
spawnee->threshold = thresholdset;
spawnee->reactiontime = radiusfactor*(mlength--);
// Swinging
if (lines[line].flags & ML_EFFECT1)
{
mobj->flags2 |= MF2_STRONGBOX;
mmin = ((mnumnospokes > 1) ? 1 : 0);
}
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
{
linktype = macetype;
radiusfactor = 2; // Double the radius.
}
else
radiusfactor = (((linktype = chainlink) == MT_NULL) ? 2 : 1);
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)
{
// Offsets
if (lines[line].flags & ML_EFFECT1) // Swinging
mroll = (mroll - mspokeangle) & FINEMASK;
else // Spinning
mphase = (mphase - mspokeangle) & FINEMASK;
if (mnumnospokes && !(mnumspokesset % mnumnospokes)) // Skipping a "missing" spoke
{
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;
}
// 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;
}
@ -11235,4 +11520,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;
}
}

View File

@ -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;

View File

@ -1578,6 +1578,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

View File

@ -9969,7 +9969,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....
@ -9985,14 +9985,14 @@ 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;
player->mo->tracer->tracer->lastlook += 2;
else if (cmd->forwardmove < 0 && player->mo->tracer->tracer->lastlook > player->mo->tracer->tracer->movecount)
player->mo->tracer->tracer->lastlook -= 2;
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<<ANGLETOFINESHIFT; // 2048 --> ANGLE_MAX
if (!demoplayback || P_AnalogMove(player))