mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-28 23:11:58 +00:00
- scriptified the weapon firing logic.
This commit is contained in:
parent
abee2805cb
commit
b84f7bcada
8 changed files with 289 additions and 362 deletions
|
@ -100,7 +100,6 @@ public:
|
|||
void ActivateMorphWeapon ();
|
||||
AWeapon *PickNewWeapon (PClassActor *ammotype);
|
||||
AWeapon *BestWeapon (PClassActor *ammotype);
|
||||
void CheckWeaponSwitch(PClassActor *ammotype);
|
||||
void GiveDeathmatchInventory ();
|
||||
void FilterCoopRespawnInventory (APlayerPawn *oldplayer);
|
||||
|
||||
|
@ -109,7 +108,6 @@ public:
|
|||
|
||||
// These are virtual on the script side only.
|
||||
void PlayIdle();
|
||||
void PlayAttacking ();
|
||||
void PlayAttacking2 ();
|
||||
|
||||
const char *GetSoundClass () const;
|
||||
|
|
|
@ -446,46 +446,6 @@ FState *AWeapon::GetReadyState ()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AWeapon :: GetAtkState
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
FState *AWeapon::GetAtkState (bool hold)
|
||||
{
|
||||
IFVIRTUAL(AWeapon, GetAtkState)
|
||||
{
|
||||
VMValue params[2] = { (DObject*)this, hold };
|
||||
VMReturn ret;
|
||||
FState *retval;
|
||||
ret.PointerAt((void**)&retval);
|
||||
VMCall(func, params, 2, &ret, 1);
|
||||
return retval;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AWeapon :: GetAtkState
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
FState *AWeapon::GetAltAtkState (bool hold)
|
||||
{
|
||||
IFVIRTUAL(AWeapon, GetAltAtkState)
|
||||
{
|
||||
VMValue params[2] = { (DObject*)this, hold };
|
||||
VMReturn ret;
|
||||
FState *retval;
|
||||
ret.PointerAt((void**)&retval);
|
||||
VMCall(func, params, 2, &ret, 1);
|
||||
return retval;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AWeapon :: GetStateForButtonName
|
||||
|
|
|
@ -132,8 +132,6 @@ public:
|
|||
FState *GetUpState ();
|
||||
FState *GetDownState ();
|
||||
FState *GetReadyState ();
|
||||
FState *GetAtkState (bool hold);
|
||||
FState *GetAltAtkState (bool hold);
|
||||
|
||||
FState *GetStateForButtonName (FName button);
|
||||
|
||||
|
|
275
src/p_pspr.cpp
275
src/p_pspr.cpp
|
@ -126,6 +126,7 @@ DEFINE_FIELD(DPSprite, Next)
|
|||
DEFINE_FIELD(DPSprite, Owner)
|
||||
DEFINE_FIELD(DPSprite, Sprite)
|
||||
DEFINE_FIELD(DPSprite, Frame)
|
||||
DEFINE_FIELD(DPSprite, Flags)
|
||||
DEFINE_FIELD(DPSprite, ID)
|
||||
DEFINE_FIELD(DPSprite, processPending)
|
||||
DEFINE_FIELD(DPSprite, x)
|
||||
|
@ -601,82 +602,6 @@ DEFINE_ACTION_FUNCTION(_PlayerInfo, BringUpWeapon)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC P_FireWeapon
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void P_FireWeapon (player_t *player, FState *state)
|
||||
{
|
||||
AWeapon *weapon;
|
||||
|
||||
// [SO] 9/2/02: People were able to do an awful lot of damage
|
||||
// when they were observers...
|
||||
if (player->Bot == nullptr && bot_observer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
weapon = player->ReadyWeapon;
|
||||
if (weapon == nullptr || !weapon->CheckAmmo (AWeapon::PrimaryFire, true))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
player->WeaponState &= ~WF_WEAPONBOBBING;
|
||||
player->mo->PlayAttacking ();
|
||||
weapon->bAltFire = false;
|
||||
if (state == nullptr)
|
||||
{
|
||||
state = weapon->GetAtkState(!!player->refire);
|
||||
}
|
||||
P_SetPsprite(player, PSP_WEAPON, state);
|
||||
if (!(weapon->WeaponFlags & WIF_NOALERT))
|
||||
{
|
||||
P_NoiseAlert (player->mo, player->mo, false);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC P_FireWeaponAlt
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void P_FireWeaponAlt (player_t *player, FState *state)
|
||||
{
|
||||
AWeapon *weapon;
|
||||
|
||||
// [SO] 9/2/02: People were able to do an awful lot of damage
|
||||
// when they were observers...
|
||||
if (player->Bot == nullptr && bot_observer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
weapon = player->ReadyWeapon;
|
||||
if (weapon == nullptr || weapon->FindState(NAME_AltFire) == nullptr || !weapon->CheckAmmo (AWeapon::AltFire, true))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
player->WeaponState &= ~WF_WEAPONBOBBING;
|
||||
player->mo->PlayAttacking ();
|
||||
weapon->bAltFire = true;
|
||||
|
||||
if (state == nullptr)
|
||||
{
|
||||
state = weapon->GetAltAtkState(!!player->refire);
|
||||
}
|
||||
|
||||
P_SetPsprite(player, PSP_WEAPON, state);
|
||||
if (!(weapon->WeaponFlags & WIF_NOALERT))
|
||||
{
|
||||
P_NoiseAlert (player->mo, player->mo, false);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC P_DropWeapon
|
||||
|
@ -935,78 +860,6 @@ DEFINE_ACTION_FUNCTION(AStateProvider, A_WeaponReady)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC P_CheckWeaponFire
|
||||
//
|
||||
// The player can fire the weapon.
|
||||
// [RH] This was in A_WeaponReady before, but that only works well when the
|
||||
// weapon's ready frames have a one tic delay.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void P_CheckWeaponFire (player_t *player)
|
||||
{
|
||||
AWeapon *weapon = player->ReadyWeapon;
|
||||
|
||||
if (weapon == NULL)
|
||||
return;
|
||||
|
||||
// Check for fire. Some weapons do not auto fire.
|
||||
if ((player->WeaponState & WF_WEAPONREADY) && (player->cmd.ucmd.buttons & BT_ATTACK))
|
||||
{
|
||||
if (!player->attackdown || !(weapon->WeaponFlags & WIF_NOAUTOFIRE))
|
||||
{
|
||||
player->attackdown = true;
|
||||
P_FireWeapon (player, NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if ((player->WeaponState & WF_WEAPONREADYALT) && (player->cmd.ucmd.buttons & BT_ALTATTACK))
|
||||
{
|
||||
if (!player->attackdown || !(weapon->WeaponFlags & WIF_NOAUTOFIRE))
|
||||
{
|
||||
player->attackdown = true;
|
||||
P_FireWeaponAlt (player, NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player->attackdown = false;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC P_CheckWeaponSwitch
|
||||
//
|
||||
// The player can change to another weapon at this time.
|
||||
// [GZ] This was cut from P_CheckWeaponFire.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void P_CheckWeaponSwitch (player_t *player)
|
||||
{
|
||||
if (player == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ((player->WeaponState & WF_DISABLESWITCH) || // Weapon changing has been disabled.
|
||||
player->morphTics != 0) // Morphed classes cannot change weapons.
|
||||
{ // ...so throw away any pending weapon requests.
|
||||
player->PendingWeapon = WP_NOCHANGE;
|
||||
}
|
||||
|
||||
// Put the weapon away if the player has a pending weapon or has died, and
|
||||
// we're at a place in the state sequence where dropping the weapon is okay.
|
||||
if ((player->PendingWeapon != WP_NOCHANGE || player->health <= 0) &&
|
||||
player->WeaponState & WF_WEAPONSWITCHOK)
|
||||
{
|
||||
P_DropWeapon(player);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC P_CheckWeaponButtons
|
||||
|
@ -1046,53 +899,13 @@ static void P_CheckWeaponButtons (player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC A_ReFire
|
||||
//
|
||||
// The player can re-fire the weapon without lowering it entirely.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AStateProvider, A_ReFire)
|
||||
DEFINE_ACTION_FUNCTION(APlayerPawn, CheckWeaponButtons)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE(AStateProvider);
|
||||
PARAM_STATE_ACTION_DEF(state);
|
||||
A_ReFire(self, state);
|
||||
PARAM_SELF_PROLOGUE(APlayerPawn);
|
||||
P_CheckWeaponButtons(self->player);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void A_ReFire(AActor *self, FState *state)
|
||||
{
|
||||
player_t *player = self->player;
|
||||
bool pending;
|
||||
|
||||
if (NULL == player)
|
||||
{
|
||||
return;
|
||||
}
|
||||
pending = player->PendingWeapon != WP_NOCHANGE && (player->WeaponState & WF_REFIRESWITCHOK);
|
||||
if ((player->cmd.ucmd.buttons & BT_ATTACK)
|
||||
&& !player->ReadyWeapon->bAltFire && !pending && player->health > 0)
|
||||
{
|
||||
player->refire++;
|
||||
P_FireWeapon (player, state);
|
||||
}
|
||||
else if ((player->cmd.ucmd.buttons & BT_ALTATTACK)
|
||||
&& player->ReadyWeapon->bAltFire && !pending && player->health > 0)
|
||||
{
|
||||
player->refire++;
|
||||
P_FireWeaponAlt (player, state);
|
||||
}
|
||||
else
|
||||
{
|
||||
player->refire = 0;
|
||||
player->ReadyWeapon->CheckAmmo (player->ReadyWeapon->bAltFire
|
||||
? AWeapon::AltFire : AWeapon::PrimaryFire, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC A_OverlayOffset
|
||||
|
@ -1459,86 +1272,6 @@ void P_SetupPsprites(player_t *player, bool startweaponup)
|
|||
P_BringUpWeapon (player);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// PROC P_MovePsprites
|
||||
//
|
||||
// Called every tic by player thinking routine
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
void player_t::TickPSprites()
|
||||
{
|
||||
DPSprite *pspr = psprites;
|
||||
while (pspr)
|
||||
{
|
||||
// Destroy the psprite if it's from a weapon that isn't currently selected by the player
|
||||
// or if it's from an inventory item that the player no longer owns.
|
||||
if ((pspr->Caller == nullptr ||
|
||||
(pspr->Caller->IsKindOf(RUNTIME_CLASS(AInventory)) && barrier_cast<AInventory *>(pspr->Caller)->Owner != pspr->Owner->mo) ||
|
||||
(pspr->Caller->IsKindOf(NAME_Weapon) && pspr->Caller != pspr->Owner->ReadyWeapon)))
|
||||
{
|
||||
pspr->Destroy();
|
||||
}
|
||||
else
|
||||
{
|
||||
pspr->Tick();
|
||||
}
|
||||
|
||||
pspr = pspr->Next;
|
||||
}
|
||||
|
||||
if ((health > 0) || (ReadyWeapon != nullptr && !(ReadyWeapon->WeaponFlags & WIF_NODEATHINPUT)))
|
||||
{
|
||||
if (ReadyWeapon == nullptr)
|
||||
{
|
||||
if (PendingWeapon != WP_NOCHANGE)
|
||||
P_BringUpWeapon(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
P_CheckWeaponSwitch(this);
|
||||
if (WeaponState & (WF_WEAPONREADY | WF_WEAPONREADYALT))
|
||||
{
|
||||
P_CheckWeaponFire(this);
|
||||
}
|
||||
// Check custom buttons
|
||||
P_CheckWeaponButtons(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_PlayerInfo, TickPSprites)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(player_t);
|
||||
self->TickPSprites();
|
||||
return 0;
|
||||
}
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
void DPSprite::Tick()
|
||||
{
|
||||
if (processPending)
|
||||
{
|
||||
// drop tic count and possibly change state
|
||||
if (Tics != -1) // a -1 tic count never changes
|
||||
{
|
||||
Tics--;
|
||||
|
||||
// [BC] Apply double firing speed.
|
||||
if ((Flags & PSPF_POWDOUBLE) && Tics && (Owner->mo->FindInventory (PClass::FindActor(NAME_PowerDoubleFiringSpeed), true)))
|
||||
Tics--;
|
||||
|
||||
if (!Tics)
|
||||
SetState(State->GetNextState());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
|
|
|
@ -103,7 +103,6 @@ private:
|
|||
DPSprite () {}
|
||||
|
||||
void Serialize(FSerializer &arc);
|
||||
void Tick();
|
||||
|
||||
public: // must be public to be able to generate the field export tables. Grrr...
|
||||
TObjPtr<AActor*> Caller;
|
||||
|
|
|
@ -1217,6 +1217,12 @@ AWeapon *APlayerPawn::BestWeapon(PClassActor *ammotype)
|
|||
return bestMatch;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(APlayerPawn, BestWeapon)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(APlayerPawn);
|
||||
PARAM_CLASS(ammo, AActor);
|
||||
ACTION_RETURN_POINTER(self->BestWeapon(ammo));
|
||||
}
|
||||
//===========================================================================
|
||||
//
|
||||
// APlayerPawn :: PickNewWeapon
|
||||
|
@ -1246,38 +1252,6 @@ AWeapon *APlayerPawn::PickNewWeapon(PClassActor *ammotype)
|
|||
return best;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APlayerPawn :: CheckWeaponSwitch
|
||||
//
|
||||
// Checks if weapons should be changed after picking up ammo
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APlayerPawn::CheckWeaponSwitch(PClassActor *ammotype)
|
||||
{
|
||||
if (!player->userinfo.GetNeverSwitch() &&
|
||||
player->PendingWeapon == WP_NOCHANGE &&
|
||||
(player->ReadyWeapon == NULL ||
|
||||
(player->ReadyWeapon->WeaponFlags & WIF_WIMPY_WEAPON)))
|
||||
{
|
||||
AWeapon *best = BestWeapon (ammotype);
|
||||
if (best != NULL && (player->ReadyWeapon == NULL ||
|
||||
best->SelectionOrder < player->ReadyWeapon->SelectionOrder))
|
||||
{
|
||||
player->PendingWeapon = best;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(APlayerPawn, CheckWeaponSwitch)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(APlayerPawn);
|
||||
PARAM_POINTER(ammotype, PClassActor);
|
||||
self->CheckWeaponSwitch(ammotype);
|
||||
return 0;
|
||||
}
|
||||
//===========================================================================
|
||||
//
|
||||
// APlayerPawn :: GiveDeathmatchInventory
|
||||
|
@ -1541,15 +1515,6 @@ void APlayerPawn::PlayIdle ()
|
|||
}
|
||||
}
|
||||
|
||||
void APlayerPawn::PlayAttacking ()
|
||||
{
|
||||
IFVIRTUAL(APlayerPawn, PlayAttacking)
|
||||
{
|
||||
VMValue params[1] = { (DObject*)this };
|
||||
VMCall(func, params, 1, nullptr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void APlayerPawn::PlayAttacking2 ()
|
||||
{
|
||||
IFVIRTUAL(APlayerPawn, PlayAttacking2)
|
||||
|
|
|
@ -8,7 +8,43 @@ class StateProvider : Inventory native
|
|||
action native void A_RailAttack(int damage, int spawnofs_xy = 0, bool useammo = true, color color1 = 0, color color2 = 0, int flags = 0, double maxdiff = 0, class<Actor> pufftype = "BulletPuff", double spread_xy = 0, double spread_z = 0, double range = 0, int duration = 0, double sparsity = 1.0, double driftspeed = 1.0, class<Actor> spawnclass = "none", double spawnofs_z = 0, int spiraloffset = 270, int limit = 0);
|
||||
action native void A_WeaponReady(int flags = 0);
|
||||
|
||||
action native void A_ReFire(statelabel flash = null);
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC A_ReFire
|
||||
//
|
||||
// The player can re-fire the weapon without lowering it entirely.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
action void A_ReFire(statelabel flash = null)
|
||||
{
|
||||
let player = self.player;
|
||||
bool pending;
|
||||
|
||||
if (NULL == player)
|
||||
{
|
||||
return;
|
||||
}
|
||||
pending = player.PendingWeapon != WP_NOCHANGE && (player.WeaponState & WF_REFIRESWITCHOK);
|
||||
if ((player.cmd.buttons & BT_ATTACK)
|
||||
&& !player.ReadyWeapon.bAltFire && !pending && player.health > 0)
|
||||
{
|
||||
player.refire++;
|
||||
player.mo.FireWeapon(ResolveState(flash));
|
||||
}
|
||||
else if ((player.cmd.buttons & BT_ALTATTACK)
|
||||
&& player.ReadyWeapon.bAltFire && !pending && player.health > 0)
|
||||
{
|
||||
player.refire++;
|
||||
player.mo.FireWeaponAlt(ResolveState(flash));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.refire = 0;
|
||||
player.ReadyWeapon.CheckAmmo (player.ReadyWeapon.bAltFire? Weapon.AltFire : Weapon.PrimaryFire, true);
|
||||
}
|
||||
}
|
||||
|
||||
action native state A_CheckForReload(int counter, statelabel label, bool dontincrement = false);
|
||||
action native void A_ResetReloadCounter();
|
||||
|
||||
|
|
|
@ -218,6 +218,224 @@ class PlayerPawn : Actor native
|
|||
return -1, -1;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APlayerPawn :: CheckWeaponSwitch
|
||||
//
|
||||
// Checks if weapons should be changed after picking up ammo
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void CheckWeaponSwitch(Class<Ammo> ammotype)
|
||||
{
|
||||
let player = self.player;
|
||||
if (!player.GetNeverSwitch() && player.PendingWeapon == WP_NOCHANGE &&
|
||||
(player.ReadyWeapon == NULL || player.ReadyWeapon.bWimpy_Weapon))
|
||||
{
|
||||
let best = BestWeapon (ammotype);
|
||||
if (best != NULL && (player.ReadyWeapon == NULL ||
|
||||
best.SelectionOrder < player.ReadyWeapon.SelectionOrder))
|
||||
{
|
||||
player.PendingWeapon = best;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC P_FireWeapon
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
virtual void FireWeapon (State stat)
|
||||
{
|
||||
let player = self.player;
|
||||
|
||||
// [SO] 9/2/02: People were able to do an awful lot of damage
|
||||
// when they were observers...
|
||||
if (player.Bot == null && bot_observer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let weapn = player.ReadyWeapon;
|
||||
if (weapn == null || !weapn.CheckAmmo (Weapon.PrimaryFire, true))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
player.WeaponState &= ~WF_WEAPONBOBBING;
|
||||
PlayAttacking ();
|
||||
weapn.bAltFire = false;
|
||||
if (stat == null)
|
||||
{
|
||||
stat = weapn.GetAtkState(!!player.refire);
|
||||
}
|
||||
player.SetPsprite(PSP_WEAPON, stat);
|
||||
if (!weapn.bNoAlert)
|
||||
{
|
||||
SoundAlert (self, false);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC P_FireWeaponAlt
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
virtual void FireWeaponAlt (State stat)
|
||||
{
|
||||
// [SO] 9/2/02: People were able to do an awful lot of damage
|
||||
// when they were observers...
|
||||
if (player.Bot == null && bot_observer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let weapn = player.ReadyWeapon;
|
||||
if (weapn == null || weapn.FindState('AltFire') == null || !weapn.CheckAmmo (Weapon.AltFire, true))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
player.WeaponState &= ~WF_WEAPONBOBBING;
|
||||
PlayAttacking ();
|
||||
weapn.bAltFire = true;
|
||||
|
||||
if (stat == null)
|
||||
{
|
||||
stat = weapn.GetAltAtkState(!!player.refire);
|
||||
}
|
||||
|
||||
player.SetPsprite(PSP_WEAPON, stat);
|
||||
if (!weapn.bNoAlert)
|
||||
{
|
||||
SoundAlert (self, false);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC P_CheckWeaponFire
|
||||
//
|
||||
// The player can fire the weapon.
|
||||
// [RH] This was in A_WeaponReady before, but that only works well when the
|
||||
// weapon's ready frames have a one tic delay.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void CheckWeaponFire ()
|
||||
{
|
||||
let player = self.player;
|
||||
let weapon = player.ReadyWeapon;
|
||||
|
||||
if (weapon == NULL)
|
||||
return;
|
||||
|
||||
// Check for fire. Some weapons do not auto fire.
|
||||
if ((player.WeaponState & WF_WEAPONREADY) && (player.cmd.buttons & BT_ATTACK))
|
||||
{
|
||||
if (!player.attackdown || !weapon.bNoAutofire)
|
||||
{
|
||||
player.attackdown = true;
|
||||
FireWeapon (NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if ((player.WeaponState & WF_WEAPONREADYALT) && (player.cmd.buttons & BT_ALTATTACK))
|
||||
{
|
||||
if (!player.attackdown || !weapon.bNoAutofire)
|
||||
{
|
||||
player.attackdown = true;
|
||||
FireWeaponAlt (NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player.attackdown = false;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC P_CheckWeaponChange
|
||||
//
|
||||
// The player can change to another weapon at this time.
|
||||
// [GZ] This was cut from P_CheckWeaponFire.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
virtual void CheckWeaponChange ()
|
||||
{
|
||||
let player = self.player;
|
||||
if ((player.WeaponState & WF_DISABLESWITCH) || // Weapon changing has been disabled.
|
||||
player.morphTics != 0) // Morphed classes cannot change weapons.
|
||||
{ // ...so throw away any pending weapon requests.
|
||||
player.PendingWeapon = WP_NOCHANGE;
|
||||
}
|
||||
|
||||
// Put the weapon away if the player has a pending weapon or has died, and
|
||||
// we're at a place in the state sequence where dropping the weapon is okay.
|
||||
if ((player.PendingWeapon != WP_NOCHANGE || player.health <= 0) &&
|
||||
player.WeaponState & WF_WEAPONSWITCHOK)
|
||||
{
|
||||
player.DropWeapon();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// PROC P_MovePsprites
|
||||
//
|
||||
// Called every tic by player thinking routine
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
virtual void TickPSprites()
|
||||
{
|
||||
let player = self.player;
|
||||
let pspr = player.psprites;
|
||||
while (pspr)
|
||||
{
|
||||
// Destroy the psprite if it's from a weapon that isn't currently selected by the player
|
||||
// or if it's from an inventory item that the player no longer owns.
|
||||
if ((pspr.Caller == null ||
|
||||
(pspr.Caller is "Inventory" && Inventory(pspr.Caller).Owner != pspr.Owner.mo) ||
|
||||
(pspr.Caller is "Weapon" && pspr.Caller != pspr.Owner.ReadyWeapon)))
|
||||
{
|
||||
pspr.Destroy();
|
||||
}
|
||||
else
|
||||
{
|
||||
pspr.Tick();
|
||||
}
|
||||
|
||||
pspr = pspr.Next;
|
||||
}
|
||||
|
||||
if ((health > 0) || (player.ReadyWeapon != null && !player.ReadyWeapon.bNoDeathInput))
|
||||
{
|
||||
if (player.ReadyWeapon == null)
|
||||
{
|
||||
if (player.PendingWeapon != WP_NOCHANGE)
|
||||
player.BringUpWeapon();
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckWeaponChange();
|
||||
if (player.WeaponState & (WF_WEAPONREADY | WF_WEAPONREADYALT))
|
||||
{
|
||||
CheckWeaponFire();
|
||||
}
|
||||
// Check custom buttons
|
||||
CheckWeaponButtons();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// P_DeathThink
|
||||
|
@ -231,7 +449,7 @@ class PlayerPawn : Actor native
|
|||
double delta;
|
||||
|
||||
player.Uncrouch();
|
||||
player.TickPSprites();
|
||||
TickPSprites();
|
||||
|
||||
player.onground = (pos.Z <= floorz);
|
||||
if (self is "PlayerChunk")
|
||||
|
@ -1022,7 +1240,7 @@ class PlayerPawn : Actor native
|
|||
CheckUse();
|
||||
CheckUndoMorph();
|
||||
// Cycle psprites
|
||||
player.TickPSprites();
|
||||
TickPSprites();
|
||||
|
||||
// Other Counters
|
||||
if (player.damagecount) player.damagecount--;
|
||||
|
@ -1049,12 +1267,13 @@ class PlayerPawn : Actor native
|
|||
|
||||
native clearscope int GetMaxHealth(bool withupgrades = false) const;
|
||||
native bool ResetAirSupply (bool playgasp = false);
|
||||
native void CheckWeaponSwitch(class<Inventory> item);
|
||||
native clearscope static String GetPrintableDisplayName(Class<Actor> cls);
|
||||
native void CheckMusicChange();
|
||||
native void CalcHeight ();
|
||||
native void CheckEnvironment();
|
||||
native void CheckUse();
|
||||
native void CheckWeaponButtons();
|
||||
native Weapon BestWeapon(class<Ammo> ammotype);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1112,6 +1331,26 @@ class PSprite : Object native play
|
|||
|
||||
native void SetState(State newstate, bool pending = false);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
void Tick()
|
||||
{
|
||||
if (processPending)
|
||||
{
|
||||
// drop tic count and possibly change state
|
||||
if (Tics != -1) // a -1 tic count never changes
|
||||
{
|
||||
Tics--;
|
||||
// [BC] Apply double firing speed.
|
||||
if (bPowDouble && Tics && (Owner.mo.FindInventory ("PowerDoubleFiringSpeed", true))) Tics--;
|
||||
if (!Tics) SetState(CurState.NextState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum EPlayerState
|
||||
|
@ -1243,7 +1482,6 @@ struct PlayerInfo native play // this is what internally is known as player_t
|
|||
native bool GetNoAutostartMap() const;
|
||||
native void SetFOV(float fov);
|
||||
native clearscope bool HasWeaponsInSlot(int slot) const;
|
||||
native void TickPSprites();
|
||||
|
||||
bool IsTotallyFrozen()
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue