mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 15:02:01 +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 ();
|
V_RefreshViewBorder ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for timing the statusbar code.
|
||||||
|
//cycle_t stb;
|
||||||
|
//stb.Reset();
|
||||||
|
//stb.Clock();
|
||||||
if (hud_althud && viewheight == SCREENHEIGHT && screenblocks > 10)
|
if (hud_althud && viewheight == SCREENHEIGHT && screenblocks > 10)
|
||||||
{
|
{
|
||||||
StatusBar->DrawBottomStuff (HUD_AltHud);
|
StatusBar->DrawBottomStuff (HUD_AltHud);
|
||||||
|
@ -828,6 +832,8 @@ void D_Display ()
|
||||||
StatusBar->CallDraw (HUD_StatusBar);
|
StatusBar->CallDraw (HUD_StatusBar);
|
||||||
StatusBar->DrawTopStuff (HUD_StatusBar);
|
StatusBar->DrawTopStuff (HUD_StatusBar);
|
||||||
}
|
}
|
||||||
|
//stb.Unclock();
|
||||||
|
//Printf("Stbar = %f\n", stb.TimeMS());
|
||||||
CT_Drawer ();
|
CT_Drawer ();
|
||||||
break;
|
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
|
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;
|
FTextureID picnum, AltIcon = item->AltHUDIcon;
|
||||||
FState * state=NULL, *ReadyState;
|
FState * state=NULL, *ReadyState;
|
||||||
|
|
||||||
|
@ -718,6 +725,17 @@ FTextureID GetInventoryIcon(AInventory *item, uint32_t flags, bool *applyscale=N
|
||||||
return picnum;
|
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)
|
static void DrawOneWeapon(player_t * CPlayer, int x, int & y, AWeapon * weapon)
|
||||||
{
|
{
|
||||||
|
|
|
@ -373,6 +373,28 @@ public:
|
||||||
virtual bool MustDrawLog(EHudState state);
|
virtual bool MustDrawLog(EHudState state);
|
||||||
virtual void SetMugShotState (const char *state_name, bool wait_till_done=false, bool reset=false);
|
virtual void SetMugShotState (const char *state_name, bool wait_till_done=false, bool reset=false);
|
||||||
void DrawLog();
|
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)
|
void GetCoords(int &x, int &y)
|
||||||
{
|
{
|
||||||
|
|
|
@ -57,6 +57,7 @@
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
#include "g_levellocals.h"
|
#include "g_levellocals.h"
|
||||||
#include "virtual.h"
|
#include "virtual.h"
|
||||||
|
#include "r_data/r_translate.h"
|
||||||
|
|
||||||
#include "../version.h"
|
#include "../version.h"
|
||||||
|
|
||||||
|
@ -624,9 +625,6 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, RefreshBackground)
|
||||||
|
|
||||||
void DBaseStatusBar::DrawCrosshair ()
|
void DBaseStatusBar::DrawCrosshair ()
|
||||||
{
|
{
|
||||||
static uint32_t prevcolor = 0xffffffff;
|
|
||||||
static int palettecolor = 0;
|
|
||||||
|
|
||||||
uint32_t color;
|
uint32_t color;
|
||||||
double size;
|
double size;
|
||||||
int w, h;
|
int w, h;
|
||||||
|
@ -693,19 +691,13 @@ void DBaseStatusBar::DrawCrosshair ()
|
||||||
color = crosshaircolor;
|
color = crosshaircolor;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (color != prevcolor)
|
|
||||||
{
|
|
||||||
prevcolor = color;
|
|
||||||
palettecolor = ColorMatcher.Pick (RPART(color), GPART(color), BPART(color));
|
|
||||||
}
|
|
||||||
|
|
||||||
screen->DrawTexture (CrosshairImage,
|
screen->DrawTexture (CrosshairImage,
|
||||||
viewwidth / 2 + viewwindowx,
|
viewwidth / 2 + viewwindowx,
|
||||||
viewheight / 2 + viewwindowy,
|
viewheight / 2 + viewwindowy,
|
||||||
DTA_DestWidth, w,
|
DTA_DestWidth, w,
|
||||||
DTA_DestHeight, h,
|
DTA_DestHeight, h,
|
||||||
DTA_AlphaChannel, true,
|
DTA_AlphaChannel, true,
|
||||||
DTA_FillColor, (palettecolor << 24) | (color & 0xFFFFFF),
|
DTA_FillColor, color & 0xFFFFFF,
|
||||||
TAG_DONE);
|
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
|
// CCMD showpop
|
||||||
|
@ -1438,36 +1544,3 @@ static DObject *InitObject(PClass *type, int paramnum, VM_ARGS)
|
||||||
return obj;
|
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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Function->Variants[0].Implementation->PrintableName.CompareNoCase("CustomStatusBar.DrawTexture") == 0)
|
||||||
|
{
|
||||||
|
int a = 0;
|
||||||
|
}
|
||||||
|
|
||||||
CallingFunction = ctx.Function;
|
CallingFunction = ctx.Function;
|
||||||
if (ArgList.Size() > 0)
|
if (ArgList.Size() > 0)
|
||||||
{
|
{
|
||||||
|
@ -8736,6 +8741,12 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx)
|
||||||
delete old;
|
delete old;
|
||||||
// now fill the gap with constants created from the default list so that we got a full list of arguments.
|
// 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 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++)
|
for (int k = 0; k < insert; k++)
|
||||||
{
|
{
|
||||||
auto ntype = argtypes[i + k + implicit];
|
auto ntype = argtypes[i + k + implicit];
|
||||||
|
@ -8745,8 +8756,23 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx)
|
||||||
assert(ntype->IsKindOf(RUNTIME_CLASS(PPointer)));
|
assert(ntype->IsKindOf(RUNTIME_CLASS(PPointer)));
|
||||||
ntype = TypeNullPtr; // the default of a reference type can only be a null pointer
|
ntype = TypeNullPtr; // the default of a reference type can only be a null pointer
|
||||||
}
|
}
|
||||||
auto x = new FxConstant(ntype, defaults[i + k + implicit], ScriptPosition);
|
if (ntype->GetRegCount() == 1)
|
||||||
ArgList.Insert(i + k, x);
|
{
|
||||||
|
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;
|
done = true;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -2503,10 +2503,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
||||||
{
|
{
|
||||||
flags |= VARF_Optional;
|
flags |= VARF_Optional;
|
||||||
hasoptionals = true;
|
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);
|
FxExpression *x = new FxTypeCast(ConvertNode(p->Default), type, false);
|
||||||
FCompileContext ctx(OutNamespace, c->Type(), false);
|
FCompileContext ctx(OutNamespace, c->Type(), false);
|
||||||
x = x->Resolve(ctx);
|
x = x->Resolve(ctx);
|
||||||
|
|
|
@ -104,6 +104,7 @@ void SWCanvas::DrawTexture(DCanvas *canvas, FTexture *img, DrawParms &parms)
|
||||||
|
|
||||||
drawerargs.SetTranslationMap(translation);
|
drawerargs.SetTranslationMap(translation);
|
||||||
drawerargs.SetLight(basecolormap, 0.0f, shade);
|
drawerargs.SetLight(basecolormap, 0.0f, shade);
|
||||||
|
|
||||||
bool visible = drawerargs.SetStyle(viewport, parms.style, parms.Alpha, -1, parms.fillcolor, basecolormap);
|
bool visible = drawerargs.SetStyle(viewport, parms.style, parms.Alpha, -1, parms.fillcolor, basecolormap);
|
||||||
|
|
||||||
double x0 = parms.x - parms.left * parms.destwidth / parms.texwidth;
|
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:
|
case DTA_FillColor:
|
||||||
parms->fillcolor = ListGetInt(tags);
|
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;
|
break;
|
||||||
|
|
||||||
case DTA_TranslationIndex:
|
case DTA_TranslationIndex:
|
||||||
|
|
|
@ -35,7 +35,6 @@ version "2.5"
|
||||||
#include "zscript/statusbar/statusbar.txt"
|
#include "zscript/statusbar/statusbar.txt"
|
||||||
#include "zscript/statusbar/strife_sbar.txt"
|
#include "zscript/statusbar/strife_sbar.txt"
|
||||||
#include "zscript/statusbar/sbarinfowrapper.txt"
|
#include "zscript/statusbar/sbarinfowrapper.txt"
|
||||||
#include "zscript/statusbar/statusbarwidget.txt"
|
|
||||||
|
|
||||||
#include "zscript/inventory/inventory.txt"
|
#include "zscript/inventory/inventory.txt"
|
||||||
#include "zscript/inventory/inv_misc.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 GiveBody (int num, int max=0);
|
||||||
native bool HitFloor();
|
native bool HitFloor();
|
||||||
native clearscope bool isTeammate(Actor other) const;
|
native clearscope bool isTeammate(Actor other) const;
|
||||||
native int PlayerNumber();
|
native clearscope int PlayerNumber() const;
|
||||||
native void SetFriendPlayer(PlayerInfo player);
|
native void SetFriendPlayer(PlayerInfo player);
|
||||||
native void SoundAlert(Actor target, bool splash = false, double maxdist = 0);
|
native void SoundAlert(Actor target, bool splash = false, double maxdist = 0);
|
||||||
native void DaggerAlert(Actor target);
|
native void DaggerAlert(Actor target);
|
||||||
|
|
|
@ -80,6 +80,11 @@ class BaseStatusBar native ui
|
||||||
|
|
||||||
native void RefreshBackground () const;
|
native void RefreshBackground () const;
|
||||||
native Inventory ValidateInvFirst (int numVisible) 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;
|
let ammocount2 = ammo2 != NULL ? ammo2.Amount : 0;
|
||||||
return ammo1, ammo2, ammocount1, ammocount2;
|
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.
|
// Number of tics to move the popscreen up and down.
|
||||||
|
@ -59,6 +59,7 @@ class StrifeStatusBar : BaseStatusBar
|
||||||
|
|
||||||
override void Init()
|
override void Init()
|
||||||
{
|
{
|
||||||
|
Super.Init();
|
||||||
SetSize(32, 320, 200);
|
SetSize(32, 320, 200);
|
||||||
DoCommonInit();
|
DoCommonInit();
|
||||||
}
|
}
|
||||||
|
@ -368,20 +369,17 @@ class StrifeStatusBar : BaseStatusBar
|
||||||
|
|
||||||
protected void DrawFullScreenStuff ()
|
protected void DrawFullScreenStuff ()
|
||||||
{
|
{
|
||||||
|
fullscreenoffsets = true;
|
||||||
// Draw health
|
// Draw health
|
||||||
DrINumberOuter (CPlayer.health, 4, -10, false, 7);
|
DrINumberOuter (CPlayer.health, 4, -10, false, 7);
|
||||||
screen.DrawTexture (Images[imgMEDI], true, 14, -17,
|
DrawTexture(Images[imgMEDI], (14, -17), false, 1.0, BOTTOM|LEFT, itemalign: BOTTOM|HCENTER);
|
||||||
DTA_HUDRules, HUD_Normal,
|
|
||||||
DTA_CenterBottomOffset, true);
|
|
||||||
|
|
||||||
// Draw armor
|
// Draw armor
|
||||||
let armor = CPlayer.mo.FindInventory('BasicArmor');
|
let armor = CPlayer.mo.FindInventory('BasicArmor');
|
||||||
if (armor != NULL && armor.Amount != 0)
|
if (armor != NULL && armor.Amount != 0)
|
||||||
{
|
{
|
||||||
DrINumberOuter (armor.Amount, 35, -10, false, 7);
|
DrINumberOuter (armor.Amount, 35, -10, false, 7);
|
||||||
screen.DrawTexture (armor.Icon, true, 45, -17,
|
DrawTexture(armor.Icon, (45, -17), false, 1.0, BOTTOM|LEFT, itemalign: BOTTOM|HCENTER);
|
||||||
DTA_HUDRules, HUD_Normal,
|
|
||||||
DTA_CenterBottomOffset, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw ammo
|
// Draw ammo
|
||||||
|
@ -393,16 +391,12 @@ class StrifeStatusBar : BaseStatusBar
|
||||||
{
|
{
|
||||||
// Draw primary ammo in the bottom-right corner
|
// Draw primary ammo in the bottom-right corner
|
||||||
DrINumberOuter (ammo1.Amount, -23, -10, false, 7);
|
DrINumberOuter (ammo1.Amount, -23, -10, false, 7);
|
||||||
screen.DrawTexture (ammo1.Icon, true, -14, -17,
|
DrawTexture(ammo1.Icon, (-14, -17), false, 1.0, BOTTOM|RIGHT, itemalign: BOTTOM|HCENTER);
|
||||||
DTA_HUDRules, HUD_Normal,
|
|
||||||
DTA_CenterBottomOffset, true);
|
|
||||||
if (ammo2 != NULL && ammo1!=ammo2)
|
if (ammo2 != NULL && ammo1!=ammo2)
|
||||||
{
|
{
|
||||||
// Draw secondary ammo just above the primary ammo
|
// Draw secondary ammo just above the primary ammo
|
||||||
DrINumberOuter (ammo2.Amount, -23, -48, false, 7);
|
DrINumberOuter (ammo2.Amount, -23, -48, false, 7);
|
||||||
screen.DrawTexture (ammo2.Icon, -14, -55,
|
DrawTexture(ammo1.Icon, (-14, -55), false, 1.0, BOTTOM|RIGHT, itemalign: BOTTOM|HCENTER);
|
||||||
DTA_HUDRules, HUD_Normal,
|
|
||||||
DTA_CenterBottomOffset, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,6 +452,7 @@ class StrifeStatusBar : BaseStatusBar
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fullscreenoffsets = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void DrawPopScreen (int bottom, double TicFrac)
|
protected void DrawPopScreen (int bottom, double TicFrac)
|
||||||
|
|
Loading…
Reference in a new issue