From f8dd9b64abfa69a4af52bfe3923204b07b68f2c7 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 8 Jul 2016 21:55:17 +0100 Subject: [PATCH] Elemental shield ability now coded. REQUIRES NEW PATCH.DTA FROM THE FTP. - Press spin in midair to stomp directly downwards (losing horizontal momentum), creating a flickering fireball around you. - No bouncing on enemies, item boxes, etc - just go straight through. - Hurts other players on touch whilst you're stomping. - Spawns a bunch of flames around you when you hit the ground. Also: - Electric shield's ability now uses different sounds, because I'm picky. --- src/dehacked.c | 14 ++++++- src/info.c | 75 +++++++++++++++++++++++++--------- src/info.h | 15 ++++++- src/lua_baselib.c | 3 +- src/p_inter.c | 12 ++++-- src/p_local.h | 2 +- src/p_map.c | 8 ++-- src/p_mobj.c | 22 ++++++++++ src/p_user.c | 100 ++++++++++++++++++++++++++++++++-------------- 9 files changed, 191 insertions(+), 60 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index f5d3b55cb..1afa5f0cf 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4782,7 +4782,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_SPIKEBALL7", "S_SPIKEBALL8", - // Fire Shield's Spawn + // Elemental Shield's Spawn + "S_SPINFIRE0", "S_SPINFIRE1", "S_SPINFIRE2", "S_SPINFIRE3", @@ -4790,6 +4791,15 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_SPINFIRE5", "S_SPINFIRE6", + // Elemental Shield's FLYING Spawn + "S_AIRSPINFIRE_FLY1", + "S_AIRSPINFIRE_FLY2", + "S_AIRSPINFIRE_FLY3", + "S_AIRSPINFIRE_FLY4", + "S_AIRSPINFIRE_FLY5", + "S_AIRSPINFIRE_FLY6", + "S_AIRSPINFIRE_DIE", + // Spikes "S_SPIKE1", "S_SPIKE2", @@ -5399,6 +5409,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ELEMF6", "S_ELEMF7", "S_ELEMF8", + "S_ELEMF9", + "S_ELEMF10", "S_PITY1", "S_PITY2", diff --git a/src/info.c b/src/info.c index 5e6528c01..f946e72e8 100644 --- a/src/info.c +++ b/src/info.c @@ -1123,13 +1123,23 @@ state_t states[NUMSTATES] = {SPR_SPIK, 6, 1, {A_RotateSpikeBall}, 0, 0, S_SPIKEBALL8}, // S_SPIKEBALL7 {SPR_SPIK, 7, 1, {A_RotateSpikeBall}, 0, 0, S_SPIKEBALL1}, // S_SPIKEBALL8 - // Red Shield's Spawn - {SPR_SFLM, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_SPINFIRE2}, // S_SPINFIRE1 - {SPR_SFLM, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_SPINFIRE3}, // S_SPINFIRE2 - {SPR_SFLM, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_SPINFIRE4}, // S_SPINFIRE3 - {SPR_SFLM, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_SPINFIRE5}, // S_SPINFIRE4 - {SPR_SFLM, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_SPINFIRE6}, // S_SPINFIRE5 - {SPR_SFLM, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_SPINFIRE1}, // S_SPINFIRE6 + // Elemental Shield's Spawn + {SPR_SFLM, FF_FULLBRIGHT|5, 2, {A_SetFuse}, 6*TICRATE, 0, S_SPINFIRE1}, // S_SPINFIRE0 + {SPR_SFLM, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_SPINFIRE2}, // S_SPINFIRE1 + {SPR_SFLM, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_SPINFIRE3}, // S_SPINFIRE2 + {SPR_SFLM, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_SPINFIRE4}, // S_SPINFIRE3 + {SPR_SFLM, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_SPINFIRE5}, // S_SPINFIRE4 + {SPR_SFLM, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_SPINFIRE6}, // S_SPINFIRE5 + {SPR_SFLM, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_SPINFIRE1}, // S_SPINFIRE6 + + // Elemental Shield's FLYING Spawn + {SPR_SFLM, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_AIRSPINFIRE_FLY2}, //S_AIRSPINFIRE_FLY1, + {SPR_SFLM, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_AIRSPINFIRE_FLY3}, //S_AIRSPINFIRE_FLY2, + {SPR_SFLM, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_AIRSPINFIRE_FLY4}, //S_AIRSPINFIRE_FLY3, + {SPR_SFLM, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_AIRSPINFIRE_FLY5}, //S_AIRSPINFIRE_FLY4, + {SPR_SFLM, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_AIRSPINFIRE_FLY6}, //S_AIRSPINFIRE_FLY5, + {SPR_SFLM, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_AIRSPINFIRE_FLY1}, //S_AIRSPINFIRE_FLY6, + {SPR_SFLM, FF_FULLBRIGHT, 0, {A_SpawnObjectRelative}, 0, MT_SPINFIRE, S_NULL}, //S_AIRSPINFIRE_DIE, // Floor Spike {SPR_USPK, 0,-1, {A_SpikeRetract}, 1, 0, S_SPIKE2}, // S_SPIKE1 -- Fully extended @@ -1742,14 +1752,16 @@ state_t states[NUMSTATES] = {SPR_ELEM, FF_TRANS50|10, 4, {NULL}, 0, 0, S_ELEM12}, // S_ELEM11 {SPR_ELEM, FF_TRANS50|11, 4, {NULL}, 0, 0, S_ELEM1 }, // S_ELEM12 - {SPR_ELEM, FF_FULLBRIGHT|12, 3, {NULL}, 0, 0, S_ELEMF2}, // S_ELEMF1 - {SPR_ELEM, FF_FULLBRIGHT|13, 3, {NULL}, 0, 0, S_ELEMF3}, // S_ELEMF2 - {SPR_ELEM, FF_FULLBRIGHT|14, 3, {NULL}, 0, 0, S_ELEMF4}, // S_ELEMF3 - {SPR_ELEM, FF_FULLBRIGHT|15, 3, {NULL}, 0, 0, S_ELEMF5}, // S_ELEMF4 - {SPR_ELEM, FF_FULLBRIGHT|16, 3, {NULL}, 0, 0, S_ELEMF6}, // S_ELEMF5 - {SPR_ELEM, FF_FULLBRIGHT|17, 3, {NULL}, 0, 0, S_ELEMF7}, // S_ELEMF6 - {SPR_ELEM, FF_FULLBRIGHT|18, 3, {NULL}, 0, 0, S_ELEMF8}, // S_ELEMF7 - {SPR_ELEM, FF_FULLBRIGHT|19, 3, {NULL}, 0, 0, S_ELEMF1}, // S_ELEMF8 + {SPR_ELEM, FF_FULLBRIGHT|12, 3, {NULL}, 0, 0, S_ELEMF2 }, // S_ELEMF1 + {SPR_ELEM, FF_FULLBRIGHT|13, 3, {NULL}, 0, 0, S_ELEMF3 }, // S_ELEMF2 + {SPR_ELEM, FF_FULLBRIGHT|14, 3, {NULL}, 0, 0, S_ELEMF4 }, // S_ELEMF3 + {SPR_ELEM, FF_FULLBRIGHT|15, 3, {NULL}, 0, 0, S_ELEMF5 }, // S_ELEMF4 + {SPR_ELEM, FF_FULLBRIGHT|16, 3, {NULL}, 0, 0, S_ELEMF6 }, // S_ELEMF5 + {SPR_ELEM, FF_FULLBRIGHT|17, 3, {NULL}, 0, 0, S_ELEMF7 }, // S_ELEMF6 + {SPR_ELEM, FF_FULLBRIGHT|18, 3, {NULL}, 0, 0, S_ELEMF8 }, // S_ELEMF7 + {SPR_ELEM, FF_FULLBRIGHT|19, 3, {NULL}, 0, 0, S_ELEMF1 }, // S_ELEMF8 + {SPR_ELEM, FF_FULLBRIGHT|20, 1, {NULL}, 0, 0, S_ELEMF10}, // S_ELEMF9 + {SPR_NULL, 0, 1, {NULL}, 0, 0, S_ELEMF1 }, // S_ELEMF10 {SPR_PITY, FF_TRANS20 , 1, {NULL}, 0, 0, S_PITY2 }, // S_PITY1 {SPR_PITY, FF_TRANS20|1, 1, {NULL}, 0, 0, S_PITY3 }, // S_PITY2 @@ -5392,7 +5404,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_SPINFIRE -1, // doomednum - S_SPINFIRE1, // spawnstate + S_SPINFIRE0, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -5413,7 +5425,34 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 1, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY|MF_FIRE, // flags + MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY|MF_FIRE|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate + }, + + { // MT_AIRSPINFIRE + -1, // doomednum + S_AIRSPINFIRE_FLY1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_AIRSPINFIRE_DIE, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 10*FRACUNIT, // speed + 8*FRACUNIT, // radius + 14*FRACUNIT, // height + 0, // display offset + 100, // mass + 1, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_MISSILE|MF_FIRE, // flags S_NULL // raisestate }, @@ -9833,7 +9872,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // seesound 0, // reactiontime sfx_None, // attacksound - S_NULL, // painstate + S_ELEMF9, // painstate SKINCOLOR_NONE, // painchance sfx_None, // painsound S_NULL, // meleestate diff --git a/src/info.h b/src/info.h index f49a56baa..8a56ef77e 100644 --- a/src/info.h +++ b/src/info.h @@ -1633,7 +1633,8 @@ typedef enum state S_SPIKEBALL7, S_SPIKEBALL8, - // Fire Shield's Spawn + // Elemental Shield's Spawn + S_SPINFIRE0, S_SPINFIRE1, S_SPINFIRE2, S_SPINFIRE3, @@ -1641,6 +1642,15 @@ typedef enum state S_SPINFIRE5, S_SPINFIRE6, + // Elemental Shield's FLYING Spawn + S_AIRSPINFIRE_FLY1, + S_AIRSPINFIRE_FLY2, + S_AIRSPINFIRE_FLY3, + S_AIRSPINFIRE_FLY4, + S_AIRSPINFIRE_FLY5, + S_AIRSPINFIRE_FLY6, + S_AIRSPINFIRE_DIE, + // Spikes S_SPIKE1, S_SPIKE2, @@ -2250,6 +2260,8 @@ typedef enum state S_ELEMF6, S_ELEMF7, S_ELEMF8, + S_ELEMF9, + S_ELEMF10, S_PITY1, S_PITY2, @@ -3131,6 +3143,7 @@ typedef enum mobj_type MT_SPIKEBALL, // Spike Ball MT_SPECIALSPIKEBALL, MT_SPINFIRE, + MT_AIRSPINFIRE, // Elemental flame flying through the air MT_SPIKE, MT_STARPOST, MT_BIGMINE, diff --git a/src/lua_baselib.c b/src/lua_baselib.c index b478a8cf6..8846e2403 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -780,10 +780,11 @@ static int lib_pBlackOw(lua_State *L) static int lib_pElementalFireTrail(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + boolean cropcircle = lua_opttrueboolean(L, 2); NOHUD if (!player) return LUA_ErrInvalid(L, "player_t"); - P_ElementalFireTrail(player); + P_ElementalFireTrail(player, cropcircle); return 0; } diff --git a/src/p_inter.c b/src/p_inter.c index 9d6230cb2..c2e8561a2 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -237,6 +237,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { player_t *player; INT32 i; + boolean elementalpierce; if (objectplacing) return; @@ -291,6 +292,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; #endif + elementalpierce = (((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) && (player->pflags & PF_SHIELDABILITY)); + if (special->flags & MF_BOSS) { if (special->type == MT_BLACKEGGMAN) @@ -301,9 +304,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) 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? + || player->powers[pw_invulnerability] || player->powers[pw_super] + || elementalpierce) // Do you possess the ability to subdue the object? { - if (P_MobjFlip(toucher)*toucher->momz < 0) + if ((P_MobjFlip(toucher)*toucher->momz < 0) && !elementalpierce) toucher->momz = -toucher->momz; toucher->momx = -toucher->momx; toucher->momy = -toucher->momy; @@ -330,7 +334,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) /////ENEMIES!!////////////////////////////////////////// //////////////////////////////////////////////////////// if (special->type == MT_GSNAPPER && !(((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) - || player->powers[pw_invulnerability] || player->powers[pw_super]) + || player->powers[pw_invulnerability] || player->powers[pw_super] || elementalpierce) && toucher->z < special->z + special->height && toucher->z + toucher->height > special->z) { // Can only hit snapper from above @@ -346,7 +350,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) || (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) + if ((P_MobjFlip(toucher)*toucher->momz < 0) && !elementalpierce) toucher->momz = -toucher->momz; P_DamageMobj(special, toucher, toucher, 1, 0); diff --git a/src/p_local.h b/src/p_local.h index 0f21b317e..26369d899 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -151,7 +151,7 @@ boolean P_AutoPause(void); void P_DoJumpShield(player_t *player); void P_BlackOw(player_t *player); -void P_ElementalFireTrail(player_t *player); +void P_ElementalFireTrail(player_t *player, boolean cropcircle); void P_DoPityCheck(player_t *player); void P_PlayerThink(player_t *player); diff --git a/src/p_map.c b/src/p_map.c index af7c4667e..468b46ea3 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -855,10 +855,10 @@ static boolean PIT_CheckThing(mobj_t *thing) { if (G_RingSlingerGametype() && (!G_GametypeHasTeams() || tmthing->player->ctfteam != thing->player->ctfteam)) { - if ((tmthing->player->powers[pw_invulnerability] || tmthing->player->powers[pw_super]) + if ((tmthing->player->powers[pw_invulnerability] || tmthing->player->powers[pw_super] || (((tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) && (tmthing->player->pflags & PF_SHIELDABILITY))) && !thing->player->powers[pw_super]) P_DamageMobj(thing, tmthing, tmthing, 1, 0); - else if ((thing->player->powers[pw_invulnerability] || thing->player->powers[pw_super]) + else if ((thing->player->powers[pw_invulnerability] || thing->player->powers[pw_super] || (((thing->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) && (thing->player->pflags & PF_SHIELDABILITY))) && !tmthing->player->powers[pw_super]) P_DamageMobj(tmthing, thing, thing, 1, 0); } @@ -942,11 +942,13 @@ static boolean PIT_CheckThing(mobj_t *thing) { SINT8 flipval = P_MobjFlip(thing); // Save this value in case monitor gets removed. fixed_t *momz = &tmthing->momz; // tmthing gets changed by P_DamageMobj, so we need a new pointer?! X_x;; + boolean elementalpierce = (((tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) && (tmthing->player->pflags & PF_SHIELDABILITY)); P_DamageMobj(thing, tmthing, tmthing, 1, 0); // break the monitor // Going down? Then bounce back up. if ((P_MobjWasRemoved(thing) // Monitor was removed || !thing->health) // or otherwise popped - && (flipval*(*momz) < 0)) // monitor is on the floor and you're going down, or on the ceiling and you're going up + && (flipval*(*momz) < 0) // monitor is on the floor and you're going down, or on the ceiling and you're going up + && !elementalpierce) // you're not piercing through the monitor... *momz = -*momz; // Therefore, you should be thrust in the opposite direction, vertically. return false; } diff --git a/src/p_mobj.c b/src/p_mobj.c index 9b9fdea24..ab8071904 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2980,7 +2980,19 @@ static void P_PlayerZMovement(mobj_t *mo) if (!(mo->player->pflags & PF_GLIDING)) mo->player->pflags &= ~PF_JUMPED; + + if (((mo->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) && (mo->player->pflags & PF_SHIELDABILITY)) // Elemental pierce attack. + { + if (mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) // play a blunt sound + S_StartSound(mo, sfx_s3k4c); + else // create a fire pattern on the ground + { + S_StartSound(mo, sfx_s3k47); + P_ElementalFireTrail(mo->player, true); + } + } mo->player->pflags &= ~(PF_THOKKED|PF_SHIELDABILITY); + //mo->player->pflags &= ~PF_GLIDING; mo->player->jumping = 0; mo->player->secondjump = 0; @@ -6456,6 +6468,16 @@ void P_MobjThinker(mobj_t *mobj) } else P_AddOverlay(mobj); + if ((mobj->target->type == MT_GREENORB) + && (mobj->target->target) + && (mobj->target->target->player) + && ((mobj->target->target->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) + && (mobj->target->target->player->pflags & PF_SHIELDABILITY) + && (mobj->state->nextstate < mobj->target->info->painstate)) // Special casing for elemental shield piercing attack. + { + P_SetMobjState(mobj, mobj->target->info->painstate); + mobj->tics++; + } break; case MT_BLACKORB: case MT_WHITEORB: diff --git a/src/p_user.c b/src/p_user.c index 84eea16a0..e1a44cfd0 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1347,6 +1347,8 @@ void P_SpawnShieldOrb(player_t *player) I_Error("P_SpawnShieldOrb: player->mo is NULL!\n"); #endif + player->pflags &= ~PF_SHIELDABILITY; // Prevent edge cases when switching shields. + if (player->powers[pw_shield] & SH_FORCE) orbtype = MT_BLUEORB; else switch (player->powers[pw_shield] & SH_NOSTACK) @@ -6198,7 +6200,7 @@ void P_BlackOw(player_t *player) player->powers[pw_shield] = player->powers[pw_shield] & SH_STACK; } -void P_ElementalFireTrail(player_t *player) +void P_ElementalFireTrail(player_t *player, boolean cropcircle) { fixed_t newx; fixed_t newy; @@ -6216,40 +6218,61 @@ void P_ElementalFireTrail(player_t *player) else ground = player->mo->floorz; - travelangle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy); - - for (i = 0; i < 2; i++) + if (cropcircle) { - newx = player->mo->x + P_ReturnThrustX(player->mo, travelangle + ((i&1) ? -1 : 1)*ANGLE_135, FixedMul(24*FRACUNIT, player->mo->scale)); - newy = player->mo->y + P_ReturnThrustY(player->mo, travelangle + ((i&1) ? -1 : 1)*ANGLE_135, FixedMul(24*FRACUNIT, player->mo->scale)); -#ifdef ESLOPE - if (player->mo->standingslope) + travelangle = player->mo->angle + P_RandomRange(-ANGLE_45, ANGLE_45); +#define numangles 8 + for (i = 0; i < 8; i++) { - ground = P_GetZAt(player->mo->standingslope, newx, newy); - if (player->mo->eflags & MFE_VERTICALFLIP) - ground -= FixedMul(mobjinfo[MT_SPINFIRE].height, player->mo->scale); + flame = P_SpawnMobj(player->mo->x, player->mo->y, ground, MT_AIRSPINFIRE); + P_SetTarget(&flame->target, player->mo); + flame->angle = travelangle + i*(ANGLE_MAX/numangles); + flame->destscale = player->mo->scale; + P_SetScale(flame, player->mo->scale); + flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); + P_InstaThrust(flame, flame->angle, FixedMul(3*FRACUNIT, flame->scale)); + P_SetObjectMomZ(flame, 3*FRACUNIT, false); } -#endif - flame = P_SpawnMobj(newx, newy, ground, MT_SPINFIRE); - P_SetTarget(&flame->target, player->mo); - flame->angle = travelangle; - flame->fuse = TICRATE*6; - flame->destscale = player->mo->scale; - P_SetScale(flame, player->mo->scale); - flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); - - flame->momx = 8; - P_XYMovement(flame); - if (P_MobjWasRemoved(flame)) - continue; - - if (player->mo->eflags & MFE_VERTICALFLIP) +#undef numangles + } + else + { + travelangle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy); + for (i = 0; i < 2; i++) { - if (flame->z + flame->height < flame->ceilingz) + + newx = player->mo->x + P_ReturnThrustX(player->mo, (travelangle + ((i&1) ? -1 : 1)*ANGLE_135), FixedMul(24*FRACUNIT, player->mo->scale)); + newy = player->mo->y + P_ReturnThrustY(player->mo, (travelangle + ((i&1) ? -1 : 1)*ANGLE_135), FixedMul(24*FRACUNIT, player->mo->scale)); + +#ifdef ESLOPE + if (player->mo->standingslope) + { + ground = P_GetZAt(player->mo->standingslope, newx, newy); + if (player->mo->eflags & MFE_VERTICALFLIP) + ground -= FixedMul(mobjinfo[MT_SPINFIRE].height, player->mo->scale); + } +#endif + flame = P_SpawnMobj(newx, newy, ground, MT_SPINFIRE); + P_SetTarget(&flame->target, player->mo); + flame->angle = travelangle; + // flame->fuse = TICRATE*6; // now done in spawnstate + flame->destscale = player->mo->scale; + P_SetScale(flame, player->mo->scale); + flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); + + flame->momx = 8; + P_XYMovement(flame); + if (P_MobjWasRemoved(flame)) + continue; + + if (player->mo->eflags & MFE_VERTICALFLIP) + { + if (flame->z + flame->height < flame->ceilingz) + P_RemoveMobj(flame); + } + else if (flame->z > flame->floorz) P_RemoveMobj(flame); } - else if (flame->z > flame->floorz) - P_RemoveMobj(flame); } } @@ -6789,7 +6812,7 @@ static void P_MovePlayer(player_t *player) if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL && (player->pflags & PF_SPINNING) && player->speed > FixedMul(4<mo->scale) && onground && (leveltime & 1) && !(player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))) - P_ElementalFireTrail(player); + P_ElementalFireTrail(player, false); P_DoSpinDash(player, cmd); @@ -6897,9 +6920,24 @@ static void P_MovePlayer(player_t *player) { player->pflags |= PF_THOKKED|PF_SHIELDABILITY; player->homing = 2; - S_StartSound(player->mo, sfx_spdpad); if (P_LookForEnemies(player, false) && player->mo->tracer) + { + S_StartSound(player->mo, sfx_s3k40); player->homing = 3*TICRATE; + } + else + S_StartSound(player->mo, sfx_s3k41); + } + } + // Elemental shield activation + if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) + { + if (!(player->pflags & PF_THOKKED)) + { + player->pflags |= PF_THOKKED|PF_SHIELDABILITY; + S_StartSound(player->mo, sfx_s3k43); + player->mo->momx = player->mo->momy = 0; + P_SetObjectMomZ(player->mo, -24*FRACUNIT, false); } } }