mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-14 08:30:35 +00:00
- ported Exhumed's status bar.
Not tested yet.
This commit is contained in:
parent
5a6121d424
commit
b71c725e3e
11 changed files with 997 additions and 30 deletions
|
@ -829,10 +829,10 @@ void CreateStatusBar()
|
|||
StatusBar->SetSize(0, 320, 200);
|
||||
InitStatusBar();
|
||||
// this is for comparing the scriptification with the C++ versions
|
||||
//stbarclass = PClass::FindClass("NativeBloodStatusBar");
|
||||
//StatusBar2 = static_cast<DBaseStatusBar*>(stbarclass->CreateNew());
|
||||
//StatusBar2->SetSize(0, 320, 200);
|
||||
//StatusBar2->Release();
|
||||
stbarclass = PClass::FindClass("NativeExhumedStatusBar");
|
||||
StatusBar2 = static_cast<DBaseStatusBar*>(stbarclass->CreateNew());
|
||||
StatusBar2->SetSize(0, 320, 200);
|
||||
StatusBar2->Release();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -203,17 +203,17 @@ static void cmd_Give(int player, uint8_t** stream, bool skip)
|
|||
if (buttons & kButtonCheatGuns) // LOBOCOP cheat
|
||||
{
|
||||
FillWeapons(player);
|
||||
if (player == myconnectindex) StatusMessage(150, GStrings("TXT_EX_WEAPONS"));
|
||||
if (player == myconnectindex) Printf(PRINT_NOTIFY, "%s\n", GStrings("TXT_EX_WEAPONS"));
|
||||
}
|
||||
if (buttons & kButtonCheatKeys) // LOBOPICK cheat
|
||||
{
|
||||
PlayerList[player].keys = 0xFFFF;
|
||||
if (player == myconnectindex) StatusMessage(150, GStrings("TXT_EX_KEYS"));
|
||||
if (player == myconnectindex) Printf(PRINT_NOTIFY, "%s\n", GStrings("TXT_EX_KEYS"));
|
||||
}
|
||||
if (buttons & kButtonCheatItems) // LOBOSWAG cheat
|
||||
{
|
||||
FillItems(player);
|
||||
if (player == myconnectindex) StatusMessage(150, GStrings("TXT_EX_ITEMS"));
|
||||
if (player == myconnectindex) Printf(PRINT_NOTIFY, "%s\n", GStrings("TXT_EX_ITEMS"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
x(Torch1, 338)
|
||||
x(Torch2, 350)
|
||||
x(TileRamsesGold, 590)
|
||||
x(TileRamsesWorkTile, 591)
|
||||
x(TileRamsesNormal, 592)
|
||||
x(TileStatusBar, 657)
|
||||
x(KeyIcon1, 675)
|
||||
x(KeyIcon2, 679)
|
||||
x(KeyIcon3, 683)
|
||||
x(KeyIcon4, 687)
|
||||
x(CrosshairTile, 1579)
|
||||
x(SkullJaw, 3437)
|
||||
x(PowerslaveLogo, 3442)
|
||||
|
|
|
@ -20,12 +20,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
|
||||
enum
|
||||
{
|
||||
kTorch1 = 338,
|
||||
kTorch2 = 350,
|
||||
kTileRamsesGold = 590,
|
||||
kTileRamsesWorkTile = 591,
|
||||
kTileRamsesNormal = 592,
|
||||
kTileStatusBar = 657,
|
||||
kTile985 = 985,
|
||||
kTile986 = 986,
|
||||
kTile3000 = 3000,
|
||||
|
|
|
@ -2760,4 +2760,54 @@ void SerializePlayer(FSerializer& arc)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, nHealth);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, nLives);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, nDouble);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, nInvisible);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, nTorch);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, field_2);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, nAction);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, nSprite);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, bIsMummified);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, invincibility);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, nAir);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, nSeq);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, nMaskAmount);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, keys);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, nMagic);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, nItem);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, items);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, nAmmo); // TODO - kMaxWeapons?
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, pad);
|
||||
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, nCurrentWeapon);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, field_3FOUR);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, bIsFiring);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, field_38);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, field_3A);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, field_3C);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, nRun);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, bPlayerPan);
|
||||
DEFINE_FIELD_X(ExhumedPlayer, Player, bLockPan);
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Exhumed, GetViewPlayer)
|
||||
{
|
||||
ACTION_RETURN_POINTER(&PlayerList[nLocalPlayer]);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_ExhumedPlayer, IsUnderwater)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(Player);
|
||||
auto nLocalPlayer = self - PlayerList;
|
||||
ACTION_RETURN_BOOL(SectFlag[nPlayerViewSect[nLocalPlayer]] & kSectUnderwater);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_ExhumedPlayer, GetAngle)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(Player);
|
||||
ACTION_RETURN_INT(sprite[self->nSprite].ang);
|
||||
}
|
||||
|
||||
|
||||
END_PS_NS
|
||||
|
|
|
@ -65,7 +65,7 @@ struct Player
|
|||
uint16_t keys;
|
||||
short nMagic;
|
||||
short nItem;
|
||||
char items[8];
|
||||
uint8_t items[8];
|
||||
short nAmmo[7]; // TODO - kMaxWeapons?
|
||||
short pad[2];
|
||||
|
||||
|
|
|
@ -47,9 +47,77 @@ void InitStatus()
|
|||
nStatusSeqOffset = SeqOffsets[kSeqStatus];
|
||||
}
|
||||
|
||||
class DExhumedStatusBar : public DBaseStatusBar
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// This is to hide the dirt from the script code.
|
||||
// These sequence arrays later need to be refactored
|
||||
// if this is ever supposed to become a useful feature,
|
||||
// so hide the dirty internals behind a handful of functions.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
struct ChunkFrame
|
||||
{
|
||||
DECLARE_CLASS(DExhumedStatusBar, DBaseStatusBar)
|
||||
FTextureID tex;
|
||||
int x, y;
|
||||
int flags;
|
||||
|
||||
void GetChunkFrame(int nFrameBase)
|
||||
{
|
||||
x = ChunkXpos[nFrameBase];
|
||||
y = ChunkYpos[nFrameBase];
|
||||
auto ttex = tileGetTexture(nFrameBase);
|
||||
if (ttex) tex = ttex->GetID();
|
||||
else tex.SetInvalid();
|
||||
flags = ChunkFlag[nFrameBase];
|
||||
}
|
||||
};
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_ChunkFrame, GetChunkFrame)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(ChunkFrame);
|
||||
PARAM_INT(index);
|
||||
self->GetChunkFrame(index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Exhumed, GetStatusSequence)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_INT(nSequence);
|
||||
PARAM_INT(frameindex);
|
||||
|
||||
frameindex += SeqBase[nStatusSeqOffset + nSequence];
|
||||
if (numret > 0) ret[0].SetInt(FrameBase[frameindex]);
|
||||
if (numret > 1) ret[1].SetInt(FrameSize[frameindex]);
|
||||
return min(numret, 2);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Exhumed, MoveStatusSequence)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_INT(s1);
|
||||
PARAM_INT(s2);
|
||||
seq_MoveSequence(-1, nStatusSeqOffset + s1, s2);
|
||||
ACTION_RETURN_INT(SeqSize[nStatusSeqOffset + s1]);
|
||||
}
|
||||
|
||||
int SizeOfStatusSequence(int s1)
|
||||
{
|
||||
return SeqSize[nStatusSeqOffset + s1];
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(_Exhumed, SizeOfStatusSequence, SizeOfStatusSequence)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_INT(s1);
|
||||
ACTION_RETURN_INT(SeqSize[nStatusSeqOffset + s1]);
|
||||
}
|
||||
|
||||
class DNativeExhumedStatusBar : public DBaseStatusBar
|
||||
{
|
||||
DECLARE_CLASS(DNativeExhumedStatusBar, DBaseStatusBar)
|
||||
HAS_OBJECT_POINTERS
|
||||
|
||||
TObjPtr<DHUDFont*> textfont, numberFont;
|
||||
|
@ -81,7 +149,7 @@ class DExhumedStatusBar : public DBaseStatusBar
|
|||
};
|
||||
|
||||
public:
|
||||
DExhumedStatusBar()
|
||||
DNativeExhumedStatusBar()
|
||||
{
|
||||
textfont = Create<DHUDFont>(SmallFont, 1, Off, 1, 1);
|
||||
numberFont = Create<DHUDFont>(BigFont, 0, Off, 1, 1);
|
||||
|
@ -505,12 +573,6 @@ private:
|
|||
}
|
||||
|
||||
DrawMulti();
|
||||
|
||||
if (nSnakeCam >= 0)
|
||||
{
|
||||
BeginHUD(320, 200, 1);
|
||||
SBar_DrawString(this, textfont, "S E R P E N T C A M", 0, 0, DI_TEXT_ALIGN_CENTER | DI_SCREEN_CENTER_TOP, CR_UNTRANSLATED, 1, -1, 0, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -898,8 +960,8 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
IMPLEMENT_CLASS(DExhumedStatusBar, false, true)
|
||||
IMPLEMENT_POINTERS_START(DExhumedStatusBar)
|
||||
IMPLEMENT_CLASS(DNativeExhumedStatusBar, false, true)
|
||||
IMPLEMENT_POINTERS_START(DNativeExhumedStatusBar)
|
||||
IMPLEMENT_POINTER(textfont)
|
||||
IMPLEMENT_POINTER(numberFont)
|
||||
IMPLEMENT_POINTERS_END
|
||||
|
@ -928,7 +990,7 @@ void StatusMessage(int messageTime, const char* fmt, ...)
|
|||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
CVAR(Bool, sb_native, false, 0)
|
||||
void DrawStatusBar()
|
||||
{
|
||||
if (nFreeze == 2) return; // Hide when Ramses is talking.
|
||||
|
@ -936,7 +998,21 @@ void DrawStatusBar()
|
|||
{
|
||||
UpdateFrame();
|
||||
}
|
||||
StatusBar->UpdateStatusBar();
|
||||
SummaryInfo info{};
|
||||
info.kills = nCreaturesKilled;
|
||||
info.maxkills = nCreaturesTotal;
|
||||
// got no secrets in the game
|
||||
info.time = Scale(PlayClock, 1000, 120);
|
||||
if (!sb_native) UpdateStatusBar(&info);
|
||||
else StatusBar2->UpdateStatusBar();
|
||||
|
||||
if (nSnakeCam >= 0)
|
||||
{
|
||||
const char* text = "S E R P E N T C A M";
|
||||
int width = SmallFont->StringWidth(text);
|
||||
DrawText(twod, SmallFont, CR_UNTRANSLATED, 160 - width / 2, 1, text, DTA_FullscreenScale, FSMode_Fit320x200, TAG_DONE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
END_PS_NS
|
||||
|
|
|
@ -43,4 +43,5 @@ version "4.3"
|
|||
#include "zscript/games/sw/ui/screens.zs"
|
||||
#include "zscript/games/exhumed/exhumedgame.zs"
|
||||
#include "zscript/games/exhumed/ui/menu.zs"
|
||||
#include "zscript/games/exhumed/ui/sbar.zs"
|
||||
#include "zscript/games/exhumed/ui/screens.zs"
|
||||
|
|
|
@ -7,14 +7,17 @@ struct Exhumed native
|
|||
native static bool LocalSoundPlaying();
|
||||
native static void playCDTrack(int track, bool looped);
|
||||
native static void DrawPlasma();
|
||||
|
||||
native static int, int GetStatusSequence(int seq, int index);
|
||||
native static int MoveStatusSequence(int s1, int s2);
|
||||
native static int SizeOfStatusSequence(int s1);
|
||||
native static ExhumedPlayer GetViewPlayer();
|
||||
|
||||
static void DrawAbs(String img, int x, int y, int shade = 0)
|
||||
{
|
||||
Screen.DrawTexture(TexMan.CheckForTexture(img, TexMan.Type_Any), false, x, y, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TopLeft, true, DTA_Color, Raze.shadeToLight(shade));
|
||||
}
|
||||
|
||||
static void DRawRel(String img, int x, int y, int shade = 0)
|
||||
static void DrawRel(String img, int x, int y, int shade = 0)
|
||||
{
|
||||
let tex = TexMan.CheckForTexture(img, TexMan.Type_Any);
|
||||
if (!tex.IsValid()) return;
|
||||
|
@ -27,6 +30,56 @@ struct Exhumed native
|
|||
}
|
||||
}
|
||||
|
||||
struct ExhumedPlayer native
|
||||
{
|
||||
native int16 nHealth;
|
||||
native int16 nLives;
|
||||
native int16 nDouble;
|
||||
native int16 nInvisible;
|
||||
native int16 nTorch;
|
||||
native int16 field_2;
|
||||
native int16 nAction;
|
||||
native int16 nSprite;
|
||||
native int16 bIsMummified;
|
||||
native int16 invincibility;
|
||||
native int16 nAir;
|
||||
native int16 nSeq;
|
||||
native int16 nMaskAmount;
|
||||
native uint16 keys;
|
||||
native int16 nMagic;
|
||||
native int16 nItem;
|
||||
native uint8 items[8];
|
||||
native int16 nAmmo[7]; // TODO - kMaxWeapons?
|
||||
native int16 pad[2];
|
||||
|
||||
native int16 nCurrentWeapon;
|
||||
native int16 field_3FOUR;
|
||||
native int16 bIsFiring;
|
||||
native int16 field_38;
|
||||
native int16 field_3A;
|
||||
native int16 field_3C;
|
||||
native int16 nRun;
|
||||
native bool bPlayerPan, bLockPan;
|
||||
//fixedhoriz nDestVertPan;
|
||||
|
||||
//PlayerHorizon horizon;
|
||||
//PlayerAngle angle;
|
||||
|
||||
native bool IsUnderwater();
|
||||
native int GetAngle();
|
||||
}
|
||||
|
||||
enum EEWeap
|
||||
{
|
||||
kWeaponSword = 0,
|
||||
kWeaponPistol,
|
||||
kWeaponM60,
|
||||
kWeaponFlamer,
|
||||
kWeaponGrenade,
|
||||
kWeaponStaff,
|
||||
kWeaponRing,
|
||||
kWeaponMummified
|
||||
}
|
||||
|
||||
struct ExhumedSnd native
|
||||
{
|
||||
|
|
781
wadsrc/static/zscript/games/exhumed/ui/sbar.zs
Normal file
781
wadsrc/static/zscript/games/exhumed/ui/sbar.zs
Normal file
|
@ -0,0 +1,781 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 sirlemonhead, Nuke.YKT
|
||||
Copyright (C) 2020-2021 Christoph Oelckers
|
||||
|
||||
This file is part of Raze.
|
||||
|
||||
This is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
struct ChunkFrame // this wraps the internal (mis-)representation of the chunk data.
|
||||
{
|
||||
TextureID tex;
|
||||
int x, y;
|
||||
int flags;
|
||||
|
||||
native void GetChunkFrame(int nFrameBase);
|
||||
}
|
||||
|
||||
class ExhumedStatusBar : RazeStatusBar
|
||||
{
|
||||
HUDFont textfont, numberFont;
|
||||
|
||||
int keyanims[4];
|
||||
int airframe, lungframe;
|
||||
|
||||
int nSelectedItem;
|
||||
int nHealthLevel;
|
||||
int nMagicLevel;
|
||||
int nMeterRange;
|
||||
int nHurt;
|
||||
int nHealthFrame;
|
||||
int nMagicFrame;
|
||||
int nItemAltSeq;
|
||||
int nItemSeq;
|
||||
int nItemFrames;
|
||||
int nItemFrame;
|
||||
int totalmoves;
|
||||
|
||||
|
||||
int nCounter;
|
||||
int nCounterDest;
|
||||
int nDigit[3];
|
||||
int ammodelay;
|
||||
int nLastWeapon;
|
||||
|
||||
enum EConst
|
||||
{
|
||||
KeySeq = 36,
|
||||
}
|
||||
|
||||
override void Init()
|
||||
{
|
||||
textfont = HUDFont.Create(SmallFont, 1, Mono_Off, 1, 1);
|
||||
numberFont = HUDFont.Create(BigFont, 0, Mono_Off, 1, 1);
|
||||
|
||||
let nPicNum = GetStatusSequencePic(0, 0);
|
||||
let siz = TexMan.GetScaledSize(nPicNum);
|
||||
nMeterRange = siz.Y;
|
||||
Reset();
|
||||
}
|
||||
|
||||
override void Reset()
|
||||
{
|
||||
airframe = lungframe = nHurt = nHealthFrame = nMagicFrame = nItemAltSeq = nItemFrames = nItemFrame = nCounter = 0;
|
||||
|
||||
nDigit[0] = nDigit[1] = nDigit[2] = 0;
|
||||
nHealthLevel = -1;
|
||||
nMagicLevel = -1;
|
||||
nSelectedItem = -1;
|
||||
nItemSeq = -1;
|
||||
ammodelay = 3;
|
||||
nLastWeapon = -1;
|
||||
totalmoves = 0;
|
||||
nCounterDest = 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// draws a sequence animation to the status bar
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void DrawStatusSequence(int nSequence, int frameindex, double yoffset, double xoffset = 0)
|
||||
{
|
||||
int nFrameBase, nFrameSize;
|
||||
[nFrameBase, nFrameSize] = Exhumed.GetStatusSequence(nSequence, frameindex);
|
||||
|
||||
for(; nFrameSize > 0; nFrameSize--, nFrameBase++)
|
||||
{
|
||||
int flags = 0;
|
||||
ChunkFrame chunk;
|
||||
chunk.GetChunkFrame(nFrameBase);
|
||||
|
||||
double x = chunk.x + xoffset;
|
||||
double y = chunk.y + yoffset;
|
||||
|
||||
if (hud_size <= Hud_StbarOverlay)
|
||||
{
|
||||
x += 161;
|
||||
y += 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x < 0)
|
||||
{
|
||||
x += 160;
|
||||
flags |= DI_SCREEN_LEFT_BOTTOM;
|
||||
}
|
||||
else if (x > 0)
|
||||
{
|
||||
x -= 159; // graphics do not match up precisely.
|
||||
flags |= DI_SCREEN_RIGHT_BOTTOM;
|
||||
}
|
||||
y -= 100;
|
||||
}
|
||||
|
||||
if (chunk.flags & 3)
|
||||
{
|
||||
// This is hard to align with bad offsets, so skip that treatment for mirrored elements.
|
||||
flags |= DI_ITEM_RELCENTER;
|
||||
}
|
||||
else
|
||||
{
|
||||
let tsiz = TexMan.GetScaledSize(chunk.tex);
|
||||
x -= tsiz.x * .5;
|
||||
y -= tsiz.y * .5;
|
||||
flags |= DI_ITEM_OFFSETS;
|
||||
}
|
||||
|
||||
if (chunk.flags & 1)
|
||||
flags |= DI_MIRROR;
|
||||
if (chunk.flags & 2)
|
||||
flags |= DI_MIRRORY;
|
||||
|
||||
DrawTexture(chunk.tex, (x, y), flags);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// draws a sequence animation to the status bar
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
TextureID GetStatusSequencePic(int nSequence, int frameindex)
|
||||
{
|
||||
int nFrameBase = Exhumed.GetStatusSequence(nSequence, frameindex);
|
||||
ChunkFrame chunk;
|
||||
chunk.GetChunkFrame(nFrameBase);
|
||||
return chunk.tex;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Frag display - very ugly and may have to be redone if multiplayer support gets added.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void DrawMulti()
|
||||
{
|
||||
/*
|
||||
char stringBuf[30];
|
||||
if (netgame)
|
||||
{
|
||||
BeginHUD(1, false, 320, 200);
|
||||
|
||||
int shade;
|
||||
|
||||
if ((PlayClock / 120) & 1)
|
||||
shade = -100;
|
||||
else
|
||||
shade = 127;
|
||||
|
||||
int nTile = 3593;
|
||||
|
||||
int xx = 320 / (nTotalPlayers + 1);
|
||||
int x = xx - 160;
|
||||
|
||||
for (int i = 0; i < nTotalPlayers; i++)
|
||||
{
|
||||
DrawImage(String.Format("#%05d", nTile)), (x, 7), DI_ITEM_CENTER);
|
||||
|
||||
if (i != nLocalPlayer) {
|
||||
shade = -100;
|
||||
}
|
||||
|
||||
sprintf(stringBuf, "%d", nPlayerScore[i]);
|
||||
DrawString(this, textfont, stringBuf, x, 0, DI_ITEM_TOP | DI_TEXT_ALIGN_CENTER, i != nLocalPlayer ? CR_UNTRANSLATED : CR_GOLD, 1, -1, 0, 1, 1);
|
||||
x += xx;
|
||||
nTile++;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Fullscreen HUD variant #1
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int ItemTimer(ExhumedPlayer pPlayer, int num)
|
||||
{
|
||||
switch (num) {
|
||||
case 1: //Scarab item
|
||||
return (pPlayer.invincibility * 100) / 900;
|
||||
case 3: //Hand item
|
||||
return (pPlayer.nDouble * 100) / 1350;
|
||||
case 5: //Mask
|
||||
return (pPlayer.nMaskAmount * 100) / 1350;
|
||||
case 4: //Invisible
|
||||
return (pPlayer.nInvisible * 100) / 900;
|
||||
case 2: //Torch
|
||||
return (pPlayer.nTorch * 100) / 900;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void DrawHUD2(ExhumedPlayer pp)
|
||||
{
|
||||
BeginHUD(1, false, 320, 200);
|
||||
|
||||
String format;
|
||||
TextureID img;
|
||||
double imgScale;
|
||||
double baseScale = numberFont.mFont.GetHeight() * 0.75;
|
||||
|
||||
|
||||
//
|
||||
// Health
|
||||
//
|
||||
img = GetStatusSequencePic(125, 0);
|
||||
let size = TexMan.GetScaledSize(img);
|
||||
imgScale = baseScale / size.Y;
|
||||
DrawTexture(img, (1.5, -1), DI_ITEM_LEFT_BOTTOM, scale:(imgScale, imgScale));
|
||||
|
||||
if (!hud_flashing || pp.nHealth > 150 || (PlayClock & 32))
|
||||
{
|
||||
int s = -8;
|
||||
if (hud_flashing && pp.nHealth > 800)
|
||||
s += Raze.bsin(PlayClock << 5, -10);
|
||||
int intens = clamp(255 - 4 * s, 0, 255);
|
||||
format = String.Format("%d", pp.nHealth >> 3);
|
||||
DrawString(numberFont, format, (13, -numberFont.mFont.GetHeight() + 3), DI_TEXT_ALIGN_LEFT, intens / 255.);
|
||||
}
|
||||
|
||||
//
|
||||
// Air
|
||||
//
|
||||
if (pp.isUnderwater())
|
||||
{
|
||||
img = GetStatusSequencePic(133, airframe);
|
||||
let size = TexMan.GetScaledSize(img);
|
||||
imgScale = baseScale / size.Y;
|
||||
DrawTexture(img, (-4, -22), DI_ITEM_RIGHT_BOTTOM, scale:(imgScale, imgScale));
|
||||
}
|
||||
|
||||
//
|
||||
// Magic
|
||||
//
|
||||
if (nItemSeq >= 0)
|
||||
{
|
||||
img = GetStatusSequencePic(nItemSeq, nItemFrame);
|
||||
//int tile = GetStatusSequenceTile(nItemSeq, nItemFrame);
|
||||
//int tile2 = tile;
|
||||
//if (tile2 > 744 && tile2 < 751) tile2 = 744;
|
||||
|
||||
let size = TexMan.GetScaledSize(img);
|
||||
imgScale = baseScale / size.Y;
|
||||
DrawTexture(img, (70, -1), DI_ITEM_CENTER_BOTTOM, scale:(imgScale, imgScale));
|
||||
|
||||
format = String.Format("%d", pp.nMagic / 10);
|
||||
|
||||
int nItem = pp.nItem;
|
||||
int timer = ItemTimer(pp, nItem);
|
||||
if (timer > 0)
|
||||
{
|
||||
format.AppendFormat("/%d", timer);
|
||||
}
|
||||
DrawString(numberFont, format, (79.5, -numberFont.mFont.GetHeight() + 3), DI_TEXT_ALIGN_LEFT);
|
||||
}
|
||||
//
|
||||
// Weapon
|
||||
//
|
||||
int weapon = pp.nCurrentWeapon;
|
||||
int ammo = nCounterDest;
|
||||
if (ammo > 0) // wicon > 0
|
||||
{
|
||||
format = String.Format("%d", ammo);
|
||||
/* non-implemented weapon icon.
|
||||
int wicon = 0;// ammo_sprites[weapon];
|
||||
img = tileGetTexture(wicon);
|
||||
imgScale = baseScale / img.GetDisplayHeight();
|
||||
let imgX = 21.125;
|
||||
let strlen = format.Len();
|
||||
|
||||
if (strlen > 1)
|
||||
{
|
||||
imgX += (imgX * 0.855) * (strlen - 1);
|
||||
}
|
||||
*/
|
||||
|
||||
if ((!hud_flashing || PlayClock & 32 || ammo > 10))// (DamageData[weapon].max_ammo / 10)))
|
||||
{
|
||||
DrawString(numberFont, format, (-3, -numberFont.mFont.GetHeight() + 3), DI_TEXT_ALIGN_RIGHT);
|
||||
}
|
||||
|
||||
//DrawGraphic(img, (-imgX, -1), DI_ITEM_RIGHT_BOTTOM, scale:(imgScale, imgScale));
|
||||
}
|
||||
|
||||
//
|
||||
// keys
|
||||
//
|
||||
|
||||
int nKeys = pp.keys;
|
||||
int x = -134;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (nKeys & (0x1000 << i))
|
||||
{
|
||||
DrawImage(String.Format("KeyIcon%d", i+1), (x, -2), DI_ITEM_LEFT_BOTTOM);
|
||||
}
|
||||
x += 20;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// draw the full status bar
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void DrawStatus(ExhumedPlayer pp)
|
||||
{
|
||||
if (hud_size <= Hud_StbarOverlay)
|
||||
{
|
||||
// draw the main bar itself
|
||||
BeginStatusBar(false, 320, 200, 40);
|
||||
if (hud_size == Hud_StbarOverlay) Set43ClipRect();
|
||||
DrawImage("TileStatusBar", (160, 200), DI_ITEM_CENTER_BOTTOM);
|
||||
screen.ClearClipRect();
|
||||
}
|
||||
else if (hud_size == Hud_Mini)
|
||||
{
|
||||
BeginHUD(1, false, 320, 200);
|
||||
DrawImage("hud_l", (0, 0), DI_ITEM_LEFT_BOTTOM | DI_SCREEN_LEFT_BOTTOM);
|
||||
DrawImage("hud_r", (0, 0), DI_ITEM_RIGHT_BOTTOM | DI_SCREEN_RIGHT_BOTTOM);
|
||||
}
|
||||
else if (hud_size == Hud_full)
|
||||
{
|
||||
DrawHUD2(pp);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (pp.keys & (4096 << i))
|
||||
{
|
||||
DrawStatusSequence(KeySeq + 2 * i, keyanims[i], 0.5, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
//if (/*!bFullScreen &&*/ nNetTime)
|
||||
{
|
||||
DrawStatusSequence(127, 0, 0);
|
||||
DrawStatusSequence(129, nMagicFrame, nMagicLevel);
|
||||
DrawStatusSequence(131, 0, 0); // magic pool frame (bottom)
|
||||
|
||||
DrawStatusSequence(128, 0, 0);
|
||||
DrawStatusSequence(1, nHealthFrame, nHealthLevel);
|
||||
DrawStatusSequence(125, 0, 0); // draw ankh on health pool
|
||||
DrawStatusSequence(130, 0, 0); // draw health pool frame (top)
|
||||
|
||||
// Item on the magic pool
|
||||
if (nItemSeq >= 0) DrawStatusSequence(nItemSeq, nItemFrame, 1);
|
||||
|
||||
// draw the blue air level meter when underwater
|
||||
if (pp.isUnderwater()) DrawStatusSequence(133, airframe, 0, 0.5);
|
||||
else DrawStatusSequence(132, lungframe, 0);
|
||||
|
||||
// item count dots.
|
||||
if (nSelectedItem >= 0)
|
||||
{
|
||||
int count = pp.items[nSelectedItem];
|
||||
DrawStatusSequence(156 + 2 * count, 0, 0);
|
||||
}
|
||||
|
||||
// life dots.
|
||||
DrawStatusSequence(145 + (2 * pp.nLives), 0, 0);
|
||||
|
||||
if (nHurt > 0) DrawStatusSequence(4, nHurt - 1, 0);
|
||||
|
||||
// draw compass
|
||||
if (hud_size <= Hud_StbarOverlay) DrawStatusSequence(35, ((pp.GetAngle() + 128) & Raze.kAngleMask) >> 8, 0, 0.5);
|
||||
|
||||
//if (hud_size < Hud_full)
|
||||
{
|
||||
// draw ammo count
|
||||
DrawStatusSequence(44, nDigit[2], 0, 0.5);
|
||||
DrawStatusSequence(45, nDigit[1], 0, 0.5);
|
||||
DrawStatusSequence(46, nDigit[0], 0, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
DrawMulti();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void DoLevelStats(int bottomy, Summaryinfo summary)
|
||||
{
|
||||
StatsPrintInfo stats;
|
||||
|
||||
stats.fontscale = 1.;
|
||||
stats.spacing = SmallFont.GetHeight();
|
||||
stats.screenbottomspace = bottomy;
|
||||
stats.statfont = SmallFont;
|
||||
stats.letterColor = TEXTCOLOR_RED;
|
||||
stats.standardColor = TEXTCOLOR_UNTRANSLATED;
|
||||
|
||||
if (automapMode == am_full)
|
||||
{
|
||||
PrintAutomapInfo(stats, true);
|
||||
}
|
||||
else if (automapMode == am_off && hud_stats)
|
||||
{
|
||||
stats.completeColor = TEXTCOLOR_DARKGREEN;
|
||||
PrintLevelStats(stats, summary);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void SetItemSeq(ExhumedPlayer pp)
|
||||
{
|
||||
static const int nItemSeqOffset[] = { 91, 72, 76, 79, 68, 87, 83 };
|
||||
static const int nItemMagic[] = { 500, 1000, 100, 500, 400, 200, 700, 0 };
|
||||
|
||||
int nItem = pp.nItem;
|
||||
if (nItem < 0)
|
||||
{
|
||||
nItemSeq = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (nItemMagic[nItem] <= pp.nMagic) nItemAltSeq = 0;
|
||||
else nItemAltSeq = 2;
|
||||
|
||||
nItemFrame = 0;
|
||||
nItemSeq = nItemSeqOffset[nItem] + nItemAltSeq;
|
||||
nItemFrames = Exhumed.SizeofStatusSequence(nItemSeq);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void SetMagicFrame(ExhumedPlayer pp)
|
||||
{
|
||||
int magicperline = 1000 / nMeterRange;
|
||||
|
||||
int newMagicLevel = (1000 - pp.nMagic) / magicperline;
|
||||
newMagicLevel = clamp(newMagicLevel, 0, nMeterRange - 1);
|
||||
if (newMagicLevel != nMagicLevel) SetItemSeq(pp);
|
||||
nMagicLevel = newMagicLevel;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void SetHealthFrame(ExhumedPlayer pp)
|
||||
{
|
||||
if (nHurt)
|
||||
{
|
||||
nHurt++;
|
||||
if (nHurt > Exhumed.SizeofStatusSequence(4)) nHurt = 0;
|
||||
}
|
||||
|
||||
int healthperline = 800 / nMeterRange;
|
||||
|
||||
int newHealthLevel = (800 - pp.nHealth) / healthperline;
|
||||
newHealthLevel = clamp(newHealthLevel, 0, nMeterRange - 1);
|
||||
if (newHealthLevel > nHealthLevel) nHurt = 1;
|
||||
nHealthLevel = newHealthLevel;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void SetCounter(int nVal)
|
||||
{
|
||||
nCounterDest = clamp(nVal, 0, 999);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void SetCounterImmediate(int nVal)
|
||||
{
|
||||
SetCounter(nVal);
|
||||
nCounter = nCounterDest;
|
||||
SetCounterDigits();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void SetCounterDigits()
|
||||
{
|
||||
nDigit[2] = 3 * (nCounter / 100 % 10);
|
||||
nDigit[1] = 3 * (nCounter / 10 % 10);
|
||||
nDigit[0] = 3 * (nCounter % 10);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void UpdateCounter(ExhumedPlayer pp)
|
||||
{
|
||||
int nWeapon = pp.nCurrentWeapon;
|
||||
|
||||
if (nWeapon < 0)
|
||||
{
|
||||
SetCounterImmediate(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int thiscount;
|
||||
|
||||
if (nWeapon >= kWeaponSword && nWeapon <= kWeaponRing)
|
||||
thiscount = pp.nAmmo[nWeapon];
|
||||
else
|
||||
thiscount = 0;
|
||||
|
||||
if (nWeapon != nLastWeapon) SetCounterImmediate(thiscount);
|
||||
else SetCounter(thiscount);
|
||||
}
|
||||
nLastWeapon = nWeapon;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void MoveStatus(ExhumedPlayer pp)
|
||||
{
|
||||
if (nItemSeq >= 0)
|
||||
{
|
||||
nItemFrame++;
|
||||
|
||||
if (nItemFrame >= nItemFrames)
|
||||
{
|
||||
if (nItemSeq == 67) {
|
||||
SetItemSeq(pp);
|
||||
}
|
||||
else
|
||||
{
|
||||
nItemSeq -= nItemAltSeq;
|
||||
|
||||
if (nItemAltSeq || (totalmoves & 0x1F))
|
||||
{
|
||||
if (nItemSeq < 2) {
|
||||
nItemAltSeq = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nItemAltSeq = 1;
|
||||
}
|
||||
|
||||
nItemFrame = 0;
|
||||
nItemSeq += nItemAltSeq;
|
||||
nItemFrames = Exhumed.SizeofStatusSequence(nItemSeq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nHealthFrame++;
|
||||
if (nHealthFrame >= Exhumed.SizeofStatusSequence(1)) nHealthFrame = 0;
|
||||
|
||||
nMagicFrame++;
|
||||
if (nMagicFrame >= Exhumed.SizeofStatusSequence(129)) nMagicFrame = 0;
|
||||
|
||||
if (nCounter == nCounterDest)
|
||||
{
|
||||
nCounter = nCounterDest;
|
||||
ammodelay = 3;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ammodelay--;
|
||||
if (ammodelay > 0)
|
||||
return;
|
||||
}
|
||||
|
||||
int eax = nCounterDest - nCounter;
|
||||
|
||||
if (eax <= 0)
|
||||
{
|
||||
if (eax >= -30)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
nDigit[i]--;
|
||||
|
||||
if (nDigit[i] < 0)
|
||||
{
|
||||
nDigit[i] += 30;
|
||||
}
|
||||
|
||||
if (nDigit[i] < 27) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nCounter += (nCounterDest - nCounter) >> 1;
|
||||
SetCounterDigits();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (eax <= 30)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
nDigit[i]++;
|
||||
|
||||
if (nDigit[i] <= 27)
|
||||
break;
|
||||
|
||||
if (nDigit[i] >= 30)
|
||||
nDigit[i] -= 30;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nCounter += (nCounterDest - nCounter) >> 1;
|
||||
SetCounterDigits();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(nDigit[0] % 3))
|
||||
nCounter = nDigit[0] / 3 + 100 * (nDigit[2] / 3) + 10 * (nDigit[1] / 3);
|
||||
|
||||
eax = nCounterDest - nCounter;
|
||||
if (eax < 0)
|
||||
eax = -eax;
|
||||
|
||||
ammodelay = max(1, 4 - (eax >> 1));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void SetPlayerItem(ExhumedPlayer pp)
|
||||
{
|
||||
if (nSelectedItem != pp.nItem)
|
||||
{
|
||||
nSelectedItem = pp.nItem;
|
||||
SetItemSeq(pp);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
override void Tick()
|
||||
{
|
||||
totalmoves++;
|
||||
let pp = Exhumed.GetViewPlayer();
|
||||
SetMagicFrame(pp);
|
||||
SetHealthFrame(pp);
|
||||
SetPlayerItem(pp);
|
||||
UpdateCounter(pp);
|
||||
MoveStatus(pp);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int seq = KeySeq + 2 * i;
|
||||
if (pp.keys & (4096 << i))
|
||||
{
|
||||
if (keyanims[i] < Exhumed.SizeofStatusSequence(seq) - 1)
|
||||
{
|
||||
Exhumed.MoveStatusSequence(seq, 0); // this plays the pickup sound.
|
||||
keyanims[i]++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
keyanims[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (pp.isUnderwater())
|
||||
{
|
||||
|
||||
int nAirFrames = Exhumed.SizeofStatusSequence(133);
|
||||
int airperline = 100 / nAirFrames;
|
||||
|
||||
airframe = pp.nAir / airperline;
|
||||
|
||||
if (airframe >= nAirFrames)
|
||||
{
|
||||
airframe = nAirFrames - 1;
|
||||
}
|
||||
else if (airframe < 0)
|
||||
{
|
||||
airframe = 0;
|
||||
}
|
||||
lungframe = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int size = Exhumed.SizeofStatusSequence(132);
|
||||
if (++lungframe == size) lungframe = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override void UpdateStatusBar(SummaryInfo info)
|
||||
{
|
||||
if (hud_size <= Hud_full)
|
||||
{
|
||||
DrawStatus(Exhumed.GetViewPlayer());
|
||||
}
|
||||
DoLevelStats(hud_size == Hud_Nothing ? 0 : hud_size == Hud_full ? 22 : 40, info);
|
||||
}
|
||||
}
|
|
@ -134,6 +134,8 @@ struct SummaryInfo native
|
|||
|
||||
struct Raze
|
||||
{
|
||||
const kAngleMask = 0x7FF;
|
||||
|
||||
static int calcSinTableValue(int ang)
|
||||
{
|
||||
return int(16384 * sin((360./2048) * ang));
|
||||
|
@ -254,7 +256,7 @@ class DukeStatusBar : DukeCommonStatusBar native
|
|||
class RedneckStatusBar : DukeCommonStatusBar native
|
||||
{}
|
||||
|
||||
class ExhumedStatusBar : BaseStatusBar native
|
||||
class NativeExhumedStatusBar : BaseStatusBar native
|
||||
{}
|
||||
|
||||
class SWStatusBar : BaseStatusBar native
|
||||
|
|
Loading…
Reference in a new issue