diff --git a/src/info.c b/src/info.c index f56e5d78e..65185517a 100644 --- a/src/info.c +++ b/src/info.c @@ -7977,7 +7977,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = DMG_SPIKE, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + MF_SOLID|MF_SCENERY, // flags S_NULL // raisestate }, @@ -8004,7 +8004,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = DMG_SPIKE, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOGRAVITY|MF_SCENERY|MF_NOCLIPHEIGHT|MF_PAPERCOLLISION, // flags + MF_SOLID|MF_NOGRAVITY|MF_SCENERY|MF_PAPERCOLLISION, // flags S_NULL // raisestate }, @@ -8031,7 +8031,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 4, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPTHING, // flags + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_SCENERY|MF_NOCLIP|MF_NOCLIPTHING, // flags S_NULL // raisestate }, diff --git a/src/p_map.c b/src/p_map.c index 836e75c4e..b2dd52127 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1465,86 +1465,6 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } - // Sprite Spikes! - // Do not return because solidity code comes below. - if (tmthing->type == MT_SPIKE && tmthing->flags & MF_SOLID && thing->player) // moving spike rams into player?! - { - if (tmthing->eflags & MFE_VERTICALFLIP) - { - if (thing->z + thing->height <= tmthing->z + FixedMul(FRACUNIT, tmthing->scale) - && thing->z + thing->height + thing->momz >= tmthing->z + FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz - && !(thing->player->charability == CA_BOUNCE && thing->player->panim == PA_ABILITY && thing->eflags & MFE_VERTICALFLIP)) - P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE); - } - else if (thing->z >= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale) - && thing->z + thing->momz <= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz - && !(thing->player->charability == CA_BOUNCE && thing->player->panim == PA_ABILITY && !(thing->eflags & MFE_VERTICALFLIP))) - P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE); - } - else if (thing->type == MT_SPIKE && thing->flags & MF_SOLID && tmthing->player) // unfortunate player falls into spike?! - { - if (thing->eflags & MFE_VERTICALFLIP) - { - if (tmthing->z + tmthing->height <= thing->z - FixedMul(FRACUNIT, thing->scale) - && tmthing->z + tmthing->height + tmthing->momz >= thing->z - FixedMul(FRACUNIT, thing->scale) - && !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && tmthing->eflags & MFE_VERTICALFLIP)) - P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE); - } - else if (tmthing->z >= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) - && tmthing->z + tmthing->momz <= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) - && !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && !(tmthing->eflags & MFE_VERTICALFLIP))) - P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE); - } - - if (tmthing->type == MT_WALLSPIKE && tmthing->flags & MF_SOLID && thing->player) // wall spike impales player - { - fixed_t bottomz, topz; - bottomz = tmthing->z; - topz = tmthing->z + tmthing->height; - if (tmthing->eflags & MFE_VERTICALFLIP) - bottomz -= FixedMul(FRACUNIT, tmthing->scale); - else - topz += FixedMul(FRACUNIT, tmthing->scale); - - if (thing->z + thing->height > bottomz // above bottom - && thing->z < topz) // below top - // don't check angle, the player was clearly in the way in this case - P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE); - } - else if (thing->type == MT_WALLSPIKE && thing->flags & MF_SOLID && tmthing->player) - { - fixed_t bottomz, topz; - angle_t touchangle = R_PointToAngle2(thing->tracer->x, thing->tracer->y, tmthing->x, tmthing->y); - - if (P_PlayerInPain(tmthing->player) && (tmthing->momx || tmthing->momy)) - { - angle_t playerangle = R_PointToAngle2(0, 0, tmthing->momx, tmthing->momy) - touchangle; - if (playerangle > ANGLE_180) - playerangle = InvAngle(playerangle); - if (playerangle < ANGLE_90) - return true; // Yes, this is intentionally outside the z-height check. No standing on spikes whilst moving away from them. - } - - bottomz = thing->z; - topz = thing->z + thing->height; - - if (thing->eflags & MFE_VERTICALFLIP) - bottomz -= FixedMul(FRACUNIT, thing->scale); - else - topz += FixedMul(FRACUNIT, thing->scale); - - if (tmthing->z + tmthing->height > bottomz // above bottom - && tmthing->z < topz // below top - && !P_MobjWasRemoved(thing->tracer)) // this probably wouldn't work if we didn't have a tracer - { // use base as a reference point to determine what angle you touched the spike at - touchangle = thing->angle - touchangle; - if (touchangle > ANGLE_180) - touchangle = InvAngle(touchangle); - if (touchangle <= ANGLE_22h) // if you touched it at this close an angle, you get poked! - P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE); - } - } - if (thing->flags & MF_PUSHABLE) { if (tmthing->type == MT_FAN || tmthing->type == MT_STEAM) @@ -1623,6 +1543,22 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->player) { + if (tmthing->type == MT_WALLSPIKE && (tmthing->flags & MF_SOLID)) // wall spike impales player + { + fixed_t bottomz, topz; + bottomz = tmthing->z; + topz = tmthing->z + tmthing->height; + if (tmthing->eflags & MFE_VERTICALFLIP) + bottomz -= FixedMul(FRACUNIT, tmthing->scale); + else + topz += FixedMul(FRACUNIT, tmthing->scale); + + if (thing->z + thing->height > bottomz // above bottom + && thing->z < topz) // below top + // don't check angle, the player was clearly in the way in this case + P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE); + } + // Doesn't matter what gravity player's following! Just do your stuff in YOUR direction only if (tmthing->eflags & MFE_VERTICALFLIP && (tmthing->z + tmthing->height + tmthing->momz < thing->z @@ -1657,6 +1593,55 @@ static boolean PIT_CheckThing(mobj_t *thing) if (!tmthing->health) return true; + if (thing->type == MT_SPIKE && (thing->flags & MF_SOLID)) // unfortunate player falls into spike?! + { + if (thing->eflags & MFE_VERTICALFLIP) + { + if (tmthing->z + tmthing->height <= thing->z - FixedMul(FRACUNIT, thing->scale) + && tmthing->z + tmthing->height + tmthing->momz >= thing->z - FixedMul(FRACUNIT, thing->scale) + && !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && tmthing->eflags & MFE_VERTICALFLIP)) + P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE); + } + else if (tmthing->z >= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) + && tmthing->z + tmthing->momz <= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) + && !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && !(tmthing->eflags & MFE_VERTICALFLIP))) + P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE); + } + + if (thing->type == MT_WALLSPIKE && (thing->flags & MF_SOLID)) + { + fixed_t bottomz, topz; + angle_t touchangle = R_PointToAngle2(thing->tracer->x, thing->tracer->y, tmthing->x, tmthing->y); + + if (P_PlayerInPain(tmthing->player) && (tmthing->momx || tmthing->momy)) + { + angle_t playerangle = R_PointToAngle2(0, 0, tmthing->momx, tmthing->momy) - touchangle; + if (playerangle > ANGLE_180) + playerangle = InvAngle(playerangle); + if (playerangle < ANGLE_90) + return true; // Yes, this is intentionally outside the z-height check. No standing on spikes whilst moving away from them. + } + + bottomz = thing->z; + topz = thing->z + thing->height; + + if (thing->eflags & MFE_VERTICALFLIP) + bottomz -= FixedMul(FRACUNIT, thing->scale); + else + topz += FixedMul(FRACUNIT, thing->scale); + + if (tmthing->z + tmthing->height > bottomz // above bottom + && tmthing->z < topz // below top + && !P_MobjWasRemoved(thing->tracer)) // this probably wouldn't work if we didn't have a tracer + { // use base as a reference point to determine what angle you touched the spike at + touchangle = thing->angle - touchangle; + if (touchangle > ANGLE_180) + touchangle = InvAngle(touchangle); + if (touchangle <= ANGLE_22h) // if you touched it at this close an angle, you get poked! + P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE); + } + } + if (thing->type == MT_FAN || thing->type == MT_STEAM) P_DoFanAndGasJet(thing, tmthing); else if (thing->flags & MF_SPRING && tmthing->player->powers[pw_carry] != CR_MINECART) @@ -1721,8 +1706,8 @@ static boolean PIT_CheckThing(mobj_t *thing) } } - if ((tmthing->flags & MF_SPRING || tmthing->type == MT_STEAM || tmthing->type == MT_SPIKE || tmthing->type == MT_WALLSPIKE) && (thing->player)) - ; // springs, gas jets and springs should never be able to step up onto a player + if ((thing->player) && (tmthing->flags & MF_SPRING || tmthing->type == MT_STEAM)) + ; // springs and gas jets should never be able to step up onto a player // z checking at last // Treat noclip things as non-solid! else if ((thing->flags & (MF_SOLID|MF_NOCLIP)) == MF_SOLID @@ -1730,6 +1715,9 @@ static boolean PIT_CheckThing(mobj_t *thing) { fixed_t topz, tmtopz; + if (tmthing->type == MT_SPIKE || tmthing->type == MT_WALLSPIKE) // do not run height checks if you are a spike + return true; + if (tmthing->eflags & MFE_VERTICALFLIP) { // pass under diff --git a/src/p_mobj.c b/src/p_mobj.c index 83f9ebf3c..e43414a80 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7842,6 +7842,48 @@ static void P_MobjSceneryThink(mobj_t *mobj) if (P_MobjFlip(mobj)*mobj->momz < mobj->info->speed) mobj->momz = P_MobjFlip(mobj)*mobj->info->speed; break; + case MT_SPIKE: + if (mobj->fuse) + { + mobj->fuse--; + break; + } + P_SetMobjState(mobj, mobj->state->nextstate); + mobj->fuse = mobj->info->speed; + if (mobj->spawnpoint) + mobj->fuse += mobj->spawnpoint->angle; + break; + case MT_WALLSPIKE: + if (mobj->fuse) + { + mobj->fuse--; + break; + } + P_SetMobjState(mobj, mobj->state->nextstate); + mobj->fuse = mobj->info->speed; + if (mobj->spawnpoint) + mobj->fuse += (mobj->spawnpoint->angle / 360); + break; + case MT_WALLSPIKEBASE: + if (!mobj->target) + { + P_RemoveMobj(mobj); + return; + } + mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|(mobj->target->frame & FF_FRAMEMASK); +#if 0 + if (mobj->angle != mobj->target->angle + ANGLE_90) // reposition if not the correct angle + { + mobj_t* target = mobj->target; // shortcut + const fixed_t baseradius = target->radius - (target->scale/2); //FixedMul(FRACUNIT/2, target->scale); + P_UnsetThingPosition(mobj); + mobj->x = target->x - P_ReturnThrustX(target, target->angle, baseradius); + mobj->y = target->y - P_ReturnThrustY(target, target->angle, baseradius); + P_SetThingPosition(mobj); + mobj->angle = target->angle + ANGLE_90; + } +#endif + break; case MT_ROCKCRUMBLE1: case MT_ROCKCRUMBLE2: case MT_ROCKCRUMBLE3: @@ -9238,25 +9280,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj) switch (mobj->type) { - case MT_WALLSPIKEBASE: - if (!mobj->target) { - P_RemoveMobj(mobj); - return false; - } - mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|(mobj->target->frame & FF_FRAMEMASK); -#if 0 - if (mobj->angle != mobj->target->angle + ANGLE_90) // reposition if not the correct angle - { - mobj_t* target = mobj->target; // shortcut - const fixed_t baseradius = target->radius - (target->scale/2); //FixedMul(FRACUNIT/2, target->scale); - P_UnsetThingPosition(mobj); - mobj->x = target->x - P_ReturnThrustX(target, target->angle, baseradius); - mobj->y = target->y - P_ReturnThrustY(target, target->angle, baseradius); - P_SetThingPosition(mobj); - mobj->angle = target->angle + ANGLE_90; - } -#endif - break; case MT_FALLINGROCK: // Despawn rocks here in case zmovement code can't do so (blame slopes) if (!mobj->momx && !mobj->momy && !mobj->momz @@ -9942,18 +9965,6 @@ static boolean P_FuseThink(mobj_t *mobj) break; case MT_METALSONIC_BATTLE: break; // don't remove - case MT_SPIKE: - P_SetMobjState(mobj, mobj->state->nextstate); - mobj->fuse = mobj->info->speed; - if (mobj->spawnpoint) - mobj->fuse += mobj->spawnpoint->angle; - break; - case MT_WALLSPIKE: - P_SetMobjState(mobj, mobj->state->nextstate); - mobj->fuse = mobj->info->speed; - if (mobj->spawnpoint) - mobj->fuse += (mobj->spawnpoint->angle / 360); - break; case MT_NIGHTSCORE: P_RemoveMobj(mobj); return false; @@ -12956,17 +12967,18 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean // Pop up spikes! if (mthing->options & MTF_OBJECTSPECIAL) { - mobj->flags &= ~MF_SCENERY; mobj->fuse = (16 - mthing->extrainfo)*(mthing->angle + mobj->info->speed)/16; if (mthing->options & MTF_EXTRA) P_SetMobjState(mobj, mobj->info->meleestate); } - // Use per-thing collision for spikes if the deaf flag isn't checked. - if (!(mthing->options & MTF_AMBUSH) && !metalrecording) + else + mobj->flags |= MF_NOTHINK; + // no collision for spikes if the ambush flag is checked + if ((mthing->options & MTF_AMBUSH) || metalrecording) { P_UnsetThingPosition(mobj); - mobj->flags &= ~(MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT); - mobj->flags |= MF_SOLID; + mobj->flags |= (MF_NOBLOCKMAP|MF_NOCLIPHEIGHT); + mobj->flags &= ~MF_SOLID; P_SetThingPosition(mobj); } break; @@ -12974,20 +12986,20 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean // Pop up spikes! if (mthing->options & MTF_OBJECTSPECIAL) { - mobj->flags &= ~MF_SCENERY; mobj->fuse = (16 - mthing->extrainfo)*((mthing->angle/360) + mobj->info->speed)/16; if (mthing->options & MTF_EXTRA) P_SetMobjState(mobj, mobj->info->meleestate); } - // Use per-thing collision for spikes if the deaf flag isn't checked. - if (!(mthing->options & MTF_AMBUSH) && !metalrecording) + else + mobj->flags |= MF_NOTHINK; + // no collision for spikes if the ambush flag is checked + if ((mthing->options & MTF_AMBUSH) || metalrecording) { P_UnsetThingPosition(mobj); - mobj->flags &= ~(MF_NOBLOCKMAP | MF_NOCLIPHEIGHT); - mobj->flags |= MF_SOLID; + mobj->flags |= (MF_NOBLOCKMAP|MF_NOCLIPHEIGHT); + mobj->flags &= ~MF_SOLID; P_SetThingPosition(mobj); } - // spawn base { const angle_t mobjangle = FixedAngle(mthing->angle << FRACBITS); // the mobj's own angle hasn't been set quite yet so... @@ -13001,6 +13013,8 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean P_SetScale(base, mobj->scale); P_SetTarget(&base->target, mobj); P_SetTarget(&mobj->tracer, base); + if (!(mthing->options & MTF_OBJECTSPECIAL)) + base->flags |= MF_NOTHINK; } break; case MT_RING_BOX: