class RLStatusBar : BaseStatusBar; static const string ArmorList[] = { // HELLO ELEMENT BLOAT MY OLD FRIEND "RLGenericArmor", "RLGreenArmor", "RLBlueArmor", "RLRedArmor", // Assembled armors // Basic "RLTowerShieldArmor", "RLTacticalArmor", "RLBallisticGreenArmor", "RLBallisticBlueArmor", "RLBallisticRedArmor", "RLFireproofGreenArmor", "RLFireproofBlueArmor", "RLFireproofRedArmor", "RLNanofiberGreenArmor", "RLNanofiberBlueArmor", "RLNanofiberRedArmor", "RLPowerGreenArmor", "RLPowerBlueArmor", "RLPowerRedArmor", // Advanced "RLFireshieldArmor", "RLAblativeGreenArmor", "RLAblativeBlueArmor", "RLAblativeRedArmor", "RLNanofiberSkinGreenArmor", "RLNanofiberSkinBlueArmor", "RLNanofiberSkinRedArmor", // Master "RLCerberusArmor", "RLCybernanoGreenArmor", "RLCybernanoBlueArmor", "RLCybernanoRedArmor", // dis be exotic shit yo "RLBallisticShieldArmor", "RLBallisticVestArmor", "RLBulletProofVestArmor", "RLCyberwarriorArmor", "RLDuelistArmor", "RLEnergyShieldedVestArmor", "RLEnergyShieldArmor", "RLGothicArmor", "RLMedicalArmor", "RLPhaseshiftArmor", "RLPlasmaShieldArmor", "RLRepulsionWaveSuitArmor", "RLSurvivalMediArmor", "RLOnyxArmor", "RLOverchargeSystemArmor", // Many superiors "RLNuclearArmor", "RLRechargeableEnergyShieldArmor", // Uniques "RLBerserkerArmor", "RLBerserkPowersuitArmor", "RLBlazingPhoenixDeviceSuitArmor", "RLCyberneticArmor", "RLEnergyDischargeHarnessArmor", "RLFrontlineEngineerSuitArmor", "RLGeosGoldenGauntletArmor", "RLJetpackArmor", "RLKateMatterstormHarnessArmor", "RLKyleTeslaboltArmor", "RLLavaArmor", "RLMaleksArmor", "RLMedicalPowerArmor", "RLNanoAblativeArmor", "RLNuclearPowerArmor", "RLPrototypeAssaultShieldArmor", "RLRoystensCommandArmor", "RLRyanCordellPsychicAmplifierSuitArmor", "RLShieldedArmor", "RLSoloOperativeSuitArmor", "RLTacticalAssemblerSuitArmor", "RLTerminusEst13BattlesuitArmor", "RLTorgueBlastplateArmor", "RLWildWeaselPeacekeeperArmor", "RLXaserPowerArmor", "RLZeroDiamondAssaultforceArmor", // de-de-demon "RLDemonicCarapaceArmor", "RLNecroArmor", "RLSoulshatterArmor", // LEGENDARIES? What for?! "RLAngelicArmor", "RLTheBeeArmor", "RLReactiveShieldSystemArmor", "RLChronotrooperArmor", // Onyx modded "RLOModGreenArmor", "RLOModBlueArmor", "RLOModRedArmor", "RLOModBallisticVestArmor", "RLOModBulletProofVestArmor", "RLOModCyberwarriorArmor", "RLOModDuelistArmor", "RLOModEnergyShieldedVestArmor", "RLOModGothicArmor", "RLOModMedicalArmor", "RLOModPhaseshiftArmor", "RLOModRepulsionWaveSuitArmor", "RLOModSurvivalMediArmor", // Cybernetic madness "RLCyberneticArmorBulk", "RLCyberneticArmorPower", "RLCyberneticArmorAgility", "RLCyberneticArmorTechnical", "RLCyberneticArmorSniper", "RLCyberneticArmorFirestorm", "RLCyberneticArmorNano", "RLCyberneticArmorOnyx", // Boots "RLGenericBoots", "RLSteelBoots", "RLProtectiveBoots", "RLPlasteelBoots", // Exotic time! "RLAcidProofBoots", "RLGothicBoots", "RLPhaseshiftBoots", "RLShockwaveBoots", // Unique booty "RLEnviroBoots", "RLFrontlineEngineerBoots", "RLLavaBoots", "RLLeonidasBoots", "RLNuclearPowerBoots", "RLNyarlaptotepsBoots", "RLRoystensCombatBoots", "RLSoloOperativeBoots", "RLTacticalAssemblerBoots", "RLTorgueBlastBoots", // DEEEEEEEEMONIC "RLDemonicBoots", // Legenboots "RLAngelicBoots", // Assemblo boots // Basic "RLTacticalBoots", "RLFireproofSteelBoots", "RLFireproofProtectiveBoots", "RLFireproofPlasteelBoots", "RLGrapplingSteelBoots", "RLGrapplingProtectiveBoots", "RLGrapplingPlasteelBoots", // Advanced "RLEnviromentalSteelBoots", "RLEnviromentalProtectiveBoots", "RLEnviromentalPlasteelBoots", "RLAntigravSteelBoots", "RLAntigravProtectiveBoots", "RLAntigravPlasteelBoots", // Master "RLCerberusBoots" }; static const name ModColors[] = { "Red", "Blue", "Green", "Yellow", "White", "Orange", "Purple", "DarkRed" }; const LeftYBase = -20; const RightYBase = -20; RLBasePlayer RLPlayer; HUDFont BigFont; HUDFont SmallFont; HUDFont IndexFont; HUDFont AmountFont; InventoryBarState InvBar; DynamicValueInterpolator HealthInterp; DynamicValueInterpolator ArmorInterp; int LeftY; int RightY; override void Init() { Super.Init(); SetSize(0, 320, 240); InitFonts(); InvBar = InventoryBarState.Create(); HealthInterp = DynamicValueInterpolator.Create(100, 0.25, 1, 8); ArmorInterp = DynamicValueInterpolator.Create(0, 0.25, 1, 8); } override void Tick() { Super.Tick(); RLPlayer = RLBasePlayer(CPlayer.MO); if (RLplayer == null || RLplayer.Health <= 0) return; HealthInterp.Update(RLplayer.Health); ArmorInterp.Update(GetArmorAmount()); } override void Draw(int state, double ticFrac) { Super.Draw(state, ticFrac); if (!(state == HUD_StatusBar || state == HUD_Fullscreen) || RLplayer == null || RLplayer.Health <= 0) return; LeftY = LeftYBase; RightY = RightYBase; BeginHUD(); DrawMugArea(); DrawTimers(); DrawAmmoArea(); DrawWeaponInfo(); DrawInventory(); } void InitFonts() { Font fnt; fnt = "HUDFONT_DOOM"; BigFont = HUDFont.Create(fnt, fnt.GetCharWidth("0"), true, 4, 1); fnt = "SMALLFONT"; SmallFont = HUDFont.Create(fnt, 0, false, 1, 1); fnt = "INDEXFONT_DOOM"; IndexFont = HUDFont.Create(fnt, fnt.GetCharWidth("0"), true); fnt = "INDEXFONT"; AmountFont = HUDFont.Create(fnt); } void DrawMugArea() { Inventory armor = RLPlayer.FindInventory("BasicArmor"); DrawTexture(GetMugShot(5), (0, -36), DI_ITEM_OFFSETS); DrawString(BigFont, FormatNumber(HealthInterp.GetValue(), 3), (36, LeftY)); LeftY -= 18; if (armor != null && GetArmorAmount() > 0) DrawString(BigFont, FormatNumber(ArmorInterp.GetValue(), 3), (36, LeftY), 0, Font.FindFontColor("Green")); LeftY -= 18; for (int i = 0; i < ArmorList.Size(); i++) { if (!Type.ClassExists(ArmorList[i] .. "Pickup") || !RLPlayer.FindInventory(ArmorList[i] .. "Token")) continue; TextureID icon = GetIconForItem((Class)(ArmorList[i] .. "Pickup")); int width, height; bool boots = ArmorList[i].IndexOf("Boots") > 0; [width, height] = TexMan.GetSize(icon); DrawTexture(icon, (17, boots ? -48 - height : -40)); } } void DrawTimers() { int radiation = RLPlayer.GetEffectTicsForItem("RadSuit"); int infrared = RLPlayer.GetEffectTicsForItem("Infrared"); int blur = RLPlayer.GetEffectTicsForItem("BlurSphere"); int invuln = RLPlayer.GetEffectTicsForItem("InvulnerabilitySphere"); int air = CPlayer.air_finished - Level.Time; if (radiation > 0) { DrawString(BigFont, FormatNumber(radiation / 35 + 1, 3), (36, LeftY), 0, Font.FindFontColor("DarkGreen")); LeftY -= 18; } if (infrared > 0) { DrawString(BigFont, FormatNumber(infrared / 35 + 1, 3), (36, LeftY), 0, Font.FindFontColor("Brick")); LeftY -= 18; } if (blur > 0) { DrawString(BigFont, FormatNumber(blur / 35 + 1, 3), (36, LeftY), 0, Font.FindFontColor("Blue")); LeftY -= 18; } if (invuln > 0) { DrawString(BigFont, FormatNumber(invuln / 35 + 1, 3), (36, LeftY), 0, Font.FindFontColor("Gold")); LeftY -= 18; } if (RLplayer.WaterLevel == 3 && radiation <= 0 && invuln <= 0) { DrawString(BigFont, FormatNumber(air > 0 ? air / 35 + 1 : 0, 3), (36, LeftY), 0, Font.FindFontColor("Cyan")); LeftY -= 18; } } void DrawAmmoArea() { Inventory ammo1, ammo2; int amount1, amount2; RLBaseWeapon weapon = RLBaseWeapon(CPlayer.ReadyWeapon); [ammo1, ammo2, amount1, amount2] = GetCurrentAmmo(); Color ammoColor = Font.FindFontColor("White"); if (weapon != null) { if (ammo2 != null) { DrawInventoryIcon(Ammo2, (-14, RightY + 14)); DrawString(BigFont, FormatNumber(amount2, 3), (-30, RightY), DI_TEXT_ALIGN_RIGHT, ammoColor); RightY -= 20; } if (ammo1 != null) { DrawInventoryIcon(Ammo1, (-14, RightY + 14)); DrawString(BigFont, FormatNumber(amount1, 3), (-30, RightY), DI_TEXT_ALIGN_RIGHT, ammoColor); RightY -= 20; } } // TODO: Stamina for melee only } void DrawWeaponInfo() { RLBaseWeapon weapon = RLBaseWeapon(CPlayer.ReadyWeapon); Vector2 pos = (-2, 0); if (weapon == null) return; string name = weapon.GetClassName(); array upgrades; int y = 0; upgrades.Push(name .. "PowerMod"); upgrades.Push(name .. "BulkMod"); upgrades.Push(name .. "AgilityMod"); upgrades.Push(name .. "TechnicalMod"); upgrades.Push(name .. "NanoMod"); upgrades.Push(name .. "FirestormMod"); upgrades.Push(name .. "SniperMod"); upgrades.Push(name .. "DemonArtifacts"); DrawInventoryIcon(weapon, (pos.X - 48, pos.Y + 28)); DrawString(SmallFont, weapon.GetTag(), pos, DI_TEXT_ALIGN_RIGHT, Font.FindFontColor("White")); if (IsModdable()) { for (int i = 0; i < upgrades.Size(); i++) { if (!Type.ClassExists(upgrades[i])) continue; int amount = RLPlayer.CountInv(upgrades[i]); if (amount > 0) DrawString(SmallFont, FormatNumber(amount), (pos.X, pos.Y + 8 + (y++ * 8)), DI_TEXT_ALIGN_RIGHT, Font.FindFontColor(ModColors[i])); } } } void DrawInventory() { if (!isInventoryBarVisible() && !Level.NoInventoryBar && RLPlayer.InvSel != null) { DrawInventoryIcon(RLPlayer.InvSel, (-14, RightY + 17)); DrawString(BigFont, FormatNumber(RLPlayer.InvSel.Amount, 3), (-30, RightY), DI_TEXT_ALIGN_RIGHT, Font.FindFontColor("White")); } if (IsInventoryBarVisible()) DrawInventoryBar(InvBar, (3, 169), 14, DI_ITEM_LEFT_TOP); } clearscope TextureID GetIconForItem(Class type) const { readonly inv = Inventory(GetDefaultByType(type)); if (inv.Icon.IsValid()) return inv.Icon; else if (inv.AltHUDIcon.IsValid()) return inv.AltHUDIcon; if (inv.SpawnState) return inv.SpawnState.GetSpriteTexture(0); if (Weapon(inv)) { let ready = Weapon(inv).FindState('Ready'); if (ready) return ready.GetSpriteTexture(0); } TextureID tex; tex.SetNull(); return tex; } bool IsModdable() const { return !RLPlayer.CountInv("RLFistSelected"); } bool IsDemonicWeapon() const { return RLPlayer.CountInv("RLDemonicWeaponToken"); }