mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-23 04:22:34 +00:00
- AltHUD ammo drawer scriptified.
This commit is contained in:
parent
0cd93c14af
commit
fbc441673a
3 changed files with 191 additions and 155 deletions
|
@ -251,162 +251,18 @@ static int DrawKeys(player_t * CPlayer, int x, int y)
|
|||
// Drawing Ammo
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
static TArray<PClassActor *> orderedammos;
|
||||
|
||||
static void AddAmmoToList(AInventory * weapdef)
|
||||
{
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
auto ti = weapdef->PointerVar<PClassActor>(i == 0 ? NAME_AmmoType1 : NAME_AmmoType2);
|
||||
if (ti)
|
||||
{
|
||||
auto ammodef = (AInventory*)GetDefaultByType(ti);
|
||||
|
||||
if (ammodef && !(ammodef->ItemFlags&IF_INVBAR))
|
||||
{
|
||||
unsigned int j;
|
||||
|
||||
for (j = 0; j < orderedammos.Size(); j++)
|
||||
{
|
||||
if (ti == orderedammos[j]) break;
|
||||
}
|
||||
if (j == orderedammos.Size()) orderedammos.Push(ti);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int GetDigitCount(int value)
|
||||
{
|
||||
int digits = 0;
|
||||
|
||||
do
|
||||
{
|
||||
value /= 10;
|
||||
++digits;
|
||||
}
|
||||
while (0 != value);
|
||||
|
||||
return digits;
|
||||
}
|
||||
|
||||
static void GetAmmoTextLengths(player_t *CPlayer, int& ammocur, int& ammomax)
|
||||
{
|
||||
for (auto type : orderedammos)
|
||||
{
|
||||
auto ammoitem = CPlayer->mo->FindInventory(type);
|
||||
auto inv = nullptr == ammoitem
|
||||
? static_cast<AInventory*>(GetDefaultByType(type))
|
||||
: ammoitem;
|
||||
assert(nullptr != inv);
|
||||
|
||||
ammocur = MAX(ammocur, nullptr == ammoitem ? 0 : ammoitem->Amount);
|
||||
ammomax = MAX(ammomax, inv->MaxAmount);
|
||||
}
|
||||
|
||||
ammocur = GetDigitCount(ammocur);
|
||||
ammomax = GetDigitCount(ammomax);
|
||||
}
|
||||
|
||||
static int DrawAmmo(player_t *CPlayer, int x, int y)
|
||||
{
|
||||
|
||||
int i,j,k;
|
||||
char buf[256];
|
||||
AInventory *inv;
|
||||
|
||||
auto wi=CPlayer->ReadyWeapon;
|
||||
|
||||
orderedammos.Clear();
|
||||
|
||||
if (0 == hud_showammo)
|
||||
IFVM(AltHud, DrawAmmo)
|
||||
{
|
||||
// Show ammo for current weapon if any
|
||||
if (wi) AddAmmoToList(wi);
|
||||
VMValue params[] = { althud, CPlayer, x, y };
|
||||
int retv;
|
||||
VMReturn ret(&retv);
|
||||
VMCall(func, params, countof(params), &ret, 1);
|
||||
return retv;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Order ammo by use of weapons in the weapon slots
|
||||
for (k = 0; k < NUM_WEAPON_SLOTS; k++) for(j = 0; j < CPlayer->weapons.SlotSize(k); j++)
|
||||
{
|
||||
PClassActor *weap = CPlayer->weapons.GetWeapon(k, j);
|
||||
|
||||
if (weap)
|
||||
{
|
||||
// Show ammo for available weapons if hud_showammo CVAR is 1
|
||||
// or show ammo for all weapons if hud_showammo is greater than 1
|
||||
|
||||
if (hud_showammo > 1 || CPlayer->mo->FindInventory(weap))
|
||||
{
|
||||
AddAmmoToList((AInventory*)GetDefaultByType(weap));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now check for the remaining weapons that are in the inventory but not in the weapon slots
|
||||
for(inv=CPlayer->mo->Inventory;inv;inv=inv->Inventory)
|
||||
{
|
||||
if (inv->IsKindOf(NAME_Weapon))
|
||||
{
|
||||
AddAmmoToList(inv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ok, we got all ammo types. Now draw the list back to front (bottom to top)
|
||||
|
||||
int ammocurlen = 0;
|
||||
int ammomaxlen = 0;
|
||||
GetAmmoTextLengths(CPlayer, ammocurlen, ammomaxlen);
|
||||
|
||||
mysnprintf(buf, countof(buf), "%0*d/%0*d", ammocurlen, 0, ammomaxlen, 0);
|
||||
|
||||
int def_width = ConFont->StringWidth(buf);
|
||||
int yadd = ConFont->GetHeight();
|
||||
|
||||
int xtext = x - def_width;
|
||||
int ximage = x;
|
||||
|
||||
if (hud_ammo_order > 0)
|
||||
{
|
||||
xtext -= 24;
|
||||
ximage -= 20;
|
||||
}
|
||||
else
|
||||
{
|
||||
ximage -= def_width + 20;
|
||||
}
|
||||
|
||||
for(i=orderedammos.Size()-1;i>=0;i--)
|
||||
{
|
||||
|
||||
auto type = orderedammos[i];
|
||||
auto ammoitem = CPlayer->mo->FindInventory(type);
|
||||
|
||||
auto inv = ammoitem? ammoitem : (AInventory*)GetDefaultByType(orderedammos[i]);
|
||||
FTextureID AltIcon = inv->AltHUDIcon;
|
||||
FTextureID icon = !AltIcon.isNull()? AltIcon : inv->Icon;
|
||||
if (!icon.isValid()) continue;
|
||||
|
||||
double trans= (wi && (type==wi->PointerVar<PClassActor>(NAME_AmmoType1) || type==wi->PointerVar<PClassActor>(NAME_AmmoType2))) ? 0.75 : 0.375;
|
||||
|
||||
int maxammo = inv->MaxAmount;
|
||||
int ammo = ammoitem? ammoitem->Amount : 0;
|
||||
|
||||
mysnprintf(buf, countof(buf), "%*d/%*d", ammocurlen, ammo, ammomaxlen, maxammo);
|
||||
|
||||
int tex_width= clamp<int>(ConFont->StringWidth(buf)-def_width, 0, 1000);
|
||||
|
||||
int fontcolor=( !maxammo ? CR_GRAY :
|
||||
ammo < ( (maxammo * hud_ammo_red) / 100) ? CR_RED :
|
||||
ammo < ( (maxammo * hud_ammo_yellow) / 100) ? CR_GOLD : CR_GREEN );
|
||||
|
||||
DrawHudText(ConFont, fontcolor, buf, xtext-tex_width, y+yadd, trans);
|
||||
DrawImageToBox(TexMan[icon], ximage, y, 16, 8, trans);
|
||||
y-=10;
|
||||
}
|
||||
return y;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1111,8 +1111,8 @@ class WeaponGiver : Weapon
|
|||
|
||||
struct WeaponSlots native
|
||||
{
|
||||
native bool, int, int LocateWeapon(class<Weapon> weap);
|
||||
native bool, int, int LocateWeapon(class<Weapon> weap) const;
|
||||
native static void SetupWeaponSlots(PlayerPawn pp);
|
||||
native class<Weapon> GetWeapon(int slot, int index);
|
||||
native int SlotSize(int slot);
|
||||
native class<Weapon> GetWeapon(int slot, int index) const;
|
||||
native int SlotSize(int slot) const;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,8 @@ class AltHud
|
|||
int statspace;
|
||||
Font HudFont; // The font for the health and armor display
|
||||
Font IndexFont; // The font for the inventory indices
|
||||
|
||||
Array< Class<Ammo> > orderedammos;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Draws an image into a box with its bottom center at the bottom
|
||||
|
@ -346,4 +347,183 @@ class AltHud
|
|||
return y - 11;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Drawing Ammo helpers
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void AddAmmoToList(readonly<Weapon> weapdef)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
let ti = i == 0? weapdef.AmmoType1 : weapdef.AmmoType2;
|
||||
if (ti)
|
||||
{
|
||||
let ammodef = GetDefaultByType(ti);
|
||||
|
||||
if (ammodef && !ammodef.bInvBar)
|
||||
{
|
||||
if (orderedAmmos.Find(ti) == orderedAmmos.Size())
|
||||
{
|
||||
orderedammos.Push(ti);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int GetDigitCount(int value)
|
||||
{
|
||||
int digits = 0;
|
||||
|
||||
do
|
||||
{
|
||||
value /= 10;
|
||||
++digits;
|
||||
}
|
||||
while (0 != value);
|
||||
|
||||
return digits;
|
||||
}
|
||||
|
||||
int, int GetAmmoTextLengths(PlayerInfo CPlayer)
|
||||
{
|
||||
int tammomax = 0, tammocur = 0;
|
||||
for(int i = 0; i < orderedammos.Size(); i++)
|
||||
{
|
||||
let type = orderedammos[i];
|
||||
let ammoitem = CPlayer.mo.FindInventory(type);
|
||||
int ammomax, ammocur;
|
||||
if (ammoitem == null)
|
||||
{
|
||||
ammomax = GetDefaultByType(type).MaxAmount;
|
||||
ammocur = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ammomax = ammoitem.MaxAmount;
|
||||
ammocur = ammoItem.Amount;
|
||||
}
|
||||
|
||||
tammocur = MAX(ammocur, tammocur);
|
||||
tammomax = MAX(ammomax, tammomax);
|
||||
}
|
||||
return GetDigitCount(tammocur), GetDigitCount(tammomax);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Drawing Ammo
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
int DrawAmmo(PlayerInfo CPlayer, int x, int y)
|
||||
{
|
||||
|
||||
int i,j,k;
|
||||
String buf;
|
||||
Inventory inv;
|
||||
|
||||
let wi = CPlayer.ReadyWeapon;
|
||||
|
||||
orderedammos.Clear();
|
||||
|
||||
if (0 == hud_showammo)
|
||||
{
|
||||
// Show ammo for current weapon if any
|
||||
if (wi) AddAmmoToList(wi.default);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Order ammo by use of weapons in the weapon slots
|
||||
for (k = 0; k < PlayerPawn.NUM_WEAPON_SLOTS; k++)
|
||||
{
|
||||
int slotsize = CPlayer.weapons.SlotSize(k);
|
||||
for(j = 0; j < slotsize; j++)
|
||||
{
|
||||
let weap = CPlayer.weapons.GetWeapon(k, j);
|
||||
|
||||
if (weap)
|
||||
{
|
||||
// Show ammo for available weapons if hud_showammo CVAR is 1
|
||||
// or show ammo for all weapons if hud_showammo is greater than 1
|
||||
|
||||
if (hud_showammo > 1 || CPlayer.mo.FindInventory(weap))
|
||||
{
|
||||
AddAmmoToList(GetDefaultByType(weap));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now check for the remaining weapons that are in the inventory but not in the weapon slots
|
||||
for(inv = CPlayer.mo.Inv; inv; inv = inv.Inv)
|
||||
{
|
||||
let weap = Weapon(inv);
|
||||
if (weap)
|
||||
{
|
||||
AddAmmoToList(weap.default);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ok, we got all ammo types. Now draw the list back to front (bottom to top)
|
||||
|
||||
int ammocurlen = 0;
|
||||
int ammomaxlen = 0;
|
||||
[ammocurlen, ammomaxlen] = GetAmmoTextLengths(CPlayer);
|
||||
|
||||
//buf = String.Format("%0d/%0d", 0, 0);
|
||||
buf = String.Format("%0*d/%0*d", ammocurlen, 0, ammomaxlen, 0);
|
||||
|
||||
int def_width = ConFont.StringWidth(buf);
|
||||
int yadd = ConFont.GetHeight();
|
||||
|
||||
int xtext = x - def_width;
|
||||
int ximage = x;
|
||||
|
||||
if (hud_ammo_order > 0)
|
||||
{
|
||||
xtext -= 24;
|
||||
ximage -= 20;
|
||||
}
|
||||
else
|
||||
{
|
||||
ximage -= def_width + 20;
|
||||
}
|
||||
|
||||
for(i = orderedammos.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
let type = orderedammos[i];
|
||||
let ammoitem = CPlayer.mo.FindInventory(type);
|
||||
let inv = GetDefaultByType(type);
|
||||
|
||||
let AltIcon = inv.AltHUDIcon;
|
||||
int maxammo = inv.MaxAmount;
|
||||
|
||||
let icon = !AltIcon.isNull()? AltIcon : inv.Icon;
|
||||
if (!icon.isValid()) continue;
|
||||
|
||||
double trans= (wi && (type == wi.AmmoType1 || type == wi.AmmoType2)) ? 0.75 : 0.375;
|
||||
|
||||
int ammo = ammoitem? ammoitem.Amount : 0;
|
||||
|
||||
// buf = String.Format("%d/%d", ammo, maxammo);
|
||||
buf = String.Format("%*d/%*d", ammocurlen, ammo, ammomaxlen, maxammo);
|
||||
|
||||
int tex_width= clamp(ConFont.StringWidth(buf) - def_width, 0, 1000);
|
||||
|
||||
int fontcolor=( !maxammo ? Font.CR_GRAY :
|
||||
ammo < ( (maxammo * hud_ammo_red) / 100) ? Font.CR_RED :
|
||||
ammo < ( (maxammo * hud_ammo_yellow) / 100) ? Font.CR_GOLD : Font.CR_GREEN );
|
||||
|
||||
DrawHudText(ConFont, fontcolor, buf, xtext-tex_width, y+yadd, trans);
|
||||
DrawImageToBox(icon, ximage, y, 16, 8, trans);
|
||||
y-=10;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in a new issue