diff --git a/src/actor.h b/src/actor.h index 67f266fb6..1773da915 100644 --- a/src/actor.h +++ b/src/actor.h @@ -768,9 +768,6 @@ public: // Adds one item of a particular type. Returns NULL if it could not be added. AInventory *GiveInventoryType (PClassActor *type); - // Returns the first item held with IF_INVBAR set. - AInventory *FirstInv (); - // Destroys all the inventory the actor is holding. void DestroyAllInventory (); diff --git a/src/g_statusbar/sbarinfo_commands.cpp b/src/g_statusbar/sbarinfo_commands.cpp index e859d728e..2eb527979 100644 --- a/src/g_statusbar/sbarinfo_commands.cpp +++ b/src/g_statusbar/sbarinfo_commands.cpp @@ -2133,7 +2133,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->FirstInv() != statusBar->CPlayer->mo->InvFirst) + if (!noArrows && statusBar->CPlayer->mo->InvFirst->PrevInv()) { int offset = (style != STYLE_Strife ? (style != STYLE_HexenStrict ? -12 : -10) : 14); int yOffset = style != STYLE_HexenStrict ? 0 : -1; diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index dcb38f3c9..8a5c0533e 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -1294,84 +1294,15 @@ void DBaseStatusBar::CallScreenSizeChanged() AInventory *DBaseStatusBar::ValidateInvFirst (int numVisible) const { - AInventory *item; - int i; - - if (CPlayer->mo->InvFirst == NULL) + IFVM(BaseStatusBar, ValidateInvFirst) { - CPlayer->mo->InvFirst = CPlayer->mo->FirstInv(); - if (CPlayer->mo->InvFirst == NULL) - { // Nothing to show - return NULL; - } - } - - assert (CPlayer->mo->InvFirst->Owner == CPlayer->mo); - - // If there are fewer than numVisible items shown, see if we can shift the - // view left to show more. - for (i = 0, item = CPlayer->mo->InvFirst; item != NULL && i < numVisible; ++i, item = item->NextInv()) - { } - - while (i < numVisible) - { - item = CPlayer->mo->InvFirst->PrevInv (); - if (item == NULL) - { - break; - } - else - { - CPlayer->mo->InvFirst = item; - ++i; - } - } - - if (CPlayer->mo->InvSel == NULL) - { - // Nothing selected, so don't move the view. - return CPlayer->mo->InvFirst == NULL ? CPlayer->mo->Inventory : CPlayer->mo->InvFirst; - } - else - { - // Check if InvSel is already visible - for (item = CPlayer->mo->InvFirst, i = numVisible; - item != NULL && i != 0; - item = item->NextInv(), --i) - { - if (item == CPlayer->mo->InvSel) - { - return CPlayer->mo->InvFirst; - } - } - // Check if InvSel is to the right of the visible range - for (i = 1; item != NULL; item = item->NextInv(), ++i) - { - if (item == CPlayer->mo->InvSel) - { - // Found it. Now advance InvFirst - for (item = CPlayer->mo->InvFirst; i != 0; --i) - { - item = item->NextInv(); - } - return item; - } - } - // Check if InvSel is to the left of the visible range - for (item = CPlayer->mo->Inventory; - item != CPlayer->mo->InvSel; - item = item->NextInv()) - { } - if (item != NULL) - { - // Found it, so let it become the first item shown - return item; - } - // Didn't find the selected item, so don't move the view. - // This should never happen, so let debug builds assert. - assert (item != NULL); - return CPlayer->mo->InvFirst; + VMValue params[] = { (AInventory*)this, numVisible }; + AInventory *item; + VMReturn ret((void**)&item); + VMCall(func, params, 2, &ret, 1); + return item; } + return nullptr; } uint32_t DBaseStatusBar::GetTranslation() const @@ -1907,10 +1838,3 @@ FTextureID GetInventoryIcon(AInventory *item, uint32_t flags, int *applyscale) return picnum; } -DEFINE_ACTION_FUNCTION(DBaseStatusBar, ValidateInvFirst) -{ - PARAM_SELF_PROLOGUE(DBaseStatusBar); - PARAM_INT(num); - ACTION_RETURN_POINTER(self->ValidateInvFirst(num)); -} - diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index fe48ebcd5..ae2b1432e 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -809,33 +809,6 @@ DEFINE_ACTION_FUNCTION(AActor, DestroyAllInventory) self->DestroyAllInventory(); return 0; } -//============================================================================ -// -// AActor :: FirstInv -// -// Returns the first item in this actor's inventory that has IF_INVBAR set. -// -//============================================================================ - -AInventory *AActor::FirstInv () -{ - if (Inventory == NULL) - { - return NULL; - } - if (Inventory->ItemFlags & IF_INVBAR) - { - return Inventory; - } - return Inventory->NextInv (); -} - -DEFINE_ACTION_FUNCTION(AActor, FirstInv) -{ - PARAM_SELF_PROLOGUE(AActor); - ACTION_RETURN_OBJECT(self->FirstInv()); -} - //============================================================================ // // AActor :: UseInventory diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 8748be7ff..c88141033 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -585,7 +585,6 @@ class Actor : Thinker native native void SetShade(color col); native clearscope int GetRenderStyle() const; native clearscope bool CheckKeys(int locknum, bool remote, bool quiet = false); - native clearscope Inventory FirstInv() const; protected native void CheckPortalTransition(bool linked = true); native clearscope string GetTag(string defstr = "") const; diff --git a/wadsrc/static/zscript/actor_inventory.txt b/wadsrc/static/zscript/actor_inventory.txt index 9641cf1f3..27816f041 100644 --- a/wadsrc/static/zscript/actor_inventory.txt +++ b/wadsrc/static/zscript/actor_inventory.txt @@ -1,5 +1,27 @@ extend class Actor { + + //============================================================================ + // + // AActor :: FirstInv + // + // Returns the first item in this actor's inventory that has IF_INVBAR set. + // + //============================================================================ + + clearscope Inventory FirstInv () + { + if (Inv == NULL) + { + return NULL; + } + if (Inv.bInvBar) + { + return Inv; + } + return Inv.NextInv (); + } + //============================================================================ // // AActor :: AddInventory diff --git a/wadsrc/static/zscript/inventory/inventory.txt b/wadsrc/static/zscript/inventory/inventory.txt index 2dcd1d857..fed1ab972 100644 --- a/wadsrc/static/zscript/inventory/inventory.txt +++ b/wadsrc/static/zscript/inventory/inventory.txt @@ -1039,7 +1039,7 @@ class Inventory : Actor native // //=========================================================================== - Inventory PrevInv () + clearscope Inventory PrevInv () { Inventory lastgood = NULL; Inventory item = Owner.Inv; diff --git a/wadsrc/static/zscript/statusbar/statusbar.txt b/wadsrc/static/zscript/statusbar/statusbar.txt index 2a187d701..a55af690e 100644 --- a/wadsrc/static/zscript/statusbar/statusbar.txt +++ b/wadsrc/static/zscript/statusbar/statusbar.txt @@ -341,7 +341,6 @@ class BaseStatusBar native ui native TextureID GetMugshot(int accuracy, int stateflags=MugShot.STANDARD, String default_face = "STF"); // These functions are kept native solely for performance reasons. They get called repeatedly and can drag down performance easily if they get too slow. - native Inventory ValidateInvFirst (int numVisible) const; native static TextureID, bool GetInventoryIcon(Inventory item, int flags); native void DrawTexture(TextureID texture, Vector2 pos, int flags = 0, double Alpha = 1., Vector2 box = (-1, -1), Vector2 scale = (1, 1)); native void DrawImage(String texture, Vector2 pos, int flags = 0, double Alpha = 1., Vector2 box = (-1, -1), Vector2 scale = (1, 1)); @@ -358,6 +357,95 @@ class BaseStatusBar native ui screen.ClearClipRect(); } + //--------------------------------------------------------------------------- + // + // ValidateInvFirst + // + // Returns an inventory item that, when drawn as the first item, is sure to + // include the selected item in the inventory bar. + // + //--------------------------------------------------------------------------- + + Inventory ValidateInvFirst (int numVisible) const + { + Inventory item; + int i; + let pmo = CPlayer.mo; + + if (pmo.InvFirst == NULL) + { + pmo.InvFirst = pmo.FirstInv(); + if (pmo.InvFirst == NULL) + { // Nothing to show + return NULL; + } + } + + // If there are fewer than numVisible items shown, see if we can shift the + // view left to show more. + for (i = 0, item = pmo.InvFirst; item != NULL && i < numVisible; ++i, item = item.NextInv()) + { } + + while (i < numVisible) + { + item = pmo.InvFirst.PrevInv (); + if (item == NULL) + { + break; + } + else + { + pmo.InvFirst = item; + ++i; + } + } + + if (pmo.InvSel == NULL) + { + // Nothing selected, so don't move the view. + return pmo.InvFirst == NULL ? pmo.Inv : pmo.InvFirst; + } + else + { + // Check if InvSel is already visible + for (item = pmo.InvFirst, i = numVisible; + item != NULL && i != 0; + item = item.NextInv(), --i) + { + if (item == pmo.InvSel) + { + return pmo.InvFirst; + } + } + // Check if InvSel is to the right of the visible range + for (i = 1; item != NULL; item = item.NextInv(), ++i) + { + if (item == pmo.InvSel) + { + // Found it. Now advance InvFirst + for (item = pmo.InvFirst; i != 0; --i) + { + item = item.NextInv(); + } + return item; + } + } + // Check if InvSel is to the left of the visible range + for (item = pmo.Inv; + item != pmo.InvSel; + item = item.NextInv()) + { } + if (item != NULL) + { + // Found it, so let it become the first item shown + return item; + } + // Didn't find the selected item, so don't move the view. + // This should never happen. + return pmo.InvFirst; + } + } + //============================================================================ // // DBaseStatusBar :: GetCurrentAmmo