Exemple #1
0
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireArrow)
{
	PARAM_ACTION_PROLOGUE;
	PARAM_CLASS(ti, AActor);

	angle_t savedangle;

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

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

	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);
	}
	return 0;
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnSingleItem)
{
	PARAM_ACTION_PROLOGUE;
	PARAM_CLASS		(cls, AActor);
	PARAM_INT_OPT	(fail_sp) { fail_sp = 0; }
	PARAM_INT_OPT	(fail_co) { fail_co = 0; }
	PARAM_INT_OPT	(fail_dm) { fail_dm = 0; }

	AActor *spot = NULL;
	DSpotState *state = DSpotState::GetSpotState();

	if (state != NULL) spot = state->GetRandomSpot(self->GetClass(), true);
	if (spot == NULL) return 0;

	if (!multiplayer && pr_spawnmace() < fail_sp)
	{ // Sometimes doesn't show up if not in deathmatch
		return 0;
	}

	if (multiplayer && !deathmatch && pr_spawnmace() < fail_co)
	{
		return 0;
	}

	if (deathmatch && pr_spawnmace() < fail_dm)
	{
		return 0;
	}

	if (cls == NULL)
	{
		return 0;
	}

	AActor *spawned = Spawn(cls, self->Pos(), ALLOW_REPLACE);

	if (spawned)
	{
		spawned->SetOrigin (spot->Pos(), false);
		spawned->SetZ(spawned->floorz);
		// We want this to respawn.
		if (!(self->flags & MF_DROPPED)) 
		{
			spawned->flags &= ~MF_DROPPED;
		}
		if (spawned->IsKindOf(RUNTIME_CLASS(AInventory)))
		{
			static_cast<AInventory*>(spawned)->SpawnPointClass = self->GetClass();
		}
	}
	return 0;
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DropWeaponPieces)
{
	PARAM_SELF_PROLOGUE(AActor);
	PARAM_CLASS(p1, AActor);
	PARAM_CLASS(p2, AActor);
	PARAM_CLASS(p3, AActor);

	for (int i = 0, j = 0; i < 3; ++i)
	{
		PClassActor *cls = j == 0 ?  p1 : j == 1 ? p2 : p3;
		if (cls)
		{
			AActor *piece = Spawn (cls, self->Pos(), ALLOW_REPLACE);
			if (piece != NULL)
			{
				piece->Vel = self->Vel + DAngle(i*120.).ToVector(1);
				piece->flags |= MF_DROPPED;
				j = (j == 0) ? (pr_quietusdrop() & 1) + 1 : 3-j;
			}
		}
	}
	return 0;
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireGrenade)
{
	PARAM_ACTION_PROLOGUE;
	PARAM_CLASS(grenadetype, AActor);
	PARAM_ANGLE(angleofs);
	PARAM_STATE(flash)

	player_t *player = self->player;
	AActor *grenade;
	DAngle an;
	AWeapon *weapon;

	if (player == nullptr || grenadetype == nullptr)
		return 0;

	if ((weapon = player->ReadyWeapon) == nullptr)
		return 0;

	if (!weapon->DepleteAmmo (weapon->bAltFire))
		return 0;

	P_SetPsprite (player, PSP_FLASH, flash, true);

	if (grenadetype != nullptr)
	{
		self->AddZ(32);
		grenade = P_SpawnSubMissile (self, grenadetype, self);
		self->AddZ(-32);
		if (grenade == nullptr)
			return 0;

		if (grenade->SeeSound != 0)
		{
			S_Sound (grenade, CHAN_VOICE, grenade->SeeSound, 1, ATTN_NORM);
		}

		grenade->Vel.Z = (-self->Angles.Pitch.TanClamped()) * grenade->Speed + 8;

		DVector2 offset = self->Angles.Yaw.ToVector(self->radius + grenade->radius);
		DAngle an = self->Angles.Yaw + angleofs;
		offset += an.ToVector(15);
		grenade->SetOrigin(grenade->Vec3Offset(offset.X, offset.Y, 0.), false);
	}
	return 0;
}