diff --git a/src/info.c b/src/info.c index 382ecba7fbb5205b146ab90a5e5c46096ee9034a..ab46cdbc728de4d8d71c39e97adf245235301acc 100644 --- a/src/info.c +++ b/src/info.c @@ -7493,12 +7493,12 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_steam1, // deathsound 0, // speed 32*FRACUNIT, // radius - 1*FRACUNIT, // height + 16*FRACUNIT, // height 0, // display offset 20*FRACUNIT, // mass 0, // damage sfx_None, // activesound - MF_SOLID, // flags + MF_SPECIAL, // flags S_NULL // raisestate }, diff --git a/src/p_enemy.c b/src/p_enemy.c index d0ed0a24e3463fa4afa65ce663f4835803b234d4..4990db6fd50a2f96102056984b4d02e3c0205ddb 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5194,7 +5194,7 @@ void A_SetSolidSteam(mobj_t *actor) return; actor->flags &= ~MF_NOCLIP; - actor->flags |= MF_SOLID; + actor->flags |= MF_SPECIAL; if (!(actor->flags2 & MF2_AMBUSH)) { if (P_RandomChance(FRACUNIT/8)) @@ -5224,7 +5224,7 @@ void A_UnsetSolidSteam(mobj_t *actor) if (LUA_CallAction(A_UNSETSOLIDSTEAM, actor)) return; - actor->flags &= ~MF_SOLID; + actor->flags &= ~MF_SPECIAL; actor->flags |= MF_NOCLIP; } diff --git a/src/p_inter.c b/src/p_inter.c index 5534f7865c23afc2d70ceae209e6ea432f6223f8..406f4af2227d294adb2883433009b4699b9881bf 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -392,17 +392,50 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } } + // Ignore multihits in "ouchie" mode + if (special->flags & (MF_ENEMY | MF_BOSS) && special->flags2 & MF2_FRET) + return; + player = toucher->player; - I_Assert(player != NULL); // Only players can touch stuff! - if (player->spectator) - return; + if (player) + { + if (player->spectator) + return; - // Ignore multihits in "ouchie" mode - if (special->flags & (MF_ENEMY|MF_BOSS) && special->flags2 & MF2_FRET) - return; + // Some hooks may assume that the toucher is a player, so we keep it in here. + if (LUA_HookTouchSpecial(special, toucher) || P_MobjWasRemoved(special)) + return; + } - if (LUA_HookTouchSpecial(special, toucher) || P_MobjWasRemoved(special)) + if (player || (toucher->flags & MF_PUSHABLE)) // Special area for objects that are interactable by both player AND MF_PUSHABLE. + { + if (special->type == MT_STEAM) + { + if (player && player->mo->state == &states[player->mo->info->painstate]) // can't use gas jets when player is in pain! + return; + + fixed_t speed = special->info->mass; // gas jets use this for the vertical thrust + SINT8 flipval = P_MobjFlip(special); // virtually everything here centers around the thruster's gravity, not the object's! + + if (special->state != &states[S_STEAM1]) // Only when it bursts + return; + + toucher->eflags |= MFE_SPRUNG; + toucher->momz = flipval * FixedMul(speed, FixedSqrt(FixedMul(special->scale, toucher->scale))); // scale the speed with both objects' scales, just like with springs! + + if (player) + { + P_ResetPlayer(player); + if (player->panim != PA_FALL) + P_SetMobjState(toucher, S_PLAY_FALL); + } + + return; // Don't collect it! + } + } + + if (!player) // Only players can touch stuff! return; // 0 = none, 1 = elemental pierce, 2 = bubble bounce @@ -1881,6 +1914,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) toucher->tracer->flags2 = (toucher->tracer->flags2 & ~MF2_AMBUSH) | destambush; } return; + default: // SOC or script pickup if (player->bot && player->bot != BOT_MPAI) return; diff --git a/src/p_map.c b/src/p_map.c index 7b64fe3bb782de111f0b70053306ce851a1ea190..f97ddfa3cd8aa3fa9f7e9dbb3e6d76b041aca164 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -502,72 +502,56 @@ springstate: return final; } -static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) +static void P_DoFan(mobj_t *fan, mobj_t *object) { player_t *p = object->player; // will be NULL if not a player fixed_t zdist; // distance between bottoms - fixed_t speed = spring->info->mass; // conveniently, both fans and gas jets use this for the vertical thrust - SINT8 flipval = P_MobjFlip(spring); // virtually everything here centers around the thruster's gravity, not the object's! + fixed_t speed = fan->info->mass; // fans use this for the vertical thrust + SINT8 flipval = P_MobjFlip(fan); // virtually everything here centers around the thruster's gravity, not the object's! - if (p && object->state == &states[object->info->painstate]) // can't use fans and gas jets when player is in pain! + if (p && object->state == &states[object->info->painstate]) // can't use fans when player is in pain! return; // is object's top below thruster's position? if not, calculate distance between their bottoms - if (spring->eflags & MFE_VERTICALFLIP) + if (fan->eflags & MFE_VERTICALFLIP) { - if (object->z > spring->z + spring->height) + if (object->z > fan->z + fan->height) return; - zdist = (spring->z + spring->height) - (object->z + object->height); + zdist = (fan->z + fan->height) - (object->z + object->height); } else { - if (object->z + object->height < spring->z) + if (object->z + object->height < fan->z) return; - zdist = object->z - spring->z; + zdist = object->z - fan->z; } object->standingslope = NULL; // No launching off at silly angles for you. - switch (spring->type) + switch (fan->type) { case MT_FAN: // fan - if (zdist > (spring->health << FRACBITS)) // max z distance determined by health (set by map thing args[0]) + if (zdist > (fan->health << FRACBITS)) // max z distance determined by health (set by map thing args[0]) break; - if (flipval*object->momz >= FixedMul(speed, spring->scale)) // if object's already moving faster than your best, don't bother + if (flipval*object->momz >= FixedMul(speed, fan->scale)) // if object's already moving faster than your best, don't bother break; if (p && (p->climbing || p->pflags & PF_GLIDING)) // doesn't affect Knux when he's using his abilities! break; - object->momz += flipval*FixedMul(speed/4, spring->scale); + object->momz += flipval*FixedMul(speed/4, fan->scale); // limit the speed if too high - if (flipval*object->momz > FixedMul(speed, spring->scale)) - object->momz = flipval*FixedMul(speed, spring->scale); + if (flipval*object->momz > FixedMul(speed, fan->scale)) + object->momz = flipval*FixedMul(speed, fan->scale); if (p && !p->powers[pw_tailsfly] && !p->powers[pw_carry]) // doesn't reset anim for Tails' flight { P_ResetPlayer(p); P_SetMobjState(object, S_PLAY_FALL); - P_SetTarget(&object->tracer, spring); + P_SetTarget(&object->tracer, fan); p->powers[pw_carry] = CR_FAN; } break; - case MT_STEAM: // Steam - if (zdist > FixedMul(16*FRACUNIT, spring->scale)) - break; - if (spring->state != &states[S_STEAM1]) // Only when it bursts - break; - - object->eflags |= MFE_SPRUNG; - object->momz = flipval*FixedMul(speed, FixedSqrt(FixedMul(spring->scale, object->scale))); // scale the speed with both objects' scales, just like with springs! - - if (p) - { - P_ResetPlayer(p); - if (p->panim != PA_FALL) - P_SetMobjState(object, S_PLAY_FALL); - } - break; default: break; } @@ -1484,13 +1468,13 @@ static unsigned PIT_DoCheckThing(mobj_t *thing) } // check for special pickup - if (thing->flags & MF_SPECIAL && tmthing->player) + if (thing->flags & MF_SPECIAL) { P_TouchSpecialThing(thing, tmthing, true); // can remove thing return CHECKTHING_COLLIDE; } // check again for special pickup - if (tmthing->flags & MF_SPECIAL && thing->player) + if (tmthing->flags & MF_SPECIAL) { P_TouchSpecialThing(tmthing, thing, true); // can remove thing return CHECKTHING_COLLIDE; @@ -1578,15 +1562,15 @@ static unsigned PIT_DoCheckThing(mobj_t *thing) if (thing->flags & MF_PUSHABLE) { - if (tmthing->type == MT_FAN || tmthing->type == MT_STEAM) - P_DoFanAndGasJet(tmthing, thing); + if (tmthing->type == MT_FAN) + P_DoFan(tmthing, thing); } if (tmthing->flags & MF_PUSHABLE) { - if (thing->type == MT_FAN || thing->type == MT_STEAM) + if (thing->type == MT_FAN) { - P_DoFanAndGasJet(thing, tmthing); + P_DoFan(thing, tmthing); return CHECKTHING_COLLIDE; } else if (thing->flags & MF_SPRING) @@ -1679,8 +1663,8 @@ static unsigned PIT_DoCheckThing(mobj_t *thing) } } - if (tmthing->type == MT_FAN || tmthing->type == MT_STEAM) - P_DoFanAndGasJet(tmthing, thing); + if (tmthing->type == MT_FAN) + P_DoFan(tmthing, thing); } if (tmthing->player) // Is the moving/interacting object the player? @@ -1688,8 +1672,8 @@ static unsigned PIT_DoCheckThing(mobj_t *thing) if (!tmthing->health) return CHECKTHING_IGNORE; - if (thing->type == MT_FAN || thing->type == MT_STEAM) - P_DoFanAndGasJet(thing, tmthing); + if (thing->type == MT_FAN) + P_DoFan(thing, tmthing); else if (thing->flags & MF_SPRING && tmthing->player->powers[pw_carry] != CR_MINECART) { if ( thing->z <= tmthing->z + tmthing->height @@ -1755,8 +1739,8 @@ static unsigned PIT_DoCheckThing(mobj_t *thing) // not solid not blocked unsigned collide = CHECKTHING_NOCOLLIDE; - 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 ((tmthing->flags & MF_SPRING || tmthing->type == MT_SPIKE || tmthing->type == MT_WALLSPIKE) && (thing->player)) + ; // springs and spikes 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