mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 21:11:39 +00:00
- major progress on the status bar code: SBARINFO's DrawGraphic has been ported into a generic function of the base statusbar class and put to use for a few items on the Strife status bar.
- decided to ditch the widget system I had started to lay out. As it turns out that would make things far more complicated and slower than they need to be.
This commit is contained in:
parent
74a2d58a52
commit
a3ee3c287e
13 changed files with 653 additions and 809 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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<DObject>(NAME_Owner);
|
||||
self->PointerVar<DObject>(NAME_Next) = obj;
|
||||
obj->PointerVar<DObject>(NAME_Prev) = self;
|
||||
obj->PointerVar<DObject>(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<DObject>(NAME_Owner) = self;
|
||||
self->PointerVar<DObject>(NAME_Children) = head;
|
||||
ACTION_RETURN_POINTER(head);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<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;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// 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<Inventory> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<StatusbarWidget> cls, ...);
|
||||
native vararg StatusbarWidget BeginCondition(class<StatusbarCondition> 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<Weapon> Weap1, Weap2;
|
||||
private bool Negate;
|
||||
private bool CheckSister;
|
||||
|
||||
void Init(class<Weapon> w1, class<Weapon> 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<PlayerPawn> PlayerClasses[6];
|
||||
private bool Negate;
|
||||
|
||||
void Init(class<PlayerPawn> p1, class<PlayerPawn> p2, class<PlayerPawn> p3, class<PlayerPawn> p4, class<PlayerPawn> p5, class<PlayerPawn> 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<Weapon> Weap1;
|
||||
private int PieceNum;
|
||||
private bool Negate;
|
||||
|
||||
void Init(class<Weapon> 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<Ammo> AmmoType1, AmmoType2;
|
||||
private int ValidModes;
|
||||
private bool Negate;
|
||||
|
||||
void Init(class<Ammo> ammotype_1, class<Ammo> 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<Inventory> InventoryType1, InventoryType2;
|
||||
private int Amount1, Amount2;
|
||||
private int ValidModes;
|
||||
private bool Negate;
|
||||
|
||||
void Init(class<Inventory> Inventorytype_1, int am1, class<Inventory> 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();
|
||||
}
|
||||
}
|
||||
*/
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue