- AltHUD ammo drawer scriptified.

This commit is contained in:
Christoph Oelckers 2018-12-02 09:33:59 +01:00
parent 0cd93c14af
commit fbc441673a
3 changed files with 191 additions and 155 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}
}