DEFINE_ACTION_FUNCTION(AActor, A_SerpentHeadCheck) { PARAM_ACTION_PROLOGUE; if (self->Z() <= self->floorz) { if (Terrains[P_GetThingFloorType(self)].IsLiquid) { P_HitFloor (self); self->SetState (NULL); } else { self->SetState (self->FindState(NAME_Death)); } } return 0; }
void P_PlayerInSpecialSector(player_t *player) { sector_t *sector; static int pushTab[5] = { 2048*5, 2048*10, 2048*25, 2048*30, 2048*35 }; sector = player->mo->subsector->sector; if(player->mo->z != sector->floorheight) { // Player is not touching the floor return; } switch(sector->special) { case 7: // Damage_Sludge if(!(leveltime&31)) { P_DamageMobj(player->mo, NULL, NULL, 4); } break; case 5: // Damage_LavaWimpy if(!(leveltime&15)) { P_DamageMobj(player->mo, &LavaInflictor, NULL, 5); P_HitFloor(player->mo); } break; case 16: // Damage_LavaHefty if(!(leveltime&15)) { P_DamageMobj(player->mo, &LavaInflictor, NULL, 8); P_HitFloor(player->mo); } break; case 4: // Scroll_EastLavaDamage P_Thrust(player, 0, 2048*28); if(!(leveltime&15)) { P_DamageMobj(player->mo, &LavaInflictor, NULL, 5); P_HitFloor(player->mo); } break; case 9: // SecretArea player->secretcount++; sector->special = 0; break; case 11: // Exit_SuperDamage (DOOM E1M8 finale) /* player->cheats &= ~CF_GODMODE; if(!(leveltime&0x1f)) { P_DamageMobj(player->mo, NULL, NULL, 20); } if(player->health <= 10) { G_ExitLevel(); } */ break; case 25: case 26: case 27: case 28: case 29: // Scroll_North P_Thrust(player, ANG90, pushTab[sector->special-25]); break; case 20: case 21: case 22: case 23: case 24: // Scroll_East P_Thrust(player, 0, pushTab[sector->special-20]); break; case 30: case 31: case 32: case 33: case 34: // Scroll_South P_Thrust(player, ANG270, pushTab[sector->special-30]); break; case 35: case 36: case 37: case 38: case 39: // Scroll_West P_Thrust(player, ANG180, pushTab[sector->special-35]); break; case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47: case 48: case 49: case 50: case 51: // Wind specials are handled in (P_mobj):P_XYMovement break; case 15: // Friction_Low // Only used in (P_mobj):P_XYMovement and (P_user):P_Thrust break; default: I_Error("P_PlayerInSpecialSector: " "unknown special %i", sector->special); } }
void AFastProjectile::Tick () { int i; DVector3 frac; int changexy; ClearInterpolation(); double oldz = Z(); if (!(flags5 & MF5_NOTIMEFREEZE)) { //Added by MC: Freeze mode. if (bglobal.freeze || level.flags2 & LEVEL2_FROZEN) { return; } } // [RH] Ripping is a little different than it was in Hexen FCheckPosition tm(!!(flags2 & MF2_RIP)); int count = 8; if (radius > 0) { while ( fabs(Vel.X) > radius * count || fabs(Vel.Y) > radius * count) { // we need to take smaller steps. count += count; } } // Handle movement if (!Vel.isZero() || (Z() != floorz)) { // force some lateral movement so that collision detection works as intended. if ((flags & MF_MISSILE) && Vel.X == 0 && Vel.Y == 0 && !IsZeroDamage()) { Vel.X = MinVel; } frac = Vel / count; changexy = frac.X != 0 || frac.Y != 0; int ripcount = count / 8; for (i = 0; i < count; i++) { if (changexy) { if (--ripcount <= 0) { tm.LastRipped.Clear(); // [RH] Do rip damage each step, like Hexen } if (!P_TryMove (this, Pos() + frac, true, NULL, tm)) { // Blocked move if (!(flags3 & MF3_SKYEXPLODE)) { if (tm.ceilingline && tm.ceilingline->backsector && tm.ceilingline->backsector->GetTexture(sector_t::ceiling) == skyflatnum && Z() >= tm.ceilingline->backsector->ceilingplane.ZatPoint(PosRelative(tm.ceilingline))) { // Hack to prevent missiles exploding against the sky. // Does not handle sky floors. Destroy (); return; } // [RH] Don't explode on horizon lines. if (BlockingLine != NULL && BlockingLine->special == Line_Horizon) { Destroy (); return; } } P_ExplodeMissile (this, BlockingLine, BlockingMobj); return; } } AddZ(frac.Z); UpdateWaterLevel (); oldz = Z(); if (oldz <= floorz) { // Hit the floor if (floorpic == skyflatnum && !(flags3 & MF3_SKYEXPLODE)) { // [RH] Just remove the missile without exploding it // if this is a sky floor. Destroy (); return; } SetZ(floorz); P_HitFloor (this); P_ExplodeMissile (this, NULL, NULL); return; } if (Top() > ceilingz) { // Hit the ceiling if (ceilingpic == skyflatnum && !(flags3 & MF3_SKYEXPLODE)) { Destroy (); return; } SetZ(ceilingz - Height); P_ExplodeMissile (this, NULL, NULL); return; } if (!frac.isZero() && ripcount <= 0) { ripcount = count >> 3; Effect(); } } }