mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-16 17:31:23 +00:00
3e67a8bafa
- better handling of ForceScale for the fullscreen HUD that doesn't mess around with CVARs. - moved the mug shot into the status bar, because this is global state that needs to be shared between different pieces of code which want to display a mug shot. - SBARINFO should work off the current status bar settings instead of the ones stored in its script object
782 lines
22 KiB
Text
782 lines
22 KiB
Text
|
|
struct MugShot
|
|
{
|
|
enum StateFlags
|
|
{
|
|
STANDARD = 0x0,
|
|
|
|
XDEATHFACE = 0x1,
|
|
ANIMATEDGODMODE = 0x2,
|
|
DISABLEGRIN = 0x4,
|
|
DISABLEOUCH = 0x8,
|
|
DISABLEPAIN = 0x10,
|
|
DISABLERAMPAGE = 0x20,
|
|
CUSTOM = 0x40,
|
|
}
|
|
}
|
|
|
|
|
|
class BaseStatusBar native ui
|
|
{
|
|
enum EPop
|
|
{
|
|
POP_NoChange = -1,
|
|
POP_None,
|
|
POP_Log,
|
|
POP_Keys,
|
|
POP_Status
|
|
}
|
|
|
|
// Status face stuff
|
|
enum EMug
|
|
{
|
|
ST_NUMPAINFACES = 5,
|
|
ST_NUMSTRAIGHTFACES = 3,
|
|
ST_NUMTURNFACES = 2,
|
|
ST_NUMSPECIALFACES = 3,
|
|
ST_NUMEXTRAFACES = 2,
|
|
ST_FACESTRIDE = ST_NUMSTRAIGHTFACES+ST_NUMTURNFACES+ST_NUMSPECIALFACES,
|
|
ST_NUMFACES = ST_FACESTRIDE*ST_NUMPAINFACES+ST_NUMEXTRAFACES,
|
|
|
|
ST_TURNOFFSET = ST_NUMSTRAIGHTFACES,
|
|
ST_OUCHOFFSET = ST_TURNOFFSET + ST_NUMTURNFACES,
|
|
ST_EVILGRINOFFSET = ST_OUCHOFFSET + 1,
|
|
ST_RAMPAGEOFFSET = ST_EVILGRINOFFSET + 1,
|
|
ST_GODFACE = ST_NUMPAINFACES*ST_FACESTRIDE,
|
|
ST_DEADFACE = ST_GODFACE + 1
|
|
}
|
|
|
|
enum EHudState
|
|
{
|
|
HUD_StatusBar,
|
|
HUD_Fullscreen,
|
|
HUD_None,
|
|
|
|
HUD_AltHud // Used for passing through popups to the alt hud
|
|
}
|
|
|
|
enum DI_Flags
|
|
{
|
|
DI_SKIPICON = 0x1,
|
|
DI_SKIPALTICON = 0x2,
|
|
DI_SKIPSPAWN = 0x4,
|
|
DI_SKIPREADY = 0x8,
|
|
DI_ALTICONFIRST = 0x10,
|
|
DI_TRANSLATABLE = 0x20,
|
|
DI_FORCESCALE = 0x40,
|
|
DI_DIM = 0x80,
|
|
};
|
|
|
|
enum IconType
|
|
{
|
|
ITYPE_PLAYERICON = 1000,
|
|
ITYPE_AMMO1,
|
|
ITYPE_AMMO2,
|
|
ITYPE_ARMOR,
|
|
ITYPE_WEAPON,
|
|
ITYPE_SIGIL,
|
|
ITYPE_WEAPONSLOT,
|
|
ITYPE_SELECTEDINVENTORY,
|
|
}
|
|
|
|
enum HexArmorType
|
|
{
|
|
HEXENARMOR_ARMOR,
|
|
HEXENARMOR_SHIELD,
|
|
HEXENARMOR_HELM,
|
|
HEXENARMOR_AMULET,
|
|
};
|
|
|
|
enum EAlign
|
|
{
|
|
ALIGN_TOP = 0,
|
|
ALIGN_VCENTER = 1,
|
|
ALIGN_BOTTOM = 2,
|
|
ALIGN_VOFFSET = 3,
|
|
ALIGN_VMASK = 3,
|
|
|
|
ALIGN_LEFT = 0,
|
|
ALIGN_HCENTER = 4,
|
|
ALIGN_RIGHT = 8,
|
|
ALIGN_HOFFSET = 12,
|
|
ALIGN_HMASK = 12,
|
|
|
|
ALIGN_CENTER = ALIGN_VCENTER|ALIGN_HCENTER,
|
|
ALIGN_CENTER_BOTTOM = ALIGN_BOTTOM|ALIGN_HCENTER,
|
|
ALIGN_OFFSETS = ALIGN_HOFFSET|ALIGN_VOFFSET
|
|
};
|
|
|
|
enum ETextAlign
|
|
{
|
|
TEXT_LEFT = 0,
|
|
TEXT_CENTER = 1,
|
|
TEXT_RIGHT = 2
|
|
};
|
|
|
|
enum SBGameModes
|
|
{
|
|
GAMEMODE_SINGLEPLAYER = 0x1,
|
|
GAMEMODE_COOPERATIVE = 0x2,
|
|
GAMEMODE_DEATHMATCH = 0x4,
|
|
GAMEMODE_TEAMGAME = 0x8
|
|
};
|
|
|
|
enum AmmoModes
|
|
{
|
|
AMMO_PRIMARY,
|
|
AMMO_SECONDARY,
|
|
AMMO_ANY,
|
|
AMMO_BOTH
|
|
};
|
|
|
|
enum EHudDraw
|
|
{
|
|
HUD_Normal,
|
|
HUD_HorizCenter
|
|
}
|
|
|
|
enum ENumFlags
|
|
{
|
|
FNF_FILLZEROS,
|
|
FNF_WHENNOTZERO,
|
|
}
|
|
|
|
const XHAIRSHRINKSIZE =(1./18);
|
|
const XHAIRPICKUPSIZE = (2+XHAIRSHRINKSIZE);
|
|
const POWERUPICONSIZE = 32;
|
|
|
|
|
|
native int ST_X, ST_Y;
|
|
native int RelTop;
|
|
native int HorizontalResolution, VerticalResolution;
|
|
native bool Scaled;
|
|
native bool Centering;
|
|
native bool FixedOrigin;
|
|
native bool CompleteBorder;
|
|
native double CrosshairSize;
|
|
native double Displacement;
|
|
native PlayerInfo CPlayer;
|
|
native bool ShowLog;
|
|
native Vector2 defaultScale; // factor for fully scaled fullscreen display.
|
|
|
|
// These are block properties for the drawers. A child class can set them to have a block of items use the same settings.
|
|
native double Alpha;
|
|
native Vector2 drawOffset; // can be set by subclasses to offset drawing operations
|
|
native double drawClip[4]; // defines a clipping rectangle (not used yet)
|
|
native bool fullscreenOffsets; // current screen is displayed with fullscreen behavior.
|
|
|
|
|
|
native void SetSize(int height, int vwidth, int vheight);
|
|
native Vector2 GetHUDScale();
|
|
native void BeginStatusBar(int resW, int resH, int relTop, bool completeborder = false, bool forceScaled = false);
|
|
native void BeginHUD(int resW, int resH, double Alpha, bool forcescaled = false);
|
|
|
|
virtual void Init() {}
|
|
|
|
native virtual void SetScaled(bool scale, bool force = false);
|
|
native virtual void Tick ();
|
|
native virtual void Draw (int state, double TicFrac);
|
|
native virtual void ScreenSizeChanged ();
|
|
native virtual clearscope void ReceivedWeapon (Weapon weapn);
|
|
native virtual clearscope void SetMugShotState (String state_name, bool wait_till_done=false, bool reset=false);
|
|
|
|
virtual void FlashItem (class<Inventory> itemtype) {}
|
|
virtual void AttachToPlayer (PlayerInfo player) { CPlayer = player; }
|
|
virtual void FlashCrosshair () { CrosshairSize = XHAIRPICKUPSIZE; }
|
|
virtual void NewGame () {}
|
|
virtual void ShowPop (int popnum) { ShowLog = (popnum == POP_Log && !ShowLog); }
|
|
virtual bool MustDrawLog(int state) { return true; }
|
|
|
|
native void RefreshBackground () const;
|
|
native TextureID GetMugshot(PlayerInfo player, String default_face, int accuracy, int stateflags=MugShot.STANDARD);
|
|
|
|
// 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 DrawGraphic(TextureID texture, bool animate, Vector2 pos, double Alpha, bool translatable, bool dim, int imgAlign, int screenalign, bool alphamap, Vector2 box);
|
|
native void DrawString(Font font, String string, Vector2 pos , double Alpha, int translation, int align, int screenalign, int spacing=0, bool monospaced = false, int shadowX=0, int shadowY=0, int wrapwidth = -1, int linespacing = 4);
|
|
native static String FormatNumber(int number, int minsize, int maxsize, int format, String prefix = "");
|
|
|
|
|
|
//============================================================================
|
|
//
|
|
// DBaseStatusBar :: GetCurrentAmmo
|
|
//
|
|
// Returns the types and amounts of ammo used by the current weapon. If the
|
|
// weapon only uses one type of ammo, it is always returned as ammo1.
|
|
//
|
|
//============================================================================
|
|
|
|
Inventory, Inventory, int, int GetCurrentAmmo () const
|
|
{
|
|
Ammo ammo1, ammo2;
|
|
if (CPlayer.ReadyWeapon != NULL)
|
|
{
|
|
ammo1 = CPlayer.ReadyWeapon.Ammo1;
|
|
ammo2 = CPlayer.ReadyWeapon.Ammo2;
|
|
if (ammo1 == NULL)
|
|
{
|
|
ammo1 = ammo2;
|
|
ammo2 = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ammo1 = ammo2 = NULL;
|
|
}
|
|
let ammocount1 = ammo1 != NULL ? ammo1.Amount : 0;
|
|
let ammocount2 = ammo2 != NULL ? ammo2.Amount : 0;
|
|
return ammo1, ammo2, ammocount1, ammocount2;
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// 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;
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// Convenience functions to retrieve item tags
|
|
//
|
|
//============================================================================
|
|
|
|
String GetAmmoTag(bool secondary = false)
|
|
{
|
|
let w = CPlayer.ReadyWeapon;
|
|
if (w == null) return "";
|
|
let ammo = secondary? w.ammo2 : w.ammo1;
|
|
return ammo.GetTag();
|
|
}
|
|
|
|
String GetWeaponTag()
|
|
{
|
|
let w = CPlayer.ReadyWeapon;
|
|
if (w == null) return "";
|
|
return w.GetTag();
|
|
}
|
|
|
|
String GetSelectedInventoryTag()
|
|
{
|
|
let w = CPlayer.mo.InvSel;
|
|
if (w == null) return "";
|
|
return w.GetTag();
|
|
}
|
|
|
|
// These cannot be done in ZScript.
|
|
native String GetGlobalACSString(int index);
|
|
native String GetGlobalACSArrayString(int arrayno, int index);
|
|
native int GetGlobalACSValue(int index);
|
|
native int GetGlobalACSArrayValue(int arrayno, int index);
|
|
|
|
//============================================================================
|
|
//
|
|
// Convenience functions to retrieve some numbers
|
|
//
|
|
//============================================================================
|
|
|
|
int GetArmorAmount()
|
|
{
|
|
let armor = CPlayer.mo.FindInventory("BasicArmor");
|
|
return armor? armor.Amount : 0;
|
|
}
|
|
|
|
int GetMaxAmount(class<Inventory> item)
|
|
{
|
|
let it = CPlayer.mo.FindInventory(item);
|
|
return it? it.MaxAmount : GetDefaultByType(item).MaxAmount;
|
|
}
|
|
|
|
int GetArmorSavePercent()
|
|
{
|
|
double add = 0;
|
|
let harmor = HexenArmor(CPlayer.mo.FindInventory("HexenArmor"));
|
|
if(harmor != NULL)
|
|
{
|
|
add = harmor.Slots[0] + harmor.Slots[1] + harmor.Slots[2] + harmor.Slots[3] + harmor.Slots[4];
|
|
}
|
|
//Hexen counts basic armor also so we should too.
|
|
let armor = BasicArmor(CPlayer.mo.FindInventory("BasicArmor"));
|
|
if(armor != NULL)
|
|
{
|
|
add += armor.SavePercent * 100;
|
|
}
|
|
return int(add);
|
|
}
|
|
|
|
// Note that this retrieves the value in tics, not seconds like the equivalent SBARINFO function.
|
|
// The idea is to let the caller decide what to do with it instead of destroying accuracy here.
|
|
int GetAirTime()
|
|
{
|
|
if(CPlayer.mo.waterlevel < 3)
|
|
return level.airsupply;
|
|
else
|
|
return max(CPlayer.air_finished - level.time, 0);
|
|
}
|
|
|
|
int GetSelectedInventoryAmount()
|
|
{
|
|
if(CPlayer.mo.InvSel != NULL) return CPlayer.mo.InvSel.Amount;
|
|
return 0;
|
|
}
|
|
|
|
int GetKeyCount()
|
|
{
|
|
int num = 0;
|
|
for(Inventory item = CPlayer.mo.Inv;item != NULL;item = item.Inv)
|
|
{
|
|
if(item is "Key") num++;
|
|
}
|
|
return num;
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// various checker functions, based on SBARINFOs condition nodes.
|
|
//
|
|
//============================================================================
|
|
|
|
//============================================================================
|
|
//
|
|
// checks current game mode against a flag mask
|
|
//
|
|
//============================================================================
|
|
|
|
bool CheckGameMode(int ValidModes)
|
|
{
|
|
return (!multiplayer && (ValidModes & GAMEMODE_SINGLEPLAYER)) ||
|
|
(deathmatch && (ValidModes & GAMEMODE_DEATHMATCH)) ||
|
|
(multiplayer && !deathmatch && (ValidModes & GAMEMODE_COOPERATIVE)) ||
|
|
(teamplay && (ValidModes & GAMEMODE_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<Weapon> 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<Weapon> 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<Ammo> 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<Inventory> item, int amount = 1)
|
|
{
|
|
if (CPlayer == null) return false;
|
|
|
|
let it = CPlayer.mo.FindInventory(item);
|
|
return it != null && it.Amount >= amount;
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
//
|
|
// DrawPowerups
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
virtual void DrawPowerups ()
|
|
{
|
|
// The AltHUD specific adjustments have been removed here, because the AltHUD uses its own variant of this function
|
|
// that can obey AltHUD rules - which this cannot.
|
|
Vector2 pos = (-20, POWERUPICONSIZE * 5 / 4);
|
|
double maxpos = screen.GetWidth() / 2;
|
|
for (let item = CPlayer.mo.Inv; item != NULL; item = item.Inv)
|
|
{
|
|
let icon = item.GetPowerupIcon();
|
|
if (icon.IsValid())
|
|
{
|
|
// Each icon gets a 32x32 block.
|
|
DrawTexture(icon, pos, true, 1.0, ALIGN_TOP|ALIGN_RIGHT, (POWERUPICONSIZE, POWERUPICONSIZE), ALIGN_CENTER_BOTTOM);
|
|
pos.x -= POWERUPICONSIZE;
|
|
if (pos.x < -maxpos)
|
|
{
|
|
pos.x = -20;
|
|
pos.y += POWERUPICONSIZE * 3 / 2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// 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 = ALIGN_TOP|ALIGN_LEFT, Vector2 boxsize = (-1, -1), int itemAlign = ALIGN_TOP|ALIGN_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;
|
|
}
|
|
else
|
|
{
|
|
boxsize = texsize;
|
|
}
|
|
DrawGraphic(texture, animated, pos, Alpha, !!(flags & DI_TRANSLATABLE), !!(flags & DI_DIM), itemAlign, screenAlign, false, boxsize);
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
//
|
|
//
|
|
//============================================================================
|
|
|
|
void DrawImage(String imagename, Vector2 pos, bool animated = false, double alpha = 1.0, int screenalign = ALIGN_TOP|ALIGN_LEFT, Vector2 boxsize = (-1, -1), int itemAlign = ALIGN_TOP|ALIGN_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 = ALIGN_TOP|ALIGN_LEFT, Vector2 boxsize = (-1, -1), int itemAlign = ALIGN_TOP|ALIGN_LEFT, int flags = 0)
|
|
{
|
|
TextureID texture;
|
|
Vector2 applyscale = (1, 1);
|
|
Inventory atype1, atype2;
|
|
switch (icontype)
|
|
{
|
|
case ITYPE_PLAYERICON:
|
|
texture = CPlayer.mo.ScoreIcon;
|
|
break;
|
|
|
|
case ITYPE_AMMO1:
|
|
case ITYPE_AMMO2:
|
|
[atype1, atype2] = GetCurrentAmmo();
|
|
[texture, applyscale] = GetIcon(icontype == ITYPE_AMMO1? atype1 : atype2, flags, true);
|
|
break;
|
|
|
|
case ITYPE_ARMOR:
|
|
[texture, applyscale] = GetIcon(CPlayer.mo.FindInventory("BasicArmor"), flags, false);
|
|
break;
|
|
|
|
case ITYPE_WEAPON:
|
|
[texture, applyscale] = GetIcon(CPlayer.ReadyWeapon, flags, false);
|
|
break;
|
|
|
|
case ITYPE_SIGIL:
|
|
[texture, applyscale] = GetIcon(CPlayer.mo.FindInventory("Sigil"), flags, false);
|
|
break;
|
|
|
|
case ITYPE_SELECTEDINVENTORY:
|
|
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 = ALIGN_TOP|ALIGN_LEFT, Vector2 boxsize = (-1, -1), int itemAlign = ALIGN_TOP|ALIGN_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<Inventory> item, String image, Vector2 pos, bool animated = false, double alpha = 1.0, int screenalign = ALIGN_TOP|ALIGN_LEFT, Vector2 boxsize = (-1, -1), int itemAlign = ALIGN_TOP|ALIGN_LEFT, int flags = 0)
|
|
{
|
|
let texture = GetDefaultByType(item).Icon;
|
|
if (texture.IsValid())
|
|
{
|
|
DrawTexture(texture, pos, animated, screenalign, alpha, boxsize, itemAlign, flags);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// a generic value interpolator for status bar elements that can change
|
|
// gradually to their new value.
|
|
//
|
|
//============================================================================
|
|
|
|
class LinearValueInterpolator : Object
|
|
{
|
|
int mCurrentValue;
|
|
int mMaxChange;
|
|
|
|
static LinearValueInterpolator Create(int startval, int maxchange)
|
|
{
|
|
let v = new("LinearValueInterpolator");
|
|
v.mCurrentValue = startval;
|
|
v.mMaxChange = maxchange;
|
|
return v;
|
|
}
|
|
|
|
// This must be called peroiodically in the status bar's Tick function.
|
|
// Do not call this in the Draw function because that may skip some frames!
|
|
void Update(int destvalue)
|
|
{
|
|
if (mCurrentValue > destvalue)
|
|
{
|
|
mCurrentValue = max(destvalue, mCurrentValue - mMaxChange);
|
|
}
|
|
else
|
|
{
|
|
mCurrentValue = min(destvalue, mCurrentValue + mMaxChange);
|
|
}
|
|
}
|
|
|
|
// This must be called in the draw function to retrieve the value for output.
|
|
int GetValue()
|
|
{
|
|
return mCurrentValue;
|
|
}
|
|
}
|
|
|
|
class DynamicValueInterpolator : Object
|
|
{
|
|
int mCurrentValue;
|
|
int mMinChange;
|
|
double mChangeFactor;
|
|
|
|
|
|
static DynamicValueInterpolator Create(int startval, double changefactor, int minchange)
|
|
{
|
|
let v = new("DynamicValueInterpolator");
|
|
v.mCurrentValue = startval;
|
|
v.mMinChange = minchange;
|
|
v.mChangeFactor = changefactor;
|
|
return v;
|
|
}
|
|
|
|
// This must be called peroiodically in the status bar's Tick function.
|
|
// Do not call this in the Draw function because that may skip some frames!
|
|
void Update(int destvalue)
|
|
{
|
|
int diff = int(max(abs(destvalue - mCurrentValue) * mChangeFactor, mMinChange));
|
|
if (mCurrentValue > destvalue)
|
|
{
|
|
mCurrentValue = max(destvalue, mCurrentValue - diff);
|
|
}
|
|
else
|
|
{
|
|
mCurrentValue = min(destvalue, mCurrentValue + diff);
|
|
}
|
|
}
|
|
|
|
// This must be called in the draw function to retrieve the value for output.
|
|
int GetValue()
|
|
{
|
|
return mCurrentValue;
|
|
}
|
|
}
|
|
|