Esempio n. 1
0
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;
}
Esempio n. 2
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);
	}
}
Esempio n. 3
0
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();
			}
		}
	}