- ported the Hexen status bar to zscript.

Note that DrawBar with a background texture does not work yet because the clipping rectangle is not done yet.
This commit is contained in:
Christoph Oelckers 2017-03-28 11:00:05 +02:00
parent bac464f2b7
commit b9485d4edf
10 changed files with 430 additions and 12 deletions

View File

@ -734,6 +734,8 @@ static int grid = 0;
bool automapactive = false;
DEFINE_GLOBAL(automapactive);
// location of window on screen
static int f_x;
static int f_y;

View File

@ -397,6 +397,7 @@ public:
void DrawGraphic(FTextureID texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY);
void DrawString(FFont *font, const FString &cstring, double x, double y, int flags, double Alpha, int translation, int spacing, bool monospaced, int shadowX, int shadowY);
void Fill(PalEntry color, double x, double y, double w, double h, int flags = 0);
void BeginStatusBar(int resW, int resH, int relTop, bool completeborder = false, bool forceScaled = false);
void BeginHUD(int resW, int resH, double Alpha, bool forceScaled = false);

View File

@ -1935,6 +1935,86 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, DrawString)
}
//============================================================================
//
// draw stuff
//
//============================================================================
void DBaseStatusBar::Fill(PalEntry color, double x, double y, double w, double h, int flags)
{
// resolve auto-alignment before making any adjustments to the position values.
if (!(flags & DI_SCREEN_MANUAL_ALIGN))
{
if (x < 0) flags |= DI_SCREEN_RIGHT;
else flags |= DI_SCREEN_LEFT;
if (y < 0) flags |= DI_SCREEN_BOTTOM;
else flags |= DI_SCREEN_TOP;
}
double Alpha = color.a * this->Alpha / 255;
if (Alpha <= 0) return;
x += drawOffset.X;
y += drawOffset.Y;
if (!fullscreenOffsets)
{
x += ST_X;
//y += ST_Y;
// Todo: Allow other scaling values, too.
if (Scaled)
{
screen->VirtualToRealCoords(x, y, w, h, HorizontalResolution, VerticalResolution, true, true);
}
}
else
{
double orgx, orgy;
switch (flags & DI_SCREEN_HMASK)
{
default: orgx = 0; break;
case DI_SCREEN_HCENTER: orgx = screen->GetWidth() / 2; break;
case DI_SCREEN_RIGHT: orgx = screen->GetWidth(); break;
}
switch (flags & DI_SCREEN_VMASK)
{
default: orgy = 0; break;
case DI_SCREEN_VCENTER: orgy = screen->GetHeight() / 2; break;
case DI_SCREEN_BOTTOM: orgy = screen->GetHeight(); break;
}
// move stuff in the top right corner a bit down if the fps counter is on.
if ((flags & (DI_SCREEN_HMASK | DI_SCREEN_VMASK)) == DI_SCREEN_RIGHT_TOP && vid_fps) y += 10;
DVector2 Scale = GetHUDScale();
x *= Scale.X;
y *= Scale.Y;
w *= Scale.X;
h *= Scale.Y;
x += orgx;
y += orgy;
}
screen->Dim(color, float(Alpha), int(x), int(y), int(w), int(h));
}
DEFINE_ACTION_FUNCTION(DBaseStatusBar, Fill)
{
PARAM_SELF_PROLOGUE(DBaseStatusBar);
PARAM_COLOR(color);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_FLOAT(w);
PARAM_FLOAT(h);
PARAM_INT_DEF(flags);
self->Fill(color, x, y, w, h);
return 0;
}
//============================================================================
//
// CCMD showpop

View File

@ -27,7 +27,8 @@ gameinfo
defaultbloodcolor = "68 00 00"
defaultbloodparticlecolor = "ff 00 00"
backpacktype = "BagOfHolding" // Hexen doesn't have a backpack so use Heretic's.
statusbar = "sbarinfo/hexen.txt"
//statusbar = "sbarinfo/hexen.txt"
statusbarclass = "HexenStatusBar"
intermissionmusic = "hub"
intermissioncounter = false
weaponslot = 1, "FWeapFist", "CWeapMace", "MWeapWand"

View File

@ -35,6 +35,7 @@ version "2.5"
#include "zscript/statusbar/statusbar.txt"
#include "zscript/statusbar/doom_sbar.txt"
#include "zscript/statusbar/heretic_sbar.txt"
#include "zscript/statusbar/hexen_sbar.txt"
#include "zscript/statusbar/strife_sbar.txt"
#include "zscript/statusbar/sbarinfowrapper.txt"

View File

@ -14,6 +14,7 @@ struct _ native // These are the global variables, the struct is only here to av
native play @PlayerInfo players[MAXPLAYERS];
native readonly bool playeringame[MAXPLAYERS];
native readonly bool automapactive;
native play uint gameaction;
native readonly int gamestate;
native readonly TextureID skyflatnum;

View File

@ -119,7 +119,7 @@ class DoomStatusBar : BaseStatusBar
{
DrawTexture(GetMugShot(5), (143, 168), DI_ITEM_OFFSETS);
}
if (CPlayer.inventorytics != 0 && !level.NoInventoryBar)
if (isInventoryBarVisible())
{
DrawInventoryBar(diparms, (48, 169), 7, DI_ITEM_LEFT_TOP);
}
@ -155,7 +155,7 @@ class DoomStatusBar : BaseStatusBar
DrawString(mHUDFont, FormatNumber(ammotype2.Amount, 3), (-30, invY), DI_TEXT_ALIGN_RIGHT);
invY -= 20;
}
if (CPlayer.inventorytics == 0 && CPlayer.mo.InvSel != null && !level.NoInventoryBar)
if (!isInventoryBarVisible() && !level.NoInventoryBar)
{
DrawInventoryIcon(CPlayer.mo.InvSel, (-14, invY + 17));
DrawString(mHUDFont, FormatNumber(CPlayer.mo.InvSel.Amount, 3), (-30, invY), DI_TEXT_ALIGN_RIGHT);
@ -187,7 +187,7 @@ class DoomStatusBar : BaseStatusBar
}
}
}
if (CPlayer.inventorytics != 0 && !level.NoInventoryBar)
if (isInventoryBarVisible())
{
DrawInventoryBar(diparms, (0, 0), 7, DI_SCREEN_CENTER_BOTTOM, HX_SHADOW);
}

View File

@ -11,7 +11,7 @@ class HereticStatusBar : BaseStatusBar
override void Init()
{
Super.Init();
SetSize(48, 320, 200);
SetSize(42, 320, 200);
// Create the font used for the fullscreen HUD
Font fnt = "HUDFONT_RAVEN";
@ -75,7 +75,7 @@ class HereticStatusBar : BaseStatusBar
DrawShader(SHADER_HORZ, (19, 190), (16, 10));
DrawShader(SHADER_HORZ|SHADER_REVERSE, (278, 190), (16, 10));
if (CPlayer.inventorytics == 0 || level.NoInventoryBar)
if (!isInventoryBarVisible())
{
//statbar
if (!deathmatch)
@ -132,7 +132,6 @@ class HereticStatusBar : BaseStatusBar
protected void DrawFullScreenStuff ()
{
//health
DrawImage("PTN1A0", (51, -3));
DrawString(mBigFont, FormatNumber(mHealthInterpolator.GetValue()), (41, -21), DI_TEXT_ALIGN_RIGHT);
@ -190,7 +189,7 @@ class HereticStatusBar : BaseStatusBar
y -= 40;
}
if (CPlayer.inventorytics == 0 && CPlayer.mo.InvSel != null && !level.NoInventoryBar)
if (!isInventoryBarVisible() && !level.NoInventoryBar)
{
// This code was changed to always fit the item into the box, regardless of alignment or sprite size.
// Heretic's ARTIBOX is 30x30 pixels.
@ -201,7 +200,7 @@ class HereticStatusBar : BaseStatusBar
DrawString(mIndexFont, FormatNumber(CPlayer.mo.InvSel.Amount, 3), (-32, -2 - mIndexFont.mFont.GetHeight()), DI_TEXT_ALIGN_RIGHT);
}
}
if (CPlayer.inventorytics != 0 && !level.NoInventoryBar)
if (isInventoryBarVisible())
{
DrawInventoryBar(diparms, (0, 0), 7, DI_SCREEN_CENTER_BOTTOM, HX_SHADOW);
}

View File

@ -0,0 +1,258 @@
class HexenStatusBar : BaseStatusBar
{
DynamicValueInterpolator mHealthInterpolator;
DynamicValueInterpolator mHealthInterpolator2;
HUDFont mHUDFont;
HUDFont mIndexFont;
HUDFont mBigFont;
InventoryBarState diparms;
InventoryBarState diparms_sbar;
override void Init()
{
Super.Init();
SetSize(38, 320, 200);
// Create the font used for the fullscreen HUD
Font fnt = "HUDFONT_RAVEN";
mHUDFont = HUDFont.Create(fnt, fnt.GetCharWidth("0") + 1, true, 1, 1);
fnt = "INDEXFONT_RAVEN";
mIndexFont = HUDFont.Create(fnt, fnt.GetCharWidth("0"), true);
fnt = "BIGFONT";
mBigFont = HUDFont.Create(fnt, fnt.GetCharWidth("0"), true, 2, 2);
diparms = InventoryBarState.Create(mIndexFont);
diparms_sbar = InventoryBarState.CreateNoBox(mIndexFont, boxsize:(31, 31), arrowoffs:(0,-10));
mHealthInterpolator = DynamicValueInterpolator.Create(0, 0.25, 1, 8);
mHealthInterpolator2 = DynamicValueInterpolator.Create(0, 0.25, 1, 6); // the chain uses a maximum of 6, not 8.
}
override void NewGame ()
{
Super.NewGame();
mHealthInterpolator.Reset (0);
mHealthInterpolator2.Reset (0);
}
override void Tick()
{
Super.Tick();
mHealthInterpolator.Update(CPlayer.health);
mHealthInterpolator2.Update(CPlayer.health);
}
override void Draw (int state, double TicFrac)
{
Super.Draw (state, TicFrac);
if (state == HUD_StatusBar)
{
BeginStatusBar(320, 200, 38);
DrawMainBar (TicFrac);
}
else if (state == HUD_Fullscreen)
{
BeginHUD(320, 200, 1., false);
DrawFullScreenStuff ();
}
}
protected void DrawFullScreenStuff ()
{
//health
DrawImage("PTN1A0", (51, -3));
DrawString(mBigFont, FormatNumber(mHealthInterpolator.GetValue()), (41, -21), DI_TEXT_ALIGN_RIGHT);
//frags/keys
if (deathmatch)
{
DrawString(mHUDFont, FormatNumber(CPlayer.FragCount, 3), (70, -16));
}
if (!isInventoryBarVisible() && !level.NoInventoryBar)
{
// This code was changed to always fit the item into the box, regardless of alignment or sprite size.
// Heretic's ARTIBOX is 30x30 pixels.
DrawImage("ARTIBOX", (-66, -1), 0, HX_SHADOW);
DrawInventoryIcon(CPlayer.mo.InvSel, (-66, -15), DI_ARTIFLASH|DI_ITEM_CENTER, boxsize:(28, 28));
if (CPlayer.mo.InvSel.Amount > 1)
{
DrawString(mIndexFont, FormatNumber(CPlayer.mo.InvSel.Amount, 3), (-52, -2 - mIndexFont.mFont.GetHeight()), DI_TEXT_ALIGN_RIGHT);
}
}
Ammo ammo1, ammo2;
[ammo1, ammo2] = GetCurrentAmmo();
if ((ammo1 is "Mana1") || (ammo2 is "Mana1")) DrawImage("MANABRT1", (-17, -30), DI_ITEM_OFFSETS);
else DrawImage("MANADIM1", (-17, -30), DI_ITEM_OFFSETS);
if ((ammo1 is "Mana2") || (ammo2 is "Mana2")) DrawImage("MANABRT2", (-17, -15), DI_ITEM_OFFSETS);
else DrawImage("MANADIM2", (-17, -15), DI_ITEM_OFFSETS);
DrawString(mHUDFont, FormatNumber(GetAmount("Mana1"), 3), (-21, -30), DI_TEXT_ALIGN_RIGHT);
DrawString(mHUDFont, FormatNumber(GetAmount("Mana2"), 3), (-21, -15), DI_TEXT_ALIGN_RIGHT);
if (isInventoryBarVisible())
{
DrawInventoryBar(diparms, (0, 0), 7, DI_SCREEN_CENTER_BOTTOM, HX_SHADOW);
}
}
protected void DrawMainBar (double TicFrac)
{
DrawImage("H2BAR", (0, 134), DI_ITEM_OFFSETS);
if (!automapactive)
{
if (isInventoryBarVisible())
{
DrawImage("INVBAR", (38, 162), DI_ITEM_OFFSETS);
DrawInventoryBar(diparms_sbar, (52, 163), 7, DI_ITEM_LEFT_TOP, HX_SHADOW);
return;
}
else
{
DrawImage("STATBAR", (38, 162), DI_ITEM_OFFSETS);
//inventory box
if (CPlayer.mo.InvSel != null)
{
DrawInventoryIcon(CPlayer.mo.InvSel, (159.5, 177), DI_ARTIFLASH|DI_ITEM_CENTER, boxsize:(28, 28));
if (CPlayer.mo.InvSel.Amount > 1)
{
DrawString(mIndexFont, FormatNumber(CPlayer.mo.InvSel.Amount, 3), (174, 184), DI_TEXT_ALIGN_RIGHT);
}
}
if (deathmatch || teamplay)
{
DrawImage("KILLS", (38, 163), DI_ITEM_OFFSETS);
DrawString(mHUDFont, FormatNumber(CPlayer.FragCount, 3), (66, 176), DI_TEXT_ALIGN_RIGHT);
}
else
{
DrawImage("ARMCLS", (41, 178), DI_ITEM_OFFSETS);
// Note that this has been changed to use red only if the REAL health is below 25, not when an interpolated value is below 25!
DrawString(mHUDFont, FormatNumber(mHealthInterpolator.GetValue(), 3), (66, 176), DI_TEXT_ALIGN_RIGHT, CPlayer.Health < 25? Font.CR_RED : Font.CR_UNTRANSLATED);
}
//armor
DrawImage("ARMCLS", (255, 178), DI_ITEM_OFFSETS);
DrawString(mHUDFont, FormatNumber(GetArmorSavePercent() / 5, 2), (276, 176), DI_TEXT_ALIGN_RIGHT);
Ammo ammo1, ammo2;
[ammo1, ammo2] = GetCurrentAmmo();
if (ammo1 != null && !(ammo1 is "Mana1") && !(ammo1 is "Mana2"))
{
DrawImage("HAMOBACK", (77, 164), DI_ITEM_OFFSETS);
if (ammo2 != null)
{
DrawTexture(ammo1.icon, (89, 172), DI_ITEM_CENTER);
DrawTexture(ammo2.icon, (113, 172), DI_ITEM_CENTER);
DrawString(mIndexFont, FormatNumber(ammo1.amount, 3), ( 98, 182), DI_TEXT_ALIGN_RIGHT);
DrawString(mIndexFont, FormatNumber(ammo2.amount, 3), (122, 182), DI_TEXT_ALIGN_RIGHT);
}
else
{
DrawTexture(ammo1.icon, (100, 172), DI_ITEM_CENTER);
DrawString(mIndexFont, FormatNumber(ammo1.amount, 3), (109, 182), DI_TEXT_ALIGN_RIGHT);
}
}
else
{
int amt1, maxamt1, amt2, maxamt2;
[amt1, maxamt1] = GetAmount("Mana1");
[amt2, maxamt2] = GetAmount("Mana2");
if ((ammo1 is "Mana1") || (ammo2 is "Mana1"))
{
DrawImage("MANABRT1", (77, 164), DI_ITEM_OFFSETS);
DrawBar("MANAVL1", "", amt1, maxamt1, (94, 164), 1, SHADER_VERT, DI_ITEM_OFFSETS);
}
else
{
DrawImage("MANADIM1", (77, 164), DI_ITEM_OFFSETS);
DrawBar("MANAVL1D", "", amt1, maxamt1, (94, 164), 1, SHADER_VERT, DI_ITEM_OFFSETS);
}
if ((ammo1 is "Mana2") || (ammo2 is "Mana2"))
{
DrawImage("MANABRT2", (110, 164), DI_ITEM_OFFSETS);
DrawBar("MANAVL2", "", amt2, maxamt2, (102, 164), 1, SHADER_VERT, DI_ITEM_OFFSETS);
}
else
{
DrawImage("MANADIM2", (110, 164), DI_ITEM_OFFSETS);
DrawBar("MANAVL2D", "", amt2, maxamt2, (102, 164), 1, SHADER_VERT, DI_ITEM_OFFSETS);
}
DrawString(mIndexFont, FormatNumber(amt1, 3), ( 92, 181), DI_TEXT_ALIGN_RIGHT);
DrawString(mIndexFont, FormatNumber(amt2, 3), (124, 181), DI_TEXT_ALIGN_RIGHT);
}
if (CPlayer.mo is "ClericPlayer")
{
DrawImage("WPSLOT1", (190, 162), DI_ITEM_OFFSETS);
if (CheckInventory("CWeapWraithverge")) DrawImage("WPFULL1", (190, 162), DI_ITEM_OFFSETS);
else
{
int pieces = GetWeaponPieceMask("CWeapWraithverge");
if (pieces & 1) DrawImage("WPIECEC1", (190, 162), DI_ITEM_OFFSETS);
if (pieces & 2) DrawImage("WPIECEC2", (212, 162), DI_ITEM_OFFSETS);
if (pieces & 4) DrawImage("WPIECEC3", (225, 162), DI_ITEM_OFFSETS);
}
}
else if (CPlayer.mo is "MagePlayer")
{
DrawImage("WPSLOT2", (190, 162), DI_ITEM_OFFSETS);
if (CheckInventory("MWeapBloodscourge")) DrawImage("WPFULL2", (190, 162), DI_ITEM_OFFSETS);
else
{
int pieces = GetWeaponPieceMask("MWeapBloodscourge");
if (pieces & 1) DrawImage("WPIECEM1", (190, 162), DI_ITEM_OFFSETS);
if (pieces & 2) DrawImage("WPIECEM2", (205, 162), DI_ITEM_OFFSETS);
if (pieces & 4) DrawImage("WPIECEM3", (224, 162), DI_ITEM_OFFSETS);
}
}
else
{
DrawImage("WPSLOT0", (190, 162), DI_ITEM_OFFSETS);
if (CheckInventory("FWeapQuietus")) DrawImage("WPFULL0", (190, 162), DI_ITEM_OFFSETS);
else
{
int pieces = GetWeaponPieceMask("FWeapQuietus");
if (pieces & 1) DrawImage("WPIECEF1", (190, 162), DI_ITEM_OFFSETS);
if (pieces & 2) DrawImage("WPIECEF2", (225, 162), DI_ITEM_OFFSETS);
if (pieces & 4) DrawImage("WPIECEF3", (234, 162), DI_ITEM_OFFSETS);
}
}
}
}
else // automap
{
DrawImage("H2BAR", (0, 134), DI_ITEM_OFFSETS);
DrawImage("KEYBAR", (38, 162), DI_ITEM_OFFSETS);
int cnt = 0;
Vector2 keypos = (46, 164);
for(let i = CPlayer.mo.Inv; i != null; i = i.Inv)
{
if (i is "Key" && i.Icon.IsValid())
{
DrawTexture(i.Icon, keypos, DI_ITEM_OFFSETS);
keypos.X += 20;
if (++cnt >= 5) break;
}
}
DrawHexenArmor(HEXENARMOR_ARMOR, "ARMSLOT1", (150, 164), DI_ITEM_OFFSETS);
DrawHexenArmor(HEXENARMOR_SHIELD, "ARMSLOT2", (181, 164), DI_ITEM_OFFSETS);
DrawHexenArmor(HEXENARMOR_HELM, "ARMSLOT3", (212, 164), DI_ITEM_OFFSETS);
DrawHexenArmor(HEXENARMOR_AMULET, "ARMSLOT4", (243, 164), DI_ITEM_OFFSETS);
}
String Gem;
if (CPlayer.mo is "ClericPlayer") Gem = "LIFEGMC2";
else if (CPlayer.mo is "MagePlayer") Gem = "LIFEGMM2";
else Gem = "LIFEGMF2";
int inthealth = mHealthInterpolator2.GetValue();
DrawGem("CHAIN", "LIFEGMF2", inthealth, CPlayer.mo.GetMaxHealth(true), (30, 193), -23, 49, 15, (multiplayer? DI_TRANSLATABLE : 0) | DI_ITEM_LEFT_TOP);
DrawImage("LFEDGE", (0, 193), DI_ITEM_OFFSETS);
DrawImage("RTEDGE", (277, 193), DI_ITEM_OFFSETS);
}
}

View File

@ -27,6 +27,7 @@ class InventoryBarState ui
TextureID selector;
Vector2 boxsize;
Vector2 boxofs;
Vector2 selectofs;
Vector2 innersize;
TextureID left;
@ -52,6 +53,11 @@ class InventoryBarState ui
me.innersize = innersize;
me.boxofs = (me.boxsize - me.innersize) / 2;
}
if (me.selector.IsValid())
{
Vector2 sel = TexMan.GetScaledSize(me.selector);
me.selectofs = (me.boxsize - sel) / 2;
}
me.left = TexMan.CheckForTexture(leftgfx, TexMan.TYPE_MiscPatch);
me.right = TexMan.CheckForTexture(rightgfx, TexMan.TYPE_MiscPatch);
me.arrowoffset = arrowoffs;
@ -316,6 +322,7 @@ class BaseStatusBar native ui
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));
native void DrawString(HUDFont font, String string, Vector2 pos, int flags = 0, int translation = Font.CR_UNTRANSLATED, double Alpha = 1., int wrapwidth = -1, int linespacing = 4);
native void Fill(Color col, double x, double y, double w, double h, int flags = 0);
native static String FormatNumber(int number, int minsize = 0, int maxsize = 0, int format = 0, String prefix = "");
@ -513,7 +520,7 @@ class BaseStatusBar native ui
bool isInventoryBarVisible()
{
if (CPlayer == null) return false;
return (CPlayer.inventorytics <= 0 || level.NoInventoryBar);
return (CPlayer.inventorytics > 0 && !level.NoInventoryBar);
}
//============================================================================
@ -563,7 +570,7 @@ class BaseStatusBar native ui
//
//============================================================================
bool CheckWeaponPiece(class<Weapon> weap, int piecenum)
int CheckWeaponPiece(class<Weapon> weap, int piecenum)
{
if (CPlayer == null) return false;
for(let inv = CPlayer.mo.Inv; inv != NULL; inv = inv.Inv)
@ -583,6 +590,26 @@ class BaseStatusBar native ui
//
//============================================================================
int GetWeaponPieceMask(class<Weapon> weap)
{
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;
}
}
return 0;
}
//============================================================================
//
// checks if player has the given weapon piece
//
//============================================================================
bool WeaponUsesAmmoType(class<Ammo> ammotype)
{
if (CPlayer == null) return false;
@ -794,6 +821,54 @@ class BaseStatusBar native ui
DrawImage(gem, pos + (offset + leftPadding, 0), flags | DI_ITEM_LEFT_TOP);
}
//============================================================================
//
// DrawBar
//
//============================================================================
void DrawBar(String ongfx, String offgfx, double curval, double maxval, Vector2 position, int border, int vertical, int flags = 0, double alpha = 1.)
{
let ontex = TexMan.CheckForTexture(ongfx, TexMan.TYPE_MiscPatch);
if (!ontex.IsValid()) return;
let offtex = TexMan.CheckForTexture(offgfx, TexMan.TYPE_MiscPatch);
Vector2 texsize = TexMan.GetScaledSize(ontex);
[position, flags] = AdjustPosition(position, flags, texsize.X, texsize.Y);
double value = clamp(curval / maxval, 0, 1);
if(border != 0) value = 1. - value; //invert since the new drawing method requires drawing the bg on the fg.
// {cx, cb, cr, cy}
double Clip[4];
Clip[0] = Clip[1] = Clip[2] = Clip[3] = 0;
bool horizontal = !(vertical & SHADER_VERT);
bool reverse = !!(vertical & SHADER_REVERSE);
double sizeOfImage = (horizontal ? texsize.X - border*2 : texsize.Y - border*2);
Clip[(!horizontal) | ((!reverse)<<1)] = sizeOfImage - sizeOfImage *value;
if(border != 0)
{
for(int i = 0; i < 4; i++) Clip[i] += border;
//Draw the whole foreground
DrawTexture(ontex, position, flags | DI_ITEM_LEFT_TOP);
// SetClip
}
if (offtex.IsValid() && TexMan.GetScaledSize(offtex) == texsize) DrawTexture(offtex, position, flags | DI_ITEM_LEFT_TOP);
else Fill(color(255,0,0,0), position.X + Clip[0], position.Y + Clip[1], texsize.X - Clip[0] - Clip[2], texsize.Y - Clip[1] - Clip[3]);
if (border == 0)
{
// SetClip
DrawTexture(ontex, position, flags | DI_ITEM_LEFT_TOP);
}
// UnsetClip
}
//============================================================================
//
// DrawInventoryBar
@ -837,7 +912,7 @@ class BaseStatusBar native ui
{
double flashAlpha = bgalpha;
if (flags & DI_ARTIFLASH) flashAlpha *= itemflashFade;
DrawTexture(parms.selector, position + (boxsize.X * i, 0), flags | DI_ITEM_LEFT_TOP, flashAlpha);
DrawTexture(parms.selector, position + parms.selectofs + (boxsize.X * i, 0), flags | DI_ITEM_LEFT_TOP, flashAlpha);
}
}
else