Ejemplo n.º 1
0
void C_DECL A_LeafCheck(mobj_t *actor)
{
    int                 n;

    actor->special1++;
    if(actor->special1 >= 20)
    {
        P_MobjChangeState(actor, S_NULL);
        return;
    }

    if(P_Random() > 64)
    {
        if(FEQUAL(actor->mom[MX], 0) && FEQUAL(actor->mom[MY], 0))
        {
            P_ThrustMobj(actor, actor->target->angle,
                         FIX2FLT(P_Random() << 9) + 1);
        }
        return;
    }

    P_MobjChangeState(actor, S_LEAF1_8);
    n = P_Random();
    actor->mom[MZ] = FIX2FLT(n << 9) + 1;
    P_ThrustMobj(actor, actor->target->angle, FIX2FLT(P_Random() << 9) + 2);
    actor->flags |= MF_MISSILE;
}
Ejemplo n.º 2
0
DEFINE_ACTION_FUNCTION(AActor, A_BishopDoBlur)
{
	// [BB] This is server-side.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		return;
	}

	self->special1 = (pr_doblur() & 3) + 3; // Random number of blurs
	if (pr_doblur() < 120)
	{
		P_ThrustMobj (self, self->angle + ANG90, 11*FRACUNIT);
	}
	else if (pr_doblur() > 125)
	{
		P_ThrustMobj (self, self->angle - ANG90, 11*FRACUNIT);
	}
	else
	{ // Thrust forward
		P_ThrustMobj (self, self->angle, 11*FRACUNIT);
	}
	S_Sound (self, CHAN_BODY, "BishopBlur", 1, ATTN_NORM);

	// [BB] If we're the server, update the thing's momentum and play the sound.
	if ( NETWORK_GetState( ) == NETSTATE_SERVER )
	{
		SERVERCOMMANDS_MoveThingExact( self, CM_MOMX|CM_MOMY );
		SERVERCOMMANDS_SoundActor( self, CHAN_BODY, "BishopBlur", 1, ATTN_NORM );
	}
}
Ejemplo n.º 3
0
void C_DECL A_LeafSpawn(mobj_t* actor)
{
    coord_t pos[3];
    mobj_t* mo;
    int i;

    for(i = (P_Random() & 3) + 1; i; i--)
    {
        pos[VX] = actor->origin[VX];
        pos[VY] = actor->origin[VY];
        pos[VZ] = actor->origin[VZ];

        pos[VX] += FIX2FLT((P_Random() - P_Random()) << 14);
        pos[VY] += FIX2FLT((P_Random() - P_Random()) << 14);
        pos[VZ] += FIX2FLT(P_Random() << 14);

        /// @todo  We should not be using the original indices to determine
        ///         the mobjtype. Use a local table instead.
        if((mo = P_SpawnMobj(MT_LEAF1 + (P_Random() & 1), pos,
                             actor->angle, 0)))
        {
            P_ThrustMobj(mo, actor->angle, FIX2FLT(P_Random() << 9) + 3);
            mo->target = actor;
            mo->special1 = 0;
        }
    }
}
Ejemplo n.º 4
0
static bool TryPunch(APlayerPawn *pmo, angle_t angle, int damage, fixed_t power)
{
	const PClass *pufftype;
	AActor *linetarget;
	int slope;

	slope = P_AimLineAttack (pmo, angle, 2*MELEERANGE, &linetarget);
	if (linetarget != NULL)
	{
		if (++pmo->weaponspecial >= 3)
		{
			damage <<= 1;
			power *= 3;
			pufftype = PClass::FindClass ("HammerPuff");
		}
		else
		{
			pufftype = PClass::FindClass ("PunchPuff");
		}
		P_LineAttack (pmo, angle, 2*MELEERANGE, slope, damage, NAME_Melee, pufftype, true, &linetarget);
		if (linetarget != NULL)
		{
			if (linetarget->player != NULL || 
				(linetarget->Mass != INT_MAX && (linetarget->flags3 & MF3_ISMONSTER)))
			{
				P_ThrustMobj (linetarget, angle, power);
			}
			AdjustPlayerAngle (pmo, linetarget);
			return true;
		}
	}
	return false;
}
Ejemplo n.º 5
0
void A_MakePod (AActor *actor)
{
	APod *mo;
	fixed_t x;
	fixed_t y;
	fixed_t z;

	if (actor->special1 == MAX_GEN_PODS)
	{ // Too many generated pods
		return;
	}
	x = actor->x;
	y = actor->y;
	z = actor->z;
	mo = Spawn<APod> (x, y, ONFLOORZ, ALLOW_REPLACE);
	if (P_CheckPosition (mo, x, y) == false)
	{ // Didn't fit
		mo->Destroy ();
		return;
	}
	mo->SetState (&APod::States[S_POD_GROW]);
	P_ThrustMobj (mo, pr_makepod()<<24, (fixed_t)(4.5*FRACUNIT));
	S_Sound (mo, CHAN_BODY, "world/podgrow", 1, ATTN_IDLE);
	actor->special1++; // Increment generated pod count
	mo->Generator = actor; // Link the generator to the pod
	return;
}
Ejemplo n.º 6
0
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MakePod)
{
	ACTION_PARAM_START(1);
	ACTION_PARAM_CLASS(podtype, 0);

	AActor *mo;
	fixed_t x;
	fixed_t y;
	fixed_t z;

	if (self->special1 == MAX_GEN_PODS)
	{ // Too many generated pods
		return;
	}
	x = self->x;
	y = self->y;
	z = self->z;
	mo = Spawn(podtype, x, y, ONFLOORZ, ALLOW_REPLACE);
	if (!P_CheckPosition (mo, x, y))
	{ // Didn't fit
		mo->Destroy ();
		return;
	}
	mo->SetState (mo->FindState("Grow"));
	P_ThrustMobj (mo, pr_makepod()<<24, (fixed_t)(4.5*FRACUNIT));
	S_Sound (mo, CHAN_BODY, self->AttackSound, 1, ATTN_IDLE);
	self->special1++; // Increment generated pod count
	mo->master = self; // Link the generator to the pod
	return;
}
Ejemplo n.º 7
0
DEFINE_ACTION_FUNCTION(AActor, A_BishopDoBlur)
{
	self->special1 = (pr_doblur() & 3) + 3; // Random number of blurs
	if (pr_doblur() < 120)
	{
		P_ThrustMobj (self, self->angle + ANG90, 11*FRACUNIT);
	}
	else if (pr_doblur() > 125)
	{
		P_ThrustMobj (self, self->angle - ANG90, 11*FRACUNIT);
	}
	else
	{ // Thrust forward
		P_ThrustMobj (self, self->angle, 11*FRACUNIT);
	}
	S_Sound (self, CHAN_BODY, "BishopBlur", 1, ATTN_NORM);
}
Ejemplo n.º 8
0
void A_BishopDoBlur (AActor *actor)
{
	actor->special1 = (pr_doblur() & 3) + 3; // Random number of blurs
	if (pr_doblur() < 120)
	{
		P_ThrustMobj (actor, actor->angle + ANG90, 11*FRACUNIT);
	}
	else if (pr_doblur() > 125)
	{
		P_ThrustMobj (actor, actor->angle - ANG90, 11*FRACUNIT);
	}
	else
	{ // Thrust forward
		P_ThrustMobj (actor, actor->angle, 11*FRACUNIT);
	}
	S_Sound (actor, CHAN_BODY, "BishopBlur", 1, ATTN_NORM);
}
Ejemplo n.º 9
0
DEFINE_ACTION_FUNCTION(AActor, A_LeafCheck)
{
	self->special1++;
	if (self->special1 >= 20)
	{
		self->SetState (NULL);
		return;
	}
	angle_t ang = self->target ? self->target->angle : self->angle;
	if (pr_leafcheck() > 64)
	{
		if (!self->velx && !self->vely)
		{
			P_ThrustMobj (self, ang, (pr_leafcheck()<<9)+FRACUNIT);
		}
		return;
	}
	self->SetState (self->SpawnState + 7);
	self->velz = (pr_leafcheck()<<9)+FRACUNIT;
	P_ThrustMobj (self, ang, (pr_leafcheck()<<9)+2*FRACUNIT);
	self->flags |= MF_MISSILE;
}
Ejemplo n.º 10
0
void DEarthquake::Tick ()
{
	int i;

	if (m_Spot == NULL)
	{
		Destroy ();
		return;
	}
	
	if (!S_IsActorPlayingSomething (m_Spot, CHAN_BODY, m_QuakeSFX))
	{
		S_Sound (m_Spot, CHAN_BODY | CHAN_LOOP, m_QuakeSFX, 1, ATTN_NORM);
	}
	if (m_DamageRadius > 0)
	{
		for (i = 0; i < MAXPLAYERS; i++)
		{
			if (playeringame[i] && !(players[i].cheats & CF_NOCLIP))
			{
				AActor *victim = players[i].mo;
				fixed_t dist;

				dist = P_AproxDistance (victim->x - m_Spot->x, victim->y - m_Spot->y);
				// Check if in damage radius
				if (dist < m_DamageRadius && victim->z <= victim->floorz)
				{
					if (pr_quake() < 50)
					{
						P_DamageMobj (victim, NULL, NULL, pr_quake.HitDice (1), NAME_None);
					}
					// Thrust player around
					angle_t an = victim->angle + ANGLE_1*pr_quake();
					if (m_IntensityX == m_IntensityY)
					{ // Thrust in a circle
						P_ThrustMobj (victim, an, m_IntensityX << (FRACBITS-1));
					}
					else
					{ // Thrust in an ellipse
						an >>= ANGLETOFINESHIFT;
						// So this is actually completely wrong, but it ought to be good
						// enough. Otherwise, I'd have to use tangents and square roots.
						victim->velx += FixedMul(m_IntensityX << (FRACBITS-1), finecosine[an]);
						victim->vely += FixedMul(m_IntensityY << (FRACBITS-1), finesine[an]);
					}
				}
			}
		}
	}
Ejemplo n.º 11
0
void C_DECL A_Quake(mobj_t* actor)
{
    angle_t angle;
    player_t* player;
    mobj_t* victim;
    int richters = actor->args[0];
    int playnum;
    coord_t dist;

    if(actor->args[1]-- > 0)
    {
        for(playnum = 0; playnum < MAXPLAYERS; ++playnum)
        {
            player = &players[playnum];
            if(!players[playnum].plr->inGame)
                continue;

            victim = player->plr->mo;
            dist =  M_ApproxDistance(actor->origin[VX] - victim->origin[VX],
                                     actor->origin[VY] - victim->origin[VY]);

            dist = FIX2FLT(FLT2FIX(dist) >> (FRACBITS + 6));

            // Tested in tile units (64 pixels).
            if(dist < FIX2FLT(actor->args[3])) // In tremor radius.
            {
                localQuakeHappening[playnum] = richters;
                players[playnum].update |= PSF_LOCAL_QUAKE;
            }

            // Check if in damage radius.
            if(dist < FIX2FLT(actor->args[2]) &&
                    victim->origin[VZ] <= victim->floorZ)
            {
                if(P_Random() < 50)
                {
                    P_DamageMobj(victim, NULL, NULL, HITDICE(1), false);
                }

                // Thrust player around.
                angle = victim->angle + ANGLE_1 * P_Random();
                P_ThrustMobj(victim, angle, FIX2FLT(richters << (FRACBITS - 1)));
            }
        }
    }
    else
    {
        for(playnum = 0; playnum < MAXPLAYERS; playnum++)
Ejemplo n.º 12
0
DEFINE_ACTION_FUNCTION(AActor, A_FireMauler2)
{
	if (self->player != NULL)
	{
		AWeapon *weapon = self->player->ReadyWeapon;
		if (weapon != NULL)
		{
			if (!weapon->DepleteAmmo (weapon->bAltFire))
				return;
		}
		self->player->mo->PlayAttacking2 ();
	}
	P_SpawnPlayerMissile (self, PClass::FindClass("MaulerTorpedo"));
	P_DamageMobj (self, self, NULL, 20, self->DamageType);
	P_ThrustMobj (self, self->angle + ANGLE_180, 0x7D000);
}
Ejemplo n.º 13
0
void DEarthquake::Tick ()
{
	int i;

	if (m_Spot == NULL)
	{
		Destroy ();
		return;
	}

	if (!S_IsActorPlayingSomething (m_Spot, CHAN_BODY, m_QuakeSFX))
	{
		S_Sound (m_Spot, CHAN_BODY | CHAN_LOOP, m_QuakeSFX, 1, ATTN_NORM);
	}
	if (m_DamageRadius > 0)
	{
		for (i = 0; i < MAXPLAYERS; i++)
		{
			if (playeringame[i] && !(players[i].cheats & CF_NOCLIP))
			{
				AActor *victim = players[i].mo;
				fixed_t dist;

				dist = P_AproxDistance (victim->x - m_Spot->x, victim->y - m_Spot->y);
				// Check if in damage radius
				if (dist < m_DamageRadius && victim->z <= victim->floorz)
				{
					if (pr_quake() < 50)
					{
						P_DamageMobj (victim, NULL, NULL, pr_quake.HitDice (1), NAME_None);
					}
					// Thrust player around
					angle_t an = victim->angle + ANGLE_1*pr_quake();
					P_ThrustMobj (victim, an, m_Intensity << (FRACBITS-1));
				}
			}
		}
	}
	if (--m_Countdown == 0)
	{
		if (S_IsActorPlayingSomething(m_Spot, CHAN_BODY, m_QuakeSFX))
		{
			S_StopSound(m_Spot, CHAN_BODY);
		}
		Destroy();
	}
}
Ejemplo n.º 14
0
DEFINE_ACTION_FUNCTION(AActor, A_LeafSpawn)
{
	AActor *mo;
	int i;

	for (i = (pr_leaf()&3)+1; i; i--)
	{
		mo = Spawn (pr_leaf()&1 ? PClass::FindClass ("Leaf1") : PClass::FindClass ("Leaf2"),
			self->x + (pr_leaf.Random2()<<14),
			self->y + (pr_leaf.Random2()<<14),
			self->z + (pr_leaf()<<14), ALLOW_REPLACE);
		if (mo)
		{
			P_ThrustMobj (mo, self->angle, (pr_leaf()<<9)+3*FRACUNIT);
			mo->target = self;
			mo->special1 = 0;
		}
	}
}
Ejemplo n.º 15
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.º 16
0
void A_FPunchAttack (AActor *actor)
{
	angle_t angle;
	int damage;
	int slope;
	fixed_t power;
	int i;
	player_t *player;
	const PClass *pufftype;

	if (NULL == (player = actor->player))
	{
		return;
	}
	APlayerPawn *pmo = player->mo;

	damage = 40+(pr_fpatk()&15);
	power = 2*FRACUNIT;
	pufftype = RUNTIME_CLASS(APunchPuff);
	for (i = 0; i < 16; i++)
	{
		angle = pmo->angle + i*(ANG45/16);
		slope = P_AimLineAttack (pmo, angle, 2*MELEERANGE);
		if (linetarget)
		{
			pmo->special1++;
			if (pmo->special1 == 3)
			{
				damage <<= 1;
				power = 6*FRACUNIT;
				pufftype = RUNTIME_CLASS(AHammerPuff);
			}
			P_LineAttack (pmo, angle, 2*MELEERANGE, slope, damage, MOD_HIT, pufftype);
			if (linetarget->flags3&MF3_ISMONSTER || linetarget->player)
			{
				P_ThrustMobj (linetarget, angle, power);
			}
			AdjustPlayerAngle (pmo);
			goto punchdone;
		}
		angle = pmo->angle-i * (ANG45/16);
		slope = P_AimLineAttack (pmo, angle, 2*MELEERANGE);
		if (linetarget)
		{
			pmo->special1++;
			if (pmo->special1 == 3)
			{
				damage <<= 1;
				power = 6*FRACUNIT;
				pufftype = RUNTIME_CLASS(AHammerPuff);
			}
			P_LineAttack (pmo, angle, 2*MELEERANGE, slope, damage, MOD_HIT, pufftype);
			if (linetarget->flags3&MF3_ISMONSTER || linetarget->player)
			{
				P_ThrustMobj (linetarget, angle, power);
			}
			AdjustPlayerAngle (pmo);
			goto punchdone;
		}
	}
	// didn't find any creatures, so try to strike any walls
	pmo->special1 = 0;

	angle = pmo->angle;
	slope = P_AimLineAttack (pmo, angle, MELEERANGE);
	P_LineAttack (pmo, angle, MELEERANGE, slope, damage, MOD_HIT, pufftype);

punchdone:
	if (pmo->special1 == 3)
	{
		pmo->special1 = 0;
		P_SetPsprite (player, ps_weapon, &AFWeapFist::States[S_PUNCHATK2]);
		S_Sound (pmo, CHAN_VOICE, "*fistgrunt", 1, ATTN_NORM);
	}
	return;		
}
Ejemplo n.º 17
0
boolean P_ExecuteLineSpecial(int special, byte *args, line_t *line, int side,
							 mobj_t *mo)
{
	boolean buttonSuccess;

	buttonSuccess = false;
	switch (special)
	{
	case 1:					// Poly Start Line
		break;
	case 2:					// Poly Rotate Left
		buttonSuccess = EV_RotatePoly(line, args, 1, false);
		break;
	case 3:					// Poly Rotate Right
		buttonSuccess = EV_RotatePoly(line, args, -1, false);
		break;
	case 4:					// Poly Move
		buttonSuccess = EV_MovePoly(line, args, false, false);
		break;
	case 5:					// Poly Explicit Line:  Only used in initialization
		break;
	case 6:					// Poly Move Times 8
		buttonSuccess = EV_MovePoly(line, args, true, false);
		break;
	case 7:					// Poly Door Swing
		buttonSuccess = EV_OpenPolyDoor(line, args, PODOOR_SWING);
		break;
	case 8:					// Poly Door Slide
		buttonSuccess = EV_OpenPolyDoor(line, args, PODOOR_SLIDE);
		break;
	case 10:					// Door Close
		buttonSuccess = EV_DoDoor(line, args, DREV_CLOSE);
		break;
	case 11:					// Door Open
		if(!args[0])
		{
			buttonSuccess = EV_VerticalDoor(line, mo);
		}
		else
		{
			buttonSuccess = EV_DoDoor(line, args, DREV_OPEN);
		}
		break;
	case 12:					// Door Raise
		if(!args[0])
		{
			buttonSuccess = EV_VerticalDoor(line, mo);
		}
		else
		{
			buttonSuccess = EV_DoDoor(line, args, DREV_NORMAL);
		}
		break;
	case 13:					// Door Locked_Raise
		if(CheckedLockedDoor(mo, args[3]))
		{
			if(!args[0])
			{
				buttonSuccess = EV_VerticalDoor(line, mo);
			}
			else
			{
				buttonSuccess = EV_DoDoor(line, args, DREV_NORMAL);
			}
		}
		break;
	case 20:					// Floor Lower by Value
		buttonSuccess = EV_DoFloor(line, args, FLEV_LOWERFLOORBYVALUE);
		break;
	case 21:					// Floor Lower to Lowest
		buttonSuccess = EV_DoFloor(line, args, FLEV_LOWERFLOORTOLOWEST);
		break;
	case 22:					// Floor Lower to Nearest
		buttonSuccess = EV_DoFloor(line, args, FLEV_LOWERFLOOR);
		break;
	case 23:					// Floor Raise by Value
		buttonSuccess = EV_DoFloor(line, args, FLEV_RAISEFLOORBYVALUE);
		break;
	case 24:					// Floor Raise to Highest
		buttonSuccess = EV_DoFloor(line, args, FLEV_RAISEFLOOR);
		break;
	case 25:					// Floor Raise to Nearest
		buttonSuccess = EV_DoFloor(line, args, FLEV_RAISEFLOORTONEAREST);
		break;
	case 26:					// Stairs Build Down Normal
		buttonSuccess = EV_BuildStairs(line, args, -1, STAIRS_NORMAL);
		break;
	case 27:					// Build Stairs Up Normal
		buttonSuccess = EV_BuildStairs(line, args, 1, STAIRS_NORMAL);
		break;
	case 28:					// Floor Raise and Crush
		buttonSuccess = EV_DoFloor(line, args, FLEV_RAISEFLOORCRUSH);
		break;
	case 29:					// Build Pillar (no crushing)
		buttonSuccess = EV_BuildPillar(line, args, false);
		break;
	case 30:					// Open Pillar
		buttonSuccess = EV_OpenPillar(line, args);
		break;
	case 31:					// Stairs Build Down Sync
		buttonSuccess = EV_BuildStairs(line, args, -1, STAIRS_SYNC);
		break;
	case 32:					// Build Stairs Up Sync
		buttonSuccess = EV_BuildStairs(line, args, 1, STAIRS_SYNC);
		break;
	case 35:					// Raise Floor by Value Times 8
		buttonSuccess = EV_DoFloor(line, args, FLEV_RAISEBYVALUETIMES8);
		break;
	case 36:					// Lower Floor by Value Times 8
		buttonSuccess = EV_DoFloor(line, args, FLEV_LOWERBYVALUETIMES8);
		break;
	case 40:					// Ceiling Lower by Value
		buttonSuccess = EV_DoCeiling(line, args, CLEV_LOWERBYVALUE);
		break;
	case 41:					// Ceiling Raise by Value
		buttonSuccess = EV_DoCeiling(line, args, CLEV_RAISEBYVALUE);
		break;
	case 42:					// Ceiling Crush and Raise
		buttonSuccess = EV_DoCeiling(line, args, CLEV_CRUSHANDRAISE);
		break;
	case 43:					// Ceiling Lower and Crush
		buttonSuccess = EV_DoCeiling(line, args, CLEV_LOWERANDCRUSH);
		break;
	case 44:					// Ceiling Crush Stop
		buttonSuccess = EV_CeilingCrushStop(line, args);
		break;
	case 45:					// Ceiling Crush Raise and Stay
		buttonSuccess = EV_DoCeiling(line, args, CLEV_CRUSHRAISEANDSTAY);
		break;
	case 46:					// Floor Crush Stop
		buttonSuccess = EV_FloorCrushStop(line, args);
		break;
	case 60:					// Plat Perpetual Raise
		buttonSuccess = EV_DoPlat(line, args, PLAT_PERPETUALRAISE, 0);
		break;
	case 61:					// Plat Stop
		EV_StopPlat(line, args);
		break;
	case 62:					// Plat Down-Wait-Up-Stay
		buttonSuccess = EV_DoPlat(line, args, PLAT_DOWNWAITUPSTAY, 0);
		break;
	case 63:					// Plat Down-by-Value*8-Wait-Up-Stay
		buttonSuccess = EV_DoPlat(line, args, PLAT_DOWNBYVALUEWAITUPSTAY, 0);
		break;
	case 64:					// Plat Up-Wait-Down-Stay
		buttonSuccess = EV_DoPlat(line, args, PLAT_UPWAITDOWNSTAY, 0);
		break;
	case 65:					// Plat Up-by-Value*8-Wait-Down-Stay
		buttonSuccess = EV_DoPlat(line, args, PLAT_UPBYVALUEWAITDOWNSTAY, 0);
		break;
	case 66:					// Floor Lower Instant * 8
		buttonSuccess = EV_DoFloor(line, args, FLEV_LOWERTIMES8INSTANT);
		break;
	case 67:					// Floor Raise Instant * 8
		buttonSuccess = EV_DoFloor(line, args, FLEV_RAISETIMES8INSTANT);
		break;
	case 68:					// Floor Move to Value * 8
		buttonSuccess = EV_DoFloor(line, args, FLEV_MOVETOVALUETIMES8);
		break;
	case 69:					// Ceiling Move to Value * 8
		buttonSuccess = EV_DoCeiling(line, args, CLEV_MOVETOVALUETIMES8);
		break;
	case 70:					// Teleport
		if(side == 0)
		{						// Only teleport when crossing the front side of a line
			buttonSuccess = EV_Teleport(args[0], mo, true);
		}
		break;
	case 71:					// Teleport, no fog
		if(side == 0)
		{						// Only teleport when crossing the front side of a line
			buttonSuccess = EV_Teleport(args[0], mo, false);
		}
		break;
	case 72:					// Thrust Mobj
		if(!side)				// Only thrust on side 0
		{
			P_ThrustMobj(mo, args[0] * (ANGLE_90 / 64), args[1] << FRACBITS);
			buttonSuccess = 1;
		}
		break;
	case 73:					// Damage Mobj
		if(args[0])
		{
			P_DamageMobj(mo, NULL, NULL, args[0]);
		}
		else
		{						// If arg1 is zero, then guarantee a kill
			P_DamageMobj(mo, NULL, NULL, 10000);
		}
		buttonSuccess = 1;
		break;
	case 74:					// Teleport_NewMap
		if(side == 0)
		{						// Only teleport when crossing the front side of a line
			if(!(mo && mo->player && mo->player->playerstate == PST_DEAD))	// Players must be alive to teleport
			{
				G_Completed(args[0], args[1]);
				buttonSuccess = true;
			}
		}
		break;
	case 75:					// Teleport_EndGame
		if(side == 0)
		{						// Only teleport when crossing the front side of a line
			if(!(mo && mo->player && mo->player->playerstate == PST_DEAD))	// Players must be alive to teleport
			{
				buttonSuccess = true;
				if(deathmatch)
				{				// Winning in deathmatch just goes back to map 1
					G_Completed(1, 0);
				}
				else
				{				// Passing -1, -1 to G_Completed() starts the Finale
					G_Completed(-1, -1);
				}
			}
		}
		break;
	case 80:					// ACS_Execute
		buttonSuccess = P_StartACS(args[0], args[1], &args[2], mo, line, side);
		break;
	case 81:					// ACS_Suspend
		buttonSuccess = P_SuspendACS(args[0], args[1]);
		break;
	case 82:					// ACS_Terminate
		buttonSuccess = P_TerminateACS(args[0], args[1]);
		break;
	case 83:					// ACS_LockedExecute
		buttonSuccess = P_StartLockedACS(line, args, mo, side);
		break;
	case 90:					// Poly Rotate Left Override
		buttonSuccess = EV_RotatePoly(line, args, 1, true);
		break;
	case 91:					// Poly Rotate Right Override
		buttonSuccess = EV_RotatePoly(line, args, -1, true);
		break;
	case 92:					// Poly Move Override
		buttonSuccess = EV_MovePoly(line, args, false, true);
		break;
	case 93:					// Poly Move Times 8 Override
		buttonSuccess = EV_MovePoly(line, args, true, true);
		break;
	case 94:					// Build Pillar Crush 
		buttonSuccess = EV_BuildPillar(line, args, true);
		break;
	case 95:					// Lower Floor and Ceiling
		buttonSuccess = EV_DoFloorAndCeiling(line, args, false);
		break;
	case 96:					// Raise Floor and Ceiling
		buttonSuccess = EV_DoFloorAndCeiling(line, args, true);
		break;
	case 109:					// Force Lightning
		buttonSuccess = true;
		P_ForceLightning();
		break;
	case 110:					// Light Raise by Value
		buttonSuccess = EV_SpawnLight(line, args, LITE_RAISEBYVALUE);
		break;
	case 111:					// Light Lower by Value
		buttonSuccess = EV_SpawnLight(line, args, LITE_LOWERBYVALUE);
		break;
	case 112:					// Light Change to Value
		buttonSuccess = EV_SpawnLight(line, args, LITE_CHANGETOVALUE);
		break;
	case 113:					// Light Fade
		buttonSuccess = EV_SpawnLight(line, args, LITE_FADE);
		break;
	case 114:					// Light Glow
		buttonSuccess = EV_SpawnLight(line, args, LITE_GLOW);
		break;
	case 115:					// Light Flicker
		buttonSuccess = EV_SpawnLight(line, args, LITE_FLICKER);
		break;
	case 116:					// Light Strobe
		buttonSuccess = EV_SpawnLight(line, args, LITE_STROBE);
		break;
	case 120:					// Quake Tremor
		buttonSuccess = A_LocalQuake(args, mo);
		break;
	case 129:					// UsePuzzleItem
		buttonSuccess = EV_LineSearchForPuzzleItem(line, args, mo);
		break;
	case 130:					// Thing_Activate
		buttonSuccess = EV_ThingActivate(args[0]);
		break;
	case 131:					// Thing_Deactivate
		buttonSuccess = EV_ThingDeactivate(args[0]);
		break;
	case 132:					// Thing_Remove
		buttonSuccess = EV_ThingRemove(args[0]);
		break;
	case 133:					// Thing_Destroy
		buttonSuccess = EV_ThingDestroy(args[0]);
		break;
	case 134:					// Thing_Projectile
		buttonSuccess = EV_ThingProjectile(args, 0);
		break;
	case 135:					// Thing_Spawn
		buttonSuccess = EV_ThingSpawn(args, 1);
		break;
	case 136:					// Thing_ProjectileGravity
		buttonSuccess = EV_ThingProjectile(args, 1);
		break;
	case 137:					// Thing_SpawnNoFog
		buttonSuccess = EV_ThingSpawn(args, 0);
		break;
	case 138:					// Floor_Waggle
		buttonSuccess =
			EV_StartFloorWaggle(args[0], args[1], args[2], args[3], args[4]);
		break;
	case 140:					// Sector_SoundChange
		buttonSuccess = EV_SectorSoundChange(args);
		break;

		// Line specials only processed during level initialization
		// 100: Scroll_Texture_Left
		// 101: Scroll_Texture_Right
		// 102: Scroll_Texture_Up
		// 103: Scroll_Texture_Down
		// 121: Line_SetIdentification

		// Inert Line specials
	default:
		break;
	}
	return buttonSuccess;
}
Ejemplo n.º 18
0
DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack)
{
	angle_t angle;
	fixed_t power;
	int damage;
	int slope;
	int i;
	int useMana;
	player_t *player;
	AWeapon *weapon;
	const PClass *pufftype;
	AActor *linetarget;

	if (NULL == (player = self->player))
	{
		return;
	}
	AActor *pmo=player->mo;

	damage = 40+(pr_axeatk()&15);
	damage += pr_axeatk()&7;
	power = 0;
	weapon = player->ReadyWeapon;
	if (player->ReadyWeapon->Ammo1->Amount > 0)
	{
		damage <<= 1;
		power = 6*FRACUNIT;
		pufftype = PClass::FindClass ("AxePuffGlow");
		useMana = 1;
	}
	else
	{
		pufftype = PClass::FindClass ("AxePuff");
		useMana = 0;
	}
	for (i = 0; i < 16; i++)
	{
		angle = pmo->angle+i*(ANG45/16);
		slope = P_AimLineAttack (pmo, angle, AXERANGE, &linetarget);
		if (linetarget)
		{
			P_LineAttack (pmo, angle, AXERANGE, slope, damage, NAME_Melee, pufftype, true, &linetarget);
			if (linetarget != NULL)
			{
				if (linetarget->flags3&MF3_ISMONSTER || linetarget->player)
				{
					P_ThrustMobj (linetarget, angle, power);
				}
				AdjustPlayerAngle (pmo, linetarget);
				useMana++; 
				goto axedone;
			}
		}
		angle = pmo->angle-i*(ANG45/16);
		slope = P_AimLineAttack (pmo, angle, AXERANGE, &linetarget);
		if (linetarget)
		{
			P_LineAttack (pmo, angle, AXERANGE, slope, damage, NAME_Melee, pufftype, true, &linetarget);
			if (linetarget != NULL)
			{
				if (linetarget->flags3&MF3_ISMONSTER)
				{
					P_ThrustMobj (linetarget, angle, power);
				}
				AdjustPlayerAngle (pmo, linetarget);
				useMana++; 
				goto axedone;
			}
		}
	}
	// didn't find any creatures, so try to strike any walls
	pmo->special1 = 0;

	angle = pmo->angle;
	slope = P_AimLineAttack (pmo, angle, MELEERANGE, &linetarget);
	P_LineAttack (pmo, angle, MELEERANGE, slope, damage, NAME_Melee, pufftype, true);

axedone:
	if (useMana == 2)
	{
		AWeapon *weapon = player->ReadyWeapon;
		if (weapon != NULL)
		{
			weapon->DepleteAmmo (weapon->bAltFire, false);

			if ((weapon->Ammo1 == NULL || weapon->Ammo1->Amount == 0) &&
				(!(weapon->WeaponFlags & WIF_PRIMARY_USES_BOTH) ||
				  weapon->Ammo2 == NULL || weapon->Ammo2->Amount == 0))
			{
				P_SetPsprite (player, ps_weapon, player->ReadyWeapon->FindState ("Fire") + 5);
			}
		}
	}
	return;		
}
Ejemplo n.º 19
0
void A_FAxeAttack (AActor *actor)
{
	angle_t angle;
	fixed_t power;
	int damage;
	int slope;
	int i;
	int useMana;
	player_t *player;
	AWeapon *weapon;
	const TypeInfo *pufftype;

	if (NULL == (player = actor->player))
	{
		return;
	}
	AActor *pmo=player->mo;

	damage = 40+(pr_atk()&15);
	damage += pr_atk()&7;
	power = 0;
	weapon = player->ReadyWeapon;
	if (player->ReadyWeapon->Ammo1->Amount > 0)
	{
		damage <<= 1;
		power = 6*FRACUNIT;
		pufftype = RUNTIME_CLASS(AAxePuffGlow);
		useMana = 1;
	}
	else
	{
		pufftype = RUNTIME_CLASS(AAxePuff);
		useMana = 0;
	}
	for (i = 0; i < 16; i++)
	{
		angle = pmo->angle+i*(ANG45/16);
		slope = P_AimLineAttack (pmo, angle, AXERANGE);
		if (linetarget)
		{
			P_LineAttack (pmo, angle, AXERANGE, slope, damage, MOD_HIT, pufftype);
			if (linetarget->flags3&MF3_ISMONSTER || linetarget->player)
			{
				P_ThrustMobj (linetarget, angle, power);
			}
			AdjustPlayerAngle (pmo);
			useMana++; 
			goto axedone;
		}
		angle = pmo->angle-i*(ANG45/16);
		slope = P_AimLineAttack (pmo, angle, AXERANGE);
		if (linetarget)
		{
			P_LineAttack (pmo, angle, AXERANGE, slope, damage, MOD_HIT, pufftype);
			if (linetarget->flags3&MF3_ISMONSTER)
			{
				P_ThrustMobj (linetarget, angle, power);
			}
			AdjustPlayerAngle (pmo);
			useMana++; 
			goto axedone;
		}
	}
	// didn't find any creatures, so try to strike any walls
	pmo->special1 = 0;

	angle = pmo->angle;
	slope = P_AimLineAttack (pmo, angle, MELEERANGE);
	P_LineAttack (pmo, angle, MELEERANGE, slope, damage, MOD_HIT, pufftype);

axedone:
	if (useMana == 2)
	{
		AWeapon *weapon = player->ReadyWeapon;
		if (weapon != NULL)
		{
			weapon->DepleteAmmo (weapon->bAltFire, false);

			if ((weapon->Ammo1 == NULL || weapon->Ammo1->Amount == 0) &&
				(!(weapon->WeaponFlags & WIF_PRIMARY_USES_BOTH) ||
				  weapon->Ammo2 == NULL || weapon->Ammo2->Amount == 0))
			{
				P_SetPsprite (player, ps_weapon, &AFWeapAxe::States[S_FAXEATK+5]);
			}
		}
	}
	return;		
}
Ejemplo n.º 20
0
DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack)
{
	angle_t angle;
	int damage;
	fixed_t power;
	int slope;
	int i;
	player_t *player;
	AActor *linetarget;

	if (NULL == (player = self->player))
	{
		return;
	}
	AActor *pmo=player->mo;

	damage = 60+(pr_hammeratk()&63);
	power = 10*FRACUNIT;
	for (i = 0; i < 16; i++)
	{
		angle = pmo->angle + i*(ANG45/32);
		slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, &linetarget, 0, ALF_CHECK3D);
		if (linetarget)
		{
			P_LineAttack (pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, PClass::FindClass ("HammerPuff"), true, &linetarget);
			if (linetarget != NULL)
			{
				AdjustPlayerAngle(pmo, linetarget);
				if (linetarget->flags3&MF3_ISMONSTER || linetarget->player)
				{
					P_ThrustMobj (linetarget, angle, power);
				}

				// [BC] Apply spread.
				if ( player->cheats & CF_SPREAD )
				{
					P_LineAttack (pmo, angle + ( ANGLE_45 / 3 ), HAMMER_RANGE, slope, damage, NAME_Melee, PClass::FindClass ("HammerPuff"), true);
					AdjustPlayerAngle(pmo, linetarget);
					if ( linetarget->flags3 & MF3_ISMONSTER || linetarget->player )
					{
						P_ThrustMobj( linetarget, angle + ( ANGLE_45 / 3 ), power );
					}

					P_LineAttack (pmo, angle - ( ANGLE_45 / 3 ), HAMMER_RANGE, slope, damage, NAME_Melee, PClass::FindClass ("HammerPuff"), true);
					AdjustPlayerAngle(pmo, linetarget);
					if ( linetarget->flags3 & MF3_ISMONSTER || linetarget->player )
					{
						P_ThrustMobj( linetarget, angle - ( ANGLE_45 / 3 ), power );
					}
				}

				pmo->special1 = false; // Don't throw a hammer
				goto hammerdone;
			}
		}
		angle = pmo->angle-i*(ANG45/32);
		slope = P_AimLineAttack(pmo, angle, HAMMER_RANGE, &linetarget, 0, ALF_CHECK3D);
		if(linetarget)
		{
			P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, PClass::FindClass ("HammerPuff"), true, &linetarget);
			if (linetarget != NULL)
			{
				AdjustPlayerAngle(pmo, linetarget);
				if (linetarget->flags3&MF3_ISMONSTER || linetarget->player)
				{
					P_ThrustMobj(linetarget, angle, power);
				}

				// [BC] Apply spread.
				if ( player->cheats & CF_SPREAD )
				{
					P_LineAttack(pmo, angle + ( ANGLE_45 / 3 ), HAMMER_RANGE, slope, damage, NAME_Melee, PClass::FindClass ("HammerPuff"), true);
					AdjustPlayerAngle(pmo, linetarget);
					if ( linetarget->flags3 & MF3_ISMONSTER || linetarget->player )
					{
						P_ThrustMobj( linetarget, angle + ( ANGLE_45 / 3 ), power );
					}

					P_LineAttack(pmo, angle - ( ANGLE_45 / 3 ), HAMMER_RANGE, slope, damage, NAME_Melee, PClass::FindClass ("HammerPuff"), true);
					AdjustPlayerAngle(pmo, linetarget);
					if ( linetarget->flags3 & MF3_ISMONSTER || linetarget->player )
					{
						P_ThrustMobj( linetarget, angle - ( ANGLE_45 / 3 ), power );
					}
				}

				pmo->special1 = false; // Don't throw a hammer
				goto hammerdone;
			}
		}
	}
	// didn't find any targets in meleerange, so set to throw out a hammer
	angle = pmo->angle;
	slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, &linetarget, 0, ALF_CHECK3D);
	if (P_LineAttack (pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, PClass::FindClass ("HammerPuff"), true) != NULL)
	{
		pmo->special1 = false;
	}
	else
	{
		pmo->special1 = true;
	}

	// [BC] Apply spread.
	if ( player->cheats & CF_SPREAD )
	{
		if (P_LineAttack (pmo, angle + ( ANGLE_45 / 3 ), HAMMER_RANGE, slope, damage, NAME_Melee, PClass::FindClass ("HammerPuff"), true) != NULL)
			pmo->special1 = false;
		else
			pmo->special1 = true;

		if (P_LineAttack (pmo, angle - ( ANGLE_45 / 3 ), HAMMER_RANGE, slope, damage, NAME_Melee, PClass::FindClass ("HammerPuff"), true) != NULL)
			pmo->special1 = false;
		else
			pmo->special1 = true;
	}

hammerdone:
	// Don't spawn a hammer if the player doesn't have enough mana
	if (player->ReadyWeapon == NULL ||
		!player->ReadyWeapon->CheckAmmo (player->ReadyWeapon->bAltFire ?
			AWeapon::AltFire : AWeapon::PrimaryFire, false, true))
	{ 
		pmo->special1 = false;
	}
	return;		
}