- scriptified A_SkullPop and ObtainInventory.

These were the last relevant items to access PlayerPawn.InvFirst.
This commit is contained in:
Christoph Oelckers 2019-01-03 00:35:56 +01:00
parent 6eb8ded471
commit c753d59a72
8 changed files with 101 additions and 107 deletions

View File

@ -118,10 +118,8 @@ public:
int BonusHealth;
int MugShotMaxHealth;
int RunHealth;
int PlayerFlags;
double FullHeight;
TObjPtr<AActor*> InvFirst; // first inventory item displayed on inventory bar
TObjPtr<AActor*> InvSel; // selected inventory item
// [GRB] Player class properties
@ -129,8 +127,6 @@ public:
double GruntSpeed;
double FallingScreamMinSpeed, FallingScreamMaxSpeed;
double ViewHeight;
double ForwardMove1, ForwardMove2;
double SideMove1, SideMove2;
FTextureID ScoreIcon;
int SpawnMask;
FName MorphWeapon;
@ -153,6 +149,10 @@ public:
double HexenArmor[5];
// Everything below this point is only used by scripted code.
int RunHealth;
TObjPtr<AActor*> InvFirst; // first inventory item displayed on inventory bar
double ForwardMove1, ForwardMove2;
double SideMove1, SideMove2;
PClassActor *FlechetteType;
};

View File

@ -2119,11 +2119,12 @@ class CommandDrawInventoryBar : public SBarInfoCommand
AActor *item;
unsigned int i = 0;
auto &InvFirst = statusBar->CPlayer->mo->PointerVar<AActor>(NAME_InvFirst);
// If the player has no artifacts, don't draw the bar
statusBar->CPlayer->mo->InvFirst = statusBar->wrapper->ValidateInvFirst(size);
if(statusBar->CPlayer->mo->InvFirst != NULL || alwaysShow)
InvFirst = statusBar->wrapper->ValidateInvFirst(size);
if (InvFirst != nullptr || alwaysShow)
{
for(item = statusBar->CPlayer->mo->InvFirst, i = 0; item != NULL && i < size; item = NextInv(item), ++i)
for(item = InvFirst, i = 0; item != NULL && i < size; item = NextInv(item), ++i)
{
SBarInfoCoordinate rx = x + (!vertical ? i*spacing : 0);
SBarInfoCoordinate ry = y + (vertical ? i*spacing : 0);
@ -2157,7 +2158,7 @@ class CommandDrawInventoryBar : public SBarInfoCommand
statusBar->DrawGraphic(statusBar->Images[statusBar->invBarOffset + imgARTIBOX], x + (!vertical ? (i*spacing) : 0), y + (vertical ? (i*spacing) : 0), block->XOffset(), block->YOffset(), bgalpha, block->FullScreenOffsets());
// Is there something to the left?
if (!noArrows && statusBar->CPlayer->mo->InvFirst && PrevInv(statusBar->CPlayer->mo->InvFirst))
if (!noArrows && InvFirst && PrevInv(statusBar->CPlayer->mo->InvFirst))
{
int offset = (style != STYLE_Strife ? (style != STYLE_HexenStrict ? -12 : -10) : 14);
int yOffset = style != STYLE_HexenStrict ? 0 : -1;

View File

@ -1031,7 +1031,7 @@ xx(PickupSound)
// PlayerPawn member fields
xx(ColorRangeStart)
xx(ColorRangeEnd)
xx(InvFirst)
xx(BlueCard)
xx(YellowCard)

View File

@ -812,50 +812,6 @@ DEFINE_ACTION_FUNCTION(AActor, CopyFriendliness)
self->CopyFriendliness(other, changetarget, resethealth);
return 0;
}
//============================================================================
//
// AActor :: ObtainInventory
//
// Removes the items from the other actor and puts them in this actor's
// inventory. The actor receiving the inventory must not have any items.
//
//============================================================================
void AActor::ObtainInventory (AActor *other)
{
assert (Inventory == NULL);
Inventory = other->Inventory;
InventoryID = other->InventoryID;
other->Inventory = NULL;
other->InventoryID = 0;
if (other->IsKindOf(RUNTIME_CLASS(APlayerPawn)) && this->IsKindOf(RUNTIME_CLASS(APlayerPawn)))
{
APlayerPawn *you = static_cast<APlayerPawn *>(other);
APlayerPawn *me = static_cast<APlayerPawn *>(this);
me->InvFirst = you->InvFirst;
me->InvSel = you->InvSel;
you->InvFirst = NULL;
you->InvSel = NULL;
}
auto item = Inventory;
while (item != nullptr)
{
item->PointerVar<AActor>(NAME_Owner) = this;
item = item->Inventory;
}
}
DEFINE_ACTION_FUNCTION(AActor, ObtainInventory)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT(other, AActor);
self->ObtainInventory(other);
return 0;
}
//---------------------------------------------------------------------------
//
// FUNC P_GetRealMaxHealth
@ -5039,7 +4995,11 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags)
else if (oldactor != NULL && oldactor->player == p && !(flags & SPF_TEMPPLAYER))
{
// Move the voodoo doll's inventory to the new player.
mobj->ObtainInventory (oldactor);
IFVM(Actor, ObtainInventory)
{
VMValue params[] = { mobj, oldactor };
VMCall(func, params, 2, nullptr, 0);
}
FBehavior::StaticStopMyScripts (oldactor); // cancel all ENTER/RESPAWN scripts for the voodoo doll
}

View File

@ -1183,56 +1183,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_PlayerScream)
}
//----------------------------------------------------------------------------
//
// PROC A_SkullPop
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_SkullPop)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_CLASS(spawntype, APlayerPawn);
APlayerPawn *mo;
player_t *player;
// [GRB] Parameterized version
if (spawntype == NULL || !spawntype->IsDescendantOf("PlayerChunk"))
{
spawntype = PClass::FindActor("BloodySkull");
if (spawntype == NULL)
return 0;
}
self->flags &= ~MF_SOLID;
mo = (APlayerPawn *)Spawn (spawntype, self->PosPlusZ(48.), NO_REPLACE);
//mo->target = self;
mo->Vel.X = pr_skullpop.Random2() / 128.;
mo->Vel.Y = pr_skullpop.Random2() / 128.;
mo->Vel.Z = 2. + (pr_skullpop() / 1024.);
// Attach player mobj to bloody skull
player = self->player;
self->player = NULL;
mo->ObtainInventory (self);
mo->player = player;
mo->health = self->health;
mo->Angles.Yaw = self->Angles.Yaw;
if (player != NULL)
{
player->mo = mo;
player->damagecount = 32;
}
for (int i = 0; i < MAXPLAYERS; ++i)
{
if (playeringame[i] && players[i].camera == self)
{
players[i].camera = mo;
}
}
return 0;
}
//===========================================================================
//
// P_CheckPlayerSprites

View File

@ -777,7 +777,6 @@ class Actor : Thinker native
protected native void DestroyAllInventory(); // This is not supposed to be called by user code!
native clearscope Inventory FindInventory(class<Inventory> itemtype, bool subclass = false) const;
native Inventory GiveInventoryType(class<Inventory> itemtype);
native void ObtainInventory(Actor other);
native bool UsePuzzleItem(int PuzzleItemType);
action native void SetCamera(Actor cam, bool revert = false);
@ -1029,7 +1028,6 @@ class Actor : Thinker native
native void A_FastChase();
native void A_PlayerScream();
native void A_SkullPop(class<PlayerChunk> skulltype = "BloodySkull");
native void A_CheckTerrain();
native void A_Wander(int flags = 0);

View File

@ -730,6 +730,44 @@ extend class Actor
return false;
}
//============================================================================
//
// AActor :: ObtainInventory
//
// Removes the items from the other actor and puts them in this actor's
// inventory. The actor receiving the inventory must not have any items.
//
//============================================================================
void ObtainInventory (Actor other)
{
Inv = other.Inv;
InventoryID = other.InventoryID;
other.Inv = NULL;
other.InventoryID = 0;
let you = PlayerPawn(other);
let me = PlayerPawn(self);
if (you)
{
if (me)
{
me.InvFirst = you.InvFirst;
me.InvSel = you.InvSel;
}
you.InvFirst = NULL;
you.InvSel = NULL;
}
for (let item = Inv; item != null; item = item.Inv)
{
item.Owner = self;
}
}
//===========================================================================
//
// A_SelectWeapon

View File

@ -2173,7 +2173,7 @@ class PlayerPawn : Actor native
return p1 * (1. - ticfrac) + p2 * ticfrac;
}
//----------------------------------------------------------------------------
//
//
@ -2191,6 +2191,53 @@ class PlayerPawn : Actor native
native void MarkPlayerSounds();
}
extend class Actor
{
//----------------------------------------------------------------------------
//
// PROC A_SkullPop
// This should really be in PlayerPawn but cannot be.
//
//----------------------------------------------------------------------------
void A_SkullPop(class<PlayerChunk> skulltype = "BloodySkull")
{
// [GRB] Parameterized version
if (skulltype == NULL || !(skulltype is "PlayerChunk"))
{
skulltype = "BloodySkull";
if (skulltype == NULL)
return;
}
bSolid = false;
let mo = PlayerPawn(Spawn (skulltype, Pos + (0, 0, 48), NO_REPLACE));
//mo.target = self;
mo.Vel.X = Random2[SkullPop]() / 128.;
mo.Vel.Y = Random2[SkullPop]() / 128.;
mo.Vel.Z = 2. + (Random[SkullPop]() / 1024.);
// Attach player mobj to bloody skull
let player = self.player;
self.player = NULL;
mo.ObtainInventory (self);
mo.player = player;
mo.health = health;
mo.Angle = Angle;
if (player != NULL)
{
player.mo = mo;
player.damagecount = 32;
}
for (int i = 0; i < MAXPLAYERS; ++i)
{
if (playeringame[i] && players[i].camera == self)
{
players[i].camera = mo;
}
}
}
}
class PlayerChunk : PlayerPawn
{
Default