diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 205a0eea3a..1ac665fb2c 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -238,16 +238,6 @@ public enum FishingMinigames #endregion - #region Speedrun Timer - // The Calamity Speedrun Timer uses the highest precision timing available to .NET and thus to the system hardware. - // Current session time is maintained by CalamityMod.SpeedrunTimer, which is a C# Stopwatch running constantly while a player is loaded. - // Total time is calculated on demand by adding the current stopwatch time to the previous session total. - // This allows time to be tracked accurately through multiple save and quits. - internal TimeSpan previousSessionTotal; - internal int lastSplitType = -1; - internal TimeSpan lastSplit; - #endregion - #region Tile Entity Trackers public int CurrentlyViewedFactoryID = -1; public int CurrentlyViewedChargerID = -1; @@ -1928,10 +1918,6 @@ public override void SaveData(TagCompound tag) boost.AddWithCondition("HasTalkedAtCodebreaker", HasTalkedAtCodebreaker); boost.AddWithCondition("HasCraftedDraedonsForge", HasCraftedDraedonsForge); - // Calculate the new total time of all sessions at the instant of this player save. - TimeSpan newSessionTotal = previousSessionTotal.Add(SpeedrunTimerSystem.Elapsed); - long totalTicks = newSessionTotal.Ticks; - // Save all cooldowns which are marked as persisting through save/load. TagCompound cooldownsTag = new TagCompound(); var cdIterator = cooldowns.GetEnumerator(); @@ -1959,9 +1945,6 @@ public override void SaveData(TagCompound tag) tag["moveSpeedBonus"] = moveSpeedBonus; tag["defenseDamage"] = totalDefenseDamage; tag["defenseDamageRecoveryFrames"] = defenseDamageRecoveryFrames; - tag["totalSpeedrunTicks"] = totalTicks; - tag["lastSplitType"] = lastSplitType; - tag["lastSplitTicks"] = lastSplit.Ticks; tag["cooldowns"] = cooldownsTag; tag["SeenDraedonDialogs"] = SeenDraedonDialogs; } @@ -2050,13 +2033,6 @@ public override void LoadData(TagCompound tag) if (totalDefenseDamageRecoveryFrames <= 0) totalDefenseDamageRecoveryFrames = DefenseDamageBaseRecoveryTime; - // Load the previous total elapsed time to know where to start the timer when it starts. - long ticks = tag.GetLong("totalSpeedrunTicks"); - previousSessionTotal = new TimeSpan(ticks); - // Also load the last split, so it will show up. - lastSplitType = tag.GetInt("lastSplitType"); - ticks = tag.GetLong("lastSplitTicks"); - lastSplit = new TimeSpan(ticks); SeenDraedonDialogs = tag.GetList("SeenDraedonDialogs").ToList(); // Clear the player's cooldowns in preparation for loading. @@ -6135,7 +6111,6 @@ internal void rollBabSpears(int randAmt, bool chaseable) private static int startMessageDisplayDelay = -1; // Triggers effects that must occur when the player enters the world. This sends a bunch of packets in multiplayer. - // It also starts the speedrun timer if applicable. public override void OnEnterWorld() { if (CalamityClientConfig.Instance.StutterFix) @@ -6144,11 +6119,6 @@ public override void OnEnterWorld() if (Main.netMode == NetmodeID.MultiplayerClient) EnterWorldSync(); - // Enabling the config while a player is loaded will show the timer immediately. - // But it won't start running until you save and quit and re-enter a world. - if (CalamityClientConfig.Instance.SpeedrunTimer) - SpeedrunTimerSystem.Restart(); - bool showWikiMessage = CalamityClientConfig.Instance.WikiStatusMessage; bool showVCMMMessage = CalamityClientConfig.Instance.VCMMStatusMessage && !ExternalMods.VCMMAvailable; bool showStartupMessages = showWikiMessage || showVCMMMessage; diff --git a/CalamityConfig.cs b/CalamityConfig.cs index af43e1923a..2e333f295d 100644 --- a/CalamityConfig.cs +++ b/CalamityConfig.cs @@ -143,10 +143,6 @@ internal void ClampValues(StreamingContext context) [DefaultValue(2f)] public float RipperMeterShake { get; set; } - [BackgroundColor(192, 54, 64, 192)] - [DefaultValue(false)] - public bool SpeedrunTimer { get; set; } - [BackgroundColor(192, 54, 64, 192)] [DefaultValue(true)] public bool FlightBar { get; set; } @@ -215,18 +211,6 @@ internal void ClampValues(StreamingContext context) [DefaultValue(RipperUI.DefaultAdrenPosY)] public float AdrenalineMeterPosY { get; set; } - [BackgroundColor(192, 54, 64, 192)] - [SliderColor(224, 165, 56, 128)] - [Range(0f, 100f)] - [DefaultValue(SpeedrunTimerUI.DefaultTimerPosX)] - public float SpeedrunTimerPosX { get; set; } - - [BackgroundColor(192, 54, 64, 192)] - [SliderColor(224, 165, 56, 128)] - [Range(0f, 100f)] - [DefaultValue(SpeedrunTimerUI.DefaultTimerPosY)] - public float SpeedrunTimerPosY { get; set; } - [BackgroundColor(192, 54, 64, 192)] [SliderColor(224, 165, 56, 128)] [Range(0f, 100f)] diff --git a/Localization/en-US/Mods.CalamityMod.Configs.hjson b/Localization/en-US/Mods.CalamityMod.Configs.hjson index e4eb0c04ad..a473074822 100644 --- a/Localization/en-US/Mods.CalamityMod.Configs.hjson +++ b/Localization/en-US/Mods.CalamityMod.Configs.hjson @@ -256,34 +256,6 @@ CalamityClientConfig: { Tooltip: Adds an icon that appears over Town NPCs when they have new items in their shops. } - SpeedrunTimer: { - Label: "[i:Stopwatch] Display Speedrun Timer" - Tooltip: - ''' - Enables an in-game speedrun timer which shows in-game time down to the millisecond. - A second line displays the time of your most recent boss kill. - The time is tracked per player and only counts time while loaded into a world. - ''' - } - - SpeedrunTimerPosX: { - Label: "[i:LaserRuler] Speedrun Timer X Position" - Tooltip: - ''' - The X position of the Speedrun Timer, measured as a % of your screen width. - The meter can be dragged with the mouse if Lock Meter Positions is disabled. - ''' - } - - SpeedrunTimerPosY: { - Label: "[i:LaserRuler] Speedrun Timer Y Position" - Tooltip: - ''' - The Y position of the Speedrun Timer, measured as a % of your screen height. - The meter can be dragged with the mouse if Lock Meter Positions is disabled. - ''' - } - StealthInvisibility: { Label: "[i:CalamityMod/StealthHairDye] Stealth Invisibility" Tooltip: diff --git a/Localization/en-US/Mods.CalamityMod.Misc.hjson b/Localization/en-US/Mods.CalamityMod.Misc.hjson index 8d617226ec..b9623fa1dc 100644 --- a/Localization/en-US/Mods.CalamityMod.Misc.hjson +++ b/Localization/en-US/Mods.CalamityMod.Misc.hjson @@ -127,3 +127,42 @@ GFBRougeUppercase: Rouge GFBRogueLowercase: rogue GFBRougeLowercase: rouge HotkeyNotBound: "[None]" + +SpeedrunDisplay: { + DesertScourge: DS + Crabulon: Crab + HiveMind: Hive + Perforators: Perfs + SlimeGod: SG + Cryogen: Cryogen + AquaticScourge: AS + BrimstoneElemental: Brimmy + CalamitasClone: CalClone + Leviathan: Levi + AstrumAureus: Aureus + PlaguebringerGoliath: PBG + Ravager: Rav + AstrumDeus: Deus + ProfanedGuardians: PG + Dragonfolly: Folly + Providence: Provi + CeaselessVoid: CV + StormWeaver: SW + Signus: Signus + Polterghast: Polter + OldDuke: OD + DevourerOfGods: DoG + Yharon: Yharon + SupremeCalamitas: SCal + ExoMechs: Exos + PrimordialWyrm: Wyrm + Cynosure: Cynosure + AllCalamityBosses: All Bosses + + DoGPumpkinMoon: PumpMoon2 + DoGFrostMoon: FrostMoon2 + DoGEclipse: Eclipse2 + + CalamityCynosure: Calamity: Cynosure + CalamityAllBosses: Calamity: All Bosses +} diff --git a/ModSupport/ExternalMods.cs b/ModSupport/ExternalMods.cs index f69d8d110d..c039387e1d 100644 --- a/ModSupport/ExternalMods.cs +++ b/ModSupport/ExternalMods.cs @@ -27,6 +27,7 @@ public sealed class ExternalMods : ModSystem internal static Mod redemption = null; internal static Mod remnants = null; internal static Mod soa = null; + internal static Mod speedrunDisplay = null; internal static Mod subworldLibrary = null; internal static Mod summonersAssociation = null; internal static Mod thorium = null; @@ -66,6 +67,8 @@ public override void Load() ModLoader.TryGetMod("Remnants", out remnants); soa = null; ModLoader.TryGetMod("SacredTools", out soa); + speedrunDisplay = null; + ModLoader.TryGetMod("SpeedrunDisplay", out speedrunDisplay); subworldLibrary = null; ModLoader.TryGetMod("SubworldLibrary", out subworldLibrary); summonersAssociation = null; @@ -96,6 +99,7 @@ public override void Unload() redemption = null; remnants = null; soa = null; + speedrunDisplay = null; subworldLibrary = null; summonersAssociation = null; thorium = null; diff --git a/ModSupport/WeakReferenceSupport.cs b/ModSupport/WeakReferenceSupport.cs index 0fcbeb04a1..e52a131f3d 100644 --- a/ModSupport/WeakReferenceSupport.cs +++ b/ModSupport/WeakReferenceSupport.cs @@ -40,6 +40,7 @@ using CalamityMod.NPCs.Perforator; using CalamityMod.NPCs.PlaguebringerGoliath; using CalamityMod.NPCs.Polterghast; +using CalamityMod.NPCs.PrimordialWyrm; using CalamityMod.NPCs.ProfanedGuardians; using CalamityMod.NPCs.Providence; using CalamityMod.NPCs.Ravager; @@ -57,7 +58,9 @@ using CalamityMod.Systems.Graphic.LiquidSystem; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using ReLogic.Content; using Terraria; +using Terraria.GameContent; using Terraria.ID; using Terraria.IO; using Terraria.Localization; @@ -193,11 +196,8 @@ public override void PostSetupContent() SummonersAssociationSupport(); ColoredDamageTypesSupport(); LuminanceSupport(); - - if (!Main.dedServ) - { - WikiThisSupport(); - } + WikiThisSupport(); + SpeedrunDisplaySupport(); } #region BiomeLava @@ -246,117 +246,6 @@ bool InflictsOnFire() } #endregion - #region WikiThis - // This is a separate function because it only runs clientside - private static void WikiThisSupport() - { - // Wikithis is a clientside mod - if (Main.dedServ) - return; - - CalamityMod calamity = GetInstance(); - Mod wiki = ExternalMods.wikithis; - if (wiki is null) - return; - - bool oldVersion = wiki.Version < new Version(2, 4, 7, 5); - - wiki.Call("AddModURL", calamity, oldVersion ? CalamityWikiURLOld : CalamityWikiURL); - wiki.Call(0, calamity, oldVersion ? CalamityWikiURLOld : CalamityWikiURL); - wiki.Call("AddWikiTexture", calamity, Request("CalamityMod/ModSupport/WikiThisIcon")); - wiki.Call(3, calamity, Request("CalamityMod/ModSupport/WikiThisIcon")); - - // Clear up name conflicts - void ItemRedirect(int item, string pageName) => wiki.Call(1, item, pageName); - void EnemyRedirect(int item, string pageName) => wiki.Call(2, item, pageName); - - // Items - ItemRedirect(ItemType(), "Pineapple (calamity)"); - ItemRedirect(ItemType(), "Trash Can (pet)"); - // Lore items - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - ItemRedirect(ItemType(), loreItemPage); - - // Enemies - EnemyRedirect(NPCType(), "Crown Jewels"); - EnemyRedirect(NPCType(), "Tooth Ball (Old Duke)"); - EnemyRedirect(NPCType(), "Enchantment"); - EnemyRedirect(NPCType(), "%3F%3F%3F"); - } - #endregion - - #region Subworld Library - // Wrapper function to detect if a subworld is in use for Subworld Library. - internal static bool InAnySubworld() - { - if (ExternalMods.subworldLibrary is null) - return false; - - foreach (Mod mod in ModLoader.Mods) - { - if (mod.Name.Equals(ExternalMods.subworldLibrary.Name)) - continue; - - bool anySubworldForMod = (ExternalMods.subworldLibrary.Call("AnyActive", mod) as bool?) ?? false; - if (anySubworldForMod) - return true; - } - return false; - } - #endregion - #region Boss Checklist // Wrapper function to add bosses to Boss Checklist. private static void AddBoss(Mod bossChecklist, Mod hostMod, string name, float difficulty, Func downed, object npcTypes, Dictionary extraInfo) @@ -1103,6 +992,62 @@ private static void RegisterCalamityExtraInfo(Mod bossChecklist, Mod calamity) #endregion #endregion + #region Colored Damage Types + // These are vanilla Terraria's colors for tooltips and damage + private static Color DefaultTooltipColor = Color.White; + private static Color DefaultDamageColor = new(255, 160, 80); + private static Color DefaultCritColor = new(255, 100, 30); + + // These are Colored Damage Types' colors for the Melee class + private static Color MeleeTooltipColor = new(254, 121, 2); + private static Color MeleeDamageColor = new(254, 121, 2); + private static Color MeleeCritColor = new(253, 62, 3); + + private static Color MeleeRangedTooltipColor = new(144, 171, 76); + private static Color MeleeRangedDamageColor = new(144, 171, 76); + private static Color MeleeRangedCritColor = new(86, 102, 46); + + private static Color RogueTooltipColor = new(206, 132, 227); + private static Color RogueDamageColor = new(206, 132, 227); + private static Color RogueCritColor = new(194, 38, 212); + private static Color StealthTooltipColor = RogueTooltipColor; + private static Color StealthDamageColor = new(185, 105, 250); + private static Color StealthCritColor = new(144, 33, 235); + + private static void ColoredDamageTypesSupport() + { + Mod coloredDamageTypes = ExternalMods.coloredDamageTypes; + if (coloredDamageTypes is null) + return; + + // Anything that directly uses AverageDamageClass uses the default vanilla colors. + coloredDamageTypes.Call("AddDamageType", AverageDamageClass.Instance, DefaultTooltipColor, DefaultDamageColor, DefaultCritColor); + + // True melee uses the same colorations as regular Melee. + coloredDamageTypes.Call("AddDamageType", TrueMeleeDamageClass.Instance, MeleeTooltipColor, MeleeDamageColor, MeleeCritColor); + coloredDamageTypes.Call("AddDamageType", TrueMeleeNoSpeedDamageClass.Instance, MeleeTooltipColor, MeleeDamageColor, MeleeCritColor); + + // Melee-ranged hybrid damage uses a 50% blend between Melee and Ranged, turning into Olive green + coloredDamageTypes.Call("AddDamageType", MeleeRangedHybridDamageClass.Instance, MeleeRangedTooltipColor, MeleeRangedDamageColor, MeleeRangedCritColor); + + // Rogue has its own lavender color. Stealth strikes are hued towards violet so they stick out more. + // They would be hued towards magenta, but that would make them collide with Nebula-colored Magic in Colored Damage Types config. + coloredDamageTypes.Call("AddDamageType", RogueDamageClass.Instance, RogueTooltipColor, RogueDamageColor, RogueCritColor); + coloredDamageTypes.Call("AddDamageType", StealthDamageClass.Instance, StealthTooltipColor, StealthDamageColor, StealthCritColor); + } + #endregion + + #region Dialogue Tweaks + private static void DialogueTweakSupport() + { + Mod dialogueMod = ExternalMods.dialogueTweak; + if (dialogueMod != null) + { + dialogueMod.Call("ReplaceShopButtonIcon", NPCType(), "Head"); + } + } + #endregion + #region Fargo's Mutant Mod private static void FargosSupport() { @@ -1133,14 +1078,165 @@ void AddToMutantShop(string bossName, string summonItemName, Func downed, } #endregion - #region Dialogue Tweaks - private static void DialogueTweakSupport() + #region Luminance + private static void RegisterWorldInfoIcon(Mod luminance, string texturePath, string hoverTextKey, Func shouldAppear, byte priority) + => luminance.Call("RegisterWorldInfoIcon", texturePath, hoverTextKey, shouldAppear, priority); + + private static void LuminanceSupport() { - Mod dialogueMod = ExternalMods.dialogueTweak; - if (dialogueMod != null) + Mod luminance = ExternalMods.luminance; + if (luminance is null) + return; + + Func deathEnabled = data => { - dialogueMod.Call("ReplaceShopButtonIcon", NPCType(), "Head"); + if (!data.TryGetHeaderData(out var tagData)) + return false; + + return tagData.ContainsKey("DeathMode") && tagData.GetBool("DeathMode"); + }; + + Func revengeanceEnabled = data => + { + if (!data.TryGetHeaderData(out var tagData)) + return false; + + return tagData.ContainsKey("RevengeanceMode") && tagData.GetBool("RevengeanceMode") && !(tagData.ContainsKey("DeathMode") && tagData.GetBool("DeathMode")); + }; + + RegisterWorldInfoIcon(luminance, "CalamityMod/UI/ModeIndicator/ModeIndicator_Death", "Mods.CalamityMod.UI.Death", deathEnabled, 50); + RegisterWorldInfoIcon(luminance, "CalamityMod/UI/ModeIndicator/ModeIndicator_Rev", "Mods.CalamityMod.UI.Revengeance", revengeanceEnabled, 50); + } + #endregion + + #region Speedrun Display + private static bool cachedPumpkinMoon = false; + private static bool cachedFrostMoon = false; + private static bool cachedEclipse = false; + + private static void SpeedrunDisplaySupport() + { + if (Main.dedServ) + return; + + Mod speedrunDisplay = ExternalMods.speedrunDisplay; + if (speedrunDisplay is null) + return; + + static string Localize(string key) => $"Mods.CalamityMod.Misc.SpeedrunDisplay.{key}"; + static Asset BossHead() where T : ModNPC => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[NPCType()]]; + + object GetSplit(string splitKey) => speedrunDisplay.Call("GetSplit", splitKey); + object AddSplit(string splitKey, Asset splitIcon, Func completionCheck) => speedrunDisplay.Call("AddSplit", splitKey, Localize(splitKey), splitIcon, completionCheck); + object AddCategory(string categoryKey, object completionSplit) => speedrunDisplay.Call("AddCategory", categoryKey, Localize(categoryKey), completionSplit); + + AddSplit("DesertScourge", BossHead(), DownedDesertScourge); + AddSplit("Crabulon", BossHead(), DownedCrabulon); + AddSplit("HiveMind", Request("CalamityMod/NPCs/HiveMind/HiveMindP2_Head_Boss"), DownedHiveMind); + AddSplit("Perforators", BossHead(), DownedPerforators); + AddSplit("SlimeGod", BossHead(), DownedSlimeGod); + AddSplit("Cryogen", Request("CalamityMod/NPCs/Cryogen/Cryogen_Phase1_Head_Boss"), DownedCryogen); + AddSplit("AquaticScourge", BossHead(), DownedAquaticScourge); + AddSplit("BrimstoneElemental", BossHead(), DownedBrimstoneElemental); + AddSplit("CalamitasClone", BossHead(), DownedCalClone); + AddSplit("Leviathan", BossHead(), DownedLeviathan); + AddSplit("AstrumAureus", BossHead(), DownedAureus); + AddSplit("PlaguebringerGoliath", BossHead(), DownedPBG); + AddSplit("Ravager", BossHead(), DownedRavager); + AddSplit("AstrumDeus", BossHead(), DownedDeus); + AddSplit("ProfanedGuardians", BossHead(), DownedGuardians); + AddSplit("Dragonfolly", BossHead(), DownedDragonfolly); + AddSplit("Providence", BossHead(), DownedProvidence); + AddSplit("CeaselessVoid", BossHead(), DownedCeaselessVoid); + AddSplit("StormWeaver", Request("CalamityMod/NPCs/StormWeaver/StormWeaverHead_Head_Boss"), DownedStormWeaver); + AddSplit("Signus", BossHead(), DownedSignus); + AddSplit("Polterghast", Request("CalamityMod/NPCs/Polterghast/Necroplasm_Head_Boss"), DownedPolterghast); + AddSplit("OldDuke", BossHead(), DownedOldDuke); + AddSplit("DevourerOfGods", Request("CalamityMod/NPCs/DevourerofGods/DevourerofGodsHead_Head_Boss"), DownedDoG); + AddSplit("Yharon", BossHead(), DownedYharon); + AddSplit("SupremeCalamitas", Request("CalamityMod/NPCs/SupremeCalamitas/HoodlessHeadIcon"), DownedCalamitas); + AddSplit("ExoMechs", Request("CalamityMod/NPCs/ExoMechs/Ares/AresBody_Head_Boss"), DownedExoMechs); + AddSplit("PrimordialWyrm", BossHead(), DownedPrimordialWyrm); + + AddSplit("DoGPumpkinMoon", Request("Terraria/Images/Extra_12"), () => + { + bool moonEnded = cachedPumpkinMoon && !Main.pumpkinMoon; + cachedPumpkinMoon = Main.pumpkinMoon; + return moonEnded && DownedBossSystem.downedDoG; + }); + + AddSplit("DoGFrostMoon", Request("Terraria/Images/Extra_8"), () => + { + bool moonEnded = cachedFrostMoon && !Main.snowMoon; + cachedFrostMoon = Main.snowMoon; + return moonEnded && DownedBossSystem.downedDoG; + }); + + AddSplit("DoGEclipse", Request("SpeedrunDisplay/Assets/Textures/SolarEclipse"), () => + { + bool eclipseEnded = cachedEclipse && !Main.eclipse; + cachedEclipse = Main.eclipse; + return eclipseEnded && DownedBossSystem.downedDoG; + }); + + // Re-use the vanilla "AllBosses%" completion check + object allBosses = GetSplit("AllBosses"); + var completionCheckProperty = allBosses.GetType().GetProperty("CompletionCheck", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); + Func allBossesCheck = (Func)completionCheckProperty.GetValue(allBosses); + + // Cynosure is only available in the "Calamity: Any%" category + AddSplit("Cynosure", Request("CalamityMod/Items/LoreItems/LoreCynosure"), () => (string)speedrunDisplay.Call("runcategory") == "CalamityAny%" && DownedBossSystem.downedCalamitas && DownedBossSystem.downedExoMechs); + AddSplit("AllCalamityBosses", Request("CalamityMod/icon_small"), () => + // Descending order is used because it is microseconds faster (important performance difference) + DownedBossSystem.downedExoMechs && + DownedBossSystem.downedCalamitas && + DownedBossSystem.downedYharon && + DownedBossSystem.downedDoG && + DownedBossSystem.downedBoomerDuke && + DownedBossSystem.downedPolterghast && + DownedBossSystem.downedSignus && + DownedBossSystem.downedStormWeaver && + DownedBossSystem.downedCeaselessVoid && + DownedBossSystem.downedProvidence && + DownedBossSystem.downedDragonfolly && + DownedBossSystem.downedGuardians && + allBossesCheck() && // Placed where ML would be + DownedBossSystem.downedAstrumDeus && + DownedBossSystem.downedRavager && + DownedBossSystem.downedPlaguebringer && + DownedBossSystem.downedAstrumAureus && + DownedBossSystem.downedLeviathan && + DownedBossSystem.downedCalamitasClone && + DownedBossSystem.downedBrimstoneElemental && + DownedBossSystem.downedAquaticScourge && + DownedBossSystem.downedCryogen && + DownedBossSystem.downedSlimeGod && + (DownedBossSystem.downedHiveMind || DownedBossSystem.downedPerforator) && + DownedBossSystem.downedCrabulon && + DownedBossSystem.downedDesertScourge); + + AddCategory("CalamityCynosure", GetSplit("Cynosure")); + AddCategory("CalamityAllBosses", GetSplit("CalamityAllBosses")); + } + #endregion + + #region Subworld Library + // Wrapper function to detect if a subworld is in use for Subworld Library. + internal static bool InAnySubworld() + { + if (ExternalMods.subworldLibrary is null) + return false; + + foreach (Mod mod in ModLoader.Mods) + { + if (mod.Name.Equals(ExternalMods.subworldLibrary.Name)) + continue; + + bool anySubworldForMod = (ExternalMods.subworldLibrary.Call("AnyActive", mod) as bool?) ?? false; + if (anySubworldForMod) + return true; } + return false; } #endregion @@ -1265,79 +1361,94 @@ void RegisterSummon(int summonItem, int summonBuff, int summonProjectile) } #endregion - #region Colored Damage Types - // These are vanilla Terraria's colors for tooltips and damage - private static Color DefaultTooltipColor = Color.White; - private static Color DefaultDamageColor = new(255, 160, 80); - private static Color DefaultCritColor = new(255, 100, 30); - - // These are Colored Damage Types' colors for the Melee class - private static Color MeleeTooltipColor = new(254, 121, 2); - private static Color MeleeDamageColor = new(254, 121, 2); - private static Color MeleeCritColor = new(253, 62, 3); - - private static Color MeleeRangedTooltipColor = new(144, 171, 76); - private static Color MeleeRangedDamageColor = new(144, 171, 76); - private static Color MeleeRangedCritColor = new(86, 102, 46); - - private static Color RogueTooltipColor = new(206, 132, 227); - private static Color RogueDamageColor = new(206, 132, 227); - private static Color RogueCritColor = new(194, 38, 212); - private static Color StealthTooltipColor = RogueTooltipColor; - private static Color StealthDamageColor = new(185, 105, 250); - private static Color StealthCritColor = new(144, 33, 235); - - private static void ColoredDamageTypesSupport() + #region WikiThis + // This is a separate function because it only runs clientside + private static void WikiThisSupport() { - Mod coloredDamageTypes = ExternalMods.coloredDamageTypes; - if (coloredDamageTypes is null) + // Wikithis is a clientside mod + if (Main.dedServ) return; - // Anything that directly uses AverageDamageClass uses the default vanilla colors. - coloredDamageTypes.Call("AddDamageType", AverageDamageClass.Instance, DefaultTooltipColor, DefaultDamageColor, DefaultCritColor); - - // True melee uses the same colorations as regular Melee. - coloredDamageTypes.Call("AddDamageType", TrueMeleeDamageClass.Instance, MeleeTooltipColor, MeleeDamageColor, MeleeCritColor); - coloredDamageTypes.Call("AddDamageType", TrueMeleeNoSpeedDamageClass.Instance, MeleeTooltipColor, MeleeDamageColor, MeleeCritColor); - - // Melee-ranged hybrid damage uses a 50% blend between Melee and Ranged, turning into Olive green - coloredDamageTypes.Call("AddDamageType", MeleeRangedHybridDamageClass.Instance, MeleeRangedTooltipColor, MeleeRangedDamageColor, MeleeRangedCritColor); - - // Rogue has its own lavender color. Stealth strikes are hued towards violet so they stick out more. - // They would be hued towards magenta, but that would make them collide with Nebula-colored Magic in Colored Damage Types config. - coloredDamageTypes.Call("AddDamageType", RogueDamageClass.Instance, RogueTooltipColor, RogueDamageColor, RogueCritColor); - coloredDamageTypes.Call("AddDamageType", StealthDamageClass.Instance, StealthTooltipColor, StealthDamageColor, StealthCritColor); - } - #endregion - - #region Luminance - private static void RegisterWorldInfoIcon(Mod luminance, string texturePath, string hoverTextKey, Func shouldAppear, byte priority) - => luminance.Call("RegisterWorldInfoIcon", texturePath, hoverTextKey, shouldAppear, priority); - - private static void LuminanceSupport() - { - Mod luminance = ExternalMods.luminance; - if (luminance is null) + CalamityMod calamity = GetInstance(); + Mod wiki = ExternalMods.wikithis; + if (wiki is null) return; - Func deathEnabled = data => - { - if (!data.TryGetHeaderData(out var tagData)) - return false; + bool oldVersion = wiki.Version < new Version(2, 4, 7, 5); - return tagData.ContainsKey("DeathMode") && tagData.GetBool("DeathMode"); - }; + wiki.Call("AddModURL", calamity, oldVersion ? CalamityWikiURLOld : CalamityWikiURL); + wiki.Call(0, calamity, oldVersion ? CalamityWikiURLOld : CalamityWikiURL); + wiki.Call("AddWikiTexture", calamity, Request("CalamityMod/ModSupport/WikiThisIcon")); + wiki.Call(3, calamity, Request("CalamityMod/ModSupport/WikiThisIcon")); - Func revengeanceEnabled = data => - { - if (!data.TryGetHeaderData(out var tagData)) - return false; + // Clear up name conflicts + void ItemRedirect(int item, string pageName) => wiki.Call(1, item, pageName); + void EnemyRedirect(int item, string pageName) => wiki.Call(2, item, pageName); - return tagData.ContainsKey("RevengeanceMode") && tagData.GetBool("RevengeanceMode") && !(tagData.ContainsKey("DeathMode") && tagData.GetBool("DeathMode")); - }; + // Items + ItemRedirect(ItemType(), "Pineapple (calamity)"); + ItemRedirect(ItemType(), "Trash Can (pet)"); + // Lore items + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); + ItemRedirect(ItemType(), loreItemPage); - RegisterWorldInfoIcon(luminance, "CalamityMod/UI/ModeIndicator/ModeIndicator_Death", "Mods.CalamityMod.UI.Death", deathEnabled, 50); - RegisterWorldInfoIcon(luminance, "CalamityMod/UI/ModeIndicator/ModeIndicator_Rev", "Mods.CalamityMod.UI.Revengeance", revengeanceEnabled, 50); + // Enemies + EnemyRedirect(NPCType(), "Crown Jewels"); + EnemyRedirect(NPCType(), "Tooth Ball (Old Duke)"); + EnemyRedirect(NPCType(), "Enchantment"); + EnemyRedirect(NPCType(), "%3F%3F%3F"); } #endregion } diff --git a/NPCs/AquaticScourge/AquaticScourgeHead.cs b/NPCs/AquaticScourge/AquaticScourgeHead.cs index 28db71c293..6845fdc811 100644 --- a/NPCs/AquaticScourge/AquaticScourgeHead.cs +++ b/NPCs/AquaticScourge/AquaticScourgeHead.cs @@ -713,8 +713,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); - // If Aquatic Scourge has not yet been killed, notify players of buffed Acid Rain if (!DownedBossSystem.downedAquaticScourge) { diff --git a/NPCs/AstrumAureus/AstrumAureus.cs b/NPCs/AstrumAureus/AstrumAureus.cs index e9e311449f..452e631674 100644 --- a/NPCs/AstrumAureus/AstrumAureus.cs +++ b/NPCs/AstrumAureus/AstrumAureus.cs @@ -1339,8 +1339,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); - // If Astrum Aureus has not yet been killed, notify players of new Astral enemy drops if (!DownedBossSystem.downedAstrumAureus) { diff --git a/NPCs/AstrumDeus/AstrumDeusHead.cs b/NPCs/AstrumDeus/AstrumDeusHead.cs index fe6991d43f..0a32923c62 100644 --- a/NPCs/AstrumDeus/AstrumDeusHead.cs +++ b/NPCs/AstrumDeus/AstrumDeusHead.cs @@ -933,8 +933,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); - // Notify players that Astral Ore can be mined if Deus has never been killed yet if (!DownedBossSystem.downedAstrumDeus) { diff --git a/NPCs/BrimstoneElemental/BrimstoneElemental.cs b/NPCs/BrimstoneElemental/BrimstoneElemental.cs index d2704738f7..9dd34c9937 100644 --- a/NPCs/BrimstoneElemental/BrimstoneElemental.cs +++ b/NPCs/BrimstoneElemental/BrimstoneElemental.cs @@ -926,8 +926,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); - // Mark brimmy as dead DownedBossSystem.downedBrimstoneElemental = true; CalamityNetcode.SyncWorld(); diff --git a/NPCs/Bumblebirb/Dragonfolly.cs b/NPCs/Bumblebirb/Dragonfolly.cs index 51810443f1..68a06fcffd 100644 --- a/NPCs/Bumblebirb/Dragonfolly.cs +++ b/NPCs/Bumblebirb/Dragonfolly.cs @@ -1280,8 +1280,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); - // Mark The Dragonfolly as dead DownedBossSystem.downedDragonfolly = true; CalamityNetcode.SyncWorld(); diff --git a/NPCs/CalClone/CalamitasClone.cs b/NPCs/CalClone/CalamitasClone.cs index 7f96e910bc..4d8691b63f 100644 --- a/NPCs/CalClone/CalamitasClone.cs +++ b/NPCs/CalClone/CalamitasClone.cs @@ -1086,8 +1086,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); - CalamityGlobalTownNPC.SetNewShopVariable(new int[] { ModContent.NPCType() }, DownedBossSystem.downedCalamitasClone); // Mark the Calamitas Clone as dead diff --git a/NPCs/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index a41d9d117e..71ab36666b 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -5353,26 +5353,6 @@ public static bool GetDownedBossVariable(int type) } #endregion - #region Speedrun Display - public static void SetNewBossJustDowned(NPC npc) - { - if (!GetDownedBossVariable(npc.type)) - { - CalamityNPCSets.BossSpeedrunTimerID.TryGetValue(npc.type, out int newBossTypeJustDowned); - for (int i = 0; i < Main.maxPlayers; i++) - { - Player player = Main.player[i]; - if (!player.active) - continue; - - CalamityPlayer mp = player.Calamity(); - mp.lastSplitType = newBossTypeJustDowned; - mp.lastSplit = mp.previousSessionTotal.Add(SpeedrunTimerSystem.Elapsed); - } - } - } - #endregion - #region Player Counts public static bool AnyLivingPlayers() { diff --git a/NPCs/CalamityGlobalNPCLoot.cs b/NPCs/CalamityGlobalNPCLoot.cs index 8576c9b207..7d93ea9978 100644 --- a/NPCs/CalamityGlobalNPCLoot.cs +++ b/NPCs/CalamityGlobalNPCLoot.cs @@ -1936,7 +1936,6 @@ public override void OnKill(NPC npc) if ((npc.boss && (npc.type == NPCID.EaterofWorldsHead || npc.type == NPCID.EaterofWorldsBody || npc.type == NPCID.EaterofWorldsTail)) || npc.type == NPCID.BrainofCthulhu) { SetNewShopVariable(new int[] { NPCID.Merchant, NPCID.ArmsDealer, NPCID.Dryad }, NPC.downedBoss2); - SetNewBossJustDowned(npc); } // On-kill NON-LOOT behavior for every other vanilla boss (and Dreadnautilus) @@ -1944,26 +1943,21 @@ public override void OnKill(NPC npc) { case NPCID.KingSlime: SetNewShopVariable(new int[] { NPCID.Dryad }, NPC.downedSlimeKing); - SetNewBossJustDowned(npc); break; case NPCID.EyeofCthulhu: SetNewShopVariable(new int[] { NPCID.Merchant, NPCID.Dryad }, NPC.downedBoss1); - SetNewBossJustDowned(npc); break; case NPCID.Deerclops: - SetNewBossJustDowned(npc); break; case NPCID.QueenBee: SetNewShopVariable(new int[] { NPCID.ArmsDealer, NPCID.Dryad }, NPC.downedQueenBee); - SetNewBossJustDowned(npc); break; case NPCID.SkeletronHead: SetNewShopVariable(new int[] { NPCID.Merchant, NPCID.Dryad }, NPC.downedBoss3); - SetNewBossJustDowned(npc); // First kill: Notify of Abyss chests being unlocked. if (!NPC.downedBoss3 && !BossRushEvent.BossRushActive) @@ -1979,7 +1973,6 @@ public override void OnKill(NPC npc) case NPCID.WallofFlesh: SetNewShopVariable(new int[] { NPCID.Merchant, NPCID.ArmsDealer, NPCID.Dryad, NPCID.Painter, NPCID.WitchDoctor, NPCID.Stylist, NPCID.DyeTrader, NPCID.Demolitionist, NPCID.PartyGirl, NPCID.Clothier, NPCID.SkeletonMerchant }, Main.hardMode); - SetNewBossJustDowned(npc); if (!Main.hardMode && !BossRushEvent.BossRushActive) { @@ -1999,14 +1992,12 @@ public override void OnKill(NPC npc) CalamityNetcode.SyncWorld(); break; - case NPCID.QueenSlimeBoss: - SetNewBossJustDowned(npc); - break; + //case NPCID.QueenSlimeBoss: + // break; case NPCID.TheDestroyer: SetNewShopVariable(new int[] { NPCID.Demolitionist, NPCID.DD2Bartender, NPCID.Stylist, NPCID.Truffle }, NPC.downedMechBossAny); SetNewShopVariable(new int[] { NPCID.Stylist, ModContent.NPCType(), ModContent.NPCType() }, NPC.downedMechBoss1 || !NPC.downedMechBoss2 || !NPC.downedMechBoss3); - SetNewBossJustDowned(npc); if (!NPC.downedMechBoss1 && CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) SpawnMechBossHardmodeOres(); @@ -2018,7 +2009,6 @@ public override void OnKill(NPC npc) { SetNewShopVariable(new int[] { NPCID.Demolitionist, NPCID.DD2Bartender, NPCID.Stylist, NPCID.Truffle }, NPC.downedMechBossAny); SetNewShopVariable(new int[] { NPCID.Stylist, ModContent.NPCType(), ModContent.NPCType() }, !NPC.downedMechBoss1 || NPC.downedMechBoss2 || !NPC.downedMechBoss3); - SetNewBossJustDowned(npc); if (!NPC.downedMechBoss2 && CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) SpawnMechBossHardmodeOres(); @@ -2028,7 +2018,6 @@ public override void OnKill(NPC npc) case NPCID.SkeletronPrime: SetNewShopVariable(new int[] { NPCID.Demolitionist, NPCID.DD2Bartender, NPCID.Stylist, NPCID.Truffle }, NPC.downedMechBossAny); SetNewShopVariable(new int[] { NPCID.Stylist, ModContent.NPCType(), ModContent.NPCType() }, !NPC.downedMechBoss1 || !NPC.downedMechBoss2 || NPC.downedMechBoss3); - SetNewBossJustDowned(npc); if (!NPC.downedMechBoss3 && CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) SpawnMechBossHardmodeOres(); @@ -2036,7 +2025,6 @@ public override void OnKill(NPC npc) case NPCID.Plantera: SetNewShopVariable(new int[] { NPCID.WitchDoctor, NPCID.Truffle, NPCID.BestiaryGirl, ModContent.NPCType() }, NPC.downedPlantBoss); - SetNewBossJustDowned(npc); // Spawn Perennial Ore if Plantera has never been killed if (!NPC.downedPlantBoss && !BossRushEvent.BossRushActive) @@ -2054,9 +2042,8 @@ public override void OnKill(NPC npc) } break; - case NPCID.HallowBoss: - SetNewBossJustDowned(npc); - break; + //case NPCID.HallowBoss: + // break; case NPCID.Everscream: SetNewShopVariable(new int[] { ModContent.NPCType() }, NPC.downedChristmasTree || !NPC.downedChristmasSantank || !NPC.downedChristmasIceQueen); @@ -2072,7 +2059,6 @@ public override void OnKill(NPC npc) case NPCID.Golem: SetNewShopVariable(new int[] { NPCID.ArmsDealer, NPCID.Cyborg, NPCID.Steampunker, NPCID.Wizard, NPCID.WitchDoctor, NPCID.DD2Bartender, ModContent.NPCType() }, NPC.downedGolemBoss); - SetNewBossJustDowned(npc); // If Golem has never been killed, send a message about the Plague. if (!NPC.downedGolemBoss && !BossRushEvent.BossRushActive) @@ -2093,13 +2079,11 @@ public override void OnKill(NPC npc) CalamityNetcode.SyncWorld(); break; - case NPCID.DukeFishron: - SetNewBossJustDowned(npc); - break; + //case NPCID.DukeFishron: + // break; - case NPCID.CultistBoss: - SetNewBossJustDowned(npc); - break; + //case NPCID.CultistBoss: + // break; case NPCID.LunarTowerSolar: SetNewShopVariable(new int[] { NPCID.BestiaryGirl }, NPC.downedTowerSolar); @@ -2107,7 +2091,6 @@ public override void OnKill(NPC npc) case NPCID.MoonLordCore: SetNewShopVariable(new int[] { NPCID.Princess, ModContent.NPCType() }, NPC.downedMoonlord); - SetNewBossJustDowned(npc); string key5 = "Mods.CalamityMod.Status.Progression.MoonBossText"; Color messageColor5 = Color.Orange; diff --git a/NPCs/CeaselessVoid/CeaselessVoid.cs b/NPCs/CeaselessVoid/CeaselessVoid.cs index ed48566ff3..b937f5695c 100644 --- a/NPCs/CeaselessVoid/CeaselessVoid.cs +++ b/NPCs/CeaselessVoid/CeaselessVoid.cs @@ -737,7 +737,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); DownedBossSystem.downedCeaselessVoid = true; CalamityNetcode.SyncWorld(); } diff --git a/NPCs/Crabulon/Crabulon.cs b/NPCs/Crabulon/Crabulon.cs index 3ecd980cd7..df55f8e6c7 100644 --- a/NPCs/Crabulon/Crabulon.cs +++ b/NPCs/Crabulon/Crabulon.cs @@ -1206,8 +1206,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); - // Start the Goblin Invasion if the player hasn't gotten one yet (this also gives players more of a reason to fight this boss) if (!NPC.downedGoblins && Main.netMode != NetmodeID.MultiplayerClient && !Main.snowMoon && !Main.pumpkinMoon && !DD2Event.Ongoing && !Main.ShouldNormalEventsBeAbleToStart() && Main.invasionType != 1) Main.StartInvasion(); diff --git a/NPCs/Cryogen/Cryogen.cs b/NPCs/Cryogen/Cryogen.cs index edea410818..dc2dd7b730 100644 --- a/NPCs/Cryogen/Cryogen.cs +++ b/NPCs/Cryogen/Cryogen.cs @@ -1400,8 +1400,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); - // Spawn Permafrost if he isn't in the world int permafrostNPC = NPC.FindFirstNPC(ModContent.NPCType()); if (permafrostNPC == -1 && !BossRushEvent.BossRushActive) diff --git a/NPCs/DesertScourge/DesertScourgeHead.cs b/NPCs/DesertScourge/DesertScourgeHead.cs index ae7a2ac6fb..049589178e 100644 --- a/NPCs/DesertScourge/DesertScourgeHead.cs +++ b/NPCs/DesertScourge/DesertScourgeHead.cs @@ -929,8 +929,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); - // If Desert Scourge has not been killed yet, notify players that the Sunken Sea is open and Sandstorms can happen. if (!DownedBossSystem.downedDesertScourge) { diff --git a/NPCs/DevourerofGods/DevourerofGodsHead.cs b/NPCs/DevourerofGods/DevourerofGodsHead.cs index 9b1d42e7e7..f7f748403c 100644 --- a/NPCs/DevourerofGods/DevourerofGodsHead.cs +++ b/NPCs/DevourerofGods/DevourerofGodsHead.cs @@ -2562,8 +2562,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); - CalamityGlobalTownNPC.SetNewShopVariable(new int[] { ModContent.NPCType() }, DownedBossSystem.downedDoG); // If DoG has not been killed yet, notify players that the holiday moons are buffed diff --git a/NPCs/ExoMechs/Ares/AresBody.cs b/NPCs/ExoMechs/Ares/AresBody.cs index a254f33078..8fe4754aca 100644 --- a/NPCs/ExoMechs/Ares/AresBody.cs +++ b/NPCs/ExoMechs/Ares/AresBody.cs @@ -1562,8 +1562,6 @@ public static void DoMiscDeathEffects(NPC npc, MechType mechType) if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(npc); - switch (mechType) { case MechType.Thanatos: diff --git a/NPCs/HiveMind/HiveMind.cs b/NPCs/HiveMind/HiveMind.cs index c3da3cc0f7..0099c49790 100644 --- a/NPCs/HiveMind/HiveMind.cs +++ b/NPCs/HiveMind/HiveMind.cs @@ -1303,8 +1303,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); - // If neither The Hive Mind nor The Perforator Hive have been killed yet, notify players of Aerialite Ore if (!DownedBossSystem.downedHiveMind && !DownedBossSystem.downedPerforator) { diff --git a/NPCs/Leviathan/Leviathan.cs b/NPCs/Leviathan/Leviathan.cs index e25f31ae91..67871adba7 100644 --- a/NPCs/Leviathan/Leviathan.cs +++ b/NPCs/Leviathan/Leviathan.cs @@ -808,8 +808,6 @@ public static void RealOnKill(NPC npc) if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(npc); - // Abyss awakens after killing Anahita & Leviathan string key = "Mods.CalamityMod.Status.Progression.AbyssDropsText"; Color messageColor = Color.RoyalBlue; diff --git a/NPCs/OldDuke/OldDuke.cs b/NPCs/OldDuke/OldDuke.cs index 6ed76faa1a..097ff41aaf 100644 --- a/NPCs/OldDuke/OldDuke.cs +++ b/NPCs/OldDuke/OldDuke.cs @@ -2067,8 +2067,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); - CalamityGlobalTownNPC.SetNewShopVariable(new int[] { ModContent.NPCType() }, DownedBossSystem.downedBoomerDuke); // Mark Old Duke as dead diff --git a/NPCs/Perforator/PerforatorHive.cs b/NPCs/Perforator/PerforatorHive.cs index 4699dddf4c..1d503a6867 100644 --- a/NPCs/Perforator/PerforatorHive.cs +++ b/NPCs/Perforator/PerforatorHive.cs @@ -649,8 +649,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); - // If neither The Hive Mind nor The Perforator Hive have been killed yet, notify players of Aerialite Ore if (!DownedBossSystem.downedHiveMind && !DownedBossSystem.downedPerforator) { diff --git a/NPCs/PlaguebringerGoliath/PlaguebringerGoliath.cs b/NPCs/PlaguebringerGoliath/PlaguebringerGoliath.cs index 47724c6a71..6b8922a690 100644 --- a/NPCs/PlaguebringerGoliath/PlaguebringerGoliath.cs +++ b/NPCs/PlaguebringerGoliath/PlaguebringerGoliath.cs @@ -1319,8 +1319,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); - // Mark PBG as dead DownedBossSystem.downedPlaguebringer = true; CalamityNetcode.SyncWorld(); diff --git a/NPCs/Polterghast/Polterghast.cs b/NPCs/Polterghast/Polterghast.cs index 684cccea79..4e2fc6262f 100644 --- a/NPCs/Polterghast/Polterghast.cs +++ b/NPCs/Polterghast/Polterghast.cs @@ -941,8 +941,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); - CalamityGlobalTownNPC.SetNewShopVariable(new int[] { NPCID.Cyborg }, DownedBossSystem.downedPolterghast); // If Polterghast has not been killed, notify players about the Abyss minibosses now dropping items diff --git a/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs b/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs index b5008992fa..88531ba348 100644 --- a/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs +++ b/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs @@ -1237,8 +1237,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); - // Mark the Profaned Guardians as dead DownedBossSystem.downedGuardians = true; CalamityNetcode.SyncWorld(); diff --git a/NPCs/Providence/Providence.cs b/NPCs/Providence/Providence.cs index 5005f77496..b4cbe75273 100644 --- a/NPCs/Providence/Providence.cs +++ b/NPCs/Providence/Providence.cs @@ -1988,8 +1988,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); - // If Providence has not been killed, notify players of Uelibloom Ore if (!DownedBossSystem.downedProvidence) { diff --git a/NPCs/Ravager/RavagerBody.cs b/NPCs/Ravager/RavagerBody.cs index 8df6960258..4da391d3f4 100644 --- a/NPCs/Ravager/RavagerBody.cs +++ b/NPCs/Ravager/RavagerBody.cs @@ -997,8 +997,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); - // Mark Ravager as dead DownedBossSystem.downedRavager = true; CalamityNetcode.SyncWorld(); diff --git a/NPCs/Signus/Signus.cs b/NPCs/Signus/Signus.cs index 9e4f9f9c79..e2e6c1cdb5 100644 --- a/NPCs/Signus/Signus.cs +++ b/NPCs/Signus/Signus.cs @@ -899,7 +899,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); DownedBossSystem.downedSignus = true; CalamityNetcode.SyncWorld(); } diff --git a/NPCs/SlimeGod/SlimeGodCore.cs b/NPCs/SlimeGod/SlimeGodCore.cs index 4981b94c3f..31fd1516e4 100644 --- a/NPCs/SlimeGod/SlimeGodCore.cs +++ b/NPCs/SlimeGod/SlimeGodCore.cs @@ -628,8 +628,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); - // Mark the Slime God as dead DownedBossSystem.downedSlimeGod = true; CalamityNetcode.SyncWorld(); diff --git a/NPCs/StormWeaver/StormWeaverHead.cs b/NPCs/StormWeaver/StormWeaverHead.cs index 9c34dbc2f2..7c60820b23 100644 --- a/NPCs/StormWeaver/StormWeaverHead.cs +++ b/NPCs/StormWeaver/StormWeaverHead.cs @@ -957,7 +957,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); DownedBossSystem.downedStormWeaver = true; CalamityNetcode.SyncWorld(); } diff --git a/NPCs/SupremeCalamitas/SupremeCalamitas.cs b/NPCs/SupremeCalamitas/SupremeCalamitas.cs index d27b72b1ba..28ae5305f8 100644 --- a/NPCs/SupremeCalamitas/SupremeCalamitas.cs +++ b/NPCs/SupremeCalamitas/SupremeCalamitas.cs @@ -3521,8 +3521,6 @@ public override void OnKill() if (BossRushEvent.BossRushActive) return; - CalamityGlobalNPC.SetNewBossJustDowned(NPC); - // Increase the player's SCal kill count if (Main.player[NPC.target].Calamity().sCalKillCount < 5) Main.player[NPC.target].Calamity().sCalKillCount++; diff --git a/NPCs/Yharon/Yharon.cs b/NPCs/Yharon/Yharon.cs index c554318e43..f7ba6cca1c 100644 --- a/NPCs/Yharon/Yharon.cs +++ b/NPCs/Yharon/Yharon.cs @@ -3019,7 +3019,6 @@ public override void OnKill() return; CalamityGlobalTownNPC.SetNewShopVariable(new int[] { ModContent.NPCType() }, DownedBossSystem.downedYharon); - CalamityGlobalNPC.SetNewBossJustDowned(NPC); // If Yharon has not been killed yet, notify players of Auric Ore if (!DownedBossSystem.downedYharon) diff --git a/Systems/Collections/CalamityNPCSets.cs b/Systems/Collections/CalamityNPCSets.cs index 5a234bd2a8..702fd10499 100644 --- a/Systems/Collections/CalamityNPCSets.cs +++ b/Systems/Collections/CalamityNPCSets.cs @@ -295,66 +295,5 @@ public static class CalamityNPCSets { NPCID.MoonLordHead, 60000 }, { NPCID.MoonLordLeechBlob, 800 } }; - - /// - /// Associates an NPC type with an ID number used for Calamity's Speedrun Timer. Used for drawing the correct map icon for the boss.
- /// If an NPC type is not a key in this dictionary, then it will not be displayed on the Speedrun Timer. - ///
- public static Dictionary BossSpeedrunTimerID = new Dictionary - { - { NPCID.KingSlime, 1 }, - { NPCType(), 2 }, - { NPCID.EyeofCthulhu, 3 }, - { NPCType(), 4 }, - { NPCID.EaterofWorldsHead, 5 }, - { NPCID.EaterofWorldsBody, 5 }, - { NPCID.EaterofWorldsTail, 5 }, - { NPCID.BrainofCthulhu, 6 }, - { NPCType(), 7 }, - { NPCType(), 8 }, - { NPCID.QueenBee, 9 }, - { NPCID.SkeletronHead, 10 }, - { NPCType(), 11 }, - { NPCType(), 11 }, - { NPCType(), 11 }, - { NPCID.WallofFlesh, 12 }, - { NPCType(), 13 }, - { NPCID.Retinazer, 14 }, - { NPCID.Spazmatism, 14 }, - { NPCType(), 15 }, - { NPCID.TheDestroyer, 16 }, - { NPCType(), 17 }, - { NPCID.SkeletronPrime, 18 }, - { NPCType(), 19 }, - { NPCID.Plantera, 20 }, - { NPCType(), 21 }, - { NPCType(), 21 }, - { NPCType(), 22 }, - { NPCID.Golem, 23 }, - { NPCType(), 24 }, - { NPCID.DukeFishron, 25 }, - { NPCType(), 26 }, - { NPCID.CultistBoss, 27 }, - { NPCType(), 28 }, - { NPCID.MoonLordCore, 29 }, - { NPCType(), 30 }, - { NPCType(), 31 }, - { NPCType(), 32 }, - { NPCType(), 33 }, - { NPCType(), 34 }, - { NPCType(), 35 }, - { NPCType(), 36 }, - { NPCType(), 37 }, - { NPCType(), 38 }, - { NPCType(), 39 }, - { NPCType(), 40 }, - { NPCType(), 41 }, - { NPCType(), 41 }, - { NPCType(), 41 }, - { NPCType(), 41 }, - { NPCID.QueenSlimeBoss, 42 }, - { NPCID.HallowBoss, 43 }, - { NPCID.Deerclops, 44 } - }; } } diff --git a/Systems/Mechanic/SpeedrunTimerSystem.cs b/Systems/Mechanic/SpeedrunTimerSystem.cs deleted file mode 100644 index f5a2226b32..0000000000 --- a/Systems/Mechanic/SpeedrunTimerSystem.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Diagnostics; -using CalamityMod.CalPlayer; -using Terraria.ModLoader; - -namespace CalamityMod.Systems -{ - internal sealed class SpeedrunTimerSystem : ModSystem - { - public static TimeSpan Elapsed => _SpeedrunTimer.Elapsed; - - private static Stopwatch _SpeedrunTimer = new(); - - private const string FormatStringForDay = @"hh\:mm\:ss\.ff"; - private const string FormatString = @"d\:hh\:mm\:ss\.ff"; - - public static void Restart() - { - _SpeedrunTimer.Restart(); - } - - public static string GetTimerText(CalamityPlayer player) - { - string formatStr = @"hh\:mm\:ss\.ff"; - string formatStrDays = @"d\:hh\:mm\:ss\.ff"; - TimeSpan totalTime = Elapsed.Add(player.previousSessionTotal); - return totalTime.ToString(totalTime.Days > 0 ? formatStrDays : formatStr); - } - - public static string GetSplitText(CalamityPlayer player) - { - TimeSpan split = player.lastSplit; - return split.ToString(split.Days > 0 ? FormatStringForDay : FormatString); - } - - public override void PreSaveAndQuit() => _SpeedrunTimer?.Stop(); - } -} diff --git a/Systems/UIManagementSystem.cs b/Systems/UIManagementSystem.cs index 337623ac94..17b552d47a 100644 --- a/Systems/UIManagementSystem.cs +++ b/Systems/UIManagementSystem.cs @@ -62,13 +62,6 @@ public override void ModifyInterfaceLayers(List layers) return true; }, InterfaceScaleType.UI)); - // Speedrun Timer - layers.Insert(mouseIndex, new LegacyGameInterfaceLayer("Speedrun Timer", delegate () - { - SpeedrunTimerUI.Draw(Main.LocalPlayer); - return true; - }, InterfaceScaleType.None)); - // Rage and Adrenaline bars layers.Insert(mouseIndex, new LegacyGameInterfaceLayer("Rage and Adrenaline UI", delegate () { diff --git a/UI/SpeedrunTimerUI.cs b/UI/SpeedrunTimerUI.cs deleted file mode 100644 index 43609177a0..0000000000 --- a/UI/SpeedrunTimerUI.cs +++ /dev/null @@ -1,137 +0,0 @@ -using CalamityMod.CalPlayer; -using CalamityMod.NPCs.AquaticScourge; -using CalamityMod.NPCs.AstrumAureus; -using CalamityMod.NPCs.AstrumDeus; -using CalamityMod.NPCs.BrimstoneElemental; -using CalamityMod.NPCs.Bumblebirb; -using CalamityMod.NPCs.CalClone; -using CalamityMod.NPCs.CeaselessVoid; -using CalamityMod.NPCs.Crabulon; -using CalamityMod.NPCs.Cryogen; -using CalamityMod.NPCs.DesertScourge; -using CalamityMod.NPCs.ExoMechs.Ares; -using CalamityMod.NPCs.Leviathan; -using CalamityMod.NPCs.OldDuke; -using CalamityMod.NPCs.Perforator; -using CalamityMod.NPCs.PlaguebringerGoliath; -using CalamityMod.NPCs.PrimordialWyrm; -using CalamityMod.NPCs.ProfanedGuardians; -using CalamityMod.NPCs.Providence; -using CalamityMod.NPCs.Ravager; -using CalamityMod.NPCs.Signus; -using CalamityMod.NPCs.SlimeGod; -using CalamityMod.NPCs.Yharon; -using CalamityMod.Systems; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using Terraria; -using Terraria.GameContent; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.UI -{ - public class SpeedrunTimerUI - { - // These values put the Speedrun Timer roughly at the top center of a 1080p screen. - internal const float DefaultTimerPosX = 46f; - internal const float DefaultTimerPosY = 1.481f; - - private static readonly float SplitHorizontalOffset = +30f; - private static readonly float SplitVerticalOffset = +44f; - - public static void Draw(Player player) - { - if (Main.gameMenu || !CalamityClientConfig.Instance.SpeedrunTimer) - return; - - // Sanity check the planned position before drawing - Vector2 screenRatioPosition = new Vector2(CalamityClientConfig.Instance.SpeedrunTimerPosX, CalamityClientConfig.Instance.SpeedrunTimerPosY); - if (screenRatioPosition.X < 0f || screenRatioPosition.X > 100f) - screenRatioPosition.X = DefaultTimerPosX; - if (screenRatioPosition.Y < 0f || screenRatioPosition.Y > 100f) - screenRatioPosition.Y = DefaultTimerPosY; - - // Convert the screen ratio position to an absolute position in pixels - // Cast to integer to prevent blurriness which results from decimal pixel positions - Vector2 screenPos = screenRatioPosition; - screenPos.X = (int)(screenPos.X * 0.01f * Main.screenWidth); - screenPos.Y = (int)(screenPos.Y * 0.01f * Main.screenHeight); - - CalamityPlayer calamityPlayer = player.Calamity(); - - // Main timer - string text = SpeedrunTimerSystem.GetTimerText(calamityPlayer); - float scale = 2f; - Utils.DrawBorderStringFourWay(Main.spriteBatch, FontAssets.MouseText.Value, text, screenPos.X, screenPos.Y, Color.White, Color.Black, default, scale); - - if (calamityPlayer.lastSplitType == -1) - return; - - // Latest split - text = SpeedrunTimerSystem.GetSplitText(calamityPlayer); - scale = 1f; - float lineTwoX = screenPos.X + SplitHorizontalOffset; - float lineTwoY = screenPos.Y + SplitVerticalOffset; - Texture2D texture = GetSplitIcon(calamityPlayer.lastSplitType); - - // If a split icon exists, draw it. - if (texture != null) - Main.spriteBatch.Draw(texture, new Vector2(lineTwoX - texture.Width - 4f, lineTwoY), null, Color.White, 0f, default, 1f, SpriteEffects.None, 0f); - - // Draw the latest split time. - Utils.DrawBorderStringFourWay(Main.spriteBatch, FontAssets.MouseText.Value, text, lineTwoX, lineTwoY, Color.White, Color.Black, default, scale); - } - - // TODO -- these should not be magic numbers that are not used ANYWHERE else - private static Texture2D GetSplitIcon(int magicNumber) => magicNumber switch - { - 1 => TextureAssets.NpcHeadBoss[7].Value, // King Slime - 2 => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[ModContent.NPCType()]].Value, - 3 => TextureAssets.NpcHeadBoss[1].Value, // Eye of Cthulhu - 4 => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[ModContent.NPCType()]].Value, - 5 => TextureAssets.NpcHeadBoss[2].Value, // Eater of Worlds - 6 => TextureAssets.NpcHeadBoss[23].Value, // Brain of Cthulhu - 7 => ModContent.Request("CalamityMod/NPCs/HiveMind/HiveMindP2_Head_Boss").Value, - 8 => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[ModContent.NPCType()]].Value, - 9 => TextureAssets.NpcHeadBoss[14].Value, // Queen Bee - 10 => TextureAssets.NpcHeadBoss[19].Value, // Skeletron - 11 => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[ModContent.NPCType()]].Value, - 12 => TextureAssets.NpcHeadBoss[22].Value, // Wall of Flesh - 13 => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[ModContent.NPCType()]].Value, - 14 => TextureAssets.NpcHeadBoss[21].Value, // The Twins - 15 => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[ModContent.NPCType()]].Value, - 16 => TextureAssets.NpcHeadBoss[25].Value, // The Destroyer - 17 => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[ModContent.NPCType()]].Value, - 18 => TextureAssets.NpcHeadBoss[18].Value, // Skeletron Prime - 19 => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[ModContent.NPCType()]].Value, - 20 => TextureAssets.NpcHeadBoss[12].Value, // Plantera - 21 => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[ModContent.NPCType()]].Value, - 22 => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[ModContent.NPCType()]].Value, - 23 => TextureAssets.NpcHeadBoss[5].Value, // Golem - 24 => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[ModContent.NPCType()]].Value, - 25 => TextureAssets.NpcHeadBoss[4].Value, // Duke Fishron - 26 => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[ModContent.NPCType()]].Value, - 27 => TextureAssets.NpcHeadBoss[31].Value, // Lunatic Cultist - 28 => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[ModContent.NPCType()]].Value, - 29 => TextureAssets.NpcHeadBoss[8].Value, // Moon Lord - 30 => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[ModContent.NPCType()]].Value, - 31 => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[ModContent.NPCType()]].Value, - 32 => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[ModContent.NPCType()]].Value, - 33 => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[ModContent.NPCType()]].Value, - 34 => ModContent.Request("CalamityMod/NPCs/StormWeaver/StormWeaverHeadNaked_Head_Boss").Value, - 35 => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[ModContent.NPCType()]].Value, - 36 => ModContent.Request("CalamityMod/NPCs/Polterghast/Necroplasm_Head_Boss").Value, - 37 => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[ModContent.NPCType()]].Value, - 38 => ModContent.Request("CalamityMod/NPCs/DevourerofGods/DevourerofGodsHead_Head_Boss").Value, - 39 => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[ModContent.NPCType()]].Value, - 40 => ModContent.Request("CalamityMod/NPCs/SupremeCalamitas/HoodlessHeadIcon").Value, - 41 => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[ModContent.NPCType()]].Value, - 42 => TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[ModContent.NPCType()]].Value, - 43 => TextureAssets.NpcHeadBoss[38].Value, // Queen Slime - 44 => TextureAssets.NpcHeadBoss[37].Value, // Empress of Light - 45 => TextureAssets.NpcHeadBoss[39].Value, // Deerclops - _ => null - }; - } -}