diff --git a/src/d_main.cpp b/src/d_main.cpp index 69d980932..25dc4537c 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -803,6 +803,10 @@ void D_Display () V_RefreshViewBorder (); } + // for timing the statusbar code. + //cycle_t stb; + //stb.Reset(); + //stb.Clock(); if (hud_althud && viewheight == SCREENHEIGHT && screenblocks > 10) { StatusBar->DrawBottomStuff (HUD_AltHud); @@ -828,6 +832,8 @@ void D_Display () StatusBar->CallDraw (HUD_StatusBar); StatusBar->DrawTopStuff (HUD_StatusBar); } + //stb.Unclock(); + //Printf("Stbar = %f\n", stb.TimeMS()); CT_Drawer (); break; diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index f4a3d2c6e..ab8255cdf 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -672,6 +672,13 @@ static int DrawAmmo(player_t *CPlayer, int x, int y) //--------------------------------------------------------------------------- FTextureID GetInventoryIcon(AInventory *item, uint32_t flags, bool *applyscale=NULL) // This function is also used by SBARINFO { + if (applyscale != NULL) + { + *applyscale = false; + } + + if (item == nullptr) return FNullTextureID(); + FTextureID picnum, AltIcon = item->AltHUDIcon; FState * state=NULL, *ReadyState; @@ -718,6 +725,17 @@ FTextureID GetInventoryIcon(AInventory *item, uint32_t flags, bool *applyscale=N return picnum; } +DEFINE_ACTION_FUNCTION(DBaseStatusBar, GetInventoryIcon) +{ + PARAM_PROLOGUE; + PARAM_OBJECT(item, AInventory); + PARAM_INT(flags); + bool applyscale; + FTextureID icon = GetInventoryIcon(item, flags, &applyscale); + if (numret >= 1) ret[0].SetInt(icon.GetIndex()); + if (numret >= 2) ret[1].SetInt(applyscale); + return MIN(numret, 2); +} static void DrawOneWeapon(player_t * CPlayer, int x, int & y, AWeapon * weapon) { diff --git a/src/g_statusbar/sbar.h b/src/g_statusbar/sbar.h index 927617c0b..5e12a695b 100644 --- a/src/g_statusbar/sbar.h +++ b/src/g_statusbar/sbar.h @@ -373,6 +373,28 @@ public: virtual bool MustDrawLog(EHudState state); virtual void SetMugShotState (const char *state_name, bool wait_till_done=false, bool reset=false); void DrawLog(); + uint32_t GetTranslation() const; + + enum EAlign + { + TOP = 0, + VCENTER = 1, + BOTTOM = 2, + VOFFSET = 3, + VMASK = 3, + + LEFT = 0, + HCENTER = 4, + RIGHT = 8, + HOFFSET = 12, + HMASK = 12, + + CENTER = VCENTER | HCENTER, + CENTER_BOTTOM = BOTTOM | HCENTER + }; + + void DBaseStatusBar::DrawGraphic(FTextureID texture, bool animate, double x, double y, double Alpha = 1., bool translatable = false, bool dim = false, + int imgAlign = TOP | LEFT, int screenalign = TOP | LEFT, bool alphamap = false, double width = -1, double height = -1, double scaleX = 1, double scaleY = 1, bool fullscreenoffsets = false); void GetCoords(int &x, int &y) { diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index e6ed9ac19..c41732c14 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -57,6 +57,7 @@ #include "cmdlib.h" #include "g_levellocals.h" #include "virtual.h" +#include "r_data/r_translate.h" #include "../version.h" @@ -624,9 +625,6 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, RefreshBackground) void DBaseStatusBar::DrawCrosshair () { - static uint32_t prevcolor = 0xffffffff; - static int palettecolor = 0; - uint32_t color; double size; int w, h; @@ -693,19 +691,13 @@ void DBaseStatusBar::DrawCrosshair () color = crosshaircolor; } - if (color != prevcolor) - { - prevcolor = color; - palettecolor = ColorMatcher.Pick (RPART(color), GPART(color), BPART(color)); - } - screen->DrawTexture (CrosshairImage, viewwidth / 2 + viewwindowx, viewheight / 2 + viewwindowy, DTA_DestWidth, w, DTA_DestHeight, h, DTA_AlphaChannel, true, - DTA_FillColor, (palettecolor << 24) | (color & 0xFFFFFF), + DTA_FillColor, color & 0xFFFFFF, TAG_DONE); } @@ -1377,6 +1369,120 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, ValidateInvFirst) } +uint32_t DBaseStatusBar::GetTranslation() const +{ + if (gameinfo.gametype & GAME_Raven) + return TRANSLATION(TRANSLATION_PlayersExtra, int(CPlayer - players)); + return TRANSLATION(TRANSLATION_Players, int(CPlayer - players)); +} + +//============================================================================ +// +// draw stuff +// +//============================================================================ +EXTERN_CVAR(Bool, hud_scale) +EXTERN_CVAR(Bool, vid_fps) + +void DBaseStatusBar::DrawGraphic(FTextureID texture, bool animate, double x, double y, double Alpha, bool translatable, bool dim, + int imgAlign, int screenalign, bool alphamap, double width, double height, double scaleX, double scaleY, bool fullscreenoffsets) +{ + if (!texture.isValid()) + return; + + FTexture *tex = animate ? TexMan(texture) : TexMan[texture]; + + switch (imgAlign & HMASK) + { + case HCENTER: x -= width / 2; break; + case RIGHT: x -= width; break; + case HOFFSET: x -= tex->GetScaledLeftOffsetDouble() * width / tex->GetScaledWidthDouble(); break; + } + + switch (imgAlign & VMASK) + { + case VCENTER: y -= height / 2; break; + case BOTTOM: y -= height; break; + case VOFFSET: y -= tex->GetScaledTopOffsetDouble() * height / tex->GetScaledHeightDouble(); break; + } + + if (!fullscreenoffsets) + { + x += ST_X; + y += ST_Y; + + // Todo: Allow other scaling values, too. + if (Scaled) + { + y += RelTop - VerticalResolution; + screen->VirtualToRealCoords(x, y, width, height, HorizontalResolution, VerticalResolution, true, true); + } + } + else + { + double orgx, orgy; + + switch (screenalign & HMASK) + { + default: orgx = 0; break; + case HCENTER: orgx = screen->GetWidth() / 2; break; + case RIGHT: orgx = screen->GetWidth(); break; + } + + switch (screenalign & VMASK) + { + default: orgy = 0; break; + case VCENTER: orgy = screen->GetHeight() / 2; break; + case BOTTOM: orgy = screen->GetHeight(); break; + } + + if (screenalign == (RIGHT | TOP) && vid_fps) y += 10; + + if (hud_scale) + { + x *= scaleX; + y *= scaleY; + width *= scaleX; + height *= scaleY; + } + x += orgx; + y += orgy; + } + screen->DrawTexture(tex, x, y, + DTA_TopOffset, 0, + DTA_LeftOffset, 0, + DTA_DestWidthF, width, + DTA_DestHeightF, height, + DTA_TranslationIndex, translatable ? GetTranslation() : 0, + DTA_ColorOverlay, dim ? PalEntry(170, 0, 0, 0) : 0, + DTA_Alpha, Alpha, + DTA_AlphaChannel, alphamap, + DTA_FillColor, alphamap ? 0 : -1); +} + + +DEFINE_ACTION_FUNCTION(DBaseStatusBar, DrawGraphic) +{ + PARAM_SELF_PROLOGUE(DBaseStatusBar); + PARAM_INT(texid); + PARAM_BOOL(animate); + PARAM_FLOAT(x); + PARAM_FLOAT(y); + PARAM_FLOAT(alpha); + PARAM_BOOL(translatable); + PARAM_BOOL(dim); + PARAM_INT(ialign); + PARAM_INT(salign); + PARAM_BOOL(alphamap); + PARAM_FLOAT(w); + PARAM_FLOAT(h); + PARAM_FLOAT(sx); + PARAM_FLOAT(sy); + PARAM_BOOL(fso); + self->DrawGraphic(FSetTextureID(texid), animate, x, y, alpha, translatable, dim, ialign, salign, alphamap, w, h, sx, sy, fso); + return 0; +} + //============================================================================ // // CCMD showpop @@ -1438,36 +1544,3 @@ static DObject *InitObject(PClass *type, int paramnum, VM_ARGS) return obj; } -DEFINE_ACTION_FUNCTION(DStatusbarWidget, AppendWidget) -{ - PARAM_SELF_PROLOGUE(DObject); - PARAM_CLASS(type, DObject); - if (!type->IsDescendantOf(NAME_StatusbarWidget) || type->IsDescendantOf(NAME_StatusbarCondition)) - { - ThrowAbortException(X_OTHER, "Invalid class %s for AppendWidget", type->TypeName.GetChars()); - } - auto obj = InitObject(type, paramnum, VM_ARGS_NAMES); - auto owner = self->PointerVar(NAME_Owner); - self->PointerVar(NAME_Next) = obj; - obj->PointerVar(NAME_Prev) = self; - obj->PointerVar(NAME_Owner) = owner; - ACTION_RETURN_POINTER(obj); -} - -DEFINE_ACTION_FUNCTION(DStatusbarWidget, BeginCondition) -{ - PARAM_SELF_PROLOGUE(DObject); - PARAM_CLASS(type, DObject); - if (!type->IsDescendantOf(NAME_StatusbarCondition)) - { - ThrowAbortException(X_OTHER, "Invalid class %s for BeginCondition", type->TypeName.GetChars()); - } - auto obj = InitObject(type, paramnum, VM_ARGS_NAMES); - auto head = PClass::FindClass(NAME_StatusbarWidget)->CreateNew(); - - head->PointerVar(NAME_Owner) = self; - self->PointerVar(NAME_Children) = head; - ACTION_RETURN_POINTER(head); -} - - diff --git a/src/scripting/backend/codegen.cpp b/src/scripting/backend/codegen.cpp index 3e7aa1a21..86e0a4a55 100644 --- a/src/scripting/backend/codegen.cpp +++ b/src/scripting/backend/codegen.cpp @@ -8674,6 +8674,11 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx) return nullptr; } + if (Function->Variants[0].Implementation->PrintableName.CompareNoCase("CustomStatusBar.DrawTexture") == 0) + { + int a = 0; + } + CallingFunction = ctx.Function; if (ArgList.Size() > 0) { @@ -8736,6 +8741,12 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx) delete old; // now fill the gap with constants created from the default list so that we got a full list of arguments. int insert = j - i; + int skipdefs = 0; + // Defaults contain multiple entries for pointers so we need to calculate how much additional defaults we need to skip + for (unsigned k = 0; k < i + implicit; k++) + { + skipdefs += argtypes[k]->GetRegCount() - 1; + } for (int k = 0; k < insert; k++) { auto ntype = argtypes[i + k + implicit]; @@ -8745,8 +8756,23 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx) assert(ntype->IsKindOf(RUNTIME_CLASS(PPointer))); ntype = TypeNullPtr; // the default of a reference type can only be a null pointer } - auto x = new FxConstant(ntype, defaults[i + k + implicit], ScriptPosition); - ArgList.Insert(i + k, x); + if (ntype->GetRegCount() == 1) + { + auto x = new FxConstant(ntype, defaults[i + k + skipdefs + implicit], ScriptPosition); + ArgList.Insert(i + k, x); + } + else + { + // Vectors need special treatment because they are not normal constants + FxConstant *cs[3] = { nullptr }; + for (int l = 0; l < ntype->GetRegCount(); l++) + { + cs[l] = new FxConstant(TypeFloat64, defaults[l + i + k + skipdefs + implicit], ScriptPosition); + } + FxExpression *x = new FxVectorValue(cs[0], cs[1], cs[2], ScriptPosition); + ArgList.Insert(i + k, x); + skipdefs += ntype->GetRegCount() - 1; + } } done = true; break; diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index f5856be9a..8dfed30e7 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -2503,10 +2503,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool { flags |= VARF_Optional; hasoptionals = true; - // The simplifier is not suited to convert the constant into something usable. - // All it does is reduce the expression to a constant but we still got to do proper type checking and conversion. - // It will also lose important type info about enums, once these get implemented - // The code generator can do this properly for us. + FxExpression *x = new FxTypeCast(ConvertNode(p->Default), type, false); FCompileContext ctx(OutNamespace, c->Type(), false); x = x->Resolve(ctx); diff --git a/src/swrenderer/r_swcanvas.cpp b/src/swrenderer/r_swcanvas.cpp index f888e34c4..0448db1ab 100644 --- a/src/swrenderer/r_swcanvas.cpp +++ b/src/swrenderer/r_swcanvas.cpp @@ -104,6 +104,7 @@ void SWCanvas::DrawTexture(DCanvas *canvas, FTexture *img, DrawParms &parms) drawerargs.SetTranslationMap(translation); drawerargs.SetLight(basecolormap, 0.0f, shade); + bool visible = drawerargs.SetStyle(viewport, parms.style, parms.Alpha, -1, parms.fillcolor, basecolormap); double x0 = parms.x - parms.left * parms.destwidth / parms.texwidth; diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 3312fca47..65aa1b7f6 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -521,7 +521,15 @@ bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t t case DTA_FillColor: parms->fillcolor = ListGetInt(tags); - fillcolorset = true; + if (parms->fillcolor != -1) + { + fillcolorset = true; + } + else if (parms->fillcolor != 0) + { + // The crosshair is the only thing which uses a non-black fill color. + parms->fillcolor = PalEntry(ColorMatcher.Pick(parms->fillcolor), RPART(parms->fillcolor), GPART(parms->fillcolor), BPART(parms->fillcolor)); + } break; case DTA_TranslationIndex: diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index b0eeba68e..82987b55f 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -35,7 +35,6 @@ version "2.5" #include "zscript/statusbar/statusbar.txt" #include "zscript/statusbar/strife_sbar.txt" #include "zscript/statusbar/sbarinfowrapper.txt" -#include "zscript/statusbar/statusbarwidget.txt" #include "zscript/inventory/inventory.txt" #include "zscript/inventory/inv_misc.txt" diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 409b90c92..71b4a7915 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -509,7 +509,7 @@ class Actor : Thinker native native bool GiveBody (int num, int max=0); native bool HitFloor(); native clearscope bool isTeammate(Actor other) const; - native int PlayerNumber(); + native clearscope int PlayerNumber() const; native void SetFriendPlayer(PlayerInfo player); native void SoundAlert(Actor target, bool splash = false, double maxdist = 0); native void DaggerAlert(Actor target); diff --git a/wadsrc/static/zscript/statusbar/statusbar.txt b/wadsrc/static/zscript/statusbar/statusbar.txt index 5d79de756..2499cfc31 100644 --- a/wadsrc/static/zscript/statusbar/statusbar.txt +++ b/wadsrc/static/zscript/statusbar/statusbar.txt @@ -80,6 +80,11 @@ class BaseStatusBar native ui native void RefreshBackground () const; native Inventory ValidateInvFirst (int numVisible) const; + native static TextureID, bool GetInventoryIcon(Inventory item, int flags); + + native void DrawGraphic(TextureID texture, bool animate, Vector2 pos, double Alpha, bool translatable, bool dim, + int imgAlign, int screenalign, bool alphamap, Vector2 box, Vector2 scale, bool fso); + //============================================================================ // @@ -111,6 +116,444 @@ class BaseStatusBar native ui let ammocount2 = ammo2 != NULL ? ammo2.Amount : 0; return ammo1, ammo2, ammocount1, ammocount2; } +} + +//============================================================================ +// +// This is only needed to shadow the native base class because a native class +// cannot have scripted variables added. +// +//============================================================================ + +class CustomStatusBar : BaseStatusBar +{ + enum DI_Flags + { + DI_SKIPICON = 0x1, + DI_SKIPALTICON = 0x2, + DI_SKIPSPAWN = 0x4, + DI_SKIPREADY = 0x8, + DI_ALTICONFIRST = 0x10, + DI_TRANSLATABLE = 0x20, + DI_FORCESCALE = 0x40 + }; + + enum IconType + { + PLAYERICON = 1000, + AMMO1, + AMMO2, + ARMOR, + WEAPONICON, + SIGIL, + WEAPONSLOT, + SELECTEDINVENTORYICON, + HEXENARMOR_ARMOR, + HEXENARMOR_SHIELD, + HEXENARMOR_HELM, + HEXENARMOR_AMULET, + }; + + enum EAlign + { + TOP = 0, + VCENTER = 1, + BOTTOM = 2, + VOFFSET = 3, + VMASK = 3, + + LEFT = 0, + HCENTER = 4, + RIGHT = 8, + HOFFSET = 12, + HMASK = 12, + + CENTER = VCENTER|HCENTER, + CENTER_BOTTOM = BOTTOM|HCENTER + }; + + enum SBGameModes + { + SINGLEPLAYER = 0x1, + COOPERATIVE = 0x2, + DEATHMATCH = 0x4, + TEAMGAME = 0x8 + }; + + enum AmmoModes + { + AMMO_PRIMARY, + AMMO_SECONDARY, + AMMO_ANY, + AMMO_BOTH + }; + + double Alpha; + Vector2 drawOffset; // can be set by subclasses to offset drawing operations + double drawClip[4]; // defines a clipping rectangle (not used yet) + bool fullscreenOffsets; // current screen is displayed with fullscreen behavior. + + Vector2 cleanScale; // factor for scaled fullscreen display. + + override void Init() + { + Super.Init(); + Alpha = 1; + DrawOffset = (0, 0); + drawClip[0] = 0; + drawClip[1] = 0; + drawClip[2] = 0; + drawClip[3] = 0; + cleanScale = (CleanXfac, CleanYfac); + fullscreenOffsets = false; + } + + //============================================================================ + // + // Get an icon + // + //============================================================================ + + TextureID, Vector2 GetIcon(Inventory item, int flags, bool showdepleted = false) + { + TextureID icon; + Vector2 scale = (1,1); + icon.SetInvalid(); + if (item != null) + { + bool applyscale; + [icon, applyscale] = GetInventoryIcon(item, flags); + + if (item.Amount == 0 && !showdepleted) return icon; + + if (applyscale) + scale = item.Scale; + } + return icon; + } + + //============================================================================ + // + // various checker functions, based on SBARINFOs condition nodes. + // + //============================================================================ + + //============================================================================ + // + // checks current game mode against a flag mask + // + //============================================================================ + + bool CheckGameMode(int ValidModes) + { + return (!multiplayer && (ValidModes & SINGLEPLAYER)) || + (deathmatch && (ValidModes & DEATHMATCH)) || + (multiplayer && !deathmatch && (ValidModes & COOPERATIVE)) || + (teamplay && (ValidModes & TEAMGAME)); + } + + //============================================================================ + // + // checks ammo use of current weapon + // + //============================================================================ + + bool WeaponUsesAmmo(int ValidModes) + { + if (CPlayer == null) return false; + let w = CPlayer.ReadyWeapon; + if (w == null) return false; + bool usesammo1 = w.AmmoType1 != NULL; + bool usesammo2 = w.AmmoType2 != NULL; + + if (ValidModes == AMMO_PRIMARY) return usesammo1; + if (ValidModes == AMMO_SECONDARY) return usesammo2; + if (ValidModes == AMMO_ANY) return (usesammo1 || usesammo2); + if (ValidModes == AMMO_BOTH) return (usesammo1 && usesammo2); + return false; + } + + //============================================================================ + // + // checks if inventory bar is visible + // + //============================================================================ + + bool isInventoryBarVisible() + { + if (CPlayer == null) return false; + return (CPlayer.inventorytics <= 0 || level.NoInventoryBar); + } + + //============================================================================ + // + // checks if aspect ratio is in a given range + // + //============================================================================ + + bool CheckAspectRatio(double min, double max) + { + if (CPlayer == null) return false; + double aspect = screen.GetAspectRatio(); + return (aspect >= min && aspect < max); + } + + //============================================================================ + // + // checks if weapon is selected. + // + //============================================================================ + + bool CheckWeaponSelected(class weap, bool checksister = true) + { + if (CPlayer == null) return false; + let w = CPlayer.ReadyWeapon; + if (w == null) return false; + if (w.GetClass() == weap) return true; + if (checksister && w.SisterWeapon != null && w.SisterWeapon.GetClass() == weap) return true; + return false; + } + + //============================================================================ + // + // checks if player has the given display name + // + //============================================================================ + + bool CheckDiplayName(String displayname) + { + if (CPlayer == null) return false; + return displayname == PlayerPawn.GetPrintableDisplayName(CPlayer.mo.GetClass()); + } + + //============================================================================ + // + // checks if player has the given weapon piece + // + //============================================================================ + + bool CheckWeaponPiece(class weap, int piecenum) + { + if (CPlayer == null) return false; + for(let inv = CPlayer.mo.Inv; inv != NULL; inv = inv.Inv) + { + let wh = WeaponHolder(inv); + if (wh != null && wh.PieceWeapon == weap) + { + return (!!(wh.PieceMask & (1 << (PieceNum-1)))); + } + } + return false; + } + + //============================================================================ + // + // checks if player has the given weapon piece + // + //============================================================================ + + bool WeaponUsesAmmoType(class ammotype) + { + if (CPlayer == null) return false; + let w = CPlayer.ReadyWeapon; + if (w == NULL) return false; + return w.AmmoType1 == ammotype || w.AmmoType2 == ammotype; + } + + //============================================================================ + // + // checks if player has the required health + // + //============================================================================ + + bool CheckHealth(int Amount, bool percentage = false) + { + if (CPlayer == null) return false; + + int phealth = percentage ? CPlayer.mo.health * 100 / CPlayer.mo.GetMaxHealth() : CPlayer.mo.health; + return (phealth >= Amount); + } + + //============================================================================ + // + // checks if player is invulnerable + // + //============================================================================ + + bool isInvulnerable() + { + if (CPlayer == null) return false; + return ((CPlayer.mo.bInvulnerable) || (CPlayer.cheats & (CF_GODMODE | CF_GODMODE2))); + } + + //============================================================================ + // + // checks if player owns enough of the item + // + //============================================================================ + + bool CheckInventory(class item, int amount = 1) + { + if (CPlayer == null) return false; + + let it = CPlayer.mo.FindInventory(item); + return it != null && it.Amount >= amount; + } + + + //============================================================================ + // + // draw stuff + // + //============================================================================ + + int GetTranslation() const + { + if(gameinfo.gametype & GAME_Raven) + return Translation.MakeID(TRANSLATION_PlayersExtra, CPlayer.mo.PlayerNumber()); + else + return Translation.MakeID(TRANSLATION_Players, CPlayer.mo.PlayerNumber()); + } + + //============================================================================ + // + // draw stuff + // + //============================================================================ + + void DrawTexture(TextureID texture, Vector2 pos, bool animated = false, double alpha = 1.0, int screenalign = TOP|LEFT, Vector2 boxsize = (-1, -1), int itemAlign = TOP|LEFT, int flags = 0, Vector2 scale = (1., 1.) ) + { + if (!texture.IsValid()) return; // nothing to draw + + alpha *= self.alpha; + if (alpha <= 0) return; // invisible + + Vector2 texsize = TexMan.GetScaledSize(texture); + texsize.X *= scale.X; + texsize.Y *= scale.Y; + if (boxsize.X > 0 || boxsize.Y > 0) + { + double scale1 = 1., scale2 = 1.; + + if (boxsize.X != -1 && (boxsize.X < texsize.X || (flags & DI_FORCESCALE))) + { + scale1 = boxsize.X / texsize.X; + } + if (boxsize.Y != -1 && (boxsize.Y < texsize.Y || (flags & DI_FORCESCALE))) + { + scale2 = boxsize.Y / texsize.Y; + } + + if (flags & DI_FORCESCALE) + { + if (boxsize.X == -1 || (boxsize.Y != -1 && scale2 < scale1)) + scale1 = scale2; + } + else scale1 = min(scale1, scale2); + + boxsize = texsize * scale1; + screenAlign = TOP|LEFT; // anything else makes no sense here. + } + else + { + boxsize = texsize; + } + DrawGraphic(texture, animated, pos + drawOffset, Alpha * self.Alpha, !!(flags & DI_TRANSLATABLE), false, itemAlign, screenAlign, false, boxsize, cleanscale, fullscreenoffsets); + } + + //============================================================================ + // + // + // + //============================================================================ + + void DrawImage(String imagename, Vector2 pos, bool animated = false, double alpha = 1.0, int screenalign = TOP|LEFT, Vector2 boxsize = (-1, -1), int itemAlign = TOP|LEFT, int flags = 0, Vector2 scale = (1., 1.) ) + { + let tex = TexMan.CheckForTexture(imagename, TexMan.TYPE_MiscPatch); + DrawTexture(tex, pos, animated, screenalign, alpha, boxsize, itemAlign, flags, scale); + } + + //============================================================================ + // + // + // + //============================================================================ + + void DrawIcon(int icontype, Vector2 pos, bool animated = false, double alpha = 1.0, int screenalign = TOP|LEFT, Vector2 boxsize = (-1, -1), int itemAlign = TOP|LEFT, int flags = 0) + { + TextureID texture; + Vector2 applyscale = (1, 1); + Inventory atype1, atype2; + switch (icontype) + { + case PLAYERICON: + texture = CPlayer.mo.ScoreIcon; + break; + + case AMMO1: + case AMMO2: + [atype1, atype2] = GetCurrentAmmo(); + [texture, applyscale] = GetIcon(icontype == AMMO1? atype1 : atype2, flags, true); + break; + + case ARMOR: + [texture, applyscale] = GetIcon(CPlayer.mo.FindInventory("BasicArmor"), flags, false); + break; + + case WEAPONICON: + [texture, applyscale] = GetIcon(CPlayer.ReadyWeapon, flags, false); + break; + + case SIGIL: + [texture, applyscale] = GetIcon(CPlayer.mo.FindInventory("Sigil"), flags, false); + break; + + case SELECTEDINVENTORYICON: + if (CPlayer.mo.InvSel != NULL) + texture = CPlayer.mo.InvSel.Icon; + break; + } + DrawTexture(texture, pos, animated, screenalign, alpha, boxsize, itemAlign, flags, applyscale); + } + + //============================================================================ + // + // + // + //============================================================================ + + void DrawHexenArmor(int armortype, String image, Vector2 pos, bool animated = false, double alpha = 1.0, int screenalign = TOP|LEFT, Vector2 boxsize = (-1, -1), int itemAlign = TOP|LEFT, int flags = 0) + { + let harmor = HexenArmor(statusBar.CPlayer.mo.FindInventory("HexenArmor")); + if (harmor != NULL) + { + let slotval = harmor.Slots[armorType]; + let slotincr = harmor.SlotsIncrement[armorType]; + + if (slotval > 0 && slotincr > 0) + { + //combine the alpha values + alpha *= MIN(1., slotval / slotincr); + } + else return; + } + DrawImage(image, pos, animated, screenalign, alpha, boxsize, itemAlign, flags); + } + + //============================================================================ + // + // + // + //============================================================================ + + void DrawInventoryIcon(class item, String image, Vector2 pos, bool animated = false, double alpha = 1.0, int screenalign = TOP|LEFT, Vector2 boxsize = (-1, -1), int itemAlign = TOP|LEFT, int flags = 0) + { + let texture = GetDefaultByType(item).Icon; + if (texture.IsValid()) + { + DrawTexture(texture, pos, animated, screenalign, alpha, boxsize, itemAlign, flags); + } + } } diff --git a/wadsrc/static/zscript/statusbar/statusbarwidget.txt b/wadsrc/static/zscript/statusbar/statusbarwidget.txt deleted file mode 100644 index b518caf49..000000000 --- a/wadsrc/static/zscript/statusbar/statusbarwidget.txt +++ /dev/null @@ -1,744 +0,0 @@ - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class StatusbarWidget ui -{ - enum EAlign - { - TOP = 0x1, - VMIDDLE = 0x2, - BOTTOM = 0x4, - - LEFT = 0x10, - RIGHT = 0x20, - HMIDDLE = 0x40, - - CENTER = VMIDDLE|HMIDDLE, - CENTER_BOTTOM = BOTTOM|HMIDDLE - }; - - StatusbarWidget Next; - StatusbarWidget Prev; - StatusbarWidget Owner; - - native vararg StatusbarWidget AppendWidget(class cls, ...); - native vararg StatusbarWidget BeginCondition(class cls, ...); - - void Init() - { - } - StatusbarCondition EndCondition() - { - if (owner == null || !(owner is "StatusbarCondition")) - { - ThrowAbortException("No matching BeginCondition found for EndCondition"); - } - return StatusbarCondition(owner); - } - - StatusbarWidget ElseCondition() - { - let condi = StatusbarCondition(owner); - if (condi == null) - { - ThrowAbortException("No matching BeginCondition found for EndCondition"); - } - if (condi.FalseChildren != null) - { - ThrowAbortException("Duplicate ElseCondition()"); - } - condi.FalseChildren = new("StatusbarWidget"); - condi.FalseChildren.Owner = condi; - return condi.FalseChildren; - - } - - StatusbarHead Finish() - { - if (owner == null || !(Owner is "StatusbarHead")) - { - ThrowAbortException("No matching Begin found for Finish"); - } - return StatusbarHead(owner); - } - - - virtual void Draw(WidgetStatusBar stbar) {} - virtual void Reset() {} - virtual void Tick(WidgetStatusBar stbar, bool change) {} -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class StatusbarHead : StatusbarWidget -{ - StatusbarWidget Children; - - override void Draw(WidgetStatusBar stbar) - { - for(let p = Children; p != null; p = p.Next) - { - p.Draw(stbar); - } - } - override void Reset() - { - for(let p = Children; p != null; p = p.Next) - { - p.Reset(); - } - } - override void Tick(WidgetStatusBar stbar, bool change) - { - for(let p = Children; p != null; p = p.Next) - { - p.Tick(stbar, change); - } - } - -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class StatusbarCondition : StatusbarWidget -{ - StatusbarWidget TrueChildren; - StatusbarWidget FalseChildren; - bool LastCondition; - virtual int Condition(WidgetStatusBar stbar) { return -1; } - void Init() - { - LastCondition = true; - } - override void Draw(WidgetStatusBar stbar) - { - for(let p = LastCondition? TrueChildren : FalseChildren; p != null; p = p.Next) - { - p.Draw(stbar); - } - } - override void Reset() - { - for(let p = TrueChildren; p != null; p = p.Next) - { - p.Reset(); - } - for(let p = FalseChildren; p != null; p = p.Next) - { - p.Reset(); - } - } - override void Tick(WidgetStatusBar stbar, bool change) - { - for(let p = LastCondition? TrueChildren : FalseChildren; p != null; p = p.Next) - { - p.Tick(stbar, change); - } - int i = Condition(stbar); - if (i >= 0 && LastCondition != !!i) - { - LastCondition = !!i; - for(let p = LastCondition? TrueChildren : FalseChildren; p != null; p = p.Next) - { - p.Tick(stbar, true); - } - } - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class SBConditionGamemode : StatusbarCondition -{ - enum GameModes - { - SINGLEPLAYER = 0x1, - COOPERATIVE = 0x2, - DEATHMATCH = 0x4, - TEAMGAME = 0x8 - }; - - private int ValidModes; - - void Init(int modemask) - { - ValidModes = modemask; - } - - override int Condition(WidgetStatusBar stbar) - { - return (!multiplayer && (ValidModes & SINGLEPLAYER)) || - (deathmatch && (ValidModes & DEATHMATCH)) || - (multiplayer && !deathmatch && (ValidModes & COOPERATIVE)) || - (teamplay && (ValidModes & TEAMGAME)); - - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class SBConditionUsesAmmo : StatusbarCondition -{ - enum AmmoModes - { - AMMO1, - AMMO2, - AMMO_ANY, - AMMO_BOTH - }; - - private int ValidModes; - private bool Negate; - - void Init(int modemask, bool neg = false) - { - ValidModes = modemask; - Negate = neg; - } - - override int Condition(WidgetStatusBar stbar) - { - if (stbar.CPlayer == null) return -1; - let w = stbar.CPlayer.ReadyWeapon; - if (w == null) return false; - bool usesammo1 = w.AmmoType1 != NULL; - bool usesammo2 = w.AmmoType2 != NULL; - - if (ValidModes == AMMO1) return usesammo1 ^ Negate; - else if (ValidModes == AMMO2) return usesammo2 ^ Negate; - if (ValidModes == AMMO_ANY) return (usesammo1 || usesammo2) ^ Negate; - if (ValidModes == AMMO_BOTH) return (usesammo1 && usesammo2) ^ Negate; - return -1; - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class SBConditionInventoryBarVisible : StatusbarCondition -{ - private bool Negate; - - void Init(bool neg = false) - { - Negate = neg; - } - - override int Condition(WidgetStatusBar stbar) - { - if (stbar.CPlayer == null) return -1; - return (stbar.CPlayer.inventorytics <= 0 || level.NoInventoryBar) ^ Negate; - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class SBConditionAspectRatio : StatusbarCondition -{ - private double MinValid, MaxValid; - private bool Negate; - - void Init(double min, double max, bool neg = false) - { - MinValid = min; - MaxValid = max; - Negate = neg; - } - - override int Condition(WidgetStatusBar stbar) - { - if (stbar.CPlayer == null) return -1; - double aspect = screen.GetAspectRatio(); - return (aspect >= MinValid && aspect < MaxValid) ^ Negate; - } -} - -//--------------------------------------------------------------------------- -// -// uses two names, like SBARINFO -// -//--------------------------------------------------------------------------- - -class SBConditionWeaponSelected : StatusbarCondition -{ - private class Weap1, Weap2; - private bool Negate; - private bool CheckSister; - - void Init(class w1, class w2, bool sister = false, bool neg = false) - { - Weap1 = w1; - Weap2 = w2; - CheckSister = sister; - Negate = neg; - } - - override int Condition(WidgetStatusBar stbar) - { - if (stbar.CPlayer == null) return -1; - let w = stbar.CPlayer.ReadyWeapon; - return (w != null && ((w.GetClass() == Weap1 || w.GetClass() == Weap2) || (CheckSister && w.SisterWeapon != null && (w.SisterWeapon.GetClass() == Weap1 || w.SisterWeapon.GetClass() == Weap2)))) ^ Negate; - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class SBConditionPlayerclass : StatusbarCondition -{ - private Name PlayerClasses[6]; - private bool Negate; - - void Init(Name p1, Name p2 = 'none', Name p3 = 'none', Name p4 = 'none', Name p5 = 'none', Name p6 = 'none', bool neg = false) - { - PlayerClasses[0] = p1; - PlayerClasses[1] = p2; - PlayerClasses[2] = p3; - PlayerClasses[3] = p4; - PlayerClasses[4] = p5; - PlayerClasses[5] = p6; - Negate = neg; - } - - override int Condition(WidgetStatusBar stbar) - { - if (stbar.CPlayer == null) return -1; - Name dn = PlayerPawn.GetPrintableDisplayName(stbar.CPlayer.mo.GetClass()); - for(int i=0; i<6; i++) - { - if (PlayerClasses[i] != 'none' && dn == PlayerPawn.GetPrintableDisplayName(PlayerClasses[i])) return !Negate; - } - return Negate; - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class SBConditionPlayerType : StatusbarCondition -{ - private class PlayerClasses[6]; - private bool Negate; - - void Init(class p1, class p2, class p3, class p4, class p5, class p6, bool neg = false) - { - PlayerClasses[0] = p1; - PlayerClasses[1] = p2; - PlayerClasses[2] = p3; - PlayerClasses[3] = p4; - PlayerClasses[4] = p5; - PlayerClasses[5] = p6; - Negate = neg; - } - - override int Condition(WidgetStatusBar stbar) - { - if (stbar.CPlayer == null) return -1; - for(int i=0; i<6; i++) - { - if (PlayerClasses[i] != null && stbar.CPlayer.mo is PlayerClasses[i]) return !Negate; - } - return Negate; - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class SBConditionHasWeaponPiece : StatusbarCondition -{ - private class Weap1; - private int PieceNum; - private bool Negate; - - void Init(class w1, int piecenum, bool neg = false) - { - Weap1 = w1; - PieceNum = piecenum - 1; - Negate = neg; - } - - override int Condition(WidgetStatusBar stbar) - { - if (stbar.CPlayer == null) return -1; - for(let inv = stbar.CPlayer.mo.Inv; inv != NULL; inv = inv.Inv) - { - let wh = WeaponHolder(inv); - if (wh.PieceWeapon == Weap1) - { - return (!!(wh.PieceMask & (1 << PieceNum))) ^ Negate; - } - } - return Negate; - } -} - -//--------------------------------------------------------------------------- -// -// Checks if the current weapon uses the given ammo types. -// -//--------------------------------------------------------------------------- - -class SBConditionWeaponUsesAmmo : StatusbarCondition -{ - enum AmmoModes - { - AMMO1, - AMMO2, - AMMO_ANY, - AMMO_BOTH - }; - - private class AmmoType1, AmmoType2; - private int ValidModes; - private bool Negate; - - void Init(class ammotype_1, class ammotype_2, int modemask, bool neg = false) - { - AmmoType1 = ammotype_1; - AmmoType2 = ammotype_2; - ValidModes = modemask; - Negate = neg; - } - - override int Condition(WidgetStatusBar stbar) - { - if (stbar.CPlayer == null) return -1; - let w = stbar.CPlayer.ReadyWeapon; - if (w == NULL) return false; - - let WeapType1 = w.AmmoType1; - let WeapType2 = w.AmmoType2; - - bool usesammo1 = WeapType1 != NULL; - bool usesammo2 = WeapType2 != NULL; - - if(AmmoType2 != NULL) - { - bool match1 = ((usesammo1 && (AmmoType1 == WeapType1 || AmmoType2 == WeapType1)) || !usesammo1); - bool match2 = ((usesammo1 && (AmmoType1 == WeapType2 || AmmoType2 == WeapType2)) || !usesammo2); - - if (ValidModes == AMMO1) return match1 ^ Negate; - if (ValidModes == AMMO2) return match2 ^ Negate; - if (ValidModes == AMMO_ANY) return (match1 || match2) ^ Negate; - if (ValidModes == AMMO_BOTH) return (match1 && match2) ^ Negate; - return -1; - } - else - { - if((usesammo1 && (WeapType1 == AmmoType1)) || (usesammo2 && (WeapType2 == AmmoType1))) - { - return !Negate; - } - } - return Negate; - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class SBConditionHealth : StatusbarCondition -{ - private int amount; - private bool Negate; - private bool percentage; - - void Init(int amt, bool percent, bool neg = false) - { - amount = amt; - percentage = percent; - Negate = neg; - } - - override int Condition(WidgetStatusBar stbar) - { - if (stbar.CPlayer == null) return -1; - - int phealth = percentage ? stbar.CPlayer.mo.health * 100 / stbar.CPlayer.mo.GetMaxHealth() : stbar.CPlayer.mo.health; - return (phealth >= Amount) ^ Negate; - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class SBConditionInvulnerable : StatusbarCondition -{ - private bool Negate; - - void Init(bool neg = false) - { - Negate = neg; - } - - override int Condition(WidgetStatusBar stbar) - { - if (stbar.CPlayer == null) return -1; - - return ((stbar.CPlayer.mo.bInvulnerable) || (stbar.CPlayer.cheats & (CF_GODMODE | CF_GODMODE2))) ^ Negate; - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class SBConditionWaterLevel : StatusbarCondition -{ - private int amount; - private bool Negate; - - void Init(int amt, bool neg = false) - { - amount = amt; - Negate = neg; - } - - override int Condition(WidgetStatusBar stbar) - { - if (stbar.CPlayer == null) return -1; - - return (stbar.CPlayer.mo.waterlevel >= amount) ^ Negate; - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class SBConditionCVarNumeric : StatusbarCondition -{ - enum EOp - { - LESS, - LESSEQ, - EQ, - NEQ, - GREATEREQ, - GREATER - }; - - private String cv; - private int Operator; - private double Value; - - void Init(String cvname, int op, double val) - { - cv = cvname; - Operator = op; - Value = val; - } - - override int Condition(WidgetStatusBar stbar) - { - if (stbar.CPlayer == null) return -1; - let cvr = CVar.FindCVar(cv, stbar.CPlayer); - if (cvr == null) return -1; - double val = cvr.GetFloat(); - switch (Operator) - { - case LESS: - return val < Value; - - case LESSEQ: - return val <= Value; - - case EQ: - return val ~== Value; - - case NEQ: - return !(val ~== Value); - - case GREATEREQ: - return val >= Value; - - case GREATER: - return val > Value; - } - return -1; - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class SBConditionInInventory : StatusbarCondition -{ - enum AmmoModes - { - ITEM1, - ITEM2, - ITEM_ANY, - ITEM_BOTH - }; - - private class InventoryType1, InventoryType2; - private int Amount1, Amount2; - private int ValidModes; - private bool Negate; - - void Init(class Inventorytype_1, int am1, class Inventorytype_2, int am2, int modemask, bool neg = false) - { - InventoryType1 = Inventorytype_1; - InventoryType2 = Inventorytype_2; - Amount1 = am1; - Amount2 = am2; - ValidModes = modemask; - Negate = neg; - } - - override int Condition(WidgetStatusBar stbar) - { - if (stbar.CPlayer == null) return -1; - - let it1 = stbar.CPlayer.mo.FindInventory(InventoryType1); - let it2 = stbar.CPlayer.mo.FindInventory(InventoryType2); - if (it1 != NULL && amount1 > 0 && it1.Amount < amount1) it1 = NULL; - if (it2 != NULL && amount2 > 0 && it2.Amount < amount2) it2 = NULL; - - - if (ValidModes == ITEM1) return (!!it1) ^ Negate; - if (ValidModes == ITEM2) return (!!it2) ^ Negate; - if (ValidModes == ITEM_ANY) return (it1 || it2) ^ Negate; - if (ValidModes == ITEM_BOTH) return (it1 && it2) ^ Negate; - return -1; - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class WidgetStatusBar : BaseStatusBar -{ - private StatusbarHead Head; - - StatusbarWidget Begin() - { - Head = new("StatusbarHead"); - Head.Owner = Head; - Head.Children = new ("StatusbarWidget"); - Head.Children.Owner = Head; - return Head.Children; - } - - // this is just copied from SBARINFO. We may need it. - static Vector2 adjustRelCenter(bool relX, bool relY, Vector2 pos, Vector3 scale) - { - Vector2 outvec; - if(relX) - outvec.X = pos.X + (screen.GetWidth()/(hud_scale ? Scale.X*2 : 2)); - else - outvec.X = pos.X; - if(relY) - outvec.Y = pos.y + (screen.GetHeight()/(hud_scale ? Scale.Y*2 : 2)); - else - outvec.Y = pos.y; - - return outvec; - } - - -} - - -/* for testing the above. This block compiles. -class TestWidgets : WidgetStatusBar -{ - override void Init() - { - Begin() - .AppendWidget("StatusbarWidget") - .AppendWidget("StatusbarWidget") - .AppendWidget("StatusbarWidget") - .AppendWidget("StatusbarWidget") - .AppendWidget("StatusbarWidget") - .BeginCondition("StatusbarCondition") - .AppendWidget("StatusbarWidget") - .AppendWidget("StatusbarWidget") - .AppendWidget("StatusbarWidget") - .AppendWidget("StatusbarWidget") - .EndCondition() - .AppendWidget("StatusbarWidget") - .AppendWidget("StatusbarWidget") - .AppendWidget("StatusbarWidget") - .BeginCondition("StatusbarCondition") - .AppendWidget("StatusbarWidget") - .AppendWidget("StatusbarWidget") - .BeginCondition("StatusbarCondition") - .AppendWidget("StatusbarWidget") - .AppendWidget("StatusbarWidget") - .AppendWidget("StatusbarWidget") - .AppendWidget("StatusbarWidget") - .EndCondition() - .AppendWidget("StatusbarWidget") - .AppendWidget("StatusbarWidget") - .EndCondition() - .AppendWidget("StatusbarWidget") - .AppendWidget("StatusbarWidget") - .AppendWidget("StatusbarWidget") - .AppendWidget("StatusbarWidget") - .AppendWidget("StatusbarWidget") - .BeginCondition("StatusbarCondition") - .AppendWidget("StatusbarWidget") - .AppendWidget("StatusbarWidget") - .AppendWidget("StatusbarWidget") - .AppendWidget("StatusbarWidget") - .EndCondition() - .AppendWidget("StatusbarWidget") - .Finish(); - } -} -*/ \ No newline at end of file diff --git a/wadsrc/static/zscript/statusbar/strife_sbar.txt b/wadsrc/static/zscript/statusbar/strife_sbar.txt index 0ec43e8de..e19f9b4a1 100644 --- a/wadsrc/static/zscript/statusbar/strife_sbar.txt +++ b/wadsrc/static/zscript/statusbar/strife_sbar.txt @@ -1,5 +1,5 @@ -class StrifeStatusBar : BaseStatusBar +class StrifeStatusBar : CustomStatusBar { // Number of tics to move the popscreen up and down. @@ -59,6 +59,7 @@ class StrifeStatusBar : BaseStatusBar override void Init() { + Super.Init(); SetSize(32, 320, 200); DoCommonInit(); } @@ -368,20 +369,17 @@ class StrifeStatusBar : BaseStatusBar protected void DrawFullScreenStuff () { + fullscreenoffsets = true; // Draw health DrINumberOuter (CPlayer.health, 4, -10, false, 7); - screen.DrawTexture (Images[imgMEDI], true, 14, -17, - DTA_HUDRules, HUD_Normal, - DTA_CenterBottomOffset, true); + DrawTexture(Images[imgMEDI], (14, -17), false, 1.0, BOTTOM|LEFT, itemalign: BOTTOM|HCENTER); // Draw armor let armor = CPlayer.mo.FindInventory('BasicArmor'); if (armor != NULL && armor.Amount != 0) { DrINumberOuter (armor.Amount, 35, -10, false, 7); - screen.DrawTexture (armor.Icon, true, 45, -17, - DTA_HUDRules, HUD_Normal, - DTA_CenterBottomOffset, true); + DrawTexture(armor.Icon, (45, -17), false, 1.0, BOTTOM|LEFT, itemalign: BOTTOM|HCENTER); } // Draw ammo @@ -393,16 +391,12 @@ class StrifeStatusBar : BaseStatusBar { // Draw primary ammo in the bottom-right corner DrINumberOuter (ammo1.Amount, -23, -10, false, 7); - screen.DrawTexture (ammo1.Icon, true, -14, -17, - DTA_HUDRules, HUD_Normal, - DTA_CenterBottomOffset, true); + DrawTexture(ammo1.Icon, (-14, -17), false, 1.0, BOTTOM|RIGHT, itemalign: BOTTOM|HCENTER); if (ammo2 != NULL && ammo1!=ammo2) { // Draw secondary ammo just above the primary ammo DrINumberOuter (ammo2.Amount, -23, -48, false, 7); - screen.DrawTexture (ammo2.Icon, -14, -55, - DTA_HUDRules, HUD_Normal, - DTA_CenterBottomOffset, true); + DrawTexture(ammo1.Icon, (-14, -55), false, 1.0, BOTTOM|RIGHT, itemalign: BOTTOM|HCENTER); } } @@ -458,6 +452,7 @@ class StrifeStatusBar : BaseStatusBar } } } + fullscreenoffsets = false; } protected void DrawPopScreen (int bottom, double TicFrac)