Пример #1
0
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DropWeaponPieces)
{
	ACTION_PARAM_START(3);
	ACTION_PARAM_CLASS(p1, 0);
	ACTION_PARAM_CLASS(p2, 1);
	ACTION_PARAM_CLASS(p3, 2);

	for (int i = 0, j = 0, fineang = 0; i < 3; ++i)
	{
		const PClass *cls = j==0? p1 : j==1? p2 : p3;
		if (cls)
		{
			AActor *piece = Spawn (cls, self->x, self->y, self->z, ALLOW_REPLACE);
			if (piece != NULL)
			{
				piece->velx = self->velx + finecosine[fineang];
				piece->vely = self->vely + finesine[fineang];
				piece->velz = self->velz;
				piece->flags |= MF_DROPPED;
				fineang += FINEANGLES/3;
				j = (j == 0) ? (pr_quietusdrop() & 1) + 1 : 3-j;
			}
		}
	}
}
Пример #2
0
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack1)
{
	AActor *missile;
	angle_t an;

	if (!self->target)
		return;

	ACTION_PARAM_START(1);
	ACTION_PARAM_CLASS(spawntype, 0);

	if (spawntype == NULL) spawntype = PClass::FindClass("FatShot");

	A_FaceTarget (self);
	// Change direction  to ...
	self->angle += FATSPREAD;
	missile = P_SpawnMissile (self, self->target, spawntype);

	// [BC] If we're the server, tell clients to spawn the missile.
	if (( NETWORK_GetState( ) == NETSTATE_SERVER ) && ( missile ))
		SERVERCOMMANDS_SpawnMissile( missile );

	missile = P_SpawnMissile (self, self->target, spawntype);
	if (missile != NULL)
	{
		missile->angle += FATSPREAD;
		an = missile->angle >> ANGLETOFINESHIFT;
		missile->velx = FixedMul (missile->Speed, finecosine[an]);
		missile->vely = FixedMul (missile->Speed, finesine[an]);

		// [BC] If we're the server, tell clients to spawn the missile.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			SERVERCOMMANDS_SpawnMissile( missile );
	}
Пример #3
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;
}
Пример #4
0
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack1)
{
	AActor *missile;
	angle_t an;

	if (!self->target)
		return;

	ACTION_PARAM_START(1);
	ACTION_PARAM_CLASS(spawntype, 0);

	if (spawntype == NULL) spawntype = PClass::FindClass("FatShot");

	A_FaceTarget (self);
	// Change direction  to ...
	self->angle += FATSPREAD;
	P_SpawnMissile (self, self->target, spawntype);

	missile = P_SpawnMissile (self, self->target, spawntype);
	if (missile != NULL)
	{
		missile->angle += FATSPREAD;
		an = missile->angle >> ANGLETOFINESHIFT;
		missile->velx = FixedMul (missile->Speed, finecosine[an]);
		missile->vely = FixedMul (missile->Speed, finesine[an]);
	}
Пример #5
0
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BridgeInit)
{
	angle_t startangle;
	AActor *ball;
	fixed_t cx, cy, cz;

	ACTION_PARAM_START(1);
	ACTION_PARAM_CLASS(balltype, 0);

	if (balltype == NULL) balltype = PClass::FindClass("BridgeBall");

	cx = self->x;
	cy = self->y;
	cz = self->z;
	startangle = pr_orbit() << 24;
	self->special1 = 0;

	// Spawn triad into world -- may be more than a triad now.
	int ballcount = self->args[2]==0 ? 3 : self->args[2];

	for (int i = 0; i < ballcount; i++)
	{
		ball = Spawn(balltype, cx, cy, cz, ALLOW_REPLACE);
		ball->angle = startangle + (ANGLE_45/32) * (256/ballcount) * i;
		ball->target = self;
		CALL_ACTION(A_BridgeOrbit, ball);

		// [Dusk] bridge balls should not be included in full updates
		// as the bridge thing will spawn them instead.
		if (NETWORK_GetState() == NETSTATE_SERVER)
			ball->ulNetworkFlags |= NETFL_ALLOWCLIENTSPAWN;
	}
}
Пример #6
0
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireArrow)
{
	angle_t savedangle;

	ACTION_PARAM_START(1);
	ACTION_PARAM_CLASS(ti, 0);

	if (self->player == NULL)
		return;

	AWeapon *weapon = self->player->ReadyWeapon;
	if (weapon != NULL)
	{
		if (!weapon->DepleteAmmo (weapon->bAltFire))
			return;
	}

	if (ti) 
	{
		savedangle = self->angle;
		self->angle += pr_electric.Random2 () << (18 - self->player->mo->accuracy * 5 / 100);
		self->player->mo->PlayAttacking2 ();
		P_SpawnPlayerMissile (self, ti);
		self->angle = savedangle;
		S_Sound (self, CHAN_WEAPON, "weapons/xbowshoot", 1, ATTN_NORM);
	}
}
Пример #7
0
static const PClass *GetSpawnType(DECLARE_PARAMINFO)
{
	ACTION_PARAM_START(1);
	ACTION_PARAM_CLASS(spawntype, 0);

	if (spawntype == NULL) spawntype = PClass::FindClass("LostSoul");
	return spawntype;
}
Пример #8
0
//
// A_PainAttack
// Spawn a lost soul and launch it at the target
// 
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainAttack)
{
	if (!self->target)
		return;

	ACTION_PARAM_START(4);
	ACTION_PARAM_CLASS(spawntype, 0);
	ACTION_PARAM_ANGLE(angle, 1);
	ACTION_PARAM_INT(flags, 2);
	ACTION_PARAM_INT(limit, 3);

	if (spawntype == NULL) spawntype = PClass::FindClass("LostSoul");

	if (!(flags & PAF_AIMFACING))
		A_FaceTarget (self);
	A_PainShootSkull (self, self->angle+angle, spawntype, flags, limit);
}
Пример #9
0
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnFly)
{
	FSoundID sound;

	ACTION_PARAM_START(1);
	ACTION_PARAM_CLASS(spawntype, 0);

	if (spawntype != NULL) 
	{
		sound = GetDefaultByType(spawntype)->SeeSound;
	}
	else
	{
		spawntype = PClass::FindClass ("SpawnFire");
		sound = "brain/spawn";
	}
	SpawnFly(self, spawntype, sound);
}
Пример #10
0
//
// A_VileTarget
// Spawn the hellfire
//
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileTarget)
{
	ACTION_PARAM_START(1);
	ACTION_PARAM_CLASS(fire,0);
	AActor *fog;
		
	if (!self->target)
		return;

	A_FaceTarget (self);

	fog = Spawn (fire, self->target->x, self->target->y,
		self->target->z, ALLOW_REPLACE);
	
	self->tracer = fog;
	fog->target = self;
	fog->tracer = self->target;
	A_Fire(fog, 0);
}
Пример #11
0
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PodPain)
{
	ACTION_PARAM_START(1);
	ACTION_PARAM_CLASS(gootype, 0);

	int count;
	int chance;
	AActor *goo;

	chance = pr_podpain ();
	if (chance < 128)
	{
		return;
	}
	for (count = chance > 240 ? 2 : 1; count; count--)
	{
		goo = Spawn(gootype, self->x, self->y, self->z + 48*FRACUNIT, ALLOW_REPLACE);
		goo->target = self;
		goo->velx = pr_podpain.Random2() << 9;
		goo->vely = pr_podpain.Random2() << 9;
		goo->velz = FRACUNIT/2 + (pr_podpain() << 9);
	}
}
Пример #12
0
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BrainSpit)
{
	DSpotState *state = DSpotState::GetSpotState();
	AActor *targ;
	AActor *spit;
	bool isdefault = false;

	ACTION_PARAM_START(1);
	ACTION_PARAM_CLASS(spawntype, 0);

	// shoot a cube at current target
	targ = state->GetNextInList(PClass::FindClass("BossTarget"), G_SkillProperty(SKILLP_EasyBossBrain));

	if (targ != NULL)
	{
		if (spawntype == NULL) 
		{
			spawntype = PClass::FindClass("SpawnShot");
			isdefault = true;
		}

		// spawn brain missile
		spit = P_SpawnMissile (self, targ, spawntype);

		if (spit != NULL)
		{
			// Boss cubes should move freely to their destination so it's
			// probably best to disable all collision detection for them.
			if (spit->flags & MF_NOCLIP) spit->flags5 |= MF5_NOINTERACTION;
	
			spit->target = targ;
			spit->master = self;
			// [RH] Do this correctly for any trajectory. Doom would divide by 0
			// if the target had the same y coordinate as the spitter.
			if ((spit->velx | spit->vely) == 0)
			{
				spit->special2 = 0;
			}
			else if (abs(spit->vely) > abs(spit->velx))
			{
				spit->special2 = (targ->y - self->y) / spit->vely;
			}
			else
			{
				spit->special2 = (targ->x - self->x) / spit->velx;
			}
			// [GZ] Calculates when the projectile will have reached destination
			spit->special2 += level.maptime;
			spit->flags6 |= MF6_BOSSCUBE;
		}

		if (!isdefault)
		{
			S_Sound(self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NONE);
		}
		else
		{
			// compatibility fallback
			S_Sound (self, CHAN_WEAPON, "brain/spit", 1, ATTN_NONE);
		}
	}
}
Пример #13
0
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
{
	angle_t angle;
	angle_t slope;
	player_t *player;
	AActor *linetarget;
	int actualdamage;

	ACTION_PARAM_START(11);
	ACTION_PARAM_SOUND(fullsound, 0);
	ACTION_PARAM_SOUND(hitsound, 1);
	ACTION_PARAM_INT(damage, 2);
	ACTION_PARAM_CLASS(pufftype, 3);
	ACTION_PARAM_INT(Flags, 4);
	ACTION_PARAM_FIXED(Range, 5);
	ACTION_PARAM_ANGLE(Spread_XY, 6);
	ACTION_PARAM_ANGLE(Spread_Z, 7);
	ACTION_PARAM_FIXED(LifeSteal, 8);
	ACTION_PARAM_INT(lifestealmax, 9);
	ACTION_PARAM_CLASS(armorbonustype, 10);

	if (NULL == (player = self->player))
	{
		return;
	}

	if (pufftype == NULL) pufftype = PClass::FindClass(NAME_BulletPuff);
	if (damage == 0) damage = 2;

	if (!(Flags & SF_NORANDOM))
		damage *= (pr_saw()%10+1);
	
	// use meleerange + 1 so the puff doesn't skip the flash (i.e. plays all states)
	if (Range == 0) Range = MELEERANGE+1;

	angle = self->angle + (pr_saw.Random2() * (Spread_XY / 255));
	slope = P_AimLineAttack (self, angle, Range, &linetarget) + (pr_saw.Random2() * (Spread_Z / 255));

	AWeapon *weapon = self->player->ReadyWeapon;
	if ((weapon != NULL) && !(Flags & SF_NOUSEAMMO) && !(!linetarget && (Flags & SF_NOUSEAMMOMISS)) && !(weapon->WeaponFlags & WIF_DEHAMMO))
	{
		if (!weapon->DepleteAmmo (weapon->bAltFire))
			return;
	}

	P_LineAttack (self, angle, Range, slope, damage, NAME_Melee, pufftype, false, &linetarget, &actualdamage);

	if (!linetarget)
	{
		if ((Flags & SF_RANDOMLIGHTMISS) && (pr_saw() > 64))
		{
			player->extralight = !player->extralight;
		}
		S_Sound (self, CHAN_WEAPON, fullsound, 1, ATTN_NORM);
		return;
	}

	if (Flags & SF_RANDOMLIGHTHIT)
	{
		int randVal = pr_saw();
		if (randVal < 64)
		{
			player->extralight = 0;
		}
		else if (randVal < 160)
		{
			player->extralight = 1;
		}
		else
		{
			player->extralight = 2;
		}
	}

	if (LifeSteal && !(linetarget->flags5 & MF5_DONTDRAIN))
	{
		if (Flags & SF_STEALARMOR)
		{
			if (!armorbonustype) armorbonustype = PClass::FindClass("ArmorBonus");

			if (armorbonustype->IsDescendantOf (RUNTIME_CLASS(ABasicArmorBonus)))
			{
				ABasicArmorBonus *armorbonus = static_cast<ABasicArmorBonus *>(Spawn (armorbonustype, 0,0,0, NO_REPLACE));
				armorbonus->SaveAmount *= (actualdamage * LifeSteal) >> FRACBITS;
				armorbonus->MaxSaveAmount = lifestealmax <= 0 ? armorbonus->MaxSaveAmount : lifestealmax;
				armorbonus->flags |= MF_DROPPED;
				armorbonus->ClearCounters();

				if (!armorbonus->CallTryPickup (self))
				{
					armorbonus->Destroy ();
				}
			}
		}

		else
		{