- scriptified the main statusbar interface and the Strife status bar.

Note that the Strife status bar does not draw the health bars yet. I tried to replace the hacky custom texture with a single fill operation but had to find out that all the coordinate mangling for the status bar is being done deep in the video code. This needs to be fixed before this can be made to work.

Currently this is not usable in mods because they cannot initialize custom status bars yet.
This commit is contained in:
Christoph Oelckers 2017-03-21 20:09:09 +01:00
parent 4110f34139
commit 9bffe4ee50
29 changed files with 1186 additions and 1169 deletions

View file

@ -1096,7 +1096,6 @@ set (PCH_SOURCES
g_statusbar/sbarinfo.cpp
g_statusbar/sbar_mugshot.cpp
g_statusbar/shared_sbar.cpp
g_statusbar/strife_sbar.cpp
gl/compatibility/gl_20.cpp
gl/data/gl_data.cpp
gl/data/gl_portaldata.cpp

View file

@ -1452,7 +1452,6 @@ void AM_ToggleMap ()
if (dmflags2 & DF2_NO_AUTOMAP)
return;
ST_SetNeedRefresh();
if (!automapactive)
{
AM_Start ();
@ -1463,7 +1462,6 @@ void AM_ToggleMap ()
if (am_overlay==1 && viewactive)
{
viewactive = false;
ST_SetNeedRefresh();
}
else
{

View file

@ -387,11 +387,6 @@ bool FCajunMaster::DoAddBot (uint8_t *info, botskill_t skill)
Printf ("%s joined the game\n", players[bnum].userinfo.GetName());
G_DoReborn (bnum, true);
if (StatusBar != NULL)
{
StatusBar->MultiplayerChanged ();
}
return true;
}
@ -414,7 +409,7 @@ void FCajunMaster::RemoveAllBots (bool fromlist)
players[j].camera = players[j].mo;
if (j == consoleplayer)
{
StatusBar->AttachToPlayer (players + j);
StatusBar->CallAttachToPlayer (players + j);
}
}
}

View file

@ -1296,7 +1296,6 @@ void C_DrawConsole (bool hw2d)
{
screen->Dim (PalEntry ((unsigned char)(player->BlendR*255), (unsigned char)(player->BlendG*255), (unsigned char)(player->BlendB*255)),
player->BlendA, 0, ConBottom, screen->GetWidth(), screen->GetHeight() - ConBottom);
ST_SetNeedRefresh();
V_SetBorderNeedRefresh();
}
}

View file

@ -473,7 +473,7 @@ CUSTOM_CVAR (Int, dmflags2, 0, CVAR_SERVERINFO)
p->camera = p->mo;
S_UpdateSounds (p->camera);
StatusBar->AttachToPlayer (p);
StatusBar->CallAttachToPlayer (p);
if (demoplayback || multiplayer)
StatusBar->ShowPlayerName ();
@ -686,7 +686,7 @@ void D_Display ()
// Let the status bar know the screen size changed
if (StatusBar != NULL)
{
StatusBar->ScreenSizeChanged ();
StatusBar->CallScreenSizeChanged ();
}
// Refresh the console.
C_NewModeAdjust ();
@ -707,7 +707,6 @@ void D_Display ()
if (screen->Lock (false))
{
ST_SetNeedRefresh();
V_SetBorderNeedRefresh();
}
@ -785,7 +784,6 @@ void D_Display ()
if ((hw2d = screen->Begin2D(viewactive)))
{
// Redraw everything every frame when using 2D accel
ST_SetNeedRefresh();
V_SetBorderNeedRefresh();
}
Renderer->DrawRemainingPlayerSprites();
@ -813,7 +811,7 @@ void D_Display ()
{
StatusBar->DrawCrosshair();
}
StatusBar->Draw (HUD_AltHud);
StatusBar->CallDraw (HUD_AltHud);
StatusBar->DrawTopStuff (HUD_AltHud);
}
else
@ -821,13 +819,13 @@ void D_Display ()
{
EHudState state = DrawFSHUD ? HUD_Fullscreen : HUD_None;
StatusBar->DrawBottomStuff (state);
StatusBar->Draw (state);
StatusBar->CallDraw (state);
StatusBar->DrawTopStuff (state);
}
else
{
StatusBar->DrawBottomStuff (HUD_StatusBar);
StatusBar->Draw (HUD_StatusBar);
StatusBar->CallDraw (HUD_StatusBar);
StatusBar->DrawTopStuff (HUD_StatusBar);
}
CT_Drawer ();

View file

@ -342,7 +342,7 @@ static void UpdateTeam (int pnum, int team, bool update)
R_BuildPlayerTranslation (pnum);
if (StatusBar != NULL && StatusBar->GetPlayer() == pnum)
{
StatusBar->AttachToPlayer (&players[pnum]);
StatusBar->CallAttachToPlayer (&players[pnum]);
}
// Double-check
if (!TeamLibrary.IsValidTeam (team))
@ -884,7 +884,7 @@ void D_ReadUserInfoStrings (int pnum, uint8_t **stream, bool update)
R_BuildPlayerTranslation(pnum);
if (StatusBar != NULL && pnum == StatusBar->GetPlayer())
{
StatusBar->AttachToPlayer(&players[pnum]);
StatusBar->CallAttachToPlayer(&players[pnum]);
}
}
}

View file

@ -923,7 +923,7 @@ static void ChangeSpy (int changespy)
players[consoleplayer].camera = players[pnum].mo;
S_UpdateSounds(players[consoleplayer].camera);
StatusBar->AttachToPlayer (&players[pnum]);
StatusBar->CallAttachToPlayer (&players[pnum]);
if (demoplayback || multiplayer)
{
StatusBar->ShowPlayerName ();
@ -1823,7 +1823,7 @@ void G_DoPlayerPop(int playernum)
players[ii].camera = players[ii].mo;
if (ii == consoleplayer && StatusBar != NULL)
{
StatusBar->AttachToPlayer(&players[ii]);
StatusBar->CallAttachToPlayer(&players[ii]);
}
}
}
@ -2909,7 +2909,7 @@ bool G_CheckDemoStatus (void)
players[0].camera = NULL;
if (StatusBar != NULL)
{
StatusBar->AttachToPlayer (&players[0]);
StatusBar->CallAttachToPlayer (&players[0]);
}
if (singledemo || timingdemo)
{

View file

@ -328,7 +328,6 @@ void G_NewInit ()
}
G_ClearSnapshots ();
ST_SetNeedRefresh();
netgame = false;
multiplayer = multiplayernext;
multiplayernext = false;
@ -485,7 +484,7 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
}
}
GC::WriteBarrier(StatusBar);
StatusBar->AttachToPlayer (&players[consoleplayer]);
StatusBar->CallAttachToPlayer (&players[consoleplayer]);
StatusBar->NewGame ();
setsizeneeded = true;
@ -1091,7 +1090,7 @@ void G_DoLoadLevel (int position, bool autosave)
FBehavior::StaticStartTypedScripts(SCRIPT_Reopen, NULL, false);
}
StatusBar->AttachToPlayer (&players[consoleplayer]);
StatusBar->CallAttachToPlayer (&players[consoleplayer]);
// unsafe world load
E_WorldLoadedUnsafe();
// regular world load (savegames are handled internally)

View file

@ -43,8 +43,6 @@
class player_t;
struct FRemapTable;
extern int SB_state;
enum EHudState
{
HUD_StatusBar,
@ -56,8 +54,6 @@ enum EHudState
class AWeapon;
void ST_SetNeedRefresh();
bool ST_IsTimeVisible();
bool ST_IsLatencyVisible();
@ -341,7 +337,7 @@ public:
ST_DEADFACE = ST_GODFACE + 1
};
DBaseStatusBar (int reltop, int hres=320, int vres=200);
DBaseStatusBar (int reltop = 32, int hres=320, int vres=200);
void OnDestroy() override;
void AttachMessage (DHUDMessage *msg, uint32_t id=0, int layer=HUDMSGLayer_Default);
@ -358,19 +354,23 @@ public:
void SerializeMessages(FSerializer &arc);
virtual void SetScaled(bool scale, bool force = false);
void CallSetScaled(bool scale, bool force = false);
virtual void Tick ();
void CallTick();
virtual void Draw (EHudState state);
void CallDraw(EHudState state);
void DrawBottomStuff (EHudState state);
void DrawTopStuff (EHudState state);
virtual void FlashItem (const PClass *itemtype);
virtual void AttachToPlayer (player_t *player);
void CallAttachToPlayer(player_t *player);
virtual void FlashCrosshair ();
virtual void BlendView (float blend[4]);
virtual void NewGame ();
virtual void ScreenSizeChanged ();
virtual void MultiplayerChanged ();
virtual void SetInteger (int pname, int param);
void CallScreenSizeChanged();
virtual void ShowPop (int popnum);
void CallShowPop(int popnum);
virtual void ReceivedWeapon (AWeapon *weapon);
virtual bool MustDrawLog(EHudState state);
virtual void SetMugShotState (const char *state_name, bool wait_till_done=false, bool reset=false);
@ -383,7 +383,7 @@ public:
}
protected:
//protected:
void DrawPowerups ();
@ -410,7 +410,6 @@ public:
player_t *CPlayer;
private:
DBaseStatusBar() {}
bool RepositionCoords (int &x, int &y, int xo, int yo, const int w, const int h) const;
void DrawMessages (int layer, int bottom);
void DrawConsistancy () const;

View file

@ -87,7 +87,6 @@ DBaseStatusBar *StatusBar;
extern int setblocks;
int gST_X, gST_Y;
int SB_state = 3;
FTexture *CrosshairImage;
static int CrosshairNum;
@ -107,7 +106,7 @@ CUSTOM_CVAR (Bool, st_scale, true, CVAR_ARCHIVE)
{
if (StatusBar)
{
StatusBar->SetScaled (self);
StatusBar->CallSetScaled (self);
setsizeneeded = true;
}
}
@ -219,17 +218,6 @@ void ST_Clear()
CrosshairNum = 0;
}
//---------------------------------------------------------------------------
//
// ST_SetNeedRefresh
//
//---------------------------------------------------------------------------
void ST_SetNeedRefresh()
{
SB_state = (StatusBar == NULL || screen == NULL) ? 0 : screen->GetPageCount();
}
//---------------------------------------------------------------------------
//
// Constructor
@ -250,7 +238,7 @@ DBaseStatusBar::DBaseStatusBar (int reltop, int hres, int vres)
HorizontalResolution = hres;
VerticalResolution = vres;
SetScaled (st_scale);
CallSetScaled (st_scale);
}
//---------------------------------------------------------------------------
@ -319,7 +307,25 @@ void DBaseStatusBar::SetScaled (bool scale, bool force)
Displacement = 0;
}
gST_X = ST_X;
ST_SetNeedRefresh();
}
DEFINE_ACTION_FUNCTION(DBaseStatusBar, SetScaled)
{
PARAM_SELF_PROLOGUE(DBaseStatusBar);
PARAM_BOOL(scale);
PARAM_BOOL_DEF(force);
self->SetScaled(scale, force);
return 0;
}
void DBaseStatusBar::CallSetScaled(bool scale, bool force)
{
IFVIRTUAL(DBaseStatusBar, SetScaled)
{
VMValue params[] = { (DObject*)this, scale, force };
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
}
else SetScaled(scale, force);
}
//---------------------------------------------------------------------------
@ -331,7 +337,24 @@ void DBaseStatusBar::SetScaled (bool scale, bool force)
void DBaseStatusBar::AttachToPlayer (player_t *player)
{
CPlayer = player;
ST_SetNeedRefresh();
}
DEFINE_ACTION_FUNCTION(DBaseStatusBar, AttachToPlayer)
{
PARAM_SELF_PROLOGUE(DBaseStatusBar);
PARAM_POINTER(player, player_t);
self->AttachToPlayer(player);
return 0;
}
void DBaseStatusBar::CallAttachToPlayer(player_t *player)
{
IFVIRTUAL(DBaseStatusBar, AttachToPlayer)
{
VMValue params[] = { (DObject*)this, player };
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
}
else AttachToPlayer(player);
}
//---------------------------------------------------------------------------
@ -345,17 +368,6 @@ int DBaseStatusBar::GetPlayer ()
return int(CPlayer - players);
}
//---------------------------------------------------------------------------
//
// PROC MultiplayerChanged
//
//---------------------------------------------------------------------------
void DBaseStatusBar::MultiplayerChanged ()
{
ST_SetNeedRefresh();
}
//---------------------------------------------------------------------------
//
// PROC Tick
@ -397,6 +409,23 @@ void DBaseStatusBar::Tick ()
}
}
DEFINE_ACTION_FUNCTION(DBaseStatusBar, Tick)
{
PARAM_SELF_PROLOGUE(DBaseStatusBar);
self->Tick();
return 0;
}
void DBaseStatusBar::CallTick()
{
IFVIRTUAL(DBaseStatusBar, Tick)
{
VMValue params[] = { (DObject*)this };
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
}
else Tick();
}
//---------------------------------------------------------------------------
//
// PROC AttachMessage
@ -460,11 +489,6 @@ DHUDMessage *DBaseStatusBar::DetachMessage (DHUDMessage *msg)
{
*prev = probe->Next;
probe->Next = NULL;
// Redraw the status bar in case it was covered
if (screen != NULL)
{
ST_SetNeedRefresh();
}
return probe;
}
}
@ -487,11 +511,6 @@ DHUDMessage *DBaseStatusBar::DetachMessage (uint32_t id)
{
*prev = probe->Next;
probe->Next = NULL;
// Redraw the status bar in case it was covered
if (screen != NULL)
{
ST_SetNeedRefresh();
}
return probe;
}
}
@ -589,6 +608,13 @@ void DBaseStatusBar::RefreshBackground () const
}
}
DEFINE_ACTION_FUNCTION(DBaseStatusBar, RefreshBackground)
{
PARAM_SELF_PROLOGUE(DBaseStatusBar);
self->RefreshBackground();
return 0;
}
//---------------------------------------------------------------------------
//
// DrawCrosshair
@ -734,7 +760,7 @@ void DBaseStatusBar::Draw (EHudState state)
char line[64+10];
if ((SB_state != 0 || BorderNeedRefresh) && state == HUD_StatusBar)
if (state == HUD_StatusBar)
{
RefreshBackground ();
}
@ -902,6 +928,25 @@ void DBaseStatusBar::Draw (EHudState state)
}
}
DEFINE_ACTION_FUNCTION(DBaseStatusBar, Draw)
{
PARAM_SELF_PROLOGUE(DBaseStatusBar);
PARAM_INT(state);
self->Draw((EHudState)state);
return 0;
}
void DBaseStatusBar::CallDraw(EHudState state)
{
IFVIRTUAL(DBaseStatusBar, Draw)
{
VMValue params[] = { (DObject*)this, state, r_viewpoint.TicFrac };
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
}
else Draw(state);
}
void DBaseStatusBar::DrawLog ()
{
@ -959,8 +1004,16 @@ void DBaseStatusBar::DrawLog ()
}
}
bool DBaseStatusBar::MustDrawLog(EHudState)
bool DBaseStatusBar::MustDrawLog(EHudState state)
{
IFVIRTUAL(DBaseStatusBar, MustDrawLog)
{
VMValue params[] = { (DObject*)this };
int rv;
VMReturn ret(&rv);
GlobalVMStack.Call(func, params, countof(params), &ret, 1);
return !!rv;
}
return true;
}
@ -1154,14 +1207,20 @@ void DBaseStatusBar::DrawWaiting () const
void DBaseStatusBar::FlashItem (const PClass *itemtype)
{
IFVIRTUAL(DBaseStatusBar, FlashItem)
{
VMValue params[] = { (DObject*)this, (PClass*)itemtype };
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
}
}
void DBaseStatusBar::NewGame ()
{
}
void DBaseStatusBar::SetInteger (int pname, int param)
{
IFVIRTUAL(DBaseStatusBar, NewGame)
{
VMValue params[] = { (DObject*)this };
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
}
}
void DBaseStatusBar::ShowPop (int popnum)
@ -1169,15 +1228,35 @@ void DBaseStatusBar::ShowPop (int popnum)
ShowLog = (popnum == POP_Log && !ShowLog);
}
DEFINE_ACTION_FUNCTION(DBaseStatusBar, ShowPop)
{
PARAM_SELF_PROLOGUE(DBaseStatusBar);
PARAM_INT(state);
self->ShowPop(state);
return 0;
}
void DBaseStatusBar::CallShowPop(int pop)
{
IFVIRTUAL(DBaseStatusBar, ShowPop)
{
VMValue params[] = { (DObject*)this, pop };
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
}
else ShowPop(pop);
}
void DBaseStatusBar::ReceivedWeapon (AWeapon *weapon)
{
}
DEFINE_ACTION_FUNCTION(_StatusBar, ReceivedWeapon)
DEFINE_ACTION_FUNCTION(DBaseStatusBar, ReceivedWeapon)
{
PARAM_PROLOGUE;
PARAM_SELF_PROLOGUE(DBaseStatusBar);
PARAM_POINTER(w, AWeapon);
StatusBar->ReceivedWeapon(w);
self->ReceivedWeapon(w);
return 0;
}
@ -1190,7 +1269,6 @@ void DBaseStatusBar::SerializeMessages(FSerializer &arc)
void DBaseStatusBar::ScreenSizeChanged ()
{
st_scale.Callback ();
ST_SetNeedRefresh();
for (size_t i = 0; i < countof(Messages); ++i)
{
@ -1203,6 +1281,23 @@ void DBaseStatusBar::ScreenSizeChanged ()
}
}
DEFINE_ACTION_FUNCTION(DBaseStatusBar, ScreenSizeChanged)
{
PARAM_SELF_PROLOGUE(DBaseStatusBar);
self->ScreenSizeChanged();
return 0;
}
void DBaseStatusBar::CallScreenSizeChanged()
{
IFVIRTUAL(DBaseStatusBar, ScreenSizeChanged)
{
VMValue params[] = { (DObject*)this };
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
}
else ScreenSizeChanged();
}
//---------------------------------------------------------------------------
//
// ValidateInvFirst
@ -1294,6 +1389,14 @@ AInventory *DBaseStatusBar::ValidateInvFirst (int numVisible) const
}
}
DEFINE_ACTION_FUNCTION(DBaseStatusBar, ValidateInvFirst)
{
PARAM_SELF_PROLOGUE(DBaseStatusBar);
PARAM_INT(num);
ACTION_RETURN_POINTER(self->ValidateInvFirst(num));
}
//============================================================================
//
// DBaseStatusBar :: GetCurrentAmmo
@ -1323,6 +1426,20 @@ void DBaseStatusBar::GetCurrentAmmo (AInventory *&ammo1, AInventory *&ammo2, int
ammocount2 = ammo2 != NULL ? ammo2->Amount : 0;
}
DEFINE_ACTION_FUNCTION(DBaseStatusBar, GetCurrentAmmo)
{
PARAM_SELF_PROLOGUE(DBaseStatusBar);
AInventory *ammo1, *ammo2;
int ammocount1, ammocount2;
self->GetCurrentAmmo(ammo1, ammo2, ammocount1, ammocount2);
if (numret >= 1) ret[0].SetPointer(ammo1, ATAG_OBJECT);
if (numret >= 2) ret[1].SetPointer(ammo2, ATAG_OBJECT);
if (numret >= 3) ret[2].SetInt(ammocount1);
if (numret >= 4) ret[3].SetInt(ammocount2);
return MIN(numret, 4);
}
//============================================================================
//
// CCMD showpop
@ -1344,6 +1461,32 @@ CCMD (showpop)
{
popnum = 0;
}
StatusBar->ShowPop (popnum);
StatusBar->CallShowPop (popnum);
}
}
DEFINE_FIELD(DBaseStatusBar, ST_X);
DEFINE_FIELD(DBaseStatusBar, ST_Y);
DEFINE_FIELD(DBaseStatusBar, RelTop);
DEFINE_FIELD(DBaseStatusBar, HorizontalResolution);
DEFINE_FIELD(DBaseStatusBar, VerticalResolution);
DEFINE_FIELD(DBaseStatusBar, Scaled);
DEFINE_FIELD(DBaseStatusBar, Centering);
DEFINE_FIELD(DBaseStatusBar, FixedOrigin);
DEFINE_FIELD(DBaseStatusBar, CompleteBorder);
DEFINE_FIELD(DBaseStatusBar, CrosshairSize);
DEFINE_FIELD(DBaseStatusBar, Displacement);
DEFINE_FIELD(DBaseStatusBar, CPlayer);
DEFINE_GLOBAL(StatusBar);
DBaseStatusBar *CreateStrifeStatusBar()
{
auto sb = (DBaseStatusBar *)PClass::FindClass("StrifeStatusBar")->CreateNew();
IFVIRTUALPTR(sb, DBaseStatusBar, Init)
{
VMValue params[] = { sb };
GlobalVMStack.Call(func, params, 1, nullptr, 0);
}
return sb;
}

File diff suppressed because it is too large Load diff

View file

@ -77,7 +77,6 @@ CVAR(Bool, vid_hwaalines, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CUSTOM_CVAR(Bool, vid_hw2d, true, CVAR_NOINITCALL)
{
V_SetBorderNeedRefresh();
ST_SetNeedRefresh();
}
#else
EXTERN_CVAR(Bool, vid_hwaalines)

View file

@ -109,7 +109,6 @@ void cht_DoCheat (player_t *player, int cheat)
msg = GStrings("STSTR_DQDON");
else
msg = GStrings("STSTR_DQDOFF");
ST_SetNeedRefresh();
break;
case CHT_BUDDHA:
@ -126,7 +125,6 @@ void cht_DoCheat (player_t *player, int cheat)
msg = GStrings("STSTR_DQD2ON");
else
msg = GStrings("STSTR_DQD2OFF");
ST_SetNeedRefresh();
break;
case CHT_BUDDHA2:

View file

@ -118,7 +118,7 @@ CUSTOM_CVAR (Bool, vid_tft, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
setsizeneeded = true;
if (StatusBar != NULL)
{
StatusBar->ScreenSizeChanged();
StatusBar->CallScreenSizeChanged();
}
}

View file

@ -5584,7 +5584,7 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags)
if (StatusBar != NULL && (playernum == consoleplayer || StatusBar->GetPlayer() == playernum))
{
StatusBar->AttachToPlayer (p);
StatusBar->CallAttachToPlayer (p);
}
if (multiplayer)
@ -7740,7 +7740,7 @@ const char *AActor::GetTag(const char *def) const
DEFINE_ACTION_FUNCTION(AActor, GetTag)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_STRING(def);
PARAM_STRING_DEF(def);
ACTION_RETURN_STRING(self->GetTag(def.Len() == 0? nullptr : def.GetChars()));
}

View file

@ -128,7 +128,7 @@ void P_Ticker (void)
// [ZZ] call the WorldTick hook
E_WorldTick();
StatusBar->Tick (); // [RH] moved this here
StatusBar->CallTick (); // [RH] moved this here
level.Tick (); // [RH] let the level tick
DThinker::RunThinkers ();

View file

@ -942,7 +942,7 @@ void NullParam(const char *varname);
#define PARAM_COLOR_DEF_AT(p,x) PalEntry x; if (PARAM_EXISTS(p)) { ASSERTINT(param[p]); x = param[p].i; } else { ASSERTINT(defaultparam[p]); x = defaultparam[p].i; }
#define PARAM_FLOAT_DEF_AT(p,x) double x; if (PARAM_EXISTS(p)) { ASSERTFLOAT(param[p]); x = param[p].f; } else { ASSERTFLOAT(defaultparam[p]); x = defaultparam[p].f; }
#define PARAM_ANGLE_DEF_AT(p,x) DAngle x; if (PARAM_EXISTS(p)) { ASSERTFLOAT(param[p]); x = param[p].f; } else { ASSERTFLOAT(defaultparam[p]); x = defaultparam[p].f; }
#define PARAM_STRING_DEF_AT(p,x) FString x; if (PARAM_EXISTS(p)) { ASSERTSTRING(param[p]); x = param[p].s; } else { ASSERTSTRING(defaultparam[p]); x = defaultparam[p].s; }
#define PARAM_STRING_DEF_AT(p,x) FString x; if (PARAM_EXISTS(p)) { ASSERTSTRING(param[p]); x = param[p].s(); } else { ASSERTSTRING(defaultparam[p]); x = defaultparam[p].s(); }
#define PARAM_STATE_DEF_AT(p,x) FState *x; if (PARAM_EXISTS(p)) { ASSERTINT(param[p]); x = (FState*)StateLabels.GetState(param[p].i, self->GetClass()); } else { ASSERTINT(defaultparam[p]); x = (FState*)StateLabels.GetState(defaultparam[p].i, self->GetClass()); }
#define PARAM_STATE_ACTION_DEF_AT(p,x) FState *x; if (PARAM_EXISTS(p)) { ASSERTINT(param[p]); x = (FState*)StateLabels.GetState(param[p].i, stateowner->GetClass()); } else { ASSERTINT(defaultparam[p]); x = (FState*)StateLabels.GetState(defaultparam[p].i, stateowner->GetClass()); }
#define PARAM_POINTER_DEF_AT(p,x,t) t *x; if (PARAM_EXISTS(p)) { ASSERTPOINTER(param[p]); x = (t*)param[p].a; } else { ASSERTPOINTER(defaultparam[p]); x = (t*)defaultparam[p].a; }

View file

@ -1213,6 +1213,9 @@ bool ZCCCompiler::CompileFields(PStruct *type, TArray<ZCC_VarDeclarator *> &Fiel
ZCC_Latent | ZCC_Final | ZCC_Action | ZCC_Static | ZCC_FuncConst | ZCC_Abstract | ZCC_Virtual | ZCC_Override | ZCC_Meta | ZCC_Extension | ZCC_VirtualScope | ZCC_ClearScope :
ZCC_Latent | ZCC_Final | ZCC_Action | ZCC_Static | ZCC_FuncConst | ZCC_Abstract | ZCC_Virtual | ZCC_Override | ZCC_Extension | ZCC_VirtualScope | ZCC_ClearScope;
// Some internal fields need to be set to clearscope.
if (Wads.GetLumpFile(Lump) == 0) notallowed &= ~ZCC_ClearScope;
if (field->Flags & notallowed)
{
Error(field, "Invalid qualifiers for %s (%s not allowed)", FName(field->Names->Name).GetChars(), FlagsToString(field->Flags & notallowed).GetChars());

View file

@ -85,7 +85,6 @@ void FStat::ToggleStat (const char *name)
void FStat::ToggleStat ()
{
m_Active = !m_Active;
ST_SetNeedRefresh();
}
void FStat::PrintStat ()
@ -113,10 +112,6 @@ void FStat::PrintStat ()
}
}
}
if (count)
{
ST_SetNeedRefresh();
}
}
void FStat::DumpRegisteredStats ()

View file

@ -67,7 +67,7 @@ CUSTOM_CVAR(Int, uiscale, 2, CVAR_ARCHIVE | CVAR_NOINITCALL)
{
if (StatusBar != NULL)
{
StatusBar->ScreenSizeChanged();
StatusBar->CallScreenSizeChanged();
}
}
@ -1169,13 +1169,6 @@ int BorderNeedRefresh;
static void V_DrawViewBorder (void)
{
// [RH] Redraw the status bar if SCREENWIDTH > status bar width.
// Will draw borders around itself, too.
if (SCREENWIDTH > 320)
{
ST_SetNeedRefresh();
}
if (viewwidth == SCREENWIDTH)
{
return;

View file

@ -1384,7 +1384,7 @@ void V_OutputResized (int width, int height)
setsizeneeded = true;
if (StatusBar != NULL)
{
StatusBar->ScreenSizeChanged();
StatusBar->CallScreenSizeChanged();
}
C_NewModeAdjust();
}
@ -1634,7 +1634,7 @@ CUSTOM_CVAR (Bool, vid_nowidescreen, false, CVAR_GLOBALCONFIG|CVAR_ARCHIVE)
setsizeneeded = true;
if (StatusBar != NULL)
{
StatusBar->ScreenSizeChanged();
StatusBar->CallScreenSizeChanged();
}
}
@ -1643,7 +1643,7 @@ CUSTOM_CVAR (Int, vid_aspect, 0, CVAR_GLOBALCONFIG|CVAR_ARCHIVE)
setsizeneeded = true;
if (StatusBar != NULL)
{
StatusBar->ScreenSizeChanged();
StatusBar->CallScreenSizeChanged();
}
}

View file

@ -228,7 +228,6 @@ const char *const D3DFB::ShaderNames[D3DFB::NUM_SHADERS] =
CUSTOM_CVAR(Bool, vid_hw2d, true, CVAR_NOINITCALL)
{
V_SetBorderNeedRefresh();
ST_SetNeedRefresh();
}
CVAR(Bool, d3d_antilag, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)

View file

@ -32,6 +32,9 @@ version "2.5"
#include "zscript/statscreen/statscreen_dm.txt"
#include "zscript/statscreen/statscreen_coop.txt"
#include "zscript/statusbar/statusbar.txt"
#include "zscript/statusbar/strife_sbar.txt"
#include "zscript/inventory/inventory.txt"
#include "zscript/inventory/inv_misc.txt"
#include "zscript/inventory/stateprovider.txt"

View file

@ -39,6 +39,7 @@ struct _ native // These are the global variables, the struct is only here to av
native ui int BackbuttonTime;
native ui float BackbuttonAlpha;
native readonly int Net_Arbitrator;
native ui BaseStatusBar StatusBar;
}
@ -379,10 +380,10 @@ class Thinker : Object native play
virtual native void PostBeginPlay();
virtual native void ChangeStatNum(int stat);
static int Tics2Seconds(int tics)
static clearscope int Tics2Seconds(int tics)
{
// This compensates for one tic being slightly less than 1/35 of a second.
return int(tics * (0.98 * TICRATE));
return int(tics * (0.98 / TICRATE));
}
}

View file

@ -31,10 +31,3 @@ extend class StateProvider
A_FireProjectile(missiletype, angle, useammo, spawnofs_xy, spawnheight, flags, -pitch);
}
}
// this is just a placeholder until the statusbar gets properly exported.
struct StatusBar native
{
native static void ReceivedWeapon(Weapon weap);
}

View file

@ -855,6 +855,25 @@ class Inventory : Actor native
return false;
}
//===========================================================================
//
// AInventory :: NextInv
//
// Returns the next item with IF_INVBAR set.
//
//===========================================================================
clearscope Inventory NextInv () const
{
Inventory item = Inv;
while (item != NULL && !item.bInvBar)
{
item = item.Inv;
}
return item;
}
}

View file

@ -7,8 +7,8 @@ class PlayerPawn : Actor native
native int MugShotMaxHealth;
native int RunHealth;
native int PlayerFlags;
native Inventory InvFirst; // first inventory item displayed on inventory bar
native Inventory InvSel; // selected inventory item
native clearscope Inventory InvFirst; // first inventory item displayed on inventory bar
native clearscope Inventory InvSel; // selected inventory item
native Name SoundClass; // Sound class
native Name Face; // Doom status bar face (when used)
native Name Portrait;
@ -179,7 +179,7 @@ class PlayerPawn : Actor native
}
return -1, -1;
}
native clearscope int GetMaxHealth(bool withupgrades = false) const;
native bool ResetAirSupply (bool playgasp = false);
native void CheckWeaponSwitch(class<Inventory> item);
@ -276,7 +276,7 @@ struct PlayerInfo native play // this is what internally is known as player_t
native bool usedown;
native uint oldbuttons;
native int health;
native int inventorytics;
native clearscope int inventorytics;
native uint8 CurrentPlayerClass;
native int frags[MAXPLAYERS];
native int fragcount;

View file

@ -0,0 +1,79 @@
class BaseStatusBar native ui
{
enum EPop
{
POP_NoChange = -1,
POP_None,
POP_Log,
POP_Keys,
POP_Status
}
// Status face stuff
enum EMug
{
ST_NUMPAINFACES = 5,
ST_NUMSTRAIGHTFACES = 3,
ST_NUMTURNFACES = 2,
ST_NUMSPECIALFACES = 3,
ST_NUMEXTRAFACES = 2,
ST_FACESTRIDE = ST_NUMSTRAIGHTFACES+ST_NUMTURNFACES+ST_NUMSPECIALFACES,
ST_NUMFACES = ST_FACESTRIDE*ST_NUMPAINFACES+ST_NUMEXTRAFACES,
ST_TURNOFFSET = ST_NUMSTRAIGHTFACES,
ST_OUCHOFFSET = ST_TURNOFFSET + ST_NUMTURNFACES,
ST_EVILGRINOFFSET = ST_OUCHOFFSET + 1,
ST_RAMPAGEOFFSET = ST_EVILGRINOFFSET + 1,
ST_GODFACE = ST_NUMPAINFACES*ST_FACESTRIDE,
ST_DEADFACE = ST_GODFACE + 1
}
enum EHudState
{
HUD_StatusBar,
HUD_Fullscreen,
HUD_None,
HUD_AltHud // Used for passing through popups to the alt hud
}
enum EHudDraw
{
HUD_Normal,
HUD_HorizCenter
}
const XHAIRSHRINKSIZE =(1./18);
const XHAIRPICKUPSIZE = (2+XHAIRSHRINKSIZE);
native int ST_X, ST_Y;
native int RelTop;
native int HorizontalResolution, VerticalResolution;
native bool Scaled;
native bool Centering;
native bool FixedOrigin;
native bool CompleteBorder;
native double CrosshairSize;
native double Displacement;
native PlayerInfo CPlayer;
virtual void Init() {}
native virtual void SetScaled(bool scale, bool force = false);
native virtual void Tick ();
native virtual void Draw (int state, double TicFrac);
virtual void FlashItem (class<Inventory> itemtype) {}
native virtual void AttachToPlayer (PlayerInfo player);
virtual void FlashCrosshair () { CrosshairSize = XHAIRPICKUPSIZE; }
virtual void NewGame () {}
native virtual void ScreenSizeChanged ();
native virtual void ShowPop (int popnum);
native virtual clearscope void ReceivedWeapon (Weapon weapn);
virtual bool MustDrawLog(int state) { return true; }
// native virtual void SetMugShotState (String state_name, bool wait_till_done=false, bool reset=false); later - at the moment the backing code is not accessible from the script side.
native void RefreshBackground () const;
native Inventory, Inventory, int, int GetCurrentAmmo () const;
native Inventory ValidateInvFirst (int numVisible) const;
}

View file

@ -0,0 +1,854 @@
class StrifeStatusBar : BaseStatusBar
{
// Number of tics to move the popscreen up and down.
const POP_TIME = (Thinker.TICRATE/8);
// Popscreen height when fully extended
const POP_HEIGHT = 104;
// Number of tics to scroll keys left
const KEY_TIME = (Thinker.TICRATE/3);
enum eImg
{
imgINVCURS,
imgCURSOR01,
imgINVBACK,
imgINVTOP,
imgINVPOP,
imgINVPOP2,
imgINVPBAK,
imgINVPBAK2,
imgFONG0,
imgFONG1,
imgFONG2,
imgFONG3,
imgFONG4,
imgFONG5,
imgFONG6,
imgFONG7,
imgFONG8,
imgFONG9,
imgFONG_PERCENT,
imgFONY0,
imgFONY1,
imgFONY2,
imgFONY3,
imgFONY4,
imgFONY5,
imgFONY6,
imgFONY7,
imgFONY8,
imgFONY9,
imgFONY_PERCENT,
imgCOMM,
imgMEDI,
imgARM1,
imgARM2,
imgNEGATIVE,
imgINumbers = imgFONG0,
};
TextureID Images[imgNEGATIVE + 1];
int CursorImage;
int CurrentPop, PendingPop, PopHeight, PopHeightChange;
int KeyPopPos, KeyPopScroll;
double ItemFlash;
override void Init()
{
DoCommonInit();
}
override void NewGame ()
{
DoCommonInit ();
if (CPlayer != NULL)
{
AttachToPlayer (CPlayer);
}
}
override void Draw (int state, double TicFrac)
{
Super.Draw (state, TicFrac);
if (state == HUD_StatusBar)
{
DrawMainBar (TicFrac);
}
else
{
if (state == HUD_Fullscreen)
{
DrawFullScreenStuff ();
}
// Draw pop screen (log, keys, and status)
if (CurrentPop != POP_None && PopHeight < 0)
{
DrawPopScreen (screen.GetHeight(), TicFrac);
}
}
}
override void ShowPop (int popnum)
{
Super.ShowPop(popnum);
if (popnum == CurrentPop)
{
if (popnum == POP_Keys)
{
Inventory item;
KeyPopPos += 10;
KeyPopScroll = 280;
int i = 0;
for (item = CPlayer.mo.Inv; item != NULL; item = item.Inv)
{
if (item is "Key")
{
if (i == KeyPopPos)
{
return;
}
i++;
}
}
}
PendingPop = POP_None;
// Do not scroll keys horizontally when dropping the popscreen
KeyPopScroll = 0;
KeyPopPos -= 10;
}
else
{
KeyPopPos = 0;
PendingPop = popnum;
}
}
override bool MustDrawLog(int state)
{
// Tell the base class to draw the log if the pop screen won't be displayed.
return false;
}
void DoCommonInit ()
{
static const String strifeLumpNames[] =
{
"INVCURS", "CURSOR01", "INVBACK", "INVTOP", "INVPOP", "INVPOP2",
"INVPBAK", "INVPBAK2",
"INVFONG0", "INVFONG1", "INVFONG2", "INVFONG3", "INVFONG4",
"INVFONG5", "INVFONG6", "INVFONG7", "INVFONG8", "INVFONG9",
"INVFONG%",
"INVFONY0", "INVFONY1", "INVFONY2", "INVFONY3", "INVFONY4",
"INVFONY5", "INVFONY6", "INVFONY7", "INVFONY8", "INVFONY9",
"INVFONY%",
"I_COMM", "I_MDKT", "I_ARM1", "I_ARM2", ""
};
for(int i = 0; i <= imgNEGATIVE; i++)
{
Images[i] = TexMan.CheckForTexture(strifeLumpNames[i], TexMan.TYPE_MiscPatch);
}
CursorImage = Images[imgINVCURS].IsValid() ? imgINVCURS : imgCURSOR01;
CurrentPop = POP_None;
PendingPop = POP_NoChange;
PopHeight = 0;
KeyPopPos = 0;
KeyPopScroll = 0;
ItemFlash = 0;
}
override void Tick ()
{
Super.Tick ();
if (ItemFlash > 0)
{
ItemFlash -= 1/14.;
if (ItemFlash < 0)
{
ItemFlash = 0;
}
}
PopHeightChange = 0;
if (PendingPop != POP_NoChange)
{
if (PopHeight < 0)
{
PopHeightChange = POP_HEIGHT / POP_TIME;
PopHeight += POP_HEIGHT / POP_TIME;
}
else
{
CurrentPop = PendingPop;
PendingPop = POP_NoChange;
}
}
else
{
if (CurrentPop == POP_None)
{
PopHeight = 0;
}
else if (PopHeight > -POP_HEIGHT)
{
PopHeight -= POP_HEIGHT / POP_TIME;
if (PopHeight < -POP_HEIGHT)
{
PopHeight = -POP_HEIGHT;
}
else
{
PopHeightChange = -POP_HEIGHT / POP_TIME;
}
}
if (KeyPopScroll > 0)
{
KeyPopScroll -= 280 / KEY_TIME;
if (KeyPopScroll < 0)
{
KeyPopScroll = 0;
}
}
}
}
override void FlashItem (Class<Inventory> itemtype)
{
ItemFlash = 0.75;
}
private void FillBar(int x, int y, int start, int stopp, Color color1, Color color2)
{
// right now there is no function to draw this.
// The old code used a crude texture hack to work arounf this omission.
}
protected void DrawHealthBar(int health, int x, int y)
{
Color green1 = Color(180, 228, 128); // light green
Color green2 = Color(128, 180, 80); // dark green
Color blue1 = Color(196, 204, 252); // light blue
Color blue2 = Color(148, 152, 200); // dark blue
Color gold1 = Color(224, 188, 0); // light gold
Color gold2 = Color(208, 128, 0); // dark gold
Color red1 = Color(216, 44, 44); // light red
Color red2 = Color(172, 28, 28); // dark red
if (health == 999)
{
FillBar (x, y, 0, 200, gold1, gold2);
}
else
{
if (health <= 100)
{
if (health <= 10)
{
FillBar (x, y, 0, health*2, red1, red2);
}
else if (health <= 20)
{
FillBar (x, y, 0, health*2, gold1, gold2);
}
else
{
FillBar (x, y, 0, health, green1, green2);
}
FillBar (x, y, health, 200, 0, 0);
}
else
{
int stopp = 100 - (health - 100);
FillBar (x, y, 0, stopp*2, green1, green2);
FillBar (x, y, stopp*2, 200, blue1, blue2);
}
}
}
protected void DrawMainBar (double TicFrac)
{
Inventory item;
int i;
// Pop screen (log, keys, and status)
if (CurrentPop != POP_None && PopHeight < 0)
{
DrawPopScreen (Scaled ? (ST_Y - 8) * screen.GetHeight() / 200 : ST_Y - 8, TicFrac);
}
DrawImage (Images[imgINVBACK], 0, 0);
DrawImage (Images[imgINVTOP], 0, -8);
// Health
DrINumber (CPlayer.health, 79, -6, imgFONG0);
int points;
if (CPlayer.cheats & CF_GODMODE)
{
points = 999;
}
else
{
points = min(CPlayer.health, 200);
}
DrawHealthBar (points, 49, 4);
DrawHealthBar (points, 49, 7);
// Armor
item = CPlayer.mo.FindInventory('BasicArmor');
if (item != NULL && item.Amount > 0)
{
DrawImage (item.Icon, 2, 9);
DrINumber (item.Amount, 27, 23, imgFONY0);
}
// Ammo
Inventory ammo1, ammo2;
int ammocount1, ammocount2;
[ammo1, ammo2, ammocount1, ammocount2] = GetCurrentAmmo ();
if (ammo1 != NULL)
{
DrINumber (ammo1.Amount, 311, -6, imgFONG0);
DrawImage (ammo1.Icon, 290, 13);
}
// Sigil
item = CPlayer.mo.FindInventory('Sigil');
if (item != NULL)
{
DrawImage (item.Icon, 253, 7);
}
// Inventory
CPlayer.inventorytics = 0;
CPlayer.mo.InvFirst = ValidateInvFirst (6);
i = 0;
for (item = CPlayer.mo.InvFirst; item != NULL && i < 6; item = item.NextInv())
{
if (item == CPlayer.mo.InvSel)
{
screen.DrawTexture (Images[CursorImage], true,
42 + 35*i + ST_X, 12 + ST_Y,
DTA_Bottom320x200, Scaled,
DTA_Alpha, 1. - ItemFlash);
}
if (item.Icon.isValid())
{
DrawDimImage (item.Icon, 48 + 35*i, 14, item.Amount <= 0);
}
DrINumber (item.Amount, 74 + 35*i, 23, imgFONY0);
i++;
}
}
protected void DrawFullScreenStuff ()
{
// Draw health
DrINumberOuter (CPlayer.health, 4, -10, false, 7);
screen.DrawTexture (Images[imgMEDI], true, 14, -17,
DTA_HUDRules, HUD_Normal,
DTA_CenterBottomOffset, true);
// 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);
}
// Draw ammo
Inventory ammo1, ammo2;
int ammocount1, ammocount2;
[ammo1, ammo2, ammocount1, ammocount2] = GetCurrentAmmo ();
if (ammo1 != NULL)
{
// 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);
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);
}
}
if (deathmatch)
{ // Draw frags (in DM)
DrBNumberOuterFont (CPlayer.fragcount, -44, 1);
}
// Draw inventory
if (CPlayer.inventorytics == 0)
{
if (CPlayer.mo.InvSel != null)
{
if (ItemFlash > 0)
{
vector2 size = TexMan.GetScaledSize(Images[CursorImage]);
screen.DrawTexture (Images[CursorImage], true, -28, -15,
DTA_HUDRules, HUD_Normal,
DTA_LeftOffsetF, size.X,
DTA_TopOffsetF, size.Y,
DTA_Alpha, ItemFlash);
}
DrINumberOuter (CPlayer.mo.InvSel.Amount, -51, -10, false, 7);
screen.DrawTexture (CPlayer.mo.InvSel.Icon, true, -42, -17,
DTA_HUDRules, HUD_Normal,
DTA_CenterBottomOffset, true,
DTA_ColorOverlay, CPlayer.mo.InvSel.Amount > 0 ? 0 : Color(170, 0, 0, 0));
}
}
else
{
CPlayer.mo.InvFirst = ValidateInvFirst (6);
int i = 0;
Inventory item;
if (CPlayer.mo.InvFirst != NULL)
{
for (item = CPlayer.mo.InvFirst; item != NULL && i < 6; item = item.NextInv())
{
if (item == CPlayer.mo.InvSel)
{
screen.DrawTexture (Images[CursorImage], true, -100+i*35, -21,
DTA_HUDRules, HUD_HorizCenter,
DTA_Alpha, 0.75);
}
if (item.Icon.isValid())
{
screen.DrawTexture (item.Icon, true, -94 + i*35, -19,
DTA_HUDRules, HUD_HorizCenter,
DTA_ColorOverlay, CPlayer.mo.InvSel.Amount > 0 ? 0 : Color(170, 0, 0, 0));
}
DrINumberOuter (item.Amount, -89 + i*35, -10, true, 7);
++i;
}
}
}
}
protected void DrawPopScreen (int bottom, double TicFrac)
{
String buff;
String label;
int i;
Inventory item;
int xscale, yscale, left, top;
int bars = (CurrentPop == POP_Status) ? imgINVPOP : imgINVPOP2;
int back = (CurrentPop == POP_Status) ? imgINVPBAK : imgINVPBAK2;
// Extrapolate the height of the popscreen for smoother movement
int height = clamp (PopHeight + int(TicFrac * PopHeightChange), -POP_HEIGHT, 0);
xscale = CleanXfac;
yscale = CleanYfac;
left = screen.GetWidth()/2 - 160*CleanXfac;
top = bottom + height * yscale;
screen.DrawTexture (Images[back], true, left, top, DTA_CleanNoMove, true, DTA_Alpha, 0.75);
screen.DrawTexture (Images[bars], true, left, top, DTA_CleanNoMove, true);
switch (CurrentPop)
{
case POP_Log:
{
int seconds = Thinker.Tics2Seconds(level.time);
// Draw the latest log message.
buff = String.Format("%02d:%02d:%02d",
seconds / 3600,
(seconds % 3600) / 60,
(seconds) % 60);
screen.DrawText(SmallFont2, Font.CR_UNTRANSLATED, left + 210 * xscale, top + 8 * yscale, buff,
DTA_CleanNoMove, true);
if (CPlayer.LogText.Length() > 0)
{
BrokenLines lines = SmallFont2.BreakLines(CPlayer.LogText, 272);
for (i = 0; i < lines.Count(); ++i)
{
screen.DrawText(SmallFont2, Font.CR_UNTRANSLATED, left + 24 * xscale, top + (18 + i * 12)*yscale,
lines.StringAt(i), DTA_CleanNoMove, true);
}
}
break;
}
case POP_Keys:
// List the keys the player has.
int pos, endpos, leftcol;
int clipleft, clipright;
pos = KeyPopPos;
endpos = pos + 10;
leftcol = 20;
clipleft = left + 17*xscale;
clipright = left + (320-17)*xscale;
if (KeyPopScroll > 0)
{
// Extrapolate the scroll position for smoother scrolling
int scroll = MAX (0, KeyPopScroll - int(TicFrac * (280./KEY_TIME)));
pos -= 10;
leftcol = leftcol - 280 + scroll;
}
i = 0;
for (item = CPlayer.mo.Inv; i < endpos && item != NULL; item = item.Inv)
{
if (!(item is "Key"))
continue;
if (i < pos)
{
i++;
continue;
}
label = item.GetTag();
int colnum = ((i-pos) / 5) & (KeyPopScroll > 0 ? 3 : 1);
int rownum = (i % 5) * 18;
screen.DrawTexture (item.Icon, true,
left + (colnum * 140 + leftcol)*xscale,
top + (6 + rownum)*yscale,
DTA_CleanNoMove, true,
DTA_ClipLeft, clipleft,
DTA_ClipRight, clipright);
screen.DrawText (SmallFont2, Font.CR_UNTRANSLATED,
left + (colnum * 140 + leftcol + 17)*xscale,
top + (11 + rownum)*yscale,
label,
DTA_CleanNoMove, true,
DTA_ClipLeft, clipleft,
DTA_ClipRight, clipright);
i++;
}
break;
case POP_Status:
// Show miscellaneous status items.
// Print stats
DrINumber2 (CPlayer.mo.accuracy, left+268*xscale, top+28*yscale, 7*xscale, imgFONY0);
DrINumber2 (CPlayer.mo.stamina, left+268*xscale, top+52*yscale, 7*xscale, imgFONY0);
// How many keys does the player have?
i = 0;
for (item = CPlayer.mo.Inv; item != NULL; item = item.Inv)
{
if (item is "Key")
{
i++;
}
}
DrINumber2 (i, left+268*xscale, top+76*yscale, 7*xscale, imgFONY0);
// Does the player have a communicator?
item = CPlayer.mo.FindInventory ("Communicator");
if (item != NULL)
{
screen.DrawTexture (item.Icon, true,
left + 280*xscale,
top + 74*yscale,
DTA_CleanNoMove, true);
}
// How much ammo does the player have?
static const class<Ammo> AmmoList[] = {
"ClipOfBullets",
"PoisonBolts",
"ElectricBolts",
"HEGrenadeRounds",
"PhosphorusGrenadeRounds",
"MiniMissiles",
"EnergyPod"};
static const int AmmoY[] = {19, 35, 43, 59, 67, 75, 83};
for (i = 0; i < 7; ++i)
{
item = CPlayer.mo.FindInventory (AmmoList[i]);
if (item == NULL)
{
DrINumber2 (0, left+206*xscale, top+AmmoY[i] * yscale, 7*xscale, imgFONY0);
DrINumber2 (GetDefaultByType(AmmoList[i]).MaxAmount, left+239*xscale, top+AmmoY[i] * yscale, 7*xscale, imgFONY0);
}
else
{
DrINumber2 (item.Amount, left+206*xscale, top+AmmoY[i] * yscale, 7*xscale, imgFONY0);
DrINumber2 (item.MaxAmount, left+239*xscale, top+AmmoY[i] * yscale, 7*xscale, imgFONY0);
}
}
// What weapons does the player have?
static const class<Weapon> WeaponList[] =
{
"StrifeCrossbow",
"AssaultGun",
"FlameThrower",
"MiniMissileLauncher",
"StrifeGrenadeLauncher",
"Mauler"
};
static const int WeaponX[] = {23, 21, 57, 20, 55, 52};
static const int WeaponY[] = {19, 41, 50, 64, 20, 75};
for (i = 0; i < 6; ++i)
{
item = CPlayer.mo.FindInventory (WeaponList[i]);
if (item != NULL)
{
screen.DrawTexture (item.Icon, true,
left + WeaponX[i] * xscale,
top + WeaponY[i] * yscale,
DTA_CleanNoMove, true,
DTA_LeftOffset, 0,
DTA_TopOffset, 0);
}
}
break;
}
}
void DrINumber (int val, int x, int y, int imgBase) const
{
x -= 7;
if (val == 0)
{
DrawImage (Images[imgBase], x, y);
}
else
{
while (val != 0)
{
DrawImage (Images[imgBase+val%10], x, y);
val /= 10;
x -= 7;
}
}
}
void DrINumber2 (int val, int x, int y, int width, int imgBase) const
{
x -= width;
if (val == 0)
{
screen.DrawTexture (Images[imgBase], true, x, y, DTA_CleanNoMove, true);
}
else
{
while (val != 0)
{
screen.DrawTexture (Images[imgBase+val%10], true, x, y, DTA_CleanNoMove, true);
val /= 10;
x -= width;
}
}
}
//---------------------------------------------------------------------------
//
// PROC DrINumberOuter
//
// Draws a number outside the status bar, possibly scaled.
//
//---------------------------------------------------------------------------
void DrINumberOuter(int val, int x, int y, bool center, int w) const
{
bool negative = false;
x += w * 2;
if (val < 0)
{
negative = true;
val = -val;
}
else if (val == 0)
{
screen.DrawTexture(Images[imgINumbers], true, x + 1, y + 1,
DTA_FillColor, 0, DTA_Alpha, HR_SHADOW,
DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal);
screen.DrawTexture(Images[imgINumbers], true, x, y,
DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal);
return;
}
int oval = val;
int ox = x;
// First the shadow
while (val != 0)
{
screen.DrawTexture(Images[imgINumbers + val % 10], true, x + 1, y + 1,
DTA_FillColor, 0, DTA_Alpha, HR_SHADOW,
DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal);
x -= w;
val /= 10;
}
if (negative)
{
screen.DrawTexture(Images[imgNEGATIVE], true, x + 1, y + 1,
DTA_FillColor, 0, DTA_Alpha, HR_SHADOW,
DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal);
}
// Then the real deal
val = oval;
x = ox;
while (val != 0)
{
screen.DrawTexture(Images[imgINumbers + val % 10], true, x, y,
DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal);
x -= w;
val /= 10;
}
if (negative)
{
screen.DrawTexture(Images[imgNEGATIVE], true, x, y,
DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal);
}
}
//---------------------------------------------------------------------------
//
// PROC DrBNumberOuter
//
// Draws a three digit number using the real big font outside the status bar.
//
//---------------------------------------------------------------------------
void DrBNumberOuterFont(int val, int x, int y, int size = 3) const
{
int v;
bool negative = false;
TextureID pic;
int w = BigFont.GetCharWidth("0");
int ww = w;
if (w > 1)
{
w--;
}
int xpos = x + w / 2 + (size - 1)*w;
if (val == 0)
{
screen.DrawChar(BigFont, Font.CR_UNTRANSLATED, xpos - v / 2 + 2, y + 2, "0",
DTA_HUDRules, HUD_Normal,
DTA_Alpha, HR_SHADOW,
DTA_FillColor, 0);
screen.DrawChar(BigFont, Font.CR_UNTRANSLATED, xpos - v / 2, y, "0",
DTA_HUDRules, HUD_Normal);
return;
}
else if (val < 0)
{
negative = true;
val = -val;
}
int oval = val;
int oxpos = xpos;
// First the shadow
while (val != 0)
{
v = BigFont.GetCharWidth(int("0") + val % 10);
screen.DrawChar(BigFont, Font.CR_UNTRANSLATED, xpos - v / 2 + 2, y + 2,
DTA_HUDRules, HUD_Normal,
DTA_Alpha, HR_SHADOW,
DTA_FillColor, 0);
val /= 10;
xpos -= w;
}
if (negative)
{
v = BigFont.GetCharWidth("-");
screen.DrawChar(BigFont, Font.CR_UNTRANSLATED, xpos - v / 2 + 2, y + 2, "-",
DTA_HUDRules, HUD_Normal,
DTA_Alpha, HR_SHADOW,
DTA_FillColor, 0);
}
// Then the foreground number
val = oval;
xpos = oxpos;
while (val != 0)
{
v = BigFont.GetCharWidth(int("0") + val % 10);
screen.DrawChar(BigFont, Font.CR_UNTRANSLATED, xpos - v / 2, y, "0", DTA_HUDRules, HUD_Normal);
val /= 10;
xpos -= w;
}
if (negative)
{
v = BigFont.GetCharWidth("-");
screen.DrawChar(BigFont, Font.CR_UNTRANSLATED, xpos - v / 2, y, "-", DTA_HUDRules, HUD_Normal);
}
}
//---------------------------------------------------------------------------
//
// PROC DrawImage
//
// Draws an image with the status bar's upper-left corner as the origin.
//
//---------------------------------------------------------------------------
void DrawImage(TextureID img, int x, int y) const
{
if (img.IsValid())
{
screen.DrawTexture(img, true, x + ST_X, y + ST_Y, DTA_Bottom320x200, Scaled);
}
}
//---------------------------------------------------------------------------
//
// PROC DrawImage
//
// Draws an optionally dimmed image with the status bar's upper-left corner
// as the origin.
//
//---------------------------------------------------------------------------
void DrawDimImage(TextureID img, int x, int y, bool dimmed) const
{
if (img.IsValid())
{
screen.DrawTexture(img, true, x + ST_X, y + ST_Y, DTA_ColorOverlay, dimmed ? Color(170, 0, 0, 0) : 0, DTA_Bottom320x200, Scaled);
}
}
}