- exported a few more weapon handling functions so that the native GetDownState stub could be removed.

This commit is contained in:
Christoph Oelckers 2018-11-24 18:21:40 +01:00
parent d8aa39e03e
commit 595208f2fd
9 changed files with 159 additions and 169 deletions

View file

@ -227,26 +227,6 @@ bool AWeapon::CheckAmmo(int fireMode, bool autoSwitch, bool requireAmmo, int amm
return false;
}
//===========================================================================
//
// AWeapon :: GetDownState
//
//===========================================================================
FState *AWeapon::GetDownState ()
{
IFVIRTUAL(AWeapon, GetDownState)
{
VMValue params[1] = { (DObject*)this };
VMReturn ret;
FState *retval;
ret.PointerAt((void**)&retval);
VMCall(func, params, 1, &ret, 1);
return retval;
}
return nullptr;
}
/* Weapon slots ***********************************************************/
//===========================================================================

View file

@ -128,9 +128,6 @@ public:
void Finalize(FStateDefinitions &statedef) override;
void Serialize(FSerializer &arc) override;
// scripted virtuals.
FState *GetDownState ();
enum
{
PrimaryFire,

View file

@ -599,7 +599,13 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOf
flags &= ~MF_SOLID;
player->playerstate = PST_DEAD;
P_DropWeapon (player);
IFVM(PlayerPawn, DropWeapon)
{
VMValue param = player->mo;
VMCall(func, &param, 1, nullptr, 0);
}
if (this == players[consoleplayer].camera && automapactive)
{
// don't die in auto map, switch view prior to dying

View file

@ -80,7 +80,6 @@ extern int bmapnegy;
// P_PSPR
//
void P_SetupPsprites (player_t* curplayer, bool startweaponup);
void P_DropWeapon (player_t* player);
//

View file

@ -563,34 +563,6 @@ void P_BringUpWeapon (player_t *player)
}
}
//---------------------------------------------------------------------------
//
// PROC P_DropWeapon
//
// The player died, so put the weapon away.
//
//---------------------------------------------------------------------------
void P_DropWeapon (player_t *player)
{
if (player == nullptr)
{
return;
}
// Since the weapon is dropping, stop blocking switching.
player->WeaponState &= ~WF_DISABLESWITCH;
if ((player->ReadyWeapon != nullptr) && (player->health > 0 || !(player->ReadyWeapon->WeaponFlags & WIF_NODEATHDESELECT)))
{
P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->GetDownState());
}
}
DEFINE_ACTION_FUNCTION(_PlayerInfo, DropWeapon)
{
PARAM_SELF_STRUCT_PROLOGUE(player_t);
P_DropWeapon(self);
return 0;
}
//============================================================================
//
// P_BobWeapon

View file

@ -124,7 +124,6 @@ void P_CalcSwing (player_t *player);
void P_SetPsprite(player_t *player, PSPLayers id, FState *state, bool pending = false);
void P_BringUpWeapon (player_t *player);
void P_FireWeapon (player_t *player);
void P_DropWeapon (player_t *player);
void P_BobWeapon (player_t *player, float *x, float *y, double ticfrac);
DAngle P_BulletSlope (AActor *mo, FTranslatedLineTarget *pLineTarget = NULL, int aimflags = 0);
AActor *P_AimTarget(AActor *mo);

View file

@ -1041,73 +1041,6 @@ bool APlayerPawn::UseInventory (AInventory *item)
return true;
}
//===========================================================================
//
// APlayerPawn :: BestWeapon
//
// Returns the best weapon a player has, possibly restricted to a single
// type of ammo.
//
//===========================================================================
AWeapon *APlayerPawn::BestWeapon(PClassActor *ammotype)
{
AWeapon *bestMatch = NULL;
int bestOrder = INT_MAX;
AInventory *item;
AWeapon *weap;
bool tomed = NULL != FindInventory (PClass::FindActor(NAME_PowerWeaponLevel2), true);
// Find the best weapon the player has.
for (item = Inventory; item != NULL; item = item->Inventory)
{
if (!item->IsKindOf(NAME_Weapon))
continue;
weap = static_cast<AWeapon *> (item);
// Don't select it if it's worse than what was already found.
if (weap->SelectionOrder > bestOrder)
continue;
// Don't select it if its primary fire doesn't use the desired ammo.
if (ammotype != NULL &&
(weap->Ammo1 == NULL ||
weap->Ammo1->GetClass() != ammotype))
continue;
// Don't select it if the Tome is active and this isn't the powered-up version.
if (tomed && weap->SisterWeapon != NULL && weap->SisterWeapon->WeaponFlags & WIF_POWERED_UP)
continue;
// Don't select it if it's powered-up and the Tome is not active.
if (!tomed && weap->WeaponFlags & WIF_POWERED_UP)
continue;
// Don't select it if there isn't enough ammo to use its primary fire.
if (!(weap->WeaponFlags & WIF_AMMO_OPTIONAL) &&
!weap->CheckAmmo (AWeapon::PrimaryFire, false))
continue;
// Don't select if if there isn't enough ammo as determined by the weapon's author.
if (weap->MinSelAmmo1 > 0 && (weap->Ammo1 == NULL || weap->Ammo1->Amount < weap->MinSelAmmo1))
continue;
if (weap->MinSelAmmo2 > 0 && (weap->Ammo2 == NULL || weap->Ammo2->Amount < weap->MinSelAmmo2))
continue;
// This weapon is usable!
bestOrder = weap->SelectionOrder;
bestMatch = weap;
}
return bestMatch;
}
DEFINE_ACTION_FUNCTION(APlayerPawn, BestWeapon)
{
PARAM_SELF_PROLOGUE(APlayerPawn);
PARAM_CLASS(ammo, AActor);
ACTION_RETURN_POINTER(self->BestWeapon(ammo));
}
//===========================================================================
//
// APlayerPawn :: PickNewWeapon
@ -1120,29 +1053,17 @@ DEFINE_ACTION_FUNCTION(APlayerPawn, BestWeapon)
AWeapon *APlayerPawn::PickNewWeapon(PClassActor *ammotype)
{
AWeapon *best = BestWeapon (ammotype);
if (best != NULL)
AWeapon *best = nullptr;
IFVM(PlayerPawn, DropWeapon)
{
player->PendingWeapon = best;
if (player->ReadyWeapon != NULL)
{
P_DropWeapon(player);
}
else if (player->PendingWeapon != WP_NOCHANGE)
{
P_BringUpWeapon (player);
}
VMValue param = player->mo;
VMReturn ret((void**)&best);
VMCall(func, &param, 1, &ret, 1);
}
return best;
}
DEFINE_ACTION_FUNCTION(APlayerPawn, PickNewWeapon)
{
PARAM_SELF_PROLOGUE(APlayerPawn);
PARAM_CLASS(ammo, AActor);
ACTION_RETURN_POINTER(self->PickNewWeapon(ammo));
}
//===========================================================================
//
// APlayerPawn :: GiveDeathmatchInventory

View file

@ -218,7 +218,7 @@ class Weapon : StateProvider native
}
if (player.PendingWeapon != WP_NOCHANGE)
{
player.DropWeapon();
player.mo.DropWeapon();
return;
}
if (player.ReadyWeapon == null)

View file

@ -382,7 +382,7 @@ class PlayerPawn : Actor native
if ((player.PendingWeapon != WP_NOCHANGE || player.health <= 0) &&
player.WeaponState & WF_WEAPONSWITCHOK)
{
player.DropWeapon();
DropWeapon();
}
}
@ -1312,7 +1312,119 @@ class PlayerPawn : Actor native
}
}
//===========================================================================
//
// APlayerPawn :: BestWeapon
//
// Returns the best weapon a player has, possibly restricted to a single
// type of ammo.
//
//===========================================================================
Weapon BestWeapon(Class<Ammo> ammotype)
{
Weapon bestMatch = NULL;
int bestOrder = int.max;
Inventory item;
bool tomed = !!FindInventory ('PowerWeaponLevel2', true);
// Find the best weapon the player has.
for (item = Inv; item != NULL; item = item.Inv)
{
let weap = Weapon(item);
if (weap == null)
continue;
// Don't select it if it's worse than what was already found.
if (weap.SelectionOrder > bestOrder)
continue;
// Don't select it if its primary fire doesn't use the desired ammo.
if (ammotype != NULL &&
(weap.Ammo1 == NULL ||
weap.Ammo1.GetClass() != ammotype))
continue;
// Don't select it if the Tome is active and this isn't the powered-up version.
if (tomed && weap.SisterWeapon != NULL && weap.SisterWeapon.bPowered_Up)
continue;
// Don't select it if it's powered-up and the Tome is not active.
if (!tomed && weap.bPowered_Up)
continue;
// Don't select it if there isn't enough ammo to use its primary fire.
if (!(weap.bAMMO_OPTIONAL) &&
!weap.CheckAmmo (Weapon.PrimaryFire, false))
continue;
// Don't select if if there isn't enough ammo as determined by the weapon's author.
if (weap.MinSelAmmo1 > 0 && (weap.Ammo1 == NULL || weap.Ammo1.Amount < weap.MinSelAmmo1))
continue;
if (weap.MinSelAmmo2 > 0 && (weap.Ammo2 == NULL || weap.Ammo2.Amount < weap.MinSelAmmo2))
continue;
// This weapon is usable!
bestOrder = weap.SelectionOrder;
bestMatch = weap;
}
return bestMatch;
}
//---------------------------------------------------------------------------
//
// PROC P_DropWeapon
//
// The player died, so put the weapon away.
//
//---------------------------------------------------------------------------
void DropWeapon ()
{
let player = self.player;
if (player == null)
{
return;
}
// Since the weapon is dropping, stop blocking switching.
player.WeaponState &= ~WF_DISABLESWITCH;
Weapon weap = player.ReadyWeapon;
if ((weap != null) && (player.health > 0 || !weap.bNoDeathDeselect))
{
player.SetPsprite(PSP_WEAPON, weap.GetDownState());
}
}
//===========================================================================
//
// APlayerPawn :: PickNewWeapon
//
// Picks a new weapon for this player. Used mostly for running out of ammo,
// but it also works when an ACS script explicitly takes the ready weapon
// away or the player picks up some ammo they had previously run out of.
//
//===========================================================================
Weapon PickNewWeapon(Class<Ammo> ammotype)
{
Weapon best = BestWeapon (ammotype);
if (best != NULL)
{
player.PendingWeapon = best;
if (player.ReadyWeapon != NULL)
{
DropWeapon();
}
else if (player.PendingWeapon != WP_NOCHANGE)
{
BringUpWeapon ();
}
}
return best;
}
//----------------------------------------------------------------------------
//
//
@ -1327,8 +1439,6 @@ class PlayerPawn : Actor native
native void CheckEnvironment();
native void CheckUse();
native void CheckWeaponButtons();
native Weapon BestWeapon(class<Ammo> ammotype);
native Weapon PickNewWeapon(class<Ammo> ammotype);
}
class PlayerChunk : PlayerPawn
@ -1523,6 +1633,30 @@ struct PlayerInfo native play // this is what internally is known as player_t
native @UserCmd cmd;
native readonly @UserCmd original_cmd;
native bool PoisonPlayer(Actor poisoner, Actor source, int poison);
native void PoisonDamage(Actor source, int damage, bool playPainSound);
native void SetPsprite(int id, State stat, bool pending = false);
native void SetSafeFlash(Weapon weap, State flashstate, int index);
native PSprite GetPSprite(int id) const;
native PSprite FindPSprite(int id) const;
native void SetLogNumber (int text);
native void SetLogText (String text);
native bool Resurrect();
native String GetUserName() const;
native Color GetColor() const;
native Color GetDisplayColor() const;
native int GetColorSet() const;
native int GetPlayerClassNum() const;
native int GetSkin() const;
native bool GetNeverSwitch() const;
native int GetGender() const;
native int GetTeam() const;
native float GetAutoaim() const;
native bool GetNoAutostartMap() const;
native void SetFOV(float fov);
native bool GetClassicFlight() const;
native clearscope bool HasWeaponsInSlot(int slot) const;
// The actual implementation is on PlayerPawn where it can be overridden. Use that directly in the future.
deprecated("3.7") bool MorphPlayer(playerinfo p, Class<PlayerPawn> spawntype, int duration, int style, Class<Actor> enter_flash = null, Class<Actor> exit_flash = null)
@ -1543,33 +1677,15 @@ struct PlayerInfo native play // this is what internally is known as player_t
}
return false;
}
deprecated("3.7") void DropWeapon()
{
if (mo != null)
{
mo.DropWeapon();
}
}
native bool PoisonPlayer(Actor poisoner, Actor source, int poison);
native void PoisonDamage(Actor source, int damage, bool playPainSound);
native void SetPsprite(int id, State stat, bool pending = false);
native void SetSafeFlash(Weapon weap, State flashstate, int index);
native PSprite GetPSprite(int id) const;
native PSprite FindPSprite(int id) const;
native void SetLogNumber (int text);
native void SetLogText (String text);
native void DropWeapon();
native bool Resurrect();
native String GetUserName() const;
native Color GetColor() const;
native Color GetDisplayColor() const;
native int GetColorSet() const;
native int GetPlayerClassNum() const;
native int GetSkin() const;
native bool GetNeverSwitch() const;
native int GetGender() const;
native int GetTeam() const;
native float GetAutoaim() const;
native bool GetNoAutostartMap() const;
native void SetFOV(float fov);
native bool GetClassicFlight() const;
native clearscope bool HasWeaponsInSlot(int slot) const;
bool IsTotallyFrozen()
{
return