Ejemplo n.º 1
0
DEFINE_ACTION_FUNCTION(AActor, A_Beacon)
{
	PARAM_ACTION_PROLOGUE;

	AActor *owner = self->target;
	AActor *rebel;

	rebel = Spawn("Rebel1", self->PosAtZ(self->floorz), ALLOW_REPLACE);
	if (!P_TryMove (rebel, rebel->Pos(), true))
	{
		rebel->Destroy ();
		return 0;
	}
	// Once the rebels start teleporting in, you can't pick up the beacon anymore.
	self->flags &= ~MF_SPECIAL;
	static_cast<AInventory *>(self)->DropTime = 0;
	// Set up the new rebel.
	rebel->threshold = rebel->DefThreshold;
	rebel->target = NULL;
	rebel->flags4 |= MF4_INCOMBAT;
	rebel->LastHeard = owner;	// Make sure the rebels look for targets
	if (deathmatch)
	{
		rebel->health *= 2;
	}
	if (owner != NULL)
	{
		// Rebels are the same color as their owner (but only in multiplayer)
		if (multiplayer)
		{
			rebel->Translation = owner->Translation;
		}
		rebel->SetFriendPlayer(owner->player);
		// Set the rebel's target to whatever last hurt the player, so long as it's not
		// one of the player's other rebels.
		if (owner->target != NULL && !rebel->IsFriend (owner->target))
		{
			rebel->target = owner->target;
		}
	}

	rebel->SetState (rebel->SeeState);
	rebel->Angles.Yaw = self->Angles.Yaw;
	Spawn<ATeleportFog> (rebel->Vec3Angle(20., self->Angles.Yaw, TELEFOGHEIGHT), ALLOW_REPLACE);
	if (--self->health < 0)
	{
		self->SetState(self->FindState(NAME_Death));
	}
	return 0;
}
Ejemplo n.º 2
0
void A_BishopMissileWeave (AActor *actor)
{
	fixed_t newX, newY;
	int weaveXY, weaveZ;
	int angle;

	weaveXY = actor->special2 >> 16;
	weaveZ = actor->special2 & 0xFFFF;
	angle = (actor->angle + ANG90) >> ANGLETOFINESHIFT;
	newX = actor->x - FixedMul (finecosine[angle], FloatBobOffsets[weaveXY]<<1);
	newY = actor->y - FixedMul (finesine[angle], FloatBobOffsets[weaveXY]<<1);
	weaveXY = (weaveXY + 2) & 63;
	newX += FixedMul (finecosine[angle], FloatBobOffsets[weaveXY]<<1);
	newY += FixedMul (finesine[angle], FloatBobOffsets[weaveXY]<<1);
	P_TryMove (actor, newX, newY, true);
	actor->z -= FloatBobOffsets[weaveZ];
	weaveZ = (weaveZ + 2) & 63;
	actor->z += FloatBobOffsets[weaveZ];	
	actor->special2 = weaveZ + (weaveXY<<16);
}
Ejemplo n.º 3
0
DEFINE_ACTION_FUNCTION(AActor, A_BishopMissileWeave)
{
	fixed_t newX, newY;
	int weaveXY, weaveZ;
	int angle;

	if (self->special2 == 0) self->special2 = 16;

	weaveXY = self->special2 >> 16;
	weaveZ = self->special2 & 0xFFFF;
	angle = (self->angle + ANG90) >> ANGLETOFINESHIFT;
	newX = self->x - FixedMul (finecosine[angle], FloatBobOffsets[weaveXY]<<1);
	newY = self->y - FixedMul (finesine[angle], FloatBobOffsets[weaveXY]<<1);
	weaveXY = (weaveXY + 2) & 63;
	newX += FixedMul (finecosine[angle], FloatBobOffsets[weaveXY]<<1);
	newY += FixedMul (finesine[angle], FloatBobOffsets[weaveXY]<<1);
	P_TryMove (self, newX, newY, true);
	self->z -= FloatBobOffsets[weaveZ];
	weaveZ = (weaveZ + 2) & 63;
	self->z += FloatBobOffsets[weaveZ];	
	self->special2 = weaveZ + (weaveXY<<16);
}
Ejemplo n.º 4
0
int EV_Teleport( line_t *line,mobj_t *thing )
{
   int      i;
   int      tag;
   boolean  flag;
   mobj_t   *m,*fog;
   unsigned int	an;
   sector_t *sector;
   fixed_t   oldx, oldy, oldz;
   int       side;
	
   side = !P_PointOnLineSide (thing->x, thing->y, line);

   if(thing->flags & MF_MISSILE)
      return 0; /* don't teleport missiles */

   if(side == 1) /* don't teleport if hit back of line, */
      return 0;  /* so you can get out of teleporter */
	
   tag = line->tag;
   for(i = 0; i < numsectors; i++)
   {
      if (sectors[ i ].tag == tag )
      {
         for(m = mobjhead.next; m != &mobjhead; m = m->next)
         {
            // CALICO: skip removed mobjs
            if(m->latecall == P_RemoveMobjDeferred)
               continue;

            if(m->type != MT_TELEPORTMAN)
               continue; // not a teleportman

            sector = m->subsector->sector;
            if(sector-sectors != i )
               continue; // wrong sector

            oldx = thing->x;
            oldy = thing->y;
            oldz = thing->z;
            thing->flags |= MF_TELEPORT;
            P_Telefrag(thing, m->x, m->y);
            flag = P_TryMove (thing, m->x, m->y);
            thing->flags &= ~MF_TELEPORT;
            if(!flag)
               return 0; /* move is blocked */
            thing->z = thing->floorz;
            
            /* spawn teleport fog at source and destination */
            fog = P_SpawnMobj (oldx, oldy, oldz, MT_TFOG);
            S_StartSound(fog, sfx_telept);
            an  = m->angle >> ANGLETOFINESHIFT;
            fog = P_SpawnMobj (m->x+20*finecosine[an], m->y+20*finesine[an], thing->z, MT_TFOG);
            S_StartSound(fog, sfx_telept);
            if(thing->player)
               thing->reactiontime = 18;	/* don't move for a bit */
            thing->angle = m->angle;
            thing->momx = thing->momy = thing->momz = 0;
            return 1;
         }	
      }
   }
   return 0;
}
Ejemplo n.º 5
0
DEFINE_ACTION_FUNCTION(AActor, A_Beacon)
{
	AActor *owner = self->target;
	AActor *rebel;
	angle_t an;
	// [BC]
	AActor	*pFog;

	// [BC] This is handled server-side.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		return;
	}

	rebel = Spawn("Rebel1", self->x, self->y, self->floorz, ALLOW_REPLACE);
	if (!P_TryMove (rebel, rebel->x, rebel->y, true))
	{
		rebel->Destroy ();
		return;
	}
	// Once the rebels start teleporting in, you can't pick up the beacon anymore.
	self->flags &= ~MF_SPECIAL;
	static_cast<AInventory *>(self)->DropTime = 0;
	// Set up the new rebel.
	rebel->threshold = BASETHRESHOLD;
	rebel->target = NULL;
	rebel->flags4 |= MF4_INCOMBAT;
	rebel->LastHeard = owner;	// Make sure the rebels look for targets
	if (deathmatch)
	{
		rebel->health *= 2;
	}
	if (owner != NULL)
	{
		// Rebels are the same color as their owner (but only in multiplayer)
		// [BB] Changed "multiplayer" check
		if ( NETWORK_GetState( ) != NETSTATE_SINGLE )
		{
			rebel->Translation = owner->Translation;
		}
		rebel->FriendPlayer = owner->player != NULL ? BYTE(owner->player - players + 1) : 0;
		// Set the rebel's target to whatever last hurt the player, so long as it's not
		// one of the player's other rebels.
		if (owner->target != NULL && !rebel->IsFriend (owner->target))
		{
			rebel->target = owner->target;
		}
	}

	// [BC] Spawn the rebel, and put him in the see state.
	if ( NETWORK_GetState( ) == NETSTATE_SERVER )
	{
		SERVERCOMMANDS_SpawnThing( rebel );
		SERVERCOMMANDS_SetThingState( rebel, STATE_SEE );
	}

	rebel->SetState (rebel->SeeState);
	rebel->angle = self->angle;
	an = self->angle >> ANGLETOFINESHIFT;
	pFog = Spawn<ATeleportFog> (rebel->x + 20*finecosine[an], rebel->y + 20*finesine[an], rebel->z + TELEFOGHEIGHT, ALLOW_REPLACE);
	// [BC] Spawn the teleport fog.
	if (( NETWORK_GetState( ) == NETSTATE_SERVER ) &&
		( pFog ))
	{
		SERVERCOMMANDS_SpawnThing( pFog );
	}

	if (--self->health < 0)
	{
		// [BB] Tell clients to set the thing's state.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			SERVERCOMMANDS_SetThingState( self, STATE_DEATH );

		self->SetState(self->FindState(NAME_Death));
	}
}
Ejemplo n.º 6
0
void P_XYMovement (mobj_t* mo) 
{ 	
    fixed_t 	ptryx;
    fixed_t	ptryy;
    player_t*	player;
    fixed_t	xmove;
    fixed_t	ymove;
			
    if (!mo->momx && !mo->momy)
    {
	if (mo->flags & MF_SKULLFLY)
	{
	    // the skull slammed into something
	    mo->flags &= ~MF_SKULLFLY;
	    mo->momx = mo->momy = mo->momz = 0;

	    P_SetMobjState (mo, mo->info->spawnstate);
	}
	return;
    }
	
    player = mo->player;
		
    if (mo->momx > MAXMOVE)
	mo->momx = MAXMOVE;
    else if (mo->momx < -MAXMOVE)
	mo->momx = -MAXMOVE;

    if (mo->momy > MAXMOVE)
	mo->momy = MAXMOVE;
    else if (mo->momy < -MAXMOVE)
	mo->momy = -MAXMOVE;
		
    xmove = mo->momx;
    ymove = mo->momy;
	
    do
    {
	if (xmove > MAXMOVE/2 || ymove > MAXMOVE/2)
	{
	    ptryx = mo->x + xmove/2;
	    ptryy = mo->y + ymove/2;
	    xmove >>= 1;
	    ymove >>= 1;
	}
	else
	{
	    ptryx = mo->x + xmove;
	    ptryy = mo->y + ymove;
	    xmove = ymove = 0;
	}
		
	if (!P_TryMove (mo, ptryx, ptryy))
	{
	    // blocked move
	    if (mo->player)
	    {	// try to slide along it
		P_SlideMove (mo);
	    }
	    else if (mo->flags & MF_MISSILE)
	    {
		// explode a missile
		if (ceilingline &&
		    ceilingline->backsector &&
		    ceilingline->backsector->ceilingpic == skyflatnum)
		{
		    // Hack to prevent missiles exploding
		    // against the sky.
		    // Does not handle sky floors.
		    P_RemoveMobj (mo);
		    return;
		}
		P_ExplodeMissile (mo);
	    }
	    else
		mo->momx = mo->momy = 0;
	}
    } while (xmove || ymove);
Ejemplo n.º 7
0
//
// P_XYMovement
//
void P_XYMovement (AActor *mo)
{
//	angle_t angle;
	fixed_t ptryx, ptryy;
	player_t *player = NULL;
	fixed_t xmove, ymove;

	if (!mo->momx && !mo->momy)
	{
		if (mo->flags & MF_SKULLFLY)
		{
			// the skull slammed into something
			mo->flags &= ~MF_SKULLFLY;
			mo->momx = mo->momy = mo->momz = 0;

			P_SetMobjState (mo, mo->info->spawnstate);
		}
		return;
	}

	player = mo->player;

	if(!player || !player->mo)
		player = NULL;

	int maxmove = (mo->waterlevel < 2) || (mo->flags & MF_MISSILE) ? MAXMOVE : MAXMOVE/4;

	if (mo->momx > maxmove)
		mo->momx = maxmove;
	else if (mo->momx < -maxmove)
		mo->momx = -maxmove;

	if (mo->momy > maxmove)
		mo->momy = maxmove;
	else if (mo->momy < -maxmove)
		mo->momy = -maxmove;

	xmove = mo->momx;
	ymove = mo->momy;

	maxmove /= 2;

	do
	{
		if (xmove > maxmove || ymove > maxmove )
		{
			ptryx = mo->x + xmove/2;
			ptryy = mo->y + ymove/2;
			xmove >>= 1;
			ymove >>= 1;
		}
		else
		{
			ptryx = mo->x + xmove;
			ptryy = mo->y + ymove;
			xmove = ymove = 0;
		}

		// killough 3/15/98: Allow objects to drop off
		if (!P_TryMove (mo, ptryx, ptryy, true))
		{
			// blocked move
			if (mo->player)
			{	// try to slide along it
				P_SlideMove (mo);
			}
			else if (mo->flags & MF_MISSILE)
			{
				// explode a missile
				if (ceilingline &&
					ceilingline->backsector &&
					ceilingline->backsector->ceilingpic == skyflatnum)
				{
					// Hack to prevent missiles exploding
					// against the sky.
					// Does not handle sky floors.
					mo->Destroy ();
					return;
				}
				P_ExplodeMissile (mo);
			}
			else
			{
				mo->momx = mo->momy = 0;
			}
		}
	} while (xmove || ymove);
Ejemplo n.º 8
0
void P_XYMovement(mobj_t *mo)
{
    player_t *player;
    fixed_t  xmove, ymove;

    if (!mo->momx && !mo->momy)
    {
        if (mo->flags & MF_SKULLFLY)
        {
            // the skull slammed into something
            mo->flags &= ~MF_SKULLFLY;
            mo->momx = mo->momy = mo->momz = 0;

            P_SetMobjState(mo, (statenum_t)mo->info->spawnstate);
        }
        return;
    }

    player = mo->player;

    if (mo->type == MT_ROCKET)
    {
        if (puffcount++ > 1)
            P_SpawnPuff(mo->x, mo->y, mo->z, mo->angle);
    }

    if (mo->momx > MAXMOVE)
        mo->momx = MAXMOVE;
    else if (mo->momx < -MAXMOVE)
        mo->momx = -MAXMOVE;

    if (mo->momy > MAXMOVE)
        mo->momy = MAXMOVE;
    else if (mo->momy < -MAXMOVE)
        mo->momy = -MAXMOVE;

    xmove = mo->momx;
    ymove = mo->momy;

    do
    {
        fixed_t  ptryx, ptryy;

        if (xmove > MAXMOVE / 2 || ymove > MAXMOVE / 2
            || xmove < -MAXMOVE / 2 || ymove < -MAXMOVE / 2)
        {
            ptryx = mo->x + xmove / 2;
            ptryy = mo->y + ymove / 2;
            xmove >>= 1;
            ymove >>= 1;
        }
        else
        {
            ptryx = mo->x + xmove;
            ptryy = mo->y + ymove;
            xmove = ymove = 0;
        }

        if (!P_TryMove(mo, ptryx, ptryy))
        {
            // blocked move
            if (mo->player)
            {
                // try to slide along it
                P_SlideMove(mo);
            }
            else if (mo->flags & MF_MISSILE)
            {
                // explode a missile
                if (ceilingline
                    && ceilingline->backsector
                    && ceilingline->backsector->ceilingpic == skyflatnum
                    && mo->z > ceilingline->backsector->ceilingheight)
                {
                    // Hack to prevent missiles exploding
                    // against the sky.
                    // Does not handle sky floors.
                    shootingsky = true;
                    P_RemoveMobj(mo);
                    return;
                }
                P_ExplodeMissile(mo);
            }
            else
            {
                mo->momx = mo->momy = 0;
            }
        }
    }
Ejemplo n.º 9
0
int P_Thing_Warp(AActor *caller, AActor *reference, double xofs, double yofs, double zofs, DAngle angle, int flags, double heightoffset, double radiusoffset, DAngle pitch)
{
    if (flags & WARPF_MOVEPTR)
    {
        AActor *temp = reference;
        reference = caller;
        caller = temp;
    }

    DVector3 old = caller->Pos();
    int oldpgroup = caller->Sector->PortalGroup;

    zofs += reference->Height * heightoffset;


    if (!(flags & WARPF_ABSOLUTEANGLE))
    {
        angle += (flags & WARPF_USECALLERANGLE) ? caller->Angles.Yaw: reference->Angles.Yaw;
    }

    const double rad = radiusoffset * reference->radius;
    const double s = angle.Sin();
    const double c = angle.Cos();

    if (!(flags & WARPF_ABSOLUTEPOSITION))
    {
        if (!(flags & WARPF_ABSOLUTEOFFSET))
        {
            double xofs1 = xofs;

            // (borrowed from A_SpawnItemEx, assumed workable)
            // in relative mode negative y values mean 'left' and positive ones mean 'right'
            // This is the inverse orientation of the absolute mode!

            xofs = xofs1 * c + yofs * s;
            yofs = xofs1 * s - yofs * c;
        }

        if (flags & WARPF_TOFLOOR)
        {
            // set correct xy
            // now the caller's floorz should be appropriate for the assigned xy-position
            // assigning position again with.
            // extra unlink, link and environment calculation
            caller->SetOrigin(reference->Vec3Offset(xofs + rad * c, yofs + rad * s, 0.), true);
            // The two-step process is important.
            caller->SetZ(caller->floorz + zofs);
        }
        else
        {
            caller->SetOrigin(reference->Vec3Offset(xofs + rad * c, yofs + rad * s, zofs), true);
        }
    }
    else // [MC] The idea behind "absolute" is meant to be "absolute". Override everything, just like A_SpawnItemEx's.
    {
        caller->SetOrigin(xofs + rad * c, yofs + rad * s, zofs, true);
        if (flags & WARPF_TOFLOOR)
        {
            caller->SetZ(caller->floorz + zofs);
        }
    }

    if ((flags & WARPF_NOCHECKPOSITION) || P_TestMobjLocation(caller))
    {
        if (flags & WARPF_TESTONLY)
        {
            caller->SetOrigin(old, true);
        }
        else
        {
            caller->Angles.Yaw = angle;

            if (flags & WARPF_COPYPITCH)
                caller->SetPitch(reference->Angles.Pitch, false);

            if (pitch != 0)
                caller->SetPitch(caller->Angles.Pitch + pitch, false);

            if (flags & WARPF_COPYVELOCITY)
            {
                caller->Vel = reference->Vel;
            }
            if (flags & WARPF_STOP)
            {
                caller->Vel.Zero();
            }

            // this is no fun with line portals
            if (flags & WARPF_WARPINTERPOLATION)
            {
                // This just translates the movement but doesn't change the vector
                DVector3 displacedold  = old + Displacements.getOffset(oldpgroup, caller->Sector->PortalGroup);
                caller->Prev += caller->Pos() - displacedold;
                caller->PrevPortalGroup = caller->Sector->PortalGroup;
            }
            else if (flags & WARPF_COPYINTERPOLATION)
            {
                // Map both positions of the reference actor to the current portal group
                DVector3 displacedold = old + Displacements.getOffset(reference->PrevPortalGroup, caller->Sector->PortalGroup);
                DVector3 displacedref = old + Displacements.getOffset(reference->Sector->PortalGroup, caller->Sector->PortalGroup);
                caller->Prev = caller->Pos() + displacedold - displacedref;
                caller->PrevPortalGroup = caller->Sector->PortalGroup;
            }
            else if (!(flags & WARPF_INTERPOLATE))
            {
                caller->ClearInterpolation();
            }

            if ((flags & WARPF_BOB) && (reference->flags2 & MF2_FLOATBOB))
            {
                caller->AddZ(reference->GetBobOffset());
            }
            P_TryMove(caller, caller->Pos(), false);
        }
        return true;
    }
    caller->SetOrigin(old, true);
    return false;
}
Ejemplo n.º 10
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();
			}
		}
	}
Ejemplo n.º 11
0
//
// P_XYMovement
//
void P_XYMovement(AActor *mo)
{
//	angle_t angle;
	fixed_t ptryx, ptryy;
	player_t *player = NULL;
	fixed_t xmove, ymove;
	fixed_t maxmove;
	static const int windTab[3] = {2048*5, 2048*10, 2048*25};

	if (!mo->subsector)
		return;
			
	if (!mo->momx && !mo->momy)
	{
		if (mo->flags & MF_SKULLFLY)
		{
			// the skull slammed into something
			mo->flags &= ~MF_SKULLFLY;
			mo->momx = mo->momy = mo->momz = 0;

			P_SetMobjState (mo, mo->info->spawnstate);
		}
		return;
	}

	maxmove = (mo->waterlevel < 2) || (mo->flags & MF_MISSILE) ? MAXMOVE : MAXMOVE/4;
	
	if (mo->flags2 & MF2_WINDTHRUST)
	{
		int special = mo->subsector->sector->special;
		switch (special)
		{
			case 40: case 41: case 42: // Wind_East
				P_ThrustMobj (mo, 0, windTab[special-40]);
				break;
			case 43: case 44: case 45: // Wind_North
				P_ThrustMobj (mo, ANG90, windTab[special-43]);
				break;
			case 46: case 47: case 48: // Wind_South
				P_ThrustMobj (mo, ANG270, windTab[special-46]);
				break;
			case 49: case 50: case 51: // Wind_West
				P_ThrustMobj (mo, ANG180, windTab[special-49]);
				break;
		}
	}
	
	xmove = mo->momx = clamp (mo->momx, -maxmove, maxmove);
	ymove = mo->momy = clamp (mo->momy, -maxmove, maxmove);

	player = mo->player;

	if(!player || !player->mo)
		player = NULL;
		
	maxmove /= 2;

	do
	{
		if (xmove > maxmove || ymove > maxmove )
		{
			ptryx = mo->x + xmove/2;
			ptryy = mo->y + ymove/2;
			xmove >>= 1;
			ymove >>= 1;
		}
		else
		{
			ptryx = mo->x + xmove;
			ptryy = mo->y + ymove;
			xmove = ymove = 0;
		}

		// killough 3/15/98: Allow objects to drop off
		if (!P_TryMove (mo, ptryx, ptryy, true))
		{
			// blocked move
            if (mo->flags2 & MF2_SLIDE)
			{
				// try to slide along it
				if (BlockingMobj == NULL)
				{ // slide against wall
					if (BlockingLine != NULL &&
						mo->player && mo->waterlevel && mo->waterlevel < 3 &&
						(mo->player->cmd.ucmd.forwardmove | mo->player->cmd.ucmd.sidemove) &&
						BlockingLine->sidenum[1] != -1)
					{
						mo->momz = WATER_JUMP_SPEED;
					}
					P_SlideMove (mo);
				}
				else
				{ // slide against mobj
					if (P_TryMove (mo, mo->x, ptryy, true))
					{
						mo->momx = 0;
					}
					else if (P_TryMove (mo, ptryx, mo->y, true))
					{
						mo->momy = 0;
					}
					else
					{
						mo->momx = mo->momy = 0;
					}
				}
			}
			else if (mo->flags & MF_MISSILE)
			{
				// explode a missile
				if (ceilingline &&
					ceilingline->backsector &&
					ceilingline->backsector->ceilingpic == skyflatnum)
				{
					// Hack to prevent missiles exploding
					// against the sky.
					// Does not handle sky floors.
					mo->Destroy ();
					return;
				}
				// [SL] 2011-06-02 - Only server should control explosions 
				if (serverside)
					 P_ExplodeMissile (mo);

			}
			else
			{
				mo->momx = mo->momy = 0;
			}
		}
	} while (xmove || ymove);
Ejemplo n.º 12
0
void P_XYMovement (mobj_t* mo) 
{
    fixed_t     ptryx;
    fixed_t     ptryy;
    player_t*   player;
    fixed_t     xmove;
    fixed_t     ymove;

    // villsa [STRIFE] unused
    /*
    if (!mo->momx && !mo->momy)
    {
        if (mo->flags & MF_SKULLFLY)
        {
            // the skull slammed into something
            mo->flags &= ~MF_SKULLFLY;
            mo->momx = mo->momy = mo->momz = 0;

            P_SetMobjState (mo, mo->info->spawnstate);
        }
        return;
    }
    */

    player = mo->player;

    if (mo->momx > MAXMOVE)
        mo->momx = MAXMOVE;
    else if (mo->momx < -MAXMOVE)
        mo->momx = -MAXMOVE;

    if (mo->momy > MAXMOVE)
        mo->momy = MAXMOVE;
    else if (mo->momy < -MAXMOVE)
        mo->momy = -MAXMOVE;

    xmove = mo->momx;
    ymove = mo->momy;

    do
    {
        if (xmove > MAXMOVE/2 || ymove > MAXMOVE/2)
        {
            ptryx = mo->x + xmove/2;
            ptryy = mo->y + ymove/2;
            xmove >>= 1;
            ymove >>= 1;
        }
        else
        {
            ptryx = mo->x + xmove;
            ptryy = mo->y + ymove;
            xmove = ymove = 0;
        }

        if (!P_TryMove (mo, ptryx, ptryy))
        {
            // blocked move
            if (mo->player)
            {   // try to slide along it
                P_SlideMove (mo);
            }
            // villsa [STRIFE] check for bouncy missiles
            else if(mo->flags & MF_BOUNCE)
            {
                mo->momx >>= 3;
                mo->momy >>= 3;

                if (P_TryMove(mo, mo->x - xmove, ymove + mo->y))
                    mo->momy = -mo->momy;
                else
                    mo->momx = -mo->momx;

                xmove = 0;
                ymove = 0;
            }
            else if (mo->flags & MF_MISSILE)