- ported Duke and RR status bars.

Compiles but not tested yet.
This commit is contained in:
Christoph Oelckers 2021-05-15 14:27:32 +02:00
parent d311792e06
commit f84f58e714
14 changed files with 1663 additions and 24 deletions

View file

@ -133,6 +133,55 @@ DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, DrawImage, SBar_DrawImage)
return 0;
}
void SBar_DrawImageRotated(DStatusBarCore* self, const FString& texid, double x, double y, int flags, double angle, double alpha, double scaleX, double scaleY, int style, int color, int translation)
{
if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
self->DrawRotated(TexMan.CheckForTexture(texid, ETextureType::Any), x, y, flags, alpha, scaleX, scaleY, color, translation, style);
}
DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, DrawImageRotated, SBar_DrawImageRotated)
{
PARAM_SELF_PROLOGUE(DStatusBarCore);
PARAM_STRING(texid);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_INT(flags);
PARAM_FLOAT(angle);
PARAM_FLOAT(alpha);
PARAM_FLOAT(scaleX);
PARAM_FLOAT(scaleY);
PARAM_INT(style);
PARAM_INT(col);
PARAM_INT(trans);
SBar_DrawImageRotated(self, texid, x, y, flags, angle, alpha, scaleX, scaleY, style, col, trans);
return 0;
}
void SBar_DrawTextureRotated(DStatusBarCore* self, int texid, double x, double y, int flags, double angle, double alpha, double scaleX, double scaleY, int style, int color, int translation)
{
if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
self->DrawRotated(FSetTextureID(texid), x, y, flags, alpha, scaleX, scaleY, color, translation, style);
}
DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, DrawTextureRotated, SBar_DrawTextureRotated)
{
PARAM_SELF_PROLOGUE(DStatusBarCore);
PARAM_INT(texid);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_INT(flags);
PARAM_FLOAT(angle);
PARAM_FLOAT(alpha);
PARAM_FLOAT(scaleX);
PARAM_FLOAT(scaleY);
PARAM_INT(style);
PARAM_INT(col);
PARAM_INT(trans);
SBar_DrawTextureRotated(self, texid, x, y, flags, angle, alpha, scaleX, scaleY, style, col, trans);
return 0;
}
void SBar_DrawString(DStatusBarCore* self, DHUDFont* font, const FString& string, double x, double y, int flags, int trans, double alpha, int wrapwidth, int linespacing, double scaleX, double scaleY, int translation, int style);
DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, DrawString, SBar_DrawString)

View file

@ -1559,6 +1559,25 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Raze, bcos, bcos)
ACTION_RETURN_INT(bcos(v, shift));
}
DEFINE_ACTION_FUNCTION_NATIVE(_Raze, GetBuildTime, I_GetBuildTime)
{
ACTION_RETURN_INT(I_GetBuildTime());
}
bool PickTexture(FRenderState* state, FGameTexture* tex, int paletteid, TexturePick& pick);
DEFINE_ACTION_FUNCTION(_Raze, PickTexture)
{
PARAM_PROLOGUE;
PARAM_INT(texid);
TexturePick pick;
if (PickTexture(nullptr, TexMan.GetGameTexture(FSetTextureID(texid)), TRANSLATION(Translation_Remap, 0), pick))
{
ACTION_RETURN_INT(pick.texture->GetID().GetIndex());
}
ACTION_RETURN_INT(texid);
}
DEFINE_ACTION_FUNCTION(_MapRecord, GetCluster)
{
PARAM_SELF_STRUCT_PROLOGUE(MapRecord);

View file

@ -37,6 +37,7 @@ source as it is released.
#include "global.h"
#include "mapinfo.h"
#include "dukeactor.h"
#include "vm.h"
BEGIN_DUKE_NS
@ -1064,4 +1065,203 @@ void shootbloodsplat(DDukeActor* actor, int p, int sx, int sy, int sz, int sa, i
}
}
DEFINE_FIELD_X(DukePlayer, player_struct, gotweapon)
DEFINE_FIELD_X(DukePlayer, player_struct, pals)
DEFINE_FIELD_X(DukePlayer, player_struct, weapon_sway)
DEFINE_FIELD_X(DukePlayer, player_struct, oweapon_sway)
DEFINE_FIELD_X(DukePlayer, player_struct, weapon_pos)
DEFINE_FIELD_X(DukePlayer, player_struct, kickback_pic)
DEFINE_FIELD_X(DukePlayer, player_struct, random_club_frame)
DEFINE_FIELD_X(DukePlayer, player_struct, oweapon_pos)
DEFINE_FIELD_X(DukePlayer, player_struct, okickback_pic)
DEFINE_FIELD_X(DukePlayer, player_struct, orandom_club_frame)
DEFINE_FIELD_X(DukePlayer, player_struct, hard_landing)
DEFINE_FIELD_X(DukePlayer, player_struct, ohard_landing)
DEFINE_FIELD_X(DukePlayer, player_struct, psectlotag)
DEFINE_FIELD_X(DukePlayer, player_struct, exitx)
DEFINE_FIELD_X(DukePlayer, player_struct, exity)
DEFINE_FIELD_X(DukePlayer, player_struct, loogiex)
DEFINE_FIELD_X(DukePlayer, player_struct, loogiey)
DEFINE_FIELD_X(DukePlayer, player_struct, numloogs)
DEFINE_FIELD_X(DukePlayer, player_struct, loogcnt)
DEFINE_FIELD_X(DukePlayer, player_struct, invdisptime)
DEFINE_FIELD_X(DukePlayer, player_struct, bobposx)
DEFINE_FIELD_X(DukePlayer, player_struct, bobposy)
DEFINE_FIELD_X(DukePlayer, player_struct, oposx)
DEFINE_FIELD_X(DukePlayer, player_struct, oposy)
DEFINE_FIELD_X(DukePlayer, player_struct, oposz)
DEFINE_FIELD_X(DukePlayer, player_struct, pyoff)
DEFINE_FIELD_X(DukePlayer, player_struct, opyoff)
DEFINE_FIELD_X(DukePlayer, player_struct, posxv)
DEFINE_FIELD_X(DukePlayer, player_struct, posyv)
DEFINE_FIELD_X(DukePlayer, player_struct, poszv)
DEFINE_FIELD_X(DukePlayer, player_struct, last_pissed_time)
DEFINE_FIELD_X(DukePlayer, player_struct, truefz)
DEFINE_FIELD_X(DukePlayer, player_struct, truecz)
DEFINE_FIELD_X(DukePlayer, player_struct, player_par)
DEFINE_FIELD_X(DukePlayer, player_struct, visibility)
DEFINE_FIELD_X(DukePlayer, player_struct, bobcounter)
DEFINE_FIELD_X(DukePlayer, player_struct, randomflamex)
DEFINE_FIELD_X(DukePlayer, player_struct, crack_time)
DEFINE_FIELD_X(DukePlayer, player_struct, aim_mode)
DEFINE_FIELD_X(DukePlayer, player_struct, ftt)
DEFINE_FIELD_X(DukePlayer, player_struct, cursectnum)
DEFINE_FIELD_X(DukePlayer, player_struct, last_extra)
DEFINE_FIELD_X(DukePlayer, player_struct, subweapon)
DEFINE_FIELD_X(DukePlayer, player_struct, ammo_amount)
DEFINE_FIELD_X(DukePlayer, player_struct, frag)
DEFINE_FIELD_X(DukePlayer, player_struct, fraggedself)
DEFINE_FIELD_X(DukePlayer, player_struct, curr_weapon)
DEFINE_FIELD_X(DukePlayer, player_struct, last_weapon)
DEFINE_FIELD_X(DukePlayer, player_struct, tipincs)
DEFINE_FIELD_X(DukePlayer, player_struct, wantweaponfire)
DEFINE_FIELD_X(DukePlayer, player_struct, holoduke_amount)
DEFINE_FIELD_X(DukePlayer, player_struct, hurt_delay)
DEFINE_FIELD_X(DukePlayer, player_struct, hbomb_hold_delay)
DEFINE_FIELD_X(DukePlayer, player_struct, jumping_counter)
DEFINE_FIELD_X(DukePlayer, player_struct, airleft)
DEFINE_FIELD_X(DukePlayer, player_struct, knee_incs)
DEFINE_FIELD_X(DukePlayer, player_struct, access_incs)
DEFINE_FIELD_X(DukePlayer, player_struct, ftq)
DEFINE_FIELD_X(DukePlayer, player_struct, access_wallnum)
DEFINE_FIELD_X(DukePlayer, player_struct, got_access)
DEFINE_FIELD_X(DukePlayer, player_struct, weapon_ang)
DEFINE_FIELD_X(DukePlayer, player_struct, firstaid_amount)
DEFINE_FIELD_X(DukePlayer, player_struct, i)
DEFINE_FIELD_X(DukePlayer, player_struct, one_parallax_sectnum)
DEFINE_FIELD_X(DukePlayer, player_struct, over_shoulder_on)
DEFINE_FIELD_X(DukePlayer, player_struct, fist_incs)
DEFINE_FIELD_X(DukePlayer, player_struct, cheat_phase)
DEFINE_FIELD_X(DukePlayer, player_struct, extra_extra8)
DEFINE_FIELD_X(DukePlayer, player_struct, quick_kick)
DEFINE_FIELD_X(DukePlayer, player_struct, last_quick_kick)
DEFINE_FIELD_X(DukePlayer, player_struct, heat_amount)
DEFINE_FIELD_X(DukePlayer, player_struct, timebeforeexit)
DEFINE_FIELD_X(DukePlayer, player_struct, customexitsound)
DEFINE_FIELD_X(DukePlayer, player_struct, weaprecs)
DEFINE_FIELD_X(DukePlayer, player_struct, weapreccnt)
DEFINE_FIELD_X(DukePlayer, player_struct, interface_toggle_flag)
DEFINE_FIELD_X(DukePlayer, player_struct, dead_flag)
DEFINE_FIELD_X(DukePlayer, player_struct, show_empty_weapon)
DEFINE_FIELD_X(DukePlayer, player_struct, scuba_amount)
DEFINE_FIELD_X(DukePlayer, player_struct, jetpack_amount)
DEFINE_FIELD_X(DukePlayer, player_struct, steroids_amount)
DEFINE_FIELD_X(DukePlayer, player_struct, shield_amount)
DEFINE_FIELD_X(DukePlayer, player_struct, pycount)
DEFINE_FIELD_X(DukePlayer, player_struct, frag_ps)
DEFINE_FIELD_X(DukePlayer, player_struct, transporter_hold)
DEFINE_FIELD_X(DukePlayer, player_struct, last_full_weapon)
DEFINE_FIELD_X(DukePlayer, player_struct, footprintshade)
DEFINE_FIELD_X(DukePlayer, player_struct, boot_amount)
DEFINE_FIELD_X(DukePlayer, player_struct, on_warping_sector)
DEFINE_FIELD_X(DukePlayer, player_struct, footprintcount)
DEFINE_FIELD_X(DukePlayer, player_struct, hbomb_on)
DEFINE_FIELD_X(DukePlayer, player_struct, jumping_toggle)
DEFINE_FIELD_X(DukePlayer, player_struct, rapid_fire_hold)
DEFINE_FIELD_X(DukePlayer, player_struct, on_ground)
DEFINE_FIELD_X(DukePlayer, player_struct, inven_icon)
DEFINE_FIELD_X(DukePlayer, player_struct, buttonpalette)
DEFINE_FIELD_X(DukePlayer, player_struct, jetpack_on)
DEFINE_FIELD_X(DukePlayer, player_struct, spritebridge)
DEFINE_FIELD_X(DukePlayer, player_struct, lastrandomspot)
DEFINE_FIELD_X(DukePlayer, player_struct, scuba_on)
DEFINE_FIELD_X(DukePlayer, player_struct, footprintpal)
DEFINE_FIELD_X(DukePlayer, player_struct, heat_on)
DEFINE_FIELD_X(DukePlayer, player_struct, holster_weapon)
DEFINE_FIELD_X(DukePlayer, player_struct, falling_counter)
DEFINE_FIELD_X(DukePlayer, player_struct, refresh_inventory)
DEFINE_FIELD_X(DukePlayer, player_struct, toggle_key_flag)
DEFINE_FIELD_X(DukePlayer, player_struct, knuckle_incs)
DEFINE_FIELD_X(DukePlayer, player_struct, walking_snd_toggle)
DEFINE_FIELD_X(DukePlayer, player_struct, palookup)
DEFINE_FIELD_X(DukePlayer, player_struct, quick_kick_msg)
DEFINE_FIELD_X(DukePlayer, player_struct, max_secret_rooms)
DEFINE_FIELD_X(DukePlayer, player_struct, secret_rooms)
DEFINE_FIELD_X(DukePlayer, player_struct, max_actors_killed)
DEFINE_FIELD_X(DukePlayer, player_struct, actors_killed)
DEFINE_FIELD_X(DukePlayer, player_struct, resurrected)
DEFINE_FIELD_X(DukePlayer, player_struct, stairs)
DEFINE_FIELD_X(DukePlayer, player_struct, detonate_count)
DEFINE_FIELD_X(DukePlayer, player_struct, noise_x)
DEFINE_FIELD_X(DukePlayer, player_struct, noise_y)
DEFINE_FIELD_X(DukePlayer, player_struct, noise_radius)
DEFINE_FIELD_X(DukePlayer, player_struct, drink_timer)
DEFINE_FIELD_X(DukePlayer, player_struct, eat_timer)
DEFINE_FIELD_X(DukePlayer, player_struct, SlotWin)
DEFINE_FIELD_X(DukePlayer, player_struct, recoil)
DEFINE_FIELD_X(DukePlayer, player_struct, detonate_time)
DEFINE_FIELD_X(DukePlayer, player_struct, yehaa_timer)
DEFINE_FIELD_X(DukePlayer, player_struct, drink_amt)
DEFINE_FIELD_X(DukePlayer, player_struct, eat)
DEFINE_FIELD_X(DukePlayer, player_struct, drunkang)
DEFINE_FIELD_X(DukePlayer, player_struct, eatang)
DEFINE_FIELD_X(DukePlayer, player_struct, shotgun_state)
DEFINE_FIELD_X(DukePlayer, player_struct, donoise)
DEFINE_FIELD_X(DukePlayer, player_struct, keys)
DEFINE_FIELD_X(DukePlayer, player_struct, drug_aspect)
DEFINE_FIELD_X(DukePlayer, player_struct, drug_timer)
DEFINE_FIELD_X(DukePlayer, player_struct, SeaSick)
DEFINE_FIELD_X(DukePlayer, player_struct, MamaEnd)
DEFINE_FIELD_X(DukePlayer, player_struct, moto_drink)
DEFINE_FIELD_X(DukePlayer, player_struct, TiltStatus)
DEFINE_FIELD_X(DukePlayer, player_struct, oTiltStatus)
DEFINE_FIELD_X(DukePlayer, player_struct, VBumpNow)
DEFINE_FIELD_X(DukePlayer, player_struct, VBumpTarget)
DEFINE_FIELD_X(DukePlayer, player_struct, TurbCount)
DEFINE_FIELD_X(DukePlayer, player_struct, drug_stat)
DEFINE_FIELD_X(DukePlayer, player_struct, DrugMode)
DEFINE_FIELD_X(DukePlayer, player_struct, lotag800kill)
DEFINE_FIELD_X(DukePlayer, player_struct, sea_sick_stat)
DEFINE_FIELD_X(DukePlayer, player_struct, hurt_delay2)
DEFINE_FIELD_X(DukePlayer, player_struct, nocheat)
DEFINE_FIELD_X(DukePlayer, player_struct, OnMotorcycle)
DEFINE_FIELD_X(DukePlayer, player_struct, OnBoat)
DEFINE_FIELD_X(DukePlayer, player_struct, moto_underwater)
DEFINE_FIELD_X(DukePlayer, player_struct, NotOnWater)
DEFINE_FIELD_X(DukePlayer, player_struct, MotoOnGround)
DEFINE_FIELD_X(DukePlayer, player_struct, moto_do_bump)
DEFINE_FIELD_X(DukePlayer, player_struct, moto_bump_fast)
DEFINE_FIELD_X(DukePlayer, player_struct, moto_on_oil)
DEFINE_FIELD_X(DukePlayer, player_struct, moto_on_mud)
DEFINE_FIELD_X(DukePlayer, player_struct, vehForwardScale)
DEFINE_FIELD_X(DukePlayer, player_struct, vehReverseScale)
DEFINE_FIELD_X(DukePlayer, player_struct, MotoSpeed)
DEFINE_FIELD_X(DukePlayer, player_struct, vehTurnLeft)
DEFINE_FIELD_X(DukePlayer, player_struct, vehTurnRight)
DEFINE_FIELD_X(DukePlayer, player_struct, vehBraking)
DEFINE_FIELD_X(DukePlayer, player_struct, holoduke_on)
DEFINE_ACTION_FUNCTION(_DukePlayer, IsFrozen)
{
PARAM_SELF_STRUCT_PROLOGUE(player_struct);
ACTION_RETURN_BOOL(self->GetActor()->s->pal == 1 && self->last_extra < 2);
}
DEFINE_ACTION_FUNCTION(_DukePlayer, GetGameVar)
{
PARAM_SELF_STRUCT_PROLOGUE(player_struct);
PARAM_STRING(name);
PARAM_INT(def);
ACTION_RETURN_INT(GetGameVar(name, def, self->GetActor(), self->GetPlayerNum()));
}
DEFINE_ACTION_FUNCTION(_Duke, GetViewPlayer)
{
ACTION_RETURN_POINTER(&ps[screenpeek]);
}
DEFINE_ACTION_FUNCTION(_Duke, MaxPlayerHealth)
{
ACTION_RETURN_INT(gs.max_player_health);
}
DEFINE_ACTION_FUNCTION(_Duke, MaxAmmoAmount)
{
PARAM_PROLOGUE;
PARAM_INT(weap);
int max = weap < 0 || weap >= MAX_WEAPONS ? 0 : gs.max_ammo_amount[weap];
ACTION_RETURN_INT(max);
}
END_DUKE_NS

View file

@ -44,8 +44,8 @@ source as it is released.
BEGIN_DUKE_NS
IMPLEMENT_CLASS(DDukeCommonStatusBar, true, true)
IMPLEMENT_POINTERS_START(DDukeCommonStatusBar)
IMPLEMENT_CLASS(DNativeDukeCommonStatusBar, true, true)
IMPLEMENT_POINTERS_START(DNativeDukeCommonStatusBar)
IMPLEMENT_POINTER(miniFont)
IMPLEMENT_POINTER(numberFont)
IMPLEMENT_POINTER(digiFont)
@ -59,7 +59,7 @@ IMPLEMENT_POINTERS_END
//
//==========================================================================
DDukeCommonStatusBar::DDukeCommonStatusBar()
DNativeDukeCommonStatusBar::DNativeDukeCommonStatusBar()
{
drawOffset.Y = 0;
}
@ -71,7 +71,7 @@ DDukeCommonStatusBar::DDukeCommonStatusBar()
//
//==========================================================================
#if 0
void DDukeCommonStatusBar::displayfragbar(void)
void DNativeDukeCommonStatusBar::displayfragbar(void)
{
short i, j;
@ -98,7 +98,7 @@ void DDukeCommonStatusBar::displayfragbar(void)
//
//==========================================================================
std::pair<const char*, int> DDukeCommonStatusBar::ontext(struct player_struct *p)
std::pair<const char*, int> DNativeDukeCommonStatusBar::ontext(struct player_struct *p)
{
std::pair<const char*, int> retval(nullptr, CR_RED);
@ -136,7 +136,7 @@ std::pair<const char*, int> DDukeCommonStatusBar::ontext(struct player_struct *p
//
//==========================================================================
void DDukeCommonStatusBar::DrawInventory(const struct player_struct* p, double x, double y, int align)
void DNativeDukeCommonStatusBar::DrawInventory(const struct player_struct* p, double x, double y, int align)
{
if (p->invdisptime <= 0)return;
@ -173,7 +173,7 @@ void DDukeCommonStatusBar::DrawInventory(const struct player_struct* p, double x
//
//==========================================================================
PalEntry DDukeCommonStatusBar::LightForShade(int shade)
PalEntry DNativeDukeCommonStatusBar::LightForShade(int shade)
{
int ll = clamp((numshades - shade) * 255 / numshades, 0, 255);
return PalEntry(255, ll, ll, ll);
@ -186,7 +186,7 @@ PalEntry DDukeCommonStatusBar::LightForShade(int shade)
//
//==========================================================================
void DDukeCommonStatusBar::PrintLevelStats(int bottomy)
void DNativeDukeCommonStatusBar::PrintLevelStats(int bottomy)
{
FLevelStats stats{};
auto pp = &ps[myconnectindex];

View file

@ -7,9 +7,9 @@
BEGIN_DUKE_NS
class DDukeCommonStatusBar : public DBaseStatusBar
class DNativeDukeCommonStatusBar : public DBaseStatusBar
{
DECLARE_ABSTRACT_CLASS(DDukeCommonStatusBar, DBaseStatusBar)
DECLARE_ABSTRACT_CLASS(DNativeDukeCommonStatusBar, DBaseStatusBar)
HAS_OBJECT_POINTERS
protected:
@ -21,7 +21,7 @@ protected:
std::array<int, MAX_WEAPONS> ammo_sprites;
std::array<int, 8> item_icons;
DDukeCommonStatusBar();
DNativeDukeCommonStatusBar();
std::pair<const char*, int> ontext(struct player_struct *p);
void DrawInventory(const struct player_struct* p, double x, double y, int align);
PalEntry LightForShade(int shade);

View file

@ -55,14 +55,14 @@ BEGIN_DUKE_NS
//
//==========================================================================
class DDukeStatusBar : public DDukeCommonStatusBar
class DNativeDukeStatusBar : public DNativeDukeCommonStatusBar
{
DECLARE_CLASS(DDukeStatusBar, DDukeCommonStatusBar)
DECLARE_CLASS(DNativeDukeStatusBar, DNativeDukeCommonStatusBar)
int fontheight[2];
public:
DDukeStatusBar()
DNativeDukeStatusBar()
{
numberFont = Create<DHUDFont>( BigFont, 0, Off, 1, 1 );
indexFont = Create<DHUDFont>(IndexFont, 4, CellRight, 1, 1 );
@ -481,11 +481,11 @@ public:
}
};
IMPLEMENT_CLASS(DDukeStatusBar, false, false)
IMPLEMENT_CLASS(DNativeDukeStatusBar, false, false)
DBaseStatusBar* CreateDukeStatusBar()
{
return Create<DDukeStatusBar>();
return Create<DNativeDukeStatusBar>();
}
END_DUKE_NS

View file

@ -47,12 +47,12 @@ BEGIN_DUKE_NS
//
//==========================================================================
class DRedneckStatusBar : public DDukeCommonStatusBar
class DNativeRedneckStatusBar : public DNativeDukeCommonStatusBar
{
DECLARE_CLASS(DRedneckStatusBar, DDukeCommonStatusBar)
DECLARE_CLASS(DNativeRedneckStatusBar, DNativeDukeCommonStatusBar)
public:
DRedneckStatusBar()
DNativeRedneckStatusBar()
{
numberFont = Create<DHUDFont>(BigFont, 0, Off, 1, 1 );
miniFont = Create<DHUDFont>(SmallFont2, 0, Off, 1, 1 );
@ -466,11 +466,11 @@ public:
};
IMPLEMENT_CLASS(DRedneckStatusBar, false, false)
IMPLEMENT_CLASS(DNativeRedneckStatusBar, false, false)
DBaseStatusBar* CreateRedneckStatusBar()
{
return Create<DRedneckStatusBar>();
return Create<DNativeRedneckStatusBar>();
}

View file

@ -31,6 +31,9 @@ version "4.3"
#include "zscript/screenjob.zs"
#include "zscript/statusbar.zs"
#include "zscript/games/duke/dukegame.zs"
#include "zscript/games/duke/ui/sbar.zs"
#include "zscript/games/duke/ui/sbar_d.zs"
#include "zscript/games/duke/ui/sbar_r.zs"
#include "zscript/games/duke/ui/screens.zs"
#include "zscript/games/duke/ui/cutscenes.zs"
#include "zscript/games/duke/ui/menu.zs"

View file

@ -110,6 +110,10 @@ class StatusBarCore native ui
native double, double, double, double StatusbarToRealCoords(double x, double y=0, double w=0, double h=0);
native void DrawTexture(TextureID texture, Vector2 pos, int flags = 0, double Alpha = 1., Vector2 box = (-1, -1), Vector2 scale = (1, 1), ERenderStyle style = STYLE_Translucent, Color col = 0xffffffff, int translation = 0, double clipwidth = -1);
native void DrawImage(String texture, Vector2 pos, int flags = 0, double Alpha = 1., Vector2 box = (-1, -1), Vector2 scale = (1, 1), ERenderStyle style = STYLE_Translucent, Color col = 0xffffffff, int translation = 0, double clipwidth = -1);
native void DrawTextureRotated(TextureID texid, Vector2 pos, int flags, double angle, double alpha = 1, Vector2 scale = (1, 1), ERenderStyle style = STYLE_Translucent, Color col = 0xffffffff, int translation = 0);
native void DrawImageRotated(String texid, Vector2 pos, int flags, double angle, double alpha = 1, Vector2 scale = (1, 1), ERenderStyle style = STYLE_Translucent, Color col = 0xffffffff, int translation = 0);
native void DrawString(HUDFont font, String string, Vector2 pos, int flags = 0, int translation = Font.CR_UNTRANSLATED, double Alpha = 1., int wrapwidth = -1, int linespacing = 4, Vector2 scale = (1, 1), int pt = 0, ERenderStyle style = STYLE_Translucent);
native double, double, double, double TransformRect(double x, double y, double w, double h, int flags = 0);
native void Fill(Color col, double x, double y, double w, double h, int flags = 0);

View file

@ -49,10 +49,26 @@ struct Duke native
BASEPALCOUNT
};
enum dukeinvicon_t
{
ICON_NONE, // 0
ICON_FIRSTAID,
ICON_STEROIDS,
ICON_HOLODUKE,
ICON_JETPACK,
ICON_HEATS, // 5
ICON_SCUBA,
ICON_BOOTS,
ICON_MAX
};
native static void PlaySpecialMusic(int which);
native static int PlaySound(int num, int channel = CHAN_AUTO, int flags = 0, float vol =0.8f);
native static void StopSound(int num);
native static bool CheckSoundPlaying(int num);
native static DukePlayer GetViewPlayer();
native static int MaxPlayerHealth();
native static int MaxAmmoAmount(int weap);
static void PlayBonusMusic()
{
@ -111,6 +127,206 @@ struct Duke native
}
struct DukePlayer
{
// The sound code wants to read a vector out of this so we need to define one for the main coordinate.
/*
union
{
vec3_t pos;
struct { int32_t posx, posy, posz; };
};
// player's horizon and angle structs.
PlayerHorizon horizon;
PlayerAngle angle;
uint16_t frags[MAXPLAYERS];
*/
native bool gotweapon[DukeWpn.MAX_WEAPONS];
// Palette management uses indices into the engine's palette table now.
native color pals;
// this was a global variable originally.
//vec2_t fric;
// weapon drawer variables and their interpolation counterparts.
native int weapon_sway;
native int oweapon_sway;
native int16 weapon_pos, kickback_pic, random_club_frame;
native int16 oweapon_pos, okickback_pic, orandom_club_frame;
native uint8 hard_landing;
native uint8 ohard_landing;
// Store current psectlotag as determined in processinput() for use with scaling angle aiming.
native int16 psectlotag;
// From here on it is unaltered from JFDuke with the exception of a few fields that are no longer needed and were removed.
native int exitx, exity, loogiex[64], loogiey[64], numloogs, loogcnt;
native int invdisptime;
native int bobposx, bobposy, oposx, oposy, oposz, pyoff, opyoff;
native int posxv, posyv, poszv, last_pissed_time, truefz, truecz;
native int player_par, visibility;
native int bobcounter;
native int randomflamex, crack_time;
native int aim_mode, ftt;
native int16 cursectnum, last_extra, subweapon;
native int16 ammo_amount[DukeWpn.MAX_WEAPONS], frag, fraggedself;
native int16 curr_weapon, last_weapon, tipincs, wantweaponfire;
native int16 holoduke_amount, hurt_delay, hbomb_hold_delay;
native int16 jumping_counter, airleft, knee_incs, access_incs;
native int16 ftq, access_wallnum;
native int16 got_access, weapon_ang, firstaid_amount;
native int16 i, one_parallax_sectnum;
native int16 over_shoulder_on, fist_incs;
native int16 cheat_phase;
native int16 extra_extra8, quick_kick, last_quick_kick;
native int16 heat_amount, timebeforeexit, customexitsound;
//DDukeActor* actorsqu, *wackedbyactor, *on_crane, *holoduke_on, *somethingonplayer, *access_spritenum, *dummyplayersprite, *newOwner; // later
native voidptr holoduke_on; // cannot do it as a proper actor pointer - but the status bar needs it.
native int16 weaprecs[256], weapreccnt;
native uint interface_toggle_flag;
native int16 dead_flag, show_empty_weapon; // JBF 20031220: added orotscrnang
native int16 scuba_amount, jetpack_amount, steroids_amount, shield_amount;
native int16 pycount, frag_ps;
native int16 transporter_hold, last_full_weapon, footprintshade, boot_amount;
native uint8 on_warping_sector, footprintcount;
native uint8 hbomb_on, jumping_toggle, rapid_fire_hold, on_ground;
//char name[32];
native uint8 inven_icon, buttonpalette;
native uint8 jetpack_on, spritebridge, lastrandomspot;
native uint8 scuba_on, footprintpal, heat_on;
native uint8 holster_weapon;
native uint8 falling_counter;
native uint8 refresh_inventory;
native uint8 toggle_key_flag, knuckle_incs; // ,select_dir;
native uint8 walking_snd_toggle, palookup;
native bool quick_kick_msg;
native int max_secret_rooms, secret_rooms, max_actors_killed, actors_killed;
native bool resurrected;
// Redneck Rampage additions. Those which did not have names in the reconstructed source got one from either RedneckGDX or RedNukem.
// Items were reordered by size.
native int stairs;
native int detonate_count; // at57e
native int noise_x, noise_y, noise_radius; // at286, at28a, at290
native int drink_timer; // at58e
native int eat_timer; // at592
native int SlotWin;
native int16 recoil;
native int16 detonate_time; // at57c
native int16 yehaa_timer;
native int16 drink_amt, eat, drunkang, eatang;
native uint8 shotgun_state[2];
native uint8 donoise; // at28e
native uint8 keys[5];
// RRRA. The same as for the RR block applies.
native int drug_aspect;
native int drug_timer;
native int SeaSick;
native int16 MamaEnd; // raat609
native int16 moto_drink;
native float TiltStatus, oTiltStatus;
native int16 VBumpNow, VBumpTarget, TurbCount;
native int16 drug_stat[3]; // raat5f1..5
native uint8 DrugMode, lotag800kill;
native uint8 sea_sick_stat; // raat5dd
native uint8 hurt_delay2, nocheat;
native uint8 OnMotorcycle, OnBoat, moto_underwater, NotOnWater, MotoOnGround;
native uint8 moto_do_bump, moto_bump_fast, moto_on_oil, moto_on_mud;
native double vehForwardScale, vehReverseScale, MotoSpeed;
native bool vehTurnLeft, vehTurnRight, vehBraking;
// input stuff.
//InputPacket sync;
/*
DDukeActor* GetActor();
int GetPlayerNum();
void apply_seasick(double factor);
void backuppos(bool noclipping = false);
void backupweapon();
void checkhardlanding();
void playerweaponsway(int xvel);
float adjustavel(float avel)
{
return (psectlotag == ST_2_UNDERWATER)? avel * 0.875f : avel;
}
*/
native bool IsFrozen();
native int GetGameVar(String varname, int defval);
}
struct DukeWpn
{
enum dukeweapon_t
{
KNEE_WEAPON, // 0
PISTOL_WEAPON,
SHOTGUN_WEAPON,
CHAINGUN_WEAPON,
RPG_WEAPON,
HANDBOMB_WEAPON, // 5
SHRINKER_WEAPON,
DEVISTATOR_WEAPON,
TRIPBOMB_WEAPON,
FREEZE_WEAPON,
HANDREMOTE_WEAPON, // 10
GROW_WEAPON,
FLAMETHROWER_WEAPON, // World Tour
MIN_WEAPON = 0,
MAX_WEAPON = 9,
MAX_WEAPONS = 17
}
}
struct RRWpn
{
enum redneck_weapon_t
{
// These names have been pieced together from RedneckGDX and RedNukem because the reconstructed source recycled Duke's names for the first 11 weapons.
// Names for 0-2 are the same
KNEE_WEAPON, // 0
PISTOL_WEAPON,
SHOTGUN_WEAPON,
RIFLEGUN_WEAPON,
DYNAMITE_WEAPON,
CROSSBOW_WEAPON, // 5
THROWSAW_WEAPON,
ALIENBLASTER_WEAPON,
POWDERKEG_WEAPON,
TIT_WEAPON,
THROWINGDYNAMITE_WEAPON, // 10
BUZZSAW_WEAPON,
BOWLING_WEAPON,
MOTORCYCLE_WEAPON,
BOAT_WEAPON,
SLINGBLADE_WEAPON, // 15
CHICKEN_WEAPON,
MAX_WEAPONS
}
}
struct DukeSnd native
{
// This really needs to be done better...

View file

@ -0,0 +1,218 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
Copyright (C) 2000, 2003 - Matt Saettler (EDuke Enhancements)
Copyright (C) 2020-2021 - Christoph Oelckers
This file is part of Enhanced Duke Nukem 3D version 1.5 - Atomic Edition
Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
EDuke enhancements integrated: 04/13/2003 - Matt Saettler
Note: EDuke source was in transition. Changes are in-progress in the
source as it is released.
*/
//-------------------------------------------------------------------------
class DukeCommonStatusBar : RazeStatusBar
{
HUDFont numberFont;
HUDFont miniFont;
HUDFont digiFont;
double scale;
Array<String> ammo_sprites;
Array<String> item_icons;
int tileHeight(String tex)
{
let img = TexMan.CheckForTexture(tex, TexMan.TYPE_Any);
let siz = TexMan.GetScaledSize(img);
return int(siz.Y);
}
//==========================================================================
//
// Frag bar - todo
//
//==========================================================================
/*
void displayfragbar(void)
{
short i, j;
j = 0;
for (i = connecthead; i >= 0; i = connectpoint2[i])
if (i > j) j = i;
auto tex = tileGetTexture(TILE_FRAGBAR);
for (int y = 0; y < 32; y += 8)
DrawTexture(twod, tex, 0, 0, DTA_FullscreenScale, FSMode_Fit320x200, DTA_ScaleX, 1.001, DTA_ScaleY, 1.001, TAG_Done);
for (i = connecthead; i >= 0; i = connectpoint2[i])
{
m initext(21 + (73 * (i & 3)), 2 + ((i & 28) << 1), &ud.user_name[i][0], ps[i].GetActor().s.pal, 2 + 8 + 16 + 128);
sprintf(tempbuf, "%d", ps[i].frag - ps[i].fraggedself);
m initext(17 + 50 + (73 * (i & 3)), 2 + ((i & 28) << 1), tempbuf, ps[i].GetActor().s.pal, 2 + 8 + 16 + 128);
}
}
*/
//==========================================================================
//
// Common inventory icon code for all styles
//
//==========================================================================
String, int ontext(DukePlayer p)
{
String first = "";
int second = 6;
int onstate = 0x80000000;
switch (p.inven_icon)
{
case Duke.ICON_HOLODUKE:
onstate = p.holoduke_on != null;
break;
case Duke.ICON_JETPACK:
onstate = p.jetpack_on;
break;
case Duke.ICON_HEATS:
onstate = p.heat_on;
break;
}
// Texts are intentionally not translated because the font is too small for making localization work and the translated words are too long.
if (onstate != 0x80000000 && !(gameinfo.gameType & (GAMEFLAG_WW2GI|GAMEFLAG_RRALL)))
{
second = onstate > 0 ? 0 : 2;
first = onstate > 0 ? "ON" : "OFF";
}
if (p.inven_icon >= Duke.ICON_SCUBA)
{
second = 2;
first = "AUTO";
}
return first, second;
}
//==========================================================================
//
// draws the inventory selector
//
//==========================================================================
void DrawInventory(DukePlayer p, double x, double y, int align)
{
if (p.invdisptime <= 0)return;
int n = 0, j = 0;
if (p.firstaid_amount > 0) { n |= 1; j++; }
if (p.steroids_amount > 0) { n |= 2; j++; }
if (p.holoduke_amount > 0) { n |= 4; j++; }
if (p.jetpack_amount > 0) { n |= 8; j++; }
if (p.heat_amount > 0) { n |= 16; j++; }
if (p.scuba_amount > 0) { n |= 32; j++; }
if (p.boot_amount > 0) { n |= 64; j++; }
x -= (j * 11);
y -= 6;
align |= DI_ITEM_CENTER;
for(int bit = 0; bit < 7; bit++)
{
int i = 1 << bit;
if (n & i)
{
int select = 1 << (p.inven_icon - 1);
double alpha = select == i ? 1.0 : 0.7;
DrawImage(item_icons[bit+1], (x, y), align, alpha, scale:(scale, scale));
if (select == i) DrawImage("ARROW", (Raze.isWW2GI()? x + 7.5 : x, Raze.isWW2GI()? y + 0.5 : y), align, alpha, scale:(scale, scale));
x += 22;
}
}
}
//==========================================================================
//
// Statistics output
//
//==========================================================================
void DoLevelStats(int bottomy, SummaryInfo info)
{
StatsPrintInfo stats;
stats.fontscale = Raze.isRR() ? 0.5 : 1.;
stats.screenbottomspace = bottomy;
stats.statfont = SmallFont;
if (Raze.isNamWW2GI())
{
// The stock font of these games is totally unusable for this.
stats.statfont = ConFont;
stats.spacing = ConFont.GetHeight() + 1;
}
if (automapMode == am_full)
{
bool textfont = am_textfont;
if (!am_textfont)
{
// For non-English languages force use of the text font. The tiny one is simply too small to ever add localized characters to it.
let p = StringTable.Localize("$REQUIRED_CHARACTERS");
if (p.length() > 0) textfont = true;
}
if (!textfont)
{
stats.statfont = SmallFont2;
stats.spacing = 6;
}
else stats.spacing = stats.statfont.GetHeight() + 1;
stats.standardColor = (Raze.isNamWW2GI() && am_textfont)? Font.TEXTCOLOR_ORANGE : Font.TEXTCOLOR_UNTRANSLATED;
stats.letterColor = Font.TEXTCOLOR_GOLD;
PrintAutomapInfo(stats, textfont);
}
else if (hud_stats)
{
stats.spacing = Raze.isRR() ? 10 : 7;
stats.letterColor = Font.TEXTCOLOR_ORANGE;
if (Raze.isNamWW2GI())
{
stats.standardColor = Font.TEXTCOLOR_YELLOW;
stats.completeColor = Font.TEXTCOLOR_FIRE;
}
else if (!Raze.isRR())
{
stats.standardColor = Font.TEXTCOLOR_CREAM;
stats.completeColor = Font.TEXTCOLOR_FIRE;
}
else
{
stats.standardColor =
stats.completeColor = Font.TEXTCOLOR_UNTRANSLATED;
}
PrintLevelStats(stats, info);
}
}
}

View file

@ -0,0 +1,479 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
Copyright (C) 2000, 2003 - Matt Saettler (EDuke Enhancements)
Copyright (C) 2020 - Christoph Oelckers
This file is part of Enhanced Duke Nukem 3D version 1.5 - Atomic Edition
Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
EDuke enhancements integrated: 04/13/2003 - Matt Saettler
Note: EDuke source was in transition. Changes are in-progress in the
source as it is released.
*/
//-------------------------------------------------------------------------
class DukeStatusBar : DukeCommonStatusBar
{
int fontheight[2];
TextureID ThreeByFive[12];
HUDFont indxfont;
override void Init()
{
numberFont = HUDFont.Create(BigFont, 0, Mono_Off, 1, 1 );
indxfont = HUDFont.Create(Font.FindFont("IndexFont"), 4, Mono_CellRight, 1, 1 );
miniFont = HUDFont.Create(SmallFont2, 0, Mono_Off, 1, 1 );
digiFont = HUDFont.Create(Font.FindFont("DigiFont"), 1, Mono_Off, 1, 1 );
// optionally draw at the top of the screen.
SetSize(tileHeight("BOTTOMSTATUSBAR"), 320, 200);
scale = 1;
ammo_sprites.PushV("", "AMMO", "SHOTGUNAMMO", "BATTERYAMMO", "RPGAMMO", "HBOMBAMMO", "CRYSTALAMMO", "DEVISTATORAMMO", "TRIPBOMBSPRITE", "FREEZEAMMO1", "HBOMBAMMO", "GROWAMMO", "FLAMETHROWERAMMO1" );
item_icons.PushV("", "FIRSTAID_ICON", "STEROIDS_ICON", "HOLODUKE_ICON", "JETPACK_ICON", "HEAT_ICON", "AIRTANK_ICON", "BOOT_ICON" );
// get the true size of the font.
fontheight[1] = fontheight[0] = 0;
for (int i = 0; i <= 9; i++)
{
let name = String.Format("BIGALPHANUM%d", i);
let zerotex = TexMan.CheckForTexture(name, TexMan.Type_Any);
if (zerotex.IsValid())
{
int fh0 = TexMan.CheckRealHeight(zerotex);
int fh1 = fh0;
let hitex = Raze.PickTexture(zerotex);
if (hitex.IsValid())
{
let osize = TexMan.GetScaledSize(zerotex);
let dsize = TexMan.GetScaledSize(hitex);
int dReal = TexMan.CheckRealHeight(hitex);
fh1 = int(dReal * osize.Y / dsize.Y);
}
if (fh0 > fontheight[0]) fontheight[0] = fh0;
if (fh1 > fontheight[1]) fontheight[1] = fh1;
}
}
for (int i = 0; i <= 11; i++)
{
let str = String.Format("THREEBYFIVE%d", i);
ThreeByFive[i] = TexMan.CheckForTexture(str, TexMan.Type_Any);
}
}
//==========================================================================
//
// Helpers
//
//==========================================================================
int getinvamount(DukePlayer p)
{
switch (p.inven_icon)
{
case Duke.ICON_FIRSTAID:
return p.firstaid_amount;
case Duke.ICON_STEROIDS:
return (p.steroids_amount + 3) >> 2;
case Duke.ICON_HOLODUKE:
return (p.holoduke_amount + 15) / 24;
case Duke.ICON_JETPACK:
return (p.jetpack_amount + 15) >> 4;
case Duke.ICON_HEATS:
return p.heat_amount / 12;
case Duke.ICON_SCUBA:
return (p.scuba_amount + 63) >> 6;
case Duke.ICON_BOOTS:
return p.boot_amount >> 1;
}
return -1;
}
int GetMoraleOrShield(DukePlayer p)
{
// special handling for WW2GI
int lAmount = p.GetGameVar("PLR_MORALE", -1);
if (lAmount == -1) lAmount = p.shield_amount;
return lAmount;
}
//==========================================================================
//
// Fullscreen HUD variant #1
//
//==========================================================================
void FullscreenHUD1(DukePlayer p)
{
int fh = fontheight[hw_hightile ? 1 : 0];
String format;
TextureID img;
double imgScale;
double baseScale = (scale * (fh+1));
double texty = -fh - 2.5;
//
// Health
//
img = TexMan.CheckForTexture(Raze.isNamWW2GI()? "FIRSTAID_ICON" : "COLA");
let siz = TexMan.GetScaledSize(img);
imgScale = baseScale / siz.Y;
DrawTexture(img, (2, -1.5), DI_ITEM_LEFT_BOTTOM, scale:(imgScale, imgScale));
if (!hud_flashing || p.last_extra > (Duke.MaxPlayerHealth() >> 2) || (PlayClock & 32) || (p.IsFrozen() && p.last_extra < 2))
{
int s = -8;
if (hud_flashing && p.last_extra > Duke.MaxPlayerHealth())
s += Raze.bsin(Raze.GetBuildTime() << 5) / 768;
int intens = clamp(255 - 6 * s, 0, 255);
format = String.Format("%d", p.last_extra);
DrawString(numberFont, format, (25, texty), DI_TEXT_ALIGN_LEFT, Font.CR_UNTRANSLATED, intens / 255., 0, 0);
}
//
// Armor
//
img = TexMan.CheckForTexture("SHIELD");
siz = TexMan.GetScaledSize(img);
imgScale = baseScale / siz.Y;
DrawTexture(img, (67.375, -1.5), DI_ITEM_LEFT_BOTTOM, scale:(imgScale, imgScale));
format = String.Format("%d", GetMoraleOrShield(p));
DrawString(numberFont, format, (85, texty), DI_TEXT_ALIGN_LEFT, Font.CR_UNTRANSLATED, 1, 0, 0);
//
// Weapon
//
int weapon = p.curr_weapon;
if (weapon == DukeWpn.HANDREMOTE_WEAPON) weapon = DukeWpn.HANDBOMB_WEAPON;
let wicon = ammo_sprites[weapon];
if (wicon.length() > 0)
{
int ammo = p.ammo_amount[weapon];
if (weapon != DukeWpn.PISTOL_WEAPON || (weapon == DukeWpn.PISTOL_WEAPON && !cl_showmagamt))
{
format = String.Format("%d", ammo);
}
else
{
int clip = CalcMagazineAmount(ammo, Raze.isNam() ? 20 : 12, p.kickback_pic >= 1);
format = String.Format("%d/%d", clip, ammo - clip);
}
img = TexMan.CheckForTexture(wicon, TexMan.TYPE_Any);
siz = TexMan.GetScaledSize(img);
imgScale = baseScale / siz.Y;
let imgX = 20.;
let strlen = format.length();
if (strlen > 1)
{
imgX += (imgX * 0.6) * (strlen - 1);
}
if (weapon != DukeWpn.KNEE_WEAPON && (!hud_flashing || PlayClock & 32 || ammo > (Duke.MaxAmmoAmount(weapon) / 10)))
{
DrawString(numberFont, format, (-3, texty), DI_TEXT_ALIGN_RIGHT, Font.CR_UNTRANSLATED);
}
DrawTexture(img, (-imgX, -1.5), DI_ITEM_RIGHT_BOTTOM, scale:(imgScale, imgScale));
}
//
// Selected inventory item
//
uint icon = p.inven_icon;
if (icon > 0)
{
int x = 128;
if (icon < Duke.ICON_MAX)
{
img = TexMan.CheckForTexture(item_icons[icon], TexMan.TYPE_Any);
siz = TexMan.GetScaledSize(img);
imgScale = baseScale / siz.Y;
DrawTexture(img, (x, -1.5), DI_ITEM_LEFT_BOTTOM, scale:(imgScale, imgScale));
}
int percentv = getinvamount(p);
format = String.Format("%3d%%", percentv);
int color = percentv > 50 ? 11 : percentv > 25 ? 23 : 2;
DrawString(miniFont, format, (x + 36.5, -indxfont.mFont.GetHeight() + 0.5), DI_TEXT_ALIGN_RIGHT, pt:Translation.MakeID(Translation_Remap, color));
String text;
int pal;
[text, pal] = ontext(p);
if (text.length() > 0) DrawString(miniFont, text, (x + 36.5, -miniFont.mFont.GetHeight() - 9.5), DI_TEXT_ALIGN_RIGHT, pt:Translation.MakeID(Translation_Remap, pal));
}
//
// keys
//
if (p.got_access & 1) DrawImage("ACCESSCARD", (-12, -23.5), DI_ITEM_RIGHT, 1, (-1, -1), (0.5, 0.5), STYLE_Translucent, 0xffffffff, Translation.MakeID(Translation_Remap, 0));
if (p.got_access & 4) DrawImage("ACCESSCARD", (-7 , -21.5), DI_ITEM_RIGHT, 1, (-1, -1), (0.5, 0.5), STYLE_Translucent, 0xffffffff, Translation.MakeID(Translation_Remap, 23));
if (p.got_access & 2) DrawImage("ACCESSCARD", (-2 , -19.5), DI_ITEM_RIGHT, 1, (-1, -1), (0.5, 0.5), STYLE_Translucent, 0xffffffff, Translation.MakeID(Translation_Remap, 21));
}
//==========================================================================
//
// Fullscreen HUD variant #2
//
//==========================================================================
void FullscreenHUD2(DukePlayer p)
{
//
// health
//
DrawImage("HEALTHBOX", (5, -2), DI_ITEM_LEFT_BOTTOM, scale:(scale, scale));
int health = p.IsFrozen() ? 1 : p.last_extra;
String format = String.Format("%d", health);
DrawString(digiFont, format, (20, -digiFont.mFont.GetHeight() * scale - 3), DI_TEXT_ALIGN_CENTER, Font.CR_UNTRANSLATED, scale:(scale, scale));
//
// ammo
//
DrawImage("AMMOBOX", (37, -2), DI_ITEM_LEFT_BOTTOM, scale:(scale, scale));
int wp = (p.curr_weapon == DukeWpn.HANDREMOTE_WEAPON) ? DukeWpn.HANDBOMB_WEAPON : p.curr_weapon;
format = String.Format("%d", p.ammo_amount[wp]);
DrawString(digiFont, format, (52, -digiFont.mFont.GetHeight() * scale - 3), DI_TEXT_ALIGN_CENTER, Font.CR_UNTRANSLATED, scale:(scale, scale));
//
// inventory
//
uint icon = p.inven_icon;
if (icon > 0)
{
int x = 73;
DrawImage("INVENTORYBOX", (69, -2), DI_ITEM_LEFT_BOTTOM, scale:(scale, scale));
if (icon < Duke.ICON_MAX)
DrawImage(item_icons[icon], (x, -13.5), DI_ITEM_LEFT|DI_ITEM_VCENTER, scale:(scale, scale));
int percentv = getinvamount(p);
format = String.Format("%3d%%", percentv);
int color = percentv > 50 ? 11 : percentv > 25 ? 23 : 2;
DrawString(miniFont, format, (x + 34, -indxfont.mFont.GetHeight() - 3), DI_TEXT_ALIGN_RIGHT, pt:Translation.MakeID(Translation_Remap, color));
String text;
int pal;
[text, pal] = ontext(p);
if (text.length() > 0) DrawString(miniFont, text, (x + 34, -miniFont.mFont.GetHeight() - 14), DI_TEXT_ALIGN_RIGHT, pt:Translation.MakeID(Translation_Remap, pal));
}
}
//==========================================================================
//
// Fullscreen HUD drawer
//
//==========================================================================
void DrawHud(DukePlayer p, int style, SummaryInfo info)
{
BeginHUD(1, false, 320, 200);
if (style == 1)
{
DrawInventory(p, 0, -46, DI_SCREEN_CENTER_BOTTOM);
FullscreenHUD1(p);
DoLevelStats(tileHeight("BIGALPHANUM") +10, info);
}
else if (style == 2)
{
DrawInventory(p, netgame ? 56 : 65, -28, DI_SCREEN_CENTER_BOTTOM);
FullscreenHUD2(p);
DoLevelStats(tileHeight("HEALTHBOX") + 4, info);
}
else
{
DrawInventory(p, 0, -28, DI_SCREEN_CENTER_BOTTOM);
DoLevelStats(2, info);
}
}
//==========================================================================
//
// Helper for weapon display
//
//==========================================================================
void DrawWeaponNum(int index, double x, double y, int num1, int num2, int shade, int numdigits)
{
/*
if (isShareware() && (ind > DukeWpn.HANDBOMB_WEAPON || ind < 0))
{
minitextshade(x + 1, y - 4, "ORDER", 20, 11, 2 + 8 + 16 + ROTATESPRITE_MAX);
return;
}
*/
String format;
bool parsedDivisor = false;
if (numdigits == 2)
{
if (num1 > 99) num1 = 99;
if (num2 > 99) num2 = 99;
format = String.Format("%2d/%d", num1, num2);
}
else
{
if (num1 > 999) num1 = 999;
if (num2 > 999) num2 = 999;
format = String.Format("%3d/%d", num1, num2);
}
y--;
DrawTexture(ThreeByFive[index], (x - 7, y), DI_ITEM_LEFT|DI_ITEM_VCENTER, 1, (-1, -1), (1, 1), STYLE_Translucent, Raze.ShadeToLight(shade - 10), Translation.MakeID(Translation_Remap, 7));
let pe = Raze.ShadeToLight(shade);
DrawTexture(ThreeByFive[10], (x - 3, y), DI_ITEM_LEFT | DI_ITEM_VCENTER, 1, (-1, -1), (1, 1), STYLE_Translucent, pe);
for (int i = 0; i < format.Length(); i++)
{
int cc = format.ByteAt(i);
if (cc != " ")
{
int c = cc == "/" ? 11 : cc - int("0");
DrawTexture(ThreeByFive[c], (x + 4 * i + (parsedDivisor ? 1 : 0), y), DI_ITEM_LEFT | DI_ITEM_VCENTER, col:pe);
}
if (cc == "/")
{
parsedDivisor = true;
}
}
}
//==========================================================================
//
// Weapon display (Duke only)
//
//==========================================================================
int ShadeForWeapon(DukePlayer p, int weapon, int optweapon = -1)
{
// Headache-inducing math at play here.
return (((!p.ammo_amount[weapon]) | (!p.gotweapon[weapon])) * 9) + 12 - 18 * ((p.curr_weapon == weapon) || (optweapon != -1 && p.curr_weapon == optweapon));
}
void DrawWeaponAmounts(DukePlayer p, double x, double y)
{
int cw = p.curr_weapon;
DrawWeaponNum(2, x, y, p.ammo_amount[DukeWpn.PISTOL_WEAPON], Duke.MaxAmmoAmount(DukeWpn.PISTOL_WEAPON), 12 - 20 * (cw == DukeWpn.PISTOL_WEAPON), 3);
DrawWeaponNum(3, x, y + 6, p.ammo_amount[DukeWpn.SHOTGUN_WEAPON], Duke.MaxAmmoAmount(DukeWpn.SHOTGUN_WEAPON), ShadeForWeapon(p, DukeWpn.SHOTGUN_WEAPON), 3);
DrawWeaponNum(4, x, y + 12, p.ammo_amount[DukeWpn.CHAINGUN_WEAPON], Duke.MaxAmmoAmount(DukeWpn.CHAINGUN_WEAPON), ShadeForWeapon(p, DukeWpn.CHAINGUN_WEAPON), 3);
DrawWeaponNum(5, x + 39, y, p.ammo_amount[DukeWpn.RPG_WEAPON], Duke.MaxAmmoAmount(DukeWpn.RPG_WEAPON), ShadeForWeapon(p, DukeWpn.RPG_WEAPON), 2);
DrawWeaponNum(6, x + 39, y + 6, p.ammo_amount[DukeWpn.HANDBOMB_WEAPON], Duke.MaxAmmoAmount(DukeWpn.HANDBOMB_WEAPON), ShadeForWeapon(p, DukeWpn.HANDBOMB_WEAPON, DukeWpn.HANDREMOTE_WEAPON), 2);
if (p.subweapon & (1 << DukeWpn.GROW_WEAPON)) // original code says: if(!p.ammo_amount[SHRINKER_WEAPON] || cw == GROW_WEAPON)
DrawWeaponNum(7, x + 39, y + 12, p.ammo_amount[DukeWpn.GROW_WEAPON], Duke.MaxAmmoAmount(DukeWpn.GROW_WEAPON), ShadeForWeapon(p, DukeWpn.GROW_WEAPON), 2);
else
DrawWeaponNum(7, x + 39, y + 12, p.ammo_amount[DukeWpn.SHRINKER_WEAPON], Duke.MaxAmmoAmount(DukeWpn.SHRINKER_WEAPON), ShadeForWeapon(p, DukeWpn.SHRINKER_WEAPON), 2);
DrawWeaponNum(8, x + 70, y, p.ammo_amount[DukeWpn.DEVISTATOR_WEAPON], Duke.MaxAmmoAmount(DukeWpn.DEVISTATOR_WEAPON), ShadeForWeapon(p, DukeWpn.DEVISTATOR_WEAPON), 2);
DrawWeaponNum(9, x + 70, y + 6, p.ammo_amount[DukeWpn.TRIPBOMB_WEAPON], Duke.MaxAmmoAmount(DukeWpn.TRIPBOMB_WEAPON), ShadeForWeapon(p, DukeWpn.TRIPBOMB_WEAPON), 2);
DrawWeaponNum(0, x + 70, y + 12, p.ammo_amount[DukeWpn.FREEZE_WEAPON], Duke.MaxAmmoAmount(DukeWpn.FREEZE_WEAPON), ShadeForWeapon(p, DukeWpn.FREEZE_WEAPON), 2);
}
//==========================================================================
//
// Status bar drawer
//
//==========================================================================
void Statusbar(DukePlayer p)
{
let bsb = TexMan.CheckForTexture("BOTTOMSTATUSBAR", Texman.Type_Any);
let siz = TexMan.GetScaledSize(bsb);
int h = int(siz.Y);
int top = 200 - h;
int left = (320 - int(siz.X)) / 2;
BeginStatusBar(false, 320, 200, h);
DrawInventory(p, 160, 154, 0);
if (hud_size == Hud_StbarOverlay) Set43ClipRect();
DrawTexture(bsb, (left, top), DI_ITEM_LEFT_TOP, 1);
screen.ClearClipRect();
String format;
/*
if (ud.multimode > 1 && !ud.coop)
{
DrawTexture("KILLSICON", (228, top + 8), DI_ITEM_OFFSETS, 1, 0, 0);
format = String.Format("%d", max(p.frag - p.fraggedself, 0));
DrawString(digiFont, format, (287, top + 17), DI_TEXT_ALIGN_CENTER);
}
else*/
{
let key = TexMan.CheckForTexture("ACCESS_ICON", TexMan.Type_Any);
if (p.got_access & 4) DrawTexture(key, (275.5, top + 16), DI_ITEM_OFFSETS, style:STYLE_Translucent, translation:Translation.MakeID(Translation_Remap, 23));
if (p.got_access & 2) DrawTexture(key, (288.5, top + 16), DI_ITEM_OFFSETS, style:STYLE_Translucent, translation:Translation.MakeID(Translation_Remap, 21));
if (p.got_access & 1) DrawTexture(key, (282, top + 23), DI_ITEM_OFFSETS, style:STYLE_Translucent, translation:Translation.MakeID(Translation_Remap, 0));
}
DrawWeaponAmounts(p, 96, top + 15.5);
int num = (p.IsFrozen()) ? 1 : p.last_extra;
format = String.Format("%d", num);
DrawString(digiFont, format, (31, top + 17), DI_TEXT_ALIGN_CENTER);
format = String.Format("%d", GetMoraleOrShield(p));
DrawString(digiFont, format, (63, top + 17), DI_TEXT_ALIGN_CENTER);
if (p.curr_weapon != DukeWpn.KNEE_WEAPON)
{
int wep = (p.curr_weapon == DukeWpn.HANDREMOTE_WEAPON)? DukeWpn.HANDBOMB_WEAPON : p.curr_weapon;
format = String.Format("%d", p.ammo_amount[wep]);
DrawString(digiFont, format, (207, top + 17), DI_TEXT_ALIGN_CENTER);
}
int icon = p.inven_icon;
if (icon)
{
int x = 232;
if (icon < Duke.ICON_MAX)
DrawImage(item_icons[icon], (x, top + 20.5), DI_ITEM_LEFT | DI_ITEM_VCENTER);
int percentv = getinvamount(p);
format = String.Format("%3d%%", percentv);
int color = percentv > 50 ? 11 : percentv > 25 ? 23 : 2;
DrawString(miniFont, format, (x + 34, top + 24), DI_TEXT_ALIGN_RIGHT, Font.CR_UNDEFINED, 1, 0, 0, (1, 1), Translation.MakeID(Translation_Remap, color));
String text;
int pal;
[text, pal] = ontext(p);
if (text.length() > 0) DrawString(miniFont, text, (x + 34, top + 14), DI_TEXT_ALIGN_RIGHT, Font.CR_UNDEFINED, 1, 0, 0, (1, 1), Translation.MakeID(Translation_Remap, pal));
}
}
override void UpdateStatusBar(SummaryInfo info)
{
let p = Duke.GetViewPlayer();
if (hud_size >= Hud_Mini)
{
DrawHud(p, hud_size == Hud_Nothing ? 0 : hud_size == Hud_full ? 1 : 2, info);
}
else
{
Statusbar(p);
DoLevelStats(-1, info);
}
}
}

View file

@ -0,0 +1,448 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
Copyright (C) 2020 - Christoph Oelckers
This file is part of Enhanced Duke Nukem 3D version 1.5 - Atomic Edition
Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------
class RedneckStatusBar : DukeCommonStatusBar
{
override void Init()
{
numberFont = HudFont.Create(BigFont, 0, Mono_Off, 1, 1 );
miniFont = HudFont.Create(SmallFont2, 0, Mono_Off, 1, 1 );
digiFont = HudFont.Create(Font.FindFont("DigiFont"), 2, Mono_Off, 1, 1 );
// optionally draw at the top of the screen.
SetSize(tileHeight("BOTTOMSTATUSBAR"), 320, 200);
scale = 0.5;
ammo_sprites.PushV("", "AMMO", "SHOTGUNAMMO", "BATTERYAMMO", "HBOMBAMMO", "HBOMBAMMO", "SAWAMMO", "DEVISTATORAMMO",
"TRIPBOMBSPRITE", "GROWSPRITEICON", "HBOMBAMMO", "", "BOWLINGBALLSPRITE", "MOTOAMMO", "BOATAMMO", "", "RPG2SPRITE");
item_icons.PushV("", "FIRSTAID_ICON", "STEROIDS_ICON", "HOLODUKE_ICON", "JETPACK_ICON", "HEAT_ICON", "AIRTANK_ICON", "BOOT_ICON" );
}
int getinvamount(DukePlayer p)
{
switch (p.inven_icon)
{
case Duke.ICON_FIRSTAID:
return p.firstaid_amount;
case Duke.ICON_STEROIDS:
return (p.steroids_amount + 3) >> 2;
case Duke.ICON_HOLODUKE:
return (p.holoduke_amount) / 400;
case Duke.ICON_JETPACK:
return (p.jetpack_amount) / 100;
case Duke.ICON_HEATS:
return p.heat_amount / 12;
case Duke.ICON_SCUBA:
return (p.scuba_amount + 63) >> 6;
case Duke.ICON_BOOTS:
return (p.boot_amount / 10) >> 1;
}
return -1;
}
//==========================================================================
//
// Fullscreen HUD variant #1 for RR
//
//==========================================================================
void FullscreenHUD1(DukePlayer p)
{
String format;
TextureID img;
double imgScale;
double baseScale = (scale * numberFont.mFont.GetHeight()) * 0.76;
//
// Health
//
img = TexMan.CheckForTexture("SPINNINGNUKEICON1");
let siz = TexMan.GetScaledSize(img);
imgScale = baseScale / siz.Y;
DrawTexture(img, (2, -2), DI_ITEM_LEFT_BOTTOM, scale:(imgScale, imgScale));
if (!hud_flashing || p.last_extra > (Duke.MaxPlayerHealth() >> 2) || (PlayClock & 32) || (p.IsFrozen() && p.last_extra < 2))
{
int s = -8;
if (hud_flashing && p.last_extra > Duke.MaxPlayerHealth())
s += Raze.bsin(Raze.GetBuildTime() << 5) / 768;
int intens = clamp(255 - 6 * s, 0, 255);
format = String.Format("%d", p.last_extra);
DrawString(numberFont, format, (26.5, -numberFont.mFont.GetHeight() * scale + 4), DI_TEXT_ALIGN_LEFT, Font.CR_UNTRANSLATED, intens / 255., 0, 0, (scale, scale));
}
//
// drink
//
img = TexMan.CheckForTexture("BEER");
siz = TexMan.GetScaledSize(img);
imgScale = baseScale / siz.Y;
DrawTexture(img, (74, -2), DI_ITEM_LEFT_BOTTOM, scale:(imgScale, imgScale));
format = String.Format("%d", p.drink_amt);
DrawString(numberFont, format, (86, -numberFont.mFont.GetHeight() * scale + 4), DI_TEXT_ALIGN_LEFT, scale:(scale, scale));
//
// eat
//
img = TexMan.CheckForTexture("COWPIE");
siz = TexMan.GetScaledSize(img);
imgScale = baseScale / siz.Y;
DrawTexture(img, (133.5, -2), DI_ITEM_LEFT_BOTTOM, scale:(imgScale, imgScale));
format = String.Format("%d", p.eat);
DrawString(numberFont, format, (173, -numberFont.mFont.GetHeight() * scale + 4), DI_TEXT_ALIGN_LEFT, scale:(scale, scale));
//
// selected weapon
//
int weapon = p.curr_weapon;
if (weapon == RRWpn.THROWINGDYNAMITE_WEAPON) weapon = RRWpn.DYNAMITE_WEAPON;
let wicon = ammo_sprites[weapon];
if (wicon.length() > 0)
{
int ammo = p.ammo_amount[weapon];
bool reloadableWeapon = weapon == RRWpn.PISTOL_WEAPON || weapon == RRWpn.SHOTGUN_WEAPON;
if (!reloadableWeapon || (reloadableWeapon && !cl_showmagamt))
{
format = String.Format("%d", ammo);
}
else
{
int clip;
switch (weapon)
{
case RRWpn.PISTOL_WEAPON:
clip = CalcMagazineAmount(ammo, 6, p.kickback_pic >= 1);
break;
case RRWpn.SHOTGUN_WEAPON:
clip = CalcMagazineAmount(ammo, 2, p.kickback_pic >= 4);
break;
}
format = String.Format("%d/%d", clip, ammo - clip);
}
img = TexMan.CheckForTexture(wicon, TexMan.TYPE_Any);
siz = TexMan.GetScaledSize(img);
imgScale = baseScale / siz.Y;
let imgX = 22.5;
let strlen = format.Length();
if (strlen > 1)
{
imgX += (imgX * 0.755) * (strlen - 1);
}
if (weapon != RRWpn.KNEE_WEAPON && weapon != RRWpn.SLINGBLADE_WEAPON && (!hud_flashing || PlayClock & 32 || ammo > (Duke.MaxAmmoAmount(weapon) / 10)))
{
DrawString(numberFont, format, (-1, -numberFont.mFont.GetHeight() * scale + 4), DI_TEXT_ALIGN_RIGHT, scale:(scale, scale));
}
DrawTexture(img, (-imgX, -2), DI_ITEM_RIGHT_BOTTOM, scale:(imgScale, imgScale));
}
//
// Selected inventory item
//
uint icon = p.inven_icon;
if (icon > 0)
{
int x = -130;
if (icon < Duke.ICON_MAX)
{
img = TexMan.CheckForTexture(item_icons[icon], TexMan.TYPE_Any);
siz = TexMan.GetScaledSize(img);
imgScale = baseScale / siz.Y;
DrawTexture(img, (x, -2), DI_ITEM_RIGHT_BOTTOM, scale:(imgScale, imgScale));
}
int percentv = getinvamount(p);
if (icon <= 2) format = String.Format("%d%%", percentv);
else format = String.Format("%d", percentv);
DrawString(miniFont, format, (x + 19, -miniFont.mFont.GetHeight() * scale - 1), DI_TEXT_ALIGN_RIGHT, scale:(scale, scale));
let text = ontext(p);
if (text.length() > 0) DrawString(miniFont, text, (x + 20, -miniFont.mFont.GetHeight() * scale - 15), DI_TEXT_ALIGN_RIGHT, scale:(scale, scale));
}
//
// keys
//
if (p.keys[1]) DrawImage("ACCESSCARD", (-28.5, -32 ), DI_ITEM_BOTTOM, 1, (-1, -1), (scale, scale), STYLE_Translucent, 0xffffffff, Translation.MakeID(Translation_Remap, 0));
if (p.keys[3]) DrawImage("ACCESSCARD", (-21.25, -28.375), DI_ITEM_BOTTOM, 1, (-1, -1), (scale, scale), STYLE_Translucent, 0xffffffff, Translation.MakeID(Translation_Remap, 23));
if (p.keys[2]) DrawImage("ACCESSCARD", (-14, -24.75 ), DI_ITEM_BOTTOM, 1, (-1, -1), (scale, scale), STYLE_Translucent, 0xffffffff, Translation.MakeID(Translation_Remap, 21));
}
//==========================================================================
//
// Fullscreen HUD variant #2 for RR
//
//==========================================================================
void FullscreenHUD2(DukePlayer p)
{
//
// health
//
DrawImage("HEALTHBOX", (2, -2), DI_ITEM_LEFT_BOTTOM, scale:(scale, scale));
int health = p.IsFrozen() ? 1 : p.last_extra;
String format = String.Format("%d", health);
DrawString(digiFont, format, (21.5, -digiFont.mFont.GetHeight() * scale - 5.5), DI_TEXT_ALIGN_CENTER, scale:(scale, scale));
//
// ammo
//
DrawImage("AMMOBOX", (37, -2), DI_ITEM_LEFT_BOTTOM, scale:(scale, scale));
int wp = p.curr_weapon == RRWpn.THROWINGDYNAMITE_WEAPON? RRWpn.DYNAMITE_WEAPON : p.curr_weapon;
format = String.Format("%d", p.ammo_amount[wp]);
DrawString(digiFont, format, (60.25, -digiFont.mFont.GetHeight() * scale - 5.5), DI_TEXT_ALIGN_CENTER, scale:(scale, scale));
//
// inventory
//
uint icon = p.inven_icon;
if (icon > 0)
{
int x = 84;
DrawImage("INVENTORYBOX", (69, -2), DI_ITEM_LEFT_BOTTOM, scale:(scale, scale));
if (icon < Duke.ICON_MAX)
DrawImage(item_icons[icon], (x, -15.375), DI_ITEM_LEFT|DI_ITEM_VCENTER, scale:(scale, scale));
int percentv = getinvamount(p);
if (icon <= 2) format = String.Format("%d%%", percentv);
else format = String.Format("%d", percentv);
DrawString(miniFont, format, (x + 31.5, -miniFont.mFont.GetHeight() * scale - 6.5), DI_TEXT_ALIGN_RIGHT, scale:(scale, scale));
}
}
//==========================================================================
//
// Fullscreen HUD drawer
//
//==========================================================================
void DrawHud(DukePlayer p, int style, SummaryInfo info)
{
BeginHUD(320, 200, 1.f);
if (style == 1)
{
double y = -40;
//if (ud.multimode > 1) y -= 4;
//if (ud.multimode > 4) y -= 4;
DrawInventory(p, 0, y, DI_SCREEN_CENTER_BOTTOM);
FullscreenHUD1(p);
DoLevelStats(int(scale * tileHeight("BIGALPHANUM") + 10), info);
}
else if (style == 2)
{
DrawInventory(p, 56, -20, DI_SCREEN_CENTER_BOTTOM);
FullscreenHUD2(p);
DoLevelStats(int(scale * tileHeight("HEALTHBOX") + 4), info);
}
else
{
DrawInventory(p, 0, -20, DI_SCREEN_CENTER_BOTTOM);
DoLevelStats(2, info);
}
}
//==========================================================================
//
// Status bar drawer (RR)
//
//==========================================================================
void DrawWeaponBar(DukePlayer p, int top)
{
double sbscale = 32800. / 65536.;
DrawImage("WEAPONBAR", (0, 158), DI_ITEM_OFFSETS, scale:(sbscale, sbscale));
for (int i = 0; i < 9; i++)
{
String format, texname;
if ((gameinfo.gameType & GAMEFLAG_RRRA) && i == 4 && p.curr_weapon == RRWpn.CHICKEN_WEAPON)
{
texname = "AMMO_ICON10";
format = String.Format("%d", p.ammo_amount[RRWpn.CHICKEN_WEAPON]);
}
else
{
if (p.gotweapon[i+1])
{
texname = "AMMO_ICON" .. i;
format = String.Format("%d", p.ammo_amount[i+1]);
}
}
DrawImage(texname, (18 + i * 32, top - 6.5), DI_ITEM_OFFSETS, scale:(sbscale, sbscale));
if (format.Length())
{
DrawString(miniFont, format, (38 + i * 32, 162.75 - miniFont.mFont.GetHeight() * scale * 0.5), DI_TEXT_ALIGN_CENTER, scale:(scale * .875, scale * .875));
}
}
}
//==========================================================================
//
// Status bar drawer (RR)
//
//==========================================================================
void Statusbar(DukePlayer p)
{
let bsb = TexMan.CheckForTexture("BOTTOMSTATUSBAR", Texman.Type_Any);
let siz = TexMan.GetScaledSize(bsb);
double wh = 0;
if (hud_size < Hud_Stbar) wh = tileHeight("WEAPONBAR") * scale;
double h = siz.Y;
double top = 200 - h;
int left = (320 - int(siz.X)) / 2;
BeginStatusBar(false, 320, 200, int(wh + h));
DrawInventory(p, 160, hud_size <= Hud_Stbar? 148 : 154, 0);
if (hud_size <= Hud_Stbar)
DrawWeaponBar(p, int(top));
if (hud_size == Hud_StbarOverlay) Set43ClipRect();
DrawTexture(bsb, (left, top), DI_ITEM_LEFT_TOP, scale:(scale, scale));
screen.ClearClipRect();
String format;
/*
if (ud.multimode > 1 && !ud.coop)
{
DrawTexture("KILLSICON", (228, top + 8), DI_ITEM_OFFSETS, 1, 0, 0);
format = String.Format("%d", max(p.frag - p.fraggedself, 0));
DrawString(digiFont, format, (287, top + 17), DI_TEXT_ALIGN_CENTER, Font.CR_UNTRANSLATED, 1, 0, 0, (scale, scale));
}
else*/
{
let key = TexMan.CheckForTexture("ACCESS_ICON", TexMan.Type_Any);
if (p.keys[3]) DrawTexture(key, (138, top + 13), DI_ITEM_OFFSETS, 1, (-1, -1), (scale, scale), STYLE_Translucent, 0xffffffff, Translation.MakeID(Translation_Remap, 23));
if (p.keys[2]) DrawTexture(key, (152, top + 13), DI_ITEM_OFFSETS, 1, (-1, -1), (scale, scale), STYLE_Translucent, 0xffffffff, Translation.MakeID(Translation_Remap, 21));
if (p.keys[1]) DrawTexture(key, (145, top + 21), DI_ITEM_OFFSETS, 1, (-1, -1), (scale, scale), STYLE_Translucent, 0xffffffff, Translation.MakeID(Translation_Remap, 0));
}
int num = (p.IsFrozen()) ? 1 : p.last_extra;
format = String.Format("%d", num);
DrawString(digiFont, format, (66.5, top + 16), DI_TEXT_ALIGN_CENTER, scale:(scale, scale));
if (p.curr_weapon != RRWpn.KNEE_WEAPON)
{
int wep = (p.curr_weapon == RRWpn.THROWINGDYNAMITE_WEAPON) ? RRWpn.DYNAMITE_WEAPON : p.curr_weapon;
format = String.Format("%d", p.ammo_amount[wep]);
DrawString(digiFont, format, (110, top + 16), DI_TEXT_ALIGN_CENTER, scale:(scale, scale));
}
int icon = p.inven_icon;
if (icon)
{
int x = 182;
if (icon < Duke.ICON_MAX)
DrawImage(item_icons[icon], (x, top + 20.125), DI_ITEM_LEFT | DI_ITEM_VCENTER, scale:(scale, scale));
int percentv = getinvamount(p);
if (icon <= 2) format = String.Format("%d%%", percentv);
else format = String.Format("%d", percentv);
DrawString(miniFont, format, (x + 38, top + 23.5), DI_TEXT_ALIGN_RIGHT, scale:(scale, scale));
if (p.inven_icon == Duke.ICON_SCUBA || p.inven_icon == Duke.ICON_BOOTS)
DrawString(miniFont, "AUTO", (x + 39, top + 13), DI_TEXT_ALIGN_RIGHT, scale:(scale, scale));
}
p.drunkang = ((p.drink_amt * 8) + 1647) & 2047;
if (p.drink_amt >= 100)
{
p.drink_amt = 100;
p.drunkang = 400;
}
DrawImageRotated("GUTMETER", (256, top + 15), DI_ITEM_RELCENTER, p.drunkang * -Raze.BAngToDegree, 1, (scale, scale), 0xffffffff, 0);
DrawImageRotated("GUTMETER", (292, top + 15), DI_ITEM_RELCENTER, p.eatang * -Raze.BAngToDegree, 1, (scale, scale), 0xffffffff, 0);
if (p.drink_amt >= 0 && p.drink_amt <= 30)
{
DrawImage("GUTMETER_LIGHT1", (239, top + 24), DI_ITEM_OFFSETS, scale:(scale, scale));
}
else if (p.drink_amt >= 31 && p.drink_amt <= 65)
{
DrawImage("GUTMETER_LIGHT2", (248, top + 24), DI_ITEM_OFFSETS, scale:(scale, scale));
}
else if (p.drink_amt >= 66 && p.drink_amt <= 87)
{
DrawImage("GUTMETER_LIGHT3", (256, top + 24), DI_ITEM_OFFSETS, scale:(scale, scale));
}
else
{
DrawImage("GUTMETER_LIGHT4", (265, top + 24), DI_ITEM_OFFSETS, scale:(scale, scale));
}
if (p.eat >= 0 && p.eat <= 30)
{
DrawImage("GUTMETER_LIGHT1", (276, top + 24), DI_ITEM_OFFSETS, scale:(scale, scale));
}
else if (p.eat >= 31 && p.eat <= 65)
{
DrawImage("GUTMETER_LIGHT2", (285, top + 24), DI_ITEM_OFFSETS, scale:(scale, scale));
}
else if (p.eat >= 66 && p.eat <= 87)
{
DrawImage("GUTMETER_LIGHT3", (294, top + 24), DI_ITEM_OFFSETS, scale:(scale, scale));
}
else
{
DrawImage("GUTMETER_LIGHT4", (302, top + 24), DI_ITEM_OFFSETS, scale:(scale, scale));
}
}
override void UpdateStatusBar(SummaryInfo info)
{
let p = Duke.GetViewPlayer();
if (hud_size >= Hud_Mini)
{
DrawHud(p, hud_size == Hud_Nothing ? 0 : hud_size == Hud_full ? 1 : 2, info);
}
else
{
Statusbar(p);
DoLevelStats(-1, info);
}
}
}

View file

@ -135,6 +135,7 @@ struct SummaryInfo native
struct Raze
{
const kAngleMask = 0x7FF;
const BAngToDegree = 360. / 2048.;
static int calcSinTableValue(int ang)
{
@ -150,6 +151,8 @@ struct Raze
native static double GetTimeFrac();
native static int bsin(int angle, int shift = 0);
native static int bcos(int angle, int shift = 0);
native static TextureID PickTexture(TextureID texid);
native static int GetBuildTime();
static bool specialKeyEvent(InputEvent ev)
{
@ -247,13 +250,13 @@ class BaseStatusBar : StatusBarCore native
{}
class DukeCommonStatusBar : BaseStatusBar native
class NativeDukeCommonStatusBar : BaseStatusBar native
{}
class DukeStatusBar : DukeCommonStatusBar native
class NativeDukeStatusBar : NativeDukeCommonStatusBar native
{}
class RedneckStatusBar : DukeCommonStatusBar native
class NativeRedneckStatusBar : NativeDukeCommonStatusBar native
{}
class SWStatusBar : BaseStatusBar native