From 48ffe33eaf1fa49dc745687e4ae9145e01bf3a5f Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Sat, 18 May 2024 20:50:05 -0500 Subject: [PATCH 001/401] Reduced Purple Candle defense effectiveness increase from 15% to 10% and Blue Candle movement speed and wing time increase from 10% to 5%. --- Buffs/Placeables/CirrusPurpleCandleBuff.cs | 2 +- CalPlayer/CalamityPlayerMiscEffects.cs | 4 ++-- Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Buffs/Placeables/CirrusPurpleCandleBuff.cs b/Buffs/Placeables/CirrusPurpleCandleBuff.cs index 1d50225a40..a56d3e179b 100644 --- a/Buffs/Placeables/CirrusPurpleCandleBuff.cs +++ b/Buffs/Placeables/CirrusPurpleCandleBuff.cs @@ -6,7 +6,7 @@ namespace CalamityMod.Buffs.Placeables { public class CirrusPurpleCandleBuff : ModBuff { - public static float DefenseRatioBonus = 0.15f; + public static float DefenseRatioBonus = 0.1f; public override void SetStaticDefaults() { diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index e7486c2ef0..4da98a113f 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -2819,7 +2819,7 @@ private void OtherBuffEffects() (harpyRing ? 0.2 : 0D) + (reaverSpeed ? 0.1 : 0D) + (angelTreads ? 0.1 : 0D) + - (blueCandle ? 0.1 : 0D) + + (blueCandle ? 0.05 : 0D) + (soaring ? 0.1 : 0D) + (prismaticGreaves ? 0.1 : 0D) + (plagueReaper ? 0.05 : 0D) + @@ -2827,7 +2827,7 @@ private void OtherBuffEffects() (Player.empressBrooch ? 0.25 : 0D); if (blueCandle) - Player.moveSpeed += 0.1f; + Player.moveSpeed += 0.05f; if (community) { diff --git a/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson b/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson index 2db3dd95ea..15755848c2 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson @@ -730,7 +730,7 @@ ResilientCandle: { DisplayName: Resilient Candle Tooltip: ''' - When placed, nearby players' defense blocks 15% more damage + When placed, nearby players' defense blocks 10% more damage 'Neither rain nor wind can snuff its undying flame' ''' } @@ -984,7 +984,7 @@ WeightlessCandle: { DisplayName: Weightless Candle Tooltip: ''' - When placed, nearby players gain 10% movement speed, 10% wing time and 5% acceleration + When placed, nearby players gain 5% increased movement speed, wing time and acceleration 'The floating flame seems to uplift your very spirit' ''' } From d1d2ca12ada41a4ac2e9479172f23dff67549809 Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Sat, 18 May 2024 12:26:34 +0700 Subject: [PATCH 002/401] so true memes (magna cannon 0 damage) --- Items/Weapons/Ranged/MagnaCannon.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Items/Weapons/Ranged/MagnaCannon.cs b/Items/Weapons/Ranged/MagnaCannon.cs index 88422994c3..aa926fe2ab 100644 --- a/Items/Weapons/Ranged/MagnaCannon.cs +++ b/Items/Weapons/Ranged/MagnaCannon.cs @@ -52,7 +52,7 @@ public override void SetDefaults() public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) { Vector2 spawnPosition = player.RotatedRelativePoint(player.MountedCenter); - Projectile.NewProjectileDirect(source, spawnPosition, player.Calamity().mouseWorld - player.RotatedRelativePoint(player.MountedCenter), ModContent.ProjectileType(), 0, 0f, player.whoAmI); + Projectile.NewProjectileDirect(source, spawnPosition, player.Calamity().mouseWorld - player.RotatedRelativePoint(player.MountedCenter), ModContent.ProjectileType(), damage, knockback, player.whoAmI); return false; } From dc74fbbecacfaa34d05cb7e88aa492758bed13ce Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Sat, 18 May 2024 12:27:40 +0700 Subject: [PATCH 003/401] opal --- Items/Weapons/Ranged/OpalStriker.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Items/Weapons/Ranged/OpalStriker.cs b/Items/Weapons/Ranged/OpalStriker.cs index 35158cca97..2367059962 100644 --- a/Items/Weapons/Ranged/OpalStriker.cs +++ b/Items/Weapons/Ranged/OpalStriker.cs @@ -51,7 +51,7 @@ public override void SetDefaults() public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) { Vector2 spawnPosition = player.RotatedRelativePoint(player.MountedCenter, true); - Projectile.NewProjectileDirect(source, spawnPosition, player.Calamity().mouseWorld - spawnPosition, ModContent.ProjectileType(), 0, 0f, player.whoAmI); + Projectile.NewProjectileDirect(source, spawnPosition, player.Calamity().mouseWorld - spawnPosition, ModContent.ProjectileType(), damage, knockback, player.whoAmI); return false; } From 7581a6f79ebb735e195cd8c4c5798969553cb06a Mon Sep 17 00:00:00 2001 From: Memes Date: Sat, 18 May 2024 14:09:15 +0200 Subject: [PATCH 004/401] Entirely fixed MP Harvest Staff, thanks Direwolf. --- Projectiles/Summon/HarvestStaffMinion.cs | 55 +++++++++++------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/Projectiles/Summon/HarvestStaffMinion.cs b/Projectiles/Summon/HarvestStaffMinion.cs index c2b19b285f..15842a6816 100644 --- a/Projectiles/Summon/HarvestStaffMinion.cs +++ b/Projectiles/Summon/HarvestStaffMinion.cs @@ -211,8 +211,6 @@ public Projectile MySentry } } - public bool KILLYOURSELF { get; set; } - #endregion #region AI and Collisions @@ -222,8 +220,11 @@ public override void AI() Owner ??= Main.player[Projectile.owner]; Projectile.width = Projectile.height = Variant == 0 ? 28 : (Variant == 1 ? 22 : 20); - if (Animation == AnimationState.Grow && (MySentry is null || Projectile.Distance(MySentry.Center) > 600f)) + if (Animation == AnimationState.Grow && (MySentry is null || Projectile.Distance(MySentry.Center) > 600f) && Main.myPlayer == Projectile.owner) + { Projectile.Kill(); + return; + } Target = Projectile.Center.MinionHoming(State == AIState.Still ? PlantedEnemyDistanceDetection : NormalEnemyDistanceDetection, Owner, false); @@ -243,9 +244,6 @@ public override void AI() if (IdleJumpCooldown > 0) IdleJumpCooldown--; - if (KILLYOURSELF) - Projectile.Kill(); - Projectile.timeLeft = 2; DoGravity(); DoAnimation(); @@ -296,7 +294,11 @@ public override void OnKill(int timeLeft) return; Projectile.ExpandHitboxBy(4f); - Projectile.Damage(); + if (Main.myPlayer == Projectile.owner) + Projectile.Damage(); + + if (Main.dedServ) + return; for (int i = 0; i < (int)Utils.Remap(Variant, 0f, 2f, 4f, 2f); i++) { @@ -306,11 +308,6 @@ public override void OnKill(int timeLeft) gore.timeLeft = 15; } - KILLYOURSELF = true; - - if (Main.dedServ) - return; - for (int i = 0; i < 20; i++) { if (BirthdayParty.PartyIsUp) @@ -556,28 +553,26 @@ public override void SetDefaults() public override void SendExtraAI(BinaryWriter writer) { - writer.Write(Direction); - writer.Write(IdleWalkingTime); - writer.Write(IdleWalkingTimer); - writer.Write(IdleJumpCount); - writer.Write(IdleJumpCooldown); - writer.Write(IdleWalkingDirection); - writer.Write(AnimationFrames); - writer.Write(FramesUntilNextAnimationFrame); - writer.Write(KILLYOURSELF); + writer.Write7BitEncodedInt(Direction); + writer.Write7BitEncodedInt(IdleWalkingTime); + writer.Write7BitEncodedInt(IdleWalkingTimer); + writer.Write7BitEncodedInt(IdleJumpCount); + writer.Write7BitEncodedInt(IdleJumpCooldown); + writer.Write7BitEncodedInt(IdleWalkingDirection); + writer.Write7BitEncodedInt(AnimationFrames); + writer.Write7BitEncodedInt(FramesUntilNextAnimationFrame); } public override void ReceiveExtraAI(BinaryReader reader) { - Direction = reader.ReadInt32(); - IdleWalkingTime = reader.ReadInt32(); - IdleWalkingTimer = reader.ReadInt32(); - IdleJumpCount = reader.ReadInt32(); - IdleJumpCooldown = reader.ReadInt32(); - IdleWalkingDirection = reader.ReadInt32(); - AnimationFrames = reader.ReadInt32(); - FramesUntilNextAnimationFrame = reader.ReadInt32(); - KILLYOURSELF = reader.ReadBoolean(); + Direction = reader.Read7BitEncodedInt(); + IdleWalkingTime = reader.Read7BitEncodedInt(); + IdleWalkingTimer = reader.Read7BitEncodedInt(); + IdleJumpCount = reader.Read7BitEncodedInt(); + IdleJumpCooldown = reader.Read7BitEncodedInt(); + IdleWalkingDirection = reader.Read7BitEncodedInt(); + AnimationFrames = reader.Read7BitEncodedInt(); + FramesUntilNextAnimationFrame = reader.Read7BitEncodedInt(); } public override bool? CanDamage() => State == AIState.Attack ? null : false; From 297037eaf212dfec556fc0040fb8680ddfc5a280 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Sun, 19 May 2024 02:07:43 -0500 Subject: [PATCH 005/401] Reduced the defense provided by various accessories due to it being way too much in total (it was possible to take 1 damage from many Master Death Mode attacks, which isn't okay and means that on lower difficulties this issue is even more pronounced), especially given that these items also provide a lot of utility outside of raw defense. --- Items/Accessories/AsgardianAegis.cs | 2 +- Items/Accessories/AsgardsValor.cs | 2 +- Items/Accessories/ElysianAegis.cs | 2 +- Items/Accessories/OrnateShield.cs | 2 +- Items/Accessories/RampartofDeities.cs | 2 +- Items/Accessories/Regenator.cs | 2 +- Items/Accessories/ShieldoftheHighRuler.cs | 2 +- Items/Accessories/YharimsGift.cs | 2 +- Items/CalamityGlobalItemTweaks.cs | 16 ++++++++-------- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Items/Accessories/AsgardianAegis.cs b/Items/Accessories/AsgardianAegis.cs index 4bffcce0e7..cbb8941b60 100644 --- a/Items/Accessories/AsgardianAegis.cs +++ b/Items/Accessories/AsgardianAegis.cs @@ -27,7 +27,7 @@ public override void SetDefaults() Item.width = 60; Item.height = 54; Item.value = CalamityGlobalItem.RarityDarkBlueBuyPrice; - Item.defense = 20; + Item.defense = 12; Item.accessory = true; Item.rare = ModContent.RarityType(); } diff --git a/Items/Accessories/AsgardsValor.cs b/Items/Accessories/AsgardsValor.cs index e2aacf1b97..a4e4da6e8c 100644 --- a/Items/Accessories/AsgardsValor.cs +++ b/Items/Accessories/AsgardsValor.cs @@ -22,7 +22,7 @@ public override void SetDefaults() Item.height = 44; Item.value = CalamityGlobalItem.RarityLimeBuyPrice; Item.rare = ItemRarityID.Lime; - Item.defense = 12; // we buff Ankh Shield to 12 + Item.defense = 8; // we buff Ankh Shield to 8 Item.accessory = true; } diff --git a/Items/Accessories/ElysianAegis.cs b/Items/Accessories/ElysianAegis.cs index a7231b9b11..3c1b4d6f67 100644 --- a/Items/Accessories/ElysianAegis.cs +++ b/Items/Accessories/ElysianAegis.cs @@ -25,7 +25,7 @@ public override void SetDefaults() Item.height = 42; Item.value = CalamityGlobalItem.RarityTurquoiseBuyPrice; Item.rare = ModContent.RarityType(); - Item.defense = 16; + Item.defense = 10; Item.accessory = true; } diff --git a/Items/Accessories/OrnateShield.cs b/Items/Accessories/OrnateShield.cs index 4591e8c680..2b12a2aa69 100644 --- a/Items/Accessories/OrnateShield.cs +++ b/Items/Accessories/OrnateShield.cs @@ -20,7 +20,7 @@ public override void SetDefaults() Item.height = 32; Item.value = CalamityGlobalItem.RarityPinkBuyPrice; Item.rare = ItemRarityID.Pink; - Item.defense = 8; + Item.defense = 4; // This has a ram dash, it should give a bit less defense due to how good it is Item.accessory = true; } diff --git a/Items/Accessories/RampartofDeities.cs b/Items/Accessories/RampartofDeities.cs index 04b7481d08..2ac41f439d 100644 --- a/Items/Accessories/RampartofDeities.cs +++ b/Items/Accessories/RampartofDeities.cs @@ -18,7 +18,7 @@ public override void SetDefaults() Item.width = 64; Item.height = 62; Item.value = CalamityGlobalItem.RarityVioletBuyPrice; - Item.defense = 18; + Item.defense = 12; Item.accessory = true; Item.rare = ModContent.RarityType(); } diff --git a/Items/Accessories/Regenator.cs b/Items/Accessories/Regenator.cs index 292b762fa4..f13b41822a 100644 --- a/Items/Accessories/Regenator.cs +++ b/Items/Accessories/Regenator.cs @@ -14,7 +14,7 @@ public override void SetDefaults() Item.height = 56; Item.value = CalamityGlobalItem.RarityLimeBuyPrice; Item.rare = ItemRarityID.Lime; - Item.defense = 10; + Item.defense = 4; // This should have less defense due to the regen it provides Item.accessory = true; } diff --git a/Items/Accessories/ShieldoftheHighRuler.cs b/Items/Accessories/ShieldoftheHighRuler.cs index f717c20560..aa530beaaa 100644 --- a/Items/Accessories/ShieldoftheHighRuler.cs +++ b/Items/Accessories/ShieldoftheHighRuler.cs @@ -25,7 +25,7 @@ public override void SetDefaults() Item.value = CalamityGlobalItem.RarityYellowBuyPrice; Item.rare = ItemRarityID.Yellow; Item.Calamity().donorItem = true; - Item.defense = 12; + Item.defense = 6; Item.accessory = true; } diff --git a/Items/Accessories/YharimsGift.cs b/Items/Accessories/YharimsGift.cs index 6f5cc3c2e9..0a59362b0f 100644 --- a/Items/Accessories/YharimsGift.cs +++ b/Items/Accessories/YharimsGift.cs @@ -18,7 +18,7 @@ public override void SetDefaults() { Item.width = 20; Item.height = 22; - Item.defense = 30; + Item.defense = 15; // Why did this give 30 defense? This thing really needs a rework lol Item.accessory = true; Item.value = CalamityGlobalItem.RarityVioletBuyPrice; Item.rare = ModContent.RarityType(); diff --git a/Items/CalamityGlobalItemTweaks.cs b/Items/CalamityGlobalItemTweaks.cs index 84cac6a50a..33eba91d0c 100644 --- a/Items/CalamityGlobalItemTweaks.cs +++ b/Items/CalamityGlobalItemTweaks.cs @@ -282,31 +282,31 @@ internal static void LoadTweaks() #region CATEGORY 2: Defense Balancing { ItemID.AncientHallowedGreaves, Do(DefenseDelta(+2)) }, { ItemID.AncientHallowedPlateMail, Do(DefenseDelta(+3)) }, - { ItemID.AnkhShield, Do(DefenseDelta(+8)) }, - { ItemID.CobaltShield, Do(DefenseDelta(+3)) }, + { ItemID.AnkhShield, Do(DefenseDelta(+4)) }, // 8 total + { ItemID.CobaltShield, Do(DefenseDelta(+3)) }, // 4 total { ItemID.EoCShield, Do(DefenseDelta(+1)) }, // Shield of Cthulhu - { ItemID.FrozenShield, Do(DefenseDelta(+7)) }, + { ItemID.FrozenShield, Do(DefenseDelta(+4)) }, // 10 total (plus the Frozen Turtle Shell DR effect) { ItemID.FrozenTurtleShell, Do(DefenseExact(6)) }, { ItemID.HallowedGreaves, Do(DefenseDelta(+2)) }, { ItemID.HallowedPlateMail, Do(DefenseDelta(+3)) }, - { ItemID.HeroShield, Do(DefenseDelta(+10)) }, + { ItemID.HeroShield, Do(DefenseDelta(+5)) }, // 15 total (plus increased max life) { ItemID.LavaSkull, Do(DefenseExact(4)) }, // Magma Skull { ItemID.MoltenSkullRose, Do(DefenseExact(8)) }, - { ItemID.ObsidianShield, Do(DefenseDelta(+5)) }, - { ItemID.ObsidianSkull, Do(DefenseDelta(+1)) }, + { ItemID.ObsidianShield, Do(DefenseDelta(+4)) }, // 6 total + { ItemID.ObsidianSkull, Do(DefenseDelta(+1)) }, // 2 total { ItemID.ObsidianSkullRose, Do(DefenseExact(4)) }, { ItemID.OrichalcumBreastplate, Do(DefenseDelta(+3)) }, { ItemID.OrichalcumHeadgear, Do(DefenseDelta(+2)) }, { ItemID.OrichalcumHelmet, Do(DefenseDelta(+3)) }, { ItemID.OrichalcumLeggings, Do(DefenseDelta(+4)) }, { ItemID.OrichalcumMask, Do(DefenseDelta(+3)) }, - { ItemID.PaladinsShield, Do(DefenseDelta(+3)) }, + { ItemID.PaladinsShield, Do(DefenseDelta(+2)) }, // 8 total { ItemID.PalladiumBreastplate, Do(DefenseDelta(+3)) }, { ItemID.PalladiumHeadgear, Do(DefenseDelta(+2)) }, { ItemID.PalladiumHelmet, Do(DefenseDelta(+3)) }, { ItemID.PalladiumMask, Do(DefenseDelta(+1)) }, { ItemID.PalladiumLeggings, Do(DefenseDelta(+3)) }, - { ItemID.Shackle, Do(DefenseDelta(+2)) }, + { ItemID.Shackle, Do(DefenseDelta(+2)) }, // 3 total #endregion #region CATEGORY 3: Tool Balancing From 32b1b21311c8cd5d09b751f99f0da2cd4fe96697 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 18 May 2024 22:04:58 -0400 Subject: [PATCH 006/401] Increased Ink Bomb drop rates Cuttlefish: 5% / 10% -> 10% / 20% Colossal Squid: 20% -> 33% --- NPCs/Abyss/ColossalSquid.cs | 2 +- NPCs/Abyss/Cuttlefish.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NPCs/Abyss/ColossalSquid.cs b/NPCs/Abyss/ColossalSquid.cs index 3081a1a826..e44d689057 100644 --- a/NPCs/Abyss/ColossalSquid.cs +++ b/NPCs/Abyss/ColossalSquid.cs @@ -630,7 +630,7 @@ public override void OnHitPlayer(Player target, Player.HurtInfo hurtInfo) public override void ModifyNPCLoot(NPCLoot npcLoot) { npcLoot.Add(ItemID.BlackInk, 1, 3, 5); - npcLoot.Add(ModContent.ItemType(), 5); + npcLoot.Add(ModContent.ItemType(), 3); var postLevi = npcLoot.DefineConditionalDropSet(DropHelper.PostLevi()); postLevi.Add(DropHelper.NormalVsExpertQuantity(ModContent.ItemType(), 2, 26, 38, 31, 45)); diff --git a/NPCs/Abyss/Cuttlefish.cs b/NPCs/Abyss/Cuttlefish.cs index 1770f6b684..fe588479a6 100644 --- a/NPCs/Abyss/Cuttlefish.cs +++ b/NPCs/Abyss/Cuttlefish.cs @@ -379,7 +379,7 @@ public override float SpawnChance(NPCSpawnInfo spawnInfo) public override void ModifyNPCLoot(NPCLoot npcLoot) { npcLoot.Add(ModContent.ItemType(), 2); - npcLoot.Add(ItemDropRule.NormalvsExpert(ModContent.ItemType(), 20, 10)); + npcLoot.Add(ItemDropRule.NormalvsExpert(ModContent.ItemType(), 10, 5)); } public override void HitEffect(NPC.HitInfo hit) From 5719618bf475e45aeec33e31592de04fba438479 Mon Sep 17 00:00:00 2001 From: Xyk Date: Sat, 18 May 2024 19:53:33 -0700 Subject: [PATCH 007/401] electrified intensity change --- NPCs/CalamityGlobalNPC.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/NPCs/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index a7bf7b1224..0431d27c13 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -6442,7 +6442,10 @@ public override void DrawEffects(NPC npc, ref Color drawColor) drawColor = Color.Cyan; else if (electrified > 0) - drawColor = Main.rand.NextBool(5) ? Color.White : Color.SlateGray; + { + int scaleFactor = (int)(Utils.Remap(npc.width, 30, 400, 5, 15, true)); + drawColor = Main.rand.NextBool(scaleFactor) ? Color.Lerp(Color.SlateGray, Color.White, Utils.Remap(npc.width, 30, 400, 0, 0.7f, true)) : Color.White; + } else if (absorberAffliction > 0) drawColor = Color.DarkSeaGreen; From eaa002c43887498279e9c96aa3fa954da43d6057 Mon Sep 17 00:00:00 2001 From: tomat Date: Sat, 18 May 2024 20:46:56 -0700 Subject: [PATCH 008/401] Mergreable tile system now works with vanilla tiles. --- Tiles/Abyss/AbyssGravel.cs | 4 +- Tiles/Abyss/HardenedSulphurousSandstone.cs | 4 +- Tiles/Abyss/PlantyMush.cs | 4 +- Tiles/Abyss/PyreMantle.cs | 6 +- Tiles/Abyss/PyreMantleMolten.cs | 4 +- Tiles/Abyss/SulphurousSand.cs | 4 +- Tiles/Abyss/SulphurousSandstone.cs | 4 +- Tiles/Abyss/SulphurousShale.cs | 4 +- Tiles/Abyss/Voidstone.cs | 4 +- Tiles/AerialiteBrick.cs | 5 +- Tiles/Astral/AstralClay.cs | 5 +- Tiles/Astral/AstralDirt.cs | 5 +- Tiles/Astral/AstralMonolith.cs | 4 +- Tiles/Astral/AstralStone.cs | 5 +- Tiles/Astral/NovaeSlag.cs | 5 +- Tiles/AstralBrick.cs | 5 +- Tiles/AstralDesert/AstralSand.cs | 5 +- Tiles/AstralDesert/AstralSandstone.cs | 5 +- Tiles/AstralDesert/CelestialRemains.cs | 5 +- Tiles/AstralDesert/HardenedAstralSand.cs | 5 +- Tiles/AstralSnow/AstralIce.cs | 5 +- Tiles/AstralSnow/AstralSnow.cs | 5 +- Tiles/Crags/BrimstoneSlab.cs | 4 +- Tiles/Crags/BrimstoneSlag.cs | 4 +- Tiles/Crags/ScorchedBone.cs | 5 +- Tiles/Crags/ScorchedRemains.cs | 5 +- Tiles/Crags/ScorchedRemainsGrass.cs | 4 +- Tiles/CryonicBrick.cs | 5 +- Tiles/DraedonStructures/LaboratoryPanels.cs | 5 +- .../LaboratoryPipePlating.cs | 5 +- Tiles/DraedonStructures/LaboratoryPlating.cs | 4 +- Tiles/DraedonStructures/RustedPlating.cs | 6 +- Tiles/IMergeableTile.cs | 62 ------------------- Tiles/MergeableTile.cs | 57 +++++++++++++++++ Tiles/Ores/AerialiteOre.cs | 5 +- Tiles/Ores/AerialiteOreDisenchanted.cs | 6 +- Tiles/Ores/AstralOre.cs | 5 +- Tiles/Ores/AuricOre.cs | 5 +- Tiles/Ores/ExodiumOre.cs | 5 +- Tiles/Ores/HallowedOre.cs | 5 +- Tiles/Ores/InfernalSuevite.cs | 6 +- Tiles/Ores/PerennialOre.cs | 4 +- Tiles/Ores/ScoriaOre.cs | 4 +- Tiles/Ores/UelibloomOre.cs | 5 +- Tiles/PerennialBrick.cs | 5 +- Tiles/ScoriaBrick.cs | 5 +- Tiles/SunkenSea/EutrophicSand.cs | 4 +- Tiles/SunkenSea/HardenedEutrophicSand.cs | 4 +- Tiles/SunkenSea/Navystone.cs | 4 +- Tiles/SunkenSea/SeaPrism.cs | 4 +- Tiles/UelibloomBrick.cs | 4 +- Tiles/VernalSoil.cs | 5 +- 52 files changed, 137 insertions(+), 216 deletions(-) delete mode 100644 Tiles/IMergeableTile.cs create mode 100644 Tiles/MergeableTile.cs diff --git a/Tiles/Abyss/AbyssGravel.cs b/Tiles/Abyss/AbyssGravel.cs index 1754b7fc58..04d2dd8bb0 100644 --- a/Tiles/Abyss/AbyssGravel.cs +++ b/Tiles/Abyss/AbyssGravel.cs @@ -9,13 +9,11 @@ namespace CalamityMod.Tiles.Abyss { - public class AbyssGravel : ModTile, IMergeableTile + public class AbyssGravel : ModTile { int animationFrameWidth = 234; public static readonly SoundStyle MineSound = new("CalamityMod/Sounds/Custom/AbyssGravelMine", 3); - - List IMergeableTile.TileAdjacencies { get; } = []; public override void SetStaticDefaults() { diff --git a/Tiles/Abyss/HardenedSulphurousSandstone.cs b/Tiles/Abyss/HardenedSulphurousSandstone.cs index e7f7eeb788..f48079fad5 100644 --- a/Tiles/Abyss/HardenedSulphurousSandstone.cs +++ b/Tiles/Abyss/HardenedSulphurousSandstone.cs @@ -8,10 +8,8 @@ namespace CalamityMod.Tiles.Abyss { - public class HardenedSulphurousSandstone : ModTile, IMergeableTile + public class HardenedSulphurousSandstone : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/Abyss/PlantyMush.cs b/Tiles/Abyss/PlantyMush.cs index f80d61113a..52fa770985 100644 --- a/Tiles/Abyss/PlantyMush.cs +++ b/Tiles/Abyss/PlantyMush.cs @@ -14,11 +14,9 @@ namespace CalamityMod.Tiles.Abyss { // Transforms any and all Tenebris in old worlds into planty mush. [LegacyName("Tenebris")] - public class PlantyMush : ModTile, IMergeableTile + public class PlantyMush : ModTile { public static readonly SoundStyle MineSound = new("CalamityMod/Sounds/Custom/PlantyMushMine", 3); - - List IMergeableTile.TileAdjacencies { get; } = []; public override void SetStaticDefaults() { diff --git a/Tiles/Abyss/PyreMantle.cs b/Tiles/Abyss/PyreMantle.cs index 12d1cd6f9c..90da582ec4 100644 --- a/Tiles/Abyss/PyreMantle.cs +++ b/Tiles/Abyss/PyreMantle.cs @@ -11,12 +11,10 @@ namespace CalamityMod.Tiles.Abyss { - public class PyreMantle : ModTile, IMergeableTile + public class PyreMantle : ModTile { public static readonly SoundStyle MineSound = new("CalamityMod/Sounds/Custom/VoidstoneMine", 3) { Volume = 0.4f }; - - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/Abyss/PyreMantleMolten.cs b/Tiles/Abyss/PyreMantleMolten.cs index 74c659b73f..9fe87dc7c4 100644 --- a/Tiles/Abyss/PyreMantleMolten.cs +++ b/Tiles/Abyss/PyreMantleMolten.cs @@ -11,13 +11,11 @@ namespace CalamityMod.Tiles.Abyss { - public class PyreMantleMolten : ModTile, IMergeableTile + public class PyreMantleMolten : ModTile { public static readonly SoundStyle MineSound = new("CalamityMod/Sounds/Custom/VoidstoneMine", 3) { Volume = 0.4f }; internal static Texture2D GlowTexture; - List IMergeableTile.TileAdjacencies { get; } = []; - public override void SetStaticDefaults() { if (!Main.dedServ) diff --git a/Tiles/Abyss/SulphurousSand.cs b/Tiles/Abyss/SulphurousSand.cs index c0e83d585a..3dbc1957d9 100644 --- a/Tiles/Abyss/SulphurousSand.cs +++ b/Tiles/Abyss/SulphurousSand.cs @@ -16,10 +16,8 @@ namespace CalamityMod.Tiles.Abyss // It would create block swap issues with regular sulphurous sand and was rendered obsolete with the removal of this tile's water emission mechanic. // For compatibility reasons (including with schematics), however, that tile is converted into this one. [LegacyName("SulphurousSandNoWater")] - public class SulphurousSand : ModTile, IMergeableTile + public class SulphurousSand : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/Abyss/SulphurousSandstone.cs b/Tiles/Abyss/SulphurousSandstone.cs index 5b2c948dfe..692a04edbc 100644 --- a/Tiles/Abyss/SulphurousSandstone.cs +++ b/Tiles/Abyss/SulphurousSandstone.cs @@ -8,10 +8,8 @@ namespace CalamityMod.Tiles.Abyss { - public class SulphurousSandstone : ModTile, IMergeableTile + public class SulphurousSandstone : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/Abyss/SulphurousShale.cs b/Tiles/Abyss/SulphurousShale.cs index c4652868ac..22bddd38b4 100644 --- a/Tiles/Abyss/SulphurousShale.cs +++ b/Tiles/Abyss/SulphurousShale.cs @@ -13,14 +13,12 @@ namespace CalamityMod.Tiles.Abyss { - public class SulphurousShale : ModTile, IMergeableTile + public class SulphurousShale : ModTile { int animationFrameWidth = 234; public static readonly SoundStyle MineSound = new("CalamityMod/Sounds/Custom/AbyssGravelMine", 3); - List IMergeableTile.TileAdjacencies { get; } = []; - public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/Abyss/Voidstone.cs b/Tiles/Abyss/Voidstone.cs index 45f6f30719..8d859cad1f 100644 --- a/Tiles/Abyss/Voidstone.cs +++ b/Tiles/Abyss/Voidstone.cs @@ -11,12 +11,10 @@ namespace CalamityMod.Tiles.Abyss { - public class Voidstone : ModTile, IMergeableTile + public class Voidstone : ModTile { public static readonly SoundStyle MineSound = new("CalamityMod/Sounds/Custom/VoidstoneMine", 3) { Volume = 0.4f }; internal static Texture2D GlowTexture; - - List IMergeableTile.TileAdjacencies { get; } = []; public override void SetStaticDefaults() { diff --git a/Tiles/AerialiteBrick.cs b/Tiles/AerialiteBrick.cs index 73a3990d3f..d5df1c8c04 100644 --- a/Tiles/AerialiteBrick.cs +++ b/Tiles/AerialiteBrick.cs @@ -7,10 +7,9 @@ namespace CalamityMod.Tiles { - public class AerialiteBrick : ModTile, IMergeableTile + public class AerialiteBrick : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/Astral/AstralClay.cs b/Tiles/Astral/AstralClay.cs index d5afdd919e..b84e3de8ab 100644 --- a/Tiles/Astral/AstralClay.cs +++ b/Tiles/Astral/AstralClay.cs @@ -9,10 +9,9 @@ namespace CalamityMod.Tiles.Astral { - public class AstralClay : ModTile, IMergeableTile + public class AstralClay : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/Astral/AstralDirt.cs b/Tiles/Astral/AstralDirt.cs index 4cd269dab8..18ff19942a 100644 --- a/Tiles/Astral/AstralDirt.cs +++ b/Tiles/Astral/AstralDirt.cs @@ -9,10 +9,9 @@ namespace CalamityMod.Tiles.Astral { - public class AstralDirt : ModTile, IMergeableTile + public class AstralDirt : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/Astral/AstralMonolith.cs b/Tiles/Astral/AstralMonolith.cs index 9724660bfb..1ce58af87c 100644 --- a/Tiles/Astral/AstralMonolith.cs +++ b/Tiles/Astral/AstralMonolith.cs @@ -10,13 +10,11 @@ namespace CalamityMod.Tiles.Astral { - public class AstralMonolith : ModTile, IMergeableTile + public class AstralMonolith : ModTile { private static int sheetWidth = 216; private static int sheetHeight = 72; - List IMergeableTile.TileAdjacencies { get; } = []; - public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/Astral/AstralStone.cs b/Tiles/Astral/AstralStone.cs index 5d4eb9f993..75f1648019 100644 --- a/Tiles/Astral/AstralStone.cs +++ b/Tiles/Astral/AstralStone.cs @@ -9,10 +9,9 @@ namespace CalamityMod.Tiles.Astral { - public class AstralStone : ModTile, IMergeableTile + public class AstralStone : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/Astral/NovaeSlag.cs b/Tiles/Astral/NovaeSlag.cs index 60fd932b1d..b8fda17830 100644 --- a/Tiles/Astral/NovaeSlag.cs +++ b/Tiles/Astral/NovaeSlag.cs @@ -11,10 +11,9 @@ namespace CalamityMod.Tiles.Astral { [LegacyName("AstralSilt")] - public class NovaeSlag : ModTile, IMergeableTile + public class NovaeSlag : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/AstralBrick.cs b/Tiles/AstralBrick.cs index 3af5cfe613..17921c8fcb 100644 --- a/Tiles/AstralBrick.cs +++ b/Tiles/AstralBrick.cs @@ -9,13 +9,12 @@ namespace CalamityMod.Tiles { - public class AstralBrick : ModTile, IMergeableTile + public class AstralBrick : ModTile { private const short subsheetWidth = 324; private const short subsheetHeight = 90; - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/AstralDesert/AstralSand.cs b/Tiles/AstralDesert/AstralSand.cs index b93e3e27db..1d49d41226 100644 --- a/Tiles/AstralDesert/AstralSand.cs +++ b/Tiles/AstralDesert/AstralSand.cs @@ -11,10 +11,9 @@ namespace CalamityMod.Tiles.AstralDesert { - public class AstralSand : ModTile, IMergeableTile + public class AstralSand : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/AstralDesert/AstralSandstone.cs b/Tiles/AstralDesert/AstralSandstone.cs index 026c0bf2df..12389f0650 100644 --- a/Tiles/AstralDesert/AstralSandstone.cs +++ b/Tiles/AstralDesert/AstralSandstone.cs @@ -9,10 +9,9 @@ namespace CalamityMod.Tiles.AstralDesert { - public class AstralSandstone : ModTile, IMergeableTile + public class AstralSandstone : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/AstralDesert/CelestialRemains.cs b/Tiles/AstralDesert/CelestialRemains.cs index 515e549546..984b7f9937 100644 --- a/Tiles/AstralDesert/CelestialRemains.cs +++ b/Tiles/AstralDesert/CelestialRemains.cs @@ -10,10 +10,9 @@ namespace CalamityMod.Tiles.AstralDesert { [LegacyName("AstralFossil")] - public class CelestialRemains : ModTile, IMergeableTile + public class CelestialRemains : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/AstralDesert/HardenedAstralSand.cs b/Tiles/AstralDesert/HardenedAstralSand.cs index 0918cabd0a..1c2a7d92d0 100644 --- a/Tiles/AstralDesert/HardenedAstralSand.cs +++ b/Tiles/AstralDesert/HardenedAstralSand.cs @@ -8,10 +8,9 @@ namespace CalamityMod.Tiles.AstralDesert { - public class HardenedAstralSand : ModTile, IMergeableTile + public class HardenedAstralSand : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/AstralSnow/AstralIce.cs b/Tiles/AstralSnow/AstralIce.cs index a339f14e98..767b6e94dd 100644 --- a/Tiles/AstralSnow/AstralIce.cs +++ b/Tiles/AstralSnow/AstralIce.cs @@ -9,10 +9,9 @@ namespace CalamityMod.Tiles.AstralSnow { - public class AstralIce : ModTile, IMergeableTile + public class AstralIce : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/AstralSnow/AstralSnow.cs b/Tiles/AstralSnow/AstralSnow.cs index 6ab01d8390..27b8b2a29e 100644 --- a/Tiles/AstralSnow/AstralSnow.cs +++ b/Tiles/AstralSnow/AstralSnow.cs @@ -9,10 +9,9 @@ namespace CalamityMod.Tiles.AstralSnow { - public class AstralSnow : ModTile, IMergeableTile + public class AstralSnow : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/Crags/BrimstoneSlab.cs b/Tiles/Crags/BrimstoneSlab.cs index 04d2cd4666..61ff7a8d59 100644 --- a/Tiles/Crags/BrimstoneSlab.cs +++ b/Tiles/Crags/BrimstoneSlab.cs @@ -9,13 +9,11 @@ namespace CalamityMod.Tiles.Crags { - public class BrimstoneSlab : ModTile, IMergeableTile + public class BrimstoneSlab : ModTile { private int subsheetWidth = 450; private int subsheetHeight = 198; - List IMergeableTile.TileAdjacencies { get; } = []; - public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/Crags/BrimstoneSlag.cs b/Tiles/Crags/BrimstoneSlag.cs index 3a1a485968..b63f9e0daa 100644 --- a/Tiles/Crags/BrimstoneSlag.cs +++ b/Tiles/Crags/BrimstoneSlag.cs @@ -8,13 +8,11 @@ namespace CalamityMod.Tiles.Crags { - public class BrimstoneSlag : ModTile, IMergeableTile + public class BrimstoneSlag : ModTile { private const short subsheetWidth = 450; private const short subsheetHeight = 198; - List IMergeableTile.TileAdjacencies { get; } = []; - public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/Crags/ScorchedBone.cs b/Tiles/Crags/ScorchedBone.cs index 9a875a0ff7..540a6774d7 100644 --- a/Tiles/Crags/ScorchedBone.cs +++ b/Tiles/Crags/ScorchedBone.cs @@ -8,13 +8,12 @@ namespace CalamityMod.Tiles.Crags { - public class ScorchedBone : ModTile, IMergeableTile + public class ScorchedBone : ModTile { private int sheetWidth = 450; private int sheetHeight = 198; - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/Crags/ScorchedRemains.cs b/Tiles/Crags/ScorchedRemains.cs index 74f47d6744..065de6ee5c 100644 --- a/Tiles/Crags/ScorchedRemains.cs +++ b/Tiles/Crags/ScorchedRemains.cs @@ -8,13 +8,12 @@ namespace CalamityMod.Tiles.Crags { - public class ScorchedRemains : ModTile, IMergeableTile + public class ScorchedRemains : ModTile { private int sheetWidth = 234; private int sheetHeight = 90; - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/Crags/ScorchedRemainsGrass.cs b/Tiles/Crags/ScorchedRemainsGrass.cs index a83fa18de3..5cf19faafc 100644 --- a/Tiles/Crags/ScorchedRemainsGrass.cs +++ b/Tiles/Crags/ScorchedRemainsGrass.cs @@ -10,15 +10,13 @@ namespace CalamityMod.Tiles.Crags { - public class ScorchedRemainsGrass : ModTile, IMergeableTile + public class ScorchedRemainsGrass : ModTile { private const short subsheetWidth = 234; private const short subsheetHeight = 90; private int extraFrameHeight = 36; private int extraFrameWidth = 90; - List IMergeableTile.TileAdjacencies { get; } = []; - public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/CryonicBrick.cs b/Tiles/CryonicBrick.cs index 96c010298a..cd7dbfeaa2 100644 --- a/Tiles/CryonicBrick.cs +++ b/Tiles/CryonicBrick.cs @@ -7,13 +7,12 @@ namespace CalamityMod.Tiles { - public class CryonicBrick : ModTile, IMergeableTile + public class CryonicBrick : ModTile { int subsheetHeight = 90; int subsheetWidth = 234; - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/DraedonStructures/LaboratoryPanels.cs b/Tiles/DraedonStructures/LaboratoryPanels.cs index 61724a0d54..d63549d56c 100644 --- a/Tiles/DraedonStructures/LaboratoryPanels.cs +++ b/Tiles/DraedonStructures/LaboratoryPanels.cs @@ -8,12 +8,11 @@ namespace CalamityMod.Tiles.DraedonStructures { - public class LaboratoryPanels : ModTile, IMergeableTile + public class LaboratoryPanels : ModTile { public static readonly SoundStyle MinePlatingSound = new("CalamityMod/Sounds/Custom/PlatingMine", 3); - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/DraedonStructures/LaboratoryPipePlating.cs b/Tiles/DraedonStructures/LaboratoryPipePlating.cs index 963d4ed162..d7ec964a52 100644 --- a/Tiles/DraedonStructures/LaboratoryPipePlating.cs +++ b/Tiles/DraedonStructures/LaboratoryPipePlating.cs @@ -8,12 +8,11 @@ namespace CalamityMod.Tiles.DraedonStructures { - public class LaboratoryPipePlating : ModTile, IMergeableTile + public class LaboratoryPipePlating : ModTile { public static readonly SoundStyle MinePlatingSound = new("CalamityMod/Sounds/Custom/PlatingMine", 3); - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/DraedonStructures/LaboratoryPlating.cs b/Tiles/DraedonStructures/LaboratoryPlating.cs index 9f6e1c8f72..c778e72cba 100644 --- a/Tiles/DraedonStructures/LaboratoryPlating.cs +++ b/Tiles/DraedonStructures/LaboratoryPlating.cs @@ -8,12 +8,10 @@ namespace CalamityMod.Tiles.DraedonStructures { - public class LaboratoryPlating : ModTile, IMergeableTile + public class LaboratoryPlating : ModTile { public static readonly SoundStyle MinePlatingSound = new("CalamityMod/Sounds/Custom/PlatingMine", 3); - List IMergeableTile.TileAdjacencies { get; } = []; - public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/DraedonStructures/RustedPlating.cs b/Tiles/DraedonStructures/RustedPlating.cs index 44eff8e23b..3dac585830 100644 --- a/Tiles/DraedonStructures/RustedPlating.cs +++ b/Tiles/DraedonStructures/RustedPlating.cs @@ -8,12 +8,10 @@ namespace CalamityMod.Tiles.DraedonStructures { - public class RustedPlating : ModTile, IMergeableTile + public class RustedPlating : ModTile { public static readonly SoundStyle MinePlatingSound = new("CalamityMod/Sounds/Custom/PlatingMine", 3); - - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/IMergeableTile.cs b/Tiles/IMergeableTile.cs deleted file mode 100644 index 9455c50bcc..0000000000 --- a/Tiles/IMergeableTile.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using Microsoft.Xna.Framework.Graphics; -using Terraria.ModLoader; - -namespace CalamityMod.Tiles -{ - /// - /// Interface for tiles that specify custom universal merge data. - /// - internal interface IMergeableTile - { - List TileAdjacencies { get; } - } - - internal static class MergeableTile - { - private sealed class MergeableTileGlobalTile : GlobalTile - { - public override void PostDraw(int i, int j, int type, SpriteBatch spriteBatch) - { - if (!TryGetMergeableTile(type, out var mergeableTile)) - return; - - TileFraming.DrawUniversalMergeFrames(i, j, mergeableTile.TileAdjacencies); - } - - public override bool TileFrame(int i, int j, int type, ref bool resetFrame, ref bool noBreak) - { - if (!TryGetMergeableTile(type, out var mergeableTile)) - return base.TileFrame(i, j, type, ref resetFrame, ref noBreak); - - foreach (var adjacency in mergeableTile.TileAdjacencies) - TileFraming.GetAdjacencyData(i, j, adjacency); - - return base.TileFrame(i, j, type, ref resetFrame, ref noBreak); - } - - private static bool TryGetMergeableTile(int type, [NotNullWhen(returnValue: true)] out IMergeableTile mergeableTile) - { - if (TileLoader.GetTile(type) is IMergeableTile theMergeableTile) - { - mergeableTile = theMergeableTile; - return true; - } - - mergeableTile = null; - return false; - } - } - - public static void RegisterUniversalMerge(this IMergeableTile mergeableTile, int tileId, string blendSheetPath) - { - if (mergeableTile is not ModTile tile) - throw new InvalidCastException($"{nameof(IMergeableTile)} is implemented on type {mergeableTile.GetType().FullName}; said type should inherit from {nameof(ModTile)}"); - - TileFraming.SetUpUniversalMerge(tile.Type, tileId, blendSheetPath, out var data); - mergeableTile.TileAdjacencies.Add(data); - } - } -} diff --git a/Tiles/MergeableTile.cs b/Tiles/MergeableTile.cs new file mode 100644 index 0000000000..9f5742457a --- /dev/null +++ b/Tiles/MergeableTile.cs @@ -0,0 +1,57 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework.Graphics; +using Terraria.ID; +using Terraria.ModLoader; + +namespace CalamityMod.Tiles +{ + internal static class MergeableTile + { + private sealed class MergeableTileGlobalTile : GlobalTile + { + public override void PostDraw(int i, int j, int type, SpriteBatch spriteBatch) + { + TileFraming.DrawUniversalMergeFrames(i, j, GetOrCreateTileAdjacencies(type)); + } + + public override bool TileFrame(int i, int j, int type, ref bool resetFrame, ref bool noBreak) + { + foreach (var adjacency in GetOrCreateTileAdjacencies(type)) + TileFraming.GetAdjacencyData(i, j, adjacency); + + return base.TileFrame(i, j, type, ref resetFrame, ref noBreak); + } + } + + private sealed class MergeableTileSystem : ModSystem + { + public override void PostSetupContent() + { + // Tomat: @heartplusup, you can add vanilla merges like so: + // RegisterUniversalMerge(TileID.Dirt, TileID.Stone, "CalamityMod/Tiles/Merges/StoneMerge"); - Already-merged tiles look weird; needs changes by someone else. + // RegisterUniversalMerge(TileID.WoodBlock, TileID.Stone, "CalamityMod/Tiles/Merges/StoneMerge"); + } + } + + private static readonly Dictionary> tileAdjacencyMap = []; + + public static void RegisterUniversalMerge(this ModTile tile, int mergeType, string blendSheetPath) + { + RegisterUniversalMerge(tile.Type, mergeType, blendSheetPath); + } + + public static void RegisterUniversalMerge(int tileId, int mergeType, string blendSheetPath) + { + TileFraming.SetUpUniversalMerge(tileId, mergeType, blendSheetPath, out var data); + GetOrCreateTileAdjacencies(tileId).Add(data); + } + + private static List GetOrCreateTileAdjacencies(int tileId) + { + if (!tileAdjacencyMap.TryGetValue(tileId, out var adjacencies)) + tileAdjacencyMap[tileId] = adjacencies = []; + + return adjacencies; + } + } +} diff --git a/Tiles/Ores/AerialiteOre.cs b/Tiles/Ores/AerialiteOre.cs index 427c90d2b2..4c0aeb9049 100644 --- a/Tiles/Ores/AerialiteOre.cs +++ b/Tiles/Ores/AerialiteOre.cs @@ -11,13 +11,12 @@ namespace CalamityMod.Tiles.Ores { - public class AerialiteOre : ModTile, IMergeableTile + public class AerialiteOre : ModTile { public static readonly SoundStyle MineSound = new("CalamityMod/Sounds/Custom/MagicalRockMine", 3); internal static Texture2D GlowTexture; - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { if (!Main.dedServ) diff --git a/Tiles/Ores/AerialiteOreDisenchanted.cs b/Tiles/Ores/AerialiteOreDisenchanted.cs index 4780b063e0..bd6f41dac4 100644 --- a/Tiles/Ores/AerialiteOreDisenchanted.cs +++ b/Tiles/Ores/AerialiteOreDisenchanted.cs @@ -7,12 +7,10 @@ namespace CalamityMod.Tiles.Ores { - public class AerialiteOreDisenchanted : ModTile, IMergeableTile + public class AerialiteOreDisenchanted : ModTile { private const int AnimationFrameWidth = 234; - - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileBlockLight[Type] = true; diff --git a/Tiles/Ores/AstralOre.cs b/Tiles/Ores/AstralOre.cs index c2e220d120..2b9da5ece9 100644 --- a/Tiles/Ores/AstralOre.cs +++ b/Tiles/Ores/AstralOre.cs @@ -10,10 +10,9 @@ namespace CalamityMod.Tiles.Ores { - public class AstralOre : ModTile, IMergeableTile + public class AstralOre : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileLighted[Type] = true; diff --git a/Tiles/Ores/AuricOre.cs b/Tiles/Ores/AuricOre.cs index 8d5facedb2..bc4ad02243 100644 --- a/Tiles/Ores/AuricOre.cs +++ b/Tiles/Ores/AuricOre.cs @@ -14,14 +14,13 @@ namespace CalamityMod.Tiles.Ores { - public class AuricOre : ModTile, IMergeableTile + public class AuricOre : ModTile { public static readonly SoundStyle MineSound = new("CalamityMod/Sounds/Custom/AuricMine", 3); public static bool Animate; internal static Texture2D GlowTexture; - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { if (!Main.dedServ) diff --git a/Tiles/Ores/ExodiumOre.cs b/Tiles/Ores/ExodiumOre.cs index 41fc92d67f..298a81c0e1 100644 --- a/Tiles/Ores/ExodiumOre.cs +++ b/Tiles/Ores/ExodiumOre.cs @@ -10,10 +10,9 @@ namespace CalamityMod.Tiles.Ores { - public class ExodiumOre : ModTile, IMergeableTile + public class ExodiumOre : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/Ores/HallowedOre.cs b/Tiles/Ores/HallowedOre.cs index 049ca594f2..dfe58dd453 100644 --- a/Tiles/Ores/HallowedOre.cs +++ b/Tiles/Ores/HallowedOre.cs @@ -9,10 +9,9 @@ namespace CalamityMod.Tiles.Ores { - public class HallowedOre : ModTile, IMergeableTile + public class HallowedOre : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileLighted[Type] = true; diff --git a/Tiles/Ores/InfernalSuevite.cs b/Tiles/Ores/InfernalSuevite.cs index 4d00e3d10c..9c5aa5ff20 100644 --- a/Tiles/Ores/InfernalSuevite.cs +++ b/Tiles/Ores/InfernalSuevite.cs @@ -10,13 +10,11 @@ namespace CalamityMod.Tiles.Ores { [LegacyName("CharredOre")] - public class InfernalSuevite : ModTile, IMergeableTile + public class InfernalSuevite : ModTile { private int sheetWidth = 234; private int sheetHeight = 90; - - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/Ores/PerennialOre.cs b/Tiles/Ores/PerennialOre.cs index 08d732e51e..3cc6d1c162 100644 --- a/Tiles/Ores/PerennialOre.cs +++ b/Tiles/Ores/PerennialOre.cs @@ -11,12 +11,10 @@ namespace CalamityMod.Tiles.Ores { - public class PerennialOre : ModTile, IMergeableTile + public class PerennialOre : ModTile { internal static Texture2D GlowTexture; - List IMergeableTile.TileAdjacencies { get; } = []; - public override void SetStaticDefaults() { if (!Main.dedServ) diff --git a/Tiles/Ores/ScoriaOre.cs b/Tiles/Ores/ScoriaOre.cs index 238f5f1cd4..fe8efcf707 100644 --- a/Tiles/Ores/ScoriaOre.cs +++ b/Tiles/Ores/ScoriaOre.cs @@ -12,10 +12,8 @@ namespace CalamityMod.Tiles.Ores { [LegacyName("ChaoticOre")] - public class ScoriaOre : ModTile, IMergeableTile + public class ScoriaOre : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - public override void SetStaticDefaults() { Main.tileLighted[Type] = true; diff --git a/Tiles/Ores/UelibloomOre.cs b/Tiles/Ores/UelibloomOre.cs index 14ab406efd..b213b57d7b 100644 --- a/Tiles/Ores/UelibloomOre.cs +++ b/Tiles/Ores/UelibloomOre.cs @@ -9,10 +9,9 @@ namespace CalamityMod.Tiles.Ores { - public class UelibloomOre : ModTile, IMergeableTile + public class UelibloomOre : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/PerennialBrick.cs b/Tiles/PerennialBrick.cs index 9133c5f6cb..0b647557dc 100644 --- a/Tiles/PerennialBrick.cs +++ b/Tiles/PerennialBrick.cs @@ -8,10 +8,9 @@ namespace CalamityMod.Tiles { - public class PerennialBrick : ModTile, IMergeableTile + public class PerennialBrick : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/ScoriaBrick.cs b/Tiles/ScoriaBrick.cs index 800e5d6d57..1509aa27f4 100644 --- a/Tiles/ScoriaBrick.cs +++ b/Tiles/ScoriaBrick.cs @@ -10,13 +10,12 @@ namespace CalamityMod.Tiles { [LegacyName("ChaoticBrick")] - public class ScoriaBrick : ModTile, IMergeableTile + public class ScoriaBrick : ModTile { int subsheetHeight = 72; internal static Texture2D GlowTexture; - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { if (!Main.dedServ) diff --git a/Tiles/SunkenSea/EutrophicSand.cs b/Tiles/SunkenSea/EutrophicSand.cs index c9ef48f1f5..58baf6e83c 100644 --- a/Tiles/SunkenSea/EutrophicSand.cs +++ b/Tiles/SunkenSea/EutrophicSand.cs @@ -10,10 +10,8 @@ namespace CalamityMod.Tiles.SunkenSea { - public class EutrophicSand : ModTile, IMergeableTile + public class EutrophicSand : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/SunkenSea/HardenedEutrophicSand.cs b/Tiles/SunkenSea/HardenedEutrophicSand.cs index 209e0a22cd..b198501573 100644 --- a/Tiles/SunkenSea/HardenedEutrophicSand.cs +++ b/Tiles/SunkenSea/HardenedEutrophicSand.cs @@ -8,10 +8,8 @@ namespace CalamityMod.Tiles.SunkenSea { - public class HardenedEutrophicSand : ModTile, IMergeableTile + public class HardenedEutrophicSand : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/SunkenSea/Navystone.cs b/Tiles/SunkenSea/Navystone.cs index 8799172e30..783d94f011 100644 --- a/Tiles/SunkenSea/Navystone.cs +++ b/Tiles/SunkenSea/Navystone.cs @@ -8,10 +8,8 @@ namespace CalamityMod.Tiles.SunkenSea { - public class Navystone : ModTile, IMergeableTile + public class Navystone : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/SunkenSea/SeaPrism.cs b/Tiles/SunkenSea/SeaPrism.cs index 83d6da7082..c0227a3a46 100644 --- a/Tiles/SunkenSea/SeaPrism.cs +++ b/Tiles/SunkenSea/SeaPrism.cs @@ -8,13 +8,11 @@ namespace CalamityMod.Tiles.SunkenSea { - public class SeaPrism : ModTile, IMergeableTile + public class SeaPrism : ModTile { private const short subsheetWidth = 450; private const short subsheetHeight = 198; - List IMergeableTile.TileAdjacencies { get; } = []; - public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/UelibloomBrick.cs b/Tiles/UelibloomBrick.cs index ee453b6ab0..49b1e8e449 100644 --- a/Tiles/UelibloomBrick.cs +++ b/Tiles/UelibloomBrick.cs @@ -10,13 +10,11 @@ namespace CalamityMod.Tiles { - public class UelibloomBrick : ModTile, IMergeableTile + public class UelibloomBrick : ModTile { private int extraFrameHeight = 36; private int extraFrameWidth = 90; - List IMergeableTile.TileAdjacencies { get; } = []; - public override void SetStaticDefaults() { Main.tileSolid[Type] = true; diff --git a/Tiles/VernalSoil.cs b/Tiles/VernalSoil.cs index eb4e766460..ebfd615be2 100644 --- a/Tiles/VernalSoil.cs +++ b/Tiles/VernalSoil.cs @@ -11,10 +11,9 @@ namespace CalamityMod.Tiles { - public class VernalSoil : ModTile, IMergeableTile + public class VernalSoil : ModTile { - List IMergeableTile.TileAdjacencies { get; } = []; - + public override void SetStaticDefaults() { Main.tileSolid[Type] = true; From 27c55e3a16d3784efa792983b1a95c4f25451b9f Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Sat, 18 May 2024 22:30:14 -0700 Subject: [PATCH 009/401] ash wood sword counts as a wooden sword --- Utilities/CalamityRecipes.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Utilities/CalamityRecipes.cs b/Utilities/CalamityRecipes.cs index 81a27225f2..bc4aefe0a0 100644 --- a/Utilities/CalamityRecipes.cs +++ b/Utilities/CalamityRecipes.cs @@ -356,7 +356,8 @@ private static void AddEquipmentRecipeGroups() ItemID.PalmWoodSword, ItemID.EbonwoodSword, ItemID.ShadewoodSword, - ItemID.PearlwoodSword + ItemID.PearlwoodSword, + ItemID.AshWoodSword }); AnyWoodenSword = RecipeGroup.RegisterGroup("AnyWoodenSword", group); From 616c9d330645eaadcbea2a479247c90ac235abb2 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Sun, 19 May 2024 06:10:18 -0500 Subject: [PATCH 010/401] Updated many vanilla boss player targeting behaviors (some target one player aggressively, others will swap targets, etc.). --- NPCs/NormalNPCs/SkeletronPrime2.cs | 5 - .../Bosses/BrainOfCthulhuAI.cs | 5 - .../VanillaNPCAIOverrides/Bosses/CultistAI.cs | 16 ++-- .../Bosses/DestroyerAI.cs | 10 +- .../Bosses/DukeFishronAI.cs | 19 +--- .../Bosses/EaterOfWorldsAI.cs | 7 +- .../Bosses/EyeOfCthulhuAI.cs | 19 +--- NPCs/VanillaNPCAIOverrides/Bosses/GolemAI.cs | 63 +++++-------- .../Bosses/KingSlimeAI.cs | 8 -- .../Bosses/PlanteraAI.cs | 13 +-- .../Bosses/QueenBeeAI.cs | 12 +-- .../Bosses/QueenSlimeAI.cs | 7 -- .../Bosses/SkeletronAI.cs | 27 +++--- .../Bosses/SkeletronPrimeAI.cs | 91 ++++++++----------- NPCs/VanillaNPCAIOverrides/Bosses/TwinsAI.cs | 29 +----- .../Bosses/WallOfFleshAI.cs | 8 +- 16 files changed, 105 insertions(+), 234 deletions(-) diff --git a/NPCs/NormalNPCs/SkeletronPrime2.cs b/NPCs/NormalNPCs/SkeletronPrime2.cs index 87cfa1a4bf..d644a5d641 100644 --- a/NPCs/NormalNPCs/SkeletronPrime2.cs +++ b/NPCs/NormalNPCs/SkeletronPrime2.cs @@ -281,7 +281,6 @@ public override void AI() { NPC.ai[2] = 0f; NPC.ai[1] = 1f; - NPC.TargetClosest(); NPC.netUpdate = true; } else if (shouldSpinAround || NPC.ai[1] != 4f) @@ -294,7 +293,6 @@ public override void AI() NPC.ai[2] = 0f; NPC.ai[1] = shouldSpinAround ? 5f : 1f; - NPC.TargetClosest(); NPC.netUpdate = true; } } @@ -438,7 +436,6 @@ public override void AI() if (NPC.ai[2] >= (phaseTimer - (death ? 60f * (1f - lifeRatio) : 0f))) { - NPC.TargetClosest(); NPC.ai[2] = 0f; NPC.ai[1] = 4f; NPC.localAI[0] = 0f; @@ -697,7 +694,6 @@ public override void AI() calamityGlobalNPC.newAI[0] = 0f; NPC.SyncVanillaLocalAI(); NPC.SyncExtraAI(); - NPC.TargetClosest(); NPC.netUpdate = true; } } @@ -775,7 +771,6 @@ public override void AI() NPC.localAI[0] = 0f; NPC.SyncVanillaLocalAI(); NPC.SyncExtraAI(); - NPC.TargetClosest(); NPC.netUpdate = true; } } diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/BrainOfCthulhuAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/BrainOfCthulhuAI.cs index ebfd7f20ae..78bf26e4cb 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/BrainOfCthulhuAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/BrainOfCthulhuAI.cs @@ -29,10 +29,6 @@ public static bool BuffedBrainofCthulhuAI(NPC npc, Mod mod) if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - bool enrage = true; int targetTileX = (int)Main.player[npc.target].Center.X / 16; int targetTileY = (int)Main.player[npc.target].Center.Y / 16; @@ -517,7 +513,6 @@ void SpawnMasterModeCreepers() npc.ai[1] = 0f; npc.ai[2] = 0f; npc.ai[3] = 0f; - npc.TargetClosest(); npc.netUpdate = true; } } diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/CultistAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/CultistAI.cs index cc7f023757..c3fe7ce175 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/CultistAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/CultistAI.cs @@ -96,23 +96,15 @@ public static bool BuffedCultistAI(NPC npc, Mod mod) idleTime = 20; } - // Get a target - if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) - npc.TargetClosest(false); - // Center and target Player player = Main.player[npc.target]; - if (npc.target < 0 || npc.target == Main.maxPlayers || player.dead || !player.active) + if (npc.target < 0 || npc.target == Main.maxPlayers || player.dead || !player.active || Vector2.Distance(player.Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance350Tiles) { npc.TargetClosest(false); player = Main.player[npc.target]; npc.netUpdate = true; } - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(player.Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(false); - // Enrage if (!Collision.CanHit(npc.position, npc.width, npc.height, player.position, player.width, player.height) || CalamityWorld.LegendaryMode) { @@ -157,6 +149,7 @@ public static bool BuffedCultistAI(NPC npc, Mod mod) npc.ai[1] = 0f; npc.ai[3] += 1f; npc.velocity = Vector2.Zero; + npc.TargetClosest(false); npc.netUpdate = true; if (Main.netMode != NetmodeID.MultiplayerClient) @@ -170,7 +163,7 @@ public static bool BuffedCultistAI(NPC npc, Mod mod) } // Despawn - if (player.dead || Vector2.Distance(player.Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance350Tiles) + if (player.dead || !player.active || Vector2.Distance(player.Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance350Tiles) { npc.life = 0; npc.HitEffect(0, 10.0); @@ -803,6 +796,7 @@ public static bool BuffedCultistAI(NPC npc, Mod mod) npc.ai[1] = 0f; npc.ai[3] += 1f; npc.velocity = Vector2.Zero; + npc.TargetClosest(false); npc.netUpdate = true; } } @@ -1309,6 +1303,7 @@ public static bool VanillaCultistAI(NPC npc, Mod mod) npc.ai[1] = 0f; npc.ai[3] += 1f; npc.velocity = Vector2.Zero; + npc.TargetClosest(false); npc.netUpdate = true; List list = new List(); for (int i = 0; i < Main.maxNPCs; i++) @@ -2030,6 +2025,7 @@ public static bool VanillaCultistAI(NPC npc, Mod mod) npc.ai[1] = 0f; npc.ai[3] += 1f; npc.velocity = Vector2.Zero; + npc.TargetClosest(false); npc.netUpdate = true; } } diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/DestroyerAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/DestroyerAI.cs index 455726721e..1308fee41f 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/DestroyerAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/DestroyerAI.cs @@ -92,10 +92,7 @@ public static bool BuffedDestroyerAI(NPC npc, Mod mod) // Return to ground phase, with less time spent in later phases if (calamityGlobalNPC.newAI[3] >= FlightPhaseResetGateValue) - { calamityGlobalNPC.newAI[3] = flightPhaseTimerSetValue; - npc.TargetClosest(); - } // Spawn DR check bool hasSpawnDR = calamityGlobalNPC.newAI[1] < DRIncreaseTime && calamityGlobalNPC.newAI[1] > 60f; @@ -124,10 +121,6 @@ public static bool BuffedDestroyerAI(NPC npc, Mod mod) bool increaseSpeed = Vector2.Distance(player.Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles; bool increaseSpeedMore = Vector2.Distance(player.Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance350Tiles; - // Get a new target if current target is too far away - if (increaseSpeedMore && npc.type == NPCID.TheDestroyer) - npc.TargetClosest(); - float enrageScale = bossRush ? 1f : 0f; if (Main.IsItDay() || bossRush) { @@ -1144,7 +1137,7 @@ public static bool VanillaDestroyerAI(NPC npc, Mod mod) if (npc.ai[3] > 0f) npc.realLife = (int)npc.ai[3]; - if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead) + if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); if (npc.type >= NPCID.TheDestroyer && npc.type <= NPCID.TheDestroyerTail) @@ -1546,7 +1539,6 @@ public static bool VanillaDestroyerAI(NPC npc, Mod mod) { if (!flag2) { - npc.TargetClosest(); npc.velocity.Y += 0.15f; if (Main.masterMode && npc.velocity.Y > 0f) npc.velocity.Y += 0.05f; diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/DukeFishronAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/DukeFishronAI.cs index b351e11655..c50a12c01b 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/DukeFishronAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/DukeFishronAI.cs @@ -121,22 +121,16 @@ public static bool BuffedDukeFishronAI(NPC npc, Mod mod) Player player = Main.player[npc.target]; // Get target - if (npc.target < 0 || npc.target == Main.maxPlayers || player.dead || !player.active) + if (npc.target < 0 || npc.target == Main.maxPlayers || player.dead || !player.active || Vector2.Distance(player.Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance350Tiles) { npc.TargetClosest(); player = Main.player[npc.target]; npc.netUpdate = true; } - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(player.Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - // Despawn if (player.dead || Vector2.Distance(player.Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance350Tiles) { - npc.TargetClosest(); - npc.velocity.Y -= 0.4f; if (npc.timeLeft > 10) @@ -477,7 +471,6 @@ public static bool BuffedDukeFishronAI(NPC npc, Mod mod) npc.ai[1] = 0f; npc.ai[2] = 0f; npc.ai[3] += 2f; - npc.TargetClosest(); npc.netUpdate = true; } } @@ -526,7 +519,6 @@ public static bool BuffedDukeFishronAI(NPC npc, Mod mod) npc.ai[0] = 0f; npc.ai[1] = 0f; npc.ai[2] = 0f; - npc.TargetClosest(); npc.netUpdate = true; } } @@ -566,7 +558,6 @@ public static bool BuffedDukeFishronAI(NPC npc, Mod mod) npc.ai[0] = 0f; npc.ai[1] = 0f; npc.ai[2] = 0f; - npc.TargetClosest(); npc.netUpdate = true; } } @@ -592,7 +583,6 @@ public static bool BuffedDukeFishronAI(NPC npc, Mod mod) npc.ai[1] = 0f; npc.ai[2] = 0f; npc.ai[3] = 0f; - npc.TargetClosest(); npc.netUpdate = true; } } @@ -751,7 +741,6 @@ public static bool BuffedDukeFishronAI(NPC npc, Mod mod) npc.ai[1] = 0f; npc.ai[2] = 0f; npc.ai[3] += 2f; - npc.TargetClosest(); npc.netUpdate = true; } } @@ -797,7 +786,6 @@ public static bool BuffedDukeFishronAI(NPC npc, Mod mod) npc.ai[0] = 5f; npc.ai[1] = 0f; npc.ai[2] = 0f; - npc.TargetClosest(); npc.netUpdate = true; } } @@ -825,7 +813,6 @@ public static bool BuffedDukeFishronAI(NPC npc, Mod mod) npc.ai[0] = 5f; npc.ai[1] = 0f; npc.ai[2] = 0f; - npc.TargetClosest(); npc.netUpdate = true; } } @@ -871,7 +858,6 @@ public static bool BuffedDukeFishronAI(NPC npc, Mod mod) npc.ai[1] = 0f; npc.ai[2] = 0f; npc.ai[3] = 0f; - npc.TargetClosest(); npc.netUpdate = true; } } @@ -1062,7 +1048,6 @@ public static bool BuffedDukeFishronAI(NPC npc, Mod mod) if (!phase4 || !death) npc.ai[3] += 1f; - npc.TargetClosest(); npc.netUpdate = true; } } @@ -1163,7 +1148,7 @@ public static bool BuffedDetonatingBubbleAI(NPC npc, Mod mod) Vector2 velocityVector = (Main.player[npc.target].Center - npc.Center).SafeNormalize(Vector2.UnitY); float inertia = 30f; - float velocity = 25f; + float velocity = 24f; npc.velocity = (npc.velocity * inertia + velocityVector * velocity) / (inertia + 1f); npc.scale = npc.ai[3]; diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/EaterOfWorldsAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/EaterOfWorldsAI.cs index 22922a5ce6..7e10b43aef 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/EaterOfWorldsAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/EaterOfWorldsAI.cs @@ -37,10 +37,6 @@ public static bool BuffedEaterofWorldsAI(NPC npc, Mod mod) if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles && npc.type == NPCID.EaterofWorldsHead) - npc.TargetClosest(); - bool enrage = true; int targetTileX = (int)Main.player[npc.target].Center.X / 16; int targetTileY = (int)Main.player[npc.target].Center.Y / 16; @@ -785,7 +781,7 @@ public static bool VanillaEaterofWorldsAI(NPC npc, Mod mod) npc.realLife = -1; - if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead) + if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); if (Main.player[npc.target].dead) @@ -998,7 +994,6 @@ public static bool VanillaEaterofWorldsAI(NPC npc, Mod mod) { if (!flag2) { - npc.TargetClosest(); npc.velocity.Y += 0.11f; if (Main.masterMode && npc.velocity.Y > 0f) npc.velocity.Y += 0.07f; diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/EyeOfCthulhuAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/EyeOfCthulhuAI.cs index 8bf28b1f87..535d6b48c8 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/EyeOfCthulhuAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/EyeOfCthulhuAI.cs @@ -55,10 +55,6 @@ public static bool BuffedEyeofCthulhuAI(NPC npc, Mod mod) if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - bool dead = Main.player[npc.target].dead; float targetXDistance = npc.Center.X - Main.player[npc.target].position.X - (Main.player[npc.target].width / 2); float targetYDistance = npc.position.Y + npc.height - 59f - Main.player[npc.target].position.Y - (Main.player[npc.target].height / 2); @@ -277,7 +273,6 @@ public static bool BuffedEyeofCthulhuAI(NPC npc, Mod mod) { npc.ai[3] += 1f; npc.ai[2] = 0f; - npc.TargetClosest(); npc.rotation = eyeRotation; float numCharges = death ? 4f : 3f; @@ -503,7 +498,6 @@ public static bool BuffedEyeofCthulhuAI(NPC npc, Mod mod) npc.ai[1] = 1f; npc.ai[2] = 0f; npc.ai[3] = 0f; - npc.TargetClosest(); npc.netUpdate = true; } } @@ -570,7 +564,6 @@ public static bool BuffedEyeofCthulhuAI(NPC npc, Mod mod) { npc.ai[3] += 1f; npc.ai[2] = 0f; - npc.TargetClosest(); npc.rotation = eyeRotation; float numCharges = death ? 4f : 3f; @@ -598,7 +591,6 @@ public static bool BuffedEyeofCthulhuAI(NPC npc, Mod mod) // Deal less damage overall while not charging npc.damage = reducedSetDamage; - npc.TargetClosest(); npc.ai[1] = 0f; npc.ai[2] = 0f; npc.ai[3] = 0f; @@ -874,7 +866,6 @@ public static bool BuffedEyeofCthulhuAI(NPC npc, Mod mod) break; } - npc.TargetClosest(); calamityGlobalNPC.newAI[0] += ((masterMode && calamityGlobalNPC.newAI[0] % 2f != 0f) ? Main.rand.Next(2) + 1f : 1f); if (calamityGlobalNPC.newAI[0] > 3f) calamityGlobalNPC.newAI[0] = masterMode ? Main.rand.Next(2) : 0f; @@ -1114,7 +1105,7 @@ public static bool VanillaEyeofCthulhuAI(NPC npc, Mod mod) npc.ai[1] = 1f; npc.ai[2] = 0f; npc.ai[3] = 0f; - npc.target = Main.maxPlayers; + npc.TargetClosest(); npc.netUpdate = true; } else if ((npc.position.Y + (float)npc.height < Main.player[npc.target].position.Y && num15 < 500f) || (Main.expertMode && num15 < (Main.masterMode ? 750f : 500f))) @@ -1233,7 +1224,6 @@ public static bool VanillaEyeofCthulhuAI(NPC npc, Mod mod) { npc.ai[3] += 1f; npc.ai[2] = 0f; - npc.target = Main.maxPlayers; npc.rotation = num7; if (npc.ai[3] >= (Main.masterMode ? 4f : 3f)) { @@ -1263,6 +1253,7 @@ public static bool VanillaEyeofCthulhuAI(NPC npc, Mod mod) npc.ai[1] = 0f; npc.ai[2] = 0f; npc.ai[3] = 0f; + npc.TargetClosest(); npc.netUpdate = true; if (npc.netSpam > 10) npc.netSpam = 10; @@ -1464,13 +1455,11 @@ public static bool VanillaEyeofCthulhuAI(NPC npc, Mod mod) if (Main.expertMode && (double)npc.life < (double)npc.lifeMax * (Main.masterMode ? 0.45 : 0.35)) npc.ai[1] = 3f; - npc.target = Main.maxPlayers; npc.netUpdate = true; } if (Main.expertMode && flag3) { - npc.TargetClosest(); npc.netUpdate = true; npc.ai[1] = 3f; npc.ai[2] = 0f; @@ -1542,7 +1531,6 @@ public static bool VanillaEyeofCthulhuAI(NPC npc, Mod mod) { npc.ai[3] += 1f; npc.ai[2] = 0f; - npc.target = Main.maxPlayers; npc.rotation = num7; if (npc.ai[3] >= 3f) { @@ -1572,7 +1560,6 @@ public static bool VanillaEyeofCthulhuAI(NPC npc, Mod mod) // Deal less damage while not charging npc.damage = reducedSetDamage; - npc.TargetClosest(); npc.ai[1] = 0f; npc.ai[2] = 0f; npc.ai[3] = 0f; @@ -1582,7 +1569,6 @@ public static bool VanillaEyeofCthulhuAI(NPC npc, Mod mod) } else if (Main.netMode != NetmodeID.MultiplayerClient) { - npc.TargetClosest(); float num50 = Main.masterMode ? 24f : 20f; Vector2 vector10 = npc.Center; float num51 = Main.player[npc.target].Center.X - vector10.X; @@ -1775,7 +1761,6 @@ public static bool VanillaEyeofCthulhuAI(NPC npc, Mod mod) npc.ai[2] += 1f; if (npc.ai[2] >= (Main.masterMode ? 40f : 70f)) { - npc.TargetClosest(); npc.ai[1] = 3f; npc.ai[2] = -1f; npc.ai[3] = Main.rand.Next(-3, 1); diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/GolemAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/GolemAI.cs index df15000bff..4ade8b50a9 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/GolemAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/GolemAI.cs @@ -43,14 +43,6 @@ public static bool BuffedGolemAI(NPC npc, Mod mod) NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X - 3, (int)npc.Center.Y - 57, NPCID.GolemHead); } - // Get a target - if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) - npc.TargetClosest(); - - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - // Despawn if (npc.target >= 0 && Main.player[npc.target].dead) { @@ -265,7 +257,8 @@ public static bool BuffedGolemAI(NPC npc, Mod mod) else if (npc.ai[1] == -1f) { // Set jump velocity - npc.TargetClosest(); + if (!headAlive) + npc.TargetClosest(); // Set damage npc.damage = npc.defDamage; @@ -412,8 +405,6 @@ void NormalJump() // Avoid cheap bullshit npc.damage = 0; - npc.TargetClosest(); - // Play sound SoundEngine.PlaySound(SoundID.Item14, npc.Center); @@ -602,6 +593,10 @@ void CustomGravity(bool isSlamming) npc.velocity.Y = maxFallSpeed; } + // Get a target + if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) + npc.TargetClosest(); + // Despawn if (Math.Abs(npc.Center.X - Main.player[npc.target].Center.X) + Math.Abs(npc.Center.Y - Main.player[npc.target].Center.Y) > despawnDistance) { @@ -705,8 +700,6 @@ public static bool BuffedGolemFistAI(NPC npc, Mod mod) float fistPunchGateValue = masterMode ? 120f : 40f; if (npc.ai[1] >= fistPunchGateValue) { - npc.TargetClosest(); - if (canPunch) { npc.ai[1] = 0f; @@ -950,10 +943,6 @@ public static bool BuffedGolemHeadAI(NPC npc, Mod mod) if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - // Die if body is gone if (NPC.golemBoss < 0) { @@ -1021,8 +1010,6 @@ public static bool BuffedGolemHeadAI(NPC npc, Mod mod) if (Main.netMode != NetmodeID.MultiplayerClient && npc.ai[1] >= shootFireballGateValue) { - npc.TargetClosest(); - npc.ai[1] = 0f; Vector2 headCent = new Vector2(npc.Center.X, npc.Center.Y + 10f * npc.scale); @@ -1076,8 +1063,6 @@ public static bool BuffedGolemHeadAI(NPC npc, Mod mod) if (Main.netMode != NetmodeID.MultiplayerClient && npc.ai[1] >= shootFireballGateValue) { - npc.TargetClosest(); - npc.ai[1] = 0f; float fireballSpeedFistsDed = turboEnrage ? 32f : enrage ? 24f : 12f; @@ -1111,8 +1096,6 @@ public static bool BuffedGolemHeadAI(NPC npc, Mod mod) if (npc.ai[2] >= 300f) { - npc.TargetClosest(); - npc.ai[2] = 0f; int projType = ProjectileID.EyeBeam; @@ -1199,10 +1182,6 @@ public static bool BuffedGolemHeadFreeAI(NPC npc, Mod mod) if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - // Die if body is gone if (NPC.golemBoss < 0) { @@ -1393,8 +1372,6 @@ public static bool BuffedGolemHeadFreeAI(NPC npc, Mod mod) if (Main.netMode != NetmodeID.MultiplayerClient && npc.ai[1] >= shootFireballGateValue) { - npc.TargetClosest(); - npc.ai[1] = 0f; Vector2 freeHeadCenter = new Vector2(npc.Center.X, npc.Center.Y + 20f * npc.scale); @@ -1434,8 +1411,6 @@ public static bool BuffedGolemHeadFreeAI(NPC npc, Mod mod) float laserGateValue = 300f - (death ? 240f * (1f - combinedLifeRatio) : 180f * (1f - combinedLifeRatio)); if (Main.netMode != NetmodeID.MultiplayerClient && npc.ai[2] >= laserGateValue) { - npc.TargetClosest(); - npc.ai[2] = 0f; int numLasers = 2; @@ -1676,7 +1651,10 @@ public static bool VanillaGolemAI(NPC npc, Mod mod) npc.damage = npc.defDamage; npc.noTileCollide = true; - npc.TargetClosest(); + + if (!flag) + npc.TargetClosest(); + npc.velocity.X = 4 * npc.direction; if (npc.life < npc.lifeMax) { @@ -1718,7 +1696,6 @@ public static bool VanillaGolemAI(NPC npc, Mod mod) // Set damage npc.damage = npc.defDamage; - npc.TargetClosest(); if (npc.position.X < Main.player[npc.target].position.X && npc.position.X + (float)npc.width > Main.player[npc.target].position.X + (float)Main.player[npc.target].width) { npc.velocity.X *= 0.9f; @@ -1752,7 +1729,7 @@ public static bool VanillaGolemAI(NPC npc, Mod mod) } } - if (npc.target <= 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead) + if (npc.target <= 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); int num8 = 3000; @@ -1776,6 +1753,10 @@ public static bool VanillaGolemFistAI(NPC npc, Mod mod) if (Main.getGoodWorld) enrageScale += 3f; + // Get a target + if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) + npc.TargetClosest(); + if ((!Main.player[npc.target].ZoneLihzhardTemple && !Main.player[npc.target].ZoneJungle) || (double)Main.player[npc.target].Center.Y < Main.worldSurface * 16.0) enrageScale *= 2f; @@ -1843,7 +1824,6 @@ public static bool VanillaGolemFistAI(NPC npc, Mod mod) if (npc.ai[1] >= 60f) { - npc.TargetClosest(); if ((npc.type == NPCID.GolemFistLeft && npc.Center.X + 100f > Main.player[npc.target].Center.X) || (npc.type == NPCID.GolemFistRight && npc.Center.X - 100f < Main.player[npc.target].Center.X)) { npc.ai[1] = 0f; @@ -2044,6 +2024,10 @@ public static bool VanillaGolemHeadAI(NPC npc, Mod mod) if (Main.getGoodWorld) enrageScale += 3f; + // Get a target + if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) + npc.TargetClosest(); + if ((!Main.player[npc.target].ZoneLihzhardTemple && !Main.player[npc.target].ZoneJungle) || (double)Main.player[npc.target].Center.Y < Main.worldSurface * 16.0) enrageScale *= 2f; @@ -2103,7 +2087,6 @@ public static bool VanillaGolemHeadAI(NPC npc, Mod mod) if (npc.ai[1] >= (float)num711) { - npc.TargetClosest(); npc.ai[1] = 0f; Vector2 vector90 = new Vector2(npc.Center.X, npc.Center.Y + 10f * npc.scale); float num712 = 8f; @@ -2122,7 +2105,6 @@ public static bool VanillaGolemHeadAI(NPC npc, Mod mod) } else if (npc.ai[0] == 1f) { - npc.TargetClosest(); Vector2 vector91 = new Vector2(npc.Center.X, npc.Center.Y + 10f * npc.scale); if (Main.player[npc.target].Center.X < npc.Center.X - (float)npc.width) { @@ -2153,7 +2135,6 @@ public static bool VanillaGolemHeadAI(NPC npc, Mod mod) if (npc.ai[1] >= (float)num720) { - npc.TargetClosest(); npc.ai[1] = 0f; float num721 = 8f; float num722 = Main.player[npc.target].Center.X - vector91.X; @@ -2257,6 +2238,10 @@ public static bool VanillaGolemHeadFreeAI(NPC npc, Mod mod) if (Main.getGoodWorld) enrageScale += 3f; + // Get a target + if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) + npc.TargetClosest(); + if ((!Main.player[npc.target].ZoneLihzhardTemple && !Main.player[npc.target].ZoneJungle) || (double)Main.player[npc.target].Center.Y < Main.worldSurface * 16.0) enrageScale *= 2f; @@ -2276,7 +2261,6 @@ public static bool VanillaGolemHeadFreeAI(NPC npc, Mod mod) return false; } - npc.TargetClosest(); float num742 = 7f; float num743 = 0.05f; Vector2 vector92 = npc.Center; @@ -2337,7 +2321,6 @@ public static bool VanillaGolemHeadFreeAI(NPC npc, Mod mod) if (npc.ai[1] >= (float)num748) { - npc.TargetClosest(); npc.ai[1] = 0f; Vector2 vector93 = new Vector2(npc.Center.X, npc.Center.Y + 20f * npc.scale); float num749 = 8f; diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs index 54060f5524..d2f68c28c4 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs @@ -39,10 +39,6 @@ public static bool BuffedKingSlimeAI(NPC npc, Mod mod) if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - // Phases based on life percentage // Higher velocity jumps phase @@ -330,7 +326,6 @@ public static bool BuffedKingSlimeAI(NPC npc, Mod mod) npc.damage = setDamage; npc.netUpdate = true; - npc.TargetClosest(); float distanceBelowTarget = npc.position.Y - (Main.player[npc.target].position.Y + 80f); float speedMult = 1f; @@ -603,7 +598,6 @@ public static bool VanillaKingSlimeAI(NPC npc, Mod mod) npc.ai[1] = 5f; if (Main.netMode != NetmodeID.MultiplayerClient) { - npc.TargetClosest(faceTarget: false); Point point3 = npc.Center.ToTileCoordinates(); Point point4 = Main.player[npc.target].Center.ToTileCoordinates(); Vector2 vector30 = Main.player[npc.target].Center - npc.Center; @@ -790,7 +784,6 @@ public static bool VanillaKingSlimeAI(NPC npc, Mod mod) npc.damage = npc.defDamage; npc.netUpdate = true; - npc.TargetClosest(); if (npc.ai[1] == 3f) { npc.velocity.Y = -13f; @@ -890,7 +883,6 @@ public static bool VanillaKingSlimeAI(NPC npc, Mod mod) public static void GetPlaceToTeleportTo(NPC npc) { - npc.TargetClosest(false); float distanceAhead = 800f; Vector2 randomDefault = Main.rand.NextBool() ? Vector2.UnitX : -Vector2.UnitX; Vector2 vectorAimedAheadOfTarget = Main.player[npc.target].Center + new Vector2((float)Math.Round(Main.player[npc.target].velocity.X), 0f).SafeNormalize(randomDefault) * distanceAhead; diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/PlanteraAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/PlanteraAI.cs index a7c993715b..04d87dc3be 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/PlanteraAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/PlanteraAI.cs @@ -39,10 +39,6 @@ public static bool BuffedPlanteraAI(NPC npc, Mod mod) if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - // Percent life remaining float lifeRatio = npc.life / (float)npc.lifeMax; @@ -301,6 +297,8 @@ public static bool BuffedPlanteraAI(NPC npc, Mod mod) } } + npc.TargetClosest(); + npc.ai[1] = -SeedGatlingDuration; } } @@ -622,7 +620,6 @@ public static bool BuffedPlanteraAI(NPC npc, Mod mod) if (npc.localAI[1] >= shootProjectileGateValue) { npc.localAI[1] = 0f; - npc.TargetClosest(); bool shootPoisonSeed = CalamityWorld.LegendaryMode || Main.rand.NextBool(masterMode ? 2 : 4); int projectileType = shootPoisonSeed ? ProjectileID.PoisonSeedPlantera : ProjectileID.SeedPlantera; float projectileSpeed = masterMode ? 16f : 14f; @@ -1208,7 +1205,11 @@ public static bool VanillaPlanteraAI(NPC npc, Mod mod) { bool flag39 = false; bool flag40 = false; - npc.TargetClosest(); + + // Get a target + if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) + npc.TargetClosest(); + if (Main.player[npc.target].dead) { flag40 = true; diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/QueenBeeAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/QueenBeeAI.cs index 95257c3031..e8bb17fb34 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/QueenBeeAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/QueenBeeAI.cs @@ -23,10 +23,6 @@ public static bool BuffedQueenBeeAI(NPC npc, Mod mod) if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - bool bossRush = BossRushEvent.BossRushActive; bool masterMode = Main.masterMode || bossRush; bool death = CalamityWorld.death || bossRush; @@ -1031,6 +1027,7 @@ public static bool VanillaQueenBeeAI(NPC npc, Mod mod) } while ((float)num647 == num646); + npc.TargetClosest(); npc.ai[0] = num647; npc.ai[1] = 0f; npc.ai[2] = 0f; @@ -1081,8 +1078,6 @@ public static bool VanillaQueenBeeAI(NPC npc, Mod mod) { // Avoid cheap bullshit npc.damage = 0; - - npc.TargetClosest(); float chargeDistanceY = 20f; chargeDistanceY += 20f * num644; @@ -1239,8 +1234,6 @@ public static bool VanillaQueenBeeAI(NPC npc, Mod mod) // Avoid cheap bullshit npc.damage = 0; - npc.TargetClosest(); - float playerLocation = npc.Center.X - Main.player[npc.target].Center.X; npc.direction = playerLocation < 0 ? 1 : -1; npc.spriteDirection = npc.direction; @@ -1290,8 +1283,6 @@ public static bool VanillaQueenBeeAI(NPC npc, Mod mod) // Avoid cheap bullshit npc.damage = 0; - npc.TargetClosest(); - float playerLocation = npc.Center.X - Main.player[npc.target].Center.X; npc.direction = playerLocation < 0 ? 1 : -1; npc.spriteDirection = npc.direction; @@ -1322,7 +1313,6 @@ public static bool VanillaQueenBeeAI(NPC npc, Mod mod) npc.damage = 0; npc.localAI[0] = 0f; - npc.TargetClosest(); float num672 = Main.masterMode ? 16f : 14f; float num673 = Main.masterMode ? 0.15f : 0.1f; diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/QueenSlimeAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/QueenSlimeAI.cs index 40b7d577b3..1ce6e0c5c6 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/QueenSlimeAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/QueenSlimeAI.cs @@ -68,7 +68,6 @@ public static bool BuffedQueenSlimeAI(NPC npc, Mod mod) if (Main.netMode != NetmodeID.MultiplayerClient) { npc.netUpdate = true; - npc.TargetClosest(faceTarget: false); Vector2 vectorAimedAheadOfTarget = Main.player[npc.target].Center + new Vector2((float)Math.Round(Main.player[npc.target].velocity.X), 0f).SafeNormalize(Vector2.Zero) * 800f; Point predictiveTeleportPoint = vectorAimedAheadOfTarget.ToTileCoordinates(); int randomTeleportOffset = 5; @@ -403,7 +402,6 @@ public static bool BuffedQueenSlimeAI(NPC npc, Mod mod) speedMult = 2f; npc.netUpdate = true; - npc.TargetClosest(); if (npc.ai[2] == 3f) { npc.velocity.Y = -13f * speedMult; @@ -931,7 +929,6 @@ public static bool VanillaQueenSlimeAI(NPC npc, Mod mod) if (Main.netMode != NetmodeID.MultiplayerClient) { npc.netUpdate = true; - npc.TargetClosest(false); Point point = npc.Center.ToTileCoordinates(); Point point2 = Main.player[npc.target].Center.ToTileCoordinates(); Vector2 vector = Main.player[npc.target].Center - npc.Center; @@ -1251,7 +1248,6 @@ public static bool VanillaQueenSlimeAI(NPC npc, Mod mod) npc.damage = npc.defDamage; npc.netUpdate = true; - npc.TargetClosest(); if (npc.ai[2] == 3f) { npc.velocity.Y = -13f; @@ -1629,8 +1625,6 @@ public static void QueenSlime_FlyMovement(NPC npc) float flyAcceleration = bossRush ? 0.3f : death ? (masterMode ? 0.18f : 0.14f) : (masterMode ? 0.16f : 0.12f); float flyDistanceY = masterMode ? 350f : 450f; - npc.TargetClosest(); - Vector2 desiredVelocity = npc.Center; if (npc.timeLeft > 10) @@ -1698,7 +1692,6 @@ public static void QueenSlime_FlyMovement_Vanilla(NPC npc) float num = Main.masterMode ? 18f : Main.expertMode ? 15f : 12f; float num2 = Main.masterMode ? 0.12f : Main.expertMode ? 0.1f : 0.085f; float num3 = 250f; - npc.TargetClosest(); Vector2 desiredVelocity = npc.Center; if (npc.timeLeft > 10) { diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronAI.cs index 843d68d94c..abf2444bac 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronAI.cs @@ -64,10 +64,6 @@ public static bool BuffedSkeletronAI(NPC npc, Mod mod) if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - // Spawn hands if (Main.netMode != NetmodeID.MultiplayerClient) { @@ -467,7 +463,6 @@ void SpawnHands() npc.localAI[2] = 0f; calamityGlobalNPC.newAI[1] = 0f; - npc.TargetClosest(); npc.SyncExtraAI(); npc.SyncVanillaLocalAI(); npc.netUpdate = true; @@ -870,10 +865,6 @@ public static bool BuffedSkeletronHandAI(NPC npc, Mod mod) if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - float yMultiplier = 1f; if (calamityGlobalNPC.newAI[0] != 0f) yMultiplier = calamityGlobalNPC.newAI[0]; @@ -1018,6 +1009,7 @@ public static bool BuffedSkeletronHandAI(NPC npc, Mod mod) npc.ai[3] += slapTimerIncrement; if (npc.ai[3] >= slapGateValue) { + npc.target = Main.npc[(int)npc.ai[1]].target; npc.ai[2] += 1f; npc.ai[3] = calamityGlobalNPC.newAI[2] = slapGateValue; calamityGlobalNPC.newAI[3] = 0f; @@ -1107,7 +1099,6 @@ public static bool BuffedSkeletronHandAI(NPC npc, Mod mod) // Set damage npc.damage = npc.defDamage; - npc.TargetClosest(); npc.ai[2] = 2f; npc.ai[3] = 0f; npc.velocity = (Main.player[npc.target].Center - npc.Center).SafeNormalize(Vector2.UnitY) * handSwipeVelocity; @@ -1167,7 +1158,6 @@ public static bool BuffedSkeletronHandAI(NPC npc, Mod mod) // Set damage npc.damage = npc.defDamage; - npc.TargetClosest(); npc.ai[2] = 5f; npc.ai[3] = 0f; npc.velocity = (Main.player[npc.target].Center - npc.Center).SafeNormalize(Vector2.UnitY) * handSwipeVelocity; @@ -1254,9 +1244,13 @@ public static bool VanillaSkeletronAI(NPC npc, Mod mod) { npc.reflectsProjectiles = false; npc.defense = npc.defDefense; + + // Get a target + if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) + npc.TargetClosest(); + if (npc.ai[0] == 0f && Main.netMode != NetmodeID.MultiplayerClient) { - npc.TargetClosest(); npc.ai[0] = 1f; int num148 = NPC.NewNPC(npc.GetSource_FromAI(), (int)(npc.Center.X), (int)npc.Center.Y, NPCID.SkeletronHand, npc.whoAmI); Main.npc[num148].ai[0] = -1f; @@ -1355,7 +1349,6 @@ public static bool VanillaSkeletronAI(NPC npc, Mod mod) { npc.ai[2] = 0f; npc.ai[1] = 1f; - npc.TargetClosest(); npc.netUpdate = true; } @@ -1451,6 +1444,7 @@ public static bool VanillaSkeletronAI(NPC npc, Mod mod) { npc.ai[2] = 0f; npc.ai[1] = 0f; + npc.TargetClosest(); } npc.rotation += (float)npc.direction * 0.3f; @@ -1575,6 +1569,10 @@ public static bool VanillaSkeletronHandAI(NPC npc, Mod mod) } } + // Get a target + if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) + npc.TargetClosest(); + if (npc.ai[2] == 0f || npc.ai[2] == 3f) { // Avoid cheap bullshit @@ -1640,6 +1638,7 @@ public static bool VanillaSkeletronHandAI(NPC npc, Mod mod) if (npc.ai[3] >= 300f) { + npc.target = Main.npc[(int)npc.ai[1]].target; npc.ai[2] += 1f; npc.ai[3] = 0f; npc.netUpdate = true; @@ -1765,7 +1764,6 @@ public static bool VanillaSkeletronHandAI(NPC npc, Mod mod) // Set damage npc.damage = npc.defDamage; - npc.TargetClosest(); npc.ai[2] = 2f; vector23 = npc.Center; num184 = Main.player[npc.target].Center.X - vector23.X; @@ -1820,7 +1818,6 @@ public static bool VanillaSkeletronHandAI(NPC npc, Mod mod) // Set damage npc.damage = npc.defDamage; - npc.TargetClosest(); npc.ai[2] = 5f; vector24 = npc.Center; num187 = Main.player[npc.target].Center.X - vector24.X; diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronPrimeAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronPrimeAI.cs index 3d01ee7107..a7f40acc14 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronPrimeAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronPrimeAI.cs @@ -26,10 +26,6 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - // Percent life remaining float lifeRatio = npc.life / (float)npc.lifeMax; @@ -208,11 +204,17 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) } // Despawn - if (Main.player[npc.target].dead || Math.Abs(npc.Center.X - Main.player[npc.target].Center.X) > 6000f || Math.Abs(npc.Center.Y - Main.player[npc.target].Center.Y) > 6000f) + if (npc.ai[1] != 3f) { - npc.TargetClosest(); - if (Main.player[npc.target].dead || Math.Abs(npc.Center.X - Main.player[npc.target].Center.X) > 6000f || Math.Abs(npc.Center.Y - Main.player[npc.target].Center.Y) > 6000f) - npc.ai[1] = 3f; + int despawnDistanceInTiles = 500; + if (Main.player[npc.target].dead || Math.Abs(npc.Center.X - Main.player[npc.target].Center.X) / 16f > despawnDistanceInTiles) + { + npc.TargetClosest(); + if (Main.player[npc.target].dead || Math.Abs(npc.Center.X - Main.player[npc.target].Center.X) / 16f > despawnDistanceInTiles) + npc.ai[1] = 3f; + } + else if (npc.timeLeft < 1800) + npc.timeLeft = 1800; } // Activate daytime enrage @@ -274,7 +276,6 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) { npc.ai[2] = 0f; npc.ai[1] = 1f; - npc.TargetClosest(); npc.netUpdate = true; } else if (shouldSpinAround || npc.ai[1] != 4f) @@ -287,7 +288,6 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) npc.ai[2] = 0f; npc.ai[1] = shouldSpinAround ? 5f : 1f; - npc.TargetClosest(); npc.netUpdate = true; } } @@ -788,10 +788,6 @@ public static bool BuffedPrimeLaserAI(NPC npc, Mod mod) if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - // Set direction npc.spriteDirection = -(int)npc.ai[0]; @@ -922,10 +918,10 @@ public static bool BuffedPrimeLaserAI(NPC npc, Mod mod) if (npc.ai[3] >= (masterMode ? 200f : 800f)) { + npc.target = Main.npc[(int)npc.ai[1]].target; npc.localAI[0] = 0f; npc.ai[2] = 1f; npc.ai[3] = 0f; - npc.TargetClosest(); npc.netUpdate = true; } @@ -949,7 +945,6 @@ public static bool BuffedPrimeLaserAI(NPC npc, Mod mod) if (npc.localAI[0] >= 48f) { npc.localAI[0] = 0f; - npc.TargetClosest(); float laserSpeed = bossRush ? 5f : 4f; int type = ProjectileID.DeathLaser; int damage = npc.GetProjectileDamage(type); @@ -991,10 +986,10 @@ public static bool BuffedPrimeLaserAI(NPC npc, Mod mod) if (npc.ai[3] >= timeLimit) { + npc.target = Main.npc[(int)npc.ai[1]].target; npc.localAI[0] = 0f; npc.ai[2] = 0f; npc.ai[3] = 0f; - npc.TargetClosest(); npc.netUpdate = true; } @@ -1017,7 +1012,6 @@ public static bool BuffedPrimeLaserAI(NPC npc, Mod mod) if (npc.localAI[0] >= 120f) { npc.localAI[0] = 0f; - npc.TargetClosest(); int totalProjectiles = bossRush ? 32 : (masterMode ? 24 : 16); float radians = MathHelper.TwoPi / totalProjectiles; int type = ProjectileID.DeathLaser; @@ -1063,10 +1057,6 @@ public static bool BuffedPrimeCannonAI(NPC npc, Mod mod) if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - npc.spriteDirection = -(int)npc.ai[0]; if (!Main.npc[(int)npc.ai[1]].active || Main.npc[(int)npc.ai[1]].aiStyle != NPCAIStyleID.SkeletronPrimeHead) @@ -1139,11 +1129,11 @@ public static bool BuffedPrimeCannonAI(NPC npc, Mod mod) if (npc.ai[3] >= (masterMode ? 200f : 800f)) { + npc.target = Main.npc[(int)npc.ai[1]].target; npc.localAI[0] = 0f; npc.ai[2] = 1f; fireSlower = false; npc.ai[3] = 0f; - npc.TargetClosest(); npc.netUpdate = true; } } @@ -1163,11 +1153,11 @@ public static bool BuffedPrimeCannonAI(NPC npc, Mod mod) if (npc.ai[3] >= timeLimit) { + npc.target = Main.npc[(int)npc.ai[1]].target; npc.localAI[0] = 0f; npc.ai[2] = 0f; fireSlower = true; npc.ai[3] = 0f; - npc.TargetClosest(); npc.netUpdate = true; } } @@ -1259,7 +1249,6 @@ public static bool BuffedPrimeCannonAI(NPC npc, Mod mod) { SoundEngine.PlaySound(SoundID.Item62, npc.Center); npc.localAI[0] = 0f; - npc.TargetClosest(); int type = ProjectileID.RocketSkeleton; int damage = npc.GetProjectileDamage(type); @@ -1307,7 +1296,6 @@ public static bool BuffedPrimeCannonAI(NPC npc, Mod mod) { SoundEngine.PlaySound(SoundID.Item62, npc.Center); npc.localAI[0] = 0f; - npc.TargetClosest(); int type = ProjectileID.RocketSkeleton; int damage = npc.GetProjectileDamage(type); @@ -1349,10 +1337,6 @@ public static bool BuffedPrimeViceAI(NPC npc, Mod mod) if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - // Direction npc.spriteDirection = -(int)npc.ai[0]; @@ -1495,9 +1479,9 @@ public static bool BuffedPrimeViceAI(NPC npc, Mod mod) if (npc.ai[3] >= (masterMode ? 150f : 600f)) { + npc.target = Main.npc[(int)npc.ai[1]].target; npc.ai[2] += 1f; npc.ai[3] = 0f; - npc.TargetClosest(); npc.netUpdate = true; } @@ -1603,7 +1587,6 @@ public static bool BuffedPrimeViceAI(NPC npc, Mod mod) chargeVelocity += 1.5f; npc.ai[2] = 2f; - npc.TargetClosest(); viceArmChargePosition = npc.Center; viceArmChargeTargetX = Main.player[npc.target].Center.X - viceArmChargePosition.X; viceArmChargeTargetY = Main.player[npc.target].Center.Y - viceArmChargePosition.Y; @@ -1636,7 +1619,6 @@ public static bool BuffedPrimeViceAI(NPC npc, Mod mod) // Return to head npc.ai[2] = 3f; npc.ai[3] = 0f; - npc.TargetClosest(); return false; } @@ -1673,7 +1655,6 @@ public static bool BuffedPrimeViceAI(NPC npc, Mod mod) chargeVelocity += 1.15f; npc.ai[2] = 5f; - npc.TargetClosest(); viceArmOtherChargePosition = npc.Center; viceArmOtherChargeTargetX = Main.player[npc.target].Center.X - viceArmOtherChargePosition.X; viceArmOtherChargeTargetY = Main.player[npc.target].Center.Y - viceArmOtherChargePosition.Y; @@ -1704,7 +1685,6 @@ public static bool BuffedPrimeViceAI(NPC npc, Mod mod) // Return to head npc.ai[2] = 0f; npc.ai[3] = 0f; - npc.TargetClosest(); return false; } @@ -1726,10 +1706,6 @@ public static bool BuffedPrimeSawAI(NPC npc, Mod mod) if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - Vector2 sawArmLocation = npc.Center; float sawArmIdleXPos = Main.npc[(int)npc.ai[1]].Center.X - 200f * npc.ai[0] - sawArmLocation.X; float sawArmIdleYPos = Main.npc[(int)npc.ai[1]].position.Y + 230f - sawArmLocation.Y; @@ -1866,9 +1842,9 @@ public static bool BuffedPrimeSawAI(NPC npc, Mod mod) if (npc.ai[3] >= (masterMode ? 90f : 180f)) { + npc.target = Main.npc[(int)npc.ai[1]].target; npc.ai[2] += 1f; npc.ai[3] = 0f; - npc.TargetClosest(); npc.netUpdate = true; } @@ -1968,7 +1944,6 @@ public static bool BuffedPrimeSawAI(NPC npc, Mod mod) chargeVelocity += 1.5f; npc.ai[2] = 2f; - npc.TargetClosest(); sawArmChargePos = npc.Center; sawArmChargeTargetX = Main.player[npc.target].Center.X - sawArmChargePos.X; sawArmChargeTargetY = Main.player[npc.target].Center.Y - sawArmChargePos.Y; @@ -2057,7 +2032,6 @@ public static bool BuffedPrimeSawAI(NPC npc, Mod mod) { npc.ai[2] = 0f; npc.ai[3] = 0f; - npc.TargetClosest(); npc.netUpdate = true; } @@ -2133,7 +2107,6 @@ public static bool VanillaSkeletronPrimeAI(NPC npc, Mod mod) { npc.ai[2] = 0f; npc.ai[1] = 1f; - npc.TargetClosest(); npc.netUpdate = true; } @@ -2220,6 +2193,7 @@ public static bool VanillaSkeletronPrimeAI(NPC npc, Mod mod) { npc.ai[2] = 0f; npc.ai[1] = 0f; + npc.TargetClosest(); } if (NPC.IsMechQueenUp) @@ -2375,6 +2349,10 @@ public static bool VanillaPrimeLaserAI(NPC npc, Mod mod) } } + // Get a target + if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) + npc.TargetClosest(); + npc.damage = 0; if (npc.ai[2] == 0f || npc.ai[2] == 3f) @@ -2443,6 +2421,7 @@ public static bool VanillaPrimeLaserAI(NPC npc, Mod mod) npc.ai[3] += 1f; if (npc.ai[3] >= (Main.masterMode ? 400f : Main.expertMode ? 600f : 800f)) { + npc.target = Main.npc[(int)npc.ai[1]].target; npc.ai[2] += 1f; npc.ai[3] = 0f; npc.netUpdate = true; @@ -2502,7 +2481,6 @@ public static bool VanillaPrimeLaserAI(NPC npc, Mod mod) } } - npc.TargetClosest(); Vector2 vector68 = npc.Center; float num559 = Main.player[npc.target].Center.X - vector68.X; float num560 = Main.player[npc.target].Center.Y - vector68.Y; @@ -2546,6 +2524,7 @@ public static bool VanillaPrimeLaserAI(NPC npc, Mod mod) npc.ai[3] += 1f; if (npc.ai[3] >= (Main.masterMode ? 150f : Main.expertMode ? 175f : 200f)) { + npc.target = Main.npc[(int)npc.ai[1]].target; npc.localAI[0] = 0f; npc.ai[2] = 0f; npc.ai[3] = 0f; @@ -2602,7 +2581,6 @@ public static bool VanillaPrimeLaserAI(NPC npc, Mod mod) npc.velocity.Y += num498; } - npc.TargetClosest(); vector69 = npc.Center; num566 = Main.player[npc.target].Center.X - vector69.X; num567 = Main.player[npc.target].Center.Y - vector69.Y; @@ -2656,6 +2634,10 @@ public static bool VanillaPrimeCannonAI(NPC npc, Mod mod) } } + // Get a target + if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) + npc.TargetClosest(); + npc.damage = 0; if (npc.ai[2] == 0f) @@ -2724,6 +2706,7 @@ public static bool VanillaPrimeCannonAI(NPC npc, Mod mod) npc.ai[3] += 1f; if (npc.ai[3] >= (Main.masterMode ? 700f : Main.expertMode ? 900f : 1100f)) { + npc.target = Main.npc[(int)npc.ai[1]].target; npc.localAI[0] = 0f; npc.ai[2] = 1f; npc.ai[3] = 0f; @@ -2815,6 +2798,7 @@ public static bool VanillaPrimeCannonAI(NPC npc, Mod mod) npc.ai[3] += 1f; if (npc.ai[3] >= (Main.masterMode ? 180f : Main.expertMode ? 240f : 300f)) { + npc.target = Main.npc[(int)npc.ai[1]].target; npc.localAI[0] = 0f; npc.ai[2] = 0f; npc.ai[3] = 0f; @@ -2872,7 +2856,6 @@ public static bool VanillaPrimeCannonAI(NPC npc, Mod mod) npc.velocity.Y += num498; } - npc.TargetClosest(); vector67 = npc.Center; num552 = Main.player[npc.target].Center.X - vector67.X; num553 = Main.player[npc.target].Center.Y - vector67.Y; @@ -2926,6 +2909,10 @@ public static bool VanillaPrimeViceAI(NPC npc, Mod mod) } } + // Get a target + if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) + npc.TargetClosest(); + // Avoid cheap bullshit npc.damage = 0; @@ -2991,7 +2978,6 @@ public static bool VanillaPrimeViceAI(NPC npc, Mod mod) if (Main.npc[(int)npc.ai[1]].ai[1] != 0f) { - npc.TargetClosest(); if (Main.player[npc.target].dead) { npc.velocity.Y += 0.1f; @@ -3033,6 +3019,7 @@ public static bool VanillaPrimeViceAI(NPC npc, Mod mod) npc.ai[3] += 1f; if (npc.ai[3] >= (Main.masterMode ? 400f : Main.expertMode ? 500f : 600f)) { + npc.target = Main.npc[(int)npc.ai[1]].target; npc.ai[2] += 1f; npc.ai[3] = 0f; npc.netUpdate = true; @@ -3120,7 +3107,6 @@ public static bool VanillaPrimeViceAI(NPC npc, Mod mod) // Set damage npc.damage = npc.defDamage; - npc.TargetClosest(); npc.ai[2] = 2f; vector64 = npc.Center; num539 = Main.player[npc.target].Center.X - vector64.X; @@ -3169,7 +3155,6 @@ public static bool VanillaPrimeViceAI(NPC npc, Mod mod) // Set damage npc.damage = npc.defDamage; - npc.TargetClosest(); npc.ai[2] = 5f; vector65 = npc.Center; num542 = Main.player[npc.target].Center.X - vector65.X; @@ -3228,6 +3213,10 @@ public static bool VanillaPrimeSawAI(NPC npc, Mod mod) } } + // Get a target + if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) + npc.TargetClosest(); + // Min saw damage int reducedSetDamage = (int)Math.Round(npc.defDamage * 0.5); @@ -3296,7 +3285,6 @@ public static bool VanillaPrimeSawAI(NPC npc, Mod mod) if (Main.npc[(int)npc.ai[1]].ai[1] != 0f) { - npc.TargetClosest(); if (Main.player[npc.target].dead) { npc.velocity.Y += 0.1f; @@ -3362,6 +3350,7 @@ public static bool VanillaPrimeSawAI(NPC npc, Mod mod) npc.ai[3] += 1f; if (npc.ai[3] >= (Main.masterMode ? 180f : Main.expertMode ? 240f : 300f)) { + npc.target = Main.npc[(int)npc.ai[1]].target; npc.ai[2] += 1f; npc.ai[3] = 0f; npc.netUpdate = true; @@ -3446,7 +3435,6 @@ public static bool VanillaPrimeSawAI(NPC npc, Mod mod) // Set damage npc.damage = npc.defDamage; - npc.TargetClosest(); npc.ai[2] = 2f; vector59 = npc.Center; num524 = Main.player[npc.target].Center.X - vector59.X; @@ -3471,7 +3459,6 @@ public static bool VanillaPrimeSawAI(NPC npc, Mod mod) // Set damage npc.damage = npc.defDamage; - npc.TargetClosest(); Vector2 vector60 = npc.Center; float num527 = Main.player[npc.target].Center.X - vector60.X; float num528 = Main.player[npc.target].Center.Y - vector60.Y; diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/TwinsAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/TwinsAI.cs index 7f270bebca..1647c03d42 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/TwinsAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/TwinsAI.cs @@ -25,10 +25,6 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - float enrageScale = bossRush ? 0.5f : masterMode ? 0.4f : 0f; if (Main.IsItDay() || bossRush) { @@ -382,13 +378,13 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) { npc.ai[3] += 1f; npc.ai[2] = 0f; - npc.TargetClosest(); npc.rotation = retinazerHoverRotation; float totalCharges = death ? 6f : 5f; if (npc.ai[3] >= totalCharges) { npc.ai[1] = 0f; npc.ai[3] = 0f; + npc.TargetClosest(); } else npc.ai[1] = 1f; @@ -895,13 +891,13 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) npc.ai[3] += chargeIncrement; - npc.TargetClosest(); npc.rotation = retinazerHoverRotation; float maxChargeAmt = spazAlive ? 2f : 4f; if (npc.ai[3] >= maxChargeAmt) { npc.ai[1] = 0f; npc.ai[3] = 0f; + npc.TargetClosest(); } else npc.ai[1] = 4f; @@ -974,7 +970,6 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) npc.ai[2] += 1f; if (npc.ai[2] >= (spazAlive ? 75f : 60f) - (death ? 20f * ((phase2LifeRatio - lifeRatio) / phase2LifeRatio) : 0f)) { - npc.TargetClosest(); npc.ai[1] = 2f; npc.ai[2] = 0f; npc.netUpdate = true; @@ -998,10 +993,6 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - float enrageScale = bossRush ? 0.5f : masterMode ? 0.4f : 0f; if (Main.IsItDay() || bossRush) { @@ -1261,7 +1252,6 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) npc.ai[1] = 1f; npc.ai[2] = 0f; npc.ai[3] = 0f; - npc.TargetClosest(); npc.netUpdate = true; } else @@ -1367,7 +1357,6 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) // Reset AI array and go to cursed fireball phase npc.ai[3] += 1f; npc.ai[2] = 0f; - npc.TargetClosest(); npc.rotation = spazmatismRotation; float totalCharges = 8f; if (death) @@ -1584,7 +1573,6 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) npc.ai[1] = (!retAlive || finalPhase) ? 5f : 1f; npc.ai[2] = 0f; npc.ai[3] = 0f; - npc.TargetClosest(); npc.netUpdate = true; } @@ -1744,7 +1732,6 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) { npc.ai[3] += 1f; npc.ai[2] = 0f; - npc.TargetClosest(); npc.rotation = spazmatismRotation; if (npc.ai[3] >= 5f) { @@ -1766,7 +1753,6 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) float secondFastCharge = 4f; if (npc.ai[3] >= (retAlive ? secondFastCharge : secondFastCharge + 1f)) { - npc.TargetClosest(); npc.ai[1] = retAlive ? 0f : 5f; npc.ai[2] = 0f; npc.ai[3] = 0f; @@ -1996,7 +1982,6 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) // Take 3 seconds to get in position, then charge if (npc.ai[2] >= (retAlive ? 180f : 135f) - (death ? 45f * ((phase2LifeRatio - lifeRatio) / phase2LifeRatio) : 0f)) { - npc.TargetClosest(); npc.ai[1] = 3f; npc.ai[2] = -1f; npc.ai[3] = 0f; @@ -2196,7 +2181,7 @@ public static bool VanillaRetinazerAI(NPC npc, Mod mod) npc.ai[1] = 1f; npc.ai[2] = 0f; npc.ai[3] = 0f; - npc.target = Main.maxPlayers; + npc.TargetClosest(); npc.netUpdate = true; } else if (npc.position.Y + (float)npc.height < Main.player[npc.target].position.Y && num425 < (Main.masterMode ? 720f : Main.expertMode ? 560f : 400f)) @@ -2299,11 +2284,11 @@ public static bool VanillaRetinazerAI(NPC npc, Mod mod) { npc.ai[3] += 1f; npc.ai[2] = 0f; - npc.target = Main.maxPlayers; npc.rotation = num414; float numCharges = Main.masterMode ? 6f : Main.expertMode ? 5f : 4f; if (npc.ai[3] >= numCharges) { + npc.TargetClosest(); npc.ai[1] = 0f; npc.ai[3] = 0f; } @@ -2318,6 +2303,7 @@ public static bool VanillaRetinazerAI(NPC npc, Mod mod) npc.ai[1] = 0f; npc.ai[2] = 0f; npc.ai[3] = 0f; + npc.TargetClosest(); npc.netUpdate = true; } @@ -2748,7 +2734,6 @@ public static bool VanillaSpazmatismAI(NPC npc, Mod mod) // Avoid cheap bullshit npc.damage = 0; - npc.TargetClosest(); float num463 = 12f; float num464 = 0.4f; if (Main.expertMode) @@ -2838,7 +2823,6 @@ public static bool VanillaSpazmatismAI(NPC npc, Mod mod) npc.ai[1] = 1f; npc.ai[2] = 0f; npc.ai[3] = 0f; - npc.target = Main.maxPlayers; npc.netUpdate = true; } else @@ -2942,7 +2926,6 @@ public static bool VanillaSpazmatismAI(NPC npc, Mod mod) { npc.ai[3] += 1f; npc.ai[2] = 0f; - npc.target = Main.maxPlayers; npc.rotation = num458; float numCharges = Main.masterMode ? 6f : Main.expertMode ? 8f : 10f; if (npc.ai[3] >= numCharges) @@ -3130,7 +3113,6 @@ public static bool VanillaSpazmatismAI(NPC npc, Mod mod) npc.ai[1] = 1f; npc.ai[2] = 0f; npc.ai[3] = 0f; - npc.target = Main.maxPlayers; npc.netUpdate = true; } @@ -3274,7 +3256,6 @@ public static bool VanillaSpazmatismAI(NPC npc, Mod mod) { npc.ai[3] += 1f; npc.ai[2] = 0f; - npc.target = Main.maxPlayers; npc.rotation = num458; float numCharges = Main.masterMode ? Main.rand.Next(4, 7) : 6f; if (npc.ai[3] >= numCharges) diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/WallOfFleshAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/WallOfFleshAI.cs index 8ece6740c8..0a8ab9133b 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/WallOfFleshAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/WallOfFleshAI.cs @@ -872,7 +872,6 @@ public static bool BuffedWallofFleshEyeAI(NPC npc, Mod mod) { npc.localAI[2] = 1f; npc.localAI[1] = 0f; - npc.TargetClosest(); } } else if (npc.localAI[1] > 45f && (canHit || masterModeDetach) && !charging) @@ -880,7 +879,10 @@ public static bool BuffedWallofFleshEyeAI(NPC npc, Mod mod) npc.localAI[1] = 0f; npc.localAI[2] += 1f; if (npc.localAI[2] >= TotalLasersPerBarrage + 1f) + { npc.localAI[2] = 0f; + npc.TargetClosest(); + } if (shouldFireLasers) { @@ -1351,7 +1353,6 @@ public static bool VanillaWallofFleshEyeAI(NPC npc, Mod mod) // Avoid cheap bullshit npc.damage = 0; - npc.TargetClosest(); npc.position.X = Main.npc[Main.wofNPCIndex].position.X; npc.direction = Main.npc[Main.wofNPCIndex].direction; npc.spriteDirection = npc.direction; @@ -1464,7 +1465,10 @@ public static bool VanillaWallofFleshEyeAI(NPC npc, Mod mod) npc.localAI[1] = 0f; npc.localAI[2] += 1f; if (npc.localAI[2] >= (float)num396) + { npc.localAI[2] = 0f; + npc.TargetClosest(); + } if (flag27) { From 362b2c5b34fbb8f03f6a37a6f8542a0eb1495dec Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Sun, 19 May 2024 22:00:56 -0500 Subject: [PATCH 011/401] Fixed Slime God Core despawn issue. --- NPCs/SlimeGod/SlimeGodCore.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/NPCs/SlimeGod/SlimeGodCore.cs b/NPCs/SlimeGod/SlimeGodCore.cs index c0bdd4c2f6..153c0e85ad 100644 --- a/NPCs/SlimeGod/SlimeGodCore.cs +++ b/NPCs/SlimeGod/SlimeGodCore.cs @@ -158,6 +158,9 @@ public override void AI() calamityGlobalNPC.newAI[0] = Main.npc[CalamityGlobalNPC.slimeGodPurple].Center.X; calamityGlobalNPC.newAI[1] = Main.npc[CalamityGlobalNPC.slimeGodPurple].Center.Y; + // Despawn check + calamityGlobalNPC.newAI[3] = Main.npc[CalamityGlobalNPC.slimeGodPurple].ai[0] == 4f ? 1f : 0f; + purpleSlimeAlive = true; } } @@ -173,6 +176,9 @@ public override void AI() NPC.ai[1] = Main.npc[CalamityGlobalNPC.slimeGodRed].Center.X; NPC.ai[2] = Main.npc[CalamityGlobalNPC.slimeGodRed].Center.Y; + + // Despawn check + calamityGlobalNPC.newAI[3] = Main.npc[CalamityGlobalNPC.slimeGodRed].ai[0] == 3f ? 1f : 0f; redSlimeAlive = true; } @@ -265,6 +271,7 @@ public override void AI() { NPC.ApplyInteraction(i); } + NPC.active = false; NPC.HitEffect(); NPC.NPCLoot(); @@ -275,11 +282,15 @@ public override void AI() } // Despawn - if (!player.active || player.dead || Vector2.Distance(player.Center, NPC.Center) > (bossRush ? CalamityGlobalNPC.CatchUpDistance350Tiles : CalamityGlobalNPC.CatchUpDistance200Tiles)) + if (!player.active || player.dead || Vector2.Distance(player.Center, NPC.Center) > (bossRush ? CalamityGlobalNPC.CatchUpDistance350Tiles : CalamityGlobalNPC.CatchUpDistance200Tiles) || calamityGlobalNPC.newAI[3] == 1f) { - NPC.TargetClosest(false); - player = Main.player[NPC.target]; - if (!player.active || player.dead || Vector2.Distance(player.Center, NPC.Center) > (bossRush ? CalamityGlobalNPC.CatchUpDistance350Tiles : CalamityGlobalNPC.CatchUpDistance200Tiles)) + if (calamityGlobalNPC.newAI[3] != 1f) + { + NPC.TargetClosest(false); + player = Main.player[NPC.target]; + } + + if (!player.active || player.dead || Vector2.Distance(player.Center, NPC.Center) > (bossRush ? CalamityGlobalNPC.CatchUpDistance350Tiles : CalamityGlobalNPC.CatchUpDistance200Tiles) || calamityGlobalNPC.newAI[3] == 1f) { if (NPC.velocity.Y < -3f) NPC.velocity.Y = -3f; From 378606060ca13adf6281164b003d8c512709bf68 Mon Sep 17 00:00:00 2001 From: Memes Date: Sun, 19 May 2024 13:31:35 +0200 Subject: [PATCH 012/401] Adamantite Particle Accelerator as a base holdout. --- .../BaseGunHoldoutProjectile.cs | 4 +- .../Ranged/AdamantiteAcceleratorHoldout.cs | 110 ++++++++---------- 2 files changed, 48 insertions(+), 66 deletions(-) diff --git a/Projectiles/BaseProjectiles/BaseGunHoldoutProjectile.cs b/Projectiles/BaseProjectiles/BaseGunHoldoutProjectile.cs index 81c50e3baa..48e3be1879 100644 --- a/Projectiles/BaseProjectiles/BaseGunHoldoutProjectile.cs +++ b/Projectiles/BaseProjectiles/BaseGunHoldoutProjectile.cs @@ -256,7 +256,7 @@ public sealed override void SendExtraAI(BinaryWriter writer) writer.Write(Projectile.rotation); writer.Write(KeepRefreshingLifetime); writer.Write(OffsetLengthFromArm); - writer.Write(Projectile.spriteDirection); + writer.Write7BitEncodedInt(Projectile.spriteDirection); SendExtraAIHoldout(writer); } @@ -265,7 +265,7 @@ public sealed override void ReceiveExtraAI(BinaryReader reader) Projectile.rotation = reader.ReadSingle(); KeepRefreshingLifetime = reader.ReadBoolean(); OffsetLengthFromArm = reader.ReadSingle(); - Projectile.spriteDirection = reader.ReadInt32(); + Projectile.spriteDirection = reader.Read7BitEncodedInt(); ReceiveExtraAIHoldout(reader); } diff --git a/Projectiles/Ranged/AdamantiteAcceleratorHoldout.cs b/Projectiles/Ranged/AdamantiteAcceleratorHoldout.cs index 57f572b000..3af7722d96 100644 --- a/Projectiles/Ranged/AdamantiteAcceleratorHoldout.cs +++ b/Projectiles/Ranged/AdamantiteAcceleratorHoldout.cs @@ -1,59 +1,59 @@ -using System; +using System.IO; using CalamityMod.Items.Weapons.Ranged; using CalamityMod.Particles; +using CalamityMod.Projectiles.BaseProjectiles; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using ReLogic.Utilities; using Terraria; using Terraria.Audio; using Terraria.ID; -using Terraria.Localization; -using Terraria.ModLoader; using static CalamityMod.CalamityUtils; using static Terraria.ModLoader.ModContent; namespace CalamityMod.Projectiles.Ranged { - public class AdamantiteAcceleratorHoldout : ModProjectile + public class AdamantiteAcceleratorHoldout : BaseGunHoldoutProjectile { - public override LocalizedText DisplayName => CalamityUtils.GetItemName(); - public override string Texture => "CalamityMod/Items/Weapons/Ranged/AdamantiteParticleAccelerator"; - const float maxTimeAnim = 35; - public Player Owner => Main.player[Projectile.owner]; - public float Timer => maxTimeAnim - Projectile.timeLeft; + public override int AssociatedItemID => ItemType(); + public override Vector2 GunTipPosition => Owner.MountedCenter + Projectile.rotation.ToRotationVector2() * 70f + (Vector2.UnitY * -12f * Owner.direction).RotatedBy(Projectile.rotation); + public override float MaxOffsetLengthFromArm => base.MaxOffsetLengthFromArm; + public override float OffsetXUpwards => base.OffsetXUpwards; + public override float OffsetXDownwards => base.OffsetXDownwards; + public override float BaseOffsetY => base.BaseOffsetY; + public override float OffsetYUpwards => base.OffsetYUpwards; + public override float OffsetYDownwards => base.OffsetYDownwards; + public ref float ChargeTimer => ref Projectile.ai[0]; public ref float DelayTimer => ref Projectile.ai[1]; public ref float ChargeRate => ref Projectile.localAI[0]; public ref float BounceBackPower => ref Projectile.localAI[1]; - public Vector2 NuzzlePosition => Owner.MountedCenter + Projectile.rotation.ToRotationVector2() * 70f + (Vector2.UnitY * -12f * Owner.direction).RotatedBy(Projectile.rotation); private SlotId ChargeupSoundSlot; - public override void SetDefaults() + public override void KillHoldoutLogic() { - Projectile.width = 54; - Projectile.height = 52; - // This projectile has no hitboxes and no damage type. - Projectile.friendly = false; - Projectile.tileCollide = false; - Projectile.ignoreWater = true; - Projectile.timeLeft = 900; - Projectile.velocity = Vector2.Zero; + int maxTime = AdamantiteParticleAccelerator.ChargeFrames + AdamantiteParticleAccelerator.CooldownFrames; + if (ChargeTimer > maxTime) + { + if (!Owner.CantUseHoldout()) + ResetToStart(); + else + { + Projectile.Kill(); + return; + } + } } // ChargeTimer is a time-dilated frame counter. DelayTimer is the frame counter for when the beams are fired. // ChargeRate is the rate at which the "frame" counter increases. BounceBackPower is there for the visuals of the gun recoiling in the players hands. - public override void AI() + public override void HoldoutAI() { - Player player = Main.player[Projectile.owner]; - Vector2 rrp = player.RotatedRelativePoint(player.MountedCenter, true); - - Projectile.rotation = Owner.MountedCenter.AngleTo(Owner.Calamity().mouseWorld); - // Calculate how quickly the gun should charge. Charge increases by some number close to 1 every frame. // Speed increasing reforges make this number greater than 1. Slowing reforges make it smaller than 1. if (ChargeRate == 0f) - ChargeRate = 44f / player.ActiveItem().useTime; + ChargeRate = 44f / HeldItem.useTime; if (ChargeTimer == 0f) ChargeupSoundSlot = SoundEngine.PlaySound(SoundID.DD2_WitherBeastAuraPulse with { Volume = SoundID.DD2_WitherBeastAuraPulse.Volume * 1.6f }, Projectile.Center); @@ -69,24 +69,10 @@ public override void AI() // Increment the timer for the gun. If the timer has passed 44, destroy it. ChargeTimer += ChargeRate; - int maxTime = AdamantiteParticleAccelerator.ChargeFrames + AdamantiteParticleAccelerator.CooldownFrames; - if (ChargeTimer > maxTime) - { - if (Owner.channel) - ResetToStart(); - else - { - Projectile.Kill(); - return; - } - } // Compute the weapon's charge. float chargeLevel = MathHelper.Clamp(Projectile.ai[0] / AdamantiteParticleAccelerator.ChargeFrames, 0f, 1f); - // Common code among holdouts to keep the holdout projectile directly in the player's hand - UpdatePlayerVisuals(player, rrp); - // Firing or charging? if (chargeLevel >= 1f) { @@ -96,8 +82,8 @@ public override void AI() FiringEffects(new Color(235, 40, 121)); if (Projectile.owner == Main.myPlayer) { - Projectile redLaser = Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), NuzzlePosition, Projectile.rotation.ToRotationVector2(), ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner, 0, 120); - redLaser.Center = NuzzlePosition; + Projectile redLaser = Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), GunTipPosition, Projectile.rotation.ToRotationVector2(), ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner, 0, 120); + redLaser.Center = GunTipPosition; } } @@ -107,8 +93,8 @@ public override void AI() FiringEffects(new Color(49, 161, 246)); if (Projectile.owner == Main.myPlayer) { - Projectile blueLaser = Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), NuzzlePosition, Projectile.rotation.ToRotationVector2(), ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner, 0, -120); - blueLaser.Center = NuzzlePosition; + Projectile blueLaser = Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), GunTipPosition, Projectile.rotation.ToRotationVector2(), ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner, 0, -120); + blueLaser.Center = GunTipPosition; } } DelayTimer += 1f; @@ -124,27 +110,12 @@ public override void AI() public CurveSegment oversquish = new CurveSegment(SineBumpEasing, 0.7f, 0f, -0.6f); internal float RecoilSquish => PiecewiseAnimation(1 - MathHelper.Clamp(BounceBackPower * 2f, 0f, 1f), new CurveSegment[] { unsquish, oversquish }); - private void UpdatePlayerVisuals(Player player, Vector2 rrp) - { - // Place the projectile directly into the player's hand at all times - Projectile.Center = rrp; - - // The gun is a holdout projectile, so change the player's variables to reflect that - player.ChangeDir(Math.Sign(Projectile.rotation.ToRotationVector2().X)); - player.heldProj = Projectile.whoAmI; - player.itemTime = 2; - player.itemAnimation = 2; - - player.SetCompositeArmFront(true, Player.CompositeArmStretchAmount.Full, Projectile.rotation - MathHelper.PiOver2); - - } - private void FiringEffects(Color color) { - SoundEngine.PlaySound(SoundID.Item92, NuzzlePosition); - SoundEngine.PlaySound(SoundID.Item60, NuzzlePosition); + SoundEngine.PlaySound(SoundID.Item92, GunTipPosition); + SoundEngine.PlaySound(SoundID.Item60, GunTipPosition); - Particle pulse = new DirectionalPulseRing(NuzzlePosition + Projectile.rotation.ToRotationVector2() * 5f, Vector2.Zero, color, new Vector2(0.5f, 1f), Projectile.rotation, 0.05f, 0.34f + Main.rand.NextFloat(0.3f), 30); + Particle pulse = new DirectionalPulseRing(GunTipPosition + Projectile.rotation.ToRotationVector2() * 5f, Vector2.Zero, color, new Vector2(0.5f, 1f), Projectile.rotation, 0.05f, 0.34f + Main.rand.NextFloat(0.3f), 30); GeneralParticleHandler.SpawnParticle(pulse); if (Owner == Main.LocalPlayer && Owner.Calamity().GeneralScreenShakePower < 5) @@ -174,7 +145,7 @@ public override bool PreDraw(ref Color lightColor) public override bool PreKill(int timeLeft) { - if (Owner.channel) + if (!Owner.CantUseHoldout()) { ResetToStart(); return false; @@ -185,9 +156,20 @@ public override bool PreKill(int timeLeft) public void ResetToStart() { - Projectile.timeLeft = 900; ChargeTimer = 0f; DelayTimer = 0f; } + + public override void SendExtraAIHoldout(BinaryWriter writer) + { + writer.Write(ChargeRate); + writer.Write(BounceBackPower); + } + + public override void ReceiveExtraAIHoldout(BinaryReader reader) + { + ChargeRate = reader.ReadSingle(); + BounceBackPower = reader.ReadSingle(); + } } } From b5ef022814c04a0efd7a87f53014ff5c56a123a4 Mon Sep 17 00:00:00 2001 From: Memes Date: Sun, 19 May 2024 14:01:43 +0200 Subject: [PATCH 013/401] Condemnation as a base holdout. --- Items/Weapons/Ranged/Condemnation.cs | 9 +- Projectiles/Ranged/CondemnationHoldout.cs | 163 +++++++++------------- 2 files changed, 70 insertions(+), 102 deletions(-) diff --git a/Items/Weapons/Ranged/Condemnation.cs b/Items/Weapons/Ranged/Condemnation.cs index 9f80655ae3..8adb29a61a 100644 --- a/Items/Weapons/Ranged/Condemnation.cs +++ b/Items/Weapons/Ranged/Condemnation.cs @@ -44,10 +44,15 @@ public override void SetDefaults() public override void HoldItem(Player player) { + var calPlayer = player.Calamity(); + if (Main.myPlayer == player.whoAmI) - player.Calamity().rightClickListener = true; + { + calPlayer.rightClickListener = true; + calPlayer.mouseRotationListener = true; + } - if (player.Calamity().mouseRight && player.ownedProjectileCounts[ModContent.ProjectileType()] <= 0) + if (calPlayer.mouseRight && player.ownedProjectileCounts[ModContent.ProjectileType()] <= 0) { Item.noUseGraphic = false; } diff --git a/Projectiles/Ranged/CondemnationHoldout.cs b/Projectiles/Ranged/CondemnationHoldout.cs index 04693f2c48..adb6c6d397 100644 --- a/Projectiles/Ranged/CondemnationHoldout.cs +++ b/Projectiles/Ranged/CondemnationHoldout.cs @@ -1,18 +1,20 @@ -using CalamityMod.Items.Weapons.Ranged; -using CalamityMod.Sounds; +using System.IO; +using CalamityMod.Items.Weapons.Ranged; +using CalamityMod.Projectiles.BaseProjectiles; using Microsoft.Xna.Framework; using Terraria; using Terraria.Audio; using Terraria.ID; -using Terraria.Localization; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Ranged { - public class CondemnationHoldout : ModProjectile + public class CondemnationHoldout : BaseGunHoldoutProjectile { - public override LocalizedText DisplayName => CalamityUtils.GetItemName(); - private Player Owner => Main.player[Projectile.owner]; + public override int AssociatedItemID => ModContent.ItemType(); + public override float MaxOffsetLengthFromArm => 25f; + public override float OffsetXUpwards => -5f; + public override float BaseOffsetY => -5f; private ref float CurrentChargingFrames => ref Projectile.ai[0]; private ref float ArrowsLoaded => ref Projectile.ai[1]; @@ -22,24 +24,8 @@ public class CondemnationHoldout : ModProjectile public const float velocityMultiplier = 1.2f; public bool homing = false; - public override string Texture => "CalamityMod/Items/Weapons/Ranged/Condemnation"; - - public override void SetDefaults() - { - Projectile.width = 130; - Projectile.height = 42; - Projectile.friendly = true; - Projectile.penetrate = -1; - Projectile.tileCollide = false; - Projectile.DamageType = DamageClass.Ranged; - Projectile.ignoreWater = true; - } - - public override void AI() + public override void KillHoldoutLogic() { - Vector2 armPosition = Owner.RotatedRelativePoint(Owner.MountedCenter, true); - Vector2 tipPosition = armPosition + Projectile.velocity * Projectile.width * 0.5f; - // Fire arrows if the owner stops channeling or otherwise cannot use the weapon. if (Owner.CantUseHoldout()) { @@ -51,65 +37,61 @@ public override void AI() } // Fire one charged arrow every frame until you're out of arrows. - ShootProjectiles(tipPosition, homing); + ShootProjectiles(homing); --ArrowsLoaded; if (ArrowsLoaded == 0 && homing == true) homing = false; } - else + } + + public override void HoldoutAI() + { + // Frame 1 effects: Record how fast the Condemnation item being used is, to determine how fast to load arrows. + if (FramesToLoadNextArrow == 0f) { + SoundEngine.PlaySound(SoundID.Item20, Projectile.Center); + FramesToLoadNextArrow = HeldItem.useAnimation; + } - // Frame 1 effects: Record how fast the Condemnation item being used is, to determine how fast to load arrows. - if (FramesToLoadNextArrow == 0f) - { - SoundEngine.PlaySound(SoundID.Item20, Projectile.Center); - FramesToLoadNextArrow = Owner.ActiveItem().useAnimation; - } + // If no arrows are loaded, spawn a bit of dust to indicate it's not ready yet. + // Spawn the same dust if the max number of arrows have been loaded or the player ran out of ammos to load. + if (ArrowsLoaded <= 0f || ArrowsLoaded >= Condemnation.MaxLoadedArrows || !Owner.HasAmmo(Owner.ActiveItem())) + SpawnCannotLoadArrowsDust(GunTipPosition); - // If no arrows are loaded, spawn a bit of dust to indicate it's not ready yet. - // Spawn the same dust if the max number of arrows have been loaded or the player ran out of ammos to load. - if (ArrowsLoaded <= 0f || ArrowsLoaded >= Condemnation.MaxLoadedArrows || !Owner.HasAmmo(Owner.ActiveItem())) - SpawnCannotLoadArrowsDust(tipPosition); + if (Owner.HasAmmo(HeldItem)) + { + // Actually make progress towards loading more arrows. + ++CurrentChargingFrames; - if (Owner.HasAmmo(Owner.ActiveItem())) + // If it is time to load an arrow, produce a pulse of dust and add an arrow. + // Also accelerate charging, because it's fucking awesome. + // Take the ammo here as well + if (CurrentChargingFrames >= FramesToLoadNextArrow && ArrowsLoaded < Condemnation.MaxLoadedArrows) { - // Actually make progress towards loading more arrows. - ++CurrentChargingFrames; + // Save the stats here for later + Owner.PickAmmo(HeldItem, out _, out float shootSpeed, out int damage, out float knockback, out _); + Projectile.damage = damage; + Projectile.knockBack = knockback; + storedVelocity = shootSpeed * velocityMultiplier; + + SpawnArrowLoadedDust(); + CurrentChargingFrames = 0f; + ++ArrowsLoaded; + --FramesToLoadNextArrow; + + // Play a sound for additional notification that an arrow has been loaded. + var loadSound = SoundEngine.PlaySound(SoundID.Item108 with { Volume = SoundID.Item108.Volume * 0.3f }); - // If it is time to load an arrow, produce a pulse of dust and add an arrow. - // Also accelerate charging, because it's fucking awesome. - // Take the ammo here as well - if (CurrentChargingFrames >= FramesToLoadNextArrow && ArrowsLoaded < Condemnation.MaxLoadedArrows) + if (ArrowsLoaded >= Condemnation.MaxLoadedArrows) { - // Save the stats here for later - Item heldItem = Owner.ActiveItem(); - Owner.PickAmmo(heldItem, out _, out float shootSpeed, out int damage, out float knockback, out _); - Projectile.damage = damage; - Projectile.knockBack = knockback; - storedVelocity = shootSpeed * velocityMultiplier; - - SpawnArrowLoadedDust(tipPosition); - CurrentChargingFrames = 0f; - ++ArrowsLoaded; - --FramesToLoadNextArrow; - - // Play a sound for additional notification that an arrow has been loaded. - var loadSound = SoundEngine.PlaySound(SoundID.Item108 with { Volume = SoundID.Item108.Volume * 0.3f }); - - if (ArrowsLoaded >= Condemnation.MaxLoadedArrows) - { - SoundEngine.PlaySound(new("CalamityMod/Sounds/Custom/AbilitySounds/BrimflameRecharge")); - homing = true; - } + SoundEngine.PlaySound(new("CalamityMod/Sounds/Custom/AbilitySounds/BrimflameRecharge")); + homing = true; } } } - - UpdateProjectileHeldVariables(armPosition); - ManipulatePlayerVariables(); } - public void SpawnArrowLoadedDust(Vector2 tipPosition) + public void SpawnArrowLoadedDust() { if (Main.dedServ) return; @@ -126,7 +108,7 @@ public void SpawnArrowLoadedDust(Vector2 tipPosition) Vector2 end = nextAngle.ToRotationVector2(); for (int j = 0; j < 40; j++) { - Dust starDust = Dust.NewDustPerfect(tipPosition, 267); + Dust starDust = Dust.NewDustPerfect(GunTipPosition, 267); starDust.scale = 2.5f; starDust.velocity = Vector2.Lerp(start, end, j / 40f) * 16f; starDust.color = Color.Crimson; @@ -138,7 +120,7 @@ public void SpawnArrowLoadedDust(Vector2 tipPosition) for (int i = 0; i < 36; i++) { - Dust chargeMagic = Dust.NewDustPerfect(tipPosition, 267); + Dust chargeMagic = Dust.NewDustPerfect(GunTipPosition, 267); chargeMagic.velocity = (MathHelper.TwoPi * i / 36f).ToRotationVector2() * 5f + Owner.velocity; chargeMagic.scale = Main.rand.NextFloat(1f, 1.5f); chargeMagic.color = Color.Violet; @@ -146,62 +128,43 @@ public void SpawnArrowLoadedDust(Vector2 tipPosition) } } - public void SpawnCannotLoadArrowsDust(Vector2 tipPosition) + public void SpawnCannotLoadArrowsDust(Vector2 GunTipPosition) { if (Main.dedServ) return; for (int i = 0; i < 2; i++) { - Dust chargeMagic = Dust.NewDustPerfect(tipPosition + Main.rand.NextVector2Circular(20f, 20f), 267); - chargeMagic.velocity = (tipPosition - chargeMagic.position) * 0.1f + Owner.velocity; + Dust chargeMagic = Dust.NewDustPerfect(GunTipPosition + Main.rand.NextVector2Circular(20f, 20f), 267); + chargeMagic.velocity = (GunTipPosition - chargeMagic.position) * 0.1f + Owner.velocity; chargeMagic.scale = Main.rand.NextFloat(1f, 1.5f); chargeMagic.color = Projectile.GetAlpha(Color.White); chargeMagic.noGravity = true; } } - public void ShootProjectiles(Vector2 tipPosition, bool homing) + public void ShootProjectiles(bool homing) { if (Main.myPlayer != Projectile.owner) return; Vector2 shootVelocity = Projectile.velocity.SafeNormalize(Vector2.UnitY) * storedVelocity; int ArrowType = homing ? ModContent.ProjectileType() : ModContent.ProjectileType(); - Projectile.NewProjectile(Projectile.GetSource_FromThis(), tipPosition, shootVelocity, ArrowType, Projectile.damage, Projectile.knockBack, Projectile.owner); + Projectile.NewProjectile(Projectile.GetSource_FromThis(), GunTipPosition, shootVelocity, ArrowType, Projectile.damage, Projectile.knockBack, Projectile.owner); } - private void UpdateProjectileHeldVariables(Vector2 armPosition) + public override void SendExtraAIHoldout(BinaryWriter writer) { - if (Main.myPlayer == Projectile.owner) - { - float interpolant = Utils.GetLerpValue(5f, 25f, Projectile.Distance(Main.MouseWorld), true); - Vector2 oldVelocity = Projectile.velocity; - Projectile.velocity = Vector2.Lerp(Projectile.velocity, Projectile.SafeDirectionTo(Main.MouseWorld), interpolant); - if (Projectile.velocity != oldVelocity) - { - Projectile.netSpam = 0; - Projectile.netUpdate = true; - } - } - - Projectile.position = armPosition - Projectile.Size * 0.5f; - Projectile.rotation = Projectile.velocity.ToRotation(); - if (Projectile.spriteDirection == -1) - Projectile.rotation += MathHelper.Pi; - Projectile.spriteDirection = Projectile.direction; - Projectile.timeLeft = 2; + writer.Write(FramesToLoadNextArrow); + writer.Write(storedVelocity); + writer.Write(homing); } - private void ManipulatePlayerVariables() + public override void ReceiveExtraAIHoldout(BinaryReader reader) { - Owner.ChangeDir(Projectile.direction); - Owner.heldProj = Projectile.whoAmI; - Owner.itemTime = 2; - Owner.itemAnimation = 2; - Owner.itemRotation = (Projectile.velocity * Projectile.direction).ToRotation(); + FramesToLoadNextArrow = reader.ReadSingle(); + storedVelocity = reader.ReadSingle(); + homing = reader.ReadBoolean(); } - - public override bool? CanDamage() => false; } } From d3e4542b191d5fc7b3f6b680a6986b3f049225ef Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sun, 19 May 2024 11:22:28 -0400 Subject: [PATCH 014/401] Thank You shenanigans --- Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs index 17aec33a70..c48fa96e83 100644 --- a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs +++ b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs @@ -72,7 +72,6 @@ public override void ModifyTooltips(List tooltips) "CosmaticMango", "CrabBar", "Dia", - "DylanDoe21", "enamoured", "Fluffi", "HaguriHat", @@ -94,7 +93,6 @@ public override void ModifyTooltips(List tooltips) "Shayy", "Spider Prov", "StipulateVenus", - "Tomat", "Triangle", "Uncle Danny", "Xyk", @@ -126,6 +124,7 @@ public override void ModifyTooltips(List tooltips) "Doog", "drh", "dwshin", + "DylanDoe21", "Earth", "EchoDuck", "Ein", @@ -191,6 +190,7 @@ public override void ModifyTooltips(List tooltips) "ThousandFields", "TikiWiki", "Tinymanx", + "Tomat", "Trivaxy", "Uberransy", "Vaikyia", From 7a67efd11278014d705571ca106896456e7fa0e9 Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Sun, 19 May 2024 22:24:06 +0700 Subject: [PATCH 015/401] basher tooltip update --- Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson index afeab0b76b..7fa39e9879 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson @@ -169,7 +169,7 @@ BansheeHook: { Basher: { DisplayName: Basher - Tooltip: Swings a rotten club that poisons and irradiates enemies on hit + Tooltip: Swings a rotten club that irradiates enemies on hit } BladecrestOathsword: { From 48aa53353dfd858e772c3ee4a027b4e7140c73f7 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sun, 19 May 2024 17:16:59 -0400 Subject: [PATCH 016/401] Reverted Basher tooltip change --- Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson index 7fa39e9879..afeab0b76b 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson @@ -169,7 +169,7 @@ BansheeHook: { Basher: { DisplayName: Basher - Tooltip: Swings a rotten club that irradiates enemies on hit + Tooltip: Swings a rotten club that poisons and irradiates enemies on hit } BladecrestOathsword: { From 5ebed72ac8a42a350f47256cde4e479f8451312f Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sun, 19 May 2024 17:17:29 -0400 Subject: [PATCH 017/401] ENNWAY development absorption --- Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs index c48fa96e83..63db3bcde1 100644 --- a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs +++ b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs @@ -73,6 +73,7 @@ public override void ModifyTooltips(List tooltips) "CrabBar", "Dia", "enamoured", + "ENNWAY", "Fluffi", "HaguriHat", "Heart Plus Up!", @@ -128,7 +129,6 @@ public override void ModifyTooltips(List tooltips) "Earth", "EchoDuck", "Ein", - "ENNWAY", "Enreden", "Epsilon", "Fargowilta", From 0035b2d3049409421caeae75221eea367ea7fb61 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Mon, 20 May 2024 03:43:37 -0500 Subject: [PATCH 018/401] I hate how things despawn in this game so much --- NPCs/SlimeGod/CrimulanPaladin.cs | 2 - NPCs/SlimeGod/EbonianPaladin.cs | 2 - NPCs/SlimeGod/SlimeGodCore.cs | 70 ++++++++++++------- NPCs/SlimeGod/SplitCrimulanPaladin.cs | 2 - NPCs/SlimeGod/SplitEbonianPaladin.cs | 2 - .../Bosses/SkeletronAI.cs | 3 - 6 files changed, 44 insertions(+), 37 deletions(-) diff --git a/NPCs/SlimeGod/CrimulanPaladin.cs b/NPCs/SlimeGod/CrimulanPaladin.cs index 59c8c721e0..8d7147dc4d 100644 --- a/NPCs/SlimeGod/CrimulanPaladin.cs +++ b/NPCs/SlimeGod/CrimulanPaladin.cs @@ -742,8 +742,6 @@ public override void AI() return newColor * NPC.Opacity; } - public override bool CheckActive() => NPC.ai[0] == 3f; - public override void HitEffect(NPC.HitInfo hit) { Color dustColor = Color.Crimson; diff --git a/NPCs/SlimeGod/EbonianPaladin.cs b/NPCs/SlimeGod/EbonianPaladin.cs index f59df6f5f8..fe2ae3f8a7 100644 --- a/NPCs/SlimeGod/EbonianPaladin.cs +++ b/NPCs/SlimeGod/EbonianPaladin.cs @@ -787,8 +787,6 @@ public override void AI() return newColor * NPC.Opacity; } - public override bool CheckActive() => NPC.ai[0] == 4f; - public override void HitEffect(NPC.HitInfo hit) { Color dustColor = Color.Lavender; diff --git a/NPCs/SlimeGod/SlimeGodCore.cs b/NPCs/SlimeGod/SlimeGodCore.cs index 153c0e85ad..d2f4e0bb7c 100644 --- a/NPCs/SlimeGod/SlimeGodCore.cs +++ b/NPCs/SlimeGod/SlimeGodCore.cs @@ -100,6 +100,7 @@ public override void SetBestiary(BestiaryDatabase database, BestiaryEntry bestia public override void SendExtraAI(BinaryWriter writer) { + writer.Write(slimesSpawned); writer.Write(buffedSlime); writer.Write(NPC.Opacity); for (int i = 0; i < 4; i++) @@ -108,6 +109,7 @@ public override void SendExtraAI(BinaryWriter writer) public override void ReceiveExtraAI(BinaryReader reader) { + slimesSpawned = reader.ReadBoolean(); buffedSlime = reader.ReadInt32(); NPC.Opacity = reader.ReadSingle(); for (int i = 0; i < 4; i++) @@ -135,11 +137,14 @@ public override void AI() Player player = Main.player[NPC.target]; - if (Main.netMode != NetmodeID.MultiplayerClient && !slimesSpawned) + if (!slimesSpawned) { slimesSpawned = true; - NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y, ModContent.NPCType()); - NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y, ModContent.NPCType()); + if (Main.netMode != NetmodeID.MultiplayerClient) + { + NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y, ModContent.NPCType()); + NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y, ModContent.NPCType()); + } } // Enrage based on large slimes @@ -188,7 +193,7 @@ public override void AI() bool phase2 = !purpleSlimeAlive || !redSlimeAlive; // Vanish phase - if (!purpleSlimeAlive && !redSlimeAlive) + if ((!purpleSlimeAlive && !redSlimeAlive) || calamityGlobalNPC.newAI[3] == 1f || NPC.ai[3] == 1f) { // Avoid cheap bullshit NPC.damage = 0; @@ -257,40 +262,53 @@ public override void AI() Main.dust[slimyDust2].velocity *= 2f; } - // Let the player know that the Slime God isn't dead fr - if (!DownedBossSystem.downedSlimeGod) + if (calamityGlobalNPC.newAI[3] != 1f) { - string key = "Mods.CalamityMod.Status.Boss.SlimeGodRun"; - Color messageColor = Color.Magenta; + // Let the player know that the Slime God isn't dead fr + if (!DownedBossSystem.downedSlimeGod) + { + string key = "Mods.CalamityMod.Status.Boss.SlimeGodRun"; + Color messageColor = Color.Magenta; - CalamityUtils.DisplayLocalizedText(key, messageColor); - } + CalamityUtils.DisplayLocalizedText(key, messageColor); + } - // Set Slime God to have interacted with all players - for (int i = Main.maxPlayers - 1; i >= 0; i--) - { - NPC.ApplyInteraction(i); + // Set Slime God to have interacted with all players + for (int i = Main.maxPlayers - 1; i >= 0; i--) + NPC.ApplyInteraction(i); + + NPC.active = false; + NPC.HitEffect(); + NPC.NPCLoot(); + NPC.netUpdate = true; } + else + { + for (int x = 0; x < Main.maxNPCs; x++) + { + if (Main.npc[x].type == ModContent.NPCType() || Main.npc[x].type == ModContent.NPCType() || + Main.npc[x].type == ModContent.NPCType() || Main.npc[x].type == ModContent.NPCType()) + { + Main.npc[x].active = false; + Main.npc[x].netUpdate = true; + } + } - NPC.active = false; - NPC.HitEffect(); - NPC.NPCLoot(); - NPC.netUpdate = true; + NPC.active = false; + NPC.HitEffect(); + NPC.netUpdate = true; + } } return; } // Despawn - if (!player.active || player.dead || Vector2.Distance(player.Center, NPC.Center) > (bossRush ? CalamityGlobalNPC.CatchUpDistance350Tiles : CalamityGlobalNPC.CatchUpDistance200Tiles) || calamityGlobalNPC.newAI[3] == 1f) + if (!player.active || player.dead || Vector2.Distance(player.Center, NPC.Center) > (bossRush ? CalamityGlobalNPC.CatchUpDistance350Tiles : CalamityGlobalNPC.CatchUpDistance200Tiles)) { - if (calamityGlobalNPC.newAI[3] != 1f) - { - NPC.TargetClosest(false); - player = Main.player[NPC.target]; - } - - if (!player.active || player.dead || Vector2.Distance(player.Center, NPC.Center) > (bossRush ? CalamityGlobalNPC.CatchUpDistance350Tiles : CalamityGlobalNPC.CatchUpDistance200Tiles) || calamityGlobalNPC.newAI[3] == 1f) + NPC.TargetClosest(false); + player = Main.player[NPC.target]; + if (!player.active || player.dead || Vector2.Distance(player.Center, NPC.Center) > (bossRush ? CalamityGlobalNPC.CatchUpDistance350Tiles : CalamityGlobalNPC.CatchUpDistance200Tiles)) { if (NPC.velocity.Y < -3f) NPC.velocity.Y = -3f; diff --git a/NPCs/SlimeGod/SplitCrimulanPaladin.cs b/NPCs/SlimeGod/SplitCrimulanPaladin.cs index 7ad8a1e363..a51706798a 100644 --- a/NPCs/SlimeGod/SplitCrimulanPaladin.cs +++ b/NPCs/SlimeGod/SplitCrimulanPaladin.cs @@ -736,8 +736,6 @@ public override void ModifyNPCLoot(NPCLoot npcLoot) npcLoot.Add(ItemID.Gel, 1, 32, 48); } - public override bool CheckActive() => NPC.ai[0] == 3f; - public override void HitEffect(NPC.HitInfo hit) { Color dustColor = Color.Crimson; diff --git a/NPCs/SlimeGod/SplitEbonianPaladin.cs b/NPCs/SlimeGod/SplitEbonianPaladin.cs index 8dddef1603..fad784a39e 100644 --- a/NPCs/SlimeGod/SplitEbonianPaladin.cs +++ b/NPCs/SlimeGod/SplitEbonianPaladin.cs @@ -780,8 +780,6 @@ public override void ModifyNPCLoot(NPCLoot npcLoot) npcLoot.Add(ItemID.Gel, 1, 32, 48); } - public override bool CheckActive() => NPC.ai[0] == 4f; - public override void HitEffect(NPC.HitInfo hit) { Color dustColor = Color.Lavender; diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronAI.cs index abf2444bac..68e01972b2 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronAI.cs @@ -125,9 +125,6 @@ void SpawnHands() } } - // Distance from target - float distance = Vector2.Distance(Main.player[npc.target].Center, npc.Center); - // Despawn if (npc.ai[1] != 3f) { From a2d091ae5e52a05ac6b4efe9d1fbaf8dede51da2 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Mon, 20 May 2024 00:39:59 -0400 Subject: [PATCH 019/401] New Chaos State cooldown end sound --- .../Custom/AbilitySounds/ChaosStateOver.ogg | Bin 22883 -> 23940 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Sounds/Custom/AbilitySounds/ChaosStateOver.ogg b/Sounds/Custom/AbilitySounds/ChaosStateOver.ogg index 8019d05fd430649c22f831c27a9009c5be855779..38d88f18ed2e026eb927d0c6936e214c00ad5f81 100644 GIT binary patch literal 23940 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%0A#d3YLUk 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 literal 22883 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

w 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 Date: Mon, 20 May 2024 15:40:58 +0700 Subject: [PATCH 020/401] bestiary debuff type icon resprites --- UI/DebuffSystem/ColdDebuffType.png | Bin 255 -> 375 bytes UI/DebuffSystem/ElectricityDebuffType.png | Bin 234 -> 286 bytes UI/DebuffSystem/HeatDebuffType.png | Bin 259 -> 367 bytes UI/DebuffSystem/SicknessDebuffType.png | Bin 262 -> 349 bytes UI/DebuffSystem/WaterDebuffType.png | Bin 247 -> 330 bytes 5 files changed, 0 insertions(+), 0 deletions(-) diff --git a/UI/DebuffSystem/ColdDebuffType.png b/UI/DebuffSystem/ColdDebuffType.png index eb0a88f11a4aef5fa48ab549419c5bc63996b16e..f64ac9f30b9ad41d72f684cba46dbdf46f07f298 100644 GIT binary patch literal 375 zcmV--0f_#IP)Px$F-b&0R7i>KlP^-kKp4e;g$hJx%J9c!&~-(0a0oJ_s*2vBaDYbS1QF>0Xfa#> zR25}F;1~or4iE_povEl{ibx*KW*RVE1j94=_PtH^mv49BUw>bv>c!P8YmD2?Qg*Do z$j`sGvTVY#in!$g;N({R(I1Xvb?gx8-$ih`yAMG3?HPb!JO!Y#vkgFRqh^qe+s)(b z2krGx5}8O^&RUw(jC_FxV1e-K9IAJ7qVJ{No;=w(W&qWrLjd+R9RPy$ zEdavz7Xa>G=3GOqaNu>#;$pddVi5Gvb?OE!%jgqNT2z<$OkMCegbk-8002ovPDHLkV1gNDq=*0j literal 255 zcmeAS@N?(olHy`uVBq!ia0vp^LO?9R!3-o1bjN}y#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvVv3w_=LEs*4+R6^Z)X@->sH>mWbWfe)0dQxBr2Xik@0>K#HRz$S?Rm1Tfrd z-Wv%N<1FxqEM{QfI}E~%$MaXD00m<_T^vI+g17cMaxoZkFmHAH{a;=`@I%1u$80=l z8Ef7w+%FjF?VhD@^|Jb-$6L>28QBXoYdz%NxJ)-JKO_IZ8QVj5c}_%&s~ifrY%j;r nF`>jkjX)S3j3^P6Px#*hxe|R7i=*Mis&>%BA!4);T60F?W#3AgP%mN^+vYw0(3NbtJyEI z*REaRic`*=nVh-b9r$+wyAUlJ@jDmv=9knRl~0WQOP`c`& zkg@+9%Ag3n$eQ}~&|-g#C1VZ&55v5IO~1$tuQ_~5S!VX<6qyNsL!orbnhF1u?Oc{M k6F-^5FlX;eGx2r9JK=vy7!SyAsQ>@~07*qoM6N<$f8vp!lvI6=10X`wFN)4xr&)mNB|5xGf|3I-VYnP=0Db|u8zu^Bs!0>w;UocRBv%n*= zn1O-sFbFdq&tH)O6b$xsaSYK2u00pc#h}39a`EHF|E9+?0w+}Mf7BxOXSK4;SCvIs z6SFcL8)mwsRc}y`n_T4UdLVM|^v#p*Stb3+aa!}gWMtr$B-(^ W{IKc!x4S^&89ZJ6T-G@yGywo(TvdMn diff --git a/UI/DebuffSystem/HeatDebuffType.png b/UI/DebuffSystem/HeatDebuffType.png index 8b25d715bb4dc37b19812f8b2e54523043c10ff5..d1c54b3e8d75325068f98ca9270e714ac47a823e 100644 GIT binary patch literal 367 zcmV-#0g(QQP)Px$DM>^@R7i=vlRZiUK@`V-8)Mibq)s7LR;ffG#71%siANCZyhcdx4MLg?Lc}VS zmFx-j2%AJ)i+MBdOmGD7+)6vtk!)1Zr_R|mIKgfbN)r$ z-^h|XV;^JgON>88sz+$aMmwLZ`*8-qHp`8n=W?g=o&67?`@@Ym1|$236#RUM{r`(HAH{8o{rb6gy zSPmm(B1?AiZ0^-u92@^ZJ;HGQLRm65pQMd(`kN9BjF5-YBmBzbAoIrLy*WetE!lvI6;{0X`wFJFFyrl{5Ul&G5s7;s0i}|9^h~WrDU?WC1Dmk|4j}|6sr%<<0B{ z6yhxKh%9Dc;5!V$jK}j=qyPm|JY5_^G=f{tI|?-@@Hk)Gmbvr)#HZbQE*El6*|aHc zEjxDR?z_*XX-rCaF_UMCOw_EMTs`%>N43-pNyEPuf}*Q_G%U|vHxHl!PC{xWt~$(69CQSTVMbH diff --git a/UI/DebuffSystem/SicknessDebuffType.png b/UI/DebuffSystem/SicknessDebuffType.png index db56ba844955181a82e20d6f327aeb8ffb6cb113..8c498f6d77d10490b457ff2fdf388a7d4f50f1c8 100644 GIT binary patch literal 349 zcmV-j0iyniP)Px$7fD1xR7i>Kl(A|8K@f&NMZHb~0YMP)6+}|S5YRUe!8gctHokz6Iu8&bkY2D( zVFC&%!lvI6d34x4LxK`F!|xFLRoD!6rSE21NlU1)%&Zi=R3`inAohFZe$c zFa-NofNbF`@Q5sCVBk9p!i>lBSEK+1<2_v*Lo|Z-p7Z8wP~c&?@bC0r|24rKiX3`# zc|Ul}Uij^lz01@>`Qu(LXNs0Tp2x82Oxn8x!kq~QkGhRq&nOwps8pKrPx$1W80eR7i={l(B2VKoo~RYnLpYN)YQL)FFtAo2a03R}oygsnGwXQ*jeS5Lfqr z7XJW|4rVThIJt;}jYD!^LXvav4*J{PyBG5Daqr;Y$Eew^QM27!=O6A3@F*L|WeNZ| z(Dhq`r1`rOrs58SH>*?u;Agc2;J9eSegirk3U}dJ=2E@G*VeBK@MJy%aML;n^qs2B6=m2I{a&efLn1iHMDfNWi5! zLUG@~1Yo}Y3k(Xk`D`+SIzngqk^-3FZOU8Ij3oLTZ2>qg8a*w9()Tc&2r^BZl8|mp cU(b7Z0fpB^*a1S7umAu607*qoM6N<$g1o?y@&Et; literal 247 zcmeAS@N?(olHy`uVBq!ia0vp^LO?9R!3-o1bjN}y#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;{0X`wFoVNQ_L!TOF|16yT`^2|@lQ;ea%KX^G@*GI9mjw9*{|5sGDQ{*s zpb%$)M`SSr1K(i~W;~w1A_XWI;pyTSq7htsu95420tZXL)-V6`vLL+`gtvWs{iPhb-TQy^R*aigE8dB*PoB{QIgt{S0?Z fztd@Z%sEZ`Rv$ZSYeq~W&<+MqS3j3^P6 Date: Mon, 20 May 2024 21:14:36 -0500 Subject: [PATCH 021/401] Fixed non-Rev WoF eyes not firing lasers. --- NPCs/VanillaNPCAIOverrides/Bosses/WallOfFleshAI.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/WallOfFleshAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/WallOfFleshAI.cs index 0a8ab9133b..b9facd07ba 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/WallOfFleshAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/WallOfFleshAI.cs @@ -1350,6 +1350,10 @@ public static bool VanillaWallofFleshEyeAI(NPC npc, Mod mod) if (Main.npc[Main.wofNPCIndex].life > 0) npc.life = Main.npc[Main.wofNPCIndex].life; + // Get a target + if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) + npc.target = Main.npc[Main.wofNPCIndex].target; + // Avoid cheap bullshit npc.damage = 0; From e0e633ba0f3a08ce3aa3e63d13391499b3fba109 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Mon, 20 May 2024 09:18:45 -0400 Subject: [PATCH 022/401] Chaos State cooldown end sound V2 --- .../Custom/AbilitySounds/ChaosStateOver.ogg | Bin 23940 -> 25141 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Sounds/Custom/AbilitySounds/ChaosStateOver.ogg b/Sounds/Custom/AbilitySounds/ChaosStateOver.ogg index 38d88f18ed2e026eb927d0c6936e214c00ad5f81..cef7b850098fe9cd9ea4091891ed77c3de5b378f 100644 GIT binary patch literal 25141 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

6a8&z62%Zsu*yd4;P0G%yY3xtw5%Kd7>HH_Y~f) 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 literal 23940 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%0A#d3YLUk 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 From 5f97ee4d88a151daaae03d3f855cf1caed5c2bbb Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Sat, 18 May 2024 14:00:41 -0400 Subject: [PATCH 023/401] DR calcs support Hellfire in case they need to for some reason --- NPCs/CalamityGlobalNPC.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NPCs/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index 0431d27c13..f337e08be9 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -3307,6 +3307,7 @@ void MultEditDR(ref float theDR, bool npcHasDebuff, int buffID) // Apply flat reductions first. All vanilla debuffs check their internal booleans. FlatEditDR(ref calcDR, npc.poisoned, BuffID.Poisoned); FlatEditDR(ref calcDR, npc.onFire, BuffID.OnFire); + FlatEditDR(ref calcDR, npc.onFire3, BuffID.OnFire3); FlatEditDR(ref calcDR, npc.venom, BuffID.Venom); FlatEditDR(ref calcDR, npc.onFrostBurn, BuffID.Frostburn); FlatEditDR(ref calcDR, npc.shadowFlame, BuffID.ShadowFlame); @@ -3325,6 +3326,7 @@ void MultEditDR(ref float theDR, bool npcHasDebuff, int buffID) // Apply multiplicative reductions second. All vanilla debuffs check their internal booleans. MultEditDR(ref calcDR, npc.poisoned, BuffID.Poisoned); MultEditDR(ref calcDR, npc.onFire, BuffID.OnFire); + MultEditDR(ref calcDR, npc.onFire3, BuffID.OnFire3); MultEditDR(ref calcDR, npc.venom, BuffID.Venom); MultEditDR(ref calcDR, npc.onFrostBurn, BuffID.Frostburn); MultEditDR(ref calcDR, npc.shadowFlame, BuffID.ShadowFlame); From 2be0ab55d0625d3a4774b376db49d2af04323cb5 Mon Sep 17 00:00:00 2001 From: SandKingg <47184464+SandKingg@users.noreply.github.com> Date: Mon, 20 May 2024 17:56:25 +0100 Subject: [PATCH 024/401] Removed duplicate Harvest Staff tooltip (#41) --- .../en-US/Mods.CalamityMod.Items.Weapons.Magic.hjson | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Magic.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Magic.hjson index 4f9a2d7f91..7c20016cf2 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Magic.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Magic.hjson @@ -392,11 +392,6 @@ HadalUrn: { ''' } -HarvestStaff: { - DisplayName: Harvest Staff - Tooltip: Casts flaming pumpkins -} - HeliumFlash: { DisplayName: Helium Flash Tooltip: From 466bd5f38ed8bfca74e9485a015ab55893bb9827 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Mon, 20 May 2024 17:23:27 -0400 Subject: [PATCH 025/401] 1 - Frog Leg and upgrades no longer stack. 2 - Amphibian Boots specifically (not any others) nerfed from +1.6 jump speed to +1.0. --- Balancing/BalancingConstants.cs | 6 ++++++ CalPlayer/CalamityPlayer.cs | 2 ++ Items/CalamityGlobalItem.cs | 24 ++++++++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/Balancing/BalancingConstants.cs b/Balancing/BalancingConstants.cs index 5087a7a6cf..4b931a4b1f 100644 --- a/Balancing/BalancingConstants.cs +++ b/Balancing/BalancingConstants.cs @@ -17,6 +17,12 @@ public static class BalancingConstants // This is a const because it replaces a hardcoded value in vanilla internal const float BalloonJumpSpeedBoost = 0.75f; + // Default jump speed boost provided by Frog Leg and tinker combinations in vanilla + internal const float VanillaFrogLegJumpSpeedBoost = 1.6f; + + // Altered jump speed boost provided by Amphibian Boots via global item UpdateAccessory + internal static readonly float AmphibianBootsJumpSpeedBoost = 1f; + // Altered movement stats provided by Shadow Armor via IL edit // This item is modified to not stack with Magiluminescence if on the ground. If in the air, it still functions. internal static readonly float ShadowArmorRunAccelerationMultiplier = 1.25f; // Vanilla and Magi = 1.75f diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 6106b15c9e..70989c1168 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -507,6 +507,7 @@ public partial class CalamityPlayer : ModPlayer public bool ascendantTrail = false; public bool eGauntlet = false; public int gloveLevel = 0; // Used to prevent glove stacking + public bool alreadyHasFrogLeg = false; // Used to prevent Frog Leg tinker stacking public bool eTalisman = false; public int statisTimer = 0; public bool nucleogenesis = false; @@ -1703,6 +1704,7 @@ public override void ResetEffects() ascendantTrail = false; eGauntlet = false; gloveLevel = 0; + alreadyHasFrogLeg = false; eTalisman = false; nucleogenesis = false; nuclearFuelRod = false; diff --git a/Items/CalamityGlobalItem.cs b/Items/CalamityGlobalItem.cs index 6b546a1061..10845a70b5 100644 --- a/Items/CalamityGlobalItem.cs +++ b/Items/CalamityGlobalItem.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using CalamityMod.Balancing; using CalamityMod.Buffs.StatBuffs; using CalamityMod.Buffs.StatDebuffs; using CalamityMod.CalPlayer; @@ -1237,6 +1238,29 @@ public override void UpdateAccessory(Item item, Player player, bool hideVisual) player.GetDamage() += 0.02f; } + // The Frog Leg line is prevented from stacking. + // Additionally, Amphibian boots are directly nerfed so they aren't the best in slot boots at all times. + switch (item.type) + { + default: + break; + case ItemID.AmphibianBoots: + if (modPlayer.alreadyHasFrogLeg) + player.jumpSpeedBoost -= BalancingConstants.VanillaFrogLegJumpSpeedBoost; + else + player.jumpSpeedBoost += BalancingConstants.AmphibianBootsJumpSpeedBoost - BalancingConstants.VanillaFrogLegJumpSpeedBoost; + modPlayer.alreadyHasFrogLeg = true; + break; + case ItemID.FrogLeg: + case ItemID.FrogFlipper: + case ItemID.FrogGear: + case ItemID.FrogWebbing: + if (modPlayer.alreadyHasFrogLeg) + player.jumpSpeedBoost -= BalancingConstants.VanillaFrogLegJumpSpeedBoost; + modPlayer.alreadyHasFrogLeg = true; + break; + } + // Feral Claws line melee speed adjustments and nonstacking // First removes all their melee speed so it can be given based on which you wear without stacking if (item.type == ItemID.FeralClaws) From 5df35a42cbc7e43332871be5bbe02e64b0b8a5b3 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Mon, 20 May 2024 20:37:00 -0400 Subject: [PATCH 026/401] Added new NPC targeting algorithm with numerous customizable options. Not used yet. --- Enums/NPCTargetType.cs | 9 + Utilities/NPCUtils.cs | 501 +++++++++++++++++++++++++++++++---------- 2 files changed, 393 insertions(+), 117 deletions(-) create mode 100644 Enums/NPCTargetType.cs diff --git a/Enums/NPCTargetType.cs b/Enums/NPCTargetType.cs new file mode 100644 index 0000000000..6fc9b0ac5c --- /dev/null +++ b/Enums/NPCTargetType.cs @@ -0,0 +1,9 @@ +namespace CalamityMod.Enums +{ + public enum NPCTargetType + { + Anyone = 0, + PreferSame = 1, + ForceSwitch = 2, + } +} diff --git a/Utilities/NPCUtils.cs b/Utilities/NPCUtils.cs index 08c4955552..5617cc237d 100644 --- a/Utilities/NPCUtils.cs +++ b/Utilities/NPCUtils.cs @@ -1,9 +1,8 @@ -using System.Linq; -using System.Reflection; +using System; +using System.Linq; using CalamityMod.Balancing; -using CalamityMod.Buffs.DamageOverTime; -using CalamityMod.Buffs.StatDebuffs; using CalamityMod.DataStructures; +using CalamityMod.Enums; using CalamityMod.Events; using CalamityMod.NPCs; using CalamityMod.NPCs.NormalNPCs; @@ -24,8 +23,85 @@ namespace CalamityMod { + #region Calamity Targeting Parameters Struct + public struct CalamityTargetingParameters + { + // Vanilla argument to TargetClosest. Defaults to true as it does in vanilla. + // If true, the NPC will turn to face the target. + public bool faceTarget = true; + + // Vanilla argument to TargetClosestUpgraded. That function is never used, but the flexibility is implemented here. + // Allows targeting distance calculations to be measured from a different position than the NPC's center, if desired. + public Vector2? targetingCenter = null; + + // Hard maximum range to search for targets. Players outside this physical Manhattan distance will always be ignored. + // + // Vanilla always uses infinity for this, leading to behavior like Queen Bee crossing the world to spawncamp you. + // Calamity defaults to a very high but not infinite value. + public float maxSearchRange = 9600f; // 600 tiles + + // Targeting preference enum. + // Anyone = Target the "closest" player, no other considerations. Vanilla behavior. + // PreferSame = Always pick the same player if they're within the search range, even if another player is closer or has more aggro. + // ForceSwitch = Try to pick any other player but the current player, if possible. Similar to an "aggro drop" in MMOs. + // + // ForceSwitch intentionally does nothing in single player, because there is nobody to switch to. + public NPCTargetType targetType = NPCTargetType.Anyone; + + // The ratio at which to consider aggro bonuses from player gear. + // 1f is vanilla. Set to 0f to ignore aggro bonuses entirely. + // Set to a negative value to make the NPC intentionally avoid tanks and preferentially go after other players. + public float aggroRatio = 1f; + + // Whether or not players must have line of sight to the NPC to be considered valid targets. + // This is always line of sight to the NPC itself, even if a different targeting center for range finding is specified. + public bool requireLineOfSight = false; + + // If true, the targeting algorithm counts missing health as a gigantic boost to aggro. + // This makes for a "merciless" or "bloodthirsty" NPC which is focused on killing the lowest health players. + public bool finishThemOff = false; + internal const float FinishThemOff_MaxAggroBoost = 4000f; + + // If true, this NPC ignores the Stardust armor set bonus "JoJo Tank Minion" (or "Algalon the Observer" according to the wiki). + // + // This is set to false by default, because that's vanilla behavior. + // As Stardust armor is postgame in vanilla, no vanilla bosses ignore the Stardust Guardian. + // It is highly recommended to set this to true for all bosses, or their aggro can be abusively manipulated. + public bool ignoreTankMinions = false; + + // If true, this NPC ignores players who have less than zero net aggro and are not actively using items. + // + // This is set to true by default, because it's (undocumented) vanilla behavior. + // Bosses will automatically attack stealthed players anyway -- you don't need to set this to false for that to occur. + public bool ignoreStealthedPlayers = true; + + // If true, this targeting change forces a net update. + // In vanilla, targeting updates cause net updates if direction changed or the target player changed, + // but NEVER if the NPC has collideX or collideY set to true. + // + // Generally this doesn't need to be set to true, as bosses will never have collideX or collideY set to true. + public bool forceNetUpdate = false; + + public CalamityTargetingParameters() + { + } + + // Quick defaults for recommended boss settings. + public CalamityTargetingParameters(bool isBoss) + { + ignoreTankMinions = isBoss; + } + + public static CalamityTargetingParameters BossDefaults => new(true); + } + #endregion + + public static partial class CalamityUtils { + public static T ModNPC(this NPC npc) where T : ModNPC => npc.ModNPC as T; + + #region NPC Counting ///

/// Efficiently counts the amount of existing enemies. May be used for multiple enemies. /// @@ -49,6 +125,22 @@ public static int CountNPCsBetter(params int[] typesToCheck) return count; } + public static bool AnyBossNPCS(bool checkForMechs = false) + { + foreach (NPC npc in Main.ActiveNPCs) + { + if (npc.IsABoss()) + { + // Added due to the new mech boss ore progression, return true if any mech is alive and checkForMechs is true, reduces mech boss projectile damage if true. + if (checkForMechs) + return npc.type == NPCID.TheDestroyer || npc.type == NPCID.SkeletronPrime || npc.type == NPCID.Spazmatism || npc.type == NPCID.Retinazer; + return true; + } + } + return FindFirstProjectile(ProjectileType()) != -1; + } + #endregion + /// /// Hides an NPC from the bestiary. This should be called in SetStaticDefaults. /// @@ -62,23 +154,7 @@ public static void HideFromBestiary(this ModNPC n) NPCID.Sets.NPCBestiaryDrawOffset.Add(n.Type, value); } - /// - /// Syncs position and velocity from a client to the server. This is to be used in contexts where these things are reliant on client-side information, such as . - /// - /// - public static void SyncMotionToServer(this NPC npc) - { - if (Main.netMode != NetmodeID.MultiplayerClient) - return; - - var netMessage = CalamityMod.Instance.GetPacket(); - netMessage.Write((byte)CalamityModMessageType.SyncNPCMotionDataToServer); - netMessage.Write(npc.whoAmI); - netMessage.WriteVector2(npc.Center); - netMessage.WriteVector2(npc.velocity); - netMessage.Send(); - } - + #region Stat Setting /// /// Allows you to set the lifeMax value of a NPC to different values based on the mode. Called instead of npc.lifeMax = X. /// @@ -123,7 +199,9 @@ public static void DR_NERD(this NPC npc, float normal, float? revengeance = null if (customDR.HasValue) npc.Calamity().customDR = true; } + #endregion + #region NPC Threat Classification // This function controls the behavior of Proximity Rage. // // TODO -- In multiplayer, with more than one player, all enemies are listed as statue spawned. @@ -171,79 +249,300 @@ public static bool IsABoss(this NPC npc) return npc.type == NPCType() || npc.type == NPCType() || npc.type == NPCType() || npc.type == NPCType(); } + #endregion - public static bool AnyBossNPCS(bool checkForMechs = false) - { - foreach (NPC npc in Main.ActiveNPCs) - { - if (npc.IsABoss()) - { - // Added due to the new mech boss ore progression, return true if any mech is alive and checkForMechs is true, reduces mech boss projectile damage if true. - if (checkForMechs) - return npc.type == NPCID.TheDestroyer || npc.type == NPCID.SkeletronPrime || npc.type == NPCID.Spazmatism || npc.type == NPCID.Retinazer; - return true; - } - } - return FindFirstProjectile(ProjectileType()) != -1; - } - + #region Net Synchronization /// - /// Syncs . This exists to sync the Destroyer's lasers so that the telegraphs and segment colors display properly. + /// Syncs . This exists specifically for AIs manipulated in a global context, as has no netUpdate related hooks. /// /// - public static void SyncDestroyerLaserColor(this NPC npc) + public static void SyncExtraAI(this NPC npc) { // Don't bother attempting to send packets in singleplayer. if (Main.netMode == NetmodeID.SinglePlayer) return; ModPacket packet = CalamityMod.Instance.GetPacket(); - packet.Write((byte)CalamityModMessageType.SyncDestroyerLaserColor); + packet.Write((byte)CalamityModMessageType.SyncCalamityNPCAIArray); packet.Write((byte)npc.whoAmI); - packet.Write(npc.Calamity().destroyerLaserColor); + + for (int i = 0; i < npc.Calamity().newAI.Length; i++) + packet.Write(npc.Calamity().newAI[i]); + packet.Send(); } /// - /// Syncs . This exists specifically for AIs manipulated in a global context, as has no netUpdate related hooks. + /// Syncs . This exists specifically for AIs manipulated in a global context, as has no netUpdate related hooks. /// /// - public static void SyncExtraAI(this NPC npc) + public static void SyncVanillaLocalAI(this NPC npc) { // Don't bother attempting to send packets in singleplayer. if (Main.netMode == NetmodeID.SinglePlayer) return; ModPacket packet = CalamityMod.Instance.GetPacket(); - packet.Write((byte)CalamityModMessageType.SyncCalamityNPCAIArray); + packet.Write((byte)CalamityModMessageType.SyncVanillaNPCLocalAIArray); packet.Write((byte)npc.whoAmI); - for (int i = 0; i < npc.Calamity().newAI.Length; i++) - packet.Write(npc.Calamity().newAI[i]); + for (int i = 0; i < NPC.maxAI; i++) + packet.Write(npc.localAI[i]); packet.Send(); } /// - /// Syncs . This exists specifically for AIs manipulated in a global context, as has no netUpdate related hooks. + /// Syncs position and velocity from a client to the server. This is to be used in contexts where these things are reliant on client-side information, such as . /// /// - public static void SyncVanillaLocalAI(this NPC npc) + public static void SyncMotionToServer(this NPC npc) + { + if (Main.netMode != NetmodeID.MultiplayerClient) + return; + + var netMessage = CalamityMod.Instance.GetPacket(); + netMessage.Write((byte)CalamityModMessageType.SyncNPCMotionDataToServer); + netMessage.Write(npc.whoAmI); + netMessage.WriteVector2(npc.Center); + netMessage.WriteVector2(npc.velocity); + netMessage.Send(); + } + + /// + /// Syncs . This exists to sync the Destroyer's lasers so that the telegraphs and segment colors display properly. + /// + /// + public static void SyncDestroyerLaserColor(this NPC npc) { // Don't bother attempting to send packets in singleplayer. if (Main.netMode == NetmodeID.SinglePlayer) return; ModPacket packet = CalamityMod.Instance.GetPacket(); - packet.Write((byte)CalamityModMessageType.SyncVanillaNPCLocalAIArray); + packet.Write((byte)CalamityModMessageType.SyncDestroyerLaserColor); packet.Write((byte)npc.whoAmI); + packet.Write(npc.Calamity().destroyerLaserColor); + packet.Send(); + } + #endregion - for (int i = 0; i < NPC.maxAI; i++) - packet.Write(npc.localAI[i]); + #region Smooth Movement + /// + /// Smoother movement for NPCs + /// + /// The NPC getting the movement change. + /// The distance where the NPC should stop moving once it's close enough to its destination. + /// How far the NPC is from its destination. + /// How quickly the NPC moves towards its destination. + /// Whether the NPC should use SimpleFlyMovement to make the movement more affected by acceleration. + public static void SmoothMovement(NPC npc, float movementDistanceGateValue, Vector2 distanceFromDestination, float baseVelocity, float acceleration, bool useSimpleFlyMovement) + { + // Inverse lerp returns the percentage of progress between A and B + float lerpValue = Utils.GetLerpValue(movementDistanceGateValue, 2400f, distanceFromDestination.Length(), true); - packet.Send(); + // Min velocity + float minVelocity = distanceFromDestination.Length(); + float minVelocityCap = baseVelocity; + if (minVelocity > minVelocityCap) + minVelocity = minVelocityCap; + + // Max velocity + Vector2 maxVelocity = distanceFromDestination / 24f; + float maxVelocityCap = minVelocityCap * 3f; + if (maxVelocity.Length() > maxVelocityCap) + maxVelocity = distanceFromDestination.SafeNormalize(Vector2.Zero) * maxVelocityCap; + + // Set the velocity + Vector2 desiredVelocity = Vector2.Lerp(distanceFromDestination.SafeNormalize(Vector2.Zero) * minVelocity, maxVelocity, lerpValue); + if (useSimpleFlyMovement) + npc.SimpleFlyMovement(desiredVelocity, acceleration); + else + npc.velocity = desiredVelocity; } + #endregion + #region Calamity Style Targeting + /// + /// Replacement and extension for vanilla's NPC.TargetClosest. Has very flexible behavior.
+ /// Like vanilla's function, this function does not return any value, but makes its changes in-place. + ///
+ /// Struct to specify all options. Refer to struct definition in NPCUtils for details. + /// The targeted player ID. + public static int CalamityTargeting(this NPC npc, CalamityTargetingParameters options) + { + float distance = 0f; + // float realDist = 0f; // Defined but not used by vanilla. Commented out here. + bool anyTargetAvailable = false; + int tankMinionProjectileID = -1; + + // The setup and initial loop is equivalent to vanilla NPC.TargetClosest, but optimized. + foreach (Player p in Main.ActivePlayers) + { + bool playerDead = p.dead || p.ghost; + if (playerDead) + continue; + + // ForceSwitch targeting. If the same player from last time is iterated over, just ignore them. + bool sameTargetAsLastTime = p.whoAmI == npc.oldTarget; + bool notSinglePlayer = Main.netMode != NetmodeID.SinglePlayer; + if (options.targetType == NPCTargetType.ForceSwitch && notSinglePlayer && sameTargetAsLastTime) + continue; + + // + // The below code is implemented in vanilla as a separate method. Here, it's inlined for efficiency. + // + + Vector2 pCenter = p.Center; + Vector2 targetCenter = options.targetingCenter ?? npc.Center; + float manhattanDist = Math.Abs(targetCenter.X - pCenter.X) + Math.Abs(targetCenter.Y - pCenter.Y); + + // Hard cutoff range specified in options. If the player is further, completely ignore them. + if (manhattanDist > options.maxSearchRange) + continue; + + // Line of sight requirement specified in options. Please don't use this without reducing the max search range. + if (options.requireLineOfSight && !Collision.CanHit(npc.Center, 1, 1, pCenter, 1, 1)) + continue; + + float aggroAdjustedDist = manhattanDist - options.aggroRatio * p.aggro; + + // Implementation of "Finish Them Off": Add enormous amounts of virtual aggro to low health players + if (options.finishThemOff) + { + float missingHPRatio = MathHelper.Clamp(1f - p.statLife / (float)p.statLifeMax2, 0f, 1f); + float bloodthirstAggro = MathHelper.Lerp(0f, CalamityTargetingParameters.FinishThemOff_MaxAggroBoost, missingHPRatio); + aggroAdjustedDist -= bloodthirstAggro; + } + + bool aggroDisabled = p.npcTypeNoAggro[npc.type]; + if (aggroDisabled && npc.direction != 0) + aggroAdjustedDist += 1000f; + + bool cancelTargeting = false; + + // PreferSame targeting. If the same player from last time is a valid target, even if not the "best" target, pick it anyway. + bool preferSameFound = options.targetType == NPCTargetType.PreferSame && sameTargetAsLastTime; + + // Standard targeting. If the adjusted distance is lower, or this is the first valid target, actually choose the new target. + bool standardTargetingRequirementsMet = !anyTargetAvailable || aggroAdjustedDist < distance; + + // If either targeting method succeeded, then this target is being engaged. + bool engageThisTarget = preferSameFound || standardTargetingRequirementsMet; + if (engageThisTarget) + { + anyTargetAvailable = true; + tankMinionProjectileID = -1; // Reset any Stardust Guardian aggro because a real player was found. + distance = aggroAdjustedDist; + npc.target = p.whoAmI; + + // If PreferSame targeting is active, and the same player was found, cancel further iteration. They are being chosen above all others. + if (preferSameFound) + cancelTargeting = true; + } + + // "Tank pet" accomodation, AKA the 1.4+ Stardust Guardian + // Basically, if the player would be targeted, give a chance to instead target their tank minion + // + // This behavior is not documented on the vanilla wiki. + if (p.tankPet >= 0 && !aggroDisabled && !options.ignoreTankMinions) + { + Projectile tankMinion = Main.projectile[p.tankPet]; + Vector2 tmCenter = tankMinion.Center; + float manhattanDistToTankMinion = Math.Abs(targetCenter.X - tmCenter.X) + Math.Abs(targetCenter.Y - tmCenter.Y); + + // The Stardust Guardian is considered to have a 200 aggro bonus by default. + // In Calamity this is scaled by the aggro ratio specified in options. + manhattanDistToTankMinion -= options.aggroRatio * 200f; + + // The Stardust Guardian only attracts the attention of NPCs within a very short distance + if (manhattanDistToTankMinion < distance && manhattanDistToTankMinion < 200f && Collision.CanHit(npc.Center, 1, 1, tmCenter, 1, 1)) + tankMinionProjectileID = p.tankPet; + } + + // If targeting has been short-circuited for any reason, cancel iteration over players. + if (cancelTargeting) + break; + } + + // If the NPC has been aggroed by a Stardust Guardian instead of an actual player, account for that + if (tankMinionProjectileID >= 0) + { + Projectile tankMinion = Main.projectile[tankMinionProjectileID]; + npc.targetRect = tankMinion.Hitbox; + + // Always set direction to a nonzero value. This NPC has been engaged in combat. + npc.direction = 1; + if (tankMinion.Center.X < npc.Center.X) + npc.direction = -1; + + npc.directionY = 1; + if (tankMinion.Center.Y < npc.Center.Y) + npc.directionY = -1; + } + + // Standard player aggro occurs here + else + { + bool shouldFaceTarget = options.faceTarget; + + // Sanitize targeted player index + if (npc.target < 0 || npc.target >= Main.maxPlayers) + npc.target = 0; + + Player targetPlayer = Main.player[npc.target]; + npc.targetRect = targetPlayer.Hitbox; + + // Do not switch facing to look at dead players. + if (targetPlayer.dead) + shouldFaceTarget = false; + + // If already engaged in combat, do not switch facing to look at players that ignore your aggro. + if (targetPlayer.npcTypeNoAggro[npc.type] && npc.direction != 0) + shouldFaceTarget = false; + + if (shouldFaceTarget) + { + bool oldTargetWasValid = npc.oldTarget >= 0 && npc.oldTarget < Main.maxPlayers; + + bool targetIsLowAggroNotUsingItem = targetPlayer.itemAnimation == 0 && targetPlayer.aggro < 0; + bool willIgnoreStealthedPlayers = !npc.boss && options.ignoreStealthedPlayers; + + // Regular NPCs (not bosses) will voluntarily ignore otherwise-valid player targets with less than zero aggro if they are not actively using an item. + // This ONLY WORKS if they already have another valid target, aka multiplayer. + // As such, having net less than zero aggro enables you to remain "stealthed" to regular enemies if you are not doing anything. + // This is undocumented vanilla behavior. + bool ignoreStealthedPlayer = willIgnoreStealthedPlayers && oldTargetWasValid && targetIsLowAggroNotUsingItem; + if (!ignoreStealthedPlayer) + { + // Always set direction to a nonzero value. This NPC has been engaged in combat. + npc.direction = 1; + if (targetPlayer.Center.X < npc.Center.X) + npc.direction = -1; + + npc.directionY = 1; + if (targetPlayer.Center.Y < npc.Center.Y) + npc.directionY = -1; + } + } + } + + // Confused enemies always run in the exact wrong direction, horizontally at least. + if (npc.confused) + npc.direction *= -1; + + // Apply net updates. + bool directionChange = npc.direction != npc.oldDirection || npc.directionY != npc.oldDirectionY; + bool targetChange = npc.target != npc.oldTarget; + bool shouldNetUpdate = (directionChange || targetChange) && !npc.collideX && !npc.collideY; + if (shouldNetUpdate || options.forceNetUpdate) + npc.netUpdate = true; + + return npc.target; + } + #endregion + + #region Minion Homing /// /// Detects nearby hostile NPCs from a given point /// @@ -329,39 +628,7 @@ public static NPC MinionHoming(this Vector2 origin, float maxDistanceToCheck, Pl } return ClosestNPCAt(origin, maxDistanceToCheck, ignoreTiles); } - - /// - /// Smoother movement for NPCs - /// - /// The NPC getting the movement change. - /// The distance where the NPC should stop moving once it's close enough to its destination. - /// How far the NPC is from its destination. - /// How quickly the NPC moves towards its destination. - /// Whether the NPC should use SimpleFlyMovement to make the movement more affected by acceleration. - public static void SmoothMovement(NPC npc, float movementDistanceGateValue, Vector2 distanceFromDestination, float baseVelocity, float acceleration, bool useSimpleFlyMovement) - { - // Inverse lerp returns the percentage of progress between A and B - float lerpValue = Utils.GetLerpValue(movementDistanceGateValue, 2400f, distanceFromDestination.Length(), true); - - // Min velocity - float minVelocity = distanceFromDestination.Length(); - float minVelocityCap = baseVelocity; - if (minVelocity > minVelocityCap) - minVelocity = minVelocityCap; - - // Max velocity - Vector2 maxVelocity = distanceFromDestination / 24f; - float maxVelocityCap = minVelocityCap * 3f; - if (maxVelocity.Length() > maxVelocityCap) - maxVelocity = distanceFromDestination.SafeNormalize(Vector2.Zero) * maxVelocityCap; - - // Set the velocity - Vector2 desiredVelocity = Vector2.Lerp(distanceFromDestination.SafeNormalize(Vector2.Zero) * minVelocity, maxVelocity, lerpValue); - if (useSimpleFlyMovement) - npc.SimpleFlyMovement(desiredVelocity, acceleration); - else - npc.velocity = desiredVelocity; - } + #endregion ///
/// Check if an NPC is organic @@ -382,24 +649,6 @@ public static bool Organic(this NPC target) return false; } - /// - /// Shortcut for the generic boss summon message. - /// - /// The whoAmI index of the summoned npc. - public static void BossAwakenMessage(int npcIndex) - { - // TODO -- this should use MiscUtils DisplayLocalizedText. - string typeName = Main.npc[npcIndex].TypeName; - if (Main.netMode == NetmodeID.SinglePlayer) - { - Main.NewText(Language.GetTextValue("Announcement.HasAwoken", typeName), new Color(175, 75, 255)); - } - else if (Main.netMode == NetmodeID.Server) - { - ChatHelper.BroadcastChatMessage(NetworkText.FromKey("Announcement.HasAwoken", new object[] { Main.npc[npcIndex].GetTypeNetName() }), new Color(175, 75, 255)); - } - } - public static void Inflict246DebuffsNPC(NPC target, int buff, float timeBase = 2f) { if (Main.rand.NextBool(4)) @@ -416,8 +665,6 @@ public static void Inflict246DebuffsNPC(NPC target, int buff, float timeBase = 2 } } - public static T ModNPC(this NPC npc) where T : ModNPC => npc.ModNPC as T; - public static NPCShop AddWithCustomValue(this NPCShop shop, int itemType, int customValue, params Condition[] conditions) { var item = new Item(itemType) @@ -432,6 +679,38 @@ public static NPCShop AddWithCustomValue(this NPCShop shop, int customValue, return shop.AddWithCustomValue(ItemType(), customValue, conditions); } + public static void DrawBackglow(this NPC npc, Color backglowColor, float backglowArea, SpriteEffects spriteEffects, Rectangle frame, Vector2 screenPos, Texture2D overrideTexture = null) + { + Texture2D texture = overrideTexture is null ? TextureAssets.Npc[npc.type].Value : overrideTexture; + Vector2 drawPosition = npc.Center - screenPos; + Vector2 origin = frame.Size() * 0.5f; + Color backAfterimageColor = backglowColor * npc.Opacity; + for (int i = 0; i < 10; i++) + { + Vector2 drawOffset = (MathHelper.TwoPi * i / 10f).ToRotationVector2() * backglowArea; + Main.spriteBatch.Draw(texture, drawPosition + drawOffset, frame, backAfterimageColor, npc.rotation, origin, npc.scale, spriteEffects, 0f); + } + } + + #region Boss Spawning + /// + /// Shortcut for the generic boss summon message. + /// + /// The whoAmI index of the summoned npc. + public static void BossAwakenMessage(int npcIndex) + { + // TODO -- this should use MiscUtils DisplayLocalizedText. + string typeName = Main.npc[npcIndex].TypeName; + if (Main.netMode == NetmodeID.SinglePlayer) + { + Main.NewText(Language.GetTextValue("Announcement.HasAwoken", typeName), new Color(175, 75, 255)); + } + else if (Main.netMode == NetmodeID.Server) + { + ChatHelper.BroadcastChatMessage(NetworkText.FromKey("Announcement.HasAwoken", new object[] { Main.npc[npcIndex].GetTypeNetName() }), new Color(175, 75, 255)); + } + } + /// /// Summons a boss near a particular area depending on a specific spawn context. /// @@ -465,19 +744,6 @@ public static NPC SpawnBossBetter(Vector2 relativeSpawnPosition, int bossType, B return null; } - public static void DrawBackglow(this NPC npc, Color backglowColor, float backglowArea, SpriteEffects spriteEffects, Rectangle frame, Vector2 screenPos, Texture2D overrideTexture = null) - { - Texture2D texture = overrideTexture is null ? TextureAssets.Npc[npc.type].Value : overrideTexture; - Vector2 drawPosition = npc.Center - screenPos; - Vector2 origin = frame.Size() * 0.5f; - Color backAfterimageColor = backglowColor * npc.Opacity; - for (int i = 0; i < 10; i++) - { - Vector2 drawOffset = (MathHelper.TwoPi * i / 10f).ToRotationVector2() * backglowArea; - Main.spriteBatch.Draw(texture, drawPosition + drawOffset, frame, backAfterimageColor, npc.rotation, origin, npc.scale, spriteEffects, 0f); - } - } - /// /// Spawns Old Duke on a player. Only works server side, and only works if the player owns a fishing bobber.
/// Old Duke will spawn above the fishing bobber if one is found. @@ -508,5 +774,6 @@ internal static void SpawnOldDuke(int playerIndex) int oldDuke = NPC.NewNPC(NPC.GetBossSpawnSource(playerIndex), (int)projectile.Center.X, (int)projectile.Center.Y + 100, NPCType()); BossAwakenMessage(oldDuke); } + #endregion } } From 59f226739d56685d3e72fc92ff2cda85d5afadc8 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Tue, 21 May 2024 03:58:57 -0500 Subject: [PATCH 027/401] 1 - Ruby Jewel projectile spread is larger and 1 less projectile is fired in non-Master. 2 - Sapphire Jewel stays above King Slime now and teleports with him. --- NPCs/NormalNPCs/KingSlimeJewel.cs | 4 +-- NPCs/NormalNPCs/KingSlimeJewel2.cs | 33 ++++++++++--------- .../Bosses/KingSlimeAI.cs | 32 ++++++++++++++++++ 3 files changed, 51 insertions(+), 18 deletions(-) diff --git a/NPCs/NormalNPCs/KingSlimeJewel.cs b/NPCs/NormalNPCs/KingSlimeJewel.cs index a6edbdf1f8..086a89025d 100644 --- a/NPCs/NormalNPCs/KingSlimeJewel.cs +++ b/NPCs/NormalNPCs/KingSlimeJewel.cs @@ -152,8 +152,8 @@ public override void AI() int damage = NPC.GetProjectileDamage(type); if (CalamityWorld.death || BossRushEvent.BossRushActive) { - int numProj = 5; - float rotation = MathHelper.ToRadians(12); + int numProj = Main.masterMode ? 5 : 4; + float rotation = MathHelper.ToRadians(18); for (int i = 0; i < numProj; i++) { Vector2 perturbedSpeed = projVector.RotatedBy(MathHelper.Lerp(-rotation, rotation, i / (float)(numProj - 1))); diff --git a/NPCs/NormalNPCs/KingSlimeJewel2.cs b/NPCs/NormalNPCs/KingSlimeJewel2.cs index d18df61e1d..b2acf064b6 100644 --- a/NPCs/NormalNPCs/KingSlimeJewel2.cs +++ b/NPCs/NormalNPCs/KingSlimeJewel2.cs @@ -71,7 +71,20 @@ public override void AI() float velocity = 5f; float acceleration = 0.1f; - if (NPC.position.Y > Main.player[NPC.target].position.Y - 300f) + int distanceFromKingSlime = 1; + Vector2 kingSlimeCenter = NPC.Center; + for (int i = 0; i < Main.maxNPCs; i++) + { + if (Main.npc[i].active && Main.npc[i].type == NPCID.KingSlime) + { + distanceFromKingSlime = (int)NPC.Distance(Main.npc[i].Center); + kingSlimeCenter = Main.npc[i].Center; + break; + } + } + + Vector2 movementTarget = kingSlimeCenter == NPC.Center ? Main.player[NPC.target].Center : kingSlimeCenter; + if (NPC.position.Y > movementTarget.Y - 200f) { if (NPC.velocity.Y > 0f) NPC.velocity.Y *= 0.98f; @@ -81,7 +94,7 @@ public override void AI() if (NPC.velocity.Y > velocity) NPC.velocity.Y = velocity; } - else if (NPC.position.Y < Main.player[NPC.target].position.Y - 400f) + else if (NPC.position.Y < movementTarget.Y - 250f) { if (NPC.velocity.Y < 0f) NPC.velocity.Y *= 0.98f; @@ -92,7 +105,7 @@ public override void AI() NPC.velocity.Y = -velocity; } - if (NPC.Center.X > Main.player[NPC.target].Center.X + 300f) + if (NPC.Center.X > movementTarget.X + 100f) { if (NPC.velocity.X > 0f) NPC.velocity.X *= 0.98f; @@ -102,7 +115,7 @@ public override void AI() if (NPC.velocity.X > 8f) NPC.velocity.X = 8f; } - if (NPC.Center.X < Main.player[NPC.target].Center.X - 300f) + if (NPC.Center.X < movementTarget.X - 100f) { if (NPC.velocity.X < 0f) NPC.velocity.X *= 0.98f; @@ -121,18 +134,6 @@ public override void AI() SoundEngine.PlaySound(SoundID.Item8, NPC.Center); - int distanceFromKingSlime = 1; - Vector2 kingSlimeCenter = NPC.Center; - for (int i = 0; i < Main.maxNPCs; i++) - { - if (Main.npc[i].active && Main.npc[i].type == NPCID.KingSlime) - { - distanceFromKingSlime = (int)NPC.Distance(Main.npc[i].Center); - kingSlimeCenter = Main.npc[i].Center; - break; - } - } - for (int dusty = 0; dusty < 10; dusty++) { Vector2 dustVel = (kingSlimeCenter - NPC.Center).SafeNormalize(Vector2.UnitY) * Main.rand.NextFloat(2f, 4f); diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs index d2f68c28c4..3b8db5b32a 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs @@ -276,6 +276,38 @@ public static bool BuffedKingSlimeAI(NPC npc, Mod mod) if (masterMode) teleportRate *= 2f; + if (npc.ai[0] == 0f) + { + // Move Blue Crystal + if (blueCrystalAlive) + { + for (int i = 0; i < Main.maxNPCs; i++) + { + NPC blueCrystal = Main.npc[i]; + if (blueCrystal.active && blueCrystal.type == ModContent.NPCType()) + { + blueCrystal.position.X = npc.position.X; + blueCrystal.position.Y = npc.position.Y - 200f; + + for (int dusty = 0; dusty < 10; dusty++) + { + Vector2 dustVel = Main.rand.NextVector2CircularEdge(5f, 5f); + int sapphire = Dust.NewDust(blueCrystal.Center, blueCrystal.width, blueCrystal.height, DustID.GemSapphire, 0f, 0f, 100, default, 2f); + Main.dust[sapphire].velocity = dustVel * Main.rand.NextFloat(1f, 2f); + Main.dust[sapphire].noGravity = true; + if (Main.rand.NextBool()) + { + Main.dust[sapphire].scale = 0.5f; + Main.dust[sapphire].fadeIn = 1f + Main.rand.Next(10) * 0.1f; + } + } + + break; + } + } + } + } + npc.ai[0] += teleportRate; teleportScale = MathHelper.Clamp(npc.ai[0] / 30f, 0f, 1f); teleportScale = 0.5f + teleportScale * 0.5f; From b2bf8b3f9742a3df3d0751939d8e47872e250335 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Tue, 21 May 2024 04:53:49 -0500 Subject: [PATCH 028/401] Master Rev+ King Slime spawns Emerald Jewel at 70%, Ruby Jewel at 50%, and Sapphire Jewel at 30%. --- .../Bosses/KingSlimeAI.cs | 124 +++++++++++++----- 1 file changed, 90 insertions(+), 34 deletions(-) diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs index 3b8db5b32a..c0555e7cae 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs @@ -44,21 +44,33 @@ public static bool BuffedKingSlimeAI(NPC npc, Mod mod) // Higher velocity jumps phase bool phase2 = lifeRatio < 0.75f; - // Spawn Crystal phase + // Spawn Emerald Crystal phase + bool spawnGreenCrystal = lifeRatio < 0.7f; + + // Spawn Ruby Crystal phase bool phase3 = lifeRatio < 0.5f; + // Spawn Sapphire Crystal phase + bool spawnBlueCrystal = lifeRatio < 0.3f; + // Check if the crystals are alive bool crystalAlive = true; bool blueCrystalAlive = false; bool greenCrystalAlive = true; - if (phase3) + + if (spawnGreenCrystal) { + if (masterMode) + greenCrystalAlive = NPC.AnyNPCs(ModContent.NPCType()); + } + + if (phase3) crystalAlive = NPC.AnyNPCs(ModContent.NPCType()); + + if (spawnBlueCrystal) + { if (masterMode) - { blueCrystalAlive = NPC.AnyNPCs(ModContent.NPCType()); - greenCrystalAlive = NPC.AnyNPCs(ModContent.NPCType()); - } } // Sapphire Crystal buffs @@ -73,27 +85,63 @@ public static bool BuffedKingSlimeAI(NPC npc, Mod mod) // Dust color when the blue crystal is alive Color dustColor = Color.Lerp(new Color(0, 0, 150, npc.alpha), new Color(125, 125, 255, npc.alpha), (float)Math.Sin(Main.GlobalTimeWrappedHourly) / 2f + 0.5f); - // Spawn crystal in phase 2 - if (phase3 && npc.Calamity().newAI[0] == 0f) + // Master Mode Crystal spawning + if (masterMode) { - npc.Calamity().newAI[0] = 1f; - npc.SyncExtraAI(); - Vector2 vector = npc.Center + new Vector2(-40f, -(float)npc.height / 2) * npc.scale; - int totalDustPerCrystalSpawn = 20; - for (int i = 0; i < totalDustPerCrystalSpawn; i++) + if (spawnGreenCrystal && npc.Calamity().newAI[0] == 0f) { - int rubyDust = Dust.NewDust(vector, npc.width / 2, npc.height / 2, DustID.GemRuby, 0f, 0f, 100, default, 2f); - Main.dust[rubyDust].velocity *= 2f; - Main.dust[rubyDust].noGravity = true; - if (Main.rand.NextBool()) + npc.Calamity().newAI[0] = 1f; + npc.SyncExtraAI(); + Vector2 vector = npc.Center + new Vector2(-40f, -(float)npc.height / 2) * npc.scale; + int totalDustPerCrystalSpawn = 20; + for (int i = 0; i < totalDustPerCrystalSpawn; i++) { - Main.dust[rubyDust].scale = 0.5f; - Main.dust[rubyDust].fadeIn = 1f + Main.rand.Next(10) * 0.1f; + int emeraldDust = Dust.NewDust(vector, npc.width / 2, npc.height / 2, DustID.GemEmerald, 0f, 0f, 100, default, 2f); + Main.dust[emeraldDust].velocity *= 2f; + Main.dust[emeraldDust].noGravity = true; + if (Main.rand.NextBool()) + { + Main.dust[emeraldDust].scale = 0.5f; + Main.dust[emeraldDust].fadeIn = 1f + Main.rand.Next(10) * 0.1f; + } } + + SoundEngine.PlaySound(SoundID.Item38, vector); + + if (Main.netMode != NetmodeID.MultiplayerClient) + NPC.NewNPC(npc.GetSource_FromAI(), (int)vector.X, (int)vector.Y, ModContent.NPCType()); } - if (masterMode) + if (phase3 && npc.Calamity().newAI[0] == 1f) { + npc.Calamity().newAI[0] = 2f; + npc.SyncExtraAI(); + Vector2 vector = npc.Center + new Vector2(-40f, -(float)npc.height / 2) * npc.scale; + int totalDustPerCrystalSpawn = 20; + for (int i = 0; i < totalDustPerCrystalSpawn; i++) + { + int rubyDust = Dust.NewDust(vector, npc.width / 2, npc.height / 2, DustID.GemRuby, 0f, 0f, 100, default, 2f); + Main.dust[rubyDust].velocity *= 2f; + Main.dust[rubyDust].noGravity = true; + if (Main.rand.NextBool()) + { + Main.dust[rubyDust].scale = 0.5f; + Main.dust[rubyDust].fadeIn = 1f + Main.rand.Next(10) * 0.1f; + } + } + + SoundEngine.PlaySound(SoundID.Item38, vector); + + if (Main.netMode != NetmodeID.MultiplayerClient) + NPC.NewNPC(npc.GetSource_FromAI(), (int)vector.X, (int)vector.Y, ModContent.NPCType()); + } + + if (spawnBlueCrystal && npc.Calamity().newAI[0] == 2f) + { + npc.Calamity().newAI[0] = 3f; + npc.SyncExtraAI(); + Vector2 vector = npc.Center + new Vector2(-40f, -(float)npc.height / 2) * npc.scale; + int totalDustPerCrystalSpawn = 20; for (int i = 0; i < totalDustPerCrystalSpawn; i++) { int sapphireDust = Dust.NewDust(vector, npc.width / 2, npc.height / 2, DustID.GemSapphire, 0f, 0f, 100, default, 2f); @@ -106,29 +154,37 @@ public static bool BuffedKingSlimeAI(NPC npc, Mod mod) } } + SoundEngine.PlaySound(SoundID.Item38, vector); + + if (Main.netMode != NetmodeID.MultiplayerClient) + NPC.NewNPC(npc.GetSource_FromAI(), (int)vector.X, (int)vector.Y, ModContent.NPCType()); + } + } + else + { + // Spawn crystal in phase 2 + if (phase3 && npc.Calamity().newAI[0] == 0f) + { + npc.Calamity().newAI[0] = 1f; + npc.SyncExtraAI(); + Vector2 vector = npc.Center + new Vector2(-40f, -(float)npc.height / 2) * npc.scale; + int totalDustPerCrystalSpawn = 20; for (int i = 0; i < totalDustPerCrystalSpawn; i++) { - int emeraldDust = Dust.NewDust(vector, npc.width / 2, npc.height / 2, DustID.GemEmerald, 0f, 0f, 100, default, 2f); - Main.dust[emeraldDust].velocity *= 2f; - Main.dust[emeraldDust].noGravity = true; + int rubyDust = Dust.NewDust(vector, npc.width / 2, npc.height / 2, DustID.GemRuby, 0f, 0f, 100, default, 2f); + Main.dust[rubyDust].velocity *= 2f; + Main.dust[rubyDust].noGravity = true; if (Main.rand.NextBool()) { - Main.dust[emeraldDust].scale = 0.5f; - Main.dust[emeraldDust].fadeIn = 1f + Main.rand.Next(10) * 0.1f; + Main.dust[rubyDust].scale = 0.5f; + Main.dust[rubyDust].fadeIn = 1f + Main.rand.Next(10) * 0.1f; } } - } - SoundEngine.PlaySound(SoundID.Item38, vector); + SoundEngine.PlaySound(SoundID.Item38, vector); - if (Main.netMode != NetmodeID.MultiplayerClient) - { - NPC.NewNPC(npc.GetSource_FromAI(), (int)vector.X, (int)vector.Y, ModContent.NPCType()); - if (masterMode) - { - NPC.NewNPC(npc.GetSource_FromAI(), (int)vector.X, (int)vector.Y, ModContent.NPCType()); - NPC.NewNPC(npc.GetSource_FromAI(), (int)vector.X, (int)vector.Y, ModContent.NPCType()); - } + if (Main.netMode != NetmodeID.MultiplayerClient) + NPC.NewNPC(npc.GetSource_FromAI(), (int)vector.X, (int)vector.Y, ModContent.NPCType()); } } From 86aa00d7be453e8f5fac85952a9babb9d8412735 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Tue, 21 May 2024 05:08:19 -0500 Subject: [PATCH 029/401] Fixed Duke's map icon vanish values in Master Mode. --- NPCs/CalamityGlobalNPC.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/NPCs/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index f337e08be9..cccd363c25 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -3353,7 +3353,9 @@ public override void BossHeadSlot(NPC npc, ref int index) { if (npc.type == NPCID.DukeFishron && (CalamityWorld.death || BossRushEvent.BossRushActive)) { - if (npc.life / (float)npc.lifeMax < 0.4f) + float lifeRatio = npc.life / (float)npc.lifeMax; + float mapIconVanishValue = Main.masterMode ? 0.3f : 0.4f; + if (lifeRatio < mapIconVanishValue || (lifeRatio > 0.9f && Main.masterMode)) index = -1; } } From 41e3520bb5965bb86ec99d7cd7d8c48162fe36b1 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Tue, 21 May 2024 05:21:12 -0500 Subject: [PATCH 030/401] Decreased King Slime Jewel HP values. --- NPCs/NormalNPCs/KingSlimeJewel.cs | 2 +- NPCs/NormalNPCs/KingSlimeJewel2.cs | 2 +- NPCs/NormalNPCs/KingSlimeJewel3.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NPCs/NormalNPCs/KingSlimeJewel.cs b/NPCs/NormalNPCs/KingSlimeJewel.cs index 086a89025d..c9eb84f9d6 100644 --- a/NPCs/NormalNPCs/KingSlimeJewel.cs +++ b/NPCs/NormalNPCs/KingSlimeJewel.cs @@ -33,7 +33,7 @@ public override void SetDefaults() NPC.defense = 10; NPC.DR_NERD(0.1f); - NPC.lifeMax = 140; + NPC.lifeMax = 120; double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); diff --git a/NPCs/NormalNPCs/KingSlimeJewel2.cs b/NPCs/NormalNPCs/KingSlimeJewel2.cs index b2acf064b6..254ef1471e 100644 --- a/NPCs/NormalNPCs/KingSlimeJewel2.cs +++ b/NPCs/NormalNPCs/KingSlimeJewel2.cs @@ -34,7 +34,7 @@ public override void SetDefaults() NPC.defense = 5; NPC.DR_NERD(0.05f); - NPC.lifeMax = 140; + NPC.lifeMax = 120; double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); diff --git a/NPCs/NormalNPCs/KingSlimeJewel3.cs b/NPCs/NormalNPCs/KingSlimeJewel3.cs index 91668e6b70..531da13e74 100644 --- a/NPCs/NormalNPCs/KingSlimeJewel3.cs +++ b/NPCs/NormalNPCs/KingSlimeJewel3.cs @@ -35,7 +35,7 @@ public override void SetDefaults() NPC.defense = 15; NPC.DR_NERD(0.15f); - NPC.lifeMax = 280; + NPC.lifeMax = 240; double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); From 69839989f74d6fd217952ce692134121a71520e3 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Tue, 21 May 2024 05:53:36 -0500 Subject: [PATCH 031/401] Adjusted Desert Scourge and Nuisance movements. --- NPCs/DesertScourge/DesertNuisanceHead.cs | 12 ++++++++---- NPCs/DesertScourge/DesertNuisanceHeadYoung.cs | 8 ++++---- NPCs/DesertScourge/DesertScourgeHead.cs | 8 ++++++++ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/NPCs/DesertScourge/DesertNuisanceHead.cs b/NPCs/DesertScourge/DesertNuisanceHead.cs index 453e4e5484..e6de898103 100644 --- a/NPCs/DesertScourge/DesertNuisanceHead.cs +++ b/NPCs/DesertScourge/DesertNuisanceHead.cs @@ -138,12 +138,12 @@ public override void AI() // Percent life remaining. float lifeRatio = NPC.life / (float)NPC.lifeMax; - float speed = death ? 0.16f : 0.14f; - float turnSpeed = death ? 0.24f : 0.2f; + float speed = death ? 0.18f : 0.16f; + float turnSpeed = death ? 0.26f : 0.22f; speed += speed * 0.4f * (1f - lifeRatio); turnSpeed += turnSpeed * 0.4f * (1f - lifeRatio); - speed += 0.14f * enrageScale; - turnSpeed += 0.2f * enrageScale; + speed += 0.16f * enrageScale; + turnSpeed += 0.22f * enrageScale; if (Main.getGoodWorld) { @@ -318,7 +318,11 @@ public override void AI() if (!shouldFly) { NPC.TargetClosest(); + NPC.velocity.Y += 0.15f; + if (NPC.velocity.Y > 0f && Math.Abs(NPC.Center.Y - Main.player[NPC.target].Center.Y) > 180f) + NPC.velocity.Y += 0.05f; + if (NPC.velocity.Y > maxChaseSpeed) NPC.velocity.Y = maxChaseSpeed; diff --git a/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs b/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs index 9380abd265..fe5a618906 100644 --- a/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs +++ b/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs @@ -134,12 +134,12 @@ public override void AI() // Percent life remaining. float lifeRatio = NPC.life / (float)NPC.lifeMax; - float speed = death ? 0.18f : 0.16f; - float turnSpeed = death ? 0.26f : 0.22f; + float speed = death ? 0.16f : 0.14f; + float turnSpeed = death ? 0.24f : 0.2f; speed += speed * 0.4f * (1f - lifeRatio); turnSpeed += turnSpeed * 0.4f * (1f - lifeRatio); - speed += 0.16f * enrageScale; - turnSpeed += 0.22f * enrageScale; + speed += 0.14f * enrageScale; + turnSpeed += 0.2f * enrageScale; if (Main.getGoodWorld) { diff --git a/NPCs/DesertScourge/DesertScourgeHead.cs b/NPCs/DesertScourge/DesertScourgeHead.cs index 5f93dd98ec..8e5a000e83 100644 --- a/NPCs/DesertScourge/DesertScourgeHead.cs +++ b/NPCs/DesertScourge/DesertScourgeHead.cs @@ -670,7 +670,15 @@ public override void AI() else if (!shouldFly) { NPC.TargetClosest(); + NPC.velocity.Y += 0.15f; + if (NPC.Center.Y - player.Center.Y < -180f) + { + NPC.velocity.Y += 0.05f; + if (NPC.velocity.Y > 0f) + NPC.velocity.Y += 0.05f; + } + if (NPC.velocity.Y > maxChaseSpeed) NPC.velocity.Y = maxChaseSpeed; From 48f05a31779028c4451de44785f16cce8cdebca8 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Tue, 21 May 2024 07:47:25 -0500 Subject: [PATCH 032/401] Desert Scourge targeting update. --- NPCs/DesertScourge/DesertScourgeHead.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/NPCs/DesertScourge/DesertScourgeHead.cs b/NPCs/DesertScourge/DesertScourgeHead.cs index 8e5a000e83..405b9dbe4b 100644 --- a/NPCs/DesertScourge/DesertScourgeHead.cs +++ b/NPCs/DesertScourge/DesertScourgeHead.cs @@ -183,10 +183,6 @@ public override void AI() if (NPC.target < 0 || NPC.target == Main.maxPlayers || Main.player[NPC.target].dead || !Main.player[NPC.target].active) NPC.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[NPC.target].Center, NPC.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - NPC.TargetClosest(); - Player player = Main.player[NPC.target]; // Enrage @@ -669,8 +665,6 @@ public override void AI() } else if (!shouldFly) { - NPC.TargetClosest(); - NPC.velocity.Y += 0.15f; if (NPC.Center.Y - player.Center.Y < -180f) { From c5e9ed7ba83681da52146babf1fae2d770025067 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Tue, 21 May 2024 07:49:22 -0500 Subject: [PATCH 033/401] Nuisance targeting updates. --- NPCs/DesertScourge/DesertNuisanceHead.cs | 2 -- NPCs/DesertScourge/DesertNuisanceHeadYoung.cs | 1 - 2 files changed, 3 deletions(-) diff --git a/NPCs/DesertScourge/DesertNuisanceHead.cs b/NPCs/DesertScourge/DesertNuisanceHead.cs index e6de898103..c9ce5c9e75 100644 --- a/NPCs/DesertScourge/DesertNuisanceHead.cs +++ b/NPCs/DesertScourge/DesertNuisanceHead.cs @@ -317,8 +317,6 @@ public override void AI() if (!shouldFly) { - NPC.TargetClosest(); - NPC.velocity.Y += 0.15f; if (NPC.velocity.Y > 0f && Math.Abs(NPC.Center.Y - Main.player[NPC.target].Center.Y) > 180f) NPC.velocity.Y += 0.05f; diff --git a/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs b/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs index fe5a618906..c428a92aa0 100644 --- a/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs +++ b/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs @@ -361,7 +361,6 @@ public override void AI() if (!shouldFly) { - NPC.TargetClosest(); NPC.velocity.Y += 0.15f; if (NPC.velocity.Y > maxChaseSpeed) NPC.velocity.Y = maxChaseSpeed; From 561d325fce1866b5babfe87a195cd655f50ae163 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Tue, 21 May 2024 18:57:59 -0500 Subject: [PATCH 034/401] Fixed Brimstone Elemental's Brimstone Ray split shots dealing full Ray damage. --- DataStructures/NPCStats.cs | 2 +- Projectiles/Boss/BrimstoneRay.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DataStructures/NPCStats.cs b/DataStructures/NPCStats.cs index 4c0a22518d..70bc44c14e 100644 --- a/DataStructures/NPCStats.cs +++ b/DataStructures/NPCStats.cs @@ -656,7 +656,7 @@ internal static void LoadEnemyStats() { new Tuple(ModContent.NPCType(), ModContent.ProjectileType()), new int[] { 80, 140, 160, 180, 270 } }, { new Tuple(ModContent.NPCType(), ModContent.ProjectileType()), new int[] { 70, 112, 128, 144, 216 } }, { new Tuple(ModContent.NPCType(), ModContent.ProjectileType()), new int[] { 80, 140, 160, 180, 270 } }, - { new Tuple(ModContent.NPCType(), ModContent.ProjectileType()), new int[] { 120, 200, 240, 280, 420 } }, + { new Tuple(ModContent.NPCType(), ModContent.ProjectileType()), new int[] { 120, 200, 240, 280, 420 } }, // Split shots: 72, 120, 144, 168, 252 { new Tuple(ModContent.NPCType(), ModContent.ProjectileType()), new int[] { 80, 140, 160, 180, 270 } }, { new Tuple(ModContent.NPCType(), ModContent.ProjectileType()), new int[] { 70, 112, 128, 144, 216 } }, diff --git a/Projectiles/Boss/BrimstoneRay.cs b/Projectiles/Boss/BrimstoneRay.cs index 4630d227b5..7e18a2f859 100644 --- a/Projectiles/Boss/BrimstoneRay.cs +++ b/Projectiles/Boss/BrimstoneRay.cs @@ -124,7 +124,7 @@ public override void AI() Vector2 fireFrom = new Vector2(Main.npc[(int)Projectile.ai[1]].Center.X + (Main.npc[(int)Projectile.ai[1]].spriteDirection > 0 ? 34f : -34f), Main.npc[(int)Projectile.ai[1]].Center.Y - 74f) + velocity * distanceBetweenProjectiles; int projectileAmt = (int)(Projectile.localAI[1] / distanceBetweenProjectiles); int type = ModContent.ProjectileType(); - int damage = Projectile.GetProjectileDamage(ModContent.NPCType()); + int damage = (int)Math.Round(Projectile.damage * 0.6); float projectileVelocityToPass = 12f; for (int i = 0; i < projectileAmt; i++) From 3161f7961df797176708190825ec3d57177010e2 Mon Sep 17 00:00:00 2001 From: AquaSG Date: Tue, 21 May 2024 10:26:43 -0400 Subject: [PATCH 035/401] closest npc to angle utility --- Utilities/NPCUtils.cs | 47 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/Utilities/NPCUtils.cs b/Utilities/NPCUtils.cs index 5617cc237d..baad855704 100644 --- a/Utilities/NPCUtils.cs +++ b/Utilities/NPCUtils.cs @@ -605,6 +605,53 @@ public static NPC ClosestNPCAt(this Vector2 origin, float maxDistanceToCheck, bo return closestTarget; } + /// + /// Detects the hostile NPC that is closest angle-wise to the rotation vector + /// + /// The position that will be used to find the rotation vector to NPCs + /// The rotation vector that the other rotation vectors to NPCs will be compared to + /// Maximum amount of pixels to check around the origin + /// When the angle between the rotation vector and the vector to the NPC is less than or equal to this, NPCs start getting ranked by distance. Set to 0 or less to ignore + /// Whether or not to ignore tiles when finding a target + /// The NPC that best fits the parameters. Null if no NPC is found + public static NPC ClosestNPCToAngle(this Vector2 origin, Vector2 checkRotationVector, float maxDistanceToCheck, float wantedHalfCone = 0.125f, bool ignoreTiles = true) + { + NPC closestTarget = null; + float distance = maxDistanceToCheck; + float angle = MathHelper.Pi; + for (int i = 0; i < Main.maxNPCs; i++) + { + NPC npc = Main.npc[i]; + if (!npc.CanBeChasedBy(null, false)) + continue; + + float checkDist = origin.Distance(npc.Center); + if (checkDist >= distance) // Immediately disqualify anything beyond the distance that must be beaten + continue; + + float angleBetween = checkRotationVector.AngleBetween(npc.Center - origin); + if (angleBetween > angle) // Narrow down to the closest npc to the angle + continue; + + if (!ignoreTiles && !Collision.CanHit(origin, 1, 1, npc.Center, 1, 1)) // Tile LoS check if wanted + continue; + + if (angle <= wantedHalfCone) + { + angle = wantedHalfCone; + distance = checkDist; // We are within the cone. Now npcs are further narrowed down by distance + closestTarget = npc; + } + else + { + angle = angleBetween; + closestTarget = npc; + } + } + + return closestTarget; + } + /// /// Detects nearby hostile NPCs from a given point with minion support /// From 8abca37eb2fe1e66eb00d63f809fdf5a03d3f620 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Tue, 21 May 2024 11:16:58 -0400 Subject: [PATCH 036/401] Astrum Deus Relic resprite --- .../Furniture/BossRelics/AstrumDeusRelic.png | Bin 1190 -> 1224 bytes .../Furniture/BossRelics/AstrumDeusRelic.png | Bin 1477 -> 1217 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/Items/Placeables/Furniture/BossRelics/AstrumDeusRelic.png b/Items/Placeables/Furniture/BossRelics/AstrumDeusRelic.png index beecae5c78915d4c03cdf4c7c1d7c1346c74031a..cfbfe599d30e26ad36b76493341635477523c221 100644 GIT binary patch delta 1191 zcmV;Y1X%l~3CIbMF@J(dL_t(&f$f=FXdG1-$A7b%O>NR`bJJ*wP1Zz{7?Bj)CS)PK zAd3)au_898p!7kZY7x{2gQ!UK!KYRW^&uF@LyGl6g+f>_km3p@DG@O?3Bhb@yEMgI z+9lB@Y1W6cU#92m4A~TfS@r)iGiT1socYcF`_8v#;eV}7mVeucZJ|}KO=WY>!HKmE zNaVY{%l>)g1%t%^1pMm(2<9&WVCCHaAhmSejSK*hZ~*|(*t|5Q0FpNX7C?Eq|T-UYz1_dnFyVN`8wuZeDpocD=|Oix8)bLqVS0OD~) zMo9hm{eX5H313&;V~WV=AH{MjM{**Qpl69$w~So#R%Gjf*73scik#%Fiu*PKP*qh6 zz^C1V0DS(%kYtyd3g`B2*!Ie$V7fZ{@ByP3HqJvz&D51cyv zHUJgXI{@f7_#^^n@;uK^O6Pcb%{HCJPB-hz>5`c|m&j2uT_7wp3wY>|#0}nP>0As%n170R( zddzPH0DridT1-Lq(fRm+7u2!gInhU_)@jEdyt+=iPRNn|ia9~dvF;LY$&4VLG37>1 zJoWNERo}Uh>+ZP%Kvm_Y93v*tB6XI$i4YTyJ@@S0fK5p9)N1NI@-P7HhgF7`FY?Y? zJJt5Rejt~KNfe5g%={!3szjw(rwO^5P>BUFK7TQ--Cw?l^b=wOBc}m-j`cpV@}gw` zCTD$)`D^#CAdpE;ss{0nNv@&pE(>6IePW{3$hqY)As1>;RYG5X!ki*3$gJ(%)<|-Pn8=Ns%y|-( zZhz$NsaE994aEUSF053nSq&`rh>3(;O~p+B#uI+cJ3>%qh(jG+fSr$a?A~Jm^qd?5 z{tLuJW~IBiRC(|6lusilGeFzZZvb{ZhD%hsDffw)G6~k#sCw=E_?&Zz`>!XK#j3TY z`NceKyR@v{InSrOSP)p!wj#Gx?c52c6{1^a_JbD;_W1Y_f z(A{%IRV6NK8`0Rjw!&!2v&1q+8);NyZEmRtU~G6S1<)J)TI+Z2+arKY&?K_Iy?+(3 zNs8JddjSaDU#+T-!7%`$KP_whyie@FPPNL@)EWlh?3tKG$|NK*$znh002ovPDHLk FV1h@2M(Y3o delta 1156 zcmV-~1bh3)38o2kEM_Qn1$)%XpFjGsj6zK80cxV)W0|z4jyn60UbAG5BfU_^31&X~j z^j_&zB6W9m9e;r7+Xn6j?>}$d;PGe|09QZy#F{6GSZ!^U2ary01JL$_dG1m-n|65sEiHR;;~Q?~ z0D?@cuGWO9RN9b{_g%jEJy7@(*@PrQnt%M%yVm&RjejdZ!Fxpx$O0r18vtCq&;ek$i(!=Yke^Q-g@Wj zvJ2#m1J}L;;OfA|+{hJc-cRFGW$)9{TxZ>fOLndeJ~2PZ8|6LvQh#zrg*ay9#z%Sm z$sAd?3V#V7F_F@jij;EWiI-A9F*#}S#;4YKA)ZxKNW5~V`h9M^IX z_-)SQO#LE?XOOVw2bb8>hZ{VA;i1v8wY}n!a^w8`v^B0O0JjqyQ~LENfD5_!#Qh-_Ko zfhCr&`Bi&M$@Pr2KXl`iE0I#J)jG-DGpLG@+}%`giMba#qvq)LAY?15+axz`xui7y z`Dd>H1@Crq=|AohGGda*)z=wvo2jDi4N&ZLZsjXdlAjHRpO_?ajS=$=tLxikGlWY> zHh-l|;ODKO@yd$Tg}O7Z$BeB#`^+w&5ZBzgON73?Y4(kNyDit7>+7mL2tn^+$9>Tc z&l}q~+W8y+wUL8B&V$>NILc9v@6t^_(hQRTb({;A7{3C06vd zy~oVEcAq!`z|1c*S%9IDudI2B_-?;nMASVJNvW^*Gyu`VhdhAEi5UP!rtEkYe0^f) zUU&q6u2>HMny{EIe=Uet3SYr9NlsB#4Knv46Gf^_|XhwYR}k8}iP;68jtL WJ@=YSS#JaY00004`0LFgpw;pi( zy$=9*e8*M*Mt?^WX5NJ>fKMPXQEsg(DO~UXW)}(pn4X?m(LWMBBAf5O3xJEiUj?%F zwj%DT@v&_{IGJzGOk4B22aBxhiqcsRpt98VO1{}Fx0Ft3P=BCagv_Ff_*FDRSED)#{J@~%0+_s|!ge*(a#C&vM3 zYj5=cdb)Z6pGVJ0kbv6On5mjZEMB@Edivc)vbk4dj zGV+?dQe9Q#0ep4VyiatA4EG%b{JieUB_b&cY46KJI$=uBzj8isy&HLvQI=E(;byUc zr145*h^%!7be>0rCX59*%iQJ|+Ykcg2ArwYH+E88WEzV1WPX>b5`Caz7 zHGdu%A{md=)tK&bWURo-PGOZ=5)oBo_dA!?iA-JXy&k|w@-O#Y0zKNYrNjfclp0F| zoEtt3`1K@m9?6tfktx6XIsj9DuL-Ohst@^+dHT5*0YB31ZFL?%SI>y1SanSI&-V|R z_bXmlWke*mt|-E8ZzM9(jn)U3O!K1~Jb!@xAO8$ouR7A!-U>iZSFc5G^$-cmVv<|A z)l(_btxXjkK<~h$6+ySFUD82#5dIA~>;xOV?lXJpl9#T@K7b zI)h8@uf5INcX$9NPYnWhenZSCr$<~Va(zRYA&YA5Mss=S=$u2!d<&LmVwHPzKkr=; zq{tAtCDB+a_sgXSCI3j@mWnP#h8oBn{onL2-EI0LRN$Ws00000NkvXXu0mjf0nj=v delta 1447 zcmV;Y1z7sQ3B?PLFn9(E7>1wQA84n}v;^d*SV{pYQ4%#&DHst5 z5EJ7<+l59=Xh_rq4J(5!F(EO4#D(#PgpGj&3>#o)LV!puk)K!s3m~aM3oRfdkj`|Z zrM2yKaqi2VbLLJVtjL9Tb35m6?tJh0-tYU)sYigOWfl6}7bts7sn zJ|EoI;R6f~S%zoJPX_?lw64i7&v;feA0)BKk$1MxCZhu^6jXSun1Ayk$%>aDA^K$_H={^mFOvvIbYa0M~^ZhRX_~qxXP5Bl8zZGAel1=3@JURM3E)x?< z{UAb{xUm1oejtDEuUMWO_lw{dMW8pZi&uTJ|gg)nj}knJ{}XJ75?opJ*&4hJVf+{SFA#OKPL|QpiVc+%!zQ)VSR0 zm#+wCPqhOf6AK%bcmU@+Pg>(*!-&_ktRnCYW5I3P4HNU`*LVPz{_J(?!r#Eg7q z$A6X z1y6fDshyzuMR0Sm`SmkBfacZBk&!xX}juC;}!lS_?- zi_By9o*OfEfAyOvj#nJHO#hjHQ7 z9jdwAenDrvyMi-b?eR6Q8da>GV`s&?_uR1hg&ZI8A!G&&GqGXB(F!( zclUguaZ))qj=48nv1O!S_UqoRHU$?}I^nx|)A-WGOGA;=$dW==kKOM^XfaX9C+>&X zF!ErxEQlI@_)cJy9-&Y z_Bm4_96n^iktcZ6@IOlKPnqeSM9KgF002ovPDHLkV1lB- B&u;(# From 3c33a9feb2f76f321839d738d95c5356538472cc Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Tue, 21 May 2024 11:18:04 -0400 Subject: [PATCH 037/401] Aerialite Dye resprite --- Items/Dyes/AerialiteDye.png | Bin 309 -> 431 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Items/Dyes/AerialiteDye.png b/Items/Dyes/AerialiteDye.png index 99402471c4d46f1dc364b0e47bd9f5825a99cfe2..d5b2f4c35eef60ca411e78c48d7b19cb554c5b00 100644 GIT binary patch delta 416 zcmV;R0bl;L04Ytt5G=&F$FSUk9Mt z83rIwy92;{c>-W-`%H>gNAOXu0C1nr0}vWVS~t@F31aaL3t(j@0f4`&1AyD|kBAta zloEoAq9@T>(o#a8Ifg?rJHG(H+=LE5aK@l?|WinJ_pMv@KOVsD8Zz(Ayy3 zD0AxR5A^gYB5*sFijM&JAFd>SL4Woo0*9hEK*)lB0bgn&>nm>f0O0000EWmrjOO-%qQ02u%P2mk;800000(o>TF0000< KMNUMnLSTYDDyQcF delta 293 zcmZ3_yp?H!WIZzj1H+NJUOOPgSRCZ;#IWw1%u67LCEd~2k%3`jKlh(RRv_Ovz$e5N zNE>NbzB`@$`~Q;p1qCN(#%P&2t~-4F+QT;!R~^tc4fDyWPn|kz=81#0F4^zCTm`B> zZ5tf{qy$TX{DS|Z0S48z^)r)zvYZ7Tk;M!Qe1|}oQB=dL0VtT~>Ealo5!`zIB44us zM{8oZX6(X8mH(H^nnWk5_5Ppwe0N3)bKLX>8Lyk)AFXX%5%#GlA@A+mt=DXySu>p3 z`~O+ZV}6&A<36?%d6H!2NnYein)h6IM)+&4V;z#}&jjq3NIjpOD#vhQY31AR)oe8k YvySs_-QIIr9cVR!r>mdKI;Vst0K?pUdH?_b From 7c7d49d7d0abfad951d96a34df9bd6b5a1235d93 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Tue, 21 May 2024 12:05:38 -0400 Subject: [PATCH 038/401] Fixed Bloodfire Arrows not removing health if you're on lifesteal cooldown, despite it ignoring lifesteal cooldown now --- Projectiles/Ranged/BloodfireArrowProj.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projectiles/Ranged/BloodfireArrowProj.cs b/Projectiles/Ranged/BloodfireArrowProj.cs index 92725f50c7..69a3118522 100644 --- a/Projectiles/Ranged/BloodfireArrowProj.cs +++ b/Projectiles/Ranged/BloodfireArrowProj.cs @@ -46,7 +46,7 @@ public override void AI() if (Projectile.localAI[0] == 0) { - player.statLife -= Main.player[Main.myPlayer].lifeSteal <= 0f ? 0 : 1; + player.statLife -= 1; if (player.statLife <= 0) { PlayerDeathReason pdr = PlayerDeathReason.ByCustomReason(CalamityUtils.GetText("Status.Death.BloodFireArrow" + Main.rand.Next(1, 2 + 1)).Format(player.name)); From 678a876e213ffaaa42d800b9a5e32f480bf3b86f Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Tue, 21 May 2024 12:11:54 -0400 Subject: [PATCH 039/401] REVERT: Frog Legs stack again. Amphibian Boots is still nerfed. --- Items/CalamityGlobalItem.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Items/CalamityGlobalItem.cs b/Items/CalamityGlobalItem.cs index 10845a70b5..077b34fc84 100644 --- a/Items/CalamityGlobalItem.cs +++ b/Items/CalamityGlobalItem.cs @@ -1240,6 +1240,9 @@ public override void UpdateAccessory(Item item, Player player, bool hideVisual) // The Frog Leg line is prevented from stacking. // Additionally, Amphibian boots are directly nerfed so they aren't the best in slot boots at all times. + // + // 21MAY2024: Ozzatron: Disabled this code. Frog Leg is allowed to stack. Amphibian Boots specific nerf is applied below. + /* switch (item.type) { default: @@ -1260,6 +1263,9 @@ public override void UpdateAccessory(Item item, Player player, bool hideVisual) modPlayer.alreadyHasFrogLeg = true; break; } + */ + if (item.type == ItemID.AmphibianBoots) + player.jumpSpeedBoost += BalancingConstants.AmphibianBootsJumpSpeedBoost - BalancingConstants.VanillaFrogLegJumpSpeedBoost; // Feral Claws line melee speed adjustments and nonstacking // First removes all their melee speed so it can be given based on which you wear without stacking From 93d2e8d66287f4d2641d7bbc61e33195f5c65b95 Mon Sep 17 00:00:00 2001 From: Xhack <72313282+energykid@users.noreply.github.com> Date: Tue, 21 May 2024 10:54:40 -0400 Subject: [PATCH 040/401] Custom use style items and projectiles; Wind Blade swing animations IMPORTANT NOTE - In order to use a projectile that extends BaseCustomUseStyleProjectile, you have to make the item that shoots it extend CustomUseProjItem. --- Items/BaseItems/CustomUseProjItem.cs | 23 ++ Items/Weapons/Melee/WindBlade.cs | 25 +- Items/Weapons/Melee/WindBlade.png | Bin 930 -> 870 bytes .../BaseCustomUseStyleProjectile.cs | 248 ++++++++++++++++++ Projectiles/Melee/WindBladeHoldout.cs | 132 ++++++++++ Projectiles/Melee/WindBladeHoldout.png | Bin 0 -> 870 bytes Projectiles/Melee/{Cyclone.cs => WindBolt.cs} | 11 +- .../Melee/{Cyclone.png => WindBolt.png} | Bin 8 files changed, 415 insertions(+), 24 deletions(-) create mode 100644 Items/BaseItems/CustomUseProjItem.cs create mode 100644 Projectiles/BaseProjectiles/BaseCustomUseStyleProjectile.cs create mode 100644 Projectiles/Melee/WindBladeHoldout.cs create mode 100644 Projectiles/Melee/WindBladeHoldout.png rename Projectiles/Melee/{Cyclone.cs => WindBolt.cs} (93%) rename Projectiles/Melee/{Cyclone.png => WindBolt.png} (100%) diff --git a/Items/BaseItems/CustomUseProjItem.cs b/Items/BaseItems/CustomUseProjItem.cs new file mode 100644 index 0000000000..800d2dfb97 --- /dev/null +++ b/Items/BaseItems/CustomUseProjItem.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Terraria; +using Terraria.ModLoader; + +namespace CalamityMod.Items.BaseItems +{ + public abstract class CustomUseProjItem : ModItem + { + public override void SetDefaults() + { + Item.channel = true; + } + + public override bool CanShoot(Player player) + { + return player.ownedProjectileCounts[Item.shoot] < 1; + } + } +} diff --git a/Items/Weapons/Melee/WindBlade.cs b/Items/Weapons/Melee/WindBlade.cs index 8676601b68..24f1c6a98b 100644 --- a/Items/Weapons/Melee/WindBlade.cs +++ b/Items/Weapons/Melee/WindBlade.cs @@ -1,4 +1,6 @@ -using CalamityMod.Items.Materials; +using CalamityMod.Items.BaseItems; +using CalamityMod.Items.Materials; +using CalamityMod.Projectiles.BaseProjectiles; using CalamityMod.Projectiles.Melee; using Microsoft.Xna.Framework; using Terraria; @@ -8,7 +10,7 @@ namespace CalamityMod.Items.Weapons.Melee { - public class WindBlade : ModItem, ILocalizedModType + public class WindBlade : CustomUseProjItem, ILocalizedModType { public new string LocalizationCategory => "Items.Weapons.Melee"; public override void SetDefaults() @@ -22,24 +24,15 @@ public override void SetDefaults() Item.useTime = 20; Item.useTurn = true; Item.knockBack = 5f; - Item.UseSound = SoundID.Item1; Item.autoReuse = true; Item.value = CalamityGlobalItem.RarityOrangeBuyPrice; Item.rare = ItemRarityID.Orange; - Item.shoot = ModContent.ProjectileType(); - Item.shootSpeed = 3f; - } - public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) - { - Projectile.NewProjectile(source, position, velocity, type, damage / 2, knockback, player.whoAmI); - return false; - } - - public override void MeleeEffects(Player player, Rectangle hitbox) - { - if (Main.rand.NextBool(3)) - Dust.NewDust(new Vector2(hitbox.X, hitbox.Y), hitbox.Width, hitbox.Height, DustID.BlueTorch); + Item.channel = true; + Item.shoot = ModContent.ProjectileType(); + Item.noUseGraphic = true; + Item.noMelee = true; + Item.useStyle = ItemUseStyleID.Shoot; } public override void AddRecipes() diff --git a/Items/Weapons/Melee/WindBlade.png b/Items/Weapons/Melee/WindBlade.png index 36d003fbdcbe511f4b0dd3a6f72ea705133b3674..b08f34b7d98f5f3f7a38e51a7dd73f46a2afc898 100644 GIT binary patch literal 870 zcmeAS@N?(olHy`uVBq!ia0vp^UO*he!3-pYE(NXtQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ivoN?Tn$sRP1>73{Jz+6c$H=S?vVfgZT9cb@Cd7$R6cccw!FDxLSBT0 zyhPo^a^CEQ5DSqR)utI%ie|2rN7kfT*6;d#qovuIOG;L?*@-JB!R+;!#^2YQ&0Q
lBSEMj7FnN2rIEF;HpS|8)v|2%cEn(7x1s<_eqCS49`}jBhcDuc;3l-beO!lq% z`npHgZn*nMu*dzh-AfIT>8Z1Mr=7L;z&Zj1Mhn$j_SCl<_!meY-<~1Gabt~Jw$)%X-xA3FCfA<#i^DpqzeXMDyX`&HV zyn)fcc}vv8`@CB+F5B2WIv+FtkP%zhb&c~;TO8*_pT2TgIM17lDlc{~n&_b0_XxaXoxbN=EO?x@za_2I+Iw${SZ| z-cZ=0#})AYea)ZGM)Qp1U9W8OsjXS?VU?HfLsJg%MUs2o|K7HjWmfwv1({OWY5LPX zepqcRJpYl|gT?Et_v`WtPtS_BdGq1Y;RmUyZ-u9?(s~{swCv}09-+xjk<+(6D)01^ h6mE806j=LTJkb1E_Xp`4e}QR@!PC{xWt~$(697sik}v=O literal 930 zcmV;T16}-yP)XhFzSdcT!?*u#N@&VB$=WD5d}B3h-lF&5QK&lBFMfr zMudbQA_hu|UlT%pq^Ju^7m6^nQiFnf-`_a5_eRU-^Qq@7=5X(Q%y8%T&N=^cT-qVA z+@dSLVx7CRBVw+DPV9s`MfmK>eBlcV&XDuR^-q|nqwQ>{+>o4Vqhnt=MjaiS4dFVm zuF6Xm{_U659g$?BPBoPz*07p8?ZT(#dW4^TKQ8>lNP8R;by95he|%s_78bnRLh2}N zExN)n>S&TliJ!^3?A)Ls$>oXfoOK;Zax1$Yli5@&ED^4L`+TUwjh& zQDB@r_quUZ_)9gFhTRDab(4wiS6>MY3z9coefo)8e9lIq!f#x?Wk}MDAQQD~B7lAp z_Tgo(@b~lQ$bQG0cuPn!Q8V*rmk>gc>A|>I`>?d49K(7Soso62sVYj&C#R&A9mw>_ z^0`ZrOw^2I&nv%JmtTvJ{rZc=Vjb=pBKzwm-v^R6^5O}>;dx2==LMf7G08;DNVYa+ zkbQMMsY}b^EU)l^bPqXyw_!{Y29k?jNitR6A86~bgd`JHV-Lh?n`I1QA0$E*l2owz zq^@M-x~)@2>B91o@TI9p&K_fuxt^mrO0oT-$fl@|VND}-GgOg5l+5rv&A0t6DMYij zbyAXM{iIc~$wbXankgdG!C>{K@V-a_sgH=+Ouy_#`ku+@T$-0=V|P|E$LOA1R3&Jp zbx}_<{hK5PLC$}>kW2;;o27c83>=rwH|g`&wUHGjYOB`$L(ommK@u?ul98uf`V%zv zLKO+5J}3NGjQJ)p(Y?B8ZSx$_v@mE}WZi~f2if=Ktm^euGt{{1o3mGBnW%Xdrdk-p z?mb*L>|UUGv5(jcq|-M7b(>>!zb*=rAT~7fjbv5CGz{m6arHUQx^`VuozI@qr+T%` z-8=dLRU50Zs%dkab#1*UluJSVbvnyY{&}^V0V$O%`dKKg)|?E(m}a6@UlfEAy>gyA z7Je=dl1~5AL}I&Hl-cu4^nWj^_L*DRwd}m`OTFF7KR&oa1!YWfJMv7_s*55EZYiC= zNbb&5Eo&Faqf1onGN4U&Yj%@kqH1?x70E->rX4i<4W%ooAtHj_!vFvP07*qoM6N<$ Ef~JAQlK=n! diff --git a/Projectiles/BaseProjectiles/BaseCustomUseStyleProjectile.cs b/Projectiles/BaseProjectiles/BaseCustomUseStyleProjectile.cs new file mode 100644 index 0000000000..09eb794278 --- /dev/null +++ b/Projectiles/BaseProjectiles/BaseCustomUseStyleProjectile.cs @@ -0,0 +1,248 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using CalamityMod.Items.Weapons.Melee; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using ReLogic.Content; +using Terraria; +using Terraria.DataStructures; +using Terraria.GameInput; +using Terraria.ModLoader; + +namespace CalamityMod.Projectiles.BaseProjectiles +{ + public abstract class BaseCustomUseStyleProjectile : ModProjectile + { + + public override void SetDefaults() + { + Projectile.friendly = true; + Projectile.tileCollide = false; + } + + public override void OnSpawn(IEntitySource source) + { + Projectile.timeLeft = Owner.HeldItem.useAnimation + 1; + } + + #region Fields + /// + /// The offset in pixels of the weapon from the projectile owner's center. This works even while using AbsolutePosition. + /// + public Vector2 Offset = Vector2.Zero; + + /// + /// The Player that is using the projectile. + /// + public virtual Player Owner => Main.player[Projectile.owner]; + + /// + /// The amount of pixels out the center of the projectile's hitbox is. + /// + public virtual float HitboxOutset => 30; + + /// + /// The projectile's hitbox size in pixels. + /// + public virtual Vector2 HitboxSize => new Vector2(30, 30); + + /// + /// The number of animations that this projectile has gone through. Useful for things like swing combos. + /// + public int NumberOfAnimations = 0; + + public float Animation = 0; + + /// + /// If true, flips the sprite with a 45-degree sword tilt in mind. + /// + public bool FlipAsSword = false; + + /// + /// The offset in radians of the weapon's rotation from its current rotation. + /// + public float RotationOffset = 0f; + + /// + /// The offset in radians of the rotation of the player's front arm. + /// + public float ArmRotationOffset = 0f; + + /// + /// The offset in radians of the rotation of the player's back arm. + /// + public float ArmRotationOffsetBack = 0f; + + /// + /// The amount of animation frames the projectile has in a vertical sheet. + /// + public virtual int FrameCount => 1; + + /// + /// The individual frame currently being drawn in a vertical sheet. + /// + public int Frame = 0; + + /// + /// The origin of the sprite when drawn on your character. + /// + /// + public virtual Vector2 SpriteOrigin() + { + return Projectile.Size / 2; + } + + /// + /// Helper method for getting the rotation of the sprite plus RotationOffset, without having to make your own local variable every time. + /// + /// + public float FinalRotation() + { + return Projectile.rotation + RotationOffset; + } + + /// + /// Rotation offset for the hitbox that doesn't affect the sprite. + /// Useful for if you have, for instance, a sword sprite at a 45 degree angle, and need that to reflect on the hitbox. + /// + /// + public virtual float HitboxRotationOffset() + { + return 0f; + } + + /// + /// Whether or not the projectile can hit enemies at the current frame. + /// Useful for wind-up animations where you don't want the projectile to deal damage. + /// + public bool CanHit = true; + + /// + /// Overrides the projectile owner's center as the projectile's location, so long as it isn't Vector2.Zero. + /// + public Vector2 AbsolutePosition = Vector2.Zero; + + /// + /// If this field is true, the projectile will draw at all times. Otherwise, it will only draw when its associated item is in use. + /// + public bool DrawUnconditionally = false; + + /// + /// The number of frames that the current use animation has progressed through. + /// + public float AnimationProgress = 0; + #endregion + + #region Use Style + /// + /// Determines the behavior to reset to when the item is not in use. + /// + public virtual void ResetStyle() { } + + /// + /// Determines the behavior of the projectile when the item is in use. + /// + public virtual void UseStyle() { } + + /// + /// Determines the behavior of the projectile when the item use animation begins for the first time in a row. + /// + public virtual void OnBeginUse() { } + + /// + /// Determines the behavior of the projectile when the item use animation ends. + /// + public virtual void OnEndUse() { } + #endregion + + public override void AI() + { + Projectile.penetrate = 100; + + if (Owner.ItemAnimationActive) + { + Animation++; + + UseStyle(); + Owner.heldProj = Projectile.whoAmI; + Owner.SetCompositeArmFront(true, Player.CompositeArmStretchAmount.Full, Projectile.rotation + RotationOffset + ArmRotationOffset); + Owner.SetCompositeArmBack(true, Player.CompositeArmStretchAmount.Full, Projectile.rotation + RotationOffset + ArmRotationOffsetBack); + } + else + { + Animation = 0; + + if (DrawUnconditionally) + { + Owner.heldProj = Projectile.whoAmI; + Owner.SetCompositeArmFront(true, Player.CompositeArmStretchAmount.Full, Projectile.rotation + RotationOffset + ArmRotationOffset); + Owner.SetCompositeArmBack(true, Player.CompositeArmStretchAmount.Full, Projectile.rotation + RotationOffset + ArmRotationOffsetBack); + } + + NumberOfAnimations = 0; + ResetStyle(); + } + + AnimationProgress = Animation % Owner.itemAnimationMax; + + if (AbsolutePosition == Vector2.Zero) + { + Projectile.position = Owner.position + (Owner.Size / 2) - (Projectile.Size / 2) + Offset; + } + else + { + Projectile.position = AbsolutePosition - (Projectile.Size / 2) + Offset; + } + + if (Owner.itemAnimation == 1) + { + OnEndUse(); + NumberOfAnimations++; + } + + if (Owner.ItemAnimationJustStarted) + { + Projectile.timeLeft = Owner.HeldItem.useAnimation + 1; + OnBeginUse(); + } + } + + public override void ModifyHitNPC(NPC target, ref NPC.HitModifiers modifiers) + { + modifiers.HitDirectionOverride = Owner.direction; + base.ModifyHitNPC(target, ref modifiers); + } + + public override bool? CanDamage() + { + return CanHit ? base.CanDamage() : false; + } + + public override void ModifyDamageHitbox(ref Rectangle hitbox) + { + Vector2 cen = Projectile.Center + new Vector2(HitboxOutset, 0).RotatedBy(FinalRotation() + HitboxRotationOffset()); + + hitbox = new Rectangle((int)cen.X - (int)(HitboxSize.X / 2), (int)cen.Y - (int)(HitboxSize.Y / 2), (int)HitboxSize.X, (int)HitboxSize.Y); + + base.ModifyDamageHitbox(ref hitbox); + } + + public override bool PreDraw(ref Color lightColor) + { + // Only draw the projectile if the projectile's owner is currently using the item this projectile is attached to. + if (Owner.itemAnimation > 0 || DrawUnconditionally) + { + Asset tex = ModContent.Request(Texture); + + float r = FlipAsSword ? MathHelper.ToRadians(90) : 0f; + + Main.EntitySpriteDraw(tex.Value, Projectile.Center - Main.screenPosition + new Vector2(0, Owner.gfxOffY), tex.Frame(1, FrameCount, 0, Frame), lightColor, Projectile.rotation + RotationOffset + r, FlipAsSword ? new Vector2(tex.Width() - SpriteOrigin().X, SpriteOrigin().Y) : SpriteOrigin(), Projectile.scale, FlipAsSword ? SpriteEffects.FlipHorizontally : SpriteEffects.None); + } + return false; + } + } +} diff --git a/Projectiles/Melee/WindBladeHoldout.cs b/Projectiles/Melee/WindBladeHoldout.cs new file mode 100644 index 0000000000..d55bf66300 --- /dev/null +++ b/Projectiles/Melee/WindBladeHoldout.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using CalamityMod.CalPlayer; +using CalamityMod.Items.Weapons.Melee; +using CalamityMod.Particles; +using CalamityMod.Projectiles.BaseProjectiles; +using Microsoft.Xna.Framework; +using Terraria; +using Terraria.Audio; +using Terraria.DataStructures; +using Terraria.ID; +using Terraria.ModLoader; + +namespace CalamityMod.Projectiles.Melee +{ + public class WindBladeHoldout : BaseCustomUseStyleProjectile, ILocalizedModType + { + public override float HitboxOutset => 60; + + public override Vector2 HitboxSize => new Vector2(70, 70); + + public override float HitboxRotationOffset() + { + return MathHelper.ToRadians(-45); + } + + public override Vector2 SpriteOrigin() + { + return new(0, 80); + } + + public override void OnSpawn(IEntitySource source) + { + Projectile.scale = 0f; + Projectile.ai[1] = 1; + base.OnSpawn(source); + } + + public override void UseStyle() + { + Vector2 mousePos = Main.MouseWorld; + // i don't know how cal handles Main.MouseWorld in netcode. todo: someone fix this up in multiplayer pls + // - ennway + + if (mousePos.X < Owner.Center.X) Owner.direction = -1; + else Owner.direction = 1; + + DrawUnconditionally = true; + + if (NumberOfAnimations % 4 < 2) + { + Projectile.rotation = Owner.AngleTo(mousePos) + MathHelper.ToRadians(45f); + + if (NumberOfAnimations % 4 == 0 && AnimationProgress < 10) + Projectile.scale = MathHelper.Lerp(Projectile.scale, 1f, 0.4f); + + if (AnimationProgress < (Owner.itemAnimationMax / 3)) + { + CanHit = false; + if (AnimationProgress == 0) + { + Projectile.ai[1] = -Projectile.ai[1]; + } + RotationOffset = MathHelper.Lerp(RotationOffset, MathHelper.ToRadians(120f * Projectile.ai[1] * Owner.direction), 0.2f); + } + else + { + CanHit = true; + if ((int)AnimationProgress == (int)(Owner.itemAnimationMax / 1.5f)) + { + SoundEngine.PlaySound(SoundID.DD2_MonkStaffSwing, Owner.Center); + } + if ((int)AnimationProgress > (int)(Owner.itemAnimationMax / 1.5f)) + { + GeneralParticleHandler.SpawnParticle(new HeavySmokeParticle(Owner.Center + (new Vector2(Main.rand.Next(30, 100), 0).RotatedBy(FinalRotation() + MathHelper.ToRadians(-45))), new Vector2(0, 10 * -Projectile.ai[1] * Owner.direction).RotatedBy(FinalRotation() + MathHelper.ToRadians(-45)), Color.LightSkyBlue, 40, 1f, 0.4f, MathHelper.ToRadians(Main.rand.NextFloat(-10f, 10f)), true)); + } + + float time = (AnimationProgress) - (Owner.itemAnimationMax / 3); + float timeMax = Owner.itemAnimationMax - (Owner.itemAnimationMax / 3); + + RotationOffset = MathHelper.Lerp(RotationOffset, MathHelper.ToRadians(MathHelper.Lerp(150f * Projectile.ai[1] * Owner.direction, 120f * -Projectile.ai[1] * Owner.direction, CalamityUtils.ExpInOutEasing(time / timeMax, 1))), + 0.2f); + } + + FlipAsSword = Owner.direction == -1 ? true : false; + } + else if (NumberOfAnimations % 4 == 3) + { + CanHit = true; + if ((int)AnimationProgress == 1) + { + SoundEngine.PlaySound(SoundID.DD2_SkyDragonsFurySwing, Owner.Center); + SoundEngine.PlaySound(SoundID.DD2_MonkStaffSwing.WithPitchOffset(-0.4f), Owner.Center); + } + RotationOffset = 0f; + if (AnimationProgress < Owner.itemAnimationMax / 3) + { + Projectile.scale = MathHelper.Lerp(Projectile.scale, 1.5f, 0.4f); + + float rot = FinalRotation() + MathHelper.ToRadians(-45); + + GeneralParticleHandler.SpawnParticle(new HeavySmokeParticle(Owner.Center + new Vector2(105 * Projectile.scale, 0).RotatedBy(rot), new Vector2(5, 0).RotatedBy(rot + MathHelper.ToRadians(Main.rand.NextFloat(-20, 20))), Color.LightSkyBlue, 30, 2f, 0.3f, MathHelper.ToRadians(Main.rand.NextFloat(-10f, 10f)), true)); + GeneralParticleHandler.SpawnParticle(new LineParticle(Owner.Center + new Vector2(0, 20).RotatedBy(rot) + new Vector2(45 * Projectile.scale, 0).RotatedBy(rot), new Vector2(5, 0).RotatedBy(rot), false, 30, 1f, Color.LightSkyBlue)); + GeneralParticleHandler.SpawnParticle(new LineParticle(Owner.Center + new Vector2(0, -20).RotatedBy(rot) + new Vector2(45 * Projectile.scale, 0).RotatedBy(rot), new Vector2(5, 0).RotatedBy(rot), false, 30, 1f, Color.LightSkyBlue)); + } + else + { + Projectile.scale = MathHelper.Lerp(Projectile.scale, 1.5f, -0.2f); + } + } + else + { + CanHit = false; + + RotationOffset = MathHelper.Lerp(RotationOffset, MathHelper.ToRadians(MathHelper.Lerp(150f * -Projectile.ai[1] * Owner.direction, 120f * Projectile.ai[1] * Owner.direction, 0.1f)), + 0.2f); + + Projectile.rotation = Owner.AngleTo(mousePos) + MathHelper.ToRadians(45f); + Projectile.scale = MathHelper.Lerp(Projectile.scale, 0f, 0.2f); + } + + ArmRotationOffset = MathHelper.ToRadians(-90f); + } + + public override void ResetStyle() + { + } + } +} diff --git a/Projectiles/Melee/WindBladeHoldout.png b/Projectiles/Melee/WindBladeHoldout.png new file mode 100644 index 0000000000000000000000000000000000000000..b08f34b7d98f5f3f7a38e51a7dd73f46a2afc898 GIT binary patch literal 870 zcmeAS@N?(olHy`uVBq!ia0vp^UO*he!3-pYE(NXtQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ivoN?Tn$sRP1>73{Jz+6c$H=S?vVfgZT9cb@Cd7$R6cccw!FDxLSBT0 zyhPo^a^CEQ5DSqR)utI%ie|2rN7kfT*6;d#qovuIOG;L?*@-JB!R+;!#^2YQ&0QlBSEMj7FnN2rIEF;HpS|8)v|2%cEn(7x1s<_eqCS49`}jBhcDuc;3l-beO!lq% z`npHgZn*nMu*dzh-AfIT>8Z1Mr=7L;z&Zj1Mhn$j_SCl<_!meY-<~1Gabt~Jw$)%X-xA3FCfA<#i^DpqzeXMDyX`&HV zyn)fcc}vv8`@CB+F5B2WIv+FtkP%zhb&c~;TO8*_pT2TgIM17lDlc{~n&_b0_XxaXoxbN=EO?x@za_2I+Iw${SZ| z-cZ=0#})AYea)ZGM)Qp1U9W8OsjXS?VU?HfLsJg%MUs2o|K7HjWmfwv1({OWY5LPX zepqcRJpYl|gT?Et_v`WtPtS_BdGq1Y;RmUyZ-u9?(s~{swCv}09-+xjk<+(6D)01^ h6mE806j=LTJkb1E_Xp`4e}QR@!PC{xWt~$(697sik}v=O literal 0 HcmV?d00001 diff --git a/Projectiles/Melee/Cyclone.cs b/Projectiles/Melee/WindBolt.cs similarity index 93% rename from Projectiles/Melee/Cyclone.cs rename to Projectiles/Melee/WindBolt.cs index e079ace083..fa7973d544 100644 --- a/Projectiles/Melee/Cyclone.cs +++ b/Projectiles/Melee/WindBolt.cs @@ -8,7 +8,7 @@ namespace CalamityMod.Projectiles.Melee { - public class Cyclone : ModProjectile, ILocalizedModType + public class WindBolt : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Melee"; public int dustvortex = 0; @@ -43,7 +43,7 @@ public override void AI() if (Projectile.ai[0] >= 12) Projectile.tileCollide = true; - Projectile.rotation += 2.5f; + Projectile.rotation += MathHelper.ToRadians(15f); Projectile.alpha -= 5; if (Projectile.alpha < 50) { @@ -95,14 +95,9 @@ public override void AI() } } - public override Color? GetAlpha(Color lightColor) - { - return new Color(204, 255, 255, Projectile.alpha); - } - public override bool PreDraw(ref Color lightColor) { - CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], lightColor, 1); + CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], lightColor); return false; } diff --git a/Projectiles/Melee/Cyclone.png b/Projectiles/Melee/WindBolt.png similarity index 100% rename from Projectiles/Melee/Cyclone.png rename to Projectiles/Melee/WindBolt.png From edce2f7c760d7d106450da67edba13bb84a49026 Mon Sep 17 00:00:00 2001 From: Xhack <72313282+energykid@users.noreply.github.com> Date: Tue, 21 May 2024 13:54:40 -0400 Subject: [PATCH 041/401] Updated code in accordance with change requests + retooled and re-added Wind Blade cyclone --- .../Mods.CalamityMod.Projectiles.Melee.hjson | 3 +- .../BaseCustomUseStyleProjectile.cs | 47 +++++++++++++ Projectiles/Melee/WindBladeHoldout.cs | 30 ++++++++ Projectiles/Melee/WindBolt.cs | 69 +++++++++++++++++++ en-US.hjson | 1 + 5 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 en-US.hjson diff --git a/Localization/en-US/Mods.CalamityMod.Projectiles.Melee.hjson b/Localization/en-US/Mods.CalamityMod.Projectiles.Melee.hjson index f49ed13e17..79a1e7d286 100644 --- a/Localization/en-US/Mods.CalamityMod.Projectiles.Melee.hjson +++ b/Localization/en-US/Mods.CalamityMod.Projectiles.Melee.hjson @@ -76,7 +76,6 @@ CosmicSpiritBomb3.DisplayName: Cosmic Bomb CrescentMoonFlail.DisplayName: Crescent Moon CrescentMoonProj.DisplayName: Crescent Moon CrystylCrusherRay.DisplayName: Crystyl Crusher Ray -Cyclone.DisplayName: Cyclone DarkBall.DisplayName: Dark Ball DarkBeam.DisplayName: Dark Beam DarkIceZero.DisplayName: Dark Ice @@ -311,8 +310,10 @@ Waterfall.DisplayName: Waterfall Beam WhiteBoltAura.DisplayName: White Aura WhiteOrb.DisplayName: White Orb Whiterain.DisplayName: White Rain +WindBolt.DisplayName: Wind Bolt WulfrumScrew.DisplayName: Wulfrum Screw WulfrumScrewdriverProj.DisplayName: Wulfrum Screwdriver YateveoBloomProj.DisplayName: Yateveo Bloom YinYoDark.DisplayName: Dark Shard YinYoLight.DisplayName: Light Shard +Cyclone.DisplayName: Cyclone diff --git a/Projectiles/BaseProjectiles/BaseCustomUseStyleProjectile.cs b/Projectiles/BaseProjectiles/BaseCustomUseStyleProjectile.cs index 09eb794278..e662a81fae 100644 --- a/Projectiles/BaseProjectiles/BaseCustomUseStyleProjectile.cs +++ b/Projectiles/BaseProjectiles/BaseCustomUseStyleProjectile.cs @@ -22,6 +22,10 @@ public override void SetDefaults() { Projectile.friendly = true; Projectile.tileCollide = false; +<<<<<<< Updated upstream +======= + Projectile.penetrate = -1; +>>>>>>> Stashed changes } public override void OnSpawn(IEntitySource source) @@ -35,6 +39,11 @@ public override void OnSpawn(IEntitySource source) ///
public Vector2 Offset = Vector2.Zero; +<<<<<<< Updated upstream +======= + public float RestrikeDelay = 0; + +>>>>>>> Stashed changes /// /// The Player that is using the projectile. /// @@ -91,29 +100,41 @@ public override void OnSpawn(IEntitySource source) /// The origin of the sprite when drawn on your character. ///
/// +<<<<<<< Updated upstream public virtual Vector2 SpriteOrigin() { return Projectile.Size / 2; } +======= + public virtual Vector2 SpriteOrigin => Projectile.Size / 2; +>>>>>>> Stashed changes /// /// Helper method for getting the rotation of the sprite plus RotationOffset, without having to make your own local variable every time. /// /// +<<<<<<< Updated upstream public float FinalRotation() { return Projectile.rotation + RotationOffset; } +======= + public float FinalRotation => Projectile.rotation + RotationOffset; +>>>>>>> Stashed changes /// /// Rotation offset for the hitbox that doesn't affect the sprite. /// Useful for if you have, for instance, a sword sprite at a 45 degree angle, and need that to reflect on the hitbox. /// /// +<<<<<<< Updated upstream public virtual float HitboxRotationOffset() { return 0f; } +======= + public virtual float HitboxRotationOffset => 0f; +>>>>>>> Stashed changes /// /// Whether or not the projectile can hit enemies at the current frame. @@ -161,7 +182,13 @@ public virtual void OnEndUse() { } public override void AI() { +<<<<<<< Updated upstream Projectile.penetrate = 100; +======= + Owner.Calamity().mouseWorldListener = true; + + RestrikeDelay--; +>>>>>>> Stashed changes if (Owner.ItemAnimationActive) { @@ -211,6 +238,18 @@ public override void AI() } } +<<<<<<< Updated upstream +======= + public override bool? CanHitNPC(NPC target) + { + bool bb = (target.immune[0] <= 0) && !target.friendly && !target.dontTakeDamage && RestrikeDelay <= 0; + + if (bb) RestrikeDelay = 1; + + return bb; + } + +>>>>>>> Stashed changes public override void ModifyHitNPC(NPC target, ref NPC.HitModifiers modifiers) { modifiers.HitDirectionOverride = Owner.direction; @@ -224,7 +263,11 @@ public override void ModifyHitNPC(NPC target, ref NPC.HitModifiers modifiers) public override void ModifyDamageHitbox(ref Rectangle hitbox) { +<<<<<<< Updated upstream Vector2 cen = Projectile.Center + new Vector2(HitboxOutset, 0).RotatedBy(FinalRotation() + HitboxRotationOffset()); +======= + Vector2 cen = Projectile.Center + new Vector2(HitboxOutset, 0).RotatedBy(FinalRotation + HitboxRotationOffset); +>>>>>>> Stashed changes hitbox = new Rectangle((int)cen.X - (int)(HitboxSize.X / 2), (int)cen.Y - (int)(HitboxSize.Y / 2), (int)HitboxSize.X, (int)HitboxSize.Y); @@ -240,7 +283,11 @@ public override bool PreDraw(ref Color lightColor) float r = FlipAsSword ? MathHelper.ToRadians(90) : 0f; +<<<<<<< Updated upstream Main.EntitySpriteDraw(tex.Value, Projectile.Center - Main.screenPosition + new Vector2(0, Owner.gfxOffY), tex.Frame(1, FrameCount, 0, Frame), lightColor, Projectile.rotation + RotationOffset + r, FlipAsSword ? new Vector2(tex.Width() - SpriteOrigin().X, SpriteOrigin().Y) : SpriteOrigin(), Projectile.scale, FlipAsSword ? SpriteEffects.FlipHorizontally : SpriteEffects.None); +======= + Main.EntitySpriteDraw(tex.Value, Projectile.Center - Main.screenPosition + new Vector2(0, Owner.gfxOffY), tex.Frame(1, FrameCount, 0, Frame), lightColor, Projectile.rotation + RotationOffset + r, FlipAsSword ? new Vector2(tex.Width() - SpriteOrigin.X, SpriteOrigin.Y) : SpriteOrigin, Projectile.scale, FlipAsSword ? SpriteEffects.FlipHorizontally : SpriteEffects.None); +>>>>>>> Stashed changes } return false; } diff --git a/Projectiles/Melee/WindBladeHoldout.cs b/Projectiles/Melee/WindBladeHoldout.cs index d55bf66300..3b3127734f 100644 --- a/Projectiles/Melee/WindBladeHoldout.cs +++ b/Projectiles/Melee/WindBladeHoldout.cs @@ -22,6 +22,7 @@ public class WindBladeHoldout : BaseCustomUseStyleProjectile, ILocalizedModType public override Vector2 HitboxSize => new Vector2(70, 70); +<<<<<<< Updated upstream public override float HitboxRotationOffset() { return MathHelper.ToRadians(-45); @@ -31,6 +32,11 @@ public override Vector2 SpriteOrigin() { return new(0, 80); } +======= + public override float HitboxRotationOffset => MathHelper.ToRadians(-45); + + public override Vector2 SpriteOrigin => new(0, 80); +>>>>>>> Stashed changes public override void OnSpawn(IEntitySource source) { @@ -41,9 +47,13 @@ public override void OnSpawn(IEntitySource source) public override void UseStyle() { +<<<<<<< Updated upstream Vector2 mousePos = Main.MouseWorld; // i don't know how cal handles Main.MouseWorld in netcode. todo: someone fix this up in multiplayer pls // - ennway +======= + Vector2 mousePos = Owner.Calamity().mouseWorld; +>>>>>>> Stashed changes if (mousePos.X < Owner.Center.X) Owner.direction = -1; else Owner.direction = 1; @@ -75,7 +85,11 @@ public override void UseStyle() } if ((int)AnimationProgress > (int)(Owner.itemAnimationMax / 1.5f)) { +<<<<<<< Updated upstream GeneralParticleHandler.SpawnParticle(new HeavySmokeParticle(Owner.Center + (new Vector2(Main.rand.Next(30, 100), 0).RotatedBy(FinalRotation() + MathHelper.ToRadians(-45))), new Vector2(0, 10 * -Projectile.ai[1] * Owner.direction).RotatedBy(FinalRotation() + MathHelper.ToRadians(-45)), Color.LightSkyBlue, 40, 1f, 0.4f, MathHelper.ToRadians(Main.rand.NextFloat(-10f, 10f)), true)); +======= + GeneralParticleHandler.SpawnParticle(new HeavySmokeParticle(Owner.Center + (new Vector2(Main.rand.Next(30, 100), 0).RotatedBy(FinalRotation + MathHelper.ToRadians(-45))), new Vector2(0, 10 * -Projectile.ai[1] * Owner.direction).RotatedBy(FinalRotation + MathHelper.ToRadians(-45)), Color.LightSkyBlue, 40, 1f, 0.4f, MathHelper.ToRadians(Main.rand.NextFloat(-10f, 10f)), true)); +>>>>>>> Stashed changes } float time = (AnimationProgress) - (Owner.itemAnimationMax / 3); @@ -89,18 +103,34 @@ public override void UseStyle() } else if (NumberOfAnimations % 4 == 3) { +<<<<<<< Updated upstream +======= + float ProjectileSpeed = 10; + int ProjectileDamage = 10; + float ProjectileKnockback = Projectile.knockBack; + +>>>>>>> Stashed changes CanHit = true; if ((int)AnimationProgress == 1) { SoundEngine.PlaySound(SoundID.DD2_SkyDragonsFurySwing, Owner.Center); SoundEngine.PlaySound(SoundID.DD2_MonkStaffSwing.WithPitchOffset(-0.4f), Owner.Center); +<<<<<<< Updated upstream +======= + + Projectile.NewProjectile(new EntitySource_ItemUse(Owner, Owner.HeldItem), Projectile.Hitbox.Center.ToVector2(), new Vector2(ProjectileSpeed, 0).RotatedBy(FinalRotation + MathHelper.ToRadians(-45)), ModContent.ProjectileType(), ProjectileDamage, ProjectileKnockback, Owner.whoAmI); +>>>>>>> Stashed changes } RotationOffset = 0f; if (AnimationProgress < Owner.itemAnimationMax / 3) { Projectile.scale = MathHelper.Lerp(Projectile.scale, 1.5f, 0.4f); +<<<<<<< Updated upstream float rot = FinalRotation() + MathHelper.ToRadians(-45); +======= + float rot = FinalRotation + MathHelper.ToRadians(-45); +>>>>>>> Stashed changes GeneralParticleHandler.SpawnParticle(new HeavySmokeParticle(Owner.Center + new Vector2(105 * Projectile.scale, 0).RotatedBy(rot), new Vector2(5, 0).RotatedBy(rot + MathHelper.ToRadians(Main.rand.NextFloat(-20, 20))), Color.LightSkyBlue, 30, 2f, 0.3f, MathHelper.ToRadians(Main.rand.NextFloat(-10f, 10f)), true)); GeneralParticleHandler.SpawnParticle(new LineParticle(Owner.Center + new Vector2(0, 20).RotatedBy(rot) + new Vector2(45 * Projectile.scale, 0).RotatedBy(rot), new Vector2(5, 0).RotatedBy(rot), false, 30, 1f, Color.LightSkyBlue)); diff --git a/Projectiles/Melee/WindBolt.cs b/Projectiles/Melee/WindBolt.cs index fa7973d544..e0b442246b 100644 --- a/Projectiles/Melee/WindBolt.cs +++ b/Projectiles/Melee/WindBolt.cs @@ -1,10 +1,22 @@ using System; using CalamityMod.CalPlayer; using Microsoft.Xna.Framework; +<<<<<<< Updated upstream using Terraria; using Terraria.Audio; using Terraria.ID; using Terraria.ModLoader; +======= +using Microsoft.Xna.Framework.Graphics; +using ReLogic.Content; +using Terraria; +using Terraria.Audio; +using Terraria.GameContent.UI; +using Terraria.ID; +using Terraria.ModLoader; +using Terraria.Utilities.Terraria.Utilities; +using XPT.Core.Audio.MP3Sharp.Decoding.Decoders.LayerIII; +>>>>>>> Stashed changes namespace CalamityMod.Projectiles.Melee { @@ -12,6 +24,10 @@ public class WindBolt : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Melee"; public int dustvortex = 0; +<<<<<<< Updated upstream +======= + public float scFactor = 0f; +>>>>>>> Stashed changes public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; @@ -27,15 +43,27 @@ public override void SetDefaults() Projectile.DamageType = DamageClass.Melee; Projectile.timeLeft = 300; Projectile.extraUpdates = 2; +<<<<<<< Updated upstream Projectile.penetrate = 2; Projectile.ignoreWater = true; Projectile.usesLocalNPCImmunity = true; Projectile.localNPCHitCooldown = -1; +======= + Projectile.penetrate = -1; + Projectile.ignoreWater = true; + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 50; +>>>>>>> Stashed changes Projectile.tileCollide = false; } public override void AI() { +<<<<<<< Updated upstream +======= + Projectile.velocity *= 0.95f; + +>>>>>>> Stashed changes Projectile.ai[0]++; Projectile.ai[1]++; @@ -43,18 +71,32 @@ public override void AI() if (Projectile.ai[0] >= 12) Projectile.tileCollide = true; +<<<<<<< Updated upstream Projectile.rotation += MathHelper.ToRadians(15f); Projectile.alpha -= 5; if (Projectile.alpha < 50) +======= + Projectile.rotation += MathHelper.ToRadians(1f); + Projectile.alpha -= 5; +>>>>>>> Stashed changes { Projectile.alpha = 50; if (Projectile.ai[1] >= 15) { +<<<<<<< Updated upstream for (int i = 1; i <= 6; i++) { Vector2 dustspeed = new Vector2(3f, 3f).RotatedBy(MathHelper.ToRadians(dustvortex)); int d = Dust.NewDust(Projectile.Center, Projectile.width / 2, Projectile.height / 2, DustID.Smoke, dustspeed.X, dustspeed.Y, 200, new Color(232, 251, 250, 200), 1.3f); +======= + scFactor = MathHelper.Lerp(scFactor, 1f, 0.1f); + for (int i = 1; i <= 6; i++) + { + Vector2 dustpos = new Vector2(48f, 48f).RotatedBy(MathHelper.ToRadians(dustvortex + Main.rand.Next(30))); + Vector2 dustspeed = new Vector2(-5f, -5f).RotatedBy(MathHelper.ToRadians(dustvortex + Main.rand.Next(30))); + int d = Dust.NewDust(Projectile.Center + dustpos, Projectile.width / 2, Projectile.height / 2, DustID.Smoke, dustspeed.X, dustspeed.Y, 200, new Color(232, 251, 250, 50), 1.3f); +>>>>>>> Stashed changes Main.dust[d].noGravity = true; Main.dust[d].velocity = dustspeed; dustvortex += 60; @@ -72,6 +114,7 @@ public override void AI() float npcCenterX = npc.position.X + (float)(npc.width / 2); float npcCenterY = npc.position.Y + (float)(npc.height / 2); float npcDistance = Math.Abs(Projectile.position.X + (float)(Projectile.width / 2) - npcCenterX) + Math.Abs(Projectile.position.Y + (float)(Projectile.height / 2) - npcCenterY); +<<<<<<< Updated upstream if (npcDistance < 600f) { if (npc.position.X < projX) @@ -91,13 +134,34 @@ public override void AI() npc.velocity.Y -= 0.05f; } } +======= + if (npcDistance < 300f) + { + float factor = MathHelper.Lerp(1f,0f,CalamityUtils.SineBumpEasing(npcDistance / 300, 1)); + + npc.velocity += npc.DirectionTo(Projectile.Center) * factor * 0.25f; + } + if (npcDistance < 40) npc.velocity *= 0.75f; +>>>>>>> Stashed changes } } } public override bool PreDraw(ref Color lightColor) { +<<<<<<< Updated upstream CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], lightColor); +======= + Asset tex = ModContent.Request(Texture); + + for (int i = 5; i >= 0; i--) + { + float c = Math.Max(i, 1); + + Main.EntitySpriteDraw(tex.Value, Projectile.Center - Main.screenPosition, tex.Frame(), new Color(1f / c, 1f / c, 1f / c, 1f / c), -Projectile.rotation * c, tex.Size() / 2, (float)MathHelper.Lerp(1f, i, scFactor), SpriteEffects.None); + } + +>>>>>>> Stashed changes return false; } @@ -107,8 +171,13 @@ public override void OnKill(int timeLeft) for (int i = 0; i <= 360; i += 3) { +<<<<<<< Updated upstream Vector2 dustspeed = new Vector2(3f, 3f).RotatedBy(MathHelper.ToRadians(i)); int d = Dust.NewDust(Projectile.Center, Projectile.width, Projectile.height, DustID.Smoke, dustspeed.X, dustspeed.Y, 200, new Color(232, 251, 250, 200), 1.4f); +======= + Vector2 dustspeed = new Vector2(12f, 12f).RotatedBy(MathHelper.ToRadians(i)); + int d = Dust.NewDust(Projectile.Center + (dustspeed * 2), Projectile.width, Projectile.height, DustID.Smoke, dustspeed.X, dustspeed.Y, 200, new Color(232, 251, 250, 200), 1.4f); +>>>>>>> Stashed changes Main.dust[d].noGravity = true; Main.dust[d].position = Projectile.Center; Main.dust[d].velocity = dustspeed; diff --git a/en-US.hjson b/en-US.hjson new file mode 100644 index 0000000000..a84ffb8057 --- /dev/null +++ b/en-US.hjson @@ -0,0 +1 @@ +Mods.CalamityMod.Projectiles.WindBladeHoldout.DisplayName: Wind Blade Holdout From 02103014240ab985dac7412dcc400d910ab66142 Mon Sep 17 00:00:00 2001 From: Xhack <72313282+energykid@users.noreply.github.com> Date: Tue, 21 May 2024 14:01:35 -0400 Subject: [PATCH 042/401] Un-exploded the PR request --- .../BaseCustomUseStyleProjectile.cs | 53 ++----------------- 1 file changed, 4 insertions(+), 49 deletions(-) diff --git a/Projectiles/BaseProjectiles/BaseCustomUseStyleProjectile.cs b/Projectiles/BaseProjectiles/BaseCustomUseStyleProjectile.cs index e662a81fae..0b9ec47dfe 100644 --- a/Projectiles/BaseProjectiles/BaseCustomUseStyleProjectile.cs +++ b/Projectiles/BaseProjectiles/BaseCustomUseStyleProjectile.cs @@ -22,10 +22,7 @@ public override void SetDefaults() { Projectile.friendly = true; Projectile.tileCollide = false; -<<<<<<< Updated upstream -======= Projectile.penetrate = -1; ->>>>>>> Stashed changes } public override void OnSpawn(IEntitySource source) @@ -39,11 +36,6 @@ public override void OnSpawn(IEntitySource source) /// public Vector2 Offset = Vector2.Zero; -<<<<<<< Updated upstream -======= - public float RestrikeDelay = 0; - ->>>>>>> Stashed changes /// /// The Player that is using the projectile. /// @@ -100,41 +92,20 @@ public override void OnSpawn(IEntitySource source) /// The origin of the sprite when drawn on your character. /// /// -<<<<<<< Updated upstream - public virtual Vector2 SpriteOrigin() - { - return Projectile.Size / 2; - } -======= public virtual Vector2 SpriteOrigin => Projectile.Size / 2; ->>>>>>> Stashed changes /// /// Helper method for getting the rotation of the sprite plus RotationOffset, without having to make your own local variable every time. /// /// -<<<<<<< Updated upstream - public float FinalRotation() - { - return Projectile.rotation + RotationOffset; - } -======= public float FinalRotation => Projectile.rotation + RotationOffset; ->>>>>>> Stashed changes /// /// Rotation offset for the hitbox that doesn't affect the sprite. /// Useful for if you have, for instance, a sword sprite at a 45 degree angle, and need that to reflect on the hitbox. /// /// -<<<<<<< Updated upstream - public virtual float HitboxRotationOffset() - { - return 0f; - } -======= public virtual float HitboxRotationOffset => 0f; ->>>>>>> Stashed changes /// /// Whether or not the projectile can hit enemies at the current frame. @@ -182,14 +153,8 @@ public virtual void OnEndUse() { } public override void AI() { -<<<<<<< Updated upstream - Projectile.penetrate = 100; -======= Owner.Calamity().mouseWorldListener = true; - RestrikeDelay--; ->>>>>>> Stashed changes - if (Owner.ItemAnimationActive) { Animation++; @@ -238,18 +203,14 @@ public override void AI() } } -<<<<<<< Updated upstream -======= public override bool? CanHitNPC(NPC target) { - bool bb = (target.immune[0] <= 0) && !target.friendly && !target.dontTakeDamage && RestrikeDelay <= 0; - - if (bb) RestrikeDelay = 1; + bool bb = (target.immune[0] <= 0) && !target.friendly && !target.dontTakeDamage; return bb; } ->>>>>>> Stashed changes + public override void ModifyHitNPC(NPC target, ref NPC.HitModifiers modifiers) { modifiers.HitDirectionOverride = Owner.direction; @@ -263,11 +224,8 @@ public override void ModifyHitNPC(NPC target, ref NPC.HitModifiers modifiers) public override void ModifyDamageHitbox(ref Rectangle hitbox) { -<<<<<<< Updated upstream - Vector2 cen = Projectile.Center + new Vector2(HitboxOutset, 0).RotatedBy(FinalRotation() + HitboxRotationOffset()); -======= Vector2 cen = Projectile.Center + new Vector2(HitboxOutset, 0).RotatedBy(FinalRotation + HitboxRotationOffset); ->>>>>>> Stashed changes + hitbox = new Rectangle((int)cen.X - (int)(HitboxSize.X / 2), (int)cen.Y - (int)(HitboxSize.Y / 2), (int)HitboxSize.X, (int)HitboxSize.Y); @@ -283,11 +241,8 @@ public override bool PreDraw(ref Color lightColor) float r = FlipAsSword ? MathHelper.ToRadians(90) : 0f; -<<<<<<< Updated upstream - Main.EntitySpriteDraw(tex.Value, Projectile.Center - Main.screenPosition + new Vector2(0, Owner.gfxOffY), tex.Frame(1, FrameCount, 0, Frame), lightColor, Projectile.rotation + RotationOffset + r, FlipAsSword ? new Vector2(tex.Width() - SpriteOrigin().X, SpriteOrigin().Y) : SpriteOrigin(), Projectile.scale, FlipAsSword ? SpriteEffects.FlipHorizontally : SpriteEffects.None); -======= Main.EntitySpriteDraw(tex.Value, Projectile.Center - Main.screenPosition + new Vector2(0, Owner.gfxOffY), tex.Frame(1, FrameCount, 0, Frame), lightColor, Projectile.rotation + RotationOffset + r, FlipAsSword ? new Vector2(tex.Width() - SpriteOrigin.X, SpriteOrigin.Y) : SpriteOrigin, Projectile.scale, FlipAsSword ? SpriteEffects.FlipHorizontally : SpriteEffects.None); ->>>>>>> Stashed changes + } return false; } From 3ec4f4a059dbfbab95bbb8bd8a0d68702447b20b Mon Sep 17 00:00:00 2001 From: Xhack <72313282+energykid@users.noreply.github.com> Date: Tue, 21 May 2024 14:04:34 -0400 Subject: [PATCH 043/401] Un-exploded the actual Wind Blade holdout and cyclone --- Projectiles/Melee/WindBladeHoldout.cs | 34 --------------- Projectiles/Melee/WindBolt.cs | 62 +-------------------------- 2 files changed, 1 insertion(+), 95 deletions(-) diff --git a/Projectiles/Melee/WindBladeHoldout.cs b/Projectiles/Melee/WindBladeHoldout.cs index 3b3127734f..03c8776d65 100644 --- a/Projectiles/Melee/WindBladeHoldout.cs +++ b/Projectiles/Melee/WindBladeHoldout.cs @@ -21,22 +21,9 @@ public class WindBladeHoldout : BaseCustomUseStyleProjectile, ILocalizedModType public override float HitboxOutset => 60; public override Vector2 HitboxSize => new Vector2(70, 70); - -<<<<<<< Updated upstream - public override float HitboxRotationOffset() - { - return MathHelper.ToRadians(-45); - } - - public override Vector2 SpriteOrigin() - { - return new(0, 80); - } -======= public override float HitboxRotationOffset => MathHelper.ToRadians(-45); public override Vector2 SpriteOrigin => new(0, 80); ->>>>>>> Stashed changes public override void OnSpawn(IEntitySource source) { @@ -47,13 +34,7 @@ public override void OnSpawn(IEntitySource source) public override void UseStyle() { -<<<<<<< Updated upstream - Vector2 mousePos = Main.MouseWorld; - // i don't know how cal handles Main.MouseWorld in netcode. todo: someone fix this up in multiplayer pls - // - ennway -======= Vector2 mousePos = Owner.Calamity().mouseWorld; ->>>>>>> Stashed changes if (mousePos.X < Owner.Center.X) Owner.direction = -1; else Owner.direction = 1; @@ -85,11 +66,7 @@ public override void UseStyle() } if ((int)AnimationProgress > (int)(Owner.itemAnimationMax / 1.5f)) { -<<<<<<< Updated upstream - GeneralParticleHandler.SpawnParticle(new HeavySmokeParticle(Owner.Center + (new Vector2(Main.rand.Next(30, 100), 0).RotatedBy(FinalRotation() + MathHelper.ToRadians(-45))), new Vector2(0, 10 * -Projectile.ai[1] * Owner.direction).RotatedBy(FinalRotation() + MathHelper.ToRadians(-45)), Color.LightSkyBlue, 40, 1f, 0.4f, MathHelper.ToRadians(Main.rand.NextFloat(-10f, 10f)), true)); -======= GeneralParticleHandler.SpawnParticle(new HeavySmokeParticle(Owner.Center + (new Vector2(Main.rand.Next(30, 100), 0).RotatedBy(FinalRotation + MathHelper.ToRadians(-45))), new Vector2(0, 10 * -Projectile.ai[1] * Owner.direction).RotatedBy(FinalRotation + MathHelper.ToRadians(-45)), Color.LightSkyBlue, 40, 1f, 0.4f, MathHelper.ToRadians(Main.rand.NextFloat(-10f, 10f)), true)); ->>>>>>> Stashed changes } float time = (AnimationProgress) - (Owner.itemAnimationMax / 3); @@ -103,34 +80,23 @@ public override void UseStyle() } else if (NumberOfAnimations % 4 == 3) { -<<<<<<< Updated upstream -======= float ProjectileSpeed = 10; int ProjectileDamage = 10; float ProjectileKnockback = Projectile.knockBack; - ->>>>>>> Stashed changes CanHit = true; if ((int)AnimationProgress == 1) { SoundEngine.PlaySound(SoundID.DD2_SkyDragonsFurySwing, Owner.Center); SoundEngine.PlaySound(SoundID.DD2_MonkStaffSwing.WithPitchOffset(-0.4f), Owner.Center); -<<<<<<< Updated upstream -======= Projectile.NewProjectile(new EntitySource_ItemUse(Owner, Owner.HeldItem), Projectile.Hitbox.Center.ToVector2(), new Vector2(ProjectileSpeed, 0).RotatedBy(FinalRotation + MathHelper.ToRadians(-45)), ModContent.ProjectileType(), ProjectileDamage, ProjectileKnockback, Owner.whoAmI); ->>>>>>> Stashed changes } RotationOffset = 0f; if (AnimationProgress < Owner.itemAnimationMax / 3) { Projectile.scale = MathHelper.Lerp(Projectile.scale, 1.5f, 0.4f); -<<<<<<< Updated upstream - float rot = FinalRotation() + MathHelper.ToRadians(-45); -======= float rot = FinalRotation + MathHelper.ToRadians(-45); ->>>>>>> Stashed changes GeneralParticleHandler.SpawnParticle(new HeavySmokeParticle(Owner.Center + new Vector2(105 * Projectile.scale, 0).RotatedBy(rot), new Vector2(5, 0).RotatedBy(rot + MathHelper.ToRadians(Main.rand.NextFloat(-20, 20))), Color.LightSkyBlue, 30, 2f, 0.3f, MathHelper.ToRadians(Main.rand.NextFloat(-10f, 10f)), true)); GeneralParticleHandler.SpawnParticle(new LineParticle(Owner.Center + new Vector2(0, 20).RotatedBy(rot) + new Vector2(45 * Projectile.scale, 0).RotatedBy(rot), new Vector2(5, 0).RotatedBy(rot), false, 30, 1f, Color.LightSkyBlue)); diff --git a/Projectiles/Melee/WindBolt.cs b/Projectiles/Melee/WindBolt.cs index e0b442246b..7c4eb7a110 100644 --- a/Projectiles/Melee/WindBolt.cs +++ b/Projectiles/Melee/WindBolt.cs @@ -1,12 +1,10 @@ using System; using CalamityMod.CalPlayer; using Microsoft.Xna.Framework; -<<<<<<< Updated upstream using Terraria; using Terraria.Audio; using Terraria.ID; using Terraria.ModLoader; -======= using Microsoft.Xna.Framework.Graphics; using ReLogic.Content; using Terraria; @@ -16,7 +14,6 @@ using Terraria.ModLoader; using Terraria.Utilities.Terraria.Utilities; using XPT.Core.Audio.MP3Sharp.Decoding.Decoders.LayerIII; ->>>>>>> Stashed changes namespace CalamityMod.Projectiles.Melee { @@ -24,10 +21,7 @@ public class WindBolt : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Melee"; public int dustvortex = 0; -<<<<<<< Updated upstream -======= public float scFactor = 0f; ->>>>>>> Stashed changes public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; @@ -43,27 +37,17 @@ public override void SetDefaults() Projectile.DamageType = DamageClass.Melee; Projectile.timeLeft = 300; Projectile.extraUpdates = 2; -<<<<<<< Updated upstream - Projectile.penetrate = 2; - Projectile.ignoreWater = true; - Projectile.usesLocalNPCImmunity = true; - Projectile.localNPCHitCooldown = -1; -======= Projectile.penetrate = -1; Projectile.ignoreWater = true; Projectile.usesLocalNPCImmunity = true; Projectile.localNPCHitCooldown = 50; ->>>>>>> Stashed changes Projectile.tileCollide = false; } public override void AI() { -<<<<<<< Updated upstream -======= Projectile.velocity *= 0.95f; ->>>>>>> Stashed changes Projectile.ai[0]++; Projectile.ai[1]++; @@ -71,32 +55,19 @@ public override void AI() if (Projectile.ai[0] >= 12) Projectile.tileCollide = true; -<<<<<<< Updated upstream - Projectile.rotation += MathHelper.ToRadians(15f); - Projectile.alpha -= 5; - if (Projectile.alpha < 50) -======= Projectile.rotation += MathHelper.ToRadians(1f); Projectile.alpha -= 5; ->>>>>>> Stashed changes { Projectile.alpha = 50; if (Projectile.ai[1] >= 15) { -<<<<<<< Updated upstream - - for (int i = 1; i <= 6; i++) - { - Vector2 dustspeed = new Vector2(3f, 3f).RotatedBy(MathHelper.ToRadians(dustvortex)); - int d = Dust.NewDust(Projectile.Center, Projectile.width / 2, Projectile.height / 2, DustID.Smoke, dustspeed.X, dustspeed.Y, 200, new Color(232, 251, 250, 200), 1.3f); -======= scFactor = MathHelper.Lerp(scFactor, 1f, 0.1f); for (int i = 1; i <= 6; i++) { Vector2 dustpos = new Vector2(48f, 48f).RotatedBy(MathHelper.ToRadians(dustvortex + Main.rand.Next(30))); Vector2 dustspeed = new Vector2(-5f, -5f).RotatedBy(MathHelper.ToRadians(dustvortex + Main.rand.Next(30))); int d = Dust.NewDust(Projectile.Center + dustpos, Projectile.width / 2, Projectile.height / 2, DustID.Smoke, dustspeed.X, dustspeed.Y, 200, new Color(232, 251, 250, 50), 1.3f); ->>>>>>> Stashed changes + Main.dust[d].noGravity = true; Main.dust[d].velocity = dustspeed; dustvortex += 60; @@ -114,27 +85,6 @@ public override void AI() float npcCenterX = npc.position.X + (float)(npc.width / 2); float npcCenterY = npc.position.Y + (float)(npc.height / 2); float npcDistance = Math.Abs(Projectile.position.X + (float)(Projectile.width / 2) - npcCenterX) + Math.Abs(Projectile.position.Y + (float)(Projectile.height / 2) - npcCenterY); -<<<<<<< Updated upstream - if (npcDistance < 600f) - { - if (npc.position.X < projX) - { - npc.velocity.X += 0.05f; - } - else - { - npc.velocity.X -= 0.05f; - } - if (npc.position.Y < projY) - { - npc.velocity.Y += 0.05f; - } - else - { - npc.velocity.Y -= 0.05f; - } - } -======= if (npcDistance < 300f) { float factor = MathHelper.Lerp(1f,0f,CalamityUtils.SineBumpEasing(npcDistance / 300, 1)); @@ -142,16 +92,12 @@ public override void AI() npc.velocity += npc.DirectionTo(Projectile.Center) * factor * 0.25f; } if (npcDistance < 40) npc.velocity *= 0.75f; ->>>>>>> Stashed changes } } } public override bool PreDraw(ref Color lightColor) { -<<<<<<< Updated upstream - CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], lightColor); -======= Asset tex = ModContent.Request(Texture); for (int i = 5; i >= 0; i--) @@ -161,7 +107,6 @@ public override bool PreDraw(ref Color lightColor) Main.EntitySpriteDraw(tex.Value, Projectile.Center - Main.screenPosition, tex.Frame(), new Color(1f / c, 1f / c, 1f / c, 1f / c), -Projectile.rotation * c, tex.Size() / 2, (float)MathHelper.Lerp(1f, i, scFactor), SpriteEffects.None); } ->>>>>>> Stashed changes return false; } @@ -171,13 +116,8 @@ public override void OnKill(int timeLeft) for (int i = 0; i <= 360; i += 3) { -<<<<<<< Updated upstream - Vector2 dustspeed = new Vector2(3f, 3f).RotatedBy(MathHelper.ToRadians(i)); - int d = Dust.NewDust(Projectile.Center, Projectile.width, Projectile.height, DustID.Smoke, dustspeed.X, dustspeed.Y, 200, new Color(232, 251, 250, 200), 1.4f); -======= Vector2 dustspeed = new Vector2(12f, 12f).RotatedBy(MathHelper.ToRadians(i)); int d = Dust.NewDust(Projectile.Center + (dustspeed * 2), Projectile.width, Projectile.height, DustID.Smoke, dustspeed.X, dustspeed.Y, 200, new Color(232, 251, 250, 200), 1.4f); ->>>>>>> Stashed changes Main.dust[d].noGravity = true; Main.dust[d].position = Projectile.Center; Main.dust[d].velocity = dustspeed; From 7aa94c1f2eec14a23a4249fa0c0220519a7b06dc Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Tue, 21 May 2024 14:31:47 -0400 Subject: [PATCH 044/401] Fix localization bleed in Wind Blade rework --- .../en-US/Mods.CalamityMod.Projectiles.Melee.hjson | 1 - Projectiles/Melee/WindBladeHoldout.cs | 11 ++++------- en-US.hjson | 1 - 3 files changed, 4 insertions(+), 9 deletions(-) delete mode 100644 en-US.hjson diff --git a/Localization/en-US/Mods.CalamityMod.Projectiles.Melee.hjson b/Localization/en-US/Mods.CalamityMod.Projectiles.Melee.hjson index 79a1e7d286..701a9c1703 100644 --- a/Localization/en-US/Mods.CalamityMod.Projectiles.Melee.hjson +++ b/Localization/en-US/Mods.CalamityMod.Projectiles.Melee.hjson @@ -316,4 +316,3 @@ WulfrumScrewdriverProj.DisplayName: Wulfrum Screwdriver YateveoBloomProj.DisplayName: Yateveo Bloom YinYoDark.DisplayName: Dark Shard YinYoLight.DisplayName: Light Shard -Cyclone.DisplayName: Cyclone diff --git a/Projectiles/Melee/WindBladeHoldout.cs b/Projectiles/Melee/WindBladeHoldout.cs index 03c8776d65..03f7c67d49 100644 --- a/Projectiles/Melee/WindBladeHoldout.cs +++ b/Projectiles/Melee/WindBladeHoldout.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using CalamityMod.CalPlayer; -using CalamityMod.Items.Weapons.Melee; +using CalamityMod.Items.Weapons.Melee; using CalamityMod.Particles; using CalamityMod.Projectiles.BaseProjectiles; using Microsoft.Xna.Framework; @@ -12,12 +6,15 @@ using Terraria.Audio; using Terraria.DataStructures; using Terraria.ID; +using Terraria.Localization; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Melee { public class WindBladeHoldout : BaseCustomUseStyleProjectile, ILocalizedModType { + public override LocalizedText DisplayName => CalamityUtils.GetItemName(); + public override float HitboxOutset => 60; public override Vector2 HitboxSize => new Vector2(70, 70); diff --git a/en-US.hjson b/en-US.hjson deleted file mode 100644 index a84ffb8057..0000000000 --- a/en-US.hjson +++ /dev/null @@ -1 +0,0 @@ -Mods.CalamityMod.Projectiles.WindBladeHoldout.DisplayName: Wind Blade Holdout From 2160d2d7944ad4c522a037234d46e4ce2d98cc07 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Tue, 21 May 2024 17:43:03 -0400 Subject: [PATCH 045/401] Wind Blade "balance" and tooltip Trying to balance this thing on a tier with two very true melee-unfriendly bosses is genuine torture, it'd be great if other testers could help me with this --- Items/Weapons/Melee/WindBlade.cs | 6 +-- ...Mods.CalamityMod.Items.Weapons.Melee.hjson | 7 ++- Projectiles/Melee/WindBladeHoldout.cs | 11 ++++- Projectiles/Melee/WindBolt.cs | 43 +++++++++++++------ 4 files changed, 49 insertions(+), 18 deletions(-) diff --git a/Items/Weapons/Melee/WindBlade.cs b/Items/Weapons/Melee/WindBlade.cs index 24f1c6a98b..2f9aa92a91 100644 --- a/Items/Weapons/Melee/WindBlade.cs +++ b/Items/Weapons/Melee/WindBlade.cs @@ -17,11 +17,11 @@ public override void SetDefaults() { Item.width = 58; Item.height = 58; - Item.damage = 41; + Item.damage = 42; Item.DamageType = DamageClass.Melee; - Item.useAnimation = 20; + Item.useAnimation = 18; Item.useStyle = ItemUseStyleID.Swing; - Item.useTime = 20; + Item.useTime = 18; Item.useTurn = true; Item.knockBack = 5f; Item.autoReuse = true; diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson index afeab0b76b..7fb4b0572d 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson @@ -1390,7 +1390,12 @@ VulcaniteLance: { WindBlade: { DisplayName: Wind Blade - Tooltip: Fires cyclones that suck enemies in + Tooltip: + ''' + Perform a three swing combo which ends by thrusting the blade forwards + Thrusting the blade launches an expanding cyclone that lingers + Cyclones pull enemies in, or pulls itself towards bosses + ''' } WulfrumScrewdriver: { diff --git a/Projectiles/Melee/WindBladeHoldout.cs b/Projectiles/Melee/WindBladeHoldout.cs index 03f7c67d49..50d4a88d50 100644 --- a/Projectiles/Melee/WindBladeHoldout.cs +++ b/Projectiles/Melee/WindBladeHoldout.cs @@ -22,6 +22,13 @@ public class WindBladeHoldout : BaseCustomUseStyleProjectile, ILocalizedModType public override Vector2 SpriteOrigin => new(0, 80); + public override void SetDefaults() + { + base.SetDefaults(); + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 10; + } + public override void OnSpawn(IEntitySource source) { Projectile.scale = 0f; @@ -78,8 +85,8 @@ public override void UseStyle() else if (NumberOfAnimations % 4 == 3) { float ProjectileSpeed = 10; - int ProjectileDamage = 10; - float ProjectileKnockback = Projectile.knockBack; + int ProjectileDamage = (int)(Projectile.damage * 0.3f); + float ProjectileKnockback = (int)(Projectile.knockBack * 0.5f); CanHit = true; if ((int)AnimationProgress == 1) { diff --git a/Projectiles/Melee/WindBolt.cs b/Projectiles/Melee/WindBolt.cs index 7c4eb7a110..08ec3d63f3 100644 --- a/Projectiles/Melee/WindBolt.cs +++ b/Projectiles/Melee/WindBolt.cs @@ -30,8 +30,8 @@ public override void SetStaticDefaults() public override void SetDefaults() { - Projectile.width = 36; - Projectile.height = 36; + Projectile.width = 40; + Projectile.height = 40; Projectile.alpha = 255; Projectile.friendly = true; Projectile.DamageType = DamageClass.Melee; @@ -40,13 +40,13 @@ public override void SetDefaults() Projectile.penetrate = -1; Projectile.ignoreWater = true; Projectile.usesLocalNPCImmunity = true; - Projectile.localNPCHitCooldown = 50; + Projectile.localNPCHitCooldown = 8 * Projectile.MaxUpdates; Projectile.tileCollide = false; } public override void AI() { - Projectile.velocity *= 0.95f; + Projectile.velocity *= 0.98f; Projectile.ai[0]++; Projectile.ai[1]++; @@ -80,18 +80,27 @@ public override void AI() float projY = Projectile.Center.Y; foreach (var npc in Main.ActiveNPCs) { - if (npc.CanBeChasedBy(Projectile, false) && Collision.CanHit(Projectile.Center, 1, 1, npc.Center, 1, 1) && !CalamityPlayer.areThereAnyDamnBosses) + if (npc.CanBeChasedBy(Projectile, false) && Collision.CanHit(Projectile.Center, 1, 1, npc.Center, 1, 1)) { - float npcCenterX = npc.position.X + (float)(npc.width / 2); - float npcCenterY = npc.position.Y + (float)(npc.height / 2); - float npcDistance = Math.Abs(Projectile.position.X + (float)(Projectile.width / 2) - npcCenterX) + Math.Abs(Projectile.position.Y + (float)(Projectile.height / 2) - npcCenterY); - if (npcDistance < 300f) + if (!CalamityPlayer.areThereAnyDamnBosses) // Pulls enemies in while no boss is alive { - float factor = MathHelper.Lerp(1f,0f,CalamityUtils.SineBumpEasing(npcDistance / 300, 1)); + float npcCenterX = npc.position.X + (float)(npc.width / 2); + float npcCenterY = npc.position.Y + (float)(npc.height / 2); + float npcDistance = Math.Abs(Projectile.position.X + (float)(Projectile.width / 2) - npcCenterX) + Math.Abs(Projectile.position.Y + (float)(Projectile.height / 2) - npcCenterY); + if (npcDistance < 320f) + { + float factor = MathHelper.Lerp(1f, 0f, CalamityUtils.SineBumpEasing(npcDistance / 300, 1)); - npc.velocity += npc.DirectionTo(Projectile.Center) * factor * 0.25f; + npc.velocity += npc.DirectionTo(Projectile.Center) * factor * 0.25f; + } + if (npcDistance < 40) + npc.velocity *= 0.75f; + } + else // Pulls itself toward enemies while a boss is alive so that the gimmick isn't entirely lost + { + if (Math.Abs(Projectile.velocity.X) < 1.5f && Math.Abs(Projectile.velocity.Y) < 1.5f) + CalamityUtils.HomeInOnNPC(Projectile, false, 320f, 1.5f, 20f); } - if (npcDistance < 40) npc.velocity *= 0.75f; } } } @@ -110,6 +119,16 @@ public override bool PreDraw(ref Color lightColor) return false; } + public override void ModifyDamageHitbox(ref Rectangle hitbox) + { + // The hitbox gets bigger over time, because the vortex visually grows + int sizeIncrease = (int)(Projectile.ai[0] * 0.3f); + hitbox.Inflate(sizeIncrease, sizeIncrease); + } + + // The vortex slows down on enemies hits, so that it is easier for it to linger on top of stuff + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) => Projectile.velocity *= 0.5f; + public override void OnKill(int timeLeft) { SoundEngine.PlaySound(SoundID.Item60 with { Volume = SoundID.Item60.Volume * 0.6f }, Projectile.Center); From 4ed05c8a641a4e80b42b5afb49927bda9095ece4 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Tue, 21 May 2024 17:44:50 -0400 Subject: [PATCH 046/401] Killing localization files with my mind --- Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson index 7fb4b0572d..cebfe4bd20 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson @@ -1394,7 +1394,7 @@ WindBlade: { ''' Perform a three swing combo which ends by thrusting the blade forwards Thrusting the blade launches an expanding cyclone that lingers - Cyclones pull enemies in, or pulls itself towards bosses + Cyclones pull enemies in, or pulls itself towards bosses ''' } From 85c92575851827bcd1812b59f235477b7dbe3ed3 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Tue, 21 May 2024 18:03:45 -0400 Subject: [PATCH 047/401] Sulphurous armor nerf --- CalPlayer/CalamityPlayerHitHurt.cs | 4 ++-- CalPlayer/CalamityPlayerOnHit.cs | 2 +- Items/Armor/Sulphurous/SulphurousBreastplate.cs | 4 ++-- Items/Armor/Sulphurous/SulphurousHelmet.cs | 2 +- .../en-US/Mods.CalamityMod.Items.Armor.PreHardmode.hjson | 4 ++-- NPCs/CalamityGlobalNPC.cs | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CalPlayer/CalamityPlayerHitHurt.cs b/CalPlayer/CalamityPlayerHitHurt.cs index 30b3177ccb..16e9b7e6a8 100644 --- a/CalPlayer/CalamityPlayerHitHurt.cs +++ b/CalPlayer/CalamityPlayerHitHurt.cs @@ -1233,13 +1233,13 @@ public override void OnHitByProjectile(Projectile proj, Player.HurtInfo hurtInfo if (Main.player[proj.owner] is null) { if (!Main.npc[proj.owner].friendly) - Main.npc[proj.owner].AddBuff(BuffID.Poisoned, 120); + Main.npc[proj.owner].AddBuff(BuffID.Poisoned, 90); } else { Player p = Main.player[proj.owner]; if (p.hostile && Player.hostile && (Player.team != p.team || p.team == 0)) - p.AddBuff(BuffID.Poisoned, 120); + p.AddBuff(BuffID.Poisoned, 90); } } diff --git a/CalPlayer/CalamityPlayerOnHit.cs b/CalPlayer/CalamityPlayerOnHit.cs index 42a6b1c2af..3122d55209 100644 --- a/CalPlayer/CalamityPlayerOnHit.cs +++ b/CalPlayer/CalamityPlayerOnHit.cs @@ -1266,7 +1266,7 @@ public void NPCDebuffs(NPC target, bool melee, bool ranged, bool magic, bool sum if (omegaBlueChestplate) target.AddBuff(BuffType(), 180); if (sulphurSet) - target.AddBuff(BuffID.Poisoned, 120); + target.AddBuff(BuffID.Poisoned, 90); if (abyssalAmulet) { CalamityUtils.Inflict246DebuffsNPC(target, BuffType()); diff --git a/Items/Armor/Sulphurous/SulphurousBreastplate.cs b/Items/Armor/Sulphurous/SulphurousBreastplate.cs index ee6c63df21..6848c2825b 100644 --- a/Items/Armor/Sulphurous/SulphurousBreastplate.cs +++ b/Items/Armor/Sulphurous/SulphurousBreastplate.cs @@ -22,8 +22,8 @@ public override void SetDefaults() public override void UpdateEquip(Player player) { - player.GetDamage() += 0.08f; - player.GetCritChance() += 5; + player.GetDamage() += 0.06f; + player.GetCritChance() += 4; } public override void AddRecipes() diff --git a/Items/Armor/Sulphurous/SulphurousHelmet.cs b/Items/Armor/Sulphurous/SulphurousHelmet.cs index b2b6e7b765..f7375d88c0 100644 --- a/Items/Armor/Sulphurous/SulphurousHelmet.cs +++ b/Items/Armor/Sulphurous/SulphurousHelmet.cs @@ -33,7 +33,7 @@ public override void UpdateArmorSet(Player player) var modPlayer = player.Calamity(); modPlayer.sulphurSet = true; player.GetJumpState().Enable(); - modPlayer.rogueStealthMax += 0.7f; + modPlayer.rogueStealthMax += 0.65f; modPlayer.wearingRogueArmor = true; player.ignoreWater = true; } diff --git a/Localization/en-US/Mods.CalamityMod.Items.Armor.PreHardmode.hjson b/Localization/en-US/Mods.CalamityMod.Items.Armor.PreHardmode.hjson index b1f4f411f9..ab21fcb087 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Armor.PreHardmode.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Armor.PreHardmode.hjson @@ -186,7 +186,7 @@ StatigelHeadSummon: { SulphurousBreastplate: { DisplayName: Sulphurous Breastplate - Tooltip: 8% increased rogue damage and 5% increased rogue critical strike chance + Tooltip: 6% increased rogue damage and 4% increased rogue critical strike chance } SulphurousHelmet: { @@ -199,7 +199,7 @@ SulphurousHelmet: { ''' SetBonus: ''' - +70 maximum stealth + +65 maximum stealth Attacking and being attacked by enemies inflicts poison Grants an additional jump that summons a sulphurous bubble Provides increased underwater mobility and reduces the severity of the sulphuric waters diff --git a/NPCs/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index cccd363c25..5cb59af057 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -5255,7 +5255,7 @@ public override void OnHitPlayer(NPC npc, Player target, Player.HurtInfo hurtInf return; if (target.Calamity().sulphurSet) - npc.AddBuff(BuffID.Poisoned, 120); + npc.AddBuff(BuffID.Poisoned, 90); if (target.Calamity().snowman) { From 95e37ca9cfa5331112fe699b2f881395422a27c2 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Tue, 21 May 2024 18:17:16 -0400 Subject: [PATCH 048/401] Fixed Hardened Honeycomb spawning twice as many projectiles as intended when hitting enemies --- Projectiles/Rogue/Honeycomb.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Projectiles/Rogue/Honeycomb.cs b/Projectiles/Rogue/Honeycomb.cs index 5e3ca0a392..657b228b40 100644 --- a/Projectiles/Rogue/Honeycomb.cs +++ b/Projectiles/Rogue/Honeycomb.cs @@ -71,6 +71,11 @@ public override void OnKill(int timeLeft) public void SpawnProjectiles() { + // If it's already spawned projectiles, don't do anything. Prevents it from spawning double the projectile amount when hitting enemies. + if (Projectile.ai[1] == 1f) + return; + + Projectile.ai[1] = 1f; Player player = Main.player[Main.myPlayer]; int fragAmt = 2; for (int i = 0; i < fragAmt; i++) From 45fe6e5aba8d879ffcc57b472cda75565e9e5a39 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Tue, 21 May 2024 18:41:23 -0400 Subject: [PATCH 049/401] Per old community suggestion, Guardians no longer enrage outside the Hallow or Underworld --- .../ProfanedGuardianCommander.cs | 56 +++++++------------ .../ProfanedGuardianDefender.cs | 34 +++-------- .../ProfanedGuardianHealer.cs | 26 ++------- 3 files changed, 31 insertions(+), 85 deletions(-) diff --git a/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs b/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs index d85a7326d6..a4279922e8 100644 --- a/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs +++ b/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs @@ -33,7 +33,6 @@ public class ProfanedGuardianCommander : ModNPC { private int spearType = 0; private int healTimer = 0; - private int biomeEnrageTimer = CalamityGlobalNPC.biomeEnrageTimerMax; private const float TimeForShieldDespawn = 120f; public static readonly SoundStyle HolyRaySound = new("CalamityMod/Sounds/Custom/ProfanedGuardians/GuardianRay") { Volume = 1.25f }; public static readonly SoundStyle DashSound = new("CalamityMod/Sounds/Custom/ProfanedGuardians/GuardianDash"); @@ -105,7 +104,6 @@ public override void SendExtraAI(BinaryWriter writer) { writer.Write(spearType); writer.Write(healTimer); - writer.Write(biomeEnrageTimer); writer.Write(NPC.chaseable); writer.Write(NPC.localAI[0]); writer.Write(NPC.localAI[1]); @@ -119,7 +117,6 @@ public override void ReceiveExtraAI(BinaryReader reader) { spearType = reader.ReadInt32(); healTimer = reader.ReadInt32(); - biomeEnrageTimer = reader.ReadInt32(); NPC.chaseable = reader.ReadBoolean(); NPC.localAI[0] = reader.ReadSingle(); NPC.localAI[1] = reader.ReadSingle(); @@ -334,21 +331,6 @@ public override void AI() if (NPC.ai[3] < 0f) NPC.ai[3] = 0f; - // Become immune over time if target isn't in hell or hallow - bool isHoly = player.ZoneHallow; - bool isHell = player.ZoneUnderworldHeight; - if (!isHoly && !isHell && !bossRush) - { - if (biomeEnrageTimer > 0) - biomeEnrageTimer--; - else - NPC.Calamity().CurrentlyEnraged = true; - } - else - biomeEnrageTimer = CalamityGlobalNPC.biomeEnrageTimerMax; - - bool biomeEnraged = biomeEnrageTimer <= 0; - bool phase1 = healerAlive || defenderAlive; NPC.chaseable = !phase1; @@ -373,7 +355,7 @@ public override void AI() float goLowOrHighDistance = 540f; // Side swap variables for Phase 2 - float defenderCommanderGuardPhase2Duration = (bossRush || biomeEnraged) ? 420f : death ? 480f : revenge ? 510f : expertMode ? 540f : 600f; + float defenderCommanderGuardPhase2Duration = bossRush ? 420f : death ? 480f : revenge ? 510f : expertMode ? 540f : 600f; float moveToOtherSideInPhase2GateValue = defenderCommanderGuardPhase2Duration - 120f; float timeBeforeMoveToOtherSideInPhase2Reset = moveToOtherSideInPhase2GateValue * 2f; float totalGoLowDurationPhase2 = 210f; @@ -381,13 +363,13 @@ public override void AI() // Charge variables float chargeVelocityMult = 0.25f; - float maxChargeVelocity = (bossRush || biomeEnraged) ? 32f : death ? 28f : revenge ? 26f : expertMode ? 24f : 20f; + float maxChargeVelocity = bossRush ? 32f : death ? 28f : revenge ? 26f : expertMode ? 24f : 20f; if (Main.getGoodWorld) maxChargeVelocity *= 1.15f; if (CalamityWorld.LegendaryMode && revenge) maxChargeVelocity *= 2f; - float inertia = (bossRush || biomeEnraged) ? 40f : death ? 45f : revenge ? 47f : expertMode ? 50f : 55f; + float inertia = bossRush ? 40f : death ? 45f : revenge ? 47f : expertMode ? 50f : 55f; if (lifeRatio < 0.5f) inertia *= 0.8f; if (!phase1) @@ -470,7 +452,7 @@ public override void AI() if (!goLow && !goLowPhase2 && !goHigh) calamityGlobalNPC.newAI[0] = -NPC.direction; - float velocity = (bossRush || biomeEnraged) ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f; + float velocity = bossRush ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f; if (Main.getGoodWorld) velocity *= 1.25f; if (healerAlive) @@ -507,7 +489,7 @@ public override void AI() Vector2 targetVector = destination - NPC.Center; Vector2 desiredVelocity = targetVector.SafeNormalize(new Vector2(NPC.direction, 0f)) * velocity; - float phaseGateValue = (bossRush || biomeEnraged) ? 50f : death ? 66f : revenge ? 75f : expertMode ? 83f : 100f; + float phaseGateValue = bossRush ? 50f : death ? 66f : revenge ? 75f : expertMode ? 83f : 100f; bool continueShootingProjectiles = phase1 || (NPC.ai[2] < (phaseGateValue * 5f)); if (continueShootingProjectiles) @@ -521,7 +503,7 @@ public override void AI() // Alternate between firing profaned spears and holy fire // Shoot holy blasts in final phase NPC.ai[2] += 1f; - float projectileShootGateValue = (bossRush || biomeEnraged) ? 40f : death ? 60f : revenge ? 90f : expertMode ? 100f : 150f; + float projectileShootGateValue = bossRush ? 40f : death ? 60f : revenge ? 90f : expertMode ? 100f : 150f; if (NPC.ai[2] % projectileShootGateValue == 0f) { if (phase1) @@ -535,7 +517,7 @@ public override void AI() } bool shootSpear = NPC.ai[2] % (projectileShootGateValue * 2f) == 0f; - float projectileVelocity = (bossRush || biomeEnraged) ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f; + float projectileVelocity = bossRush ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f; Vector2 finalProjectileVelocity = Vector2.Normalize(player.Center - shootFrom) * projectileVelocity; int type = shootSpear ? ModContent.ProjectileType() : ModContent.ProjectileType(); int damage = NPC.GetProjectileDamage(type); @@ -548,8 +530,8 @@ public override void AI() if (fireExtraProjectiles && shootSpear) { - int baseProjectileAmt = (bossRush || biomeEnraged) ? 4 : 2; - int spread = (bossRush || biomeEnraged) ? 18 : 10; + int baseProjectileAmt = bossRush ? 4 : 2; + int spread = bossRush ? 18 : 10; float rotation = MathHelper.ToRadians(spread); for (int i = 0; i < baseProjectileAmt; i++) { @@ -568,7 +550,7 @@ public override void AI() else { // Shoot holy blasts - float holyBlastVelocity = (bossRush || biomeEnraged) ? 20f : death ? 18f : revenge ? 17f : expertMode ? 16f : 14f; + float holyBlastVelocity = bossRush ? 20f : death ? 18f : revenge ? 17f : expertMode ? 16f : 14f; int projTimeLeft = (int)(2000f / holyBlastVelocity); Vector2 finalHolyBlastVelocity = Vector2.Normalize(player.Center - shootFrom) * holyBlastVelocity; if (Main.netMode != NetmodeID.MultiplayerClient) @@ -681,7 +663,7 @@ public override void AI() NPC.spriteDirection = Math.Sign(NPC.velocity.X); NPC.ai[1] += 1f; - float phaseGateValue = (bossRush || biomeEnraged) ? 90f : death ? 100f : revenge ? 110f : expertMode ? 120f : 135f; + float phaseGateValue = bossRush ? 90f : death ? 100f : revenge ? 110f : expertMode ? 120f : 135f; if (NPC.ai[1] >= phaseGateValue) { NPC.ai[0] = 3f; @@ -702,7 +684,7 @@ public override void AI() // Accelerate if (NPC.velocity.Length() < maxChargeVelocity) { - float velocityMult = (bossRush || biomeEnraged) ? 1.053333f : death ? 1.05037f : revenge ? 1.047407f : expertMode ? 1.044444f : 1.04f; + float velocityMult = bossRush ? 1.053333f : death ? 1.05037f : revenge ? 1.047407f : expertMode ? 1.044444f : 1.04f; NPC.velocity = targetVector * (NPC.velocity.Length() * velocityMult); if (NPC.velocity.Length() > maxChargeVelocity) { @@ -790,7 +772,7 @@ public override void AI() bool targetRanAwayAndWillNowBeFucked = NPC.ai[2] == 1f; bool boostVelocityToCatchUp = NPC.ai[1] == 0f || targetRanAwayAndWillNowBeFucked; - float velocity = (bossRush || biomeEnraged) ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f; + float velocity = bossRush ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f; if (Main.getGoodWorld) velocity *= 1.25f; if (boostVelocityToCatchUp) @@ -802,7 +784,7 @@ public override void AI() Vector2 desiredVelocity = targetVector.SafeNormalize(new Vector2(NPC.direction, 0f)) * velocity; float totalSpears = 12f; - float shootDuration = (bossRush || biomeEnraged) ? 240f : death ? 280f : revenge ? 300f : expertMode ? 320f : 360f; + float shootDuration = bossRush ? 240f : death ? 280f : revenge ? 300f : expertMode ? 320f : 360f; float dontShootTime = shootDuration * 0.3f; float phaseGateValue = dontShootTime + shootDuration; @@ -847,7 +829,7 @@ public override void AI() } else if (NPC.ai[1] % spearShootDivisor == 0f) { - float spearVelocity = (bossRush || biomeEnraged) ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f; + float spearVelocity = bossRush ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f; if (Main.getGoodWorld) spearVelocity *= 1.25f; if (boostVelocityToCatchUp) @@ -865,8 +847,8 @@ public override void AI() if (NPC.ai[1] % (spearShootDivisor * 3) == 0f || targetRanAwayAndWillNowBeFucked) { knockbackVelocity *= 2f; - int baseProjectileAmt = (bossRush || biomeEnraged) ? 8 : expertMode ? 6 : 4; - int spread = (bossRush || biomeEnraged) ? 60 : expertMode ? 50 : 40; + int baseProjectileAmt = bossRush ? 8 : expertMode ? 6 : 4; + int spread = bossRush ? 60 : expertMode ? 50 : 40; float rotation = MathHelper.ToRadians(spread); for (int i = 0; i < baseProjectileAmt; i++) { @@ -902,7 +884,7 @@ public override void AI() } float laserGateValue = 120f; - float velocity = (bossRush || biomeEnraged) ? 4.5f : death ? 4f : revenge ? 3.75f : expertMode ? 3.5f : 3f; + float velocity = bossRush ? 4.5f : death ? 4f : revenge ? 3.75f : expertMode ? 3.5f : 3f; if (NPC.ai[1] < laserGateValue) velocity *= 6f; if (Main.getGoodWorld) @@ -958,7 +940,7 @@ public override void AI() { if (NPC.ai[2] == laserGateValue) { - float rotation = (bossRush || biomeEnraged) ? 435f : death ? 445f : revenge ? 450f : expertMode ? 455f : 465f; + float rotation = bossRush ? 435f : death ? 445f : revenge ? 450f : expertMode ? 455f : 465f; if (Main.player[Main.myPlayer].active && !Main.player[Main.myPlayer].dead && Vector2.Distance(Main.player[Main.myPlayer].Center, NPC.Center) < 2800f) SoundEngine.PlaySound(HolyRaySound, Main.LocalPlayer.Center); diff --git a/NPCs/ProfanedGuardians/ProfanedGuardianDefender.cs b/NPCs/ProfanedGuardians/ProfanedGuardianDefender.cs index dc0fba164b..8a4f75cfb1 100644 --- a/NPCs/ProfanedGuardians/ProfanedGuardianDefender.cs +++ b/NPCs/ProfanedGuardians/ProfanedGuardianDefender.cs @@ -24,7 +24,6 @@ namespace CalamityMod.NPCs.ProfanedGuardians public class ProfanedGuardianDefender : ModNPC { private int healTimer = 0; - private int biomeEnrageTimer = CalamityGlobalNPC.biomeEnrageTimerMax; private const float TimeForShieldDespawn = 120f; public static readonly SoundStyle DashSound = new("CalamityMod/Sounds/Custom/ProfanedGuardians/GuardianDash"); public static readonly SoundStyle RockShieldSpawnSound = new("CalamityMod/Sounds/Custom/ProfanedGuardians/GuardianRockShieldActivate"); @@ -100,7 +99,6 @@ public override void SetBestiary(BestiaryDatabase database, BestiaryEntry bestia public override void SendExtraAI(BinaryWriter writer) { writer.Write(healTimer); - writer.Write(biomeEnrageTimer); writer.Write(NPC.chaseable); writer.Write(NPC.localAI[0]); writer.Write(NPC.localAI[1]); @@ -111,7 +109,6 @@ public override void SendExtraAI(BinaryWriter writer) public override void ReceiveExtraAI(BinaryReader reader) { healTimer = reader.ReadInt32(); - biomeEnrageTimer = reader.ReadInt32(); NPC.chaseable = reader.ReadBoolean(); NPC.localAI[0] = reader.ReadSingle(); NPC.localAI[1] = reader.ReadSingle(); @@ -250,28 +247,13 @@ public override void AI() bool expertMode = Main.expertMode || bossRush; bool revenge = CalamityWorld.revenge || bossRush; bool death = CalamityWorld.death || bossRush; - bool isHoly = player.ZoneHallow; - bool isHell = player.ZoneUnderworldHeight; - - // Become immune over time if target isn't in hell or hallow - if (!isHoly && !isHell && !bossRush) - { - if (biomeEnrageTimer > 0) - biomeEnrageTimer--; - else - NPC.Calamity().CurrentlyEnraged = true; - } - else - biomeEnrageTimer = CalamityGlobalNPC.biomeEnrageTimerMax; - - bool biomeEnraged = biomeEnrageTimer <= 0; bool phase1 = healerAlive; NPC.chaseable = !phase1; // Phase durations - float commanderGuardPhase2Duration = (bossRush || biomeEnraged) ? 420f : death ? 480f : revenge ? 510f : expertMode ? 540f : 600f; + float commanderGuardPhase2Duration = bossRush ? 420f : death ? 480f : revenge ? 510f : expertMode ? 540f : 600f; float timeBeforeRocksRespawnInPhase2 = 90f; float throwRocksGateValue = 60f; @@ -280,7 +262,7 @@ public override void AI() // Charge variables float chargeVelocityMult = 0.25f; - float maxChargeVelocity = (bossRush || biomeEnraged) ? 25f : death ? 22f : revenge ? 20.5f : expertMode ? 19f : 16f; + float maxChargeVelocity = bossRush ? 25f : death ? 22f : revenge ? 20.5f : expertMode ? 19f : 16f; if (Main.getGoodWorld) maxChargeVelocity *= 1.15f; @@ -400,7 +382,7 @@ public override void AI() } } - float moveVelocity = (bossRush || biomeEnraged) ? 24f : death ? 22f : revenge ? 21f : expertMode ? 20f : 18f; + float moveVelocity = bossRush ? 24f : death ? 22f : revenge ? 21f : expertMode ? 20f : 18f; if (Main.getGoodWorld) moveVelocity *= 1.25f; if (healerAlive) @@ -450,7 +432,7 @@ public override void AI() // Lay a holy bomb every once in a while in phase 1 and while not doing the laser attack if (!commanderUsingLaser) { - float projectileShootGateValue = (bossRush || biomeEnraged) ? 420f : death ? 480f : revenge ? 510f : expertMode ? 540f : 600f; + float projectileShootGateValue = bossRush ? 420f : death ? 480f : revenge ? 510f : expertMode ? 540f : 600f; NPC.ai[1] += 1f; if (NPC.ai[1] >= projectileShootGateValue) { @@ -520,7 +502,7 @@ public override void AI() float shootMoltenBlastsGateValue = commanderGuardPhase2Duration / moltenBlastsDivisor; if (NPC.ai[1] % shootMoltenBlastsGateValue == 0f && !commanderGoingLowOrHighInPhase2) { - float moltenBlastVelocity = (bossRush || biomeEnraged) ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f; + float moltenBlastVelocity = bossRush ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f; int projTimeLeft = (int)(2400f / moltenBlastVelocity); Vector2 velocity = Vector2.Normalize(player.Center - shootFrom) * moltenBlastVelocity; if (Main.netMode != NetmodeID.MultiplayerClient) @@ -627,7 +609,7 @@ public override void AI() NPC.spriteDirection = Math.Sign(NPC.velocity.X); NPC.ai[1] += 1f; - float phaseGateValue = (bossRush || biomeEnraged) ? 120f : death ? 140f : revenge ? 150f : expertMode ? 160f : 180f; + float phaseGateValue = bossRush ? 120f : death ? 140f : revenge ? 150f : expertMode ? 160f : 180f; if (NPC.ai[1] >= phaseGateValue) { NPC.ai[0] = 3f; @@ -648,7 +630,7 @@ public override void AI() // Accelerate if (NPC.velocity.Length() < maxChargeVelocity) { - float velocityMult = (bossRush || biomeEnraged) ? 1.04f : death ? 1.036667f : revenge ? 1.035f : expertMode ? 1.033333f : 1.03f; + float velocityMult = bossRush ? 1.04f : death ? 1.036667f : revenge ? 1.035f : expertMode ? 1.033333f : 1.03f; NPC.velocity = targetVector * (NPC.velocity.Length() * velocityMult); if (NPC.velocity.Length() > maxChargeVelocity) { @@ -660,7 +642,7 @@ public override void AI() else { // Charge towards target - float inertia = (bossRush || biomeEnraged) ? 57f : death ? 63f : revenge ? 66f : expertMode ? 69f : 75f; + float inertia = bossRush ? 57f : death ? 63f : revenge ? 66f : expertMode ? 69f : 75f; NPC.velocity = (NPC.velocity * (inertia - 1f) + targetVector * (NPC.velocity.Length() + (0.111111117f * inertia))) / inertia; } diff --git a/NPCs/ProfanedGuardians/ProfanedGuardianHealer.cs b/NPCs/ProfanedGuardians/ProfanedGuardianHealer.cs index cfc275078d..a59ec9f297 100644 --- a/NPCs/ProfanedGuardians/ProfanedGuardianHealer.cs +++ b/NPCs/ProfanedGuardians/ProfanedGuardianHealer.cs @@ -39,7 +39,6 @@ private float AITimer set => NPC.ai[3] = value; } - private int biomeEnrageTimer = CalamityGlobalNPC.biomeEnrageTimerMax; public static Asset Texture_Glow; public static Asset Texture_Glow2; @@ -116,13 +115,11 @@ public override void SetBestiary(BestiaryDatabase database, BestiaryEntry bestia public override void SendExtraAI(BinaryWriter writer) { - writer.Write(biomeEnrageTimer); writer.Write(NPC.localAI[0]); } public override void ReceiveExtraAI(BinaryReader reader) { - biomeEnrageTimer = reader.ReadInt32(); NPC.localAI[0] = reader.ReadSingle(); } @@ -172,8 +169,6 @@ public override void AI() bool expertMode = Main.expertMode || bossRush; bool revenge = CalamityWorld.revenge || bossRush; bool death = CalamityWorld.death || bossRush; - bool isHoly = player.ZoneHallow; - bool isHell = player.ZoneUnderworldHeight; // Percent life remaining float lifeRatio = NPC.life / (float)NPC.lifeMax; @@ -183,19 +178,6 @@ public override void AI() if (NPC.ai[0] >= 300f) NPC.ai[1] = 1f; - // Become immune over time if target isn't in hell or hallow - if (!isHoly && !isHell && !BossRushEvent.BossRushActive) - { - if (biomeEnrageTimer > 0) - biomeEnrageTimer--; - else - NPC.Calamity().CurrentlyEnraged = true; - } - else - biomeEnrageTimer = CalamityGlobalNPC.biomeEnrageTimerMax; - - bool biomeEnraged = biomeEnrageTimer <= 0; - // Direction if (Math.Abs(NPC.Center.X - player.Center.X) > 10f) { @@ -235,7 +217,7 @@ public override void AI() } bool useCrystalShards = AIState == (float)Phase.CrystalShards; - float velocity = useCrystalShards ? ((bossRush || biomeEnraged) ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f) : (Main.npc[CalamityGlobalNPC.doughnutBoss].velocity.Length() + 5f); + float velocity = useCrystalShards ? (bossRush ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f) : (Main.npc[CalamityGlobalNPC.doughnutBoss].velocity.Length() + 5f); if (Main.getGoodWorld) velocity *= 1.25f; @@ -323,7 +305,7 @@ public override void AI() { int type = ModContent.ProjectileType(); int damage = NPC.GetProjectileDamage(type); - int totalProjectiles = biomeEnraged ? 18 : death ? 16 : revenge ? 14 : expertMode ? 12 : 10; + int totalProjectiles = bossRush ? 18 : death ? 16 : revenge ? 14 : expertMode ? 12 : 10; float speedX = -12f; float speedAdjustment = Math.Abs(speedX * 2f / (totalProjectiles - 1)); float speedY = -4f; @@ -362,7 +344,7 @@ public override void AI() { SoundEngine.PlaySound(SoundID.DD2_BetsyFireballImpact, shootFrom); - int totalFlameProjectiles = biomeEnraged ? 20 : 16; + int totalFlameProjectiles = bossRush ? 20 : 16; int totalRings = revenge ? 3 : 2; int healingStarChance = revenge ? 8 : expertMode ? 6 : 4; double radians = MathHelper.TwoPi / totalFlameProjectiles; @@ -423,7 +405,7 @@ public override void AI() // Move towards a location above the player if (distanceFromDestination.Length() > idealDistanceFromDestination) { - float inertia = (bossRush || biomeEnraged) ? 28f : death ? 32f : revenge ? 34f : expertMode ? 36f : 40f; + float inertia = bossRush ? 28f : death ? 32f : revenge ? 34f : expertMode ? 36f : 40f; if (lifeRatio < 0.5f) inertia *= 0.8f; if (Main.getGoodWorld) From 4b326c0767229c6f26922d292e573ba79ae7652d Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Wed, 22 May 2024 02:57:46 -0500 Subject: [PATCH 050/401] Fixed Deerclops Ice Spikes not dealing damage in Rev. --- Projectiles/CalamityGlobalProjectile.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Projectiles/CalamityGlobalProjectile.cs b/Projectiles/CalamityGlobalProjectile.cs index 45f9f892d1..0cb47d3729 100644 --- a/Projectiles/CalamityGlobalProjectile.cs +++ b/Projectiles/CalamityGlobalProjectile.cs @@ -2153,8 +2153,8 @@ public override bool PreAI(Projectile projectile) int numDust = 5; int numDust2 = 5; int fadeInTime = 10; - int fadeOutGateValue = masterMode ? 80 : death ? 50 : 10; - float killGateValue = masterMode ? 90f : death ? 60f : 20f; + int fadeOutGateValue = masterMode ? 80 : death ? 50 : 25; + float killGateValue = masterMode ? 90f : death ? 60f : 35f; int maxFrames = 5; bool fadeIn = projectile.ai[0] < (float)fadeInTime; @@ -4280,7 +4280,7 @@ public override void ModifyHitPlayer(Projectile projectile, Player target, ref P if (CalamityWorld.revenge || BossRushEvent.BossRushActive) { float fadeInTime = 10f; - float fadeOutGateValue = masterMode ? 80f : death ? 50f : 10f; + float fadeOutGateValue = masterMode ? 80f : death ? 50f : 25f; return (projectile.ai[0] >= fadeInTime && projectile.ai[0] < fadeOutGateValue); } break; @@ -4444,8 +4444,8 @@ public override bool PreDraw(Projectile projectile, ref Color lightColor) Vector2 origin12 = new Vector2(16f, value26.Height / 2); Color alpha5 = projectile.GetAlpha(lightColor); Vector2 vector39 = new Vector2(projectile.scale); - float fadeOutGateValue = masterMode ? 80f : death ? 50f : 10f; - float killGateValue = masterMode ? 90f : death ? 60f : 20f; + float fadeOutGateValue = masterMode ? 80f : death ? 50f : 25f; + float killGateValue = masterMode ? 90f : death ? 60f : 35f; float lerpValue5 = Utils.GetLerpValue(killGateValue, killGateValue - 10f, projectile.ai[0], clamped: true); vector39.Y *= lerpValue5; Vector4 vector40 = lightColor.ToVector4(); From 3ffaba50699b8524de66351a64d555e3bd08e80f Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Tue, 21 May 2024 21:36:35 -0400 Subject: [PATCH 051/401] Ballistic Poison Bomb --- Balancing/BalancingChangesManager.cs | 3 +++ Projectiles/Rogue/BallisticPoisonBombProj.cs | 2 +- Projectiles/Rogue/BallisticPoisonCloud.cs | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Balancing/BalancingChangesManager.cs b/Balancing/BalancingChangesManager.cs index 3daca26a39..c36cc58ade 100644 --- a/Balancing/BalancingChangesManager.cs +++ b/Balancing/BalancingChangesManager.cs @@ -264,6 +264,9 @@ bool AotCThrowCombo(Projectile p) => // 50% resist to true melee. NPCSpecificBalancingChanges.AddRange(Bundle(CalamityLists.AstrumDeusIDs, Do(ResistTrueMelee(0.5f)))); + // 35% resist to Ballistic Poison Bomb's clouds. + NPCSpecificBalancingChanges.AddRange(Bundle(CalamityLists.AstrumDeusIDs, Do(new ProjectileResistBalancingRule(0.65f, ProjectileType())))); + // 35% resist to Icicle Arrows. NPCSpecificBalancingChanges.AddRange(Bundle(CalamityLists.AstrumDeusIDs, Do(new ProjectileResistBalancingRule(0.65f, ProjectileType())))); diff --git a/Projectiles/Rogue/BallisticPoisonBombProj.cs b/Projectiles/Rogue/BallisticPoisonBombProj.cs index 1085f9f558..6ef3ba74cc 100644 --- a/Projectiles/Rogue/BallisticPoisonBombProj.cs +++ b/Projectiles/Rogue/BallisticPoisonBombProj.cs @@ -66,7 +66,7 @@ public override void OnKill(int timeLeft) Vector2 velocity = CalamityUtils.RandomVelocity(100f, 70f, 100f); Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, velocity, ModContent.ProjectileType(), Projectile.damage, 0f, Projectile.owner); } - int cloudAmt = Projectile.Calamity().stealthStrike ? Main.rand.Next(8, 12+1) : Main.rand.Next(3, 5+1); + int cloudAmt = Projectile.Calamity().stealthStrike ? Main.rand.Next(7, 10+1) : Main.rand.Next(3, 5+1); for (int c = 0; c < cloudAmt; c++) { Vector2 velocity = CalamityUtils.RandomVelocity(100f, 10f, 200f, 0.01f); diff --git a/Projectiles/Rogue/BallisticPoisonCloud.cs b/Projectiles/Rogue/BallisticPoisonCloud.cs index 47f612c1ef..df259e395b 100644 --- a/Projectiles/Rogue/BallisticPoisonCloud.cs +++ b/Projectiles/Rogue/BallisticPoisonCloud.cs @@ -19,7 +19,7 @@ public override void SetDefaults() Projectile.height = 34; Projectile.friendly = true; Projectile.alpha = 255; - Projectile.penetrate = -1; + Projectile.penetrate = 5; Projectile.tileCollide = false; Projectile.ignoreWater = true; Projectile.timeLeft = 600; From da3efa4a691576741e66d980b77947c6420f9f90 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Tue, 21 May 2024 23:29:20 -0400 Subject: [PATCH 052/401] 1 - Several ammo rebalances 2 - Remove Astrum Deus Relic tooltip --- Items/Ammo/VeriumBolt.cs | 2 +- Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson | 2 +- Projectiles/Ranged/CinderArrowProj.cs | 4 ++-- Projectiles/Ranged/DryadsTearMain.cs | 5 ++++- Projectiles/Ranged/IcicleArrowProj.cs | 6 +++--- Projectiles/Ranged/SproutingArrowMain.cs | 6 +++--- 6 files changed, 14 insertions(+), 11 deletions(-) diff --git a/Items/Ammo/VeriumBolt.cs b/Items/Ammo/VeriumBolt.cs index b2a1adb08a..bbc4756fe6 100644 --- a/Items/Ammo/VeriumBolt.cs +++ b/Items/Ammo/VeriumBolt.cs @@ -19,7 +19,7 @@ public override void SetDefaults() { Item.width = 8; Item.height = 8; - Item.damage = 7; + Item.damage = 11; Item.DamageType = DamageClass.Ranged; Item.maxStack = 9999; Item.consumable = true; diff --git a/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson b/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson index 15755848c2..c07939ffdc 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson @@ -360,7 +360,7 @@ AstrumAureusRelic: { AstrumDeusRelic: { DisplayName: Astrum Deus Relic - Tooltip: A glimpse into what could have been... + Tooltip: "" } BrimstoneElementalRelic: { diff --git a/Projectiles/Ranged/CinderArrowProj.cs b/Projectiles/Ranged/CinderArrowProj.cs index 1933630860..cfd82c1257 100644 --- a/Projectiles/Ranged/CinderArrowProj.cs +++ b/Projectiles/Ranged/CinderArrowProj.cs @@ -102,13 +102,13 @@ public override void OnKill(int timeLeft) for (int b = 0; b < 3; b++) { Vector2 velocity = Vector2.UnitY.RotatedByRandom(0.8f) * Main.rand.NextFloat(-3.5f, -3f); - Projectile shrapnel = Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), Projectile.Center, velocity, ModContent.ProjectileType(), (int)(Projectile.damage * 0.1f), 0f, Projectile.owner, ai2: 1f); + Projectile shrapnel = Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), Projectile.Center, velocity, ModContent.ProjectileType(), (int)(Projectile.damage * 0.06f), 0f, Projectile.owner, ai2: 1f); shrapnel.timeLeft = 300; shrapnel.arrow = false; shrapnel.MaxUpdates = 4; } - Projectile.damage = (int)(Projectile.damage * 0.5f); + Projectile.damage = (int)(Projectile.damage * 0.4f); Projectile.penetrate = -1; Projectile.ExpandHitboxBy(110); Projectile.Damage(); diff --git a/Projectiles/Ranged/DryadsTearMain.cs b/Projectiles/Ranged/DryadsTearMain.cs index 5676aded04..8c6d8cf7a7 100644 --- a/Projectiles/Ranged/DryadsTearMain.cs +++ b/Projectiles/Ranged/DryadsTearMain.cs @@ -34,6 +34,9 @@ public override void AI() { Lighting.AddLight(Projectile.Center, Color.LimeGreen.ToVector3() * 0.25f); + if (Projectile.localAI[0] == 0f) + Projectile.damage = (int)(Projectile.damage * 0.75f); + Projectile.localAI[0] += 1f; if (Projectile.localAI[0] > 4f) { @@ -60,7 +63,7 @@ public override void OnKill(int timeLeft) for (int b = 0; b < 2; b++) { Vector2 velocity = CalamityUtils.RandomVelocity(100f, 70f, 100f); - Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, velocity, ModContent.ProjectileType(), (int)(Projectile.damage * 0.3), 0f, Projectile.owner, 0f, 0f); + Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, velocity, ModContent.ProjectileType(), (int)(Projectile.damage * 0.4), 0f, Projectile.owner, 0f, 0f); } for (int i = 0; i < 3; i++) { diff --git a/Projectiles/Ranged/IcicleArrowProj.cs b/Projectiles/Ranged/IcicleArrowProj.cs index 45dc5b612d..dea42703d3 100644 --- a/Projectiles/Ranged/IcicleArrowProj.cs +++ b/Projectiles/Ranged/IcicleArrowProj.cs @@ -27,7 +27,7 @@ public override void SetDefaults() Projectile.extraUpdates = 6; Projectile.timeLeft = 1000; Projectile.usesLocalNPCImmunity = true; - Projectile.localNPCHitCooldown = 15 * Projectile.extraUpdates; + Projectile.localNPCHitCooldown = 15 * Projectile.MaxUpdates; Projectile.Calamity().pointBlankShotDuration = CalamityGlobalProjectile.DefaultPointBlankDuration; } @@ -119,10 +119,10 @@ public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) public override void ModifyHitNPC(NPC target, ref NPC.HitModifiers modifiers) { if (falling) - modifiers.SourceDamage *= 1.35f; + modifiers.SourceDamage *= 1.1f; if (Projectile.numHits > 1 && falling) - Projectile.damage = (int)(Projectile.damage * 0.6f); + Projectile.damage = (int)(Projectile.damage * 0.5f); if (Projectile.damage < 1) Projectile.damage = 1; } diff --git a/Projectiles/Ranged/SproutingArrowMain.cs b/Projectiles/Ranged/SproutingArrowMain.cs index 93fbb6180f..c67de8f3a6 100644 --- a/Projectiles/Ranged/SproutingArrowMain.cs +++ b/Projectiles/Ranged/SproutingArrowMain.cs @@ -34,7 +34,7 @@ public override void AI() { if (Projectile.ai[0] == 0) { - Projectile.damage = (int)(Projectile.damage * 0.18f); + Projectile.damage = (int)(Projectile.damage * 0.3f); Projectile.velocity *= 0.25f; LineParticle spark = new LineParticle(Projectile.Center + Projectile.velocity * 4, Projectile.velocity * 4.95f, false, 9, 2.4f, Color.LimeGreen); GeneralParticleHandler.SpawnParticle(spark); @@ -51,8 +51,8 @@ public override void OnKill(int timeLeft) Vector2 vel1 = (Projectile.velocity * 0.4f).RotatedBy(Main.rand.NextFloat(0.015f, 0.04f)); Vector2 vel2 = (Projectile.velocity * 0.4f).RotatedBy(Main.rand.NextFloat(-0.015f, -0.04f)); - int split1 = Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, vel1 * Main.rand.NextFloat(0.95f, 1.05f), ModContent.ProjectileType(), (int)(Projectile.damage * 3), 0f, Projectile.owner, 0f, hitDirect ? 1f : 0f); - int split2 = Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, vel2 * Main.rand.NextFloat(0.95f, 1.05f), ModContent.ProjectileType(), (int)(Projectile.damage * 3), 0f, Projectile.owner, 0f, hitDirect ? 1f : 0f); + int split1 = Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, vel1 * Main.rand.NextFloat(0.95f, 1.05f), ModContent.ProjectileType(), (int)(Projectile.damage * 2), 0f, Projectile.owner, 0f, hitDirect ? 1f : 0f); + int split2 = Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, vel2 * Main.rand.NextFloat(0.95f, 1.05f), ModContent.ProjectileType(), (int)(Projectile.damage * 2), 0f, Projectile.owner, 0f, hitDirect ? 1f : 0f); if (Projectile.Calamity().allProjectilesHome) // Allows the split arrows to home when using Arterial Assault as well { Main.projectile[split1].Calamity().allProjectilesHome = true; From febd8cc386d6049432aa76a75b4ef637401c7e23 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Wed, 22 May 2024 03:28:43 -0500 Subject: [PATCH 053/401] Why were these set to die on contact with water given they spawn in water biomes? --- Tiles/Abyss/AbyssAmbient/AbyssKelp.cs | 2 +- Tiles/Abyss/AbyssAmbient/PhoviamareHalm.cs | 2 +- Tiles/Abyss/AbyssAmbient/TenebrisRemnant.cs | 2 +- Tiles/Rubblemaker/SunkenSea/SmallCoralsEcho.cs | 2 +- Tiles/SunkenSea/SmallCorals.cs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Tiles/Abyss/AbyssAmbient/AbyssKelp.cs b/Tiles/Abyss/AbyssAmbient/AbyssKelp.cs index 780c4f5224..5685b37c6e 100644 --- a/Tiles/Abyss/AbyssAmbient/AbyssKelp.cs +++ b/Tiles/Abyss/AbyssAmbient/AbyssKelp.cs @@ -21,7 +21,7 @@ public override void SetStaticDefaults() Main.tileNoAttach[Type] = true; Main.tileNoFail[Type] = true; Main.tileLavaDeath[Type] = true; - Main.tileWaterDeath[Type] = true; + Main.tileWaterDeath[Type] = false; Main.tileFrameImportant[Type] = true; TileID.Sets.ReplaceTileBreakUp[Type] = true; TileID.Sets.SwaysInWindBasic[Type] = true; diff --git a/Tiles/Abyss/AbyssAmbient/PhoviamareHalm.cs b/Tiles/Abyss/AbyssAmbient/PhoviamareHalm.cs index df321133ff..4e4ed2bf49 100644 --- a/Tiles/Abyss/AbyssAmbient/PhoviamareHalm.cs +++ b/Tiles/Abyss/AbyssAmbient/PhoviamareHalm.cs @@ -21,7 +21,7 @@ public override void SetStaticDefaults() Main.tileNoAttach[Type] = true; Main.tileNoFail[Type] = true; Main.tileLavaDeath[Type] = true; - Main.tileWaterDeath[Type] = true; + Main.tileWaterDeath[Type] = false; Main.tileFrameImportant[Type] = true; TileID.Sets.ReplaceTileBreakUp[Type] = true; TileID.Sets.SwaysInWindBasic[Type] = true; diff --git a/Tiles/Abyss/AbyssAmbient/TenebrisRemnant.cs b/Tiles/Abyss/AbyssAmbient/TenebrisRemnant.cs index a5a676ba0f..6d10d5c19c 100644 --- a/Tiles/Abyss/AbyssAmbient/TenebrisRemnant.cs +++ b/Tiles/Abyss/AbyssAmbient/TenebrisRemnant.cs @@ -21,7 +21,7 @@ public override void SetStaticDefaults() Main.tileNoAttach[Type] = true; Main.tileNoFail[Type] = true; Main.tileLavaDeath[Type] = true; - Main.tileWaterDeath[Type] = true; + Main.tileWaterDeath[Type] = false; Main.tileFrameImportant[Type] = true; TileID.Sets.ReplaceTileBreakUp[Type] = true; TileID.Sets.SwaysInWindBasic[Type] = true; diff --git a/Tiles/Rubblemaker/SunkenSea/SmallCoralsEcho.cs b/Tiles/Rubblemaker/SunkenSea/SmallCoralsEcho.cs index 65c88d8234..099fc82862 100644 --- a/Tiles/Rubblemaker/SunkenSea/SmallCoralsEcho.cs +++ b/Tiles/Rubblemaker/SunkenSea/SmallCoralsEcho.cs @@ -18,7 +18,7 @@ public override void SetStaticDefaults() Main.tileNoAttach[Type] = true; Main.tileNoFail[Type] = true; Main.tileLavaDeath[Type] = true; - Main.tileWaterDeath[Type] = true; + Main.tileWaterDeath[Type] = false; Main.tileFrameImportant[Type] = true; TileID.Sets.ReplaceTileBreakUp[Type] = true; TileID.Sets.SwaysInWindBasic[Type] = false; diff --git a/Tiles/SunkenSea/SmallCorals.cs b/Tiles/SunkenSea/SmallCorals.cs index 6848dccbca..84237a5d3e 100644 --- a/Tiles/SunkenSea/SmallCorals.cs +++ b/Tiles/SunkenSea/SmallCorals.cs @@ -16,7 +16,7 @@ public override void SetStaticDefaults() Main.tileNoAttach[Type] = true; Main.tileNoFail[Type] = true; Main.tileLavaDeath[Type] = true; - Main.tileWaterDeath[Type] = true; + Main.tileWaterDeath[Type] = false; Main.tileFrameImportant[Type] = true; TileID.Sets.ReplaceTileBreakUp[Type] = true; TileID.Sets.SwaysInWindBasic[Type] = false; From 3766786473d63cec0224a823f621fffc813b06bf Mon Sep 17 00:00:00 2001 From: Xyk Date: Wed, 22 May 2024 00:58:53 -0700 Subject: [PATCH 054/401] Craw Carapace and Baroclaw buffs Craw Carapace: damage 5% -> 8%, now deals 50 flat damage on top of spikes damage to enemies that hit you Baroclaw: Now also has 5% dr, now deals 250 flat damage on top of spikes damage to enemies that hit you Absorber also got the flat damage for consistency's sake but it's not very high since its common knowledge absorber is a top tier accessory already. --- CalPlayer/CalamityPlayerHitHurt.cs | 6 ++++++ CalPlayer/CalamityPlayerMiscEffects.cs | 5 ++++- Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson | 4 ++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CalPlayer/CalamityPlayerHitHurt.cs b/CalPlayer/CalamityPlayerHitHurt.cs index 16e9b7e6a8..5dce1a0a3e 100644 --- a/CalPlayer/CalamityPlayerHitHurt.cs +++ b/CalPlayer/CalamityPlayerHitHurt.cs @@ -1172,6 +1172,8 @@ public override void OnHitByNPC(NPC npc, Player.HurtInfo hurtInfo) if (crawCarapace) { npc.AddBuff(ModContent.BuffType(), 900); + int onHitDamage = Player.CalcIntDamage(50); + Player.ApplyDamageToNPC(npc, onHitDamage, 0f, 0, false); SoundEngine.PlaySound(SoundID.NPCHit33 with { Volume = 0.5f }, Player.Center); } @@ -1179,6 +1181,8 @@ public override void OnHitByNPC(NPC npc, Player.HurtInfo hurtInfo) { npc.AddBuff(ModContent.BuffType(), 900); npc.AddBuff(ModContent.BuffType(), 900); + int onHitDamage = Player.CalcIntDamage(250); + Player.ApplyDamageToNPC(npc, onHitDamage, 0f, 0, false); SoundEngine.PlaySound(BaroclawHit, Player.Center); Vector2 bloodSpawnPosition = Player.Center + Main.rand.NextVector2Circular(Player.width, Player.height) * 0.04f; Vector2 splatterDirection = (Player.Center - bloodSpawnPosition).SafeNormalize(Vector2.UnitY); @@ -1198,6 +1202,8 @@ public override void OnHitByNPC(NPC npc, Player.HurtInfo hurtInfo) if (absorber) { npc.AddBuff(ModContent.BuffType(), 900); + int onHitDamage = Player.CalcIntDamage(350); + Player.ApplyDamageToNPC(npc, onHitDamage, 0f, 0, false); SoundEngine.PlaySound(AbsorberHit, Player.Center); Vector2 bloodSpawnPosition = Player.Center + Main.rand.NextVector2Circular(Player.width, Player.height) * 0.04f; Vector2 splatterDirection = (Player.Center - bloodSpawnPosition).SafeNormalize(Vector2.UnitY); diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index 4da98a113f..0a1bbeb77e 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -2581,10 +2581,13 @@ private void OtherBuffEffects() } if (crawCarapace) - Player.GetDamage() += 0.05f; + Player.GetDamage() += 0.08f; if (baroclaw) + { + Player.endurance += 0.05f; Player.GetDamage() += 0.1f; + } if (aeroStone && !Player.slowFall && Player.wingTime < Player.wingTimeMax) { diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson index 5726d7ac9a..522ee30e39 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson @@ -428,7 +428,7 @@ CrawCarapace: { DisplayName: Craw Carapace Tooltip: ''' - 5% increased damage + 8% increased damage Enemies that hit you take damage and are inflicted with Crumbling ''' } @@ -437,7 +437,7 @@ Baroclaw: { DisplayName: Baroclaw Tooltip: ''' - 10% increased damage + 10% increased damage and 5% increased damage reduction Enemies that hit you take high damage and are inflicted with Armor Crunch and Crush Depth ''' } From 2eb0a4e4e3ab8c2693c0b2891ddcae0356d503e1 Mon Sep 17 00:00:00 2001 From: Xyk Date: Wed, 22 May 2024 01:09:52 -0700 Subject: [PATCH 055/401] fixed icicle arrow tile insanity --- Projectiles/Ranged/IcicleArrowProj.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Projectiles/Ranged/IcicleArrowProj.cs b/Projectiles/Ranged/IcicleArrowProj.cs index dea42703d3..8e49752c80 100644 --- a/Projectiles/Ranged/IcicleArrowProj.cs +++ b/Projectiles/Ranged/IcicleArrowProj.cs @@ -149,6 +149,7 @@ public override bool OnTileCollide(Vector2 oldVelocity) dust2.noGravity = false; } Projectile.velocity = new Vector2(0, -6.5f).RotatedByRandom(0.25f) * Main.rand.NextFloat(0.75f, 1.1f); + Projectile.tileCollide = false; return false; } else From a0e13da37bdc5ae2bb57e6a50123ef9510d246ec Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Thu, 23 May 2024 08:48:21 -0500 Subject: [PATCH 056/401] Desert Scourge vomit spam fix? --- NPCs/DesertScourge/DesertScourgeHead.cs | 47 +++---------------------- 1 file changed, 4 insertions(+), 43 deletions(-) diff --git a/NPCs/DesertScourge/DesertScourgeHead.cs b/NPCs/DesertScourge/DesertScourgeHead.cs index 405b9dbe4b..4cd787ab44 100644 --- a/NPCs/DesertScourge/DesertScourgeHead.cs +++ b/NPCs/DesertScourge/DesertScourgeHead.cs @@ -258,47 +258,6 @@ public override void AI() turnSpeed *= 1.2f; } - // Projectile spit (unused, for now) - /*if ((phase2 || death) && revenge && NPC.Distance(Main.player[NPC.target].Center) > 400f && (Main.player[NPC.target].Center - NPC.Center).SafeNormalize(Vector2.UnitY).ToRotation().AngleTowards(NPC.velocity.ToRotation(), MathHelper.PiOver4) == NPC.velocity.ToRotation()) - { - if (NPC.Calamity().newAI[0] % (death ? SpitGateValue_Death : SpitGateValue) == 0f) - { - SoundEngine.PlaySound(SoundID.NPCDeath11, NPC.Center); - if (Main.netMode != NetmodeID.MultiplayerClient) - { - Vector2 projectileVelocity = (Main.player[NPC.target].Center - NPC.Center).SafeNormalize(Vector2.UnitY) * (masterMode ? 10f : 8f); - int numProj = death ? 9 : 6; - int spread = masterMode ? 49 : 35; - if (masterMode) - { - numProj += 3; - spread += 14; - } - - float rotation = MathHelper.ToRadians(spread); - int type = ModContent.ProjectileType(); - int damage = NPC.GetProjectileDamage(type); - for (int i = 0; i < numProj; i++) - { - Vector2 perturbedSpeed = projectileVelocity.RotatedBy(MathHelper.Lerp(-rotation, rotation, i / (float)(numProj - 1))); - - for (int k = 0; k < 10; k++) - { - int dust = Dust.NewDust(NPC.Center + Vector2.Normalize(perturbedSpeed) * 5f, 10, 10, (int)CalamityDusts.SulphurousSeaAcid); - Main.dust[dust].velocity = perturbedSpeed; - } - - if (Main.netMode != NetmodeID.MultiplayerClient) - { - int proj = Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center + perturbedSpeed.SafeNormalize(Vector2.UnitY) * 5f, perturbedSpeed, type, damage, 0f, Main.myPlayer); - Main.projectile[proj].aiStyle = -1; - Main.projectile[proj].netUpdate = true; - } - } - } - } - }*/ - // Sand splash if (!quickFall) { @@ -591,7 +550,7 @@ public override void AI() float targetDistance = (float)Math.Sqrt((double)(playerX * playerX + targettingPosition * targettingPosition)); // Lunge up towards target - if (burrow && NPC.Center.Y >= burrowTarget - 16f) + if (burrow && NPC.Center.Y >= burrowTarget - 16f && !lungeUpward && !quickFall) { NPC.Calamity().newAI[1] = 1f; NPC.localAI[3] = 0f; @@ -603,7 +562,7 @@ public override void AI() } // Quickly fall back down once above target - if (lungeUpward && NPC.Center.Y <= NPC.Calamity().newAI[3] + LungeUpwardDistanceOffset - LungeUpwardCutoffDistance && Math.Abs(NPC.Center.X - player.Center.X) < 480f) + if (lungeUpward && NPC.Center.Y <= NPC.Calamity().newAI[3] + LungeUpwardDistanceOffset - LungeUpwardCutoffDistance && Math.Abs(NPC.Center.X - player.Center.X) < 480f && !quickFall) { // Spit a huge spread of sand upwards that falls down SoundEngine.PlaySound(SoundID.NPCDeath13, NPC.Center); @@ -656,7 +615,9 @@ public override void AI() { NPC.Calamity().newAI[0] = 0f; NPC.Calamity().newAI[1] = 0f; + NPC.Calamity().newAI[3] = 0f; NPC.localAI[3] = 0f; + playRoarSound = false; } if (hide && !player.dead) From 48e30df168d6ef7e3a5efa15408e979349303748 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Wed, 22 May 2024 15:42:52 -0400 Subject: [PATCH 057/401] Removed Wind Blade rework from main branch Hi to people who snoop around in the source I guess --- Items/BaseItems/CustomUseProjItem.cs | 23 -- Items/Weapons/Melee/WindBlade.cs | 31 ++- Items/Weapons/Melee/WindBlade.png | Bin 870 -> 930 bytes ...Mods.CalamityMod.Items.Weapons.Melee.hjson | 7 +- .../Mods.CalamityMod.Projectiles.Melee.hjson | 2 +- .../BaseCustomUseStyleProjectile.cs | 250 ------------------ Projectiles/Melee/Cyclone.cs | 125 +++++++++ .../Melee/{WindBolt.png => Cyclone.png} | Bin Projectiles/Melee/WindBladeHoldout.cs | 132 --------- Projectiles/Melee/WindBladeHoldout.png | Bin 870 -> 0 bytes Projectiles/Melee/WindBolt.cs | 146 ---------- 11 files changed, 146 insertions(+), 570 deletions(-) delete mode 100644 Items/BaseItems/CustomUseProjItem.cs delete mode 100644 Projectiles/BaseProjectiles/BaseCustomUseStyleProjectile.cs create mode 100644 Projectiles/Melee/Cyclone.cs rename Projectiles/Melee/{WindBolt.png => Cyclone.png} (100%) delete mode 100644 Projectiles/Melee/WindBladeHoldout.cs delete mode 100644 Projectiles/Melee/WindBladeHoldout.png delete mode 100644 Projectiles/Melee/WindBolt.cs diff --git a/Items/BaseItems/CustomUseProjItem.cs b/Items/BaseItems/CustomUseProjItem.cs deleted file mode 100644 index 800d2dfb97..0000000000 --- a/Items/BaseItems/CustomUseProjItem.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Terraria; -using Terraria.ModLoader; - -namespace CalamityMod.Items.BaseItems -{ - public abstract class CustomUseProjItem : ModItem - { - public override void SetDefaults() - { - Item.channel = true; - } - - public override bool CanShoot(Player player) - { - return player.ownedProjectileCounts[Item.shoot] < 1; - } - } -} diff --git a/Items/Weapons/Melee/WindBlade.cs b/Items/Weapons/Melee/WindBlade.cs index 2f9aa92a91..8676601b68 100644 --- a/Items/Weapons/Melee/WindBlade.cs +++ b/Items/Weapons/Melee/WindBlade.cs @@ -1,6 +1,4 @@ -using CalamityMod.Items.BaseItems; -using CalamityMod.Items.Materials; -using CalamityMod.Projectiles.BaseProjectiles; +using CalamityMod.Items.Materials; using CalamityMod.Projectiles.Melee; using Microsoft.Xna.Framework; using Terraria; @@ -10,29 +8,38 @@ namespace CalamityMod.Items.Weapons.Melee { - public class WindBlade : CustomUseProjItem, ILocalizedModType + public class WindBlade : ModItem, ILocalizedModType { public new string LocalizationCategory => "Items.Weapons.Melee"; public override void SetDefaults() { Item.width = 58; Item.height = 58; - Item.damage = 42; + Item.damage = 41; Item.DamageType = DamageClass.Melee; - Item.useAnimation = 18; + Item.useAnimation = 20; Item.useStyle = ItemUseStyleID.Swing; - Item.useTime = 18; + Item.useTime = 20; Item.useTurn = true; Item.knockBack = 5f; + Item.UseSound = SoundID.Item1; Item.autoReuse = true; Item.value = CalamityGlobalItem.RarityOrangeBuyPrice; Item.rare = ItemRarityID.Orange; + Item.shoot = ModContent.ProjectileType(); + Item.shootSpeed = 3f; + } - Item.channel = true; - Item.shoot = ModContent.ProjectileType(); - Item.noUseGraphic = true; - Item.noMelee = true; - Item.useStyle = ItemUseStyleID.Shoot; + public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) + { + Projectile.NewProjectile(source, position, velocity, type, damage / 2, knockback, player.whoAmI); + return false; + } + + public override void MeleeEffects(Player player, Rectangle hitbox) + { + if (Main.rand.NextBool(3)) + Dust.NewDust(new Vector2(hitbox.X, hitbox.Y), hitbox.Width, hitbox.Height, DustID.BlueTorch); } public override void AddRecipes() diff --git a/Items/Weapons/Melee/WindBlade.png b/Items/Weapons/Melee/WindBlade.png index b08f34b7d98f5f3f7a38e51a7dd73f46a2afc898..36d003fbdcbe511f4b0dd3a6f72ea705133b3674 100644 GIT binary patch literal 930 zcmV;T16}-yP)XhFzSdcT!?*u#N@&VB$=WD5d}B3h-lF&5QK&lBFMfr zMudbQA_hu|UlT%pq^Ju^7m6^nQiFnf-`_a5_eRU-^Qq@7=5X(Q%y8%T&N=^cT-qVA z+@dSLVx7CRBVw+DPV9s`MfmK>eBlcV&XDuR^-q|nqwQ>{+>o4Vqhnt=MjaiS4dFVm zuF6Xm{_U659g$?BPBoPz*07p8?ZT(#dW4^TKQ8>lNP8R;by95he|%s_78bnRLh2}N zExN)n>S&TliJ!^3?A)Ls$>oXfoOK;Zax1$Yli5@&ED^4L`+TUwjh& zQDB@r_quUZ_)9gFhTRDab(4wiS6>MY3z9coefo)8e9lIq!f#x?Wk}MDAQQD~B7lAp z_Tgo(@b~lQ$bQG0cuPn!Q8V*rmk>gc>A|>I`>?d49K(7Soso62sVYj&C#R&A9mw>_ z^0`ZrOw^2I&nv%JmtTvJ{rZc=Vjb=pBKzwm-v^R6^5O}>;dx2==LMf7G08;DNVYa+ zkbQMMsY}b^EU)l^bPqXyw_!{Y29k?jNitR6A86~bgd`JHV-Lh?n`I1QA0$E*l2owz zq^@M-x~)@2>B91o@TI9p&K_fuxt^mrO0oT-$fl@|VND}-GgOg5l+5rv&A0t6DMYij zbyAXM{iIc~$wbXankgdG!C>{K@V-a_sgH=+Ouy_#`ku+@T$-0=V|P|E$LOA1R3&Jp zbx}_<{hK5PLC$}>kW2;;o27c83>=rwH|g`&wUHGjYOB`$L(ommK@u?ul98uf`V%zv zLKO+5J}3NGjQJ)p(Y?B8ZSx$_v@mE}WZi~f2if=Ktm^euGt{{1o3mGBnW%Xdrdk-p z?mb*L>|UUGv5(jcq|-M7b(>>!zb*=rAT~7fjbv5CGz{m6arHUQx^`VuozI@qr+T%` z-8=dLRU50Zs%dkab#1*UluJSVbvnyY{&}^V0V$O%`dKKg)|?E(m}a6@UlfEAy>gyA z7Je=dl1~5AL}I&Hl-cu4^nWj^_L*DRwd}m`OTFF7KR&oa1!YWfJMv7_s*55EZYiC= zNbb&5Eo&Faqf1onGN4U&Yj%@kqH1?x70E->rX4i<4W%ooAtHj_!vFvP07*qoM6N<$ Ef~JAQlK=n! literal 870 zcmeAS@N?(olHy`uVBq!ia0vp^UO*he!3-pYE(NXtQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ivoN?Tn$sRP1>73{Jz+6c$H=S?vVfgZT9cb@Cd7$R6cccw!FDxLSBT0 zyhPo^a^CEQ5DSqR)utI%ie|2rN7kfT*6;d#qovuIOG;L?*@-JB!R+;!#^2YQ&0QlBSEMj7FnN2rIEF;HpS|8)v|2%cEn(7x1s<_eqCS49`}jBhcDuc;3l-beO!lq% z`npHgZn*nMu*dzh-AfIT>8Z1Mr=7L;z&Zj1Mhn$j_SCl<_!meY-<~1Gabt~Jw$)%X-xA3FCfA<#i^DpqzeXMDyX`&HV zyn)fcc}vv8`@CB+F5B2WIv+FtkP%zhb&c~;TO8*_pT2TgIM17lDlc{~n&_b0_XxaXoxbN=EO?x@za_2I+Iw${SZ| z-cZ=0#})AYea)ZGM)Qp1U9W8OsjXS?VU?HfLsJg%MUs2o|K7HjWmfwv1({OWY5LPX zepqcRJpYl|gT?Et_v`WtPtS_BdGq1Y;RmUyZ-u9?(s~{swCv}09-+xjk<+(6D)01^ h6mE806j=LTJkb1E_Xp`4e}QR@!PC{xWt~$(697sik}v=O diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson index cebfe4bd20..afeab0b76b 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson @@ -1390,12 +1390,7 @@ VulcaniteLance: { WindBlade: { DisplayName: Wind Blade - Tooltip: - ''' - Perform a three swing combo which ends by thrusting the blade forwards - Thrusting the blade launches an expanding cyclone that lingers - Cyclones pull enemies in, or pulls itself towards bosses - ''' + Tooltip: Fires cyclones that suck enemies in } WulfrumScrewdriver: { diff --git a/Localization/en-US/Mods.CalamityMod.Projectiles.Melee.hjson b/Localization/en-US/Mods.CalamityMod.Projectiles.Melee.hjson index 701a9c1703..f49ed13e17 100644 --- a/Localization/en-US/Mods.CalamityMod.Projectiles.Melee.hjson +++ b/Localization/en-US/Mods.CalamityMod.Projectiles.Melee.hjson @@ -76,6 +76,7 @@ CosmicSpiritBomb3.DisplayName: Cosmic Bomb CrescentMoonFlail.DisplayName: Crescent Moon CrescentMoonProj.DisplayName: Crescent Moon CrystylCrusherRay.DisplayName: Crystyl Crusher Ray +Cyclone.DisplayName: Cyclone DarkBall.DisplayName: Dark Ball DarkBeam.DisplayName: Dark Beam DarkIceZero.DisplayName: Dark Ice @@ -310,7 +311,6 @@ Waterfall.DisplayName: Waterfall Beam WhiteBoltAura.DisplayName: White Aura WhiteOrb.DisplayName: White Orb Whiterain.DisplayName: White Rain -WindBolt.DisplayName: Wind Bolt WulfrumScrew.DisplayName: Wulfrum Screw WulfrumScrewdriverProj.DisplayName: Wulfrum Screwdriver YateveoBloomProj.DisplayName: Yateveo Bloom diff --git a/Projectiles/BaseProjectiles/BaseCustomUseStyleProjectile.cs b/Projectiles/BaseProjectiles/BaseCustomUseStyleProjectile.cs deleted file mode 100644 index 0b9ec47dfe..0000000000 --- a/Projectiles/BaseProjectiles/BaseCustomUseStyleProjectile.cs +++ /dev/null @@ -1,250 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using CalamityMod.Items.Weapons.Melee; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using Microsoft.Xna.Framework.Input; -using ReLogic.Content; -using Terraria; -using Terraria.DataStructures; -using Terraria.GameInput; -using Terraria.ModLoader; - -namespace CalamityMod.Projectiles.BaseProjectiles -{ - public abstract class BaseCustomUseStyleProjectile : ModProjectile - { - - public override void SetDefaults() - { - Projectile.friendly = true; - Projectile.tileCollide = false; - Projectile.penetrate = -1; - } - - public override void OnSpawn(IEntitySource source) - { - Projectile.timeLeft = Owner.HeldItem.useAnimation + 1; - } - - #region Fields - /// - /// The offset in pixels of the weapon from the projectile owner's center. This works even while using AbsolutePosition. - /// - public Vector2 Offset = Vector2.Zero; - - /// - /// The Player that is using the projectile. - /// - public virtual Player Owner => Main.player[Projectile.owner]; - - /// - /// The amount of pixels out the center of the projectile's hitbox is. - /// - public virtual float HitboxOutset => 30; - - /// - /// The projectile's hitbox size in pixels. - /// - public virtual Vector2 HitboxSize => new Vector2(30, 30); - - /// - /// The number of animations that this projectile has gone through. Useful for things like swing combos. - /// - public int NumberOfAnimations = 0; - - public float Animation = 0; - - /// - /// If true, flips the sprite with a 45-degree sword tilt in mind. - /// - public bool FlipAsSword = false; - - /// - /// The offset in radians of the weapon's rotation from its current rotation. - /// - public float RotationOffset = 0f; - - /// - /// The offset in radians of the rotation of the player's front arm. - /// - public float ArmRotationOffset = 0f; - - /// - /// The offset in radians of the rotation of the player's back arm. - /// - public float ArmRotationOffsetBack = 0f; - - /// - /// The amount of animation frames the projectile has in a vertical sheet. - /// - public virtual int FrameCount => 1; - - /// - /// The individual frame currently being drawn in a vertical sheet. - /// - public int Frame = 0; - - /// - /// The origin of the sprite when drawn on your character. - /// - /// - public virtual Vector2 SpriteOrigin => Projectile.Size / 2; - - /// - /// Helper method for getting the rotation of the sprite plus RotationOffset, without having to make your own local variable every time. - /// - /// - public float FinalRotation => Projectile.rotation + RotationOffset; - - /// - /// Rotation offset for the hitbox that doesn't affect the sprite. - /// Useful for if you have, for instance, a sword sprite at a 45 degree angle, and need that to reflect on the hitbox. - /// - /// - public virtual float HitboxRotationOffset => 0f; - - /// - /// Whether or not the projectile can hit enemies at the current frame. - /// Useful for wind-up animations where you don't want the projectile to deal damage. - /// - public bool CanHit = true; - - /// - /// Overrides the projectile owner's center as the projectile's location, so long as it isn't Vector2.Zero. - /// - public Vector2 AbsolutePosition = Vector2.Zero; - - /// - /// If this field is true, the projectile will draw at all times. Otherwise, it will only draw when its associated item is in use. - /// - public bool DrawUnconditionally = false; - - /// - /// The number of frames that the current use animation has progressed through. - /// - public float AnimationProgress = 0; - #endregion - - #region Use Style - /// - /// Determines the behavior to reset to when the item is not in use. - /// - public virtual void ResetStyle() { } - - /// - /// Determines the behavior of the projectile when the item is in use. - /// - public virtual void UseStyle() { } - - /// - /// Determines the behavior of the projectile when the item use animation begins for the first time in a row. - /// - public virtual void OnBeginUse() { } - - /// - /// Determines the behavior of the projectile when the item use animation ends. - /// - public virtual void OnEndUse() { } - #endregion - - public override void AI() - { - Owner.Calamity().mouseWorldListener = true; - - if (Owner.ItemAnimationActive) - { - Animation++; - - UseStyle(); - Owner.heldProj = Projectile.whoAmI; - Owner.SetCompositeArmFront(true, Player.CompositeArmStretchAmount.Full, Projectile.rotation + RotationOffset + ArmRotationOffset); - Owner.SetCompositeArmBack(true, Player.CompositeArmStretchAmount.Full, Projectile.rotation + RotationOffset + ArmRotationOffsetBack); - } - else - { - Animation = 0; - - if (DrawUnconditionally) - { - Owner.heldProj = Projectile.whoAmI; - Owner.SetCompositeArmFront(true, Player.CompositeArmStretchAmount.Full, Projectile.rotation + RotationOffset + ArmRotationOffset); - Owner.SetCompositeArmBack(true, Player.CompositeArmStretchAmount.Full, Projectile.rotation + RotationOffset + ArmRotationOffsetBack); - } - - NumberOfAnimations = 0; - ResetStyle(); - } - - AnimationProgress = Animation % Owner.itemAnimationMax; - - if (AbsolutePosition == Vector2.Zero) - { - Projectile.position = Owner.position + (Owner.Size / 2) - (Projectile.Size / 2) + Offset; - } - else - { - Projectile.position = AbsolutePosition - (Projectile.Size / 2) + Offset; - } - - if (Owner.itemAnimation == 1) - { - OnEndUse(); - NumberOfAnimations++; - } - - if (Owner.ItemAnimationJustStarted) - { - Projectile.timeLeft = Owner.HeldItem.useAnimation + 1; - OnBeginUse(); - } - } - - public override bool? CanHitNPC(NPC target) - { - bool bb = (target.immune[0] <= 0) && !target.friendly && !target.dontTakeDamage; - - return bb; - } - - - public override void ModifyHitNPC(NPC target, ref NPC.HitModifiers modifiers) - { - modifiers.HitDirectionOverride = Owner.direction; - base.ModifyHitNPC(target, ref modifiers); - } - - public override bool? CanDamage() - { - return CanHit ? base.CanDamage() : false; - } - - public override void ModifyDamageHitbox(ref Rectangle hitbox) - { - Vector2 cen = Projectile.Center + new Vector2(HitboxOutset, 0).RotatedBy(FinalRotation + HitboxRotationOffset); - - - hitbox = new Rectangle((int)cen.X - (int)(HitboxSize.X / 2), (int)cen.Y - (int)(HitboxSize.Y / 2), (int)HitboxSize.X, (int)HitboxSize.Y); - - base.ModifyDamageHitbox(ref hitbox); - } - - public override bool PreDraw(ref Color lightColor) - { - // Only draw the projectile if the projectile's owner is currently using the item this projectile is attached to. - if (Owner.itemAnimation > 0 || DrawUnconditionally) - { - Asset tex = ModContent.Request(Texture); - - float r = FlipAsSword ? MathHelper.ToRadians(90) : 0f; - - Main.EntitySpriteDraw(tex.Value, Projectile.Center - Main.screenPosition + new Vector2(0, Owner.gfxOffY), tex.Frame(1, FrameCount, 0, Frame), lightColor, Projectile.rotation + RotationOffset + r, FlipAsSword ? new Vector2(tex.Width() - SpriteOrigin.X, SpriteOrigin.Y) : SpriteOrigin, Projectile.scale, FlipAsSword ? SpriteEffects.FlipHorizontally : SpriteEffects.None); - - } - return false; - } - } -} diff --git a/Projectiles/Melee/Cyclone.cs b/Projectiles/Melee/Cyclone.cs new file mode 100644 index 0000000000..0a14bde12d --- /dev/null +++ b/Projectiles/Melee/Cyclone.cs @@ -0,0 +1,125 @@ +using CalamityMod.CalPlayer; +using Microsoft.Xna.Framework; +using System; +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; +using Terraria.Audio; + +namespace CalamityMod.Projectiles.Melee +{ + public class Cyclone : ModProjectile, ILocalizedModType + { + public new string LocalizationCategory => "Projectiles.Melee"; + public int dustvortex = 0; + public override void SetStaticDefaults() + { + ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; + ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + } + + public override void SetDefaults() + { + Projectile.width = 56; + Projectile.height = 56; + Projectile.alpha = 255; + Projectile.friendly = true; + Projectile.DamageType = DamageClass.Melee; + Projectile.timeLeft = 300; + Projectile.extraUpdates = 2; + Projectile.penetrate = 2; + Projectile.ignoreWater = true; + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = -1; + Projectile.tileCollide = false; + } + + public override void AI() + { + Projectile.ai[0]++; + Projectile.ai[1]++; + + //Code so it doesnt collide on tiles instantly + if (Projectile.ai[0] >= 12) + Projectile.tileCollide = true; + + Projectile.rotation += 2.5f; + Projectile.alpha -= 5; + if (Projectile.alpha < 50) + { + Projectile.alpha = 50; + if (Projectile.ai[1] >= 15) + { + + for (int i = 1; i <= 6; i++) + { + Vector2 dustspeed = new Vector2(3f, 3f).RotatedBy(MathHelper.ToRadians(dustvortex)); + int d = Dust.NewDust(Projectile.Center, Projectile.width / 2, Projectile.height / 2, 31, dustspeed.X, dustspeed.Y, 200, new Color(232, 251, 250, 200), 1.3f); + Main.dust[d].noGravity = true; + Main.dust[d].velocity = dustspeed; + dustvortex += 60; + } + dustvortex -= 355; + Projectile.ai[1] = 0; + } + } + float num472 = Projectile.Center.X; + float num473 = Projectile.Center.Y; + float num474 = 600f; + for (int num475 = 0; num475 < Main.maxNPCs; num475++) + { + NPC npc = Main.npc[num475]; + if (npc.CanBeChasedBy(Projectile, false) && Collision.CanHit(Projectile.Center, 1, 1, npc.Center, 1, 1) && !CalamityPlayer.areThereAnyDamnBosses) + { + float npcCenterX = npc.position.X + (float)(npc.width / 2); + float npcCenterY = npc.position.Y + (float)(npc.height / 2); + float num478 = Math.Abs(Projectile.position.X + (float)(Projectile.width / 2) - npcCenterX) + Math.Abs(Projectile.position.Y + (float)(Projectile.height / 2) - npcCenterY); + if (num478 < num474) + { + if (npc.position.X < num472) + { + npc.velocity.X += 0.05f; + } + else + { + npc.velocity.X -= 0.05f; + } + if (npc.position.Y < num473) + { + npc.velocity.Y += 0.05f; + } + else + { + npc.velocity.Y -= 0.05f; + } + } + } + } + } + + public override Color? GetAlpha(Color lightColor) + { + return new Color(204, 255, 255, Projectile.alpha); + } + + public override bool PreDraw(ref Color lightColor) + { + CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], lightColor, 1); + return false; + } + + public override void OnKill(int timeLeft) + { + SoundEngine.PlaySound(SoundID.Item60 with { Volume = SoundID.Item60.Volume * 0.6f }, Projectile.Center); + + for (int i = 0; i <= 360; i += 3) + { + Vector2 dustspeed = new Vector2(3f, 3f).RotatedBy(MathHelper.ToRadians(i)); + int d = Dust.NewDust(Projectile.Center, Projectile.width, Projectile.height, 31, dustspeed.X, dustspeed.Y, 200, new Color(232, 251, 250, 200), 1.4f); + Main.dust[d].noGravity = true; + Main.dust[d].position = Projectile.Center; + Main.dust[d].velocity = dustspeed; + } + } + } +} diff --git a/Projectiles/Melee/WindBolt.png b/Projectiles/Melee/Cyclone.png similarity index 100% rename from Projectiles/Melee/WindBolt.png rename to Projectiles/Melee/Cyclone.png diff --git a/Projectiles/Melee/WindBladeHoldout.cs b/Projectiles/Melee/WindBladeHoldout.cs deleted file mode 100644 index 50d4a88d50..0000000000 --- a/Projectiles/Melee/WindBladeHoldout.cs +++ /dev/null @@ -1,132 +0,0 @@ -using CalamityMod.Items.Weapons.Melee; -using CalamityMod.Particles; -using CalamityMod.Projectiles.BaseProjectiles; -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.Audio; -using Terraria.DataStructures; -using Terraria.ID; -using Terraria.Localization; -using Terraria.ModLoader; - -namespace CalamityMod.Projectiles.Melee -{ - public class WindBladeHoldout : BaseCustomUseStyleProjectile, ILocalizedModType - { - public override LocalizedText DisplayName => CalamityUtils.GetItemName(); - - public override float HitboxOutset => 60; - - public override Vector2 HitboxSize => new Vector2(70, 70); - public override float HitboxRotationOffset => MathHelper.ToRadians(-45); - - public override Vector2 SpriteOrigin => new(0, 80); - - public override void SetDefaults() - { - base.SetDefaults(); - Projectile.usesLocalNPCImmunity = true; - Projectile.localNPCHitCooldown = 10; - } - - public override void OnSpawn(IEntitySource source) - { - Projectile.scale = 0f; - Projectile.ai[1] = 1; - base.OnSpawn(source); - } - - public override void UseStyle() - { - Vector2 mousePos = Owner.Calamity().mouseWorld; - - if (mousePos.X < Owner.Center.X) Owner.direction = -1; - else Owner.direction = 1; - - DrawUnconditionally = true; - - if (NumberOfAnimations % 4 < 2) - { - Projectile.rotation = Owner.AngleTo(mousePos) + MathHelper.ToRadians(45f); - - if (NumberOfAnimations % 4 == 0 && AnimationProgress < 10) - Projectile.scale = MathHelper.Lerp(Projectile.scale, 1f, 0.4f); - - if (AnimationProgress < (Owner.itemAnimationMax / 3)) - { - CanHit = false; - if (AnimationProgress == 0) - { - Projectile.ai[1] = -Projectile.ai[1]; - } - RotationOffset = MathHelper.Lerp(RotationOffset, MathHelper.ToRadians(120f * Projectile.ai[1] * Owner.direction), 0.2f); - } - else - { - CanHit = true; - if ((int)AnimationProgress == (int)(Owner.itemAnimationMax / 1.5f)) - { - SoundEngine.PlaySound(SoundID.DD2_MonkStaffSwing, Owner.Center); - } - if ((int)AnimationProgress > (int)(Owner.itemAnimationMax / 1.5f)) - { - GeneralParticleHandler.SpawnParticle(new HeavySmokeParticle(Owner.Center + (new Vector2(Main.rand.Next(30, 100), 0).RotatedBy(FinalRotation + MathHelper.ToRadians(-45))), new Vector2(0, 10 * -Projectile.ai[1] * Owner.direction).RotatedBy(FinalRotation + MathHelper.ToRadians(-45)), Color.LightSkyBlue, 40, 1f, 0.4f, MathHelper.ToRadians(Main.rand.NextFloat(-10f, 10f)), true)); - } - - float time = (AnimationProgress) - (Owner.itemAnimationMax / 3); - float timeMax = Owner.itemAnimationMax - (Owner.itemAnimationMax / 3); - - RotationOffset = MathHelper.Lerp(RotationOffset, MathHelper.ToRadians(MathHelper.Lerp(150f * Projectile.ai[1] * Owner.direction, 120f * -Projectile.ai[1] * Owner.direction, CalamityUtils.ExpInOutEasing(time / timeMax, 1))), - 0.2f); - } - - FlipAsSword = Owner.direction == -1 ? true : false; - } - else if (NumberOfAnimations % 4 == 3) - { - float ProjectileSpeed = 10; - int ProjectileDamage = (int)(Projectile.damage * 0.3f); - float ProjectileKnockback = (int)(Projectile.knockBack * 0.5f); - CanHit = true; - if ((int)AnimationProgress == 1) - { - SoundEngine.PlaySound(SoundID.DD2_SkyDragonsFurySwing, Owner.Center); - SoundEngine.PlaySound(SoundID.DD2_MonkStaffSwing.WithPitchOffset(-0.4f), Owner.Center); - - Projectile.NewProjectile(new EntitySource_ItemUse(Owner, Owner.HeldItem), Projectile.Hitbox.Center.ToVector2(), new Vector2(ProjectileSpeed, 0).RotatedBy(FinalRotation + MathHelper.ToRadians(-45)), ModContent.ProjectileType(), ProjectileDamage, ProjectileKnockback, Owner.whoAmI); - } - RotationOffset = 0f; - if (AnimationProgress < Owner.itemAnimationMax / 3) - { - Projectile.scale = MathHelper.Lerp(Projectile.scale, 1.5f, 0.4f); - - float rot = FinalRotation + MathHelper.ToRadians(-45); - - GeneralParticleHandler.SpawnParticle(new HeavySmokeParticle(Owner.Center + new Vector2(105 * Projectile.scale, 0).RotatedBy(rot), new Vector2(5, 0).RotatedBy(rot + MathHelper.ToRadians(Main.rand.NextFloat(-20, 20))), Color.LightSkyBlue, 30, 2f, 0.3f, MathHelper.ToRadians(Main.rand.NextFloat(-10f, 10f)), true)); - GeneralParticleHandler.SpawnParticle(new LineParticle(Owner.Center + new Vector2(0, 20).RotatedBy(rot) + new Vector2(45 * Projectile.scale, 0).RotatedBy(rot), new Vector2(5, 0).RotatedBy(rot), false, 30, 1f, Color.LightSkyBlue)); - GeneralParticleHandler.SpawnParticle(new LineParticle(Owner.Center + new Vector2(0, -20).RotatedBy(rot) + new Vector2(45 * Projectile.scale, 0).RotatedBy(rot), new Vector2(5, 0).RotatedBy(rot), false, 30, 1f, Color.LightSkyBlue)); - } - else - { - Projectile.scale = MathHelper.Lerp(Projectile.scale, 1.5f, -0.2f); - } - } - else - { - CanHit = false; - - RotationOffset = MathHelper.Lerp(RotationOffset, MathHelper.ToRadians(MathHelper.Lerp(150f * -Projectile.ai[1] * Owner.direction, 120f * Projectile.ai[1] * Owner.direction, 0.1f)), - 0.2f); - - Projectile.rotation = Owner.AngleTo(mousePos) + MathHelper.ToRadians(45f); - Projectile.scale = MathHelper.Lerp(Projectile.scale, 0f, 0.2f); - } - - ArmRotationOffset = MathHelper.ToRadians(-90f); - } - - public override void ResetStyle() - { - } - } -} diff --git a/Projectiles/Melee/WindBladeHoldout.png b/Projectiles/Melee/WindBladeHoldout.png deleted file mode 100644 index b08f34b7d98f5f3f7a38e51a7dd73f46a2afc898..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 870 zcmeAS@N?(olHy`uVBq!ia0vp^UO*he!3-pYE(NXtQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ivoN?Tn$sRP1>73{Jz+6c$H=S?vVfgZT9cb@Cd7$R6cccw!FDxLSBT0 zyhPo^a^CEQ5DSqR)utI%ie|2rN7kfT*6;d#qovuIOG;L?*@-JB!R+;!#^2YQ&0QlBSEMj7FnN2rIEF;HpS|8)v|2%cEn(7x1s<_eqCS49`}jBhcDuc;3l-beO!lq% z`npHgZn*nMu*dzh-AfIT>8Z1Mr=7L;z&Zj1Mhn$j_SCl<_!meY-<~1Gabt~Jw$)%X-xA3FCfA<#i^DpqzeXMDyX`&HV zyn)fcc}vv8`@CB+F5B2WIv+FtkP%zhb&c~;TO8*_pT2TgIM17lDlc{~n&_b0_XxaXoxbN=EO?x@za_2I+Iw${SZ| z-cZ=0#})AYea)ZGM)Qp1U9W8OsjXS?VU?HfLsJg%MUs2o|K7HjWmfwv1({OWY5LPX zepqcRJpYl|gT?Et_v`WtPtS_BdGq1Y;RmUyZ-u9?(s~{swCv}09-+xjk<+(6D)01^ h6mE806j=LTJkb1E_Xp`4e}QR@!PC{xWt~$(697sik}v=O diff --git a/Projectiles/Melee/WindBolt.cs b/Projectiles/Melee/WindBolt.cs deleted file mode 100644 index 08ec3d63f3..0000000000 --- a/Projectiles/Melee/WindBolt.cs +++ /dev/null @@ -1,146 +0,0 @@ -using System; -using CalamityMod.CalPlayer; -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.Audio; -using Terraria.ID; -using Terraria.ModLoader; -using Microsoft.Xna.Framework.Graphics; -using ReLogic.Content; -using Terraria; -using Terraria.Audio; -using Terraria.GameContent.UI; -using Terraria.ID; -using Terraria.ModLoader; -using Terraria.Utilities.Terraria.Utilities; -using XPT.Core.Audio.MP3Sharp.Decoding.Decoders.LayerIII; - -namespace CalamityMod.Projectiles.Melee -{ - public class WindBolt : ModProjectile, ILocalizedModType - { - public new string LocalizationCategory => "Projectiles.Melee"; - public int dustvortex = 0; - public float scFactor = 0f; - public override void SetStaticDefaults() - { - ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; - ProjectileID.Sets.TrailingMode[Projectile.type] = 0; - } - - public override void SetDefaults() - { - Projectile.width = 40; - Projectile.height = 40; - Projectile.alpha = 255; - Projectile.friendly = true; - Projectile.DamageType = DamageClass.Melee; - Projectile.timeLeft = 300; - Projectile.extraUpdates = 2; - Projectile.penetrate = -1; - Projectile.ignoreWater = true; - Projectile.usesLocalNPCImmunity = true; - Projectile.localNPCHitCooldown = 8 * Projectile.MaxUpdates; - Projectile.tileCollide = false; - } - - public override void AI() - { - Projectile.velocity *= 0.98f; - - Projectile.ai[0]++; - Projectile.ai[1]++; - - //Code so it doesnt collide on tiles instantly - if (Projectile.ai[0] >= 12) - Projectile.tileCollide = true; - - Projectile.rotation += MathHelper.ToRadians(1f); - Projectile.alpha -= 5; - { - Projectile.alpha = 50; - if (Projectile.ai[1] >= 15) - { - scFactor = MathHelper.Lerp(scFactor, 1f, 0.1f); - for (int i = 1; i <= 6; i++) - { - Vector2 dustpos = new Vector2(48f, 48f).RotatedBy(MathHelper.ToRadians(dustvortex + Main.rand.Next(30))); - Vector2 dustspeed = new Vector2(-5f, -5f).RotatedBy(MathHelper.ToRadians(dustvortex + Main.rand.Next(30))); - int d = Dust.NewDust(Projectile.Center + dustpos, Projectile.width / 2, Projectile.height / 2, DustID.Smoke, dustspeed.X, dustspeed.Y, 200, new Color(232, 251, 250, 50), 1.3f); - - Main.dust[d].noGravity = true; - Main.dust[d].velocity = dustspeed; - dustvortex += 60; - } - dustvortex -= 355; - Projectile.ai[1] = 0; - } - } - float projX = Projectile.Center.X; - float projY = Projectile.Center.Y; - foreach (var npc in Main.ActiveNPCs) - { - if (npc.CanBeChasedBy(Projectile, false) && Collision.CanHit(Projectile.Center, 1, 1, npc.Center, 1, 1)) - { - if (!CalamityPlayer.areThereAnyDamnBosses) // Pulls enemies in while no boss is alive - { - float npcCenterX = npc.position.X + (float)(npc.width / 2); - float npcCenterY = npc.position.Y + (float)(npc.height / 2); - float npcDistance = Math.Abs(Projectile.position.X + (float)(Projectile.width / 2) - npcCenterX) + Math.Abs(Projectile.position.Y + (float)(Projectile.height / 2) - npcCenterY); - if (npcDistance < 320f) - { - float factor = MathHelper.Lerp(1f, 0f, CalamityUtils.SineBumpEasing(npcDistance / 300, 1)); - - npc.velocity += npc.DirectionTo(Projectile.Center) * factor * 0.25f; - } - if (npcDistance < 40) - npc.velocity *= 0.75f; - } - else // Pulls itself toward enemies while a boss is alive so that the gimmick isn't entirely lost - { - if (Math.Abs(Projectile.velocity.X) < 1.5f && Math.Abs(Projectile.velocity.Y) < 1.5f) - CalamityUtils.HomeInOnNPC(Projectile, false, 320f, 1.5f, 20f); - } - } - } - } - - public override bool PreDraw(ref Color lightColor) - { - Asset tex = ModContent.Request(Texture); - - for (int i = 5; i >= 0; i--) - { - float c = Math.Max(i, 1); - - Main.EntitySpriteDraw(tex.Value, Projectile.Center - Main.screenPosition, tex.Frame(), new Color(1f / c, 1f / c, 1f / c, 1f / c), -Projectile.rotation * c, tex.Size() / 2, (float)MathHelper.Lerp(1f, i, scFactor), SpriteEffects.None); - } - - return false; - } - - public override void ModifyDamageHitbox(ref Rectangle hitbox) - { - // The hitbox gets bigger over time, because the vortex visually grows - int sizeIncrease = (int)(Projectile.ai[0] * 0.3f); - hitbox.Inflate(sizeIncrease, sizeIncrease); - } - - // The vortex slows down on enemies hits, so that it is easier for it to linger on top of stuff - public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) => Projectile.velocity *= 0.5f; - - public override void OnKill(int timeLeft) - { - SoundEngine.PlaySound(SoundID.Item60 with { Volume = SoundID.Item60.Volume * 0.6f }, Projectile.Center); - - for (int i = 0; i <= 360; i += 3) - { - Vector2 dustspeed = new Vector2(12f, 12f).RotatedBy(MathHelper.ToRadians(i)); - int d = Dust.NewDust(Projectile.Center + (dustspeed * 2), Projectile.width, Projectile.height, DustID.Smoke, dustspeed.X, dustspeed.Y, 200, new Color(232, 251, 250, 200), 1.4f); - Main.dust[d].noGravity = true; - Main.dust[d].position = Projectile.Center; - Main.dust[d].velocity = dustspeed; - } - } - } -} From e2754bf5e034e95441325cc139383b49bd92f94d Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Wed, 22 May 2024 18:24:49 -0700 Subject: [PATCH 058/401] you can now place lab crates on each other this does NOT make them count as tables for crafting --- Tiles/DraedonStructures/AgedReinforcedCrate.cs | 1 + Tiles/DraedonStructures/ReinforcedCrate.cs | 1 + Tiles/FurnitureAuric/AuricReinforcedCrateTile.cs | 1 + 3 files changed, 3 insertions(+) diff --git a/Tiles/DraedonStructures/AgedReinforcedCrate.cs b/Tiles/DraedonStructures/AgedReinforcedCrate.cs index 6ff4190e16..826777407f 100644 --- a/Tiles/DraedonStructures/AgedReinforcedCrate.cs +++ b/Tiles/DraedonStructures/AgedReinforcedCrate.cs @@ -19,6 +19,7 @@ public override void SetStaticDefaults() Main.tileNoAttach[Type] = true; Main.tileLavaDeath[Type] = false; Main.tileWaterDeath[Type] = false; + Main.tileTable[Type] = true; Main.tileSolidTop[Type] = true; TileObjectData.newTile.CopyFrom(TileObjectData.Style2x2); TileObjectData.newTile.LavaDeath = false; diff --git a/Tiles/DraedonStructures/ReinforcedCrate.cs b/Tiles/DraedonStructures/ReinforcedCrate.cs index 114871a032..06b9c32ffe 100644 --- a/Tiles/DraedonStructures/ReinforcedCrate.cs +++ b/Tiles/DraedonStructures/ReinforcedCrate.cs @@ -19,6 +19,7 @@ public override void SetStaticDefaults() Main.tileNoAttach[Type] = true; Main.tileLavaDeath[Type] = false; Main.tileWaterDeath[Type] = false; + Main.tileTable[Type] = true; Main.tileSolidTop[Type] = true; TileObjectData.newTile.CopyFrom(TileObjectData.Style2x2); TileObjectData.newTile.LavaDeath = false; diff --git a/Tiles/FurnitureAuric/AuricReinforcedCrateTile.cs b/Tiles/FurnitureAuric/AuricReinforcedCrateTile.cs index 5c8fa7fa53..6fcdd98125 100644 --- a/Tiles/FurnitureAuric/AuricReinforcedCrateTile.cs +++ b/Tiles/FurnitureAuric/AuricReinforcedCrateTile.cs @@ -17,6 +17,7 @@ public override void SetStaticDefaults() Main.tileLavaDeath[Type] = false; Main.tileWaterDeath[Type] = false; Main.tileSolidTop[Type] = true; + Main.tileTable[Type] = true; TileObjectData.newTile.CopyFrom(TileObjectData.Style2x2); TileObjectData.newTile.LavaDeath = false; TileObjectData.addTile(Type); From 2f2ce3999da6d92903fb04d6e0adbf5e1bf27165 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Fri, 24 May 2024 02:54:37 -0500 Subject: [PATCH 059/401] Rev+ Eye of Cthulhu cannot do its horizontal charge unless it is within a 10 block radius of its charge position, it also increases its velocity to move to that position if it's taking too long to reach it. --- .../Bosses/EyeOfCthulhuAI.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/EyeOfCthulhuAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/EyeOfCthulhuAI.cs index 535d6b48c8..ef469adf25 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/EyeOfCthulhuAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/EyeOfCthulhuAI.cs @@ -736,6 +736,16 @@ public static bool BuffedEyeofCthulhuAI(NPC npc, Mod mod) float accelerationBoost = death ? 0.425f * (phase3LifeRatio - lifeRatio) : 0.125f * (phase3LifeRatio - lifeRatio); float hoverSpeed = 8f + speedBoost; float hoverAcceleration = 0.25f + accelerationBoost; + + bool horizontalCharge = calamityGlobalNPC.newAI[0] == 1f || calamityGlobalNPC.newAI[0] == 3f; + float timeGateValue = horizontalCharge ? (100f - (death ? 80f * (phase3LifeRatio - lifeRatio) : 0f)) : (85f - (death ? 70f * (phase3LifeRatio - lifeRatio) : 0f)); + if (npc.ai[2] > timeGateValue) + { + float velocityScalar = npc.ai[2] - timeGateValue; + hoverSpeed += velocityScalar * 0.05f; + hoverAcceleration += velocityScalar * 0.0025f; + } + hoverSpeed += enrageScale * 4f; hoverAcceleration += enrageScale * 0.125f; @@ -744,7 +754,6 @@ public static bool BuffedEyeofCthulhuAI(NPC npc, Mod mod) float lineUpChargeTargetY = Main.player[npc.target].Center.Y + offset - eyeLineUpChargeDirection.Y; Vector2 hoverDestination = Main.player[npc.target].Center + Vector2.UnitY * offset; - bool horizontalCharge = calamityGlobalNPC.newAI[0] == 1f || calamityGlobalNPC.newAI[0] == 3f; if (horizontalCharge) { float horizontalChargeOffset = death ? 450f : 500f; @@ -757,7 +766,6 @@ public static bool BuffedEyeofCthulhuAI(NPC npc, Mod mod) Vector2 idealHoverVelocity = npc.SafeDirectionTo(hoverDestination) * hoverSpeed; npc.SimpleFlyMovement(idealHoverVelocity, hoverAcceleration); - float timeGateValue = horizontalCharge ? (100f - (death ? 80f * (phase3LifeRatio - lifeRatio) : 0f)) : (85f - (death ? 70f * (phase3LifeRatio - lifeRatio) : 0f)); float servantSpawnGateValue = horizontalCharge ? (death ? 23f : 35f) : (death ? 17f : 27f); float maxServantSpawnsPerAttack = 2f; @@ -837,7 +845,8 @@ public static bool BuffedEyeofCthulhuAI(NPC npc, Mod mod) } } - if (npc.ai[2] >= timeGateValue) + float requiredDistanceForHorizontalCharge = 160f; + if (npc.ai[2] >= timeGateValue && (npc.Distance(hoverDestination) < requiredDistanceForHorizontalCharge || !horizontalCharge)) { switch ((int)calamityGlobalNPC.newAI[0]) { From f4a7ddb20ee24aec143f70167494883a2b01b185 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Thu, 23 May 2024 12:02:34 -0400 Subject: [PATCH 060/401] Internally renamed King Slime's jewels --- CalamityLists.cs | 12 ++++++------ DataStructures/NPCStats.cs | 4 ++-- Events/BossRushEvent.cs | 4 ++-- Localization/en-US/Mods.CalamityMod.NPCs.hjson | 4 ++++ ModSupport/WeakReferenceSupport.cs | 6 +++--- NPCs/CalamityGlobalNPC.cs | 2 +- ...ngSlimeJewel3.cs => KingSlimeJewelEmerald.cs} | 2 +- .../{KingSlimeJewel.cs => KingSlimeJewelRuby.cs} | 4 +++- ...gSlimeJewel2.cs => KingSlimeJewelSapphire.cs} | 2 +- NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs | 16 ++++++++-------- Utilities/NPCDebuffs.cs | 6 +++--- 11 files changed, 34 insertions(+), 28 deletions(-) rename NPCs/NormalNPCs/{KingSlimeJewel3.cs => KingSlimeJewelEmerald.cs} (99%) rename NPCs/NormalNPCs/{KingSlimeJewel.cs => KingSlimeJewelRuby.cs} (98%) rename NPCs/NormalNPCs/{KingSlimeJewel2.cs => KingSlimeJewelSapphire.cs} (99%) diff --git a/CalamityLists.cs b/CalamityLists.cs index 0e29515d35..b8ebd102e5 100644 --- a/CalamityLists.cs +++ b/CalamityLists.cs @@ -901,9 +901,9 @@ public static void LoadLists() enemyImmunityList = new List() { NPCID.KingSlime, - NPCType(), - NPCType(), - NPCType(), + NPCType(), + NPCType(), + NPCType(), NPCID.EaterofWorldsHead, NPCID.EaterofWorldsBody, NPCID.EaterofWorldsTail, @@ -2428,9 +2428,9 @@ public static void LoadLists() { NPCID.UmbrellaSlime, 5400 }, { NPCID.RainbowSlime, 30000 }, { NPCID.Pinky, 15000 }, - { NPCType(), 21000 }, - { NPCType(), 18000 }, - { NPCType(), 24000 }, + { NPCType(), 21000 }, + { NPCType(), 18000 }, + { NPCType(), 24000 }, { NPCID.EyeofCthulhu, 450000 }, // 30 seconds { NPCID.ServantofCthulhu, 6000 }, diff --git a/DataStructures/NPCStats.cs b/DataStructures/NPCStats.cs index 70bc44c14e..0aec9726b2 100644 --- a/DataStructures/NPCStats.cs +++ b/DataStructures/NPCStats.cs @@ -295,7 +295,7 @@ internal static void LoadEnemyStats() EnemyStats.ContactDamageValues = new SortedDictionary { { NPCID.KingSlime, new int[] { 40, 64, 80, 96, 144 } }, - { ModContent.NPCType(), new int[] { 30, 44, 60, 76, 114 } }, + { ModContent.NPCType(), new int[] { 30, 44, 60, 76, 114 } }, { ModContent.NPCType(), new int[] { 45, 66, 88, 110, 165 } }, { ModContent.NPCType(), new int[] { 24, 32, 40, 48, 72 } }, @@ -561,7 +561,7 @@ internal static void LoadEnemyStats() EnemyStats.ProjectileDamageValues = new SortedDictionary, int[]> { - { new Tuple(ModContent.NPCType(), ModContent.ProjectileType()), new int[] { 26, 36, 44, 52, 84 } }, + { new Tuple(ModContent.NPCType(), ModContent.ProjectileType()), new int[] { 26, 36, 44, 52, 84 } }, { new Tuple(ModContent.NPCType(), ModContent.ProjectileType()), new int[] { 26, 36, 44, 52, 84 } }, { new Tuple(ModContent.NPCType(), ModContent.ProjectileType()), new int[] { 26, 36, 44, 52, 84 } }, diff --git a/Events/BossRushEvent.cs b/Events/BossRushEvent.cs index 6da1815a4d..5c8491e682 100644 --- a/Events/BossRushEvent.cs +++ b/Events/BossRushEvent.cs @@ -150,8 +150,8 @@ public static void Load() DownedBossSystem.startedBossRushAtLeastOnce = true; }, permittedNPCs: new int[] { NPCID.BlueSlime, NPCID.YellowSlime, NPCID.PurpleSlime, NPCID.RedSlime, NPCID.GreenSlime, NPCID.RedSlime, - NPCID.IceSlime, NPCID.UmbrellaSlime, NPCID.Pinky, NPCID.SlimeSpiked, NPCID.RainbowSlime, ModContent.NPCType(), - ModContent.NPCType(), ModContent.NPCType() }), + NPCID.IceSlime, NPCID.UmbrellaSlime, NPCID.Pinky, NPCID.SlimeSpiked, NPCID.RainbowSlime, ModContent.NPCType(), + ModContent.NPCType(), ModContent.NPCType() }), new Boss(ModContent.NPCType(), spawnContext: type => { diff --git a/Localization/en-US/Mods.CalamityMod.NPCs.hjson b/Localization/en-US/Mods.CalamityMod.NPCs.hjson index 1d7421b644..42d943f37f 100644 --- a/Localization/en-US/Mods.CalamityMod.NPCs.hjson +++ b/Localization/en-US/Mods.CalamityMod.NPCs.hjson @@ -623,3 +623,7 @@ WITCH: { Princess_LovesNPC: "{NPCName} is always lonely, it's why I want to hang out with her, no one should be left alone like that!" } } + +KingSlimeJewelEmerald.DisplayName: King Slime Jewel Emerald +KingSlimeJewelRuby.DisplayName: King Slime Jewel Ruby +KingSlimeJewelSapphire.DisplayName: King Slime Jewel Sapphire diff --git a/ModSupport/WeakReferenceSupport.cs b/ModSupport/WeakReferenceSupport.cs index 086ae693e4..16293e26d9 100644 --- a/ModSupport/WeakReferenceSupport.cs +++ b/ModSupport/WeakReferenceSupport.cs @@ -296,9 +296,9 @@ public static void WikiThisSupport() // Enemies EnemyRedirect(NPCType(), "Hive (enemy)"); - EnemyRedirect(NPCType(), "Ruby Jewel (enemy)"); - EnemyRedirect(NPCType(), "Sapphire Jewel (enemy)"); - EnemyRedirect(NPCType(), "Emerald Jewel (enemy)"); + EnemyRedirect(NPCType(), "Crown Jewels"); + EnemyRedirect(NPCType(), "Crown Jewels"); + EnemyRedirect(NPCType(), "Crown Jewels"); EnemyRedirect(NPCType(), "Tooth Ball (Old Duke)"); EnemyRedirect(NPCType(), "Enchantment"); EnemyRedirect(NPCType(), "%3F%3F%3F"); diff --git a/NPCs/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index 5cb59af057..3ae1aabefa 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -6474,7 +6474,7 @@ public override void DrawEffects(NPC npc, ref Color drawColor) return new Color(Main.DiscoR, Main.DiscoG, Main.DiscoB, Main.DiscoR); if (npc.type == NPCID.KingSlime && Main.masterMode && CalamityWorld.revenge) - return NPC.AnyNPCs(ModContent.NPCType()) ? Color.Lerp(new Color(0, 0, 150, npc.alpha), new Color(125, 125, 255, npc.alpha), (float)Math.Sin(Main.GlobalTimeWrappedHourly) / 2f + 0.5f) : null; + return NPC.AnyNPCs(ModContent.NPCType()) ? Color.Lerp(new Color(0, 0, 150, npc.alpha), new Color(125, 125, 255, npc.alpha), (float)Math.Sin(Main.GlobalTimeWrappedHourly) / 2f + 0.5f) : null; if (npc.type == NPCID.QueenBee && Main.zenithWorld) { diff --git a/NPCs/NormalNPCs/KingSlimeJewel3.cs b/NPCs/NormalNPCs/KingSlimeJewelEmerald.cs similarity index 99% rename from NPCs/NormalNPCs/KingSlimeJewel3.cs rename to NPCs/NormalNPCs/KingSlimeJewelEmerald.cs index 531da13e74..5d5160792f 100644 --- a/NPCs/NormalNPCs/KingSlimeJewel3.cs +++ b/NPCs/NormalNPCs/KingSlimeJewelEmerald.cs @@ -10,7 +10,7 @@ namespace CalamityMod.NPCs.NormalNPCs { - public class KingSlimeJewel3 : ModNPC + public class KingSlimeJewelEmerald : ModNPC { public override string Texture => "CalamityMod/NPCs/NormalNPCs/KingSlimeJewel"; diff --git a/NPCs/NormalNPCs/KingSlimeJewel.cs b/NPCs/NormalNPCs/KingSlimeJewelRuby.cs similarity index 98% rename from NPCs/NormalNPCs/KingSlimeJewel.cs rename to NPCs/NormalNPCs/KingSlimeJewelRuby.cs index c9eb84f9d6..327d1d0054 100644 --- a/NPCs/NormalNPCs/KingSlimeJewel.cs +++ b/NPCs/NormalNPCs/KingSlimeJewelRuby.cs @@ -10,8 +10,10 @@ namespace CalamityMod.NPCs.NormalNPCs { - public class KingSlimeJewel : ModNPC + public class KingSlimeJewelRuby : ModNPC { + public override string Texture => "CalamityMod/NPCs/NormalNPCs/KingSlimeJewel"; + private const int BoltShootGateValue = 60; private const int BoltShootGateValue_Death = 75; private const int BoltShootGateValue_BossRush = 45; diff --git a/NPCs/NormalNPCs/KingSlimeJewel2.cs b/NPCs/NormalNPCs/KingSlimeJewelSapphire.cs similarity index 99% rename from NPCs/NormalNPCs/KingSlimeJewel2.cs rename to NPCs/NormalNPCs/KingSlimeJewelSapphire.cs index 254ef1471e..a41db05782 100644 --- a/NPCs/NormalNPCs/KingSlimeJewel2.cs +++ b/NPCs/NormalNPCs/KingSlimeJewelSapphire.cs @@ -11,7 +11,7 @@ namespace CalamityMod.NPCs.NormalNPCs { - public class KingSlimeJewel2 : ModNPC + public class KingSlimeJewelSapphire : ModNPC { public override string Texture => "CalamityMod/NPCs/NormalNPCs/KingSlimeJewel"; diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs index c0555e7cae..15bd1a8e83 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs @@ -61,16 +61,16 @@ public static bool BuffedKingSlimeAI(NPC npc, Mod mod) if (spawnGreenCrystal) { if (masterMode) - greenCrystalAlive = NPC.AnyNPCs(ModContent.NPCType()); + greenCrystalAlive = NPC.AnyNPCs(ModContent.NPCType()); } if (phase3) - crystalAlive = NPC.AnyNPCs(ModContent.NPCType()); + crystalAlive = NPC.AnyNPCs(ModContent.NPCType()); if (spawnBlueCrystal) { if (masterMode) - blueCrystalAlive = NPC.AnyNPCs(ModContent.NPCType()); + blueCrystalAlive = NPC.AnyNPCs(ModContent.NPCType()); } // Sapphire Crystal buffs @@ -109,7 +109,7 @@ public static bool BuffedKingSlimeAI(NPC npc, Mod mod) SoundEngine.PlaySound(SoundID.Item38, vector); if (Main.netMode != NetmodeID.MultiplayerClient) - NPC.NewNPC(npc.GetSource_FromAI(), (int)vector.X, (int)vector.Y, ModContent.NPCType()); + NPC.NewNPC(npc.GetSource_FromAI(), (int)vector.X, (int)vector.Y, ModContent.NPCType()); } if (phase3 && npc.Calamity().newAI[0] == 1f) @@ -133,7 +133,7 @@ public static bool BuffedKingSlimeAI(NPC npc, Mod mod) SoundEngine.PlaySound(SoundID.Item38, vector); if (Main.netMode != NetmodeID.MultiplayerClient) - NPC.NewNPC(npc.GetSource_FromAI(), (int)vector.X, (int)vector.Y, ModContent.NPCType()); + NPC.NewNPC(npc.GetSource_FromAI(), (int)vector.X, (int)vector.Y, ModContent.NPCType()); } if (spawnBlueCrystal && npc.Calamity().newAI[0] == 2f) @@ -157,7 +157,7 @@ public static bool BuffedKingSlimeAI(NPC npc, Mod mod) SoundEngine.PlaySound(SoundID.Item38, vector); if (Main.netMode != NetmodeID.MultiplayerClient) - NPC.NewNPC(npc.GetSource_FromAI(), (int)vector.X, (int)vector.Y, ModContent.NPCType()); + NPC.NewNPC(npc.GetSource_FromAI(), (int)vector.X, (int)vector.Y, ModContent.NPCType()); } } else @@ -184,7 +184,7 @@ public static bool BuffedKingSlimeAI(NPC npc, Mod mod) SoundEngine.PlaySound(SoundID.Item38, vector); if (Main.netMode != NetmodeID.MultiplayerClient) - NPC.NewNPC(npc.GetSource_FromAI(), (int)vector.X, (int)vector.Y, ModContent.NPCType()); + NPC.NewNPC(npc.GetSource_FromAI(), (int)vector.X, (int)vector.Y, ModContent.NPCType()); } } @@ -340,7 +340,7 @@ public static bool BuffedKingSlimeAI(NPC npc, Mod mod) for (int i = 0; i < Main.maxNPCs; i++) { NPC blueCrystal = Main.npc[i]; - if (blueCrystal.active && blueCrystal.type == ModContent.NPCType()) + if (blueCrystal.active && blueCrystal.type == ModContent.NPCType()) { blueCrystal.position.X = npc.position.X; blueCrystal.position.Y = npc.position.Y - 200f; diff --git a/Utilities/NPCDebuffs.cs b/Utilities/NPCDebuffs.cs index c66dbc74d2..ff965a1105 100644 --- a/Utilities/NPCDebuffs.cs +++ b/Utilities/NPCDebuffs.cs @@ -168,9 +168,9 @@ internal static void LoadDebuffs() // Is this sorted... like... at all?? EnemyStats.DebuffImmunities = new SortedDictionary> { - { ModContent.NPCType(), immuneToEverything }, - { ModContent.NPCType(), immuneToEverything }, - { ModContent.NPCType(), immuneToEverything }, + { ModContent.NPCType(), immuneToEverything }, + { ModContent.NPCType(), immuneToEverything }, + { ModContent.NPCType(), immuneToEverything }, { NPCID.Deerclops, ice }, From 9ea16d8a9d07574f921d4ec045dd139770848a24 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Thu, 23 May 2024 12:04:49 -0400 Subject: [PATCH 061/401] Slightly decreased the Craw Carapace buff --- CalPlayer/CalamityPlayerHitHurt.cs | 2 +- CalPlayer/CalamityPlayerMiscEffects.cs | 2 +- Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CalPlayer/CalamityPlayerHitHurt.cs b/CalPlayer/CalamityPlayerHitHurt.cs index 5dce1a0a3e..fe44174ba9 100644 --- a/CalPlayer/CalamityPlayerHitHurt.cs +++ b/CalPlayer/CalamityPlayerHitHurt.cs @@ -1172,7 +1172,7 @@ public override void OnHitByNPC(NPC npc, Player.HurtInfo hurtInfo) if (crawCarapace) { npc.AddBuff(ModContent.BuffType(), 900); - int onHitDamage = Player.CalcIntDamage(50); + int onHitDamage = Player.CalcIntDamage(40); Player.ApplyDamageToNPC(npc, onHitDamage, 0f, 0, false); SoundEngine.PlaySound(SoundID.NPCHit33 with { Volume = 0.5f }, Player.Center); } diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index 0a1bbeb77e..4209e88ed4 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -2581,7 +2581,7 @@ private void OtherBuffEffects() } if (crawCarapace) - Player.GetDamage() += 0.08f; + Player.GetDamage() += 0.07f; if (baroclaw) { diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson index 522ee30e39..0e08965505 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson @@ -428,7 +428,7 @@ CrawCarapace: { DisplayName: Craw Carapace Tooltip: ''' - 8% increased damage + 7% increased damage Enemies that hit you take damage and are inflicted with Crumbling ''' } From 80978973c3b5b8f5c5961cb067a59ca73556697c Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Thu, 23 May 2024 15:05:37 -0400 Subject: [PATCH 062/401] Clock Gatlignum resprite --- Items/Weapons/Ranged/ClockGatlignum.cs | 2 +- Items/Weapons/Ranged/ClockGatlignum.png | Bin 1071 -> 1214 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Items/Weapons/Ranged/ClockGatlignum.cs b/Items/Weapons/Ranged/ClockGatlignum.cs index 47e81821e0..4e4c895e55 100644 --- a/Items/Weapons/Ranged/ClockGatlignum.cs +++ b/Items/Weapons/Ranged/ClockGatlignum.cs @@ -33,7 +33,7 @@ public override void SetDefaults() Item.Calamity().canFirePointBlankShots = true; } - public override Vector2? HoldoutOffset() => new Vector2(-5, 0); + public override Vector2? HoldoutOffset() => new Vector2(-10, 0); public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) { diff --git a/Items/Weapons/Ranged/ClockGatlignum.png b/Items/Weapons/Ranged/ClockGatlignum.png index b3ec2327346e7e8f086f318f5b5724e18b9a14d6..d9483a7d49b35cb956f2e08fc21b1545e9a4bc67 100644 GIT binary patch literal 1214 zcmV;v1VQ_WP)TDCBt(h`qC zYinvOo}3DjQAVrErZZ)|HsC3J3jPU!NRq|gwNR(SGf zBJ3nP4Fde;4!=`_w2QsH;__k9?CAZw_k?HuQ|)JkN4{ROX-|%)BKMTgOSykLFAoV_GDwDS1bXDLr4yV2Z7{L{lB3OvrVN zR~9M3)#y24WxIy*rBadW+=x?%NFouCx`-sljXPs9Wb289(6Umq6Zy_lUvb!S-PkmJ zVNrR7$ou;TgpQ1uvdTJ!mTri=xWk-jh1vR-dTLHO*gcOw7M12xQ}&4ne~m=1Hv;?O z#H>87IN5&Iu&7-cBGL^-um`t~WM?=7lcQn>?O1Po`|fMTvO~p|oksS;m#?CyJ77Ne z+moZBzj@s{xHyBu=6ay7{i^7-A3S{|iy&u$NaTB^VUFBu#P(<(;r4_R4*pcjST;=(2=$9ZuNgJ6z3f;=U#-c7*nvcNFY4yR z>`gXyoNPcSh^5c0b{t8{+%x(`XoyH69FV$*B=TFgHL@dA&)V$Qy~XT3Aa=Rt1;JEn zawC3>vp#DYGjb|=ZjE>&kaH3NvG8;otd}xFA@sKSU%E3P=l%NOB!t3%Qlyc88qyr;rpd9(lWm zh|D{5wqwB%X%Fi-!1&^000B_Nkl*e{ zK9jAjbtk*y@_w#rhbmKkV(SD-)neH~q7k?{j*-sC5x3Zn6$vNEzqvRKvdjbh_q(&++LJ&Njc z$?n=)t|5yqL=vGytg~QeIVPpYBuM; zG&2=wEPbFT2L=#!I7fiUN;Pqr2i#F1bLnkCNeh<&IH)G@<6OGwZEHZ1V!W)65H(_Z z7^@y8FQ!d*`#+L}M#OCX#$CU@fyHgJ4wJoI$(R96fMz7eGNwRt{?Z5o2>U5b1Oip! z)>D>Yu}6o)u0^KnDsY_1u>E}ikr_QottZ%_fD-#fJ0AWYMVIZ__C7D)iT$rHve~6oH p<)f}e_Jh(`86bWS0|+}JzX4TPWMDbUnaltH002ovPDHLkV1lRi=N13} From fdc1eb8fc45d66c06d2ebfc078bae5025d7e79fc Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Thu, 23 May 2024 23:21:10 -0400 Subject: [PATCH 063/401] Desert Nuisances can no longer pick up money --- NPCs/DesertScourge/DesertNuisanceBody.cs | 1 + NPCs/DesertScourge/DesertNuisanceBodyYoung.cs | 1 + NPCs/DesertScourge/DesertNuisanceHead.cs | 1 + NPCs/DesertScourge/DesertNuisanceHeadYoung.cs | 1 + NPCs/DesertScourge/DesertNuisanceTail.cs | 1 + NPCs/DesertScourge/DesertNuisanceTailYoung.cs | 1 + 6 files changed, 6 insertions(+) diff --git a/NPCs/DesertScourge/DesertNuisanceBody.cs b/NPCs/DesertScourge/DesertNuisanceBody.cs index d61794d229..3498f8fe14 100644 --- a/NPCs/DesertScourge/DesertNuisanceBody.cs +++ b/NPCs/DesertScourge/DesertNuisanceBody.cs @@ -33,6 +33,7 @@ public override void SetStaticDefaults() BodyTexture3 = ModContent.Request(Texture + "3", AssetRequestMode.AsyncLoad); BodyTexture4 = ModContent.Request(Texture + "4", AssetRequestMode.AsyncLoad); } + NPCID.Sets.CantTakeLunchMoney[Type] = true; } public override void SetDefaults() diff --git a/NPCs/DesertScourge/DesertNuisanceBodyYoung.cs b/NPCs/DesertScourge/DesertNuisanceBodyYoung.cs index c1086817cc..5e9f85ba16 100644 --- a/NPCs/DesertScourge/DesertNuisanceBodyYoung.cs +++ b/NPCs/DesertScourge/DesertNuisanceBodyYoung.cs @@ -33,6 +33,7 @@ public override void SetStaticDefaults() BodyTexture3 = ModContent.Request(Texture + "3", AssetRequestMode.AsyncLoad); BodyTexture4 = ModContent.Request(Texture + "4", AssetRequestMode.AsyncLoad); } + NPCID.Sets.CantTakeLunchMoney[Type] = true; } public override void SetDefaults() diff --git a/NPCs/DesertScourge/DesertNuisanceHead.cs b/NPCs/DesertScourge/DesertNuisanceHead.cs index c9ce5c9e75..71e547d8f9 100644 --- a/NPCs/DesertScourge/DesertNuisanceHead.cs +++ b/NPCs/DesertScourge/DesertNuisanceHead.cs @@ -45,6 +45,7 @@ public override void SetStaticDefaults() value.Position.Y += 30; NPCID.Sets.NPCBestiaryDrawOffset[Type] = value; NPCID.Sets.MPAllowedEnemies[Type] = true; + NPCID.Sets.CantTakeLunchMoney[Type] = true; } public override void SetDefaults() diff --git a/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs b/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs index c428a92aa0..e984be408c 100644 --- a/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs +++ b/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs @@ -37,6 +37,7 @@ public override void SetStaticDefaults() Main.npcFrameCount[NPC.type] = 7; this.HideFromBestiary(); NPCID.Sets.MPAllowedEnemies[Type] = true; + NPCID.Sets.CantTakeLunchMoney[Type] = true; } public override void SetDefaults() diff --git a/NPCs/DesertScourge/DesertNuisanceTail.cs b/NPCs/DesertScourge/DesertNuisanceTail.cs index 860e56f7b0..709710af2f 100644 --- a/NPCs/DesertScourge/DesertNuisanceTail.cs +++ b/NPCs/DesertScourge/DesertNuisanceTail.cs @@ -15,6 +15,7 @@ public class DesertNuisanceTail : ModNPC public override void SetStaticDefaults() { this.HideFromBestiary(); + NPCID.Sets.CantTakeLunchMoney[Type] = true; } public override void SetDefaults() diff --git a/NPCs/DesertScourge/DesertNuisanceTailYoung.cs b/NPCs/DesertScourge/DesertNuisanceTailYoung.cs index df82733592..c2b49d23c3 100644 --- a/NPCs/DesertScourge/DesertNuisanceTailYoung.cs +++ b/NPCs/DesertScourge/DesertNuisanceTailYoung.cs @@ -15,6 +15,7 @@ public class DesertNuisanceTailYoung : ModNPC public override void SetStaticDefaults() { this.HideFromBestiary(); + NPCID.Sets.CantTakeLunchMoney[Type] = true; } public override void SetDefaults() From df301a368270f58286c1255d8ebf63121aa5a891 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Fri, 24 May 2024 03:00:42 -0500 Subject: [PATCH 064/401] Cut Blood Nautilus Shot projectile blood trail distance in half. --- Projectiles/CalamityGlobalProjectile.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Projectiles/CalamityGlobalProjectile.cs b/Projectiles/CalamityGlobalProjectile.cs index 0cb47d3729..27d65eacbf 100644 --- a/Projectiles/CalamityGlobalProjectile.cs +++ b/Projectiles/CalamityGlobalProjectile.cs @@ -603,7 +603,8 @@ public override bool PreAI(Projectile projectile) blood2.scale = 1.2f; blood2.position = projectile.Center + Main.rand.NextFloat() * projectile.velocity * 2f; - for (int j = 1; j < projectile.oldPos.Length && !(projectile.oldPos[j] == Vector2.Zero); j++) + int trailLength = projectile.oldPos.Length / 2; + for (int j = 1; j < trailLength && !(projectile.oldPos[j] == Vector2.Zero); j++) { if (Main.rand.NextBool(3)) { From abd97e0b6c8406a7ab6bb83b15979922aa3d31d5 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Fri, 24 May 2024 03:02:35 -0500 Subject: [PATCH 065/401] Made Bloodletting Servants a bit lighter in terms of their base draw color and their charge telegraph. --- NPCs/NormalNPCs/BloodlettingServant.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NPCs/NormalNPCs/BloodlettingServant.cs b/NPCs/NormalNPCs/BloodlettingServant.cs index 3ec7e710f1..879a389f03 100644 --- a/NPCs/NormalNPCs/BloodlettingServant.cs +++ b/NPCs/NormalNPCs/BloodlettingServant.cs @@ -248,7 +248,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d { Texture2D npcTexture = TextureAssets.Npc[NPC.type].Value; Color originalColor = NPC.GetAlpha(drawColor); - Color newColor = new Color(255, 128, 128, 255 - NPC.alpha); + Color newColor = new Color(255, 192, 192, 255 - NPC.alpha); Vector2 drawPosition = NPC.Center - screenPos + new Vector2(0, NPC.gfxOffY); Vector2 origin = NPC.frame.Size() / 2; @@ -284,7 +284,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d return true; } - public override Color? GetAlpha(Color drawColor) => new Color(128, 0, 0, 255 - NPC.alpha); + public override Color? GetAlpha(Color drawColor) => new Color(192, 0, 0, 255 - NPC.alpha); public override void HitEffect(NPC.HitInfo hit) { From 2be90960f8fd8124cb04705c77689c67cf58c32f Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Fri, 24 May 2024 03:15:47 -0500 Subject: [PATCH 066/401] Fixed an Eye of Cthulhu blood shot damage issue. --- NPCs/VanillaNPCAIOverrides/Bosses/EyeOfCthulhuAI.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/EyeOfCthulhuAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/EyeOfCthulhuAI.cs index ef469adf25..3c41eb2737 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/EyeOfCthulhuAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/EyeOfCthulhuAI.cs @@ -481,13 +481,14 @@ public static bool BuffedEyeofCthulhuAI(NPC npc, Mod mod) if (Main.netMode != NetmodeID.MultiplayerClient) { int type = ProjectileID.BloodNautilusShot; + int damage = npc.GetProjectileDamage(type); int numProj = masterMode ? Main.rand.Next(4, 6) : 3; int spread = masterMode ? numProj * 3 : 10; float rotation = MathHelper.ToRadians(spread); for (int i = 0; i < numProj; i++) { Vector2 perturbedSpeed = projectileVelocity.RotatedBy(MathHelper.Lerp(-rotation, rotation, i / (float)(numProj - 1))); - int proj = Projectile.NewProjectile(npc.GetSource_FromAI(), npc.Center + perturbedSpeed.SafeNormalize(Vector2.UnitY) * ProjectileOffset, perturbedSpeed, type, 15, 0f, Main.myPlayer); + int proj = Projectile.NewProjectile(npc.GetSource_FromAI(), npc.Center + perturbedSpeed.SafeNormalize(Vector2.UnitY) * ProjectileOffset, perturbedSpeed, type, damage, 0f, Main.myPlayer); Main.projectile[proj].timeLeft = 600; } } From d7c7626409565bd5defbe27c52e39de614091a65 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Fri, 24 May 2024 05:30:36 -0500 Subject: [PATCH 067/401] Adjusted Brain of Cthulhu Creeper aggression scaling to take enrage into account, this makes them far less aggressive while in the underground crimson. --- .../Bosses/BrainOfCthulhuAI.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/BrainOfCthulhuAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/BrainOfCthulhuAI.cs index 78bf26e4cb..e8c7ecd7a2 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/BrainOfCthulhuAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/BrainOfCthulhuAI.cs @@ -874,11 +874,15 @@ public static bool BuffedCreeperAI(NPC npc, Mod mod) if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - float enrageScale = bossRush ? 1.5f : masterMode ? 0.5f : 0f; - if ((npc.position.Y / 16f) < Main.worldSurface || bossRush) + float enrageScaleMax = 2f; + float enrageScale = bossRush ? enrageScaleMax : masterMode ? 0.5f : 0f; + if ((npc.position.Y / 16f) < Main.worldSurface) enrageScale += 0.5f; - if (!Main.player[npc.target].ZoneCrimson || bossRush) - enrageScale += 2f; + if (!Main.player[npc.target].ZoneCrimson) + enrageScale += 1f; + + if (enrageScale > enrageScaleMax) + enrageScale = enrageScaleMax; bool brainIsNotTeleportingOrCharging = Main.npc[NPC.crimsonBoss].ai[0] == 0f || Main.npc[NPC.crimsonBoss].ai[0] == -1f || Main.npc[NPC.crimsonBoss].ai[0] == -6f; bool brainIsInPhase2 = Main.npc[NPC.crimsonBoss].ai[0] < 0f; @@ -901,7 +905,9 @@ public static bool BuffedCreeperAI(NPC npc, Mod mod) creeperRatio = creeperCount / (float)GetBrainOfCthuluCreepersCountRevDeath(); // Scale the aggressiveness of the charges with amount of Creepers remaining - float chargeAggressionScale = creeperRatio <= 0.1f ? 3.5f : creeperRatio <= 0.2f ? 2.5f : creeperRatio <= 0.4f ? 1.75f : creeperRatio <= 0.6f ? 1f : creeperRatio <= 0.8f ? 0.5f : 0f; + float chargeAggressionScale = creeperRatio <= 0.1f ? 1.75f : creeperRatio <= 0.2f ? 1.25f : creeperRatio <= 0.4f ? 0.875f : creeperRatio <= 0.6f ? 0.5f : creeperRatio <= 0.8f ? 0.25f : 0f; + if (enrageScale > 0f) + chargeAggressionScale *= 1f + enrageScale; if (death) chargeAggressionScale *= 1.25f; From 5d504724bda030213e4360783c2af0e561f23e6e Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Sat, 25 May 2024 07:11:54 -0500 Subject: [PATCH 068/401] Improved Rev+ Skeletron's moving away before charging, it's slower and smoother now. --- .../Bosses/SkeletronAI.cs | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronAI.cs index 68e01972b2..d8e4856b6b 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronAI.cs @@ -205,6 +205,11 @@ void SpawnHands() if (death) headSpinVelocityMult *= 1.2f; + // Velocity used to move Skeletron away from the target before charging + float moveAwayVelocity = headSpinVelocityMult; + if (!phase3) + moveAwayVelocity *= (bossRush ? 1.5f : 2f); + // Hand DR, scale DR up if the hands are still alive as Skeletron's HP lowers npc.chaseable = handsDead; float minDR = 0.05f; @@ -484,23 +489,18 @@ void SpawnHands() { if (!canCharge || !hasMovedForcedDistance) { - float maxAcceleration = headXAcceleration + headYAcceleration + (npc.ai[2] - moveAwayGateValue) * (phase5 ? 0.006f : 0.004f); - float maxAccelerationCap = (headXAcceleration + headYAcceleration) * 5f; - if (maxAcceleration > maxAccelerationCap) - maxAcceleration = maxAccelerationCap; - - npc.velocity += (Main.player[npc.target].Center - npc.Center).SafeNormalize(Vector2.UnitY) * -maxAcceleration; - - float maxVelocity = headSpinVelocityMult + (npc.ai[2] - moveAwayGateValue) * (phase5 ? 0.12f : 0.08f); - float maxVelocityCap = headSpinVelocityMult * 2.5f; + float phase5Multiplier = 1.5f; + float maxVelocity = (npc.ai[2] - moveAwayGateValue) * (moveAwayVelocity * 0.008f); + if (phase5) + maxVelocity *= phase5Multiplier; + + float maxVelocityCap = moveAwayVelocity; + if (phase5) + maxVelocityCap *= phase5Multiplier; if (maxVelocity > maxVelocityCap) maxVelocity = maxVelocityCap; - if (npc.velocity.Length() > maxVelocity) - { - npc.velocity = npc.velocity.SafeNormalize(Vector2.UnitY); - npc.velocity *= maxVelocity; - } + npc.velocity = (Main.player[npc.target].Center - npc.Center).SafeNormalize(Vector2.UnitY) * -maxVelocity; } // New charge attack From ee2d885888397266139692d53d82962c7b888b2b Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Sat, 25 May 2024 02:45:39 +0700 Subject: [PATCH 069/401] profaned shard tooltip update --- Localization/en-US/Mods.CalamityMod.Items.SummonItems.hjson | 1 - 1 file changed, 1 deletion(-) diff --git a/Localization/en-US/Mods.CalamityMod.Items.SummonItems.hjson b/Localization/en-US/Mods.CalamityMod.Items.SummonItems.hjson index 09de1c4991..3d32178f39 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.SummonItems.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.SummonItems.hjson @@ -231,7 +231,6 @@ ProfanedShard: { Tooltip: ''' [SPAWN] - Enrage when not in the Hallow or Underworld Not consumable 'Her Guardians seek the holder of such vast stolen power.' ''' From aec4e9fa21e5a639d66332fb4ec368e9499bd68b Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 24 May 2024 16:11:15 -0400 Subject: [PATCH 070/401] Some post-Plantera gun + ammo balancing Call me a dryad the way Dryad's Tear balancing makes me cry --- Items/Ammo/DryadsTear.cs | 2 +- Items/CalamityGlobalItemTweaks.cs | 6 +++--- Projectiles/Ranged/DryadsTearMain.cs | 5 +---- Projectiles/Ranged/DryadsTearSplit.cs | 1 + 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/Items/Ammo/DryadsTear.cs b/Items/Ammo/DryadsTear.cs index 657029031b..24866b5488 100644 --- a/Items/Ammo/DryadsTear.cs +++ b/Items/Ammo/DryadsTear.cs @@ -19,7 +19,7 @@ public override void SetDefaults() { Item.width = 8; Item.height = 8; - Item.damage = 8; + Item.damage = 10; Item.DamageType = DamageClass.Ranged; Item.maxStack = 9999; Item.consumable = true; diff --git a/Items/CalamityGlobalItemTweaks.cs b/Items/CalamityGlobalItemTweaks.cs index 33eba91d0c..9c5b58366e 100644 --- a/Items/CalamityGlobalItemTweaks.cs +++ b/Items/CalamityGlobalItemTweaks.cs @@ -225,6 +225,7 @@ internal static void LoadTweaks() { ItemID.SkyFracture, Do(DamageExact(54), ShootSpeedExact(30f)) }, { ItemID.SlapHand, Do(UseTurn, DamageExact(120)) }, { ItemID.Smolstar, Do(DamageExact(9), AutoReuse, UseExact(25)) }, // Blade Staff + { ItemID.SniperRifle, Do(PointBlank, DamageExact(215)) }, { ItemID.SolarEruption, Do(DamageExact(157)) }, { ItemID.SoulDrain, Do(DamageExact(38)) }, // Life Drain { ItemID.SpaceGun, Do(DamageExact(25)) }, @@ -238,7 +239,7 @@ internal static void LoadTweaks() { ItemID.StylistKilLaKillScissorsIWish, Do(AutoReuse, UseTurn, DamageExact(18)) }, // Stylish Scissors { ItemID.Stynger, Do(DamageExact(75)) }, { ItemID.Swordfish, Do(AutoReuse, TrueMelee, DamageExact(24)) }, - { ItemID.TacticalShotgun, Do(PointBlank, DamageExact(34)) }, + { ItemID.TacticalShotgun, Do(PointBlank, DamageExact(41)) }, { ItemID.TaxCollectorsStickOfDoom, Do(AutoReuse, UseTurn, UseRatio(0.8f), DamageExact(70)) }, // Classy Cane { ItemID.TendonBow, Do(PointBlank, DamageExact(17), AutoReuse) }, { ItemID.TerraBlade, Do(DamageExact(122)) }, @@ -267,6 +268,7 @@ internal static void LoadTweaks() { ItemID.VampireKnives, Do(DamageExact(38)) }, { ItemID.ValkyrieYoyo, Do(AutoReuse, DamageExact(48)) }, // Red's Throw and Valkyrie Yoyo have the same stats { ItemID.VenomStaff, Do(DamageExact(55)) }, + { ItemID.VenusMagnum, Do(PointBlank, DamageExact(65)) }, { ItemID.WaspGun, Do(UseExact(11), DamageExact(58)) }, { ItemID.WaterBolt, Do(DamageExact(23)) }, { ItemID.WhitePhaseblade, Do(AutoReuse, UseTurn, DamageExact(32)) }, @@ -456,13 +458,11 @@ internal static void LoadTweaks() { ItemID.RichMahoganyBow, pointBlank }, { ItemID.ShadewoodBow, pointBlank }, { ItemID.SilverBow, pointBlank }, - { ItemID.SniperRifle, pointBlank }, { ItemID.SnowballCannon, pointBlank }, { ItemID.StakeLauncher, pointBlank }, { ItemID.TinBow, pointBlank }, { ItemID.TungstenBow, pointBlank }, { ItemID.Uzi, pointBlank }, - { ItemID.VenusMagnum, pointBlank }, { ItemID.VortexBeater, pointBlank }, { ItemID.WoodenBow, pointBlank }, #endregion diff --git a/Projectiles/Ranged/DryadsTearMain.cs b/Projectiles/Ranged/DryadsTearMain.cs index 8c6d8cf7a7..2002b27fe6 100644 --- a/Projectiles/Ranged/DryadsTearMain.cs +++ b/Projectiles/Ranged/DryadsTearMain.cs @@ -34,9 +34,6 @@ public override void AI() { Lighting.AddLight(Projectile.Center, Color.LimeGreen.ToVector3() * 0.25f); - if (Projectile.localAI[0] == 0f) - Projectile.damage = (int)(Projectile.damage * 0.75f); - Projectile.localAI[0] += 1f; if (Projectile.localAI[0] > 4f) { @@ -63,7 +60,7 @@ public override void OnKill(int timeLeft) for (int b = 0; b < 2; b++) { Vector2 velocity = CalamityUtils.RandomVelocity(100f, 70f, 100f); - Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, velocity, ModContent.ProjectileType(), (int)(Projectile.damage * 0.4), 0f, Projectile.owner, 0f, 0f); + Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, velocity, ModContent.ProjectileType(), (int)(Projectile.damage * 0.1), 0f, Projectile.owner, 0f, 0f); } for (int i = 0; i < 3; i++) { diff --git a/Projectiles/Ranged/DryadsTearSplit.cs b/Projectiles/Ranged/DryadsTearSplit.cs index 92d247019b..6b712b70a2 100644 --- a/Projectiles/Ranged/DryadsTearSplit.cs +++ b/Projectiles/Ranged/DryadsTearSplit.cs @@ -27,6 +27,7 @@ public override void SetDefaults() Projectile.timeLeft = 210; Projectile.extraUpdates = 1; Projectile.tileCollide = false; + Projectile.ArmorPenetration = 10; AIType = ProjectileID.Bullet; } From 3b6dd77cd30cbedb6f1b127010e6e5b865394c08 Mon Sep 17 00:00:00 2001 From: mochi-angel Date: Fri, 24 May 2024 22:49:49 -0700 Subject: [PATCH 071/401] Harvest Staff buff --- Items/Weapons/Summon/HarvestStaff.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Items/Weapons/Summon/HarvestStaff.cs b/Items/Weapons/Summon/HarvestStaff.cs index f16756177b..96da01b29c 100644 --- a/Items/Weapons/Summon/HarvestStaff.cs +++ b/Items/Weapons/Summon/HarvestStaff.cs @@ -22,7 +22,7 @@ public class HarvestStaff : ModItem, ILocalizedModType public override void SetDefaults() { - Item.damage = 26; + Item.damage = 27; Item.DamageType = DamageClass.Summon; Item.shoot = ModContent.ProjectileType(); Item.knockBack = 5f; From 41693e02442567296fbc0af5438553dd0a084cfe Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 24 May 2024 16:12:19 -0400 Subject: [PATCH 072/401] Updated Dryad's Tear tooltip --- Localization/en-US/Mods.CalamityMod.Items.Ammo.hjson | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Ammo.hjson b/Localization/en-US/Mods.CalamityMod.Items.Ammo.hjson index ee6be6c217..35b9c32329 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Ammo.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Ammo.hjson @@ -50,6 +50,11 @@ CinderArrow: { Tooltip: Explosive arrows that burst into weak flaming shards that inflict Brimstone Flames } +DryadsTear: { + DisplayName: Dryad's Tear + Tooltip: Splits into homing nature shards on impact which ignore enemy defense +} + ElysianArrow: { DisplayName: Elysian Arrow Tooltip: @@ -159,11 +164,6 @@ SproutingArrow: { ''' } -DryadsTear: { - DisplayName: Dryad's Tear - Tooltip: Explodes and splits into homing nature shards on impact -} - VanquisherArrow: { DisplayName: Vanquisher Arrow Tooltip: From 63a735175beeaded5501e7714e0ef99974e007c7 Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Sat, 25 May 2024 03:26:30 +0700 Subject: [PATCH 073/401] unified guardians boss bar --- .../ProfanedGuardianCommander.cs | 2 + UI/VanillaBossBars/ProfanedGuardianBossBar.cs | 60 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 UI/VanillaBossBars/ProfanedGuardianBossBar.cs diff --git a/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs b/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs index a4279922e8..d9682a401f 100644 --- a/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs +++ b/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs @@ -13,6 +13,7 @@ using CalamityMod.Items.SummonItems; using CalamityMod.Items.Weapons.Typeless; using CalamityMod.Projectiles.Boss; +using CalamityMod.UI.VanillaBossBars; using CalamityMod.World; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; @@ -81,6 +82,7 @@ public override void SetDefaults() NPC.noTileCollide = true; AIType = -1; NPC.boss = true; + NPC.BossBar = ModContent.GetInstance(); NPC.value = Item.buyPrice(1, 0, 0, 0); NPC.HitSound = SoundID.NPCHit52; NPC.DeathSound = SoundID.NPCDeath55; diff --git a/UI/VanillaBossBars/ProfanedGuardianBossBar.cs b/UI/VanillaBossBars/ProfanedGuardianBossBar.cs new file mode 100644 index 0000000000..35afbb34b6 --- /dev/null +++ b/UI/VanillaBossBars/ProfanedGuardianBossBar.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using CalamityMod.NPCs.ProfanedGuardians; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ReLogic.Content; +using Terraria; +using Terraria.GameContent; +using Terraria.GameContent.UI.BigProgressBar; +using Terraria.ID; +using Terraria.ModLoader; +using static Terraria.ModLoader.ModContent; + +namespace CalamityMod.UI.VanillaBossBars +{ + public class ProfanedGuardianBossBar : ModBossBar + { + // Used to determine the max health of a multi-segmented boss + public NPC FalseNPCSegment; + + public override Asset GetIconTexture(ref Rectangle? iconFrame) + { + // Icons are based on whoever should die first + if (NPC.AnyNPCs(NPCType())) + return TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[NPCType()]]; + + if (NPC.AnyNPCs(NPCType())) + return TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[NPCType()]]; + + return TextureAssets.NpcHeadBoss[NPCID.Sets.BossHeadTextures[NPCType()]]; + } + + public override bool? ModifyInfo(ref BigProgressBarInfo info, ref float life, ref float lifeMax, ref float shield, ref float shieldMax) + { + NPC target = Main.npc[info.npcIndexToAimAt]; + + if (!target.active) + return false; + + // Get the commander's health + life = target.life; + lifeMax = target.lifeMax; + + // Add max health by feeding the data of false NPCs + FalseNPCSegment = new NPC(); + FalseNPCSegment.SetDefaults(NPCType(), target.GetMatchingSpawnParams()); + lifeMax += FalseNPCSegment.lifeMax; + FalseNPCSegment.SetDefaults(NPCType(), target.GetMatchingSpawnParams()); + lifeMax += FalseNPCSegment.lifeMax; + + // Determine the current health of all guardians + foreach (NPC guardian in Main.ActiveNPCs) + { + if (guardian.type == NPCType() || guardian.type == NPCType()) + life += guardian.life; + } + return true; + } + } +} From db84d02f8210057f0811579561b309e896ce5712 Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Sat, 25 May 2024 04:55:39 +0700 Subject: [PATCH 074/401] quickfire suggestions also fixed sorting priorities AGAIN urngiudrgnju --- Items/Fishing/EnchantedStarfish.cs | 3 ++- Items/SummonItems/AstralChunk.cs | 2 +- Items/SummonItems/CharredIdol.cs | 2 +- Items/SummonItems/CryoKey.cs | 2 +- Items/SummonItems/EyeofDesolation.cs | 2 +- Items/SummonItems/OldPowerCell.cs | 2 +- Items/SummonItems/Portabulb.cs | 2 +- Items/SummonItems/SandstormsCore.cs | 2 +- Items/SummonItems/Seafood.cs | 2 +- Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson | 3 +-- Projectiles/Healing/ManaPolarizerHealOrb.cs | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Items/Fishing/EnchantedStarfish.cs b/Items/Fishing/EnchantedStarfish.cs index 2109fcecc4..8102c4c1c9 100644 --- a/Items/Fishing/EnchantedStarfish.cs +++ b/Items/Fishing/EnchantedStarfish.cs @@ -13,7 +13,8 @@ public override void SetStaticDefaults() Item.ResearchUnlockCount = 10; ItemID.Sets.CanBePlacedOnWeaponRacks[Item.type] = true; // For some reason Life/Mana boosting items are in this set (along with Magic Mirror+) - ItemID.Sets.SortingPriorityBossSpawns[Type] = 19; // Mana Crystal + ItemID.Sets.SortingPriorityBossSpawns[Type] = 21; // Mana Crystal + ItemID.Sets.ShimmerTransformToItem[Type] = ItemID.ArcaneCrystal; } public override void SetDefaults() diff --git a/Items/SummonItems/AstralChunk.cs b/Items/SummonItems/AstralChunk.cs index c5094efa77..4a0116a906 100644 --- a/Items/SummonItems/AstralChunk.cs +++ b/Items/SummonItems/AstralChunk.cs @@ -14,7 +14,7 @@ public class AstralChunk : ModItem, ILocalizedModType public new string LocalizationCategory => "Items.SummonItems"; public override void SetStaticDefaults() { - ItemID.Sets.SortingPriorityBossSpawns[Type] = 14; // Frost Moon + ItemID.Sets.SortingPriorityBossSpawns[Type] = 12; // Truffle Worm } public override void SetDefaults() diff --git a/Items/SummonItems/CharredIdol.cs b/Items/SummonItems/CharredIdol.cs index 69c33b9bfc..152bac38b9 100644 --- a/Items/SummonItems/CharredIdol.cs +++ b/Items/SummonItems/CharredIdol.cs @@ -14,7 +14,7 @@ public class CharredIdol : ModItem, ILocalizedModType public new string LocalizationCategory => "Items.SummonItems"; public override void SetStaticDefaults() { - ItemID.Sets.SortingPriorityBossSpawns[Type] = 9; // Mechanical Skull + ItemID.Sets.SortingPriorityBossSpawns[Type] = 10; // Mechanical Skull } public override void SetDefaults() diff --git a/Items/SummonItems/CryoKey.cs b/Items/SummonItems/CryoKey.cs index 6fee06e1f8..a128adc1a4 100644 --- a/Items/SummonItems/CryoKey.cs +++ b/Items/SummonItems/CryoKey.cs @@ -18,7 +18,7 @@ public class CryoKey : ModItem, ILocalizedModType public new string LocalizationCategory => "Items.SummonItems"; public override void SetStaticDefaults() { - ItemID.Sets.SortingPriorityBossSpawns[Type] = 7; // Mechanical Eye + ItemID.Sets.SortingPriorityBossSpawns[Type] = 7; // Ocram's Razor (1 below Mechanical Eye) } public override void SetDefaults() diff --git a/Items/SummonItems/EyeofDesolation.cs b/Items/SummonItems/EyeofDesolation.cs index 7e66341a3c..f8e683b1bf 100644 --- a/Items/SummonItems/EyeofDesolation.cs +++ b/Items/SummonItems/EyeofDesolation.cs @@ -26,7 +26,7 @@ public class EyeofDesolation : ModItem, ILocalizedModType public int spawnYAdd = 0; public override void SetStaticDefaults() { - ItemID.Sets.SortingPriorityBossSpawns[Type] = 10; // Pirate Map + ItemID.Sets.SortingPriorityBossSpawns[Type] = 11; // Pirate Map (1 above Mechanical Skull) } public override void SetDefaults() diff --git a/Items/SummonItems/OldPowerCell.cs b/Items/SummonItems/OldPowerCell.cs index 29ac9bf111..02c26ef26e 100644 --- a/Items/SummonItems/OldPowerCell.cs +++ b/Items/SummonItems/OldPowerCell.cs @@ -15,7 +15,7 @@ public class OldPowerCell : ModItem, ILocalizedModType public override void SetStaticDefaults() { NPCID.Sets.MPAllowedEnemies[NPCID.Golem] = true; - ItemID.Sets.SortingPriorityBossSpawns[Type] = 15; // Lihzahrd Power Cell + ItemID.Sets.SortingPriorityBossSpawns[Type] = 16; // Lihzahrd Power Cell } public override void SetDefaults() diff --git a/Items/SummonItems/Portabulb.cs b/Items/SummonItems/Portabulb.cs index 0217cd7379..2f239988b5 100644 --- a/Items/SummonItems/Portabulb.cs +++ b/Items/SummonItems/Portabulb.cs @@ -14,7 +14,7 @@ public class Portabulb : ModItem, ILocalizedModType public override void SetStaticDefaults() { NPCID.Sets.MPAllowedEnemies[NPCID.Plantera] = true; - ItemID.Sets.SortingPriorityBossSpawns[Type] = 11; // Truffle Worm + ItemID.Sets.SortingPriorityBossSpawns[Type] = 11; // Pirate Map (1 above Mechanical Skull) } public override void SetDefaults() diff --git a/Items/SummonItems/SandstormsCore.cs b/Items/SummonItems/SandstormsCore.cs index 1426db53d5..32dba4f830 100644 --- a/Items/SummonItems/SandstormsCore.cs +++ b/Items/SummonItems/SandstormsCore.cs @@ -15,7 +15,7 @@ public class SandstormsCore : ModItem, ILocalizedModType public new string LocalizationCategory => "Items.SummonItems"; public override void SetStaticDefaults() { - ItemID.Sets.SortingPriorityBossSpawns[Type] = 12; // Frost Legion + ItemID.Sets.SortingPriorityBossSpawns[Type] = 13; // Frost Legion } public override void SetDefaults() diff --git a/Items/SummonItems/Seafood.cs b/Items/SummonItems/Seafood.cs index f6618275c1..4d780eb9e0 100644 --- a/Items/SummonItems/Seafood.cs +++ b/Items/SummonItems/Seafood.cs @@ -14,7 +14,7 @@ public class Seafood : ModItem, ILocalizedModType public new string LocalizationCategory => "Items.SummonItems"; public override void SetStaticDefaults() { - ItemID.Sets.SortingPriorityBossSpawns[Type] = 8; // Mechanical Worm + ItemID.Sets.SortingPriorityBossSpawns[Type] = 9; // Mechanical Worm } public override void SetDefaults() diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson index 0e08965505..a2f6e3f0a6 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson @@ -1064,8 +1064,7 @@ ManaPolarizer: { ''' Increases max mana by 50 and magic damage by 6% -1.5 HP/s life regen if mana is above 50% of its maximum - Grants spectre healing, the amount healed scales with your mana - The healing only works while holding a magic weapon + Magic projectiles give lifesteal while holding a magic weapon The more mana you have, the more you heal ''' } diff --git a/Projectiles/Healing/ManaPolarizerHealOrb.cs b/Projectiles/Healing/ManaPolarizerHealOrb.cs index 373c1b9518..c2dbdacf55 100644 --- a/Projectiles/Healing/ManaPolarizerHealOrb.cs +++ b/Projectiles/Healing/ManaPolarizerHealOrb.cs @@ -24,7 +24,7 @@ public override void SetDefaults() public override void AI() { - Projectile.HealingProjectile((int)Projectile.ai[1], (int)Projectile.ai[0], 3f, 15f); + Projectile.HealingProjectile((int)Projectile.ai[1], (int)Projectile.ai[0], 4f, 15f); int dust = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.SpectreStaff, 0f, 0f, 100); Main.dust[dust].noGravity = true; Main.dust[dust].velocity *= 0f; From 40c1dcf870f79c4d76f6a40311ad004a9c8fc2c3 Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Sat, 25 May 2024 05:42:51 +0700 Subject: [PATCH 075/401] some gun offsets --- Items/Weapons/Ranged/ClockGatlignum.cs | 2 +- Items/Weapons/Ranged/FrostbiteBlaster.cs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Items/Weapons/Ranged/ClockGatlignum.cs b/Items/Weapons/Ranged/ClockGatlignum.cs index 4e4c895e55..422f865ff1 100644 --- a/Items/Weapons/Ranged/ClockGatlignum.cs +++ b/Items/Weapons/Ranged/ClockGatlignum.cs @@ -33,7 +33,7 @@ public override void SetDefaults() Item.Calamity().canFirePointBlankShots = true; } - public override Vector2? HoldoutOffset() => new Vector2(-10, 0); + public override Vector2? HoldoutOffset() => new Vector2(-14, 0); public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) { diff --git a/Items/Weapons/Ranged/FrostbiteBlaster.cs b/Items/Weapons/Ranged/FrostbiteBlaster.cs index 470c62ed7a..38f5f1dca7 100644 --- a/Items/Weapons/Ranged/FrostbiteBlaster.cs +++ b/Items/Weapons/Ranged/FrostbiteBlaster.cs @@ -34,6 +34,8 @@ public override void SetDefaults() Item.Calamity().canFirePointBlankShots = true; } + public override Vector2? HoldoutOffset() => new Vector2(-14, 0); + public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) { SoundEngine.PlaySound(SoundID.Item36, position); From fc55bb69851f38b0cde86bfde3d43f813b90dbb8 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 25 May 2024 01:59:09 -0400 Subject: [PATCH 076/401] Post-Golem gun + ammo balancing --- Items/Ammo/HyperiusBullet.cs | 2 +- Items/Weapons/Ranged/Leviatitan.cs | 6 +++--- Items/Weapons/Ranged/RealmRavager.cs | 8 ++++---- Projectiles/Ranged/HailstormBulletProj.cs | 4 ++-- Projectiles/Ranged/HyperiusBulletProj.cs | 4 ++-- Projectiles/Ranged/RealmRavagerBullet.cs | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Items/Ammo/HyperiusBullet.cs b/Items/Ammo/HyperiusBullet.cs index 39653cceb2..6812c127eb 100644 --- a/Items/Ammo/HyperiusBullet.cs +++ b/Items/Ammo/HyperiusBullet.cs @@ -10,7 +10,7 @@ public class HyperiusBullet : ModItem, ILocalizedModType { public new string LocalizationCategory => "Items.Ammo"; - public static int SplitBulletBonusDamage = 10; + public static int SplitBulletBonusDamage = 16; public override void SetStaticDefaults() { diff --git a/Items/Weapons/Ranged/Leviatitan.cs b/Items/Weapons/Ranged/Leviatitan.cs index 2e83fff9d7..2130046725 100644 --- a/Items/Weapons/Ranged/Leviatitan.cs +++ b/Items/Weapons/Ranged/Leviatitan.cs @@ -14,10 +14,10 @@ public override void SetDefaults() { Item.width = 82; Item.height = 28; - Item.damage = 80; + Item.damage = 77; Item.DamageType = DamageClass.Ranged; - Item.useTime = 9; - Item.useAnimation = 9; + Item.useTime = 10; + Item.useAnimation = 10; Item.useStyle = ItemUseStyleID.Shoot; Item.noMelee = true; Item.knockBack = 5f; diff --git a/Items/Weapons/Ranged/RealmRavager.cs b/Items/Weapons/Ranged/RealmRavager.cs index 2f0bbf6805..baaed6a188 100644 --- a/Items/Weapons/Ranged/RealmRavager.cs +++ b/Items/Weapons/Ranged/RealmRavager.cs @@ -14,7 +14,7 @@ public override void SetDefaults() { Item.width = 76; Item.height = 32; - Item.damage = 50; + Item.damage = 54; Item.DamageType = DamageClass.Ranged; Item.useTime = 22; Item.useAnimation = 22; @@ -35,11 +35,11 @@ public override void SetDefaults() public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) { - int numBullets = Main.rand.NextBool() ? 4 : 3; + int numBullets = 4; for (int index = 0; index < numBullets; ++index) { - float SpeedX = velocity.X + Main.rand.Next(-75, 76) * 0.05f; - float SpeedY = velocity.Y + Main.rand.Next(-75, 76) * 0.05f; + float SpeedX = velocity.X + (index == 0 ? 0 : Main.rand.Next(-75, 76) * 0.05f); + float SpeedY = velocity.Y + (index == 0 ? 0 : Main.rand.Next(-75, 76) * 0.05f); if (type == ProjectileID.Bullet) Projectile.NewProjectile(source, position.X, position.Y, SpeedX, SpeedY, ModContent.ProjectileType(), damage, knockback, player.whoAmI); diff --git a/Projectiles/Ranged/HailstormBulletProj.cs b/Projectiles/Ranged/HailstormBulletProj.cs index 66721fffd5..9da488161b 100644 --- a/Projectiles/Ranged/HailstormBulletProj.cs +++ b/Projectiles/Ranged/HailstormBulletProj.cs @@ -59,7 +59,7 @@ public override void AI() rotIncrease += 0.1f * (rotDirection ? -1 : 1); - Projectile.velocity *= 0.982f; + Projectile.velocity *= 0.984f; if (Projectile.localAI[0] > 100f && Projectile.localAI[0] < 300 && Projectile.localAI[0] % 9 == 0) { @@ -88,7 +88,7 @@ public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) WaterFlavoredParticle subTrail = new WaterFlavoredParticle(Projectile.Center + velocity * 4.5f + addedPlacement, velocity * 7, false, 6, 0.65f, Color.SkyBlue); GeneralParticleHandler.SpawnParticle(subTrail); } - int onHitDamage = Owner.CalcIntDamage(0.36f * Projectile.damage); + int onHitDamage = (int)(Projectile.damage * 0.5f); Owner.ApplyDamageToNPC(target, onHitDamage, 0f, 0, false); } } diff --git a/Projectiles/Ranged/HyperiusBulletProj.cs b/Projectiles/Ranged/HyperiusBulletProj.cs index 8a5405821b..0399e05bd4 100644 --- a/Projectiles/Ranged/HyperiusBulletProj.cs +++ b/Projectiles/Ranged/HyperiusBulletProj.cs @@ -108,7 +108,7 @@ public override bool OnTileCollide(Vector2 oldVelocity) { for (int b = 0; b < 3; b++) { - Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, -oldVelocity.RotatedByRandom(0.5f) * 0.7f, ModContent.ProjectileType(), (int)(Projectile.damage * 0.35), 0f, Projectile.owner, 0f, 0f, Main.rand.Next(0, 4 + 1)); + Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, -oldVelocity.RotatedByRandom(0.5f) * 0.7f, ModContent.ProjectileType(), (int)(Projectile.damage * 0.1), 0f, Projectile.owner, 0f, 0f, Main.rand.Next(0, 4 + 1)); } } return true; @@ -130,7 +130,7 @@ private void OnHitEffects(Vector2 targetPos) for (int b = 0; b < 3; b++) { Vector2 velocity = Projectile.velocity.RotatedByRandom(0.5f); - Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, velocity * 0.7f, ModContent.ProjectileType(), (int)(Projectile.damage * 0.15), Projectile.knockBack * 2f, Projectile.owner, 0f, 0f, Main.rand.Next(0, 4 + 1)); + Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, velocity * 0.7f, ModContent.ProjectileType(), (int)(Projectile.damage * 0.1), Projectile.knockBack * 2f, Projectile.owner, 0f, 0f, Main.rand.Next(0, 4 + 1)); } } } diff --git a/Projectiles/Ranged/RealmRavagerBullet.cs b/Projectiles/Ranged/RealmRavagerBullet.cs index f0dc66f4ef..64d52761a0 100644 --- a/Projectiles/Ranged/RealmRavagerBullet.cs +++ b/Projectiles/Ranged/RealmRavagerBullet.cs @@ -59,7 +59,7 @@ public override void OnKill(int timeLeft) Projectile.penetrate = -1; Projectile.usesLocalNPCImmunity = true; Projectile.localNPCHitCooldown = 10; - Projectile.damage /= 2; + Projectile.damage /= 3; Projectile.Damage(); } } From 10e031d7259e67e860e6afc0232d69110a7650ec Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Sat, 25 May 2024 17:52:06 -0500 Subject: [PATCH 077/401] Increased Elemental Lance use time, increased damage (untested). --- Items/Weapons/Melee/ElementalLance.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Items/Weapons/Melee/ElementalLance.cs b/Items/Weapons/Melee/ElementalLance.cs index 899b8a5f36..a4cf059a36 100644 --- a/Items/Weapons/Melee/ElementalLance.cs +++ b/Items/Weapons/Melee/ElementalLance.cs @@ -19,14 +19,14 @@ public override void SetDefaults() { Item.width = 88; Item.height = 88; - Item.damage = 160; + Item.damage = 240; Item.DamageType = DamageClass.Melee; Item.noMelee = true; Item.useTurn = true; Item.noUseGraphic = true; - Item.useAnimation = 30; + Item.useAnimation = 45; Item.useStyle = ItemUseStyleID.Shoot; - Item.useTime = 30; + Item.useTime = 45; Item.knockBack = 9.5f; Item.UseSound = SoundID.Item1; Item.autoReuse = true; From 5e3de69244d6fd3695bef7e6b9f478de2a2dc25b Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 25 May 2024 13:50:36 -0400 Subject: [PATCH 078/401] Slagsplitter Pauldron nerf --- CalPlayer/CalamityPlayerMiscEffects.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index 4209e88ed4..eb85228a17 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -310,9 +310,9 @@ public override void PostUpdateMiscEffects() SparkParticle spark2 = new SparkParticle(Player.Center + Player.velocity.RotatedBy(-2f * Player.direction) * 1.5f, SparkVelocity2, false, Main.rand.Next(11, 13), sparkscale, Main.rand.NextBool() ? Color.DarkOrange : Color.OrangeRed); GeneralParticleHandler.SpawnParticle(spark2); - if (Player.miscCounter % 5 == 0 && Player.velocity != Vector2.Zero) //every other frame spawn the hitbox + if (Player.miscCounter % 9 == 0 && Player.velocity != Vector2.Zero) //every other frame spawn the hitbox { - int damage = Player.ApplyArmorAccDamageBonusesTo(Player.GetBestClassDamage().ApplyTo(175)); + int damage = Player.ApplyArmorAccDamageBonusesTo(Player.GetBestClassDamage().ApplyTo(170)); Projectile.NewProjectile(Player.GetSource_FromThis(), Player.Center + Player.velocity * 1.5f, Vector2.Zero, ModContent.ProjectileType(), damage, 10f, Player.whoAmI); } } From 05f8307657cc95cf672592256b24c4c67065bd74 Mon Sep 17 00:00:00 2001 From: Xyk Date: Sat, 25 May 2024 11:28:19 -0700 Subject: [PATCH 079/401] Plague on kill improvement --- Buffs/DamageOverTime/Plague.cs | 4 ++-- NPCs/CalamityGlobalNPC.cs | 39 ++++++++++++++++++++++------------ 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/Buffs/DamageOverTime/Plague.cs b/Buffs/DamageOverTime/Plague.cs index defe20c5b8..747e25e7aa 100644 --- a/Buffs/DamageOverTime/Plague.cs +++ b/Buffs/DamageOverTime/Plague.cs @@ -40,7 +40,7 @@ internal static void DrawEffects(PlayerDrawSet drawInfo) { for (int i = 0; i < 2; i++) { - DirectionalPulseRing pulse = new DirectionalPulseRing(Player.Calamity().RandomDebuffVisualSpot, Vector2.Zero, Main.rand.NextBool(3) ? Color.LimeGreen : Color.Green, new Vector2(1, 1), 0, Main.rand.NextFloat(0.07f, 0.18f), 0f, 35); + DirectionalPulseRing pulse = new DirectionalPulseRing(Player.Calamity().RandomDebuffVisualSpot, Vector2.Zero, Main.rand.NextBool(3) ? Color.LimeGreen : Color.Green, new Vector2(1, 1), 0, Main.rand.NextFloat(0.07f, 0.18f), 0f, 20); GeneralParticleHandler.SpawnParticle(pulse); } @@ -62,7 +62,7 @@ internal static void DrawEffects(NPC npc, ref Color drawColor) Vector2 npcSize = npc.Center + new Vector2(Main.rand.NextFloat(-npc.width / 2, npc.width / 2), Main.rand.NextFloat(-npc.height / 2, npc.height / 2)); if (Main.rand.NextBool(3)) { - DirectionalPulseRing pulse = new DirectionalPulseRing(npcSize, Vector2.Zero, Main.rand.NextBool(3) ? Color.LimeGreen : Color.Green, new Vector2(1, 1), 0, Main.rand.NextFloat(0.07f, 0.18f) + (0.0000007f * npc.width * npc.height), 0f, 35); + DirectionalPulseRing pulse = new DirectionalPulseRing(npcSize, Vector2.Zero, Main.rand.NextBool(3) ? Color.LimeGreen : Color.Green, new Vector2(1, 1), 0, Main.rand.NextFloat(0.07f, 0.18f) + (0.0000007f * npc.width * npc.height), 0f, 15); GeneralParticleHandler.SpawnParticle(pulse); for (int i = 0; i < 4; i++) diff --git a/NPCs/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index 3ae1aabefa..c916f8802f 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -5818,24 +5818,37 @@ public override void HitEffect(NPC npc, NPC.HitInfo hit) } } + // Plague debuff on kill effect if (pFlames > 0 && npc.life <= 0) { - Rectangle hitbox = npc.Hitbox; - for (int i = 0; i < 20; i++) - { - int idx = Dust.NewDust(hitbox.TopLeft(), npc.width, npc.height, DustID.GemEmerald, 0f, -2.5f); - Dust dust = Main.dust[idx]; - dust.alpha = 200; - dust.velocity *= 1.4f; - dust.scale += Main.rand.NextFloat(); - } - if (Main.netMode != NetmodeID.MultiplayerClient) { - foreach (NPC nPC in Main.ActiveNPCs) + for (int i = 0; i < 10; i++) + { + int DustID = 220; + Dust dust2 = Dust.NewDustDirect(npc.Center, npc.width, npc.height, DustID); + dust2.scale = Main.rand.NextFloat(0.6f, 0.75f); + dust2.velocity = new Vector2(12, 12).RotatedByRandom(100) * Main.rand.NextFloat(0.5f, 0.8f); + dust2.noGravity = true; + } + + for (int i = 0; i < Main.maxNPCs; i++) { - if (!nPC.buffImmune[BuffType()] && npc.Distance(nPC.Center) < 100f && !nPC.dontTakeDamage && nPC.lifeMax > 5 && !nPC.friendly && !nPC.townNPC) - nPC.AddBuff(BuffType(), 300); + NPC target = Main.npc[i]; + + if (target != null && target.IsAnEnemy(true, true) && !target.buffImmune[BuffType()] && Vector2.Distance(target.Center, npc.Center) < 400) + { + if (target.HasBuff() || target.life <= 0) + { + target.AddBuff(BuffType(), 300); + } + else + { + target.AddBuff(BuffType(), 300); + DirectionalPulseRing pulse = new DirectionalPulseRing(target.Center, Vector2.Zero, Main.rand.NextBool(3) ? Color.LimeGreen : Color.Green, new Vector2(1, 1), 0, Main.rand.NextFloat(0.07f, 0.18f) * 3, 0f, 15); + GeneralParticleHandler.SpawnParticle(pulse); + } + } } } } From f2510baa46e00a4725012a6747742afc891f2940 Mon Sep 17 00:00:00 2001 From: Xyk Date: Sat, 25 May 2024 11:55:29 -0700 Subject: [PATCH 080/401] Pauldron re-nerf Pauldron hit can no longer hit the same enemy once spawned as there's a delay of 22 frames before they can hit again --- CalPlayer/CalamityPlayerMiscEffects.cs | 2 +- Projectiles/Typeless/PauldronDash.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index eb85228a17..fc0de93d70 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -310,7 +310,7 @@ public override void PostUpdateMiscEffects() SparkParticle spark2 = new SparkParticle(Player.Center + Player.velocity.RotatedBy(-2f * Player.direction) * 1.5f, SparkVelocity2, false, Main.rand.Next(11, 13), sparkscale, Main.rand.NextBool() ? Color.DarkOrange : Color.OrangeRed); GeneralParticleHandler.SpawnParticle(spark2); - if (Player.miscCounter % 9 == 0 && Player.velocity != Vector2.Zero) //every other frame spawn the hitbox + if (Player.miscCounter % 6 == 0 && Player.velocity != Vector2.Zero) { int damage = Player.ApplyArmorAccDamageBonusesTo(Player.GetBestClassDamage().ApplyTo(170)); Projectile.NewProjectile(Player.GetSource_FromThis(), Player.Center + Player.velocity * 1.5f, Vector2.Zero, ModContent.ProjectileType(), damage, 10f, Player.whoAmI); diff --git a/Projectiles/Typeless/PauldronDash.cs b/Projectiles/Typeless/PauldronDash.cs index 6a17b3d5f8..04613c3e65 100644 --- a/Projectiles/Typeless/PauldronDash.cs +++ b/Projectiles/Typeless/PauldronDash.cs @@ -27,8 +27,8 @@ public override void SetDefaults() Projectile.tileCollide = false; Projectile.penetrate = 1; Projectile.timeLeft = 4; - Projectile.usesLocalNPCImmunity = true; - Projectile.localNPCHitCooldown = -1; + Projectile.usesIDStaticNPCImmunity = true; + Projectile.idStaticNPCHitCooldown = 22; } public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) From a682cd1b28169a7727e44cccc83bcd55a9d7d9bf Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 25 May 2024 17:24:23 -0400 Subject: [PATCH 081/401] Post-Moon Lord and Provi gun + ammo balance --- Items/Ammo/HolyFireBullet.cs | 4 ++-- Items/CalamityGlobalItemTweaks.cs | 3 ++- Items/Weapons/Ranged/AngelicShotgun.cs | 10 +++++----- Items/Weapons/Ranged/Disseminator.cs | 6 +++--- Projectiles/Ranged/BloodfireBulletProj.cs | 17 +++++++++-------- Projectiles/Ranged/HolyFireBulletProj.cs | 2 +- 6 files changed, 22 insertions(+), 20 deletions(-) diff --git a/Items/Ammo/HolyFireBullet.cs b/Items/Ammo/HolyFireBullet.cs index 9135150910..9c54ed0152 100644 --- a/Items/Ammo/HolyFireBullet.cs +++ b/Items/Ammo/HolyFireBullet.cs @@ -10,7 +10,7 @@ namespace CalamityMod.Items.Ammo public class HolyFireBullet : ModItem, ILocalizedModType { public new string LocalizationCategory => "Items.Ammo"; - internal const float ExplosionMultiplier = 0.33f; + internal const float ExplosionMultiplier = 0.275f; public static readonly SoundStyle Explosion = new("CalamityMod/Sounds/Item/HolyFireBulletExplosion") { PitchVariance = 0.2f, Volume = 0.6f }; public override void SetStaticDefaults() { @@ -21,7 +21,7 @@ public override void SetDefaults() { Item.width = 22; Item.height = 22; - Item.damage = 22; + Item.damage = 20; Item.DamageType = DamageClass.Ranged; Item.maxStack = 9999; Item.consumable = true; diff --git a/Items/CalamityGlobalItemTweaks.cs b/Items/CalamityGlobalItemTweaks.cs index 9c5b58366e..7cb2d01cd2 100644 --- a/Items/CalamityGlobalItemTweaks.cs +++ b/Items/CalamityGlobalItemTweaks.cs @@ -162,6 +162,7 @@ internal static void LoadTweaks() { ItemID.MonkStaffT1, Do(TrueMeleeNoSpeed, DamageExact(83)) }, // Sleepy Octopod { ItemID.MonkStaffT2, Do(AutoReuse, TrueMelee, DamageExact(90)) }, // Ghastly Glaive { ItemID.MonkStaffT3, Do(DamageExact(225)) }, // Sky Dragon's Fury + { ItemID.MoonlordBullet, Do(DamageExact(19)) }, // Luminite Bullet { ItemID.MoonlordTurretStaff, Do(DamageExact(50), UseExact(15)) }, //Lunar Portal Staff { ItemID.Muramasa, Do(CritDelta(+20)) }, { ItemID.MushroomSpear, Do(AutoReuse, TrueMelee, UseRatio(0.8f), DamageExact(100)) }, @@ -211,7 +212,6 @@ internal static void LoadTweaks() { ItemID.RocketLauncher, Do(DamageExact(70)) }, { ItemID.Sandgun, Do(PointBlank, DamageExact(22), UseExact(20)) }, { ItemID.SapphireStaff, Do(DamageExact(25)) }, - { ItemID.SDMG, Do(PointBlank, DamageExact(80)) }, { ItemID.Seedler, Do(UseMeleeSpeed, DamageExact(74), ShootSpeedDelta(+4f)) }, { ItemID.ShadowbeamStaff, Do(DamageExact(100)) }, { ItemID.ShadowFlameBow, Do(PointBlank, DamageExact(55)) }, @@ -456,6 +456,7 @@ internal static void LoadTweaks() { ItemID.PulseBow, pointBlank }, { ItemID.Revolver, Do(PointBlank, AutoReuse) }, { ItemID.RichMahoganyBow, pointBlank }, + { ItemID.SDMG, pointBlank }, { ItemID.ShadewoodBow, pointBlank }, { ItemID.SilverBow, pointBlank }, { ItemID.SnowballCannon, pointBlank }, diff --git a/Items/Weapons/Ranged/AngelicShotgun.cs b/Items/Weapons/Ranged/AngelicShotgun.cs index d2fce9bbca..bd1547fa45 100644 --- a/Items/Weapons/Ranged/AngelicShotgun.cs +++ b/Items/Weapons/Ranged/AngelicShotgun.cs @@ -21,14 +21,14 @@ public override void SetDefaults() { Item.width = 86; Item.height = 38; - Item.damage = 96; + Item.damage = 92; Item.knockBack = 3f; Item.DamageType = DamageClass.Ranged; Item.noMelee = true; Item.autoReuse = true; - Item.useTime = 24; - Item.useAnimation = 24; + Item.useTime = 26; + Item.useAnimation = 26; Item.UseSound = SoundID.Item38; Item.useStyle = ItemUseStyleID.Shoot; @@ -49,7 +49,7 @@ public override void SetDefaults() public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) { - int NumBullets = Main.rand.Next(5, 8); + int NumBullets = Main.rand.Next(5, 6+1); Vector2 baseVelocity = velocity.SafeNormalize(Vector2.Zero) * BulletSpeed; // If Musket Balls are used, damage is set to match Hallow-Point Rounds for both bullets and lasers @@ -71,7 +71,7 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, // Spawn a beam from the sky ala Deathhail Staff or Lunar Flare float laserSpeed = 8f; - int laserDamage = 3 * damage; + int laserDamage = (int)(damage * 2.5f); float laserKB = 5f; Vector2 rrp = player.RotatedRelativePoint(player.MountedCenter, true); diff --git a/Items/Weapons/Ranged/Disseminator.cs b/Items/Weapons/Ranged/Disseminator.cs index a777199c5a..255bbf4bc3 100644 --- a/Items/Weapons/Ranged/Disseminator.cs +++ b/Items/Weapons/Ranged/Disseminator.cs @@ -14,10 +14,10 @@ public override void SetDefaults() { Item.width = 66; Item.height = 24; - Item.damage = 58; + Item.damage = 61; Item.DamageType = DamageClass.Ranged; - Item.useTime = 35; - Item.useAnimation = 35; + Item.useTime = 32; + Item.useAnimation = 32; Item.useStyle = ItemUseStyleID.Shoot; Item.noMelee = true; Item.knockBack = 4.5f; diff --git a/Projectiles/Ranged/BloodfireBulletProj.cs b/Projectiles/Ranged/BloodfireBulletProj.cs index e4373bbc82..e45df960a2 100644 --- a/Projectiles/Ranged/BloodfireBulletProj.cs +++ b/Projectiles/Ranged/BloodfireBulletProj.cs @@ -81,8 +81,8 @@ public override bool PreDraw(ref Color lightColor) // Returns the amount of bonus damage that should be dealt. Boosts life regeneration appropriately as a side effect. private int OnHitEffect(Player owner) { - // Adds 2 frames to lifeRegenTime on every hit. This increased value is used for the damage calculation. - owner.lifeRegenTime += 2; + // Adds 3 frames to lifeRegenTime on every hit. This increased value is used for the damage calculation. + owner.lifeRegenTime += 3; // Deals (1.00 + (0.1 * current lifeRegen))% of current lifeRegenTime as flat bonus damage on hit. // For example, at 0 life regen, you get 1% of lifeRegenTime as bonus damage. @@ -91,15 +91,16 @@ private int OnHitEffect(Player owner) int regenForCalc = owner.lifeRegen > 0 ? owner.lifeRegen : 0; float regenDamageRatio = (1f + 0.1f * regenForCalc) / 100f; - // For the sake of bonus damage, life regen time caps at 3600, aka 60 seconds. This is its natural cap in vanilla. This then gets divided by 2 for computing final damage. - int regenTimeForCalc = (int)MathHelper.Clamp(owner.lifeRegenTime, 0f, 3600f) / 2; + // For the sake of bonus damage, life regen time caps at 3600, aka 60 seconds. This is its natural cap in vanilla. 75% of this is taken for computing the final damage. + int regenTimeForCalc = (int)(MathHelper.Clamp(owner.lifeRegenTime, 0f, 3600f) * 0.75f); int finalDamageBoost = (int)(regenDamageRatio * regenTimeForCalc); - // Damage boost has a cap of 25 to prevent it from getting too crazy. - if (finalDamageBoost > 25) - finalDamageBoost = 25; + // Damage boost has a cap of 35 to prevent it from getting too crazy. + int damageCap = 35; + if (finalDamageBoost > damageCap) + finalDamageBoost = damageCap; - if (finalDamageBoost == 25) // Special hit visual if youre at max bonus damage + if (finalDamageBoost == damageCap) // Special hit visual if the bonus damage is at the cap. { for (int k = 0; k < 3; k++) { diff --git a/Projectiles/Ranged/HolyFireBulletProj.cs b/Projectiles/Ranged/HolyFireBulletProj.cs index 97da541fc2..d02a941194 100644 --- a/Projectiles/Ranged/HolyFireBulletProj.cs +++ b/Projectiles/Ranged/HolyFireBulletProj.cs @@ -81,7 +81,7 @@ public override bool PreDraw(ref Color lightColor) public override void OnKill(int timeLeft) { - // Spawn an on-hit explosion which deals 75% of the projectile's damage. + // Spawn an on-hit explosion which deals 30% of the projectile's damage. if (Projectile.owner == Main.myPlayer) { Projectile.damage = (int)(Projectile.damage * HolyFireBullet.ExplosionMultiplier); From fb6716a873362c78755aad22dcf8cecf67a083c9 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 25 May 2024 17:42:54 -0400 Subject: [PATCH 082/401] Weak Petrification now only reduces flight time and disables extra jumps --- CalPlayer/CalamityPlayer.cs | 6 ------ CalPlayer/CalamityPlayerLifeRegen.cs | 7 ------- 2 files changed, 13 deletions(-) diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 70989c1168..c61fbf50db 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -4395,13 +4395,7 @@ private void WeakPetrification() Player.blockExtraJumps = true; Player.rocketBoots = 0; - Player.jumpBoost = false; - Player.slowFall = false; - Player.gravControl = false; - Player.gravControl2 = false; - Player.jumpSpeedBoost = 0f; Player.wingTimeMax = (int)(Player.wingTimeMax * 0.5); - Player.balloon = -1; } #endregion diff --git a/CalPlayer/CalamityPlayerLifeRegen.cs b/CalPlayer/CalamityPlayerLifeRegen.cs index 73a7ec8f66..761aaf2ceb 100644 --- a/CalPlayer/CalamityPlayerLifeRegen.cs +++ b/CalPlayer/CalamityPlayerLifeRegen.cs @@ -585,13 +585,6 @@ void ApplyDoTDebuff(bool hasDebuff, int negativeLifeRegenToApply, bool immuneCon } } } - - // TODO -- Why is this here? - if (weakPetrification) - { - if (Player.mount.Active) - Player.mount.Dismount(Player); - } #endregion // Chalice of the Blood God bleedout From f076ea22a429d18d1fd89a025fb1e647f904de4c Mon Sep 17 00:00:00 2001 From: Xyk Date: Sat, 25 May 2024 15:20:12 -0700 Subject: [PATCH 083/401] Nerfs for Ambrosial and Radiance --- CalPlayer/CalamityPlayerLifeRegen.cs | 4 ++-- Items/Accessories/AmbrosialAmpoule.cs | 2 +- Items/Accessories/Radiance.cs | 2 +- Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CalPlayer/CalamityPlayerLifeRegen.cs b/CalPlayer/CalamityPlayerLifeRegen.cs index 761aaf2ceb..834104e3e4 100644 --- a/CalPlayer/CalamityPlayerLifeRegen.cs +++ b/CalPlayer/CalamityPlayerLifeRegen.cs @@ -422,8 +422,8 @@ void ApplyDoTDebuff(bool hasDebuff, int negativeLifeRegenToApply, bool immuneCon if (rOoze || aAmpoule || purity) { float missingLifeRatio = (Player.statLifeMax2 - Player.statLife) / Player.statLifeMax2; - //Ambrosial Ampule and ooze give between 2 and 6 hp/s, Purity gives between 3 and 7 hp/s - float lifeRegenToGive = MathHelper.Lerp(purity ? 6f : 4f, purity ? 14f : 12f, missingLifeRatio); + //Ambrosial Ampule and ooze give between 2 and 6 hp/s + float lifeRegenToGive = MathHelper.Lerp(4f, 12f, missingLifeRatio); Player.lifeRegen += (int)lifeRegenToGive; } diff --git a/Items/Accessories/AmbrosialAmpoule.cs b/Items/Accessories/AmbrosialAmpoule.cs index ae0904ba07..6d42653934 100644 --- a/Items/Accessories/AmbrosialAmpoule.cs +++ b/Items/Accessories/AmbrosialAmpoule.cs @@ -22,7 +22,7 @@ public override void SetDefaults() public override void UpdateAccessory(Player player, bool hideVisual) { CalamityPlayer modPlayer = player.Calamity(); - player.statLifeMax2 += 70; + player.statLifeMax2 += 50; // bool left in for abyss light purposes and life regen effects modPlayer.aAmpoule = true; diff --git a/Items/Accessories/Radiance.cs b/Items/Accessories/Radiance.cs index b8f71335c4..68b3b5836c 100644 --- a/Items/Accessories/Radiance.cs +++ b/Items/Accessories/Radiance.cs @@ -33,7 +33,7 @@ public override void SetDefaults() public override void UpdateAccessory(Player player, bool hideVisual) { CalamityPlayer modPlayer = player.Calamity(); - player.statLifeMax2 += 100; + player.statLifeMax2 += 70; // Abyss light, debuff near-immunity, life regen effects, and massively enhances debuff halving modPlayer.purity = true; diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson index a2f6e3f0a6..d0131bd3cc 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson @@ -136,7 +136,7 @@ AmbrosialAmpoule: { DisplayName: Ambrosial Ampoule Tooltip: ''' - +70 max life + +50 max life Grants +2 to +6 HP/s life regen based on missing health Provides life regeneration equivalent to standing in Honey Standing still grants extremely powerful regen @@ -1330,8 +1330,8 @@ Radiance: { DisplayName: Radiance Tooltip: ''' - +100 max life - Grants +3 to +7 HP/s life regen based on missing health + +70 max life + Grants +2 to +6 HP/s life regen based on missing health Provides life regeneration equivalent to standing in Honey Standing still grants extremely powerful regen Grants 20 defense and continuous healing while afflicted with any debuff From f39f58cd17df045ec9b0e23c859c3ab99e3028c4 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 25 May 2024 18:36:03 -0400 Subject: [PATCH 084/401] Actually Sulphurous Poisoned duration further nerf --- CalPlayer/CalamityPlayerHitHurt.cs | 4 ++-- CalPlayer/CalamityPlayerOnHit.cs | 2 +- NPCs/CalamityGlobalNPC.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CalPlayer/CalamityPlayerHitHurt.cs b/CalPlayer/CalamityPlayerHitHurt.cs index fe44174ba9..7430951616 100644 --- a/CalPlayer/CalamityPlayerHitHurt.cs +++ b/CalPlayer/CalamityPlayerHitHurt.cs @@ -1239,13 +1239,13 @@ public override void OnHitByProjectile(Projectile proj, Player.HurtInfo hurtInfo if (Main.player[proj.owner] is null) { if (!Main.npc[proj.owner].friendly) - Main.npc[proj.owner].AddBuff(BuffID.Poisoned, 90); + Main.npc[proj.owner].AddBuff(BuffID.Poisoned, 60); } else { Player p = Main.player[proj.owner]; if (p.hostile && Player.hostile && (Player.team != p.team || p.team == 0)) - p.AddBuff(BuffID.Poisoned, 90); + p.AddBuff(BuffID.Poisoned, 60); } } diff --git a/CalPlayer/CalamityPlayerOnHit.cs b/CalPlayer/CalamityPlayerOnHit.cs index 3122d55209..d4463c46bd 100644 --- a/CalPlayer/CalamityPlayerOnHit.cs +++ b/CalPlayer/CalamityPlayerOnHit.cs @@ -1266,7 +1266,7 @@ public void NPCDebuffs(NPC target, bool melee, bool ranged, bool magic, bool sum if (omegaBlueChestplate) target.AddBuff(BuffType(), 180); if (sulphurSet) - target.AddBuff(BuffID.Poisoned, 90); + target.AddBuff(BuffID.Poisoned, 60); if (abyssalAmulet) { CalamityUtils.Inflict246DebuffsNPC(target, BuffType()); diff --git a/NPCs/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index c916f8802f..33a3d3ed2f 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -5255,7 +5255,7 @@ public override void OnHitPlayer(NPC npc, Player target, Player.HurtInfo hurtInf return; if (target.Calamity().sulphurSet) - npc.AddBuff(BuffID.Poisoned, 90); + npc.AddBuff(BuffID.Poisoned, 60); if (target.Calamity().snowman) { From becd581829187233ae9bd28ccc8e6f2a90b9c874 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Sun, 26 May 2024 02:50:56 -0500 Subject: [PATCH 085/401] Decreased Rev+ Skeletron Hand HP --- NPCs/CalamityGlobalNPC.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NPCs/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index 33a3d3ed2f..45176c2362 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -1458,9 +1458,9 @@ private void RevDeathStatChanges(NPC npc, Mod mod) else if (npc.type == NPCID.SkeletronHand) { if (CalamityWorld.death) - npc.lifeMax = (int)Math.Round(npc.lifeMax * 0.65); + npc.lifeMax = (int)Math.Round(npc.lifeMax * 0.5); else - npc.lifeMax = (int)Math.Round(npc.lifeMax * 0.9); + npc.lifeMax = (int)Math.Round(npc.lifeMax * 0.75); } else if (npc.type == NPCID.QueenBee) { From e8578d4cfb0f82e1f5674dba4be540acb6dd92df Mon Sep 17 00:00:00 2001 From: Xyk Date: Sat, 25 May 2024 19:46:23 -0700 Subject: [PATCH 086/401] fixed sandsteam explosion dealing rogue damage --- Projectiles/Magic/SandstreamScepterExplosion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projectiles/Magic/SandstreamScepterExplosion.cs b/Projectiles/Magic/SandstreamScepterExplosion.cs index 6e5e86bd99..9b6ecb208e 100644 --- a/Projectiles/Magic/SandstreamScepterExplosion.cs +++ b/Projectiles/Magic/SandstreamScepterExplosion.cs @@ -16,7 +16,7 @@ public override void SetDefaults() Projectile.width = 112; Projectile.height = 112; Projectile.friendly = true; - Projectile.DamageType = RogueDamageClass.Instance; + Projectile.DamageType = DamageClass.Magic; Projectile.ignoreWater = true; Projectile.tileCollide = false; Projectile.penetrate = -1; From ec42bb9131d0b9675d96dbb5ac156f0c9fd13a72 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 25 May 2024 23:10:35 -0400 Subject: [PATCH 087/401] 1 - Profaned Guardians now enrage at night instead of despawning 2 - Guardians now use their cyan glowmask at night instead of in Remix World, and glowmasks are now rainbow in GFB 3 - Guardians projectiles and shields now draw cyan at night 4 - Fixed Providence always being enraged in Remix world instead of never enraging --- Items/SummonItems/ProfanedShard.cs | 2 +- .../Mods.CalamityMod.Items.SummonItems.hjson | 6 +- .../ProfanedGuardianCommander.cs | 65 +++++++++++------- .../ProfanedGuardianDefender.cs | 41 +++++++---- .../ProfanedGuardianHealer.cs | 27 ++++++-- NPCs/Providence/Providence.cs | 2 +- Projectiles/Boss/HolyBlast.cs | 10 +++ Projectiles/Boss/HolyBomb.cs | 10 +++ Projectiles/Boss/HolyBurnOrb.cs | 10 +++ Projectiles/Boss/HolyFire.cs | 10 +++ Projectiles/Boss/HolyFire2.cs | 10 +++ Projectiles/Boss/HolyFlare.cs | 10 +++ Projectiles/Boss/HolySpear.cs | 10 +++ Projectiles/Boss/MoltenBlast.cs | 10 +++ Projectiles/Boss/MoltenBlob.cs | 10 +++ Projectiles/Boss/ProfanedSpear.cs | 19 ++++- Projectiles/Boss/ProfanedSpearNight.png | Bin 0 -> 465 bytes Projectiles/Boss/ProvidenceHolyRay.cs | 10 +++ 18 files changed, 211 insertions(+), 51 deletions(-) create mode 100644 Projectiles/Boss/ProfanedSpearNight.png diff --git a/Items/SummonItems/ProfanedShard.cs b/Items/SummonItems/ProfanedShard.cs index f5e1076208..e65cceda1b 100644 --- a/Items/SummonItems/ProfanedShard.cs +++ b/Items/SummonItems/ProfanedShard.cs @@ -36,7 +36,7 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite public override bool CanUseItem(Player player) { - return !NPC.AnyNPCs(ModContent.NPCType()) && (Main.dayTime || Main.remixWorld) && (player.ZoneHallow || player.ZoneUnderworldHeight) && !BossRushEvent.BossRushActive; + return !NPC.AnyNPCs(ModContent.NPCType()) && (player.ZoneHallow || player.ZoneUnderworldHeight) && !BossRushEvent.BossRushActive; } public override bool? UseItem(Player player) diff --git a/Localization/en-US/Mods.CalamityMod.Items.SummonItems.hjson b/Localization/en-US/Mods.CalamityMod.Items.SummonItems.hjson index 3d32178f39..ef8f23c883 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.SummonItems.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.SummonItems.hjson @@ -234,7 +234,11 @@ ProfanedShard: { Not consumable 'Her Guardians seek the holder of such vast stolen power.' ''' - SpawnNormal: Summons the Profaned Guardians when used in the Hallow or Underworld during daytime + SpawnNormal: + ''' + Summons the Profaned Guardians when used in the Hallow or Underworld + Enrages when fought during nighttime + ''' SpawnRemix: Summons the Profaned Guardians when used in the Hallow or Underworld } diff --git a/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs b/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs index d9682a401f..a98ab63273 100644 --- a/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs +++ b/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs @@ -296,11 +296,11 @@ public override void AI() Player player = Main.player[NPC.target]; - if ((!Main.dayTime && !Main.remixWorld) || !player.active || player.dead || Vector2.Distance(Main.player[NPC.target].Center, NPC.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) + if (!player.active || player.dead || Vector2.Distance(Main.player[NPC.target].Center, NPC.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) { NPC.TargetClosest(false); player = Main.player[NPC.target]; - if ((!Main.dayTime && !Main.remixWorld) || !player.active || player.dead || Vector2.Distance(Main.player[NPC.target].Center, NPC.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) + if (!player.active || player.dead || Vector2.Distance(Main.player[NPC.target].Center, NPC.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) { if (NPC.velocity.Y > 3f) NPC.velocity.Y = 3f; @@ -333,6 +333,14 @@ public override void AI() if (NPC.ai[3] < 0f) NPC.ai[3] = 0f; + // Enrage at nighttime + bool enraged = false; + if (!Main.dayTime && !Main.remixWorld) + { + enraged = true; + NPC.Calamity().CurrentlyEnraged = true; + } + bool phase1 = healerAlive || defenderAlive; NPC.chaseable = !phase1; @@ -357,7 +365,7 @@ public override void AI() float goLowOrHighDistance = 540f; // Side swap variables for Phase 2 - float defenderCommanderGuardPhase2Duration = bossRush ? 420f : death ? 480f : revenge ? 510f : expertMode ? 540f : 600f; + float defenderCommanderGuardPhase2Duration = (bossRush || enraged) ? 420f : death ? 480f : revenge ? 510f : expertMode ? 540f : 600f; float moveToOtherSideInPhase2GateValue = defenderCommanderGuardPhase2Duration - 120f; float timeBeforeMoveToOtherSideInPhase2Reset = moveToOtherSideInPhase2GateValue * 2f; float totalGoLowDurationPhase2 = 210f; @@ -365,13 +373,13 @@ public override void AI() // Charge variables float chargeVelocityMult = 0.25f; - float maxChargeVelocity = bossRush ? 32f : death ? 28f : revenge ? 26f : expertMode ? 24f : 20f; + float maxChargeVelocity = (bossRush || enraged) ? 32f : death ? 28f : revenge ? 26f : expertMode ? 24f : 20f; if (Main.getGoodWorld) maxChargeVelocity *= 1.15f; if (CalamityWorld.LegendaryMode && revenge) maxChargeVelocity *= 2f; - float inertia = bossRush ? 40f : death ? 45f : revenge ? 47f : expertMode ? 50f : 55f; + float inertia = (bossRush || enraged) ? 40f : death ? 45f : revenge ? 47f : expertMode ? 50f : 55f; if (lifeRatio < 0.5f) inertia *= 0.8f; if (!phase1) @@ -454,7 +462,7 @@ public override void AI() if (!goLow && !goLowPhase2 && !goHigh) calamityGlobalNPC.newAI[0] = -NPC.direction; - float velocity = bossRush ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f; + float velocity = (bossRush || enraged) ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f; if (Main.getGoodWorld) velocity *= 1.25f; if (healerAlive) @@ -491,7 +499,7 @@ public override void AI() Vector2 targetVector = destination - NPC.Center; Vector2 desiredVelocity = targetVector.SafeNormalize(new Vector2(NPC.direction, 0f)) * velocity; - float phaseGateValue = bossRush ? 50f : death ? 66f : revenge ? 75f : expertMode ? 83f : 100f; + float phaseGateValue = (bossRush || enraged) ? 50f : death ? 66f : revenge ? 75f : expertMode ? 83f : 100f; bool continueShootingProjectiles = phase1 || (NPC.ai[2] < (phaseGateValue * 5f)); if (continueShootingProjectiles) @@ -505,7 +513,7 @@ public override void AI() // Alternate between firing profaned spears and holy fire // Shoot holy blasts in final phase NPC.ai[2] += 1f; - float projectileShootGateValue = bossRush ? 40f : death ? 60f : revenge ? 90f : expertMode ? 100f : 150f; + float projectileShootGateValue = (bossRush || enraged) ? 40f : death ? 60f : revenge ? 90f : expertMode ? 100f : 150f; if (NPC.ai[2] % projectileShootGateValue == 0f) { if (phase1) @@ -519,7 +527,7 @@ public override void AI() } bool shootSpear = NPC.ai[2] % (projectileShootGateValue * 2f) == 0f; - float projectileVelocity = bossRush ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f; + float projectileVelocity = (bossRush || enraged) ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f; Vector2 finalProjectileVelocity = Vector2.Normalize(player.Center - shootFrom) * projectileVelocity; int type = shootSpear ? ModContent.ProjectileType() : ModContent.ProjectileType(); int damage = NPC.GetProjectileDamage(type); @@ -532,8 +540,8 @@ public override void AI() if (fireExtraProjectiles && shootSpear) { - int baseProjectileAmt = bossRush ? 4 : 2; - int spread = bossRush ? 18 : 10; + int baseProjectileAmt = (bossRush || enraged) ? 4 : 2; + int spread = (bossRush || enraged) ? 18 : 10; float rotation = MathHelper.ToRadians(spread); for (int i = 0; i < baseProjectileAmt; i++) { @@ -552,7 +560,7 @@ public override void AI() else { // Shoot holy blasts - float holyBlastVelocity = bossRush ? 20f : death ? 18f : revenge ? 17f : expertMode ? 16f : 14f; + float holyBlastVelocity = (bossRush || enraged) ? 20f : death ? 18f : revenge ? 17f : expertMode ? 16f : 14f; int projTimeLeft = (int)(2000f / holyBlastVelocity); Vector2 finalHolyBlastVelocity = Vector2.Normalize(player.Center - shootFrom) * holyBlastVelocity; if (Main.netMode != NetmodeID.MultiplayerClient) @@ -665,7 +673,7 @@ public override void AI() NPC.spriteDirection = Math.Sign(NPC.velocity.X); NPC.ai[1] += 1f; - float phaseGateValue = bossRush ? 90f : death ? 100f : revenge ? 110f : expertMode ? 120f : 135f; + float phaseGateValue = (bossRush || enraged) ? 90f : death ? 100f : revenge ? 110f : expertMode ? 120f : 135f; if (NPC.ai[1] >= phaseGateValue) { NPC.ai[0] = 3f; @@ -686,7 +694,7 @@ public override void AI() // Accelerate if (NPC.velocity.Length() < maxChargeVelocity) { - float velocityMult = bossRush ? 1.053333f : death ? 1.05037f : revenge ? 1.047407f : expertMode ? 1.044444f : 1.04f; + float velocityMult = (bossRush || enraged) ? 1.053333f : death ? 1.05037f : revenge ? 1.047407f : expertMode ? 1.044444f : 1.04f; NPC.velocity = targetVector * (NPC.velocity.Length() * velocityMult); if (NPC.velocity.Length() > maxChargeVelocity) { @@ -774,7 +782,7 @@ public override void AI() bool targetRanAwayAndWillNowBeFucked = NPC.ai[2] == 1f; bool boostVelocityToCatchUp = NPC.ai[1] == 0f || targetRanAwayAndWillNowBeFucked; - float velocity = bossRush ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f; + float velocity = (bossRush || enraged) ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f; if (Main.getGoodWorld) velocity *= 1.25f; if (boostVelocityToCatchUp) @@ -786,7 +794,7 @@ public override void AI() Vector2 desiredVelocity = targetVector.SafeNormalize(new Vector2(NPC.direction, 0f)) * velocity; float totalSpears = 12f; - float shootDuration = bossRush ? 240f : death ? 280f : revenge ? 300f : expertMode ? 320f : 360f; + float shootDuration = (bossRush || enraged) ? 240f : death ? 280f : revenge ? 300f : expertMode ? 320f : 360f; float dontShootTime = shootDuration * 0.3f; float phaseGateValue = dontShootTime + shootDuration; @@ -831,7 +839,7 @@ public override void AI() } else if (NPC.ai[1] % spearShootDivisor == 0f) { - float spearVelocity = bossRush ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f; + float spearVelocity = (bossRush || enraged) ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f; if (Main.getGoodWorld) spearVelocity *= 1.25f; if (boostVelocityToCatchUp) @@ -849,8 +857,8 @@ public override void AI() if (NPC.ai[1] % (spearShootDivisor * 3) == 0f || targetRanAwayAndWillNowBeFucked) { knockbackVelocity *= 2f; - int baseProjectileAmt = bossRush ? 8 : expertMode ? 6 : 4; - int spread = bossRush ? 60 : expertMode ? 50 : 40; + int baseProjectileAmt = (bossRush || enraged) ? 8 : expertMode ? 6 : 4; + int spread = (bossRush || enraged) ? 60 : expertMode ? 50 : 40; float rotation = MathHelper.ToRadians(spread); for (int i = 0; i < baseProjectileAmt; i++) { @@ -886,7 +894,7 @@ public override void AI() } float laserGateValue = 120f; - float velocity = bossRush ? 4.5f : death ? 4f : revenge ? 3.75f : expertMode ? 3.5f : 3f; + float velocity = (bossRush || enraged) ? 4.5f : death ? 4f : revenge ? 3.75f : expertMode ? 3.5f : 3f; if (NPC.ai[1] < laserGateValue) velocity *= 6f; if (Main.getGoodWorld) @@ -942,7 +950,7 @@ public override void AI() { if (NPC.ai[2] == laserGateValue) { - float rotation = bossRush ? 435f : death ? 445f : revenge ? 450f : expertMode ? 455f : 465f; + float rotation = (bossRush || enraged) ? 435f : death ? 445f : revenge ? 450f : expertMode ? 455f : 465f; if (Main.player[Main.myPlayer].active && !Main.player[Main.myPlayer].dead && Vector2.Distance(Main.player[Main.myPlayer].Center, NPC.Center) < 2800f) SoundEngine.PlaySound(HolyRaySound, Main.LocalPlayer.Center); @@ -1032,10 +1040,15 @@ void drawGuardianInstance(Vector2 drawOffset, Color? colorOverride) texture2D15 = Texture_Glow.Value; Color timeBasedColorLerp = Color.Lerp(Color.White, Color.Yellow, 0.5f); - if (Main.remixWorld) + if (NPC.Calamity().CurrentlyEnraged) + { + texture2D15 = TextureNight_Glow.Value; + timeBasedColorLerp = Color.Lerp(Color.White, Color.Cyan, 0.75f); + } + if (Main.zenithWorld) { texture2D15 = TextureNight_Glow.Value; - timeBasedColorLerp = Color.Cyan; + timeBasedColorLerp = Main.DiscoColor; } if (colorOverride != null) timeBasedColorLerp = colorOverride.Value; @@ -1134,14 +1147,14 @@ void drawGuardianInstance(Vector2 drawOffset, Color? colorOverride) Vector2 shieldDrawPos = NPC.Center - screenPos; shieldDrawPos -= new Vector2(shieldTexture.Width, shieldTexture.Height) * NPC.scale / 2f; shieldDrawPos += origin * NPC.scale + new Vector2(0f, NPC.gfxOffY); - float minHue = (defenderAlive && healerAlive) ? 0.18f : 0.06f; + float minHue = NPC.Calamity().CurrentlyEnraged ? 0.4f : (defenderAlive && healerAlive) ? 0.18f : 0.06f; float maxHue = minHue + 0.12f; float opacityScaleDuringShieldDespawn = (TimeForShieldDespawn - NPC.localAI[1]) / TimeForShieldDespawn; float scaleDuringShieldDespawnScale = 1.8f; float scaleDuringShieldDespawn = (1f - opacityScaleDuringShieldDespawn) * scaleDuringShieldDespawnScale; float colorScale = MathHelper.Lerp(0f, shieldOpacity, opacityScaleDuringShieldDespawn); - Color color = Main.hslToRgb(MathHelper.Lerp(maxHue - minHue, maxHue, ((float)Math.Sin(Main.GlobalTimeWrappedHourly * MathHelper.TwoPi) + 1f) * 0.5f), 1f, 0.5f) * colorScale; - Color color2 = Main.hslToRgb(MathHelper.Lerp(minHue, maxHue - minHue, ((float)Math.Sin(Main.GlobalTimeWrappedHourly * MathHelper.Pi * 3f) + 1f) * 0.5f), 1f, 0.5f) * colorScale; + Color color = Main.hslToRgb(MathHelper.Lerp(NPC.Calamity().CurrentlyEnraged ? minHue : maxHue - minHue, maxHue, ((float)Math.Sin(Main.GlobalTimeWrappedHourly * MathHelper.TwoPi) + 1f) * 0.5f), 1f, 0.5f) * colorScale; + Color color2 = Main.hslToRgb(MathHelper.Lerp(minHue, NPC.Calamity().CurrentlyEnraged ? maxHue : maxHue - minHue, ((float)Math.Sin(Main.GlobalTimeWrappedHourly * MathHelper.Pi * 3f) + 1f) * 0.5f), 1f, 0.5f) * colorScale; color2.A = 0; color *= 0.6f; color2 *= 0.6f; diff --git a/NPCs/ProfanedGuardians/ProfanedGuardianDefender.cs b/NPCs/ProfanedGuardians/ProfanedGuardianDefender.cs index 8a4f75cfb1..b4033cedc5 100644 --- a/NPCs/ProfanedGuardians/ProfanedGuardianDefender.cs +++ b/NPCs/ProfanedGuardians/ProfanedGuardianDefender.cs @@ -248,12 +248,20 @@ public override void AI() bool revenge = CalamityWorld.revenge || bossRush; bool death = CalamityWorld.death || bossRush; + // Enrage at nighttime + bool enraged = false; + if (!Main.dayTime && !Main.remixWorld) + { + enraged = true; + NPC.Calamity().CurrentlyEnraged = true; + } + bool phase1 = healerAlive; NPC.chaseable = !phase1; // Phase durations - float commanderGuardPhase2Duration = bossRush ? 420f : death ? 480f : revenge ? 510f : expertMode ? 540f : 600f; + float commanderGuardPhase2Duration = (bossRush || enraged) ? 420f : death ? 480f : revenge ? 510f : expertMode ? 540f : 600f; float timeBeforeRocksRespawnInPhase2 = 90f; float throwRocksGateValue = 60f; @@ -262,7 +270,7 @@ public override void AI() // Charge variables float chargeVelocityMult = 0.25f; - float maxChargeVelocity = bossRush ? 25f : death ? 22f : revenge ? 20.5f : expertMode ? 19f : 16f; + float maxChargeVelocity = (bossRush || enraged) ? 25f : death ? 22f : revenge ? 20.5f : expertMode ? 19f : 16f; if (Main.getGoodWorld) maxChargeVelocity *= 1.15f; @@ -382,7 +390,7 @@ public override void AI() } } - float moveVelocity = bossRush ? 24f : death ? 22f : revenge ? 21f : expertMode ? 20f : 18f; + float moveVelocity = (bossRush || enraged) ? 24f : death ? 22f : revenge ? 21f : expertMode ? 20f : 18f; if (Main.getGoodWorld) moveVelocity *= 1.25f; if (healerAlive) @@ -432,7 +440,7 @@ public override void AI() // Lay a holy bomb every once in a while in phase 1 and while not doing the laser attack if (!commanderUsingLaser) { - float projectileShootGateValue = bossRush ? 420f : death ? 480f : revenge ? 510f : expertMode ? 540f : 600f; + float projectileShootGateValue = (bossRush || enraged) ? 420f : death ? 480f : revenge ? 510f : expertMode ? 540f : 600f; NPC.ai[1] += 1f; if (NPC.ai[1] >= projectileShootGateValue) { @@ -502,7 +510,7 @@ public override void AI() float shootMoltenBlastsGateValue = commanderGuardPhase2Duration / moltenBlastsDivisor; if (NPC.ai[1] % shootMoltenBlastsGateValue == 0f && !commanderGoingLowOrHighInPhase2) { - float moltenBlastVelocity = bossRush ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f; + float moltenBlastVelocity = (bossRush || enraged) ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f; int projTimeLeft = (int)(2400f / moltenBlastVelocity); Vector2 velocity = Vector2.Normalize(player.Center - shootFrom) * moltenBlastVelocity; if (Main.netMode != NetmodeID.MultiplayerClient) @@ -609,7 +617,7 @@ public override void AI() NPC.spriteDirection = Math.Sign(NPC.velocity.X); NPC.ai[1] += 1f; - float phaseGateValue = bossRush ? 120f : death ? 140f : revenge ? 150f : expertMode ? 160f : 180f; + float phaseGateValue = (bossRush || enraged) ? 120f : death ? 140f : revenge ? 150f : expertMode ? 160f : 180f; if (NPC.ai[1] >= phaseGateValue) { NPC.ai[0] = 3f; @@ -630,7 +638,7 @@ public override void AI() // Accelerate if (NPC.velocity.Length() < maxChargeVelocity) { - float velocityMult = bossRush ? 1.04f : death ? 1.036667f : revenge ? 1.035f : expertMode ? 1.033333f : 1.03f; + float velocityMult = (bossRush || enraged) ? 1.04f : death ? 1.036667f : revenge ? 1.035f : expertMode ? 1.033333f : 1.03f; NPC.velocity = targetVector * (NPC.velocity.Length() * velocityMult); if (NPC.velocity.Length() > maxChargeVelocity) { @@ -642,7 +650,7 @@ public override void AI() else { // Charge towards target - float inertia = bossRush ? 57f : death ? 63f : revenge ? 66f : expertMode ? 69f : 75f; + float inertia = (bossRush || enraged) ? 57f : death ? 63f : revenge ? 66f : expertMode ? 69f : 75f; NPC.velocity = (NPC.velocity * (inertia - 1f) + targetVector * (NPC.velocity.Length() + (0.111111117f * inertia))) / inertia; } @@ -755,10 +763,15 @@ void drawGuardianInstance(Vector2 drawOffset, Color? colorOverride) texture2D15 = Texture_Glow.Value; Color timeBasedGlowColor = Color.Lerp(Color.White, Color.Yellow, 0.5f); - if (Main.remixWorld) + if (NPC.Calamity().CurrentlyEnraged) + { + texture2D15 = TextureNight_Glow.Value; + timeBasedGlowColor = Color.Lerp(Color.White, Color.Cyan, 0.75f); + } + if (Main.zenithWorld) { texture2D15 = TextureNight_Glow.Value; - timeBasedGlowColor = Color.Cyan; + timeBasedGlowColor = Main.DiscoColor; } if (colorOverride != null) timeBasedGlowColor = colorOverride.Value; @@ -849,14 +862,14 @@ void drawGuardianInstance(Vector2 drawOffset, Color? colorOverride) Vector2 shieldDrawPos = NPC.Center - screenPos; shieldDrawPos -= new Vector2(shieldTexture.Width, shieldTexture.Height) * NPC.scale / 2f; shieldDrawPos += origin * NPC.scale + new Vector2(0f, NPC.gfxOffY); - float minHue = 0.06f; - float maxHue = 0.18f; + float minHue = NPC.Calamity().CurrentlyEnraged ? 0.4f : 0.06f; + float maxHue = minHue + 0.12f; float opacityScaleDuringShieldDespawn = (TimeForShieldDespawn - NPC.localAI[1]) / TimeForShieldDespawn; float scaleDuringShieldDespawnScale = 1.8f; float scaleDuringShieldDespawn = (1f - opacityScaleDuringShieldDespawn) * scaleDuringShieldDespawnScale; float colorScale = MathHelper.Lerp(0f, shieldOpacity, opacityScaleDuringShieldDespawn); - Color color = Main.hslToRgb(MathHelper.Lerp(maxHue - minHue, maxHue, ((float)Math.Sin(Main.GlobalTimeWrappedHourly * MathHelper.TwoPi) + 1f) * 0.5f), 1f, 0.5f) * colorScale; - Color color2 = Main.hslToRgb(MathHelper.Lerp(minHue, maxHue - minHue, ((float)Math.Sin(Main.GlobalTimeWrappedHourly * MathHelper.Pi * 3f) + 1f) * 0.5f), 1f, 0.5f) * colorScale; + Color color = Main.hslToRgb(MathHelper.Lerp(NPC.Calamity().CurrentlyEnraged ? minHue : maxHue - minHue, maxHue, ((float)Math.Sin(Main.GlobalTimeWrappedHourly * MathHelper.TwoPi) + 1f) * 0.5f), 1f, 0.5f) * colorScale; + Color color2 = Main.hslToRgb(MathHelper.Lerp(minHue, NPC.Calamity().CurrentlyEnraged ? maxHue : maxHue - minHue, ((float)Math.Sin(Main.GlobalTimeWrappedHourly * MathHelper.Pi * 3f) + 1f) * 0.5f), 1f, 0.5f) * colorScale; color2.A = 0; color *= 0.6f; color2 *= 0.6f; diff --git a/NPCs/ProfanedGuardians/ProfanedGuardianHealer.cs b/NPCs/ProfanedGuardians/ProfanedGuardianHealer.cs index a59ec9f297..03ed34ed59 100644 --- a/NPCs/ProfanedGuardians/ProfanedGuardianHealer.cs +++ b/NPCs/ProfanedGuardians/ProfanedGuardianHealer.cs @@ -178,6 +178,14 @@ public override void AI() if (NPC.ai[0] >= 300f) NPC.ai[1] = 1f; + // Enrage at nighttime + bool enraged = false; + if (!Main.dayTime && !Main.remixWorld) + { + enraged = true; + NPC.Calamity().CurrentlyEnraged = true; + } + // Direction if (Math.Abs(NPC.Center.X - player.Center.X) > 10f) { @@ -217,7 +225,7 @@ public override void AI() } bool useCrystalShards = AIState == (float)Phase.CrystalShards; - float velocity = useCrystalShards ? (bossRush ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f) : (Main.npc[CalamityGlobalNPC.doughnutBoss].velocity.Length() + 5f); + float velocity = useCrystalShards ? ((bossRush || enraged) ? 18f : death ? 16f : revenge ? 15f : expertMode ? 14f : 12f) : (Main.npc[CalamityGlobalNPC.doughnutBoss].velocity.Length() + 5f); if (Main.getGoodWorld) velocity *= 1.25f; @@ -305,7 +313,7 @@ public override void AI() { int type = ModContent.ProjectileType(); int damage = NPC.GetProjectileDamage(type); - int totalProjectiles = bossRush ? 18 : death ? 16 : revenge ? 14 : expertMode ? 12 : 10; + int totalProjectiles = (bossRush || enraged) ? 18 : death ? 16 : revenge ? 14 : expertMode ? 12 : 10; float speedX = -12f; float speedAdjustment = Math.Abs(speedX * 2f / (totalProjectiles - 1)); float speedY = -4f; @@ -344,7 +352,7 @@ public override void AI() { SoundEngine.PlaySound(SoundID.DD2_BetsyFireballImpact, shootFrom); - int totalFlameProjectiles = bossRush ? 20 : 16; + int totalFlameProjectiles = (bossRush || enraged) ? 20 : 16; int totalRings = revenge ? 3 : 2; int healingStarChance = revenge ? 8 : expertMode ? 6 : 4; double radians = MathHelper.TwoPi / totalFlameProjectiles; @@ -362,7 +370,7 @@ public override void AI() int type = ModContent.ProjectileType(); int dmgAmt = NPC.GetProjectileDamage(type); - if (Main.rand.NextBool(healingStarChance) && !death) + if (Main.rand.NextBool(healingStarChance) && !enraged && !death) { type = ModContent.ProjectileType(); dmgAmt = NPC.GetProjectileDamageNoScaling(type); @@ -405,7 +413,7 @@ public override void AI() // Move towards a location above the player if (distanceFromDestination.Length() > idealDistanceFromDestination) { - float inertia = bossRush ? 28f : death ? 32f : revenge ? 34f : expertMode ? 36f : 40f; + float inertia = (bossRush || enraged) ? 28f : death ? 32f : revenge ? 34f : expertMode ? 36f : 40f; if (lifeRatio < 0.5f) inertia *= 0.8f; if (Main.getGoodWorld) @@ -460,10 +468,15 @@ void drawGuardianInstance(Vector2 drawOffset, Color? colorOverride) texture2D15 = Texture_Glow.Value; Color timeBasedDrawColor = Color.Lerp(Color.White, Color.Yellow, 0.5f); - if (Main.remixWorld) + if (NPC.Calamity().CurrentlyEnraged) + { + texture2D15 = TextureNight_Glow.Value; + timeBasedDrawColor = Color.Lerp(Color.White, Color.Cyan, 0.75f); + } + if (Main.zenithWorld) { texture2D15 = TextureNight_Glow.Value; - timeBasedDrawColor = Color.Cyan; + timeBasedDrawColor = Main.DiscoColor; } Color overrideColor = Color.Lerp(Color.White, Color.Violet, 0.5f); if (colorOverride != null) diff --git a/NPCs/Providence/Providence.cs b/NPCs/Providence/Providence.cs index 7f0bbfabc3..aeb2b7d136 100644 --- a/NPCs/Providence/Providence.cs +++ b/NPCs/Providence/Providence.cs @@ -366,7 +366,7 @@ public override void AI() colorShiftTimer = 0; } } - else if (!Main.IsItDay() || bossRush) //Normal Night time activity + else if ((!Main.dayTime && !Main.remixWorld) || bossRush) //Normal Night time activity NPC.localAI[1] = (float)BossMode.Night; else NPC.localAI[1] = (float)BossMode.Day; diff --git a/Projectiles/Boss/HolyBlast.cs b/Projectiles/Boss/HolyBlast.cs index 6736fc4ea1..d6e09c41fd 100644 --- a/Projectiles/Boss/HolyBlast.cs +++ b/Projectiles/Boss/HolyBlast.cs @@ -58,6 +58,16 @@ public override void AI() if (Main.npc[CalamityGlobalNPC.holyBoss].active) Projectile.maxPenetrate = (int)Main.npc[CalamityGlobalNPC.holyBoss].localAI[1]; } + else if (CalamityGlobalNPC.doughnutBoss != -1) + { + if (Main.npc[CalamityGlobalNPC.doughnutBoss].active) + { + if (Main.npc[CalamityGlobalNPC.doughnutBoss].Calamity().CurrentlyEnraged) + Projectile.maxPenetrate = (int)Providence.BossMode.Night; + else + Projectile.maxPenetrate = (int)Providence.BossMode.Day; + } + } else Projectile.maxPenetrate = (int)Providence.BossMode.Day; diff --git a/Projectiles/Boss/HolyBomb.cs b/Projectiles/Boss/HolyBomb.cs index 7bdb4af478..15ff7a1b48 100644 --- a/Projectiles/Boss/HolyBomb.cs +++ b/Projectiles/Boss/HolyBomb.cs @@ -47,6 +47,16 @@ public override void AI() if (Main.npc[CalamityGlobalNPC.holyBoss].active) Projectile.maxPenetrate = (int)Main.npc[CalamityGlobalNPC.holyBoss].localAI[1]; } + else if (CalamityGlobalNPC.doughnutBoss != -1) + { + if (Main.npc[CalamityGlobalNPC.doughnutBoss].active) + { + if (Main.npc[CalamityGlobalNPC.doughnutBoss].Calamity().CurrentlyEnraged) + Projectile.maxPenetrate = (int)Providence.BossMode.Night; + else + Projectile.maxPenetrate = (int)Providence.BossMode.Day; + } + } else Projectile.maxPenetrate = (int)Providence.BossMode.Day; diff --git a/Projectiles/Boss/HolyBurnOrb.cs b/Projectiles/Boss/HolyBurnOrb.cs index 7509889518..b7bdb2c51b 100644 --- a/Projectiles/Boss/HolyBurnOrb.cs +++ b/Projectiles/Boss/HolyBurnOrb.cs @@ -41,6 +41,16 @@ public override void AI() if (Main.npc[CalamityGlobalNPC.holyBoss].active) Projectile.maxPenetrate = (int)Main.npc[CalamityGlobalNPC.holyBoss].localAI[1]; } + else if (CalamityGlobalNPC.doughnutBoss != -1) + { + if (Main.npc[CalamityGlobalNPC.doughnutBoss].active) + { + if (Main.npc[CalamityGlobalNPC.doughnutBoss].Calamity().CurrentlyEnraged) + Projectile.maxPenetrate = (int)Providence.BossMode.Night; + else + Projectile.maxPenetrate = (int)Providence.BossMode.Day; + } + } else Projectile.maxPenetrate = (int)Providence.BossMode.Day; diff --git a/Projectiles/Boss/HolyFire.cs b/Projectiles/Boss/HolyFire.cs index 72a76cb870..0a19097430 100644 --- a/Projectiles/Boss/HolyFire.cs +++ b/Projectiles/Boss/HolyFire.cs @@ -42,6 +42,16 @@ public override void AI() if (Main.npc[CalamityGlobalNPC.holyBoss].active) Projectile.maxPenetrate = (int)Main.npc[CalamityGlobalNPC.holyBoss].localAI[1]; } + else if (CalamityGlobalNPC.doughnutBoss != -1) + { + if (Main.npc[CalamityGlobalNPC.doughnutBoss].active) + { + if (Main.npc[CalamityGlobalNPC.doughnutBoss].Calamity().CurrentlyEnraged) + Projectile.maxPenetrate = (int)Providence.BossMode.Night; + else + Projectile.maxPenetrate = (int)Providence.BossMode.Day; + } + } else Projectile.maxPenetrate = (int)Providence.BossMode.Day; diff --git a/Projectiles/Boss/HolyFire2.cs b/Projectiles/Boss/HolyFire2.cs index d694d1753f..8e8c50642e 100644 --- a/Projectiles/Boss/HolyFire2.cs +++ b/Projectiles/Boss/HolyFire2.cs @@ -42,6 +42,16 @@ public override void AI() if (Main.npc[CalamityGlobalNPC.holyBoss].active) Projectile.maxPenetrate = (int)Main.npc[CalamityGlobalNPC.holyBoss].localAI[1]; } + else if (CalamityGlobalNPC.doughnutBoss != -1) + { + if (Main.npc[CalamityGlobalNPC.doughnutBoss].active) + { + if (Main.npc[CalamityGlobalNPC.doughnutBoss].Calamity().CurrentlyEnraged) + Projectile.maxPenetrate = (int)Providence.BossMode.Night; + else + Projectile.maxPenetrate = (int)Providence.BossMode.Day; + } + } else Projectile.maxPenetrate = (int)Providence.BossMode.Day; diff --git a/Projectiles/Boss/HolyFlare.cs b/Projectiles/Boss/HolyFlare.cs index ce8b652245..1208b849ad 100644 --- a/Projectiles/Boss/HolyFlare.cs +++ b/Projectiles/Boss/HolyFlare.cs @@ -42,6 +42,16 @@ public override void AI() if (Main.npc[CalamityGlobalNPC.holyBoss].active) Projectile.maxPenetrate = (int)Main.npc[CalamityGlobalNPC.holyBoss].localAI[1]; } + else if (CalamityGlobalNPC.doughnutBoss != -1) + { + if (Main.npc[CalamityGlobalNPC.doughnutBoss].active) + { + if (Main.npc[CalamityGlobalNPC.doughnutBoss].Calamity().CurrentlyEnraged) + Projectile.maxPenetrate = (int)Providence.BossMode.Night; + else + Projectile.maxPenetrate = (int)Providence.BossMode.Day; + } + } else Projectile.maxPenetrate = (int)Providence.BossMode.Day; diff --git a/Projectiles/Boss/HolySpear.cs b/Projectiles/Boss/HolySpear.cs index 03116c57ea..697dfa6c2a 100644 --- a/Projectiles/Boss/HolySpear.cs +++ b/Projectiles/Boss/HolySpear.cs @@ -61,6 +61,16 @@ public override void AI() if (Main.npc[CalamityGlobalNPC.holyBoss].active) Projectile.maxPenetrate = (int)Main.npc[CalamityGlobalNPC.holyBoss].localAI[1]; } + else if (CalamityGlobalNPC.doughnutBoss != -1) + { + if (Main.npc[CalamityGlobalNPC.doughnutBoss].active) + { + if (Main.npc[CalamityGlobalNPC.doughnutBoss].Calamity().CurrentlyEnraged) + Projectile.maxPenetrate = (int)Providence.BossMode.Night; + else + Projectile.maxPenetrate = (int)Providence.BossMode.Day; + } + } else Projectile.maxPenetrate = (int)Providence.BossMode.Day; diff --git a/Projectiles/Boss/MoltenBlast.cs b/Projectiles/Boss/MoltenBlast.cs index f80225ae09..18ee564f3b 100644 --- a/Projectiles/Boss/MoltenBlast.cs +++ b/Projectiles/Boss/MoltenBlast.cs @@ -58,6 +58,16 @@ public override void AI() if (Main.npc[CalamityGlobalNPC.holyBoss].active) Projectile.maxPenetrate = (int)Main.npc[CalamityGlobalNPC.holyBoss].localAI[1]; } + else if (CalamityGlobalNPC.doughnutBoss != -1) + { + if (Main.npc[CalamityGlobalNPC.doughnutBoss].active) + { + if (Main.npc[CalamityGlobalNPC.doughnutBoss].Calamity().CurrentlyEnraged) + Projectile.maxPenetrate = (int)Providence.BossMode.Night; + else + Projectile.maxPenetrate = (int)Providence.BossMode.Day; + } + } else Projectile.maxPenetrate = (int)Providence.BossMode.Day; diff --git a/Projectiles/Boss/MoltenBlob.cs b/Projectiles/Boss/MoltenBlob.cs index 2ff2619640..f0516d1376 100644 --- a/Projectiles/Boss/MoltenBlob.cs +++ b/Projectiles/Boss/MoltenBlob.cs @@ -39,6 +39,16 @@ public override void AI() if (Main.npc[CalamityGlobalNPC.holyBoss].active) Projectile.maxPenetrate = (int)Main.npc[CalamityGlobalNPC.holyBoss].localAI[1]; } + else if (CalamityGlobalNPC.doughnutBoss != -1) + { + if (Main.npc[CalamityGlobalNPC.doughnutBoss].active) + { + if (Main.npc[CalamityGlobalNPC.doughnutBoss].Calamity().CurrentlyEnraged) + Projectile.maxPenetrate = (int)Providence.BossMode.Night; + else + Projectile.maxPenetrate = (int)Providence.BossMode.Day; + } + } else Projectile.maxPenetrate = (int)Providence.BossMode.Day; diff --git a/Projectiles/Boss/ProfanedSpear.cs b/Projectiles/Boss/ProfanedSpear.cs index 7187932d5e..f716020d87 100644 --- a/Projectiles/Boss/ProfanedSpear.cs +++ b/Projectiles/Boss/ProfanedSpear.cs @@ -1,6 +1,9 @@ using System; using CalamityMod.Buffs.DamageOverTime; +using CalamityMod.NPCs; +using CalamityMod.NPCs.Providence; using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -32,6 +35,17 @@ public override void AI() { Lighting.AddLight(Projectile.Center, 0.45f, 0.35f, 0f); + if (CalamityGlobalNPC.doughnutBoss != -1) + { + if (Main.npc[CalamityGlobalNPC.doughnutBoss].active) + { + if (Main.npc[CalamityGlobalNPC.doughnutBoss].Calamity().CurrentlyEnraged) + Projectile.maxPenetrate = (int)Providence.BossMode.Night; + else + Projectile.maxPenetrate = (int)Providence.BossMode.Day; + } + } + if (Projectile.timeLeft < 510) Projectile.tileCollide = true; @@ -56,11 +70,14 @@ public override void AI() public override Color? GetAlpha(Color lightColor) { - return new Color(250, 150, 0, Projectile.alpha); + return ProvUtils.GetProjectileColor(Projectile.maxPenetrate, Projectile.alpha); } public override bool PreDraw(ref Color lightColor) { + Texture2D texture = (Projectile.maxPenetrate == (int)Providence.BossMode.Day) ? Terraria.GameContent.TextureAssets.Projectile[Projectile.type].Value : ModContent.Request("CalamityMod/Projectiles/Boss/ProfanedSpearNight").Value; + Projectile.DrawBackglow(ProvUtils.GetProjectileColor(Projectile.maxPenetrate, Projectile.alpha, true), 4f, texture); + Main.spriteBatch.Draw(texture, Projectile.Center - Main.screenPosition + new Vector2(0f, Projectile.gfxOffY), new Microsoft.Xna.Framework.Rectangle?(new Rectangle(0, 0, texture.Width, texture.Height)), Projectile.GetAlpha(lightColor), Projectile.rotation, new Vector2(texture.Width / 2f, texture.Height / 2f), Projectile.scale, SpriteEffects.None, 0); CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], lightColor, 1); return false; } diff --git a/Projectiles/Boss/ProfanedSpearNight.png b/Projectiles/Boss/ProfanedSpearNight.png new file mode 100644 index 0000000000000000000000000000000000000000..712ed5b89df3f3c726a3275468b1c0e75a890548 GIT binary patch literal 465 zcmV;?0WSWDP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0cJ@=K~z{r-IhUa zgD?<9X%E5*wr~M%!48SDAWpz7*l`Ok09#mbkv5+8N8zg@Q#C1O-ezLiLGjBUo44pB znx^@1wQbuUf5R{gGXE~4fO(q1s;Xqiec$h%2@_zRXQ^zC*Og@{^Y#rMH3uWix~{u* zNs{c=1#j@rxNby8I(Y2E8Dxu(*w3JLo^b{NvWR&tn|Q8WgXms>E@pFio_~M(VwxtY zK6Cg->>Je1KQ_l`COMn-3>HNpI~>Px_gxsh?OevcHOSeuYmkA_IF4nEOrjg>x_0Fb z%mFrtF|gmo$Q-ztkgA=F0H(B?2-q{InZuiMmSs}Au9FHlqZ)j^+B1mE0AvR{Pt(+u zJIk_2g^{D{fL(*!b=nOBU=H}Q2<#c;n*(gyCY25P%=);#L0{Kt=AOlM4I(?>Rfc>7 zZ}2eAC|msxu9rbR@n7AgKCWXB=FT?8gx|$yb>~q6HyA~q&9>&Au4kb^00000NkvXX Hu0mjfkgLlp literal 0 HcmV?d00001 diff --git a/Projectiles/Boss/ProvidenceHolyRay.cs b/Projectiles/Boss/ProvidenceHolyRay.cs index 0a5609302b..fff9c36e64 100644 --- a/Projectiles/Boss/ProvidenceHolyRay.cs +++ b/Projectiles/Boss/ProvidenceHolyRay.cs @@ -55,6 +55,16 @@ public override void AI() if (Main.npc[CalamityGlobalNPC.holyBoss].active) Projectile.maxPenetrate = (int)Main.npc[CalamityGlobalNPC.holyBoss].localAI[1]; } + else if (CalamityGlobalNPC.doughnutBoss != -1) + { + if (Main.npc[CalamityGlobalNPC.doughnutBoss].active) + { + if (Main.npc[CalamityGlobalNPC.doughnutBoss].Calamity().CurrentlyEnraged) + Projectile.maxPenetrate = (int)Providence.BossMode.Night; + else + Projectile.maxPenetrate = (int)Providence.BossMode.Day; + } + } else Projectile.maxPenetrate = (int)Providence.BossMode.Day; From 700380275d3973f1fc2e5733b4798ffa605f5709 Mon Sep 17 00:00:00 2001 From: Xyk Date: Sat, 25 May 2024 20:26:40 -0700 Subject: [PATCH 088/401] Hailstorm freeze reinstatement --- Localization/en-US/Mods.CalamityMod.Items.Ammo.hjson | 2 +- Projectiles/Ranged/HailstormBulletProj.cs | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Ammo.hjson b/Localization/en-US/Mods.CalamityMod.Items.Ammo.hjson index 35b9c32329..e582fd1bcc 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Ammo.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Ammo.hjson @@ -103,7 +103,7 @@ HailstormBullet: { ''' Bullets imbued with potent ice magic These bullets rapidly decelerate after being fired - Critical hits cause a flash freeze, dealing additional damage + Critical hits cause a flash freeze, dealing additional damage and freezing normal enemies ''' } diff --git a/Projectiles/Ranged/HailstormBulletProj.cs b/Projectiles/Ranged/HailstormBulletProj.cs index 9da488161b..ac240f4e5d 100644 --- a/Projectiles/Ranged/HailstormBulletProj.cs +++ b/Projectiles/Ranged/HailstormBulletProj.cs @@ -1,4 +1,5 @@ -using CalamityMod.Buffs.StatDebuffs; +using CalamityMod.Buffs.DamageOverTime; +using CalamityMod.Buffs.StatDebuffs; using CalamityMod.Particles; using Microsoft.Xna.Framework; using Terraria; @@ -71,12 +72,15 @@ public override void AI() public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { Player Owner = Main.player[Projectile.owner]; - target.AddBuff(BuffID.Frostburn, 120); + target.AddBuff(BuffID.Frostburn2, 120); if (hit.Crit) { SoundStyle crit = new("CalamityMod/Sounds/NPCHit/CryogenPhaseTransitionCrack"); SoundEngine.PlaySound(crit with { Volume = 0.35f, Pitch = 1f }, Projectile.Center); - target.AddBuff(BuffID.Frostburn2, 300); + + if (!target.boss) + target.AddBuff(ModContent.BuffType(), 120); + int points = 6; float radians = MathHelper.TwoPi / points; Vector2 spinningPoint = Vector2.Normalize(new Vector2(-1f, -1f)); From 468ac6f4a203aa44ba12dcc16085a9d351a84883 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 25 May 2024 23:31:06 -0400 Subject: [PATCH 089/401] Disabled the custom tile merging system again, because it was repeatedly causing the mod to crash with an out of memory exception --- Tiles/MergeableTile.cs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/Tiles/MergeableTile.cs b/Tiles/MergeableTile.cs index 9f5742457a..86d6438fc6 100644 --- a/Tiles/MergeableTile.cs +++ b/Tiles/MergeableTile.cs @@ -7,9 +7,12 @@ namespace CalamityMod.Tiles { internal static class MergeableTile { + // CIT 25MAY2024: This custom tile merging system was repeatedly crashing the mod with an out of memory exception. + // Because the person who made this system is no longer on the dev team, I am just going to disable it again. + private sealed class MergeableTileGlobalTile : GlobalTile { - public override void PostDraw(int i, int j, int type, SpriteBatch spriteBatch) + /*public override void PostDraw(int i, int j, int type, SpriteBatch spriteBatch) { TileFraming.DrawUniversalMergeFrames(i, j, GetOrCreateTileAdjacencies(type)); } @@ -20,38 +23,38 @@ public override bool TileFrame(int i, int j, int type, ref bool resetFrame, ref TileFraming.GetAdjacencyData(i, j, adjacency); return base.TileFrame(i, j, type, ref resetFrame, ref noBreak); - } + }*/ } private sealed class MergeableTileSystem : ModSystem { - public override void PostSetupContent() + /*public override void PostSetupContent() { // Tomat: @heartplusup, you can add vanilla merges like so: // RegisterUniversalMerge(TileID.Dirt, TileID.Stone, "CalamityMod/Tiles/Merges/StoneMerge"); - Already-merged tiles look weird; needs changes by someone else. // RegisterUniversalMerge(TileID.WoodBlock, TileID.Stone, "CalamityMod/Tiles/Merges/StoneMerge"); - } + }*/ } private static readonly Dictionary> tileAdjacencyMap = []; public static void RegisterUniversalMerge(this ModTile tile, int mergeType, string blendSheetPath) { - RegisterUniversalMerge(tile.Type, mergeType, blendSheetPath); + // RegisterUniversalMerge(tile.Type, mergeType, blendSheetPath); } public static void RegisterUniversalMerge(int tileId, int mergeType, string blendSheetPath) { - TileFraming.SetUpUniversalMerge(tileId, mergeType, blendSheetPath, out var data); - GetOrCreateTileAdjacencies(tileId).Add(data); + // TileFraming.SetUpUniversalMerge(tileId, mergeType, blendSheetPath, out var data); + // GetOrCreateTileAdjacencies(tileId).Add(data); } - private static List GetOrCreateTileAdjacencies(int tileId) + /*private static List GetOrCreateTileAdjacencies(int tileId) { - if (!tileAdjacencyMap.TryGetValue(tileId, out var adjacencies)) + /*if (!tileAdjacencyMap.TryGetValue(tileId, out var adjacencies)) tileAdjacencyMap[tileId] = adjacencies = []; return adjacencies; - } + }*/ } } From a5f1d7f49fc6a032bcf38f66dce8f41120341ea2 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 25 May 2024 23:31:55 -0400 Subject: [PATCH 090/401] Realm Ravager tooltip fix --- Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson index 5b6a9163a6..f12bbcfdce 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson @@ -994,7 +994,7 @@ RealmRavager: { DisplayName: Realm Ravager Tooltip: ''' - Shoots a burst of 3 to 4 bullets + Shoots a burst of 4 bullets Converts musket balls into explosive bullets ''' } From 3487f96417a4cbc2725513ce7ba50bfa3d2cbd4a Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Sat, 25 May 2024 23:29:23 -0700 Subject: [PATCH 091/401] yharon now counts as an organic enemy --- Utilities/NPCUtils.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Utilities/NPCUtils.cs b/Utilities/NPCUtils.cs index baad855704..719631c115 100644 --- a/Utilities/NPCUtils.cs +++ b/Utilities/NPCUtils.cs @@ -9,6 +9,7 @@ using CalamityMod.NPCs.OldDuke; using CalamityMod.NPCs.Providence; using CalamityMod.NPCs.SlimeGod; +using CalamityMod.NPCs.Yharon; using CalamityMod.Projectiles.Boss; using CalamityMod.World; using Microsoft.Xna.Framework; @@ -689,7 +690,7 @@ public static bool Organic(this NPC target) target.HitSound != SoundID.NPCHit34 && target.HitSound != SoundID.NPCHit36 && target.HitSound != SoundID.NPCHit42 && target.HitSound != SoundID.NPCHit49 && target.HitSound != SoundID.NPCHit52 && target.HitSound != SoundID.NPCHit53 && target.HitSound != SoundID.NPCHit54 && target.HitSound != null) || target.type == NPCType() || - target.type == NPCType()) + target.type == NPCType() || target.type == NPCType()) { return true; } From 8983684bcd1b8a690c586913a2b8b9448f312fc4 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Mon, 27 May 2024 09:24:16 -0500 Subject: [PATCH 092/401] Nerfed Mythril Armor set flare damage cap from 50 to 40 and damage mult from 0.4 to 0.3 (untested, but this should help balance it more). --- Items/VanillaArmorChanges/MythrilArmorSetChange.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Items/VanillaArmorChanges/MythrilArmorSetChange.cs b/Items/VanillaArmorChanges/MythrilArmorSetChange.cs index c92a58262a..772fad8a35 100644 --- a/Items/VanillaArmorChanges/MythrilArmorSetChange.cs +++ b/Items/VanillaArmorChanges/MythrilArmorSetChange.cs @@ -20,7 +20,7 @@ public class MythrilArmorSetChange : VanillaArmorChange public const int MaxManaBoost = 20; public const int FlareFrameSpawnDelay = 12; - public const int FlareDamageSoftcap = 50; + public const int FlareDamageSoftcap = 40; public override void UpdateSetBonusText(ref string setBonusText) { @@ -51,7 +51,7 @@ public static void OnHitEffects(NPC victim, int originalDamage, Player owner) // Reset the spawn delay. owner.Calamity().MythrilFlareSpawnCountdown = FlareFrameSpawnDelay; - int flareDamage = CalamityUtils.DamageSoftCap(originalDamage * 0.4, FlareDamageSoftcap); + int flareDamage = CalamityUtils.DamageSoftCap(originalDamage * 0.3, FlareDamageSoftcap); flareDamage = owner.ApplyArmorAccDamageBonusesTo(flareDamage); Vector2 flareSpawnPosition = victim.Center + Main.rand.NextVector2Circular(10f, 10f); From bd6447e294bfe5c7f498877e1620ad2a56ba60f8 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sun, 26 May 2024 13:06:47 -0400 Subject: [PATCH 093/401] Boss Rush no longer disables wiring --- Localization/en-US/Mods.CalamityMod.Items.SummonItems.hjson | 6 +----- Tiles/CalamityGlobalTile.cs | 5 ----- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/Localization/en-US/Mods.CalamityMod.Items.SummonItems.hjson b/Localization/en-US/Mods.CalamityMod.Items.SummonItems.hjson index ef8f23c883..9329498724 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.SummonItems.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.SummonItems.hjson @@ -305,11 +305,7 @@ Teratoma: { Terminus: { DisplayName: Terminus GFBName: Ogscule - Tooltip: - ''' - Activates Boss Rush Mode, using it again will deactivate Boss Rush Mode - During the Boss Rush, all wires and wired devices will be disabled - ''' + Tooltip: Activates Boss Rush Mode, using it again will deactivate Boss Rush Mode } YharonEgg: { diff --git a/Tiles/CalamityGlobalTile.cs b/Tiles/CalamityGlobalTile.cs index d3bdbfd406..bccfbf26c0 100644 --- a/Tiles/CalamityGlobalTile.cs +++ b/Tiles/CalamityGlobalTile.cs @@ -63,11 +63,6 @@ public override void SetStaticDefaults() Main.tileOreFinderPriority[TileID.LunarOre] = 900; } - public override bool PreHitWire(int i, int j, int type) - { - return !BossRushEvent.BossRushActive; - } - public override bool TileFrame(int i, int j, int type, ref bool resetFrame, ref bool noBreak) { // Custom plant framing From ac59d25180e3b0d7a913a5d181a1925465af58ab Mon Sep 17 00:00:00 2001 From: AquaSG Date: Sun, 26 May 2024 21:48:33 -0400 Subject: [PATCH 094/401] bordernado shader bleeding into other things fixed --- Projectiles/Boss/InfernadoRevenge.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Projectiles/Boss/InfernadoRevenge.cs b/Projectiles/Boss/InfernadoRevenge.cs index dfb8a4e429..bfc028fc5b 100644 --- a/Projectiles/Boss/InfernadoRevenge.cs +++ b/Projectiles/Boss/InfernadoRevenge.cs @@ -72,6 +72,8 @@ internal Color ColorFunction(float completionRatio) public override bool PreDraw(ref Color lightColor) { + Main.spriteBatch.EnterShaderRegion(); + GameShaders.Misc["CalamityMod:Bordernado"].UseSaturation(-0.2f); GameShaders.Misc["CalamityMod:Bordernado"].SetShaderTexture(ModContent.Request("Terraria/Images/Misc/Perlin")); Vector2[] drawPoints = new Vector2[5]; @@ -86,6 +88,8 @@ public override bool PreDraw(ref Color lightColor) drawPoints[drawPoints.Length - 1] = bottom; PrimitiveRenderer.RenderTrail(drawPoints, new((_) => Projectile.width * 0.5f + 16f, ColorFunction, shader: GameShaders.Misc["CalamityMod:Bordernado"]), 85); + Main.spriteBatch.ExitShaderRegion(); + Texture2D vortexTexture = ModContent.Request("CalamityMod/Projectiles/Boss/OldDukeVortex").Value; for (int i = 0; i < 110; i++) { From c3ba05bc8a4395c13f48cf8855959a6b3910e1d3 Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Mon, 27 May 2024 10:53:29 +0700 Subject: [PATCH 095/401] Melee reforge fixes Collateral: Light is no longer a T0 tool reforge --- Utilities/ItemUtils.cs | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/Utilities/ItemUtils.cs b/Utilities/ItemUtils.cs index 88bb34ef06..2a1911dd9e 100644 --- a/Utilities/ItemUtils.cs +++ b/Utilities/ItemUtils.cs @@ -136,7 +136,7 @@ int GetCalPrefix(string name) { // Terrarian (has its own special "Legendary" for marketing reasons) // Other items that want to use Legendary2 are also compatible - if (item.type == ItemID.Terrarian || PrefixLegacy.ItemSets.ItemsThatCanHaveLegendary2[item.type]) + if (PrefixLegacy.ItemSets.ItemsThatCanHaveLegendary2[item.type]) { int[][] terrarianReforgeTiers = new int[][] { @@ -148,26 +148,8 @@ int GetCalPrefix(string name) prefix = IteratePrefix(rand, terrarianReforgeTiers, currentPrefix); } - // Yoyos, Flails, Spears, etc. - // Spears actually work fine with Legendary, but vanilla doesn't give it to them, so we won't either. - // Rapiers, whips, and other specific vanilla weapons (ie. Zenith or Excalibur) are specifically excluded from this, so they get broadsword reforges despite not scaling with melee speed. - // - // 18FEB2024: Ozzatron: removed the (item.channel || item.noMelee) because vanilla lets Burning Sky get Legendary - // 12MAY2024: Shade: added item.useStyle != ItemUseStyleID.Shoot because vanilla lets Sahara Slicers and Death's Ascension get Legendary - else if (item.channel && item.useStyle != ItemUseStyleID.Rapier && !item.CountsAsClass() && !PrefixLegacy.ItemSets.SwordsHammersAxesPicks[item.type] && item.useStyle != ItemUseStyleID.Shoot) - { - int[][] meleeNoSpeedReforgeTiers = new int[][] - { - /* 0 */ new int[] { PrefixID.Keen, PrefixID.Forceful, PrefixID.Strong }, - /* 1 */ new int[] { PrefixID.Hurtful, PrefixID.Ruthless, PrefixID.Zealous }, - /* 2 */ new int[] { PrefixID.Superior, PrefixID.Demonic }, - /* 3 */ new int[] { PrefixID.Godly } - }; - prefix = IteratePrefix(rand, meleeNoSpeedReforgeTiers, currentPrefix); - } - - // All other melee weapons - else + // Swords, Whips, Tools, other items that support the Legendary modifier + else if (PrefixLegacy.ItemSets.SwordsHammersAxesPicks[item.type] || (item.ModItem != null && item.ModItem.MeleePrefix())) { int[][] meleeReforgeTiers = new int[][] { @@ -180,7 +162,7 @@ int GetCalPrefix(string name) }; int[][] toolReforgeTiers = new int[][] { - /* 0 */ new int[] { PrefixID.Keen, PrefixID.Nimble, PrefixID.Nasty, PrefixID.Heavy, PrefixID.Light, PrefixID.Forceful, PrefixID.Strong }, + /* 0 */ new int[] { PrefixID.Keen, PrefixID.Nimble, PrefixID.Nasty, PrefixID.Heavy, PrefixID.Forceful, PrefixID.Strong }, /* 1 */ new int[] { PrefixID.Hurtful, PrefixID.Ruthless, PrefixID.Zealous, PrefixID.Quick, PrefixID.Pointy, PrefixID.Bulky }, /* 2 */ new int[] { PrefixID.Murderous, PrefixID.Agile, PrefixID.Large, PrefixID.Dangerous, PrefixID.Sharp }, /* 3 */ new int[] { PrefixID.Massive, PrefixID.Unpleasant, PrefixID.Savage, PrefixID.Superior }, @@ -191,6 +173,20 @@ int GetCalPrefix(string name) var tierListToUse = (item.pick > 0 || item.axe > 0 || item.hammer > 0) ? toolReforgeTiers : meleeReforgeTiers; prefix = IteratePrefix(rand, tierListToUse, currentPrefix); } + + // Yoyos, Flails, Spears, etc. + // Spears actually work fine with Legendary, but vanilla doesn't give it to them, so we won't either. + else + { + int[][] meleeNoSpeedReforgeTiers = new int[][] + { + /* 0 */ new int[] { PrefixID.Keen, PrefixID.Forceful, PrefixID.Strong }, + /* 1 */ new int[] { PrefixID.Hurtful, PrefixID.Ruthless, PrefixID.Zealous }, + /* 2 */ new int[] { PrefixID.Superior, PrefixID.Demonic }, + /* 3 */ new int[] { PrefixID.Godly } + }; + prefix = IteratePrefix(rand, meleeNoSpeedReforgeTiers, currentPrefix); + } } // RANGED From 93c59a4d33774a7d0d0615aa52c4b85fa37942e5 Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Mon, 27 May 2024 11:33:45 +0700 Subject: [PATCH 096/401] flamethrower tweaks buffed gel efficiency on early ones (spark spreader stats net buffed accordingly to slower uses) fixed havocs breath fire not fading properly and use anim stopgap --- Items/Weapons/Ranged/HavocsBreath.cs | 1 + Items/Weapons/Ranged/Shadethrower.cs | 2 +- Items/Weapons/Ranged/SparkSpreader.cs | 6 ++++-- Projectiles/Ranged/BrimstoneFireFriendly.cs | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Items/Weapons/Ranged/HavocsBreath.cs b/Items/Weapons/Ranged/HavocsBreath.cs index efad9edd1e..fa23d2cd9b 100644 --- a/Items/Weapons/Ranged/HavocsBreath.cs +++ b/Items/Weapons/Ranged/HavocsBreath.cs @@ -20,6 +20,7 @@ public override void SetDefaults() Item.useTime = 5; Item.useAnimation = 35; Item.reuseDelay = 20; + Item.useLimitPerAnimation = 7; Item.useStyle = ItemUseStyleID.Shoot; Item.noMelee = true; Item.knockBack = 1.5f; diff --git a/Items/Weapons/Ranged/Shadethrower.cs b/Items/Weapons/Ranged/Shadethrower.cs index a212cfe9d1..ddb3786745 100644 --- a/Items/Weapons/Ranged/Shadethrower.cs +++ b/Items/Weapons/Ranged/Shadethrower.cs @@ -17,7 +17,7 @@ public override void SetDefaults() Item.damage = 23; Item.DamageType = DamageClass.Ranged; Item.useTime = 10; - Item.useAnimation = 30; + Item.useAnimation = 40; Item.useStyle = ItemUseStyleID.Shoot; Item.noMelee = true; Item.knockBack = 1.5f; diff --git a/Items/Weapons/Ranged/SparkSpreader.cs b/Items/Weapons/Ranged/SparkSpreader.cs index 8b292401c2..8ff1657262 100644 --- a/Items/Weapons/Ranged/SparkSpreader.cs +++ b/Items/Weapons/Ranged/SparkSpreader.cs @@ -13,12 +13,14 @@ public override void SetDefaults() { Item.width = 56; Item.height = 26; - Item.damage = 10; + Item.damage = 16; Item.knockBack = 1f; Item.DamageType = DamageClass.Ranged; Item.autoReuse = true; Item.useTime = 12; - Item.useAnimation = 36; + Item.useAnimation = 48; + Item.reuseDelay = 12; + Item.useLimitPerAnimation = 4; Item.useAmmo = AmmoID.Gel; Item.consumeAmmoOnFirstShotOnly = true; Item.shootSpeed = 6f; diff --git a/Projectiles/Ranged/BrimstoneFireFriendly.cs b/Projectiles/Ranged/BrimstoneFireFriendly.cs index 60828b0eef..e419809b56 100644 --- a/Projectiles/Ranged/BrimstoneFireFriendly.cs +++ b/Projectiles/Ranged/BrimstoneFireFriendly.cs @@ -15,7 +15,7 @@ public class BrimstoneFireFriendly : ModProjectile, ILocalizedModType public override string Texture => "CalamityMod/Projectiles/FireProj"; public static int Lifetime => 60; - public static int Fadetime => 80; + public static int Fadetime => 50; public ref float Time => ref Projectile.ai[0]; public int MistType = -1; From e1be94d5c4f1ca069d9a708eecaa44111c786f01 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Mon, 27 May 2024 01:05:58 -0400 Subject: [PATCH 097/401] Added even more missing HP/s life regen tooltips --- Items/CalamityGlobalItemTooltip.cs | 37 ++++++++++++++++++- .../Mods.CalamityMod.Items.Accessories.hjson | 32 ++++++++-------- ...CalamityMod.Items.Armor.PostMoonLord.hjson | 2 +- .../Mods.CalamityMod.Items.Fishing.hjson | 4 +- .../Mods.CalamityMod.Items.Potions.hjson | 5 ++- ...Mods.CalamityMod.Items.Weapons.Melee.hjson | 4 +- ...Mods.CalamityMod.Items.Weapons.Rogue.hjson | 2 +- ...ods.CalamityMod.Items.Weapons.Summon.hjson | 2 +- 8 files changed, 62 insertions(+), 26 deletions(-) diff --git a/Items/CalamityGlobalItemTooltip.cs b/Items/CalamityGlobalItemTooltip.cs index d2fa8e249d..3cff630860 100644 --- a/Items/CalamityGlobalItemTooltip.cs +++ b/Items/CalamityGlobalItemTooltip.cs @@ -292,6 +292,37 @@ void AddTooltip(string text) EditTooltipByNum(0, (line) => line.Text += "\nDemon Altars now drop Souls of Night instead of generating ores when destroyed" + "\nHardmode ores now generate after defeating Mechanical Bosses for the first time"); + // Exact life regen descriptions + bool isCampfire = item.type == ItemID.Campfire || item.type == ItemID.CursedCampfire || item.type == ItemID.DemonCampfire || item.type == ItemID.FrozenCampfire || item.type == ItemID.IchorCampfire || item.type == ItemID.RainbowCampfire || item.type == ItemID.UltraBrightCampfire || item.type == ItemID.BoneCampfire || item.type == ItemID.DesertCampfire || item.type == ItemID.CoralCampfire || item.type == ItemID.CorruptCampfire || item.type == ItemID.CrimsonCampfire || item.type == ItemID.HallowedCampfire || item.type == ItemID.JungleCampfire || item.type == ItemID.MushroomCampfire || item.type == ItemID.ShimmerCampfire; + if (isCampfire) + EditTooltipByNum(0, (line) => line.Text = "Life regen is increased by 0.5 HP/s when near a campfire"); + + if (item.type == ItemID.HeartLantern) + EditTooltipByNum(0, (line) => line.Text = "Grants +1 HP/s life regeneration when placed nearby"); + + if (item.type == ItemID.BottledHoney) + EditTooltipByNum(0, (line) => line.Text = "Grants +1 HP/s life regen for a short time" + + "\nGrants an additional +1 HP/s life regen while inflicted with a damaging debuff"); + + if (item.type == ItemID.ShinyStone) + EditTooltipByNum(0, (line) => line.Text = "Grants +2 HP/s life regen and accelerates natural life regen when not moving"); + + if (item.type == ItemID.BandofRegeneration) + EditTooltipByNum(0, (line) => line.Text = "Grants +1 HP/s life regeneration"); + + if (item.type == ItemID.CharmofMyths) + EditTooltipByNum(0, (line) => line.Text = "Grants +1 HP/s life regeneration and reduces the cooldown of healing potions by 25%"); + + if (item.type == ItemID.RegenerationPotion) + EditTooltipByNum(0, (line) => line.Text = "Provides +2 HP/s life regeneration"); + + if (item.type == ItemID.SoulDrain) + EditTooltipByNum(0, (line) => line.Text += "\nThis grants +1.5 HP/s life regen and accelerates natural life regen" + + "\nLife drain stacks based on the number of enemies being hit"); + + if (item.type == ItemID.HamBat) + EditTooltipByNum(1, (line) => line.Text = "Defeating enemies temporarily grants +3 HP/s life regen"); + // Warmth Potion provides debuff immunities if (item.type == ItemID.WarmthPotion) { @@ -900,8 +931,10 @@ void AddTooltip(string text) // DD2 armor tooltip edits #region DD2 Armor - // Reduce DD2 armor piece bonuses because they're overpowered + // Reduce DD2 armor piece bonuses because they're overpowered, and clarify life regen boosts // Squire armor + if (item.type == ItemID.SquireGreatHelm) + EditTooltipByNum(0, (line) => line.Text = "Increases your max number of sentries by 1 and grants +2 HP/s life regen"); if (item.type == ItemID.SquirePlating) EditTooltipByNum(0, (line) => line.Text = "10% increased minion and melee damage"); if (item.type == ItemID.SquireGreaves) @@ -931,7 +964,7 @@ void AddTooltip(string text) // Valhalla Knight armor if (item.type == ItemID.SquireAltShirt) - EditTooltipByNum(0, (line) => line.Text = "30% increased minion damage and increased life regeneration"); + EditTooltipByNum(0, (line) => line.Text = "30% increased minion damage and grants +4 HP/s life regen"); if (item.type == ItemID.SquireAltPants) EditTooltipByNum(0, (line) => line.Text = "10% increased minion damage and melee critical strike chance"); diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson index d0131bd3cc..a59c1a9563 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson @@ -138,8 +138,8 @@ AmbrosialAmpoule: { ''' +50 max life Grants +2 to +6 HP/s life regen based on missing health - Provides life regeneration equivalent to standing in Honey - Standing still grants extremely powerful regen + Grants +1 HP/s life regen and an additional 1 HP/s life regen when inflicted with a damage debuff + Standing still grants +1.5 HP/s life regen Halves how long you are afflicted with fire and sickness debuffs You emit yellow light if visibility is enabled ''' @@ -885,8 +885,9 @@ HallowedRune: { Tooltip: ''' Whenever your minions hit an enemy you will gain a random buff, does not stack with downgrades - These buffs will either boost your defense, summon damage, or life regen for a while - If you have the offensive boost, enemies hit by minions will sometimes be hit by stars + Hallowed Power increases summon damage by 10% and makes enemy hits from minions rain stars + Hallowed Defense increases defense by 8 and DR by 4% + Hallowed Regen grants +1.5 HP/s life regeneration ''' } @@ -935,8 +936,8 @@ HoneyDew: { Tooltip: ''' +30 max life - Provides life regeneration equivalent to standing in Honey - Standing still in Honey grants extremely powerful regen + Grants +1 HP/s life regen and an additional 1 HP/s life regen when inflicted with a damage debuff + Standing still in Honey grants +1.5 HP/s life regen Halves how long you are afflicted with sickness debuffs ''' } @@ -1023,8 +1024,8 @@ LivingDew: { Tooltip: ''' +50 max life - Provides life regeneration equivalent to standing in Honey - Standing still in Honey grants extremely powerful regen + Grants +1 HP/s life regen and an additional 1 HP/s life regen when inflicted with a damage debuff + Standing still in Honey grants +1.5 HP/s life regen Halves how long you are afflicted with fire and sickness debuffs ''' } @@ -1242,10 +1243,9 @@ PhantomicArtifact: { Tooltip: ''' Whenever your minions hit an enemy you will gain a random phantomic buff, does not stack with downgrades - These buffs will either boost your defense, summon damage, or life regen for a while - If you have the offensive boost, enemies hit by minions will sometimes be hit by phantomic knives - If you have the regenerative boost, a phantomic heart will occasionally materialise granting massive health regen - If you have the defensive boost, a phantomic bulwark will absorb 20% of the next projectile's damage that hits the bulwark, shattering it + Phantomic Empowerment increases summon damage by 10% and makes minion hits spawn phantomic knives + Phantomic Shield increases defense by 10 and DR by 5% and spawns a phantomic bulwark which absorbs 20% of the next projectile's damage that touches it + Phantomic Regen grants +2 HP/s life regen and spawns a phantomic heart which grants an additional 2 HP/s life regen when touched ''' } @@ -1332,8 +1332,8 @@ Radiance: { ''' +70 max life Grants +2 to +6 HP/s life regen based on missing health - Provides life regeneration equivalent to standing in Honey - Standing still grants extremely powerful regen + Grants +1 HP/s life regen and an additional 1 HP/s life regen when inflicted with a damage debuff + Standing still grants +2 HP/s life regen Grants 20 defense and continuous healing while afflicted with any debuff The healing eventually slows down if debuffed for an extended period of time Massively boosts natural life regen while afflicted with any debuff @@ -1586,7 +1586,9 @@ SpiritGlyph: { Tooltip: ''' Whenever your minions hit an enemy you will gain a random buff - These buffs will either boost your defense, summon damage, or life regen for a while + Spirit Power increases summon damage by 10% + Spirit Defense increases defense by 6 and DR by 3% + Spirit Regen grants +1 HP/s life regeneration ''' } diff --git a/Localization/en-US/Mods.CalamityMod.Items.Armor.PostMoonLord.hjson b/Localization/en-US/Mods.CalamityMod.Items.Armor.PostMoonLord.hjson index 06272e4042..f4e3ddf84b 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Armor.PostMoonLord.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Armor.PostMoonLord.hjson @@ -527,7 +527,7 @@ TarragonHeadMelee: { ''' 15% increased melee speed Enemies are more likely to target you - You gain a life regen buff when you take damage + Taking damage gives the Tarra Life buff, which grants +1.5 HP/s life regen Press {0} to cloak yourself in life energy that heavily reduces enemy contact damage for 10 seconds This has a 30 second cooldown ''' diff --git a/Localization/en-US/Mods.CalamityMod.Items.Fishing.hjson b/Localization/en-US/Mods.CalamityMod.Items.Fishing.hjson index 8e96193a93..433e0e4d83 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Fishing.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Fishing.hjson @@ -54,8 +54,8 @@ Bloodfin: { DisplayName: Bloodfin Tooltip: ''' - Grants a buff that boosts life regen for 10 seconds - The life regen boost is stronger if below 75% health + Grants a buff that grants +2.5 HP/s life regen + This buff directly restores HP if below 75% health 10 second duration 'The wonders of angiogenesis' ''' diff --git a/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson b/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson index 0c7a8a0250..94bfd6c74c 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson @@ -18,7 +18,7 @@ Baguette: { Tooltip: ''' {$CommonItemTooltip.MinorStats} - Boosts the effects of Red Wine + Red Wine heals 250 HP, but reduces life regen by 2 HP/s [c/FCE391:'je suis Monte'] ''' } @@ -104,7 +104,8 @@ PhotosynthesisPotion: { DisplayName: Photosynthesis Potion Tooltip: ''' - You regen life quickly while not moving, this effect is five times as strong during daytime + Grants +0.5 HP/s life regen and accelerates natural life regen while not moving + This natural life regen effect is five times as strong during daytime Dropped hearts heal more HP ''' } diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson index afeab0b76b..88b9e92839 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson @@ -287,7 +287,7 @@ CosmicDischarge: { Tooltip: ''' Striking an enemy with the whip causes glacial explosions and grants the player the cosmic freeze buff - This buff gives the player increased life regen while standing still and freezes enemies near the player + This buff gives the player +2 HP/s life regen while standing still and freezes enemies near the player ''' } @@ -707,7 +707,7 @@ Lacerator: { DisplayName: Lacerator Tooltip: ''' - Enemies that are hit by the yoyo will have their life drained + Accelerates natural life regeneration on hits with the yoyo An exceptionally agile yoyo [GFB] ''' diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Rogue.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Rogue.hjson index abd9755e31..69ed27ce98 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Rogue.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Rogue.hjson @@ -193,7 +193,7 @@ CorpusAvertor: { Attacks grant lifesteal based on damage dealt The lower your HP the more damage this weapon does and heals the player on enemy hits Stealth strikes throw a single rainbow outlined dagger - On enemy hits, this dagger boosts the damage and life regen of all members of your team + On enemy hits, this dagger grants 10% damage and +2 HP/s life regen to all members of your team However, there is a small chance it will cut your health in half instead 'Seems like it has worn down over time' ''' diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Summon.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Summon.hjson index 0b7073c368..2fa9a00315 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Summon.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Summon.hjson @@ -789,7 +789,7 @@ WulfrumController: { Summons a wulfrum droid to fight for you Hold right click while holding the remote to switch all of your drones into supercharge mode Supercharged droids will stop attacking and focus wulfrum energy onto you - The beam provides extra regeneration and defense + Supercharged droids provide +0.5 HP/s life regen and 3 defense per droid Can also be used to heal other players by keeping your mouse cursor close enough to them ''' } From 4c8204bf0c0f75c342164ffea55983973085c42a Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Mon, 27 May 2024 01:32:35 -0400 Subject: [PATCH 098/401] Altar of the Accursed outdated tooltip fix --- Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson | 1 - 1 file changed, 1 deletion(-) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson b/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson index c07939ffdc..ddb61fbc36 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson @@ -523,7 +523,6 @@ AltarOfTheAccursedItem: { ''' Offer Ashes of Calamity at this altar to summon the Witch Doing so will create a square arena of blocks, with the altar at its center - During the battle, heart pickups only heal for half as much The Witch enrages while you are outside of the arena {$CommonItemTooltip.SpecialCrafting} ''' From 5fd66762366f53971e57613e68427abe15e54822 Mon Sep 17 00:00:00 2001 From: Xyk Date: Mon, 27 May 2024 00:00:38 -0700 Subject: [PATCH 099/401] Old Dukes Scales Buff Recovery time reduced by half a second, stamina recovers faster and instead of requiring you to stand still for the stronger bonus, you can get it if you press no movement keys. --- Items/Accessories/OldDukeScales.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Items/Accessories/OldDukeScales.cs b/Items/Accessories/OldDukeScales.cs index 43a9746187..94816ec2a7 100644 --- a/Items/Accessories/OldDukeScales.cs +++ b/Items/Accessories/OldDukeScales.cs @@ -12,7 +12,7 @@ public class OldDukeScales : ModItem, ILocalizedModType { public new string LocalizationCategory => "Items.Accessories"; - public static int RecoverTime = 120; + public static int RecoverTime = 90; public static int DashFatigueIncrease = 240; public static int MaxFatigue = 1200; // This is also the time that it takes the player to recover from the loss of all stamina. @@ -128,8 +128,9 @@ public override void PostUpdateMiscEffects() RecoverTimer--; // If the player has recovered, start decreasing the fatigue. + bool PressingMoveKeys = Player.controlLeft || Player.controlRight || Player.controlDown || Player.controlJump; if (Fatigue > 0 && RecoverTimer <= 0) - Fatigue -= Player.StandingStill() ? 2 : 1; + Fatigue -= PressingMoveKeys ? 3 : 5; // The fatigue cannot go higher than the max. if (Fatigue >= OldDukeScales.MaxFatigue) From e7e4f48b230a1f0c9dbc34b9e1e26c8f0b494dda Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Mon, 27 May 2024 12:07:06 -0500 Subject: [PATCH 100/401] Fixed King Slime out of bounds errors. --- .../Bosses/KingSlimeAI.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs index 15bd1a8e83..3e40e48be0 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs @@ -975,6 +975,15 @@ public static void GetPlaceToTeleportTo(NPC npc) Vector2 randomDefault = Main.rand.NextBool() ? Vector2.UnitX : -Vector2.UnitX; Vector2 vectorAimedAheadOfTarget = Main.player[npc.target].Center + new Vector2((float)Math.Round(Main.player[npc.target].velocity.X), 0f).SafeNormalize(randomDefault) * distanceAhead; Point predictiveTeleportPoint = vectorAimedAheadOfTarget.ToTileCoordinates(); + if (predictiveTeleportPoint.X < 10) + predictiveTeleportPoint.X = 10; + if (predictiveTeleportPoint.X > Main.maxTilesX - 10) + predictiveTeleportPoint.X = Main.maxTilesX - 10; + if (predictiveTeleportPoint.Y < 10) + predictiveTeleportPoint.Y = 10; + if (predictiveTeleportPoint.Y > Main.maxTilesY - 10) + predictiveTeleportPoint.Y = Main.maxTilesY - 10; + int randomPredictiveTeleportOffset = 5; int teleportTries = 0; while (teleportTries < 100) @@ -998,10 +1007,22 @@ public static void GetPlaceToTeleportTo(NPC npc) break; } else + { predictiveTeleportPoint.X += predictiveTeleportPoint.X < 0f ? 1 : -1; + if (predictiveTeleportPoint.X < 10) + predictiveTeleportPoint.X = 10; + if (predictiveTeleportPoint.X > Main.maxTilesX - 10) + predictiveTeleportPoint.X = Main.maxTilesX - 10; + } } else + { predictiveTeleportPoint.X += predictiveTeleportPoint.X < 0f ? 1 : -1; + if (predictiveTeleportPoint.X < 10) + predictiveTeleportPoint.X = 10; + if (predictiveTeleportPoint.X > Main.maxTilesX - 10) + predictiveTeleportPoint.X = Main.maxTilesX - 10; + } } // Default teleport if the above conditions aren't met in 100 iterations From 71475b29559eb14af30efcaf2c74e7659ee5a10f Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Mon, 27 May 2024 11:57:01 -0400 Subject: [PATCH 101/401] 1 - Alch Flask now reduces Plague damage instead of granting full immunity 2 - Reduced several debuff damage reducing effects --- Buffs/DamageOverTime/Plague.cs | 9 ++++++--- CalPlayer/CalamityPlayerLifeRegen.cs | 2 +- CalPlayer/CalamityPlayerMiscEffects.cs | 10 ++++++---- Items/Accessories/AlchemicalFlask.cs | 1 - .../en-US/Mods.CalamityMod.Items.Accessories.hjson | 2 +- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Buffs/DamageOverTime/Plague.cs b/Buffs/DamageOverTime/Plague.cs index 747e25e7aa..f776337e36 100644 --- a/Buffs/DamageOverTime/Plague.cs +++ b/Buffs/DamageOverTime/Plague.cs @@ -36,15 +36,18 @@ internal static void DrawEffects(PlayerDrawSet drawInfo) float numberOfDusts = 2f; float rotFactor = 360f / numberOfDusts; + int particleAmt = Player.Calamity().alchFlask ? 1 : 2; + int dustSpawnAmt = Player.Calamity().alchFlask ? 4 : 7; if (Player.miscCounter % 4 == 0) { - for (int i = 0; i < 2; i++) + for (int i = 0; i < particleAmt; i++) { - DirectionalPulseRing pulse = new DirectionalPulseRing(Player.Calamity().RandomDebuffVisualSpot, Vector2.Zero, Main.rand.NextBool(3) ? Color.LimeGreen : Color.Green, new Vector2(1, 1), 0, Main.rand.NextFloat(0.07f, 0.18f), 0f, 20); + float pulseScale = Main.rand.NextFloat(Player.Calamity().alchFlask ? 0.04f : 0.07f, Player.Calamity().alchFlask ? 0.12f : 0.18f); + DirectionalPulseRing pulse = new DirectionalPulseRing(Player.Calamity().RandomDebuffVisualSpot, Vector2.Zero, Main.rand.NextBool(3) ? Color.LimeGreen : Color.Green, Vector2.One, 0, pulseScale, 0f, 20); GeneralParticleHandler.SpawnParticle(pulse); } - for (int i = 0; i < 7; i++) + for (int i = 0; i < dustSpawnAmt; i++) { int DustID = Main.rand.NextBool(30) ? 220 : 89; float rot = MathHelper.ToRadians(i * rotFactor); diff --git a/CalPlayer/CalamityPlayerLifeRegen.cs b/CalPlayer/CalamityPlayerLifeRegen.cs index 834104e3e4..b3a4716447 100644 --- a/CalPlayer/CalamityPlayerLifeRegen.cs +++ b/CalPlayer/CalamityPlayerLifeRegen.cs @@ -106,7 +106,7 @@ void ApplyDoTDebuff(bool hasDebuff, int negativeLifeRegenToApply, bool immuneCon ApplyDoTDebuff(vHex, 35); ApplyDoTDebuff(cDepth, 18, purity); ApplyDoTDebuff(astralInfection, 24, infectedJewel || purity); - ApplyDoTDebuff(pFlames, 30, purity); + ApplyDoTDebuff(pFlames, alchFlask ? 15 : 30, purity); ApplyDoTDebuff(cragsLava, 30); ApplyDoTDebuff(shadowflame, 30, purity); // Profaned Soul Crystal turns you into Providence, a God, and you take more damage from God Slayer Inferno diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index fc0de93d70..03434292cc 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -2918,15 +2918,17 @@ private void OtherBuffEffects() } if (wDeath && !purity) - Player.GetDamage() -= 0.25f; + Player.GetDamage() -= 0.2f; if (astralInfection && !(infectedJewel || purity)) - Player.GetDamage() -= 0.15f; + Player.GetDamage() -= 0.1f; if (pFlames && !purity) { - Player.blind = true; - Player.GetDamage() -= 0.15f; + if (!alchFlask) + Player.blind = true; + + Player.GetDamage() -= 0.1f; } if (aCrunch && !laudanum && !purity) diff --git a/Items/Accessories/AlchemicalFlask.cs b/Items/Accessories/AlchemicalFlask.cs index 909aa4106f..86d4aa1de4 100644 --- a/Items/Accessories/AlchemicalFlask.cs +++ b/Items/Accessories/AlchemicalFlask.cs @@ -23,7 +23,6 @@ public override void UpdateAccessory(Player player, bool hideVisual) { CalamityPlayer modPlayer = player.Calamity(); modPlayer.alchFlask = true; - player.buffImmune[ModContent.BuffType()] = true; } public override void AddRecipes() diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson index a59c1a9563..6da5c57dca 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson @@ -102,7 +102,7 @@ AlchemicalFlask: { DisplayName: Alchemical Flask Tooltip: ''' - All attacks inflict the Plague and grants immunity to the Plague + All attacks inflict the Plague and reduces damage taken from the Plague Projectiles spawn plague seekers on enemy hits ''' } From be1b3d8d8f625d5f96ee534a6f66206580bc9ac0 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Mon, 27 May 2024 12:02:20 -0400 Subject: [PATCH 102/401] Actually was gonna make it reduce to this --- CalPlayer/CalamityPlayerLifeRegen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CalPlayer/CalamityPlayerLifeRegen.cs b/CalPlayer/CalamityPlayerLifeRegen.cs index b3a4716447..97262ff6c1 100644 --- a/CalPlayer/CalamityPlayerLifeRegen.cs +++ b/CalPlayer/CalamityPlayerLifeRegen.cs @@ -106,7 +106,7 @@ void ApplyDoTDebuff(bool hasDebuff, int negativeLifeRegenToApply, bool immuneCon ApplyDoTDebuff(vHex, 35); ApplyDoTDebuff(cDepth, 18, purity); ApplyDoTDebuff(astralInfection, 24, infectedJewel || purity); - ApplyDoTDebuff(pFlames, alchFlask ? 15 : 30, purity); + ApplyDoTDebuff(pFlames, alchFlask ? 10 : 30, purity); ApplyDoTDebuff(cragsLava, 30); ApplyDoTDebuff(shadowflame, 30, purity); // Profaned Soul Crystal turns you into Providence, a God, and you take more damage from God Slayer Inferno From 353a51fa2afec669b4f82063639f4e0dc962e629 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Tue, 28 May 2024 08:11:56 -0500 Subject: [PATCH 103/401] Decreased Rev+ Queen Bee's acceleration during her regular stinger phase. --- NPCs/VanillaNPCAIOverrides/Bosses/QueenBeeAI.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/QueenBeeAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/QueenBeeAI.cs index e8bb17fb34..ab6a393d15 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/QueenBeeAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/QueenBeeAI.cs @@ -717,9 +717,9 @@ public static bool BuffedQueenBeeAI(NPC npc, Mod mod) // Get target location and shoot from ass float stingerAttackSpeed = 16f + enrageScale * 4f; - float stingerAttackAccel = phase6 ? 0.32f : 0.24f; + float stingerAttackAccel = phase6 ? 0.24f : 0.18f; if (enrageScale > 0f) - stingerAttackAccel = MathHelper.Lerp(phase6 ? 0.4f : 0.32f, phase6 ? 0.8f : 0.64f, enrageScale / maxEnrageScale); + stingerAttackAccel = MathHelper.Lerp(phase6 ? 0.3f : 0.24f, phase6 ? 0.6f : 0.48f, enrageScale / maxEnrageScale); if (masterMode) { From fa5e1996e81131aa05e433c067c7d2c1b41b1ba6 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Mon, 27 May 2024 13:30:58 -0400 Subject: [PATCH 104/401] Small Hallowed Rune tooltip wording change --- Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson index 6da5c57dca..3404dbabe0 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson @@ -885,7 +885,7 @@ HallowedRune: { Tooltip: ''' Whenever your minions hit an enemy you will gain a random buff, does not stack with downgrades - Hallowed Power increases summon damage by 10% and makes enemy hits from minions rain stars + Hallowed Power increases summon damage by 10% and makes minion hits rain stars Hallowed Defense increases defense by 8 and DR by 4% Hallowed Regen grants +1.5 HP/s life regeneration ''' From 0a15c0ec4e44492c37b379c918efb6ad0f910798 Mon Sep 17 00:00:00 2001 From: Storm2103 Date: Sun, 26 May 2024 00:24:02 -0600 Subject: [PATCH 105/401] NEEDS MORE TESTING: fixed that annoying mp cooldown error spam by moving ascendant insignia (error only triggered once (instead of several), it would be best if it doesnt happen at all) --- CalPlayer/CalamityPlayer.cs | 9 ++++++++ CalPlayer/CalamityPlayerMiscEffects.cs | 31 +++++++++++--------------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index c61fbf50db..553903583f 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -2699,6 +2699,15 @@ public override void ProcessTriggers(TriggersSet triggersSet) if (Player.dead) return; + if (ascendantInsignia && Main.myPlayer == Player.whoAmI && CalamityKeybinds.AscendantInsigniaHotKey.JustPressed && ascendantInsigniaCooldown <= 0) + { + var source = Player.GetSource_Accessory(FindAccessory(ModContent.ItemType())); + Projectile.NewProjectileDirect(source, Player.Center - Vector2.UnitY * 45f, Vector2.Zero, ModContent.ProjectileType(), 0, 0f); + SoundEngine.PlaySound(new SoundStyle("CalamityMod/Sounds/Item/AscendantActivate")); + ascendantInsigniaCooldown = 2400; + ascendantInsigniaBuffTime = 240; //4 seconds + } + //Only increment hotkey holdtime if not on ground, not mounted, not on rope, not hooked, not tongued, otherwise reset hold time to zero if (CalamityKeybinds.GravistarSabatonHotkey.Current && gSabaton && Main.myPlayer == Player.whoAmI && (Player.velocity.Y != Player.oldVelocity.Y) && !Player.pulley && !Player.mount.Active && Player.grappling[0] == -1 && !Player.tongued) { diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index 03434292cc..ba586732b5 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -1337,6 +1337,8 @@ private void MiscEffects() if (expiredCooldowns.Count > 0) SyncCooldownRemoval(Main.netMode == NetmodeID.Server, expiredCooldowns); + if (ascendantInsigniaCooldown > 0 && ascendantInsigniaBuffTime <= 0) + ascendantInsigniaCooldown--; if (DragonsBreathAudioCooldown > 0) DragonsBreathAudioCooldown--; if (DragonsBreathAudioCooldown2 > 0) @@ -2012,6 +2014,13 @@ private void MiscEffects() } // This section of code ensures set bonuses and accessories with cooldowns go on cooldown immediately if the armor or accessory is removed. + if (!ascendantInsignia && ascendantInsigniaBuffTime > 0) + { + ascendantInsigniaBuffTime = 0; + ascendantInsigniaCooldown = 2400; + Player.AddCooldown(AscendEffect.ID, 2400); + } + if (!brimflameSet && brimflameFrenzy) { brimflameFrenzy = false; @@ -3077,27 +3086,13 @@ private void OtherBuffEffects() } } - if (ascendantInsignia) + if (ascendantInsignia && ascendantInsigniaBuffTime > 0) { - if (CalamityKeybinds.AscendantInsigniaHotKey.JustPressed && ascendantInsigniaCooldown <= 0) - { - var source = Player.GetSource_Accessory(FindAccessory(ModContent.ItemType())); - Projectile.NewProjectileDirect(source, Player.Center - Vector2.UnitY * 45f, Vector2.Zero, ModContent.ProjectileType(), 0, 0f); - SoundEngine.PlaySound(new SoundStyle("CalamityMod/Sounds/Item/AscendantActivate")); - ascendantInsigniaCooldown = 2400; - ascendantInsigniaBuffTime = 240; //4 seconds - } - - if (ascendantInsigniaCooldown > 0 && ascendantInsigniaBuffTime <= 0) - ascendantInsigniaCooldown--; + ascendantTrail = true; + infiniteFlight = true; if (ascendantInsigniaBuffTime == 1) Player.AddCooldown(AscendEffect.ID, 2400); - if (ascendantInsigniaBuffTime > 0) - { - ascendantTrail = true; - infiniteFlight = true; - ascendantInsigniaBuffTime--; - } + ascendantInsigniaBuffTime--; } if (abyssalDivingSuit && !Player.IsUnderwater()) From 8bcb001176d9e4832075521778a1a0cdce743700 Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Sat, 25 May 2024 23:26:11 -0700 Subject: [PATCH 106/401] Added The Cauldron --- Gores/CauldronChunk.png | Bin 0 -> 292 bytes Items/Weapons/Magic/TheCauldron.cs | 71 +++++++++++ Items/Weapons/Magic/TheCauldron.png | Bin 0 -> 1169 bytes Items/Weapons/Magic/TheCauldronGlow.png | Bin 0 -> 372 bytes ...Mods.CalamityMod.Items.Weapons.Magic.hjson | 10 ++ .../Mods.CalamityMod.Projectiles.Magic.hjson | 2 + Projectiles/Magic/CauldronProj.cs | 113 ++++++++++++++++++ Projectiles/Magic/CauldronProjSmall.cs | 91 ++++++++++++++ Projectiles/Magic/CauldronProjSmall.png | Bin 0 -> 606 bytes Projectiles/Magic/CauldronProjSmallGlow.png | Bin 0 -> 280 bytes 10 files changed, 287 insertions(+) create mode 100644 Gores/CauldronChunk.png create mode 100644 Items/Weapons/Magic/TheCauldron.cs create mode 100644 Items/Weapons/Magic/TheCauldron.png create mode 100644 Items/Weapons/Magic/TheCauldronGlow.png create mode 100644 Projectiles/Magic/CauldronProj.cs create mode 100644 Projectiles/Magic/CauldronProjSmall.cs create mode 100644 Projectiles/Magic/CauldronProjSmall.png create mode 100644 Projectiles/Magic/CauldronProjSmallGlow.png diff --git a/Gores/CauldronChunk.png b/Gores/CauldronChunk.png new file mode 100644 index 0000000000000000000000000000000000000000..feac67f62f0f5bc49c7cd87670ac1b875eefbc38 GIT binary patch literal 292 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xa#^NA%Cx&(BWL^R}M?75|Lo_C? zowT0oP=Ls>df|%-&7B60-3Jp)q3E%KjfUWzG+%b298R9ILn>-V>jbx-)djD~z zGnY@wse5{_cz^Xd{(aTFQJ^q7ta_T~TWei1L{R56X=#;&a "Items.Weapons.Magic"; + public static Asset Glow; + public override void SetStaticDefaults() + { + if (!Main.dedServ) + { + Glow = ModContent.Request(Texture + "Glow"); + } + } + public override void SetDefaults() + { + Item.width = 46; + Item.height = 46; + Item.damage = 64; + Item.noMelee = true; + Item.noUseGraphic = true; + Item.useStyle = ItemUseStyleID.Swing; + Item.useAnimation = 46; + Item.useTime = 46; + Item.knockBack = 8f; + Item.mana = 18; + Item.UseSound = SoundID.DD2_MonkStaffSwing; + Item.autoReuse = true; + Item.value = CalamityGlobalItem.RarityOrangeBuyPrice; + Item.rare = ItemRarityID.Orange; + Item.shoot = ModContent.ProjectileType(); + Item.shootSpeed = 12f; + Item.DamageType = DamageClass.Magic; + Item.Calamity().donorItem = true; + } + + // Reduce mana cost while in lava or the underworld + public override void ModifyManaCost(Player player, ref float reduce, ref float mult) + { + if (player.lavaWet || player.ZoneUnderworldHeight) + { + mult = manaReductionMult; + } + } + public override void PostDrawInWorld(SpriteBatch spriteBatch, Color lightColor, Color alphaColor, float rotation, float scale, int whoAmI) + { + Item.DrawItemGlowmaskSingleFrame(spriteBatch, rotation, Glow.Value); + } + + public override void AddRecipes() + { + CreateRecipe() + .AddIngredient(ItemID.LavaBucket, 1) + .AddIngredient(ItemID.HellstoneBar, 8) + .AddIngredient(ItemID.Obsidian, 20) + .AddIngredient(ItemID.AshBlock, 20) + .AddTile(TileID.Anvils) + .Register(); + } + } +} diff --git a/Items/Weapons/Magic/TheCauldron.png b/Items/Weapons/Magic/TheCauldron.png new file mode 100644 index 0000000000000000000000000000000000000000..475a7260203f7798243962f33ed777de9665bd39 GIT binary patch literal 1169 zcmV;C1aA9@P)Px(F-b&0RA_;zIkVI4)?;K zjpk0@&2WD1Irl#2yYF}Ip@jcPt)*odfR;6P2DYF4BVMwa@k(#PJ^e3Q)l;rU9ori- z0CSf|ocgn`uXD=D-f93o|K%^I{-yZvviElD5*OKxvE_$)cdh*%{B|y|{he3-1eUHq z82MX=co^ZvS|i1lW&q|A6963g{R#k8?Nb1J{NWt{9G@6_56lM066x+FaXE*1kdyMod(?+gI1zIQtS{qr`CpIPNLeykTC@i6ze zG`r}Oo7cI|UfZw@fLP5&r(VRRV=r5*$Dh6*fafYsIqf3<=A$tn?@C&s$P!=TDle4R zWdNpEAl+7@c8l%Ayp>}qi&Z~A%4MWfj}ffPmbHgb=JYeH>NRp?iRZA2^b_mL0XVxh z1wie@v~$7ijx7LGRo6K6zMo6aj+&4AE+hG|@2`wcUhWfF;-Q)I$YzVVx3a|FXxR$D z(O7k0|M-F}-i}K5T{z#i9e~&hH*&Q3J0Ks+&rjQU=`7*gc#8|s_VF@5ww2M8sUEDn z%emmdoW-)pFZNvk;IX!yffFQ0F9Ug(k-sap$A_{pZJWv*X{q9YdH@C|Zdk=w9EdV; z{jvML+nffGm-d};W4pfpLO~PA-x1lND}nvmKdl0wx}u4Dcxil@$@EpmQ7u2fc)-Fsyltr zDW7~Xz3c=74{ZpnPfjHO_$lSGD|+HfVmy}_-?pE_JzoR)nDNs8NlV2`+?T%sh3elD_7z#;e*?)Sp)$Pxb1eV>01jnX jNoGw=04e|g00;m8000000Mb*F00000NkvXXu0mjf66HpI literal 0 HcmV?d00001 diff --git a/Items/Weapons/Magic/TheCauldronGlow.png b/Items/Weapons/Magic/TheCauldronGlow.png new file mode 100644 index 0000000000000000000000000000000000000000..04cb3a66a507f9ab6831bda0c6972b4d3d4f80b0 GIT binary patch literal 372 zcmeAS@N?(olHy`uVBq!ia0vp^dLYcf3?viMZ?gg^#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lf+U3kd_r757YjVKQkX3!`)9N2vtPbI;d_m0H-QveNswRge-L2Uyno4lpa^Gy zM`SSr1K(i~W;~w1A_XXT)6>N<#KZgS6mOvx1s>MsgTLb|Gvs-EI>SCj`s6p<(DVp+ zE0eT5uT!AUg)ird^Mw^tY_4BO_TWFb#^YV;KKJY2-c`;_>ss@AYvJ+4`_HY;?Yj3! zZgJX_eZl;k#6?y&P|%SsBP1_{ku-h z(ep64JhAH2D!-Xi{(L#K_C=PQ`>XARzT*D!ifdly|Cv}fPyUyJvgWx95j%jMWbkzL Kb6Mw<&;$U8sGLXu literal 0 HcmV?d00001 diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Magic.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Magic.hjson index 7c20016cf2..9960bc50ca 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Magic.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Magic.hjson @@ -792,6 +792,16 @@ Teslastaff: { ''' } +TheCauldron: { + DisplayName: The Cauldron + Tooltip: + ''' + Launches lava bombs which explode into more lava bombs + 80% reduced mana usage while submerged in lava or while in the underworld + 'Believe it or not, its original wielder was only a few centimeters tall!' + ''' +} + TheDanceofLight: { DisplayName: The Dance of Light Tooltip: diff --git a/Localization/en-US/Mods.CalamityMod.Projectiles.Magic.hjson b/Localization/en-US/Mods.CalamityMod.Projectiles.Magic.hjson index 6510a1aba6..89edecb071 100644 --- a/Localization/en-US/Mods.CalamityMod.Projectiles.Magic.hjson +++ b/Localization/en-US/Mods.CalamityMod.Projectiles.Magic.hjson @@ -41,6 +41,8 @@ BrimstoneFireball.DisplayName: Brimstone Fireball BrimstoneHellfireballFriendly.DisplayName: Hellfireball BrimstoneHomer.DisplayName: Brimstone Homer BrimstoneTentacle.DisplayName: Brimstone Tentacle +CauldronProj.DisplayName: Cauldron +CauldronProjSmall.DisplayName: Smauldron ChronoIcicleLarge.DisplayName: Chrono Icicle ChronoIcicleSmall.DisplayName: Chrono Icicle ChronomancersScytheHoldout.DisplayName: Chronomancer's Scythe diff --git a/Projectiles/Magic/CauldronProj.cs b/Projectiles/Magic/CauldronProj.cs new file mode 100644 index 0000000000..24d2aee01e --- /dev/null +++ b/Projectiles/Magic/CauldronProj.cs @@ -0,0 +1,113 @@ +using System; +using CalamityMod.Items.Weapons.Magic; +using CalamityMod.Items.Weapons.Rogue; +using CalamityMod.Particles; +using CalamityMod.Projectiles.Rogue; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ReLogic.Content; +using Terraria; +using Terraria.Audio; +using Terraria.GameContent; +using Terraria.ID; +using Terraria.ModLoader; + +namespace CalamityMod.Projectiles.Magic +{ + public class CauldronProj : ModProjectile, ILocalizedModType + { + public new string LocalizationCategory => "Projectiles.Magic"; + public override string Texture => "CalamityMod/Items/Weapons/Magic/TheCauldron"; + public override void SetStaticDefaults() + { + ProjectileID.Sets.TrailCacheLength[Projectile.type] = 5; + ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + } + + public override void SetDefaults() + { + Projectile.width = 46; + Projectile.height = 46; + Projectile.friendly = true; + Projectile.tileCollide = false; + Projectile.penetrate = 1; + Projectile.timeLeft = 180; + Projectile.DamageType = DamageClass.Magic; + } + public override void AI() + { + Projectile.ai[0] += 1f; + if (Projectile.ai[0] > 10f) + { + Projectile.ai[0] = 10f; + if (Projectile.velocity.Y == 0f && Projectile.velocity.X != 0f) + { + Projectile.velocity.X = Projectile.velocity.X * 0.97f; + if (Projectile.velocity.X > -0.01f && Projectile.velocity.X < 0.01f) + { + Projectile.velocity.X = 0f; + Projectile.netUpdate = true; + } + } + Projectile.velocity.Y += 0.4f; + } + Projectile.ai[1] += 1f; + if (Projectile.ai[1] > 3) + { + Projectile.tileCollide = true; + } + Projectile.rotation += Projectile.velocity.X * 0.05f; + int dust = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.Torch, Scale: Main.rand.NextFloat(1f, 1.4f)); + Main.dust[dust].noGravity = true; + Main.dust[dust].velocity *= 0f; + } + public override void OnKill(int timeLeft) + { + SoundEngine.PlaySound(SoundID.Item89, Projectile.Center); + SoundEngine.PlaySound(SoundID.Item14, Projectile.Center); + Projectile.ExpandHitboxBy(128); + Projectile.maxPenetrate = -1; + Projectile.penetrate = -1; + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 10; + Projectile.Damage(); + if (Projectile.owner == Main.myPlayer) + { + for (int i = 0; i < 3; i++) + { + Vector2 smauldronSpeed = (Vector2.UnitY * Main.rand.NextFloat(-10f, -8f)).RotatedByRandom(MathHelper.ToRadians(30f)); + Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, smauldronSpeed, ModContent.ProjectileType(), Projectile.damage, 3f, Projectile.owner); + } + } + for (int i = 0; i < 40; i++) + { + int size = 20; + Vector2 position = Projectile.Center; + Vector2 velocity = Main.rand.NextVector2Circular(size, size); + SquishyLightParticle energy = new(position, velocity, Main.rand.NextFloat(0.3f, 0.4f), Color.Orange, Main.rand.Next(6, 9), 1, 1.5f); + GeneralParticleHandler.SpawnParticle(energy); + Dust dust = Dust.NewDustPerfect(position, DustID.Torch, velocity, 0, default, Main.rand.NextFloat(1.6f, 3.1f)); + dust.noGravity = true; + if (Main.rand.NextBool(13)) + { + if (Main.netMode != NetmodeID.Server) + { + int rocc = Gore.NewGore(Projectile.GetSource_Death(), Projectile.Center, Main.rand.NextVector2Circular(6, 6), Mod.Find("CauldronChunk").Type); + Main.gore[rocc].timeLeft /= 10; + } + } + } + } + + public override bool PreDraw(ref Color lightColor) + { + CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], lightColor, 2); + Vector2 origin = TheCauldron.Glow.Value.Size() / 2f; + Main.EntitySpriteDraw(TheCauldron.Glow.Value, Projectile.Center - Main.screenPosition, null, Color.White, Projectile.rotation, origin, Projectile.scale, SpriteEffects.None, 0); + return false; + } + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) => target.AddBuff(BuffID.OnFire3, 180); + + public override void OnHitPlayer(Player target, Player.HurtInfo info) => target.AddBuff(BuffID.OnFire3, 180); + } +} diff --git a/Projectiles/Magic/CauldronProjSmall.cs b/Projectiles/Magic/CauldronProjSmall.cs new file mode 100644 index 0000000000..10d894c385 --- /dev/null +++ b/Projectiles/Magic/CauldronProjSmall.cs @@ -0,0 +1,91 @@ +using System; +using CalamityMod.Particles; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ReLogic.Content; +using Terraria; +using Terraria.Audio; +using Terraria.GameContent; +using Terraria.ID; +using Terraria.ModLoader; + +namespace CalamityMod.Projectiles.Magic +{ + public class CauldronProjSmall : ModProjectile, ILocalizedModType + { + public new string LocalizationCategory => "Projectiles.Magic"; + + public static Asset Glow; + public override void SetStaticDefaults() + { + ProjectileID.Sets.TrailCacheLength[Projectile.type] = 5; + ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + if (!Main.dedServ) + { + Glow = ModContent.Request(Texture + "Glow"); + } + } + + public override void SetDefaults() + { + Projectile.width = 28; + Projectile.height = 28; + Projectile.friendly = true; + Projectile.penetrate = 1; + Projectile.timeLeft = 120; + Projectile.DamageType = DamageClass.Magic; + } + public override void AI() + { + Projectile.ai[0] += 1f; + if (Projectile.ai[0] > 10f) + { + Projectile.ai[0] = 10f; + if (Projectile.velocity.Y == 0f && Projectile.velocity.X != 0f) + { + Projectile.velocity.X = Projectile.velocity.X * 0.97f; + if (Projectile.velocity.X > -0.01f && Projectile.velocity.X < 0.01f) + { + Projectile.velocity.X = 0f; + Projectile.netUpdate = true; + } + } + Projectile.velocity.Y += 0.3f; + } + Projectile.rotation += Projectile.velocity.X * 0.05f; + int dust = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.Torch, Scale: Main.rand.NextFloat(0.6f, 0.8f)); + Main.dust[dust].noGravity = true; + Main.dust[dust].velocity *= 0f; + } + public override void OnKill(int timeLeft) + { + SoundEngine.PlaySound(SoundID.Item14, Projectile.Center); + Projectile.ExpandHitboxBy(46); + Projectile.maxPenetrate = -1; + Projectile.penetrate = -1; + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 10; + Projectile.Damage(); + for (int i = 0; i < 10; i++) + { + int size = 10; + Vector2 position = Projectile.Center; + Vector2 velocity = Main.rand.NextVector2Circular(size, size); + SquishyLightParticle energy = new(position, velocity, Main.rand.NextFloat(0.1f, 0.2f), Color.Orange, Main.rand.Next(5, 8), 1, 1.5f); + GeneralParticleHandler.SpawnParticle(energy); + Dust dust = Dust.NewDustPerfect(position, DustID.Torch, velocity, 0, default, Main.rand.NextFloat(0.8f, 1.2f)); + dust.noGravity = true; + } + } + public override bool PreDraw(ref Color lightColor) + { + CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], lightColor, 2); + Vector2 origin = Glow.Value.Size() / 2f; + Main.EntitySpriteDraw(Glow.Value, Projectile.Center - Main.screenPosition, null, Color.White, Projectile.rotation, origin, Projectile.scale, SpriteEffects.None, 0); + return false; + } + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) => target.AddBuff(BuffID.OnFire3, 180); + + public override void OnHitPlayer(Player target, Player.HurtInfo info) => target.AddBuff(BuffID.OnFire3, 180); + } +} diff --git a/Projectiles/Magic/CauldronProjSmall.png b/Projectiles/Magic/CauldronProjSmall.png new file mode 100644 index 0000000000000000000000000000000000000000..f50600398ab5d352e6121dd8c7836a2c964b6e2b GIT binary patch literal 606 zcmV-k0-^nhP)Px${z*hZR7i=(_(PBH$PbaC#t*S$02Y~sDXoA>U0_uO|s_ndp~>7k3} z2Fe##eP1s6?eBa0Jy(tI?e@cet-i2hV(hL*RQd56fCpm(08BkT1mNR`8vyh+&jDD8 zWoA3_v}Ub0Cq8lNgn#}nvSL05z<9yPhKeQ6;8kU(?L;D$zHFZWuwFj}64LB_D6(!U zJh|z$r#Ju-Qu%!S)2TNueZtUp;1eFzVgR1yY%@gGcxy!S@2&$dR2;SOO@DkPx(2|U zi{9*g7)Ir6y$-=gaDj`7(P#Zr}6UTWdf<)={!^ zq@9#LVf^#hz2@zq6}lBGcNUg5Jwrw5(Z&jpMCD=>0T7?LB$o5cGRUPPx9ohB290pC zWGhp&RiFO?5+6n{-nX4d8D_!V9$O8crFPr|{)Z^ly*5egdMs0voevwXS44~BkE|nd zzIW$OIXNUvpD?LGd|xW+6pc~~Ss)RKP`>-T{Vn7BP&G)U>28Z*dx%KqQPTNql`$w5 zl5_s|*A&%KLxy$e>YaRB!`H+8KvKI%)trCBhjnW9grSs)I!V5l!a6im>V%g=VydI< sTy`Y@000hUSV?A0O#mtY000O800000007cclK=n!07*qoM6N<$f=`DQ5dZ)H literal 0 HcmV?d00001 diff --git a/Projectiles/Magic/CauldronProjSmallGlow.png b/Projectiles/Magic/CauldronProjSmallGlow.png new file mode 100644 index 0000000000000000000000000000000000000000..41b88520128195eaabd1fa55bc630c302438a4ef GIT binary patch literal 280 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s3?yAI>n{URjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij?1AIbU6WPTkh{)_VSN>cq@Mp8?vtPbInXAc9HUla4k|4j}|6sr%<<0B{ z6yhxKh%9Dc;5!V$jK}j=qyPmgJzX3_Ed1wA^5$bzG;zuyoBsf;Zb$EInVn;fr4S>UGzhO1^(ni~lij`|)Wud-m}H P9l_w~>gTe~DWM4f>O^G- literal 0 HcmV?d00001 From 6816532aae3ffb55a3d7ecabc9da4bc58c3545c1 Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Sun, 26 May 2024 20:18:38 -0700 Subject: [PATCH 107/401] sound updates --- Projectiles/Magic/CauldronProj.cs | 3 +-- Projectiles/Magic/CauldronProjSmall.cs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Projectiles/Magic/CauldronProj.cs b/Projectiles/Magic/CauldronProj.cs index 24d2aee01e..45b420369b 100644 --- a/Projectiles/Magic/CauldronProj.cs +++ b/Projectiles/Magic/CauldronProj.cs @@ -63,8 +63,7 @@ public override void AI() } public override void OnKill(int timeLeft) { - SoundEngine.PlaySound(SoundID.Item89, Projectile.Center); - SoundEngine.PlaySound(SoundID.Item14, Projectile.Center); + SoundEngine.PlaySound(SoundID.DD2_ExplosiveTrapExplode, Projectile.Center); Projectile.ExpandHitboxBy(128); Projectile.maxPenetrate = -1; Projectile.penetrate = -1; diff --git a/Projectiles/Magic/CauldronProjSmall.cs b/Projectiles/Magic/CauldronProjSmall.cs index 10d894c385..ddfc180708 100644 --- a/Projectiles/Magic/CauldronProjSmall.cs +++ b/Projectiles/Magic/CauldronProjSmall.cs @@ -59,7 +59,7 @@ public override void AI() } public override void OnKill(int timeLeft) { - SoundEngine.PlaySound(SoundID.Item14, Projectile.Center); + SoundEngine.PlaySound(SoundID.DD2_ExplosiveTrapExplode with { Pitch = 0.8f, Volume = 0.6f }, Projectile.Center); Projectile.ExpandHitboxBy(46); Projectile.maxPenetrate = -1; Projectile.penetrate = -1; From 8bc0596000fb3f48617bb0a32200946c2135b74d Mon Sep 17 00:00:00 2001 From: Xyk Date: Mon, 6 May 2024 22:07:25 -0700 Subject: [PATCH 108/401] Respiteblock --- Items/Weapons/Melee/Respiteblock.cs | 63 ++++++ Items/Weapons/Melee/Respiteblock.png | Bin 0 -> 1648 bytes ...Mods.CalamityMod.Items.Weapons.Melee.hjson | 10 + .../Mods.CalamityMod.Projectiles.Melee.hjson | 2 + Projectiles/Melee/RespiteblockBlood.cs | 78 +++++++ Projectiles/Melee/RespiteblockHoldout.cs | 202 ++++++++++++++++++ Projectiles/Melee/RespiteblockHoldout.png | Bin 0 -> 2534 bytes 7 files changed, 355 insertions(+) create mode 100644 Items/Weapons/Melee/Respiteblock.cs create mode 100644 Items/Weapons/Melee/Respiteblock.png create mode 100644 Projectiles/Melee/RespiteblockBlood.cs create mode 100644 Projectiles/Melee/RespiteblockHoldout.cs create mode 100644 Projectiles/Melee/RespiteblockHoldout.png diff --git a/Items/Weapons/Melee/Respiteblock.cs b/Items/Weapons/Melee/Respiteblock.cs new file mode 100644 index 0000000000..673badb103 --- /dev/null +++ b/Items/Weapons/Melee/Respiteblock.cs @@ -0,0 +1,63 @@ +using CalamityMod.Items.Accessories; +using CalamityMod.Items.Materials; +using CalamityMod.Items.Weapons.Magic; +using CalamityMod.Projectiles.Melee; +using CalamityMod.Rarities; +using CalamityMod.Tiles.Furniture.CraftingStations; +using Microsoft.Xna.Framework; +using Terraria; +using Terraria.DataStructures; +using Terraria.ID; +using Terraria.ModLoader; + +namespace CalamityMod.Items.Weapons.Melee +{ + public class Respiteblock : ModItem, ILocalizedModType + { + public new string LocalizationCategory => "Items.Weapons.Melee"; + + public override void SetDefaults() + { + Item.width = 108; + Item.height = 40; + Item.damage = 70; + Item.knockBack = 9f; + Item.useTime = 4; + Item.useAnimation = 20; + // In-game, the displayed axe power is 5x the value set here. + // This corrects for trees having 500% hardness internally. + // So that the axe power in the code looks like the axe power you see on screen, divide by 5. + Item.axe = 612 / 5; // Apparently 612 is a homestuck reference + // The axe power is entirely for show. It instantly one shots trees. + + Item.DamageType = DamageClass.Melee; + Item.noMelee = true; + Item.noUseGraphic = true; + Item.channel = true; + Item.useStyle = ItemUseStyleID.Shoot; + Item.autoReuse = false; + Item.shoot = ModContent.ProjectileType(); + Item.shootSpeed = 1f; + + Item.rare = ModContent.RarityType(); + Item.value = CalamityGlobalItem.RarityVioletBuyPrice; + Item.Calamity().donorItem = true; + } + public override bool CanUseItem(Player player) => player.ownedProjectileCounts[Item.shoot] <= 0; + + public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) + { + Projectile.NewProjectile(source, position, velocity, type, damage, knockback, player.whoAmI, 0f, 0f); + return false; + } + public override void AddRecipes() + { + CreateRecipe(). + AddIngredient(ItemID.ButchersChainsaw). + AddIngredient(ItemID.FragmentSolar, 4). // 413 is also a homestuck referene I think... + AddIngredient(13). + AddTile(TileID.LunarCraftingStation). + Register(); + } + } +} diff --git a/Items/Weapons/Melee/Respiteblock.png b/Items/Weapons/Melee/Respiteblock.png new file mode 100644 index 0000000000000000000000000000000000000000..9999a6134265753398bd6549d0856e9cff9b5723 GIT binary patch literal 1648 zcmV-$29NoPP)Px*5J^NqRCt{2n_p;^WgN#pr^ZZWc>FV*Hod5JA!mP@$-spYWoB_O`X{d4)Rlu0 z3ByS6s#s2n61zASQk0?)DbxW=jYMqW0*9L-G-|1HPL}h?YBQa@T|DQzL*n_*Dw2-iXDR6|%94rAK*7Yy|g}sviC~h&Xt&_bIbFkZ_kg$L$aD+*b z73}~VKREzEF-s=$IJZq9VFA+}Ls)HXt(9LjH#d(M?G^sG2!QLyj+u_TIyTHGBrIT> zFv47-wrtsAjjvw4+5_n7>dMK^Gea8yI2UOG;B@NXEjZAZ;zyA~QAz=Yi-Y8K-R99D9R}n(mg3q2k z3uL0Y($Z3kELprCQIbf?r@p>E0Cw;O0H;%?@=;f3qDA>aNhGXU_?C5UmmraqZ(ik` zs(SkQbWQ5rYyolihM{s9=HDD+qP}< zz@NCLrY6f`M3!sul1o%wU7dB`v}w}-Xm4*%&oI}Dc_Wjkb=-Y+^co`9Ec_6F)2V~j zc^BOKA^=BD{Fa_)lXi9JF9511y<)AmuEwmlwZ+Wqe&i=0LzXo2gG&tp1LU4geY(8*`pt#D#!Uz~Fa=sL3miC9!j z{ne@iR@)^mBrKrv&BNrgMyq^2WN!B=0G_T|3_vt`-5Ou^@eKgJ{N(o$*BPyElx4ak zFIs=eYEL<2YLmmht;$|!U|EY9Kl-R?r+qdttrN?+f6O!e2O{rV{mZ>K%?~EMW$oIv z5rCI4d7VfrD=P!w*BK{(OuiNp7BCgacgfc%|7mM$`(HNDdOu$@-~AYaVRq^vAX7;Z zSv^0PFZa%vxlehaND*QC_ZuIvdGlrMA7!npR6{xzNOeU@GPLUvjWchx+O%^PlB_c(bd!O5O=c(FlNuoDCV?sM~6(eD=5SBJ^Ox_ELS060n>0E=8`5$ zm&NAuJuZo^TuXO-jN9)L;pSB$$gPC<K9?sXy2OB|7MG<@hT)NV7ldR#g3IwSFYubm-xFyAz=a2za4|b uTK50WHUIzs4rN$LW=%~1DgXcg2mk;800000(o>TF0000 "Projectiles.Melee"; + public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public Color mainColor = Color.White; + public int time = 0; + + public override void SetDefaults() + { + Projectile.width = 45; + Projectile.height = 45; + Projectile.friendly = true; + Projectile.ignoreWater = true; + Projectile.tileCollide = false; // Because it has a large hitbox it has custom tile kill + Projectile.penetrate = -1; + Projectile.timeLeft = 900; + Projectile.extraUpdates = 7; + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = -1; + Projectile.DamageType = DamageClass.Melee; + } + public override void AI() + { + if (mainColor == Color.White) + { + mainColor = Main.rand.NextBool() ? Color.Green : Color.Purple; + } + + if (Collision.SolidCollision(Projectile.Center, 5, 5)) + Projectile.Kill(); + + Lighting.AddLight(Projectile.Center, Color.Lerp(mainColor, Color.White, 0.5f).ToVector3()); + + Player Owner = Main.player[Projectile.owner]; + float targetDist = Vector2.Distance(Owner.Center, Projectile.Center); //used for some drawing prevention for when it's offscreen since it makes a fuck load of particles + if (Projectile.timeLeft % 2 == 0 && time >= 1f && targetDist < 1400f) + { + Particle spark = new WaterFlavoredParticle(Projectile.Center, -Projectile.velocity * 0.05f, false, 6, 0.8f, (mainColor * 0.65f) * Utils.GetLerpValue(0, 90, time, true)); + GeneralParticleHandler.SpawnParticle(spark); + } + if (Main.rand.NextBool(4)) + { + Dust dust = Dust.NewDustPerfect(Projectile.Center, mainColor == Color.Green ? 89 : 86, -Projectile.velocity * Main.rand.NextFloat(0.1f, 0.8f), 0, default, Main.rand.NextFloat(0.8f, 1.1f)); + dust.noGravity = true; + dust.noLight = true; + dust.noLightEmittence = true; + dust.alpha = 90; + } + + Projectile.velocity.X *= 0.998f; + Projectile.velocity.Y += 0.01f; + + time++; + } + public override void OnKill(int timeLeft) + { + for (int i = 0; i < 4; i++) + { + Particle blood = new PointParticle(Projectile.Center, (-Projectile.velocity * 2).RotatedByRandom(0.6f) * Main.rand.NextFloat(0.2f, 0.9f) + new Vector2(0, Main.rand.NextFloat(-5, -1 + 1)), true, 20, Main.rand.NextFloat(0.7f, 1.2f), mainColor * 0.5f, false); + GeneralParticleHandler.SpawnParticle(blood); + } + } + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + target.AddBuff(ModContent.BuffType(), 180); + } + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) => CalamityUtils.CircularHitboxCollision(Projectile.Center, 45, targetHitbox); + } +} diff --git a/Projectiles/Melee/RespiteblockHoldout.cs b/Projectiles/Melee/RespiteblockHoldout.cs new file mode 100644 index 0000000000..3c1a34d464 --- /dev/null +++ b/Projectiles/Melee/RespiteblockHoldout.cs @@ -0,0 +1,202 @@ +using System; +using CalamityMod.Particles; +using CalamityMod.Buffs.DamageOverTime; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.Audio; +using Terraria.GameContent.Achievements; +using Terraria.ID; +using Terraria.ModLoader; + +namespace CalamityMod.Projectiles.Melee +{ + public class RespiteblockHoldout : ModProjectile, ILocalizedModType + { + public new string LocalizationCategory => "Projectiles.Melee"; + public Player Owner => Main.player[Projectile.owner]; + public ref float Time => ref Projectile.ai[0]; + + public override void SetDefaults() + { + Projectile.width = 108; + Projectile.height = 40; + Projectile.friendly = true; + Projectile.penetrate = -1; + Projectile.tileCollide = false; + Projectile.DamageType = DamageClass.Melee; + Projectile.ownerHitCheck = true; + // No reason to ID-static the chainsaw -- multiple players can true melee simultaneously! + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 4; + Projectile.noEnchantmentVisuals = true; + Projectile.ArmorPenetration = 15; + } + + public override bool PreDraw(ref Color lightColor) + { + Texture2D texture = Terraria.GameContent.TextureAssets.Projectile[Projectile.type].Value; + Texture2D centerTexture = ModContent.Request("CalamityMod/Items/Weapons/Melee/Respiteblock").Value; + Vector2 origin = centerTexture.Size() * 0.5f; + Vector2 drawPosition = Projectile.Center - Main.screenPosition; + SpriteEffects direction = Projectile.spriteDirection == 1 ? SpriteEffects.None : SpriteEffects.FlipHorizontally; + Rectangle rectangle = texture.Frame(1, 4, 0, Projectile.frame); + + Main.EntitySpriteDraw(texture, drawPosition, rectangle, Projectile.GetAlpha(lightColor), Projectile.rotation, origin, Projectile.scale, direction, 0); + return false; + } + + public override void AI() + { + // Recalculate damage every frame for balance reasons, as this is a long-lasting holdout. + // This is important because you could start using it while benefitting from Auric Tesla standstill bonus, for example. + Projectile.damage = Owner.ActiveItem() is null ? 0 : Owner.GetWeaponDamage(Owner.ActiveItem()); + + PlayChainsawSounds(); + + // Determines the owner's position whilst incorporating their fullRotation field. + // It uses vector transformation on a Z rotation matrix based on said rotation under the hood. + // This is essentially just the pure mathematical definition of the RotatedBy method. + Vector2 playerRotatedPosition = Owner.RotatedRelativePoint(Owner.MountedCenter); + if (Main.myPlayer == Projectile.owner) + { + if (!Owner.CantUseHoldout() && Owner.active && !Owner.dead) + HandleChannelMovement(playerRotatedPosition); + else + Projectile.Kill(); + } + + Lighting.AddLight(Projectile.Center, Color.White.ToVector3()); + + for (int i = 0; i <= 3; i++) + { + Dust dust = Dust.NewDustPerfect(Projectile.Center + (Projectile.velocity.RotatedBy(MathHelper.ToRadians(45f * Projectile.direction)) * 10) + Main.rand.NextVector2Circular(13, 13), Main.rand.NextBool() ? 89 : 86, (Projectile.velocity * 30).RotatedByRandom(0.3f) * Main.rand.NextFloat(0.05f, 0.9f), 0, default, Main.rand.NextFloat(0.4f, 0.95f)); + dust.noGravity = true; + dust.noLight = true; + dust.noLightEmittence = true; + dust.alpha = 90; + } + if (Time % 4 == 0) + { + Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), Projectile.Center + (Projectile.velocity.RotatedBy(MathHelper.ToRadians(45f * Projectile.direction)) * 10) + Main.rand.NextVector2Circular(13, 13) + Projectile.velocity * Main.rand.Next(10, 20 + 1), Projectile.velocity.RotatedBy(Main.rand.NextFloat(-0.01f, -0.35f) * Projectile.direction) * 4, ModContent.ProjectileType(), Projectile.damage / 3, Projectile.knockBack, Projectile.owner, 0); + } + + DetermineVisuals(playerRotatedPosition); + ManipulatePlayerValues(); + + // Prevent the projectile from dying normally. However, if anything for whatever reason + // goes wrong it will immediately be destroyed on the next frame. + Projectile.timeLeft = 2; + + Time++; + } + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + target.AddBuff(ModContent.BuffType(), 500); + + Player player = Main.player[Projectile.owner]; + Vector2 spawnPos = Projectile.Center + (Projectile.velocity.RotatedBy(MathHelper.ToRadians(45f * Projectile.direction)) * 10) + Main.rand.NextVector2Circular(13, 13); + for (int i = 0; i <= 3; i++) + { + spawnPos = Projectile.Center + (Projectile.velocity.RotatedBy(MathHelper.ToRadians(45f * Projectile.direction)) * 10) + Main.rand.NextVector2Circular(13, 13); + Particle blood = new PointParticle(spawnPos, (Projectile.velocity * 30).RotatedByRandom(0.3f) * Main.rand.NextFloat(0.2f, 0.9f) + new Vector2(0, Main.rand.NextFloat(-7, -2 + 1)), true, 25, Main.rand.NextFloat(0.7f, 1.2f), (Main.rand.NextBool() ? Color.Green : Color.Purple) * 0.5f, false); + GeneralParticleHandler.SpawnParticle(blood); + + Dust dust = Dust.NewDustPerfect(spawnPos, 263, (Projectile.velocity * 50).RotatedByRandom(0.3f) * Main.rand.NextFloat(0.05f, 0.9f), 0, default, Main.rand.NextFloat(0.6f, 0.95f)); + dust.noGravity = true; + dust.color = Color.White; + } + + SoundStyle fire = new("CalamityMod/Sounds/Item/WulfrumKnifeTileHit", 2); + SoundEngine.PlaySound(fire with { Volume = 0.55f, Pitch = 0.3f }, Projectile.Center); + + if (player.moonLeech || player.lifeSteal <= 0f || target.lifeMax <= 5) + return; + + int heal = Main.rand.NextBool(4) ? 2 : 1; + player.lifeSteal -= heal; + player.statLife += heal; + player.HealEffect(heal); + if (player.statLife > player.statLifeMax2) + player.statLife = player.statLifeMax2; + } + + public void PlayChainsawSounds() + { + if (Projectile.soundDelay <= 0) + { + SoundEngine.PlaySound(SoundID.Item22 with { Pitch = 0.3f}, Projectile.Center); + Projectile.soundDelay = 6; + } + } + public void DetermineVisuals(Vector2 playerRotatedPosition) + { + float directionAngle = Projectile.velocity.ToRotation(); + Projectile.rotation = directionAngle; + + int oldDirection = Projectile.spriteDirection; + if (oldDirection == -1) + Projectile.rotation += MathHelper.Pi; + + Projectile.direction = Projectile.spriteDirection = (Math.Cos(directionAngle) > 0).ToDirectionInt(); + + // If the direction differs from what it originaly was, undo the previous 180 degree turn. + // If this is not done, the chainsaw will have 1 frame of rotational "jitter" when the direction changes based on the + // original angle. This effect looks very strange in-game. + if (Projectile.spriteDirection != oldDirection) + Projectile.rotation -= MathHelper.Pi; + + // Positioning close to the player's arm. + Projectile.position = playerRotatedPosition - Projectile.Size * 0.5f + (directionAngle.ToRotationVector2().RotatedBy(MathHelper.ToRadians(-45f * Projectile.direction)) * 10f) + directionAngle.ToRotationVector2() * 30; + + // Update the position a tiny bit every frame at random to make it look like the saw is vibrating. + // It is reset on the next frame. + Projectile.position += Main.rand.NextVector2Circular(1.4f, 1.4f); + + Projectile.frameCounter += 33; + if (Projectile.frameCounter >= 32) + { + Projectile.frame = (Projectile.frame + 1) % 4; + Projectile.frameCounter = 0; + } + } + + public void HandleChannelMovement(Vector2 playerRotatedPosition) + { + Vector2 idealAimDirection = (Main.MouseWorld - playerRotatedPosition).SafeNormalize(Vector2.UnitX * Owner.direction); + + float angularAimVelocity = 0.15f; + float directionAngularDisparity = Projectile.velocity.AngleBetween(idealAimDirection) / MathHelper.Pi; + + // Increase the turn speed if close to the ideal direction, since successive linear interpolations + // are asymptotic. + angularAimVelocity += MathHelper.Lerp(0f, 0.25f, Utils.GetLerpValue(0.28f, 0.08f, directionAngularDisparity, true)); + + if (directionAngularDisparity > 0.02f) + Projectile.velocity = Vector2.Lerp(Projectile.velocity, idealAimDirection, angularAimVelocity); + else + Projectile.velocity = idealAimDirection; + + Projectile.velocity = Projectile.velocity.SafeNormalize(Vector2.UnitX * Owner.direction); + } + + public void ManipulatePlayerValues() + { + Owner.itemRotation = (Projectile.velocity * Projectile.direction).ToRotation(); + Owner.itemTime = 2; + Owner.itemAnimation = 2; + Owner.ChangeDir(Projectile.direction); + } + + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) + { + // Collision is done as a line to bypass the fact that hitboxes cannot rotate and that + // this projectile is notably flat in terms of sprite shape. + float _ = 0f; + float width = Projectile.scale * 36f; + Vector2 start = Projectile.Center; + Vector2 end = Projectile.Center + Projectile.velocity * 60f; + return Collision.CheckAABBvLineCollision(targetHitbox.TopLeft(), targetHitbox.Size(), start, end, width, ref _); + } + } +} diff --git a/Projectiles/Melee/RespiteblockHoldout.png b/Projectiles/Melee/RespiteblockHoldout.png new file mode 100644 index 0000000000000000000000000000000000000000..7cd0f37ed7ff0a056f9dd5fd09e0da319794fffa GIT binary patch literal 2534 zcmXYz3p`Zm8^>RyXsPx;h>==5{nLszGGcP8ZQN>xCih%hBe|BDkyy8qRzzZ?VaN;t%_S_! z{}AVU2;~wfnK(J0qc~YJN%C-&2bm^e$STu*+*h+=8#BFoilrv81!rLq5sr7|>jpDo zKRo#fL49}`VHzHx2A&dm{UCE0N#^_f+WD; zhdhTIZ0EyNtnX=rNF<`K@mgBWjdP~iu*(u)AqS=PZeU=btTy!Soixa#P>Kd*$|4Vy1s@-^YDhtPyEk;O z7WhU-ZVK+}~vP1fH%kNF3o!7TmpVsB8x)VO_Pa5U*!d(U!UjZUS&DH*r+F z_{&}?P`T13Fm;I1)D*Km7J`_(y_=|!DB;}j^ZH;e>v^`WojJ;DqR=06xGq#6X^TvK zE5m4-8-@*<7>bRE{C&XF(-Smp9P3JUza*-m`VdZYb3bq3xI6TgS{=p7E=KihFnNKv zvn@&*RBzt%d_SJTaw^|youDJD(xTl{IvXQDIN3eR+gQWr6LhCj=U}S;FHUiZo{R%|>W8<4@*A`i zKA7t?h|bE+E+LKG_KJv(I=P}9hO8euxoidAkr9-zNt?Xo%;R@I8k7|{>n-s)Z+8i} zjfc!g1^1qfm^}Xc6_cee0jx(gPrHZ9nY}ZkSi6h3WZ%=XNOnmA#vIy17%>R%xTVfh zyl_%xIyh9XV_omIqsc45<(_Oq7+J7Eerx&W;>lN$m2O@$H7iugLhr@rYGh`1k%%3X(2>XDpMb;L&b&>$><#qHlVTog=G4%Z9QZuG|IPKa!}0WR4Ugws4Hxfx zn67DHvX3DO z5pOg3**_qtwts1%&QIhPrKMtzx++l%+{$MHjA`5yB9_PG&nf0S4yY}uP*9oKf#=x! zu4>hmILCgQE61k6wDH5`{Mw$tUBIXhHjfC2vYwCDRVHn;Ox6k%j1!ZuyF=pqa?Y8U zHgv4Hp8b9<_Q_utC|?I#MtRkxt!&zCV>Nw#YoH!yjymH^H0-1y*#4yZOn%5C^kY&Z z^i-Wt`c4?zBJ`^4{TL+-+?cPDb#Rt-uFPiB5JIC%tHy#G`l`q6Q?&Hc7@Y9RD9wwB zkk~66PwYA3QNZN2Q`!0c1A4~lwkLLHp)HoSRt`XVYpXV8I)LM$Qd%2krbKkG?7i=8JbkU{d~!o;3TH zayJd3+o!^&by_K@UF=CF?0yWvt~&hlFhOZsj@dog)0UlPLXXIDr+%#$iu4llVM-8Y zl6*m`#*`%1A+;{=iOf*xX0&NYEBXBh@!T#O<32w>ba@p?)75c(?mGg05Mv-Yy{YyjDqnM7?7?H$tR3PiZW?toxsH1y8 zSiZ)XMTIkQ)l?-374;!xJoJ7B+5&gX6biI62Yu>RgKk%`T+hMGgzo%=U`)MQ@@SD( zZB4#I6ckoEdT7d-co?blFtx{4$t}x=^SwU}>Y7V`L2bZFQ~A(OANqR`QCd5D26`K6 zdw-wZqpRLe{zUc-jFdLiU6Fsi@GIt5W8rJ(4o6p=nqZrDr@{pJu?~-naOeM$bIZNo z??F@q>FDX5DnG^T!%U0$-OZ>UG!H~Uzh`^!PF6k`4A6vp8E9-@eV5X Date: Sun, 26 May 2024 20:30:10 -0700 Subject: [PATCH 109/401] sprite fix --- Items/Weapons/Melee/Respiteblock.png | Bin 1648 -> 4223 bytes Projectiles/Melee/RespiteblockHoldout.png | Bin 2534 -> 5166 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/Items/Weapons/Melee/Respiteblock.png b/Items/Weapons/Melee/Respiteblock.png index 9999a6134265753398bd6549d0856e9cff9b5723..8e3bfa165cd2bd60a590487b977f92ce6548d475 100644 GIT binary patch literal 4223 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%0Dy!50Qvv` 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 literal 2534 zcmXYz3p`Zm8^>RyXsPx;h>==5{nLszGGcP8ZQN>xCih%hBe|BDkyy8qRzzZ?VaN;t%_S_! z{}AVU2;~wfnK(J0qc~YJN%C-&2bm^e$STu*+*h+=8#BFoilrv81!rLq5sr7|>jpDo zKRo#fL49}`VHzHx2A&dm{UCE0N#^_f+WD; zhdhTIZ0EyNtnX=rNF<`K@mgBWjdP~iu*(u)AqS=PZeU=btTy!Soixa#P>Kd*$|4Vy1s@-^YDhtPyEk;O z7WhU-ZVK+}~vP1fH%kNF3o!7TmpVsB8x)VO_Pa5U*!d(U!UjZUS&DH*r+F z_{&}?P`T13Fm;I1)D*Km7J`_(y_=|!DB;}j^ZH;e>v^`WojJ;DqR=06xGq#6X^TvK zE5m4-8-@*<7>bRE{C&XF(-Smp9P3JUza*-m`VdZYb3bq3xI6TgS{=p7E=KihFnNKv zvn@&*RBzt%d_SJTaw^|youDJD(xTl{IvXQDIN3eR+gQWr6LhCj=U}S;FHUiZo{R%|>W8<4@*A`i zKA7t?h|bE+E+LKG_KJv(I=P}9hO8euxoidAkr9-zNt?Xo%;R@I8k7|{>n-s)Z+8i} zjfc!g1^1qfm^}Xc6_cee0jx(gPrHZ9nY}ZkSi6h3WZ%=XNOnmA#vIy17%>R%xTVfh zyl_%xIyh9XV_omIqsc45<(_Oq7+J7Eerx&W;>lN$m2O@$H7iugLhr@rYGh`1k%%3X(2>XDpMb;L&b&>$><#qHlVTog=G4%Z9QZuG|IPKa!}0WR4Ugws4Hxfx zn67DHvX3DO z5pOg3**_qtwts1%&QIhPrKMtzx++l%+{$MHjA`5yB9_PG&nf0S4yY}uP*9oKf#=x! zu4>hmILCgQE61k6wDH5`{Mw$tUBIXhHjfC2vYwCDRVHn;Ox6k%j1!ZuyF=pqa?Y8U zHgv4Hp8b9<_Q_utC|?I#MtRkxt!&zCV>Nw#YoH!yjymH^H0-1y*#4yZOn%5C^kY&Z z^i-Wt`c4?zBJ`^4{TL+-+?cPDb#Rt-uFPiB5JIC%tHy#G`l`q6Q?&Hc7@Y9RD9wwB zkk~66PwYA3QNZN2Q`!0c1A4~lwkLLHp)HoSRt`XVYpXV8I)LM$Qd%2krbKkG?7i=8JbkU{d~!o;3TH zayJd3+o!^&by_K@UF=CF?0yWvt~&hlFhOZsj@dog)0UlPLXXIDr+%#$iu4llVM-8Y zl6*m`#*`%1A+;{=iOf*xX0&NYEBXBh@!T#O<32w>ba@p?)75c(?mGg05Mv-Yy{YyjDqnM7?7?H$tR3PiZW?toxsH1y8 zSiZ)XMTIkQ)l?-374;!xJoJ7B+5&gX6biI62Yu>RgKk%`T+hMGgzo%=U`)MQ@@SD( zZB4#I6ckoEdT7d-co?blFtx{4$t}x=^SwU}>Y7V`L2bZFQ~A(OANqR`QCd5D26`K6 zdw-wZqpRLe{zUc-jFdLiU6Fsi@GIt5W8rJ(4o6p=nqZrDr@{pJu?~-naOeM$bIZNo z??F@q>FDX5DnG^T!%U0$-OZ>UG!H~Uzh`^!PF6k`4A6vp8E9-@eV5X Date: Mon, 27 May 2024 19:02:51 -0400 Subject: [PATCH 110/401] Fix Respiteblock holdout display name loc --- Localization/en-US/Mods.CalamityMod.Projectiles.Melee.hjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/en-US/Mods.CalamityMod.Projectiles.Melee.hjson b/Localization/en-US/Mods.CalamityMod.Projectiles.Melee.hjson index d2cc4b590f..2116398cd1 100644 --- a/Localization/en-US/Mods.CalamityMod.Projectiles.Melee.hjson +++ b/Localization/en-US/Mods.CalamityMod.Projectiles.Melee.hjson @@ -316,5 +316,5 @@ WulfrumScrewdriverProj.DisplayName: Wulfrum Screwdriver YateveoBloomProj.DisplayName: Yateveo Bloom YinYoDark.DisplayName: Dark Shard YinYoLight.DisplayName: Light Shard -RespiteblockHoldout.DisplayName: Respiteblock Holdout +RespiteblockHoldout.DisplayName: Respiteblock RespiteblockBlood.DisplayName: Respiteblock Blood From 457d821c27bf42c810a25f22e03446da2696c0f2 Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Mon, 27 May 2024 21:03:55 -0700 Subject: [PATCH 111/401] cauldron is now a holdout --- Gores/CauldronChunk.png | Bin 292 -> 0 bytes Items/Weapons/Magic/TheCauldron.cs | 12 +- .../Mods.CalamityMod.Projectiles.Magic.hjson | 4 +- Projectiles/Magic/CauldronHoldout.cs | 127 ++++++++++++++++++ Projectiles/Magic/CauldronProj.cs | 36 ++--- Projectiles/Magic/CauldronProj.png | Bin 0 -> 606 bytes Projectiles/Magic/CauldronProjGlow.png | Bin 0 -> 280 bytes Projectiles/Magic/CauldronProjSmall.cs | 8 +- Projectiles/Magic/CauldronProjSmall.png | Bin 606 -> 292 bytes Projectiles/Magic/CauldronProjSmallGlow.png | Bin 280 -> 222 bytes 10 files changed, 156 insertions(+), 31 deletions(-) delete mode 100644 Gores/CauldronChunk.png create mode 100644 Projectiles/Magic/CauldronHoldout.cs create mode 100644 Projectiles/Magic/CauldronProj.png create mode 100644 Projectiles/Magic/CauldronProjGlow.png diff --git a/Gores/CauldronChunk.png b/Gores/CauldronChunk.png deleted file mode 100644 index feac67f62f0f5bc49c7cd87670ac1b875eefbc38..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 292 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xa#^NA%Cx&(BWL^R}M?75|Lo_C? zowT0oP=Ls>df|%-&7B60-3Jp)q3E%KjfUWzG+%b298R9ILn>-V>jbx-)djD~z zGnY@wse5{_cz^Xd{(aTFQJ^q7ta_T~TWei1L{R56X=#;&a(); + Item.shoot = ModContent.ProjectileType(); Item.shootSpeed = 12f; Item.DamageType = DamageClass.Magic; + Item.channel = true; Item.Calamity().donorItem = true; } @@ -57,6 +57,14 @@ public override void PostDrawInWorld(SpriteBatch spriteBatch, Color lightColor, Item.DrawItemGlowmaskSingleFrame(spriteBatch, rotation, Glow.Value); } + public override bool CanUseItem(Player player) => player.ownedProjectileCounts[Item.shoot] <= 0; + + public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) + { + Projectile.NewProjectile(source, position.X, position.Y, velocity.X, velocity.Y, ModContent.ProjectileType(), damage, knockback, player.whoAmI, 46); + return false; + } + public override void AddRecipes() { CreateRecipe() diff --git a/Localization/en-US/Mods.CalamityMod.Projectiles.Magic.hjson b/Localization/en-US/Mods.CalamityMod.Projectiles.Magic.hjson index 89edecb071..7c05554882 100644 --- a/Localization/en-US/Mods.CalamityMod.Projectiles.Magic.hjson +++ b/Localization/en-US/Mods.CalamityMod.Projectiles.Magic.hjson @@ -41,8 +41,8 @@ BrimstoneFireball.DisplayName: Brimstone Fireball BrimstoneHellfireballFriendly.DisplayName: Hellfireball BrimstoneHomer.DisplayName: Brimstone Homer BrimstoneTentacle.DisplayName: Brimstone Tentacle -CauldronProj.DisplayName: Cauldron -CauldronProjSmall.DisplayName: Smauldron +CauldronProj.DisplayName: Smauldron +CauldronProjSmall.DisplayName: Smaullerdron ChronoIcicleLarge.DisplayName: Chrono Icicle ChronoIcicleSmall.DisplayName: Chrono Icicle ChronomancersScytheHoldout.DisplayName: Chronomancer's Scythe diff --git a/Projectiles/Magic/CauldronHoldout.cs b/Projectiles/Magic/CauldronHoldout.cs new file mode 100644 index 0000000000..d858664c9d --- /dev/null +++ b/Projectiles/Magic/CauldronHoldout.cs @@ -0,0 +1,127 @@ +using System; +using CalamityMod.Items.Weapons.Magic; +using CalamityMod.Particles; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.Audio; +using Terraria.GameContent; +using Terraria.ID; +using Terraria.Localization; +using Terraria.ModLoader; +using static CalamityMod.CalamityUtils; + +namespace CalamityMod.Projectiles.Magic +{ + public class CauldronHoldout : ModProjectile, ILocalizedModType + { + public override LocalizedText DisplayName => GetItemName(); + + public override string Texture => "CalamityMod/Items/Weapons/Magic/TheCauldron"; + + public static int FireRate = 46; + + public override void SetDefaults() + { + Projectile.width = 46; + Projectile.height = 46; + Projectile.friendly = true; + Projectile.penetrate = -1; + Projectile.tileCollide = false; + Projectile.DamageType = DamageClass.Magic; + Projectile.ignoreWater = true; + } + public override void AI() + { + Player player = Main.player[Projectile.owner]; + float rotoffset = MathHelper.PiOver4; + Vector2 playerpos = player.RotatedRelativePoint(player.MountedCenter, true); + bool shouldBeHeld = !player.CantUseHoldout(); + Projectile.damage = player.ActiveItem() is null ? 0 : player.GetWeaponDamage(player.ActiveItem()); + if (Projectile.ai[0] > 0f) + { + Projectile.ai[0] -= 1f; + } + if (Main.myPlayer == Projectile.owner) + { + if (shouldBeHeld) + { + float holdscale = player.ActiveItem().shootSpeed * Projectile.scale; + Vector2 playerpos2 = playerpos; + Vector2 going = Main.screenPosition + new Vector2((float)Main.mouseX, (float)Main.mouseY) - Projectile.Center; + if (player.gravDir == -1f) + { + going.Y = (float)(Main.screenHeight - Main.mouseY) + Main.screenPosition.Y - Projectile.Center.Y; + } + Vector2 normalizedgoing = Vector2.Normalize(going); + if (float.IsNaN(normalizedgoing.X) || float.IsNaN(normalizedgoing.Y)) + { + normalizedgoing = -Vector2.UnitY; + } + normalizedgoing *= holdscale; + if (normalizedgoing.X != Projectile.velocity.X || normalizedgoing.Y != Projectile.velocity.Y) + { + Projectile.netUpdate = true; + } + Projectile.velocity = normalizedgoing * 0.55f; + + if (Projectile.ai[0] <= 0) + { + bool manaCostPaid = player.CheckMana(player.ActiveItem(), -1, true, false); + if (manaCostPaid) + { + SoundEngine.PlaySound(SoundID.DD2_BetsyFireballShot, Projectile.Center); + + int projType = ModContent.ProjectileType(); + int projDamage = Projectile.damage; + float speedscale = 18f; + Vector2 shotSpeed = Vector2.Normalize(Projectile.velocity) * speedscale; + if (float.IsNaN(shotSpeed.X) || float.IsNaN(shotSpeed.Y)) + { + shotSpeed = -Vector2.UnitY; + } + Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, shotSpeed, projType, projDamage, Projectile.knockBack, player.whoAmI); + + for (int i = 0; i < 6; i++) + { + Vector2 burstSpeed = (Projectile.rotation - rotoffset).ToRotationVector2().RotatedByRandom(MathHelper.ToRadians(45f)) * Main.rand.NextFloat(8f, 14f); + SquishyLightParticle energy = new(Projectile.Center + Projectile.rotation.ToRotationVector2() * 5, burstSpeed, Main.rand.NextFloat(0.2f, 0.3f), Color.Orange, Main.rand.Next(6, 11), 3, 1.5f); + GeneralParticleHandler.SpawnParticle(energy); + } + Projectile.ai[0] = FireRate; + } + else + { + Projectile.Kill(); + } + } + } + else + { + Projectile.Kill(); + } + } + Projectile.Center = player.RotatedRelativePoint(player.MountedCenter, true) - new Vector2(player.direction == 1 ? 6 : 0, 30); + Projectile.rotation = Projectile.velocity.ToRotation() + rotoffset; + Projectile.spriteDirection = Projectile.direction; + Projectile.timeLeft = 2; + player.ChangeDir(Projectile.direction); + player.heldProj = Projectile.whoAmI; + player.itemTime = 2; + player.itemAnimation = 2; + player.itemRotation = (float)Math.Atan2((double)(Projectile.velocity.Y * (float)Projectile.direction), (double)(Projectile.velocity.X * (float)Projectile.direction)); + player.SetCompositeArmFront(true, Player.CompositeArmStretchAmount.Full, MathHelper.Pi); + player.SetCompositeArmBack(true, Player.CompositeArmStretchAmount.Full, MathHelper.Pi); + } + + public override bool? CanDamage() => false; + + public override bool PreDraw(ref Color lightColor) + { + Texture2D tex = TextureAssets.Projectile[Type].Value; + Main.EntitySpriteDraw(tex, Projectile.Center - Main.screenPosition, null, Projectile.GetAlpha(lightColor), Projectile.rotation, tex.Size() / 2, Projectile.scale, SpriteEffects.None, 0); + Main.EntitySpriteDraw(TheCauldron.Glow.Value, Projectile.Center - Main.screenPosition, null, Color.White, Projectile.rotation, tex.Size() / 2, Projectile.scale, SpriteEffects.None, 0); + return false; + } + } +} diff --git a/Projectiles/Magic/CauldronProj.cs b/Projectiles/Magic/CauldronProj.cs index 45b420369b..2c7dc86130 100644 --- a/Projectiles/Magic/CauldronProj.cs +++ b/Projectiles/Magic/CauldronProj.cs @@ -1,14 +1,9 @@ -using System; -using CalamityMod.Items.Weapons.Magic; -using CalamityMod.Items.Weapons.Rogue; -using CalamityMod.Particles; -using CalamityMod.Projectiles.Rogue; +using CalamityMod.Particles; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using ReLogic.Content; using Terraria; using Terraria.Audio; -using Terraria.GameContent; using Terraria.ID; using Terraria.ModLoader; @@ -17,17 +12,22 @@ namespace CalamityMod.Projectiles.Magic public class CauldronProj : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Magic"; - public override string Texture => "CalamityMod/Items/Weapons/Magic/TheCauldron"; + + public static Asset Glow; public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 5; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + if (!Main.dedServ) + { + Glow = ModContent.Request(Texture + "Glow"); + } } public override void SetDefaults() { - Projectile.width = 46; - Projectile.height = 46; + Projectile.width = 28; + Projectile.height = 28; Projectile.friendly = true; Projectile.tileCollide = false; Projectile.penetrate = 1; @@ -80,29 +80,21 @@ public override void OnKill(int timeLeft) } for (int i = 0; i < 40; i++) { - int size = 20; + int size = 16; Vector2 position = Projectile.Center; Vector2 velocity = Main.rand.NextVector2Circular(size, size); - SquishyLightParticle energy = new(position, velocity, Main.rand.NextFloat(0.3f, 0.4f), Color.Orange, Main.rand.Next(6, 9), 1, 1.5f); + SquishyLightParticle energy = new(position, velocity, Main.rand.NextFloat(0.2f, 0.3f), Color.Orange, Main.rand.Next(6, 9), 1, 1.5f); GeneralParticleHandler.SpawnParticle(energy); - Dust dust = Dust.NewDustPerfect(position, DustID.Torch, velocity, 0, default, Main.rand.NextFloat(1.6f, 3.1f)); + Dust dust = Dust.NewDustPerfect(position, DustID.Torch, velocity, 0, default, Main.rand.NextFloat(1f, 2f)); dust.noGravity = true; - if (Main.rand.NextBool(13)) - { - if (Main.netMode != NetmodeID.Server) - { - int rocc = Gore.NewGore(Projectile.GetSource_Death(), Projectile.Center, Main.rand.NextVector2Circular(6, 6), Mod.Find("CauldronChunk").Type); - Main.gore[rocc].timeLeft /= 10; - } - } } } public override bool PreDraw(ref Color lightColor) { CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], lightColor, 2); - Vector2 origin = TheCauldron.Glow.Value.Size() / 2f; - Main.EntitySpriteDraw(TheCauldron.Glow.Value, Projectile.Center - Main.screenPosition, null, Color.White, Projectile.rotation, origin, Projectile.scale, SpriteEffects.None, 0); + Vector2 origin = Glow.Value.Size() / 2f; + Main.EntitySpriteDraw(Glow.Value, Projectile.Center - Main.screenPosition, null, Color.White, Projectile.rotation, origin, Projectile.scale, SpriteEffects.None, 0); return false; } public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) => target.AddBuff(BuffID.OnFire3, 180); diff --git a/Projectiles/Magic/CauldronProj.png b/Projectiles/Magic/CauldronProj.png new file mode 100644 index 0000000000000000000000000000000000000000..f50600398ab5d352e6121dd8c7836a2c964b6e2b GIT binary patch literal 606 zcmV-k0-^nhP)Px${z*hZR7i=(_(PBH$PbaC#t*S$02Y~sDXoA>U0_uO|s_ndp~>7k3} z2Fe##eP1s6?eBa0Jy(tI?e@cet-i2hV(hL*RQd56fCpm(08BkT1mNR`8vyh+&jDD8 zWoA3_v}Ub0Cq8lNgn#}nvSL05z<9yPhKeQ6;8kU(?L;D$zHFZWuwFj}64LB_D6(!U zJh|z$r#Ju-Qu%!S)2TNueZtUp;1eFzVgR1yY%@gGcxy!S@2&$dR2;SOO@DkPx(2|U zi{9*g7)Ir6y$-=gaDj`7(P#Zr}6UTWdf<)={!^ zq@9#LVf^#hz2@zq6}lBGcNUg5Jwrw5(Z&jpMCD=>0T7?LB$o5cGRUPPx9ohB290pC zWGhp&RiFO?5+6n{-nX4d8D_!V9$O8crFPr|{)Z^ly*5egdMs0voevwXS44~BkE|nd zzIW$OIXNUvpD?LGd|xW+6pc~~Ss)RKP`>-T{Vn7BP&G)U>28Z*dx%KqQPTNql`$w5 zl5_s|*A&%KLxy$e>YaRB!`H+8KvKI%)trCBhjnW9grSs)I!V5l!a6im>V%g=VydI< sTy`Y@000hUSV?A0O#mtY000O800000007cclK=n!07*qoM6N<$f=`DQ5dZ)H literal 0 HcmV?d00001 diff --git a/Projectiles/Magic/CauldronProjGlow.png b/Projectiles/Magic/CauldronProjGlow.png new file mode 100644 index 0000000000000000000000000000000000000000..41b88520128195eaabd1fa55bc630c302438a4ef GIT binary patch literal 280 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s3?yAI>n{URjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij?1AIbU6WPTkh{)_VSN>cq@Mp8?vtPbInXAc9HUla4k|4j}|6sr%<<0B{ z6yhxKh%9Dc;5!V$jK}j=qyPmgJzX3_Ed1wA^5$bzG;zuyoBsf;Zb$EInVn;fr4S>UGzhO1^(ni~lij`|)Wud-m}H P9l_w~>gTe~DWM4f>O^G- literal 0 HcmV?d00001 diff --git a/Projectiles/Magic/CauldronProjSmall.cs b/Projectiles/Magic/CauldronProjSmall.cs index ddfc180708..0d3613fb04 100644 --- a/Projectiles/Magic/CauldronProjSmall.cs +++ b/Projectiles/Magic/CauldronProjSmall.cs @@ -1,11 +1,9 @@ -using System; -using CalamityMod.Particles; +using CalamityMod.Particles; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using ReLogic.Content; using Terraria; using Terraria.Audio; -using Terraria.GameContent; using Terraria.ID; using Terraria.ModLoader; @@ -28,8 +26,8 @@ public override void SetStaticDefaults() public override void SetDefaults() { - Projectile.width = 28; - Projectile.height = 28; + Projectile.width = 14; + Projectile.height = 14; Projectile.friendly = true; Projectile.penetrate = 1; Projectile.timeLeft = 120; diff --git a/Projectiles/Magic/CauldronProjSmall.png b/Projectiles/Magic/CauldronProjSmall.png index f50600398ab5d352e6121dd8c7836a2c964b6e2b..feac67f62f0f5bc49c7cd87670ac1b875eefbc38 100644 GIT binary patch delta 264 zcmV+j0r&pi1f&9giBL{Q4GJ0x0000DNk~Le0000E0000E2nGNE03S##(EtDd0drDE zLIAGL9O(c60K`c|K~yM_t&*<_!cY{(e-qIlgNZOfi@{(t8Vs7mSFrgI28+TT#z!!i z7X;ISNntB892x|T{t0ITcam&=<=%6@d(IEOdkvJPW&8bqT_4(&l<)3+1E8QAe^pVF zCS4PNUjGWf!fODq3va2$>_kmko3aiEGSeXdU>sHfXx8O^cH+j8jTMs;MWYS?c3dyr z7XYiH)cI4@shRTtfSK14|1Q37{fp>d9zuAQ0NA> O%{D6sY+*x_I07c})oFwP delta 580 zcmV-K0=xaB0^S6FiBL{Q4GJ0x0000DNk~Le0000S0000S2nGNE0CElAlmGw#0drDE zLIAGL9O(c60scuuK~zYI&6dwgR8bViKRTK-;IkRB2{J+uGDsMrg)Um;Cc(d;t$#so zgH~;4(Vx)Pzd+DcQHw-`gc1z|2@+J~O-?cXnsjmQx7WRYGvjRHy}q0G?tS;%cR%-> zd+zC>i{=K(7gv2>F8b~7d;2|CjqmOD!+)*5uw!EEu18e)@f&~#V*>z8Jw62Bf!N`V+CC}hhWvA^#B9^{vp8&94KLrxf z?0qP*ZYn%~x#_j1H~Rd{PWno=Ix;sx)m#T7M30T7?LB$o5cGRUPP zx9ohB290pCWGhp&RiFO?5+6n{-nX4d8D_!V9$O8crFPr|{)Z^ly*5egdMs0voevwX zS44~BkE|ndzIW$OIXNUvpD?LGd|xW+6pc~~Ss)RKP`>-T{Vn7BP&G)U>28Z*dx%Kq zQPTN5Yn3r57Ls%R_tzBFQbUGy=<1z(Tf^7G{XkN?NY$Kw!-sWh_JpC7i8@KXm%=(U SRO*D6Lt?6oz6FbbLAacJ&!sr6ke z`Yvj-8r<$*CDX8b<||#X+EY(1b3F4{zC1u=hRxdi+Vz#5E{-7<{&OdJ^RX&&uq^z0=l_X*u@f^QZ3?qeqmOAQ7*9}m zv`8(q@fw4F-3m3&=mP;u_f5Q8P^-+?74!MgtR+&5zjsXAp3Pq*5uZ|bczeFe{K-$d z*KYc9$TcQJMfz`8y5=Flo9!x=p0D2UMK68zy6a9Q-@mEF{}{Oa_%xgOJ^Ofpu3_+W L^>bP0l+XkK(q~dM From 78be698597f3c95646750ef02edabae559960b20 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Mon, 27 May 2024 23:59:19 -0400 Subject: [PATCH 112/401] Planar Ripper visual effects for speed boost --- CalPlayer/CalamityPlayerDrawEffects.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CalPlayer/CalamityPlayerDrawEffects.cs b/CalPlayer/CalamityPlayerDrawEffects.cs index d5326f5e54..19d13db305 100644 --- a/CalPlayer/CalamityPlayerDrawEffects.cs +++ b/CalPlayer/CalamityPlayerDrawEffects.cs @@ -330,6 +330,24 @@ public override void DrawEffects(PlayerDrawSet drawInfo, ref float r, ref float } } + // Prideful Hunter's Planar Ripper movement speed boost + if (calamityPlayer.planarSpeedBoost > 0 && drawInfo.shadow == 0f) + { + int spawnChance = (int)(13 - (calamityPlayer.planarSpeedBoost / 2)); + if (Main.rand.NextBool(spawnChance)) + { + Vector2 sparkVelocity = -(Vector2.UnitY * Main.rand.NextFloat(2.5f, 5f)).RotatedByRandom(MathHelper.Pi / 10); + Vector2 sparkPos = new Vector2(Player.position.X + Main.rand.NextFloat(-8f, 40f), Player.position.Y + Main.rand.NextFloat(-8f, 56f)); + Particle movementSpark = new AltLineParticle(sparkPos, sparkVelocity, false, 20, Main.rand.NextFloat(0.375f, 0.5f), new Color(130, 255, 255)); + GeneralParticleHandler.SpawnParticle(movementSpark); + + sparkVelocity = -(Vector2.UnitY * Main.rand.NextFloat(3f, 5.5f)).RotatedByRandom(MathHelper.Pi / 6); + sparkPos = new Vector2(Player.position.X + Main.rand.NextFloat(-8f, 40f), Player.position.Y + Main.rand.NextFloat(-8f, 56f)); + Particle addSparks = new CustomPulse(sparkPos, sparkVelocity, new Color(180, 255, 255), "CalamityMod/Particles/ElectricSpark", Vector2.One, 0f, 0.5f, 0.65f, 20); + GeneralParticleHandler.SpawnParticle(addSparks); + } + } + // Some extraneous and probably undocumented visual effect caused by the heart lad pet thing if ((calamityPlayer.ladHearts > 0) && !Player.loveStruck && Main.netMode != NetmodeID.Server && drawInfo.shadow == 0f) { From 72d04e1034ef4f0b796dfdefeecff0b140f469c8 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Tue, 28 May 2024 08:28:18 -0500 Subject: [PATCH 113/401] Distinct bee spawning noise for Queen Bee. --- NPCs/VanillaNPCAIOverrides/Bosses/QueenBeeAI.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/QueenBeeAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/QueenBeeAI.cs index ab6a393d15..f7b4de517e 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/QueenBeeAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/QueenBeeAI.cs @@ -422,7 +422,7 @@ public static bool BuffedQueenBeeAI(NPC npc, Mod mod) bool spawnBee = phase4 && calamityGlobalNPC.newAI[0] % beeSpawnGateValue == 0f && Collision.CanHit(npc.Center, 1, 1, Main.player[npc.target].position, Main.player[npc.target].width, Main.player[npc.target].height); if (spawnBee) { - SoundEngine.PlaySound(SoundID.NPCHit1, npc.Center); + SoundEngine.PlaySound(SoundID.NPCHit18, npc.Center); if (Main.netMode != NetmodeID.MultiplayerClient) { @@ -615,10 +615,7 @@ public static bool BuffedQueenBeeAI(NPC npc, Mod mod) // Spawn bees if (Collision.CanHit(beeSpawnLocation, 1, 1, Main.player[npc.target].position, Main.player[npc.target].width, Main.player[npc.target].height) && spawnBee && (!beeLimitReached || !hornetLimitReached)) { - if (!phase3 || Main.zenithWorld) - SoundEngine.PlaySound(SoundID.NPCHit1, beeSpawnLocation); - else - SoundEngine.PlaySound(SoundID.NPCHit18, beeSpawnLocation); + SoundEngine.PlaySound(SoundID.NPCHit18, beeSpawnLocation); if (Main.netMode != NetmodeID.MultiplayerClient) { @@ -1359,7 +1356,7 @@ public static bool VanillaQueenBeeAI(NPC npc, Mod mod) if (Collision.CanHit(beeSpawnLocation, 1, 1, Main.player[npc.target].position, Main.player[npc.target].width, Main.player[npc.target].height) && flag35) { - SoundEngine.PlaySound(SoundID.NPCHit1, npc.Center); + SoundEngine.PlaySound(SoundID.NPCHit18, npc.Center); if (Main.netMode != NetmodeID.MultiplayerClient) { int num670 = Main.rand.Next(NPCID.Bee, NPCID.BeeSmall + 1); From 4837b0d0a96c54ba2a1f4c91e9ca1f84f3d802cf Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Tue, 28 May 2024 20:14:37 -0500 Subject: [PATCH 114/401] 1 - Hive Mind adjustments (Astrum Aureus, Ceaseless Void, and Brimstone Elemental changes coming soon). 2 - Greatsword of Judgement nerf (this thing is ridiculous due to the obscene projectile and dust spam it causes and hopefully its rework is implemented soon). --- NPCs/HiveMind/DarkHeart.cs | 98 +++++++++++++++--------------- NPCs/HiveMind/HiveBlob.cs | 14 +++-- NPCs/HiveMind/HiveBlob2.cs | 14 +++-- NPCs/HiveMind/HiveMind.cs | 55 ++++++++++++++--- Projectiles/Melee/JudgementProj.cs | 12 ++-- Projectiles/Melee/WhiteBoltAura.cs | 7 ++- 6 files changed, 125 insertions(+), 75 deletions(-) diff --git a/NPCs/HiveMind/DarkHeart.cs b/NPCs/HiveMind/DarkHeart.cs index 0449ae3853..c1dcf2d49f 100644 --- a/NPCs/HiveMind/DarkHeart.cs +++ b/NPCs/HiveMind/DarkHeart.cs @@ -61,63 +61,68 @@ public override void AI() NPC.damage = 0; bool revenge = CalamityWorld.revenge || BossRushEvent.BossRushActive; + + // Float around the player + NPC.rotation = NPC.velocity.X / 20f; + NPC.TargetClosest(); - float npcSpeed = (CalamityWorld.LegendaryMode && CalamityWorld.revenge) ? 8f : revenge ? 4.5f : 4f; - float velocityMult = (CalamityWorld.LegendaryMode && CalamityWorld.revenge) ? 1f : revenge ? 0.8f : 0.75f; + + float velocity = (CalamityWorld.LegendaryMode && CalamityWorld.revenge) ? 10f : revenge ? 6f : 4f; + float acceleration = (CalamityWorld.LegendaryMode && CalamityWorld.revenge) ? 0.5f : revenge ? 0.3f : 0.2f; if (BossRushEvent.BossRushActive) { - npcSpeed *= 2f; - velocityMult *= 2f; + velocity *= 2f; + acceleration *= 2f; } - Vector2 npcCenter = new Vector2(NPC.Center.X, NPC.Center.Y); - float playerXDist = Main.player[NPC.target].Center.X - npcCenter.X; - float playerYDist = Main.player[NPC.target].Center.Y - npcCenter.Y - ((CalamityWorld.LegendaryMode && CalamityWorld.revenge) ? 500f : 400f); - float playerDistance = (float)Math.Sqrt(playerXDist * playerXDist + playerYDist * playerYDist); - if (playerDistance < ((CalamityWorld.LegendaryMode && CalamityWorld.revenge) ? 10f : 20f)) - { - playerXDist = NPC.velocity.X; - playerYDist = NPC.velocity.Y; - } - else - { - playerDistance = npcSpeed / playerDistance; - playerXDist *= playerDistance; - playerYDist *= playerDistance; - } - if (NPC.velocity.X < playerXDist) + if (NPC.position.Y > Main.player[NPC.target].position.Y - 350f) { - NPC.velocity.X = NPC.velocity.X + velocityMult; - if (NPC.velocity.X < 0f && playerXDist > 0f) - { - NPC.velocity.X = NPC.velocity.X + velocityMult * 2f; - } + if (NPC.velocity.Y > 0f) + NPC.velocity.Y *= 0.98f; + + NPC.velocity.Y -= acceleration; + + if (NPC.velocity.Y > velocity) + NPC.velocity.Y = velocity; } - else if (NPC.velocity.X > playerXDist) + else if (NPC.position.Y < Main.player[NPC.target].position.Y - 450f) { - NPC.velocity.X = NPC.velocity.X - velocityMult; - if (NPC.velocity.X > 0f && playerXDist < 0f) - { - NPC.velocity.X = NPC.velocity.X - velocityMult * 2f; - } + if (NPC.velocity.Y < 0f) + NPC.velocity.Y *= 0.98f; + + NPC.velocity.Y += acceleration; + + if (NPC.velocity.Y < -velocity) + NPC.velocity.Y = -velocity; } - if (NPC.velocity.Y < playerYDist) + + bool dropRain = NPC.Bottom < Main.player[NPC.target].position.Y - 200f && Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[NPC.target].position, Main.player[NPC.target].width, Main.player[NPC.target].height); + if (NPC.Center.X > Main.player[NPC.target].Center.X + 400f) { - NPC.velocity.Y = NPC.velocity.Y + velocityMult; - if (NPC.velocity.Y < 0f && playerYDist > 0f) - { - NPC.velocity.Y = NPC.velocity.Y + velocityMult * 2f; - } + dropRain = false; + + if (NPC.velocity.X > 0f) + NPC.velocity.X *= 0.98f; + + NPC.velocity.X -= acceleration; + + if (NPC.velocity.X > 8f) + NPC.velocity.X = 8f; } - else if (NPC.velocity.Y > playerYDist) + if (NPC.Center.X < Main.player[NPC.target].Center.X - 400f) { - NPC.velocity.Y = NPC.velocity.Y - velocityMult; - if (NPC.velocity.Y > 0f && playerYDist < 0f) - { - NPC.velocity.Y = NPC.velocity.Y - velocityMult * 2f; - } + dropRain = false; + + if (NPC.velocity.X < 0f) + NPC.velocity.X *= 0.98f; + + NPC.velocity.X += acceleration; + + if (NPC.velocity.X < -8f) + NPC.velocity.X = -8f; } - if (NPC.position.X + NPC.width > Main.player[NPC.target].position.X && NPC.position.X < Main.player[NPC.target].position.X + Main.player[NPC.target].width && NPC.position.Y + NPC.height < Main.player[NPC.target].position.Y && Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[NPC.target].position, Main.player[NPC.target].width, Main.player[NPC.target].height) && Main.netMode != NetmodeID.MultiplayerClient) + + if (dropRain && Main.netMode != NetmodeID.MultiplayerClient) { NPC.ai[0] += 1f; if (NPC.ai[0] >= (Main.getGoodWorld ? 12f : 24f)) @@ -143,15 +148,12 @@ public override void OnKill() public override void HitEffect(NPC.HitInfo hit) { for (int k = 0; k < 3; k++) - { Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Demonite, hit.HitDirection, -1f, 0, default, 1f); - } + if (NPC.life <= 0) { for (int k = 0; k < 20; k++) - { Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Demonite, hit.HitDirection, -1f, 0, default, 1f); - } } } } diff --git a/NPCs/HiveMind/HiveBlob.cs b/NPCs/HiveMind/HiveBlob.cs index cd07a4b5fe..06555527d3 100644 --- a/NPCs/HiveMind/HiveBlob.cs +++ b/NPCs/HiveMind/HiveBlob.cs @@ -54,6 +54,7 @@ public override void AI() NPC.damage = 0; bool expertMode = Main.expertMode || BossRushEvent.BossRushActive; + bool masterMode = Main.masterMode || BossRushEvent.BossRushActive; bool revenge = CalamityWorld.revenge || BossRushEvent.BossRushActive; bool death = CalamityWorld.death || BossRushEvent.BossRushActive; @@ -144,19 +145,24 @@ public override void AI() NPC.localAI[1] = 180f; NPC.localAI[1] += Main.rand.Next(2) + 1f; + if (masterMode) + NPC.localAI[1] += 1f; + if (NPC.localAI[1] >= 360f && Vector2.Distance(Main.player[NPC.target].Center, NPC.Center) > 80f) { NPC.localAI[1] = 0f; - NPC.TargetClosest(true); + NPC.TargetClosest(); if (Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[NPC.target].position, Main.player[NPC.target].width, Main.player[NPC.target].height)) { float projSpeed = death ? 5f : revenge ? 4.5f : expertMode ? 4f : 3.5f; + if (masterMode) + projSpeed += 2.5f; if (Main.getGoodWorld) projSpeed *= 2.4f; - Vector2 projDirection = new Vector2(NPC.position.X + NPC.width * 0.5f, NPC.position.Y + (NPC.height / 2)); - float playerX = Main.player[NPC.target].position.X + Main.player[NPC.target].width * 0.5f - projDirection.X; - float playerY = Main.player[NPC.target].position.Y + Main.player[NPC.target].height * 0.5f - projDirection.Y; + Vector2 projDirection = NPC.Center; + float playerX = Main.player[NPC.target].Center.X - projDirection.X; + float playerY = Main.player[NPC.target].Center.Y - projDirection.Y; float playerDist = (float)Math.Sqrt(playerX * playerX + playerY * playerY); playerDist = projSpeed / playerDist; playerX *= playerDist; diff --git a/NPCs/HiveMind/HiveBlob2.cs b/NPCs/HiveMind/HiveBlob2.cs index 1d704aa619..614b842a67 100644 --- a/NPCs/HiveMind/HiveBlob2.cs +++ b/NPCs/HiveMind/HiveBlob2.cs @@ -57,6 +57,7 @@ public override void AI() NPC.damage = 0; bool expertMode = Main.expertMode || BossRushEvent.BossRushActive; + bool masterMode = Main.masterMode || BossRushEvent.BossRushActive; bool revenge = CalamityWorld.revenge || BossRushEvent.BossRushActive; bool death = CalamityWorld.death || BossRushEvent.BossRushActive; @@ -147,19 +148,24 @@ public override void AI() NPC.localAI[1] = 180f; NPC.localAI[1] += Main.rand.Next(3) + 1f; + if (masterMode) + NPC.localAI[1] += 1f; + if (NPC.localAI[1] >= 360f && Vector2.Distance(Main.player[NPC.target].Center, NPC.Center) > 80f) { NPC.localAI[1] = 0f; - NPC.TargetClosest(true); + NPC.TargetClosest(); if (Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[NPC.target].position, Main.player[NPC.target].width, Main.player[NPC.target].height)) { float projSpeed = death ? 5f : revenge ? 4.5f : expertMode ? 4f : 3.5f; + if (masterMode) + projSpeed += 2.5f; if (Main.getGoodWorld) projSpeed *= 2.4f; - Vector2 projDirection = new Vector2(NPC.position.X + NPC.width * 0.5f, NPC.position.Y + (NPC.height / 2)); - float playerX = Main.player[NPC.target].position.X + Main.player[NPC.target].width * 0.5f - projDirection.X; - float playerY = Main.player[NPC.target].position.Y + Main.player[NPC.target].height * 0.5f - projDirection.Y; + Vector2 projDirection = NPC.Center; + float playerX = Main.player[NPC.target].Center.X - projDirection.X; + float playerY = Main.player[NPC.target].Center.Y - projDirection.Y; float playerDist = (float)Math.Sqrt(playerX * playerX + playerY * playerY); playerDist = projSpeed / playerDist; playerX *= playerDist; diff --git a/NPCs/HiveMind/HiveMind.cs b/NPCs/HiveMind/HiveMind.cs index fee10f41f3..db562fef6a 100644 --- a/NPCs/HiveMind/HiveMind.cs +++ b/NPCs/HiveMind/HiveMind.cs @@ -129,13 +129,19 @@ public override void SetDefaults() NPC.HitSound = SoundID.NPCHit1; NPC.DeathSound = SoundID.NPCDeath1; - if (Main.expertMode) + bool bossRush = BossRushEvent.BossRushActive; + bool expertMode = Main.expertMode || bossRush; + bool masterMode = Main.masterMode || bossRush; + bool revenge = CalamityWorld.revenge || bossRush; + bool death = CalamityWorld.death || bossRush; + + if (expertMode) { minimumDriftTime = 120; reelbackFade = 4; } - if (CalamityWorld.revenge) + if (revenge) { lungeRots = 0.3; minimumDriftTime = 90; @@ -145,17 +151,17 @@ public override void SetDefaults() driftBoost = 2f; } - if (CalamityWorld.death) + if (death) { lungeRots = 0.4; minimumDriftTime = 60; reelbackFade = 6; lungeTime = 23; - driftSpeed = 3f; - driftBoost = 1f; + driftSpeed = 3.5f; + driftBoost = 1.5f; } - if (BossRushEvent.BossRushActive) + if (bossRush) { lungeRots = 0.4; minimumDriftTime = 40; @@ -165,6 +171,16 @@ public override void SetDefaults() driftBoost = 1f; } + if (masterMode) + { + lungeRots += 0.1; + minimumDriftTime /= 2; + reelbackFade *= 2; + lungeTime -= 5; + driftSpeed += ((death && !bossRush) ? 0.5f : 1f); + driftBoost += ((death && !bossRush) ? 0.5f : 1f); + } + if (Main.getGoodWorld) { reelbackFade *= 10; @@ -319,7 +335,13 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d private void SpawnStuff() { - int maxSpawns = (CalamityWorld.death || BossRushEvent.BossRushActive) ? 5 : CalamityWorld.revenge ? 4 : Main.expertMode ? Main.rand.Next(3, 5) : Main.rand.Next(2, 4); + bool bossRush = BossRushEvent.BossRushActive; + bool expertMode = Main.expertMode || bossRush; + bool masterMode = Main.masterMode || bossRush; + bool revenge = CalamityWorld.revenge || bossRush; + bool death = CalamityWorld.death || bossRush; + + int maxSpawns = death ? 5 : revenge ? 4 : expertMode ? Main.rand.Next(3, 5) : Main.rand.Next(2, 4); for (int i = 0; i < maxSpawns; i++) { int type = NPCID.EaterofSouls; @@ -357,11 +379,14 @@ private void SpawnStuff() private void ReelBack() { + bool bossRush = BossRushEvent.BossRushActive; + bool revenge = CalamityWorld.revenge || bossRush; + NPC.alpha = 0; phase2timer = 0; deceleration = NPC.velocity / 255f * reelbackFade; - if (CalamityWorld.revenge || BossRushEvent.BossRushActive) + if (revenge) { state = 2; SoundEngine.PlaySound(FastRoarSound, NPC.Center); @@ -395,6 +420,7 @@ public override void AI() bool bossRush = BossRushEvent.BossRushActive; bool expertMode = Main.expertMode || bossRush; + bool masterMode = Main.masterMode || bossRush; bool revenge = CalamityWorld.revenge || bossRush; bool death = CalamityWorld.death || bossRush; @@ -691,7 +717,7 @@ public override void AI() else { reelCount++; - if (Main.expertMode && reelCount == 2) + if (expertMode && reelCount == 2) { reelCount = 0; nextState = 2; @@ -741,6 +767,15 @@ public override void AI() NPC.velocity = player.Center - NPC.Center; phase2timer--; + + // Use an attack sooner in expert mode if being hit + if (NPC.justHit && expertMode) + phase2timer--; + + // Use an attack sooner if target is close + if (NPC.Distance(player.Center) < 160f) + phase2timer -= 2; + if (phase2timer <= -180) // No stalling drift mode forever { NPC.velocity *= 2f / 255f * (reelbackFade + 2 * (int)enrageScale); @@ -779,7 +814,7 @@ public override void AI() NPC.position.Y = NPC.ai[2] * 16 - height_Phase2 / 2; } - phase2timer = minimumDriftTime + Main.rand.Next(121); + phase2timer = minimumDriftTime + Main.rand.Next(masterMode ? 61 : 121); NPC.netUpdate = true; NPC.netSpam = 0; } diff --git a/Projectiles/Melee/JudgementProj.cs b/Projectiles/Melee/JudgementProj.cs index 49de81f947..2f18c9c6ef 100644 --- a/Projectiles/Melee/JudgementProj.cs +++ b/Projectiles/Melee/JudgementProj.cs @@ -11,7 +11,7 @@ public class JudgementProj : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Melee"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; - int whiteLightTimer = 5; + int whiteLightTimer = 20; public override void SetDefaults() { @@ -41,15 +41,15 @@ public override void AI() for (i = 0; i < 1; i++) { offsetAngle = startAngle + deltaAngle * (i + i * i) / 2f + 32f * i; - int projectile1 = Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center.X, Projectile.Center.Y, (float)(Math.Sin(offsetAngle) * 5f), (float)(Math.Cos(offsetAngle) * 5f), ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner, 0f, 0f); - int projectile2 = Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center.X, Projectile.Center.Y, (float)(-Math.Sin(offsetAngle) * 5f), (float)(-Math.Cos(offsetAngle) * 5f), ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner, 0f, 0f); + int projectile1 = Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center.X, Projectile.Center.Y, (float)(Math.Sin(offsetAngle) * 5f), (float)(Math.Cos(offsetAngle) * 5f), ModContent.ProjectileType(), Projectile.damage / 2, Projectile.knockBack * 0.5f, Projectile.owner); + int projectile2 = Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center.X, Projectile.Center.Y, (float)(-Math.Sin(offsetAngle) * 5f), (float)(-Math.Cos(offsetAngle) * 5f), ModContent.ProjectileType(), Projectile.damage / 2, Projectile.knockBack * 0.5f, Projectile.owner); Main.projectile[projectile1].velocity.X *= 0.1f; Main.projectile[projectile1].velocity.Y *= 0.1f; Main.projectile[projectile2].velocity.X *= 0.1f; Main.projectile[projectile2].velocity.Y *= 0.1f; } } - whiteLightTimer = 5; + whiteLightTimer = 20; } Lighting.AddLight(Projectile.Center, (255 - Projectile.alpha) * 0.5f / 255f, (255 - Projectile.alpha) * 0.5f / 255f, (255 - Projectile.alpha) * 0.5f / 255f); @@ -69,9 +69,7 @@ public override void OnKill(int timeLeft) { SoundEngine.PlaySound(SoundID.Item122, Projectile.position); if (Projectile.owner == Main.myPlayer) - { - Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center.X, Projectile.Center.Y - 100, 0f, 0f, ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner, 0f, 0f); - } + Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center.X, Projectile.Center.Y - 100, 0f, 0f, ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner); } } } diff --git a/Projectiles/Melee/WhiteBoltAura.cs b/Projectiles/Melee/WhiteBoltAura.cs index d361a79873..4679ea9aa9 100644 --- a/Projectiles/Melee/WhiteBoltAura.cs +++ b/Projectiles/Melee/WhiteBoltAura.cs @@ -39,12 +39,13 @@ public override void AI() { int randOrbXOffset = (int)(Projectile.position.X + 14f + (float)Main.rand.Next(Projectile.width - 28)); int randOrbYOffset = (int)(Projectile.position.Y + (float)Projectile.height + 4f); - Projectile.NewProjectile(Projectile.GetSource_FromThis(), (float)randOrbXOffset, (float)randOrbYOffset, 0f, 5f, ModContent.ProjectileType(), Projectile.damage, 0f, Projectile.owner, 0f, 0f); + Projectile.NewProjectile(Projectile.GetSource_FromThis(), (float)randOrbXOffset, (float)randOrbYOffset, 0f, 5f, ModContent.ProjectileType(), Projectile.damage / 2, 0f, Projectile.owner, 0f, 0f); } } } + Projectile.localAI[0] += 1f; - if (Projectile.localAI[0] >= 10f) + if (Projectile.localAI[0] >= 20f) { Projectile.localAI[0] = 0f; int projTimer = 0; @@ -70,5 +71,7 @@ public override void AI() } } } + + public override bool? CanDamage() => false; } } From edc01eb99e896801f233cec0963f9558b3ac4030 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Tue, 28 May 2024 12:53:38 -0400 Subject: [PATCH 115/401] The Cauldron balance --- Items/Weapons/Magic/TheCauldron.cs | 6 +++--- Projectiles/Magic/CauldronHoldout.cs | 2 +- Projectiles/Magic/CauldronProj.cs | 7 ++++--- Projectiles/Magic/CauldronProjSmall.cs | 14 +++++++++----- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/Items/Weapons/Magic/TheCauldron.cs b/Items/Weapons/Magic/TheCauldron.cs index e2bb46fd41..c05c1dd41c 100644 --- a/Items/Weapons/Magic/TheCauldron.cs +++ b/Items/Weapons/Magic/TheCauldron.cs @@ -25,12 +25,12 @@ public override void SetDefaults() { Item.width = 46; Item.height = 46; - Item.damage = 64; + Item.damage = 59; Item.noMelee = true; Item.noUseGraphic = true; Item.useStyle = ItemUseStyleID.Swing; - Item.useAnimation = 46; - Item.useTime = 46; + Item.useAnimation = 60; + Item.useTime = 60; Item.knockBack = 8f; Item.mana = 18; Item.UseSound = SoundID.DD2_MonkStaffSwing; diff --git a/Projectiles/Magic/CauldronHoldout.cs b/Projectiles/Magic/CauldronHoldout.cs index d858664c9d..80d327c3ef 100644 --- a/Projectiles/Magic/CauldronHoldout.cs +++ b/Projectiles/Magic/CauldronHoldout.cs @@ -19,7 +19,7 @@ public class CauldronHoldout : ModProjectile, ILocalizedModType public override string Texture => "CalamityMod/Items/Weapons/Magic/TheCauldron"; - public static int FireRate = 46; + public static int FireRate = 60; public override void SetDefaults() { diff --git a/Projectiles/Magic/CauldronProj.cs b/Projectiles/Magic/CauldronProj.cs index 2c7dc86130..4c6b92ca08 100644 --- a/Projectiles/Magic/CauldronProj.cs +++ b/Projectiles/Magic/CauldronProj.cs @@ -69,13 +69,14 @@ public override void OnKill(int timeLeft) Projectile.penetrate = -1; Projectile.usesLocalNPCImmunity = true; Projectile.localNPCHitCooldown = 10; + Projectile.damage = (int)(Projectile.damage * 0.66f); Projectile.Damage(); if (Projectile.owner == Main.myPlayer) { for (int i = 0; i < 3; i++) { Vector2 smauldronSpeed = (Vector2.UnitY * Main.rand.NextFloat(-10f, -8f)).RotatedByRandom(MathHelper.ToRadians(30f)); - Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, smauldronSpeed, ModContent.ProjectileType(), Projectile.damage, 3f, Projectile.owner); + Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, smauldronSpeed, ModContent.ProjectileType(), (int)(Projectile.damage * 0.5f), 3f, Projectile.owner); // 33% damage } } for (int i = 0; i < 40; i++) @@ -97,8 +98,8 @@ public override bool PreDraw(ref Color lightColor) Main.EntitySpriteDraw(Glow.Value, Projectile.Center - Main.screenPosition, null, Color.White, Projectile.rotation, origin, Projectile.scale, SpriteEffects.None, 0); return false; } - public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) => target.AddBuff(BuffID.OnFire3, 180); + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) => target.AddBuff(BuffID.OnFire3, 90); - public override void OnHitPlayer(Player target, Player.HurtInfo info) => target.AddBuff(BuffID.OnFire3, 180); + public override void OnHitPlayer(Player target, Player.HurtInfo info) => target.AddBuff(BuffID.OnFire3, 90); } } diff --git a/Projectiles/Magic/CauldronProjSmall.cs b/Projectiles/Magic/CauldronProjSmall.cs index 0d3613fb04..e3d01d3509 100644 --- a/Projectiles/Magic/CauldronProjSmall.cs +++ b/Projectiles/Magic/CauldronProjSmall.cs @@ -36,9 +36,9 @@ public override void SetDefaults() public override void AI() { Projectile.ai[0] += 1f; - if (Projectile.ai[0] > 10f) + if (Projectile.ai[0] > 8f) { - Projectile.ai[0] = 10f; + Projectile.ai[0] = 8f; if (Projectile.velocity.Y == 0f && Projectile.velocity.X != 0f) { Projectile.velocity.X = Projectile.velocity.X * 0.97f; @@ -48,7 +48,7 @@ public override void AI() Projectile.netUpdate = true; } } - Projectile.velocity.Y += 0.3f; + Projectile.velocity.Y += 0.38f; } Projectile.rotation += Projectile.velocity.X * 0.05f; int dust = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.Torch, Scale: Main.rand.NextFloat(0.6f, 0.8f)); @@ -63,6 +63,7 @@ public override void OnKill(int timeLeft) Projectile.penetrate = -1; Projectile.usesLocalNPCImmunity = true; Projectile.localNPCHitCooldown = 10; + Projectile.damage /= 2; Projectile.Damage(); for (int i = 0; i < 10; i++) { @@ -82,8 +83,11 @@ public override bool PreDraw(ref Color lightColor) Main.EntitySpriteDraw(Glow.Value, Projectile.Center - Main.screenPosition, null, Color.White, Projectile.rotation, origin, Projectile.scale, SpriteEffects.None, 0); return false; } - public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) => target.AddBuff(BuffID.OnFire3, 180); - public override void OnHitPlayer(Player target, Player.HurtInfo info) => target.AddBuff(BuffID.OnFire3, 180); + public override bool? CanDamage() => Projectile.velocity.Y < 0f ? false : null; + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) => target.AddBuff(BuffID.OnFire3, 90); + + public override void OnHitPlayer(Player target, Player.HurtInfo info) => target.AddBuff(BuffID.OnFire3, 90); } } From a40772fa18326060476463f2d04bebd8c650feb3 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Tue, 28 May 2024 13:28:46 -0400 Subject: [PATCH 116/401] Respiteblock balance --- CalamityLists.cs | 1 + Projectiles/Melee/RespiteblockHoldout.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CalamityLists.cs b/CalamityLists.cs index b8ebd102e5..0fba8bdfb7 100644 --- a/CalamityLists.cs +++ b/CalamityLists.cs @@ -1943,6 +1943,7 @@ public static void LoadLists() ProjectileType(), ProjectileType(), ProjectileType(), + ProjectileType(), ProjectileType(), ProjectileType(), ProjectileType(), diff --git a/Projectiles/Melee/RespiteblockHoldout.cs b/Projectiles/Melee/RespiteblockHoldout.cs index 3c1a34d464..069743702f 100644 --- a/Projectiles/Melee/RespiteblockHoldout.cs +++ b/Projectiles/Melee/RespiteblockHoldout.cs @@ -78,7 +78,7 @@ public override void AI() } if (Time % 4 == 0) { - Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), Projectile.Center + (Projectile.velocity.RotatedBy(MathHelper.ToRadians(45f * Projectile.direction)) * 10) + Main.rand.NextVector2Circular(13, 13) + Projectile.velocity * Main.rand.Next(10, 20 + 1), Projectile.velocity.RotatedBy(Main.rand.NextFloat(-0.01f, -0.35f) * Projectile.direction) * 4, ModContent.ProjectileType(), Projectile.damage / 3, Projectile.knockBack, Projectile.owner, 0); + Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), Projectile.Center + (Projectile.velocity.RotatedBy(MathHelper.ToRadians(45f * Projectile.direction)) * 10) + Main.rand.NextVector2Circular(13, 13) + Projectile.velocity * Main.rand.Next(10, 20 + 1), Projectile.velocity.RotatedBy(Main.rand.NextFloat(-0.01f, -0.25f) * Projectile.direction) * 4, ModContent.ProjectileType(), (int)(Projectile.damage * 0.4f), Projectile.knockBack, Projectile.owner, 0); } DetermineVisuals(playerRotatedPosition); From 75e07238fb03c97670ee24f62a1f1eecd8d1149d Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Tue, 28 May 2024 14:33:40 -0400 Subject: [PATCH 117/401] Some more life regen tooltips that I missed --- Items/Accessories/StatMeter.cs | 2 +- Items/CalamityGlobalItemTooltip.cs | 2 ++ .../NebulaArmorSetChange.cs | 25 +++++++++++++++++++ .../PalladiumArmorSetChange.cs | 5 ++++ .../Mods.CalamityMod.Items.Accessories.hjson | 2 +- .../Mods.CalamityMod.Vanilla.Armor.hjson | 11 ++++++++ 6 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 Items/VanillaArmorChanges/NebulaArmorSetChange.cs diff --git a/Items/Accessories/StatMeter.cs b/Items/Accessories/StatMeter.cs index 9fc54df8eb..eb6eb0c6b2 100644 --- a/Items/Accessories/StatMeter.cs +++ b/Items/Accessories/StatMeter.cs @@ -213,7 +213,7 @@ public override void ModifyTooltips(List list) string stats3 = "\n" + this.GetLocalization("GenericStats").Format( player.GetCurrentDefense(false), TwoPlaces(100f * player.endurance), - player.lifeRegen, // Normally we'd divide this by 2 in Expert without Well Fed, but we disable that shit + OnePlace((float)player.lifeRegen / 2f), // Divided by 2 to show HP/s, because vanilla! Also normally we'd divide this by 2 in Expert without Well Fed, but we disable that shit Sign(moveSpeedBoost) + TwoPlaces(100f * moveSpeedBoost), TwoPlaces(20f * player.GetJumpBoost())); // Show wing stats only if over 0 flight time diff --git a/Items/CalamityGlobalItemTooltip.cs b/Items/CalamityGlobalItemTooltip.cs index 3cff630860..e41a3e87cc 100644 --- a/Items/CalamityGlobalItemTooltip.cs +++ b/Items/CalamityGlobalItemTooltip.cs @@ -920,6 +920,8 @@ void AddTooltip(string text) // Solar Flare if (item.type == ItemID.SolarFlareHelmet) EditTooltipByNum(0, (line) => line.Text = line.Text.Replace("26%", "20%")); + if (item.type == ItemID.SolarFlareHelmet || item.type == ItemID.SolarFlareBreastplate || item.type == ItemID.SolarFlareLeggings) + EditTooltipByNum(1, (line) => line.Text = "Grants +1 HP/s life regeneration"); // Vortex if (item.type == ItemID.VortexHelmet) diff --git a/Items/VanillaArmorChanges/NebulaArmorSetChange.cs b/Items/VanillaArmorChanges/NebulaArmorSetChange.cs new file mode 100644 index 0000000000..ebab9693fb --- /dev/null +++ b/Items/VanillaArmorChanges/NebulaArmorSetChange.cs @@ -0,0 +1,25 @@ +using System.Text; +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; + +namespace CalamityMod.Items.VanillaArmorChanges +{ + public class NebulaArmorSetChange : VanillaArmorChange + { + public override int? HeadPieceID => ItemID.NebulaHelmet; + + public override int? BodyPieceID => ItemID.NebulaBreastplate; + + public override int? LegPieceID => ItemID.NebulaLeggings; + + public override string ArmorSetName => "Nebula"; + + // The only thing this class does is change the set bonus text. + // Buff booster nerfs are handled separately as IL edits. + public override void UpdateSetBonusText(ref string setBonusText) + { + setBonusText += $"\n{CalamityUtils.GetTextValue($"Vanilla.Armor.SetBonus.{ArmorSetName}")}"; + } + } +} diff --git a/Items/VanillaArmorChanges/PalladiumArmorSetChange.cs b/Items/VanillaArmorChanges/PalladiumArmorSetChange.cs index 7d0756257c..064aa47036 100644 --- a/Items/VanillaArmorChanges/PalladiumArmorSetChange.cs +++ b/Items/VanillaArmorChanges/PalladiumArmorSetChange.cs @@ -28,5 +28,10 @@ public override void ApplyLegPieceEffect(Player player) { player.GetDamage() += LeggingsDamagePercentageBoost * 0.01f; } + + public override void UpdateSetBonusText(ref string setBonusText) + { + setBonusText = $"{CalamityUtils.GetTextValue($"Vanilla.Armor.SetBonus.{ArmorSetName}")}"; + } } } diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson index 3404dbabe0..ab9e5b1784 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson @@ -1721,7 +1721,7 @@ StatMeter: { // Other stats GenericStats: ''' - Defense: {0} | DR: {1}% | Life Regen: {2} + Defense: {0} | DR: {1}% | Life Regen: {2} HP/s Move Speed: {3}% | Jump Boost: {4}% ''' FlightTime: " | Wing Flight Time: {0} seconds" diff --git a/Localization/en-US/Mods.CalamityMod.Vanilla.Armor.hjson b/Localization/en-US/Mods.CalamityMod.Vanilla.Armor.hjson index f1625a0e8f..3e221f5442 100644 --- a/Localization/en-US/Mods.CalamityMod.Vanilla.Armor.hjson +++ b/Localization/en-US/Mods.CalamityMod.Vanilla.Armor.hjson @@ -88,6 +88,12 @@ SetBonus: { Enemy hits release mythril flares, which home in on enemies after a short delay Once a flare is created, there is a {0} frame delay before another one can appear ''' + Nebula: + ''' + Pink damage boosters grant 7.5% damage per stack + Orange life boosters grant +2 HP/s life regen per stack + Blue mana boosters grant +5 MP/s mana regen per stack + ''' Necro: ''' Allows you to temporarily survive fatal damage @@ -99,6 +105,11 @@ SetBonus: { Increases minion damage by 15% Grants immunity to fire blocks and temporary immunity to lava ''' + Palladium: + ''' + Grants +2 HP/s life regeneration after striking an enemy + This life regeneration bypasses negative life regeneration + ''' PlatinumChainmail: 3% increased critical strike chance Platinum: ''' From 86b510620f2f915667bc9d401d08328f0d41ba9e Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Tue, 28 May 2024 14:48:19 -0400 Subject: [PATCH 118/401] Actually just one more --- Items/CalamityGlobalItemTooltip.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Items/CalamityGlobalItemTooltip.cs b/Items/CalamityGlobalItemTooltip.cs index e41a3e87cc..3a07a6d2b9 100644 --- a/Items/CalamityGlobalItemTooltip.cs +++ b/Items/CalamityGlobalItemTooltip.cs @@ -323,6 +323,9 @@ void AddTooltip(string text) if (item.type == ItemID.HamBat) EditTooltipByNum(1, (line) => line.Text = "Defeating enemies temporarily grants +3 HP/s life regen"); + if (item.type == ItemID.AegisCrystal) + EditTooltipByNum(0, (line) => line.Text = "Permanently boosts natural life regeneration"); + // Warmth Potion provides debuff immunities if (item.type == ItemID.WarmthPotion) { From ea27524cc1e9e21ad5010a9d1549e36dc9bd23fe Mon Sep 17 00:00:00 2001 From: mochi-angel Date: Tue, 28 May 2024 12:16:26 -0700 Subject: [PATCH 119/401] Post-Evil2 Mage, Ranger and Rogue --- Balancing/BalancingChangesManager.cs | 5 +++++ Items/CalamityGlobalItemTweaks.cs | 6 +++--- Items/Weapons/DraedonsArsenal/PulsePistol.cs | 2 +- Items/Weapons/DraedonsArsenal/Taser.cs | 4 ++-- Items/Weapons/DraedonsArsenal/TrackingDisk.cs | 2 +- Items/Weapons/Magic/Tradewinds.cs | 4 ++-- Items/Weapons/Ranged/AquashardShotgun.cs | 2 +- Items/Weapons/Ranged/Eviscerator.cs | 2 +- Items/Weapons/Rogue/FeatherKnife.cs | 2 ++ Items/Weapons/Rogue/Turbulance.cs | 2 +- Projectiles/CalamityGlobalProjectileTweaks.cs | 9 +++++---- Projectiles/Magic/ShadeNimbusCloud.cs | 2 +- Projectiles/Magic/Shaderain.cs | 2 +- Projectiles/Ranged/Aquashard.cs | 3 ++- Projectiles/Ranged/AquashardSplit.cs | 7 ++++--- Projectiles/Ranged/BloodClotFriendly.cs | 4 ++-- Projectiles/Ranged/ShadeFire.cs | 2 +- Projectiles/Rogue/TurbulanceWindSlash.cs | 4 ++-- 18 files changed, 37 insertions(+), 27 deletions(-) diff --git a/Balancing/BalancingChangesManager.cs b/Balancing/BalancingChangesManager.cs index c36cc58ade..6612159240 100644 --- a/Balancing/BalancingChangesManager.cs +++ b/Balancing/BalancingChangesManager.cs @@ -119,6 +119,11 @@ bool AotCThrowCombo(Projectile p) => NPCSpecificBalancingChanges.AddRange(Bundle(CalamityLists.PerforatorIDs, Do(ResistTrueMelee(0.5f)))); #endregion + #region Slime God + //15% resist to Tradewings. + NPCSpecificBalancingChanges.AddRange(Bundle(CalamityLists.SlimeGodIDs, Do(new ProjectileResistBalancingRule(0.85f, ProjectileType())))); + #endregion + #region Wall of Flesh // 40% resist to Corro/Crimslime Staff. NPCSpecificBalancingChanges.Add(new NPCBalancingChange(NPCID.WallofFleshEye, Do(new ProjectileResistBalancingRule(0.6f, ProjectileType(), ProjectileType())))); diff --git a/Items/CalamityGlobalItemTweaks.cs b/Items/CalamityGlobalItemTweaks.cs index 7cb2d01cd2..4813480522 100644 --- a/Items/CalamityGlobalItemTweaks.cs +++ b/Items/CalamityGlobalItemTweaks.cs @@ -45,8 +45,8 @@ internal static void LoadTweaks() { ItemID.Bananarang, Do(DamageExact(76), UseExact(14)) }, { ItemID.BatScepter, Do(DamageExact(56)) }, { ItemID.BeamSword, Do(UseMeleeSpeed, DamageExact(142), UseAnimationExact(45), ShootSpeedExact(23f), KnockbackExact(8)) }, - { ItemID.BeeGun, Do(DamageExact(10), ManaExact(4)) }, - { ItemID.BeesKnees, Do(PointBlank, DamageExact(18), UseExact(38)) }, + { ItemID.BeeGun, Do(DamageExact(15), ManaExact(4)) }, + { ItemID.BeesKnees, Do(PointBlank, DamageExact(24), UseExact(38)) }, { ItemID.Bladetongue, Do(UseTurn, UseRatio(0.8f), DamageExact(120)) }, { ItemID.BlizzardStaff, Do(DamageExact(41), ManaExact(7)) }, { ItemID.BloodyMachete, Do(AutoReuse, DamageExact(24)) }, @@ -185,7 +185,7 @@ internal static void LoadTweaks() { ItemID.PalladiumSword, Do(UseTurn, DamageExact(100)) }, { ItemID.PearlwoodBow, Do(AutoReuse, PointBlank, DamageExact(20), UseDelta(+8), ShootSpeedDelta(+3.4f), KnockbackDelta(+1f)) }, { ItemID.PearlwoodSword, Do(UseTurn, DamageExact(45)) }, - { ItemID.PewMaticHorn, Do(DamageExact(24)) }, + { ItemID.PewMaticHorn, Do(DamageExact(25), ShootSpeedExact(15)) }, { ItemID.Phantasm, Do(PointBlank, DamageExact(48)) }, { ItemID.PhoenixBlaster, Do(AutoReuse, PointBlank, UseExact(18)) }, { ItemID.PiranhaGun, Do(DamageExact(48)) }, diff --git a/Items/Weapons/DraedonsArsenal/PulsePistol.cs b/Items/Weapons/DraedonsArsenal/PulsePistol.cs index 04e2185db0..40e91d117a 100644 --- a/Items/Weapons/DraedonsArsenal/PulsePistol.cs +++ b/Items/Weapons/DraedonsArsenal/PulsePistol.cs @@ -22,7 +22,7 @@ public override void SetDefaults() Item.width = 62; Item.height = 22; Item.DamageType = DamageClass.Magic; - Item.damage = 23; + Item.damage = 30; Item.knockBack = 0f; Item.useTime = Item.useAnimation = 21; Item.autoReuse = true; diff --git a/Items/Weapons/DraedonsArsenal/Taser.cs b/Items/Weapons/DraedonsArsenal/Taser.cs index 52c92a47a3..1fb627359e 100644 --- a/Items/Weapons/DraedonsArsenal/Taser.cs +++ b/Items/Weapons/DraedonsArsenal/Taser.cs @@ -21,7 +21,7 @@ public override void SetDefaults() Item.width = 50; Item.height = 26; Item.DamageType = DamageClass.Ranged; - Item.damage = 15; + Item.damage = 20; Item.knockBack = 0f; Item.useTime = Item.useAnimation = 28; Item.autoReuse = true; @@ -34,7 +34,7 @@ public override void SetDefaults() Item.rare = ItemRarityID.Orange; Item.shoot = ModContent.ProjectileType(); - Item.shootSpeed = 15f; + Item.shootSpeed = 25f; modItem.UsesCharge = true; modItem.MaxCharge = 50f; diff --git a/Items/Weapons/DraedonsArsenal/TrackingDisk.cs b/Items/Weapons/DraedonsArsenal/TrackingDisk.cs index f69d253b41..3292e3fc4b 100644 --- a/Items/Weapons/DraedonsArsenal/TrackingDisk.cs +++ b/Items/Weapons/DraedonsArsenal/TrackingDisk.cs @@ -22,7 +22,7 @@ public override void SetDefaults() Item.width = 30; Item.height = 34; - Item.damage = 16; + Item.damage = 19; Item.DamageType = RogueDamageClass.Instance; Item.useTime = 40; Item.useAnimation = 40; diff --git a/Items/Weapons/Magic/Tradewinds.cs b/Items/Weapons/Magic/Tradewinds.cs index 64a725372a..d88ac0f0ac 100644 --- a/Items/Weapons/Magic/Tradewinds.cs +++ b/Items/Weapons/Magic/Tradewinds.cs @@ -13,7 +13,7 @@ public override void SetDefaults() { Item.width = 28; Item.height = 30; - Item.damage = 23; + Item.damage = 30; Item.DamageType = DamageClass.Magic; Item.mana = 5; Item.useTime = 12; @@ -26,7 +26,7 @@ public override void SetDefaults() Item.UseSound = SoundID.Item7; Item.autoReuse = true; Item.shoot = ModContent.ProjectileType(); - Item.shootSpeed = 20f; + Item.shootSpeed = 25.5f; } public override void AddRecipes() diff --git a/Items/Weapons/Ranged/AquashardShotgun.cs b/Items/Weapons/Ranged/AquashardShotgun.cs index 55fe5c3db9..142c00c383 100644 --- a/Items/Weapons/Ranged/AquashardShotgun.cs +++ b/Items/Weapons/Ranged/AquashardShotgun.cs @@ -28,7 +28,7 @@ public override void SetDefaults() Item.UseSound = SoundID.Item61; Item.autoReuse = true; Item.shoot = ModContent.ProjectileType(); - Item.shootSpeed = 22f; + Item.shootSpeed = 30f; Item.useAmmo = AmmoID.Bullet; Item.Calamity().canFirePointBlankShots = true; } diff --git a/Items/Weapons/Ranged/Eviscerator.cs b/Items/Weapons/Ranged/Eviscerator.cs index 75849b1bb2..9dacc5018b 100644 --- a/Items/Weapons/Ranged/Eviscerator.cs +++ b/Items/Weapons/Ranged/Eviscerator.cs @@ -15,7 +15,7 @@ public override void SetDefaults() { Item.width = 58; Item.height = 22; - Item.damage = 65; + Item.damage = 70; Item.DamageType = DamageClass.Ranged; Item.useTime = 60; Item.useAnimation = 60; diff --git a/Items/Weapons/Rogue/FeatherKnife.cs b/Items/Weapons/Rogue/FeatherKnife.cs index 545601781a..c90f06dd71 100644 --- a/Items/Weapons/Rogue/FeatherKnife.cs +++ b/Items/Weapons/Rogue/FeatherKnife.cs @@ -38,6 +38,8 @@ public override void SetDefaults() Item.rare = ItemRarityID.Orange; } + public override float StealthDamageMultiplier => 0.80f; + public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) { if (player.Calamity().StealthStrikeAvailable()) //setting the stealth strike diff --git a/Items/Weapons/Rogue/Turbulance.cs b/Items/Weapons/Rogue/Turbulance.cs index 00536460cd..ce7c035e66 100644 --- a/Items/Weapons/Rogue/Turbulance.cs +++ b/Items/Weapons/Rogue/Turbulance.cs @@ -14,7 +14,7 @@ public override void SetDefaults() { Item.width = 14; Item.height = 14; - Item.damage = 18; + Item.damage = 28; Item.noMelee = true; Item.noUseGraphic = true; Item.useAnimation = 18; diff --git a/Projectiles/CalamityGlobalProjectileTweaks.cs b/Projectiles/CalamityGlobalProjectileTweaks.cs index 916a1412a8..d10155dc4f 100644 --- a/Projectiles/CalamityGlobalProjectileTweaks.cs +++ b/Projectiles/CalamityGlobalProjectileTweaks.cs @@ -116,7 +116,8 @@ internal static void LoadTweaks() { ProjectileID.AdamantiteChainsaw, standardChainsawTweaks }, { ProjectileID.AdamantiteDrill, standardDrillTweaks }, { ProjectileID.Anchor, Do(ExtraUpdatesExact(1)) }, - { ProjectileID.Bee, Do(PiercingExact(2)) }, + { ProjectileID.Bee, Do(PiercingExact(2), ExtraUpdatesExact(2)) }, + { ProjectileID.BeeArrow, Do(PointBlank, ExtraUpdatesExact(1)) }, { ProjectileID.BlackCounterweight, counterweightTweaks }, { ProjectileID.BlueCounterweight, counterweightTweaks }, { ProjectileID.BlueMoon, Do(ExtraUpdatesExact(1)) }, @@ -153,7 +154,7 @@ internal static void LoadTweaks() { ProjectileID.FlyingKnife, Do(ExtraUpdatesExact(1)) }, { ProjectileID.FrostBoltStaff, Do(ExtraUpdatesExact(1)) }, { ProjectileID.FruitcakeChakram, Do(ExtraUpdatesExact(1)) }, - { ProjectileID.GiantBee, Do(PiercingExact(2)) }, + { ProjectileID.GiantBee, Do(PiercingExact(2), ExtraUpdatesExact(2)) }, { ProjectileID.GoldenBullet, standardBulletTweaks }, { ProjectileID.GoldenShowerFriendly, Do(PiercingExact(2)) }, { ProjectileID.GreenCounterweight, counterweightTweaks }, @@ -209,6 +210,7 @@ internal static void LoadTweaks() { ProjectileID.VenomFang, Do(LocalIFrames(10)) }, { ProjectileID.VortexDrill, standardDrillTweaks }, { ProjectileID.Wasp, Do(PiercingExact(2)) }, + { ProjectileID.WeatherPainShot, Do(ExtraUpdatesExact(2), TimeLeftExact(1400)) }, { ProjectileID.YellowCounterweight, counterweightTweaks }, #endregion @@ -251,7 +253,6 @@ internal static void LoadTweaks() #endregion #region CATEGORY 4: Point Blank support - { ProjectileID.BeeArrow, pointBlank }, { ProjectileID.Blizzard, pointBlank }, // Blizzard Staff projectiles, re-used in Frostbite Blaster. { ProjectileID.BlueFlare, pointBlank }, { ProjectileID.BoneArrow, pointBlank }, @@ -268,8 +269,8 @@ internal static void LoadTweaks() { ProjectileID.Flare, pointBlank }, { ProjectileID.FrostburnArrow, pointBlank }, { ProjectileID.Harpoon, pointBlank }, - { ProjectileID.HellfireArrow, pointBlank }, { ProjectileID.Hellwing, pointBlank }, + { ProjectileID.HellfireArrow, pointBlank }, { ProjectileID.HolyArrow, pointBlank }, { ProjectileID.IchorArrow, pointBlank }, { ProjectileID.JestersArrow, pointBlank }, diff --git a/Projectiles/Magic/ShadeNimbusCloud.cs b/Projectiles/Magic/ShadeNimbusCloud.cs index 2556ed189a..a94a50d56c 100644 --- a/Projectiles/Magic/ShadeNimbusCloud.cs +++ b/Projectiles/Magic/ShadeNimbusCloud.cs @@ -60,7 +60,7 @@ public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.Demonite, 0, 0, 0, default, 0.5f); } - target.AddBuff(ModContent.BuffType(), 90); + target.AddBuff(ModContent.BuffType(), 120); } } } diff --git a/Projectiles/Magic/Shaderain.cs b/Projectiles/Magic/Shaderain.cs index c2c0650580..da5645ebb2 100644 --- a/Projectiles/Magic/Shaderain.cs +++ b/Projectiles/Magic/Shaderain.cs @@ -36,7 +36,7 @@ public override void AI() } public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { - target.AddBuff(ModContent.BuffType(), 120); + target.AddBuff(ModContent.BuffType(), 180); } } } diff --git a/Projectiles/Ranged/Aquashard.cs b/Projectiles/Ranged/Aquashard.cs index 4194e268b6..b07fbb4dd9 100644 --- a/Projectiles/Ranged/Aquashard.cs +++ b/Projectiles/Ranged/Aquashard.cs @@ -18,6 +18,7 @@ public override void SetDefaults() Projectile.penetrate = 1; Projectile.timeLeft = 300; Projectile.aiStyle = ProjAIStyleID.Arrow; + Projectile.extraUpdates = 1; Projectile.Calamity().pointBlankShotDuration = CalamityGlobalProjectile.DefaultPointBlankDuration; } @@ -35,7 +36,7 @@ public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) for (int i = 0; i < projAmt; i++) { Vector2 velocity = CalamityUtils.RandomVelocity(100f, 70f, 100f); - Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, velocity, ModContent.ProjectileType(), (int)(Projectile.damage * 0.4), 0f, Projectile.owner); + Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, velocity, ModContent.ProjectileType(), (int)(Projectile.damage * 0.6), 0f, Projectile.owner); } } } diff --git a/Projectiles/Ranged/AquashardSplit.cs b/Projectiles/Ranged/AquashardSplit.cs index f044a6e80b..0fc3c0e6eb 100644 --- a/Projectiles/Ranged/AquashardSplit.cs +++ b/Projectiles/Ranged/AquashardSplit.cs @@ -17,18 +17,19 @@ public override void SetDefaults() Projectile.friendly = true; Projectile.DamageType = DamageClass.Ranged; Projectile.penetrate = 1; - Projectile.timeLeft = 180; + Projectile.timeLeft = 300; + Projectile.extraUpdates = 1; Projectile.aiStyle = ProjAIStyleID.Arrow; } - public override bool? CanHitNPC(NPC target) => Projectile.timeLeft < 150 && target.CanBeChasedBy(Projectile); + public override bool? CanHitNPC(NPC target) => Projectile.timeLeft < 280 && target.CanBeChasedBy(Projectile); public override void AI() { Projectile.velocity.X *= 0.9995f; Projectile.velocity.Y += 0.01f; - if (Projectile.timeLeft < 150) + if (Projectile.timeLeft < 280) CalamityUtils.HomeInOnNPC(Projectile, !Projectile.tileCollide, 450f, Projectile.ai[1] == 1f ? 8f : 6f, 20f); } diff --git a/Projectiles/Ranged/BloodClotFriendly.cs b/Projectiles/Ranged/BloodClotFriendly.cs index 82c8855ae5..1d96edd43d 100644 --- a/Projectiles/Ranged/BloodClotFriendly.cs +++ b/Projectiles/Ranged/BloodClotFriendly.cs @@ -43,9 +43,9 @@ public override void AI() } } - public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) => target.AddBuff(ModContent.BuffType(), 90); + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) => target.AddBuff(ModContent.BuffType(), 240); - public override void OnHitPlayer(Player target, Player.HurtInfo info) => target.AddBuff(ModContent.BuffType(), 90); + public override void OnHitPlayer(Player target, Player.HurtInfo info) => target.AddBuff(ModContent.BuffType(), 240); public override bool PreDraw(ref Color lightColor) { diff --git a/Projectiles/Ranged/ShadeFire.cs b/Projectiles/Ranged/ShadeFire.cs index 0bb282dd6b..805fe68972 100644 --- a/Projectiles/Ranged/ShadeFire.cs +++ b/Projectiles/Ranged/ShadeFire.cs @@ -26,7 +26,7 @@ public override void SetDefaults() Projectile.MaxUpdates = 3; Projectile.timeLeft = Lifetime; // 20 effectively Projectile.usesIDStaticNPCImmunity = true; - Projectile.idStaticNPCHitCooldown = 15; + Projectile.idStaticNPCHitCooldown = 10; } public override void AI() diff --git a/Projectiles/Rogue/TurbulanceWindSlash.cs b/Projectiles/Rogue/TurbulanceWindSlash.cs index b3a9087d3e..59ecdedeb3 100644 --- a/Projectiles/Rogue/TurbulanceWindSlash.cs +++ b/Projectiles/Rogue/TurbulanceWindSlash.cs @@ -24,10 +24,10 @@ public override void SetDefaults() Projectile.alpha = 255; Projectile.ignoreWater = true; Projectile.DamageType = RogueDamageClass.Instance; - Projectile.timeLeft = 180; + Projectile.timeLeft = 240; } - public override bool? CanHitNPC(NPC target) => Projectile.timeLeft < 150 && target.CanBeChasedBy(Projectile); + public override bool? CanHitNPC(NPC target) => Projectile.timeLeft < 200 && target.CanBeChasedBy(Projectile); public override void AI() { From 27bbd5ca517d4bd7011b96b04aed3a0e8d0c7184 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Tue, 28 May 2024 15:35:36 -0400 Subject: [PATCH 120/401] Fixed Bandit and Cirrus not feeling the shrooms --- NPCs/TownNPCs/FAP.cs | 3 +++ NPCs/TownNPCs/THIEF.cs | 13 ++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/NPCs/TownNPCs/FAP.cs b/NPCs/TownNPCs/FAP.cs index 24b57edf9b..90bf0ba3b2 100644 --- a/NPCs/TownNPCs/FAP.cs +++ b/NPCs/TownNPCs/FAP.cs @@ -822,6 +822,9 @@ public override string GetChat() public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color drawColor) { + if (Main.LocalPlayer.Calamity().trippy) + return false; + var something = NPC.direction == -1 ? SpriteEffects.None : SpriteEffects.FlipHorizontally; spriteBatch.Draw(BirthdayParty.PartyIsUp ? AltTexture.Value : TextureAssets.Npc[NPC.type].Value, NPC.Center - screenPos + new Vector2(0, NPC.gfxOffY) - new Vector2(0f, 6f), NPC.frame, drawColor, NPC.rotation, NPC.frame.Size() / 2, NPC.scale, something, 0); return false; diff --git a/NPCs/TownNPCs/THIEF.cs b/NPCs/TownNPCs/THIEF.cs index c9ea97d8d4..ff591a3aea 100644 --- a/NPCs/TownNPCs/THIEF.cs +++ b/NPCs/TownNPCs/THIEF.cs @@ -103,12 +103,12 @@ public override bool CanTownNPCSpawn(int numTownNPCs) public override List SetNPCNameList() => new List() { // Patron names - "Xplizzy", // <@!98826096237109248> (Whitegiraffe#6342) - "Freakish", // <@!750363283520749598> (Freakish#0001) + "Xplizzy", // <@!98826096237109248> (whitegiraffe) + "Freakish", // <@!750363283520749598> (freak5650) "Calder", // <@!601897959176798228> (hardlightcaster) - "Hunter Jinx", // <@!757401399783850134> (Jinx_enthusiast#1580) - "Goose", // <@!591421917706321962> (DullElili#8016) - "Jackson", // <@!525827730646892549> (ChowChow, Sin of Sleep Schedules#1235) + "Hunter Jinx", // <@!757401399783850134> (dragonslayerornstein.) + "Goose", // <@!591421917706321962> (dullelili) + "Jackson", // <@!525827730646892549> (chowchow360) "Altarca", // <@!1140673052108128337> (altarca_27226_49175) "Jackie", // <@!353241811717718016> (jackalchan) @@ -244,6 +244,9 @@ public string Refund() public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color drawColor) { + if (Main.LocalPlayer.Calamity().trippy) + return false; + var something = NPC.direction == -1 ? SpriteEffects.None : SpriteEffects.FlipHorizontally; spriteBatch.Draw(BirthdayParty.PartyIsUp ? AltTexture.Value : TextureAssets.Npc[NPC.type].Value, NPC.Center - screenPos + new Vector2(0, NPC.gfxOffY) - new Vector2(0f, 6f), NPC.frame, drawColor, NPC.rotation, NPC.frame.Size() / 2, NPC.scale, something, 0); return false; From c9df771d52d27fd78a5f5d6650906763fadd6641 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Tue, 28 May 2024 16:25:03 -0400 Subject: [PATCH 121/401] Nerfed some stuff that I suspected (and confirmed through testing) got overbuffed --- Balancing/BalancingChangesManager.cs | 5 ----- Items/CalamityGlobalItemTweaks.cs | 2 +- Items/Weapons/DraedonsArsenal/PulsePistol.cs | 2 +- Items/Weapons/Magic/Tradewinds.cs | 2 +- Items/Weapons/Ranged/Shadethrower.cs | 2 +- 5 files changed, 4 insertions(+), 9 deletions(-) diff --git a/Balancing/BalancingChangesManager.cs b/Balancing/BalancingChangesManager.cs index 6612159240..c36cc58ade 100644 --- a/Balancing/BalancingChangesManager.cs +++ b/Balancing/BalancingChangesManager.cs @@ -119,11 +119,6 @@ bool AotCThrowCombo(Projectile p) => NPCSpecificBalancingChanges.AddRange(Bundle(CalamityLists.PerforatorIDs, Do(ResistTrueMelee(0.5f)))); #endregion - #region Slime God - //15% resist to Tradewings. - NPCSpecificBalancingChanges.AddRange(Bundle(CalamityLists.SlimeGodIDs, Do(new ProjectileResistBalancingRule(0.85f, ProjectileType())))); - #endregion - #region Wall of Flesh // 40% resist to Corro/Crimslime Staff. NPCSpecificBalancingChanges.Add(new NPCBalancingChange(NPCID.WallofFleshEye, Do(new ProjectileResistBalancingRule(0.6f, ProjectileType(), ProjectileType())))); diff --git a/Items/CalamityGlobalItemTweaks.cs b/Items/CalamityGlobalItemTweaks.cs index 4813480522..e71962751b 100644 --- a/Items/CalamityGlobalItemTweaks.cs +++ b/Items/CalamityGlobalItemTweaks.cs @@ -45,7 +45,7 @@ internal static void LoadTweaks() { ItemID.Bananarang, Do(DamageExact(76), UseExact(14)) }, { ItemID.BatScepter, Do(DamageExact(56)) }, { ItemID.BeamSword, Do(UseMeleeSpeed, DamageExact(142), UseAnimationExact(45), ShootSpeedExact(23f), KnockbackExact(8)) }, - { ItemID.BeeGun, Do(DamageExact(15), ManaExact(4)) }, + { ItemID.BeeGun, Do(DamageExact(13), ManaExact(4)) }, { ItemID.BeesKnees, Do(PointBlank, DamageExact(24), UseExact(38)) }, { ItemID.Bladetongue, Do(UseTurn, UseRatio(0.8f), DamageExact(120)) }, { ItemID.BlizzardStaff, Do(DamageExact(41), ManaExact(7)) }, diff --git a/Items/Weapons/DraedonsArsenal/PulsePistol.cs b/Items/Weapons/DraedonsArsenal/PulsePistol.cs index 40e91d117a..6c06402f6e 100644 --- a/Items/Weapons/DraedonsArsenal/PulsePistol.cs +++ b/Items/Weapons/DraedonsArsenal/PulsePistol.cs @@ -22,7 +22,7 @@ public override void SetDefaults() Item.width = 62; Item.height = 22; Item.DamageType = DamageClass.Magic; - Item.damage = 30; + Item.damage = 27; Item.knockBack = 0f; Item.useTime = Item.useAnimation = 21; Item.autoReuse = true; diff --git a/Items/Weapons/Magic/Tradewinds.cs b/Items/Weapons/Magic/Tradewinds.cs index d88ac0f0ac..1119ef868d 100644 --- a/Items/Weapons/Magic/Tradewinds.cs +++ b/Items/Weapons/Magic/Tradewinds.cs @@ -13,7 +13,7 @@ public override void SetDefaults() { Item.width = 28; Item.height = 30; - Item.damage = 30; + Item.damage = 27; Item.DamageType = DamageClass.Magic; Item.mana = 5; Item.useTime = 12; diff --git a/Items/Weapons/Ranged/Shadethrower.cs b/Items/Weapons/Ranged/Shadethrower.cs index ddb3786745..a3e0f85b9d 100644 --- a/Items/Weapons/Ranged/Shadethrower.cs +++ b/Items/Weapons/Ranged/Shadethrower.cs @@ -14,7 +14,7 @@ public override void SetDefaults() { Item.width = 76; Item.height = 30; - Item.damage = 23; + Item.damage = 22; Item.DamageType = DamageClass.Ranged; Item.useTime = 10; Item.useAnimation = 40; From f3984baf306c007188565722a021ac294e85febb Mon Sep 17 00:00:00 2001 From: mochi-angel Date: Tue, 28 May 2024 21:54:50 -0700 Subject: [PATCH 122/401] Everything but BBB --- Items/CalamityGlobalItemTweaks.cs | 4 ++-- Items/Weapons/Melee/AirSpinner.cs | 2 +- Items/Weapons/Melee/Aorta.cs | 2 +- Items/Weapons/Melee/GoldplumeSpear.cs | 6 +++--- Items/Weapons/Melee/PerfectDark.cs | 4 ++-- Items/Weapons/Melee/VeinBurster.cs | 4 ++-- Items/Weapons/Melee/WindBlade.cs | 2 +- Items/Weapons/Summon/DankStaff.cs | 2 +- Items/Weapons/Summon/FleshOfInfidelity.cs | 2 +- Projectiles/Melee/Feather.cs | 1 + Projectiles/Melee/Yoyos/AirSpinnerYoyo.cs | 2 +- Projectiles/Melee/Yoyos/AortaYoyo.cs | 2 +- Projectiles/Summon/FleshBlood.cs | 1 + 13 files changed, 18 insertions(+), 16 deletions(-) diff --git a/Items/CalamityGlobalItemTweaks.cs b/Items/CalamityGlobalItemTweaks.cs index e71962751b..107986fa4e 100644 --- a/Items/CalamityGlobalItemTweaks.cs +++ b/Items/CalamityGlobalItemTweaks.cs @@ -46,6 +46,7 @@ internal static void LoadTweaks() { ItemID.BatScepter, Do(DamageExact(56)) }, { ItemID.BeamSword, Do(UseMeleeSpeed, DamageExact(142), UseAnimationExact(45), ShootSpeedExact(23f), KnockbackExact(8)) }, { ItemID.BeeGun, Do(DamageExact(13), ManaExact(4)) }, + { ItemID.BeeKeeper, Do((UseTurn),DamageExact(32)) }, { ItemID.BeesKnees, Do(PointBlank, DamageExact(24), UseExact(38)) }, { ItemID.Bladetongue, Do(UseTurn, UseRatio(0.8f), DamageExact(120)) }, { ItemID.BlizzardStaff, Do(DamageExact(41), ManaExact(7)) }, @@ -127,7 +128,7 @@ internal static void LoadTweaks() { ItemID.HellwingBow, Do(PointBlank, DamageExact(16)) }, { ItemID.HighVelocityBullet, Do(DamageExact(13)) }, { ItemID.HiveFive, Do(AutoReuse, DamageExact(26)) }, - { ItemID.HornetStaff, Do(AutoReuse, DamageExact(13), UseExact(30)) }, + { ItemID.HornetStaff, Do(AutoReuse, DamageExact(18), UseExact(30)) }, { ItemID.IceBlade, Do(UseMeleeSpeed) }, { ItemID.IceBoomerang, Do(UseExact(25), ShootSpeedExact(9)) }, { ItemID.IceRod, Do(UseExact(6), DamageExact(30), ShootSpeedExact(20)) }, @@ -511,7 +512,6 @@ internal static void LoadTweaks() #region CATEGORY 7: Other Quality of Life (AutoReuse / UseTurn) { ItemID.Amarok, autoReuse }, { ItemID.BatBat, autoReuse }, - { ItemID.BeeKeeper, Do(UseTurn) }, { ItemID.BladeofGrass, Do(AutoReuse, UseTurn) }, { ItemID.BloodButcherer, Do(AutoReuse, UseTurn) }, { ItemID.BoneSword, Do(AutoReuse, UseTurn) }, diff --git a/Items/Weapons/Melee/AirSpinner.cs b/Items/Weapons/Melee/AirSpinner.cs index 9fff13ee27..1ab080f85e 100644 --- a/Items/Weapons/Melee/AirSpinner.cs +++ b/Items/Weapons/Melee/AirSpinner.cs @@ -21,7 +21,7 @@ public override void SetDefaults() Item.width = 28; Item.height = 28; Item.DamageType = DamageClass.MeleeNoSpeed; - Item.damage = 26; + Item.damage = 29; Item.knockBack = 4f; Item.useTime = 22; Item.useAnimation = 22; diff --git a/Items/Weapons/Melee/Aorta.cs b/Items/Weapons/Melee/Aorta.cs index 182dab333b..62b40b8710 100644 --- a/Items/Weapons/Melee/Aorta.cs +++ b/Items/Weapons/Melee/Aorta.cs @@ -21,7 +21,7 @@ public override void SetDefaults() Item.width = 30; Item.height = 26; Item.DamageType = DamageClass.MeleeNoSpeed; - Item.damage = 29; + Item.damage = 31; Item.knockBack = 4.25f; Item.useTime = 22; Item.useAnimation = 22; diff --git a/Items/Weapons/Melee/GoldplumeSpear.cs b/Items/Weapons/Melee/GoldplumeSpear.cs index d2b38a87c0..3bd09d84d9 100644 --- a/Items/Weapons/Melee/GoldplumeSpear.cs +++ b/Items/Weapons/Melee/GoldplumeSpear.cs @@ -18,14 +18,14 @@ public override void SetDefaults() { Item.width = 54; Item.height = 54; - Item.damage = 27; + Item.damage = 37; Item.DamageType = DamageClass.Melee; Item.noMelee = true; Item.useTurn = true; Item.noUseGraphic = true; - Item.useAnimation = 23; + Item.useAnimation = 28; Item.useStyle = ItemUseStyleID.Shoot; - Item.useTime = 23; + Item.useTime = 28; Item.knockBack = 5.75f; Item.UseSound = SoundID.Item1; Item.autoReuse = true; diff --git a/Items/Weapons/Melee/PerfectDark.cs b/Items/Weapons/Melee/PerfectDark.cs index 25216877bd..666b744d04 100644 --- a/Items/Weapons/Melee/PerfectDark.cs +++ b/Items/Weapons/Melee/PerfectDark.cs @@ -14,7 +14,7 @@ public override void SetDefaults() { Item.width = 50; Item.height = 50; - Item.damage = 26; + Item.damage = 29; Item.DamageType = DamageClass.Melee; Item.useAnimation = 24; Item.useStyle = ItemUseStyleID.Swing; @@ -26,7 +26,7 @@ public override void SetDefaults() Item.value = CalamityGlobalItem.RarityOrangeBuyPrice; Item.rare = ItemRarityID.Orange; Item.shoot = ModContent.ProjectileType(); - Item.shootSpeed = 12f; + Item.shootSpeed = 14.5f; } public override void OnHitNPC(Player player, NPC target, NPC.HitInfo hit, int damageDone) { diff --git a/Items/Weapons/Melee/VeinBurster.cs b/Items/Weapons/Melee/VeinBurster.cs index fe8d0adf61..206efd2059 100644 --- a/Items/Weapons/Melee/VeinBurster.cs +++ b/Items/Weapons/Melee/VeinBurster.cs @@ -14,7 +14,7 @@ public override void SetDefaults() { Item.width = 52; Item.height = 50; - Item.damage = 42; + Item.damage = 47; Item.DamageType = DamageClass.Melee; Item.useAnimation = 41; Item.useStyle = ItemUseStyleID.Swing; @@ -26,7 +26,7 @@ public override void SetDefaults() Item.value = CalamityGlobalItem.RarityOrangeBuyPrice; Item.rare = ItemRarityID.Orange; Item.shoot = ModContent.ProjectileType(); - Item.shootSpeed = 13f; + Item.shootSpeed = 16f; } public override void OnHitNPC(Player player, NPC target, NPC.HitInfo hit, int damageDone) { diff --git a/Items/Weapons/Melee/WindBlade.cs b/Items/Weapons/Melee/WindBlade.cs index 8676601b68..1a580759cc 100644 --- a/Items/Weapons/Melee/WindBlade.cs +++ b/Items/Weapons/Melee/WindBlade.cs @@ -27,7 +27,7 @@ public override void SetDefaults() Item.value = CalamityGlobalItem.RarityOrangeBuyPrice; Item.rare = ItemRarityID.Orange; Item.shoot = ModContent.ProjectileType(); - Item.shootSpeed = 3f; + Item.shootSpeed = 5f; } public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) diff --git a/Items/Weapons/Summon/DankStaff.cs b/Items/Weapons/Summon/DankStaff.cs index 3a40da3bcc..ad9e9a42a6 100644 --- a/Items/Weapons/Summon/DankStaff.cs +++ b/Items/Weapons/Summon/DankStaff.cs @@ -15,7 +15,7 @@ public override void SetDefaults() { Item.width = 58; Item.height = 58; - Item.damage = 9; + Item.damage = 14; Item.mana = 10; Item.useTime = Item.useAnimation = 30; Item.useStyle = ItemUseStyleID.Swing; diff --git a/Items/Weapons/Summon/FleshOfInfidelity.cs b/Items/Weapons/Summon/FleshOfInfidelity.cs index a0ed0e586b..1373817513 100644 --- a/Items/Weapons/Summon/FleshOfInfidelity.cs +++ b/Items/Weapons/Summon/FleshOfInfidelity.cs @@ -16,7 +16,7 @@ public override void SetDefaults() { Item.width = 42; Item.height = 42; - Item.damage = 15; + Item.damage = 20; Item.DamageType = DamageClass.Summon; Item.shoot = ModContent.ProjectileType(); Item.knockBack = 1f; diff --git a/Projectiles/Melee/Feather.cs b/Projectiles/Melee/Feather.cs index fade5444c1..507f59ee20 100644 --- a/Projectiles/Melee/Feather.cs +++ b/Projectiles/Melee/Feather.cs @@ -23,6 +23,7 @@ public override void SetDefaults() Projectile.penetrate = 1; Projectile.timeLeft = TimeLeft; Projectile.aiStyle = ProjAIStyleID.Arrow; + Projectile.extraUpdates = 1; } public override void AI() diff --git a/Projectiles/Melee/Yoyos/AirSpinnerYoyo.cs b/Projectiles/Melee/Yoyos/AirSpinnerYoyo.cs index 4475b6d6b5..f43f41c800 100644 --- a/Projectiles/Melee/Yoyos/AirSpinnerYoyo.cs +++ b/Projectiles/Melee/Yoyos/AirSpinnerYoyo.cs @@ -15,7 +15,7 @@ public class AirSpinnerYoyo : ModProjectile public override void SetStaticDefaults() { ProjectileID.Sets.YoyosLifeTimeMultiplier[Projectile.type] = 30f * MaxUpdates; - ProjectileID.Sets.YoyosMaximumRange[Projectile.type] = 320f; + ProjectileID.Sets.YoyosMaximumRange[Projectile.type] = 330f; ProjectileID.Sets.YoyosTopSpeed[Projectile.type] = 32f / MaxUpdates; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; diff --git a/Projectiles/Melee/Yoyos/AortaYoyo.cs b/Projectiles/Melee/Yoyos/AortaYoyo.cs index 50fc877468..64dd6c5d35 100644 --- a/Projectiles/Melee/Yoyos/AortaYoyo.cs +++ b/Projectiles/Melee/Yoyos/AortaYoyo.cs @@ -16,7 +16,7 @@ public class AortaYoyo : ModProjectile public override void SetStaticDefaults() { ProjectileID.Sets.YoyosLifeTimeMultiplier[Projectile.type] = 24f * MaxUpdates; - ProjectileID.Sets.YoyosMaximumRange[Projectile.type] = 320f; + ProjectileID.Sets.YoyosMaximumRange[Projectile.type] = 330f; ProjectileID.Sets.YoyosTopSpeed[Projectile.type] = 25f / MaxUpdates; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; diff --git a/Projectiles/Summon/FleshBlood.cs b/Projectiles/Summon/FleshBlood.cs index 1a850a0e03..cb94a352f8 100644 --- a/Projectiles/Summon/FleshBlood.cs +++ b/Projectiles/Summon/FleshBlood.cs @@ -22,6 +22,7 @@ public override void SetDefaults() Projectile.minion = true; Projectile.penetrate = 1; Projectile.timeLeft = LifeTime; + Projectile.extraUpdates = 1; Projectile.DamageType = DamageClass.Summon; } From 0439529eb767e199b287a98ddfa59199810202a7 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Wed, 29 May 2024 00:56:29 -0400 Subject: [PATCH 123/401] Fixed Dark Heart compile error --- NPCs/HiveMind/DarkHeart.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NPCs/HiveMind/DarkHeart.cs b/NPCs/HiveMind/DarkHeart.cs index c1dcf2d49f..a96a194763 100644 --- a/NPCs/HiveMind/DarkHeart.cs +++ b/NPCs/HiveMind/DarkHeart.cs @@ -96,7 +96,7 @@ public override void AI() NPC.velocity.Y = -velocity; } - bool dropRain = NPC.Bottom < Main.player[NPC.target].position.Y - 200f && Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[NPC.target].position, Main.player[NPC.target].width, Main.player[NPC.target].height); + bool dropRain = NPC.Bottom.Y < Main.player[NPC.target].position.Y - 200f && Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[NPC.target].position, Main.player[NPC.target].width, Main.player[NPC.target].height); if (NPC.Center.X > Main.player[NPC.target].Center.X + 400f) { dropRain = false; From eee4304e9fc655e3c092a8d84ecf64c0fc6824b4 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Wed, 29 May 2024 14:37:22 -0500 Subject: [PATCH 124/401] Hive Mind Hive Blob teleport with the Hive Mind, Hive Blobs keep up with Hive Mind's movements, Dark Heart limit, alpha caps. --- NPCs/HiveMind/HiveBlob.cs | 34 +++++++++++++++------- NPCs/HiveMind/HiveBlob2.cs | 34 +++++++++++++++------- NPCs/HiveMind/HiveMind.cs | 59 +++++++++++++++++++++++++++++++------- 3 files changed, 95 insertions(+), 32 deletions(-) diff --git a/NPCs/HiveMind/HiveBlob.cs b/NPCs/HiveMind/HiveBlob.cs index 06555527d3..38bec7c7e6 100644 --- a/NPCs/HiveMind/HiveBlob.cs +++ b/NPCs/HiveMind/HiveBlob.cs @@ -70,6 +70,8 @@ public override void AI() return; } + NPC.alpha = Main.npc[hiveMind].alpha; + if (NPC.ai[3] > 0f) hiveMind = (int)NPC.ai[3] - 1; @@ -86,15 +88,16 @@ public override void AI() } } - NPC.TargetClosest(true); + NPC.TargetClosest(); - float relocateSpeed = getFuckedAI ? 1.2f : death ? 0.8f : revenge ? 0.7f : expertMode ? 0.6f : 0.5f; + float hiveMindVelocity = Main.npc[hiveMind].velocity.Length(); + float relocateSpeed = (getFuckedAI ? 1.2f : death ? 0.8f : revenge ? 0.7f : expertMode ? 0.6f : 0.5f) + hiveMindVelocity * 0.0625f; Vector2 randomLocationVector = new Vector2(NPC.ai[0] * 16f + 8f, NPC.ai[1] * 16f + 8f); - float targetX = Main.player[NPC.target].position.X + (Main.player[NPC.target].width / 2) - (NPC.width / 2) - randomLocationVector.X; - float targetY = Main.player[NPC.target].position.Y + (Main.player[NPC.target].height / 2) - (NPC.height / 2) - randomLocationVector.Y; + float targetX = Main.player[NPC.target].Center.X - (NPC.width / 2) - randomLocationVector.X; + float targetY = Main.player[NPC.target].Center.Y - (NPC.height / 2) - randomLocationVector.Y; float targetDistance = (float)Math.Sqrt(targetX * targetX + targetY * targetY); - float hiveMindX = Main.npc[hiveMind].position.X + (Main.npc[hiveMind].width / 2); - float hiveMindY = Main.npc[hiveMind].position.Y + (Main.npc[hiveMind].height / 2); + float hiveMindX = Main.npc[hiveMind].Center.X; + float hiveMindY = Main.npc[hiveMind].Center.Y; Vector2 hiveMindPos = new Vector2(hiveMindX, hiveMindY); float randomPosX = hiveMindX + NPC.ai[0]; float randomPosY = hiveMindY + NPC.ai[1]; @@ -129,7 +132,7 @@ public override void AI() NPC.velocity.Y = NPC.velocity.Y * 0.8f; } - float velocityLimit = getFuckedAI ? 32f : 8f; + float velocityLimit = relocateSpeed * 16f; if (NPC.velocity.X > velocityLimit) NPC.velocity.X = velocityLimit; if (NPC.velocity.X < -velocityLimit) @@ -144,11 +147,18 @@ public override void AI() if (!Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[NPC.target].position, Main.player[NPC.target].width, Main.player[NPC.target].height)) NPC.localAI[1] = 180f; - NPC.localAI[1] += Main.rand.Next(2) + 1f; - if (masterMode) - NPC.localAI[1] += 1f; + float shootGateValue = 360f; + if (NPC.localAI[1] < shootGateValue) + { + NPC.localAI[1] += Main.rand.Next(2) + 1f; + if (masterMode) + NPC.localAI[1] += 1f; + } - if (NPC.localAI[1] >= 360f && Vector2.Distance(Main.player[NPC.target].Center, NPC.Center) > 80f) + if (NPC.alpha > 0) + return; + + if (NPC.localAI[1] >= shootGateValue && Vector2.Distance(Main.player[NPC.target].Center, NPC.Center) > 80f) { NPC.localAI[1] = 0f; NPC.TargetClosest(); @@ -182,6 +192,8 @@ public override void AI() } } + public override bool CanHitNPC(NPC target) => NPC.alpha == 0; // Can only be hit while fully visible + public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color drawColor) { SpriteEffects spriteEffects = SpriteEffects.None; diff --git a/NPCs/HiveMind/HiveBlob2.cs b/NPCs/HiveMind/HiveBlob2.cs index 614b842a67..4b860e61aa 100644 --- a/NPCs/HiveMind/HiveBlob2.cs +++ b/NPCs/HiveMind/HiveBlob2.cs @@ -73,6 +73,8 @@ public override void AI() return; } + NPC.alpha = Main.npc[hiveMind].alpha; + if (NPC.ai[3] > 0f) hiveMind = (int)NPC.ai[3] - 1; @@ -89,15 +91,16 @@ public override void AI() } } - NPC.TargetClosest(true); + NPC.TargetClosest(); - float relocateSpeed = getFuckedAI ? 1.2f : death ? 0.8f : revenge ? 0.7f : expertMode ? 0.6f : 0.5f; + float hiveMindVelocity = Main.npc[hiveMind].velocity.Length(); + float relocateSpeed = (getFuckedAI ? 1.2f : death ? 0.8f : revenge ? 0.7f : expertMode ? 0.6f : 0.5f) + hiveMindVelocity * 0.0625f; Vector2 randomRelocateVector = new Vector2(NPC.ai[0] * 16f + 8f, NPC.ai[1] * 16f + 8f); - float targetX = Main.player[NPC.target].position.X + (Main.player[NPC.target].width / 2) - (NPC.width / 2) - randomRelocateVector.X; - float targetY = Main.player[NPC.target].position.Y + (Main.player[NPC.target].height / 2) - (NPC.height / 2) - randomRelocateVector.Y; + float targetX = Main.player[NPC.target].Center.X - (NPC.width / 2) - randomRelocateVector.X; + float targetY = Main.player[NPC.target].Center.Y - (NPC.height / 2) - randomRelocateVector.Y; float targetDistance = (float)Math.Sqrt(targetX * targetX + targetY * targetY); - float hiveMindX = Main.npc[hiveMind].position.X + (Main.npc[hiveMind].width / 2); - float hiveMindY = Main.npc[hiveMind].position.Y + (Main.npc[hiveMind].height / 2); + float hiveMindX = Main.npc[hiveMind].Center.X; + float hiveMindY = Main.npc[hiveMind].Center.Y; Vector2 hiveMindPos = new Vector2(hiveMindX, hiveMindY); float randomPosX = hiveMindX + NPC.ai[0]; float randomPosY = hiveMindY + NPC.ai[1]; @@ -132,7 +135,7 @@ public override void AI() NPC.velocity.Y = NPC.velocity.Y * 0.8f; } - float velocityLimit = getFuckedAI ? 32f : 8f; + float velocityLimit = relocateSpeed * 16f; if (NPC.velocity.X > velocityLimit) NPC.velocity.X = velocityLimit; if (NPC.velocity.X < -velocityLimit) @@ -147,11 +150,18 @@ public override void AI() if (!Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[NPC.target].position, Main.player[NPC.target].width, Main.player[NPC.target].height)) NPC.localAI[1] = 180f; - NPC.localAI[1] += Main.rand.Next(3) + 1f; - if (masterMode) - NPC.localAI[1] += 1f; + float shootGateValue = 360f; + if (NPC.localAI[1] < shootGateValue) + { + NPC.localAI[1] += Main.rand.Next(3) + 1f; + if (masterMode) + NPC.localAI[1] += 1f; + } - if (NPC.localAI[1] >= 360f && Vector2.Distance(Main.player[NPC.target].Center, NPC.Center) > 80f) + if (NPC.alpha > 0) + return; + + if (NPC.localAI[1] >= shootGateValue && Vector2.Distance(Main.player[NPC.target].Center, NPC.Center) > 80f) { NPC.localAI[1] = 0f; NPC.TargetClosest(); @@ -185,6 +195,8 @@ public override void AI() } } + public override bool CanHitNPC(NPC target) => NPC.alpha == 0; // Can only be hit while fully visible + public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color drawColor) { SpriteEffects spriteEffects = SpriteEffects.None; diff --git a/NPCs/HiveMind/HiveMind.cs b/NPCs/HiveMind/HiveMind.cs index db562fef6a..8972d8a532 100644 --- a/NPCs/HiveMind/HiveMind.cs +++ b/NPCs/HiveMind/HiveMind.cs @@ -595,6 +595,8 @@ public override void AI() { NPC.scale += 0.0165f; NPC.alpha -= 4; + if (NPC.alpha < 0) + NPC.alpha = 0; int burrowedDust = Dust.NewDust(new Vector2(NPC.position.X, NPC.Center.Y), NPC.width, NPC.height / 2, DustID.Demonite, 0f, -3f, 100, default, 2.5f * NPC.scale); Main.dust[burrowedDust].velocity *= 2f; @@ -628,6 +630,16 @@ public override void AI() tilePosY++; NPC.position.Y += 16; } + + for (int i = 0; i < Main.maxNPCs; i++) + { + NPC hiveBlob = Main.npc[i]; + if (hiveBlob.active && (hiveBlob.type == ModContent.NPCType() || hiveBlob.type == ModContent.NPCType())) + { + hiveBlob.position.X = NPC.position.X; + hiveBlob.position.Y = NPC.position.Y; + } + } } NPC.netUpdate = true; NPC.netSpam = 0; @@ -636,6 +648,8 @@ public override void AI() { NPC.scale -= 0.0165f; NPC.alpha += 4; + if (NPC.alpha > 255) + NPC.alpha = 255; int burrowedDust = Dust.NewDust(new Vector2(NPC.position.X, NPC.Center.Y), NPC.width, NPC.height / 2, DustID.Demonite, 0f, -3f, 100, default, 2.5f * NPC.scale); Main.dust[burrowedDust].velocity *= 2f; @@ -678,7 +692,11 @@ public override void AI() NPC.damage = 0; if (NPC.alpha > 0) + { NPC.alpha -= 3; + if (NPC.alpha < 0) + NPC.alpha = 0; + } if (nextState == 0) { @@ -812,6 +830,16 @@ public override void AI() { NPC.position.X = NPC.ai[1] * 16 - NPC.width / 2; NPC.position.Y = NPC.ai[2] * 16 - height_Phase2 / 2; + + for (int i = 0; i < Main.maxNPCs; i++) + { + NPC hiveBlob = Main.npc[i]; + if (hiveBlob.active && (hiveBlob.type == ModContent.NPCType() || hiveBlob.type == ModContent.NPCType())) + { + hiveBlob.position.X = NPC.position.X; + hiveBlob.position.Y = NPC.position.Y; + } + } } phase2timer = minimumDriftTime + Main.rand.Next(masterMode ? 61 : 121); @@ -880,6 +908,8 @@ public override void AI() if (NPC.alpha > 0) { NPC.alpha -= lungeFade; + if (NPC.alpha < 0) + NPC.alpha = 0; if (Main.netMode != NetmodeID.MultiplayerClient) NPC.Center = player.Center + new Vector2(teleportRadius, 0).RotatedBy(rotation); @@ -938,12 +968,16 @@ public override void AI() if (NPC.alpha > 0) { - NPC.alpha -= 5; + NPC.alpha -= masterMode ? 10 : 5; + if (NPC.alpha < 0) + NPC.alpha = 0; + if (Main.netMode != NetmodeID.MultiplayerClient) { NPC.Center = player.Center; NPC.position.Y += teleportRadius; } + NPC.netUpdate = true; NPC.netSpam = 0; } @@ -972,24 +1006,25 @@ public override void AI() if (phase2timer == (int)arcTime / 6) { phase2timer = 0; - NPC.ai[0]++; + NPC.ai[0] += 1f; if (Main.netMode != NetmodeID.MultiplayerClient && Collision.CanHit(NPC.Center, 1, 1, player.position, player.width, player.height)) { - if (NPC.ai[0] == 2 || NPC.ai[0] == 4) + if (NPC.ai[0] == 2f || (NPC.ai[0] == 4f && death)) { - if (expertMode && !NPC.AnyNPCs(ModContent.NPCType())) + int maxHearts = revenge ? 2 : 1; + if (expertMode && NPC.CountNPCS(ModContent.NPCType()) < maxHearts) NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y, ModContent.NPCType()); } else if (!NPC.AnyNPCs(NPCID.EaterofSouls)) NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y, NPCID.EaterofSouls); } - if (NPC.ai[0] == 6) + if (NPC.ai[0] == 6f) { NPC.velocity = NPC.velocity.RotatedBy(MathHelper.Pi / arcTime * -rotationDirection); SpawnStuff(); state = 6; - NPC.ai[0] = 0; + NPC.ai[0] = 0f; deceleration = NPC.velocity / decelerationTime; } } @@ -1005,13 +1040,17 @@ public override void AI() if (NPC.alpha > 0) { - NPC.alpha -= 5; + NPC.alpha -= masterMode ? 10 : 5; + if (NPC.alpha < 0) + NPC.alpha = 0; + if (Main.netMode != NetmodeID.MultiplayerClient) { NPC.Center = player.Center; NPC.position.Y -= teleportRadius; NPC.position.X += teleportRadius * rotationDirection; } + NPC.netUpdate = true; NPC.netSpam = 0; } @@ -1038,7 +1077,7 @@ public override void AI() if (phase2timer == (int)arcTime / 20) { phase2timer = 0; - NPC.ai[0]++; + NPC.ai[0] += 1f; if (Main.netMode != NetmodeID.MultiplayerClient) { int type = ModContent.ProjectileType(); @@ -1048,10 +1087,10 @@ public override void AI() Projectile.NewProjectile(NPC.GetSource_FromAI(), cloudSpawnPos, randomVelocity, type, damage, 0, Main.myPlayer, 11f); } - if (NPC.ai[0] == 10) + if (NPC.ai[0] == 10f) { state = 6; - NPC.ai[0] = 0; + NPC.ai[0] = 0f; deceleration = NPC.velocity / decelerationTime; } } From a73da314701e2f60975b15bc940b1ae6a8030b3b Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Wed, 29 May 2024 17:34:29 -0500 Subject: [PATCH 125/401] More Hive Mind and Blob adjustments and fixes. --- NPCs/HiveMind/HiveBlob.cs | 30 +++++++++--------- NPCs/HiveMind/HiveBlob2.cs | 30 +++++++++--------- NPCs/HiveMind/HiveMind.cs | 65 +++++++++++++++++++++++++++++++++----- 3 files changed, 87 insertions(+), 38 deletions(-) diff --git a/NPCs/HiveMind/HiveBlob.cs b/NPCs/HiveMind/HiveBlob.cs index 38bec7c7e6..14d3a860b5 100644 --- a/NPCs/HiveMind/HiveBlob.cs +++ b/NPCs/HiveMind/HiveBlob.cs @@ -91,11 +91,10 @@ public override void AI() NPC.TargetClosest(); float hiveMindVelocity = Main.npc[hiveMind].velocity.Length(); - float relocateSpeed = (getFuckedAI ? 1.2f : death ? 0.8f : revenge ? 0.7f : expertMode ? 0.6f : 0.5f) + hiveMindVelocity * 0.0625f; - Vector2 randomLocationVector = new Vector2(NPC.ai[0] * 16f + 8f, NPC.ai[1] * 16f + 8f); - float targetX = Main.player[NPC.target].Center.X - (NPC.width / 2) - randomLocationVector.X; - float targetY = Main.player[NPC.target].Center.Y - (NPC.height / 2) - randomLocationVector.Y; - float targetDistance = (float)Math.Sqrt(targetX * targetX + targetY * targetY); + float relocateSpeed = getFuckedAI ? 1.2f : death ? 0.8f : revenge ? 0.7f : expertMode ? 0.6f : 0.5f; + float acceleration = 0.8f; + float distanceFromMind = Main.getGoodWorld ? 256f : 128f; + float hiveMindX = Main.npc[hiveMind].Center.X; float hiveMindY = Main.npc[hiveMind].Center.Y; Vector2 hiveMindPos = new Vector2(hiveMindX, hiveMindY); @@ -104,32 +103,33 @@ public override void AI() float finalRandPosX = randomPosX - hiveMindPos.X; float finalRandPosY = randomPosY - hiveMindPos.Y; float finalRandDistance = (float)Math.Sqrt(finalRandPosX * finalRandPosX + finalRandPosY * finalRandPosY); - finalRandDistance = (Main.getGoodWorld ? 256f : 128f) / finalRandDistance; + finalRandDistance = distanceFromMind / finalRandDistance; finalRandPosX *= finalRandDistance; finalRandPosY *= finalRandDistance; + if (NPC.position.X < hiveMindX + finalRandPosX) { - NPC.velocity.X = NPC.velocity.X + relocateSpeed; + NPC.velocity.X += relocateSpeed; if (NPC.velocity.X < 0f && finalRandPosX > 0f) - NPC.velocity.X = NPC.velocity.X * 0.8f; + NPC.velocity.X *= acceleration; } else if (NPC.position.X > hiveMindX + finalRandPosX) { - NPC.velocity.X = NPC.velocity.X - relocateSpeed; + NPC.velocity.X -= relocateSpeed; if (NPC.velocity.X > 0f && finalRandPosX < 0f) - NPC.velocity.X = NPC.velocity.X * 0.8f; + NPC.velocity.X *= acceleration; } if (NPC.position.Y < hiveMindY + finalRandPosY) { - NPC.velocity.Y = NPC.velocity.Y + relocateSpeed; + NPC.velocity.Y += relocateSpeed; if (NPC.velocity.Y < 0f && finalRandPosY > 0f) - NPC.velocity.Y = NPC.velocity.Y * 0.8f; + NPC.velocity.Y *= acceleration; } else if (NPC.position.Y > hiveMindY + finalRandPosY) { - NPC.velocity.Y = NPC.velocity.Y - relocateSpeed; + NPC.velocity.Y -= relocateSpeed; if (NPC.velocity.Y > 0f && finalRandPosY < 0f) - NPC.velocity.Y = NPC.velocity.Y * 0.8f; + NPC.velocity.Y *= acceleration; } float velocityLimit = relocateSpeed * 16f; @@ -209,7 +209,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color color = NPC.GetAlpha(drawColor); if (NPC.localAI[1] > 240f) - color = Color.Lerp(color, Color.Green, MathHelper.Clamp((NPC.localAI[1] - 240f) / 120f, 0f, 1f)); + color = Color.Lerp(color, Color.Green * NPC.Opacity, MathHelper.Clamp((NPC.localAI[1] - 240f) / 120f, 0f, 1f)); spriteBatch.Draw(texture, vector2, NPC.frame, color, NPC.rotation, vector, NPC.scale, spriteEffects, 0f); diff --git a/NPCs/HiveMind/HiveBlob2.cs b/NPCs/HiveMind/HiveBlob2.cs index 4b860e61aa..7774a4db71 100644 --- a/NPCs/HiveMind/HiveBlob2.cs +++ b/NPCs/HiveMind/HiveBlob2.cs @@ -94,11 +94,10 @@ public override void AI() NPC.TargetClosest(); float hiveMindVelocity = Main.npc[hiveMind].velocity.Length(); - float relocateSpeed = (getFuckedAI ? 1.2f : death ? 0.8f : revenge ? 0.7f : expertMode ? 0.6f : 0.5f) + hiveMindVelocity * 0.0625f; - Vector2 randomRelocateVector = new Vector2(NPC.ai[0] * 16f + 8f, NPC.ai[1] * 16f + 8f); - float targetX = Main.player[NPC.target].Center.X - (NPC.width / 2) - randomRelocateVector.X; - float targetY = Main.player[NPC.target].Center.Y - (NPC.height / 2) - randomRelocateVector.Y; - float targetDistance = (float)Math.Sqrt(targetX * targetX + targetY * targetY); + float relocateSpeed = getFuckedAI ? 1.2f : death ? 0.8f : revenge ? 0.7f : expertMode ? 0.6f : 0.5f; + float acceleration = 0.8f; + float distanceFromMind = Main.getGoodWorld ? 192f : 96f; + float hiveMindX = Main.npc[hiveMind].Center.X; float hiveMindY = Main.npc[hiveMind].Center.Y; Vector2 hiveMindPos = new Vector2(hiveMindX, hiveMindY); @@ -107,32 +106,33 @@ public override void AI() float finalRandPosX = randomPosX - hiveMindPos.X; float finalRandPosY = randomPosY - hiveMindPos.Y; float finalRandDistance = (float)Math.Sqrt(finalRandPosX * finalRandPosX + finalRandPosY * finalRandPosY); - finalRandDistance = (Main.getGoodWorld ? 192f : 96f) / finalRandDistance; + finalRandDistance = distanceFromMind / finalRandDistance; finalRandPosX *= finalRandDistance; finalRandPosY *= finalRandDistance; + if (NPC.position.X < hiveMindX + finalRandPosX) { - NPC.velocity.X = NPC.velocity.X + relocateSpeed; + NPC.velocity.X += relocateSpeed; if (NPC.velocity.X < 0f && finalRandPosX > 0f) - NPC.velocity.X = NPC.velocity.X * 0.8f; + NPC.velocity.X *= acceleration; } else if (NPC.position.X > hiveMindX + finalRandPosX) { - NPC.velocity.X = NPC.velocity.X - relocateSpeed; + NPC.velocity.X -= relocateSpeed; if (NPC.velocity.X > 0f && finalRandPosX < 0f) - NPC.velocity.X = NPC.velocity.X * 0.8f; + NPC.velocity.X *= acceleration; } if (NPC.position.Y < hiveMindY + finalRandPosY) { - NPC.velocity.Y = NPC.velocity.Y + relocateSpeed; + NPC.velocity.Y += relocateSpeed; if (NPC.velocity.Y < 0f && finalRandPosY > 0f) - NPC.velocity.Y = NPC.velocity.Y * 0.8f; + NPC.velocity.Y *= acceleration; } else if (NPC.position.Y > hiveMindY + finalRandPosY) { - NPC.velocity.Y = NPC.velocity.Y - relocateSpeed; + NPC.velocity.Y -= relocateSpeed; if (NPC.velocity.Y > 0f && finalRandPosY < 0f) - NPC.velocity.Y = NPC.velocity.Y * 0.8f; + NPC.velocity.Y *= acceleration; } float velocityLimit = relocateSpeed * 16f; @@ -212,7 +212,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color color = NPC.GetAlpha(drawColor); if (NPC.localAI[1] > 240f) - color = Color.Lerp(color, Color.Green, MathHelper.Clamp((NPC.localAI[1] - 240f) / 120f, 0f, 1f)); + color = Color.Lerp(color, Color.Green * NPC.Opacity, MathHelper.Clamp((NPC.localAI[1] - 240f) / 120f, 0f, 1f)); spriteBatch.Draw(texture, vector2, NPC.frame, color, NPC.rotation, vector, NPC.scale, spriteEffects, 0f); diff --git a/NPCs/HiveMind/HiveMind.cs b/NPCs/HiveMind/HiveMind.cs index 8972d8a532..0b98d73ab0 100644 --- a/NPCs/HiveMind/HiveMind.cs +++ b/NPCs/HiveMind/HiveMind.cs @@ -572,7 +572,7 @@ public override void AI() int fivePercentMinions = NPC.NewNPC(NPC.GetSource_FromAI(), x, y, type); Main.npc[fivePercentMinions].SetDefaults(type); if (Main.netMode == NetmodeID.Server && fivePercentMinions < Main.maxNPCs) - NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, fivePercentMinions, 0f, 0f, 0f, 0, 0, 0); + NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, fivePercentMinions); } return; @@ -830,15 +830,15 @@ public override void AI() { NPC.position.X = NPC.ai[1] * 16 - NPC.width / 2; NPC.position.Y = NPC.ai[2] * 16 - height_Phase2 / 2; + } - for (int i = 0; i < Main.maxNPCs; i++) + for (int i = 0; i < Main.maxNPCs; i++) + { + NPC hiveBlob = Main.npc[i]; + if (hiveBlob.active && (hiveBlob.type == ModContent.NPCType() || hiveBlob.type == ModContent.NPCType())) { - NPC hiveBlob = Main.npc[i]; - if (hiveBlob.active && (hiveBlob.type == ModContent.NPCType() || hiveBlob.type == ModContent.NPCType())) - { - hiveBlob.position.X = NPC.position.X; - hiveBlob.position.Y = NPC.position.Y; - } + hiveBlob.position.X = NPC.position.X; + hiveBlob.position.Y = NPC.position.Y; } } @@ -879,6 +879,16 @@ public override void AI() NPC.velocity = Vector2.Zero; dashStarted = false; + for (int i = 0; i < Main.maxNPCs; i++) + { + NPC hiveBlob = Main.npc[i]; + if (hiveBlob.active && (hiveBlob.type == ModContent.NPCType() || hiveBlob.type == ModContent.NPCType())) + { + hiveBlob.position.X = NPC.position.X; + hiveBlob.position.Y = NPC.position.Y; + } + } + if (revenge && lifeRatio < 0.53f) { state = nextState; @@ -914,6 +924,19 @@ public override void AI() if (Main.netMode != NetmodeID.MultiplayerClient) NPC.Center = player.Center + new Vector2(teleportRadius, 0).RotatedBy(rotation); + if (NPC.alpha == 255 - lungeFade) + { + for (int i = 0; i < Main.maxNPCs; i++) + { + NPC hiveBlob = Main.npc[i]; + if (hiveBlob.active && (hiveBlob.type == ModContent.NPCType() || hiveBlob.type == ModContent.NPCType())) + { + hiveBlob.position.X = NPC.position.X; + hiveBlob.position.Y = NPC.position.Y; + } + } + } + rotation += rotationIncrement * rotationDirection; phase2timer = lungeDelay; } @@ -978,6 +1001,19 @@ public override void AI() NPC.position.Y += teleportRadius; } + if (NPC.alpha == 255 - (masterMode ? 10 : 5)) + { + for (int i = 0; i < Main.maxNPCs; i++) + { + NPC hiveBlob = Main.npc[i]; + if (hiveBlob.active && (hiveBlob.type == ModContent.NPCType() || hiveBlob.type == ModContent.NPCType())) + { + hiveBlob.position.X = NPC.position.X; + hiveBlob.position.Y = NPC.position.Y; + } + } + } + NPC.netUpdate = true; NPC.netSpam = 0; } @@ -1051,6 +1087,19 @@ public override void AI() NPC.position.X += teleportRadius * rotationDirection; } + if (NPC.alpha == 255 - (masterMode ? 10 : 5)) + { + for (int i = 0; i < Main.maxNPCs; i++) + { + NPC hiveBlob = Main.npc[i]; + if (hiveBlob.active && (hiveBlob.type == ModContent.NPCType() || hiveBlob.type == ModContent.NPCType())) + { + hiveBlob.position.X = NPC.position.X; + hiveBlob.position.Y = NPC.position.Y; + } + } + } + NPC.netUpdate = true; NPC.netSpam = 0; } From 301805dbd2df5c51ea6f6b4ea90819bdebbc3e73 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <142704082+CongratsIsTrash@users.noreply.github.com> Date: Wed, 29 May 2024 16:11:26 -0400 Subject: [PATCH 126/401] Ice Golems no longer inflict Glacial State --- CalPlayer/CalamityPlayerHitHurt.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CalPlayer/CalamityPlayerHitHurt.cs b/CalPlayer/CalamityPlayerHitHurt.cs index 7430951616..a9660d4c5b 100644 --- a/CalPlayer/CalamityPlayerHitHurt.cs +++ b/CalPlayer/CalamityPlayerHitHurt.cs @@ -1306,10 +1306,6 @@ public override void OnHitByProjectile(Projectile proj, Player.HurtInfo hurtInfo { Player.AddBuff(BuffID.BrokenArmor, 600); } - else if (proj.type == ProjectileID.FrostBeam && !Player.frozen && !gState) - { - Player.AddBuff(ModContent.BuffType(), 60); - } else if (proj.type == ProjectileID.DeathLaser || proj.type == ProjectileID.RocketSkeleton || proj.type == ProjectileID.BombSkeletronPrime) { Player.AddBuff(BuffID.OnFire, 180); From 6bd84f882a057756b8337d6028d64f3f2ad02b6e Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Wed, 29 May 2024 16:23:54 -0400 Subject: [PATCH 127/401] Cultist's ice mists can't freeze you if you're already frozen Not like it does that much in the long run but I'd rather it exist than not --- CalPlayer/CalamityPlayerHitHurt.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CalPlayer/CalamityPlayerHitHurt.cs b/CalPlayer/CalamityPlayerHitHurt.cs index a9660d4c5b..c0ff47501d 100644 --- a/CalPlayer/CalamityPlayerHitHurt.cs +++ b/CalPlayer/CalamityPlayerHitHurt.cs @@ -1341,7 +1341,9 @@ public override void OnHitByProjectile(Projectile proj, Player.HurtInfo hurtInfo } else if (proj.type == ProjectileID.CultistBossIceMist) { - Player.AddBuff(BuffID.Frozen, 60); + if (!Player.frozen) + Player.AddBuff(BuffID.Frozen, 60); + Player.AddBuff(BuffID.Chilled, 180); } else if (proj.type == ProjectileID.CultistBossLightningOrbArc) From 976a82eabcb31378c2bafa8335a37ae277d04783 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Wed, 29 May 2024 16:47:13 -0400 Subject: [PATCH 128/401] Statis' Blessing no longer inflicts Holy Flames Buffed summon damage boost to compensate --- CalPlayer/CalamityPlayerOnHit.cs | 3 --- Items/Accessories/StatisBlessing.cs | 2 +- Items/Accessories/StatisCurse.cs | 2 +- .../en-US/Mods.CalamityMod.Items.Accessories.hjson | 7 +++---- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/CalPlayer/CalamityPlayerOnHit.cs b/CalPlayer/CalamityPlayerOnHit.cs index d4463c46bd..3452552dab 100644 --- a/CalPlayer/CalamityPlayerOnHit.cs +++ b/CalPlayer/CalamityPlayerOnHit.cs @@ -1237,9 +1237,6 @@ public void NPCDebuffs(NPC target, bool melee, bool ranged, bool magic, bool sum if (divineBless) target.AddBuff(BuffType(), 60); - if (holyMinions) - target.AddBuff(BuffType(), 180); - if (shadowMinions) target.AddBuff(BuffID.ShadowFlame, 180); diff --git a/Items/Accessories/StatisBlessing.cs b/Items/Accessories/StatisBlessing.cs index 72fa58ce65..a08ba8d9a7 100644 --- a/Items/Accessories/StatisBlessing.cs +++ b/Items/Accessories/StatisBlessing.cs @@ -24,7 +24,7 @@ public override void UpdateAccessory(Player player, bool hideVisual) CalamityPlayer modPlayer = player.Calamity(); modPlayer.holyMinions = true; player.GetKnockback() += 2.5f; - player.GetDamage() += 0.1f; + player.GetDamage() += 0.12f; } public override void AddRecipes() diff --git a/Items/Accessories/StatisCurse.cs b/Items/Accessories/StatisCurse.cs index e16ebd5b2e..efe65bb8df 100644 --- a/Items/Accessories/StatisCurse.cs +++ b/Items/Accessories/StatisCurse.cs @@ -35,7 +35,7 @@ public override void UpdateAccessory(Player player, bool hideVisual) modPlayer.shadowMinions = true; modPlayer.holyMinions = true; player.GetKnockback() += 2.75f; - player.GetDamage() += 0.1f; + player.GetDamage() += 0.12f; player.buffImmune[ModContent.BuffType()] = true; } diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson index ab9e5b1784..2e9be4b5ab 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson @@ -1616,9 +1616,8 @@ StatisBlessing: { DisplayName: Statis' Blessing Tooltip: ''' - Increased max minions by 2 and 10% increased summon damage + Increased max minions by 2 and 12% increased summon damage Increased minion knockback - Minions inflict holy flames on hit ''' } @@ -1627,9 +1626,9 @@ StatisCurse: { Tooltip: ''' Increases max minions by 3, does not stack with downgrades - 10% increased summon damage + 12% increased summon damage Increased minion knockback - Minions inflict holy flames and shadowflames on hit + Minions inflict shadowflames on hit Grants immunity to Shadowflame ''' } From c582ca68eb82bf39e6a9edab0573b7d218ea3e71 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Wed, 29 May 2024 17:46:08 -0400 Subject: [PATCH 129/401] Judgement balancing --- Items/Weapons/Melee/GreatswordofJudgement.cs | 2 +- Projectiles/Melee/JudgementProj.cs | 8 ++++---- Projectiles/Melee/WhiteBoltAura.cs | 2 +- Projectiles/Melee/WhiteOrb.cs | 12 +++++------- Projectiles/Melee/Whiterain.cs | 2 +- 5 files changed, 12 insertions(+), 14 deletions(-) diff --git a/Items/Weapons/Melee/GreatswordofJudgement.cs b/Items/Weapons/Melee/GreatswordofJudgement.cs index 1732260e9d..b2ded44e87 100644 --- a/Items/Weapons/Melee/GreatswordofJudgement.cs +++ b/Items/Weapons/Melee/GreatswordofJudgement.cs @@ -11,7 +11,7 @@ public override void SetDefaults() { Item.width = 78; Item.height = 78; - Item.damage = 40; + Item.damage = 85; Item.DamageType = DamageClass.Melee; Item.useAnimation = 18; Item.useStyle = ItemUseStyleID.Swing; diff --git a/Projectiles/Melee/JudgementProj.cs b/Projectiles/Melee/JudgementProj.cs index 2f18c9c6ef..0137b32032 100644 --- a/Projectiles/Melee/JudgementProj.cs +++ b/Projectiles/Melee/JudgementProj.cs @@ -11,7 +11,7 @@ public class JudgementProj : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Melee"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; - int whiteLightTimer = 20; + int whiteLightTimer = 15; public override void SetDefaults() { @@ -20,7 +20,7 @@ public override void SetDefaults() Projectile.friendly = true; Projectile.ignoreWater = true; Projectile.penetrate = -1; - Projectile.timeLeft = 60; + Projectile.timeLeft = 90; Projectile.DamageType = DamageClass.Melee; Projectile.usesIDStaticNPCImmunity = true; Projectile.idStaticNPCHitCooldown = 10; @@ -49,7 +49,7 @@ public override void AI() Main.projectile[projectile2].velocity.Y *= 0.1f; } } - whiteLightTimer = 20; + whiteLightTimer = 15; } Lighting.AddLight(Projectile.Center, (255 - Projectile.alpha) * 0.5f / 255f, (255 - Projectile.alpha) * 0.5f / 255f, (255 - Projectile.alpha) * 0.5f / 255f); @@ -62,7 +62,7 @@ public override void AI() Main.dust[shinyDust].velocity += Projectile.velocity * 0.1f; } - CalamityUtils.HomeInOnNPC(Projectile, !Projectile.tileCollide, 200f, 9f, 20f); + CalamityUtils.HomeInOnNPC(Projectile, !Projectile.tileCollide, 200f, 10f, 20f); } public override void OnKill(int timeLeft) diff --git a/Projectiles/Melee/WhiteBoltAura.cs b/Projectiles/Melee/WhiteBoltAura.cs index 4679ea9aa9..f6778cd633 100644 --- a/Projectiles/Melee/WhiteBoltAura.cs +++ b/Projectiles/Melee/WhiteBoltAura.cs @@ -39,7 +39,7 @@ public override void AI() { int randOrbXOffset = (int)(Projectile.position.X + 14f + (float)Main.rand.Next(Projectile.width - 28)); int randOrbYOffset = (int)(Projectile.position.Y + (float)Projectile.height + 4f); - Projectile.NewProjectile(Projectile.GetSource_FromThis(), (float)randOrbXOffset, (float)randOrbYOffset, 0f, 5f, ModContent.ProjectileType(), Projectile.damage / 2, 0f, Projectile.owner, 0f, 0f); + Projectile.NewProjectile(Projectile.GetSource_FromThis(), (float)randOrbXOffset, (float)randOrbYOffset, 0f, 5f, ModContent.ProjectileType(), Projectile.damage, 0f, Projectile.owner, 0f, 0f); } } } diff --git a/Projectiles/Melee/WhiteOrb.cs b/Projectiles/Melee/WhiteOrb.cs index 84ae9ebcf4..75df233253 100644 --- a/Projectiles/Melee/WhiteOrb.cs +++ b/Projectiles/Melee/WhiteOrb.cs @@ -25,13 +25,11 @@ public override void SetDefaults() public override void AI() { Lighting.AddLight(Projectile.Center, 0.2f, 0.2f, 0.2f); - for (int i = 0; i < 2; i++) - { - int shiny = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.GemDiamond, 0f, 0f, 100, default, 1.25f); - Main.dust[shiny].noGravity = true; - Main.dust[shiny].velocity *= 0.5f; - Main.dust[shiny].velocity += Projectile.velocity * 0.1f; - } + + int shiny = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.GemDiamond, 0f, 0f, 100, default, 1.25f); + Main.dust[shiny].noGravity = true; + Main.dust[shiny].velocity *= 0.5f; + Main.dust[shiny].velocity += Projectile.velocity * 0.1f; } } } diff --git a/Projectiles/Melee/Whiterain.cs b/Projectiles/Melee/Whiterain.cs index 6e7978918c..1b5cacdb91 100644 --- a/Projectiles/Melee/Whiterain.cs +++ b/Projectiles/Melee/Whiterain.cs @@ -41,7 +41,7 @@ public override void AI() Main.dust[shiny].velocity += Projectile.velocity * 0.1f; } - CalamityUtils.HomeInOnNPC(Projectile, true, 200f, 12f, 20f); + CalamityUtils.HomeInOnNPC(Projectile, true, 320f, 14f, 20f); } } } From 5f13039edb3e9c10d4dd9391a9b1373f0a39203e Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Wed, 29 May 2024 17:45:42 -0500 Subject: [PATCH 130/401] Minor Hive Mind edit --- NPCs/HiveMind/HiveMind.cs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/NPCs/HiveMind/HiveMind.cs b/NPCs/HiveMind/HiveMind.cs index 0b98d73ab0..36bfa89073 100644 --- a/NPCs/HiveMind/HiveMind.cs +++ b/NPCs/HiveMind/HiveMind.cs @@ -917,14 +917,10 @@ public override void AI() NPC.netSpam = 0; if (NPC.alpha > 0) { - NPC.alpha -= lungeFade; - if (NPC.alpha < 0) - NPC.alpha = 0; - if (Main.netMode != NetmodeID.MultiplayerClient) NPC.Center = player.Center + new Vector2(teleportRadius, 0).RotatedBy(rotation); - if (NPC.alpha == 255 - lungeFade) + if (NPC.alpha == 255) { for (int i = 0; i < Main.maxNPCs; i++) { @@ -939,6 +935,10 @@ public override void AI() rotation += rotationIncrement * rotationDirection; phase2timer = lungeDelay; + + NPC.alpha -= lungeFade; + if (NPC.alpha < 0) + NPC.alpha = 0; } else { @@ -991,17 +991,13 @@ public override void AI() if (NPC.alpha > 0) { - NPC.alpha -= masterMode ? 10 : 5; - if (NPC.alpha < 0) - NPC.alpha = 0; - if (Main.netMode != NetmodeID.MultiplayerClient) { NPC.Center = player.Center; NPC.position.Y += teleportRadius; } - if (NPC.alpha == 255 - (masterMode ? 10 : 5)) + if (NPC.alpha == 255) { for (int i = 0; i < Main.maxNPCs; i++) { @@ -1014,6 +1010,10 @@ public override void AI() } } + NPC.alpha -= masterMode ? 10 : 5; + if (NPC.alpha < 0) + NPC.alpha = 0; + NPC.netUpdate = true; NPC.netSpam = 0; } @@ -1076,10 +1076,6 @@ public override void AI() if (NPC.alpha > 0) { - NPC.alpha -= masterMode ? 10 : 5; - if (NPC.alpha < 0) - NPC.alpha = 0; - if (Main.netMode != NetmodeID.MultiplayerClient) { NPC.Center = player.Center; @@ -1087,7 +1083,7 @@ public override void AI() NPC.position.X += teleportRadius * rotationDirection; } - if (NPC.alpha == 255 - (masterMode ? 10 : 5)) + if (NPC.alpha == 255) { for (int i = 0; i < Main.maxNPCs; i++) { @@ -1100,6 +1096,10 @@ public override void AI() } } + NPC.alpha -= masterMode ? 10 : 5; + if (NPC.alpha < 0) + NPC.alpha = 0; + NPC.netUpdate = true; NPC.netSpam = 0; } From bea920500d4202cf3524ae89b9acfb8575c519ae Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Wed, 29 May 2024 18:34:35 -0500 Subject: [PATCH 131/401] Cryogen Ice Bombs cannot Glacial State stunlock you. --- Projectiles/Boss/IceBomb.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Projectiles/Boss/IceBomb.cs b/Projectiles/Boss/IceBomb.cs index d963860aff..ce60e05cb7 100644 --- a/Projectiles/Boss/IceBomb.cs +++ b/Projectiles/Boss/IceBomb.cs @@ -101,7 +101,9 @@ public override void OnHitPlayer(Player target, Player.HurtInfo info) { target.AddBuff(BuffID.Frostburn, 180, true); target.AddBuff(BuffID.Chilled, 90, true); - target.AddBuff(ModContent.BuffType(), 60); + + if (!target.Calamity().gState) + target.AddBuff(ModContent.BuffType(), 60); } } } From da2c458d4d817800957056a1a0be598664df9554 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Wed, 29 May 2024 19:12:31 -0500 Subject: [PATCH 132/401] Only Ceaseless Void itself inflicts Distorted now, and only while succing. --- NPCs/CeaselessVoid/CeaselessVoid.cs | 6 ++++++ NPCs/CeaselessVoid/DarkEnergy.cs | 9 +++++---- Projectiles/Boss/DarkEnergyBall.cs | 6 ++---- Projectiles/Boss/DarkEnergyBall2.cs | 6 ++---- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/NPCs/CeaselessVoid/CeaselessVoid.cs b/NPCs/CeaselessVoid/CeaselessVoid.cs index 8a3a648268..b7e2cb704c 100644 --- a/NPCs/CeaselessVoid/CeaselessVoid.cs +++ b/NPCs/CeaselessVoid/CeaselessVoid.cs @@ -146,6 +146,12 @@ public override bool CanHitPlayer(Player target, ref int cooldownSlot) return minDist <= 50f; } + public override void OnHitPlayer(Player target, Player.HurtInfo hurtInfo) + { + if (hurtInfo.Damage > 0) + target.AddBuff(BuffID.VortexDebuff, 60, true); + } + public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color drawColor) { SpriteEffects spriteEffects = SpriteEffects.None; diff --git a/NPCs/CeaselessVoid/DarkEnergy.cs b/NPCs/CeaselessVoid/DarkEnergy.cs index 202e8d1e86..c5fee54bad 100644 --- a/NPCs/CeaselessVoid/DarkEnergy.cs +++ b/NPCs/CeaselessVoid/DarkEnergy.cs @@ -282,10 +282,11 @@ public override void ApplyDifficultyAndPlayerScaling(int numPlayers, float balan public override void OnHitPlayer(Player target, Player.HurtInfo hurtInfo) { - int debufftype = Main.zenithWorld ? BuffID.Obstructed : BuffID.VortexDebuff; - int duration = Main.zenithWorld ? 30 : 60; - if (hurtInfo.Damage > 0) - target.AddBuff(debufftype, duration, true); + if (Main.zenithWorld) + { + if (hurtInfo.Damage > 0) + target.AddBuff(BuffID.Obstructed, 30, true); + } } public override bool CanHitPlayer(Player target, ref int cooldownSlot) diff --git a/Projectiles/Boss/DarkEnergyBall.cs b/Projectiles/Boss/DarkEnergyBall.cs index 85a46e55e9..b9e79f2352 100644 --- a/Projectiles/Boss/DarkEnergyBall.cs +++ b/Projectiles/Boss/DarkEnergyBall.cs @@ -94,10 +94,8 @@ public override void OnHitPlayer(Player target, Player.HurtInfo info) if (Projectile.Opacity == 1f) { - int debufftype = Main.zenithWorld ? BuffID.Obstructed : BuffID.VortexDebuff; - int duration = Main.zenithWorld ? 30 : 60; - if (info.Damage > 0) - target.AddBuff(debufftype, duration, true); + if (Main.zenithWorld) + target.AddBuff(BuffID.Obstructed, 30, true); } } diff --git a/Projectiles/Boss/DarkEnergyBall2.cs b/Projectiles/Boss/DarkEnergyBall2.cs index 8cf3a9e8b2..7ad6d26771 100644 --- a/Projectiles/Boss/DarkEnergyBall2.cs +++ b/Projectiles/Boss/DarkEnergyBall2.cs @@ -92,10 +92,8 @@ public override void OnHitPlayer(Player target, Player.HurtInfo info) if (Projectile.Opacity == 1f) { - int debufftype = Main.zenithWorld ? BuffID.Obstructed : BuffID.VortexDebuff; - int duration = Main.zenithWorld ? 30 : 60; - if (info.Damage > 0) - target.AddBuff(debufftype, duration, true); + if (Main.zenithWorld) + target.AddBuff(BuffID.Obstructed, 30, true); } } From bcb0a0636f1831583ea5069a6eac59c0661e552f Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Wed, 29 May 2024 19:44:53 -0500 Subject: [PATCH 133/401] Ceaseless Void movement adjustments while not in succ phase, should hopefully make it more predictable and fun without being too predictable. --- .../CalamityBossAIs/CeaselessVoidAI.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/NPCs/CalamityAIs/CalamityBossAIs/CeaselessVoidAI.cs b/NPCs/CalamityAIs/CalamityBossAIs/CeaselessVoidAI.cs index 6f7fa5b9bd..e33ab45fd9 100644 --- a/NPCs/CalamityAIs/CalamityBossAIs/CeaselessVoidAI.cs +++ b/NPCs/CalamityAIs/CalamityBossAIs/CeaselessVoidAI.cs @@ -448,7 +448,7 @@ public static void VanillaCeaselessVoidAI(NPC npc, Mod mod) void Movement(bool succ) { float velocity = moveVeryFast ? 25f : bossRush ? 15f : ((expertMode ? 7.5f : 6f) + (float)(death ? 2f * (1D - lifeRatio) : 0f)) * tileEnrageMult; - float acceleration = moveVeryFast ? 0.75f : bossRush ? 0.3f : death ? 0.2f : expertMode ? 0.16f : 0.12f; + float acceleration = (moveVeryFast ? 0.75f : bossRush ? 0.3f : death ? 0.2f : expertMode ? 0.16f : 0.12f) + (float)(death ? 0.04f * (1D - lifeRatio) : 0f) * tileEnrageMult; // Increase speed dramatically in succ phase if (succ) @@ -472,7 +472,7 @@ void Movement(bool succ) { // Move to a new location every few seconds calamityGlobalNPC.newAI[2] += 1f; - float newPositionGateValue = bossRush ? 180f : death ? 270f : revenge ? 300f : expertMode ? 360f : 480f; + float newPositionGateValue = bossRush ? 120f : death ? 180f : revenge ? 210f : expertMode ? 240f : 300f; if (calamityGlobalNPC.newAI[2] > newPositionGateValue) { calamityGlobalNPC.newAI[2] = 0f; @@ -520,7 +520,18 @@ void Movement(bool succ) Vector2 distanceFromDestination = destination - npc.Center; // Movement - CalamityUtils.SmoothMovement(npc, 0f, distanceFromDestination, velocity, acceleration, true); + if (npc.Distance(destination) > maxDistance || succ) + { + CalamityUtils.SmoothMovement(npc, 0f, distanceFromDestination, velocity, acceleration, true); + } + else + { + // Slow down + if (npc.velocity.Length() > 0.5f) + npc.velocity *= 0.8f; + else + npc.velocity = Vector2.Zero; + } } // Spawn more Dark Energies as the fight progresses From 43d0d3f726672dd579e2899dd32d7bc1c35c5b41 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Thu, 30 May 2024 13:02:01 -0500 Subject: [PATCH 134/401] More Hive Mind polish --- NPCs/CalamityGlobalNPC.cs | 63 +++++++++++++++++++ NPCs/HiveMind/HiveBlob.cs | 34 +++++++--- NPCs/HiveMind/HiveBlob2.cs | 34 +++++++--- NPCs/HiveMind/HiveMind.cs | 125 +++++++++++++++---------------------- 4 files changed, 166 insertions(+), 90 deletions(-) diff --git a/NPCs/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index 45176c2362..1a93568467 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -3491,6 +3491,69 @@ public override bool PreAI(NPC npc) return DukeFishronAI.BuffedDetonatingBubbleAI(npc, Mod); } + // Expert+ Hive Mind Vile Spits + if (npc.type == NPCID.VileSpitEaterOfWorlds) + { + if (Main.expertMode || BossRushEvent.BossRushActive) + { + if (npc.ai[1] == 69f) + { + if (npc.target == Main.maxPlayers) + { + npc.TargetClosest(); + float velocity = Main.getGoodWorld ? 10f : (Main.masterMode || BossRushEvent.BossRushActive) ? 8f : 6f; + npc.velocity = (Main.player[npc.target].Center - npc.Center).SafeNormalize(Vector2.UnitY) * velocity; + } + + if (Main.getGoodWorld && !npc.dontTakeDamage) + { + if ((double)(npc.Center.Y / 16f) < Main.worldSurface) + npc.dontTakeDamage = true; + } + + npc.damage = npc.GetAttackDamage_ScaledByStrength(32f); + + npc.ai[0] += 1f; + if (npc.ai[0] > 3f) + npc.ai[0] = 3f; + + if (npc.ai[0] == 2f) + { + npc.position += npc.velocity; + SoundEngine.PlaySound(SoundID.NPCDeath9, npc.Center); + for (int i = 0; i < 20; i++) + { + int dust = Dust.NewDust(new Vector2(npc.position.X, npc.position.Y + 2f) + npc.netOffset, npc.width, npc.height, 18, 0f, 0f, 100, default, 1.8f); + Main.dust[dust].velocity *= 1.3f; + Main.dust[dust].velocity += npc.velocity; + Main.dust[dust].noGravity = true; + } + } + + if (Collision.SolidCollision(npc.position, npc.width, npc.height)) + { + if (Main.netMode != NetmodeID.MultiplayerClient) + npc.StrikeInstantKill(); + } + + npc.EncourageDespawn(100); + + npc.position += npc.netOffset; + for (int i = 0; i < 2; i++) + { + int dust = Dust.NewDust(new Vector2(npc.position.X, npc.position.Y + 2f), npc.width, npc.height, 18, npc.velocity.X * 0.1f, npc.velocity.Y * 0.1f, 80, default, 1.3f); + Main.dust[dust].velocity *= 0.3f; + Main.dust[dust].noGravity = true; + } + + npc.rotation += 0.4f * npc.direction; + npc.position -= npc.netOffset; + + return false; + } + } + } + if (CalamityWorld.revenge || BossRushEvent.BossRushActive) { switch (npc.type) diff --git a/NPCs/HiveMind/HiveBlob.cs b/NPCs/HiveMind/HiveBlob.cs index 14d3a860b5..63398f2ab9 100644 --- a/NPCs/HiveMind/HiveBlob.cs +++ b/NPCs/HiveMind/HiveBlob.cs @@ -14,6 +14,10 @@ namespace CalamityMod.NPCs.HiveMind { public class HiveBlob : ModNPC { + private const float ShootGateValue = 240f; + private const float TelegraphDuration = 120f; + private const float ShowTelegraphValue = ShootGateValue - TelegraphDuration; + public override void SetStaticDefaults() { this.HideFromBestiary(); @@ -70,6 +74,18 @@ public override void AI() return; } + // When Hive Mind starts flying around + bool phase2 = Main.npc[hiveMind].life / (float)Main.npc[hiveMind].lifeMax < 0.8f; + + if (phase2) + { + NPC.life = 0; + NPC.HitEffect(); + NPC.active = false; + NPC.netUpdate = true; + return; + } + NPC.alpha = Main.npc[hiveMind].alpha; if (NPC.ai[3] > 0f) @@ -145,12 +161,14 @@ public override void AI() if (Main.netMode != NetmodeID.MultiplayerClient) { if (!Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[NPC.target].position, Main.player[NPC.target].width, Main.player[NPC.target].height)) - NPC.localAI[1] = 180f; + NPC.localAI[1] = ShootGateValue * 0.5f; - float shootGateValue = 360f; + float shootGateValue = ShootGateValue; if (NPC.localAI[1] < shootGateValue) { - NPC.localAI[1] += Main.rand.Next(2) + 1f; + NPC.localAI[1] += 1f; + if (NPC.localAI[1] < ShowTelegraphValue) + NPC.localAI[1] += Main.rand.Next(2); if (masterMode) NPC.localAI[1] += 1f; } @@ -164,11 +182,11 @@ public override void AI() NPC.TargetClosest(); if (Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[NPC.target].position, Main.player[NPC.target].width, Main.player[NPC.target].height)) { - float projSpeed = death ? 5f : revenge ? 4.5f : expertMode ? 4f : 3.5f; + float projSpeed = death ? 8f : revenge ? 7f : expertMode ? 6f : 4f; if (masterMode) - projSpeed += 2.5f; + projSpeed += 2f; if (Main.getGoodWorld) - projSpeed *= 2.4f; + projSpeed *= 1.5f; Vector2 projDirection = NPC.Center; float playerX = Main.player[NPC.target].Center.X - projDirection.X; @@ -208,8 +226,8 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d vector2 += vector * NPC.scale + new Vector2(0f, NPC.gfxOffY); Color color = NPC.GetAlpha(drawColor); - if (NPC.localAI[1] > 240f) - color = Color.Lerp(color, Color.Green * NPC.Opacity, MathHelper.Clamp((NPC.localAI[1] - 240f) / 120f, 0f, 1f)); + if (NPC.localAI[1] > ShowTelegraphValue) + color = Color.Lerp(color, Color.LimeGreen * NPC.Opacity, MathHelper.Clamp((NPC.localAI[1] - ShowTelegraphValue) / TelegraphDuration, 0f, 1f)); spriteBatch.Draw(texture, vector2, NPC.frame, color, NPC.rotation, vector, NPC.scale, spriteEffects, 0f); diff --git a/NPCs/HiveMind/HiveBlob2.cs b/NPCs/HiveMind/HiveBlob2.cs index 7774a4db71..14853a8c6c 100644 --- a/NPCs/HiveMind/HiveBlob2.cs +++ b/NPCs/HiveMind/HiveBlob2.cs @@ -14,6 +14,10 @@ namespace CalamityMod.NPCs.HiveMind { public class HiveBlob2 : ModNPC { + private const float ShootGateValue = 180f; + private const float TelegraphDuration = 120f; + private const float ShowTelegraphValue = ShootGateValue - TelegraphDuration; + public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.HiveBlob.DisplayName"); public override string Texture => "CalamityMod/NPCs/HiveMind/HiveBlob"; @@ -73,6 +77,18 @@ public override void AI() return; } + // When Hive Mind starts flying around + bool phase2 = Main.npc[hiveMind].life / (float)Main.npc[hiveMind].lifeMax < 0.8f; + + if (phase2) + { + NPC.life = 0; + NPC.HitEffect(); + NPC.active = false; + NPC.netUpdate = true; + return; + } + NPC.alpha = Main.npc[hiveMind].alpha; if (NPC.ai[3] > 0f) @@ -148,12 +164,14 @@ public override void AI() if (Main.netMode != NetmodeID.MultiplayerClient) { if (!Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[NPC.target].position, Main.player[NPC.target].width, Main.player[NPC.target].height)) - NPC.localAI[1] = 180f; + NPC.localAI[1] = ShootGateValue * 0.5f; - float shootGateValue = 360f; + float shootGateValue = ShootGateValue; if (NPC.localAI[1] < shootGateValue) { - NPC.localAI[1] += Main.rand.Next(3) + 1f; + NPC.localAI[1] += 1f; + if (NPC.localAI[1] < ShowTelegraphValue) + NPC.localAI[1] += Main.rand.Next(2); if (masterMode) NPC.localAI[1] += 1f; } @@ -167,11 +185,11 @@ public override void AI() NPC.TargetClosest(); if (Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[NPC.target].position, Main.player[NPC.target].width, Main.player[NPC.target].height)) { - float projSpeed = death ? 5f : revenge ? 4.5f : expertMode ? 4f : 3.5f; + float projSpeed = death ? 8f : revenge ? 7f : expertMode ? 6f : 4f; if (masterMode) - projSpeed += 2.5f; + projSpeed += 2f; if (Main.getGoodWorld) - projSpeed *= 2.4f; + projSpeed *= 1.5f; Vector2 projDirection = NPC.Center; float playerX = Main.player[NPC.target].Center.X - projDirection.X; @@ -211,8 +229,8 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d vector2 += vector * NPC.scale + new Vector2(0f, NPC.gfxOffY); Color color = NPC.GetAlpha(drawColor); - if (NPC.localAI[1] > 240f) - color = Color.Lerp(color, Color.Green * NPC.Opacity, MathHelper.Clamp((NPC.localAI[1] - 240f) / 120f, 0f, 1f)); + if (NPC.localAI[1] > ShowTelegraphValue) + color = Color.Lerp(color, Color.LimeGreen * NPC.Opacity, MathHelper.Clamp((NPC.localAI[1] - ShowTelegraphValue) / TelegraphDuration, 0f, 1f)); spriteBatch.Draw(texture, vector2, NPC.frame, color, NPC.rotation, vector, NPC.scale, spriteEffects, 0f); diff --git a/NPCs/HiveMind/HiveMind.cs b/NPCs/HiveMind/HiveMind.cs index 36bfa89073..b355b66504 100644 --- a/NPCs/HiveMind/HiveMind.cs +++ b/NPCs/HiveMind/HiveMind.cs @@ -70,6 +70,7 @@ internal static void LoadHeadIcons() private int lungeFade = 15; // Divide 255 by this for duration of hive mind spin before slowing for lunge private double lungeRots = 0.2; // Number of revolutions made while spinning/fading in for lunge private bool dashStarted = false; + private int vileSpitFireRate = 24; // Fire rate for Expert-exclusive Vile Spits during phase 1 teleports private int phase2timer = 360; private int rotationDirection; private double rotation; @@ -149,6 +150,7 @@ public override void SetDefaults() lungeTime = 28; driftSpeed = 2f; driftBoost = 2f; + vileSpitFireRate = 18; } if (death) @@ -159,6 +161,7 @@ public override void SetDefaults() lungeTime = 23; driftSpeed = 3.5f; driftBoost = 1.5f; + vileSpitFireRate = 15; } if (bossRush) @@ -169,6 +172,7 @@ public override void SetDefaults() lungeTime = 16; driftSpeed = 6f; driftBoost = 1f; + vileSpitFireRate = 12; } if (masterMode) @@ -179,6 +183,7 @@ public override void SetDefaults() lungeTime -= 5; driftSpeed += ((death && !bossRush) ? 0.5f : 1f); driftBoost += ((death && !bossRush) ? 0.5f : 1f); + vileSpitFireRate -= 6; } if (Main.getGoodWorld) @@ -541,7 +546,7 @@ public override void AI() maxBlobs = 50; for (int i = 0; i < maxBlobs; i++) - NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y, ModContent.NPCType(), NPC.whoAmI); + NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y, Main.rand.NextBool() ? ModContent.NPCType() : ModContent.NPCType(), NPC.whoAmI); } } @@ -550,13 +555,34 @@ public override void AI() if (NPC.life > 0) { - if (Main.netMode != NetmodeID.MultiplayerClient) + int fivePercentHP = (int)(NPC.lifeMax * 0.05); + if ((NPC.life + fivePercentHP) < NPC.ai[3]) { - int fivePercentHP = (int)(NPC.lifeMax * 0.05); - if ((NPC.life + fivePercentHP) < NPC.ai[3]) + SoundEngine.PlaySound(SoundID.NPCDeath22, NPC.Center); + + NPC.ai[3] = NPC.life; + + for (int i = 0; i < 20; i++) { - NPC.ai[3] = NPC.life; + int dust = Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Demonite, 0f, 0f, 100, default, 2f); + Main.dust[dust].velocity *= 3f; + if (Main.rand.NextBool()) + { + Main.dust[dust].scale = 0.5f; + Main.dust[dust].fadeIn = 1f + Main.rand.Next(10) * 0.1f; + } + } + for (int j = 0; j < 35; j++) + { + int dust = Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Demonite, 0f, 0f, 100, default, 3f); + Main.dust[dust].noGravity = true; + Main.dust[dust].velocity *= 5f; + dust = Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Demonite, 0f, 0f, 100, default, 2f); + Main.dust[dust].velocity *= 2f; + } + if (Main.netMode != NetmodeID.MultiplayerClient) + { int maxSpawns = bossRush ? 10 : death ? 5 : revenge ? 4 : expertMode ? Main.rand.Next(3, 5) : Main.rand.Next(2, 4); int maxDankSpawns = bossRush ? 4 : death ? Main.rand.Next(2, 4) : revenge ? 2 : expertMode ? Main.rand.Next(1, 3) : 1; @@ -565,7 +591,7 @@ public override void AI() int x = (int)(NPC.position.X + Main.rand.Next(NPC.width - 32)); int y = (int)(NPC.position.Y + Main.rand.Next(NPC.height - 32)); - int type = ModContent.NPCType(); + int type = Main.rand.NextBool() ? ModContent.NPCType() : ModContent.NPCType(); if (NPC.CountNPCS(ModContent.NPCType()) < maxDankSpawns) type = ModContent.NPCType(); @@ -614,6 +640,15 @@ public override void AI() burrowedDust2 = Dust.NewDust(new Vector2(NPC.position.X, NPC.Center.Y), NPC.width, NPC.height / 2, DustID.Demonite, 0f, -3f, 100, default, 2.5f * NPC.scale); Main.dust[burrowedDust2].velocity *= 1f; } + + if (expertMode) + { + if (Main.netMode != NetmodeID.MultiplayerClient) + { + if (Collision.CanHitLine(NPC.Center, 1, 1, player.Center, 1, 1) && NPC.Distance(player.Center) > 160f && burrowTimer % vileSpitFireRate == 0) + NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y, NPCID.VileSpitEaterOfWorlds, 0, 0f, 69f); + } + } } else if (burrowTimer == -60) { @@ -667,6 +702,15 @@ public override void AI() burrowedDust2 = Dust.NewDust(new Vector2(NPC.position.X, NPC.Center.Y), NPC.width, NPC.height / 2, DustID.Demonite, 0f, -3f, 100, default, 2.5f * NPC.scale); Main.dust[burrowedDust2].velocity *= 1f; } + + if (expertMode) + { + if (Main.netMode != NetmodeID.MultiplayerClient) + { + if (Collision.CanHitLine(NPC.Center, 1, 1, player.Center, 1, 1) && NPC.Distance(player.Center) > 160f && burrowTimer % vileSpitFireRate == 0) + NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y, NPCID.VileSpitEaterOfWorlds, 0, 0f, 69f); + } + } } else if (burrowTimer == 0) { @@ -832,16 +876,6 @@ public override void AI() NPC.position.Y = NPC.ai[2] * 16 - height_Phase2 / 2; } - for (int i = 0; i < Main.maxNPCs; i++) - { - NPC hiveBlob = Main.npc[i]; - if (hiveBlob.active && (hiveBlob.type == ModContent.NPCType() || hiveBlob.type == ModContent.NPCType())) - { - hiveBlob.position.X = NPC.position.X; - hiveBlob.position.Y = NPC.position.Y; - } - } - phase2timer = minimumDriftTime + Main.rand.Next(masterMode ? 61 : 121); NPC.netUpdate = true; NPC.netSpam = 0; @@ -879,16 +913,6 @@ public override void AI() NPC.velocity = Vector2.Zero; dashStarted = false; - for (int i = 0; i < Main.maxNPCs; i++) - { - NPC hiveBlob = Main.npc[i]; - if (hiveBlob.active && (hiveBlob.type == ModContent.NPCType() || hiveBlob.type == ModContent.NPCType())) - { - hiveBlob.position.X = NPC.position.X; - hiveBlob.position.Y = NPC.position.Y; - } - } - if (revenge && lifeRatio < 0.53f) { state = nextState; @@ -920,19 +944,6 @@ public override void AI() if (Main.netMode != NetmodeID.MultiplayerClient) NPC.Center = player.Center + new Vector2(teleportRadius, 0).RotatedBy(rotation); - if (NPC.alpha == 255) - { - for (int i = 0; i < Main.maxNPCs; i++) - { - NPC hiveBlob = Main.npc[i]; - if (hiveBlob.active && (hiveBlob.type == ModContent.NPCType() || hiveBlob.type == ModContent.NPCType())) - { - hiveBlob.position.X = NPC.position.X; - hiveBlob.position.Y = NPC.position.Y; - } - } - } - rotation += rotationIncrement * rotationDirection; phase2timer = lungeDelay; @@ -997,19 +1008,6 @@ public override void AI() NPC.position.Y += teleportRadius; } - if (NPC.alpha == 255) - { - for (int i = 0; i < Main.maxNPCs; i++) - { - NPC hiveBlob = Main.npc[i]; - if (hiveBlob.active && (hiveBlob.type == ModContent.NPCType() || hiveBlob.type == ModContent.NPCType())) - { - hiveBlob.position.X = NPC.position.X; - hiveBlob.position.Y = NPC.position.Y; - } - } - } - NPC.alpha -= masterMode ? 10 : 5; if (NPC.alpha < 0) NPC.alpha = 0; @@ -1083,19 +1081,6 @@ public override void AI() NPC.position.X += teleportRadius * rotationDirection; } - if (NPC.alpha == 255) - { - for (int i = 0; i < Main.maxNPCs; i++) - { - NPC hiveBlob = Main.npc[i]; - if (hiveBlob.active && (hiveBlob.type == ModContent.NPCType() || hiveBlob.type == ModContent.NPCType())) - { - hiveBlob.position.X = NPC.position.X; - hiveBlob.position.Y = NPC.position.Y; - } - } - } - NPC.alpha -= masterMode ? 10 : 5; if (NPC.alpha < 0) NPC.alpha = 0; @@ -1217,15 +1202,7 @@ public override void HitEffect(NPC.HitInfo hit) for (int k = 0; k < hit.Damage / NPC.lifeMax * 100.0; k++) Dust.NewDust(NPC.position, NPC.width, phase2 ? height_Phase2 : NPC.height, DustID.Demonite, hit.HitDirection, -1f, 0, default, 1f); - if (phase2) - { - if (Main.netMode != NetmodeID.MultiplayerClient && Main.zenithWorld ? NPC.CountNPCS(ModContent.NPCType()) < 10 : (Main.rand.NextBool(15) && NPC.CountNPCS(ModContent.NPCType()) < 2)) - { - Vector2 spawnAt = NPC.Center + new Vector2(0f, height_Phase2 / 2f); - NPC.NewNPC(NPC.GetSource_FromThis(), (int)spawnAt.X, (int)spawnAt.Y, ModContent.NPCType()); - } - } - else + if (!phase2) { if (NPC.CountNPCS(NPCID.EaterofSouls) < 3 && NPC.CountNPCS(NPCID.DevourerHead) < 1) { From 8109f82dc139c362bfa9c6faffe2cddd15669304 Mon Sep 17 00:00:00 2001 From: Storm2103 Date: Wed, 29 May 2024 20:36:00 -0600 Subject: [PATCH 135/401] Fixed Broken Water Filter being reset in CalamityPlayer causing it to not work --- CalPlayer/CalamityPlayer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 553903583f..63aadd0349 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -1783,7 +1783,6 @@ public override void ResetEffects() corrosiveSpine = false; RustyMedallionDroplets = false; MiniSwarmers = false; - noStupidNaturalARSpawns = false; rottenDogTooth = false; angelicAlliance = false; BloomStoneRegen = false; @@ -2153,7 +2152,8 @@ public override void ResetEffects() StellarTorus = false; LiliesOfFinalityBool = false; - /* + /* Spawn blockers from back when they used to work by being favorited and not a toggleable item + noStupidNaturalARSpawns = false disableVoodooSpawns = false; disablePerfCystSpawns = false; disableHiveCystSpawns = false; From 2298a6cde1979ef50a6512817c497445e22ace63 Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Thu, 30 May 2024 11:44:56 +0700 Subject: [PATCH 136/401] cleared 2 warns on loading logs --- Items/Weapons/Ranged/BladedgeRailbow.cs | 4 ++-- Items/Weapons/Ranged/DragonsBreath.cs | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Items/Weapons/Ranged/BladedgeRailbow.cs b/Items/Weapons/Ranged/BladedgeRailbow.cs index ebf3c143c0..c870e43a22 100644 --- a/Items/Weapons/Ranged/BladedgeRailbow.cs +++ b/Items/Weapons/Ranged/BladedgeRailbow.cs @@ -16,7 +16,7 @@ public class BladedgeRailbow : ModItem, ILocalizedModType public new string LocalizationCategory => "Items.Weapons.Ranged"; #region GFB Arrow Array - public int[] arrowArr = + public static int[] arrowArr = { ProjectileID.WoodenArrowFriendly, ProjectileID.FireArrow, @@ -143,7 +143,7 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, int projType; if (Main.zenithWorld) - projType = arrowArr[Main.rand.Next(0, arrowArr.Length)]; + projType = arrowArr[Main.rand.Next(arrowArr.Length)]; else projType = ProjectileID.Leaf; diff --git a/Items/Weapons/Ranged/DragonsBreath.cs b/Items/Weapons/Ranged/DragonsBreath.cs index ec7d6f4b76..cb954c9f0f 100644 --- a/Items/Weapons/Ranged/DragonsBreath.cs +++ b/Items/Weapons/Ranged/DragonsBreath.cs @@ -29,7 +29,6 @@ public class DragonsBreath : ModItem, ILocalizedModType public bool StrongShotMode = false; public int DragonsBreathSetUseTime = 5; public int DragonsBreathSetUseAnimation = 9; - private Player Owner; public override void SetDefaults() { From d7288484cbf11a429df78d3543115dad305a8e6c Mon Sep 17 00:00:00 2001 From: Xyk Date: Mon, 27 May 2024 20:12:38 -0700 Subject: [PATCH 137/401] Toxic Heart blood boiler life regen fixes are also here, oops --- CalPlayer/CalamityPlayer.cs | 3 + CalPlayer/CalamityPlayerLifeRegen.cs | 26 ++++- Items/Accessories/ToxicHeart.cs | 41 +------- .../Mods.CalamityMod.Items.Accessories.hjson | 5 +- ...ods.CalamityMod.Projectiles.Typeless.hjson | 1 + Projectiles/Ranged/BloodBoilerFire.cs | 2 +- Projectiles/Typeless/PlaguePulse.cs | 98 ++++++++++++++++++ Sounds/Item/Heartbeat.ogg | Bin 5819 -> 7404 bytes 8 files changed, 132 insertions(+), 44 deletions(-) create mode 100644 Projectiles/Typeless/PlaguePulse.cs diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 63aadd0349..196ce3bfe9 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -53,6 +53,7 @@ using Terraria.ID; using Terraria.ModLoader; using Terraria.ModLoader.IO; +using Terraria.Utilities.Terraria.Utilities; namespace CalamityMod.CalPlayer { @@ -532,6 +533,8 @@ public partial class CalamityPlayer : ModPlayer public bool honeyDewHalveDebuffs = false; public bool livingDewHalveDebuffs = false; public int jewelBonusDefense = 0; + public float pulseCounter = 0; // Toxic Heart + public float pulseRate = 1; // Toxic Heart public bool aAmpoule = false; public bool rOoze = false; public bool JustWasDebuffed = false; diff --git a/CalPlayer/CalamityPlayerLifeRegen.cs b/CalPlayer/CalamityPlayerLifeRegen.cs index 97262ff6c1..8903fb8389 100644 --- a/CalPlayer/CalamityPlayerLifeRegen.cs +++ b/CalPlayer/CalamityPlayerLifeRegen.cs @@ -6,13 +6,16 @@ using CalamityMod.Items.Accessories; using CalamityMod.NPCs; using CalamityMod.Projectiles.Ranged; +using CalamityMod.Projectiles.Typeless; using CalamityMod.Systems; using CalamityMod.World; using Microsoft.Xna.Framework; using Terraria; +using Terraria.Audio; using Terraria.DataStructures; using Terraria.ID; using Terraria.ModLoader; +using Terraria.Utilities.Terraria.Utilities; namespace CalamityMod.CalPlayer { @@ -21,9 +24,6 @@ public partial class CalamityPlayer : ModPlayer #region Update Bad Life Regen public override void UpdateBadLifeRegen() { - if (Player.ownedProjectileCounts[ModContent.ProjectileType()] > 0) - noLifeRegen = true; - // Universal +25% increase to DoT debuff damage in Death Mode float deathNegativeRegenBonus = 0.25f; float calamityDebuffMultiplier = 1f + (CalamityWorld.death ? deathNegativeRegenBonus : 0f); @@ -878,6 +878,26 @@ public override void UpdateLifeRegen() } } } + + if (toxicHeart) // Since it needs to know your life regen, it must be placed here + { + int auraDamage = (int)Player.GetBestClassDamage().ApplyTo(180); + auraDamage = Player.ApplyArmorAccDamageBonusesTo(auraDamage); + var source = Player.GetSource_Accessory(FindAccessory(ModContent.ItemType())); + pulseRate = Utils.Remap(Player.lifeRegen, -30, 10, 20, 1, true); + if (pulseCounter >= 420) + { + Projectile.NewProjectileDirect(source, Player.Center, Vector2.Zero, ModContent.ProjectileType(), auraDamage, 0f, Player.whoAmI, 0, 0, 0); + pulseCounter = 0; + float soundVolume = Utils.Remap(Player.lifeRegen, -30, 10, 1f, 0.3f, true); + SoundStyle heartbeat = new("CalamityMod/Sounds/Item/Heartbeat"); + SoundEngine.PlaySound(heartbeat with { Volume = soundVolume, PitchVariance = 0.2f }, Player.Center); + } + else + { + pulseCounter += MathHelper.Clamp(pulseRate, 1, 20); + } + } } #endregion } diff --git a/Items/Accessories/ToxicHeart.cs b/Items/Accessories/ToxicHeart.cs index ee4b89c267..cf33597d9c 100644 --- a/Items/Accessories/ToxicHeart.cs +++ b/Items/Accessories/ToxicHeart.cs @@ -5,13 +5,16 @@ using Microsoft.Xna.Framework; using Terraria; using Terraria.ID; +using Terraria.Audio; using Terraria.ModLoader; +using Microsoft.Build.ObjectModelRemoting; namespace CalamityMod.Items.Accessories { public class ToxicHeart : ModItem, ILocalizedModType { public new string LocalizationCategory => "Items.Accessories"; + public float pulseCounter = 0; public override void SetDefaults() { Item.width = 28; @@ -25,44 +28,6 @@ public override void UpdateAccessory(Player player, bool hideVisual) { CalamityPlayer modPlayer = player.Calamity(); modPlayer.toxicHeart = true; - player.buffImmune[ModContent.BuffType()] = true; - int plagueCounter = 0; - Lighting.AddLight((int)(player.Center.X / 16f), (int)(player.Center.Y / 16f), 0.05f, 1f, 0.1f); - int plagueDebuff = ModContent.BuffType(); - bool shouldInflictPlague = plagueCounter % 60 == 0; - - int auraDamage = (int)player.GetBestClassDamage().ApplyTo(50); - auraDamage = player.ApplyArmorAccDamageBonusesTo(auraDamage); - - int random = Main.rand.Next(10); - var source = player.GetSource_Accessory(Item); - if (player.whoAmI == Main.myPlayer) - { - if (random == 0) - { - foreach (NPC nPC in Main.ActiveNPCs) - { - if (nPC.IsAnEnemy() && !nPC.dontTakeDamage && !nPC.buffImmune[plagueDebuff] && Vector2.Distance(player.Center, nPC.Center) <= 300f) - { - if (nPC.FindBuffIndex(plagueDebuff) == -1) - { - nPC.AddBuff(plagueDebuff, 120, false); - } - if (shouldInflictPlague) - { - if (player.whoAmI == Main.myPlayer) - { - Projectile.NewProjectileDirect(source, nPC.Center, Vector2.Zero, ModContent.ProjectileType(), auraDamage, 0f, player.whoAmI, nPC.whoAmI); - } - } - } - } - } - } - plagueCounter++; - if (plagueCounter >= 180) - { - } } } } diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson index 2e9be4b5ab..366f12d365 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson @@ -1882,8 +1882,9 @@ ToxicHeart: { DisplayName: Toxic Heart Tooltip: ''' - Summons a plague aura around you that damages nearby enemies - Makes you immune to the Plague debuff + Causes your heart to beat with powerful plague pulses, inflicting all nearby enemies with the Plague + The rate of these pulses scales with how low your life regen is + Pulses that kill targets create additional pulses Multiplies all sickness-based debuff damage by 1.5 ''' } diff --git a/Localization/en-US/Mods.CalamityMod.Projectiles.Typeless.hjson b/Localization/en-US/Mods.CalamityMod.Projectiles.Typeless.hjson index f56e0e7b4a..a9ca316e3e 100644 --- a/Localization/en-US/Mods.CalamityMod.Projectiles.Typeless.hjson +++ b/Localization/en-US/Mods.CalamityMod.Projectiles.Typeless.hjson @@ -133,3 +133,4 @@ WulfrumHook.DisplayName: Wulfrum Slingshot WulfrumLureSignal.DisplayName: Signal YanmeisKnifeSlash.DisplayName: Yanmei's Knife YellowLabSeeker.DisplayName: Seeking Mechanism +PlaguePulse.DisplayName: Plague Pulse diff --git a/Projectiles/Ranged/BloodBoilerFire.cs b/Projectiles/Ranged/BloodBoilerFire.cs index 52af9cd48f..6f18a4673f 100644 --- a/Projectiles/Ranged/BloodBoilerFire.cs +++ b/Projectiles/Ranged/BloodBoilerFire.cs @@ -186,7 +186,7 @@ public override void AI() { if (!Main.player[Projectile.owner].moonLeech) { - int bonusHeal = Main.rand.NextBool(3) ? 6 : 4; + int bonusHeal = Main.rand.NextBool(3) ? 5 : 3; int heal = improvedHeal ? bonusHeal : 2; if (Main.player[Main.myPlayer].lifeSteal <= 0f) diff --git a/Projectiles/Typeless/PlaguePulse.cs b/Projectiles/Typeless/PlaguePulse.cs new file mode 100644 index 0000000000..17d8ba03bb --- /dev/null +++ b/Projectiles/Typeless/PlaguePulse.cs @@ -0,0 +1,98 @@ +using System; +using Microsoft.Xna.Framework; +using Terraria; +using Terraria.Audio; +using CalamityMod.Particles; +using Terraria.ID; +using Terraria.ModLoader; +using Microsoft.Xna.Framework.Graphics; +using SteelSeries.GameSense; +using CalamityMod.Buffs.DamageOverTime; +using Mono.Cecil; + +namespace CalamityMod.Projectiles.Typeless +{ + public class PlaguePulse : ModProjectile, ILocalizedModType + { + public new string LocalizationCategory => "Projectiles.Typeless"; + public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public ref float time => ref Projectile.ai[0]; + public ref float radius => ref Projectile.ai[1]; + public float maxRadius = 300; + public int startDamage; + public override void SetDefaults() + { + Projectile.width = 96; + Projectile.height = 96; + Projectile.friendly = true; + Projectile.tileCollide = false; + Projectile.penetrate = -1; + Projectile.timeLeft = 60; + Projectile.extraUpdates = 1; + Projectile.ignoreWater = true; + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = -1; + } + + public override void AI() + { + if (time == 0) + startDamage = Projectile.damage; + + Player player = Main.player[Projectile.owner]; + if (Projectile.ai[2] == 0) + Projectile.Center = player.MountedCenter; + if (Projectile.ai[2] == 1) + { + maxRadius = 200; + } + + if (Main.rand.NextBool(5)) + { + DirectionalPulseRing pulse = new DirectionalPulseRing(Projectile.Center + Main.rand.NextVector2Circular(radius, radius), Vector2.Zero, (Main.rand.NextBool(3) ? Color.LimeGreen : Color.Green) * 0.6f, new Vector2(1, 1), 0, Main.rand.NextFloat(0.07f, 0.23f), 0f, 20); + GeneralParticleHandler.SpawnParticle(pulse); + } + if (Main.rand.NextBool(3)) + { + for (int i = 0; i < 2; i++) + { + int DustID = 89; + Vector2 spawnPos = Projectile.Center + Main.rand.NextVector2Circular(radius, radius); + Dust dust2 = Dust.NewDustPerfect(spawnPos, DustID); + dust2.scale = Main.rand.NextFloat(0.5f, 0.9f); + dust2.velocity = (spawnPos - Projectile.Center).SafeNormalize(Vector2.UnitX) * Main.rand.NextFloat(5, 10); + dust2.noGravity = true; + } + } + + radius = Utils.Remap(time, 0, 60, 30, maxRadius, true); + time++; + } + public override void ModifyHitNPC(NPC target, ref NPC.HitModifiers modifiers) + { + if (Projectile.numHits > 0) + Projectile.damage = (int)(Projectile.damage * 0.85f); + if (Projectile.damage < 1) + Projectile.damage = 1; + } + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + Player player = Main.player[Projectile.owner]; + target.AddBuff(ModContent.BuffType(), 420); + + if (target.life <= 0) + { + Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), target.Center, Vector2.Zero, ModContent.ProjectileType(), (int)(startDamage * 0.8f), 0f, Projectile.owner, 0, 0, 1); + } + } + public override bool PreDraw(ref Color lightColor) + { + Player player = Main.player[Projectile.owner]; + + Texture2D rexture = ModContent.Request("CalamityMod/Particles/HighResHollowCircleHardEdge").Value; + Main.EntitySpriteDraw(rexture, Projectile.Center - Main.screenPosition, null, (Color.Green * Utils.Remap(time, 30, 60, 0.35f, 0, true)) with { A = 0 }, Projectile.rotation, rexture.Size() * 0.5f, (Utils.Remap(time, 0, 60, 1, 6, true) / 21) * (maxRadius == 300 ? 1 : 0.7f), SpriteEffects.None, 0); + return false; + } + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) => CalamityUtils.CircularHitboxCollision(Projectile.Center, radius, targetHitbox); + } +} diff --git a/Sounds/Item/Heartbeat.ogg b/Sounds/Item/Heartbeat.ogg index b0121df73c67cf38dd4a75eebb04d64aa341987c..f0a789db214bb938a9e9af48e01a5149d3bda570 100644 GIT binary patch delta 5960 zcmZ`+c|6qJ_x~8%Sf9x{X)%)qW2wfL@w6~XW|WvD#@dV)hQj!^P<<>TVw5y?p)yI9 zQr09YCK1)6EDciGo=Bw!DVp#7@O-!5>-GEmap&H1&OPUz`+lGE`AnVh1R36a=+GVr z1^xZ(U@T2CujXMTR!bZ^8p`zNAR>uvB}g^2(6 z@sV8eWCje}{DTj#+Z}oc7wFG)J$mtskAz|QK%_J*Xh!3?808ozrZUA%k+@^?cO1!& z{|d(ys4-O{Fj-6dEF|bc7)o6BeEL)aH9i0FjKQ*t$wV&cHtx=@I#xXE;T0R%-tvM?AFuDnQA zm$1%(pqOM%JQ017iLpWx|AC<=fGuP_0>_c2FQ{~)1uSD>Or8|@bx`F96>2p9(wGwlF;z{UC4&7w5fJ=z!d}46f8q*U=;ulc)L6h*3Y|v~U_BDctFUY(L51s*BB4~M!74?fk1j@E3IdJ= ze0A7R!43zi@xcx%aP`W@z6iLY604kO>?H+o6=W>b0_R;+09R#T`8%2z3yuW~D!LfO zq)J!zf1>lutFdh5e@9O=?$%(ngA_e@l~q_yX=Rr;dvY__0a65ta-lc7wEp;ia(6{? z|F7tr{}a8`Sm?QjZ4O-RDs6@toKIw-R>YDo<0?;f>E`a05ylYY+b99y8o4G;hg)b6 zP9A~)phBEki+(efE5r$~F&JWV28V7Sz=DeqW^gd{r&x|Mg^K6W>Hb76hDIw=hajgx z2*UWrTyJ_0#hxvZf+#2m%i=Sikw*&(`1F`$n9d{1Ug7f@YydZD6vt1Yvr`cn;wGSU zQO0$m(Mk^h*=4Q@a9zbCjjrUX(5OX~Jxg|AhW&jM$EDM##L6xv*sDUP772Qo6F6`V zDpAnIB8v|NWGL{XQ~a+8cGBz# z1sWjVFuDm5FL0vk5(-=xLD+;I*0-+ z3tSeT&LfTFaCjtP4yS`G#IicbqboT;k;6HU3}Cr9;KCMX7yy?+Fa)7*JNt2>FXn?P zML|Un#3j*4BP+Rdtytiij24*DV8ktkR)ly2IM9*h3#vTm>NnH$j01;GQdu;)qkqB_*1c1WhwAYUE83@drNofeinOQ=S zt9ou*J)*vJ^Sy#Ml!)8}K{9x7?>rI$2uX+q@xhhvLuQkxG(~YuRkLbiK$33$3QtClrAp6luTb_Wzs6H3nKw!#Gb(MUok+wo}h^U z6F_E$EfFDZsd+bpo?u+XV3(SYE?o(yY;$23v$#^|$?34E)PRA_Xck9F2FloE30V_* zEFaVUaDR6=c=0CsAjpmgD5v~4T1aJr+FJr|4XAu&t0frme*dMQv@Eh~5nnv_#ea6t z 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 From d23622615699e07a54bacbc6d53a462d81368bc3 Mon Sep 17 00:00:00 2001 From: Xyk Date: Mon, 27 May 2024 22:41:38 -0700 Subject: [PATCH 138/401] Alchemical Flask --- CalPlayer/CalamityPlayer.cs | 2 + CalPlayer/CalamityPlayerHitHurt.cs | 17 ++++++++ CalPlayer/CalamityPlayerLifeRegen.cs | 2 +- CalPlayer/CalamityPlayerMiscEffects.cs | 5 +-- CalPlayer/CalamityPlayerOnHit.cs | 13 +++--- Items/Accessories/AlchemicalFlask.cs | 2 +- Items/Accessories/PlagueHive.cs | 38 ------------------ Items/Accessories/PlagueHive.png | Bin 825 -> 0 bytes .../Mods.CalamityMod.Items.Accessories.hjson | 11 +---- ...ods.CalamityMod.Projectiles.Typeless.hjson | 2 +- Projectiles/Typeless/BasicPlagueBee.cs | 15 ++++--- 11 files changed, 42 insertions(+), 65 deletions(-) delete mode 100644 Items/Accessories/PlagueHive.cs delete mode 100644 Items/Accessories/PlagueHive.png diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 196ce3bfe9..90b444ee8d 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -796,6 +796,7 @@ public partial class CalamityPlayer : ModPlayer public bool astralStarRain = false; public int astralStarRainCooldown = 0; public int AbaddonCooldown = 0; + public int AlchFlaskCooldown = 0; public bool plagueReaper = false; public bool plaguebringerPatronSet = false; public bool plaguebringerCarapace = false; @@ -2316,6 +2317,7 @@ public override void UpdateDead() gSabatonTempJumpSpeed = 0; astralStarRainCooldown = 0; AbaddonCooldown = 0; + AlchFlaskCooldown = 0; silvaMageCooldown = 0; bloodflareMageCooldown = 0; tarraRangedCooldown = 0; diff --git a/CalPlayer/CalamityPlayerHitHurt.cs b/CalPlayer/CalamityPlayerHitHurt.cs index c0ff47501d..0b6d6f69fa 100644 --- a/CalPlayer/CalamityPlayerHitHurt.cs +++ b/CalPlayer/CalamityPlayerHitHurt.cs @@ -37,6 +37,7 @@ using CalamityMod.UI; using CalamityMod.World; using Microsoft.Xna.Framework; +using Mono.Cecil; using Terraria; using Terraria.Audio; using Terraria.Chat; @@ -1219,6 +1220,22 @@ public override void OnHitByNPC(NPC npc, Player.HurtInfo hurtInfo) GeneralParticleHandler.SpawnParticle(spark); } } + + if (alchFlask) + { + for (int i = 0; i < 9; i++) + { + int seekerDamage = (int)Player.GetBestClassDamage().ApplyTo(15); + seekerDamage = Player.ApplyArmorAccDamageBonusesTo(seekerDamage); + + Projectile bee = Projectile.NewProjectileDirect(Player.GetSource_FromThis(), Player.Center, new Vector2(5, 5).RotatedByRandom(100) * Main.rand.NextFloat(0.5f, 1.2f), ModContent.ProjectileType(), seekerDamage, 0f, Player.whoAmI, -20, 30, 2); + bee.ArmorPenetration = 35; + bee.penetrate = 6; + bee.extraUpdates = 2; + bee.timeLeft = 600; + } + Player.AddBuff(BuffID.Honey, 900); + } } public override void OnHitByProjectile(Projectile proj, Player.HurtInfo hurtInfo) diff --git a/CalPlayer/CalamityPlayerLifeRegen.cs b/CalPlayer/CalamityPlayerLifeRegen.cs index 8903fb8389..e561d98c24 100644 --- a/CalPlayer/CalamityPlayerLifeRegen.cs +++ b/CalPlayer/CalamityPlayerLifeRegen.cs @@ -881,7 +881,7 @@ public override void UpdateLifeRegen() if (toxicHeart) // Since it needs to know your life regen, it must be placed here { - int auraDamage = (int)Player.GetBestClassDamage().ApplyTo(180); + int auraDamage = (int)Player.GetBestClassDamage().ApplyTo(200); auraDamage = Player.ApplyArmorAccDamageBonusesTo(auraDamage); var source = Player.GetSource_Accessory(FindAccessory(ModContent.ItemType())); pulseRate = Utils.Remap(Player.lifeRegen, -30, 10, 20, 1, true); diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index ba586732b5..f93f0dd1ea 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -1375,6 +1375,8 @@ private void MiscEffects() astralStarRainCooldown--; if (AbaddonCooldown > 0) AbaddonCooldown--; + if (AlchFlaskCooldown > 0) + AlchFlaskCooldown--; if (tarraRangedCooldown > 0) tarraRangedCooldown--; if (bloodflareMageCooldown > 0) @@ -2934,9 +2936,6 @@ private void OtherBuffEffects() if (pFlames && !purity) { - if (!alchFlask) - Player.blind = true; - Player.GetDamage() -= 0.1f; } diff --git a/CalPlayer/CalamityPlayerOnHit.cs b/CalPlayer/CalamityPlayerOnHit.cs index 3452552dab..2464cd250f 100644 --- a/CalPlayer/CalamityPlayerOnHit.cs +++ b/CalPlayer/CalamityPlayerOnHit.cs @@ -595,14 +595,17 @@ public void ProjOnHit(Projectile proj, Vector2 position, bool crit, bool npcChec if (!proj.CountsAsClass() && !proj.CountsAsClass() && Player.meleeEnchant == 7) Projectile.NewProjectile(source, position, proj.velocity, ProjectileID.ConfettiMelee, 0, 0f, proj.owner); - if (alchFlask && Player.ownedProjectileCounts[ProjectileType()] < 3 && hasClass) + if (alchFlask && AlchFlaskCooldown == 0 && proj.type != ModContent.ProjectileType()) { - int seekerDamage = (int)Player.GetBestClassDamage().ApplyTo(30); + int seekerDamage = (int)Player.GetBestClassDamage().ApplyTo(10); seekerDamage = Player.ApplyArmorAccDamageBonusesTo(seekerDamage); + Vector2 seekerVelocity = new Vector2(5, 5).RotatedByRandom(100) * Main.rand.NextFloat(0.5f, 1.2f); - Projectile projectile = CalamityUtils.SpawnOrb(proj, seekerDamage, ProjectileType(), 400f, 12f); - if (projectile.whoAmI.WithinBounds(Main.maxProjectiles)) - Main.projectile[projectile.whoAmI].DamageType = DamageClass.Generic; + Projectile bee = Projectile.NewProjectileDirect(source, position, seekerVelocity, ModContent.ProjectileType(), seekerDamage, 0f, Player.whoAmI, -20, 30, 2); + bee.ArmorPenetration = 20; + bee.penetrate = 2; + bee.extraUpdates = 1; + AlchFlaskCooldown = 7; } bool lifeAndShieldCondition = Player.statLife >= Player.statLifeMax2 && (!HasAnyEnergyShield || TotalEnergyShielding >= TotalMaxShieldDurability); diff --git a/Items/Accessories/AlchemicalFlask.cs b/Items/Accessories/AlchemicalFlask.cs index 86d4aa1de4..8a03636bf3 100644 --- a/Items/Accessories/AlchemicalFlask.cs +++ b/Items/Accessories/AlchemicalFlask.cs @@ -29,7 +29,7 @@ public override void AddRecipes() { CreateRecipe(). AddIngredient(ItemID.BottledWater). - AddIngredient(ItemID.BeeWax, 5). + AddIngredient(ItemID.HoneyComb). AddIngredient(10). AddTile(TileID.MythrilAnvil). Register(); diff --git a/Items/Accessories/PlagueHive.cs b/Items/Accessories/PlagueHive.cs deleted file mode 100644 index c0bc650ec9..0000000000 --- a/Items/Accessories/PlagueHive.cs +++ /dev/null @@ -1,38 +0,0 @@ -using CalamityMod.Buffs.DamageOverTime; -using CalamityMod.CalPlayer; -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Items.Accessories -{ - public class PlagueHive : ModItem, ILocalizedModType - { - public new string LocalizationCategory => "Items.Accessories"; - public override void SetDefaults() - { - Item.width = 42; - Item.height = 48; - Item.value = CalamityGlobalItem.RarityRedBuyPrice; - Item.rare = ItemRarityID.Red; - Item.accessory = true; - } - - public override void AddRecipes() - { - CreateRecipe(). - AddIngredient(). - AddIngredient(ItemID.HoneyComb). - AddTile(TileID.LunarCraftingStation). - Register(); - } - - public override void UpdateAccessory(Player player, bool hideVisual) - { - CalamityPlayer modPlayer = player.Calamity(); - modPlayer.uberBees = true; - modPlayer.alchFlask = true; - player.buffImmune[ModContent.BuffType()] = true; - } - } -} diff --git a/Items/Accessories/PlagueHive.png b/Items/Accessories/PlagueHive.png deleted file mode 100644 index 1cd4a7baaa9545667a8484600f7756407cdd48a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 825 zcmV-91IGM`P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!2kdb!2!6DYwZ940?tW9K~!i%?U+wU zR8bVhM-2qcU1=pG6*d_m*c3s~CL&5*MTOfIZQHf0pg%izZCkXJidJe7(IyC@CP5;b zq{6^TYiAlRtT^AipU818ZyZ~6AANB6=Dv6DeeeC|-19E4E?1+PH*Wo%{FLT@e5p8B zwf)jmpZGtobrU@{a9r)jLyzPTOFO?-MMHGWH)^CT4)5>ISyU_fGd?+7wc;nrlZOa2 z?cSnTc=uHi66fjfm3AEz|ElNd{HmpmCW=$?>B*AZtGzQX?<#c2k)JQEDrAo+c{nw< zC`TPFjq*zQXR3Bwc8Nlg+zJtc6vt^#yq}hL?P{0%^PzblPOf{h@e}2(!;>z|ewTYv zsQ92LzjAxK{Mxxs^1{i29C`9ht()ZhbI)Fl%cCV)Zv0gYPZ$NTw_ zzprSBZb*F9PRQ52=lNFoq0+28-+e%i$WgCQKR+MW^Y=l{#<%LpPhUUDCkTwbos$pu z?v+Dq?B1}P{#1va)BW<&_)B^J=o@+Oo)$So=^v`6*{h=$XXfQ064X_4koxKCrvGOK z+nVLssiTRnl99BqeWbw2Q?I?bt z2(m{mpHLeD2-1*+oNtH5J-z-=9wLddN0eMWbE!ej4xSzT-5X1CNI@{Ie_C#$c`UGevY#0`_6uo zqmetC<$Q_eU0-W%qU;hykWCZS;Xl#8B~L!%M02@6AduiP=D1~Z00000NkvXXu0mjf DiSd(8 diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson index 366f12d365..f1f7825c5e 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson @@ -104,6 +104,7 @@ AlchemicalFlask: { ''' All attacks inflict the Plague and reduces damage taken from the Plague Projectiles spawn plague seekers on enemy hits + Releases plague bees when damaged and douses you in honey ''' } @@ -1260,16 +1261,6 @@ PlaguedFuelPack: { ''' } -PlagueHive: { - DisplayName: Plague Hive - Tooltip: - ''' - All attacks inflict the Plague and grants immunity to the Plague - Releases bees when damaged that inflict the Plague - Projectiles spawn plague seekers on enemy hits - ''' -} - ProfanedSoulArtifact: { DisplayName: Profaned Soul Artifact Tooltip: diff --git a/Localization/en-US/Mods.CalamityMod.Projectiles.Typeless.hjson b/Localization/en-US/Mods.CalamityMod.Projectiles.Typeless.hjson index a9ca316e3e..f7c34ecdda 100644 --- a/Localization/en-US/Mods.CalamityMod.Projectiles.Typeless.hjson +++ b/Localization/en-US/Mods.CalamityMod.Projectiles.Typeless.hjson @@ -94,6 +94,7 @@ PauldronExplosion.DisplayName: Pauldron Explosion PendantProjectile1.DisplayName: Prism Shard PendantProjectile2.DisplayName: Prism Shard PendantProjectile3.DisplayName: Prism Shard +PlaguePulse.DisplayName: Plague Pulse PoisonousSeawater.DisplayName: Seawater PscTransformAnimation.DisplayName: Psc Transform Animation PscTransformRocks.DisplayName: Psc Transform Rocks @@ -133,4 +134,3 @@ WulfrumHook.DisplayName: Wulfrum Slingshot WulfrumLureSignal.DisplayName: Signal YanmeisKnifeSlash.DisplayName: Yanmei's Knife YellowLabSeeker.DisplayName: Seeking Mechanism -PlaguePulse.DisplayName: Plague Pulse diff --git a/Projectiles/Typeless/BasicPlagueBee.cs b/Projectiles/Typeless/BasicPlagueBee.cs index a3ea930c7b..6122f85d3a 100644 --- a/Projectiles/Typeless/BasicPlagueBee.cs +++ b/Projectiles/Typeless/BasicPlagueBee.cs @@ -33,8 +33,8 @@ public override void SetDefaults() Projectile.penetrate = 2; Projectile.timeLeft = 300; Projectile.ignoreWater = true; - Projectile.usesIDStaticNPCImmunity = true; - Projectile.idStaticNPCHitCooldown = 5; + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 12; } public override void AI() @@ -81,9 +81,8 @@ public override void AI() if (Main.rand.NextBool()) { - Dust dust = Dust.NewDustPerfect(Projectile.Center, 303, -Projectile.velocity.RotatedByRandom(0.2f) * Main.rand.NextFloat(0.2f, 0.6f), 0, default, Main.rand.NextFloat(0.35f, 0.55f)); + Dust dust = Dust.NewDustPerfect(Projectile.Center, 89, -Projectile.velocity.RotatedByRandom(0.2f) * Main.rand.NextFloat(0.2f, 0.6f), 0, default, Main.rand.NextFloat(0.5f, 0.8f)); dust.noGravity = true; - dust.color = Color.Black; dust.alpha = Main.rand.Next(90, 220 + 1); } } @@ -125,7 +124,7 @@ public override void AI() center.X = Projectile.Center.X + Projectile.velocity.X * 100f; center.Y = Projectile.Center.Y + Projectile.velocity.Y * 100f; } - float speed = 10f; + float speed = 8f; float velocityTweak = 0.30f; Vector2 projPos = Projectile.Center; Vector2 velocity = center - projPos; @@ -202,7 +201,11 @@ public override void OnKill(int timeLeft) } } - public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) => target.AddBuff(ModContent.BuffType(), (int)(Projectile.ai[1])); + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + target.AddBuff(ModContent.BuffType(), (int)(Projectile.ai[1])); + Projectile.ai[0] = 15; + } public override void OnHitPlayer(Player target, Player.HurtInfo info) => target.AddBuff(ModContent.BuffType(), (int)(Projectile.ai[1])); From 0348cb6717f9be0007f44e942e1b2ae11b83fa8f Mon Sep 17 00:00:00 2001 From: Xyk Date: Tue, 28 May 2024 00:33:03 -0700 Subject: [PATCH 139/401] Small updates --- Items/Accessories/AlchemicalFlask.cs | 3 ++- Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson | 2 +- Projectiles/Typeless/PlaguePulse.cs | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Items/Accessories/AlchemicalFlask.cs b/Items/Accessories/AlchemicalFlask.cs index 8a03636bf3..aea37c1bf8 100644 --- a/Items/Accessories/AlchemicalFlask.cs +++ b/Items/Accessories/AlchemicalFlask.cs @@ -30,7 +30,8 @@ public override void AddRecipes() CreateRecipe(). AddIngredient(ItemID.BottledWater). AddIngredient(ItemID.HoneyComb). - AddIngredient(10). + AddIngredient(ItemID.BeeWax, 8). + AddIngredient(15). AddTile(TileID.MythrilAnvil). Register(); } diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson index f1f7825c5e..069adda0db 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson @@ -1875,7 +1875,7 @@ ToxicHeart: { ''' Causes your heart to beat with powerful plague pulses, inflicting all nearby enemies with the Plague The rate of these pulses scales with how low your life regen is - Pulses that kill targets create additional pulses + Pulses that kill targets create additional pulses and heal you Multiplies all sickness-based debuff damage by 1.5 ''' } diff --git a/Projectiles/Typeless/PlaguePulse.cs b/Projectiles/Typeless/PlaguePulse.cs index 17d8ba03bb..c9439dbd73 100644 --- a/Projectiles/Typeless/PlaguePulse.cs +++ b/Projectiles/Typeless/PlaguePulse.cs @@ -82,6 +82,7 @@ public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) if (target.life <= 0) { + player.Heal(10); Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), target.Center, Vector2.Zero, ModContent.ProjectileType(), (int)(startDamage * 0.8f), 0f, Projectile.owner, 0, 0, 1); } } From 5a9822a67db74faa88d6c25a0d17259189f9e4a7 Mon Sep 17 00:00:00 2001 From: Cameron Ewell Date: Wed, 29 May 2024 23:39:11 -0400 Subject: [PATCH 140/401] Remove ridiculous suggested import in Toxic Heart --- Items/Accessories/ToxicHeart.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Items/Accessories/ToxicHeart.cs b/Items/Accessories/ToxicHeart.cs index cf33597d9c..ca3e9c0e5a 100644 --- a/Items/Accessories/ToxicHeart.cs +++ b/Items/Accessories/ToxicHeart.cs @@ -7,7 +7,6 @@ using Terraria.ID; using Terraria.Audio; using Terraria.ModLoader; -using Microsoft.Build.ObjectModelRemoting; namespace CalamityMod.Items.Accessories { From a465241cac593a427fc5856c283a180e67e9107a Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Wed, 29 May 2024 23:59:56 -0400 Subject: [PATCH 141/401] Added Demolitionist name Dorira for CrimsonCB (donor) --- NPCs/CalamityGlobalTownNPC.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/NPCs/CalamityGlobalTownNPC.cs b/NPCs/CalamityGlobalTownNPC.cs index ae24263c1f..abf91440b3 100644 --- a/NPCs/CalamityGlobalTownNPC.cs +++ b/NPCs/CalamityGlobalTownNPC.cs @@ -94,6 +94,7 @@ public static float TaxYieldFactor { "Tavish DeGroot", // <@!442447226992721930> (magicoal) "Fimmy", // <@!407348617079160832> (darkmega5) + "Dorira", // <@!215269032360804352> (crimsoncb) }; private static readonly string[] DryadNames = { From 86334227b004b55b341557ac9ba7cd549db25cc5 Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Thu, 30 May 2024 13:58:19 +0700 Subject: [PATCH 142/401] Dark Master bugfixes - Reloading mods no longer cause errors - Swapping between items no longer make clones vomit projectiles - Clones now inherit the player's damage and crit stats --- Items/Weapons/Melee/TheDarkMaster.cs | 11 ++- Projectiles/Melee/DarkMasterClone.cs | 103 +++++++++++++-------------- 2 files changed, 59 insertions(+), 55 deletions(-) diff --git a/Items/Weapons/Melee/TheDarkMaster.cs b/Items/Weapons/Melee/TheDarkMaster.cs index 5054b7ed5a..e37cb358fb 100644 --- a/Items/Weapons/Melee/TheDarkMaster.cs +++ b/Items/Weapons/Melee/TheDarkMaster.cs @@ -61,6 +61,13 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, { SoundEngine.PlaySound(SoundID.Item71, player.Center); } + + // force clones to shoot regardless of health + foreach (Projectile p in Main.ActiveProjectiles) + { + if (p.type == ModContent.ProjectileType() && p.owner == player.whoAmI) + p.ai[1] = 1f; + } } else { @@ -72,7 +79,9 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, // summon the clones. position is determined by ai[0] for (int i = 0; i < 3; i++) { - Projectile.NewProjectile(Item.GetSource_FromThis(), player.Center.X, player.Center.Y, 0, 0, ModContent.ProjectileType(), damage, knockback, player.whoAmI, i); + // Stats are set to dynamically update, so damage, kb, crit have to be feeded + Projectile clone = Projectile.NewProjectileDirect(Item.GetSource_FromThis(), player.Center, Vector2.Zero, ModContent.ProjectileType(), Item.damage, Item.knockBack, player.whoAmI, i); + clone.OriginalCritChance = Item.crit; } } } diff --git a/Projectiles/Melee/DarkMasterClone.cs b/Projectiles/Melee/DarkMasterClone.cs index d225c57331..be519e6b44 100644 --- a/Projectiles/Melee/DarkMasterClone.cs +++ b/Projectiles/Melee/DarkMasterClone.cs @@ -15,25 +15,32 @@ public class DarkMasterClone : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Melee"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public Player Owner => Main.player[Projectile.owner]; + public Player clone; + public override void SetDefaults() { Projectile.width = 20; Projectile.height = 42; Projectile.friendly = true; Projectile.ignoreWater = true; - Projectile.DamageType = DamageClass.Melee; - Projectile.timeLeft = 300; - Projectile.penetrate = -1; Projectile.tileCollide = false; + Projectile.DamageType = DamageClass.Melee; + Projectile.ContinuouslyUpdateDamageStats = true; } public override void AI() { + // if the player isn't holding the sword, DIE. + if (Owner.HeldItem.type != ModContent.ItemType() || !Owner.active || Owner.CCed || Owner == null) + { + Projectile.Kill(); + return; + } // if the velocity is not zero, the visuals get offset weirdly Projectile.velocity = Vector2.Zero; - Player owner = Main.player[Projectile.owner]; // how far the clone should move from the player - Vector2 moveTo = new Vector2(0, -160); + Vector2 moveTo = Vector2.UnitY * -160f; switch (Projectile.ai[0]) { case 1: @@ -43,39 +50,34 @@ public override void AI() moveTo = new Vector2(180, 120); break; default: - moveTo = new Vector2(0, -160); break; } - // if the player isn't holding the sword, DIE. - if (owner.HeldItem.type != ModContent.ItemType() || !owner.active || owner.CCed || owner == null) - { - Projectile.Kill(); - } // if all conditions above aren't met, the clone can stick around forever - Projectile.timeLeft = 30; + Projectile.timeLeft = 2; // move the clone to the desired position - Projectile.Center = Vector2.Lerp(Projectile.Center, owner.Center + moveTo, 0.4f); + Projectile.Center = Vector2.Lerp(Projectile.Center, Owner.Center + moveTo, 0.4f); // produce smoke during initial move - if (Projectile.Distance(owner.Center + moveTo) < 16) + if (Projectile.Distance(Owner.Center + moveTo) < 16) { Projectile.ai[2] = 1; } if (Projectile.ai[2] == 0) { - float angle = MathHelper.TwoPi * Main.rand.NextFloat(0f, 1f); + float angle = Main.rand.NextFloat(0f, MathHelper.TwoPi); Vector2 angleVec = angle.ToRotationVector2(); Particle smoke = new HeavySmokeParticle(Projectile.Center, angleVec * Main.rand.NextFloat(1f, 2f), Color.Black, 30, Main.rand.NextFloat(0.25f, 1f), 0.5f, 0.1f); GeneralParticleHandler.SpawnParticle(smoke); } // shoot beams while the player is left clicking - if (owner.itemTime == owner.itemTimeMax && owner.altFunctionUse != 2 && owner.HeldItem.type == ModContent.ItemType()) + if (Projectile.ai[1] > 0) { + Projectile.ai[1] = 0; Vector2 direction = Projectile.Center.DirectionTo(Main.MouseWorld); Projectile.direction = Math.Sign(direction.X); if (Projectile.owner == Main.myPlayer) { // ai[1] not being 0 determines if the projectile should always ignore tiles - Projectile.NewProjectile(Projectile.GetSource_FromAI(), Projectile.Center, direction * owner.HeldItem.shootSpeed, ModContent.ProjectileType(), (int)(Projectile.damage * 0.4f), Projectile.knockBack, Projectile.owner, 1, 1); + Projectile.NewProjectile(Projectile.GetSource_FromAI(), Projectile.Center, direction * Owner.HeldItem.shootSpeed, ModContent.ProjectileType(), (int)(Projectile.damage * 0.4f), Projectile.knockBack, Projectile.owner, 1, 1); } } } @@ -86,7 +88,7 @@ public override void OnKill(int timeLeft) for (int i = 0; i < 8; i++) { - float angle = MathHelper.TwoPi * Main.rand.NextFloat(0f, 1f); + float angle = Main.rand.NextFloat(0f, MathHelper.TwoPi); Vector2 angleVec = angle.ToRotationVector2(); Particle smoke = new HeavySmokeParticle(Projectile.Center, angleVec * Main.rand.NextFloat(2f, 4f), Color.Black, 60, Main.rand.NextFloat(0.45f, 1.22f), 0.6f, 0.1f); GeneralParticleHandler.SpawnParticle(smoke); @@ -96,58 +98,51 @@ public override void OnKill(int timeLeft) public override bool PreDraw(ref Color lightColor) { // make a player visual clone. it inherits the player's hair type and clothes style and is otherwise all black with red pupils - Main.playerVisualClone[Projectile.owner] ??= new(); - Player owner = Main.player[Projectile.owner]; - - Player player = Main.playerVisualClone[Projectile.owner]; - player.CopyVisuals(Main.player[Projectile.owner]); - player.hair = owner.hair; - player.skinVariant = owner.skinVariant; - player.skinColor = Color.Black; - player.shirtColor = Color.Black; - player.underShirtColor = Color.Black; - player.pantsColor = Color.Black; - player.shoeColor = Color.Black; - player.hairColor = Color.Black; - player.eyeColor = Color.Red; + // Main.playerVisualClone[Projectile.owner] will throw stack trace errors on reloads + clone ??= new Player(); + clone.CopyVisuals(Owner); + clone.skinColor = Color.Black; + clone.shirtColor = Color.Black; + clone.underShirtColor = Color.Black; + clone.pantsColor = Color.Black; + clone.shoeColor = Color.Black; + clone.hairColor = Color.Black; + clone.eyeColor = Color.Red; // become one with the shadows - for (int i = 0; i < player.dye.Length; i++) + for (int i = 0; i < clone.dye.Length; i++) { - if (player.dye[i].type != ItemID.ShadowDye) + if (clone.dye[i].type != ItemID.ShadowDye) { - player.dye[i].SetDefaults(ItemID.ShadowDye); + clone.dye[i].SetDefaults(ItemID.ShadowDye); } } // update everything for our little dummy player - player.ResetEffects(); - player.ResetVisibleAccessories(); - player.DisplayDollUpdate(); - player.UpdateSocialShadow(); - player.UpdateDyes(); - player.PlayerFrame(); + clone.ResetEffects(); + clone.ResetVisibleAccessories(); + clone.DisplayDollUpdate(); + clone.UpdateSocialShadow(); + clone.UpdateDyes(); + clone.PlayerFrame(); // copy the player's arm movements while swinging, otherwise idle - if (owner.ItemAnimationActive && owner.altFunctionUse != 2) - player.bodyFrame = owner.bodyFrame; + if (Owner.ItemAnimationActive && Owner.altFunctionUse != 2) + clone.bodyFrame = Owner.bodyFrame; else - player.bodyFrame.Y = 0; + clone.bodyFrame.Y = 0; // legs never jump or walk - player.legFrame.Y = 0; + clone.legFrame.Y = 0; // face towards the player's cursor - player.direction = Math.Sign(Projectile.DirectionTo(Main.MouseWorld).X); - Main.PlayerRenderer.DrawPlayer(Main.Camera, player, Projectile.position, 0f, player.fullRotationOrigin, 0f, 1f); + clone.direction = Math.Sign(Projectile.DirectionTo(Main.MouseWorld).X); + Main.PlayerRenderer.DrawPlayer(Main.Camera, clone, Projectile.position, 0f, clone.fullRotationOrigin, 0f, 1f); // draw the sword - if (owner.ItemAnimationActive && owner.altFunctionUse != 2) + if (Owner.ItemAnimationActive && Owner.altFunctionUse != 2) { Texture2D Sword = ModContent.Request("CalamityMod/Items/Weapons/Melee/TheDarkMaster").Value; - Vector2 distToPlayer = Projectile.position - owner.position; - Main.EntitySpriteDraw(Sword, (Vector2)owner.HandPosition + distToPlayer - Main.screenPosition, null, lightColor, owner.direction == player.direction ? owner.itemRotation : -owner.itemRotation, new Vector2(player.direction == 1 ? 0 : Sword.Width, Sword.Height), 1f, player.direction == 1 ? SpriteEffects.None : SpriteEffects.FlipHorizontally); + Vector2 distToPlayer = Projectile.position - Owner.position; + Main.EntitySpriteDraw(Sword, (Vector2)Owner.HandPosition + distToPlayer - Main.screenPosition, null, lightColor, Owner.direction == clone.direction ? Owner.itemRotation : -Owner.itemRotation, new Vector2(clone.direction == 1 ? 0 : Sword.Width, Sword.Height), 1f, clone.direction == 1 ? SpriteEffects.None : SpriteEffects.FlipHorizontally); } return false; } - public override bool? CanDamage() - { - return false; - } + public override bool? CanDamage() => false; } } From 41bb121913d30d3f4fe752616d79054ba28772d1 Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Thu, 30 May 2024 15:18:13 +0700 Subject: [PATCH 143/401] Dragon's Breath swap fix it does not involve nuh uh uh this time --- Items/Weapons/Ranged/DragonsBreath.cs | 87 ++++++++++++--------------- 1 file changed, 38 insertions(+), 49 deletions(-) diff --git a/Items/Weapons/Ranged/DragonsBreath.cs b/Items/Weapons/Ranged/DragonsBreath.cs index cb954c9f0f..c3162d97ca 100644 --- a/Items/Weapons/Ranged/DragonsBreath.cs +++ b/Items/Weapons/Ranged/DragonsBreath.cs @@ -22,13 +22,13 @@ public class DragonsBreath : ModItem, ILocalizedModType public SlotId WeldSoundSlot; - public int BetweenShotsPause = 14; - public float Counter = 2; - public float MaxFirerateShots = 20; - public float WeldingShots = 50; - public bool StrongShotMode = false; - public int DragonsBreathSetUseTime = 5; - public int DragonsBreathSetUseAnimation = 9; + public static int BaseReuseDelay = 14; + public static int MinReuseDelay = 4; + public static int ShotsToMaxFirerate = 20; + public static int ShotsToFireBeams = ShotsToMaxFirerate + 20; + public static int ShotsToReset = ShotsToFireBeams + 50; + + public int Counter = 0; public override void SetDefaults() { @@ -36,9 +36,9 @@ public override void SetDefaults() Item.height = 72; Item.damage = 478; Item.DamageType = DamageClass.Ranged; - Item.useTime = DragonsBreathSetUseTime; - Item.useAnimation = DragonsBreathSetUseAnimation; - Item.reuseDelay = BetweenShotsPause; + Item.useTime = 5; + Item.useAnimation = 9; + Item.reuseDelay = BaseReuseDelay; Item.autoReuse = true; Item.useStyle = ItemUseStyleID.Shoot; @@ -52,69 +52,58 @@ public override void SetDefaults() Item.rare = ModContent.RarityType(); Item.value = CalamityGlobalItem.RarityVioletBuyPrice; } - public override bool CanConsumeAmmo(Item ammo, Player player) => !StrongShotMode && Main.rand.NextFloat() > 0.80f; + public override bool CanConsumeAmmo(Item ammo, Player player) => Counter < ShotsToFireBeams && Main.rand.NextFloat() > 0.80f; - public override Vector2? HoldoutOffset() => new Vector2(27, 10); + public override Vector2? HoldoutOffset() => new Vector2(27, 6); public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) { - if (!StrongShotMode) + Counter++; + if (Counter < ShotsToFireBeams) { - if (Counter == 2) + if (Counter % 2 == 1) SoundEngine.PlaySound(FireballSound, player.Center); + Vector2 newVel = velocity.RotatedByRandom(MathHelper.ToRadians(2.5f)); Projectile.NewProjectile(source, position, newVel * Main.rand.NextFloat(1.2f, 0.8f), type, damage, knockback, player.whoAmI); - Counter--; - if (MaxFirerateShots > 0 && BetweenShotsPause == 4) - MaxFirerateShots--; - if (Counter <= 0) - { - if (BetweenShotsPause > 4) - { - BetweenShotsPause -= 1; - Item.reuseDelay = BetweenShotsPause; - } - Counter = 2; - } - if (BetweenShotsPause <= 4 && MaxFirerateShots == 0) - { - BetweenShotsPause = 0; - Item.reuseDelay = BetweenShotsPause; - StrongShotMode = true; - DragonsBreathSetUseTime = 2; - DragonsBreathSetUseAnimation = 2; - SoundEngine.PlaySound(WeldingStart, player.Center); - } + Item.reuseDelay = (int)Utils.Remap(Counter, 0, ShotsToMaxFirerate, BaseReuseDelay, MinReuseDelay); } - else if (StrongShotMode) + else { + if (Counter == ShotsToFireBeams) + SoundEngine.PlaySound(WeldingStart, player.Center); + if (SoundEngine.TryGetActiveSound(WeldSoundSlot, out var WeldSound) && WeldSound.IsPlaying) WeldSound.Position = player.Center; - if ((player.Calamity().DragonsBreathAudioCooldown2 == 0) && (WeldingShots < 45)) + if (player.Calamity().DragonsBreathAudioCooldown2 == 0 && Counter >= ShotsToFireBeams + 5) { player.Calamity().DragonsBreathAudioCooldown2 = 30; WeldSoundSlot = SoundEngine.PlaySound(WeldingShoot, player.Center); } - Projectile.NewProjectile(source, position, velocity * 2f, ModContent.ProjectileType(), damage, knockback, player.whoAmI, 1); - WeldingShots--; - if (WeldingShots <= 0) + + Projectile.NewProjectile(source, position, velocity * 2f, type, damage, knockback, player.whoAmI, 1); + Item.reuseDelay = 0; + + if (Counter >= ShotsToReset) { - Counter = 2; - BetweenShotsPause = 14; - Item.reuseDelay = BetweenShotsPause; + Counter = 0; + Item.reuseDelay = BaseReuseDelay; SoundEngine.PlaySound(SpeedBlaster.Empty, player.Center); Projectile.NewProjectile(source, player.Center, new Vector2(5 * -player.direction, -5), ModContent.ProjectileType(), Main.zenithWorld ? 250000 : 1, knockback, player.whoAmI); - MaxFirerateShots = 20; - WeldingShots = 50; WeldSound?.Stop(); - StrongShotMode = false; - DragonsBreathSetUseTime = 5; - DragonsBreathSetUseAnimation = 9; } } return false; } + + public override void UpdateInventory(Player player) + { + // Reset speed back to initial once swapped to another item (including one of itself) + if (player.ActiveItem() != Item) + Counter = 0; + } + public override void UseStyle(Player player, Rectangle heldItemFrame) { player.ChangeDir(Math.Sign((player.Calamity().mouseWorld - player.Center).X)); @@ -136,7 +125,7 @@ public override void UseItemFrame(Player player) float animProgress = 0.5f - player.itemTime / (float)player.itemTimeMax; float rotation = (player.Center - player.Calamity().mouseWorld).ToRotation() * player.gravDir + MathHelper.PiOver2; if (animProgress < 0.4f) - rotation += StrongShotMode && WeldingShots == 1 ? -0.25f * (float)Math.Pow((0.6f - animProgress) / 0.6f, 2) * player.direction : 0; + rotation += Counter == 0 ? -0.25f * (float)Math.Pow((0.6f - animProgress) / 0.6f, 2) * player.direction : 0; player.SetCompositeArmFront(true, Player.CompositeArmStretchAmount.Full, rotation); } From 9c820cd559b6ba15661d5bf94625514c044c8d98 Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Thu, 30 May 2024 17:19:30 +0700 Subject: [PATCH 144/401] Implemented Prismatic Breaker damage class --- DamageClasses/MeleeRangedHybridDamageClass.cs | 27 +++++++++++++++++++ Items/Weapons/Melee/PrismaticBreaker.cs | 15 +++-------- .../Mods.CalamityMod.DamageClasses.hjson | 3 ++- Projectiles/Melee/PrismaticBeam.cs | 3 +-- Projectiles/Melee/PrismaticWave.cs | 3 +-- Utilities/ItemUtils.cs | 2 +- 6 files changed, 35 insertions(+), 18 deletions(-) create mode 100644 DamageClasses/MeleeRangedHybridDamageClass.cs diff --git a/DamageClasses/MeleeRangedHybridDamageClass.cs b/DamageClasses/MeleeRangedHybridDamageClass.cs new file mode 100644 index 0000000000..1dc965aade --- /dev/null +++ b/DamageClasses/MeleeRangedHybridDamageClass.cs @@ -0,0 +1,27 @@ +using Terraria.ModLoader; + +namespace CalamityMod +{ + public class MeleeRangedHybridDamageClass : DamageClass + { + internal static MeleeRangedHybridDamageClass Instance; + + internal static readonly StatInheritanceData FiftyPercentBoost = new(0.5f, 0.5f, 0.5f, 0.5f, 0.5f); + + public override void Load() => Instance = this; + public override void Unload() => Instance = null; + + public override StatInheritanceData GetModifierInheritance(DamageClass damageClass) + { + if (damageClass == Melee || damageClass == Ranged) + return FiftyPercentBoost; + if (damageClass == Generic) + return StatInheritanceData.Full; + + return StatInheritanceData.None; + } + + // Inherits from both melee and ranged + public override bool GetEffectInheritance(DamageClass damageClass) => damageClass == Melee || damageClass == Ranged; + } +} diff --git a/Items/Weapons/Melee/PrismaticBreaker.cs b/Items/Weapons/Melee/PrismaticBreaker.cs index f86e75a993..81ad513f31 100644 --- a/Items/Weapons/Melee/PrismaticBreaker.cs +++ b/Items/Weapons/Melee/PrismaticBreaker.cs @@ -48,10 +48,7 @@ public override void SetDefaults() Item.useStyle = ItemUseStyleID.Swing; Item.useTime = Item.useAnimation = 13; Item.useTurn = true; - // TODO -- Prismatic Breaker should have its own damage type which is half Ranged, half Melee. - // Right now, it uses a hacky damage formula, see below. - // Its custom damage class should CountAs both melee AND ranged for the sake of effects. - Item.DamageType = DamageClass.Melee; + Item.DamageType = MeleeRangedHybridDamageClass.Instance; Item.knockBack = 7f; Item.UseSound = SoundID.Item1; Item.autoReuse = true; @@ -65,12 +62,6 @@ public override void SetDefaults() // Terraria seems to really dislike high crit values in SetDefaults public override void ModifyWeaponCrit(Player player, ref float crit) => crit += 8; - public override void ModifyWeaponDamage(Player player, ref StatModifier damage) - { - StatModifier halfMelee = damage.Scale(0.5f); - damage = halfMelee.CombineWith(player.GetTotalDamage().Scale(0.5f)); - } - public override void PostDrawInWorld(SpriteBatch spriteBatch, Color lightColor, Color alphaColor, float rotation, float scale, int whoAmI) { Item.DrawItemGlowmaskSingleFrame(spriteBatch, rotation, ModContent.Request("CalamityMod/Items/Weapons/Melee/PrismaticBreakerGlow").Value); @@ -80,11 +71,11 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, { if (player.altFunctionUse == 2) { - Projectile.NewProjectile(source, position.X, position.Y, velocity.X, velocity.Y, ModContent.ProjectileType(), damage, knockback, player.whoAmI); + Projectile.NewProjectile(source, position, velocity, ModContent.ProjectileType(), damage, knockback, player.whoAmI); } else { - Projectile.NewProjectile(source, position.X, position.Y, velocity.X * 0.5f, velocity.Y * 0.5f, type, (int)(damage * 1.1f), knockback, player.whoAmI); + Projectile.NewProjectile(source, position, velocity * 0.5f, type, (int)(damage * 1.1f), knockback, player.whoAmI); } return false; } diff --git a/Localization/en-US/Mods.CalamityMod.DamageClasses.hjson b/Localization/en-US/Mods.CalamityMod.DamageClasses.hjson index 5b565b8e71..b261db6100 100644 --- a/Localization/en-US/Mods.CalamityMod.DamageClasses.hjson +++ b/Localization/en-US/Mods.CalamityMod.DamageClasses.hjson @@ -1,5 +1,6 @@ AverageDamageClass.DisplayName: average damage +MeleeRangedHybridDamageClass.DisplayName: melee/ranged damage RogueDamageClass.DisplayName: rogue damage +StealthDamageClass.DisplayName: stealth damage TrueMeleeDamageClass.DisplayName: true melee damage TrueMeleeNoSpeedDamageClass.DisplayName: true melee damage -StealthDamageClass.DisplayName: Stealth Damage Class diff --git a/Projectiles/Melee/PrismaticBeam.cs b/Projectiles/Melee/PrismaticBeam.cs index e043fec076..34a62917e7 100644 --- a/Projectiles/Melee/PrismaticBeam.cs +++ b/Projectiles/Melee/PrismaticBeam.cs @@ -61,8 +61,7 @@ public override void SetDefaults() Projectile.width = 6; Projectile.height = 6; Projectile.friendly = true; - Projectile.DamageType = DamageClass.Ranged; - Projectile.DamageType = DamageClass.Melee; + Projectile.DamageType = MeleeRangedHybridDamageClass.Instance; Projectile.scale = 1.5f; Projectile.penetrate = -1; Projectile.tileCollide = false; diff --git a/Projectiles/Melee/PrismaticWave.cs b/Projectiles/Melee/PrismaticWave.cs index 582a55ff9b..532d89d457 100644 --- a/Projectiles/Melee/PrismaticWave.cs +++ b/Projectiles/Melee/PrismaticWave.cs @@ -50,8 +50,7 @@ public override void SetDefaults() Projectile.height = 36; Projectile.friendly = true; Projectile.ignoreWater = true; - Projectile.DamageType = DamageClass.Ranged; - Projectile.DamageType = DamageClass.Melee; + Projectile.DamageType = MeleeRangedHybridDamageClass.Instance; Projectile.penetrate = 2; Projectile.timeLeft = 360; Projectile.tileCollide = false; diff --git a/Utilities/ItemUtils.cs b/Utilities/ItemUtils.cs index 2a1911dd9e..1d227c7f80 100644 --- a/Utilities/ItemUtils.cs +++ b/Utilities/ItemUtils.cs @@ -132,7 +132,7 @@ int GetCalPrefix(string name) } // MELEE (includes tools and whips) - else if (item.CountsAsClass() || item.CountsAsClass()) + else if (item.CountsAsClass() || item.CountsAsClass() || item.CountsAsClass()) { // Terrarian (has its own special "Legendary" for marketing reasons) // Other items that want to use Legendary2 are also compatible From 4ce9c6131c2103dfba8dc8d8984d926c8659e891 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Thu, 30 May 2024 10:22:15 -0400 Subject: [PATCH 145/401] Warmth Potion now reduces debuff durations instead of giving full immunity Also reduced the volume of Greatsword of Judgement's whiterain --- Buffs/CalamityGlobalBuff.cs | 7 ------- CalPlayer/CalamityPlayerMiscEffects.cs | 15 +++++++++++++++ Items/CalamityGlobalItemTooltip.cs | 4 ++-- Localization/en-US/Mods.CalamityMod.Vanilla.hjson | 2 +- Projectiles/Melee/Whiterain.cs | 2 +- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/Buffs/CalamityGlobalBuff.cs b/Buffs/CalamityGlobalBuff.cs index 93d68380d4..a8239f952a 100644 --- a/Buffs/CalamityGlobalBuff.cs +++ b/Buffs/CalamityGlobalBuff.cs @@ -88,13 +88,6 @@ public override void Update(int type, Player player, ref int buffIndex) { player.endurance += BalancingConstants.SolarFlareShieldDR; } - - else if (type == BuffID.Warmth) - { - player.buffImmune[ModContent.BuffType()] = true; - player.buffImmune[BuffID.Frozen] = true; - player.buffImmune[BuffID.Chilled] = true; - } else if (type == BuffID.Rabies) { player.GetDamage() -= 0.2f; diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index f93f0dd1ea..2185b0fce0 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -2530,6 +2530,21 @@ private void OtherBuffEffects() if (AdamantiteSet) Player.statDefense += AdamantiteSetDefenseBoost; + // Warmth makes Chilled, Frozen, and Glacial State tick down 3x as fast + if (Player.HasBuff(BuffID.Warmth)) + { + for (int b = 0; b < Player.MaxBuffs; b++) + { + if (Player.buffType[b] == BuffID.Chilled || Player.buffType[b] == BuffID.Frozen || Player.buffType[b] == ModContent.BuffType()) + { + if (Player.buffTime[b] > 3) + { + Player.buffTime[b] -= 2; + } + } + } + } + if (astralInjection) { if (Player.statMana < Player.statManaMax2) diff --git a/Items/CalamityGlobalItemTooltip.cs b/Items/CalamityGlobalItemTooltip.cs index 3a07a6d2b9..b7ae69bfc6 100644 --- a/Items/CalamityGlobalItemTooltip.cs +++ b/Items/CalamityGlobalItemTooltip.cs @@ -326,10 +326,10 @@ void AddTooltip(string text) if (item.type == ItemID.AegisCrystal) EditTooltipByNum(0, (line) => line.Text = "Permanently boosts natural life regeneration"); - // Warmth Potion provides debuff immunities + // Warmth Potion reduces debuff durations if (item.type == ItemID.WarmthPotion) { - string immunityLine = "\nGrants immunity to Chilled, Frozen and Glacial State"; + string immunityLine = "\nGreatly reduces the duration of Chilled, Frozen, and Glacial State"; EditTooltipByNum(0, (line) => line.Text += immunityLine); } diff --git a/Localization/en-US/Mods.CalamityMod.Vanilla.hjson b/Localization/en-US/Mods.CalamityMod.Vanilla.hjson index aed63d706f..4373a9e37f 100644 --- a/Localization/en-US/Mods.CalamityMod.Vanilla.hjson +++ b/Localization/en-US/Mods.CalamityMod.Vanilla.hjson @@ -4,7 +4,7 @@ BuffDescription: { BeetleMight: Melee damage and speed increase by {0}% and {1}% respectively ChaosState: Rod of Discord teleports are disabled LeafCrystal: Emits powerful life pulses at nearby enemies - WarmthExtra: Grants immunity to Chilled, Frozen and Glacial State + WarmthExtra: Reduced durations of Chilled, Frozen, and Glacial State WeaponImbueConfetti: All attacks cause confetti to appear WeaponImbueCursedFlames: Melee, Whip, and Rogue attacks inflict enemies with cursed flames WeaponImbueFire: Melee, Whip, and Rogue attacks set enemies on fire diff --git a/Projectiles/Melee/Whiterain.cs b/Projectiles/Melee/Whiterain.cs index 1b5cacdb91..0bf0617dfa 100644 --- a/Projectiles/Melee/Whiterain.cs +++ b/Projectiles/Melee/Whiterain.cs @@ -28,7 +28,7 @@ public override void AI() if (Projectile.ai[1] == 0f) { Projectile.ai[1] = 1f; - SoundEngine.PlaySound(SoundID.Item125, Projectile.Center); + SoundEngine.PlaySound(SoundID.Item125 with { Volume = 0.7f }, Projectile.Center); } Lighting.AddLight(Projectile.Center, 0.2f, 0.2f, 0.2f); From efa733d40bc810b66371190894a1bae96fd474df Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Thu, 30 May 2024 13:28:47 -0500 Subject: [PATCH 146/401] Fixed some other strange issues with Hive Mind --- NPCs/HiveMind/HiveMind.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/NPCs/HiveMind/HiveMind.cs b/NPCs/HiveMind/HiveMind.cs index b355b66504..3b9158b12f 100644 --- a/NPCs/HiveMind/HiveMind.cs +++ b/NPCs/HiveMind/HiveMind.cs @@ -1204,18 +1204,18 @@ public override void HitEffect(NPC.HitInfo hit) if (!phase2) { - if (NPC.CountNPCS(NPCID.EaterofSouls) < 3 && NPC.CountNPCS(NPCID.DevourerHead) < 1) + if (Main.netMode != NetmodeID.MultiplayerClient) { - if (Main.rand.NextBool(60) && Main.netMode != NetmodeID.MultiplayerClient) + if (Main.rand.NextBool(60)) { - Vector2 spawnAt = NPC.Center + new Vector2(0f, NPC.height / 2f); - NPC.NewNPC(NPC.GetSource_FromThis(), (int)spawnAt.X, (int)spawnAt.Y, NPCID.EaterofSouls); + if (NPC.CountNPCS(NPCID.EaterofSouls) < 3) + NPC.NewNPC(NPC.GetSource_FromThis(), (int)NPC.Center.X, (int)NPC.Center.Y, NPCID.EaterofSouls); } - if (Main.rand.NextBool(150) && Main.netMode != NetmodeID.MultiplayerClient) + if (Main.rand.NextBool(150)) { - Vector2 spawnAt = NPC.Center + new Vector2(0f, NPC.height / 2f); - NPC.NewNPC(NPC.GetSource_FromThis(), (int)spawnAt.X, (int)spawnAt.Y, NPCID.DevourerHead); + if (!NPC.AnyNPCs(NPCID.DevourerHead)) + NPC.NewNPC(NPC.GetSource_FromThis(), (int)NPC.Center.X, (int)NPC.Center.Y, NPCID.DevourerHead); } } } From c8cf19fda1ad147aa600e36a25f5bde25c50251e Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Thu, 30 May 2024 16:05:22 -0500 Subject: [PATCH 147/401] 1 - Dank Creeper Kill Yourself Ability. 2 - Hive Mind and minion targeting rework. 3 - Brain Rot infliction from Shade Nimbus and Rain is no longer ridiculous. 4 - Hive Mind and Dank Creepers inflict Brain Rot on hit. --- NPCs/HiveMind/DankCreeper.cs | 88 +++++++++++++++----------- NPCs/HiveMind/DarkHeart.cs | 45 ++++++++----- NPCs/HiveMind/HiveBlob.cs | 15 ++--- NPCs/HiveMind/HiveBlob2.cs | 15 ++--- NPCs/HiveMind/HiveMind.cs | 25 +++++--- Projectiles/Boss/ShadeNimbusHostile.cs | 4 +- Projectiles/Boss/ShaderainHostile.cs | 13 +--- 7 files changed, 113 insertions(+), 92 deletions(-) diff --git a/NPCs/HiveMind/DankCreeper.cs b/NPCs/HiveMind/DankCreeper.cs index a9328ad75e..a6e676023c 100644 --- a/NPCs/HiveMind/DankCreeper.cs +++ b/NPCs/HiveMind/DankCreeper.cs @@ -1,4 +1,5 @@ using System; +using CalamityMod.Buffs.DamageOverTime; using CalamityMod.Events; using CalamityMod.Projectiles.Boss; using CalamityMod.World; @@ -25,7 +26,7 @@ public override void SetDefaults() NPC.height = 70; NPC.defense = 6; - NPC.lifeMax = 90; + NPC.lifeMax = 120; if (BossRushEvent.BossRushActive) NPC.lifeMax = 2000; if (Main.getGoodWorld) @@ -58,10 +59,13 @@ public override void AI() // Avoid cheap bullshit NPC.damage = 0; - NPC.TargetClosest(); + // Get a target + if (NPC.target < 0 || NPC.target == Main.maxPlayers || Main.player[NPC.target].dead || !Main.player[NPC.target].active) + NPC.TargetClosest(); + bool masterMode = Main.masterMode; bool revenge = CalamityWorld.revenge; - float speed = revenge ? 12f : 11f; + float speed = masterMode ? 15f : revenge ? 13f : 11f; if (BossRushEvent.BossRushActive) speed = 18f; @@ -73,56 +77,66 @@ public override void AI() NPC.rotation = NPC.velocity.X * 0.05f; Vector2 targetDirection = new Vector2(NPC.Center.X + (NPC.direction * 20), NPC.Center.Y + 6f); - float playerXDist = Main.player[NPC.target].position.X + Main.player[NPC.target].width * 0.5f - targetDirection.X; - float playerYDist = Main.player[NPC.target].Center.Y - targetDirection.Y; - float playerDistance = (float)Math.Sqrt(playerXDist * playerXDist + playerYDist * playerYDist); - float timeToReachTarget = speed / playerDistance; - playerXDist *= timeToReachTarget; - playerYDist *= timeToReachTarget; - - NPC.ai[0] -= 1f; - if (playerDistance < 200f || NPC.ai[0] > 0f) + Vector2 targetLocation = Main.player[NPC.target].Center; + + // Fly above if below 25% HP and burst to spawn a Rain Cloud when high enough + bool killYourself = NPC.life / (float)NPC.lifeMax < 0.25f; + if (killYourself && (Main.expertMode || BossRushEvent.BossRushActive)) { - // Set damage - NPC.damage = NPC.defDamage; + targetLocation -= Vector2.UnitY * 400f; + if (NPC.Distance(targetLocation) < 80f) + { + NPC.life = 0; + NPC.HitEffect(); + NPC.checkDead(); + return; + } + } - if (playerDistance < 200f) - NPC.ai[0] = 20f; + if (!killYourself) + { + NPC.ai[0] -= 1f; + bool dash = NPC.Distance(targetLocation) < 200f; + if (dash || NPC.ai[0] > 0f) + { + // Set damage + NPC.damage = NPC.defDamage; - if (NPC.velocity.X < 0f) - NPC.direction = -1; - else - NPC.direction = 1; + if (dash) + NPC.ai[0] = 20f; - return; - } + if (NPC.velocity.X < 0f) + NPC.direction = -1; + else + NPC.direction = 1; - NPC.velocity.X = (NPC.velocity.X * 50f + playerXDist) / 51f; - NPC.velocity.Y = (NPC.velocity.Y * 50f + playerYDist) / 51f; - if (playerDistance < 350f) - { - NPC.velocity.X = (NPC.velocity.X * 10f + playerXDist) / 11f; - NPC.velocity.Y = (NPC.velocity.Y * 10f + playerYDist) / 11f; - } - if (playerDistance < 300f) - { - NPC.velocity.X = (NPC.velocity.X * 7f + playerXDist) / 8f; - NPC.velocity.Y = (NPC.velocity.Y * 7f + playerYDist) / 8f; + return; + } } + + float inertia = (NPC.Distance(targetLocation) < 300f || killYourself) ? 8f : NPC.Distance(targetLocation) < 400f ? 20f : 50f; + Vector2 idealVelocity = (targetLocation - targetDirection).SafeNormalize(Vector2.UnitX * NPC.direction) * speed; + NPC.velocity = (NPC.velocity * inertia + idealVelocity) / (inertia + 1f); + } + + public override void OnHitPlayer(Player target, Player.HurtInfo hurtInfo) + { + if (hurtInfo.Damage < 0) + return; + + target.AddBuff(ModContent.BuffType(), 180); } public override void HitEffect(NPC.HitInfo hit) { for (int k = 0; k < 5; k++) - { Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Glass, hit.HitDirection, -1f, 0, default, 1f); - } + if (NPC.life <= 0) { for (int k = 0; k < 20; k++) - { Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Glass, hit.HitDirection, -1f, 0, default, 1f); - } + if (Main.netMode != NetmodeID.Server) { Gore.NewGore(NPC.GetSource_Death(), NPC.position, NPC.velocity, Mod.Find("DankCreeperGore").Type, 1f); diff --git a/NPCs/HiveMind/DarkHeart.cs b/NPCs/HiveMind/DarkHeart.cs index a96a194763..0a6591b66e 100644 --- a/NPCs/HiveMind/DarkHeart.cs +++ b/NPCs/HiveMind/DarkHeart.cs @@ -60,15 +60,26 @@ public override void AI() // Setting this in SetDefaults will disable expert mode scaling, so put it here instead NPC.damage = 0; + bool masterMode = Main.masterMode || BossRushEvent.BossRushActive; bool revenge = CalamityWorld.revenge || BossRushEvent.BossRushActive; + bool death = CalamityWorld.death || BossRushEvent.BossRushActive; // Float around the player NPC.rotation = NPC.velocity.X / 20f; - NPC.TargetClosest(); + // Get a target + if (NPC.target < 0 || NPC.target == Main.maxPlayers || Main.player[NPC.target].dead || !Main.player[NPC.target].active) + NPC.TargetClosest(); - float velocity = (CalamityWorld.LegendaryMode && CalamityWorld.revenge) ? 10f : revenge ? 6f : 4f; - float acceleration = (CalamityWorld.LegendaryMode && CalamityWorld.revenge) ? 0.5f : revenge ? 0.3f : 0.2f; + float velocity = (CalamityWorld.LegendaryMode && CalamityWorld.revenge) ? 10f : death ? 7f : revenge ? 6f : 4f; + float acceleration = (CalamityWorld.LegendaryMode && CalamityWorld.revenge) ? 0.5f : death ? 0.35f : revenge ? 0.3f : 0.2f; + float deceleration = (CalamityWorld.LegendaryMode && CalamityWorld.revenge) ? 0.9f : death ? 0.95f : revenge ? 0.96f : 0.98f; + if (masterMode) + { + velocity += 2f; + acceleration += 0.2f; + deceleration -= 0.05f; + } if (BossRushEvent.BossRushActive) { velocity *= 2f; @@ -78,7 +89,7 @@ public override void AI() if (NPC.position.Y > Main.player[NPC.target].position.Y - 350f) { if (NPC.velocity.Y > 0f) - NPC.velocity.Y *= 0.98f; + NPC.velocity.Y *= deceleration; NPC.velocity.Y -= acceleration; @@ -88,7 +99,7 @@ public override void AI() else if (NPC.position.Y < Main.player[NPC.target].position.Y - 450f) { if (NPC.velocity.Y < 0f) - NPC.velocity.Y *= 0.98f; + NPC.velocity.Y *= deceleration; NPC.velocity.Y += acceleration; @@ -97,35 +108,38 @@ public override void AI() } bool dropRain = NPC.Bottom.Y < Main.player[NPC.target].position.Y - 200f && Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[NPC.target].position, Main.player[NPC.target].width, Main.player[NPC.target].height); - if (NPC.Center.X > Main.player[NPC.target].Center.X + 400f) + float distanceX = masterMode ? 200f : 400f; + float velocityX = velocity * 1.5f; + if (NPC.Center.X > Main.player[NPC.target].Center.X + distanceX) { dropRain = false; if (NPC.velocity.X > 0f) - NPC.velocity.X *= 0.98f; + NPC.velocity.X *= deceleration; NPC.velocity.X -= acceleration; - if (NPC.velocity.X > 8f) - NPC.velocity.X = 8f; + if (NPC.velocity.X > velocityX) + NPC.velocity.X = velocityX; } - if (NPC.Center.X < Main.player[NPC.target].Center.X - 400f) + if (NPC.Center.X < Main.player[NPC.target].Center.X - distanceX) { dropRain = false; if (NPC.velocity.X < 0f) - NPC.velocity.X *= 0.98f; + NPC.velocity.X *= deceleration; NPC.velocity.X += acceleration; - if (NPC.velocity.X < -8f) - NPC.velocity.X = -8f; + if (NPC.velocity.X < -velocityX) + NPC.velocity.X = -velocityX; } if (dropRain && Main.netMode != NetmodeID.MultiplayerClient) { NPC.ai[0] += 1f; - if (NPC.ai[0] >= (Main.getGoodWorld ? 12f : 24f)) + float rainDropRate = Main.getGoodWorld ? 8f : death ? 16f : revenge ? 20f : 24f; + if (NPC.ai[0] >= rainDropRate) { NPC.ai[0] = 0f; int shaderainXPos = (int)(NPC.position.X + 10f + Main.rand.Next(NPC.width - 20)); @@ -133,7 +147,8 @@ public override void AI() int type = ModContent.ProjectileType(); int damage = NPC.GetProjectileDamage(type); float randomXVelocity = (CalamityWorld.LegendaryMode && CalamityWorld.revenge) ? Main.rand.NextFloat() * 5f : 0f; - Projectile.NewProjectile(NPC.GetSource_FromAI(), shaderainXPos, shaderainYos, randomXVelocity, 4f, type, damage, 0f, Main.myPlayer); + float velocityY = 8f; + Projectile.NewProjectile(NPC.GetSource_FromAI(), shaderainXPos, shaderainYos, randomXVelocity, velocityY, type, damage, 0f, Main.myPlayer); } } } diff --git a/NPCs/HiveMind/HiveBlob.cs b/NPCs/HiveMind/HiveBlob.cs index 63398f2ab9..6e7c638703 100644 --- a/NPCs/HiveMind/HiveBlob.cs +++ b/NPCs/HiveMind/HiveBlob.cs @@ -104,8 +104,6 @@ public override void AI() } } - NPC.TargetClosest(); - float hiveMindVelocity = Main.npc[hiveMind].velocity.Length(); float relocateSpeed = getFuckedAI ? 1.2f : death ? 0.8f : revenge ? 0.7f : expertMode ? 0.6f : 0.5f; float acceleration = 0.8f; @@ -160,7 +158,7 @@ public override void AI() if (Main.netMode != NetmodeID.MultiplayerClient) { - if (!Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[NPC.target].position, Main.player[NPC.target].width, Main.player[NPC.target].height)) + if (!Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[Main.npc[hiveMind].target].position, Main.player[Main.npc[hiveMind].target].width, Main.player[Main.npc[hiveMind].target].height)) NPC.localAI[1] = ShootGateValue * 0.5f; float shootGateValue = ShootGateValue; @@ -176,11 +174,10 @@ public override void AI() if (NPC.alpha > 0) return; - if (NPC.localAI[1] >= shootGateValue && Vector2.Distance(Main.player[NPC.target].Center, NPC.Center) > 80f) + if (NPC.localAI[1] >= shootGateValue && Vector2.Distance(Main.player[Main.npc[hiveMind].target].Center, NPC.Center) > 80f) { NPC.localAI[1] = 0f; - NPC.TargetClosest(); - if (Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[NPC.target].position, Main.player[NPC.target].width, Main.player[NPC.target].height)) + if (Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[Main.npc[hiveMind].target].position, Main.player[Main.npc[hiveMind].target].width, Main.player[Main.npc[hiveMind].target].height)) { float projSpeed = death ? 8f : revenge ? 7f : expertMode ? 6f : 4f; if (masterMode) @@ -189,8 +186,8 @@ public override void AI() projSpeed *= 1.5f; Vector2 projDirection = NPC.Center; - float playerX = Main.player[NPC.target].Center.X - projDirection.X; - float playerY = Main.player[NPC.target].Center.Y - projDirection.Y; + float playerX = Main.player[Main.npc[hiveMind].target].Center.X - projDirection.X; + float playerY = Main.player[Main.npc[hiveMind].target].Center.Y - projDirection.Y; float playerDist = (float)Math.Sqrt(playerX * playerX + playerY * playerY); playerDist = projSpeed / playerDist; playerX *= playerDist; @@ -200,7 +197,7 @@ public override void AI() Vector2 projectileVelocity = new Vector2(playerX, playerY); if (type == ProjectileID.CursedFlameHostile) { - Vector2 v = Main.player[NPC.target].Center - NPC.Center - Main.player[NPC.target].velocity * 20f; + Vector2 v = Main.player[Main.npc[hiveMind].target].Center - NPC.Center - Main.player[Main.npc[hiveMind].target].velocity * 20f; projectileVelocity = v.SafeNormalize(Vector2.UnitY) * projSpeed; } Projectile.NewProjectile(NPC.GetSource_FromAI(), projDirection, projectileVelocity, type, damage, 0f, Main.myPlayer); diff --git a/NPCs/HiveMind/HiveBlob2.cs b/NPCs/HiveMind/HiveBlob2.cs index 14853a8c6c..9b3e44fd1f 100644 --- a/NPCs/HiveMind/HiveBlob2.cs +++ b/NPCs/HiveMind/HiveBlob2.cs @@ -107,8 +107,6 @@ public override void AI() } } - NPC.TargetClosest(); - float hiveMindVelocity = Main.npc[hiveMind].velocity.Length(); float relocateSpeed = getFuckedAI ? 1.2f : death ? 0.8f : revenge ? 0.7f : expertMode ? 0.6f : 0.5f; float acceleration = 0.8f; @@ -163,7 +161,7 @@ public override void AI() if (Main.netMode != NetmodeID.MultiplayerClient) { - if (!Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[NPC.target].position, Main.player[NPC.target].width, Main.player[NPC.target].height)) + if (!Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[Main.npc[hiveMind].target].position, Main.player[Main.npc[hiveMind].target].width, Main.player[Main.npc[hiveMind].target].height)) NPC.localAI[1] = ShootGateValue * 0.5f; float shootGateValue = ShootGateValue; @@ -179,11 +177,10 @@ public override void AI() if (NPC.alpha > 0) return; - if (NPC.localAI[1] >= shootGateValue && Vector2.Distance(Main.player[NPC.target].Center, NPC.Center) > 80f) + if (NPC.localAI[1] >= shootGateValue && Vector2.Distance(Main.player[Main.npc[hiveMind].target].Center, NPC.Center) > 80f) { NPC.localAI[1] = 0f; - NPC.TargetClosest(); - if (Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[NPC.target].position, Main.player[NPC.target].width, Main.player[NPC.target].height)) + if (Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[Main.npc[hiveMind].target].position, Main.player[Main.npc[hiveMind].target].width, Main.player[Main.npc[hiveMind].target].height)) { float projSpeed = death ? 8f : revenge ? 7f : expertMode ? 6f : 4f; if (masterMode) @@ -192,8 +189,8 @@ public override void AI() projSpeed *= 1.5f; Vector2 projDirection = NPC.Center; - float playerX = Main.player[NPC.target].Center.X - projDirection.X; - float playerY = Main.player[NPC.target].Center.Y - projDirection.Y; + float playerX = Main.player[Main.npc[hiveMind].target].Center.X - projDirection.X; + float playerY = Main.player[Main.npc[hiveMind].target].Center.Y - projDirection.Y; float playerDist = (float)Math.Sqrt(playerX * playerX + playerY * playerY); playerDist = projSpeed / playerDist; playerX *= playerDist; @@ -203,7 +200,7 @@ public override void AI() Vector2 projectileVelocity = new Vector2(playerX, playerY); if (type == ProjectileID.CursedFlameHostile) { - Vector2 v = Main.player[NPC.target].Center - NPC.Center - Main.player[NPC.target].velocity * 20f; + Vector2 v = Main.player[Main.npc[hiveMind].target].Center - NPC.Center - Main.player[Main.npc[hiveMind].target].velocity * 20f; projectileVelocity = v.SafeNormalize(Vector2.UnitY) * projSpeed; } Projectile.NewProjectile(NPC.GetSource_FromAI(), projDirection, projectileVelocity, type, damage, 0f, Main.myPlayer); diff --git a/NPCs/HiveMind/HiveMind.cs b/NPCs/HiveMind/HiveMind.cs index 3b9158b12f..1807a2b245 100644 --- a/NPCs/HiveMind/HiveMind.cs +++ b/NPCs/HiveMind/HiveMind.cs @@ -1,4 +1,5 @@ using System.IO; +using CalamityMod.Buffs.DamageOverTime; using CalamityMod.Events; using CalamityMod.Items.Accessories; using CalamityMod.Items.Armor.Vanity; @@ -417,10 +418,6 @@ public override void AI() if (NPC.target < 0 || NPC.target == Main.maxPlayers || Main.player[NPC.target].dead || !Main.player[NPC.target].active) NPC.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[NPC.target].Center, NPC.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - NPC.TargetClosest(); - Player player = Main.player[NPC.target]; bool bossRush = BossRushEvent.BossRushActive; @@ -799,11 +796,11 @@ public override void AI() NPC.netSpam = 0; } - if (!player.active || player.dead || Vector2.Distance(NPC.Center, player.Center) > 5000f) + if (!player.active || player.dead || Vector2.Distance(NPC.Center, player.Center) > 8000f) { NPC.TargetClosest(false); player = Main.player[NPC.target]; - if (!player.active || player.dead || Vector2.Distance(NPC.Center, player.Center) > 5000f) + if (!player.active || player.dead || Vector2.Distance(NPC.Center, player.Center) > 8000f) { if (NPC.timeLeft > 60) NPC.timeLeft = 60; @@ -830,9 +827,9 @@ public override void AI() phase2timer--; - // Use an attack sooner in expert mode if being hit - if (NPC.justHit && expertMode) - phase2timer--; + // Use an attack sooner if being hit + if (NPC.justHit) + phase2timer -= masterMode ? 7 : expertMode ? 5 : 3; // Use an attack sooner if target is close if (NPC.Distance(player.Center) < 160f) @@ -1142,7 +1139,7 @@ public override void AI() phase2timer++; if (phase2timer == decelerationTime) { - phase2timer = minimumDriftTime + Main.rand.Next(121); + phase2timer = minimumDriftTime + Main.rand.Next(masterMode ? 61 : 121); state = 0; NPC.netUpdate = true; NPC.netSpam = 0; @@ -1175,6 +1172,14 @@ public override bool CanHitPlayer(Player target, ref int cooldownSlot) return minDist <= 60f && NPC.alpha == 0 && NPC.scale == 1f; // No damage while not fully visible or shrunk } + public override void OnHitPlayer(Player target, Player.HurtInfo hurtInfo) + { + if (hurtInfo.Damage < 0) + return; + + target.AddBuff(ModContent.BuffType(), 300); + } + public override bool? DrawHealthBar(byte hbPosition, ref float scale, ref Vector2 position) => NPC.scale == 1f; // Only draw HP bar while at full size public override void ModifyIncomingHit(ref NPC.HitModifiers modifiers) diff --git a/Projectiles/Boss/ShadeNimbusHostile.cs b/Projectiles/Boss/ShadeNimbusHostile.cs index 4c9005206e..9ebf0fb51a 100644 --- a/Projectiles/Boss/ShadeNimbusHostile.cs +++ b/Projectiles/Boss/ShadeNimbusHostile.cs @@ -53,7 +53,7 @@ public override void AI() Projectile.ai[0] = 0f; int rainSpawnX = (int)(Projectile.position.X + 14f + (float)Main.rand.Next(Projectile.width - 28)); int rainSpawnY = (int)(Projectile.position.Y + (float)Projectile.height + 4f); - Projectile.NewProjectile(Projectile.GetSource_FromThis(), (float)rainSpawnX, (float)rainSpawnY, 0f, 4f, ModContent.ProjectileType(), Projectile.damage, 0f, Main.myPlayer, 0f, 0f); + Projectile.NewProjectile(Projectile.GetSource_FromThis(), (float)rainSpawnX, (float)rainSpawnY, 0f, 8f, ModContent.ProjectileType(), Projectile.damage, 0f, Main.myPlayer); } } } @@ -63,7 +63,7 @@ public override void OnHitPlayer(Player target, Player.HurtInfo info) if (info.Damage <= 0) return; - target.AddBuff(ModContent.BuffType(), 360); + target.AddBuff(ModContent.BuffType(), 240); } } } diff --git a/Projectiles/Boss/ShaderainHostile.cs b/Projectiles/Boss/ShaderainHostile.cs index acb42b090b..8fd4a72096 100644 --- a/Projectiles/Boss/ShaderainHostile.cs +++ b/Projectiles/Boss/ShaderainHostile.cs @@ -9,19 +9,15 @@ namespace CalamityMod.Projectiles.Boss public class ShaderainHostile : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Boss"; + public override void SetDefaults() { Projectile.width = 4; Projectile.height = 40; Projectile.hostile = true; - Projectile.extraUpdates = 1; Projectile.penetrate = -1; Projectile.ignoreWater = true; Projectile.timeLeft = 300; - } - - public override void AI() - { Projectile.alpha = 50; } @@ -36,17 +32,14 @@ public override void OnKill(int timeLeft) dust.scale = 0.95f; } - public override Color? GetAlpha(Color lightColor) - { - return new Color(102, 255, 102, Projectile.alpha); - } + public override Color? GetAlpha(Color lightColor) => new Color(100, 255, 100, Projectile.alpha); public override void OnHitPlayer(Player target, Player.HurtInfo info) { if (info.Damage <= 0) return; - target.AddBuff(ModContent.BuffType(), 360); + target.AddBuff(ModContent.BuffType(), 120); } } } From 8e41cbb392d206ab502e49279954bc6ed3d36a97 Mon Sep 17 00:00:00 2001 From: Xyk Date: Wed, 29 May 2024 00:41:04 -0700 Subject: [PATCH 148/401] Shredder And Infinity P1 --- Items/Weapons/Ranged/Infinity.cs | 79 ++++++--------- Items/Weapons/Ranged/Shredder.cs | 23 ++--- .../Mods.CalamityMod.Projectiles.Ranged.hjson | 1 + Projectiles/Ranged/ChargedBlast.cs | 73 ++++++++------ Projectiles/Ranged/ChargedBlast2.cs | 79 --------------- Projectiles/Ranged/ChargedBlastSplit.cs | 97 +++++++++++++++++++ 6 files changed, 178 insertions(+), 174 deletions(-) delete mode 100644 Projectiles/Ranged/ChargedBlast2.cs create mode 100644 Projectiles/Ranged/ChargedBlastSplit.cs diff --git a/Items/Weapons/Ranged/Infinity.cs b/Items/Weapons/Ranged/Infinity.cs index 0a3822976f..4fb89f5188 100644 --- a/Items/Weapons/Ranged/Infinity.cs +++ b/Items/Weapons/Ranged/Infinity.cs @@ -1,4 +1,6 @@ -using CalamityMod.Items.Materials; +using System; +using CalamityMod.Items.Materials; +using CalamityMod.Particles; using CalamityMod.Projectiles.Ranged; using CalamityMod.Rarities; using CalamityMod.Tiles.Furniture.CraftingStations; @@ -15,6 +17,7 @@ public class Infinity : ModItem, ILocalizedModType public new string LocalizationCategory => "Items.Weapons.Ranged"; internal int rotation = 0; internal bool limit = true; + public int SineCounter = 0; public override void SetStaticDefaults() { ItemID.Sets.ItemsThatAllowRepeatedRightClick[Item.type] = true; @@ -24,11 +27,10 @@ public override void SetDefaults() { Item.width = 56; Item.height = 24; - Item.damage = 110; + Item.damage = 90; Item.DamageType = DamageClass.Ranged; - Item.useTime = 2; - Item.useAnimation = 12; - Item.reuseDelay = 12; + Item.useTime = 1; + Item.useAnimation = 4; Item.useLimitPerAnimation = 9; Item.useStyle = ItemUseStyleID.Shoot; Item.noMelee = true; @@ -38,7 +40,7 @@ public override void SetDefaults() Item.UseSound = SoundID.Item31; Item.autoReuse = true; Item.shoot = ProjectileID.PurificationPowder; - Item.shootSpeed = 12f; + Item.shootSpeed = 6f; Item.useAmmo = AmmoID.Bullet; Item.Calamity().canFirePointBlankShots = true; } @@ -55,61 +57,34 @@ public override bool AltFunctionUse(Player player) public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) { - if (player.altFunctionUse == 2) + position = position + (player.Calamity().mouseWorld - player.MountedCenter).SafeNormalize(Vector2.UnitX) * 65; + float sine = (float)Math.Sin(SineCounter * 0.175f / MathHelper.Pi) * 3.5f; + SineCounter++; + if (SineCounter % 4 == 0) { - //If you right click, shoots a helix of normal bullets - Vector2 helixVel1 = velocity.RotatedBy(MathHelper.ToRadians(rotation)); - Vector2 helixVel2 = velocity.RotatedBy(MathHelper.ToRadians(-rotation)); - int shot1 = Projectile.NewProjectile(source, position.X, position.Y, helixVel1.X, helixVel1.Y, type, damage, knockback, player.whoAmI, 0f, 0f); - Main.projectile[shot1].timeLeft = 180; - int shot2 = Projectile.NewProjectile(source, position.X, position.Y, helixVel2.X, helixVel2.Y, type, damage, knockback, player.whoAmI, 0f, 0f); - Main.projectile[shot2].timeLeft = 180; - //Code to constantly make the shooting go side to side to make the helix - if (limit) + if (player.altFunctionUse == 2) { - rotation += 2; + //If you right click, shoots a helix of normal bullets + Vector2 helixVel1 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(sine)); + Vector2 helixVel2 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(-sine)); + int shot1 = Projectile.NewProjectile(source, position.X, position.Y, helixVel1.X, helixVel1.Y, type, damage, knockback, player.whoAmI, 0f, 0f); + int shot2 = Projectile.NewProjectile(source, position.X, position.Y, helixVel2.X, helixVel2.Y, type, damage, knockback, player.whoAmI, 0f, 0f); } else { - rotation -= 2; + //If left click, do the same as above but spawn Charged Blasts instead + Vector2 helixVel1 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(sine)); + Vector2 helixVel2 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(-sine)); + int shot1 = Projectile.NewProjectile(source, position.X, position.Y, helixVel1.X, helixVel1.Y, ModContent.ProjectileType(), damage, knockback, player.whoAmI, 0f, 1, 1f); + int shot2 = Projectile.NewProjectile(source, position.X, position.Y, helixVel2.X, helixVel2.Y, ModContent.ProjectileType(), damage, knockback, player.whoAmI, 0f, 0, 1f); } - if (rotation >= 11) - { - limit = false; - } - else if (rotation <= -11) - { - limit = true; - } - return false; } - else + else if (player.altFunctionUse != 2) { - //If left click, do the same as above but spawn Charged Blasts instead - Vector2 helixVel1 = velocity.RotatedBy(MathHelper.ToRadians(rotation)); - Vector2 helixVel2 = velocity.RotatedBy(MathHelper.ToRadians(-rotation)); - int shot1 = Projectile.NewProjectile(source, position.X, position.Y, helixVel1.X, helixVel1.Y, ModContent.ProjectileType(), damage, knockback, player.whoAmI, 0f, 0f); - Main.projectile[shot1].timeLeft = 180; - int shot2 = Projectile.NewProjectile(source, position.X, position.Y, helixVel2.X, helixVel2.Y, ModContent.ProjectileType(), damage, knockback, player.whoAmI, 0f, 0f); - Main.projectile[shot2].timeLeft = 180; - if (limit) - { - rotation += 2; - } - else - { - rotation -= 2; - } - if (rotation >= 11) - { - limit = false; - } - else if (rotation <= -11) - { - limit = true; - } - return false; + Particle spark2 = new LineParticle(position + Main.rand.NextVector2Circular(6, 6), (velocity * 4).RotatedByRandom(0.2f) * Main.rand.NextFloat(0.8f, 1.2f), false, Main.rand.Next(15, 25 + 1), Main.rand.NextFloat(1.5f, 2f), new Color(229, 49, 39)); + GeneralParticleHandler.SpawnParticle(spark2); } + return false; } public override void AddRecipes() diff --git a/Items/Weapons/Ranged/Shredder.cs b/Items/Weapons/Ranged/Shredder.cs index 6665770842..eb54dab8c2 100644 --- a/Items/Weapons/Ranged/Shredder.cs +++ b/Items/Weapons/Ranged/Shredder.cs @@ -5,6 +5,7 @@ using Terraria.DataStructures; using Terraria.ID; using Terraria.ModLoader; +using System; namespace CalamityMod.Items.Weapons.Ranged { @@ -20,11 +21,11 @@ public override void SetDefaults() { Item.width = 56; Item.height = 24; - Item.damage = 31; + Item.damage = 45; Item.DamageType = DamageClass.Ranged; Item.useTime = 4; - Item.useAnimation = 24; - Item.reuseDelay = 20; + Item.useAnimation = 32; + Item.reuseDelay = 35; Item.useLimitPerAnimation = 8; Item.useStyle = ItemUseStyleID.Shoot; Item.noMelee = true; @@ -34,7 +35,7 @@ public override void SetDefaults() Item.UseSound = SoundID.Item31; Item.autoReuse = true; Item.shoot = ProjectileID.Bullet; - Item.shootSpeed = 9f; + Item.shootSpeed = 6f; Item.useAmmo = AmmoID.Bullet; Item.Calamity().canFirePointBlankShots = true; } @@ -45,29 +46,21 @@ public override void SetDefaults() public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) { - int bulletAmt = 4; + int bulletAmt = 3; if (player.altFunctionUse == 2) { - velocity *= 2f; Vector2 newPosition = position + velocity.SafeNormalize(Vector2.UnitY) * 50f; - Vector2 cachedVelocity = velocity; for (int index = 0; index < bulletAmt; index++) { - velocity += new Vector2(Main.rand.Next(-30, 31) * 0.05f, Main.rand.Next(-30, 31) * 0.05f); - int shot = Projectile.NewProjectile(source, newPosition, velocity, type, damage, knockback, player.whoAmI); - Main.projectile[shot].timeLeft = 180; - velocity = cachedVelocity; + int shot = Projectile.NewProjectile(source, newPosition, (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedByRandom(0.2f), type, damage, knockback, player.whoAmI); } } else { Vector2 newPosition = position + velocity.SafeNormalize(Vector2.UnitY) * 50f; - Vector2 cachedVelocity = velocity; for (int index = 0; index < bulletAmt; index++) { - velocity += new Vector2(Main.rand.Next(-30, 31) * 0.05f, Main.rand.Next(-30, 31) * 0.05f); - Projectile.NewProjectile(source, newPosition, velocity, ModContent.ProjectileType(), damage, knockback, player.whoAmI); - velocity = cachedVelocity; + Projectile.NewProjectile(source, newPosition, (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedByRandom(0.2f), ModContent.ProjectileType(), damage, knockback, player.whoAmI); } } return false; diff --git a/Localization/en-US/Mods.CalamityMod.Projectiles.Ranged.hjson b/Localization/en-US/Mods.CalamityMod.Projectiles.Ranged.hjson index ebaa469e9d..0b711900a8 100644 --- a/Localization/en-US/Mods.CalamityMod.Projectiles.Ranged.hjson +++ b/Localization/en-US/Mods.CalamityMod.Projectiles.Ranged.hjson @@ -249,3 +249,4 @@ WildfireBloomFire.DisplayName: Wildfire Fire WildfireBloomFlare.DisplayName: Wildfire Flare WulfrumScrapBullet.DisplayName: High Speed Scrap NitroShot.DisplayName: Nitro Shot +ChargedBlastSplit.DisplayName: Charged Blast Split diff --git a/Projectiles/Ranged/ChargedBlast.cs b/Projectiles/Ranged/ChargedBlast.cs index caacfc330d..d57b2169da 100644 --- a/Projectiles/Ranged/ChargedBlast.cs +++ b/Projectiles/Ranged/ChargedBlast.cs @@ -1,4 +1,7 @@ -using Microsoft.Xna.Framework; +using System; +using CalamityMod.Particles; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; using Terraria; using Terraria.Audio; using Terraria.ID; @@ -10,7 +13,13 @@ public class ChargedBlast : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Ranged"; public override string Texture => "CalamityMod/Projectiles/LaserProj"; - + public Color baseColor = Color.White; + public bool outOfTime = false; + public override void SetStaticDefaults() + { + ProjectileID.Sets.TrailCacheLength[Projectile.type] = 15; + ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + } public override void SetDefaults() { Projectile.width = 5; @@ -18,43 +27,51 @@ public override void SetDefaults() Projectile.friendly = true; Projectile.DamageType = DamageClass.Ranged; Projectile.penetrate = 1; - Projectile.MaxUpdates = 2; - Projectile.alpha = 255; + Projectile.extraUpdates = 6; Projectile.timeLeft = 360; Projectile.Calamity().pointBlankShotDuration = CalamityGlobalProjectile.DefaultPointBlankDuration; } public override void AI() { - if (Projectile.alpha > 0) - Projectile.alpha -= 25; - if (Projectile.alpha < 0) - Projectile.alpha = 0; - - float lightScale = 1f - Projectile.alpha / 255f; - Projectile.ai[2] = lightScale; - Lighting.AddLight(Projectile.Center, 0f, 0.3f * lightScale, 0.7f * lightScale); - - float beamLength = 60f; - float beamLengthGrowth = 1f; - Projectile.localAI[0] += beamLengthGrowth; - if (Projectile.localAI[0] > beamLength) - Projectile.localAI[0] = beamLength; + if (baseColor == Color.White) + baseColor = (Projectile.ai[2] == 1 ? new Color(229, 49, 39) : Color.DodgerBlue); + Projectile.rotation = Projectile.velocity.ToRotation() + MathHelper.PiOver2; + if (Projectile.timeLeft == 2) + outOfTime = true; } - - public override Color? GetAlpha(Color lightColor) => new Color(100, 100, 255, 0) * Projectile.ai[2]; - - public override bool PreDraw(ref Color lightColor) => Projectile.DrawBeam(100f, 3f, lightColor); - public override void OnKill(int timeLeft) { - SoundEngine.PlaySound(SoundID.Item62, Projectile.position); - int projectiles = 2; - if (Projectile.owner == Main.myPlayer) + if (!outOfTime) { - for (int k = 0; k < projectiles; k++) - Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, Main.rand.NextVector2CircularEdge(5f, 5f), ModContent.ProjectileType(), (int)(Projectile.damage * 0.5), Projectile.knockBack * 0.8f, Main.myPlayer); + SoundEngine.PlaySound(SoundID.Item62, Projectile.Center); + int projectiles = 2; + if (Projectile.owner == Main.myPlayer) + { + for (int k = 0; k < projectiles; k++) + Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), Projectile.Center, -Projectile.velocity.RotatedByRandom(0.9f) * Main.rand.NextFloat(0.6f, 0.7f), ModContent.ProjectileType(), (int)(Projectile.damage * (Projectile.ai[2] == 1 ? 0.3f : 0.5f)), Projectile.knockBack * 0.8f, Main.myPlayer, 0, 0, Projectile.ai[2] == 1 ? 1 : 0); + } + for (int k = 0; k < 3; k++) + { + Particle spark2 = new LineParticle(Projectile.Center, (-Projectile.velocity * 4).RotatedByRandom(0.9f) * Main.rand.NextFloat(0.8f, 1.2f), false, Main.rand.Next(25, 32 + 1), Main.rand.NextFloat(1.5f, 2f), baseColor); + GeneralParticleHandler.SpawnParticle(spark2); + } + if (Projectile.ai[2] == 1) + { + Particle spark2 = new LineParticle(Projectile.Center, (-Projectile.velocity * 5).RotatedByRandom(0.9f) * Main.rand.NextFloat(0.8f, 1.2f), false, Main.rand.Next(35, 48 + 1), Main.rand.NextFloat(2.3f, 3f), baseColor); + GeneralParticleHandler.SpawnParticle(spark2); + } } } + public override bool PreDraw(ref Color lightColor) + { + if (baseColor == Color.White) + return false; + Texture2D texture = ModContent.Request("CalamityMod/Particles/DrainLineBloom").Value; + CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], (baseColor * 0.7f) with { A = 0 }, 1, texture); + Main.EntitySpriteDraw(texture, Projectile.Center - Main.screenPosition, null, baseColor with { A = 0 }, Projectile.rotation, texture.Size() * 0.5f, Projectile.scale, SpriteEffects.None, 0); + return false; + } + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) => CalamityUtils.CircularHitboxCollision(Projectile.Center, 20, targetHitbox); } } diff --git a/Projectiles/Ranged/ChargedBlast2.cs b/Projectiles/Ranged/ChargedBlast2.cs deleted file mode 100644 index 89318cc187..0000000000 --- a/Projectiles/Ranged/ChargedBlast2.cs +++ /dev/null @@ -1,79 +0,0 @@ -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.Audio; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Projectiles.Ranged -{ - public class ChargedBlast2 : ModProjectile, ILocalizedModType - { - public new string LocalizationCategory => "Projectiles.Ranged"; - public override string Texture => "CalamityMod/Projectiles/LaserProj"; - - public override void SetDefaults() - { - Projectile.width = 5; - Projectile.height = 5; - Projectile.friendly = true; - Projectile.DamageType = DamageClass.Ranged; - Projectile.penetrate = 3; - Projectile.MaxUpdates = 2; - Projectile.alpha = 255; - Projectile.timeLeft = 180; - Projectile.usesLocalNPCImmunity = true; - Projectile.localNPCHitCooldown = -1; - } - - public override void AI() - { - if (Projectile.timeLeft < 60) - { - Projectile.alpha += 5; - if (Projectile.alpha >= 255) - Projectile.Kill(); - } - else - { - if (Projectile.alpha > 0) - Projectile.alpha -= 25; - if (Projectile.alpha < 0) - Projectile.alpha = 0; - } - - float lightScale = 1f - Projectile.alpha / 255f; - Projectile.ai[2] = lightScale; - Lighting.AddLight(Projectile.Center, 0f, 0.3f * lightScale, 0.7f * lightScale); - - float beamLength = 30f; - float beamLengthGrowth = 0.5f; - Projectile.localAI[0] += beamLengthGrowth; - if (Projectile.localAI[0] > beamLength) - Projectile.localAI[0] = beamLength; - } - - public override Color? GetAlpha(Color lightColor) => new Color(100, 100, 255, 0) * Projectile.ai[2]; - - public override bool PreDraw(ref Color lightColor) => Projectile.DrawBeam(100f, 3f, lightColor); - - public override bool OnTileCollide(Vector2 oldVelocity) - { - SoundEngine.PlaySound(SoundID.Item10, Projectile.position); - - Projectile.penetrate--; - if (Projectile.penetrate <= 0) - { - Projectile.Kill(); - } - else - { - if (Projectile.velocity.X != oldVelocity.X) - Projectile.velocity.X = -oldVelocity.X; - if (Projectile.velocity.Y != oldVelocity.Y) - Projectile.velocity.Y = -oldVelocity.Y; - } - - return false; - } - } -} diff --git a/Projectiles/Ranged/ChargedBlastSplit.cs b/Projectiles/Ranged/ChargedBlastSplit.cs new file mode 100644 index 0000000000..9e2da962aa --- /dev/null +++ b/Projectiles/Ranged/ChargedBlastSplit.cs @@ -0,0 +1,97 @@ +using CalamityMod.Particles; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.Audio; +using Terraria.ID; +using Terraria.ModLoader; + +namespace CalamityMod.Projectiles.Ranged +{ + public class ChargedBlastSplit : ModProjectile, ILocalizedModType + { + public new string LocalizationCategory => "Projectiles.Ranged"; + public override string Texture => "CalamityMod/Projectiles/LaserProj"; + public Color baseColor = Color.White; + public int tileHits = 4; + public Vector2 startVel; + public override void SetStaticDefaults() + { + ProjectileID.Sets.TrailCacheLength[Projectile.type] = 15; + ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + } + public override void SetDefaults() + { + Projectile.width = 5; + Projectile.height = 5; + Projectile.friendly = true; + Projectile.DamageType = DamageClass.Ranged; + Projectile.penetrate = 3; + Projectile.extraUpdates = 5; + Projectile.timeLeft = 240; + Projectile.scale = 0.7f; + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 15; + } + + public override void AI() + { + bool InfinityShot = Projectile.ai[2] == 1; + if (baseColor == Color.White) + { + baseColor = (InfinityShot ? new Color(229, 49, 39) : Color.DodgerBlue); + startVel = Projectile.velocity; + if (InfinityShot) + Projectile.timeLeft = 340; + } + Projectile.rotation = Projectile.velocity.ToRotation() + MathHelper.PiOver2; + + if (Projectile.timeLeft < 290 && InfinityShot) + { + Projectile.velocity.X = MathHelper.Lerp(Projectile.velocity.X, -startVel.X, 0.02f); + Projectile.velocity.Y = MathHelper.Lerp(Projectile.velocity.Y, -startVel.Y, 0.02f); + } + if (InfinityShot) + { + Projectile.tileCollide = false; + Projectile.penetrate = -1; + } + } + public override void OnKill(int timeLeft) + { + for (int k = 0; k < 3; k++) + { + Particle spark2 = new LineParticle(Projectile.Center, (Projectile.velocity * 5).RotatedByRandom(0.4f) * Main.rand.NextFloat(0.8f, 1.2f), false, Main.rand.Next(8, 11 + 1), Main.rand.NextFloat(0.5f, 1f), baseColor); + GeneralParticleHandler.SpawnParticle(spark2); + } + } + public override bool PreDraw(ref Color lightColor) + { + if (baseColor == Color.White) + return false; + Texture2D texture = ModContent.Request("CalamityMod/Particles/DrainLineBloom").Value; + CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], (baseColor * 0.7f) with { A = 0 }, 1, texture); + Main.EntitySpriteDraw(texture, Projectile.Center - Main.screenPosition, null, baseColor with { A = 0 }, Projectile.rotation, texture.Size() * 0.5f, Projectile.scale, SpriteEffects.None, 0); + return false; + } + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) => CalamityUtils.CircularHitboxCollision(Projectile.Center, 10, targetHitbox); + + public override bool OnTileCollide(Vector2 oldVelocity) + { + tileHits--; + if (tileHits <= 0) + { + Projectile.Kill(); + } + else + { + if (Projectile.velocity.X != oldVelocity.X) + Projectile.velocity.X = -oldVelocity.X; + if (Projectile.velocity.Y != oldVelocity.Y) + Projectile.velocity.Y = -oldVelocity.Y; + } + + return false; + } + } +} From 613dae463b089e4e768c5b68caac7f9abd45d31d Mon Sep 17 00:00:00 2001 From: Xyk Date: Wed, 29 May 2024 13:03:29 -0700 Subject: [PATCH 149/401] Svant --- Items/Weapons/Ranged/Infinity.cs | 14 ++-- Items/Weapons/Ranged/Shredder.cs | 6 ++ Items/Weapons/Ranged/Svantechnical.cs | 98 +++++++++++++------------ Projectiles/Ranged/ChargedBlast.cs | 28 ++++++- Projectiles/Ranged/ChargedBlastSplit.cs | 57 ++++++++++++-- 5 files changed, 139 insertions(+), 64 deletions(-) diff --git a/Items/Weapons/Ranged/Infinity.cs b/Items/Weapons/Ranged/Infinity.cs index 4fb89f5188..fb2c7136ee 100644 --- a/Items/Weapons/Ranged/Infinity.cs +++ b/Items/Weapons/Ranged/Infinity.cs @@ -15,8 +15,6 @@ namespace CalamityMod.Items.Weapons.Ranged public class Infinity : ModItem, ILocalizedModType { public new string LocalizationCategory => "Items.Weapons.Ranged"; - internal int rotation = 0; - internal bool limit = true; public int SineCounter = 0; public override void SetStaticDefaults() { @@ -27,11 +25,10 @@ public override void SetDefaults() { Item.width = 56; Item.height = 24; - Item.damage = 90; + Item.damage = 85; Item.DamageType = DamageClass.Ranged; Item.useTime = 1; Item.useAnimation = 4; - Item.useLimitPerAnimation = 9; Item.useStyle = ItemUseStyleID.Shoot; Item.noMelee = true; Item.knockBack = 1f; @@ -75,7 +72,7 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, //If left click, do the same as above but spawn Charged Blasts instead Vector2 helixVel1 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(sine)); Vector2 helixVel2 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(-sine)); - int shot1 = Projectile.NewProjectile(source, position.X, position.Y, helixVel1.X, helixVel1.Y, ModContent.ProjectileType(), damage, knockback, player.whoAmI, 0f, 1, 1f); + int shot1 = Projectile.NewProjectile(source, position.X, position.Y, helixVel1.X, helixVel1.Y, ModContent.ProjectileType(), damage, knockback, player.whoAmI, 0f, 0, 1f); int shot2 = Projectile.NewProjectile(source, position.X, position.Y, helixVel2.X, helixVel2.Y, ModContent.ProjectileType(), damage, knockback, player.whoAmI, 0f, 0, 1f); } } @@ -86,7 +83,12 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, } return false; } - + public override bool CanConsumeAmmo(Item ammo, Player player) + { + if (Main.rand.Next(0, 100) > 80 && SineCounter % 4 == 0) + return true; + return false; + } public override void AddRecipes() { CreateRecipe(). diff --git a/Items/Weapons/Ranged/Shredder.cs b/Items/Weapons/Ranged/Shredder.cs index eb54dab8c2..06281c5e18 100644 --- a/Items/Weapons/Ranged/Shredder.cs +++ b/Items/Weapons/Ranged/Shredder.cs @@ -65,6 +65,12 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, } return false; } + public override bool CanConsumeAmmo(Item ammo, Player player) + { + if (Main.rand.Next(0, 100) < 60) + return false; + return true; + } public override void AddRecipes() { diff --git a/Items/Weapons/Ranged/Svantechnical.cs b/Items/Weapons/Ranged/Svantechnical.cs index efb03041fc..eced3fa849 100644 --- a/Items/Weapons/Ranged/Svantechnical.cs +++ b/Items/Weapons/Ranged/Svantechnical.cs @@ -1,5 +1,7 @@ using System; using CalamityMod.Items.Materials; +using CalamityMod.Particles; +using CalamityMod.Projectiles.Ranged; using CalamityMod.Rarities; using CalamityMod.Tiles.Furniture.CraftingStations; using Microsoft.Xna.Framework; @@ -13,16 +15,19 @@ namespace CalamityMod.Items.Weapons.Ranged public class Svantechnical : ModItem, ILocalizedModType { public new string LocalizationCategory => "Items.Weapons.Ranged"; + public int SineCounter = 0; + public override void SetStaticDefaults() + { + ItemID.Sets.ItemsThatAllowRepeatedRightClick[Item.type] = true; + } public override void SetDefaults() { Item.width = 60; Item.height = 26; - Item.damage = 150; + Item.damage = 200; Item.DamageType = DamageClass.Ranged; - Item.useTime = 2; - Item.useAnimation = 24; - Item.reuseDelay = 10; - Item.useLimitPerAnimation = 12; + Item.useTime = 1; + Item.useAnimation = 3; Item.useStyle = ItemUseStyleID.Shoot; Item.noMelee = true; Item.knockBack = 3.5f; @@ -33,70 +38,67 @@ public override void SetDefaults() Item.UseSound = SoundID.Item31; Item.autoReuse = true; - Item.shootSpeed = 12f; + Item.shootSpeed = 6f; Item.shoot = ProjectileID.PurificationPowder; Item.useAmmo = AmmoID.Bullet; + Item.Calamity().canFirePointBlankShots = true; } public override Vector2? HoldoutOffset() => new Vector2(-5, 0); - - public override void HoldItem(Player player) => player.scope = true; - - public override bool CanConsumeAmmo(Item ammo, Player player) + public override bool AltFunctionUse(Player player) { - if (Main.rand.Next(0, 100) < 70) - return false; return true; } + public override void HoldItem(Player player) => player.scope = false; + public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) { - int i = Main.myPlayer; - float sSpeed = Item.shootSpeed; - player.itemTime = Item.useTime; - Vector2 realPlayerPos = player.RotatedRelativePoint(player.MountedCenter, true); - float mouseXDist = (float)Main.mouseX + Main.screenPosition.X - realPlayerPos.X; - float mouseYDist = (float)Main.mouseY + Main.screenPosition.Y - realPlayerPos.Y; - if (player.gravDir == -1f) - { - mouseYDist = Main.screenPosition.Y + (float)Main.screenHeight - (float)Main.mouseY - realPlayerPos.Y; - } - float mouseDistance = (float)Math.Sqrt((double)(mouseXDist * mouseXDist + mouseYDist * mouseYDist)); - if ((float.IsNaN(mouseXDist) && float.IsNaN(mouseYDist)) || (mouseXDist == 0f && mouseYDist == 0f)) + position = position + (player.Calamity().mouseWorld - player.MountedCenter).SafeNormalize(Vector2.UnitX) * 65; + float sine = (float)Math.Sin(SineCounter * 0.175f / MathHelper.Pi) * 4f; + float sine2 = (float)Math.Sin(SineCounter * 0.275f / MathHelper.Pi) * 2f; + SineCounter++; + if (SineCounter % 4 == 0) { - mouseXDist = (float)player.direction; - mouseYDist = 0f; + if (player.altFunctionUse == 2) + { + //If you right click, shoots a helix of normal bullets + Vector2 helixVel1 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(sine)); + Vector2 helixVel2 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(-sine)); + Vector2 helixVel3 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(sine2)); + int shot1 = Projectile.NewProjectile(source, position.X, position.Y, helixVel1.X, helixVel1.Y, type, damage, knockback, player.whoAmI, 0f, 0f); + int shot2 = Projectile.NewProjectile(source, position.X, position.Y, helixVel2.X, helixVel2.Y, type, damage, knockback, player.whoAmI, 0f, 0f); + int shot3 = Projectile.NewProjectile(source, position.X, position.Y, helixVel3.X, helixVel3.Y, type, damage, knockback, player.whoAmI, 0f, 0f); + } + else + { + //If left click, do the same as above but spawn Charged Blasts instead + Vector2 helixVel1 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(sine)); + Vector2 helixVel2 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(-sine)); + Vector2 helixVel3 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(sine2)); + int shot1 = Projectile.NewProjectile(source, position.X, position.Y, helixVel1.X, helixVel1.Y, ModContent.ProjectileType(), damage, knockback, player.whoAmI, 0f, 0, 2f); + int shot2 = Projectile.NewProjectile(source, position.X, position.Y, helixVel2.X, helixVel2.Y, ModContent.ProjectileType(), damage, knockback, player.whoAmI, 0f, 0, 4f); + int shot3 = Projectile.NewProjectile(source, position.X, position.Y, helixVel3.X, helixVel3.Y, ModContent.ProjectileType(), damage, knockback, player.whoAmI, 0f, 0, 3f); + } } - else + else if (player.altFunctionUse != 2) { - mouseDistance = sSpeed / mouseDistance; - } - float randXOffset = mouseXDist; - float randYOffset = mouseYDist; - randXOffset += (float)Main.rand.Next(-1, 2) * 0.5f; - randYOffset += (float)Main.rand.Next(-1, 2) * 0.5f; - if (Collision.CanHitLine(player.Center, 0, 0, realPlayerPos + new Vector2(randXOffset, randYOffset) * 2f, 0, 0)) - { - realPlayerPos += new Vector2(randXOffset, randYOffset); - } - Projectile.NewProjectile(source, position.X, position.Y - player.gravDir * 4f, randXOffset, randYOffset, type, damage, knockback, i, 0f, (float)Main.rand.Next(12) / 6f); - int bulletAmt = Main.rand.Next(2, 4); - for (int index = 0; index < bulletAmt; ++index) - { - float SpeedX = velocity.X + (float)Main.rand.Next(-60, 61) * 0.05f; - float SpeedY = velocity.Y + (float)Main.rand.Next(-60, 61) * 0.05f; - Projectile.NewProjectile(source, realPlayerPos.X, realPlayerPos.Y, SpeedX, SpeedY, type, damage, knockback, player.whoAmI, 0f, 0f); + Particle spark2 = new LineParticle(position + Main.rand.NextVector2Circular(6, 6), (velocity * 4).RotatedByRandom(0.35f) * Main.rand.NextFloat(0.8f, 1.2f), false, Main.rand.Next(15, 25 + 1), Main.rand.NextFloat(1.5f, 2f), Main.rand.NextBool() ? Color.MediumOrchid : Color.DarkViolet); + GeneralParticleHandler.SpawnParticle(spark2); } return false; } + public override bool CanConsumeAmmo(Item ammo, Player player) + { + if (Main.rand.Next(0, 100) > 90 && SineCounter % 4 == 0) + return true; + return false; + } public override void AddRecipes() { CreateRecipe(). - AddIngredient(). - AddIngredient(ItemID.SoulofMight, 10). - AddIngredient(ItemID.SoulofSight, 10). - AddIngredient(ItemID.SoulofFright, 10). + AddIngredient(). AddIngredient(5). AddTile(). Register(); diff --git a/Projectiles/Ranged/ChargedBlast.cs b/Projectiles/Ranged/ChargedBlast.cs index d57b2169da..e1aed457c9 100644 --- a/Projectiles/Ranged/ChargedBlast.cs +++ b/Projectiles/Ranged/ChargedBlast.cs @@ -15,6 +15,7 @@ public class ChargedBlast : ModProjectile, ILocalizedModType public override string Texture => "CalamityMod/Projectiles/LaserProj"; public Color baseColor = Color.White; public bool outOfTime = false; + public Vector2 baseVel; public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 15; @@ -34,8 +35,27 @@ public override void SetDefaults() public override void AI() { + bool Shredder = Projectile.ai[2] == 0; + bool Infinity = Projectile.ai[2] == 1; + bool Svant = Projectile.ai[2] == 2 || Projectile.ai[2] == 3 || Projectile.ai[2] == 4; + if (baseColor == Color.White) - baseColor = (Projectile.ai[2] == 1 ? new Color(229, 49, 39) : Color.DodgerBlue); + { + baseColor = (Infinity ? new Color(229, 49, 39) : Svant ? Color.DarkViolet : Color.DodgerBlue); + if (Projectile.ai[2] == 3) + { + baseColor = Color.Violet; + } + if (Projectile.ai[2] == 4) + { + baseColor = Color.MediumOrchid; + } + baseVel = Projectile.velocity; + if (Svant) + Projectile.ArmorPenetration = 100; + if (Infinity) + Projectile.ArmorPenetration = 25; + } Projectile.rotation = Projectile.velocity.ToRotation() + MathHelper.PiOver2; if (Projectile.timeLeft == 2) outOfTime = true; @@ -49,16 +69,16 @@ public override void OnKill(int timeLeft) if (Projectile.owner == Main.myPlayer) { for (int k = 0; k < projectiles; k++) - Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), Projectile.Center, -Projectile.velocity.RotatedByRandom(0.9f) * Main.rand.NextFloat(0.6f, 0.7f), ModContent.ProjectileType(), (int)(Projectile.damage * (Projectile.ai[2] == 1 ? 0.3f : 0.5f)), Projectile.knockBack * 0.8f, Main.myPlayer, 0, 0, Projectile.ai[2] == 1 ? 1 : 0); + Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), Projectile.Center, -baseVel.RotatedByRandom(0.9f) * Main.rand.NextFloat(0.6f, 0.7f), ModContent.ProjectileType(), (int)(Projectile.damage * (Projectile.ai[2] > 0 ? 0.3f : 0.5f)), Projectile.knockBack * 0.8f, Main.myPlayer, 0, 0, Projectile.ai[2]); } for (int k = 0; k < 3; k++) { - Particle spark2 = new LineParticle(Projectile.Center, (-Projectile.velocity * 4).RotatedByRandom(0.9f) * Main.rand.NextFloat(0.8f, 1.2f), false, Main.rand.Next(25, 32 + 1), Main.rand.NextFloat(1.5f, 2f), baseColor); + Particle spark2 = new LineParticle(Projectile.Center, (-baseVel * 4).RotatedByRandom(0.9f) * Main.rand.NextFloat(0.8f, 1.2f), false, Main.rand.Next(25, 32 + 1), Main.rand.NextFloat(1.5f, 2f), baseColor); GeneralParticleHandler.SpawnParticle(spark2); } if (Projectile.ai[2] == 1) { - Particle spark2 = new LineParticle(Projectile.Center, (-Projectile.velocity * 5).RotatedByRandom(0.9f) * Main.rand.NextFloat(0.8f, 1.2f), false, Main.rand.Next(35, 48 + 1), Main.rand.NextFloat(2.3f, 3f), baseColor); + Particle spark2 = new LineParticle(Projectile.Center, (-baseVel * 5).RotatedByRandom(0.9f) * Main.rand.NextFloat(0.8f, 1.2f), false, Main.rand.Next(35, 48 + 1), Main.rand.NextFloat(2.3f, 3f), baseColor); GeneralParticleHandler.SpawnParticle(spark2); } } diff --git a/Projectiles/Ranged/ChargedBlastSplit.cs b/Projectiles/Ranged/ChargedBlastSplit.cs index 9e2da962aa..a5df485570 100644 --- a/Projectiles/Ranged/ChargedBlastSplit.cs +++ b/Projectiles/Ranged/ChargedBlastSplit.cs @@ -1,10 +1,12 @@ -using CalamityMod.Particles; +using System; +using CalamityMod.Particles; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Terraria; using Terraria.Audio; using Terraria.ID; using Terraria.ModLoader; +using Terraria.Utilities.Terraria.Utilities; namespace CalamityMod.Projectiles.Ranged { @@ -15,6 +17,9 @@ public class ChargedBlastSplit : ModProjectile, ILocalizedModType public Color baseColor = Color.White; public int tileHits = 4; public Vector2 startVel; + public bool goToMouse = true; + bool direction; + public float homeSpeed; public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 15; @@ -36,22 +41,58 @@ public override void SetDefaults() public override void AI() { - bool InfinityShot = Projectile.ai[2] == 1; + Player player = Main.player[Projectile.owner]; + bool Shredder = Projectile.ai[2] == 0; + bool Infinity = Projectile.ai[2] == 1; + bool Svant = Projectile.ai[2] == 2 || Projectile.ai[2] == 3 || Projectile.ai[2] == 4; + if (baseColor == Color.White) { - baseColor = (InfinityShot ? new Color(229, 49, 39) : Color.DodgerBlue); + baseColor = (Infinity ? new Color(229, 49, 39) : Svant ? Color.DarkViolet : Color.DodgerBlue); + if (Projectile.ai[2] == 3) + baseColor = Color.Violet; + if (Projectile.ai[2] == 4) + baseColor = Color.MediumOrchid; startVel = Projectile.velocity; - if (InfinityShot) + if (Infinity) + { Projectile.timeLeft = 340; + Projectile.ArmorPenetration = 25; + } + if (Svant) + { + Projectile.timeLeft = 640; + Projectile.ArmorPenetration = 100; + } + direction = Main.rand.NextBool(); + homeSpeed = Main.rand.NextFloat(5, 8); } Projectile.rotation = Projectile.velocity.ToRotation() + MathHelper.PiOver2; - if (Projectile.timeLeft < 290 && InfinityShot) + if (Projectile.timeLeft < 290 && Infinity) { Projectile.velocity.X = MathHelper.Lerp(Projectile.velocity.X, -startVel.X, 0.02f); Projectile.velocity.Y = MathHelper.Lerp(Projectile.velocity.Y, -startVel.Y, 0.02f); } - if (InfinityShot) + if (Projectile.timeLeft <= 500 && Svant && goToMouse && Projectile.timeLeft % Projectile.extraUpdates == 0) + { + Vector2 mouseSpot = (player.Calamity().mouseWorld - Projectile.Center).SafeNormalize(Vector2.UnitX) * homeSpeed; + Projectile.velocity.X = MathHelper.Lerp(Projectile.velocity.X, mouseSpot.X, 0.085f); + Projectile.velocity.Y = MathHelper.Lerp(Projectile.velocity.Y, mouseSpot.Y, 0.085f); + if (Vector2.Distance(Projectile.Center, player.Calamity().mouseWorld) < 80) + { + Projectile.timeLeft = 300; + Projectile.velocity = Projectile.velocity.SafeNormalize(Vector2.UnitX) * homeSpeed; + goToMouse = false; + } + } + if (!goToMouse) + { + float sine = (float)Math.Sin(Projectile.timeLeft * 0.375f / MathHelper.Pi) * 2.5f; + Vector2 offset = Projectile.velocity.SafeNormalize(Vector2.UnitX).RotatedBy(MathHelper.PiOver2) * sine * (direction ? 1 : -1); + Projectile.Center += offset; + } + if (Infinity || Svant) { Projectile.tileCollide = false; Projectile.penetrate = -1; @@ -64,6 +105,10 @@ public override void OnKill(int timeLeft) Particle spark2 = new LineParticle(Projectile.Center, (Projectile.velocity * 5).RotatedByRandom(0.4f) * Main.rand.NextFloat(0.8f, 1.2f), false, Main.rand.Next(8, 11 + 1), Main.rand.NextFloat(0.5f, 1f), baseColor); GeneralParticleHandler.SpawnParticle(spark2); } + } + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + } public override bool PreDraw(ref Color lightColor) { From a2f1c481e9ab2940ae0ec17aaa933fe21b720c90 Mon Sep 17 00:00:00 2001 From: Xyk Date: Wed, 29 May 2024 13:20:11 -0700 Subject: [PATCH 150/401] Small touch ups --- Items/Weapons/Ranged/Shredder.cs | 2 +- Projectiles/Ranged/ChargedBlast.cs | 10 +++++++++- Projectiles/Ranged/ChargedBlastSplit.cs | 9 +++++---- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Items/Weapons/Ranged/Shredder.cs b/Items/Weapons/Ranged/Shredder.cs index 06281c5e18..b2dbd51af0 100644 --- a/Items/Weapons/Ranged/Shredder.cs +++ b/Items/Weapons/Ranged/Shredder.cs @@ -35,7 +35,7 @@ public override void SetDefaults() Item.UseSound = SoundID.Item31; Item.autoReuse = true; Item.shoot = ProjectileID.Bullet; - Item.shootSpeed = 6f; + Item.shootSpeed = 5f; Item.useAmmo = AmmoID.Bullet; Item.Calamity().canFirePointBlankShots = true; } diff --git a/Projectiles/Ranged/ChargedBlast.cs b/Projectiles/Ranged/ChargedBlast.cs index e1aed457c9..38cd9aad44 100644 --- a/Projectiles/Ranged/ChargedBlast.cs +++ b/Projectiles/Ranged/ChargedBlast.cs @@ -39,12 +39,15 @@ public override void AI() bool Infinity = Projectile.ai[2] == 1; bool Svant = Projectile.ai[2] == 2 || Projectile.ai[2] == 3 || Projectile.ai[2] == 4; + Player Owner = Main.player[Projectile.owner]; + float targetDist = Vector2.Distance(Owner.Center, Projectile.Center); + if (baseColor == Color.White) { baseColor = (Infinity ? new Color(229, 49, 39) : Svant ? Color.DarkViolet : Color.DodgerBlue); if (Projectile.ai[2] == 3) { - baseColor = Color.Violet; + baseColor = Color.DarkOrchid; } if (Projectile.ai[2] == 4) { @@ -59,6 +62,11 @@ public override void AI() Projectile.rotation = Projectile.velocity.ToRotation() + MathHelper.PiOver2; if (Projectile.timeLeft == 2) outOfTime = true; + if ((Svant || Infinity) && Projectile.timeLeft % 2 == 0 && targetDist < 1400f) + { + Particle spark = new LineParticle(Projectile.Center - Projectile.velocity * 3, -Projectile.velocity * 0.05f, false, 5, 2f, baseColor * 0.65f); + GeneralParticleHandler.SpawnParticle(spark); + } } public override void OnKill(int timeLeft) { diff --git a/Projectiles/Ranged/ChargedBlastSplit.cs b/Projectiles/Ranged/ChargedBlastSplit.cs index a5df485570..fb72db7217 100644 --- a/Projectiles/Ranged/ChargedBlastSplit.cs +++ b/Projectiles/Ranged/ChargedBlastSplit.cs @@ -50,7 +50,7 @@ public override void AI() { baseColor = (Infinity ? new Color(229, 49, 39) : Svant ? Color.DarkViolet : Color.DodgerBlue); if (Projectile.ai[2] == 3) - baseColor = Color.Violet; + baseColor = Color.DarkOrchid; if (Projectile.ai[2] == 4) baseColor = Color.MediumOrchid; startVel = Projectile.velocity; @@ -82,13 +82,13 @@ public override void AI() if (Vector2.Distance(Projectile.Center, player.Calamity().mouseWorld) < 80) { Projectile.timeLeft = 300; - Projectile.velocity = Projectile.velocity.SafeNormalize(Vector2.UnitX) * homeSpeed; + Projectile.velocity = Projectile.velocity.SafeNormalize(Vector2.UnitX) * homeSpeed / 2; goToMouse = false; } } if (!goToMouse) { - float sine = (float)Math.Sin(Projectile.timeLeft * 0.375f / MathHelper.Pi) * 2.5f; + float sine = (float)Math.Sin(Projectile.timeLeft * 0.175f / MathHelper.Pi) * 1.2f; Vector2 offset = Projectile.velocity.SafeNormalize(Vector2.UnitX).RotatedBy(MathHelper.PiOver2) * sine * (direction ? 1 : -1); Projectile.Center += offset; } @@ -100,7 +100,8 @@ public override void AI() } public override void OnKill(int timeLeft) { - for (int k = 0; k < 3; k++) + bool Svant = Projectile.ai[2] == 2 || Projectile.ai[2] == 3 || Projectile.ai[2] == 4; + for (int k = 0; k < (Svant ? 2 : 3); k++) { Particle spark2 = new LineParticle(Projectile.Center, (Projectile.velocity * 5).RotatedByRandom(0.4f) * Main.rand.NextFloat(0.8f, 1.2f), false, Main.rand.Next(8, 11 + 1), Main.rand.NextFloat(0.5f, 1f), baseColor); GeneralParticleHandler.SpawnParticle(spark2); From 485b15d560aebff00e99470aa2d5bcb04ff7ea9d Mon Sep 17 00:00:00 2001 From: Xyk Date: Wed, 29 May 2024 15:21:29 -0700 Subject: [PATCH 151/401] Tooltips --- .../en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson | 7 ++++--- Projectiles/Ranged/ChargedBlast.cs | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson index f12bbcfdce..d15cb408ad 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson @@ -653,7 +653,7 @@ Infinity: { DisplayName: Infinity Tooltip: ''' - Fires a barrage of energy bolts that split and bounce + Fires a twin stream of energy bolts that split Press to fire a barrage of normal bullets 'They say infinity is neverending, yet you hold it in your hands' ''' @@ -1242,8 +1242,9 @@ Svantechnical: { DisplayName: Svantechnical Tooltip: ''' - Fires several barrages of bullets - Press to zoom out + Fires a trinity of energy bolts that split into beams that track your cursor + Press to fire a barrage of normal bullets + 'The age old balance of trading damage for frames' ''' } diff --git a/Projectiles/Ranged/ChargedBlast.cs b/Projectiles/Ranged/ChargedBlast.cs index 38cd9aad44..30a3a8ef6f 100644 --- a/Projectiles/Ranged/ChargedBlast.cs +++ b/Projectiles/Ranged/ChargedBlast.cs @@ -62,7 +62,7 @@ public override void AI() Projectile.rotation = Projectile.velocity.ToRotation() + MathHelper.PiOver2; if (Projectile.timeLeft == 2) outOfTime = true; - if ((Svant || Infinity) && Projectile.timeLeft % 2 == 0 && targetDist < 1400f) + if ((Svant || Infinity) && Projectile.timeLeft % 2 == 0 && targetDist < 1400f && Projectile.timeLeft < 340) { Particle spark = new LineParticle(Projectile.Center - Projectile.velocity * 3, -Projectile.velocity * 0.05f, false, 5, 2f, baseColor * 0.65f); GeneralParticleHandler.SpawnParticle(spark); From 058c8c5412617f7e42a7221548994592756073a1 Mon Sep 17 00:00:00 2001 From: Xyk Date: Wed, 29 May 2024 22:07:28 -0700 Subject: [PATCH 152/401] Removed Redundant Code --- Items/Weapons/Ranged/Infinity.cs | 21 +++++---------------- Items/Weapons/Ranged/Shredder.cs | 18 ++++-------------- Items/Weapons/Ranged/Svantechnical.cs | 22 ++++------------------ 3 files changed, 13 insertions(+), 48 deletions(-) diff --git a/Items/Weapons/Ranged/Infinity.cs b/Items/Weapons/Ranged/Infinity.cs index fb2c7136ee..31868841d0 100644 --- a/Items/Weapons/Ranged/Infinity.cs +++ b/Items/Weapons/Ranged/Infinity.cs @@ -54,27 +54,16 @@ public override bool AltFunctionUse(Player player) public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) { + int shotType = (player.altFunctionUse == 2 ? type : ModContent.ProjectileType()); position = position + (player.Calamity().mouseWorld - player.MountedCenter).SafeNormalize(Vector2.UnitX) * 65; float sine = (float)Math.Sin(SineCounter * 0.175f / MathHelper.Pi) * 3.5f; SineCounter++; if (SineCounter % 4 == 0) { - if (player.altFunctionUse == 2) - { - //If you right click, shoots a helix of normal bullets - Vector2 helixVel1 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(sine)); - Vector2 helixVel2 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(-sine)); - int shot1 = Projectile.NewProjectile(source, position.X, position.Y, helixVel1.X, helixVel1.Y, type, damage, knockback, player.whoAmI, 0f, 0f); - int shot2 = Projectile.NewProjectile(source, position.X, position.Y, helixVel2.X, helixVel2.Y, type, damage, knockback, player.whoAmI, 0f, 0f); - } - else - { - //If left click, do the same as above but spawn Charged Blasts instead - Vector2 helixVel1 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(sine)); - Vector2 helixVel2 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(-sine)); - int shot1 = Projectile.NewProjectile(source, position.X, position.Y, helixVel1.X, helixVel1.Y, ModContent.ProjectileType(), damage, knockback, player.whoAmI, 0f, 0, 1f); - int shot2 = Projectile.NewProjectile(source, position.X, position.Y, helixVel2.X, helixVel2.Y, ModContent.ProjectileType(), damage, knockback, player.whoAmI, 0f, 0, 1f); - } + Vector2 helixVel1 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(sine)); + Vector2 helixVel2 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(-sine)); + int shot1 = Projectile.NewProjectile(source, position.X, position.Y, helixVel1.X, helixVel1.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, 1f); + int shot2 = Projectile.NewProjectile(source, position.X, position.Y, helixVel2.X, helixVel2.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, 1f); } else if (player.altFunctionUse != 2) { diff --git a/Items/Weapons/Ranged/Shredder.cs b/Items/Weapons/Ranged/Shredder.cs index b2dbd51af0..4996c2f66a 100644 --- a/Items/Weapons/Ranged/Shredder.cs +++ b/Items/Weapons/Ranged/Shredder.cs @@ -46,22 +46,12 @@ public override void SetDefaults() public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) { + int shotType = (player.altFunctionUse == 2 ? type : ModContent.ProjectileType()); int bulletAmt = 3; - if (player.altFunctionUse == 2) + Vector2 newPosition = position + velocity.SafeNormalize(Vector2.UnitY) * 50f; + for (int index = 0; index < bulletAmt; index++) { - Vector2 newPosition = position + velocity.SafeNormalize(Vector2.UnitY) * 50f; - for (int index = 0; index < bulletAmt; index++) - { - int shot = Projectile.NewProjectile(source, newPosition, (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedByRandom(0.2f), type, damage, knockback, player.whoAmI); - } - } - else - { - Vector2 newPosition = position + velocity.SafeNormalize(Vector2.UnitY) * 50f; - for (int index = 0; index < bulletAmt; index++) - { - Projectile.NewProjectile(source, newPosition, (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedByRandom(0.2f), ModContent.ProjectileType(), damage, knockback, player.whoAmI); - } + Projectile.NewProjectile(source, newPosition, (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedByRandom(0.2f), shotType, damage, knockback, player.whoAmI); } return false; } diff --git a/Items/Weapons/Ranged/Svantechnical.cs b/Items/Weapons/Ranged/Svantechnical.cs index eced3fa849..e304c42a43 100644 --- a/Items/Weapons/Ranged/Svantechnical.cs +++ b/Items/Weapons/Ranged/Svantechnical.cs @@ -49,37 +49,23 @@ public override bool AltFunctionUse(Player player) { return true; } - public override void HoldItem(Player player) => player.scope = false; public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) { + int shotType = (player.altFunctionUse == 2 ? type : ModContent.ProjectileType()); position = position + (player.Calamity().mouseWorld - player.MountedCenter).SafeNormalize(Vector2.UnitX) * 65; float sine = (float)Math.Sin(SineCounter * 0.175f / MathHelper.Pi) * 4f; float sine2 = (float)Math.Sin(SineCounter * 0.275f / MathHelper.Pi) * 2f; SineCounter++; if (SineCounter % 4 == 0) { - if (player.altFunctionUse == 2) - { - //If you right click, shoots a helix of normal bullets - Vector2 helixVel1 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(sine)); - Vector2 helixVel2 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(-sine)); - Vector2 helixVel3 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(sine2)); - int shot1 = Projectile.NewProjectile(source, position.X, position.Y, helixVel1.X, helixVel1.Y, type, damage, knockback, player.whoAmI, 0f, 0f); - int shot2 = Projectile.NewProjectile(source, position.X, position.Y, helixVel2.X, helixVel2.Y, type, damage, knockback, player.whoAmI, 0f, 0f); - int shot3 = Projectile.NewProjectile(source, position.X, position.Y, helixVel3.X, helixVel3.Y, type, damage, knockback, player.whoAmI, 0f, 0f); - } - else - { - //If left click, do the same as above but spawn Charged Blasts instead Vector2 helixVel1 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(sine)); Vector2 helixVel2 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(-sine)); Vector2 helixVel3 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(sine2)); - int shot1 = Projectile.NewProjectile(source, position.X, position.Y, helixVel1.X, helixVel1.Y, ModContent.ProjectileType(), damage, knockback, player.whoAmI, 0f, 0, 2f); - int shot2 = Projectile.NewProjectile(source, position.X, position.Y, helixVel2.X, helixVel2.Y, ModContent.ProjectileType(), damage, knockback, player.whoAmI, 0f, 0, 4f); - int shot3 = Projectile.NewProjectile(source, position.X, position.Y, helixVel3.X, helixVel3.Y, ModContent.ProjectileType(), damage, knockback, player.whoAmI, 0f, 0, 3f); - } + int shot1 = Projectile.NewProjectile(source, position.X, position.Y, helixVel1.X, helixVel1.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, 2f); + int shot2 = Projectile.NewProjectile(source, position.X, position.Y, helixVel2.X, helixVel2.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, 4f); + int shot3 = Projectile.NewProjectile(source, position.X, position.Y, helixVel3.X, helixVel3.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, 3f); } else if (player.altFunctionUse != 2) { From dffc96deb75acb2d5c31fc28c73aca2809c39f14 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Thu, 30 May 2024 16:31:25 -0500 Subject: [PATCH 153/401] Dark Hearts emit rain when higher up. --- NPCs/HiveMind/DarkHeart.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NPCs/HiveMind/DarkHeart.cs b/NPCs/HiveMind/DarkHeart.cs index 0a6591b66e..3432898fdc 100644 --- a/NPCs/HiveMind/DarkHeart.cs +++ b/NPCs/HiveMind/DarkHeart.cs @@ -107,7 +107,7 @@ public override void AI() NPC.velocity.Y = -velocity; } - bool dropRain = NPC.Bottom.Y < Main.player[NPC.target].position.Y - 200f && Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[NPC.target].position, Main.player[NPC.target].width, Main.player[NPC.target].height); + bool dropRain = NPC.Bottom.Y < Main.player[NPC.target].position.Y - 300f && Collision.CanHit(NPC.position, NPC.width, NPC.height, Main.player[NPC.target].position, Main.player[NPC.target].width, Main.player[NPC.target].height); float distanceX = masterMode ? 200f : 400f; float velocityX = velocity * 1.5f; if (NPC.Center.X > Main.player[NPC.target].Center.X + distanceX) From 8ba75d4665ac4a771b9ee68addef6f5d9dd0fcc7 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Thu, 30 May 2024 19:03:39 -0500 Subject: [PATCH 154/401] 5 seconds of immunity to immobilizing debuffs after an immobilizing debuff wears off. --- CalPlayer/CalamityPlayer.cs | 4 ++++ CalPlayer/CalamityPlayerMiscEffects.cs | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 90b444ee8d..c299cd9013 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -903,6 +903,9 @@ public GemTechArmorState GemTechState public bool wither = false; public bool ManaBurn = false; + public int ImmobilityDebuffImmunityTimer = 0; + public const int ImmobilityDebuffImmunityTimerMax = 300; + public const int SulphSeaWaterSafetyTime = 720; public const int SulphSeaWaterRecoveryTime = 150; #endregion @@ -2384,6 +2387,7 @@ public override void UpdateDead() banishingFire = false; wither = false; PurityHealSlowdownFrames = 0; + ImmobilityDebuffImmunityTimer = 0; #endregion #region Rogue diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index 2185b0fce0..822820f0a3 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -1337,6 +1337,20 @@ private void MiscEffects() if (expiredCooldowns.Count > 0) SyncCooldownRemoval(Main.netMode == NetmodeID.Server, expiredCooldowns); + // Grant the player 5 seconds of immunity to immobilizing debuffs after an immobilizing debuff wears off. + if (Player.stoned || Player.frozen || Player.webbed || gState) + { + ImmobilityDebuffImmunityTimer = ImmobilityDebuffImmunityTimerMax; + } + else if (ImmobilityDebuffImmunityTimer > 0) + { + ImmobilityDebuffImmunityTimer--; + Player.buffImmune[BuffID.Stoned] = true; + Player.buffImmune[BuffID.Frozen] = true; + Player.buffImmune[BuffID.Webbed] = true; + Player.buffImmune[ModContent.BuffType()] = true; + } + if (ascendantInsigniaCooldown > 0 && ascendantInsigniaBuffTime <= 0) ascendantInsigniaCooldown--; if (DragonsBreathAudioCooldown > 0) From 8bd975a3229b7061f476bd03c5829877976cb584 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Thu, 30 May 2024 22:55:40 -0500 Subject: [PATCH 155/401] Reduced Absorber defense from 15 to 10. --- Items/Accessories/TheAbsorber.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Items/Accessories/TheAbsorber.cs b/Items/Accessories/TheAbsorber.cs index cd3aa3500e..7a4ee85420 100644 --- a/Items/Accessories/TheAbsorber.cs +++ b/Items/Accessories/TheAbsorber.cs @@ -13,7 +13,7 @@ public override void SetDefaults() { Item.width = 20; Item.height = 24; - Item.defense = 15; + Item.defense = 10; Item.value = CalamityGlobalItem.RarityRedBuyPrice; Item.rare = ItemRarityID.Red; Item.accessory = true; From 5db80ab5b6118b5de5b835c6fbc3fa2e9972f904 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Thu, 30 May 2024 23:52:10 -0400 Subject: [PATCH 156/401] Fixed BR Desert Scourge spawning extra Desert Nuisances at the start of the fight --- Events/BossRushEvent.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Events/BossRushEvent.cs b/Events/BossRushEvent.cs index 5c8491e682..76b1624211 100644 --- a/Events/BossRushEvent.cs +++ b/Events/BossRushEvent.cs @@ -156,8 +156,6 @@ public static void Load() new Boss(ModContent.NPCType(), spawnContext: type => { NPC.SpawnOnPlayer(ClosestPlayerToWorldCenter, ModContent.NPCType()); - NPC.SpawnOnPlayer(ClosestPlayerToWorldCenter, ModContent.NPCType()); - NPC.SpawnOnPlayer(ClosestPlayerToWorldCenter, ModContent.NPCType()); }, permittedNPCs: new int[] { ModContent.NPCType(), ModContent.NPCType(), ModContent.NPCType(), ModContent.NPCType(), ModContent.NPCType(), ModContent.NPCType(), ModContent.NPCType(), ModContent.NPCType() }), From dd2da4035eea36a6950c0340f40e1ece447e5b10 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Fri, 31 May 2024 12:06:29 -0500 Subject: [PATCH 157/401] Fixed King Slime target bugs by returning the targeting to what it used to be. --- NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs index 3e40e48be0..e49f711b79 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/KingSlimeAI.cs @@ -414,6 +414,7 @@ public static bool BuffedKingSlimeAI(NPC npc, Mod mod) npc.damage = setDamage; npc.netUpdate = true; + npc.TargetClosest(); float distanceBelowTarget = npc.position.Y - (Main.player[npc.target].position.Y + 80f); float speedMult = 1f; @@ -686,6 +687,7 @@ public static bool VanillaKingSlimeAI(NPC npc, Mod mod) npc.ai[1] = 5f; if (Main.netMode != NetmodeID.MultiplayerClient) { + npc.TargetClosest(false); Point point3 = npc.Center.ToTileCoordinates(); Point point4 = Main.player[npc.target].Center.ToTileCoordinates(); Vector2 vector30 = Main.player[npc.target].Center - npc.Center; @@ -872,6 +874,8 @@ public static bool VanillaKingSlimeAI(NPC npc, Mod mod) npc.damage = npc.defDamage; npc.netUpdate = true; + npc.TargetClosest(); + if (npc.ai[1] == 3f) { npc.velocity.Y = -13f; @@ -971,6 +975,7 @@ public static bool VanillaKingSlimeAI(NPC npc, Mod mod) public static void GetPlaceToTeleportTo(NPC npc) { + npc.TargetClosest(false); float distanceAhead = 800f; Vector2 randomDefault = Main.rand.NextBool() ? Vector2.UnitX : -Vector2.UnitX; Vector2 vectorAimedAheadOfTarget = Main.player[npc.target].Center + new Vector2((float)Math.Round(Main.player[npc.target].velocity.X), 0f).SafeNormalize(randomDefault) * distanceAhead; From 635166161ef88f60c2527bbe451357bd650ad2c4 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 31 May 2024 00:24:07 -0400 Subject: [PATCH 158/401] Okay no 80% DR is completely excessive for BR EoW --- NPCs/CalamityGlobalNPC.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NPCs/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index 1a93568467..5e267f5447 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -3197,7 +3197,7 @@ public override void ModifyIncomingHit(NPC npc, ref NPC.HitModifiers modifiers) // Damage reduction on spawn for certain worm bosses. if (CalamityLists.EaterofWorldsIDs.Contains(npc.type)) - modifiers.FinalDamage *= 1f - MathHelper.Lerp(BossRushEvent.BossRushActive ? 0.8f : 0f, 0.99f, MathHelper.Clamp(1f - newAI[1] / EaterOfWorldsAI.DRIncreaseTime, 0f, 1f)); + modifiers.FinalDamage *= 1f - MathHelper.Lerp(BossRushEvent.BossRushActive ? 0.6f : 0f, 0.99f, MathHelper.Clamp(1f - newAI[1] / EaterOfWorldsAI.DRIncreaseTime, 0f, 1f)); if (CalamityLists.DestroyerIDs.Contains(npc.type)) modifiers.FinalDamage *= 1f - MathHelper.Lerp(0f, 0.99f, MathHelper.Clamp(1f - newAI[1] / DestroyerAI.DRIncreaseTime, 0f, 1f)); if (CalamityLists.AstrumDeusIDs.Contains(npc.type)) From e04b527c1cd86939d793e99929792db477439489 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 31 May 2024 01:10:55 -0400 Subject: [PATCH 159/401] Astrum Deus Relic re-resprite --- .../Furniture/BossRelics/AstrumDeusRelic.png | Bin 1224 -> 1252 bytes .../Furniture/BossRelics/AstrumDeusRelic.png | Bin 1217 -> 1386 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/Items/Placeables/Furniture/BossRelics/AstrumDeusRelic.png b/Items/Placeables/Furniture/BossRelics/AstrumDeusRelic.png index cfbfe599d30e26ad36b76493341635477523c221..077568f1c790451784ea69fd19f845da02688998 100644 GIT binary patch delta 1219 zcmV;!1U&o53FHZoF@K&(L_t(&f$f=ZNM2PO$3NFUm0~k>q)Gl=wMIefucEL=DkK;z zsy7Nng)b@=MfB&z#>f!&!Wz*ZS-lW8w%8yl76|dsLPtuLTMh8W1fRf@I04Ar-0?_~2SJt?Z z(@6kMjwh{Wt$%r9S<6U;s0N&OLIMdlj8}~->WZgu_oSH+W^4W*boqq`rIEc-;%wbClc0k6s-`R z-=a%Q(f9D9bpW)s^@c{}15Hl=(7F3n07^I91;E6JX@76u@uJn1M80)b41k0C`vI7p zI|o2h%#QlQy@qsjiOCn_DBLW8T5a8zG+*{)U;Ve-ln=lk^M+`7MUe;4 z6f-^=U1BB0mw5pD4oq6U(Aw4u1Q}fUOHo%@+2gc3tntz^-vywm+&oXDbpPP~{uDsL zIuotYC4V+KwP^rD{V}#>g2U$Ybt25s`06L(>KR)o<=Q zMSpv(^i)BXR}=v-erhK4Y(mkc-H|F;Rjw{s$t5LiTyIFZ^&e3umZch7m7`8)bav5L zp9=(}K05p^5bVg+)}Elc%w+zzj)bqNA|<q$6=}a~>mqwP@inrCjZ?$!s02uy$I0bMh{;@Ug_@{3G0YR6@gUwrj zfTYyixD9}+>o<4+#|MXjmH*DI9b&KVY5-v1Sf548B_z3IRy$7QYPQsS0ME7cSmPs0 zY(-RFh*W#m2Uh=+Pk#bHW4)r))I48qwC-$q$a;?KH#cqzjn2pt3(NeWnOgOib~)+# hS3Azt;OH75_BYL;7stZGr(pm9002ovPDHLkV1mMLS?vG- delta 1191 zcmV;Y1X%mz3CIbMF@J(dL_t(&f$f=FXdG1-$A7b%O>NR`bJJ*wP1Zz{7?Bj)CS)PK zAd3)au_898p!7kZY7x{2gQ!UK!KYRW^&uF@LyGl6g+f>_km3p@DG@O?3Bhb@yEMgI z+9lB@Y1W6cU#92m4A~TfS@r)iGiT1socYcF`_8v#;eV}7mVeucZJ|}KO=WY>!HKmE zNaVY{%l>)g1%t%^1pMm(2<9&WVCCHaAhmSejSK*hZ~*|(*t|5Q0FpNX7C?Eq|T-UYz1_dnFyVN`8wuZeDpocD=|Oix8)bLqVS0OD~) zMo9hm{eX5H313&;V~WV=AH{MjM{**Qpl69$w~So#R%Gjf*73scik#%Fiu*PKP*qh6 zz^C1V0DS(%kYtyd3g`B2*!Ie$V7fZ{@ByP3HqJvz&D51cyv zHUJgXI{@f7_#^^n@;uK^O6Pcb%{HCJPB-hz>5`c|m&j2uT_7wp3wY>|#0}nP>0As%n170R( zddzPH0DridT1-Lq(fRm+7u2!gInhU_)@jEdyt+=iPRNn|ia9~dvF;LY$&4VLG37>1 zJoWNERo}Uh>+ZP%Kvm_Y93v*tB6XI$i4YTyJ@@S0fK5p9)N1NI@-P7HhgF7`FY?Y? zJJt5Rejt~KNfe5g%={!3szjw(rwO^5P>BUFK7TQ--Cw?l^b=wOBc}m-j`cpV@}gw` zCTD$)`D^#CAdpE;ss{0nNv@&pE(>6IePW{3$hqY)As1>;RYG5X!ki*3$gJ(%)<|-Pn8=Ns%y|-( zZhz$NsaE994aEUSF053nSq&`rh>3(;O~p+B#uI+cJ3>%qh(jG+fSr$a?A~Jm^qd?5 z{tLuJW~IBiRC(|6lusilGeFzZZvb{ZhD%hsDffw)G6~k#sCw=E_?&Zz`>!XK#j3TY z`NceKyR@v{InSrOSP)p!wj#Gx?c52c6{1^a_JbD;_W1Y_f z(A{%IRV6NK8`0Rjw!&!2v&1q+8);NyZEmRtU~G6S1<)J)TI+Z2+arKY&?K_Iy?+(3 zNs8JddjSaDU#+T-!7%`$KP_whyie@FPPNL@)EWlh?3tKG$|NK*$znh002ovPDHLk FV1j4^M=1aR diff --git a/Tiles/Furniture/BossRelics/AstrumDeusRelic.png b/Tiles/Furniture/BossRelics/AstrumDeusRelic.png index 1fdf1e0d99f438f3f9bb12b8cc2f93ea4d87cab9..c5c314a84d45651226fae3503b82cfb749930300 100644 GIT binary patch delta 1355 zcmV-R1+@CX3F-=vFnjgP218k*RZhD8(8L{m&5MU7S$rjsBv#l9kyS{?%o za9y1H=gv7Zmx1cS-2Z0odEfi}&-Xar8IK6;+fxL!_FW#p)WlV*{_4$D zFT1>}zGO?|{`z~(12}teJ?d4qgra{n`hSECDL&R}H$4Rk5k+Gkk~L%lBdpxTnP#7&7}Z*b^3E4lyFz)9;@Gl z@rzbJjdLN!vwz^_?N|V@W&{W&*w$oz&yU;!;Db*G0Qls@djNFreLU~@mX;0x#=iZ* z8h7-i69DXcvI2m~=?nl9S2B0|4M3b2>FY5PpIi%gc=QN-vvbT`OA1ip7T!0)H!&tT5lSu$J@yO4D<)9u_lS ze(@aulhfY-@KjGN0FQJ%ZA~mjq!ZFL7o~|358$5aBmn6@Z{L*_iw`5(qi?;@V}9Qm z@c~jZH2`E*W`WR(Y0pd2vQCW;K4DGV(sB-f^CM%{xXECg)=kaS_y8TjI$7_rtq+M0 zBYM!DE`KBuSs&M*^gd_Wul@c#kn2A*&P7L^&4k`VC@(WA(${0VywfAL^@|@P*Cy`- zPevkcY@|K?{=3Fn9XoF78{4YQ_<#vP^<#Kmg1RYp!XKy!^rF%`>ZTUN>Y-9te7O`TDOC*{c6qAQJ3SNtai;S z>!x*uM5$-JhoG`zLm@tl=pk9*<&Ap#gBa?_VPjQv)>dqlnz5M>6d8mu*hnx>gH?a( zq<``JZWNrXDz@fRe=+D4n|4LX@nJ+(M|&<&YM)0GQ^`ZiI)&MjnoSo_Kk14jd(?@! z?%z@D0n9I$_xR>!6tK<>)<8wATZKEm_tAMa zTTc*Uh5E&Yk&?>btX^MdeqDPV!Z0Aox)R6mM!vJkIWYa_0SVn$GoS6L3%s_BMG&<&P!LX2fauRyfb zbFG~`e3ov+^vtdY<%h(~A2a5pwtuu}E)x$0QKxdbE)#B)s`{>=EFJ6KYx<>Tmh-+) z6cbUkE5$XngHl|NFFz*3)>ozk{_wBJ^4`0LFgpw;pi( zy$=9*e8*M*Mt?^WX5NJ>fKMPXQEsg(DO~UXW)}(pn4X?m(LWMBBAf5O3xJEiUj?%F zwj%DT@v&_{IGJzGOk4B22aBxhiqcsRpt98VO1{}Fx0Ft3P=BCagv_Ff_*FDRSED)#{J@~%0+_s|!ge*(a#C&vM3 zYj5=cdb)Z6pGVJ0kbv6On5mjZEMB@Edivc)vbk4dj zGV+?dQe9Q#0ep4VyiatA4EG%b{JieUB_b&cY46KJI$=uBzj8isy&HLvQI=E(;byUc zr145*h^%!7be>0rCX59*%iQJ|+Ykcg2ArwYH+E88WEzV1WPX>b5`Caz7 zHGdu%A{md=)tK&bWURo-PGOZ=5)oBo_dA!?iA-JXy&k|w@-O#Y0zKNYrNjfclp0F| zoEtt3`1K@m9?6tfktx6XIsj9DuL-Ohst@^+dHT5*0YB31ZFL?%SI>y1SanSI&-V|R z_bXmlWke*mt|-E8ZzM9(jn)U3O!K1~Jb!@xAO8$ouR7A!-U>iZSFc5G^$-cmVv<|A z)l(_btxXjkK<~h$6+ySFUD82#5dIA~>;xOV?lXJpl9#T@K7b zI)h8@uf5INcX$9NPYnWhenZSCr$<~Va(zRYA&YA5Mss=S=$u2!d<&LmVwHPzKkr=; zq{tAtCDB+a_sgXSCI3j@mWnP#h8oBn{onL2-EI0LRN$Ws00000NkvXXu0mjfsC7C~ From ac87e01185b449c8761a2d05a3bcdf41243beadb Mon Sep 17 00:00:00 2001 From: mochi-angel Date: Thu, 30 May 2024 22:58:09 -0700 Subject: [PATCH 160/401] Minor localization changes --- Items/CalamityGlobalItemTooltip.cs | 2 +- .../en-US/Mods.CalamityMod.Items.Armor.PostMoonLord.hjson | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Items/CalamityGlobalItemTooltip.cs b/Items/CalamityGlobalItemTooltip.cs index b7ae69bfc6..efa32183fa 100644 --- a/Items/CalamityGlobalItemTooltip.cs +++ b/Items/CalamityGlobalItemTooltip.cs @@ -622,7 +622,7 @@ void AddTooltip(string text) { EditTooltipByNum(0, (line) => line.Text = "Multiplies all fire-based debuff damage by 1.25\n" + "All attacks light enemies on fire\n" + - "'Never get cold feet again'\n"); + "'Never get cold feet again'"); } // Hellfire Treads buff. diff --git a/Localization/en-US/Mods.CalamityMod.Items.Armor.PostMoonLord.hjson b/Localization/en-US/Mods.CalamityMod.Items.Armor.PostMoonLord.hjson index f4e3ddf84b..a0c60646cb 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Armor.PostMoonLord.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Armor.PostMoonLord.hjson @@ -232,7 +232,7 @@ FearmongerGreathelm: { ''' 20% increased summon damage and +2 max minions Minions no longer deal less damage while wielding non-summoner weapons - Immunity to all forms of frost and flame + Immunity to all but the strongest forms of frost and flame Minion attacks grant +3.5 HP/s life regen and massively accelerate life regen 15% increased damage reduction during the Pumpkin and Frost Moons This extra damage reduction ignores the soft cap From ff434d8a800695d693febc4605a4b9f374360d91 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Fri, 31 May 2024 12:27:52 -0500 Subject: [PATCH 161/401] Gave Queen Slime the same target change as King Slime, just in case. --- NPCs/VanillaNPCAIOverrides/Bosses/QueenSlimeAI.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/QueenSlimeAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/QueenSlimeAI.cs index 1ce6e0c5c6..5b0ba579c7 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/QueenSlimeAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/QueenSlimeAI.cs @@ -68,6 +68,7 @@ public static bool BuffedQueenSlimeAI(NPC npc, Mod mod) if (Main.netMode != NetmodeID.MultiplayerClient) { npc.netUpdate = true; + npc.TargetClosest(false); Vector2 vectorAimedAheadOfTarget = Main.player[npc.target].Center + new Vector2((float)Math.Round(Main.player[npc.target].velocity.X), 0f).SafeNormalize(Vector2.Zero) * 800f; Point predictiveTeleportPoint = vectorAimedAheadOfTarget.ToTileCoordinates(); int randomTeleportOffset = 5; @@ -402,6 +403,8 @@ public static bool BuffedQueenSlimeAI(NPC npc, Mod mod) speedMult = 2f; npc.netUpdate = true; + npc.TargetClosest(); + if (npc.ai[2] == 3f) { npc.velocity.Y = -13f * speedMult; @@ -929,6 +932,7 @@ public static bool VanillaQueenSlimeAI(NPC npc, Mod mod) if (Main.netMode != NetmodeID.MultiplayerClient) { npc.netUpdate = true; + npc.TargetClosest(false); Point point = npc.Center.ToTileCoordinates(); Point point2 = Main.player[npc.target].Center.ToTileCoordinates(); Vector2 vector = Main.player[npc.target].Center - npc.Center; @@ -1248,6 +1252,8 @@ public static bool VanillaQueenSlimeAI(NPC npc, Mod mod) npc.damage = npc.defDamage; npc.netUpdate = true; + npc.TargetClosest(); + if (npc.ai[2] == 3f) { npc.velocity.Y = -13f; From edcc4e8826e449d685c21b4201900ef0223f5d3c Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Fri, 31 May 2024 13:44:23 -0500 Subject: [PATCH 162/401] 1 - Astrum Aureus walks for less time if his target is near and stays idle for less time if his target is near or hitting him. 2 - Brimstone Elemental floats around for less time if her target is near or is hitting her and teleports faster in higher difficulties. 3 - Hive Mind fires vile spits while drifting in Expert+ and fires vile spits while spinning before dashing in Master+. --- .../CalamityBossAIs/AstrumAureusAI.cs | 30 ++++++++++++++----- .../CalamityBossAIs/BrimstoneElementalAI.cs | 10 +++++-- NPCs/HiveMind/HiveMind.cs | 28 +++++++++++++++++ 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/NPCs/CalamityAIs/CalamityBossAIs/AstrumAureusAI.cs b/NPCs/CalamityAIs/CalamityBossAIs/AstrumAureusAI.cs index 5a651886f6..e91a6698d7 100644 --- a/NPCs/CalamityAIs/CalamityBossAIs/AstrumAureusAI.cs +++ b/NPCs/CalamityAIs/CalamityBossAIs/AstrumAureusAI.cs @@ -41,6 +41,7 @@ public static void VanillaAstrumAureusAI(NPC npc, Mod mod) // Variables bool bossRush = BossRushEvent.BossRushActive; bool expertMode = Main.expertMode || bossRush; + bool masterMode = Main.masterMode || bossRush; bool revenge = CalamityWorld.revenge || bossRush; bool death = CalamityWorld.death || bossRush; @@ -58,13 +59,6 @@ public static void VanillaAstrumAureusAI(NPC npc, Mod mod) calamityGlobalNPC.DR = exhausted ? 0.25f : 0.5f; npc.defense = exhausted ? npc.defDefense / 2 : npc.defDefense; - // Don't fire projectiles and don't increment phase timers for 4 seconds after the teleport phase to avoid cheap bullshit - float noProjectileOrPhaseIncrementTime = 240f; - - bool dontAttack = npc.localAI[3] > 0f; - if (dontAttack) - npc.localAI[3] -= 1f; - // Get a target if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); @@ -75,6 +69,19 @@ public static void VanillaAstrumAureusAI(NPC npc, Mod mod) Player player = Main.player[npc.target]; + // Don't fire projectiles and don't increment phase timers for 4 seconds after the teleport phase to avoid cheap bullshit + float noProjectileOrPhaseIncrementTime = 240f; + + bool dontAttack = npc.localAI[3] > 0f; + if (dontAttack) + { + npc.localAI[3] -= 1f; + if (npc.justHit) + npc.localAI[3] -= masterMode ? 7f : expertMode ? 5f : 3f; + if (npc.Distance(player.Center) < 240f) + npc.localAI[3] -= masterMode ? 4f : expertMode ? 2f : 1f; + } + float enrageScale = bossRush ? 1f : 0f; if ((Main.IsItDay() && !player.Calamity().ZoneAstral) || bossRush) { @@ -336,6 +343,11 @@ public static void VanillaAstrumAureusAI(NPC npc, Mod mod) // Stay vulnerable for 3 seconds npc.ai[1] += 1f; + if (npc.justHit) + npc.ai[1] += masterMode ? 7f : expertMode ? 5f : 3f; + if (npc.Distance(player.Center) < 240f) + npc.ai[1] += masterMode ? 4f : expertMode ? 2f : 1f; + if (npc.ai[1] >= 180f || bossRush) { // Set AI to random state and reset other AI arrays @@ -442,7 +454,11 @@ public static void VanillaAstrumAureusAI(NPC npc, Mod mod) // Walk for a maximum of 6 seconds if (!dontAttack) + { npc.ai[1] += 1f; + if (npc.Distance(player.Center) < 240f) + npc.ai[1] += masterMode ? 4f : expertMode ? 2f : 1f; + } if (npc.ai[1] >= ((bossRush ? 270f : 360f) - (death ? 90f * (1f - lifeRatio) : 0f))) { diff --git a/NPCs/CalamityAIs/CalamityBossAIs/BrimstoneElementalAI.cs b/NPCs/CalamityAIs/CalamityBossAIs/BrimstoneElementalAI.cs index 77a9dc6558..89ff485601 100644 --- a/NPCs/CalamityAIs/CalamityBossAIs/BrimstoneElementalAI.cs +++ b/NPCs/CalamityAIs/CalamityBossAIs/BrimstoneElementalAI.cs @@ -99,6 +99,7 @@ public static void VanillaBrimstoneElementalAI(NPC npc, Mod mod) // Variables for buffing the AI bool bossRush = BossRushEvent.BossRushActive; bool expertMode = Main.expertMode || bossRush; + bool masterMode = Main.masterMode || bossRush; bool revenge = CalamityWorld.revenge || bossRush; bool death = CalamityWorld.death || bossRush; @@ -253,7 +254,12 @@ public static void VanillaBrimstoneElementalAI(NPC npc, Mod mod) if (Main.netMode != NetmodeID.MultiplayerClient) { npc.localAI[1] += 1f; - if (npc.localAI[1] >= (bossRush ? 5f : death ? 30f : 180f)) + if (npc.justHit) + npc.localAI[1] += masterMode ? 7f : expertMode ? 5f : 3f; + if (npc.Distance(player.Center) < 160f) + npc.localAI[1] += masterMode ? 4f : expertMode ? 2f : 1f; + + if (npc.localAI[1] >= (bossRush ? 60f : death ? 120f : 180f)) { npc.TargetClosest(); npc.localAI[1] = 0f; @@ -307,7 +313,7 @@ public static void VanillaBrimstoneElementalAI(NPC npc, Mod mod) Main.dust[dust].noGravity = true; Main.dust[dust].fadeIn = 1f; } - npc.alpha += bossRush ? 4 : death ? 3 : 2; + npc.alpha += bossRush ? 15 : death ? 5 : revenge ? 4 : expertMode ? 3 : 2; if (npc.alpha >= 255) { int spawnType = brimmy.currentMode == 3 ? NPCID.AngryNimbus : ModContent.NPCType(); diff --git a/NPCs/HiveMind/HiveMind.cs b/NPCs/HiveMind/HiveMind.cs index 1807a2b245..868e8357c1 100644 --- a/NPCs/HiveMind/HiveMind.cs +++ b/NPCs/HiveMind/HiveMind.cs @@ -823,6 +823,16 @@ public override void AI() return; } + if (expertMode) + { + if (Main.netMode != NetmodeID.MultiplayerClient) + { + NPC.localAI[2] += 1f; + if (Collision.CanHitLine(NPC.Center, 1, 1, player.Center, 1, 1) && NPC.Distance(player.Center) > 160f && NPC.localAI[2] % vileSpitFireRate == 0) + NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y, NPCID.VileSpitEaterOfWorlds, 0, 0f, 69f); + } + } + NPC.velocity = player.Center - NPC.Center; phase2timer--; @@ -939,8 +949,17 @@ public override void AI() if (NPC.alpha > 0) { if (Main.netMode != NetmodeID.MultiplayerClient) + { NPC.Center = player.Center + new Vector2(teleportRadius, 0).RotatedBy(rotation); + if (masterMode) + { + NPC.localAI[2] += 1f; + if (Collision.CanHitLine(NPC.Center, 1, 1, player.Center, 1, 1) && NPC.Distance(player.Center) > 160f && NPC.localAI[2] % vileSpitFireRate == 0) + NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y, NPCID.VileSpitEaterOfWorlds, 0, 0f, 69f); + } + } + rotation += rotationIncrement * rotationDirection; phase2timer = lungeDelay; @@ -968,8 +987,17 @@ public override void AI() else { if (Main.netMode != NetmodeID.MultiplayerClient) + { NPC.Center = player.Center + new Vector2(teleportRadius, 0).RotatedBy(rotation); + if (masterMode) + { + NPC.localAI[2] += 1f; + if (Collision.CanHitLine(NPC.Center, 1, 1, player.Center, 1, 1) && NPC.Distance(player.Center) > 160f && NPC.localAI[2] % vileSpitFireRate == 0) + NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y, NPCID.VileSpitEaterOfWorlds, 0, 0f, 69f); + } + } + rotation += rotationIncrement * rotationDirection * phase2timer / lungeDelay; } } From f76473253e32998008f3c5a5f09fd6e803e5e4d5 Mon Sep 17 00:00:00 2001 From: NycroV <83246959+NycroV@users.noreply.github.com> Date: Mon, 27 May 2024 18:41:28 -0400 Subject: [PATCH 163/401] Music events (untested) --- CalamityNetcode.cs | 18 ++- Systems/MusicEventSystem.cs | 259 ++++++++++++++++++++++++++++++++++++ 2 files changed, 276 insertions(+), 1 deletion(-) create mode 100644 Systems/MusicEventSystem.cs diff --git a/CalamityNetcode.cs b/CalamityNetcode.cs index a75cbdfe5c..c498f8c37c 100644 --- a/CalamityNetcode.cs +++ b/CalamityNetcode.cs @@ -6,6 +6,7 @@ using CalamityMod.NPCs.NormalNPCs; using CalamityMod.NPCs.Providence; using CalamityMod.NPCs.TownNPCs; +using CalamityMod.Systems; using CalamityMod.TileEntities; using CalamityMod.World; using Microsoft.Xna.Framework; @@ -300,6 +301,17 @@ public static void HandlePacket(Mod mod, BinaryReader reader, int whoAmI) SyncCalamityWorldDifficulties(sender); break; + // + // Music event syncs + // + case CalamityModMessageType.MusicEventSyncRequest: + MusicEventSystem.FulfillSyncRequest(whoAmI); + break; + + case CalamityModMessageType.MusicEventSyncResponse: + MusicEventSystem.ReceiveSyncResponse(reader); + break; + // // Default case: with no idea how long the packet is, we can't safely read data. // Throw an exception now instead of allowing the network stream to corrupt. @@ -421,6 +433,10 @@ public enum CalamityModMessageType : byte MousePositionSync, // World state sync - SyncDifficulties + SyncDifficulties, + + // Music events + MusicEventSyncRequest, + MusicEventSyncResponse } } diff --git a/Systems/MusicEventSystem.cs b/Systems/MusicEventSystem.cs new file mode 100644 index 0000000000..c4c8abc888 --- /dev/null +++ b/Systems/MusicEventSystem.cs @@ -0,0 +1,259 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading; +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; +using Terraria.ModLoader.IO; + +namespace CalamityMod.Systems +{ + public record class MusicEventEntry(string Id, int Song, TimeSpan Length, TimeSpan IntroSilence, Func ShouldPlay); + + public class MusicEventSystem : ModSystem + { + #region Statics + + public static MusicEventEntry CurrentEvent { get; set; } = null; + + public static DateTime? TrackStart { get; set; } = null; + + // This allows for some additional silence at the end of a track + public static DateTime? TrackEnd { get; set; } = null; + + public static int LastPlayedEvent { get; set; } = -1; + + public static float VolumeCache { get; set; } = -1f; + + public static Thread EventTrackerThread { get; set; } = null; + + public static List PlayedEvents { get; set; } = []; + + public static List EventCollection { get; set; } = []; + + #endregion + + #region Events List + + public override void OnModLoad() + { + static void AddEntry(string eventId, string songName, TimeSpan introSilence, TimeSpan length, Func shouldPlay) + { + MusicEventEntry entry = new(eventId, MusicLoader.GetMusicSlot(CalamityMod.Instance.musicMod, songName), introSilence, length, shouldPlay); + EventCollection.Add(entry); + } + + AddEntry("CloneDefeated", "Interlude1", TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(216.287d), () => DownedBossSystem.downedCalamitasClone); + AddEntry("MLDefeated", "Interlude2", TimeSpan.Zero, TimeSpan.FromSeconds(160.989), () => NPC.downedMoonlord); + AddEntry("YharonDefeated", "Interlude3", TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(295.932), () => DownedBossSystem.downedYharon); + + AddEntry("DoGDefeated", "DevourerofGodsEulogy", TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(203.62d), () => DownedBossSystem.downedDoG); + } + + public override void Unload() => EventCollection.Clear(); + + #endregion + + #region Event Handling + + public override void PostUpdateTime() + { + // If the event has just finished, we want a little silence before fading back to normal + if (TrackEnd is not null) + { + // `silence` is the time after a track ends before music goes back to normal + TimeSpan silence = TimeSpan.FromSeconds(3); + TimeSpan postTrack = DateTime.Now - TrackEnd.Value; + + // Continue "playing" the track for the amount of silent time specified + if (postTrack < silence) + Main.musicBox2 = LastPlayedEvent; + + else + { + LastPlayedEvent = -1; + TrackEnd = null; + } + + // But in reality set the volume to 0, so it stays silent + Main.musicFade[Main.curMusic] = 0f; + + return; + } + + // Only check for new events to play if none is currently playing + // This makes sure events always finish before a new one starts + if (CurrentEvent is null) + { + foreach (MusicEventEntry musicEvent in EventCollection) + { + // Make sure the event hasn't already played and SHOULD play + if (!PlayedEvents.Contains(musicEvent.Id) && musicEvent.ShouldPlay()) + { + // Assign the current event and start time + CurrentEvent = musicEvent; + TrackStart = DateTime.Now + musicEvent.IntroSilence; + + // On clients, use a background thread to make sure the track always plays for exactly + // the specified length, regardless of if the game gets minimized, lags, or time becomes + // detangled from a consistent 60fps in any other way + if (!Main.dedServ) + { + EventTrackerThread = new(WatchMusicEvent); + EventTrackerThread.Start(); + } + + break; + } + } + } + + if (TrackStart is not null) + { + if (TrackStart > DateTime.Now) + { + int silenceSlot = MusicLoader.GetMusicSlot(Mod, "Sounds/Music/Silence"); + Main.musicBox2 = silenceSlot; + + VolumeCache = Main.musicVolume; + } + + else + { + Main.musicBox2 = CurrentEvent.Song; + + // This sets the music volume to 0 for one frame, then back to normal + // Effectively, it immediately starts the music without fading + // This only happens if there is intended silence before the song starts + if (VolumeCache != -1f) + { + if (Main.musicVolume != 0f) + Main.musicVolume = 0f; + + else + { + Main.musicVolume = VolumeCache; + VolumeCache = -1f; + } + } + } + + // If the event has finished playing, mark the end as now and clear the current event + if (DateTime.Now - TrackStart > CurrentEvent.Length) + { + PlayedEvents.Add(CurrentEvent.Id); + + TrackEnd = DateTime.Now; + LastPlayedEvent = CurrentEvent.Song; + + TrackStart = null; + CurrentEvent = null; + } + } + } + + /// + /// Watches for the game minimizing at any point, and adjusts the amount of time to play the song for accordingly + /// + public static void WatchMusicEvent() + { + DateTime? minimized = null; + + int currentEventSong; + while ((currentEventSong = CurrentEvent?.Song ?? -1) != -1) + { + bool musicPaused = Main.audioSystem.IsTrackPlaying(currentEventSong) && Main.musicVolume != 0f; + + if (musicPaused && !minimized.HasValue) + minimized = DateTime.Now; + + else if (!musicPaused && minimized.HasValue) + { + TrackStart = TrackStart.Value + (DateTime.Now - minimized.Value); + minimized = null; + } + } + + EventTrackerThread = null; + } + + #endregion + + #region Event Saving + + public override void SaveWorldData(TagCompound tag) + { + tag["calamityPlayedMusicEventCount"] = PlayedEvents.Count; + for (int i = 0; i < PlayedEvents.Count; i++) + tag[$"calamityPlayedMusicEvent{i}"] = PlayedEvents[i]; + } + + public override void LoadWorldData(TagCompound tag) + { + PlayedEvents.Clear(); + + if (tag.TryGet("calamityPlayedMusicEventCount", out int playedMusicEventCount)) + { + for (int i = 0; i < playedMusicEventCount; i++) + { + if (tag.TryGet($"calamityPlayedMusicEvent{i}", out string playedEvent)) + PlayedEvents.Add(playedEvent); + } + } + } + + #endregion + + #region Event Syncing + + public static void SendSyncRequest() + { + ModPacket packet = CalamityMod.Instance.GetPacket(); + packet.Write((byte)CalamityModMessageType.MusicEventSyncRequest); + packet.Send(); + } + + public static void FulfillSyncRequest(int requester) + { + // Only fulfill requests as the server host + if (!Main.dedServ) + return; + + ModPacket packet = CalamityMod.Instance.GetPacket(); + packet.Write((byte)CalamityModMessageType.MusicEventSyncResponse); + + int trackCount = PlayedEvents.Count; + packet.Write(trackCount); + + for (int i = 0; i < trackCount; i++) + packet.Write(PlayedEvents[i]); + + packet.Send(toClient: requester); + } + + public static void ReceiveSyncResponse(BinaryReader reader) + { + // Only receive info on clients + if (Main.dedServ) + return; + + PlayedEvents.Clear(); + int trackCount = reader.ReadInt32(); + + for (int i = 0; i < trackCount; i++) + PlayedEvents.Add(reader.ReadString()); + } + + #endregion + } + + public class CalamityModMusicEventPlayer : ModPlayer + { + public override void OnEnterWorld() + { + if (Main.netMode == NetmodeID.MultiplayerClient && Player.whoAmI != Main.myPlayer) + MusicEventSystem.SendSyncRequest(); + } + } +} From a617c82ee82f635670f93cc37067aca622ba319a Mon Sep 17 00:00:00 2001 From: NycroV <83246959+NycroV@users.noreply.github.com> Date: Tue, 28 May 2024 01:56:30 -0400 Subject: [PATCH 164/401] Bug fixes and event updates --- Systems/MusicEventSystem.cs | 102 ++++++++++++++++++++++-------------- 1 file changed, 63 insertions(+), 39 deletions(-) diff --git a/Systems/MusicEventSystem.cs b/Systems/MusicEventSystem.cs index c4c8abc888..4f12b8c300 100644 --- a/Systems/MusicEventSystem.cs +++ b/Systems/MusicEventSystem.cs @@ -9,7 +9,7 @@ namespace CalamityMod.Systems { - public record class MusicEventEntry(string Id, int Song, TimeSpan Length, TimeSpan IntroSilence, Func ShouldPlay); + public record class MusicEventEntry(string Id, int Song, TimeSpan Length, TimeSpan IntroSilence, TimeSpan OutroSilence, Func ShouldPlay); public class MusicEventSystem : ModSystem { @@ -24,7 +24,8 @@ public class MusicEventSystem : ModSystem public static int LastPlayedEvent { get; set; } = -1; - public static float VolumeCache { get; set; } = -1f; + // This allows skipping track fade in + public static bool NoFade { get; set; } = false; public static Thread EventTrackerThread { get; set; } = null; @@ -32,23 +33,26 @@ public class MusicEventSystem : ModSystem public static List EventCollection { get; set; } = []; + // This is to make sure that old worlds don't immediately queue a bunch of tracks on player entry + private static bool oldWorld { get; set; } = true; + #endregion #region Events List public override void OnModLoad() { - static void AddEntry(string eventId, string songName, TimeSpan introSilence, TimeSpan length, Func shouldPlay) + static void AddEntry(string eventId, string songName, TimeSpan length, Func shouldPlay, TimeSpan? introSilence = null, TimeSpan? outroSilence = null) { - MusicEventEntry entry = new(eventId, MusicLoader.GetMusicSlot(CalamityMod.Instance.musicMod, songName), introSilence, length, shouldPlay); + MusicEventEntry entry = new(eventId, CalamityMod.Instance.GetMusicFromMusicMod(songName).Value, length, introSilence ?? TimeSpan.Zero, outroSilence ?? TimeSpan.FromSeconds(3), shouldPlay); EventCollection.Add(entry); } - AddEntry("CloneDefeated", "Interlude1", TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(216.287d), () => DownedBossSystem.downedCalamitasClone); - AddEntry("MLDefeated", "Interlude2", TimeSpan.Zero, TimeSpan.FromSeconds(160.989), () => NPC.downedMoonlord); - AddEntry("YharonDefeated", "Interlude3", TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(295.932), () => DownedBossSystem.downedYharon); + AddEntry("CloneDefeated", "Interlude1", TimeSpan.FromSeconds(216.287d), () => DownedBossSystem.downedCalamitasClone, introSilence: TimeSpan.FromSeconds(5f)); + AddEntry("MLDefeated", "Interlude2", TimeSpan.FromSeconds(160.989d), () => NPC.downedMoonlord); + AddEntry("YharonDefeated", "Interlude3", TimeSpan.FromSeconds(295.932d), () => DownedBossSystem.downedYharon, outroSilence: TimeSpan.FromSeconds(1.5f)); - AddEntry("DoGDefeated", "DevourerofGodsEulogy", TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(203.62d), () => DownedBossSystem.downedDoG); + AddEntry("DoGDefeated", "DevourerofGodsEulogy", TimeSpan.FromSeconds(203.620d), () => DownedBossSystem.downedDoG, introSilence: TimeSpan.FromSeconds(5f)); } public override void Unload() => EventCollection.Clear(); @@ -59,6 +63,21 @@ static void AddEntry(string eventId, string songName, TimeSpan introSilence, Tim public override void PostUpdateTime() { + // If the player has already completed conditions to trigger certain music events, we don't + // want to queue a bunch of tracks to play as soon as they enter the world, so instead just mark them as played + if (oldWorld) + { + foreach (MusicEventEntry entry in EventCollection) + { + if (entry.ShouldPlay()) + PlayedEvents.Add(entry.Id); + } + + oldWorld = false; + } + + //PlayedEvents.Remove("MLDefeated"); + // If the event has just finished, we want a little silence before fading back to normal if (TrackEnd is not null) { @@ -66,9 +85,12 @@ public override void PostUpdateTime() TimeSpan silence = TimeSpan.FromSeconds(3); TimeSpan postTrack = DateTime.Now - TrackEnd.Value; - // Continue "playing" the track for the amount of silent time specified + // Play silence for the time specified if (postTrack < silence) - Main.musicBox2 = LastPlayedEvent; + { + int silenceSlot = MusicLoader.GetMusicSlot(Mod, "Sounds/Music/Silence"); + Main.musicBox2 = silenceSlot; + } else { @@ -76,9 +98,6 @@ public override void PostUpdateTime() TrackEnd = null; } - // But in reality set the volume to 0, so it stays silent - Main.musicFade[Main.curMusic] = 0f; - return; } @@ -94,6 +113,7 @@ public override void PostUpdateTime() // Assign the current event and start time CurrentEvent = musicEvent; TrackStart = DateTime.Now + musicEvent.IntroSilence; + PlayedEvents.Add(musicEvent.Id); // On clients, use a background thread to make sure the track always plays for exactly // the specified length, regardless of if the game gets minimized, lags, or time becomes @@ -115,40 +135,32 @@ public override void PostUpdateTime() { int silenceSlot = MusicLoader.GetMusicSlot(Mod, "Sounds/Music/Silence"); Main.musicBox2 = silenceSlot; - - VolumeCache = Main.musicVolume; + NoFade = true; } else { Main.musicBox2 = CurrentEvent.Song; - // This sets the music volume to 0 for one frame, then back to normal - // Effectively, it immediately starts the music without fading - // This only happens if there is intended silence before the song starts - if (VolumeCache != -1f) + if (NoFade) { - if (Main.musicVolume != 0f) - Main.musicVolume = 0f; - - else - { - Main.musicVolume = VolumeCache; - VolumeCache = -1f; - } + Main.musicFade[CurrentEvent.Song] = 1f; + NoFade = false; } - } - // If the event has finished playing, mark the end as now and clear the current event - if (DateTime.Now - TrackStart > CurrentEvent.Length) - { - PlayedEvents.Add(CurrentEvent.Id); + // If the event has finished playing, mark the end as now and clear the current event + if (DateTime.Now - TrackStart >= CurrentEvent.Length) + { + int silenceSlot = MusicLoader.GetMusicSlot(Mod, "Sounds/Music/Silence"); + Main.musicBox2 = silenceSlot; + Main.musicFade[CurrentEvent.Song] = 0f; - TrackEnd = DateTime.Now; - LastPlayedEvent = CurrentEvent.Song; + TrackEnd = DateTime.Now; + LastPlayedEvent = CurrentEvent.Song; - TrackStart = null; - CurrentEvent = null; + TrackStart = null; + CurrentEvent = null; + } } } } @@ -160,10 +172,9 @@ public static void WatchMusicEvent() { DateTime? minimized = null; - int currentEventSong; - while ((currentEventSong = CurrentEvent?.Song ?? -1) != -1) + while (CurrentEvent is not null) { - bool musicPaused = Main.audioSystem.IsTrackPlaying(currentEventSong) && Main.musicVolume != 0f; + bool musicPaused = Main.instance.IsActive; if (musicPaused && !minimized.HasValue) minimized = DateTime.Now; @@ -201,6 +212,19 @@ public override void LoadWorldData(TagCompound tag) PlayedEvents.Add(playedEvent); } } + + oldWorld = false; + } + + public override void OnWorldUnload() + { + oldWorld = true; + TrackStart = null; + TrackEnd = null; + CurrentEvent = null; + PlayedEvents.Clear(); + NoFade = false; + LastPlayedEvent = -1; } #endregion From a0fa9c12c6ea2cd4f7988f781977c3f888c7bf24 Mon Sep 17 00:00:00 2001 From: NycroV <83246959+NycroV@users.noreply.github.com> Date: Tue, 28 May 2024 18:54:44 -0400 Subject: [PATCH 165/401] SCal Acceptance event --- Systems/MusicEventSystem.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Systems/MusicEventSystem.cs b/Systems/MusicEventSystem.cs index 4f12b8c300..6ec4bf1cee 100644 --- a/Systems/MusicEventSystem.cs +++ b/Systems/MusicEventSystem.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Threading; +using CalamityMod.NPCs; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -50,9 +51,10 @@ static void AddEntry(string eventId, string songName, TimeSpan length, Func DownedBossSystem.downedCalamitasClone, introSilence: TimeSpan.FromSeconds(5f)); AddEntry("MLDefeated", "Interlude2", TimeSpan.FromSeconds(160.989d), () => NPC.downedMoonlord); - AddEntry("YharonDefeated", "Interlude3", TimeSpan.FromSeconds(295.932d), () => DownedBossSystem.downedYharon, outroSilence: TimeSpan.FromSeconds(1.5f)); + AddEntry("YharonDefeated", "Interlude3", TimeSpan.FromSeconds(295.932d), () => DownedBossSystem.downedYharon, outroSilence: TimeSpan.Zero); AddEntry("DoGDefeated", "DevourerofGodsEulogy", TimeSpan.FromSeconds(203.620d), () => DownedBossSystem.downedDoG, introSilence: TimeSpan.FromSeconds(5f)); + AddEntry("ScalDefeated", "CalamitasDefeat_LongFade", TimeSpan.FromSeconds(58.689d), () => CalamityGlobalNPC.SCalAcceptance != -1); } public override void Unload() => EventCollection.Clear(); From 3660c57501fba16a608b235bd7968b0a604a3be4 Mon Sep 17 00:00:00 2001 From: apotofkoolaid <72956636+apotofkoolaid@users.noreply.github.com> Date: Wed, 29 May 2024 18:48:12 -0500 Subject: [PATCH 166/401] Interlude 1 file length trim --- Systems/MusicEventSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Systems/MusicEventSystem.cs b/Systems/MusicEventSystem.cs index 6ec4bf1cee..39e1baf3c9 100644 --- a/Systems/MusicEventSystem.cs +++ b/Systems/MusicEventSystem.cs @@ -49,7 +49,7 @@ static void AddEntry(string eventId, string songName, TimeSpan length, Func DownedBossSystem.downedCalamitasClone, introSilence: TimeSpan.FromSeconds(5f)); + AddEntry("CloneDefeated", "Interlude1", TimeSpan.FromSeconds(214.577d), () => DownedBossSystem.downedCalamitasClone, introSilence: TimeSpan.FromSeconds(5f)); AddEntry("MLDefeated", "Interlude2", TimeSpan.FromSeconds(160.989d), () => NPC.downedMoonlord); AddEntry("YharonDefeated", "Interlude3", TimeSpan.FromSeconds(295.932d), () => DownedBossSystem.downedYharon, outroSilence: TimeSpan.Zero); From fb87d3a5e17768aac07020b44b38bed58f9e42ff Mon Sep 17 00:00:00 2001 From: NycroV <83246959+NycroV@users.noreply.github.com> Date: Fri, 31 May 2024 01:07:56 -0400 Subject: [PATCH 167/401] Finalized music events + configs --- CalamityConfig.cs | 21 ++++++ .../en-US/Mods.CalamityMod.Configs.hjson | 21 ++++++ Systems/MusicEventSystem.cs | 71 +++++++++++++------ 3 files changed, 90 insertions(+), 23 deletions(-) diff --git a/CalamityConfig.cs b/CalamityConfig.cs index eedd4de7ed..2a46a809b2 100644 --- a/CalamityConfig.cs +++ b/CalamityConfig.cs @@ -175,6 +175,27 @@ internal void ClampValues(StreamingContext context) public float FlightBarPosY { get; set; } #endregion + #region Music Events + [Header("MusicEvents")] + + [BackgroundColor(192, 54, 64, 192)] + [DefaultValue(true)] + public bool Interlude1 { get; set; } + + [BackgroundColor(192, 54, 64, 192)] + [DefaultValue(true)] + public bool Interlude2 { get; set; } + + [BackgroundColor(192, 54, 64, 192)] + [DefaultValue(true)] + public bool Interlude3 { get; set; } + + [BackgroundColor(192, 54, 64, 192)] + [DefaultValue(true)] + public bool DevourerofGodsEulogy { get; set; } + + #endregion + #region General Gameplay Changes [Header("Gameplay")] diff --git a/Localization/en-US/Mods.CalamityMod.Configs.hjson b/Localization/en-US/Mods.CalamityMod.Configs.hjson index ac8eba1fec..eed2a12d65 100644 --- a/Localization/en-US/Mods.CalamityMod.Configs.hjson +++ b/Localization/en-US/Mods.CalamityMod.Configs.hjson @@ -8,6 +8,7 @@ CalamityConfig: { Revengeance: Revengeance Mode Changes UI: UI Changes BaseBoosts: Base Stat Boosts + MusicEvents: Music Events } AdrenalineMeterPosX: { @@ -130,6 +131,11 @@ CalamityConfig: { Tooltip: Adds an array of debuff icons above all bosses and minibosses. } + DevourerofGodsEulogy: { + Label: "[i:CalamityModMusic/DevourerofGodsEulogyMusicBox] Eulogy for the Ego" + Tooltip: Plays Calamity Mod OST - "Scourge of The Universe (Eulogy for The Ego)" after The Devourer of Gods has been defeated. + } + EarlyHardmodeProgressionRework: { Label: "[i:Pwnhammer] Early Hardmode Progression Rework" Tooltip: @@ -226,6 +232,21 @@ CalamityConfig: { ''' } + Interlude1: { + Label: "[i:CalamityModMusic/Interlude1MusicBox] Interlude 1" + Tooltip: Plays Calamity Mod OST - Interlude 1, "Silence before the storms", after The Calamitas Clone has been defeated. + } + + Interlude2: { + Label: "[i:CalamityModMusic/Interlude2MusicBox] Interlude 2" + Tooltip: Plays Calamity Mod OST - Interlude 2, "Storms before the catastrophes", after The Moon Lord has been defeated. + } + + Interlude3: { + Label: "[i:CalamityModMusic/Interlude3MusicBox] Interlude 3" + Tooltip: Plays Calamity Mod OST - Interlude 3, "Catastrophes before the calamity", after Yharon has been defeated. + } + MeterPosLock: { Label: "[i:GemLockTopaz] Lock Meter Positions" Tooltip: diff --git a/Systems/MusicEventSystem.cs b/Systems/MusicEventSystem.cs index 39e1baf3c9..803a27df18 100644 --- a/Systems/MusicEventSystem.cs +++ b/Systems/MusicEventSystem.cs @@ -10,7 +10,7 @@ namespace CalamityMod.Systems { - public record class MusicEventEntry(string Id, int Song, TimeSpan Length, TimeSpan IntroSilence, TimeSpan OutroSilence, Func ShouldPlay); + public record class MusicEventEntry(string Id, int Song, TimeSpan Length, TimeSpan IntroSilence, TimeSpan OutroSilence, Func ShouldPlay, Func Enabled); public class MusicEventSystem : ModSystem { @@ -25,6 +25,8 @@ public class MusicEventSystem : ModSystem public static int LastPlayedEvent { get; set; } = -1; + public static TimeSpan? OutroSilence { get; set; } = null; + // This allows skipping track fade in public static bool NoFade { get; set; } = false; @@ -43,18 +45,32 @@ public class MusicEventSystem : ModSystem public override void OnModLoad() { - static void AddEntry(string eventId, string songName, TimeSpan length, Func shouldPlay, TimeSpan? introSilence = null, TimeSpan? outroSilence = null) + static void AddEntry(string eventId, string songName, TimeSpan length, Func shouldPlay, Func enabled, TimeSpan? introSilence = null, TimeSpan? outroSilence = null) { - MusicEventEntry entry = new(eventId, CalamityMod.Instance.GetMusicFromMusicMod(songName).Value, length, introSilence ?? TimeSpan.Zero, outroSilence ?? TimeSpan.FromSeconds(3), shouldPlay); + MusicEventEntry entry = new(eventId, CalamityMod.Instance.GetMusicFromMusicMod(songName).Value, length, introSilence ?? TimeSpan.Zero, outroSilence ?? TimeSpan.Zero, shouldPlay, enabled); EventCollection.Add(entry); } - AddEntry("CloneDefeated", "Interlude1", TimeSpan.FromSeconds(214.577d), () => DownedBossSystem.downedCalamitasClone, introSilence: TimeSpan.FromSeconds(5f)); - AddEntry("MLDefeated", "Interlude2", TimeSpan.FromSeconds(160.989d), () => NPC.downedMoonlord); - AddEntry("YharonDefeated", "Interlude3", TimeSpan.FromSeconds(295.932d), () => DownedBossSystem.downedYharon, outroSilence: TimeSpan.Zero); + AddEntry("CloneDefeated", "Interlude1", TimeSpan.FromSeconds(214.577d), + () => DownedBossSystem.downedCalamitasClone, () => CalamityConfig.Instance.Interlude1); + + AddEntry("MLDefeated", "Interlude2", TimeSpan.FromSeconds(191.912d), () => NPC.downedMoonlord, + () => CalamityConfig.Instance.Interlude2, outroSilence: TimeSpan.FromSeconds(1f)); + + // Alternative Interlude 2 -> AddEntry("MLDefeated", "Interlude2_CutIntro", TimeSpan.FromSeconds(160.989d), + // () => NPC.downedMoonlord, () => CalamityConfig.Instance.Interlude2, + // outroSilence: TimeSpan.FromSeconds(1f)); + + AddEntry("YharonDefeated", "Interlude3", TimeSpan.FromSeconds(295.932d), + () => DownedBossSystem.downedYharon, () => CalamityConfig.Instance.Interlude3); - AddEntry("DoGDefeated", "DevourerofGodsEulogy", TimeSpan.FromSeconds(203.620d), () => DownedBossSystem.downedDoG, introSilence: TimeSpan.FromSeconds(5f)); - AddEntry("ScalDefeated", "CalamitasDefeat_LongFade", TimeSpan.FromSeconds(58.689d), () => CalamityGlobalNPC.SCalAcceptance != -1); + AddEntry("DoGDefeated", "DevourerofGodsEulogy", TimeSpan.FromSeconds(203.620d), + () => DownedBossSystem.downedDoG, () => CalamityConfig.Instance.DevourerofGodsEulogy, + introSilence: TimeSpan.FromSeconds(7.5f)); + + // Acceptance is NOT toggleable in the config + AddEntry("ScalDefeated", "CalamitasDefeat_LongFade", TimeSpan.FromSeconds(58.689d), + () => CalamityGlobalNPC.SCalAcceptance != -1, () => true); } public override void Unload() => EventCollection.Clear(); @@ -84,7 +100,7 @@ public override void PostUpdateTime() if (TrackEnd is not null) { // `silence` is the time after a track ends before music goes back to normal - TimeSpan silence = TimeSpan.FromSeconds(3); + TimeSpan silence = OutroSilence.Value; TimeSpan postTrack = DateTime.Now - TrackEnd.Value; // Play silence for the time specified @@ -98,6 +114,7 @@ public override void PostUpdateTime() { LastPlayedEvent = -1; TrackEnd = null; + OutroSilence = null; } return; @@ -112,21 +129,28 @@ public override void PostUpdateTime() // Make sure the event hasn't already played and SHOULD play if (!PlayedEvents.Contains(musicEvent.Id) && musicEvent.ShouldPlay()) { - // Assign the current event and start time - CurrentEvent = musicEvent; - TrackStart = DateTime.Now + musicEvent.IntroSilence; + // Even if an event isn't marked as enabled, it should be counted + // as "played" so it isn't played when the player doesn't expect it PlayedEvents.Add(musicEvent.Id); - - // On clients, use a background thread to make sure the track always plays for exactly - // the specified length, regardless of if the game gets minimized, lags, or time becomes - // detangled from a consistent 60fps in any other way - if (!Main.dedServ) + + // Events are always enabled on the server + if (Main.dedServ || musicEvent.Enabled()) { - EventTrackerThread = new(WatchMusicEvent); - EventTrackerThread.Start(); + // Assign the current event and start time + CurrentEvent = musicEvent; + TrackStart = DateTime.Now + musicEvent.IntroSilence; + + // On clients, use a background thread to make sure the track always plays for exactly + // the specified length, regardless of if the game gets minimized, lags, or time becomes + // detangled from a consistent 60fps in any other way + if (!Main.dedServ) + { + EventTrackerThread = new(WatchMusicEvent); + EventTrackerThread.Start(); + } + + break; } - - break; } } } @@ -159,6 +183,7 @@ public override void PostUpdateTime() TrackEnd = DateTime.Now; LastPlayedEvent = CurrentEvent.Song; + OutroSilence = CurrentEvent.OutroSilence; TrackStart = null; CurrentEvent = null; @@ -176,14 +201,14 @@ public static void WatchMusicEvent() while (CurrentEvent is not null) { - bool musicPaused = Main.instance.IsActive; + bool musicPaused = !Main.instance.IsActive; if (musicPaused && !minimized.HasValue) minimized = DateTime.Now; else if (!musicPaused && minimized.HasValue) { - TrackStart = TrackStart.Value + (DateTime.Now - minimized.Value); + TrackStart += DateTime.Now - minimized.Value; minimized = null; } } From 778c1d0e992d4140a031e58cbaf16cbe1d8534e0 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Fri, 31 May 2024 14:15:51 -0400 Subject: [PATCH 168/401] minor localization fixes to config --- Localization/en-US/Mods.CalamityMod.Configs.hjson | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Localization/en-US/Mods.CalamityMod.Configs.hjson b/Localization/en-US/Mods.CalamityMod.Configs.hjson index eed2a12d65..44503237ef 100644 --- a/Localization/en-US/Mods.CalamityMod.Configs.hjson +++ b/Localization/en-US/Mods.CalamityMod.Configs.hjson @@ -133,7 +133,7 @@ CalamityConfig: { DevourerofGodsEulogy: { Label: "[i:CalamityModMusic/DevourerofGodsEulogyMusicBox] Eulogy for the Ego" - Tooltip: Plays Calamity Mod OST - "Scourge of The Universe (Eulogy for The Ego)" after The Devourer of Gods has been defeated. + Tooltip: Plays Calamity Mod OST - "Scourge of The Universe (Eulogy for The Ego)", after The Devourer of Gods has been defeated. } EarlyHardmodeProgressionRework: { @@ -234,12 +234,12 @@ CalamityConfig: { Interlude1: { Label: "[i:CalamityModMusic/Interlude1MusicBox] Interlude 1" - Tooltip: Plays Calamity Mod OST - Interlude 1, "Silence before the storms", after The Calamitas Clone has been defeated. + Tooltip: Plays Calamity Mod OST - Interlude 1, "Silence before the storms", after Calamitas Clone has been defeated. } Interlude2: { Label: "[i:CalamityModMusic/Interlude2MusicBox] Interlude 2" - Tooltip: Plays Calamity Mod OST - Interlude 2, "Storms before the catastrophes", after The Moon Lord has been defeated. + Tooltip: Plays Calamity Mod OST - Interlude 2, "Storms before the catastrophes", after Moon Lord has been defeated. } Interlude3: { From fbdf94afc4b1a1a3032e34cdbd96f21c01b4f114 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Fri, 31 May 2024 13:59:57 -0500 Subject: [PATCH 169/401] Crabulon gets the same treatment. --- NPCs/Crabulon/Crabulon.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/NPCs/Crabulon/Crabulon.cs b/NPCs/Crabulon/Crabulon.cs index c22d47736d..b9e96bf899 100644 --- a/NPCs/Crabulon/Crabulon.cs +++ b/NPCs/Crabulon/Crabulon.cs @@ -127,6 +127,7 @@ public override void AI() bool death = CalamityWorld.death || bossRush; bool revenge = CalamityWorld.revenge || bossRush; bool expertMode = Main.expertMode || bossRush; + bool masterMode = Main.masterMode || bossRush; NPC.spriteDirection = NPC.direction; @@ -258,6 +259,10 @@ public override void AI() NPC.ai[1] += 1f; if (phase3) NPC.ai[1] += 2f; + if (NPC.justHit) + NPC.ai[1] += masterMode ? 7f : expertMode ? 5f : 3f; + if (NPC.Distance(player.Center) < 240f) + NPC.ai[1] += masterMode ? 4f : expertMode ? 2f : 1f; float idleTime = death ? 30f : expertMode ? 60f : 120f; if (NPC.ai[1] >= idleTime) @@ -351,6 +356,9 @@ public override void AI() } NPC.ai[1] += 1f; + if (NPC.Distance(player.Center) < 160f) + NPC.ai[1] += masterMode ? 4f : expertMode ? 2f : 1f; + float stompPhaseGateValue = (revenge ? 150f : expertMode ? 240f : 360f) - (death ? 120f * (1f - lifeRatio) : 0f); if (NPC.ai[1] >= stompPhaseGateValue) { From a585cf5f75c37d5cda9bc0116ec52198caeeb188 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Fri, 31 May 2024 14:44:54 -0400 Subject: [PATCH 170/401] Cirrus now sells the Interlude Music Boxes. --- CalamityMod.cs | 6 ++++-- NPCs/TownNPCs/FAP.cs | 19 +++++++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/CalamityMod.cs b/CalamityMod.cs index 62b15634c1..7ac3568177 100644 --- a/CalamityMod.cs +++ b/CalamityMod.cs @@ -132,8 +132,10 @@ public class CalamityMod : Mod internal static CalamityMod Instance; // TODO -- Mod references should be contained in a ModSystem (example name "ModLoadedChecker") - internal Mod musicMod = null; // This is Calamity's official music mod, CalamityModMusic - internal bool MusicAvailable => !(musicMod is null); + + // This is Calamity's official music mod, CalamityModMusic. It is now a hard dependency. + internal Mod musicMod = null; + internal bool MusicAvailable => musicMod is not null; // Please keep this in alphabetical order so it's easy to read internal Mod ancientsAwakened = null; diff --git a/NPCs/TownNPCs/FAP.cs b/NPCs/TownNPCs/FAP.cs index 90bf0ba3b2..b46e82b6f0 100644 --- a/NPCs/TownNPCs/FAP.cs +++ b/NPCs/TownNPCs/FAP.cs @@ -885,11 +885,14 @@ public override void OnChatButtonClicked(bool firstButton, ref string shopName) public override void AddShops() { - Condition potionSells = CalamityConditions.PotionSellingConfig; - Condition downedAureus = CalamityConditions.DownedAstrumAureus; + Mod musicMod = CalamityMod.Instance.musicMod; + ModItem interlude1Box = musicMod.Find("Interlude1MusicBox"); + ModItem interlude2Box = musicMod.Find("Interlude2MusicBox"); + ModItem interlude3Box = musicMod.Find("Interlude3MusicBox"); + ModItem eulogyBox = musicMod.Find("DevourerofGodsEulogyMusicBox"); NPCShop shop = new(Type); - shop.AddWithCustomValue(ItemID.LovePotion, Item.buyPrice(silver: 25), potionSells, Condition.HappyEnough) + shop.AddWithCustomValue(ItemID.LovePotion, Item.buyPrice(silver: 25), CalamityConditions.PotionSellingConfig, Condition.HappyEnough) .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(silver: 30)) .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 1)) .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 2)) @@ -905,9 +908,9 @@ public override void AddShops() .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 8), Condition.DownedPlantera) .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 8), Condition.DownedPlantera) .AddWithCustomValue(ItemID.EmpressButterfly, Item.buyPrice(gold: 10), Condition.DownedPlantera) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 3), downedAureus) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 4), downedAureus, Condition.BloodMoon) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 6), downedAureus, Condition.TimeNight) + .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 3), CalamityConditions.DownedAstrumAureus) + .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 4), CalamityConditions.DownedAstrumAureus, Condition.BloodMoon) + .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 6), CalamityConditions.DownedAstrumAureus, Condition.TimeNight) .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 2), Condition.DownedGolem) .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 8), Condition.DownedGolem) .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 8), Condition.DownedGolem) @@ -921,6 +924,10 @@ public override void AddShops() .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 50)) .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 50)) .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(1)) + .AddWithCustomValue(interlude1Box.Type, Item.buyPrice(gold: 10), CalamityConditions.DownedCalamitasClone) + .AddWithCustomValue(interlude2Box.Type, Item.buyPrice(gold: 10), Condition.DownedMoonLord) + .AddWithCustomValue(interlude3Box.Type, Item.buyPrice(gold: 10), CalamityConditions.DownedYharon) + .AddWithCustomValue(eulogyBox.Type, Item.buyPrice(gold: 10), CalamityConditions.DownedDevourerOfGods) .AddWithCustomValue(ItemID.UnicornHorn, Item.buyPrice(0, 2, 50), Condition.HappyEnough, Condition.InHallow) .AddWithCustomValue(ItemID.Milkshake, Item.buyPrice(gold: 5), Condition.HappyEnough, Condition.InHallow, Condition.NpcIsPresent(NPCID.Stylist)) .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 25), Condition.HappyEnough, Condition.NpcIsPresent(NPCID.Stylist), Condition.NpcIsPresent(NPCID.BestiaryGirl)) From 0a3090ea9eabe3cc7de1ab01985a989df6827567 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Fri, 31 May 2024 14:49:19 -0400 Subject: [PATCH 171/401] Disabled Gimme Swag Plushie Campaign message. Removed unused Music Mod message. --- CalPlayer/CalamityPlayer.cs | 9 +-------- CalPlayer/CalamityPlayerMiscEffects.cs | 3 --- Localization/en-US/Mods.CalamityMod.Misc.hjson | 5 ----- 3 files changed, 1 insertion(+), 16 deletions(-) diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index c299cd9013..784402d02f 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -4878,15 +4878,8 @@ public override void OnEnterWorld() if (CalamityConfig.Instance.SpeedrunTimer) CalamityMod.SpeedrunTimer.Restart(); - // - // 04JAN2024: Ozzatron: Added a temporary message for the Gimme Swag plushie campaign. - // This message should not exist indefinitely. It is being pushed as a silent public update just for itself. - // As this message always displays and is not configurable, the previous rules about startup messages have been replaced with always-true. - // - // Set a random delay between 12 and 20 seconds. When this delay hits zero, startup messages display - bool plushieMessage = true; - if (plushieMessage || CalamityConfig.Instance.WikiStatusMessage) + if (CalamityConfig.Instance.WikiStatusMessage) { startMessageDisplayDelay = Main.rand.Next(CalamityUtils.SecondsToFrames(12), CalamityUtils.SecondsToFrames(20) + 1); } diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index 822820f0a3..5f2adbd3b7 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -4170,9 +4170,6 @@ private void HandleTextChatMessages() CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.WikiStatus1"); CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.WikiStatus2"); } - - // 04JAN2024: Ozzatron: Plushie message always appears. - CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.GimmeSwagPlushieCampaign"); } --startMessageDisplayDelay; diff --git a/Localization/en-US/Mods.CalamityMod.Misc.hjson b/Localization/en-US/Mods.CalamityMod.Misc.hjson index 9a650f9ea6..73956e7c46 100644 --- a/Localization/en-US/Mods.CalamityMod.Misc.hjson +++ b/Localization/en-US/Mods.CalamityMod.Misc.hjson @@ -21,12 +21,7 @@ RecipeGroup: { // Status WikiStatus1: "[i:Book] [c/EE4939:Note: The Fandom wiki is no longer supported by Calamity.] [i:Book]" WikiStatus2: "[i:Book] [c/EE4939:Check out the Official Calamity Mod Wiki at ][c/3989FF:calamitymod.wiki.gg][c/EE4939:!] [i:Book]" -MusicModReminder: "[i:MusicBoxMartians] [c/71DFF5:Remember to also install the Calamity Music Mod to experience our soundtrack!] [i:MusicBoxMartians]" -GimmeSwagPlushieCampaign: - ''' - [i:GreenPresent] [c/3BE022:NOW AVAILABLE! Supreme Calamitas Plushie!] [c/3989FF:calamitymod.com/plush] [i:GreenPresent] - ''' // Recipe Conditions Tier1ArsenalRecipeCondition: View an unencrypted schematic from the lab near the Sunken Sea Tier2ArsenalRecipeCondition: Decrypt a schematic from the lab in the large planetoid in the sky From 8ffc6d9f8a36bc1efb5ee22deaa792465bf954f3 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Fri, 31 May 2024 16:54:57 -0500 Subject: [PATCH 172/401] Crab fix and targeting change. --- NPCs/Crabulon/CrabShroom.cs | 5 ++++- NPCs/Crabulon/Crabulon.cs | 9 +-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/NPCs/Crabulon/CrabShroom.cs b/NPCs/Crabulon/CrabShroom.cs index c3dda3d521..af96c9a5b1 100644 --- a/NPCs/Crabulon/CrabShroom.cs +++ b/NPCs/Crabulon/CrabShroom.cs @@ -76,7 +76,10 @@ public override void AI() float xVelocityLimit = BossRushEvent.BossRushActive ? 12f : death ? 8f : revenge ? 6f : 5f; float yVelocityLimit = (CalamityWorld.LegendaryMode && CalamityWorld.revenge) ? 0.25f : death ? 0.75f : revenge ? 0.9f : 1f; - NPC.TargetClosest(); + // Get a target + if (NPC.target < 0 || NPC.target == Main.maxPlayers || Main.player[NPC.target].dead || !Main.player[NPC.target].active) + NPC.TargetClosest(); + Player player = Main.player[NPC.target]; NPC.velocity.Y += 0.02f; diff --git a/NPCs/Crabulon/Crabulon.cs b/NPCs/Crabulon/Crabulon.cs index b9e96bf899..31653519f3 100644 --- a/NPCs/Crabulon/Crabulon.cs +++ b/NPCs/Crabulon/Crabulon.cs @@ -142,10 +142,6 @@ public override void AI() if (NPC.target < 0 || NPC.target == Main.maxPlayers || Main.player[NPC.target].dead || !Main.player[NPC.target].active) NPC.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[NPC.target].Center, NPC.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - NPC.TargetClosest(); - Player player = Main.player[NPC.target]; if (!player.active || player.dead) { @@ -261,7 +257,7 @@ public override void AI() NPC.ai[1] += 2f; if (NPC.justHit) NPC.ai[1] += masterMode ? 7f : expertMode ? 5f : 3f; - if (NPC.Distance(player.Center) < 240f) + if (NPC.Distance(player.Center) < 160f) NPC.ai[1] += masterMode ? 4f : expertMode ? 2f : 1f; float idleTime = death ? 30f : expertMode ? 60f : 120f; @@ -362,7 +358,6 @@ public override void AI() float stompPhaseGateValue = (revenge ? 150f : expertMode ? 240f : 360f) - (death ? 120f * (1f - lifeRatio) : 0f); if (NPC.ai[1] >= stompPhaseGateValue) { - NPC.TargetClosest(); NPC.noGravity = false; NPC.noTileCollide = false; NPC.ai[0] = 2f; @@ -513,8 +508,6 @@ public override void AI() } } - NPC.TargetClosest(); - NPC.ai[2] += 1f; if (NPC.ai[2] >= (phase2 ? 4f : 3f)) { From e776e6d5d5aac2c4dd994ef545c02c56fda9720e Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Fri, 31 May 2024 18:01:03 -0500 Subject: [PATCH 173/401] Updated Cryogen targeting. --- NPCs/Cryogen/Cryogen.cs | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/NPCs/Cryogen/Cryogen.cs b/NPCs/Cryogen/Cryogen.cs index a5cb29f29e..36f0b6388c 100644 --- a/NPCs/Cryogen/Cryogen.cs +++ b/NPCs/Cryogen/Cryogen.cs @@ -180,10 +180,6 @@ public override void AI() if (NPC.target < 0 || NPC.target == Main.maxPlayers || Main.player[NPC.target].dead || !Main.player[NPC.target].active) NPC.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[NPC.target].Center, NPC.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - NPC.TargetClosest(); - Player player = Main.player[NPC.target]; bool bossRush = BossRushEvent.BossRushActive; @@ -381,7 +377,6 @@ public override void AI() if (NPC.localAI[0] >= 120f) { NPC.localAI[0] = 0f; - NPC.TargetClosest(); if (Collision.CanHit(NPC.position, NPC.width, NPC.height, player.position, player.width, player.height)) { SoundEngine.PlaySound(Main.zenithWorld ? SoundID.NPCHit41 : HitSound, NPC.Center); @@ -449,7 +444,6 @@ public override void AI() if (NPC.localAI[0] >= 120f) { NPC.localAI[0] = 0f; - NPC.TargetClosest(); if (Collision.CanHit(NPC.position, NPC.width, NPC.height, player.position, player.width, player.height)) { SoundEngine.PlaySound(Main.zenithWorld ? SoundID.NPCHit41 : HitSound, NPC.Center); @@ -639,7 +633,6 @@ public override void AI() if (NPC.localAI[0] >= 120f) { NPC.localAI[0] = 0f; - NPC.TargetClosest(); if (Collision.CanHit(NPC.position, NPC.width, NPC.height, player.position, player.width, player.height)) { SoundEngine.PlaySound(Main.zenithWorld ? SoundID.NPCHit41 : HitSound, NPC.Center); @@ -759,11 +752,10 @@ public override void AI() NPC.ai[1] -= 1f; if (NPC.ai[1] == chargeGateValue) { - NPC.TargetClosest(); - calamityGlobalNPC.newAI[1] += 1f; if (calamityGlobalNPC.newAI[1] > 1f) { + NPC.TargetClosest(); NPC.ai[1] = 0f; NPC.localAI[0] = 0f; calamityGlobalNPC.newAI[1] = 0f; @@ -855,16 +847,13 @@ public override void AI() NPC.localAI[2] += 1f; if (NPC.localAI[2] >= 180f) { - NPC.TargetClosest(); NPC.localAI[2] = 0f; int attackTimer = 0; - int playerTileX; - int playerTileY; - while (true) + int playerTileX = (int)player.Center.X / 16; + int playerTileY = (int)player.Center.Y / 16; + while (attackTimer <= 100) { attackTimer++; - playerTileX = (int)player.Center.X / 16; - playerTileY = (int)player.Center.Y / 16; int min = 16; int max = 20; @@ -882,15 +871,13 @@ public override void AI() if (!WorldGen.SolidTile(playerTileX, playerTileY) && Collision.CanHit(new Vector2(playerTileX * 16, playerTileY * 16), 1, 1, player.position, player.width, player.height)) break; - if (attackTimer > 100) - goto Block; + playerTileX = (int)player.Center.X / 16; + playerTileY = (int)player.Center.Y / 16; } NPC.ai[1] = 1f; teleportLocationX = playerTileX; calamityGlobalNPC.newAI[2] = playerTileY; NPC.netUpdate = true; -Block: - ; } } } @@ -951,6 +938,7 @@ public override void AI() } } + NPC.TargetClosest(); NPC.ai[1] = 2f; NPC.netUpdate = true; } @@ -1046,7 +1034,6 @@ public override void AI() if (NPC.ai[1] <= 0f) // Set the next charge, or switch back to floating above the player { NPC.ai[3] += 1f; - NPC.TargetClosest(); if (NPC.ai[3] > 2f) { NPC.ai[0] = 5f; From 9a5906e74a2c124021a6dc4caed0ce3142ec935a Mon Sep 17 00:00:00 2001 From: Xyk Date: Fri, 31 May 2024 15:32:22 -0700 Subject: [PATCH 174/401] Fixed leviathan Ambergris knockback --- Projectiles/Typeless/LeviAmberDash.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Projectiles/Typeless/LeviAmberDash.cs b/Projectiles/Typeless/LeviAmberDash.cs index 7e9848ebc4..627a1b1aad 100644 --- a/Projectiles/Typeless/LeviAmberDash.cs +++ b/Projectiles/Typeless/LeviAmberDash.cs @@ -1,4 +1,5 @@ using System; +using CalamityMod.CalPlayer; using CalamityMod.Particles; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; @@ -34,11 +35,13 @@ public override void SetDefaults() public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { - if (!target.boss && target.IsAnEnemy(true, true)) + bool isAPillar = target.type == NPCID.LunarTowerSolar || target.type == NPCID.LunarTowerVortex || target.type == NPCID.LunarTowerNebula || target.type == NPCID.LunarTowerStardust; + if (!isAPillar && !target.boss && target.IsAnEnemy(true, true) && !CalamityPlayer.areThereAnyDamnBosses && target.CanBeChasedBy(Projectile, false)) { target.velocity.Y += -1.8f; target.velocity.X += 4.2f * Owner.direction; } + target.AddBuff(BuffID.Wet, 300); target.AddBuff(ModContent.BuffType(), 180); SoundEngine.PlaySound(SoundID.Item85 with { Volume = 0.4f, PitchVariance = 0.4f }, Projectile.Center); From 382b874baca85f18a8caeac301c232aa4be10aed Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Fri, 31 May 2024 20:05:39 -0500 Subject: [PATCH 175/401] Aquatic Scourge, Brimstone Elemental, and Cal Clone targeting changes. --- NPCs/CalClone/SoulSeeker.cs | 6 ++--- .../CalamityBossAIs/AquaticScourgeAI.cs | 4 ---- .../CalamityBossAIs/BrimstoneElementalAI.cs | 4 ---- .../CalamityBossAIs/CalamitasCloneAI.cs | 22 +------------------ 4 files changed, 3 insertions(+), 33 deletions(-) diff --git a/NPCs/CalClone/SoulSeeker.cs b/NPCs/CalClone/SoulSeeker.cs index 2731b95647..adbefe7503 100644 --- a/NPCs/CalClone/SoulSeeker.cs +++ b/NPCs/CalClone/SoulSeeker.cs @@ -108,10 +108,8 @@ public override bool PreAI() start = false; } - NPC.TargetClosest(); - float projectileSpeed = 9f; - Vector2 velocity = Main.player[NPC.target].Center - NPC.Center; + Vector2 velocity = Main.player[parent.target].Center - NPC.Center; velocity.Normalize(); velocity *= projectileSpeed; NPC.rotation = velocity.ToRotation() + MathHelper.Pi; @@ -126,7 +124,7 @@ public override bool PreAI() int type = ModContent.ProjectileType(); int damage = NPC.GetProjectileDamage(type); - Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center, velocity, type, damage, 1f, NPC.target, 1f, 0f, projectileSpeed * 2f); + Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center, velocity, type, damage, 1f, parent.target, 1f, 0f, projectileSpeed * 2f); } timer = 0; } diff --git a/NPCs/CalamityAIs/CalamityBossAIs/AquaticScourgeAI.cs b/NPCs/CalamityAIs/CalamityBossAIs/AquaticScourgeAI.cs index b1086e7143..2ddd4e677e 100644 --- a/NPCs/CalamityAIs/CalamityBossAIs/AquaticScourgeAI.cs +++ b/NPCs/CalamityAIs/CalamityBossAIs/AquaticScourgeAI.cs @@ -87,10 +87,6 @@ public static void VanillaAquaticScourgeAI(NPC npc, Mod mod, bool head) if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - Player player = Main.player[npc.target]; bool notOcean = player.position.Y < 300f || diff --git a/NPCs/CalamityAIs/CalamityBossAIs/BrimstoneElementalAI.cs b/NPCs/CalamityAIs/CalamityBossAIs/BrimstoneElementalAI.cs index 89ff485601..6cc79b9e1b 100644 --- a/NPCs/CalamityAIs/CalamityBossAIs/BrimstoneElementalAI.cs +++ b/NPCs/CalamityAIs/CalamityBossAIs/BrimstoneElementalAI.cs @@ -46,10 +46,6 @@ public static void VanillaBrimstoneElementalAI(NPC npc, Mod mod) if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - Player player = Main.player[npc.target]; bool despawnDistance = Vector2.Distance(player.Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance350Tiles; diff --git a/NPCs/CalamityAIs/CalamityBossAIs/CalamitasCloneAI.cs b/NPCs/CalamityAIs/CalamityBossAIs/CalamitasCloneAI.cs index 2551962926..885505f155 100644 --- a/NPCs/CalamityAIs/CalamityBossAIs/CalamitasCloneAI.cs +++ b/NPCs/CalamityAIs/CalamityBossAIs/CalamitasCloneAI.cs @@ -185,10 +185,6 @@ void SpawnDust() if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - // Target variable Player player = Main.player[npc.target]; @@ -556,7 +552,6 @@ void SpawnDust() if (death) npc.localAI[0] = 1f; - npc.TargetClosest(); npc.netUpdate = true; } @@ -645,7 +640,6 @@ void SpawnDust() if (death) npc.localAI[0] = 1f; - npc.TargetClosest(); npc.netUpdate = true; } } @@ -706,11 +700,11 @@ void SpawnDust() npc.ai[2] = 0f; npc.rotation = rotation; - npc.TargetClosest(); npc.netUpdate = true; if (npc.ai[3] >= 2f) { + npc.TargetClosest(); npc.ai[1] = 0f; npc.ai[3] = 0f; return; @@ -727,8 +721,6 @@ void SpawnDust() npc.ai[2] += 1f; if (npc.ai[2] >= (phase4 ? 15f : 30f)) { - npc.TargetClosest(); - npc.ai[1] = 2f; npc.ai[2] = 0f; if (death) @@ -768,10 +760,6 @@ public static void VanillaCataclysmAI(NPC npc, Mod mod) if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - Player player = Main.player[npc.target]; float enrageScale = bossRush ? 1f : 0f; @@ -914,7 +902,6 @@ public static void VanillaCataclysmAI(NPC npc, Mod mod) npc.ai[2] += 1f; if (npc.ai[2] >= (240f - (death ? 120f * (1f - lifeRatio) : 0f))) { - npc.TargetClosest(); npc.ai[1] = 1f; npc.ai[2] = 0f; npc.target = 255; @@ -1047,7 +1034,6 @@ public static void VanillaCataclysmAI(NPC npc, Mod mod) npc.ai[2] = 0f; npc.target = 255; npc.rotation = calCloneBroRotation; - npc.TargetClosest(); if (npc.ai[3] >= 3f) { npc.ai[1] = 0f; @@ -1089,10 +1075,6 @@ public static void VanillaCatastropheAI(NPC npc, Mod mod) if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) npc.TargetClosest(); - // Despawn safety, make sure to target another player if the current player target is too far away - if (Vector2.Distance(Main.player[npc.target].Center, npc.Center) > CalamityGlobalNPC.CatchUpDistance200Tiles) - npc.TargetClosest(); - Player player = Main.player[npc.target]; float enrageScale = bossRush ? 1f : 0f; @@ -1235,7 +1217,6 @@ public static void VanillaCatastropheAI(NPC npc, Mod mod) npc.ai[2] += 1f; if (npc.ai[2] >= (180f - (death ? 90f * (1f - lifeRatio) : 0f))) { - npc.TargetClosest(); npc.ai[1] = 1f; npc.ai[2] = 0f; npc.target = 255; @@ -1366,7 +1347,6 @@ public static void VanillaCatastropheAI(NPC npc, Mod mod) { npc.ai[3] += 1f; npc.ai[2] = 0f; - npc.TargetClosest(); npc.rotation = calCloneBroRotation; if (npc.ai[3] >= 4f) { From 1ac2092af4825bb36db4a3e75fb7266e95323617 Mon Sep 17 00:00:00 2001 From: apotofkoolaid <72956636+apotofkoolaid@users.noreply.github.com> Date: Fri, 31 May 2024 18:16:30 -0500 Subject: [PATCH 176/401] Safer music box locating for Cirrus' shop This previously caused loading errors for me even though the strong reference to the music mod should've prevented that --- NPCs/TownNPCs/FAP.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/NPCs/TownNPCs/FAP.cs b/NPCs/TownNPCs/FAP.cs index b46e82b6f0..eef4a0d498 100644 --- a/NPCs/TownNPCs/FAP.cs +++ b/NPCs/TownNPCs/FAP.cs @@ -886,10 +886,10 @@ public override void OnChatButtonClicked(bool firstButton, ref string shopName) public override void AddShops() { Mod musicMod = CalamityMod.Instance.musicMod; - ModItem interlude1Box = musicMod.Find("Interlude1MusicBox"); - ModItem interlude2Box = musicMod.Find("Interlude2MusicBox"); - ModItem interlude3Box = musicMod.Find("Interlude3MusicBox"); - ModItem eulogyBox = musicMod.Find("DevourerofGodsEulogyMusicBox"); + musicMod.TryFind("Interlude1MusicBox", out ModItem interlude1Box); + musicMod.TryFind("Interlude2MusicBox", out ModItem interlude2Box); + musicMod.TryFind("Interlude3MusicBox", out ModItem interlude3Box); + musicMod.TryFind("DevourerofGodsEulogyMusicBox", out ModItem eulogyBox); NPCShop shop = new(Type); shop.AddWithCustomValue(ItemID.LovePotion, Item.buyPrice(silver: 25), CalamityConditions.PotionSellingConfig, Condition.HappyEnough) From 524af5189253249baa04aa95f81d4a7598fca821 Mon Sep 17 00:00:00 2001 From: serpensta <63422808+serpensta@users.noreply.github.com> Date: Fri, 31 May 2024 21:52:36 -0400 Subject: [PATCH 177/401] Slab Crabs cannot spawn (#42) Slab Crab spawn uses `OceanMonster` condition (which makes it impossible to spawn) when it should use `CaveJellyfish` condition like the other Abyssal NPCs. --- NPCs/Abyss/SlabCrab.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NPCs/Abyss/SlabCrab.cs b/NPCs/Abyss/SlabCrab.cs index 0eca2a663d..14a0dbf9f7 100644 --- a/NPCs/Abyss/SlabCrab.cs +++ b/NPCs/Abyss/SlabCrab.cs @@ -309,7 +309,7 @@ public override float SpawnChance(NPCSpawnInfo spawnInfo) { if (spawnInfo.Player.Calamity().ZoneAbyssLayer1 && spawnInfo.Water) { - return SpawnCondition.OceanMonster.Chance; + return SpawnCondition.CaveJellyfish.Chance; } return 0f; } From 95bcc714a7c46ebabc13255c5d96d7cd2be08218 Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Sat, 1 Jun 2024 19:06:11 +0700 Subject: [PATCH 178/401] 612 actually shows up on Respiteblock --- Items/CalamityGlobalItemTooltip.cs | 4 ++++ Items/Weapons/Melee/Respiteblock.cs | 21 ++++++------------- .../en-US/Mods.CalamityMod.Misc.hjson | 1 - 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/Items/CalamityGlobalItemTooltip.cs b/Items/CalamityGlobalItemTooltip.cs index efa32183fa..9830d5d689 100644 --- a/Items/CalamityGlobalItemTooltip.cs +++ b/Items/CalamityGlobalItemTooltip.cs @@ -262,6 +262,10 @@ void AddTooltip(string text) if (item.type == ModContent.ItemType()) EditTooltipByName("Damage", (line) => line.Text = LiliesOfFinality.TheNumber + " summon damage"); + // Apparently 612 is a homestuck reference + if (item.type == ModContent.ItemType()) + EditTooltipByName("AxePower", (line) => line.Text = line.Text.Replace("610%", "612%")); + // Master Mode items also drop in Revengeance // Only affects vanilla and Calamity items if (item.master && (item.type < ItemID.Count || item.ModItem?.Mod is CalamityMod)) diff --git a/Items/Weapons/Melee/Respiteblock.cs b/Items/Weapons/Melee/Respiteblock.cs index 673badb103..e3b533fcfb 100644 --- a/Items/Weapons/Melee/Respiteblock.cs +++ b/Items/Weapons/Melee/Respiteblock.cs @@ -1,12 +1,6 @@ -using CalamityMod.Items.Accessories; -using CalamityMod.Items.Materials; -using CalamityMod.Items.Weapons.Magic; +using CalamityMod.Items.Materials; using CalamityMod.Projectiles.Melee; -using CalamityMod.Rarities; -using CalamityMod.Tiles.Furniture.CraftingStations; -using Microsoft.Xna.Framework; using Terraria; -using Terraria.DataStructures; using Terraria.ID; using Terraria.ModLoader; @@ -27,8 +21,10 @@ public override void SetDefaults() // In-game, the displayed axe power is 5x the value set here. // This corrects for trees having 500% hardness internally. // So that the axe power in the code looks like the axe power you see on screen, divide by 5. - Item.axe = 612 / 5; // Apparently 612 is a homestuck reference + Item.axe = 610 / 5; // The axe power is entirely for show. It instantly one shots trees. + // ***Axe Power is an integer which increments in 5s. So any number not divisible by 5 is impossible without tooltip modifications. + // See CalamityGlobalItemTooltip for axe power tooltip edit Item.DamageType = DamageClass.Melee; Item.noMelee = true; @@ -39,17 +35,12 @@ public override void SetDefaults() Item.shoot = ModContent.ProjectileType(); Item.shootSpeed = 1f; - Item.rare = ModContent.RarityType(); - Item.value = CalamityGlobalItem.RarityVioletBuyPrice; + Item.rare = ItemRarityID.Red; + Item.value = CalamityGlobalItem.RarityRedBuyPrice; Item.Calamity().donorItem = true; } public override bool CanUseItem(Player player) => player.ownedProjectileCounts[Item.shoot] <= 0; - public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) - { - Projectile.NewProjectile(source, position, velocity, type, damage, knockback, player.whoAmI, 0f, 0f); - return false; - } public override void AddRecipes() { CreateRecipe(). diff --git a/Localization/en-US/Mods.CalamityMod.Misc.hjson b/Localization/en-US/Mods.CalamityMod.Misc.hjson index 73956e7c46..4a836bc149 100644 --- a/Localization/en-US/Mods.CalamityMod.Misc.hjson +++ b/Localization/en-US/Mods.CalamityMod.Misc.hjson @@ -21,7 +21,6 @@ RecipeGroup: { // Status WikiStatus1: "[i:Book] [c/EE4939:Note: The Fandom wiki is no longer supported by Calamity.] [i:Book]" WikiStatus2: "[i:Book] [c/EE4939:Check out the Official Calamity Mod Wiki at ][c/3989FF:calamitymod.wiki.gg][c/EE4939:!] [i:Book]" - // Recipe Conditions Tier1ArsenalRecipeCondition: View an unencrypted schematic from the lab near the Sunken Sea Tier2ArsenalRecipeCondition: Decrypt a schematic from the lab in the large planetoid in the sky From 4825a2af20457782085af047ed7ba4b23fb6b490 Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Sat, 1 Jun 2024 19:29:18 +0700 Subject: [PATCH 179/401] respiteblock balancing... as a tool --- Items/Weapons/Melee/Respiteblock.cs | 2 +- Projectiles/Melee/RespiteblockHoldout.cs | 9 +++++---- compile_temp/CalamityModMusic.dll | Bin 0 -> 28160 bytes 3 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 compile_temp/CalamityModMusic.dll diff --git a/Items/Weapons/Melee/Respiteblock.cs b/Items/Weapons/Melee/Respiteblock.cs index e3b533fcfb..4cf32c3bc9 100644 --- a/Items/Weapons/Melee/Respiteblock.cs +++ b/Items/Weapons/Melee/Respiteblock.cs @@ -16,7 +16,7 @@ public override void SetDefaults() Item.height = 40; Item.damage = 70; Item.knockBack = 9f; - Item.useTime = 4; + Item.useTime = 15; Item.useAnimation = 20; // In-game, the displayed axe power is 5x the value set here. // This corrects for trees having 500% hardness internally. diff --git a/Projectiles/Melee/RespiteblockHoldout.cs b/Projectiles/Melee/RespiteblockHoldout.cs index 069743702f..63838d7431 100644 --- a/Projectiles/Melee/RespiteblockHoldout.cs +++ b/Projectiles/Melee/RespiteblockHoldout.cs @@ -17,6 +17,8 @@ public class RespiteblockHoldout : ModProjectile, ILocalizedModType public Player Owner => Main.player[Projectile.owner]; public ref float Time => ref Projectile.ai[0]; + public override void SetStaticDefaults() => Main.projFrames[Type] = 4; + public override void SetDefaults() { Projectile.width = 108; @@ -36,13 +38,12 @@ public override void SetDefaults() public override bool PreDraw(ref Color lightColor) { Texture2D texture = Terraria.GameContent.TextureAssets.Projectile[Projectile.type].Value; - Texture2D centerTexture = ModContent.Request("CalamityMod/Items/Weapons/Melee/Respiteblock").Value; - Vector2 origin = centerTexture.Size() * 0.5f; Vector2 drawPosition = Projectile.Center - Main.screenPosition; SpriteEffects direction = Projectile.spriteDirection == 1 ? SpriteEffects.None : SpriteEffects.FlipHorizontally; - Rectangle rectangle = texture.Frame(1, 4, 0, Projectile.frame); + Rectangle frame = texture.Frame(1, Main.projFrames[Type], 0, Projectile.frame); + Vector2 origin = frame.Size() * 0.5f; - Main.EntitySpriteDraw(texture, drawPosition, rectangle, Projectile.GetAlpha(lightColor), Projectile.rotation, origin, Projectile.scale, direction, 0); + Main.EntitySpriteDraw(texture, drawPosition, frame, Projectile.GetAlpha(lightColor), Projectile.rotation, origin, Projectile.scale, direction, 0); return false; } diff --git a/compile_temp/CalamityModMusic.dll b/compile_temp/CalamityModMusic.dll new file mode 100644 index 0000000000000000000000000000000000000000..3076022bb124e916353bddfd694cb187be4e8310 GIT binary patch literal 28160 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 literal 0 HcmV?d00001 From 6ef43dd874a40c2322b8cc32937b97a71f640e1d Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Sat, 1 Jun 2024 19:29:40 +0700 Subject: [PATCH 180/401] accidentally snuck the dll during mod load oops --- compile_temp/CalamityModMusic.dll | Bin 28160 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 compile_temp/CalamityModMusic.dll diff --git a/compile_temp/CalamityModMusic.dll b/compile_temp/CalamityModMusic.dll deleted file mode 100644 index 3076022bb124e916353bddfd694cb187be4e8310..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28160 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 From 38103eac4ceff1dbf1684e773f86c3ddf977839f Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Sat, 1 Jun 2024 19:31:47 +0700 Subject: [PATCH 181/401] a little faster actually --- Items/Weapons/Melee/Respiteblock.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Items/Weapons/Melee/Respiteblock.cs b/Items/Weapons/Melee/Respiteblock.cs index 4cf32c3bc9..b7fff3656f 100644 --- a/Items/Weapons/Melee/Respiteblock.cs +++ b/Items/Weapons/Melee/Respiteblock.cs @@ -16,7 +16,7 @@ public override void SetDefaults() Item.height = 40; Item.damage = 70; Item.knockBack = 9f; - Item.useTime = 15; + Item.useTime = 10; Item.useAnimation = 20; // In-game, the displayed axe power is 5x the value set here. // This corrects for trees having 500% hardness internally. From 541e6c4bf4403eb46e79eda602dfec8b23c9b6c3 Mon Sep 17 00:00:00 2001 From: Memes Date: Sat, 1 Jun 2024 16:38:05 +0200 Subject: [PATCH 182/401] Removed funky line in summon weapons. Removed weird item time manipulation line on some summons causing bugs to another mods like Summoner's Association. --- Items/Weapons/Summon/CosmicViperEngine.cs | 1 - Items/Weapons/Summon/Endogenesis.cs | 1 - Items/Weapons/Summon/ForgottenApexWand.cs | 1 - Items/Weapons/Summon/GastricBelcherStaff.cs | 1 - Items/Weapons/Summon/ResurrectionButterfly.cs | 1 - 5 files changed, 5 deletions(-) diff --git a/Items/Weapons/Summon/CosmicViperEngine.cs b/Items/Weapons/Summon/CosmicViperEngine.cs index 2f1cacf427..535ad630a2 100644 --- a/Items/Weapons/Summon/CosmicViperEngine.cs +++ b/Items/Weapons/Summon/CosmicViperEngine.cs @@ -40,7 +40,6 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, if (player.altFunctionUse != 2) { float speed = Item.shootSpeed; - player.itemTime = Item.useTime; Vector2 spawnPos = player.RotatedRelativePoint(player.MountedCenter, true); float xPos = (float)Main.mouseX + Main.screenPosition.X - spawnPos.X; float yPos = (float)Main.mouseY + Main.screenPosition.Y - spawnPos.Y; diff --git a/Items/Weapons/Summon/Endogenesis.cs b/Items/Weapons/Summon/Endogenesis.cs index de42c89bb1..0cface095a 100644 --- a/Items/Weapons/Summon/Endogenesis.cs +++ b/Items/Weapons/Summon/Endogenesis.cs @@ -49,7 +49,6 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, { if (player.altFunctionUse != 2) { - player.itemTime = Item.useTime; CalamityUtils.KillShootProjectileMany(player, new int[] { type, diff --git a/Items/Weapons/Summon/ForgottenApexWand.cs b/Items/Weapons/Summon/ForgottenApexWand.cs index 377c934395..63625ec5e3 100644 --- a/Items/Weapons/Summon/ForgottenApexWand.cs +++ b/Items/Weapons/Summon/ForgottenApexWand.cs @@ -34,7 +34,6 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, { if (player.altFunctionUse != 2) { - player.itemTime = Item.useTime; Vector2 vector2 = player.RotatedRelativePoint(player.MountedCenter, true); vector2.X = Main.mouseX + Main.screenPosition.X; vector2.Y = Main.mouseY + Main.screenPosition.Y; diff --git a/Items/Weapons/Summon/GastricBelcherStaff.cs b/Items/Weapons/Summon/GastricBelcherStaff.cs index e5befad427..6566d75dab 100644 --- a/Items/Weapons/Summon/GastricBelcherStaff.cs +++ b/Items/Weapons/Summon/GastricBelcherStaff.cs @@ -34,7 +34,6 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, { if (player.altFunctionUse != 2) { - player.itemTime = Item.useTime; Vector2 playerPos = player.RotatedRelativePoint(player.MountedCenter, true); float directionX = Main.mouseX + Main.screenPosition.X - playerPos.X; float directionY = Main.mouseY + Main.screenPosition.Y - playerPos.Y; diff --git a/Items/Weapons/Summon/ResurrectionButterfly.cs b/Items/Weapons/Summon/ResurrectionButterfly.cs index d91f467d4c..67a1b45685 100644 --- a/Items/Weapons/Summon/ResurrectionButterfly.cs +++ b/Items/Weapons/Summon/ResurrectionButterfly.cs @@ -38,7 +38,6 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, { int i = Main.myPlayer; float projSpeed = Item.shootSpeed; - player.itemTime = Item.useTime; Vector2 realPlayerPos = player.RotatedRelativePoint(player.MountedCenter, true); float mouseXDist = (float)Main.mouseX + Main.screenPosition.X - realPlayerPos.X; float mouseYDist = (float)Main.mouseY + Main.screenPosition.Y - realPlayerPos.Y; From 20b3a092852b251c663e1ad9f658be91da5e8331 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Fri, 31 May 2024 18:34:12 -0400 Subject: [PATCH 183/401] 1 - Reimplementation of Cirrus Candles as permanent buff stations. 2 - All four Candle buffs are now mutually exclusive. 3 - Unlike other buff stations, Cirrus Candles persist through death. 4 - Changed all Cirrus Candles to be Pink rarity (matching Cirrus) and cost 2 platinum, because you only need one of them. 5 - Buffed Blue Candle from 5% to 10% movement speed, wing time, and acceleration. 6 - Buffed Pink Candle from 0.4% HP/s to 0.6% HP/s 7 - Buffed Yellow Candle from 1.05x damage to 1.07x damage. No longer ignores DR, but still ignores defense. 8 - Yellow Candle is no longer a tag debuff and does not apply to enemies in any way. 9 - Purple Candle is mechanically unchanged. --- Buffs/Placeables/CirrusBlueCandleBuff.cs | 18 +++++- Buffs/Placeables/CirrusPinkCandleBuff.cs | 20 +++--- Buffs/Placeables/CirrusPurpleCandleBuff.cs | 12 +++- Buffs/Placeables/CirrusYellowCandleBuff.cs | 19 +++--- CalPlayer/CalamityPlayer.cs | 3 +- CalPlayer/CalamityPlayerHitHurt.cs | 10 +++ CalPlayer/CalamityPlayerLifeRegen.cs | 3 +- CalPlayer/CalamityPlayerMiscEffects.cs | 6 +- Items/Placeables/Furniture/ResilientCandle.cs | 4 +- Items/Placeables/Furniture/SpitefulCandle.cs | 4 +- Items/Placeables/Furniture/VigorousCandle.cs | 4 +- .../Placeables/Furniture/WeightlessCandle.cs | 4 +- .../en-US/Mods.CalamityMod.Buffs.hjson | 6 +- .../Mods.CalamityMod.Items.Placeables.hjson | 15 +++-- NPCs/CalamityGlobalNPC.cs | 8 --- Tiles/Furniture/BlueCandle.cs | 46 ++++++++++---- Tiles/Furniture/BlueCandle_Highlight.png | Bin 0 -> 190 bytes Tiles/Furniture/PinkCandle.cs | 46 ++++++++++---- Tiles/Furniture/PinkCandle_Highlight.png | Bin 0 -> 190 bytes Tiles/Furniture/PurpleCandle.cs | 46 ++++++++++---- Tiles/Furniture/PurpleCandle_Highlight.png | Bin 0 -> 190 bytes Tiles/Furniture/YellowCandle.cs | 58 +++++++++++------- Tiles/Furniture/YellowCandle_Highlight.png | Bin 0 -> 190 bytes 23 files changed, 226 insertions(+), 106 deletions(-) create mode 100644 Tiles/Furniture/BlueCandle_Highlight.png create mode 100644 Tiles/Furniture/PinkCandle_Highlight.png create mode 100644 Tiles/Furniture/PurpleCandle_Highlight.png create mode 100644 Tiles/Furniture/YellowCandle_Highlight.png diff --git a/Buffs/Placeables/CirrusBlueCandleBuff.cs b/Buffs/Placeables/CirrusBlueCandleBuff.cs index 5552456597..1080599c10 100644 --- a/Buffs/Placeables/CirrusBlueCandleBuff.cs +++ b/Buffs/Placeables/CirrusBlueCandleBuff.cs @@ -6,17 +6,29 @@ namespace CalamityMod.Buffs.Placeables { public class CirrusBlueCandleBuff : ModBuff { + public static float MoveSpeedBoost = 0.1f; + public static double WingTimeBoost = 0.1D; + public static float AccelerationBoost = 0.1f; + public override void SetStaticDefaults() { - Main.buffNoTimeDisplay[Type] = true; - Main.debuff[Type] = true; + // These settings are standard for a "opt-in eternal" buff, which has the following properties: + // - Is not removed on death + // - Saves with the player / is not removed on logout + // - Does not display its time + // - Never reduces its duration + // - Can be manually canceled Main.pvpBuff[Type] = true; + Main.persistentBuff[Type] = true; Main.buffNoSave[Type] = false; - BuffID.Sets.NurseCannotRemoveDebuff[Type] = true; + Main.buffNoTimeDisplay[Type] = true; + BuffID.Sets.TimeLeftDoesNotDecrease[Type] = true; } + // Implementation is partially performed elsewhere using the blueCandle bool. public override void Update(Player player, ref int buffIndex) { + player.moveSpeed += MoveSpeedBoost; player.Calamity().blueCandle = true; } } diff --git a/Buffs/Placeables/CirrusPinkCandleBuff.cs b/Buffs/Placeables/CirrusPinkCandleBuff.cs index eaeb003cbc..cde31c0c50 100644 --- a/Buffs/Placeables/CirrusPinkCandleBuff.cs +++ b/Buffs/Placeables/CirrusPinkCandleBuff.cs @@ -6,18 +6,24 @@ namespace CalamityMod.Buffs.Placeables { public class CirrusPinkCandleBuff : ModBuff { + public static double PercentHealthPerSecond = 0.006D; + public override void SetStaticDefaults() { - Main.buffNoTimeDisplay[Type] = true; - Main.debuff[Type] = true; + // These settings are standard for a "opt-in eternal" buff, which has the following properties: + // - Is not removed on death + // - Saves with the player / is not removed on logout + // - Does not display its time + // - Never reduces its duration + // - Can be manually canceled Main.pvpBuff[Type] = true; + Main.persistentBuff[Type] = true; Main.buffNoSave[Type] = false; - BuffID.Sets.NurseCannotRemoveDebuff[Type] = true; + Main.buffNoTimeDisplay[Type] = true; + BuffID.Sets.TimeLeftDoesNotDecrease[Type] = true; } - public override void Update(Player player, ref int buffIndex) - { - player.Calamity().pinkCandle = true; - } + // Implementation is performed elsewhere using the pinkCandle bool. + public override void Update(Player player, ref int buffIndex) => player.Calamity().pinkCandle = true; } } diff --git a/Buffs/Placeables/CirrusPurpleCandleBuff.cs b/Buffs/Placeables/CirrusPurpleCandleBuff.cs index a56d3e179b..3ad0e23b18 100644 --- a/Buffs/Placeables/CirrusPurpleCandleBuff.cs +++ b/Buffs/Placeables/CirrusPurpleCandleBuff.cs @@ -10,11 +10,17 @@ public class CirrusPurpleCandleBuff : ModBuff public override void SetStaticDefaults() { - Main.buffNoTimeDisplay[Type] = true; - Main.debuff[Type] = true; + // These settings are standard for a "opt-in eternal" buff, which has the following properties: + // - Is not removed on death + // - Saves with the player / is not removed on logout + // - Does not display its time + // - Never reduces its duration + // - Can be manually canceled Main.pvpBuff[Type] = true; + Main.persistentBuff[Type] = true; Main.buffNoSave[Type] = false; - BuffID.Sets.NurseCannotRemoveDebuff[Type] = true; + Main.buffNoTimeDisplay[Type] = true; + BuffID.Sets.TimeLeftDoesNotDecrease[Type] = true; } public override void Update(Player player, ref int buffIndex) diff --git a/Buffs/Placeables/CirrusYellowCandleBuff.cs b/Buffs/Placeables/CirrusYellowCandleBuff.cs index 8ad664c83a..69a60673c7 100644 --- a/Buffs/Placeables/CirrusYellowCandleBuff.cs +++ b/Buffs/Placeables/CirrusYellowCandleBuff.cs @@ -6,19 +6,24 @@ namespace CalamityMod.Buffs.Placeables { public class CirrusYellowCandleBuff : ModBuff { + public static float ExtraChipDamageRatio = 0.07f; + public override void SetStaticDefaults() { - Main.buffNoTimeDisplay[Type] = true; - Main.debuff[Type] = true; + // These settings are standard for a "opt-in eternal" buff, which has the following properties: + // - Is not removed on death + // - Saves with the player / is not removed on logout + // - Does not display its time + // - Never reduces its duration + // - Can be manually canceled Main.pvpBuff[Type] = true; + Main.persistentBuff[Type] = true; Main.buffNoSave[Type] = false; - BuffID.Sets.NurseCannotRemoveDebuff[Type] = true; - - // Spite (the +5% final damage effect of Yellow Candle) is a tag buff. Nothing is immune to it. - // They may however be unaffected by it (including only temporarily) if they have incredibly high DR. - BuffID.Sets.IsATagBuff[Type] = true; + Main.buffNoTimeDisplay[Type] = true; + BuffID.Sets.TimeLeftDoesNotDecrease[Type] = true; } + // Implementation is performed elsewhere using the yellowCandle bool. public override void Update(Player player, ref int buffIndex) => player.Calamity().yellowCandle = true; } } diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 784402d02f..cb4fca8350 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -4,6 +4,7 @@ using CalamityMod.Balancing; using CalamityMod.BiomeManagers; using CalamityMod.Buffs; +using CalamityMod.Buffs.Placeables; using CalamityMod.Buffs.StatBuffs; using CalamityMod.Buffs.StatDebuffs; using CalamityMod.CalPlayer.Dashes; @@ -3715,7 +3716,7 @@ public override void PostUpdateRunSpeeds() (kamiBoost ? KamiBuff.RunAccelerationBoost : 0f) + (CobaltSet ? CobaltArmorSetChange.SpeedBoostSetBonusPercentage * 0.01f : 0f) + (silvaSet ? 0.05f : 0f) + - (blueCandle ? 0.05f : 0f) + + (blueCandle ? CirrusBlueCandleBuff.AccelerationBoost : 0f) + (planarSpeedBoost > 0 ? (0.01f * planarSpeedBoost) : 0f) + (hasteLevel * 0.05f); diff --git a/CalPlayer/CalamityPlayerHitHurt.cs b/CalPlayer/CalamityPlayerHitHurt.cs index 0b6d6f69fa..2ad91438aa 100644 --- a/CalPlayer/CalamityPlayerHitHurt.cs +++ b/CalPlayer/CalamityPlayerHitHurt.cs @@ -3,6 +3,7 @@ using CalamityMod.Balancing; using CalamityMod.Buffs.Cooldowns; using CalamityMod.Buffs.DamageOverTime; +using CalamityMod.Buffs.Placeables; using CalamityMod.Buffs.StatBuffs; using CalamityMod.Buffs.StatDebuffs; using CalamityMod.CalPlayer.Dashes; @@ -524,6 +525,15 @@ public override void ModifyHitNPCWithItem(Item item, NPC target, ref NPC.HitModi // Apply all Calamity multipliers as a sum total to TML New Damage in a single step modifiers.SourceDamage *= totalDamageMult; + // 31MAY2024: Ozzatron: apply Yellow Candle "chip damage" in a different way, by adjusting FinalDamage.Base + // This is still gated by the old conditionals to ensure it doesn't apply to "near invincible" targets + // Calamity's DR is also implemented at the FinalDamage step as a multiplier so Yellow Candle doesn't ignore DR anymore (and has been buffed to compensate) + // + // FinalDamage.Flat would technically be closer to the intended implementation, but is heavily discouraged from use and would cause huge cross-mod issues + CalamityGlobalNPC cgn = target.Calamity(); + if (Player.HasBuff() && cgn.DR < 0.99f && target.takenDamageMultiplier > 0.05f) + modifiers.FinalDamage.Base *= 1f + CirrusYellowCandleBuff.ExtraChipDamageRatio; + // Excalibur and True Excalibur deal +100% damage to targets above 75% HP. if (item.type == ItemID.Excalibur || item.type == ItemID.TrueExcalibur) { diff --git a/CalPlayer/CalamityPlayerLifeRegen.cs b/CalPlayer/CalamityPlayerLifeRegen.cs index e561d98c24..590e89edba 100644 --- a/CalPlayer/CalamityPlayerLifeRegen.cs +++ b/CalPlayer/CalamityPlayerLifeRegen.cs @@ -2,6 +2,7 @@ using System.Linq; using CalamityMod.Buffs.Alcohol; using CalamityMod.Buffs.DamageOverTime; +using CalamityMod.Buffs.Placeables; using CalamityMod.Cooldowns; using CalamityMod.Items.Accessories; using CalamityMod.NPCs; @@ -735,7 +736,7 @@ public override void UpdateLifeRegen() if (pinkCandle && !noLifeRegen) { // Every frame, add up 1/60th of the healing value (0.4% max HP per second) - pinkCandleHealFraction += Player.statLifeMax2 * 0.004 / 60; + pinkCandleHealFraction += Player.statLifeMax2 * CirrusPinkCandleBuff.PercentHealthPerSecond / 60; if (pinkCandleHealFraction >= 1D) { diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index 5f2adbd3b7..1dac773f1d 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -3,6 +3,7 @@ using System.Linq; using CalamityMod.Balancing; using CalamityMod.Buffs.DamageOverTime; +using CalamityMod.Buffs.Placeables; using CalamityMod.Buffs.Potions; using CalamityMod.Buffs.StatBuffs; using CalamityMod.Buffs.StatDebuffs; @@ -2862,16 +2863,13 @@ private void OtherBuffEffects() (harpyRing ? 0.2 : 0D) + (reaverSpeed ? 0.1 : 0D) + (angelTreads ? 0.1 : 0D) + - (blueCandle ? 0.05 : 0D) + + (blueCandle ? CirrusBlueCandleBuff.WingTimeBoost : 0D) + (soaring ? 0.1 : 0D) + (prismaticGreaves ? 0.1 : 0D) + (plagueReaper ? 0.05 : 0D) + (ascendantInsignia ? 0.05 : 0D) + // Added to soaring insignia's flight to get 30% (Player.empressBrooch ? 0.25 : 0D); - if (blueCandle) - Player.moveSpeed += 0.05f; - if (community) { float baseBoost = TheCommunity.CalculatePower(); diff --git a/Items/Placeables/Furniture/ResilientCandle.cs b/Items/Placeables/Furniture/ResilientCandle.cs index 87c79ac75d..b076d3f27b 100644 --- a/Items/Placeables/Furniture/ResilientCandle.cs +++ b/Items/Placeables/Furniture/ResilientCandle.cs @@ -19,8 +19,8 @@ public override void SetDefaults() Item.useTime = 10; Item.useStyle = ItemUseStyleID.Swing; Item.consumable = true; - Item.value = Item.buyPrice(0, 25, 0, 0); - Item.rare = ItemRarityID.LightRed; + Item.value = Item.buyPrice(platinum: 2); + Item.rare = ItemRarityID.Pink; Item.createTile = ModContent.TileType(); } } diff --git a/Items/Placeables/Furniture/SpitefulCandle.cs b/Items/Placeables/Furniture/SpitefulCandle.cs index cef61b3d9b..82ef62991d 100644 --- a/Items/Placeables/Furniture/SpitefulCandle.cs +++ b/Items/Placeables/Furniture/SpitefulCandle.cs @@ -19,8 +19,8 @@ public override void SetDefaults() Item.useTime = 10; Item.useStyle = ItemUseStyleID.Swing; Item.consumable = true; - Item.value = Item.buyPrice(0, 25, 0, 0); - Item.rare = ItemRarityID.LightRed; + Item.value = Item.buyPrice(platinum: 2); + Item.rare = ItemRarityID.Pink; Item.createTile = ModContent.TileType(); } } diff --git a/Items/Placeables/Furniture/VigorousCandle.cs b/Items/Placeables/Furniture/VigorousCandle.cs index f5457c0f4a..136b9c8c54 100644 --- a/Items/Placeables/Furniture/VigorousCandle.cs +++ b/Items/Placeables/Furniture/VigorousCandle.cs @@ -19,8 +19,8 @@ public override void SetDefaults() Item.useTime = 10; Item.useStyle = ItemUseStyleID.Swing; Item.consumable = true; - Item.value = Item.buyPrice(0, 25, 0, 0); - Item.rare = ItemRarityID.LightRed; + Item.value = Item.buyPrice(platinum: 2); + Item.rare = ItemRarityID.Pink; Item.createTile = ModContent.TileType(); } } diff --git a/Items/Placeables/Furniture/WeightlessCandle.cs b/Items/Placeables/Furniture/WeightlessCandle.cs index 903f707f04..85fec2bbd9 100644 --- a/Items/Placeables/Furniture/WeightlessCandle.cs +++ b/Items/Placeables/Furniture/WeightlessCandle.cs @@ -19,8 +19,8 @@ public override void SetDefaults() Item.useTime = 10; Item.useStyle = ItemUseStyleID.Swing; Item.consumable = true; - Item.value = Item.buyPrice(0, 25, 0, 0); - Item.rare = ItemRarityID.LightRed; + Item.value = Item.buyPrice(platinum: 2); + Item.rare = ItemRarityID.Pink; Item.createTile = ModContent.TileType(); } } diff --git a/Localization/en-US/Mods.CalamityMod.Buffs.hjson b/Localization/en-US/Mods.CalamityMod.Buffs.hjson index 7a8bcf9910..e7843c0e46 100644 --- a/Localization/en-US/Mods.CalamityMod.Buffs.hjson +++ b/Localization/en-US/Mods.CalamityMod.Buffs.hjson @@ -465,17 +465,17 @@ CirrusBlueCandleBuff: { CirrusPinkCandleBuff: { DisplayName: Vigor - Description: Its brilliant light suffuses those nearby with hope + Description: The brilliant light suffuses you with hope } CirrusPurpleCandleBuff: { DisplayName: Resilience - Description: Neither rain nor wind can snuff its undying flame + Description: Neither rain nor wind can snuff your undying flame } CirrusYellowCandleBuff: { DisplayName: Spite - Description: Its hateful glow flickers with ire + Description: The hateful, flickering glow fuels your ire } CorruptionEffigyBuff: { diff --git a/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson b/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson index ddb61fbc36..11eecccc2e 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson @@ -729,7 +729,9 @@ ResilientCandle: { DisplayName: Resilient Candle Tooltip: ''' - When placed, nearby players' defense blocks 10% more damage + when placed to make defense block 10% more damage + (60% in Classic, 85% in Expert, and 110% in Master) + This cannot be stacked with other Cirrus Candle buffs 'Neither rain nor wind can snuff its undying flame' ''' } @@ -748,8 +750,9 @@ SpitefulCandle: { DisplayName: Spiteful Candle Tooltip: ''' - When placed, nearby enemies take 5% more damage. - This extra damage bypasses enemy damage reduction and defense + when placed to deal 1.07x damage to all enemies + The extra 0.07x damage bypasses enemy defense + This cannot be stacked with other Cirrus Candle buffs 'Its hateful glow flickers with ire' ''' } @@ -973,8 +976,9 @@ VigorousCandle: { DisplayName: Vigorous Candle Tooltip: ''' - When placed, nearby players regenerate 0.4% of their maximum health per second + when placed to regenerate 0.6% of your maximum health per second This regeneration is at full power even while moving and bypasses Revengeance Mode caps + This cannot be stacked with other Cirrus Candle buffs 'Its brilliant light suffuses those nearby with hope' ''' } @@ -983,7 +987,8 @@ WeightlessCandle: { DisplayName: Weightless Candle Tooltip: ''' - When placed, nearby players gain 5% increased movement speed, wing time and acceleration + when placed to gain 10% increased movement speed, wing time and acceleration + This cannot be stacked with other Cirrus Candle buffs 'The floating flame seems to uplift your very spirit' ''' } diff --git a/NPCs/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index 5e267f5447..b2a4ed9359 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -3221,14 +3221,6 @@ private void ApplyDR(NPC npc, ref NPC.HitModifiers modifiers) if (effectiveDR <= 0f) effectiveDR = 0f; - // Add Yellow Candle damage if the NPC isn't supposed to be "near invincible" - // Armor penetration has already been applied as bonus damage. - // Yellow Candle provides +5% damage which ignores both DR and defense. - // This means Yellow Candle is buffing armor penetration and technically not ignoring defense, - // but it's small enough to let it slide. - if (npc.HasBuff() && DR < 0.99f && npc.takenDamageMultiplier > 0.05f) - finalMultiplier += 0.05f; - // Calculate extra DR based on kill time, similar to the Hush boss from The Binding of Isaac // Cirrus being active makes the extra DR cease to function bool cirrusBossActive = false; diff --git a/Tiles/Furniture/BlueCandle.cs b/Tiles/Furniture/BlueCandle.cs index e174008003..ae874cba1a 100644 --- a/Tiles/Furniture/BlueCandle.cs +++ b/Tiles/Furniture/BlueCandle.cs @@ -2,9 +2,9 @@ using CalamityMod.Items.Placeables.Furniture; using Microsoft.Xna.Framework; using Terraria; -using Terraria.DataStructures; +using Terraria.Audio; +using Terraria.GameContent.ObjectInteractions; using Terraria.ID; -using Terraria.Localization; using Terraria.ModLoader; using Terraria.ObjectData; @@ -12,6 +12,9 @@ namespace CalamityMod.Tiles.Furniture { public class BlueCandle : ModTile { + // TODO -- Unique sounds for each Cirrus Candle. + public static readonly SoundStyle ActivationSound = new("CalamityMod/Sounds/Item/LouderPhantomPhoenix2"); + public override void SetStaticDefaults() { Main.tileLighted[Type] = true; @@ -22,9 +25,39 @@ public override void SetStaticDefaults() AdjTiles = new int[] { TileID.Candles }; AddToArray(ref TileID.Sets.RoomNeeds.CountsAsTorch); AddMapEntry(new Color(238, 145, 105), CalamityUtils.GetItemName()); + TileID.Sets.HasOutlines[Type] = true; AnimationFrameHeight = 18; } + public override bool HasSmartInteract(int i, int j, SmartInteractScanSettings settings) => true; + + public override bool RightClick(int i, int j) + { + Player p = Main.LocalPlayer; + + // Forcibly remove all candle buffs. + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + + // 108000 is the duration used by Ammo Box. + p.AddBuff(ModContent.BuffType(), 108000); + + // Play a sound. + SoundEngine.PlaySound(ActivationSound, new Vector2(i * 16, j * 16)); + + return true; + } + + public override void MouseOver(int i, int j) + { + Player player = Main.LocalPlayer; + player.noThrow = 2; + player.cursorItemIconEnabled = true; + player.cursorItemIconID = ModContent.ItemType(); + } + public override void AnimateTile(ref int frame, ref int frameCounter) { frameCounter++; @@ -35,15 +68,6 @@ public override void AnimateTile(ref int frame, ref int frameCounter) } } - public override void NearbyEffects(int i, int j, bool closer) - { - Player player = Main.LocalPlayer; - if (player is null) - return; - if (!player.dead && player.active) - player.AddBuff(ModContent.BuffType(), 20); - } - public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) { r = 0.35f; diff --git a/Tiles/Furniture/BlueCandle_Highlight.png b/Tiles/Furniture/BlueCandle_Highlight.png new file mode 100644 index 0000000000000000000000000000000000000000..02427f1b605d2f4f1c853368675f17ddb8c3bba5 GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^0ze$a!3HEZ8eGc;QjEnx?oJHr&dIz4a#+$GeI0>P z{oH>NS%G{%PZ!6K2=}*F47nH-c~}lqJo&HBS5Xm@s&1y4CMBA3GmAM&BGmN%?}=w* zUf1lq-h1`IlB56r?`mXtaY%`?!A@rq!;8ZZMngx3_>AMpcASyFje#cfrABzB`T8()); + TileID.Sets.HasOutlines[Type] = true; AnimationFrameHeight = 18; } + public override bool HasSmartInteract(int i, int j, SmartInteractScanSettings settings) => true; + + public override bool RightClick(int i, int j) + { + Player p = Main.LocalPlayer; + + // Forcibly remove all candle buffs. + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + + // 108000 is the duration used by Ammo Box. + p.AddBuff(ModContent.BuffType(), 108000); + + // Play a sound. + SoundEngine.PlaySound(ActivationSound, new Vector2(i * 16, j * 16)); + + return true; + } + + public override void MouseOver(int i, int j) + { + Player player = Main.LocalPlayer; + player.noThrow = 2; + player.cursorItemIconEnabled = true; + player.cursorItemIconID = ModContent.ItemType(); + } + public override void AnimateTile(ref int frame, ref int frameCounter) { frameCounter++; @@ -35,15 +68,6 @@ public override void AnimateTile(ref int frame, ref int frameCounter) } } - public override void NearbyEffects(int i, int j, bool closer) - { - Player player = Main.LocalPlayer; - if (player is null) - return; - if (!player.dead && player.active) - player.AddBuff(ModContent.BuffType(), 20); - } - public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) { r = 0.75f; diff --git a/Tiles/Furniture/PinkCandle_Highlight.png b/Tiles/Furniture/PinkCandle_Highlight.png new file mode 100644 index 0000000000000000000000000000000000000000..02427f1b605d2f4f1c853368675f17ddb8c3bba5 GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^0ze$a!3HEZ8eGc;QjEnx?oJHr&dIz4a#+$GeI0>P z{oH>NS%G{%PZ!6K2=}*F47nH-c~}lqJo&HBS5Xm@s&1y4CMBA3GmAM&BGmN%?}=w* zUf1lq-h1`IlB56r?`mXtaY%`?!A@rq!;8ZZMngx3_>AMpcASyFje#cfrABzB`T8()); + TileID.Sets.HasOutlines[Type] = true; AnimationFrameHeight = 18; } + public override bool HasSmartInteract(int i, int j, SmartInteractScanSettings settings) => true; + + public override bool RightClick(int i, int j) + { + Player p = Main.LocalPlayer; + + // Forcibly remove all candle buffs. + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + + // 108000 is the duration used by Ammo Box. + p.AddBuff(ModContent.BuffType(), 108000); + + // Play a sound. + SoundEngine.PlaySound(ActivationSound, new Vector2(i * 16, j * 16)); + + return true; + } + + public override void MouseOver(int i, int j) + { + Player player = Main.LocalPlayer; + player.noThrow = 2; + player.cursorItemIconEnabled = true; + player.cursorItemIconID = ModContent.ItemType(); + } + public override void AnimateTile(ref int frame, ref int frameCounter) { frameCounter++; @@ -35,15 +68,6 @@ public override void AnimateTile(ref int frame, ref int frameCounter) } } - public override void NearbyEffects(int i, int j, bool closer) - { - Player player = Main.LocalPlayer; - if (player is null) - return; - if (!player.dead && player.active) - player.AddBuff(ModContent.BuffType(), 20); - } - public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) { r = 0.65f; diff --git a/Tiles/Furniture/PurpleCandle_Highlight.png b/Tiles/Furniture/PurpleCandle_Highlight.png new file mode 100644 index 0000000000000000000000000000000000000000..02427f1b605d2f4f1c853368675f17ddb8c3bba5 GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^0ze$a!3HEZ8eGc;QjEnx?oJHr&dIz4a#+$GeI0>P z{oH>NS%G{%PZ!6K2=}*F47nH-c~}lqJo&HBS5Xm@s&1y4CMBA3GmAM&BGmN%?}=w* zUf1lq-h1`IlB56r?`mXtaY%`?!A@rq!;8ZZMngx3_>AMpcASyFje#cfrABzB`T8()); + TileID.Sets.HasOutlines[Type] = true; AnimationFrameHeight = 18; } - public override void AnimateTile(ref int frame, ref int frameCounter) + public override bool HasSmartInteract(int i, int j, SmartInteractScanSettings settings) => true; + + public override bool RightClick(int i, int j) { - frameCounter++; - if (frameCounter >= 6) - { - frame = (frame + 1) % 5; - frameCounter = 0; - } + Player p = Main.LocalPlayer; + + // Forcibly remove all candle buffs. + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + + // 108000 is the duration used by Ammo Box. + p.AddBuff(ModContent.BuffType(), 108000); + + // Play a sound. + SoundEngine.PlaySound(ActivationSound, new Vector2(i * 16, j * 16)); + + return true; } - public override void NearbyEffects(int i, int j, bool closer) + public override void MouseOver(int i, int j) { Player player = Main.LocalPlayer; - if (player == null || !player.active || player.dead) - return; - player.AddBuff(ModContent.BuffType(), 20); - - if (Main.netMode == NetmodeID.MultiplayerClient) - return; + player.noThrow = 2; + player.cursorItemIconEnabled = true; + player.cursorItemIconID = ModContent.ItemType(); + } - // All NPCs within a certain distance of the player get "Tagged" with Spite. - for (int m = 0; m < Main.maxNPCs; m++) + public override void AnimateTile(ref int frame, ref int frameCounter) + { + frameCounter++; + if (frameCounter >= 6) { - NPC npc = Main.npc[m]; - if (npc is null || !npc.active || npc.friendly) - continue; - - float dist2 = npc.DistanceSQ(player.Center); - if (dist2 < 23040000f) // 4800px range - Main.npc[m].AddBuff(ModContent.BuffType(), 20, false); + frame = (frame + 1) % 5; + frameCounter = 0; } } diff --git a/Tiles/Furniture/YellowCandle_Highlight.png b/Tiles/Furniture/YellowCandle_Highlight.png new file mode 100644 index 0000000000000000000000000000000000000000..02427f1b605d2f4f1c853368675f17ddb8c3bba5 GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^0ze$a!3HEZ8eGc;QjEnx?oJHr&dIz4a#+$GeI0>P z{oH>NS%G{%PZ!6K2=}*F47nH-c~}lqJo&HBS5Xm@s&1y4CMBA3GmAM&BGmN%?}=w* zUf1lq-h1`IlB56r?`mXtaY%`?!A@rq!;8ZZMngx3_>AMpcASyFje#cfrABzB`T8 Date: Fri, 31 May 2024 22:52:59 -0400 Subject: [PATCH 184/401] Yellow Candle now applies to projectiles, no longer restricted to Use Style 1 Broadswords. --- CalPlayer/CalamityPlayerHitHurt.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/CalPlayer/CalamityPlayerHitHurt.cs b/CalPlayer/CalamityPlayerHitHurt.cs index 2ad91438aa..456ca387b0 100644 --- a/CalPlayer/CalamityPlayerHitHurt.cs +++ b/CalPlayer/CalamityPlayerHitHurt.cs @@ -531,7 +531,7 @@ public override void ModifyHitNPCWithItem(Item item, NPC target, ref NPC.HitModi // // FinalDamage.Flat would technically be closer to the intended implementation, but is heavily discouraged from use and would cause huge cross-mod issues CalamityGlobalNPC cgn = target.Calamity(); - if (Player.HasBuff() && cgn.DR < 0.99f && target.takenDamageMultiplier > 0.05f) + if (yellowCandle && cgn.DR < 0.99f && target.takenDamageMultiplier > 0.05f) modifiers.FinalDamage.Base *= 1f + CirrusYellowCandleBuff.ExtraChipDamageRatio; // Excalibur and True Excalibur deal +100% damage to targets above 75% HP. @@ -600,6 +600,15 @@ public override void ModifyHitNPCWithItem(Item item, NPC target, ref NPC.HitModi // Apply all Calamity multipliers as a sum total to TML New Damage in a single step modifiers.SourceDamage *= totalDamageMult; + // 31MAY2024: Ozzatron: apply Yellow Candle "chip damage" in a different way, by adjusting FinalDamage.Base + // This is still gated by the old conditionals to ensure it doesn't apply to "near invincible" targets + // Calamity's DR is also implemented at the FinalDamage step as a multiplier so Yellow Candle doesn't ignore DR anymore (and has been buffed to compensate) + // + // FinalDamage.Flat would technically be closer to the intended implementation, but is heavily discouraged from use and would cause huge cross-mod issues + CalamityGlobalNPC cgn = target.Calamity(); + if (yellowCandle && cgn.DR < 0.99f && target.takenDamageMultiplier > 0.05f) + modifiers.FinalDamage.Base *= 1f + CirrusYellowCandleBuff.ExtraChipDamageRatio; + // Stealth strike damage multipliers are applied here. // TODO -- stealth should be its own damage class and this should be applied as player StealthDamage *= XYZ if (proj.Calamity().stealthStrike && proj.CountsAsClass()) From 882ad6108293669cde601b01eb745349e93377b1 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Sat, 1 Jun 2024 16:49:55 -0400 Subject: [PATCH 185/401] 1 - Nerfed Yellow Candle from 1.07x to 1.04x but it ignores DR again as intended. 2 - Fixed Yellow Candle being placebo, for real this time. --- Buffs/Placeables/CirrusYellowCandleBuff.cs | 10 +++++++++- CalPlayer/CalamityPlayerHitHurt.cs | 18 ++++++++---------- .../Mods.CalamityMod.Items.Placeables.hjson | 4 ++-- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/Buffs/Placeables/CirrusYellowCandleBuff.cs b/Buffs/Placeables/CirrusYellowCandleBuff.cs index 69a60673c7..69fd6f35c9 100644 --- a/Buffs/Placeables/CirrusYellowCandleBuff.cs +++ b/Buffs/Placeables/CirrusYellowCandleBuff.cs @@ -1,12 +1,13 @@ using Terraria; using Terraria.ID; using Terraria.ModLoader; +using static Terraria.NPC; namespace CalamityMod.Buffs.Placeables { public class CirrusYellowCandleBuff : ModBuff { - public static float ExtraChipDamageRatio = 0.07f; + public static float ExtraChipDamageRatio = 0.04f; public override void SetStaticDefaults() { @@ -25,5 +26,12 @@ public override void SetStaticDefaults() // Implementation is performed elsewhere using the yellowCandle bool. public override void Update(Player player, ref int buffIndex) => player.Calamity().yellowCandle = true; + + // Yellow Candle is implemented as a dirty modifier. + internal static void ModifyHitInfo_Spite(ref HitInfo info) + { + int damageBoost = (int)(info.SourceDamage * ExtraChipDamageRatio); + info.Damage += damageBoost; + } } } diff --git a/CalPlayer/CalamityPlayerHitHurt.cs b/CalPlayer/CalamityPlayerHitHurt.cs index 456ca387b0..aca930da03 100644 --- a/CalPlayer/CalamityPlayerHitHurt.cs +++ b/CalPlayer/CalamityPlayerHitHurt.cs @@ -525,14 +525,13 @@ public override void ModifyHitNPCWithItem(Item item, NPC target, ref NPC.HitModi // Apply all Calamity multipliers as a sum total to TML New Damage in a single step modifiers.SourceDamage *= totalDamageMult; - // 31MAY2024: Ozzatron: apply Yellow Candle "chip damage" in a different way, by adjusting FinalDamage.Base - // This is still gated by the old conditionals to ensure it doesn't apply to "near invincible" targets - // Calamity's DR is also implemented at the FinalDamage step as a multiplier so Yellow Candle doesn't ignore DR anymore (and has been buffed to compensate) + // 01JUN2024: Ozzatron: apply Yellow Candle "chip damage" as a dirty modifier + // The registration of the dirty modifier is conditional to ensure it doesn't apply to "near invincible" targets // - // FinalDamage.Flat would technically be closer to the intended implementation, but is heavily discouraged from use and would cause huge cross-mod issues + // FinalDamage cannot be used for the intended effect because there is no way to access the actual damage of the hit CalamityGlobalNPC cgn = target.Calamity(); if (yellowCandle && cgn.DR < 0.99f && target.takenDamageMultiplier > 0.05f) - modifiers.FinalDamage.Base *= 1f + CirrusYellowCandleBuff.ExtraChipDamageRatio; + modifiers.ModifyHitInfo += CirrusYellowCandleBuff.ModifyHitInfo_Spite; // Excalibur and True Excalibur deal +100% damage to targets above 75% HP. if (item.type == ItemID.Excalibur || item.type == ItemID.TrueExcalibur) @@ -600,14 +599,13 @@ public override void ModifyHitNPCWithItem(Item item, NPC target, ref NPC.HitModi // Apply all Calamity multipliers as a sum total to TML New Damage in a single step modifiers.SourceDamage *= totalDamageMult; - // 31MAY2024: Ozzatron: apply Yellow Candle "chip damage" in a different way, by adjusting FinalDamage.Base - // This is still gated by the old conditionals to ensure it doesn't apply to "near invincible" targets - // Calamity's DR is also implemented at the FinalDamage step as a multiplier so Yellow Candle doesn't ignore DR anymore (and has been buffed to compensate) + // 01JUN2024: Ozzatron: apply Yellow Candle "chip damage" as a dirty modifier + // The registration of the dirty modifier is conditional to ensure it doesn't apply to "near invincible" targets // - // FinalDamage.Flat would technically be closer to the intended implementation, but is heavily discouraged from use and would cause huge cross-mod issues + // FinalDamage cannot be used for the intended effect because there is no way to access the actual damage of the hit CalamityGlobalNPC cgn = target.Calamity(); if (yellowCandle && cgn.DR < 0.99f && target.takenDamageMultiplier > 0.05f) - modifiers.FinalDamage.Base *= 1f + CirrusYellowCandleBuff.ExtraChipDamageRatio; + modifiers.ModifyHitInfo += CirrusYellowCandleBuff.ModifyHitInfo_Spite; // Stealth strike damage multipliers are applied here. // TODO -- stealth should be its own damage class and this should be applied as player StealthDamage *= XYZ diff --git a/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson b/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson index 11eecccc2e..8f64b995fd 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson @@ -750,8 +750,8 @@ SpitefulCandle: { DisplayName: Spiteful Candle Tooltip: ''' - when placed to deal 1.07x damage to all enemies - The extra 0.07x damage bypasses enemy defense + when placed to deal 1.04x damage to all enemies + The extra 0.04x damage bypasses enemy defense and damage reduction This cannot be stacked with other Cirrus Candle buffs 'Its hateful glow flickers with ire' ''' From 71da0a35cec33885d53e9b92c8bc7eac08c23b59 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Sat, 1 Jun 2024 18:01:42 -0400 Subject: [PATCH 186/401] Reverted Pink Candle buff from 0.6% HP/s to 0.4% HP/s --- Buffs/Placeables/CirrusPinkCandleBuff.cs | 2 +- Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Buffs/Placeables/CirrusPinkCandleBuff.cs b/Buffs/Placeables/CirrusPinkCandleBuff.cs index cde31c0c50..8cf6bc1437 100644 --- a/Buffs/Placeables/CirrusPinkCandleBuff.cs +++ b/Buffs/Placeables/CirrusPinkCandleBuff.cs @@ -6,7 +6,7 @@ namespace CalamityMod.Buffs.Placeables { public class CirrusPinkCandleBuff : ModBuff { - public static double PercentHealthPerSecond = 0.006D; + public static double PercentHealthPerSecond = 0.004D; public override void SetStaticDefaults() { diff --git a/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson b/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson index 8f64b995fd..11471412cf 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson @@ -976,7 +976,7 @@ VigorousCandle: { DisplayName: Vigorous Candle Tooltip: ''' - when placed to regenerate 0.6% of your maximum health per second + when placed to regenerate 0.4% of your maximum health per second This regeneration is at full power even while moving and bypasses Revengeance Mode caps This cannot be stacked with other Cirrus Candle buffs 'Its brilliant light suffuses those nearby with hope' From ebb57d6085c6774907215a60d623d4f89c5b4cd6 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 1 Jun 2024 19:18:07 -0400 Subject: [PATCH 187/401] Spiteful Candle buff --- Buffs/Placeables/CirrusYellowCandleBuff.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Buffs/Placeables/CirrusYellowCandleBuff.cs b/Buffs/Placeables/CirrusYellowCandleBuff.cs index 69fd6f35c9..1b5f9a7f96 100644 --- a/Buffs/Placeables/CirrusYellowCandleBuff.cs +++ b/Buffs/Placeables/CirrusYellowCandleBuff.cs @@ -7,7 +7,7 @@ namespace CalamityMod.Buffs.Placeables { public class CirrusYellowCandleBuff : ModBuff { - public static float ExtraChipDamageRatio = 0.04f; + public static float ExtraChipDamageRatio = 0.07f; public override void SetStaticDefaults() { From 926757506464d80b5dd0b81daabee4e185dd422d Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Sat, 1 Jun 2024 18:34:40 -0500 Subject: [PATCH 188/401] Version bump --- build.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.txt b/build.txt index b80ad208f0..cf9028fcf7 100644 --- a/build.txt +++ b/build.txt @@ -1,5 +1,5 @@ author = Fabsol and the Dev Team -version = 2.0.4.002 +version = 2.0.4.003 displayName = Calamity Mod modReferences = CalamityModMusic homepage = https://discord.gg/calamity From adb3e7b1766765d787313f049064e315e7bc0825 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 1 Jun 2024 20:16:54 -0400 Subject: [PATCH 189/401] Fixed Spiteful Candle's tooltip --- Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson b/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson index 11471412cf..4c0d8b539a 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson @@ -750,8 +750,8 @@ SpitefulCandle: { DisplayName: Spiteful Candle Tooltip: ''' - when placed to deal 1.04x damage to all enemies - The extra 0.04x damage bypasses enemy defense and damage reduction + when placed to deal 1.07x damage to all enemies + The extra 0.07x damage bypasses enemy defense and damage reduction This cannot be stacked with other Cirrus Candle buffs 'Its hateful glow flickers with ire' ''' From c140748feed2a3d1dfef33b7ce5260166fa17ed1 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Thu, 17 Oct 2024 04:09:28 -0500 Subject: [PATCH 190/401] Pretty sure this is everything. --- .../MiracleBlightRenderer.cs | 11 +-- NPCs/CalamityDrawParameterNPC.cs | 88 +++++++++++++++++++ NPCs/CalamityPolarityNPC.cs | 2 +- Utilities/GlobalEntityUtils.cs | 47 ++++++++++ build.txt | 2 +- 5 files changed, 138 insertions(+), 12 deletions(-) create mode 100644 NPCs/CalamityDrawParameterNPC.cs create mode 100644 Utilities/GlobalEntityUtils.cs diff --git a/Graphics/Renderers/CalamityRenderers/MiracleBlightRenderer.cs b/Graphics/Renderers/CalamityRenderers/MiracleBlightRenderer.cs index 9fdab1f84a..b8902c380b 100644 --- a/Graphics/Renderers/CalamityRenderers/MiracleBlightRenderer.cs +++ b/Graphics/Renderers/CalamityRenderers/MiracleBlightRenderer.cs @@ -68,16 +68,7 @@ public static bool ValidToDraw(NPC npc) if (ExcludedNPCs.Contains(npc.type) || npc.IsABestiaryIconDummy) return false; - // Safety check for weird MP bug when getting global npcs. - if (!npc.TryGetGlobalNPC(out var calNPC) || !npc.TryGetGlobalNPC(out var polNPC)) - return false; - - // Do not draw if the npc does not have miracle blight, or has the polarity effect. - if (calNPC.miracleBlight <= 0 || polNPC.CurPolarity > 0f) - return false; - - // Do not draw if the current player has the trippy effect. - if (Main.LocalPlayer.Calamity().trippy) + if (!CalamityDrawParameterNPC.DrawingMiracleBlight[npc.whoAmI]) return false; return true; diff --git a/NPCs/CalamityDrawParameterNPC.cs b/NPCs/CalamityDrawParameterNPC.cs new file mode 100644 index 0000000000..f128694f22 --- /dev/null +++ b/NPCs/CalamityDrawParameterNPC.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Steamworks; +using Terraria; +using Terraria.DataStructures; +using Terraria.ModLoader; +namespace CalamityMod.NPCs +{ + // Why this class is exist? + // It because we want to avoid Threading Issues while We using NPC's properties on Draw Thread + public sealed class CalamityDrawParameterNPC : GlobalNPC + { + public override bool InstancePerEntity => false; + + #region Draw Parameters + public static bool[] DrawingMiracleBlight { get; private set; } + public static bool[] DrawingPolarity { get; private set; } + #endregion + + public override void Load() + { + DrawingMiracleBlight = new bool[Main.maxNPCs]; + DrawingPolarity = new bool[Main.maxNPCs]; + } + + public override void Unload() + { + DrawingMiracleBlight = null; + DrawingPolarity = null; + } + + public override void SetDefaults(NPC entity) => ResetParameters(entity); + + public override bool PreAI(NPC npc) + { + if (npc is null) + return true; + var whoAmI = npc.whoAmI; + DrawingMiracleBlight[whoAmI] = ShouldDrawMiracleBlight(npc); + DrawingPolarity[whoAmI] = ShouldDrawPolarity(npc); + return true; + } + + private static void ResetParameters(NPC npc) + { + if (npc is null) + return; + var whoAmI = npc.whoAmI; + DrawingMiracleBlight[whoAmI] = false; + DrawingPolarity[whoAmI] = false; + } + + private static bool ShouldDrawMiracleBlight(NPC npc) + { + if (npc is null || !npc.active) + return false; + // Safety check for weird MP bug when getting global npcs. + if (!npc.TryGetGlobalNPCSafer(out var calNPC) || !npc.TryGetGlobalNPCSafer(out var polNPC)) + return false; + // Do not draw if the npc does not have miracle blight, or has the polarity effect. + if (calNPC.miracleBlight <= 0 || polNPC.CurPolarity > 0f) + return false; + // Do not draw if the current player has the trippy effect. + if (Main.LocalPlayer.Calamity().trippy) + return false; + return true; + } + + private static bool ShouldDrawPolarity(NPC npc) + { + if (npc is null || !npc.active) + return false; + // Safety check for weird MP bug when getting global npcs. + if (!npc.TryGetGlobalNPCSafer(out var calNPC) || !npc.TryGetGlobalNPCSafer(out var polNPC)) + return false; + // I don't know who would be using this while also inflicting miracle blight, but in that rare case, do not draw these. + if (calNPC.miracleBlight > 0) + return false; + // Do not draw if the npc doesn't have the polarity effect. + if (polNPC.CurPolarity <= 0f) + return false; + return true; + } + } +} diff --git a/NPCs/CalamityPolarityNPC.cs b/NPCs/CalamityPolarityNPC.cs index b414c40154..62389ac49f 100644 --- a/NPCs/CalamityPolarityNPC.cs +++ b/NPCs/CalamityPolarityNPC.cs @@ -96,7 +96,7 @@ public void HandlePulses() public override void PostDraw(NPC npc, SpriteBatch spriteBatch, Vector2 screenPos, Color drawColor) { // I don't know who would be using this while also inflicting miracle blight, but in that rare case, do not draw these. - if (npc.Calamity().miracleBlight > 0) + if (CalamityDrawParameterNPC.DrawingMiracleBlight[npc.whoAmI]) return; Main.spriteBatch.End(); diff --git a/Utilities/GlobalEntityUtils.cs b/Utilities/GlobalEntityUtils.cs new file mode 100644 index 0000000000..ff5a022bfc --- /dev/null +++ b/Utilities/GlobalEntityUtils.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Terraria.ModLoader; +using Terraria; + +namespace CalamityMod +{ + public static partial class CalamityUtils + { + /// + /// Actual "Thread-Safe" version of TryGetGlobalNPC + /// + /// GlobalNPC type to get + /// Input NPC + /// GlobalNPC output + /// true If we successfully get GlobalNPC. otherwise false + public static bool TryGetGlobalNPCSafer(this NPC npc, out T globalNPC) where T : GlobalNPC + { + try + { + if (npc is null) + { + globalNPC = null; + return false; + } + + int slot = ModContent.GetInstance()?.PerEntityIndex ?? -1; + int length = npc.EntityGlobals.Length; + if (slot < 0 || slot >= length) + { + globalNPC = null; + return false; + } + npc.TryGetGlobalNPC(out globalNPC); + return globalNPC != null; + } + catch + { + globalNPC = null; + return false; + } + } + } +} diff --git a/build.txt b/build.txt index cf9028fcf7..ed16d2e562 100644 --- a/build.txt +++ b/build.txt @@ -1,5 +1,5 @@ author = Fabsol and the Dev Team -version = 2.0.4.003 +version = 2.0.4.004 displayName = Calamity Mod modReferences = CalamityModMusic homepage = https://discord.gg/calamity From 90b92f88b06ab00bfd0a5283cb5e1bdf8de07f99 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Thu, 31 Oct 2024 23:06:03 -0500 Subject: [PATCH 191/401] Pretty sure this is everything, once again. I'll release this in an hour or something. --- CalPlayer/CalamityPlayer.cs | 9 +- CalPlayer/CalamityPlayerMiscEffects.cs | 3 + CalamityNetcode.cs | 24 ++ .../DyeableShadersRenderer.cs | 50 +++-- Graphics/Renderers/RendererManager.cs | 24 +- .../en-US/Mods.CalamityMod.Misc.hjson | 1 + NPCs/CalamityNetImportantNPC.cs | 211 ++++++++++++++++++ Utilities/DrawingUtils.cs | 36 ++- Utilities/NPCUtils.cs | 10 + build.txt | 2 +- 10 files changed, 348 insertions(+), 22 deletions(-) create mode 100644 NPCs/CalamityNetImportantNPC.cs diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index cb4fca8350..084a918902 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -4879,8 +4879,15 @@ public override void OnEnterWorld() if (CalamityConfig.Instance.SpeedrunTimer) CalamityMod.SpeedrunTimer.Restart(); + // + // 31OCT2024: Fabsol: Added a temporary message for the Gimme Swag plushie campaign. + // This message should not exist indefinitely. It is being pushed as a silent public update just for itself. + // As this message always displays and is not configurable, the previous rules about startup messages have been replaced with always-true. + // + // Set a random delay between 12 and 20 seconds. When this delay hits zero, startup messages display - if (CalamityConfig.Instance.WikiStatusMessage) + bool plushieMessage = true; + if (plushieMessage || CalamityConfig.Instance.WikiStatusMessage) { startMessageDisplayDelay = Main.rand.Next(CalamityUtils.SecondsToFrames(12), CalamityUtils.SecondsToFrames(20) + 1); } diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index 1dac773f1d..a3ed869174 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -4168,6 +4168,9 @@ private void HandleTextChatMessages() CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.WikiStatus1"); CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.WikiStatus2"); } + + // 31OCT2024: Fabsol: Plushie message always appears. + CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.GimmeSwagPlushieCampaign"); } --startMessageDisplayDelay; diff --git a/CalamityNetcode.cs b/CalamityNetcode.cs index c498f8c37c..1ddc123fe0 100644 --- a/CalamityNetcode.cs +++ b/CalamityNetcode.cs @@ -193,6 +193,29 @@ public static void HandlePacket(Mod mod, BinaryReader reader, int whoAmI) } break; + case CalamityModMessageType.SyncNPCPosAndRotOnly: + npcIndex = reader.ReadByte(); + Vector2 position = reader.ReadVector2(); + float rotation = (float)reader.ReadHalf(); //rotation unit is radian (-π/2 ≤ rotation ≤ π/2) so Half precision should works + + if (npcIndex >= Main.maxNPCs) + break; + + npc = Main.npc[npcIndex]; + npc.position = position; + npc.rotation = rotation; + + if (Main.dedServ) + { + ModPacket packet = CalamityMod.Instance.GetPacket(); + packet.Write((byte)CalamityModMessageType.SyncNPCPosAndRotOnly); + packet.Write((byte)npcIndex); + packet.WriteVector2(position); + packet.Write((Half)rotation); + packet.Send(ignoreClient: whoAmI); + } + break; + // // Tile Entities // @@ -400,6 +423,7 @@ public enum CalamityModMessageType : byte // General things for entities SpawnNPCOnPlayer, SyncNPCMotionDataToServer, + SyncNPCPosAndRotOnly, // Tile Entities PowerCellFactory, diff --git a/Graphics/Renderers/CalamityRenderers/DyeableShadersRenderer.cs b/Graphics/Renderers/CalamityRenderers/DyeableShadersRenderer.cs index f01c539a2f..d0570d372e 100644 --- a/Graphics/Renderers/CalamityRenderers/DyeableShadersRenderer.cs +++ b/Graphics/Renderers/CalamityRenderers/DyeableShadersRenderer.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using CalamityMod.DataStructures; @@ -36,19 +37,13 @@ public static Dictionary Dyes #region Loading public override void Load() { - if (Main.netMode == NetmodeID.Server) - return; - - Targets = new(); - Dyes = new(); - RenderersToDrawThisFrame = new(); + Targets = []; + Dyes = []; + RenderersToDrawThisFrame = []; } public override void Unload() { - if (Main.netMode == NetmodeID.Server) - return; - Targets = null; Dyes = null; RenderersToDrawThisFrame = null; @@ -60,6 +55,9 @@ internal static void FindDyesDetour(On_Player.orig_UpdateItemDye orig, Player se { orig(self, isNotInVanitySlot, isSetToHidden, armorItem, dyeItem); + if (Main.dedServ) + return; + if (armorItem.ModItem is not IDyeableShaderRenderer drawer) return; @@ -70,12 +68,20 @@ internal static void FindDyesDetour(On_Player.orig_UpdateItemDye orig, Player se internal static void CheckVanityDetour(On_Player.orig_ApplyEquipVanity_Item orig, Player self, Item currentItem) { orig(self, currentItem); + + if (Main.dedServ) + return; + CheckIfEquipIsValid(currentItem, false); } internal static void CheckAccessoryDetour(On_Player.orig_ApplyEquipFunctional orig, Player self, Item currentItem, bool hideVisual) { orig(self, currentItem, hideVisual); + + if (Main.dedServ) + return; + CheckIfEquipIsValid(currentItem, hideVisual); } @@ -83,6 +89,9 @@ internal static void CheckArmorSetsDetour(On_Player.orig_UpdateArmorSets orig, P { orig(self, i); + if (Main.dedServ) + return; + // Check each armor piece in the same manner as tMod. // If the entire set is equipped, and it is a renderer, it will be marked as valid. Item head = self.armor[0]; @@ -103,6 +112,9 @@ internal static void CheckArmorSetsDetour(On_Player.orig_UpdateArmorSets orig, P private static void CheckIfEquipIsValid(Item item, bool hideVisual) { + if (Main.dedServ) + return; + // Difficulty mode checks. if ((item.expertOnly && !Main.expertMode) || (item.masterOnly && !Main.masterMode)) return; @@ -120,9 +132,15 @@ private static void CheckIfEquipIsValid(Item item, bool hideVisual) private static void MarkAsValid(IDyeableShaderRenderer renderer) { - // If it doesn't have a dictonary entry, create one. - if (!Targets.ContainsKey(renderer)) - Main.QueueMainThreadAction(() => Targets[renderer] = new(true, ManagedRenderTarget.CreateScreenSizedTarget)); + if (Main.dedServ) + return; + + Main.QueueMainThreadAction(() => + { + // If it doesn't have a dictonary entry, create one. + if (!Targets.ContainsKey(renderer)) + Main.QueueMainThreadAction(() => Targets[renderer] = new(true, ManagedRenderTarget.CreateScreenSizedTarget)); + }); // Mark this item as drawable this frame. RenderersToDrawThisFrame.AddWithCondition(renderer, renderer.ShouldDrawDyeableShader); @@ -131,10 +149,13 @@ private static void MarkAsValid(IDyeableShaderRenderer renderer) #region Updates/Drawing // Clear the list at the beginning of each update, to ensure its only populated by correct ones. - public override void PreUpdate() => RenderersToDrawThisFrame.Clear(); + public override void PreUpdate() => RenderersToDrawThisFrame?.Clear(); public override void DrawToTarget(SpriteBatch spriteBatch) { + if (Main.dedServ) + return; + // Leave if nothing to draw. if (!RenderersToDrawThisFrame.Any()) return; @@ -155,6 +176,9 @@ public override void DrawToTarget(SpriteBatch spriteBatch) public override void DrawTarget(SpriteBatch spriteBatch) { + if (Main.dedServ) + return; + // Leave if nothing to draw. if (!RenderersToDrawThisFrame.Any()) return; diff --git a/Graphics/Renderers/RendererManager.cs b/Graphics/Renderers/RendererManager.cs index 4844fd81cb..eac7f8ce96 100644 --- a/Graphics/Renderers/RendererManager.cs +++ b/Graphics/Renderers/RendererManager.cs @@ -83,7 +83,7 @@ private void DrawToTargets(On_Main.orig_CheckMonoliths orig) { orig(); - if (Main.gameMenu) + if (Main.gameMenu || Main.dedServ) return; foreach (var renderer in Renderers) @@ -91,10 +91,24 @@ private void DrawToTargets(On_Main.orig_CheckMonoliths orig) if (!renderer.ShouldDraw) continue; - renderer.MainTarget.SwapTo(Color.Transparent); - Main.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, Main.Rasterizer, null, Main.GameViewMatrix.TransformationMatrix); - renderer.DrawToTarget(Main.spriteBatch); - Main.spriteBatch.End(); + try + { + renderer.MainTarget.SwapTo(Color.Transparent); + Main.spriteBatch.TryBegin(SpriteSortMode.Deferred, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, Main.Rasterizer, null, Main.GameViewMatrix.TransformationMatrix); + renderer.DrawToTarget(Main.spriteBatch); + } + catch (Exception e) + { + Main.QueueMainThreadAction(() => + { + CalamityMod.Instance.Logger.Error($"Exception Found on RenderDetour: {e}"); + }); + } + finally + { + // Always end the Batch! + Main.spriteBatch.TryEnd(); + } } Main.instance.GraphicsDevice.SetRenderTarget(null); diff --git a/Localization/en-US/Mods.CalamityMod.Misc.hjson b/Localization/en-US/Mods.CalamityMod.Misc.hjson index 4a836bc149..c672e49428 100644 --- a/Localization/en-US/Mods.CalamityMod.Misc.hjson +++ b/Localization/en-US/Mods.CalamityMod.Misc.hjson @@ -21,6 +21,7 @@ RecipeGroup: { // Status WikiStatus1: "[i:Book] [c/EE4939:Note: The Fandom wiki is no longer supported by Calamity.] [i:Book]" WikiStatus2: "[i:Book] [c/EE4939:Check out the Official Calamity Mod Wiki at ][c/3989FF:calamitymod.wiki.gg][c/EE4939:!] [i:Book]" +GimmeSwagPlushieCampaign: "[i:GreenPresent] [c/3BE022:NOW AVAILABLE! Yharon Plushie!] [c/3989FF:calamitymod.com/plush] [i:GreenPresent]" // Recipe Conditions Tier1ArsenalRecipeCondition: View an unencrypted schematic from the lab near the Sunken Sea Tier2ArsenalRecipeCondition: Decrypt a schematic from the lab in the large planetoid in the sky diff --git a/NPCs/CalamityNetImportantNPC.cs b/NPCs/CalamityNetImportantNPC.cs new file mode 100644 index 0000000000..e934ad3c50 --- /dev/null +++ b/NPCs/CalamityNetImportantNPC.cs @@ -0,0 +1,211 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using CalamityMod.NPCs.Abyss; +using CalamityMod.NPCs.AcidRain; +using CalamityMod.NPCs.AquaticScourge; +using CalamityMod.NPCs.AstrumDeus; +using CalamityMod.NPCs.CalClone; +using CalamityMod.NPCs.Cryogen; +using CalamityMod.NPCs.DesertScourge; +using CalamityMod.NPCs.DevourerofGods; +using CalamityMod.NPCs.ExoMechs; +using CalamityMod.NPCs.ExoMechs.Apollo; +using CalamityMod.NPCs.ExoMechs.Ares; +using CalamityMod.NPCs.ExoMechs.Artemis; +using CalamityMod.NPCs.ExoMechs.Thanatos; +using CalamityMod.NPCs.Leviathan; +using CalamityMod.NPCs.NormalNPCs; +using CalamityMod.NPCs.Perforator; +using CalamityMod.NPCs.PrimordialWyrm; +using CalamityMod.NPCs.ProfanedGuardians; +using CalamityMod.NPCs.Providence; +using CalamityMod.NPCs.StormWeaver; +using CalamityMod.NPCs.SupremeCalamitas; +using Microsoft.Xna.Framework; +using Terraria; +using Terraria.Chat; +using Terraria.DataStructures; +using Terraria.ID; +using Terraria.Localization; +using Terraria.ModLoader; + +namespace CalamityMod.NPCs +{ + public sealed class CalamityNetImportantNPC : GlobalNPC + { + private static Dictionary typesToUpdate; + + public override void Load() + { + typesToUpdate = new(); + } + + public override void Unload() + { + typesToUpdate?.Clear(); + typesToUpdate = null; + } + + public override void SetStaticDefaults() + { + #region Vanilla Enemies + MarkNPCToNetImportant(NPCID.EaterofWorldsHead); + MarkNPCToNetImportant(NPCID.EaterofWorldsBody); + MarkNPCToNetImportant(NPCID.EaterofWorldsTail); + + MarkNPCToNetImportant(NPCID.TheDestroyer); + MarkNPCToNetImportant(NPCID.TheDestroyerBody); + MarkNPCToNetImportant(NPCID.TheDestroyerTail); + #endregion Vanilla Enemies + + + + #region Pre Hardmode + MarkNPCToNetImportant(netUpdateTickOffset: 1); + MarkNPCToNetImportant(netUpdateTickOffset: 1); + MarkNPCToNetImportant(netUpdateTickOffset: 1); + + MarkNPCToNetImportant(netUpdateTickOffset: 2); + MarkNPCToNetImportant(netUpdateTickOffset: 2); + MarkNPCToNetImportant(netUpdateTickOffset: 2); + + MarkNPCToNetImportant(netUpdateTickOffset: 3); + MarkNPCToNetImportant(netUpdateTickOffset: 3); + MarkNPCToNetImportant(netUpdateTickOffset: 3); + + MarkNPCToNetImportant(netUpdateTickOffset: 1); + MarkNPCToNetImportant(netUpdateTickOffset: 1); + MarkNPCToNetImportant(netUpdateTickOffset: 1); + + MarkNPCToNetImportant(netUpdateTickOffset: 2); + MarkNPCToNetImportant(netUpdateTickOffset: 2); + MarkNPCToNetImportant(netUpdateTickOffset: 2); + + MarkNPCToNetImportant(netUpdateTickOffset: 3); + MarkNPCToNetImportant(netUpdateTickOffset: 3); + MarkNPCToNetImportant(netUpdateTickOffset: 3); + #endregion Pre Hardmode + + + + #region Hardmode + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + #endregion Hardmode + + + + #region Post ML + MarkNPCToNetImportant(netUpdateTickOffset: 1); + MarkNPCToNetImportant(netUpdateTickOffset: 1); + MarkNPCToNetImportant(netUpdateTickOffset: 1); + + MarkNPCToNetImportant(netUpdateTickOffset: 2); + MarkNPCToNetImportant(netUpdateTickOffset: 2); + MarkNPCToNetImportant(netUpdateTickOffset: 2); + + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + #endregion Post ML + + + #region Calamitas Boss + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + #endregion + + + #region Draedon Boss + MarkNPCToNetImportant(); + + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + #endregion Draedon Boss + + + + #region Abyss + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + + MarkNPCToNetImportant(netUpdateTickOffset: 1); + MarkNPCToNetImportant(netUpdateTickOffset: 1); + MarkNPCToNetImportant(netUpdateTickOffset: 1); + MarkNPCToNetImportant(netUpdateTickOffset: 1); + + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + + MarkNPCToNetImportant(netUpdateTickOffset: 2); + MarkNPCToNetImportant(netUpdateTickOffset: 2); + MarkNPCToNetImportant(netUpdateTickOffset: 2); + MarkNPCToNetImportant(netUpdateTickOffset: 2); + #endregion Abyss + } + + public override void PostAI(NPC npc) + { + // Only Server should update this! + if (!Main.dedServ) + return; + + // Obviously deactived npc is not on our interest (not sure if this is case though) + if (!npc.active) + return; + + if (!typesToUpdate.TryGetValue(npc.type, out var netUpdateTickOffset)) + return; + + if ((Main.GameUpdateCount + netUpdateTickOffset) % 45 != 0) + return; + + foreach (var player in Main.ActivePlayers) + { + // distance between 1000~1500 update with 8 tick period + // and distance over 1500 will never update + // So we forcely update NPC distanced over 1500 with 45 tick period + float distance = CalamityUtils.ManhattanDistance(player.position, npc.position); + if (distance <= 1499.0f) + continue; + + npc.SyncNPCPosAndRotOnly(); //Light-weight version to sync it's position + } + } + + private void MarkNPCToNetImportant(int netUpdateTickOffset = 0) where NPCType : ModNPC + { + MarkNPCToNetImportant(ModContent.NPCType(), netUpdateTickOffset); + } + + private void MarkNPCToNetImportant(int npcType, int netUpdateTickOffset = 0) + { + typesToUpdate[npcType] = netUpdateTickOffset; + } + } +} diff --git a/Utilities/DrawingUtils.cs b/Utilities/DrawingUtils.cs index 0b541aa8ec..0c18da9cc3 100644 --- a/Utilities/DrawingUtils.cs +++ b/Utilities/DrawingUtils.cs @@ -335,7 +335,7 @@ public static void SetBlendState(this SpriteBatch spriteBatch, BlendState blendS } // Cached for efficiency purposes. - internal static readonly FieldInfo BeginEndPairField = typeof(SpriteBatch).GetField("inBeginEndPair", BindingFlags.NonPublic | BindingFlags.Instance); + internal static readonly FieldInfo BeginCalled = typeof(SpriteBatch).GetField("beginCalled", BindingFlags.NonPublic | BindingFlags.Instance); /// /// Determines if a is in a lock due to a call. @@ -343,7 +343,39 @@ public static void SetBlendState(this SpriteBatch spriteBatch, BlendState blendS /// The sprite batch to check. public static bool HasBeginBeenCalled(this SpriteBatch spriteBatch) { - return (bool)BeginEndPairField.GetValue(spriteBatch); + return (bool)BeginCalled.GetValue(spriteBatch); + } + + public static bool TryBegin(this SpriteBatch spriteBatch, SpriteSortMode sortMode, + BlendState blendState, + SamplerState samplerState, + DepthStencilState depthStencilState, + RasterizerState rasterizerState, + Effect effect, + Matrix transformMatrix) + { + if (spriteBatch.HasBeginBeenCalled()) + { + return false; + } + else + { + spriteBatch.Begin(sortMode, blendState, samplerState, depthStencilState, rasterizerState, effect, transformMatrix); + return true; + } + } + + public static bool TryEnd(this SpriteBatch spriteBatch) + { + if (!spriteBatch.HasBeginBeenCalled()) + { + return false; + } + else + { + spriteBatch.End(); + return true; + } } /// diff --git a/Utilities/NPCUtils.cs b/Utilities/NPCUtils.cs index 719631c115..3381b44096 100644 --- a/Utilities/NPCUtils.cs +++ b/Utilities/NPCUtils.cs @@ -310,6 +310,16 @@ public static void SyncMotionToServer(this NPC npc) netMessage.Send(); } + public static void SyncNPCPosAndRotOnly(this NPC npc) + { + ModPacket packet = CalamityMod.Instance.GetPacket(); + packet.Write((byte)CalamityModMessageType.SyncNPCPosAndRotOnly); + packet.Write((byte)npc.whoAmI); + packet.WriteVector2(npc.position); + packet.Write((Half)npc.rotation); + packet.Send(); + } + /// /// Syncs . This exists to sync the Destroyer's lasers so that the telegraphs and segment colors display properly. /// diff --git a/build.txt b/build.txt index ed16d2e562..d398b44e3d 100644 --- a/build.txt +++ b/build.txt @@ -1,5 +1,5 @@ author = Fabsol and the Dev Team -version = 2.0.4.004 +version = 2.0.4.005 displayName = Calamity Mod modReferences = CalamityModMusic homepage = https://discord.gg/calamity From 8b13708027e8928f5db0717b22e2a477d11fe4f6 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Fri, 1 Nov 2024 00:26:28 -0500 Subject: [PATCH 192/401] CalamityNetImportantNPC now uses Attribute. --- NPCs/Abyss/BobbitWormHead.cs | 1 + NPCs/Abyss/BobbitWormSegment.cs | 1 + NPCs/Abyss/EidolonWyrmBody.cs | 1 + NPCs/Abyss/EidolonWyrmBodyAlt.cs | 1 + NPCs/Abyss/EidolonWyrmHead.cs | 1 + NPCs/Abyss/EidolonWyrmTail.cs | 1 + NPCs/Abyss/GulperEelBody.cs | 1 + NPCs/Abyss/GulperEelBodyAlt.cs | 1 + NPCs/Abyss/GulperEelHead.cs | 1 + NPCs/Abyss/GulperEelTail.cs | 1 + NPCs/Abyss/OarfishBody.cs | 1 + NPCs/Abyss/OarfishHead.cs | 1 + NPCs/Abyss/OarfishTail.cs | 1 + NPCs/AquaticScourge/AquaticScourgeBody.cs | 1 + NPCs/AquaticScourge/AquaticScourgeBodyAlt.cs | 1 + NPCs/AquaticScourge/AquaticScourgeHead.cs | 1 + NPCs/AquaticScourge/AquaticScourgeTail.cs | 1 + NPCs/AstrumDeus/AstrumDeusBody.cs | 1 + NPCs/AstrumDeus/AstrumDeusHead.cs | 1 + NPCs/AstrumDeus/AstrumDeusTail.cs | 1 + NPCs/CalamityNetImportantNPC.cs | 196 +++++------------- NPCs/Cryogen/Cryogen.cs | 1 + NPCs/Cryogen/CryogenShield.cs | 1 + NPCs/DesertScourge/DesertNuisanceBody.cs | 1 + NPCs/DesertScourge/DesertNuisanceBodyYoung.cs | 1 + NPCs/DesertScourge/DesertNuisanceHead.cs | 1 + NPCs/DesertScourge/DesertNuisanceHeadYoung.cs | 1 + NPCs/DesertScourge/DesertNuisanceTail.cs | 1 + NPCs/DesertScourge/DesertNuisanceTailYoung.cs | 1 + NPCs/DesertScourge/DesertScourgeBody.cs | 1 + NPCs/DesertScourge/DesertScourgeHead.cs | 1 + NPCs/DesertScourge/DesertScourgeTail.cs | 1 + NPCs/DevourerofGods/CosmicGuardianBody.cs | 1 + NPCs/DevourerofGods/CosmicGuardianHead.cs | 1 + NPCs/DevourerofGods/CosmicGuardianTail.cs | 1 + NPCs/DevourerofGods/DevourerofGodsBody.cs | 1 + NPCs/DevourerofGods/DevourerofGodsHead.cs | 1 + NPCs/DevourerofGods/DevourerofGodsTail.cs | 1 + NPCs/ExoMechs/Draedon.cs | 1 + NPCs/ExoMechs/Thanatos/ThanatosBody1.cs | 1 + NPCs/ExoMechs/Thanatos/ThanatosBody2.cs | 1 + NPCs/ExoMechs/Thanatos/ThanatosHead.cs | 1 + NPCs/ExoMechs/Thanatos/ThanatosTail.cs | 1 + NPCs/LongDistanceNetSyncAttribute.cs | 27 +++ NPCs/NormalNPCs/ArmoredDiggerBody.cs | 1 + NPCs/NormalNPCs/ArmoredDiggerHead.cs | 1 + NPCs/NormalNPCs/ArmoredDiggerTail.cs | 1 + NPCs/Perforator/PerforatorBodyLarge.cs | 1 + NPCs/Perforator/PerforatorBodyMedium.cs | 1 + NPCs/Perforator/PerforatorBodySmall.cs | 1 + NPCs/Perforator/PerforatorHeadLarge.cs | 1 + NPCs/Perforator/PerforatorHeadMedium.cs | 1 + NPCs/Perforator/PerforatorHeadSmall.cs | 1 + NPCs/Perforator/PerforatorTailLarge.cs | 1 + NPCs/Perforator/PerforatorTailMedium.cs | 1 + NPCs/Perforator/PerforatorTailSmall.cs | 1 + NPCs/PrimordialWyrm/PrimordialWyrmBody.cs | 1 + NPCs/PrimordialWyrm/PrimordialWyrmBodyAlt.cs | 1 + NPCs/PrimordialWyrm/PrimordialWyrmHead.cs | 1 + NPCs/PrimordialWyrm/PrimordialWyrmTail.cs | 1 + NPCs/StormWeaver/StormWeaverBody.cs | 1 + NPCs/StormWeaver/StormWeaverHead.cs | 1 + NPCs/StormWeaver/StormWeaverTail.cs | 1 + NPCs/SupremeCalamitas/SepulcherBody.cs | 1 + NPCs/SupremeCalamitas/SepulcherHead.cs | 1 + NPCs/SupremeCalamitas/SepulcherTail.cs | 1 + 66 files changed, 146 insertions(+), 141 deletions(-) create mode 100644 NPCs/LongDistanceNetSyncAttribute.cs diff --git a/NPCs/Abyss/BobbitWormHead.cs b/NPCs/Abyss/BobbitWormHead.cs index ce50cbf3a2..67b57b3feb 100644 --- a/NPCs/Abyss/BobbitWormHead.cs +++ b/NPCs/Abyss/BobbitWormHead.cs @@ -13,6 +13,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync] public class BobbitWormHead : ModNPC { public override void SetStaticDefaults() diff --git a/NPCs/Abyss/BobbitWormSegment.cs b/NPCs/Abyss/BobbitWormSegment.cs index aad563ed48..5b65b917d6 100644 --- a/NPCs/Abyss/BobbitWormSegment.cs +++ b/NPCs/Abyss/BobbitWormSegment.cs @@ -7,6 +7,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync(SyncWith = typeof(BobbitWormHead))] public class BobbitWormSegment : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.BobbitWormHead.DisplayName"); diff --git a/NPCs/Abyss/EidolonWyrmBody.cs b/NPCs/Abyss/EidolonWyrmBody.cs index 5e0b418ef0..3e9c9058ea 100644 --- a/NPCs/Abyss/EidolonWyrmBody.cs +++ b/NPCs/Abyss/EidolonWyrmBody.cs @@ -9,6 +9,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync(SyncWith = typeof(EidolonWyrmHead))] public class EidolonWyrmBody : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.EidolonWyrmHead.DisplayName"); diff --git a/NPCs/Abyss/EidolonWyrmBodyAlt.cs b/NPCs/Abyss/EidolonWyrmBodyAlt.cs index 9e31e16946..b2ce430dea 100644 --- a/NPCs/Abyss/EidolonWyrmBodyAlt.cs +++ b/NPCs/Abyss/EidolonWyrmBodyAlt.cs @@ -9,6 +9,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync(SyncWith = typeof(EidolonWyrmHead))] public class EidolonWyrmBodyAlt : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.EidolonWyrmHead.DisplayName"); diff --git a/NPCs/Abyss/EidolonWyrmHead.cs b/NPCs/Abyss/EidolonWyrmHead.cs index b7b311396f..87e85a233e 100644 --- a/NPCs/Abyss/EidolonWyrmHead.cs +++ b/NPCs/Abyss/EidolonWyrmHead.cs @@ -26,6 +26,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync] public class EidolonWyrmHead : ModNPC { private Vector2 patrolSpot = Vector2.Zero; diff --git a/NPCs/Abyss/EidolonWyrmTail.cs b/NPCs/Abyss/EidolonWyrmTail.cs index 78045ad275..6cc97cb4ce 100644 --- a/NPCs/Abyss/EidolonWyrmTail.cs +++ b/NPCs/Abyss/EidolonWyrmTail.cs @@ -9,6 +9,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync(SyncWith = typeof(EidolonWyrmHead))] public class EidolonWyrmTail : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.EidolonWyrmHead.DisplayName"); diff --git a/NPCs/Abyss/GulperEelBody.cs b/NPCs/Abyss/GulperEelBody.cs index 819cae17cd..29a0c69184 100644 --- a/NPCs/Abyss/GulperEelBody.cs +++ b/NPCs/Abyss/GulperEelBody.cs @@ -11,6 +11,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync(SyncWith = typeof(GulperEelHead))] public class GulperEelBody : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.GulperEelHead.DisplayName"); diff --git a/NPCs/Abyss/GulperEelBodyAlt.cs b/NPCs/Abyss/GulperEelBodyAlt.cs index 73d68d7b0f..db6035b539 100644 --- a/NPCs/Abyss/GulperEelBodyAlt.cs +++ b/NPCs/Abyss/GulperEelBodyAlt.cs @@ -11,6 +11,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync(SyncWith = typeof(GulperEelHead))] public class GulperEelBodyAlt : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.GulperEelHead.DisplayName"); diff --git a/NPCs/Abyss/GulperEelHead.cs b/NPCs/Abyss/GulperEelHead.cs index 395fc3d696..161506e481 100644 --- a/NPCs/Abyss/GulperEelHead.cs +++ b/NPCs/Abyss/GulperEelHead.cs @@ -16,6 +16,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync] public class GulperEelHead : ModNPC { private Vector2 patrolSpot = Vector2.Zero; diff --git a/NPCs/Abyss/GulperEelTail.cs b/NPCs/Abyss/GulperEelTail.cs index 8c0444d4c1..e06996e52c 100644 --- a/NPCs/Abyss/GulperEelTail.cs +++ b/NPCs/Abyss/GulperEelTail.cs @@ -11,6 +11,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync(SyncWith = typeof(GulperEelHead))] public class GulperEelTail : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.GulperEelHead.DisplayName"); diff --git a/NPCs/Abyss/OarfishBody.cs b/NPCs/Abyss/OarfishBody.cs index 2849ab2efa..b45a50ba27 100644 --- a/NPCs/Abyss/OarfishBody.cs +++ b/NPCs/Abyss/OarfishBody.cs @@ -7,6 +7,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync(SyncWith = typeof(OarfishHead))] public class OarfishBody : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.OarfishHead.DisplayName"); diff --git a/NPCs/Abyss/OarfishHead.cs b/NPCs/Abyss/OarfishHead.cs index 9459276e5a..db3d69afe7 100644 --- a/NPCs/Abyss/OarfishHead.cs +++ b/NPCs/Abyss/OarfishHead.cs @@ -13,6 +13,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync] public class OarfishHead : ModNPC { private Vector2 patrolSpot = Vector2.Zero; diff --git a/NPCs/Abyss/OarfishTail.cs b/NPCs/Abyss/OarfishTail.cs index eb0ce07f93..4e5c31e528 100644 --- a/NPCs/Abyss/OarfishTail.cs +++ b/NPCs/Abyss/OarfishTail.cs @@ -7,6 +7,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync(SyncWith = typeof(OarfishHead))] public class OarfishTail : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.OarfishHead.DisplayName"); diff --git a/NPCs/AquaticScourge/AquaticScourgeBody.cs b/NPCs/AquaticScourge/AquaticScourgeBody.cs index e7d0565bad..f2a7a7f31b 100644 --- a/NPCs/AquaticScourge/AquaticScourgeBody.cs +++ b/NPCs/AquaticScourge/AquaticScourgeBody.cs @@ -13,6 +13,7 @@ namespace CalamityMod.NPCs.AquaticScourge { + [LongDistanceNetSync(SyncWith = typeof(AquaticScourgeHead))] public class AquaticScourgeBody : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.AquaticScourgeHead.DisplayName"); diff --git a/NPCs/AquaticScourge/AquaticScourgeBodyAlt.cs b/NPCs/AquaticScourge/AquaticScourgeBodyAlt.cs index 6a2871b0a2..85d4d29c40 100644 --- a/NPCs/AquaticScourge/AquaticScourgeBodyAlt.cs +++ b/NPCs/AquaticScourge/AquaticScourgeBodyAlt.cs @@ -13,6 +13,7 @@ namespace CalamityMod.NPCs.AquaticScourge { + [LongDistanceNetSync(SyncWith = typeof(AquaticScourgeHead))] public class AquaticScourgeBodyAlt : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.AquaticScourgeHead.DisplayName"); diff --git a/NPCs/AquaticScourge/AquaticScourgeHead.cs b/NPCs/AquaticScourge/AquaticScourgeHead.cs index 01e9e94ab5..0b4cc334fa 100644 --- a/NPCs/AquaticScourge/AquaticScourgeHead.cs +++ b/NPCs/AquaticScourge/AquaticScourgeHead.cs @@ -33,6 +33,7 @@ namespace CalamityMod.NPCs.AquaticScourge { [AutoloadBossHead] + [LongDistanceNetSync] public class AquaticScourgeHead : ModNPC { public override void SetStaticDefaults() diff --git a/NPCs/AquaticScourge/AquaticScourgeTail.cs b/NPCs/AquaticScourge/AquaticScourgeTail.cs index 5b7217d8c0..c7cd744e25 100644 --- a/NPCs/AquaticScourge/AquaticScourgeTail.cs +++ b/NPCs/AquaticScourge/AquaticScourgeTail.cs @@ -13,6 +13,7 @@ namespace CalamityMod.NPCs.AquaticScourge { + [LongDistanceNetSync(SyncWith = typeof(AquaticScourgeHead))] public class AquaticScourgeTail : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.AquaticScourgeHead.DisplayName"); diff --git a/NPCs/AstrumDeus/AstrumDeusBody.cs b/NPCs/AstrumDeus/AstrumDeusBody.cs index dfc682dcb0..29d3848680 100644 --- a/NPCs/AstrumDeus/AstrumDeusBody.cs +++ b/NPCs/AstrumDeus/AstrumDeusBody.cs @@ -15,6 +15,7 @@ namespace CalamityMod.NPCs.AstrumDeus { + [LongDistanceNetSync(SyncWith = typeof(AstrumDeusHead))] public class AstrumDeusBody : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.AstrumDeusHead.DisplayName"); diff --git a/NPCs/AstrumDeus/AstrumDeusHead.cs b/NPCs/AstrumDeus/AstrumDeusHead.cs index f814c85120..8ec5567827 100644 --- a/NPCs/AstrumDeus/AstrumDeusHead.cs +++ b/NPCs/AstrumDeus/AstrumDeusHead.cs @@ -34,6 +34,7 @@ namespace CalamityMod.NPCs.AstrumDeus { [AutoloadBossHead] + [LongDistanceNetSync] public class AstrumDeusHead : ModNPC { public static readonly SoundStyle SpawnSound = new("CalamityMod/Sounds/Custom/AstrumDeus/AstrumDeusSpawn"); diff --git a/NPCs/AstrumDeus/AstrumDeusTail.cs b/NPCs/AstrumDeus/AstrumDeusTail.cs index 3a3a2f1004..95bb79480f 100644 --- a/NPCs/AstrumDeus/AstrumDeusTail.cs +++ b/NPCs/AstrumDeus/AstrumDeusTail.cs @@ -15,6 +15,7 @@ namespace CalamityMod.NPCs.AstrumDeus { + [LongDistanceNetSync(SyncWith = typeof(AstrumDeusHead))] public class AstrumDeusTail : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.AstrumDeusHead.DisplayName"); diff --git a/NPCs/CalamityNetImportantNPC.cs b/NPCs/CalamityNetImportantNPC.cs index e934ad3c50..065b2138d8 100644 --- a/NPCs/CalamityNetImportantNPC.cs +++ b/NPCs/CalamityNetImportantNPC.cs @@ -1,36 +1,12 @@ using System; using System.Collections.Generic; +using System.CommandLine.Parsing; using System.Linq; -using System.Text; -using System.Threading.Tasks; -using CalamityMod.NPCs.Abyss; -using CalamityMod.NPCs.AcidRain; -using CalamityMod.NPCs.AquaticScourge; -using CalamityMod.NPCs.AstrumDeus; -using CalamityMod.NPCs.CalClone; -using CalamityMod.NPCs.Cryogen; -using CalamityMod.NPCs.DesertScourge; -using CalamityMod.NPCs.DevourerofGods; -using CalamityMod.NPCs.ExoMechs; -using CalamityMod.NPCs.ExoMechs.Apollo; -using CalamityMod.NPCs.ExoMechs.Ares; -using CalamityMod.NPCs.ExoMechs.Artemis; -using CalamityMod.NPCs.ExoMechs.Thanatos; -using CalamityMod.NPCs.Leviathan; -using CalamityMod.NPCs.NormalNPCs; -using CalamityMod.NPCs.Perforator; -using CalamityMod.NPCs.PrimordialWyrm; -using CalamityMod.NPCs.ProfanedGuardians; -using CalamityMod.NPCs.Providence; -using CalamityMod.NPCs.StormWeaver; -using CalamityMod.NPCs.SupremeCalamitas; -using Microsoft.Xna.Framework; +using System.Reflection; using Terraria; -using Terraria.Chat; -using Terraria.DataStructures; using Terraria.ID; -using Terraria.Localization; using Terraria.ModLoader; +using Terraria.ModLoader.Core; namespace CalamityMod.NPCs { @@ -51,122 +27,60 @@ public override void Unload() public override void SetStaticDefaults() { - #region Vanilla Enemies - MarkNPCToNetImportant(NPCID.EaterofWorldsHead); - MarkNPCToNetImportant(NPCID.EaterofWorldsBody); - MarkNPCToNetImportant(NPCID.EaterofWorldsTail); + int uniqueNetOffsetID = 0; - MarkNPCToNetImportant(NPCID.TheDestroyer); - MarkNPCToNetImportant(NPCID.TheDestroyerBody); - MarkNPCToNetImportant(NPCID.TheDestroyerTail); + #region Vanilla Enemies + MarkNPCToLongDistanceSync(NPCID.EaterofWorldsHead, uniqueNetOffsetID); + MarkNPCToLongDistanceSync(NPCID.EaterofWorldsBody, uniqueNetOffsetID); + MarkNPCToLongDistanceSync(NPCID.EaterofWorldsTail, uniqueNetOffsetID); + uniqueNetOffsetID++; + + MarkNPCToLongDistanceSync(NPCID.TheDestroyer, uniqueNetOffsetID); + MarkNPCToLongDistanceSync(NPCID.TheDestroyerBody, uniqueNetOffsetID); + MarkNPCToLongDistanceSync(NPCID.TheDestroyerTail, uniqueNetOffsetID); + uniqueNetOffsetID++; #endregion Vanilla Enemies + var types = AssemblyManager.GetLoadableTypes(CalamityMod.Instance.Code) + .Where(type => !type.IsAbstract && type.IsSubclassOf(typeof(ModNPC))); + // Caching this for better performance + var npcTypeMethod = typeof(ModContent).GetMethod(nameof(ModContent.NPCType)); + var netOffsetTable = new Dictionary(); + foreach (var type in types) + { + try + { + var longDistSync = type.GetCustomAttribute(); + + if (longDistSync == null) + continue; + + var npcTypeActualMethod = npcTypeMethod.MakeGenericMethod(typeArguments: type); + + int npcType = (int)npcTypeActualMethod.Invoke(null, null); + int netOffset = uniqueNetOffsetID; + + Type typeToCheck = longDistSync.SyncWith ?? type; + if (netOffsetTable.TryGetValue(typeToCheck, out int savedUniqueID)) + { + netOffset = savedUniqueID; + } + else + { + netOffsetTable[typeToCheck] = netOffset; + uniqueNetOffsetID++; + } + + MarkNPCToLongDistanceSync(npcType, netOffset); + } + catch (Exception e) + { + CalamityMod.Instance.Logger.Error($"Exception thrown while evaluating type \"{type.Name}\": {e}"); + } + } - #region Pre Hardmode - MarkNPCToNetImportant(netUpdateTickOffset: 1); - MarkNPCToNetImportant(netUpdateTickOffset: 1); - MarkNPCToNetImportant(netUpdateTickOffset: 1); - - MarkNPCToNetImportant(netUpdateTickOffset: 2); - MarkNPCToNetImportant(netUpdateTickOffset: 2); - MarkNPCToNetImportant(netUpdateTickOffset: 2); - - MarkNPCToNetImportant(netUpdateTickOffset: 3); - MarkNPCToNetImportant(netUpdateTickOffset: 3); - MarkNPCToNetImportant(netUpdateTickOffset: 3); - - MarkNPCToNetImportant(netUpdateTickOffset: 1); - MarkNPCToNetImportant(netUpdateTickOffset: 1); - MarkNPCToNetImportant(netUpdateTickOffset: 1); - - MarkNPCToNetImportant(netUpdateTickOffset: 2); - MarkNPCToNetImportant(netUpdateTickOffset: 2); - MarkNPCToNetImportant(netUpdateTickOffset: 2); - - MarkNPCToNetImportant(netUpdateTickOffset: 3); - MarkNPCToNetImportant(netUpdateTickOffset: 3); - MarkNPCToNetImportant(netUpdateTickOffset: 3); - #endregion Pre Hardmode - - - - #region Hardmode - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - #endregion Hardmode - - - - #region Post ML - MarkNPCToNetImportant(netUpdateTickOffset: 1); - MarkNPCToNetImportant(netUpdateTickOffset: 1); - MarkNPCToNetImportant(netUpdateTickOffset: 1); - - MarkNPCToNetImportant(netUpdateTickOffset: 2); - MarkNPCToNetImportant(netUpdateTickOffset: 2); - MarkNPCToNetImportant(netUpdateTickOffset: 2); - - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - #endregion Post ML - - - #region Calamitas Boss - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - #endregion - - - #region Draedon Boss - MarkNPCToNetImportant(); - - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - #endregion Draedon Boss - - - - #region Abyss - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - - MarkNPCToNetImportant(netUpdateTickOffset: 1); - MarkNPCToNetImportant(netUpdateTickOffset: 1); - MarkNPCToNetImportant(netUpdateTickOffset: 1); - MarkNPCToNetImportant(netUpdateTickOffset: 1); - - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - - MarkNPCToNetImportant(netUpdateTickOffset: 2); - MarkNPCToNetImportant(netUpdateTickOffset: 2); - MarkNPCToNetImportant(netUpdateTickOffset: 2); - MarkNPCToNetImportant(netUpdateTickOffset: 2); - #endregion Abyss + netOffsetTable?.Clear(); } public override void PostAI(NPC npc) @@ -198,12 +112,12 @@ public override void PostAI(NPC npc) } } - private void MarkNPCToNetImportant(int netUpdateTickOffset = 0) where NPCType : ModNPC + private static void MarkNPCToLongDistanceSync(int netUpdateTickOffset = 0) where NPCType : ModNPC { - MarkNPCToNetImportant(ModContent.NPCType(), netUpdateTickOffset); + MarkNPCToLongDistanceSync(ModContent.NPCType(), netUpdateTickOffset); } - private void MarkNPCToNetImportant(int npcType, int netUpdateTickOffset = 0) + private static void MarkNPCToLongDistanceSync(int npcType, int netUpdateTickOffset = 0) { typesToUpdate[npcType] = netUpdateTickOffset; } diff --git a/NPCs/Cryogen/Cryogen.cs b/NPCs/Cryogen/Cryogen.cs index 36f0b6388c..b7e63f539d 100644 --- a/NPCs/Cryogen/Cryogen.cs +++ b/NPCs/Cryogen/Cryogen.cs @@ -39,6 +39,7 @@ namespace CalamityMod.NPCs.Cryogen { [AutoloadBossHead] + [LongDistanceNetSync] // Cryogen follows you forever like Queen Bee in vanilla, So we need this to sync it's position on minimap public class Cryogen : ModNPC { private int biomeEnrageTimer = CalamityGlobalNPC.biomeEnrageTimerMax; diff --git a/NPCs/Cryogen/CryogenShield.cs b/NPCs/Cryogen/CryogenShield.cs index d16c2fbb85..11d6978de3 100644 --- a/NPCs/Cryogen/CryogenShield.cs +++ b/NPCs/Cryogen/CryogenShield.cs @@ -11,6 +11,7 @@ namespace CalamityMod.NPCs.Cryogen { + [LongDistanceNetSync(SyncWith = typeof(Cryogen))] public class CryogenShield : ModNPC { public static readonly SoundStyle BreakSound = new("CalamityMod/Sounds/NPCKilled/CryogenShieldBreak"); diff --git a/NPCs/DesertScourge/DesertNuisanceBody.cs b/NPCs/DesertScourge/DesertNuisanceBody.cs index 3498f8fe14..6478a73a20 100644 --- a/NPCs/DesertScourge/DesertNuisanceBody.cs +++ b/NPCs/DesertScourge/DesertNuisanceBody.cs @@ -11,6 +11,7 @@ namespace CalamityMod.NPCs.DesertScourge { + [LongDistanceNetSync(SyncWith = typeof(DesertNuisanceHead))] public class DesertNuisanceBody : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.DesertNuisanceHead.DisplayName"); diff --git a/NPCs/DesertScourge/DesertNuisanceBodyYoung.cs b/NPCs/DesertScourge/DesertNuisanceBodyYoung.cs index 5e9f85ba16..063bb029b5 100644 --- a/NPCs/DesertScourge/DesertNuisanceBodyYoung.cs +++ b/NPCs/DesertScourge/DesertNuisanceBodyYoung.cs @@ -11,6 +11,7 @@ namespace CalamityMod.NPCs.DesertScourge { + [LongDistanceNetSync(SyncWith = typeof(DesertNuisanceHeadYoung))] public class DesertNuisanceBodyYoung : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.DesertNuisanceHeadYoung.DisplayName"); diff --git a/NPCs/DesertScourge/DesertNuisanceHead.cs b/NPCs/DesertScourge/DesertNuisanceHead.cs index 71e547d8f9..329c8abea3 100644 --- a/NPCs/DesertScourge/DesertNuisanceHead.cs +++ b/NPCs/DesertScourge/DesertNuisanceHead.cs @@ -12,6 +12,7 @@ namespace CalamityMod.NPCs.DesertScourge { [AutoloadBossHead] + [LongDistanceNetSync] public class DesertNuisanceHead : ModNPC { private int biomeEnrageTimer = CalamityGlobalNPC.biomeEnrageTimerMax; diff --git a/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs b/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs index e984be408c..e8ae27982d 100644 --- a/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs +++ b/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs @@ -14,6 +14,7 @@ namespace CalamityMod.NPCs.DesertScourge { [AutoloadBossHead] + [LongDistanceNetSync] public class DesertNuisanceHeadYoung : ModNPC { private int biomeEnrageTimer = CalamityGlobalNPC.biomeEnrageTimerMax; diff --git a/NPCs/DesertScourge/DesertNuisanceTail.cs b/NPCs/DesertScourge/DesertNuisanceTail.cs index 709710af2f..4b720426b8 100644 --- a/NPCs/DesertScourge/DesertNuisanceTail.cs +++ b/NPCs/DesertScourge/DesertNuisanceTail.cs @@ -8,6 +8,7 @@ namespace CalamityMod.NPCs.DesertScourge { + [LongDistanceNetSync(SyncWith = typeof(DesertNuisanceHead))] public class DesertNuisanceTail : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.DesertNuisanceHead.DisplayName"); diff --git a/NPCs/DesertScourge/DesertNuisanceTailYoung.cs b/NPCs/DesertScourge/DesertNuisanceTailYoung.cs index c2b49d23c3..ecb1eb5c0b 100644 --- a/NPCs/DesertScourge/DesertNuisanceTailYoung.cs +++ b/NPCs/DesertScourge/DesertNuisanceTailYoung.cs @@ -8,6 +8,7 @@ namespace CalamityMod.NPCs.DesertScourge { + [LongDistanceNetSync(SyncWith = typeof(DesertNuisanceHeadYoung))] public class DesertNuisanceTailYoung : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.DesertNuisanceHeadYoung.DisplayName"); diff --git a/NPCs/DesertScourge/DesertScourgeBody.cs b/NPCs/DesertScourge/DesertScourgeBody.cs index 1d30f4e6ce..2baae9ff4d 100644 --- a/NPCs/DesertScourge/DesertScourgeBody.cs +++ b/NPCs/DesertScourge/DesertScourgeBody.cs @@ -15,6 +15,7 @@ namespace CalamityMod.NPCs.DesertScourge { + [LongDistanceNetSync(SyncWith = typeof(DesertScourgeHead))] public class DesertScourgeBody : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.DesertScourgeHead.DisplayName"); diff --git a/NPCs/DesertScourge/DesertScourgeHead.cs b/NPCs/DesertScourge/DesertScourgeHead.cs index 4cd787ab44..32ed748f47 100644 --- a/NPCs/DesertScourge/DesertScourgeHead.cs +++ b/NPCs/DesertScourge/DesertScourgeHead.cs @@ -32,6 +32,7 @@ namespace CalamityMod.NPCs.DesertScourge { [AutoloadBossHead] + [LongDistanceNetSync] public class DesertScourgeHead : ModNPC { private int biomeEnrageTimer = CalamityGlobalNPC.biomeEnrageTimerMax; diff --git a/NPCs/DesertScourge/DesertScourgeTail.cs b/NPCs/DesertScourge/DesertScourgeTail.cs index 749dd0791a..c0cd5a1bdb 100644 --- a/NPCs/DesertScourge/DesertScourgeTail.cs +++ b/NPCs/DesertScourge/DesertScourgeTail.cs @@ -10,6 +10,7 @@ namespace CalamityMod.NPCs.DesertScourge { + [LongDistanceNetSync(SyncWith = typeof(DesertScourgeHead))] public class DesertScourgeTail : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.DesertScourgeHead.DisplayName"); diff --git a/NPCs/DevourerofGods/CosmicGuardianBody.cs b/NPCs/DevourerofGods/CosmicGuardianBody.cs index 6c0600c59f..a5fb60beb8 100644 --- a/NPCs/DevourerofGods/CosmicGuardianBody.cs +++ b/NPCs/DevourerofGods/CosmicGuardianBody.cs @@ -13,6 +13,7 @@ using Terraria.ModLoader; namespace CalamityMod.NPCs.DevourerofGods { + [LongDistanceNetSync(SyncWith = typeof(CosmicGuardianHead))] public class CosmicGuardianBody : ModNPC { public int invinceTime = 180; diff --git a/NPCs/DevourerofGods/CosmicGuardianHead.cs b/NPCs/DevourerofGods/CosmicGuardianHead.cs index eb7ef94bad..a4e0e2439e 100644 --- a/NPCs/DevourerofGods/CosmicGuardianHead.cs +++ b/NPCs/DevourerofGods/CosmicGuardianHead.cs @@ -15,6 +15,7 @@ namespace CalamityMod.NPCs.DevourerofGods { + [LongDistanceNetSync] public class CosmicGuardianHead : ModNPC { private bool tail = false; diff --git a/NPCs/DevourerofGods/CosmicGuardianTail.cs b/NPCs/DevourerofGods/CosmicGuardianTail.cs index d44bab21c7..125e7eef07 100644 --- a/NPCs/DevourerofGods/CosmicGuardianTail.cs +++ b/NPCs/DevourerofGods/CosmicGuardianTail.cs @@ -13,6 +13,7 @@ using Terraria.ModLoader; namespace CalamityMod.NPCs.DevourerofGods { + [LongDistanceNetSync(SyncWith = typeof(CosmicGuardianHead))] public class CosmicGuardianTail : ModNPC { public int invinceTime = 180; diff --git a/NPCs/DevourerofGods/DevourerofGodsBody.cs b/NPCs/DevourerofGods/DevourerofGodsBody.cs index aff92981bc..c8314094d3 100644 --- a/NPCs/DevourerofGods/DevourerofGodsBody.cs +++ b/NPCs/DevourerofGods/DevourerofGodsBody.cs @@ -20,6 +20,7 @@ namespace CalamityMod.NPCs.DevourerofGods { + [LongDistanceNetSync(SyncWith = typeof(DevourerofGodsHead))] public class DevourerofGodsBody : ModNPC { public static int phase2IconIndex; diff --git a/NPCs/DevourerofGods/DevourerofGodsHead.cs b/NPCs/DevourerofGods/DevourerofGodsHead.cs index 9d5119195f..085b5eff9b 100644 --- a/NPCs/DevourerofGods/DevourerofGodsHead.cs +++ b/NPCs/DevourerofGods/DevourerofGodsHead.cs @@ -44,6 +44,7 @@ namespace CalamityMod.NPCs.DevourerofGods { + [LongDistanceNetSync] public class DevourerofGodsHead : ModNPC { public static int phase1IconIndex; diff --git a/NPCs/DevourerofGods/DevourerofGodsTail.cs b/NPCs/DevourerofGods/DevourerofGodsTail.cs index 36b7a39663..b521baedb1 100644 --- a/NPCs/DevourerofGods/DevourerofGodsTail.cs +++ b/NPCs/DevourerofGods/DevourerofGodsTail.cs @@ -19,6 +19,7 @@ namespace CalamityMod.NPCs.DevourerofGods { + [LongDistanceNetSync(SyncWith = typeof(DevourerofGodsHead))] public class DevourerofGodsTail : ModNPC { public static int phase1IconIndex; diff --git a/NPCs/ExoMechs/Draedon.cs b/NPCs/ExoMechs/Draedon.cs index 623673c9f1..8aaf2a126c 100644 --- a/NPCs/ExoMechs/Draedon.cs +++ b/NPCs/ExoMechs/Draedon.cs @@ -22,6 +22,7 @@ namespace CalamityMod.NPCs.ExoMechs { + [LongDistanceNetSync] public class Draedon : ModNPC { public int KillReappearTextCountdown; diff --git a/NPCs/ExoMechs/Thanatos/ThanatosBody1.cs b/NPCs/ExoMechs/Thanatos/ThanatosBody1.cs index 4dc825f12a..28eb67978c 100644 --- a/NPCs/ExoMechs/Thanatos/ThanatosBody1.cs +++ b/NPCs/ExoMechs/Thanatos/ThanatosBody1.cs @@ -17,6 +17,7 @@ namespace CalamityMod.NPCs.ExoMechs.Thanatos { + [LongDistanceNetSync(SyncWith = typeof(ThanatosHead))] public class ThanatosBody1 : ModNPC { public static int normalIconIndex; diff --git a/NPCs/ExoMechs/Thanatos/ThanatosBody2.cs b/NPCs/ExoMechs/Thanatos/ThanatosBody2.cs index 76c6275344..612ae50f89 100644 --- a/NPCs/ExoMechs/Thanatos/ThanatosBody2.cs +++ b/NPCs/ExoMechs/Thanatos/ThanatosBody2.cs @@ -17,6 +17,7 @@ namespace CalamityMod.NPCs.ExoMechs.Thanatos { + [LongDistanceNetSync(SyncWith = typeof(ThanatosHead))] public class ThanatosBody2 : ModNPC { public static int normalIconIndex; diff --git a/NPCs/ExoMechs/Thanatos/ThanatosHead.cs b/NPCs/ExoMechs/Thanatos/ThanatosHead.cs index 3c7d01279b..1dcbca3bc4 100644 --- a/NPCs/ExoMechs/Thanatos/ThanatosHead.cs +++ b/NPCs/ExoMechs/Thanatos/ThanatosHead.cs @@ -22,6 +22,7 @@ namespace CalamityMod.NPCs.ExoMechs.Thanatos { + [LongDistanceNetSync] public class ThanatosHead : ModNPC { public static int normalIconIndex; diff --git a/NPCs/ExoMechs/Thanatos/ThanatosTail.cs b/NPCs/ExoMechs/Thanatos/ThanatosTail.cs index 23622c7c61..1ceb5d01bc 100644 --- a/NPCs/ExoMechs/Thanatos/ThanatosTail.cs +++ b/NPCs/ExoMechs/Thanatos/ThanatosTail.cs @@ -17,6 +17,7 @@ namespace CalamityMod.NPCs.ExoMechs.Thanatos { + [LongDistanceNetSync(SyncWith = typeof(ThanatosHead))] public class ThanatosTail : ModNPC { public static int normalIconIndex; diff --git a/NPCs/LongDistanceNetSyncAttribute.cs b/NPCs/LongDistanceNetSyncAttribute.cs new file mode 100644 index 0000000000..b66d997580 --- /dev/null +++ b/NPCs/LongDistanceNetSyncAttribute.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Terraria.ModLoader; + +namespace CalamityMod.NPCs +{ + /// + /// This attribute allows ModNPC to always sync for their position and rotation data at least every 45 frames + /// + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] + public sealed class LongDistanceNetSyncAttribute : Attribute + { + /// + /// Syncs this NPC to other NPC's sync frame + /// If this is not present, We cannot properly sync full NPC bodyparts in same frame! (This is important for Worm-type NPCs) + /// + public Type SyncWith { get; set; } = null; + + public LongDistanceNetSyncAttribute() + { + + } + } +} diff --git a/NPCs/NormalNPCs/ArmoredDiggerBody.cs b/NPCs/NormalNPCs/ArmoredDiggerBody.cs index 26296ef13d..9582773fef 100644 --- a/NPCs/NormalNPCs/ArmoredDiggerBody.cs +++ b/NPCs/NormalNPCs/ArmoredDiggerBody.cs @@ -10,6 +10,7 @@ namespace CalamityMod.NPCs.NormalNPCs { + [LongDistanceNetSync(SyncWith = typeof(ArmoredDiggerHead))] public class ArmoredDiggerBody : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.ArmoredDiggerHead.DisplayName"); diff --git a/NPCs/NormalNPCs/ArmoredDiggerHead.cs b/NPCs/NormalNPCs/ArmoredDiggerHead.cs index 1fc942cfb8..70fc0433aa 100644 --- a/NPCs/NormalNPCs/ArmoredDiggerHead.cs +++ b/NPCs/NormalNPCs/ArmoredDiggerHead.cs @@ -13,6 +13,7 @@ namespace CalamityMod.NPCs.NormalNPCs { + [LongDistanceNetSync] public class ArmoredDiggerHead : ModNPC { bool TailSpawned = false; diff --git a/NPCs/NormalNPCs/ArmoredDiggerTail.cs b/NPCs/NormalNPCs/ArmoredDiggerTail.cs index 62104f3a10..b6536f1e61 100644 --- a/NPCs/NormalNPCs/ArmoredDiggerTail.cs +++ b/NPCs/NormalNPCs/ArmoredDiggerTail.cs @@ -9,6 +9,7 @@ namespace CalamityMod.NPCs.NormalNPCs { + [LongDistanceNetSync(SyncWith = typeof(ArmoredDiggerHead))] public class ArmoredDiggerTail : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.ArmoredDiggerHead.DisplayName"); diff --git a/NPCs/Perforator/PerforatorBodyLarge.cs b/NPCs/Perforator/PerforatorBodyLarge.cs index c25aae7727..c824477afd 100644 --- a/NPCs/Perforator/PerforatorBodyLarge.cs +++ b/NPCs/Perforator/PerforatorBodyLarge.cs @@ -13,6 +13,7 @@ namespace CalamityMod.NPCs.Perforator { + [LongDistanceNetSync(SyncWith = typeof(PerforatorHeadLarge))] public class PerforatorBodyLarge : ModNPC { public static readonly SoundStyle HitSound = new("CalamityMod/Sounds/NPCHit/PerfLargeHit", 3); diff --git a/NPCs/Perforator/PerforatorBodyMedium.cs b/NPCs/Perforator/PerforatorBodyMedium.cs index ef764fa9f1..0c274ba469 100644 --- a/NPCs/Perforator/PerforatorBodyMedium.cs +++ b/NPCs/Perforator/PerforatorBodyMedium.cs @@ -15,6 +15,7 @@ namespace CalamityMod.NPCs.Perforator { + [LongDistanceNetSync(SyncWith = typeof(PerforatorHeadMedium))] public class PerforatorBodyMedium : ModNPC { public static readonly SoundStyle HitSound = new("CalamityMod/Sounds/NPCHit/PerfMediumHit", 3); diff --git a/NPCs/Perforator/PerforatorBodySmall.cs b/NPCs/Perforator/PerforatorBodySmall.cs index 08627fc303..a72dcb34be 100644 --- a/NPCs/Perforator/PerforatorBodySmall.cs +++ b/NPCs/Perforator/PerforatorBodySmall.cs @@ -13,6 +13,7 @@ namespace CalamityMod.NPCs.Perforator { + [LongDistanceNetSync(SyncWith = typeof(PerforatorHeadSmall))] public class PerforatorBodySmall : ModNPC { public static readonly SoundStyle HitSound = new("CalamityMod/Sounds/NPCHit/PerfSmallHit", 3); diff --git a/NPCs/Perforator/PerforatorHeadLarge.cs b/NPCs/Perforator/PerforatorHeadLarge.cs index ae4e888120..82a6499720 100644 --- a/NPCs/Perforator/PerforatorHeadLarge.cs +++ b/NPCs/Perforator/PerforatorHeadLarge.cs @@ -17,6 +17,7 @@ namespace CalamityMod.NPCs.Perforator { [AutoloadBossHead] + [LongDistanceNetSync] public class PerforatorHeadLarge : ModNPC { public static readonly SoundStyle HitSound = new("CalamityMod/Sounds/NPCHit/PerfLargeHit", 3); diff --git a/NPCs/Perforator/PerforatorHeadMedium.cs b/NPCs/Perforator/PerforatorHeadMedium.cs index acdb3c712b..9283bbbce1 100644 --- a/NPCs/Perforator/PerforatorHeadMedium.cs +++ b/NPCs/Perforator/PerforatorHeadMedium.cs @@ -16,6 +16,7 @@ namespace CalamityMod.NPCs.Perforator { [AutoloadBossHead] + [LongDistanceNetSync] public class PerforatorHeadMedium : ModNPC { public static readonly SoundStyle HitSound = new("CalamityMod/Sounds/NPCHit/PerfMediumHit", 3); diff --git a/NPCs/Perforator/PerforatorHeadSmall.cs b/NPCs/Perforator/PerforatorHeadSmall.cs index 40a2a555dc..acb6d6318a 100644 --- a/NPCs/Perforator/PerforatorHeadSmall.cs +++ b/NPCs/Perforator/PerforatorHeadSmall.cs @@ -16,6 +16,7 @@ namespace CalamityMod.NPCs.Perforator { [AutoloadBossHead] + [LongDistanceNetSync] public class PerforatorHeadSmall : ModNPC { public static readonly SoundStyle HitSound = new("CalamityMod/Sounds/NPCHit/PerfSmallHit", 3); diff --git a/NPCs/Perforator/PerforatorTailLarge.cs b/NPCs/Perforator/PerforatorTailLarge.cs index 5095d20a37..2bfc0f7eef 100644 --- a/NPCs/Perforator/PerforatorTailLarge.cs +++ b/NPCs/Perforator/PerforatorTailLarge.cs @@ -13,6 +13,7 @@ namespace CalamityMod.NPCs.Perforator { + [LongDistanceNetSync(SyncWith = typeof(PerforatorHeadLarge))] public class PerforatorTailLarge : ModNPC { public static readonly SoundStyle HitSound = new("CalamityMod/Sounds/NPCHit/PerfLargeHit", 3); diff --git a/NPCs/Perforator/PerforatorTailMedium.cs b/NPCs/Perforator/PerforatorTailMedium.cs index 6880426acc..f5128e40f5 100644 --- a/NPCs/Perforator/PerforatorTailMedium.cs +++ b/NPCs/Perforator/PerforatorTailMedium.cs @@ -15,6 +15,7 @@ namespace CalamityMod.NPCs.Perforator { + [LongDistanceNetSync(SyncWith = typeof(PerforatorHeadMedium))] public class PerforatorTailMedium : ModNPC { public static readonly SoundStyle HitSound = new("CalamityMod/Sounds/NPCHit/PerfMediumHit", 3); diff --git a/NPCs/Perforator/PerforatorTailSmall.cs b/NPCs/Perforator/PerforatorTailSmall.cs index 30ad5f8738..3653234a47 100644 --- a/NPCs/Perforator/PerforatorTailSmall.cs +++ b/NPCs/Perforator/PerforatorTailSmall.cs @@ -13,6 +13,7 @@ namespace CalamityMod.NPCs.Perforator { + [LongDistanceNetSync(SyncWith = typeof(PerforatorHeadSmall))] public class PerforatorTailSmall : ModNPC { public static readonly SoundStyle HitSound = new("CalamityMod/Sounds/NPCHit/PerfSmallHit", 3); diff --git a/NPCs/PrimordialWyrm/PrimordialWyrmBody.cs b/NPCs/PrimordialWyrm/PrimordialWyrmBody.cs index edd0b1f728..1de74e9cf4 100644 --- a/NPCs/PrimordialWyrm/PrimordialWyrmBody.cs +++ b/NPCs/PrimordialWyrm/PrimordialWyrmBody.cs @@ -12,6 +12,7 @@ namespace CalamityMod.NPCs.PrimordialWyrm { + [LongDistanceNetSync(SyncWith = typeof(PrimordialWyrmHead))] public class PrimordialWyrmBody : ModNPC { public static Asset GlowTexture; diff --git a/NPCs/PrimordialWyrm/PrimordialWyrmBodyAlt.cs b/NPCs/PrimordialWyrm/PrimordialWyrmBodyAlt.cs index 823636e046..aa679618c5 100644 --- a/NPCs/PrimordialWyrm/PrimordialWyrmBodyAlt.cs +++ b/NPCs/PrimordialWyrm/PrimordialWyrmBodyAlt.cs @@ -12,6 +12,7 @@ namespace CalamityMod.NPCs.PrimordialWyrm { + [LongDistanceNetSync(SyncWith = typeof(PrimordialWyrmHead))] public class PrimordialWyrmBodyAlt : ModNPC { public static Asset GlowTexture; diff --git a/NPCs/PrimordialWyrm/PrimordialWyrmHead.cs b/NPCs/PrimordialWyrm/PrimordialWyrmHead.cs index 49391cd55c..e0267f9335 100644 --- a/NPCs/PrimordialWyrm/PrimordialWyrmHead.cs +++ b/NPCs/PrimordialWyrm/PrimordialWyrmHead.cs @@ -28,6 +28,7 @@ namespace CalamityMod.NPCs.PrimordialWyrm { [AutoloadBossHead] + [LongDistanceNetSync] public class PrimordialWyrmHead : ModNPC { public enum Phase diff --git a/NPCs/PrimordialWyrm/PrimordialWyrmTail.cs b/NPCs/PrimordialWyrm/PrimordialWyrmTail.cs index 7b9aae19b0..8b9b49021b 100644 --- a/NPCs/PrimordialWyrm/PrimordialWyrmTail.cs +++ b/NPCs/PrimordialWyrm/PrimordialWyrmTail.cs @@ -11,6 +11,7 @@ namespace CalamityMod.NPCs.PrimordialWyrm { + [LongDistanceNetSync(SyncWith = typeof(PrimordialWyrmHead))] public class PrimordialWyrmTail : ModNPC { public static Asset GlowTexture; diff --git a/NPCs/StormWeaver/StormWeaverBody.cs b/NPCs/StormWeaver/StormWeaverBody.cs index d921c85011..f18c6ecfee 100644 --- a/NPCs/StormWeaver/StormWeaverBody.cs +++ b/NPCs/StormWeaver/StormWeaverBody.cs @@ -14,6 +14,7 @@ namespace CalamityMod.NPCs.StormWeaver { + [LongDistanceNetSync(SyncWith = typeof(StormWeaverHead))] public class StormWeaverBody : ModNPC { public static Asset Phase2Texture; diff --git a/NPCs/StormWeaver/StormWeaverHead.cs b/NPCs/StormWeaver/StormWeaverHead.cs index 75e8814fe4..91e0ac47ae 100644 --- a/NPCs/StormWeaver/StormWeaverHead.cs +++ b/NPCs/StormWeaver/StormWeaverHead.cs @@ -31,6 +31,7 @@ namespace CalamityMod.NPCs.StormWeaver { + [LongDistanceNetSync] public class StormWeaverHead : ModNPC { public static int normalIconIndex; diff --git a/NPCs/StormWeaver/StormWeaverTail.cs b/NPCs/StormWeaver/StormWeaverTail.cs index 62afff7228..9ae676af2b 100644 --- a/NPCs/StormWeaver/StormWeaverTail.cs +++ b/NPCs/StormWeaver/StormWeaverTail.cs @@ -13,6 +13,7 @@ namespace CalamityMod.NPCs.StormWeaver { + [LongDistanceNetSync(SyncWith = typeof(StormWeaverHead))] public class StormWeaverTail : ModNPC { private int invinceTime = 180; diff --git a/NPCs/SupremeCalamitas/SepulcherBody.cs b/NPCs/SupremeCalamitas/SepulcherBody.cs index a5be1ff57c..4d092f6da2 100644 --- a/NPCs/SupremeCalamitas/SepulcherBody.cs +++ b/NPCs/SupremeCalamitas/SepulcherBody.cs @@ -11,6 +11,7 @@ namespace CalamityMod.NPCs.SupremeCalamitas { + [LongDistanceNetSync(SyncWith = typeof(SepulcherHead))] public class SepulcherBody : ModNPC { private bool setAlpha = false; diff --git a/NPCs/SupremeCalamitas/SepulcherHead.cs b/NPCs/SupremeCalamitas/SepulcherHead.cs index 67df4e9c2f..05100dabd8 100644 --- a/NPCs/SupremeCalamitas/SepulcherHead.cs +++ b/NPCs/SupremeCalamitas/SepulcherHead.cs @@ -16,6 +16,7 @@ namespace CalamityMod.NPCs.SupremeCalamitas { + [LongDistanceNetSync] public class SepulcherHead : ModNPC { public static readonly SoundStyle DeathSound = new("CalamityMod/Sounds/NPCKilled/SepulcherDeath"); diff --git a/NPCs/SupremeCalamitas/SepulcherTail.cs b/NPCs/SupremeCalamitas/SepulcherTail.cs index ba744ca331..6798e03161 100644 --- a/NPCs/SupremeCalamitas/SepulcherTail.cs +++ b/NPCs/SupremeCalamitas/SepulcherTail.cs @@ -11,6 +11,7 @@ namespace CalamityMod.NPCs.SupremeCalamitas { + [LongDistanceNetSync(SyncWith = typeof(SepulcherHead))] public class SepulcherTail : ModNPC { private bool setAlpha = false; From 425dceae9a5219d126ec96e765d663e636ed7ea2 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Fri, 1 Nov 2024 00:39:04 -0500 Subject: [PATCH 193/401] Abyss Layer 4 lag hell fix. --- CalamityMod.cs | 1 + Utilities/FramedGlowMask.cs | 154 +++++++++++++++++++++++++++++++++++ Walls/VoidstoneWall.cs | 42 ++++++---- Walls/VoidstoneWallUnsafe.cs | 46 +++++++---- 4 files changed, 209 insertions(+), 34 deletions(-) create mode 100644 Utilities/FramedGlowMask.cs diff --git a/CalamityMod.cs b/CalamityMod.cs index 7ac3568177..043dd624e3 100644 --- a/CalamityMod.cs +++ b/CalamityMod.cs @@ -447,6 +447,7 @@ public override void Unload() NPCStats.Unload(); CalamityGlobalItem.UnloadTweaks(); CalamityGlobalProjectile.UnloadTweaks(); + FramedGlowMask.UnloadTexCache(); PopupGUIManager.UnloadGUIs(); InvasionProgressUIManager.UnloadGUIs(); diff --git a/Utilities/FramedGlowMask.cs b/Utilities/FramedGlowMask.cs new file mode 100644 index 0000000000..f2a95eae77 --- /dev/null +++ b/Utilities/FramedGlowMask.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ReLogic.Content; +using Terraria; +using Terraria.ModLoader; + +namespace CalamityMod +{ + public sealed class FramedGlowMask + { + /// + /// Cached Texture2D reference, null on server + /// + public Texture2D Texture { get; private set; } + + /// + /// X axis's frame count, 0 on server + /// + public int FrameXCount { get; private set; } = 0; + + /// + /// Y axis's frame count, 0 on server + /// + public int FrameYCount { get; private set; } = 0; + + /// + /// Pixel width for each frame + /// + public int FrameWidth { get; private set; } + + /// + /// Pixel height for each frame + /// + public int FrameHeight { get; private set; } + + private static event Action _OnUnload; + private readonly bool[,] _HasGlowContent; + + internal static void UnloadTexCache() + { + _OnUnload?.Invoke(); + } + + public FramedGlowMask(string asset, int frameWidth, int frameHeight, bool pretendEveryFrameHaveGlow = false) + { + FrameWidth = frameWidth; + FrameHeight = frameHeight; + + // Don't do anything further on server + if (Main.dedServ) + return; + + Texture = ModContent.Request(asset, AssetRequestMode.ImmediateLoad).Value; + if (Texture is null) + return; + + _OnUnload += () => + { + Texture = null; + FrameWidth = 0; + FrameHeight = 0; + FrameXCount = 0; + FrameYCount = 0; + }; + + FrameXCount = Texture.Width / frameWidth; + FrameYCount = Texture.Height / frameHeight; + + _HasGlowContent = new bool[FrameXCount, FrameYCount]; + + + if (pretendEveryFrameHaveGlow) + { + for (int x = 0; x < FrameXCount; x++) + { + for (int y = 0; y < FrameYCount; y++) + { + _HasGlowContent[x, y] = true; + } + } + } + else + { + Main.QueueMainThreadAction(() => + { + var colData = Texture.GetColorsFromTexture(); + Parallel.For(0, FrameXCount * FrameYCount, (i) => + { + int xFrame = i % FrameXCount; + int yFrame = i / FrameXCount; + int xStart = xFrame * frameWidth; + int xEnd = xStart + frameWidth; + int yStart = yFrame * frameHeight; + int yEnd = yStart + frameHeight; + bool frameHasData = false; + for (int x = xStart; x < xEnd; x++) + { + if (frameHasData) + { + break; + } + for (int y = yStart; y < yEnd; y++) + { + Color col = colData[x, y]; + if (col.A >= 1) + { + frameHasData = true; + break; + } + } + } + _HasGlowContent[xFrame, yFrame] = frameHasData; + }); + }); + } + } + + public bool HasContentInFrameIndex(int xFrame, int yFrame) + { + if (Texture is null) + return false; + + if (xFrame < 0 || xFrame >= FrameXCount) + return false; + + if (yFrame < 0 || yFrame >= FrameYCount) + return false; + + return _HasGlowContent[xFrame, yFrame]; + } + + public bool HasContentInFramePos(int xPos, int yPos) + { + if (Texture is null) + return false; + + int xFrame = xPos / FrameWidth; + int yFrame = yPos / FrameHeight; + + if (xFrame < 0 || xFrame >= FrameXCount) + return false; + + if (yFrame < 0 || yFrame >= FrameYCount) + return false; + + return _HasGlowContent[xFrame, yFrame]; + } + } +} diff --git a/Walls/VoidstoneWall.cs b/Walls/VoidstoneWall.cs index f4881eb777..ffa3a46d42 100644 --- a/Walls/VoidstoneWall.cs +++ b/Walls/VoidstoneWall.cs @@ -11,12 +11,13 @@ namespace CalamityMod.Walls { public class VoidstoneWall : ModWall { - internal static Texture2D GlowTexture; + internal static FramedGlowMask GlowMask; public override void SetStaticDefaults() { + GlowMask = new("CalamityMod/Walls/VoidstoneWall_Glowmask", 36, 36); + Main.wallHouse[Type] = true; - GlowTexture = ModContent.Request("CalamityMod/Walls/VoidstoneWall_Glowmask", AssetRequestMode.ImmediateLoad).Value; AddMapEntry(new Color(0, 0, 0)); } @@ -29,37 +30,44 @@ public override bool CreateDust(int i, int j, ref int type) public static void DrawWallGlow(int wallType, int i, int j, SpriteBatch spriteBatch) { - if (GlowTexture is null) + if (GlowMask.Texture is null) return; Tile tile = Main.tile[i, j]; int xLength = 32; int xOff = 0; - Rectangle frame = new Rectangle(tile.WallFrameX + xOff, tile.WallFrameY, xLength, 32); + int xPos = tile.WallFrameX + xOff; + int yPos = tile.WallFrameY; + + Rectangle frame = new Rectangle(xPos, yPos, xLength, 32); Color drawcolor; drawcolor = WorldGen.paintColor(tile.WallColor); drawcolor.A = 255; Vector2 zero = new Vector2(Main.offScreenRange, Main.offScreenRange); - float brightness = 1f; - float declareThisHereToPreventRunningTheSameCalculationMultipleTimes = Main.GameUpdateCount * 0.007f; - brightness *= (float)MathF.Sin(i / 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); - brightness *= (float)MathF.Sin(j / 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); - brightness *= (float)MathF.Sin(i * 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); - brightness *= (float)MathF.Sin(j * 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); - drawcolor *= brightness; - if (Main.drawToScreen) zero = Vector2.Zero; Vector2 pos = new Vector2(i * 16 - (int)Main.screenPosition.X, j * 16 - (int)Main.screenPosition.Y) + zero; - Main.spriteBatch.Draw(TextureAssets.Wall[wallType].Value, pos + new Vector2(-8 + xOff, -8), frame, Lighting.GetColor(i, j, Color.White), 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); - Color glowColor = drawcolor * 0.4f; - for (int k = 0; k < 3; k++) + spriteBatch.Draw(TextureAssets.Wall[wallType].Value, pos + new Vector2(-8 + xOff, -8), frame, Lighting.GetColor(i, j, Color.White), 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); + + if (GlowMask.HasContentInFramePos(xPos, yPos)) { - Vector2 offset = new Vector2(Main.rand.NextFloat(-1, 1f), Main.rand.NextFloat(-1, 1f)) * 0.2f * k; - Main.spriteBatch.Draw(GlowTexture, pos + offset + new Vector2(-8 + xOff, -8), frame, glowColor, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); + float brightness = 1f; + float declareThisHereToPreventRunningTheSameCalculationMultipleTimes = Main.GameUpdateCount * 0.007f; + brightness *= (float)MathF.Sin(i / 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); + brightness *= (float)MathF.Sin(j / 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); + brightness *= (float)MathF.Sin(i * 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); + brightness *= (float)MathF.Sin(j * 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); + drawcolor *= brightness; + Color glowColor = drawcolor * 0.4f; + + for (int k = 0; k < 3; k++) + { + Vector2 offset = new Vector2(Main.rand.NextFloat(-1, 1f), Main.rand.NextFloat(-1, 1f)) * 0.2f * k; + spriteBatch.Draw(GlowMask.Texture, pos + offset + new Vector2(-8 + xOff, -8), frame, glowColor, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); + } } } diff --git a/Walls/VoidstoneWallUnsafe.cs b/Walls/VoidstoneWallUnsafe.cs index 5f7348b9ee..0f0b24ea66 100644 --- a/Walls/VoidstoneWallUnsafe.cs +++ b/Walls/VoidstoneWallUnsafe.cs @@ -11,11 +11,14 @@ namespace CalamityMod.Walls { public class VoidstoneWallUnsafe : ModWall { - internal static Texture2D GlowTexture; + internal static FramedGlowMask GlowMask; public override void SetStaticDefaults() { - GlowTexture = ModContent.Request("CalamityMod/Walls/VoidstoneWall_Glowmask", AssetRequestMode.ImmediateLoad).Value; + // We basically have same copy in VoidstoneWall + // But leaving this in case of changing to Unsafe variant specific glowmask + GlowMask = new("CalamityMod/Walls/VoidstoneWall_Glowmask", 36, 36); + DustType = 187; AddMapEntry(new Color(0, 0, 0)); } @@ -34,37 +37,46 @@ public override void RandomUpdate(int i, int j) public static void DrawWallGlow(int wallType, int i, int j, SpriteBatch spriteBatch) { - if (GlowTexture is null) + if (GlowMask.Texture is null) return; Tile tile = Main.tile[i, j]; int xLength = 32; int xOff = 0; - Rectangle frame = new Rectangle(tile.WallFrameX + xOff, tile.WallFrameY, xLength, 32); + int xPos = tile.WallFrameX + xOff; + int yPos = tile.WallFrameY; + + Rectangle frame = new Rectangle(xPos, yPos, xLength, 32); Color drawcolor; drawcolor = WorldGen.paintColor(tile.WallColor); drawcolor.A = 255; Vector2 zero = new Vector2(Main.offScreenRange, Main.offScreenRange); - float brightness = 1f; - float declareThisHereToPreventRunningTheSameCalculationMultipleTimes = Main.GameUpdateCount * 0.007f; - brightness *= (float)MathF.Sin(i / 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); - brightness *= (float)MathF.Sin(j / 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); - brightness *= (float)MathF.Sin(i * 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); - brightness *= (float)MathF.Sin(j * 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); - drawcolor *= brightness; - if (Main.drawToScreen) zero = Vector2.Zero; Vector2 pos = new Vector2((i * 16 - (int)Main.screenPosition.X), (j * 16 - (int)Main.screenPosition.Y)) + zero; - Main.spriteBatch.Draw(TextureAssets.Wall[wallType].Value, pos + new Vector2(-8 + xOff, -8), frame, Lighting.GetColor(i, j, Color.White), 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); - Color glowColor = drawcolor * 0.4f; - for (int k = 0; k < 3; k++) + spriteBatch.Draw(TextureAssets.Wall[wallType].Value, pos + new Vector2(-8 + xOff, -8), frame, Lighting.GetColor(i, j, Color.White), 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); + + if (GlowMask.HasContentInFramePos(xPos, yPos)) { - Vector2 offset = new Vector2(Main.rand.NextFloat(-1f, 1f), Main.rand.NextFloat(-1f, 1f)) * 0.2f * k; - Main.spriteBatch.Draw(GlowTexture, pos + offset + new Vector2(-8 + xOff, -8), frame, glowColor, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); + float brightness = 1f; + float declareThisHereToPreventRunningTheSameCalculationMultipleTimes = Main.GameUpdateCount * 0.007f; + brightness *= (float)MathF.Sin(i / 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); + brightness *= (float)MathF.Sin(j / 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); + brightness *= (float)MathF.Sin(i * 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); + brightness *= (float)MathF.Sin(j * 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); + drawcolor *= brightness; + Color glowColor = drawcolor * 0.4f; + + // For now checking for glowing frames greatly reducing the bottleneck + // But maybe we could squeeze bit more by removing the loop + for (int k = 0; k < 3; k++) + { + Vector2 offset = new Vector2(Main.rand.NextFloat(-1f, 1f), Main.rand.NextFloat(-1f, 1f)) * 0.2f * k; + spriteBatch.Draw(GlowMask.Texture, pos + offset + new Vector2(-8 + xOff, -8), frame, glowColor, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); + } } } From b68469ace92cb8d00735a102e2e1f1df3219e3db Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Mon, 4 Nov 2024 15:57:27 -0500 Subject: [PATCH 194/401] Remnants compatibility for the old Sunken Sea. It will now be centered properly. --- Systems/WorldgenManagementSystem.cs | 6 ++---- World/SunkenSea.cs | 7 +++++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Systems/WorldgenManagementSystem.cs b/Systems/WorldgenManagementSystem.cs index 822a6dac34..74be220776 100644 --- a/Systems/WorldgenManagementSystem.cs +++ b/Systems/WorldgenManagementSystem.cs @@ -124,10 +124,8 @@ public override void ModifyWorldGenTasks(List tasks, ref double totalWe { progress.Message = Language.GetOrRegister("Mods.CalamityMod.UI.SunkenSea").Value; - int sunkenSeaX = GenVars.UndergroundDesertLocation.Left; - int sunkenSeaY = Main.maxTilesY - 400; - - SunkenSea.Place(new Point(sunkenSeaX, sunkenSeaY)); + Point ssBottomLeft = new Point(GenVars.UndergroundDesertLocation.Left, Main.maxTilesY - 400); + SunkenSea.Place(ssBottomLeft); })); } diff --git a/World/SunkenSea.cs b/World/SunkenSea.cs index 20e6d1b40c..720c18113f 100644 --- a/World/SunkenSea.cs +++ b/World/SunkenSea.cs @@ -739,6 +739,13 @@ public static bool Place(Point origin) // As far as I can tell, this just scales up the entire Sunken Sea to be 4x wider and 2x taller than what is listed above Vector2 arbitrary42GodVector = new Vector2(4f, 2f); + // 04NOV2024: Ozzatron: Remnants mutilates the Underground Desert beyond recognition. + // The above code assumes the size of the underground desert with arbitrary hardcoded values instead of checking it. + // To ensure the Sunken Sea is centered on an Underground Desert of any size, some adjustments are made. + // This would have been easy, but the arbitrary 4-2 God vector makes the math unnecessarily complicated. + int sunkenSeaRealWidth = (int)(sunkenSeaAreaX * arbitrary42GodVector.X); + origin.X = GenVars.UndergroundDesertLocation.Center.X - sunkenSeaRealWidth / 2; + // Place the majority of the terrain as clusters ClusterGroup clusterGroup = new ClusterGroup(); clusterGroup.Generate(sunkenSeaAreaX, sunkenSeaAreaY); From 69e399c6b51791ac3cf3bf8d4106fd7bf907563a Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Mon, 2 Dec 2024 13:11:17 -0600 Subject: [PATCH 195/401] 1 - Removed Bird/Mr.Small references. 2 - Fixed Old Duke Remix Seed enrage. 3 - Renderer Manager render state edits. 4 - Fixed lava generating in the Sunken Sea and Abyss. 5 - Fixed Brimstone Slag walls generating in incorrect locations. 6 - Mechanic Shed no longer generates in space, hopefully. --- CalPlayer/CalamityPlayer.cs | 8 -- Graphics/Renderers/RendererManager.cs | 14 ++-- Items/Accessories/Vanity/Birds_Head.png | Bin 3064 -> 0 bytes .../Vanity/Birds_Head_Extension.png | Bin 480 -> 0 bytes Items/Accessories/Vanity/Birds_Legs.png | Bin 1967 -> 0 bytes Items/Accessories/Vanity/Birds_Torso.png | Bin 4083 -> 0 bytes Items/Accessories/Vanity/CocosFeather.cs | 69 ------------------ Items/Accessories/Vanity/CocosFeather.png | Bin 753 -> 0 bytes .../DevPaintings/ThankYouPainting.cs | 1 - NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs | 4 +- World/BrimstoneCrag.cs | 6 +- World/MechanicShed.cs | 2 +- World/SulphurousSea.cs | 3 +- 13 files changed, 15 insertions(+), 92 deletions(-) delete mode 100644 Items/Accessories/Vanity/Birds_Head.png delete mode 100644 Items/Accessories/Vanity/Birds_Head_Extension.png delete mode 100644 Items/Accessories/Vanity/Birds_Legs.png delete mode 100644 Items/Accessories/Vanity/Birds_Torso.png delete mode 100644 Items/Accessories/Vanity/CocosFeather.cs delete mode 100644 Items/Accessories/Vanity/CocosFeather.png diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 084a918902..98f60d0478 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -1151,7 +1151,6 @@ public GemTechArmorState GemTechState public bool omegaBlueTransformationForce; public bool omegaBlueTransformationPower; public bool redBow; - public bool cocosFeather; #endregion #region Calamitas Enchant Effects @@ -2191,7 +2190,6 @@ public override void ResetEffects() omegaBlueTransformation = omegaBlueTransformationForce = omegaBlueTransformationPower = false; redBow = false; - cocosFeather = false; rageModeActive = false; adrenalineModeActive = false; @@ -4222,12 +4220,6 @@ public override void FrameEffects() Player.body = EquipLoader.GetEquipSlot(Mod, "RedBow", EquipType.Body); Player.head = EquipLoader.GetEquipSlot(Mod, "RedBow", EquipType.Head); } - if (cocosFeather) - { - Player.legs = EquipLoader.GetEquipSlot(Mod, "CocosFeather", EquipType.Legs); - Player.body = EquipLoader.GetEquipSlot(Mod, "CocosFeather", EquipType.Body); - Player.head = EquipLoader.GetEquipSlot(Mod, "CocosFeather", EquipType.Head); - } if (snowRuffianSet) { Player.wings = EquipLoader.GetEquipSlot(Mod, "SnowRuffianMask", EquipType.Wings); diff --git a/Graphics/Renderers/RendererManager.cs b/Graphics/Renderers/RendererManager.cs index eac7f8ce96..1505780208 100644 --- a/Graphics/Renderers/RendererManager.cs +++ b/Graphics/Renderers/RendererManager.cs @@ -124,7 +124,7 @@ private void DrawNPCRenderers(On_Main.orig_DrawNPCs orig, Main self, bool behind var renderers = Renderers.Where(renderer => renderer.ShouldDraw && renderer.Layer is DrawLayer.NPC); Main.spriteBatch.End(); - Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, Main.Rasterizer); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, RasterizerState.CullCounterClockwise); foreach (var renderer in renderers) renderer.DrawTarget(Main.spriteBatch); @@ -138,7 +138,7 @@ private void DrawProjectileRenderers(On_Main.orig_DrawProjectiles orig, Main sel var renderers = Renderers.Where(renderer => renderer.ShouldDraw && renderer.Layer is DrawLayer.Projectile); - Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, Main.Rasterizer); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, RasterizerState.CullCounterClockwise); foreach (var renderer in renderers) renderer.DrawTarget(Main.spriteBatch); @@ -152,7 +152,7 @@ private void DrawPlayerRenderers(On_Main.orig_DrawPlayers_AfterProjectiles orig, var renderers = Renderers.Where(renderer => renderer.ShouldDraw && renderer.Layer is DrawLayer.Player); - Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, Main.Rasterizer); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, RasterizerState.CullCounterClockwise); foreach (var renderer in renderers) renderer.DrawTarget(Main.spriteBatch); @@ -165,13 +165,13 @@ private void DrawBeforeTileRenderers(On_Main.orig_DrawBackgroundBlackFill orig, var renderers = Renderers.Where(renderer => renderer.ShouldDraw && renderer.Layer is DrawLayer.BeforeTiles); Main.spriteBatch.End(); - Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, Main.Rasterizer); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, RasterizerState.CullCounterClockwise); foreach (var renderer in renderers) renderer.DrawTarget(Main.spriteBatch); Main.spriteBatch.End(); - Main.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, Main.Rasterizer, null, Main.Transform); + Main.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, RasterizerState.CullCounterClockwise, null, Main.Transform); orig(self); } @@ -181,12 +181,12 @@ private void DrawAfterEverythingRenderers(On_Main.orig_DrawInfernoRings orig, Ma var renderers = Renderers.Where(renderer => renderer.ShouldDraw && renderer.Layer is DrawLayer.AfterEverything); Main.spriteBatch.End(); - Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, Main.Rasterizer); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, RasterizerState.CullCounterClockwise); foreach (var renderer in renderers) renderer.DrawTarget(Main.spriteBatch); Main.spriteBatch.End(); - Main.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, Main.Rasterizer, null, Main.Transform); + Main.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, RasterizerState.CullCounterClockwise, null, Main.Transform); orig(self); } #endregion diff --git a/Items/Accessories/Vanity/Birds_Head.png b/Items/Accessories/Vanity/Birds_Head.png deleted file mode 100644 index e475326c77aed80c24d749cbf0b0679a61ebbce4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3064 zcmeI!>sJ$J9>DRaPy|Y=fVc`J-3l0R!K1;Alxw&LA`mE0E{gRsTs$z?fI=_^ViiF# zHGmodArLNF1a$%NLSXlRQaJ$ZQu_QmdtoXNcU&CK(8 zzB4&N0X_zLJM}Oai~-5lGZ;DIFc__)n?FMSai177ki!OQu#Y>YuG>tBoM^=o4-qk# z2Q2+}-)JM}y2-u~R1D^mHuSfl1H63#gVE0;c@n=$J2Exkr~rIEdp?tAmuB6ZIc)i? z-{i>kXa2i3fAQTTldv!1V%?%B_cs%@^!+zI2-$M#xbG>s_ST#STYhYbW z=i6UDoWZjg@utq!mN@ksL(S4$$WSjbT*hr$IBcrl_yTp2*P1RDNYgZXVg{c_vCb!( zs$AyU65;lRLg||8Qt28rC%wQMz2K@-$X~KqaQ-QLM&q*fBJtdOHYCg|yvJDDC0$bb zm`lBDhwZns>T|tvs!BCL{=0wdZn>Ygs)|nyuL-}#<@b0=is7}r6LO(SIB`#k!!l+L zNN>yOIy9xl(nCV)u`9oX>}8BCWGt32R%_QL%$=)4l~l_4**w)k%o{=J?M7M*O*hxD zm%FMi+uk%2-m1}@@reDa-AYQi1CO0QQhTiQN>PU2G-E0&@cv6SoW8u4JgBt+@rKda z5~!~bX^llq80SLdEk*??z?5!h0=wf-kQ0f9x9TRYnKbxysvK$f@`{FhF;{u~CHqvk z|L{wf=r?C+*PxGuoI0{Ne6NtRQOF5}fiQzTJ~_Qy&R13nD#d=cQk0^pt|m~c{!A<* z;N#QuY51G&Ai5ne$=bv58-yJGIsX!O30L>5o#kAz!B=quD!PgD{@_=NggsOyJs#&8rGKEG3oZkIc5A><^j z!7$KmZ-IjWD+7=Sjt475=x9uxo0Bb{U{nC!3Bl3uL~>9sr*Su~hGb44&R8f#w+`y8 zM2T$>mI~2jc5i??SjD3F*B!Ra3DG2{%9IW?JPbV9PmB@5fF5$s5^ltSyJnVtAP~%1 zU(O0b-&83N>f&6|x(Ibu4B09~(R#ui=;*(1yIide1I$_5R6Q@y>awoim-P!;Cl9@kikh1cIScBt zq2X&T6$(6+BC?GU{1{i1k6hVGUmw?@?|Z(O%dv0P7IOT{2%FH^k2cOUWJ2Vimdb!K zWYzZ(NwNJr{#~o|L9J)`6@=r%W-v&ssd(2SAnfwfLwfG)i$oMKz0@eJW27pk+to(ZTY(H zM*AK5qbDlZOt^!FKg{9ZJ3_;2BloNj-Q5{>&9IVyze5(w%i{uixypsWKyaMw!E^_K z-nS+&V0RJv7#(fq_U@@&Een-aCRT4oqyOE(ju|Hlcwg+OV*{$ zQ~2`_a{D{hrA1srGwmU=<=w$U&tcp+lr`A0u%?NB@!1FrG8b7sn|`%DZRc%(an} zSFe6ZdHM+?<*MuJDNnaRQ!WzxHsx{V5~qpvlsnmoog%&F;?`4+?4|c9AEzKGFY-ZC zUgU$OJUzwQo`v4_ADQxh>b3W6M06w4E|wFFP-zhv|CR<_MWt!iqSBzNs5BV(oiu_6 zShX$HQcrT5HN2Do5s5FHLl?HWHin-{wQl<`+XS(*$v+2aQ`+vUm QBl;jnUICtU?njyb0tpZDlK=n! diff --git a/Items/Accessories/Vanity/Birds_Head_Extension.png b/Items/Accessories/Vanity/Birds_Head_Extension.png deleted file mode 100644 index 99dd209e3ebdb36cc46714ae13fb1120176efd1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 480 zcmeAS@N?(olHy`uVBq!ia0vp^8Vn392^?%d*6dv(^+1ZTILO_JVcj{Imp~3nx}&cn z1H;CC?mvmFKt5-IM`SSr1K(i~W;~w1A_b_S)YHW=q$2L^t&O~g90Xh)otaf!c5wc3 zSfrR#rLdI4YY~GM!^us|Dng$HznwBZc~4dS?y>cXTV6fScwYATO@F@M_v6>|>o&c6 zp40p9?S`F)|J}H|{q4Hh&9C2HIvbx`^i7%tXfp`RXv$MtI-3!~VOZf|KKasFD2E|r z$!yP;X)vDFrL#*)jA1;{muW$}B%!>9t`cL-yF5^y0qa$Fudgs81193OV1vu4#Zx|U zK=mz9y6fX*&J5+@(-$02yCg&&s*nMXQy9FL*m!C7!&Kt&!h`>_p0S!wxl{S_SgROF Ny{D_6%Q~loCIBHlhqwR$ diff --git a/Items/Accessories/Vanity/Birds_Legs.png b/Items/Accessories/Vanity/Birds_Legs.png deleted file mode 100644 index 87cee935482c9b8abf3f5a4a87b0d21f52093e8c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1967 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 RC23;^SlOQ~v%Gr$zW}7O#$W&d diff --git a/Items/Accessories/Vanity/CocosFeather.cs b/Items/Accessories/Vanity/CocosFeather.cs deleted file mode 100644 index 4e55c0074d..0000000000 --- a/Items/Accessories/Vanity/CocosFeather.cs +++ /dev/null @@ -1,69 +0,0 @@ -using CalamityMod; -using CalamityMod.CalPlayer; -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.Audio; -using Terraria.DataStructures; -using Terraria.ID; -using Terraria.ModLoader; - - -namespace CalamityMod.Items.Accessories.Vanity -{ - public class CocosFeather : ModItem, IExtendedHat, ILocalizedModType - { - public new string LocalizationCategory => "Items.Accessories"; - public override void Load() - { - if (Main.netMode != NetmodeID.Server) - { - EquipLoader.AddEquipTexture(Mod, "CalamityMod/Items/Accessories/Vanity/Birds_Head", EquipType.Head, this); - EquipLoader.AddEquipTexture(Mod, "CalamityMod/Items/Accessories/Vanity/Birds_Torso", EquipType.Body, this); - EquipLoader.AddEquipTexture(Mod, "CalamityMod/Items/Accessories/Vanity/Birds_Legs", EquipType.Legs, this); - } - } - - public override void SetStaticDefaults() - { - - if (Main.netMode == NetmodeID.Server) - return; - - int equipSlotHead = EquipLoader.GetEquipSlot(Mod, Name, EquipType.Head); - ArmorIDs.Head.Sets.DrawHead[equipSlotHead] = false; - - int equipSlotBody = EquipLoader.GetEquipSlot(Mod, Name, EquipType.Body); - ArmorIDs.Body.Sets.HidesTopSkin[equipSlotBody] = true; - ArmorIDs.Body.Sets.HidesArms[equipSlotBody] = true; - - int equipSlotLegs = EquipLoader.GetEquipSlot(Mod, Name, EquipType.Legs); - ArmorIDs.Legs.Sets.HidesBottomSkin[equipSlotLegs] = true; - } - - public override void SetDefaults() - { - Item.width = 42; - Item.height = 38; - Item.accessory = true; - Item.value = CalamityGlobalItem.RarityGreenBuyPrice; - Item.rare = ItemRarityID.Green; - Item.vanity = true; - Item.Calamity().devItem = true; - } - - public override void UpdateVanity(Player player) - { - player.Calamity().cocosFeather = true; - } - - public override void UpdateAccessory(Player player, bool hideVisual) - { - if (!hideVisual) - { - player.Calamity().cocosFeather = true; - } - } - public string ExtensionTexture => "CalamityMod/Items/Accessories/Vanity/Birds_Head_Extension"; - public Vector2 ExtensionSpriteOffset(PlayerDrawSet drawInfo) => new Vector2(0, -4f); - } -} diff --git a/Items/Accessories/Vanity/CocosFeather.png b/Items/Accessories/Vanity/CocosFeather.png deleted file mode 100644 index 3b69e78dca56ec1513f96169b06cb411c97bb013..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 753 zcmVPx#1ZP1_K>z@;j|==^1poj7fk{L`R9Hvtm@#M*Q5?pTGsII{lO`2StwsbX8A?S& zP!Qb%I<$j>Aa1VW=-kbMTg63O96A-D*wINRMNx_ru^hE2YLgn8#5C2^<9qi(-k*EK zp~c>7f6Mn?a*&r_zW46hcx;C-KA1-4bElEs@|R5v0-PXsJpauo4U(go0pzzz2_|n9 z?_mCP<`Htws6-mSvNoX*Y&LEveTQix<=aK!#)ox!|Dj}CW5BYZWJ<@0Q8r6&unvuKt!>iZ9NQc+^ zrvldIp9+}UXH<5P9ZVlq9gH_s2j%XiIlj&=&b)h$3||8kNROCNn)*tf^8fV{WfepU@8S4nm{sAkRk{rFohp9p@#{x=HLY`fNxU z=u4(Gqw-F|u5nJJNqI-&FXE%E#U7*bxv@W~&dHTl1xDG$Zg&zj;A0KmKvo=xAy?Dx%LYtH-^;zfTrf=katH5Nb-Gp zAsB@tpMp%-XLO>F!+<7_6$UY1Y$uU4YT`mX0dr@Z1m==|HP($tbyPDs@$oZ~oY?Qe z*y4H<*WIqF@Af3sMxKm2cz?FkzB72-3LQ&>gw-l-x%_;lf-pbgU-DSP781I z53YZ_w1)Y15h53h%*G+_V$01jnX jNoGw=04e|g00;m8000000Mb*F00000NkvXXu0mjfgzsA~ diff --git a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs index 63db3bcde1..471616bbd8 100644 --- a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs +++ b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs @@ -84,7 +84,6 @@ public override void ModifyTooltips(List tooltips) "Mercutio 'Merkalto' Takle", "Mishiro Usui", "Moonburn", - "Mr.Small", "Nycro", "Ozzatron", "Piky", diff --git a/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs b/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs index 7383afb7d4..37b8928cc3 100644 --- a/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs +++ b/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs @@ -247,14 +247,14 @@ public static void VanillaOldDukeAI(NPC npc, Mod mod) // Enrage variable bool enrage = !bossRush && - (player.position.Y < 300f || player.position.Y > Main.worldSurface * 16.0 || + (player.position.Y < 300f || player.position.Y > Main.worldSurface * 16 || (player.position.X > 8000f && player.position.X < (Main.maxTilesX * 16 - 8000))); // Check for the flipped Abyss if (Main.remixWorld) { enrage = !bossRush && - (player.position.Y < Main.UnderworldLayer * 0.8f || player.position.Y > Main.UnderworldLayer || + (player.position.Y < Main.UnderworldLayer * 16 * 0.8f || player.position.Y > Main.UnderworldLayer * 16 || (player.position.X > 8000f && player.position.X < (Main.maxTilesX * 16 - 8000))); } diff --git a/World/BrimstoneCrag.cs b/World/BrimstoneCrag.cs index 10573d76b6..01f572f27c 100644 --- a/World/BrimstoneCrag.cs +++ b/World/BrimstoneCrag.cs @@ -57,7 +57,7 @@ private static void GenCrags() for (int y = Main.maxTilesY - 90; y <= Main.maxTilesY - 5; y++) { WorldGen.PlaceTile(x, y, (ushort)ModContent.TileType()); - Main.tile[x, y + 5].WallType = (ushort)ModContent.WallType(); + Main.tile[x, y].WallType = (ushort)ModContent.WallType(); } } @@ -311,8 +311,8 @@ private static void GenCrags() } } - //settle all liquids - CalamityUtils.SettleWater(); + //DISABLED. CAUSES LAVA TO GENERATE IN THE SUNKEN SEA + //CalamityUtils.SettleWater(); //spread grass on all scorched remains with no lava above them for (int x = biomeStart; x <= biomeEdge; x++) diff --git a/World/MechanicShed.cs b/World/MechanicShed.cs index 59db3bbe80..653edd2d18 100644 --- a/World/MechanicShed.cs +++ b/World/MechanicShed.cs @@ -18,7 +18,7 @@ public static void PlaceMechanicShed(StructureMap structures) var schematic = TileMaps[mapKey]; int placementPositionX = WorldGen.genRand.Next(GenVars.snowOriginLeft + 100, GenVars.snowOriginRight - 100); - int placementPositionY = (int)Main.worldSurface - (Main.maxTilesY / 6); + int placementPositionY = (int)Main.worldSurface - (Main.maxTilesY / 12); bool foundValidGround = false; int attempts = 0; diff --git a/World/SulphurousSea.cs b/World/SulphurousSea.cs index f020932486..e43ff0d4a9 100644 --- a/World/SulphurousSea.cs +++ b/World/SulphurousSea.cs @@ -1053,7 +1053,8 @@ public static void PlaceAmbience() public static void GenerateChests(List scrapPilePositions) { GenerateTreasureChest(); - CalamityUtils.SettleWater(); + // DISABLED. CAUSES LAVA TO FILL THE ENTIRETY OF LAYER 4 + //CalamityUtils.SettleWater(); GenerateOpenAirChestChest(); GenerateScrapPileChest(scrapPilePositions); GenerateDeepWaterChest(); From d4194dfd8a5182a888c8e10be37dcecf3988a169 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Sat, 7 Dec 2024 17:53:58 -0600 Subject: [PATCH 196/401] Rain stoppage. --- NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs | 2 +- NPCs/Cryogen/Cryogen.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs b/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs index 37b8928cc3..aab7218ebb 100644 --- a/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs +++ b/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs @@ -70,7 +70,7 @@ public static void VanillaOldDukeAI(NPC npc, Mod mod) if (CalamityConfig.Instance.BossesStopWeather) CalamityMod.StopRain(); - else if (!Main.raining) + else if (!Main.raining && !BossRushEvent.BossRushActive) CalamityUtils.StartRain(); // Adjust stats diff --git a/NPCs/Cryogen/Cryogen.cs b/NPCs/Cryogen/Cryogen.cs index b7e63f539d..59847a9191 100644 --- a/NPCs/Cryogen/Cryogen.cs +++ b/NPCs/Cryogen/Cryogen.cs @@ -265,7 +265,7 @@ public override void AI() if (CalamityConfig.Instance.BossesStopWeather) CalamityMod.StopRain(); - else if (!Main.raining) + else if (!Main.raining && !BossRushEvent.BossRushActive) CalamityUtils.StartRain(); if (!player.active || player.dead) From 487ed5c04ae515d9afe5955da03b4e09d3ff5cc5 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 27 Dec 2024 00:11:58 -0500 Subject: [PATCH 197/401] A ton of minor tooltip and localization fixes --- CalamityConditions.cs | 2 +- Items/CalamityGlobalItemTooltip.cs | 4 ++-- Localization/en-US/Mods.CalamityMod.Buffs.hjson | 2 +- Localization/en-US/Mods.CalamityMod.Condition.hjson | 2 +- .../Mods.CalamityMod.Items.Accessories.Wings.hjson | 2 +- .../en-US/Mods.CalamityMod.Items.Accessories.hjson | 2 +- Localization/en-US/Mods.CalamityMod.Items.Ammo.hjson | 2 +- .../Mods.CalamityMod.Items.Armor.PostMoonLord.hjson | 2 +- .../en-US/Mods.CalamityMod.Items.Potions.hjson | 2 +- .../en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson | 6 +++--- .../en-US/Mods.CalamityMod.Items.Weapons.Summon.hjson | 2 +- Localization/en-US/Mods.CalamityMod.NPCs.hjson | 10 +++------- .../en-US/Mods.CalamityMod.Vanilla.Armor.hjson | 3 +-- 13 files changed, 18 insertions(+), 23 deletions(-) diff --git a/CalamityConditions.cs b/CalamityConditions.cs index 8cce78968e..f6b9acdd2d 100644 --- a/CalamityConditions.cs +++ b/CalamityConditions.cs @@ -56,7 +56,7 @@ private static Condition Create(string key, Func predicate) public static readonly Condition DownedAquaticScourge = Create("Drops.DownedAS", () => DownedBossSystem.downedAquaticScourge); public static readonly Condition DownedBrimstoneElemental = Create("Drops.DownedBrim", () => DownedBossSystem.downedBrimstoneElemental); public static readonly Condition DownedCalamitasClone = Create("Drops.DownedCal", () => DownedBossSystem.downedCalamitasClone); - public static readonly Condition DownedLeviathan = Create("Drops.DownedLebi", () => DownedBossSystem.downedLeviathan); + public static readonly Condition DownedLeviathan = Create("Drops.DownedLevi", () => DownedBossSystem.downedLeviathan); public static readonly Condition DownedAstrumAureus = Create("Drops.DownedAureus", () => DownedBossSystem.downedAstrumAureus); public static readonly Condition DownedPlaguebringer = Create("Drops.DownedPBG", () => DownedBossSystem.downedPlaguebringer); public static readonly Condition DownedRavager = Create("Drops.DownedRav", () => DownedBossSystem.downedRavager); diff --git a/Items/CalamityGlobalItemTooltip.cs b/Items/CalamityGlobalItemTooltip.cs index 9830d5d689..aee8d4caa8 100644 --- a/Items/CalamityGlobalItemTooltip.cs +++ b/Items/CalamityGlobalItemTooltip.cs @@ -640,7 +640,7 @@ void AddTooltip(string text) // Fairy Boots buff. if (item.type == ItemID.FairyBoots) EditTooltipByNum(2, (line) => line.Text += "\nFairies can spawn at any time on the surface and spawn far more frequently\n" + - "Nearby fairies grant +2 HP/s life regen, 10 defense and 10% movement speed\n" + + "Nearby fairies grant +2 HP/s life regen, 10 defense and 10% movement speed\n" + "Fairies are immune to damage and will no longer flee"); // Reduced Nightwither and Holy Flames damage, and melee speed removal. @@ -836,7 +836,7 @@ void AddTooltip(string text) // Lead if (item.type == ItemID.LeadHelmet || item.type == ItemID.LeadChainmail || item.type == ItemID.LeadGreaves) - AddTooltip("Increases damage reduction by 3%"); + AddTooltip("Increases damage reduction by 2%"); // Silver if (item.type == ItemID.SilverHelmet) diff --git a/Localization/en-US/Mods.CalamityMod.Buffs.hjson b/Localization/en-US/Mods.CalamityMod.Buffs.hjson index e7843c0e46..0bc3610158 100644 --- a/Localization/en-US/Mods.CalamityMod.Buffs.hjson +++ b/Localization/en-US/Mods.CalamityMod.Buffs.hjson @@ -100,7 +100,7 @@ Trippy: { VodkaBuff: { DisplayName: Vodka - Description: Damage and critical stike chance increased, defense and life regen reduced + Description: Damage and critical strike chance increased, defense and life regen reduced } WhiskeyBuff: { diff --git a/Localization/en-US/Mods.CalamityMod.Condition.hjson b/Localization/en-US/Mods.CalamityMod.Condition.hjson index 844e15ed3e..58b2c1a7c1 100644 --- a/Localization/en-US/Mods.CalamityMod.Condition.hjson +++ b/Localization/en-US/Mods.CalamityMod.Condition.hjson @@ -68,7 +68,7 @@ InCrag: In the Brimstone Crags InSulph: In the Sulphurous Sea InSunken: In the Sunken Sea InRev: In Revengeance Mode -IsRevOrMM: In Revengeance Mode or in Master Mode +InRevOrMM: In Revengeance Mode or in Master Mode AlcoholPoison: While inflicted with Alcohol Poisoning PostCal: After defeating Calamitas Clone PostAureus: After defeating Astrum Aureus diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.Wings.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.Wings.hjson index 6cd23de2b8..30755075f9 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.Wings.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.Wings.hjson @@ -30,7 +30,7 @@ ElysianWings: { Acceleration multiplier: 2.7 Great vertical speed Flight time: 240 - Temporary immunity to lava and 10% increased movement speed + Immunity to lava and 10% increased movement speed Blessed by the Profaned Flame ''' } diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson index 069adda0db..53baf2d8ff 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson @@ -1199,7 +1199,7 @@ OldDukeScales: { 25% increased dash velocity and length Gives you a stamina indicator on the cooldown rack Using any dash will consume 20% of your stamina - Stamina will gradually recover to 100% after not dashing for 1 second + Stamina will gradually recover to 100% after not dashing for 1.5 seconds Stamina recovers faster when you are stationary If your stamina reaches 0%, you become exhausted [c/CE0E18:While exhausted, this item's damage reduction and movement bonuses are negated] diff --git a/Localization/en-US/Mods.CalamityMod.Items.Ammo.hjson b/Localization/en-US/Mods.CalamityMod.Items.Ammo.hjson index e582fd1bcc..ac9bfdfda0 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Ammo.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Ammo.hjson @@ -23,7 +23,7 @@ BloodfireBullet: { ''' Passes through tiles and accelerates your natural life regen on hit Deals bonus damage based on your current life regen and natural life regen - This damage caps at 25 + This damage caps at 35 ''' } diff --git a/Localization/en-US/Mods.CalamityMod.Items.Armor.PostMoonLord.hjson b/Localization/en-US/Mods.CalamityMod.Items.Armor.PostMoonLord.hjson index a0c60646cb..4e56fa86e4 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Armor.PostMoonLord.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Armor.PostMoonLord.hjson @@ -520,7 +520,7 @@ TarragonHeadMelee: { DisplayName: Tarragon Helm Tooltip: ''' - 12% increased melee damage and critical strike chance + 12% increased melee damage and 10% increased melee critical strike chance 10% increased damage reduction ''' SetBonus: diff --git a/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson b/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson index 94bfd6c74c..b1e1a9437e 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson @@ -191,7 +191,7 @@ CaribbeanRum: { DisplayName: Caribbean Rum Tooltip: ''' - Increases life regen by 1 HP/s, movement speed by 10% and wing flight time by 20% + Increases life regen by 1 HP/s, movement speed by 10% Makes you floaty and reduces defense by 10% Drinking more than 3 different alcohols might not end well with your liver [c/B00BA5:'Why is the rum gone?'] diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson index bc3c0004e7..900d659de4 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson @@ -1212,11 +1212,11 @@ TheDarkMaster: { DisplayName: The Dark Master Tooltip: ''' - Fires red echo slash projectiles at full health - Projectile damage increases for every point of HP above 400 + Fires red echo slash projectiles when above 75% health + Projectile damage increases for every HP above 400 Press to spawn three shadow clones in a Delta formation The clones will mirror your sword swings and release projectiles - The clones will always fire projectiles regardless of your own HP + Projectiles are fired regardless of your own HP, but deal less damage The clones may only exist while holding this weapon 'The blade by which the shadows levy their foes with a terrible fate' ''' diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Summon.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Summon.hjson index 2fa9a00315..429815916b 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Summon.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Summon.hjson @@ -90,7 +90,7 @@ BrittleStarStaff: { Summons a small brittle starfish that will dash through enemies until it shatters Starfish will quickly regenerate after shattering Holding right click will swap starfish between dashing and circling you - When the starfish are circling, each one provides you with 3 defense + When the starfish are circling, each one provides you with 5 defense ''' } diff --git a/Localization/en-US/Mods.CalamityMod.NPCs.hjson b/Localization/en-US/Mods.CalamityMod.NPCs.hjson index 42d943f37f..2e4ed16928 100644 --- a/Localization/en-US/Mods.CalamityMod.NPCs.hjson +++ b/Localization/en-US/Mods.CalamityMod.NPCs.hjson @@ -169,9 +169,9 @@ Frogfish.DisplayName: Frogfish Horse.DisplayName: Earth Elemental IceClasper.DisplayName: Ice Clasper ImpiousImmolator.DisplayName: Impious Immolator -KingSlimeJewel.DisplayName: Ruby Jewel -KingSlimeJewel2.DisplayName: Sapphire Jewel -KingSlimeJewel3.DisplayName: Emerald Jewel +KingSlimeJewelEmerald.DisplayName: Emerald Jewel +KingSlimeJewelRuby.DisplayName: Ruby Jewel +KingSlimeJewelSapphire.DisplayName: Sapphire Jewel LavaSlimeNoLavaDrop.DisplayName: Lava Slime MantisShrimp.DisplayName: Mantis Shrimp OverloadedSoldier.DisplayName: Overloaded Soldier @@ -623,7 +623,3 @@ WITCH: { Princess_LovesNPC: "{NPCName} is always lonely, it's why I want to hang out with her, no one should be left alone like that!" } } - -KingSlimeJewelEmerald.DisplayName: King Slime Jewel Emerald -KingSlimeJewelRuby.DisplayName: King Slime Jewel Ruby -KingSlimeJewelSapphire.DisplayName: King Slime Jewel Sapphire diff --git a/Localization/en-US/Mods.CalamityMod.Vanilla.Armor.hjson b/Localization/en-US/Mods.CalamityMod.Vanilla.Armor.hjson index 3e221f5442..348b3784fe 100644 --- a/Localization/en-US/Mods.CalamityMod.Vanilla.Armor.hjson +++ b/Localization/en-US/Mods.CalamityMod.Vanilla.Armor.hjson @@ -101,8 +101,7 @@ SetBonus: { ''' Obsidian: ''' - Increases whip range by 50% and speed by 35% - Increases minion damage by 15% + {$ArmorSetBonus.ObsidianOutlaw} Grants immunity to fire blocks and temporary immunity to lava ''' Palladium: From 31bfc927a39ffd0d3664c2e8b40b06c1f871f6d7 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <142704082+CongratsIsTrash@users.noreply.github.com> Date: Fri, 3 Jan 2025 17:31:36 -0500 Subject: [PATCH 198/401] 1 - Fixed Artemis and Apollo charge telegraphs not appearing 2 - Fixed the yoyo burst damage exploit 3 - Fixed Mining Potion and Hand of Creation tooltips 4 - Fixed Grax's tooltip 5 - Fixed Flame Waker Boots' heat debuff multiplier not applying on projectile hits --- CalPlayer/CalamityPlayerOnHit.cs | 1 + Items/CalamityGlobalItemTooltip.cs | 10 ++++++++-- Localization/en-US/Mods.CalamityMod.Items.Tools.hjson | 2 +- Projectiles/Boss/ApolloChargeTelegraph.cs | 9 ++++----- Projectiles/Boss/ArtemisChargeTelegraph.cs | 11 ++++++----- Projectiles/CalamityGlobalProjectile.cs | 9 +++++++++ 6 files changed, 29 insertions(+), 13 deletions(-) diff --git a/CalPlayer/CalamityPlayerOnHit.cs b/CalPlayer/CalamityPlayerOnHit.cs index 2464cd250f..397a03fef3 100644 --- a/CalPlayer/CalamityPlayerOnHit.cs +++ b/CalPlayer/CalamityPlayerOnHit.cs @@ -210,6 +210,7 @@ public override void OnHitAnything(float x, float y, Entity victim) cgn.IncreasedHeatEffects_Fireball = fireball; cgn.IncreasedHeatEffects_CinnamonRoll = cinnamonRoll; + cgn.IncreasedHeatEffects_FlameWakerBoots = flameWakerBoots; cgn.IncreasedHeatEffects_HellfireTreads = hellfireTreads; cgn.IncreasedSicknessEffects_ToxicHeart = toxicHeart; diff --git a/Items/CalamityGlobalItemTooltip.cs b/Items/CalamityGlobalItemTooltip.cs index aee8d4caa8..39f43104af 100644 --- a/Items/CalamityGlobalItemTooltip.cs +++ b/Items/CalamityGlobalItemTooltip.cs @@ -602,9 +602,15 @@ void AddTooltip(string text) // Rebalances to vanilla item stats #region Vanilla Item Rebalance Tooltips - // Ancient Chisel rebalance. + // Various mining speed nerfs + if (item.type == ItemID.MiningPotion) + EditTooltipByNum(0, (line) => line.Text = line.Text.Replace("25%", "15%")); + if (item.type == ItemID.AncientChisel) - EditTooltipByNum(0, (line) => line.Text = "Increases mining speed by 15%"); + EditTooltipByNum(0, (line) => line.Text = line.Text.Replace("25%", "15%")); + + if (item.type == ItemID.HandOfCreation) + EditTooltipByNum(0, (line) => line.Text = line.Text.Replace("25%", "15%")); // Frozen Turtle Shell rebalance. if (item.type == ItemID.FrozenTurtleShell) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Tools.hjson b/Localization/en-US/Mods.CalamityMod.Items.Tools.hjson index 7d1594a478..cde8da2380 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Tools.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Tools.hjson @@ -111,7 +111,7 @@ Grax: { DisplayName: Grax Tooltip: ''' - Hitting an enemy will greatly boost your defense, melee damage and melee crit for a short time + Hitting an enemy will greatly boost your melee damage, defense, and damage reduction for a short time Press to use without hammering down walls or chopping down trees ''' } diff --git a/Projectiles/Boss/ApolloChargeTelegraph.cs b/Projectiles/Boss/ApolloChargeTelegraph.cs index 66e6f36cc1..143df6a6d3 100644 --- a/Projectiles/Boss/ApolloChargeTelegraph.cs +++ b/Projectiles/Boss/ApolloChargeTelegraph.cs @@ -118,11 +118,10 @@ public override bool PreDraw(ref Color lightColor) for (int i = ChargePositions.Length - 2; i >= 0; i--) { - Vector2[] positions = new Vector2[2] - { - ChargePositions[i], - ChargePositions[i + 1] - }; + // This is effectively a 2-point trail that is extended as Toasty's new Primitive system appears to no longer support them. + Vector2[] positions = new Vector2[5]; + for (int p = 0; p < positions.Length; p++) + positions[p] = Vector2.Lerp(ChargePositions[i], ChargePositions[i + 1], p / (positions.Length - 1f)); // Stand-in variable used to differentiate between the beams. // It is not used anywhere else. diff --git a/Projectiles/Boss/ArtemisChargeTelegraph.cs b/Projectiles/Boss/ArtemisChargeTelegraph.cs index 5370ee45f7..8f6d6cdc66 100644 --- a/Projectiles/Boss/ArtemisChargeTelegraph.cs +++ b/Projectiles/Boss/ArtemisChargeTelegraph.cs @@ -91,11 +91,12 @@ public override bool PreDraw(ref Color lightColor) { GameShaders.Misc["CalamityMod:Flame"].UseImage1("Images/Misc/Perlin"); GameShaders.Misc["CalamityMod:Flame"].UseSaturation(0.28f); - Vector2[] drawPositions = new Vector2[] - { - Projectile.Center, - Projectile.Center + Projectile.velocity.SafeNormalize(Vector2.UnitY) * TelegraphWidth - }; + + // This is effectively a 2-point trail that is extended as Toasty's new Primitive system appears to no longer support them. + Vector2[] drawPositions = new Vector2[5]; + for (int i = 0; i < drawPositions.Length; i++) + drawPositions[i] = Projectile.Center + Projectile.velocity.SafeNormalize(Vector2.UnitY) * TelegraphWidth * i / (drawPositions.Length - 1f); + PrimitiveRenderer.RenderTrail(drawPositions, new(TelegraphPrimitiveWidth, TelegraphPrimitiveColor, (_) => Projectile.Size * 0.5f, shader: GameShaders.Misc["CalamityMod:Flame"]), 87); return false; } diff --git a/Projectiles/CalamityGlobalProjectile.cs b/Projectiles/CalamityGlobalProjectile.cs index 27d65eacbf..45d77f7a00 100644 --- a/Projectiles/CalamityGlobalProjectile.cs +++ b/Projectiles/CalamityGlobalProjectile.cs @@ -269,6 +269,15 @@ public override bool PreAI(Projectile projectile) projectile.damage = (int)projectile.ai[2]; } + // This code fixes the wacky close-up burst damage bug which occurs with double yoyos and local iframes. + // Oh my good friends, do not ask me how or why this works, for I do not know! + // That being said, PLEASE DON'T REMOVE THIS, unless you think The Microwave killing Provi in 2 seconds with no effort is okay. + if (projectile.aiStyle == ProjAIStyleID.Yoyo) + { + if (projectile.ai[0] == -1) + projectile.Kill(); + } + // Chlorophyte Crystal AI rework. if (projectile.type == ProjectileID.CrystalLeaf) return ChlorophyteCrystalAI.DoChlorophyteCrystalAI(projectile); From 970450b6a8f22a5cb1c659c33d8c153ca805594c Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <142704082+CongratsIsTrash@users.noreply.github.com> Date: Mon, 6 Jan 2025 11:21:18 -0500 Subject: [PATCH 199/401] Removed "Markie" Arms Dealer name --- NPCs/CalamityGlobalTownNPC.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/NPCs/CalamityGlobalTownNPC.cs b/NPCs/CalamityGlobalTownNPC.cs index abf91440b3..c0944a024f 100644 --- a/NPCs/CalamityGlobalTownNPC.cs +++ b/NPCs/CalamityGlobalTownNPC.cs @@ -77,7 +77,6 @@ public static float TaxYieldFactor "XiaoEn0426", // <@!440448864772816896> (xiaoen0426) "Jeffred", // <@!295362230038560768> (paladinsamuel) "The Cooler Arthur", // <@!568263512523014154> (gokuartillery) - "Markie", // <@!291141964039061504> (markie_) "Shark", // <@!874464051697172492> (congratsistrash) "Sagi", // <@!508233115781693441> (sagittariod) }; From dec402677ee518d95411fc7fb3c70d69dfa176c7 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <142704082+CongratsIsTrash@users.noreply.github.com> Date: Thu, 30 Jan 2025 20:17:12 -0500 Subject: [PATCH 200/401] 1 - Fixed Craw Carapace line thorns damage being able to hit invincible enemies 2 - Fixed Altars not dropping items properly in multiplayer 3 - Fixed walls which spawn water desyncing in multiplayer 4 - Fixed Arid Artifact, Cosmolight, Martian Distress Remote, and Torrential Tear not working properly in multiplayer 5 - Fixed Caustic Tear status message and Draedon end monologue appearing multiple times per player in multiplayer 6 - Fixed Bandit refunding not working in multiplayer 7 - Fixed null reference exceptions with particle system in multiplayer 8 - Fixed Plantera Thorn Ball tile collision desyncing in multiplayer 9 - Fixed Spine Trees not dropping in multiplayer 10 - Fixed all Calamity wiring-activated mechanisms not working in multiplayer --- CalPlayer/CalamityPlayerHitHurt.cs | 21 +++++--- CalamityNetcode.cs | 39 +++++++++++++- Items/CalamityGlobalItem.cs | 12 ++++- Items/SummonItems/Invasion/CausticTear.cs | 9 ++-- .../Invasion/MartianDistressRemote.cs | 27 +++++++++- Items/Tools/ClimateChange/AridArtifact.cs | 8 +-- Items/Tools/ClimateChange/Cosmolight.cs | 9 ++-- Items/Tools/ClimateChange/TorrentialTear.cs | 8 ++- NPCs/ExoMechs/Draedon.cs | 4 +- NPCs/TownNPCs/THIEF.cs | 52 +++++++++++++----- .../Bosses/PlanteraAI.cs | 10 ++-- Particles/GeneralParticleHandler.cs | 17 +++++- Projectiles/CalamityGlobalProjectile.cs | 3 +- Tiles/CalamityGlobalTile.cs | 53 +++++++++++++------ Tiles/Crags/Tree/SpineTree.cs | 5 ++ Utilities/MiscUtils.cs | 21 ++++++-- Utilities/TileUtils.cs | 3 ++ Walls/AbyssGravelWall.cs | 2 +- Walls/EutrophicSandWall.cs | 2 +- Walls/PyreMantleWall.cs | 2 +- Walls/VoidstoneWallUnsafe.cs | 2 +- 21 files changed, 242 insertions(+), 67 deletions(-) diff --git a/CalPlayer/CalamityPlayerHitHurt.cs b/CalPlayer/CalamityPlayerHitHurt.cs index aca930da03..47ade64d1f 100644 --- a/CalPlayer/CalamityPlayerHitHurt.cs +++ b/CalPlayer/CalamityPlayerHitHurt.cs @@ -1190,8 +1190,11 @@ public override void OnHitByNPC(NPC npc, Player.HurtInfo hurtInfo) if (crawCarapace) { npc.AddBuff(ModContent.BuffType(), 900); - int onHitDamage = Player.CalcIntDamage(40); - Player.ApplyDamageToNPC(npc, onHitDamage, 0f, 0, false); + if (!npc.dontTakeDamage) + { + int onHitDamage = Player.CalcIntDamage(40); + Player.ApplyDamageToNPC(npc, onHitDamage, 0f, 0, false); + } SoundEngine.PlaySound(SoundID.NPCHit33 with { Volume = 0.5f }, Player.Center); } @@ -1199,8 +1202,11 @@ public override void OnHitByNPC(NPC npc, Player.HurtInfo hurtInfo) { npc.AddBuff(ModContent.BuffType(), 900); npc.AddBuff(ModContent.BuffType(), 900); - int onHitDamage = Player.CalcIntDamage(250); - Player.ApplyDamageToNPC(npc, onHitDamage, 0f, 0, false); + if (!npc.dontTakeDamage) + { + int onHitDamage = Player.CalcIntDamage(250); + Player.ApplyDamageToNPC(npc, onHitDamage, 0f, 0, false); + } SoundEngine.PlaySound(BaroclawHit, Player.Center); Vector2 bloodSpawnPosition = Player.Center + Main.rand.NextVector2Circular(Player.width, Player.height) * 0.04f; Vector2 splatterDirection = (Player.Center - bloodSpawnPosition).SafeNormalize(Vector2.UnitY); @@ -1220,8 +1226,11 @@ public override void OnHitByNPC(NPC npc, Player.HurtInfo hurtInfo) if (absorber) { npc.AddBuff(ModContent.BuffType(), 900); - int onHitDamage = Player.CalcIntDamage(350); - Player.ApplyDamageToNPC(npc, onHitDamage, 0f, 0, false); + if (!npc.dontTakeDamage) + { + int onHitDamage = Player.CalcIntDamage(350); + Player.ApplyDamageToNPC(npc, onHitDamage, 0f, 0, false); + } SoundEngine.PlaySound(AbsorberHit, Player.Center); Vector2 bloodSpawnPosition = Player.Center + Main.rand.NextVector2Circular(Player.width, Player.height) * 0.04f; Vector2 splatterDirection = (Player.Center - bloodSpawnPosition).SafeNormalize(Vector2.UnitY); diff --git a/CalamityNetcode.cs b/CalamityNetcode.cs index 1ddc123fe0..2bf1c92e21 100644 --- a/CalamityNetcode.cs +++ b/CalamityNetcode.cs @@ -335,6 +335,39 @@ public static void HandlePacket(Mod mod, BinaryReader reader, int whoAmI) MusicEventSystem.ReceiveSyncResponse(reader); break; + // + // Bandit refund syncs + // + case CalamityModMessageType.SomeoneGotScammedByTinkerer: + int scammedOne = reader.ReadByte(); + int stolen = reader.Read7BitEncodedInt(); + CalamityWorld.MoneyStolenByBandit += stolen; + CalamityWorld.Reforges++; + // Broadcast back for tragic event + // WorldSync DO sync the MoneyStolenByBandit and Refores variable, But spamming SyncWorld is not a ideal action + if (Main.dedServ) + { + ModPacket packet = CalamityMod.Instance.GetPacket(); + packet.Write((byte)CalamityModMessageType.SomeoneGotScammedByTinkerer); + packet.Write((byte)scammedOne); + packet.Write7BitEncodedInt(stolen); + packet.Send(ignoreClient: scammedOne); + } + break; + case CalamityModMessageType.WantToRefundReforges: + int requester = reader.ReadByte(); + // Only Server should handle this action! + if (!Main.dedServ) + break; + int banditIdx = NPC.FindFirstNPC(ModContent.NPCType()); + if (banditIdx == -1) + break; + NPC bandit = Main.npc[banditIdx]; + if (bandit == null || !bandit.active) + break; + THIEF.DoRefund(bandit); + break; + // // Default case: with no idea how long the packet is, we can't safely read data. // Throw an exception now instead of allowing the network stream to corrupt. @@ -461,6 +494,10 @@ public enum CalamityModMessageType : byte // Music events MusicEventSyncRequest, - MusicEventSyncResponse + MusicEventSyncResponse, + + // Bandit Reforge Refund + SomeoneGotScammedByTinkerer, + WantToRefundReforges } } diff --git a/Items/CalamityGlobalItem.cs b/Items/CalamityGlobalItem.cs index 077b34fc84..12531fede4 100644 --- a/Items/CalamityGlobalItem.cs +++ b/Items/CalamityGlobalItem.cs @@ -1808,11 +1808,21 @@ public override void PostReforge(Item item) ItemLoader.ReforgePrice(item, ref value, ref p.discountAvailable); // Steal 20% of that money. - CalamityWorld.MoneyStolenByBandit += value / 5; + int stolen = value / 5; + CalamityWorld.MoneyStolenByBandit += stolen; // Increment the reforge counter to allow the Bandit to refund // Also triggers Tinkerer dialogue that hints to the player that money is being stolen CalamityWorld.Reforges++; + + if (Main.netMode == NetmodeID.MultiplayerClient) + { + ModPacket packet = CalamityMod.Instance.GetPacket(); + packet.Write((byte)CalamityModMessageType.SomeoneGotScammedByTinkerer); + packet.Write((byte)p.whoAmI); + packet.Write7BitEncodedInt(stolen); + packet.Send(); + } } } #endregion diff --git a/Items/SummonItems/Invasion/CausticTear.cs b/Items/SummonItems/Invasion/CausticTear.cs index 2de57c9d47..b21039e6d5 100644 --- a/Items/SummonItems/Invasion/CausticTear.cs +++ b/Items/SummonItems/Invasion/CausticTear.cs @@ -38,9 +38,12 @@ public override bool CanUseItem(Player player) public override bool? UseItem(Player player) { - CalamityNetcode.SyncWorld(); - AcidRainEvent.TryStartEvent(true); - return true; + // Only Single Player client and Server should call this! + if (Main.netMode != NetmodeID.MultiplayerClient) + { + AcidRainEvent.TryStartEvent(forceRain: true); + // TryStartEvent already syncs the world data + } } public override void AddRecipes() diff --git a/Items/SummonItems/Invasion/MartianDistressRemote.cs b/Items/SummonItems/Invasion/MartianDistressRemote.cs index 965b1b0ff3..8b92c70260 100644 --- a/Items/SummonItems/Invasion/MartianDistressRemote.cs +++ b/Items/SummonItems/Invasion/MartianDistressRemote.cs @@ -35,11 +35,34 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite itemGroup = ContentSamples.CreativeHelper.ItemGroup.EventItem; } - public override bool CanUseItem(Player player) => Main.invasionType == InvasionID.None; + public override bool CanUseItem(Player player) + { + // Do not start new invasion when it's already on going + if (Main.invasionType != InvasionID.None) + return false; + // This is the requirement for StartInvasion for some reason + // If this part is missing MartianRemote will show DD2 invasion GUI without any enemy spawn on MP + if (!Main.player.Any(p => p.active && p.ConsumedLifeCrystals >= 5)) + return false; + return true; + } public override bool? UseItem(Player player) { - Main.StartInvasion(InvasionID.MartianMadness); + // Single Player case + if (Main.netMode == NetmodeID.SinglePlayer) + { + Main.invasionDelay = 0; + Main.StartInvasion(InvasionID.MartianMadness); + return true; + } + // MP case: only owner should send Spawn Message to Master + if (player.whoAmI == Main.myPlayer) + { + //-7.0 is hardcoded id for MartianMadness Event + NetMessage.SendData(MessageID.SpawnBossUseLicenseStartEvent, number: player.whoAmI, number2: -7.0f); + return true; + } return true; } diff --git a/Items/Tools/ClimateChange/AridArtifact.cs b/Items/Tools/ClimateChange/AridArtifact.cs index 759f43754d..2568b27f94 100644 --- a/Items/Tools/ClimateChange/AridArtifact.cs +++ b/Items/Tools/ClimateChange/AridArtifact.cs @@ -1,6 +1,7 @@ using Terraria; using Terraria.ID; using Terraria.ModLoader; +using SandstormEvent = Terraria.GameContent.Events.Sandstorm; namespace CalamityMod.Items.Tools.ClimateChange { public class AridArtifact : ModItem, ILocalizedModType @@ -27,14 +28,15 @@ public override bool CanUseItem(Player player) return DownedBossSystem.downedDesertScourge || Main.hardMode; } - // this is extremely ugly and has to be fully qualified because we add an item called Sandstorm public override bool? UseItem(Player player) { - if (Terraria.GameContent.Events.Sandstorm.Happening) + // Only SinglePlayer and Server need to sync those parameters + if (Main.netMode == NetmodeID.MultiplayerClient) + return true; + if (SandstormEvent.Happening) CalamityUtils.StopSandstorm(); else CalamityUtils.StartSandstorm(); - return true; } public override void AddRecipes() diff --git a/Items/Tools/ClimateChange/Cosmolight.cs b/Items/Tools/ClimateChange/Cosmolight.cs index 70705a1e1a..b380c4f384 100644 --- a/Items/Tools/ClimateChange/Cosmolight.cs +++ b/Items/Tools/ClimateChange/Cosmolight.cs @@ -32,10 +32,13 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite itemGroup = (ContentSamples.CreativeHelper.ItemGroup)CalamityResearchSorting.ToolsOther; } - public override bool CanUseItem(Player player) + public override bool CanUseItem(Player player) => !CalamityPlayer.areThereAnyDamnBosses; + + public override bool? UseItem(Player player) { - if (CalamityPlayer.areThereAnyDamnBosses) - return false; + //Only SinglePlayer or DedServ should change time to prevent unwanted race condition + if (Main.netMode == NetmodeID.MultiplayerClient) + return true; // Early Morning -> Noon if (Main.dayTime && Main.time < NoonCutoff) diff --git a/Items/Tools/ClimateChange/TorrentialTear.cs b/Items/Tools/ClimateChange/TorrentialTear.cs index fca095ca74..8f440f913b 100644 --- a/Items/Tools/ClimateChange/TorrentialTear.cs +++ b/Items/Tools/ClimateChange/TorrentialTear.cs @@ -31,13 +31,17 @@ public override bool CanUseItem(Player player) public override bool? UseItem(Player player) { + // Only SinglePlayer and Server need to sync those parameters + if (Main.netMode == NetmodeID.MultiplayerClient) + return true; + if (!Main.raining) { - CalamityUtils.StartRain(true); + CalamityUtils.StartRain(torrentialTear: true, worldSync: true); } else { - Main.raining = false; + CalamityUtils.StopRain(clearWeather: false, worldSync: true); } CalamityNetcode.SyncWorld(); diff --git a/NPCs/ExoMechs/Draedon.cs b/NPCs/ExoMechs/Draedon.cs index 8aaf2a126c..d0b90f2ba2 100644 --- a/NPCs/ExoMechs/Draedon.cs +++ b/NPCs/ExoMechs/Draedon.cs @@ -688,7 +688,7 @@ public void HandleDefeatStuff() ShouldStartStandingUp = true; // Different text if Exo Mechdusa - if (exoMechdusa) + if (exoMechdusa && Main.netMode != NetmodeID.MultiplayerClient) { if (DefeatTimer == DelayBeforeDefeatStandup + 50f) CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Status.Boss.DraedonMechdusaEndText1", TextColor); @@ -697,7 +697,7 @@ public void HandleDefeatStuff() CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Status.Boss.DraedonMechdusaEndText2", TextColor); } // Otherwise do normal text - else + else if (Main.netMode != NetmodeID.MultiplayerClient) { if (DefeatTimer == DelayBeforeDefeatStandup + 50f) CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Status.Boss.DraedonEndText1", TextColor); diff --git a/NPCs/TownNPCs/THIEF.cs b/NPCs/TownNPCs/THIEF.cs index ff591a3aea..94b5f94198 100644 --- a/NPCs/TownNPCs/THIEF.cs +++ b/NPCs/TownNPCs/THIEF.cs @@ -10,6 +10,7 @@ using ReLogic.Content; using Terraria; using Terraria.Audio; +using Terraria.DataStructures; using Terraria.GameContent; using Terraria.GameContent.Bestiary; using Terraria.GameContent.Events; @@ -217,20 +218,25 @@ public string Refund() int goblinIndex = NPC.FindFirstNPC(NPCID.GoblinTinkerer); if (goblinIndex != -1 && CalamityWorld.Reforges >= 1) { - CalamityWorld.Reforges = 0; - int[] coinCounts = Utils.CoinsSplit(CalamityWorld.MoneyStolenByBandit); - if (coinCounts[0] > 0) - Item.NewItem(NPC.GetSource_Loot(), NPC.Hitbox, ItemID.CopperCoin, coinCounts[0]); - if (coinCounts[1] > 0) - Item.NewItem(NPC.GetSource_Loot(), NPC.Hitbox, ItemID.SilverCoin, coinCounts[1]); - if (coinCounts[2] > 0) - Item.NewItem(NPC.GetSource_Loot(), NPC.Hitbox, ItemID.GoldCoin, coinCounts[2]); - if (coinCounts[3] > 0) - Item.NewItem(NPC.GetSource_Loot(), NPC.Hitbox, ItemID.PlatinumCoin, coinCounts[3]); - - CalamityWorld.MoneyStolenByBandit = 0; + if (Main.netMode == NetmodeID.SinglePlayer) + { + DoRefund(bandit: NPC); + } + else if (Main.netMode == NetmodeID.MultiplayerClient) + { + // Possible Bug here: Minor text bug when two players send request this simultaneously + // Which result to both player to have successful message but only one request got accepted on server + // But since this is how base gamecode works theres no way to fix this clean way (Unless someone implement net queued response for NPC dialog) + // And as this does not duplicate the coin amount, It's not that bad I think...? + // + // Other way possible is to having bandit stolen inventory per player + // But I didn't wanted to change system too much + ModPacket packet = CalamityMod.Instance.GetPacket(); + packet.Write((byte)CalamityModMessageType.WantToRefundReforges); + packet.Write((byte)Main.myPlayer); + packet.Send(); + } SoundEngine.PlaySound(SoundID.Coins); // Money dink sound - CalamityNetcode.SyncWorld(); switch (Main.rand.Next(2)) { case 0: @@ -242,6 +248,26 @@ public string Refund() return this.GetLocalizedValue("NoRefund"); } + public static void DoRefund(NPC bandit) + { + if (bandit == null) + return; + if (CalamityWorld.Reforges <= 0) + return; + int[] coinCounts = Utils.CoinsSplit(CalamityWorld.MoneyStolenByBandit); + if (coinCounts[0] > 0) + Item.NewItem(new EntitySource_Gift(bandit), bandit.Hitbox, ItemID.CopperCoin, coinCounts[0]); + if (coinCounts[1] > 0) + Item.NewItem(new EntitySource_Gift(bandit), bandit.Hitbox, ItemID.SilverCoin, coinCounts[1]); + if (coinCounts[2] > 0) + Item.NewItem(new EntitySource_Gift(bandit), bandit.Hitbox, ItemID.GoldCoin, coinCounts[2]); + if (coinCounts[3] > 0) + Item.NewItem(new EntitySource_Gift(bandit), bandit.Hitbox, ItemID.PlatinumCoin, coinCounts[3]); + CalamityWorld.MoneyStolenByBandit = 0; + CalamityWorld.Reforges = 0; + CalamityNetcode.SyncWorld(); + } + public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color drawColor) { if (Main.LocalPlayer.Calamity().trippy) diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/PlanteraAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/PlanteraAI.cs index 04d87dc3be..2a732316e9 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/PlanteraAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/PlanteraAI.cs @@ -235,9 +235,8 @@ public static bool BuffedPlanteraAI(NPC npc, Mod mod) if (Main.netMode != NetmodeID.MultiplayerClient) { - int proj = Projectile.NewProjectile(npc.GetSource_FromAI(), adjustProjectileShootLocation ? npc.Center : spawnOffset, projectileVelocity * projectileSpeed, projectileType, damage, 0f, Main.myPlayer); - if (projectileType == ProjectileID.ThornBall && (Main.rand.NextBool() || !Main.zenithWorld)) - Main.projectile[proj].tileCollide = false; + float ai2 = projectileType == ProjectileID.ThornBall && (Main.rand.NextBool() || !Main.zenithWorld) ? 1f : 0f; + Projectile.NewProjectile(npc.GetSource_FromAI(), adjustProjectileShootLocation ? npc.Center : spawnOffset, projectileVelocity * projectileSpeed, projectileType, damage, 0f, Main.myPlayer, 0f, 0f, ai2); } } } @@ -800,9 +799,10 @@ public static bool BuffedPlanteraAI(NPC npc, Mod mod) if (Main.netMode != NetmodeID.MultiplayerClient) { - int proj = Projectile.NewProjectile(npc.GetSource_FromAI(), spawnOffset, projectileVelocity * projectileSpeed, type, damage, 0f, Main.myPlayer); + float ai2 = 0f; if (Main.rand.NextBool() || !Main.zenithWorld) - Main.projectile[proj].tileCollide = false; + ai2 = 1f; + Projectile.NewProjectile(npc.GetSource_FromAI(), spawnOffset, projectileVelocity * projectileSpeed, type, damage, 0f, Main.myPlayer, 0f, 0f, ai2); } } } diff --git a/Particles/GeneralParticleHandler.cs b/Particles/GeneralParticleHandler.cs index ddcc4ff9da..acc8ebd586 100644 --- a/Particles/GeneralParticleHandler.cs +++ b/Particles/GeneralParticleHandler.cs @@ -95,6 +95,9 @@ public static void SpawnParticle(Particle particle) public static void Update() { + if (Main.dedServ) + return; + foreach (Particle particle in particles) { if (particle == null) @@ -110,11 +113,17 @@ public static void Update() public static void RemoveParticle(Particle particle) { + if (Main.dedServ) + return; + particlesToKill.Add(particle); } public static void DrawAllParticles(SpriteBatch sb) { + if (Main.dedServ) + return; + if (particles.Count == 0) return; @@ -221,7 +230,13 @@ public static int FreeSpacesAvailable() /// /// Gives you the texture of the particle type. Useful for custom drawing /// - public static Texture2D GetTexture(int type) => particleTextures[type]; + public static Texture2D GetTexture(int type) + { + if (Main.dedServ) + return null; + + return particleTextures[type]; + } #pragma warning disable CS0414 private static string noteToEveryone = "This particle system was inspired by spirit mod's own particle system, with permission granted by Yuyutsu. Love you spirit mod! -Iban"; diff --git a/Projectiles/CalamityGlobalProjectile.cs b/Projectiles/CalamityGlobalProjectile.cs index 45d77f7a00..b80b8e3805 100644 --- a/Projectiles/CalamityGlobalProjectile.cs +++ b/Projectiles/CalamityGlobalProjectile.cs @@ -2648,8 +2648,9 @@ public override bool PreAI(Projectile projectile) return false; } - else if (projectile.type == ProjectileID.ThornBall && !projectile.tileCollide) + else if (projectile.type == ProjectileID.ThornBall && projectile.ai[2] != 0) { + projectile.tileCollide = false; if (projectile.alpha > 0) { projectile.alpha -= 30; diff --git a/Tiles/CalamityGlobalTile.cs b/Tiles/CalamityGlobalTile.cs index bccfbf26c0..13fd8f4d53 100644 --- a/Tiles/CalamityGlobalTile.cs +++ b/Tiles/CalamityGlobalTile.cs @@ -395,25 +395,44 @@ void CheckShatterCrystal(int xPos, int yPos, bool dontShatter) public override void Drop(int i, int j, int type)/* tModPorter Suggestion: Use CanDrop to decide if items can drop, use this method to drop additional items. See documentation. */ { - Tile tileAtPosition = CalamityUtils.ParanoidTileRetrieval(i, j); - if (tileAtPosition.TileFrameX % 36 == 0 && tileAtPosition.TileFrameY % 36 == 0) + // Handle for Demon Altar Drops + // Drop: + // - Soul of Night (x4) (Only if Early Hardmode Progression Rework is on) + // - Evil Smasher (x1) (Every 12th altar) + if (type == TileID.DemonAltar && Main.hardMode) { - if (type == TileID.DemonAltar && Main.hardMode) + Vector2 spreadMinMax = new Vector2(-32.0f, 32.0f); + // Drop 4 Soul of Night + if (CalamityConfig.Instance.EarlyHardmodeProgressionRework) { - Vector2 pos = new Vector2(i, j) * 16; - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework) - { - WorldGen.altarCount++; - int quantity = 4; - for (int k = 0; k < quantity; k += 1) - { - pos.X += Main.rand.NextFloat(-32f, 32f); - pos.Y += Main.rand.NextFloat(-32f, 32f); - Item.NewItem(new EntitySource_TileBreak(i, j), pos, ItemID.SoulofNight); - } - } - if (WorldGen.altarCount % 12 == 0 && WorldGen.altarCount > 1) - Item.NewItem(new EntitySource_TileBreak(i, j), pos, ModContent.ItemType()); + DropItem(i, j, ItemID.SoulofNight, quantity: 4, asStack: false, spreadMinMax); + WorldGen.altarCount++; // altarCount does not update automatically if ProgressionRework is enabled! + } + // Drop Evil Smasher on every 12 alter smashed + if (WorldGen.altarCount > 1 && WorldGen.altarCount % 12 == 0) + { + DropItem(i, j, ModContent.ItemType(), quantity: 1, asStack: true); + } + } + } + + private static void DropItem(int i, int j, int itemType, int quantity, bool asStack, Vector2 spreadMinMax = default) + { + // Multiplayer Client should not spawn item themselves + if (Main.netMode == NetmodeID.MultiplayerClient) + return; + Vector2 worldPos = new Vector2(i, j) * 16.0f; + if (asStack) + { + Vector2 spawnOffset = Main.rand.NextVector2Unit(spreadMinMax.X, spreadMinMax.Y); + Item.NewItem(new EntitySource_TileBreak(i, j), worldPos + spawnOffset, itemType, Stack: quantity); + } + else + { + for (int k = 0; k < quantity; k += 1) + { + Vector2 spawnOffset = Main.rand.NextVector2Unit(spreadMinMax.X, spreadMinMax.Y); + Item.NewItem(new EntitySource_TileBreak(i, j), worldPos + spawnOffset, itemType, Stack: 1); } } } diff --git a/Tiles/Crags/Tree/SpineTree.cs b/Tiles/Crags/Tree/SpineTree.cs index a5ab31f444..fd1eb980f4 100644 --- a/Tiles/Crags/Tree/SpineTree.cs +++ b/Tiles/Crags/Tree/SpineTree.cs @@ -153,7 +153,12 @@ public override void NearbyEffects(int i, int j, bool closer) if (!Framing.GetTileSafely(i, j + 1).HasTile) { WorldGen.KillTile(i, j, false, false, false); + if (Main.netMode == NetmodeID.MultiplayerClient) + { + NetMessage.SendData(MessageID.TileManipulation, -1, -1, null, 0, i, j); + } } + } diff --git a/Utilities/MiscUtils.cs b/Utilities/MiscUtils.cs index 3654c3679a..1695877872 100644 --- a/Utilities/MiscUtils.cs +++ b/Utilities/MiscUtils.cs @@ -195,7 +195,7 @@ public static void SafeVolumeChange(ref SoundEffectInstance sfx, float volumeMul sfx.Volume = MathHelper.Clamp(sfx.Volume * volumeMultiplier, 0f, 1f); } - public static void StartRain(bool torrentialTear = false, bool maxSeverity = false) + public static void StartRain(bool torrentialTear = false, bool maxSeverity = false, bool worldSync = true) { int framesInDay = 86400; int framesInHour = framesInDay / 24; @@ -245,7 +245,19 @@ public static void StartRain(bool torrentialTear = false, bool maxSeverity = fal Main.raining = true; if (torrentialTear) TorrentialTear.AdjustRainSeverity(maxSeverity); - CalamityNetcode.SyncWorld(); + if (worldSync) + CalamityNetcode.SyncWorld(); + } + + public static void StopRain(bool clearWeather = false, bool worldSync = true) + { + if (clearWeather) + Main.StopRain(); + else + Main.raining = false; + + if (worldSync) + CalamityNetcode.SyncWorld(); } public static void StartSandstorm() @@ -277,7 +289,10 @@ public static void StartSandstorm() public static void StopSandstorm() { - Terraria.GameContent.Events.Sandstorm.Happening = false; + if (Main.netMode != NetmodeID.MultiplayerClient) + { + Terraria.GameContent.Events.Sandstorm.Happening = false; + } } public static void AddWithCondition(this List list, T type, bool condition) diff --git a/Utilities/TileUtils.cs b/Utilities/TileUtils.cs index 5b6b1e6d5b..3c387d7961 100644 --- a/Utilities/TileUtils.cs +++ b/Utilities/TileUtils.cs @@ -103,6 +103,9 @@ public static void LightHitWire(int type, int i, int j, int tileX, int tileY) Wiring.SkipWire(x + k, y + l); } } + + if (Main.netMode != NetmodeID.SinglePlayer) + NetMessage.SendTileSquare(-1, x, y, tileX, tileY); } public static void DrawFlameEffect(Texture2D flameTexture, int i, int j, int offsetX = 0, int offsetY = 0) diff --git a/Walls/AbyssGravelWall.cs b/Walls/AbyssGravelWall.cs index 6f1e832c06..44e781e3a0 100644 --- a/Walls/AbyssGravelWall.cs +++ b/Walls/AbyssGravelWall.cs @@ -20,7 +20,7 @@ public override void RandomUpdate(int i, int j) Main.tile[i, j].Get().LiquidType = LiquidID.Water; Main.tile[i, j].LiquidAmount = byte.MaxValue; WorldGen.SquareTileFrame(i, j); - if (Main.netMode == NetmodeID.MultiplayerClient) + if (Main.dedServ) NetMessage.sendWater(i, j); } } diff --git a/Walls/EutrophicSandWall.cs b/Walls/EutrophicSandWall.cs index b00ae2284b..d6b6bb71c2 100644 --- a/Walls/EutrophicSandWall.cs +++ b/Walls/EutrophicSandWall.cs @@ -20,7 +20,7 @@ public override void RandomUpdate(int i, int j) Main.tile[i, j].Get().LiquidType = LiquidID.Water; Main.tile[i, j].LiquidAmount = byte.MaxValue; WorldGen.SquareTileFrame(i, j); - if (Main.netMode == NetmodeID.MultiplayerClient) + if (Main.dedServ) NetMessage.sendWater(i, j); } } diff --git a/Walls/PyreMantleWall.cs b/Walls/PyreMantleWall.cs index 69621281e9..6ee73138b7 100644 --- a/Walls/PyreMantleWall.cs +++ b/Walls/PyreMantleWall.cs @@ -20,7 +20,7 @@ public override void RandomUpdate(int i, int j) Main.tile[i, j].Get().LiquidType = LiquidID.Water; Main.tile[i, j].LiquidAmount = byte.MaxValue; WorldGen.SquareTileFrame(i, j); - if (Main.netMode == NetmodeID.MultiplayerClient) + if (Main.dedServ) NetMessage.sendWater(i, j); } } diff --git a/Walls/VoidstoneWallUnsafe.cs b/Walls/VoidstoneWallUnsafe.cs index 0f0b24ea66..25b966c127 100644 --- a/Walls/VoidstoneWallUnsafe.cs +++ b/Walls/VoidstoneWallUnsafe.cs @@ -30,7 +30,7 @@ public override void RandomUpdate(int i, int j) Main.tile[i, j].Get().LiquidType = LiquidID.Water; Main.tile[i, j].LiquidAmount = byte.MaxValue; WorldGen.SquareTileFrame(i, j); - if (Main.netMode == NetmodeID.MultiplayerClient) + if (Main.dedServ) NetMessage.sendWater(i, j); } } From f92ebe7eac6767ae7c84d6236e3dd7586bfbb7a4 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <142704082+CongratsIsTrash@users.noreply.github.com> Date: Fri, 31 Jan 2025 13:01:05 -0500 Subject: [PATCH 201/401] Final stuff from me: Secret seed things 1 - Celebrationmk10 is now forced to spawn on the Jungle-side Ocean to prevent spawning in the Sulphurous Sea 2 - Moved Calamity final worldgen adjustments to happen before final secret seed adjustments and Dirtiest Block gen (also fixes Forsaken Archive not being painted in secret seeds) 3 - Gravity Normalizer now negates the low gravity of Remix surface 4 - Fixed Aerialite not spawning in Remix 5 - Fixed Cloud Elemental not spawning in Remix 6 - Fixed Armored Digger GFB drops appearing in the bestiary 7 - Fixed Jungle Temple not generating on the surface in Remix 8 - Fixed Mimic and Ice Mimic loot pools in Remix 9 - Fixed Sandstorm's Core broken localization in GFB --- CalPlayer/CalamityPlayerMiscEffects.cs | 2 +- Items/SummonItems/SandstormsCore.cs | 2 +- NPCs/CalamityGlobalNPCLoot.cs | 66 +++++++++++++++++++++----- NPCs/NormalNPCs/ArmoredDiggerHead.cs | 4 +- NPCs/NormalNPCs/ThiccWaifu.cs | 2 +- Systems/WorldgenManagementSystem.cs | 28 ++++++++++- Utilities/PlayerUtils.cs | 4 +- World/AerialiteOreGen.cs | 6 +-- World/CustomTemple.cs | 26 ++++++++-- 9 files changed, 112 insertions(+), 28 deletions(-) diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index a3ed869174..9c339b8add 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -2512,7 +2512,7 @@ private void OtherBuffEffects() if (gravityNormalizer) { Player.buffImmune[BuffID.VortexDebuff] = true; - if (Player.InSpace()) + if (Player.ReducedSpaceGravity()) { Player.gravity = Player.defaultGravity; if (Player.wet) diff --git a/Items/SummonItems/SandstormsCore.cs b/Items/SummonItems/SandstormsCore.cs index 32dba4f830..63d2f7ab20 100644 --- a/Items/SummonItems/SandstormsCore.cs +++ b/Items/SummonItems/SandstormsCore.cs @@ -50,7 +50,7 @@ public override bool CanUseItem(Player player) return true; } - public override void ModifyTooltips(List list) => list.FindAndReplace("[BIOME]", Main.zenithWorld ? CalamityUtils.GetTextValue("Biomes.AstralDesert") : Language.GetTextValue("Bestiary_Biomes.Desert")); + public override void ModifyTooltips(List list) => list.FindAndReplace("[BIOME]", Main.zenithWorld ? CalamityUtils.GetTextValue("Biomes.AstralDesert.TownNPCDialogueName") : Language.GetTextValue("Bestiary_Biomes.Desert")); public override void AddRecipes() { diff --git a/NPCs/CalamityGlobalNPCLoot.cs b/NPCs/CalamityGlobalNPCLoot.cs index 6b875b8cad..fee18a037d 100644 --- a/NPCs/CalamityGlobalNPCLoot.cs +++ b/NPCs/CalamityGlobalNPCLoot.cs @@ -162,19 +162,42 @@ bool ShouldDropMechLore(DropAttemptInfo info) return false; }); - int[] mimicItems = new int[] - { + // Yes, Mimics have three separate loot tables which we must reintegrate + int[] normalMimicItems = + [ ItemID.MagicDagger, ItemID.CrossNecklace, ItemID.PhilosophersStone, ItemID.StarCloak, ItemID.TitanGlove, ItemID.DualHook - }; + ]; + int[] remixPreHardMimicItems = + [ + ItemID.BandofRegeneration, + ItemID.MagicMirror, + ItemID.CloudinaBottle, + ItemID.HermesBoots, + ItemID.ShoeSpikes, + ItemID.Mace + ]; + int[] remixHardmodeMimicItems = + [ + ItemID.WandofSparking, + ItemID.CrossNecklace, + ItemID.PhilosophersStone, + ItemID.StarCloak, + ItemID.TitanGlove, + ItemID.DualHook + ]; // Mimics will not drop any items if spawned from statues. - var notStatue = npcLoot.DefineConditionalDropSet(new Conditions.NotFromStatue()); - notStatue.Add(DropHelper.CalamityStyle(DropHelper.NormalWeaponDropRateFraction, mimicItems)); + var notRemix = npcLoot.DefineConditionalDropSet(DropHelper.If(() => !(npc.SpawnedFromStatue || Main.remixWorld))); + var remixPreHM = npcLoot.DefineConditionalDropSet(DropHelper.If(() => !npc.SpawnedFromStatue && Main.remixWorld && !Main.hardMode)); + var remixHardmode = npcLoot.DefineConditionalDropSet(DropHelper.If(() => !npc.SpawnedFromStatue && Main.remixWorld && Main.hardMode)); + notRemix.Add(DropHelper.CalamityStyle(DropHelper.NormalWeaponDropRateFraction, normalMimicItems)); + remixPreHM.Add(DropHelper.CalamityStyle(DropHelper.NormalWeaponDropRateFraction, remixPreHardMimicItems)); + remixHardmode.Add(DropHelper.CalamityStyle(DropHelper.NormalWeaponDropRateFraction, remixHardmodeMimicItems)); } catch (ArgumentNullException) { } break; @@ -225,17 +248,38 @@ bool ShouldDropMechLore(DropAttemptInfo info) return false; }); - int[] iceMimicItems = new int[] - { + // Yes, Ice Mimics have three separate loot tables which me must reintegrate + int[] normalIceMimicItems = + [ ItemID.Frostbrand, ItemID.IceBow, ItemID.FlowerofFrost - }; + ]; + int[] remixPreHardIceMimicItems = + [ + ItemID.IceBoomerang, + ItemID.IceBlade, + ItemID.IceBow, + ItemID.IceSkates, + ItemID.BlizzardinaBottle, + ItemID.FlurryBoots + ]; + int[] remixHardmodeIceMimicItems = + [ + ItemID.Frostbrand, + ItemID.SnowballCannon, + ItemID.FlowerofFrost + ]; // Ice Mimics will not drop any items if spawned from statues. - var notStatue = npcLoot.DefineConditionalDropSet(new Conditions.NotFromStatue()); - notStatue.Add(DropHelper.CalamityStyle(DropHelper.NormalWeaponDropRateFraction, iceMimicItems)); - notStatue.Add(ItemID.ToySled, 20, 1, 1); + var notRemix = npcLoot.DefineConditionalDropSet(DropHelper.If(() => !(npc.SpawnedFromStatue || Main.remixWorld))); + var remixPreHM = npcLoot.DefineConditionalDropSet(DropHelper.If(() => !npc.SpawnedFromStatue && Main.remixWorld && !Main.hardMode)); + var remixHardmode = npcLoot.DefineConditionalDropSet(DropHelper.If(() => !npc.SpawnedFromStatue && Main.remixWorld && Main.hardMode)); + notRemix.Add(DropHelper.CalamityStyle(DropHelper.NormalWeaponDropRateFraction, normalIceMimicItems)); + remixPreHM.Add(DropHelper.CalamityStyle(DropHelper.NormalWeaponDropRateFraction, remixPreHardIceMimicItems)); + remixHardmode.Add(DropHelper.CalamityStyle(DropHelper.NormalWeaponDropRateFraction, remixHardmodeIceMimicItems)); + // Independent from all of the Remix madness, Ice Mimics have a 5% chance to drop Toy Sled. + npcLoot.DefineConditionalDropSet(new Conditions.NotFromStatue()).Add(ItemID.ToySled, 20); } catch (ArgumentNullException) { } break; diff --git a/NPCs/NormalNPCs/ArmoredDiggerHead.cs b/NPCs/NormalNPCs/ArmoredDiggerHead.cs index 70fc0433aa..2d46af55bd 100644 --- a/NPCs/NormalNPCs/ArmoredDiggerHead.cs +++ b/NPCs/NormalNPCs/ArmoredDiggerHead.cs @@ -475,8 +475,8 @@ public override void ModifyNPCLoot(NPCLoot npcLoot) npcLoot.Add(ModContent.ItemType(), 1, 2, 4); npcLoot.Add(ModContent.ItemType(), 1, 4, 8); npcLoot.Add(ModContent.ItemType(), 1, 4, 8); - npcLoot.AddIf(() => Main.zenithWorld, ModContent.ItemType(), 1, 3, 6); - npcLoot.AddIf(() => Main.zenithWorld, ModContent.ItemType(), 10); + npcLoot.AddIf(() => Main.zenithWorld, ModContent.ItemType(), 1, 3, 6, ui: false); + npcLoot.AddIf(() => Main.zenithWorld, ModContent.ItemType(), 10, ui: false); } public override void ModifyTypeName(ref string typeName) diff --git a/NPCs/NormalNPCs/ThiccWaifu.cs b/NPCs/NormalNPCs/ThiccWaifu.cs index f0c7452571..79fe0ad633 100644 --- a/NPCs/NormalNPCs/ThiccWaifu.cs +++ b/NPCs/NormalNPCs/ThiccWaifu.cs @@ -451,7 +451,7 @@ public override void FindFrame(int frameHeight) public override float SpawnChance(NPCSpawnInfo spawnInfo) { - if (spawnInfo.PlayerSafe || !Main.hardMode || !Main.raining || !spawnInfo.Player.ZoneSkyHeight) + if (spawnInfo.PlayerSafe || !Main.hardMode || (!Main.raining && !Main.remixWorld) || !spawnInfo.Player.ZoneSkyHeight) return 0f; // Keep this as a separate if check, because it's a loop and we don't want to be checking it constantly. diff --git a/Systems/WorldgenManagementSystem.cs b/Systems/WorldgenManagementSystem.cs index 822a6dac34..df706f93c0 100644 --- a/Systems/WorldgenManagementSystem.cs +++ b/Systems/WorldgenManagementSystem.cs @@ -94,6 +94,30 @@ public override void ModifyWorldGenTasks(List tasks, ref double totalWe })); } + // Move spawn point in Celebrationmk10 to not be in the Sulphurous Sea + int spawnPointIndex = tasks.FindIndex(genpass => genpass.Name.Equals("Spawn Point")); + if (spawnPointIndex != -1 && WorldGen.tenthAnniversaryWorldGen && !WorldGen.getGoodWorldGen) + { + tasks.Insert(spawnPointIndex + 1, new PassLegacy("Fix Tenth Anniversary Spawn", (progress, config) => + { + if ((Main.spawnTileX < Main.maxTilesX / 2 && GenVars.dungeonSide == -1) || (Main.spawnTileX > Main.maxTilesX / 2 && GenVars.dungeonSide == 1)) + { + // Flip the side of the world you spawn on if it's the Dungeon side + Main.spawnTileX = Main.maxTilesX - Main.spawnTileX; + // Then fix the Y position of the spawn point + for (int i = 0; i < Main.maxTilesY; i++) + { + if (Main.tile[Main.spawnTileX, i].HasTile) + { + Main.spawnTileY = i; + break; + } + } + } + + })); + } + // Mechanic Shed int mechanicIndex = tasks.FindIndex(genpass => genpass.Name.Equals("Sunflowers")); if (mechanicIndex != -1) @@ -131,12 +155,12 @@ public override void ModifyWorldGenTasks(List tasks, ref double totalWe })); } - // All further tasks occur after vanilla worldgen is completed + // All further tasks occur right before vanilla worldgen is completed (which includes The Dirtiest Block and final secret seed adjustments) int FinalIndex = tasks.FindIndex(genpass => genpass.Name.Equals("Final Cleanup")); if (FinalIndex != -1) { // Reallocate gems so rarity corresponds to depth - int currentFinalIndex = FinalIndex; + int currentFinalIndex = FinalIndex - 1; tasks.Insert(++currentFinalIndex, new PassLegacy("Gem Depth Adjustment", (progress, config) => { progress.Message = Language.GetOrRegister("Mods.CalamityMod.UI.GemAdjustment").Value; diff --git a/Utilities/PlayerUtils.cs b/Utilities/PlayerUtils.cs index faf8ed2d66..cdead115fc 100644 --- a/Utilities/PlayerUtils.cs +++ b/Utilities/PlayerUtils.cs @@ -327,11 +327,11 @@ public static bool CheckSolidGround(this Player player, int solidGroundAhead = 0 #region Location and Biomes public static bool IsUnderwater(this Player player) => Collision.DrownCollision(player.position, player.width, player.height, player.gravDir); - public static bool InSpace(this Player player) + public static bool ReducedSpaceGravity(this Player player) { float x = Main.maxTilesX / 4200f; x *= x; - float spaceGravityMult = (float)((player.position.Y / 16f - (60f + 10f * x)) / (Main.worldSurface / 6.0)); + float spaceGravityMult = (float)((player.position.Y / 16f - (60f + 10f * x)) / (Main.worldSurface / (Main.remixWorld ? 1.0 : 6.0))); return spaceGravityMult < 1f; } diff --git a/World/AerialiteOreGen.cs b/World/AerialiteOreGen.cs index 497e2d6017..0df55e7229 100644 --- a/World/AerialiteOreGen.cs +++ b/World/AerialiteOreGen.cs @@ -30,11 +30,11 @@ public static void Generate() Tile tile = Main.tile[x, y]; // The following conditions must happen in order for aerialite to generate: - // 1. The original tile ID must be that of a cloud. + // 1. The original tile ID must be that of a Cloud, Lesion Block, or Flesh Block. // 2. The original tile must not be empty air. // 3. A random dice-roll must land correctly, to ensure that patches of ore are occasional. // If any of these conditions are not met, this loop iteration is skipped. - if (tile.TileType != TileID.Cloud || !tile.HasTile || !WorldGen.genRand.NextBool(CloudOreConversionChance)) + if (!(tile.TileType == TileID.Cloud || tile.TileType == TileID.LesionBlock || tile.TileType == TileID.FleshBlock) || !tile.HasTile || !WorldGen.genRand.NextBool(CloudOreConversionChance)) continue; int radius = (int)(WorldGen.genRand.Next(3, 5) * WorldGen.genRand.NextFloat(0.74f, 0.82f)); @@ -51,7 +51,7 @@ public static void Generate() WorldUtils.Gen(new Point(x, y), new ModShapes.All(biggerCircle), Actions.Chain(new GenAction[] { new Actions.ClearTile(), - new Actions.PlaceTile((ushort)TileID.Cloud) + new Actions.PlaceTile(tile.TileType) })); // Circle of ore. diff --git a/World/CustomTemple.cs b/World/CustomTemple.cs index 007f9721cc..1ffd63a2b0 100644 --- a/World/CustomTemple.cs +++ b/World/CustomTemple.cs @@ -26,18 +26,34 @@ public static void NewJungleTemple() int y = WorldGen.genRand.Next((int)Main.rockLayer, Main.maxTilesY - 500); - if (Main.tile[x, y].HasTile && Main.tile[x, y].TileType == 60) + if (Main.remixWorld) { - Rectangle ugDesert = GenVars.UndergroundDesertLocation; - Rectangle InflatedSunkenSeaLocation = new Rectangle(ugDesert.Left - 160, ugDesert.Center.Y - 160, ugDesert.Width + 320, ugDesert.Height / 2 + 320); - Rectangle TempleLocation = new Rectangle(x - 80, y - 80, 160, 160); + while (Main.tile[x, y].HasTile || Main.tile[x, y].WallType > 0 || y > (int)(Main.worldSurface - 5.0)) + { + y--; + } - if (!TempleLocation.Intersects(InflatedSunkenSeaLocation)) + y++; + if (Main.tile[x, y].HasTile && (Main.tile[x, y].TileType == TileID.JungleGrass || Main.tile[x, y].TileType == TileID.Mud)) { success = true; GenNewTemple(x, y); } } + else + { + if (Main.tile[x, y].HasTile && Main.tile[x, y].TileType == TileID.JungleGrass) + { + Rectangle ugDesert = GenVars.UndergroundDesertLocation; + Rectangle InflatedSunkenSeaLocation = new Rectangle(ugDesert.Left - 160, ugDesert.Center.Y - 160, ugDesert.Width + 320, ugDesert.Height / 2 + 320); + Rectangle TempleLocation = new Rectangle(x - 80, y - 80, 160, 160); + if (!TempleLocation.Intersects(InflatedSunkenSeaLocation)) + { + success = true; + GenNewTemple(x, y); + } + } + } } } From d04b1283030cfc0ca603bbb9f0b445ddce2f0f05 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <142704082+CongratsIsTrash@users.noreply.github.com> Date: Mon, 10 Feb 2025 18:29:57 -0500 Subject: [PATCH 202/401] Fixed Amalgam making buff duration flicker when using infinite buff features --- CalPlayer/CalamityPlayerMiscEffects.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index 9c339b8add..ae99d8adb8 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -3616,7 +3616,9 @@ private void OtherBuffEffects() if (amalgam) { // Every other frame, increase the buff timer by one frame. Thus, the buff lasts twice as long. - if (Player.miscCounter % 2 == 0) + // CIT 1NOV2024: Amalgam does not add to the buff time if it's at 2 or lower, + // to prevent buff duration showing when using infinite buff features from other mods. + if (Player.miscCounter % 2 == 0 && Player.buffTime[l] > 2) Player.buffTime[l] += 1; // Buffs will not go away when you die, to prevent wasting potions. From f7e73310028c9e2285ea4d6a9c019bbd7930d2c2 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Tue, 11 Feb 2025 03:34:13 -0600 Subject: [PATCH 203/401] 1 - Removed Yharon plush promotional messages. 2 - Actually killed coco's feather. --- CalPlayer/CalamityPlayerMiscEffects.cs | 3 ++- CalPlayer/DrawLayers/HatExtensionLayer.cs | 3 --- Items/TreasureBags/MiscGrabBags/StarterBag.cs | 10 ---------- .../en-US/Mods.CalamityMod.Items.Accessories.hjson | 5 ----- NPCs/CalamityGlobalNPCLoot.cs | 1 - description_workshop.txt | 1 - 6 files changed, 2 insertions(+), 21 deletions(-) diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index a3ed869174..cbfb750504 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -4170,7 +4170,8 @@ private void HandleTextChatMessages() } // 31OCT2024: Fabsol: Plushie message always appears. - CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.GimmeSwagPlushieCampaign"); + // 11FEB2024: Fabsol: Currently commented out because the campaign has ended. + // CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.GimmeSwagPlushieCampaign"); } --startMessageDisplayDelay; diff --git a/CalPlayer/DrawLayers/HatExtensionLayer.cs b/CalPlayer/DrawLayers/HatExtensionLayer.cs index b2231f0f0a..7b512ea262 100644 --- a/CalPlayer/DrawLayers/HatExtensionLayer.cs +++ b/CalPlayer/DrawLayers/HatExtensionLayer.cs @@ -23,9 +23,6 @@ protected override void Draw(ref PlayerDrawSet drawInfo) if (drawPlayer.armor[10].type > ItemID.None) headItem = drawPlayer.armor[10]; - if (drawPlayer.Calamity().cocosFeather) - headItem = new Item(ModContent.ItemType()); - if (ModContent.GetModItem(headItem.type) is IExtendedHat extendedHatDrawer) { string equipSlotName = extendedHatDrawer.EquipSlotName(drawPlayer) != "" ? extendedHatDrawer.EquipSlotName(drawPlayer) : headItem.ModItem.Name; diff --git a/Items/TreasureBags/MiscGrabBags/StarterBag.cs b/Items/TreasureBags/MiscGrabBags/StarterBag.cs index 54fe68cbde..9423468e0d 100644 --- a/Items/TreasureBags/MiscGrabBags/StarterBag.cs +++ b/Items/TreasureBags/MiscGrabBags/StarterBag.cs @@ -110,16 +110,6 @@ static bool getsOracleHeadphones(DropAttemptInfo info) itemLoot.AddIf(getsOracleHeadphones, ModContent.ItemType()); - // Bird dev item - // Name specific: "bird" - static bool getsSakuraFeather(DropAttemptInfo info) - { - string playerName = info.player.name; - return playerName == "bird"; - } - - itemLoot.AddIf(getsSakuraFeather, ModContent.ItemType()); - // Fabsol dev item // Name specific: "Fabsol" or "Cirrus" static bool getsCrystalHeartVodka(DropAttemptInfo info) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson index 069adda0db..4fb5ea6055 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson @@ -2026,11 +2026,6 @@ CrystalHeartVodka: { Tooltip: "'Tastes like strawberry cream liqueur (and estrogen)'" } -CocosFeather: { - DisplayName: Coco's Feather - Tooltip: "" -} - HapuFruit: { DisplayName: Ha-pu Fruit Tooltip: "'A fruit that calms your nerves (may have unintended side effects)'" diff --git a/NPCs/CalamityGlobalNPCLoot.cs b/NPCs/CalamityGlobalNPCLoot.cs index 6b875b8cad..f7b300d209 100644 --- a/NPCs/CalamityGlobalNPCLoot.cs +++ b/NPCs/CalamityGlobalNPCLoot.cs @@ -107,7 +107,6 @@ bool ShouldDropMechLore(DropAttemptInfo info) // Sky Glaze @ 3.33% IF Eye of Cthulhu dead // Essence of Sunlight @ 50% IF Hardmode and not statue spawned case NPCID.Harpy: - npcLoot.Add(ModContent.ItemType(), 1000); postEoC.Add(ModContent.ItemType(), 30); hardmode.AddIf(() => !npc.SpawnedFromStatue, ModContent.ItemType(), 2); break; diff --git a/description_workshop.txt b/description_workshop.txt index 172d508e9c..5841686264 100644 --- a/description_workshop.txt +++ b/description_workshop.txt @@ -1,6 +1,5 @@ [h1]Calamity Mod[/h1] [url=https://discord.gg/calamity]Discord[/url] [url=https://calamitymod.wiki.gg]Official Wiki[/url] -[b]LIMITED TIME![/b] [url=https://calamitymod.com/plush]Gimme Swag Plushie Campaign[/url] The Calamity Mod is a vast content mod that creates a new and refreshing experience for Terraria! From 1cc67eff0b68c097e76e7506371358bde40dff82 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Tue, 11 Feb 2025 03:36:36 -0600 Subject: [PATCH 204/401] Version bump. --- build.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.txt b/build.txt index d398b44e3d..b2de9aca5b 100644 --- a/build.txt +++ b/build.txt @@ -1,5 +1,5 @@ author = Fabsol and the Dev Team -version = 2.0.4.005 +version = 2.0.4.006 displayName = Calamity Mod modReferences = CalamityModMusic homepage = https://discord.gg/calamity From 8debdd7b1a28e711a41f809ca0c285c13e3f910d Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Tue, 11 Feb 2025 13:28:49 -0500 Subject: [PATCH 205/401] Final compile error fixes --- Items/SummonItems/Invasion/CausticTear.cs | 1 + Items/SummonItems/Invasion/MartianDistressRemote.cs | 1 + Items/Tools/ClimateChange/AridArtifact.cs | 1 + 3 files changed, 3 insertions(+) diff --git a/Items/SummonItems/Invasion/CausticTear.cs b/Items/SummonItems/Invasion/CausticTear.cs index b21039e6d5..6f76b9d06b 100644 --- a/Items/SummonItems/Invasion/CausticTear.cs +++ b/Items/SummonItems/Invasion/CausticTear.cs @@ -44,6 +44,7 @@ public override bool CanUseItem(Player player) AcidRainEvent.TryStartEvent(forceRain: true); // TryStartEvent already syncs the world data } + return true; } public override void AddRecipes() diff --git a/Items/SummonItems/Invasion/MartianDistressRemote.cs b/Items/SummonItems/Invasion/MartianDistressRemote.cs index 8b92c70260..24a34211be 100644 --- a/Items/SummonItems/Invasion/MartianDistressRemote.cs +++ b/Items/SummonItems/Invasion/MartianDistressRemote.cs @@ -1,5 +1,6 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using System.Linq; using Terraria; using Terraria.ID; using Terraria.ModLoader; diff --git a/Items/Tools/ClimateChange/AridArtifact.cs b/Items/Tools/ClimateChange/AridArtifact.cs index 2568b27f94..678ca85d32 100644 --- a/Items/Tools/ClimateChange/AridArtifact.cs +++ b/Items/Tools/ClimateChange/AridArtifact.cs @@ -37,6 +37,7 @@ public override bool CanUseItem(Player player) CalamityUtils.StopSandstorm(); else CalamityUtils.StartSandstorm(); + return true; } public override void AddRecipes() From a07ce5478352df56192dee354972119572231f31 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Tue, 11 Feb 2025 15:39:35 -0500 Subject: [PATCH 206/401] Minor description updates mirrored from dev branch --- description.txt | 5 +++-- description_workshop.txt | 6 +++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/description.txt b/description.txt index e72ac9e99c..e3ebef4e0b 100644 --- a/description.txt +++ b/description.txt @@ -15,10 +15,11 @@ A more detailed breakdown of the content available in Calamity: - 200+ pieces of furniture - 11 ores - 2 full difficulty settings above Expert, separate from Master +- Significant improvements and changes to Master difficulty - 50+ changes to vanilla mechanics - 30+ new recipes for vanilla items - 450+ tweaks and improvements to vanilla items -- Cross-mod support for the Thorium Mod +- Minor cross-mod support for the Thorium Mod PLEASE NOTE THAT THIS MOD REQUIRES THE CALAMITY MUSIC MOD. -You will need to install "Calamity Mod Music" from the Mod Browser or the Workshop. +You will need to install "Calamity Mod Music" from the Mod Browser or the Steam Workshop. diff --git a/description_workshop.txt b/description_workshop.txt index 5841686264..f267cc2d72 100644 --- a/description_workshop.txt +++ b/description_workshop.txt @@ -16,6 +16,9 @@ The mod additionally tweaks tons of vanilla features whilst adding new ones to a [i]Please note that this mod [b]REQUIRES[/b] Calamity's soundtrack! You will need to download the music mod to be able to play![/i] https://steamcommunity.com/sharedfiles/filedetails/?id=2824688266 +[i]For even more Calamity music, subscribe to Vanilla Calamity Mod Music![/i] +https://steamcommunity.com/sharedfiles/filedetails/?id=2816188633 + [b]Be sure to join our Discord server linked above to keep up with the latest news about upcoming updates and features.[/b] [hr] @@ -34,8 +37,9 @@ A more detailed breakdown of the content available in Calamity: [*] 200+ pieces of furniture [*] 11 ores [*] 2 full difficulty settings above Expert, separate from Master +[*] Significant improvements and changes to Master difficulty [*] 50+ changes to vanilla mechanics [*] 30+ new recipes for vanilla items [*] 450+ tweaks and improvements to vanilla items -[*] Cross-mod support for the Thorium Mod +[*] Minor cross-mod support for the Thorium Mod [/olist] \ No newline at end of file From d0d6b3f1be6779de78a2d46ef22806d7838ad3c7 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Thu, 17 Oct 2024 04:09:28 -0500 Subject: [PATCH 207/401] Pretty sure this is everything. --- .../MiracleBlightRenderer.cs | 11 +-- NPCs/CalamityDrawParameterNPC.cs | 88 +++++++++++++++++++ NPCs/CalamityPolarityNPC.cs | 2 +- Utilities/GlobalEntityUtils.cs | 47 ++++++++++ build.txt | 2 +- 5 files changed, 138 insertions(+), 12 deletions(-) create mode 100644 NPCs/CalamityDrawParameterNPC.cs create mode 100644 Utilities/GlobalEntityUtils.cs diff --git a/Graphics/Renderers/CalamityRenderers/MiracleBlightRenderer.cs b/Graphics/Renderers/CalamityRenderers/MiracleBlightRenderer.cs index 9fdab1f84a..b8902c380b 100644 --- a/Graphics/Renderers/CalamityRenderers/MiracleBlightRenderer.cs +++ b/Graphics/Renderers/CalamityRenderers/MiracleBlightRenderer.cs @@ -68,16 +68,7 @@ public static bool ValidToDraw(NPC npc) if (ExcludedNPCs.Contains(npc.type) || npc.IsABestiaryIconDummy) return false; - // Safety check for weird MP bug when getting global npcs. - if (!npc.TryGetGlobalNPC(out var calNPC) || !npc.TryGetGlobalNPC(out var polNPC)) - return false; - - // Do not draw if the npc does not have miracle blight, or has the polarity effect. - if (calNPC.miracleBlight <= 0 || polNPC.CurPolarity > 0f) - return false; - - // Do not draw if the current player has the trippy effect. - if (Main.LocalPlayer.Calamity().trippy) + if (!CalamityDrawParameterNPC.DrawingMiracleBlight[npc.whoAmI]) return false; return true; diff --git a/NPCs/CalamityDrawParameterNPC.cs b/NPCs/CalamityDrawParameterNPC.cs new file mode 100644 index 0000000000..f128694f22 --- /dev/null +++ b/NPCs/CalamityDrawParameterNPC.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Steamworks; +using Terraria; +using Terraria.DataStructures; +using Terraria.ModLoader; +namespace CalamityMod.NPCs +{ + // Why this class is exist? + // It because we want to avoid Threading Issues while We using NPC's properties on Draw Thread + public sealed class CalamityDrawParameterNPC : GlobalNPC + { + public override bool InstancePerEntity => false; + + #region Draw Parameters + public static bool[] DrawingMiracleBlight { get; private set; } + public static bool[] DrawingPolarity { get; private set; } + #endregion + + public override void Load() + { + DrawingMiracleBlight = new bool[Main.maxNPCs]; + DrawingPolarity = new bool[Main.maxNPCs]; + } + + public override void Unload() + { + DrawingMiracleBlight = null; + DrawingPolarity = null; + } + + public override void SetDefaults(NPC entity) => ResetParameters(entity); + + public override bool PreAI(NPC npc) + { + if (npc is null) + return true; + var whoAmI = npc.whoAmI; + DrawingMiracleBlight[whoAmI] = ShouldDrawMiracleBlight(npc); + DrawingPolarity[whoAmI] = ShouldDrawPolarity(npc); + return true; + } + + private static void ResetParameters(NPC npc) + { + if (npc is null) + return; + var whoAmI = npc.whoAmI; + DrawingMiracleBlight[whoAmI] = false; + DrawingPolarity[whoAmI] = false; + } + + private static bool ShouldDrawMiracleBlight(NPC npc) + { + if (npc is null || !npc.active) + return false; + // Safety check for weird MP bug when getting global npcs. + if (!npc.TryGetGlobalNPCSafer(out var calNPC) || !npc.TryGetGlobalNPCSafer(out var polNPC)) + return false; + // Do not draw if the npc does not have miracle blight, or has the polarity effect. + if (calNPC.miracleBlight <= 0 || polNPC.CurPolarity > 0f) + return false; + // Do not draw if the current player has the trippy effect. + if (Main.LocalPlayer.Calamity().trippy) + return false; + return true; + } + + private static bool ShouldDrawPolarity(NPC npc) + { + if (npc is null || !npc.active) + return false; + // Safety check for weird MP bug when getting global npcs. + if (!npc.TryGetGlobalNPCSafer(out var calNPC) || !npc.TryGetGlobalNPCSafer(out var polNPC)) + return false; + // I don't know who would be using this while also inflicting miracle blight, but in that rare case, do not draw these. + if (calNPC.miracleBlight > 0) + return false; + // Do not draw if the npc doesn't have the polarity effect. + if (polNPC.CurPolarity <= 0f) + return false; + return true; + } + } +} diff --git a/NPCs/CalamityPolarityNPC.cs b/NPCs/CalamityPolarityNPC.cs index b414c40154..62389ac49f 100644 --- a/NPCs/CalamityPolarityNPC.cs +++ b/NPCs/CalamityPolarityNPC.cs @@ -96,7 +96,7 @@ public void HandlePulses() public override void PostDraw(NPC npc, SpriteBatch spriteBatch, Vector2 screenPos, Color drawColor) { // I don't know who would be using this while also inflicting miracle blight, but in that rare case, do not draw these. - if (npc.Calamity().miracleBlight > 0) + if (CalamityDrawParameterNPC.DrawingMiracleBlight[npc.whoAmI]) return; Main.spriteBatch.End(); diff --git a/Utilities/GlobalEntityUtils.cs b/Utilities/GlobalEntityUtils.cs new file mode 100644 index 0000000000..ff5a022bfc --- /dev/null +++ b/Utilities/GlobalEntityUtils.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Terraria.ModLoader; +using Terraria; + +namespace CalamityMod +{ + public static partial class CalamityUtils + { + /// + /// Actual "Thread-Safe" version of TryGetGlobalNPC + /// + /// GlobalNPC type to get + /// Input NPC + /// GlobalNPC output + /// true If we successfully get GlobalNPC. otherwise false + public static bool TryGetGlobalNPCSafer(this NPC npc, out T globalNPC) where T : GlobalNPC + { + try + { + if (npc is null) + { + globalNPC = null; + return false; + } + + int slot = ModContent.GetInstance()?.PerEntityIndex ?? -1; + int length = npc.EntityGlobals.Length; + if (slot < 0 || slot >= length) + { + globalNPC = null; + return false; + } + npc.TryGetGlobalNPC(out globalNPC); + return globalNPC != null; + } + catch + { + globalNPC = null; + return false; + } + } + } +} diff --git a/build.txt b/build.txt index cf9028fcf7..ed16d2e562 100644 --- a/build.txt +++ b/build.txt @@ -1,5 +1,5 @@ author = Fabsol and the Dev Team -version = 2.0.4.003 +version = 2.0.4.004 displayName = Calamity Mod modReferences = CalamityModMusic homepage = https://discord.gg/calamity From 26b06888f9bde2afd6fc604397cfaf0af2929dde Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Thu, 31 Oct 2024 23:06:03 -0500 Subject: [PATCH 208/401] Pretty sure this is everything, once again. I'll release this in an hour or something. --- CalPlayer/CalamityPlayer.cs | 9 +- CalPlayer/CalamityPlayerMiscEffects.cs | 3 + CalamityNetcode.cs | 24 ++ .../DyeableShadersRenderer.cs | 50 +++-- Graphics/Renderers/RendererManager.cs | 24 +- .../en-US/Mods.CalamityMod.Misc.hjson | 1 + NPCs/CalamityNetImportantNPC.cs | 211 ++++++++++++++++++ Utilities/DrawingUtils.cs | 36 ++- Utilities/NPCUtils.cs | 10 + build.txt | 2 +- 10 files changed, 348 insertions(+), 22 deletions(-) create mode 100644 NPCs/CalamityNetImportantNPC.cs diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index cb4fca8350..084a918902 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -4879,8 +4879,15 @@ public override void OnEnterWorld() if (CalamityConfig.Instance.SpeedrunTimer) CalamityMod.SpeedrunTimer.Restart(); + // + // 31OCT2024: Fabsol: Added a temporary message for the Gimme Swag plushie campaign. + // This message should not exist indefinitely. It is being pushed as a silent public update just for itself. + // As this message always displays and is not configurable, the previous rules about startup messages have been replaced with always-true. + // + // Set a random delay between 12 and 20 seconds. When this delay hits zero, startup messages display - if (CalamityConfig.Instance.WikiStatusMessage) + bool plushieMessage = true; + if (plushieMessage || CalamityConfig.Instance.WikiStatusMessage) { startMessageDisplayDelay = Main.rand.Next(CalamityUtils.SecondsToFrames(12), CalamityUtils.SecondsToFrames(20) + 1); } diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index 1dac773f1d..a3ed869174 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -4168,6 +4168,9 @@ private void HandleTextChatMessages() CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.WikiStatus1"); CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.WikiStatus2"); } + + // 31OCT2024: Fabsol: Plushie message always appears. + CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.GimmeSwagPlushieCampaign"); } --startMessageDisplayDelay; diff --git a/CalamityNetcode.cs b/CalamityNetcode.cs index c498f8c37c..1ddc123fe0 100644 --- a/CalamityNetcode.cs +++ b/CalamityNetcode.cs @@ -193,6 +193,29 @@ public static void HandlePacket(Mod mod, BinaryReader reader, int whoAmI) } break; + case CalamityModMessageType.SyncNPCPosAndRotOnly: + npcIndex = reader.ReadByte(); + Vector2 position = reader.ReadVector2(); + float rotation = (float)reader.ReadHalf(); //rotation unit is radian (-π/2 ≤ rotation ≤ π/2) so Half precision should works + + if (npcIndex >= Main.maxNPCs) + break; + + npc = Main.npc[npcIndex]; + npc.position = position; + npc.rotation = rotation; + + if (Main.dedServ) + { + ModPacket packet = CalamityMod.Instance.GetPacket(); + packet.Write((byte)CalamityModMessageType.SyncNPCPosAndRotOnly); + packet.Write((byte)npcIndex); + packet.WriteVector2(position); + packet.Write((Half)rotation); + packet.Send(ignoreClient: whoAmI); + } + break; + // // Tile Entities // @@ -400,6 +423,7 @@ public enum CalamityModMessageType : byte // General things for entities SpawnNPCOnPlayer, SyncNPCMotionDataToServer, + SyncNPCPosAndRotOnly, // Tile Entities PowerCellFactory, diff --git a/Graphics/Renderers/CalamityRenderers/DyeableShadersRenderer.cs b/Graphics/Renderers/CalamityRenderers/DyeableShadersRenderer.cs index f01c539a2f..d0570d372e 100644 --- a/Graphics/Renderers/CalamityRenderers/DyeableShadersRenderer.cs +++ b/Graphics/Renderers/CalamityRenderers/DyeableShadersRenderer.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using CalamityMod.DataStructures; @@ -36,19 +37,13 @@ public static Dictionary Dyes #region Loading public override void Load() { - if (Main.netMode == NetmodeID.Server) - return; - - Targets = new(); - Dyes = new(); - RenderersToDrawThisFrame = new(); + Targets = []; + Dyes = []; + RenderersToDrawThisFrame = []; } public override void Unload() { - if (Main.netMode == NetmodeID.Server) - return; - Targets = null; Dyes = null; RenderersToDrawThisFrame = null; @@ -60,6 +55,9 @@ internal static void FindDyesDetour(On_Player.orig_UpdateItemDye orig, Player se { orig(self, isNotInVanitySlot, isSetToHidden, armorItem, dyeItem); + if (Main.dedServ) + return; + if (armorItem.ModItem is not IDyeableShaderRenderer drawer) return; @@ -70,12 +68,20 @@ internal static void FindDyesDetour(On_Player.orig_UpdateItemDye orig, Player se internal static void CheckVanityDetour(On_Player.orig_ApplyEquipVanity_Item orig, Player self, Item currentItem) { orig(self, currentItem); + + if (Main.dedServ) + return; + CheckIfEquipIsValid(currentItem, false); } internal static void CheckAccessoryDetour(On_Player.orig_ApplyEquipFunctional orig, Player self, Item currentItem, bool hideVisual) { orig(self, currentItem, hideVisual); + + if (Main.dedServ) + return; + CheckIfEquipIsValid(currentItem, hideVisual); } @@ -83,6 +89,9 @@ internal static void CheckArmorSetsDetour(On_Player.orig_UpdateArmorSets orig, P { orig(self, i); + if (Main.dedServ) + return; + // Check each armor piece in the same manner as tMod. // If the entire set is equipped, and it is a renderer, it will be marked as valid. Item head = self.armor[0]; @@ -103,6 +112,9 @@ internal static void CheckArmorSetsDetour(On_Player.orig_UpdateArmorSets orig, P private static void CheckIfEquipIsValid(Item item, bool hideVisual) { + if (Main.dedServ) + return; + // Difficulty mode checks. if ((item.expertOnly && !Main.expertMode) || (item.masterOnly && !Main.masterMode)) return; @@ -120,9 +132,15 @@ private static void CheckIfEquipIsValid(Item item, bool hideVisual) private static void MarkAsValid(IDyeableShaderRenderer renderer) { - // If it doesn't have a dictonary entry, create one. - if (!Targets.ContainsKey(renderer)) - Main.QueueMainThreadAction(() => Targets[renderer] = new(true, ManagedRenderTarget.CreateScreenSizedTarget)); + if (Main.dedServ) + return; + + Main.QueueMainThreadAction(() => + { + // If it doesn't have a dictonary entry, create one. + if (!Targets.ContainsKey(renderer)) + Main.QueueMainThreadAction(() => Targets[renderer] = new(true, ManagedRenderTarget.CreateScreenSizedTarget)); + }); // Mark this item as drawable this frame. RenderersToDrawThisFrame.AddWithCondition(renderer, renderer.ShouldDrawDyeableShader); @@ -131,10 +149,13 @@ private static void MarkAsValid(IDyeableShaderRenderer renderer) #region Updates/Drawing // Clear the list at the beginning of each update, to ensure its only populated by correct ones. - public override void PreUpdate() => RenderersToDrawThisFrame.Clear(); + public override void PreUpdate() => RenderersToDrawThisFrame?.Clear(); public override void DrawToTarget(SpriteBatch spriteBatch) { + if (Main.dedServ) + return; + // Leave if nothing to draw. if (!RenderersToDrawThisFrame.Any()) return; @@ -155,6 +176,9 @@ public override void DrawToTarget(SpriteBatch spriteBatch) public override void DrawTarget(SpriteBatch spriteBatch) { + if (Main.dedServ) + return; + // Leave if nothing to draw. if (!RenderersToDrawThisFrame.Any()) return; diff --git a/Graphics/Renderers/RendererManager.cs b/Graphics/Renderers/RendererManager.cs index 4844fd81cb..eac7f8ce96 100644 --- a/Graphics/Renderers/RendererManager.cs +++ b/Graphics/Renderers/RendererManager.cs @@ -83,7 +83,7 @@ private void DrawToTargets(On_Main.orig_CheckMonoliths orig) { orig(); - if (Main.gameMenu) + if (Main.gameMenu || Main.dedServ) return; foreach (var renderer in Renderers) @@ -91,10 +91,24 @@ private void DrawToTargets(On_Main.orig_CheckMonoliths orig) if (!renderer.ShouldDraw) continue; - renderer.MainTarget.SwapTo(Color.Transparent); - Main.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, Main.Rasterizer, null, Main.GameViewMatrix.TransformationMatrix); - renderer.DrawToTarget(Main.spriteBatch); - Main.spriteBatch.End(); + try + { + renderer.MainTarget.SwapTo(Color.Transparent); + Main.spriteBatch.TryBegin(SpriteSortMode.Deferred, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, Main.Rasterizer, null, Main.GameViewMatrix.TransformationMatrix); + renderer.DrawToTarget(Main.spriteBatch); + } + catch (Exception e) + { + Main.QueueMainThreadAction(() => + { + CalamityMod.Instance.Logger.Error($"Exception Found on RenderDetour: {e}"); + }); + } + finally + { + // Always end the Batch! + Main.spriteBatch.TryEnd(); + } } Main.instance.GraphicsDevice.SetRenderTarget(null); diff --git a/Localization/en-US/Mods.CalamityMod.Misc.hjson b/Localization/en-US/Mods.CalamityMod.Misc.hjson index 4a836bc149..c672e49428 100644 --- a/Localization/en-US/Mods.CalamityMod.Misc.hjson +++ b/Localization/en-US/Mods.CalamityMod.Misc.hjson @@ -21,6 +21,7 @@ RecipeGroup: { // Status WikiStatus1: "[i:Book] [c/EE4939:Note: The Fandom wiki is no longer supported by Calamity.] [i:Book]" WikiStatus2: "[i:Book] [c/EE4939:Check out the Official Calamity Mod Wiki at ][c/3989FF:calamitymod.wiki.gg][c/EE4939:!] [i:Book]" +GimmeSwagPlushieCampaign: "[i:GreenPresent] [c/3BE022:NOW AVAILABLE! Yharon Plushie!] [c/3989FF:calamitymod.com/plush] [i:GreenPresent]" // Recipe Conditions Tier1ArsenalRecipeCondition: View an unencrypted schematic from the lab near the Sunken Sea Tier2ArsenalRecipeCondition: Decrypt a schematic from the lab in the large planetoid in the sky diff --git a/NPCs/CalamityNetImportantNPC.cs b/NPCs/CalamityNetImportantNPC.cs new file mode 100644 index 0000000000..e934ad3c50 --- /dev/null +++ b/NPCs/CalamityNetImportantNPC.cs @@ -0,0 +1,211 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using CalamityMod.NPCs.Abyss; +using CalamityMod.NPCs.AcidRain; +using CalamityMod.NPCs.AquaticScourge; +using CalamityMod.NPCs.AstrumDeus; +using CalamityMod.NPCs.CalClone; +using CalamityMod.NPCs.Cryogen; +using CalamityMod.NPCs.DesertScourge; +using CalamityMod.NPCs.DevourerofGods; +using CalamityMod.NPCs.ExoMechs; +using CalamityMod.NPCs.ExoMechs.Apollo; +using CalamityMod.NPCs.ExoMechs.Ares; +using CalamityMod.NPCs.ExoMechs.Artemis; +using CalamityMod.NPCs.ExoMechs.Thanatos; +using CalamityMod.NPCs.Leviathan; +using CalamityMod.NPCs.NormalNPCs; +using CalamityMod.NPCs.Perforator; +using CalamityMod.NPCs.PrimordialWyrm; +using CalamityMod.NPCs.ProfanedGuardians; +using CalamityMod.NPCs.Providence; +using CalamityMod.NPCs.StormWeaver; +using CalamityMod.NPCs.SupremeCalamitas; +using Microsoft.Xna.Framework; +using Terraria; +using Terraria.Chat; +using Terraria.DataStructures; +using Terraria.ID; +using Terraria.Localization; +using Terraria.ModLoader; + +namespace CalamityMod.NPCs +{ + public sealed class CalamityNetImportantNPC : GlobalNPC + { + private static Dictionary typesToUpdate; + + public override void Load() + { + typesToUpdate = new(); + } + + public override void Unload() + { + typesToUpdate?.Clear(); + typesToUpdate = null; + } + + public override void SetStaticDefaults() + { + #region Vanilla Enemies + MarkNPCToNetImportant(NPCID.EaterofWorldsHead); + MarkNPCToNetImportant(NPCID.EaterofWorldsBody); + MarkNPCToNetImportant(NPCID.EaterofWorldsTail); + + MarkNPCToNetImportant(NPCID.TheDestroyer); + MarkNPCToNetImportant(NPCID.TheDestroyerBody); + MarkNPCToNetImportant(NPCID.TheDestroyerTail); + #endregion Vanilla Enemies + + + + #region Pre Hardmode + MarkNPCToNetImportant(netUpdateTickOffset: 1); + MarkNPCToNetImportant(netUpdateTickOffset: 1); + MarkNPCToNetImportant(netUpdateTickOffset: 1); + + MarkNPCToNetImportant(netUpdateTickOffset: 2); + MarkNPCToNetImportant(netUpdateTickOffset: 2); + MarkNPCToNetImportant(netUpdateTickOffset: 2); + + MarkNPCToNetImportant(netUpdateTickOffset: 3); + MarkNPCToNetImportant(netUpdateTickOffset: 3); + MarkNPCToNetImportant(netUpdateTickOffset: 3); + + MarkNPCToNetImportant(netUpdateTickOffset: 1); + MarkNPCToNetImportant(netUpdateTickOffset: 1); + MarkNPCToNetImportant(netUpdateTickOffset: 1); + + MarkNPCToNetImportant(netUpdateTickOffset: 2); + MarkNPCToNetImportant(netUpdateTickOffset: 2); + MarkNPCToNetImportant(netUpdateTickOffset: 2); + + MarkNPCToNetImportant(netUpdateTickOffset: 3); + MarkNPCToNetImportant(netUpdateTickOffset: 3); + MarkNPCToNetImportant(netUpdateTickOffset: 3); + #endregion Pre Hardmode + + + + #region Hardmode + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + #endregion Hardmode + + + + #region Post ML + MarkNPCToNetImportant(netUpdateTickOffset: 1); + MarkNPCToNetImportant(netUpdateTickOffset: 1); + MarkNPCToNetImportant(netUpdateTickOffset: 1); + + MarkNPCToNetImportant(netUpdateTickOffset: 2); + MarkNPCToNetImportant(netUpdateTickOffset: 2); + MarkNPCToNetImportant(netUpdateTickOffset: 2); + + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + #endregion Post ML + + + #region Calamitas Boss + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + #endregion + + + #region Draedon Boss + MarkNPCToNetImportant(); + + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + #endregion Draedon Boss + + + + #region Abyss + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + + MarkNPCToNetImportant(netUpdateTickOffset: 1); + MarkNPCToNetImportant(netUpdateTickOffset: 1); + MarkNPCToNetImportant(netUpdateTickOffset: 1); + MarkNPCToNetImportant(netUpdateTickOffset: 1); + + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + MarkNPCToNetImportant(); + + MarkNPCToNetImportant(netUpdateTickOffset: 2); + MarkNPCToNetImportant(netUpdateTickOffset: 2); + MarkNPCToNetImportant(netUpdateTickOffset: 2); + MarkNPCToNetImportant(netUpdateTickOffset: 2); + #endregion Abyss + } + + public override void PostAI(NPC npc) + { + // Only Server should update this! + if (!Main.dedServ) + return; + + // Obviously deactived npc is not on our interest (not sure if this is case though) + if (!npc.active) + return; + + if (!typesToUpdate.TryGetValue(npc.type, out var netUpdateTickOffset)) + return; + + if ((Main.GameUpdateCount + netUpdateTickOffset) % 45 != 0) + return; + + foreach (var player in Main.ActivePlayers) + { + // distance between 1000~1500 update with 8 tick period + // and distance over 1500 will never update + // So we forcely update NPC distanced over 1500 with 45 tick period + float distance = CalamityUtils.ManhattanDistance(player.position, npc.position); + if (distance <= 1499.0f) + continue; + + npc.SyncNPCPosAndRotOnly(); //Light-weight version to sync it's position + } + } + + private void MarkNPCToNetImportant(int netUpdateTickOffset = 0) where NPCType : ModNPC + { + MarkNPCToNetImportant(ModContent.NPCType(), netUpdateTickOffset); + } + + private void MarkNPCToNetImportant(int npcType, int netUpdateTickOffset = 0) + { + typesToUpdate[npcType] = netUpdateTickOffset; + } + } +} diff --git a/Utilities/DrawingUtils.cs b/Utilities/DrawingUtils.cs index 0b541aa8ec..0c18da9cc3 100644 --- a/Utilities/DrawingUtils.cs +++ b/Utilities/DrawingUtils.cs @@ -335,7 +335,7 @@ public static void SetBlendState(this SpriteBatch spriteBatch, BlendState blendS } // Cached for efficiency purposes. - internal static readonly FieldInfo BeginEndPairField = typeof(SpriteBatch).GetField("inBeginEndPair", BindingFlags.NonPublic | BindingFlags.Instance); + internal static readonly FieldInfo BeginCalled = typeof(SpriteBatch).GetField("beginCalled", BindingFlags.NonPublic | BindingFlags.Instance); /// /// Determines if a is in a lock due to a call. @@ -343,7 +343,39 @@ public static void SetBlendState(this SpriteBatch spriteBatch, BlendState blendS /// The sprite batch to check. public static bool HasBeginBeenCalled(this SpriteBatch spriteBatch) { - return (bool)BeginEndPairField.GetValue(spriteBatch); + return (bool)BeginCalled.GetValue(spriteBatch); + } + + public static bool TryBegin(this SpriteBatch spriteBatch, SpriteSortMode sortMode, + BlendState blendState, + SamplerState samplerState, + DepthStencilState depthStencilState, + RasterizerState rasterizerState, + Effect effect, + Matrix transformMatrix) + { + if (spriteBatch.HasBeginBeenCalled()) + { + return false; + } + else + { + spriteBatch.Begin(sortMode, blendState, samplerState, depthStencilState, rasterizerState, effect, transformMatrix); + return true; + } + } + + public static bool TryEnd(this SpriteBatch spriteBatch) + { + if (!spriteBatch.HasBeginBeenCalled()) + { + return false; + } + else + { + spriteBatch.End(); + return true; + } } /// diff --git a/Utilities/NPCUtils.cs b/Utilities/NPCUtils.cs index 719631c115..3381b44096 100644 --- a/Utilities/NPCUtils.cs +++ b/Utilities/NPCUtils.cs @@ -310,6 +310,16 @@ public static void SyncMotionToServer(this NPC npc) netMessage.Send(); } + public static void SyncNPCPosAndRotOnly(this NPC npc) + { + ModPacket packet = CalamityMod.Instance.GetPacket(); + packet.Write((byte)CalamityModMessageType.SyncNPCPosAndRotOnly); + packet.Write((byte)npc.whoAmI); + packet.WriteVector2(npc.position); + packet.Write((Half)npc.rotation); + packet.Send(); + } + /// /// Syncs . This exists to sync the Destroyer's lasers so that the telegraphs and segment colors display properly. /// diff --git a/build.txt b/build.txt index ed16d2e562..d398b44e3d 100644 --- a/build.txt +++ b/build.txt @@ -1,5 +1,5 @@ author = Fabsol and the Dev Team -version = 2.0.4.004 +version = 2.0.4.005 displayName = Calamity Mod modReferences = CalamityModMusic homepage = https://discord.gg/calamity From 9be25fdb8d00712bf343b4167b464837aa002753 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Fri, 1 Nov 2024 00:26:28 -0500 Subject: [PATCH 209/401] CalamityNetImportantNPC now uses Attribute. --- NPCs/Abyss/BobbitWormHead.cs | 1 + NPCs/Abyss/BobbitWormSegment.cs | 1 + NPCs/Abyss/EidolonWyrmBody.cs | 1 + NPCs/Abyss/EidolonWyrmBodyAlt.cs | 1 + NPCs/Abyss/EidolonWyrmHead.cs | 1 + NPCs/Abyss/EidolonWyrmTail.cs | 1 + NPCs/Abyss/GulperEelBody.cs | 1 + NPCs/Abyss/GulperEelBodyAlt.cs | 1 + NPCs/Abyss/GulperEelHead.cs | 1 + NPCs/Abyss/GulperEelTail.cs | 1 + NPCs/Abyss/OarfishBody.cs | 1 + NPCs/Abyss/OarfishHead.cs | 1 + NPCs/Abyss/OarfishTail.cs | 1 + NPCs/AquaticScourge/AquaticScourgeBody.cs | 1 + NPCs/AquaticScourge/AquaticScourgeBodyAlt.cs | 1 + NPCs/AquaticScourge/AquaticScourgeHead.cs | 1 + NPCs/AquaticScourge/AquaticScourgeTail.cs | 1 + NPCs/AstrumDeus/AstrumDeusBody.cs | 1 + NPCs/AstrumDeus/AstrumDeusHead.cs | 1 + NPCs/AstrumDeus/AstrumDeusTail.cs | 1 + NPCs/CalamityNetImportantNPC.cs | 196 +++++------------- NPCs/Cryogen/Cryogen.cs | 1 + NPCs/Cryogen/CryogenShield.cs | 1 + NPCs/DesertScourge/DesertNuisanceBody.cs | 1 + NPCs/DesertScourge/DesertNuisanceBodyYoung.cs | 1 + NPCs/DesertScourge/DesertNuisanceHead.cs | 1 + NPCs/DesertScourge/DesertNuisanceHeadYoung.cs | 1 + NPCs/DesertScourge/DesertNuisanceTail.cs | 1 + NPCs/DesertScourge/DesertNuisanceTailYoung.cs | 1 + NPCs/DesertScourge/DesertScourgeBody.cs | 1 + NPCs/DesertScourge/DesertScourgeHead.cs | 1 + NPCs/DesertScourge/DesertScourgeTail.cs | 1 + NPCs/DevourerofGods/CosmicGuardianBody.cs | 1 + NPCs/DevourerofGods/CosmicGuardianHead.cs | 1 + NPCs/DevourerofGods/CosmicGuardianTail.cs | 1 + NPCs/DevourerofGods/DevourerofGodsBody.cs | 1 + NPCs/DevourerofGods/DevourerofGodsHead.cs | 1 + NPCs/DevourerofGods/DevourerofGodsTail.cs | 1 + NPCs/ExoMechs/Draedon.cs | 1 + NPCs/ExoMechs/Thanatos/ThanatosBody1.cs | 1 + NPCs/ExoMechs/Thanatos/ThanatosBody2.cs | 1 + NPCs/ExoMechs/Thanatos/ThanatosHead.cs | 1 + NPCs/ExoMechs/Thanatos/ThanatosTail.cs | 1 + NPCs/LongDistanceNetSyncAttribute.cs | 27 +++ NPCs/NormalNPCs/ArmoredDiggerBody.cs | 1 + NPCs/NormalNPCs/ArmoredDiggerHead.cs | 1 + NPCs/NormalNPCs/ArmoredDiggerTail.cs | 1 + NPCs/Perforator/PerforatorBodyLarge.cs | 1 + NPCs/Perforator/PerforatorBodyMedium.cs | 1 + NPCs/Perforator/PerforatorBodySmall.cs | 1 + NPCs/Perforator/PerforatorHeadLarge.cs | 1 + NPCs/Perforator/PerforatorHeadMedium.cs | 1 + NPCs/Perforator/PerforatorHeadSmall.cs | 1 + NPCs/Perforator/PerforatorTailLarge.cs | 1 + NPCs/Perforator/PerforatorTailMedium.cs | 1 + NPCs/Perforator/PerforatorTailSmall.cs | 1 + NPCs/PrimordialWyrm/PrimordialWyrmBody.cs | 1 + NPCs/PrimordialWyrm/PrimordialWyrmBodyAlt.cs | 1 + NPCs/PrimordialWyrm/PrimordialWyrmHead.cs | 1 + NPCs/PrimordialWyrm/PrimordialWyrmTail.cs | 1 + NPCs/StormWeaver/StormWeaverBody.cs | 1 + NPCs/StormWeaver/StormWeaverHead.cs | 1 + NPCs/StormWeaver/StormWeaverTail.cs | 1 + NPCs/SupremeCalamitas/SepulcherBody.cs | 1 + NPCs/SupremeCalamitas/SepulcherHead.cs | 1 + NPCs/SupremeCalamitas/SepulcherTail.cs | 1 + 66 files changed, 146 insertions(+), 141 deletions(-) create mode 100644 NPCs/LongDistanceNetSyncAttribute.cs diff --git a/NPCs/Abyss/BobbitWormHead.cs b/NPCs/Abyss/BobbitWormHead.cs index ce50cbf3a2..67b57b3feb 100644 --- a/NPCs/Abyss/BobbitWormHead.cs +++ b/NPCs/Abyss/BobbitWormHead.cs @@ -13,6 +13,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync] public class BobbitWormHead : ModNPC { public override void SetStaticDefaults() diff --git a/NPCs/Abyss/BobbitWormSegment.cs b/NPCs/Abyss/BobbitWormSegment.cs index aad563ed48..5b65b917d6 100644 --- a/NPCs/Abyss/BobbitWormSegment.cs +++ b/NPCs/Abyss/BobbitWormSegment.cs @@ -7,6 +7,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync(SyncWith = typeof(BobbitWormHead))] public class BobbitWormSegment : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.BobbitWormHead.DisplayName"); diff --git a/NPCs/Abyss/EidolonWyrmBody.cs b/NPCs/Abyss/EidolonWyrmBody.cs index 5e0b418ef0..3e9c9058ea 100644 --- a/NPCs/Abyss/EidolonWyrmBody.cs +++ b/NPCs/Abyss/EidolonWyrmBody.cs @@ -9,6 +9,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync(SyncWith = typeof(EidolonWyrmHead))] public class EidolonWyrmBody : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.EidolonWyrmHead.DisplayName"); diff --git a/NPCs/Abyss/EidolonWyrmBodyAlt.cs b/NPCs/Abyss/EidolonWyrmBodyAlt.cs index 9e31e16946..b2ce430dea 100644 --- a/NPCs/Abyss/EidolonWyrmBodyAlt.cs +++ b/NPCs/Abyss/EidolonWyrmBodyAlt.cs @@ -9,6 +9,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync(SyncWith = typeof(EidolonWyrmHead))] public class EidolonWyrmBodyAlt : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.EidolonWyrmHead.DisplayName"); diff --git a/NPCs/Abyss/EidolonWyrmHead.cs b/NPCs/Abyss/EidolonWyrmHead.cs index b7b311396f..87e85a233e 100644 --- a/NPCs/Abyss/EidolonWyrmHead.cs +++ b/NPCs/Abyss/EidolonWyrmHead.cs @@ -26,6 +26,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync] public class EidolonWyrmHead : ModNPC { private Vector2 patrolSpot = Vector2.Zero; diff --git a/NPCs/Abyss/EidolonWyrmTail.cs b/NPCs/Abyss/EidolonWyrmTail.cs index 78045ad275..6cc97cb4ce 100644 --- a/NPCs/Abyss/EidolonWyrmTail.cs +++ b/NPCs/Abyss/EidolonWyrmTail.cs @@ -9,6 +9,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync(SyncWith = typeof(EidolonWyrmHead))] public class EidolonWyrmTail : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.EidolonWyrmHead.DisplayName"); diff --git a/NPCs/Abyss/GulperEelBody.cs b/NPCs/Abyss/GulperEelBody.cs index 819cae17cd..29a0c69184 100644 --- a/NPCs/Abyss/GulperEelBody.cs +++ b/NPCs/Abyss/GulperEelBody.cs @@ -11,6 +11,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync(SyncWith = typeof(GulperEelHead))] public class GulperEelBody : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.GulperEelHead.DisplayName"); diff --git a/NPCs/Abyss/GulperEelBodyAlt.cs b/NPCs/Abyss/GulperEelBodyAlt.cs index 73d68d7b0f..db6035b539 100644 --- a/NPCs/Abyss/GulperEelBodyAlt.cs +++ b/NPCs/Abyss/GulperEelBodyAlt.cs @@ -11,6 +11,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync(SyncWith = typeof(GulperEelHead))] public class GulperEelBodyAlt : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.GulperEelHead.DisplayName"); diff --git a/NPCs/Abyss/GulperEelHead.cs b/NPCs/Abyss/GulperEelHead.cs index 395fc3d696..161506e481 100644 --- a/NPCs/Abyss/GulperEelHead.cs +++ b/NPCs/Abyss/GulperEelHead.cs @@ -16,6 +16,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync] public class GulperEelHead : ModNPC { private Vector2 patrolSpot = Vector2.Zero; diff --git a/NPCs/Abyss/GulperEelTail.cs b/NPCs/Abyss/GulperEelTail.cs index 8c0444d4c1..e06996e52c 100644 --- a/NPCs/Abyss/GulperEelTail.cs +++ b/NPCs/Abyss/GulperEelTail.cs @@ -11,6 +11,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync(SyncWith = typeof(GulperEelHead))] public class GulperEelTail : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.GulperEelHead.DisplayName"); diff --git a/NPCs/Abyss/OarfishBody.cs b/NPCs/Abyss/OarfishBody.cs index 2849ab2efa..b45a50ba27 100644 --- a/NPCs/Abyss/OarfishBody.cs +++ b/NPCs/Abyss/OarfishBody.cs @@ -7,6 +7,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync(SyncWith = typeof(OarfishHead))] public class OarfishBody : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.OarfishHead.DisplayName"); diff --git a/NPCs/Abyss/OarfishHead.cs b/NPCs/Abyss/OarfishHead.cs index 9459276e5a..db3d69afe7 100644 --- a/NPCs/Abyss/OarfishHead.cs +++ b/NPCs/Abyss/OarfishHead.cs @@ -13,6 +13,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync] public class OarfishHead : ModNPC { private Vector2 patrolSpot = Vector2.Zero; diff --git a/NPCs/Abyss/OarfishTail.cs b/NPCs/Abyss/OarfishTail.cs index eb0ce07f93..4e5c31e528 100644 --- a/NPCs/Abyss/OarfishTail.cs +++ b/NPCs/Abyss/OarfishTail.cs @@ -7,6 +7,7 @@ namespace CalamityMod.NPCs.Abyss { + [LongDistanceNetSync(SyncWith = typeof(OarfishHead))] public class OarfishTail : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.OarfishHead.DisplayName"); diff --git a/NPCs/AquaticScourge/AquaticScourgeBody.cs b/NPCs/AquaticScourge/AquaticScourgeBody.cs index e7d0565bad..f2a7a7f31b 100644 --- a/NPCs/AquaticScourge/AquaticScourgeBody.cs +++ b/NPCs/AquaticScourge/AquaticScourgeBody.cs @@ -13,6 +13,7 @@ namespace CalamityMod.NPCs.AquaticScourge { + [LongDistanceNetSync(SyncWith = typeof(AquaticScourgeHead))] public class AquaticScourgeBody : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.AquaticScourgeHead.DisplayName"); diff --git a/NPCs/AquaticScourge/AquaticScourgeBodyAlt.cs b/NPCs/AquaticScourge/AquaticScourgeBodyAlt.cs index 6a2871b0a2..85d4d29c40 100644 --- a/NPCs/AquaticScourge/AquaticScourgeBodyAlt.cs +++ b/NPCs/AquaticScourge/AquaticScourgeBodyAlt.cs @@ -13,6 +13,7 @@ namespace CalamityMod.NPCs.AquaticScourge { + [LongDistanceNetSync(SyncWith = typeof(AquaticScourgeHead))] public class AquaticScourgeBodyAlt : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.AquaticScourgeHead.DisplayName"); diff --git a/NPCs/AquaticScourge/AquaticScourgeHead.cs b/NPCs/AquaticScourge/AquaticScourgeHead.cs index 01e9e94ab5..0b4cc334fa 100644 --- a/NPCs/AquaticScourge/AquaticScourgeHead.cs +++ b/NPCs/AquaticScourge/AquaticScourgeHead.cs @@ -33,6 +33,7 @@ namespace CalamityMod.NPCs.AquaticScourge { [AutoloadBossHead] + [LongDistanceNetSync] public class AquaticScourgeHead : ModNPC { public override void SetStaticDefaults() diff --git a/NPCs/AquaticScourge/AquaticScourgeTail.cs b/NPCs/AquaticScourge/AquaticScourgeTail.cs index 5b7217d8c0..c7cd744e25 100644 --- a/NPCs/AquaticScourge/AquaticScourgeTail.cs +++ b/NPCs/AquaticScourge/AquaticScourgeTail.cs @@ -13,6 +13,7 @@ namespace CalamityMod.NPCs.AquaticScourge { + [LongDistanceNetSync(SyncWith = typeof(AquaticScourgeHead))] public class AquaticScourgeTail : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.AquaticScourgeHead.DisplayName"); diff --git a/NPCs/AstrumDeus/AstrumDeusBody.cs b/NPCs/AstrumDeus/AstrumDeusBody.cs index dfc682dcb0..29d3848680 100644 --- a/NPCs/AstrumDeus/AstrumDeusBody.cs +++ b/NPCs/AstrumDeus/AstrumDeusBody.cs @@ -15,6 +15,7 @@ namespace CalamityMod.NPCs.AstrumDeus { + [LongDistanceNetSync(SyncWith = typeof(AstrumDeusHead))] public class AstrumDeusBody : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.AstrumDeusHead.DisplayName"); diff --git a/NPCs/AstrumDeus/AstrumDeusHead.cs b/NPCs/AstrumDeus/AstrumDeusHead.cs index f814c85120..8ec5567827 100644 --- a/NPCs/AstrumDeus/AstrumDeusHead.cs +++ b/NPCs/AstrumDeus/AstrumDeusHead.cs @@ -34,6 +34,7 @@ namespace CalamityMod.NPCs.AstrumDeus { [AutoloadBossHead] + [LongDistanceNetSync] public class AstrumDeusHead : ModNPC { public static readonly SoundStyle SpawnSound = new("CalamityMod/Sounds/Custom/AstrumDeus/AstrumDeusSpawn"); diff --git a/NPCs/AstrumDeus/AstrumDeusTail.cs b/NPCs/AstrumDeus/AstrumDeusTail.cs index 3a3a2f1004..95bb79480f 100644 --- a/NPCs/AstrumDeus/AstrumDeusTail.cs +++ b/NPCs/AstrumDeus/AstrumDeusTail.cs @@ -15,6 +15,7 @@ namespace CalamityMod.NPCs.AstrumDeus { + [LongDistanceNetSync(SyncWith = typeof(AstrumDeusHead))] public class AstrumDeusTail : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.AstrumDeusHead.DisplayName"); diff --git a/NPCs/CalamityNetImportantNPC.cs b/NPCs/CalamityNetImportantNPC.cs index e934ad3c50..065b2138d8 100644 --- a/NPCs/CalamityNetImportantNPC.cs +++ b/NPCs/CalamityNetImportantNPC.cs @@ -1,36 +1,12 @@ using System; using System.Collections.Generic; +using System.CommandLine.Parsing; using System.Linq; -using System.Text; -using System.Threading.Tasks; -using CalamityMod.NPCs.Abyss; -using CalamityMod.NPCs.AcidRain; -using CalamityMod.NPCs.AquaticScourge; -using CalamityMod.NPCs.AstrumDeus; -using CalamityMod.NPCs.CalClone; -using CalamityMod.NPCs.Cryogen; -using CalamityMod.NPCs.DesertScourge; -using CalamityMod.NPCs.DevourerofGods; -using CalamityMod.NPCs.ExoMechs; -using CalamityMod.NPCs.ExoMechs.Apollo; -using CalamityMod.NPCs.ExoMechs.Ares; -using CalamityMod.NPCs.ExoMechs.Artemis; -using CalamityMod.NPCs.ExoMechs.Thanatos; -using CalamityMod.NPCs.Leviathan; -using CalamityMod.NPCs.NormalNPCs; -using CalamityMod.NPCs.Perforator; -using CalamityMod.NPCs.PrimordialWyrm; -using CalamityMod.NPCs.ProfanedGuardians; -using CalamityMod.NPCs.Providence; -using CalamityMod.NPCs.StormWeaver; -using CalamityMod.NPCs.SupremeCalamitas; -using Microsoft.Xna.Framework; +using System.Reflection; using Terraria; -using Terraria.Chat; -using Terraria.DataStructures; using Terraria.ID; -using Terraria.Localization; using Terraria.ModLoader; +using Terraria.ModLoader.Core; namespace CalamityMod.NPCs { @@ -51,122 +27,60 @@ public override void Unload() public override void SetStaticDefaults() { - #region Vanilla Enemies - MarkNPCToNetImportant(NPCID.EaterofWorldsHead); - MarkNPCToNetImportant(NPCID.EaterofWorldsBody); - MarkNPCToNetImportant(NPCID.EaterofWorldsTail); + int uniqueNetOffsetID = 0; - MarkNPCToNetImportant(NPCID.TheDestroyer); - MarkNPCToNetImportant(NPCID.TheDestroyerBody); - MarkNPCToNetImportant(NPCID.TheDestroyerTail); + #region Vanilla Enemies + MarkNPCToLongDistanceSync(NPCID.EaterofWorldsHead, uniqueNetOffsetID); + MarkNPCToLongDistanceSync(NPCID.EaterofWorldsBody, uniqueNetOffsetID); + MarkNPCToLongDistanceSync(NPCID.EaterofWorldsTail, uniqueNetOffsetID); + uniqueNetOffsetID++; + + MarkNPCToLongDistanceSync(NPCID.TheDestroyer, uniqueNetOffsetID); + MarkNPCToLongDistanceSync(NPCID.TheDestroyerBody, uniqueNetOffsetID); + MarkNPCToLongDistanceSync(NPCID.TheDestroyerTail, uniqueNetOffsetID); + uniqueNetOffsetID++; #endregion Vanilla Enemies + var types = AssemblyManager.GetLoadableTypes(CalamityMod.Instance.Code) + .Where(type => !type.IsAbstract && type.IsSubclassOf(typeof(ModNPC))); + // Caching this for better performance + var npcTypeMethod = typeof(ModContent).GetMethod(nameof(ModContent.NPCType)); + var netOffsetTable = new Dictionary(); + foreach (var type in types) + { + try + { + var longDistSync = type.GetCustomAttribute(); + + if (longDistSync == null) + continue; + + var npcTypeActualMethod = npcTypeMethod.MakeGenericMethod(typeArguments: type); + + int npcType = (int)npcTypeActualMethod.Invoke(null, null); + int netOffset = uniqueNetOffsetID; + + Type typeToCheck = longDistSync.SyncWith ?? type; + if (netOffsetTable.TryGetValue(typeToCheck, out int savedUniqueID)) + { + netOffset = savedUniqueID; + } + else + { + netOffsetTable[typeToCheck] = netOffset; + uniqueNetOffsetID++; + } + + MarkNPCToLongDistanceSync(npcType, netOffset); + } + catch (Exception e) + { + CalamityMod.Instance.Logger.Error($"Exception thrown while evaluating type \"{type.Name}\": {e}"); + } + } - #region Pre Hardmode - MarkNPCToNetImportant(netUpdateTickOffset: 1); - MarkNPCToNetImportant(netUpdateTickOffset: 1); - MarkNPCToNetImportant(netUpdateTickOffset: 1); - - MarkNPCToNetImportant(netUpdateTickOffset: 2); - MarkNPCToNetImportant(netUpdateTickOffset: 2); - MarkNPCToNetImportant(netUpdateTickOffset: 2); - - MarkNPCToNetImportant(netUpdateTickOffset: 3); - MarkNPCToNetImportant(netUpdateTickOffset: 3); - MarkNPCToNetImportant(netUpdateTickOffset: 3); - - MarkNPCToNetImportant(netUpdateTickOffset: 1); - MarkNPCToNetImportant(netUpdateTickOffset: 1); - MarkNPCToNetImportant(netUpdateTickOffset: 1); - - MarkNPCToNetImportant(netUpdateTickOffset: 2); - MarkNPCToNetImportant(netUpdateTickOffset: 2); - MarkNPCToNetImportant(netUpdateTickOffset: 2); - - MarkNPCToNetImportant(netUpdateTickOffset: 3); - MarkNPCToNetImportant(netUpdateTickOffset: 3); - MarkNPCToNetImportant(netUpdateTickOffset: 3); - #endregion Pre Hardmode - - - - #region Hardmode - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - #endregion Hardmode - - - - #region Post ML - MarkNPCToNetImportant(netUpdateTickOffset: 1); - MarkNPCToNetImportant(netUpdateTickOffset: 1); - MarkNPCToNetImportant(netUpdateTickOffset: 1); - - MarkNPCToNetImportant(netUpdateTickOffset: 2); - MarkNPCToNetImportant(netUpdateTickOffset: 2); - MarkNPCToNetImportant(netUpdateTickOffset: 2); - - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - #endregion Post ML - - - #region Calamitas Boss - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - #endregion - - - #region Draedon Boss - MarkNPCToNetImportant(); - - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - #endregion Draedon Boss - - - - #region Abyss - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - - MarkNPCToNetImportant(netUpdateTickOffset: 1); - MarkNPCToNetImportant(netUpdateTickOffset: 1); - MarkNPCToNetImportant(netUpdateTickOffset: 1); - MarkNPCToNetImportant(netUpdateTickOffset: 1); - - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - MarkNPCToNetImportant(); - - MarkNPCToNetImportant(netUpdateTickOffset: 2); - MarkNPCToNetImportant(netUpdateTickOffset: 2); - MarkNPCToNetImportant(netUpdateTickOffset: 2); - MarkNPCToNetImportant(netUpdateTickOffset: 2); - #endregion Abyss + netOffsetTable?.Clear(); } public override void PostAI(NPC npc) @@ -198,12 +112,12 @@ public override void PostAI(NPC npc) } } - private void MarkNPCToNetImportant(int netUpdateTickOffset = 0) where NPCType : ModNPC + private static void MarkNPCToLongDistanceSync(int netUpdateTickOffset = 0) where NPCType : ModNPC { - MarkNPCToNetImportant(ModContent.NPCType(), netUpdateTickOffset); + MarkNPCToLongDistanceSync(ModContent.NPCType(), netUpdateTickOffset); } - private void MarkNPCToNetImportant(int npcType, int netUpdateTickOffset = 0) + private static void MarkNPCToLongDistanceSync(int npcType, int netUpdateTickOffset = 0) { typesToUpdate[npcType] = netUpdateTickOffset; } diff --git a/NPCs/Cryogen/Cryogen.cs b/NPCs/Cryogen/Cryogen.cs index 36f0b6388c..b7e63f539d 100644 --- a/NPCs/Cryogen/Cryogen.cs +++ b/NPCs/Cryogen/Cryogen.cs @@ -39,6 +39,7 @@ namespace CalamityMod.NPCs.Cryogen { [AutoloadBossHead] + [LongDistanceNetSync] // Cryogen follows you forever like Queen Bee in vanilla, So we need this to sync it's position on minimap public class Cryogen : ModNPC { private int biomeEnrageTimer = CalamityGlobalNPC.biomeEnrageTimerMax; diff --git a/NPCs/Cryogen/CryogenShield.cs b/NPCs/Cryogen/CryogenShield.cs index d16c2fbb85..11d6978de3 100644 --- a/NPCs/Cryogen/CryogenShield.cs +++ b/NPCs/Cryogen/CryogenShield.cs @@ -11,6 +11,7 @@ namespace CalamityMod.NPCs.Cryogen { + [LongDistanceNetSync(SyncWith = typeof(Cryogen))] public class CryogenShield : ModNPC { public static readonly SoundStyle BreakSound = new("CalamityMod/Sounds/NPCKilled/CryogenShieldBreak"); diff --git a/NPCs/DesertScourge/DesertNuisanceBody.cs b/NPCs/DesertScourge/DesertNuisanceBody.cs index 3498f8fe14..6478a73a20 100644 --- a/NPCs/DesertScourge/DesertNuisanceBody.cs +++ b/NPCs/DesertScourge/DesertNuisanceBody.cs @@ -11,6 +11,7 @@ namespace CalamityMod.NPCs.DesertScourge { + [LongDistanceNetSync(SyncWith = typeof(DesertNuisanceHead))] public class DesertNuisanceBody : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.DesertNuisanceHead.DisplayName"); diff --git a/NPCs/DesertScourge/DesertNuisanceBodyYoung.cs b/NPCs/DesertScourge/DesertNuisanceBodyYoung.cs index 5e9f85ba16..063bb029b5 100644 --- a/NPCs/DesertScourge/DesertNuisanceBodyYoung.cs +++ b/NPCs/DesertScourge/DesertNuisanceBodyYoung.cs @@ -11,6 +11,7 @@ namespace CalamityMod.NPCs.DesertScourge { + [LongDistanceNetSync(SyncWith = typeof(DesertNuisanceHeadYoung))] public class DesertNuisanceBodyYoung : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.DesertNuisanceHeadYoung.DisplayName"); diff --git a/NPCs/DesertScourge/DesertNuisanceHead.cs b/NPCs/DesertScourge/DesertNuisanceHead.cs index 71e547d8f9..329c8abea3 100644 --- a/NPCs/DesertScourge/DesertNuisanceHead.cs +++ b/NPCs/DesertScourge/DesertNuisanceHead.cs @@ -12,6 +12,7 @@ namespace CalamityMod.NPCs.DesertScourge { [AutoloadBossHead] + [LongDistanceNetSync] public class DesertNuisanceHead : ModNPC { private int biomeEnrageTimer = CalamityGlobalNPC.biomeEnrageTimerMax; diff --git a/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs b/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs index e984be408c..e8ae27982d 100644 --- a/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs +++ b/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs @@ -14,6 +14,7 @@ namespace CalamityMod.NPCs.DesertScourge { [AutoloadBossHead] + [LongDistanceNetSync] public class DesertNuisanceHeadYoung : ModNPC { private int biomeEnrageTimer = CalamityGlobalNPC.biomeEnrageTimerMax; diff --git a/NPCs/DesertScourge/DesertNuisanceTail.cs b/NPCs/DesertScourge/DesertNuisanceTail.cs index 709710af2f..4b720426b8 100644 --- a/NPCs/DesertScourge/DesertNuisanceTail.cs +++ b/NPCs/DesertScourge/DesertNuisanceTail.cs @@ -8,6 +8,7 @@ namespace CalamityMod.NPCs.DesertScourge { + [LongDistanceNetSync(SyncWith = typeof(DesertNuisanceHead))] public class DesertNuisanceTail : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.DesertNuisanceHead.DisplayName"); diff --git a/NPCs/DesertScourge/DesertNuisanceTailYoung.cs b/NPCs/DesertScourge/DesertNuisanceTailYoung.cs index c2b49d23c3..ecb1eb5c0b 100644 --- a/NPCs/DesertScourge/DesertNuisanceTailYoung.cs +++ b/NPCs/DesertScourge/DesertNuisanceTailYoung.cs @@ -8,6 +8,7 @@ namespace CalamityMod.NPCs.DesertScourge { + [LongDistanceNetSync(SyncWith = typeof(DesertNuisanceHeadYoung))] public class DesertNuisanceTailYoung : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.DesertNuisanceHeadYoung.DisplayName"); diff --git a/NPCs/DesertScourge/DesertScourgeBody.cs b/NPCs/DesertScourge/DesertScourgeBody.cs index 1d30f4e6ce..2baae9ff4d 100644 --- a/NPCs/DesertScourge/DesertScourgeBody.cs +++ b/NPCs/DesertScourge/DesertScourgeBody.cs @@ -15,6 +15,7 @@ namespace CalamityMod.NPCs.DesertScourge { + [LongDistanceNetSync(SyncWith = typeof(DesertScourgeHead))] public class DesertScourgeBody : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.DesertScourgeHead.DisplayName"); diff --git a/NPCs/DesertScourge/DesertScourgeHead.cs b/NPCs/DesertScourge/DesertScourgeHead.cs index 4cd787ab44..32ed748f47 100644 --- a/NPCs/DesertScourge/DesertScourgeHead.cs +++ b/NPCs/DesertScourge/DesertScourgeHead.cs @@ -32,6 +32,7 @@ namespace CalamityMod.NPCs.DesertScourge { [AutoloadBossHead] + [LongDistanceNetSync] public class DesertScourgeHead : ModNPC { private int biomeEnrageTimer = CalamityGlobalNPC.biomeEnrageTimerMax; diff --git a/NPCs/DesertScourge/DesertScourgeTail.cs b/NPCs/DesertScourge/DesertScourgeTail.cs index 749dd0791a..c0cd5a1bdb 100644 --- a/NPCs/DesertScourge/DesertScourgeTail.cs +++ b/NPCs/DesertScourge/DesertScourgeTail.cs @@ -10,6 +10,7 @@ namespace CalamityMod.NPCs.DesertScourge { + [LongDistanceNetSync(SyncWith = typeof(DesertScourgeHead))] public class DesertScourgeTail : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.DesertScourgeHead.DisplayName"); diff --git a/NPCs/DevourerofGods/CosmicGuardianBody.cs b/NPCs/DevourerofGods/CosmicGuardianBody.cs index 6c0600c59f..a5fb60beb8 100644 --- a/NPCs/DevourerofGods/CosmicGuardianBody.cs +++ b/NPCs/DevourerofGods/CosmicGuardianBody.cs @@ -13,6 +13,7 @@ using Terraria.ModLoader; namespace CalamityMod.NPCs.DevourerofGods { + [LongDistanceNetSync(SyncWith = typeof(CosmicGuardianHead))] public class CosmicGuardianBody : ModNPC { public int invinceTime = 180; diff --git a/NPCs/DevourerofGods/CosmicGuardianHead.cs b/NPCs/DevourerofGods/CosmicGuardianHead.cs index eb7ef94bad..a4e0e2439e 100644 --- a/NPCs/DevourerofGods/CosmicGuardianHead.cs +++ b/NPCs/DevourerofGods/CosmicGuardianHead.cs @@ -15,6 +15,7 @@ namespace CalamityMod.NPCs.DevourerofGods { + [LongDistanceNetSync] public class CosmicGuardianHead : ModNPC { private bool tail = false; diff --git a/NPCs/DevourerofGods/CosmicGuardianTail.cs b/NPCs/DevourerofGods/CosmicGuardianTail.cs index d44bab21c7..125e7eef07 100644 --- a/NPCs/DevourerofGods/CosmicGuardianTail.cs +++ b/NPCs/DevourerofGods/CosmicGuardianTail.cs @@ -13,6 +13,7 @@ using Terraria.ModLoader; namespace CalamityMod.NPCs.DevourerofGods { + [LongDistanceNetSync(SyncWith = typeof(CosmicGuardianHead))] public class CosmicGuardianTail : ModNPC { public int invinceTime = 180; diff --git a/NPCs/DevourerofGods/DevourerofGodsBody.cs b/NPCs/DevourerofGods/DevourerofGodsBody.cs index aff92981bc..c8314094d3 100644 --- a/NPCs/DevourerofGods/DevourerofGodsBody.cs +++ b/NPCs/DevourerofGods/DevourerofGodsBody.cs @@ -20,6 +20,7 @@ namespace CalamityMod.NPCs.DevourerofGods { + [LongDistanceNetSync(SyncWith = typeof(DevourerofGodsHead))] public class DevourerofGodsBody : ModNPC { public static int phase2IconIndex; diff --git a/NPCs/DevourerofGods/DevourerofGodsHead.cs b/NPCs/DevourerofGods/DevourerofGodsHead.cs index 9d5119195f..085b5eff9b 100644 --- a/NPCs/DevourerofGods/DevourerofGodsHead.cs +++ b/NPCs/DevourerofGods/DevourerofGodsHead.cs @@ -44,6 +44,7 @@ namespace CalamityMod.NPCs.DevourerofGods { + [LongDistanceNetSync] public class DevourerofGodsHead : ModNPC { public static int phase1IconIndex; diff --git a/NPCs/DevourerofGods/DevourerofGodsTail.cs b/NPCs/DevourerofGods/DevourerofGodsTail.cs index 36b7a39663..b521baedb1 100644 --- a/NPCs/DevourerofGods/DevourerofGodsTail.cs +++ b/NPCs/DevourerofGods/DevourerofGodsTail.cs @@ -19,6 +19,7 @@ namespace CalamityMod.NPCs.DevourerofGods { + [LongDistanceNetSync(SyncWith = typeof(DevourerofGodsHead))] public class DevourerofGodsTail : ModNPC { public static int phase1IconIndex; diff --git a/NPCs/ExoMechs/Draedon.cs b/NPCs/ExoMechs/Draedon.cs index 623673c9f1..8aaf2a126c 100644 --- a/NPCs/ExoMechs/Draedon.cs +++ b/NPCs/ExoMechs/Draedon.cs @@ -22,6 +22,7 @@ namespace CalamityMod.NPCs.ExoMechs { + [LongDistanceNetSync] public class Draedon : ModNPC { public int KillReappearTextCountdown; diff --git a/NPCs/ExoMechs/Thanatos/ThanatosBody1.cs b/NPCs/ExoMechs/Thanatos/ThanatosBody1.cs index 4dc825f12a..28eb67978c 100644 --- a/NPCs/ExoMechs/Thanatos/ThanatosBody1.cs +++ b/NPCs/ExoMechs/Thanatos/ThanatosBody1.cs @@ -17,6 +17,7 @@ namespace CalamityMod.NPCs.ExoMechs.Thanatos { + [LongDistanceNetSync(SyncWith = typeof(ThanatosHead))] public class ThanatosBody1 : ModNPC { public static int normalIconIndex; diff --git a/NPCs/ExoMechs/Thanatos/ThanatosBody2.cs b/NPCs/ExoMechs/Thanatos/ThanatosBody2.cs index 76c6275344..612ae50f89 100644 --- a/NPCs/ExoMechs/Thanatos/ThanatosBody2.cs +++ b/NPCs/ExoMechs/Thanatos/ThanatosBody2.cs @@ -17,6 +17,7 @@ namespace CalamityMod.NPCs.ExoMechs.Thanatos { + [LongDistanceNetSync(SyncWith = typeof(ThanatosHead))] public class ThanatosBody2 : ModNPC { public static int normalIconIndex; diff --git a/NPCs/ExoMechs/Thanatos/ThanatosHead.cs b/NPCs/ExoMechs/Thanatos/ThanatosHead.cs index 3c7d01279b..1dcbca3bc4 100644 --- a/NPCs/ExoMechs/Thanatos/ThanatosHead.cs +++ b/NPCs/ExoMechs/Thanatos/ThanatosHead.cs @@ -22,6 +22,7 @@ namespace CalamityMod.NPCs.ExoMechs.Thanatos { + [LongDistanceNetSync] public class ThanatosHead : ModNPC { public static int normalIconIndex; diff --git a/NPCs/ExoMechs/Thanatos/ThanatosTail.cs b/NPCs/ExoMechs/Thanatos/ThanatosTail.cs index 23622c7c61..1ceb5d01bc 100644 --- a/NPCs/ExoMechs/Thanatos/ThanatosTail.cs +++ b/NPCs/ExoMechs/Thanatos/ThanatosTail.cs @@ -17,6 +17,7 @@ namespace CalamityMod.NPCs.ExoMechs.Thanatos { + [LongDistanceNetSync(SyncWith = typeof(ThanatosHead))] public class ThanatosTail : ModNPC { public static int normalIconIndex; diff --git a/NPCs/LongDistanceNetSyncAttribute.cs b/NPCs/LongDistanceNetSyncAttribute.cs new file mode 100644 index 0000000000..b66d997580 --- /dev/null +++ b/NPCs/LongDistanceNetSyncAttribute.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Terraria.ModLoader; + +namespace CalamityMod.NPCs +{ + /// + /// This attribute allows ModNPC to always sync for their position and rotation data at least every 45 frames + /// + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] + public sealed class LongDistanceNetSyncAttribute : Attribute + { + /// + /// Syncs this NPC to other NPC's sync frame + /// If this is not present, We cannot properly sync full NPC bodyparts in same frame! (This is important for Worm-type NPCs) + /// + public Type SyncWith { get; set; } = null; + + public LongDistanceNetSyncAttribute() + { + + } + } +} diff --git a/NPCs/NormalNPCs/ArmoredDiggerBody.cs b/NPCs/NormalNPCs/ArmoredDiggerBody.cs index 26296ef13d..9582773fef 100644 --- a/NPCs/NormalNPCs/ArmoredDiggerBody.cs +++ b/NPCs/NormalNPCs/ArmoredDiggerBody.cs @@ -10,6 +10,7 @@ namespace CalamityMod.NPCs.NormalNPCs { + [LongDistanceNetSync(SyncWith = typeof(ArmoredDiggerHead))] public class ArmoredDiggerBody : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.ArmoredDiggerHead.DisplayName"); diff --git a/NPCs/NormalNPCs/ArmoredDiggerHead.cs b/NPCs/NormalNPCs/ArmoredDiggerHead.cs index 1fc942cfb8..70fc0433aa 100644 --- a/NPCs/NormalNPCs/ArmoredDiggerHead.cs +++ b/NPCs/NormalNPCs/ArmoredDiggerHead.cs @@ -13,6 +13,7 @@ namespace CalamityMod.NPCs.NormalNPCs { + [LongDistanceNetSync] public class ArmoredDiggerHead : ModNPC { bool TailSpawned = false; diff --git a/NPCs/NormalNPCs/ArmoredDiggerTail.cs b/NPCs/NormalNPCs/ArmoredDiggerTail.cs index 62104f3a10..b6536f1e61 100644 --- a/NPCs/NormalNPCs/ArmoredDiggerTail.cs +++ b/NPCs/NormalNPCs/ArmoredDiggerTail.cs @@ -9,6 +9,7 @@ namespace CalamityMod.NPCs.NormalNPCs { + [LongDistanceNetSync(SyncWith = typeof(ArmoredDiggerHead))] public class ArmoredDiggerTail : ModNPC { public override LocalizedText DisplayName => CalamityUtils.GetText("NPCs.ArmoredDiggerHead.DisplayName"); diff --git a/NPCs/Perforator/PerforatorBodyLarge.cs b/NPCs/Perforator/PerforatorBodyLarge.cs index c25aae7727..c824477afd 100644 --- a/NPCs/Perforator/PerforatorBodyLarge.cs +++ b/NPCs/Perforator/PerforatorBodyLarge.cs @@ -13,6 +13,7 @@ namespace CalamityMod.NPCs.Perforator { + [LongDistanceNetSync(SyncWith = typeof(PerforatorHeadLarge))] public class PerforatorBodyLarge : ModNPC { public static readonly SoundStyle HitSound = new("CalamityMod/Sounds/NPCHit/PerfLargeHit", 3); diff --git a/NPCs/Perforator/PerforatorBodyMedium.cs b/NPCs/Perforator/PerforatorBodyMedium.cs index ef764fa9f1..0c274ba469 100644 --- a/NPCs/Perforator/PerforatorBodyMedium.cs +++ b/NPCs/Perforator/PerforatorBodyMedium.cs @@ -15,6 +15,7 @@ namespace CalamityMod.NPCs.Perforator { + [LongDistanceNetSync(SyncWith = typeof(PerforatorHeadMedium))] public class PerforatorBodyMedium : ModNPC { public static readonly SoundStyle HitSound = new("CalamityMod/Sounds/NPCHit/PerfMediumHit", 3); diff --git a/NPCs/Perforator/PerforatorBodySmall.cs b/NPCs/Perforator/PerforatorBodySmall.cs index 08627fc303..a72dcb34be 100644 --- a/NPCs/Perforator/PerforatorBodySmall.cs +++ b/NPCs/Perforator/PerforatorBodySmall.cs @@ -13,6 +13,7 @@ namespace CalamityMod.NPCs.Perforator { + [LongDistanceNetSync(SyncWith = typeof(PerforatorHeadSmall))] public class PerforatorBodySmall : ModNPC { public static readonly SoundStyle HitSound = new("CalamityMod/Sounds/NPCHit/PerfSmallHit", 3); diff --git a/NPCs/Perforator/PerforatorHeadLarge.cs b/NPCs/Perforator/PerforatorHeadLarge.cs index ae4e888120..82a6499720 100644 --- a/NPCs/Perforator/PerforatorHeadLarge.cs +++ b/NPCs/Perforator/PerforatorHeadLarge.cs @@ -17,6 +17,7 @@ namespace CalamityMod.NPCs.Perforator { [AutoloadBossHead] + [LongDistanceNetSync] public class PerforatorHeadLarge : ModNPC { public static readonly SoundStyle HitSound = new("CalamityMod/Sounds/NPCHit/PerfLargeHit", 3); diff --git a/NPCs/Perforator/PerforatorHeadMedium.cs b/NPCs/Perforator/PerforatorHeadMedium.cs index acdb3c712b..9283bbbce1 100644 --- a/NPCs/Perforator/PerforatorHeadMedium.cs +++ b/NPCs/Perforator/PerforatorHeadMedium.cs @@ -16,6 +16,7 @@ namespace CalamityMod.NPCs.Perforator { [AutoloadBossHead] + [LongDistanceNetSync] public class PerforatorHeadMedium : ModNPC { public static readonly SoundStyle HitSound = new("CalamityMod/Sounds/NPCHit/PerfMediumHit", 3); diff --git a/NPCs/Perforator/PerforatorHeadSmall.cs b/NPCs/Perforator/PerforatorHeadSmall.cs index 40a2a555dc..acb6d6318a 100644 --- a/NPCs/Perforator/PerforatorHeadSmall.cs +++ b/NPCs/Perforator/PerforatorHeadSmall.cs @@ -16,6 +16,7 @@ namespace CalamityMod.NPCs.Perforator { [AutoloadBossHead] + [LongDistanceNetSync] public class PerforatorHeadSmall : ModNPC { public static readonly SoundStyle HitSound = new("CalamityMod/Sounds/NPCHit/PerfSmallHit", 3); diff --git a/NPCs/Perforator/PerforatorTailLarge.cs b/NPCs/Perforator/PerforatorTailLarge.cs index 5095d20a37..2bfc0f7eef 100644 --- a/NPCs/Perforator/PerforatorTailLarge.cs +++ b/NPCs/Perforator/PerforatorTailLarge.cs @@ -13,6 +13,7 @@ namespace CalamityMod.NPCs.Perforator { + [LongDistanceNetSync(SyncWith = typeof(PerforatorHeadLarge))] public class PerforatorTailLarge : ModNPC { public static readonly SoundStyle HitSound = new("CalamityMod/Sounds/NPCHit/PerfLargeHit", 3); diff --git a/NPCs/Perforator/PerforatorTailMedium.cs b/NPCs/Perforator/PerforatorTailMedium.cs index 6880426acc..f5128e40f5 100644 --- a/NPCs/Perforator/PerforatorTailMedium.cs +++ b/NPCs/Perforator/PerforatorTailMedium.cs @@ -15,6 +15,7 @@ namespace CalamityMod.NPCs.Perforator { + [LongDistanceNetSync(SyncWith = typeof(PerforatorHeadMedium))] public class PerforatorTailMedium : ModNPC { public static readonly SoundStyle HitSound = new("CalamityMod/Sounds/NPCHit/PerfMediumHit", 3); diff --git a/NPCs/Perforator/PerforatorTailSmall.cs b/NPCs/Perforator/PerforatorTailSmall.cs index 30ad5f8738..3653234a47 100644 --- a/NPCs/Perforator/PerforatorTailSmall.cs +++ b/NPCs/Perforator/PerforatorTailSmall.cs @@ -13,6 +13,7 @@ namespace CalamityMod.NPCs.Perforator { + [LongDistanceNetSync(SyncWith = typeof(PerforatorHeadSmall))] public class PerforatorTailSmall : ModNPC { public static readonly SoundStyle HitSound = new("CalamityMod/Sounds/NPCHit/PerfSmallHit", 3); diff --git a/NPCs/PrimordialWyrm/PrimordialWyrmBody.cs b/NPCs/PrimordialWyrm/PrimordialWyrmBody.cs index edd0b1f728..1de74e9cf4 100644 --- a/NPCs/PrimordialWyrm/PrimordialWyrmBody.cs +++ b/NPCs/PrimordialWyrm/PrimordialWyrmBody.cs @@ -12,6 +12,7 @@ namespace CalamityMod.NPCs.PrimordialWyrm { + [LongDistanceNetSync(SyncWith = typeof(PrimordialWyrmHead))] public class PrimordialWyrmBody : ModNPC { public static Asset GlowTexture; diff --git a/NPCs/PrimordialWyrm/PrimordialWyrmBodyAlt.cs b/NPCs/PrimordialWyrm/PrimordialWyrmBodyAlt.cs index 823636e046..aa679618c5 100644 --- a/NPCs/PrimordialWyrm/PrimordialWyrmBodyAlt.cs +++ b/NPCs/PrimordialWyrm/PrimordialWyrmBodyAlt.cs @@ -12,6 +12,7 @@ namespace CalamityMod.NPCs.PrimordialWyrm { + [LongDistanceNetSync(SyncWith = typeof(PrimordialWyrmHead))] public class PrimordialWyrmBodyAlt : ModNPC { public static Asset GlowTexture; diff --git a/NPCs/PrimordialWyrm/PrimordialWyrmHead.cs b/NPCs/PrimordialWyrm/PrimordialWyrmHead.cs index 49391cd55c..e0267f9335 100644 --- a/NPCs/PrimordialWyrm/PrimordialWyrmHead.cs +++ b/NPCs/PrimordialWyrm/PrimordialWyrmHead.cs @@ -28,6 +28,7 @@ namespace CalamityMod.NPCs.PrimordialWyrm { [AutoloadBossHead] + [LongDistanceNetSync] public class PrimordialWyrmHead : ModNPC { public enum Phase diff --git a/NPCs/PrimordialWyrm/PrimordialWyrmTail.cs b/NPCs/PrimordialWyrm/PrimordialWyrmTail.cs index 7b9aae19b0..8b9b49021b 100644 --- a/NPCs/PrimordialWyrm/PrimordialWyrmTail.cs +++ b/NPCs/PrimordialWyrm/PrimordialWyrmTail.cs @@ -11,6 +11,7 @@ namespace CalamityMod.NPCs.PrimordialWyrm { + [LongDistanceNetSync(SyncWith = typeof(PrimordialWyrmHead))] public class PrimordialWyrmTail : ModNPC { public static Asset GlowTexture; diff --git a/NPCs/StormWeaver/StormWeaverBody.cs b/NPCs/StormWeaver/StormWeaverBody.cs index d921c85011..f18c6ecfee 100644 --- a/NPCs/StormWeaver/StormWeaverBody.cs +++ b/NPCs/StormWeaver/StormWeaverBody.cs @@ -14,6 +14,7 @@ namespace CalamityMod.NPCs.StormWeaver { + [LongDistanceNetSync(SyncWith = typeof(StormWeaverHead))] public class StormWeaverBody : ModNPC { public static Asset Phase2Texture; diff --git a/NPCs/StormWeaver/StormWeaverHead.cs b/NPCs/StormWeaver/StormWeaverHead.cs index 75e8814fe4..91e0ac47ae 100644 --- a/NPCs/StormWeaver/StormWeaverHead.cs +++ b/NPCs/StormWeaver/StormWeaverHead.cs @@ -31,6 +31,7 @@ namespace CalamityMod.NPCs.StormWeaver { + [LongDistanceNetSync] public class StormWeaverHead : ModNPC { public static int normalIconIndex; diff --git a/NPCs/StormWeaver/StormWeaverTail.cs b/NPCs/StormWeaver/StormWeaverTail.cs index 62afff7228..9ae676af2b 100644 --- a/NPCs/StormWeaver/StormWeaverTail.cs +++ b/NPCs/StormWeaver/StormWeaverTail.cs @@ -13,6 +13,7 @@ namespace CalamityMod.NPCs.StormWeaver { + [LongDistanceNetSync(SyncWith = typeof(StormWeaverHead))] public class StormWeaverTail : ModNPC { private int invinceTime = 180; diff --git a/NPCs/SupremeCalamitas/SepulcherBody.cs b/NPCs/SupremeCalamitas/SepulcherBody.cs index a5be1ff57c..4d092f6da2 100644 --- a/NPCs/SupremeCalamitas/SepulcherBody.cs +++ b/NPCs/SupremeCalamitas/SepulcherBody.cs @@ -11,6 +11,7 @@ namespace CalamityMod.NPCs.SupremeCalamitas { + [LongDistanceNetSync(SyncWith = typeof(SepulcherHead))] public class SepulcherBody : ModNPC { private bool setAlpha = false; diff --git a/NPCs/SupremeCalamitas/SepulcherHead.cs b/NPCs/SupremeCalamitas/SepulcherHead.cs index 67df4e9c2f..05100dabd8 100644 --- a/NPCs/SupremeCalamitas/SepulcherHead.cs +++ b/NPCs/SupremeCalamitas/SepulcherHead.cs @@ -16,6 +16,7 @@ namespace CalamityMod.NPCs.SupremeCalamitas { + [LongDistanceNetSync] public class SepulcherHead : ModNPC { public static readonly SoundStyle DeathSound = new("CalamityMod/Sounds/NPCKilled/SepulcherDeath"); diff --git a/NPCs/SupremeCalamitas/SepulcherTail.cs b/NPCs/SupremeCalamitas/SepulcherTail.cs index ba744ca331..6798e03161 100644 --- a/NPCs/SupremeCalamitas/SepulcherTail.cs +++ b/NPCs/SupremeCalamitas/SepulcherTail.cs @@ -11,6 +11,7 @@ namespace CalamityMod.NPCs.SupremeCalamitas { + [LongDistanceNetSync(SyncWith = typeof(SepulcherHead))] public class SepulcherTail : ModNPC { private bool setAlpha = false; From 36bade6cf6b1e1c1ca4847d2b3943662c8f573c2 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Fri, 1 Nov 2024 00:39:04 -0500 Subject: [PATCH 210/401] Abyss Layer 4 lag hell fix. --- CalamityMod.cs | 1 + Utilities/FramedGlowMask.cs | 154 +++++++++++++++++++++++++++++++++++ Walls/VoidstoneWall.cs | 42 ++++++---- Walls/VoidstoneWallUnsafe.cs | 46 +++++++---- 4 files changed, 209 insertions(+), 34 deletions(-) create mode 100644 Utilities/FramedGlowMask.cs diff --git a/CalamityMod.cs b/CalamityMod.cs index 7ac3568177..043dd624e3 100644 --- a/CalamityMod.cs +++ b/CalamityMod.cs @@ -447,6 +447,7 @@ public override void Unload() NPCStats.Unload(); CalamityGlobalItem.UnloadTweaks(); CalamityGlobalProjectile.UnloadTweaks(); + FramedGlowMask.UnloadTexCache(); PopupGUIManager.UnloadGUIs(); InvasionProgressUIManager.UnloadGUIs(); diff --git a/Utilities/FramedGlowMask.cs b/Utilities/FramedGlowMask.cs new file mode 100644 index 0000000000..f2a95eae77 --- /dev/null +++ b/Utilities/FramedGlowMask.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ReLogic.Content; +using Terraria; +using Terraria.ModLoader; + +namespace CalamityMod +{ + public sealed class FramedGlowMask + { + /// + /// Cached Texture2D reference, null on server + /// + public Texture2D Texture { get; private set; } + + /// + /// X axis's frame count, 0 on server + /// + public int FrameXCount { get; private set; } = 0; + + /// + /// Y axis's frame count, 0 on server + /// + public int FrameYCount { get; private set; } = 0; + + /// + /// Pixel width for each frame + /// + public int FrameWidth { get; private set; } + + /// + /// Pixel height for each frame + /// + public int FrameHeight { get; private set; } + + private static event Action _OnUnload; + private readonly bool[,] _HasGlowContent; + + internal static void UnloadTexCache() + { + _OnUnload?.Invoke(); + } + + public FramedGlowMask(string asset, int frameWidth, int frameHeight, bool pretendEveryFrameHaveGlow = false) + { + FrameWidth = frameWidth; + FrameHeight = frameHeight; + + // Don't do anything further on server + if (Main.dedServ) + return; + + Texture = ModContent.Request(asset, AssetRequestMode.ImmediateLoad).Value; + if (Texture is null) + return; + + _OnUnload += () => + { + Texture = null; + FrameWidth = 0; + FrameHeight = 0; + FrameXCount = 0; + FrameYCount = 0; + }; + + FrameXCount = Texture.Width / frameWidth; + FrameYCount = Texture.Height / frameHeight; + + _HasGlowContent = new bool[FrameXCount, FrameYCount]; + + + if (pretendEveryFrameHaveGlow) + { + for (int x = 0; x < FrameXCount; x++) + { + for (int y = 0; y < FrameYCount; y++) + { + _HasGlowContent[x, y] = true; + } + } + } + else + { + Main.QueueMainThreadAction(() => + { + var colData = Texture.GetColorsFromTexture(); + Parallel.For(0, FrameXCount * FrameYCount, (i) => + { + int xFrame = i % FrameXCount; + int yFrame = i / FrameXCount; + int xStart = xFrame * frameWidth; + int xEnd = xStart + frameWidth; + int yStart = yFrame * frameHeight; + int yEnd = yStart + frameHeight; + bool frameHasData = false; + for (int x = xStart; x < xEnd; x++) + { + if (frameHasData) + { + break; + } + for (int y = yStart; y < yEnd; y++) + { + Color col = colData[x, y]; + if (col.A >= 1) + { + frameHasData = true; + break; + } + } + } + _HasGlowContent[xFrame, yFrame] = frameHasData; + }); + }); + } + } + + public bool HasContentInFrameIndex(int xFrame, int yFrame) + { + if (Texture is null) + return false; + + if (xFrame < 0 || xFrame >= FrameXCount) + return false; + + if (yFrame < 0 || yFrame >= FrameYCount) + return false; + + return _HasGlowContent[xFrame, yFrame]; + } + + public bool HasContentInFramePos(int xPos, int yPos) + { + if (Texture is null) + return false; + + int xFrame = xPos / FrameWidth; + int yFrame = yPos / FrameHeight; + + if (xFrame < 0 || xFrame >= FrameXCount) + return false; + + if (yFrame < 0 || yFrame >= FrameYCount) + return false; + + return _HasGlowContent[xFrame, yFrame]; + } + } +} diff --git a/Walls/VoidstoneWall.cs b/Walls/VoidstoneWall.cs index f4881eb777..ffa3a46d42 100644 --- a/Walls/VoidstoneWall.cs +++ b/Walls/VoidstoneWall.cs @@ -11,12 +11,13 @@ namespace CalamityMod.Walls { public class VoidstoneWall : ModWall { - internal static Texture2D GlowTexture; + internal static FramedGlowMask GlowMask; public override void SetStaticDefaults() { + GlowMask = new("CalamityMod/Walls/VoidstoneWall_Glowmask", 36, 36); + Main.wallHouse[Type] = true; - GlowTexture = ModContent.Request("CalamityMod/Walls/VoidstoneWall_Glowmask", AssetRequestMode.ImmediateLoad).Value; AddMapEntry(new Color(0, 0, 0)); } @@ -29,37 +30,44 @@ public override bool CreateDust(int i, int j, ref int type) public static void DrawWallGlow(int wallType, int i, int j, SpriteBatch spriteBatch) { - if (GlowTexture is null) + if (GlowMask.Texture is null) return; Tile tile = Main.tile[i, j]; int xLength = 32; int xOff = 0; - Rectangle frame = new Rectangle(tile.WallFrameX + xOff, tile.WallFrameY, xLength, 32); + int xPos = tile.WallFrameX + xOff; + int yPos = tile.WallFrameY; + + Rectangle frame = new Rectangle(xPos, yPos, xLength, 32); Color drawcolor; drawcolor = WorldGen.paintColor(tile.WallColor); drawcolor.A = 255; Vector2 zero = new Vector2(Main.offScreenRange, Main.offScreenRange); - float brightness = 1f; - float declareThisHereToPreventRunningTheSameCalculationMultipleTimes = Main.GameUpdateCount * 0.007f; - brightness *= (float)MathF.Sin(i / 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); - brightness *= (float)MathF.Sin(j / 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); - brightness *= (float)MathF.Sin(i * 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); - brightness *= (float)MathF.Sin(j * 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); - drawcolor *= brightness; - if (Main.drawToScreen) zero = Vector2.Zero; Vector2 pos = new Vector2(i * 16 - (int)Main.screenPosition.X, j * 16 - (int)Main.screenPosition.Y) + zero; - Main.spriteBatch.Draw(TextureAssets.Wall[wallType].Value, pos + new Vector2(-8 + xOff, -8), frame, Lighting.GetColor(i, j, Color.White), 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); - Color glowColor = drawcolor * 0.4f; - for (int k = 0; k < 3; k++) + spriteBatch.Draw(TextureAssets.Wall[wallType].Value, pos + new Vector2(-8 + xOff, -8), frame, Lighting.GetColor(i, j, Color.White), 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); + + if (GlowMask.HasContentInFramePos(xPos, yPos)) { - Vector2 offset = new Vector2(Main.rand.NextFloat(-1, 1f), Main.rand.NextFloat(-1, 1f)) * 0.2f * k; - Main.spriteBatch.Draw(GlowTexture, pos + offset + new Vector2(-8 + xOff, -8), frame, glowColor, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); + float brightness = 1f; + float declareThisHereToPreventRunningTheSameCalculationMultipleTimes = Main.GameUpdateCount * 0.007f; + brightness *= (float)MathF.Sin(i / 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); + brightness *= (float)MathF.Sin(j / 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); + brightness *= (float)MathF.Sin(i * 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); + brightness *= (float)MathF.Sin(j * 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); + drawcolor *= brightness; + Color glowColor = drawcolor * 0.4f; + + for (int k = 0; k < 3; k++) + { + Vector2 offset = new Vector2(Main.rand.NextFloat(-1, 1f), Main.rand.NextFloat(-1, 1f)) * 0.2f * k; + spriteBatch.Draw(GlowMask.Texture, pos + offset + new Vector2(-8 + xOff, -8), frame, glowColor, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); + } } } diff --git a/Walls/VoidstoneWallUnsafe.cs b/Walls/VoidstoneWallUnsafe.cs index 5f7348b9ee..0f0b24ea66 100644 --- a/Walls/VoidstoneWallUnsafe.cs +++ b/Walls/VoidstoneWallUnsafe.cs @@ -11,11 +11,14 @@ namespace CalamityMod.Walls { public class VoidstoneWallUnsafe : ModWall { - internal static Texture2D GlowTexture; + internal static FramedGlowMask GlowMask; public override void SetStaticDefaults() { - GlowTexture = ModContent.Request("CalamityMod/Walls/VoidstoneWall_Glowmask", AssetRequestMode.ImmediateLoad).Value; + // We basically have same copy in VoidstoneWall + // But leaving this in case of changing to Unsafe variant specific glowmask + GlowMask = new("CalamityMod/Walls/VoidstoneWall_Glowmask", 36, 36); + DustType = 187; AddMapEntry(new Color(0, 0, 0)); } @@ -34,37 +37,46 @@ public override void RandomUpdate(int i, int j) public static void DrawWallGlow(int wallType, int i, int j, SpriteBatch spriteBatch) { - if (GlowTexture is null) + if (GlowMask.Texture is null) return; Tile tile = Main.tile[i, j]; int xLength = 32; int xOff = 0; - Rectangle frame = new Rectangle(tile.WallFrameX + xOff, tile.WallFrameY, xLength, 32); + int xPos = tile.WallFrameX + xOff; + int yPos = tile.WallFrameY; + + Rectangle frame = new Rectangle(xPos, yPos, xLength, 32); Color drawcolor; drawcolor = WorldGen.paintColor(tile.WallColor); drawcolor.A = 255; Vector2 zero = new Vector2(Main.offScreenRange, Main.offScreenRange); - float brightness = 1f; - float declareThisHereToPreventRunningTheSameCalculationMultipleTimes = Main.GameUpdateCount * 0.007f; - brightness *= (float)MathF.Sin(i / 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); - brightness *= (float)MathF.Sin(j / 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); - brightness *= (float)MathF.Sin(i * 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); - brightness *= (float)MathF.Sin(j * 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); - drawcolor *= brightness; - if (Main.drawToScreen) zero = Vector2.Zero; Vector2 pos = new Vector2((i * 16 - (int)Main.screenPosition.X), (j * 16 - (int)Main.screenPosition.Y)) + zero; - Main.spriteBatch.Draw(TextureAssets.Wall[wallType].Value, pos + new Vector2(-8 + xOff, -8), frame, Lighting.GetColor(i, j, Color.White), 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); - Color glowColor = drawcolor * 0.4f; - for (int k = 0; k < 3; k++) + spriteBatch.Draw(TextureAssets.Wall[wallType].Value, pos + new Vector2(-8 + xOff, -8), frame, Lighting.GetColor(i, j, Color.White), 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); + + if (GlowMask.HasContentInFramePos(xPos, yPos)) { - Vector2 offset = new Vector2(Main.rand.NextFloat(-1f, 1f), Main.rand.NextFloat(-1f, 1f)) * 0.2f * k; - Main.spriteBatch.Draw(GlowTexture, pos + offset + new Vector2(-8 + xOff, -8), frame, glowColor, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); + float brightness = 1f; + float declareThisHereToPreventRunningTheSameCalculationMultipleTimes = Main.GameUpdateCount * 0.007f; + brightness *= (float)MathF.Sin(i / 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); + brightness *= (float)MathF.Sin(j / 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); + brightness *= (float)MathF.Sin(i * 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); + brightness *= (float)MathF.Sin(j * 18f + declareThisHereToPreventRunningTheSameCalculationMultipleTimes); + drawcolor *= brightness; + Color glowColor = drawcolor * 0.4f; + + // For now checking for glowing frames greatly reducing the bottleneck + // But maybe we could squeeze bit more by removing the loop + for (int k = 0; k < 3; k++) + { + Vector2 offset = new Vector2(Main.rand.NextFloat(-1f, 1f), Main.rand.NextFloat(-1f, 1f)) * 0.2f * k; + spriteBatch.Draw(GlowMask.Texture, pos + offset + new Vector2(-8 + xOff, -8), frame, glowColor, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); + } } } From 0d375067426e3aba4a3261ae2aaf36ef37b441d8 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Mon, 4 Nov 2024 15:57:27 -0500 Subject: [PATCH 211/401] Remnants compatibility for the old Sunken Sea. It will now be centered properly. --- Systems/WorldgenManagementSystem.cs | 6 ++---- World/SunkenSea.cs | 7 +++++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Systems/WorldgenManagementSystem.cs b/Systems/WorldgenManagementSystem.cs index 822a6dac34..74be220776 100644 --- a/Systems/WorldgenManagementSystem.cs +++ b/Systems/WorldgenManagementSystem.cs @@ -124,10 +124,8 @@ public override void ModifyWorldGenTasks(List tasks, ref double totalWe { progress.Message = Language.GetOrRegister("Mods.CalamityMod.UI.SunkenSea").Value; - int sunkenSeaX = GenVars.UndergroundDesertLocation.Left; - int sunkenSeaY = Main.maxTilesY - 400; - - SunkenSea.Place(new Point(sunkenSeaX, sunkenSeaY)); + Point ssBottomLeft = new Point(GenVars.UndergroundDesertLocation.Left, Main.maxTilesY - 400); + SunkenSea.Place(ssBottomLeft); })); } diff --git a/World/SunkenSea.cs b/World/SunkenSea.cs index 20e6d1b40c..720c18113f 100644 --- a/World/SunkenSea.cs +++ b/World/SunkenSea.cs @@ -739,6 +739,13 @@ public static bool Place(Point origin) // As far as I can tell, this just scales up the entire Sunken Sea to be 4x wider and 2x taller than what is listed above Vector2 arbitrary42GodVector = new Vector2(4f, 2f); + // 04NOV2024: Ozzatron: Remnants mutilates the Underground Desert beyond recognition. + // The above code assumes the size of the underground desert with arbitrary hardcoded values instead of checking it. + // To ensure the Sunken Sea is centered on an Underground Desert of any size, some adjustments are made. + // This would have been easy, but the arbitrary 4-2 God vector makes the math unnecessarily complicated. + int sunkenSeaRealWidth = (int)(sunkenSeaAreaX * arbitrary42GodVector.X); + origin.X = GenVars.UndergroundDesertLocation.Center.X - sunkenSeaRealWidth / 2; + // Place the majority of the terrain as clusters ClusterGroup clusterGroup = new ClusterGroup(); clusterGroup.Generate(sunkenSeaAreaX, sunkenSeaAreaY); From ee80a448ca7147232ae0c432a6fe71eee670ab95 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Mon, 2 Dec 2024 13:11:17 -0600 Subject: [PATCH 212/401] 1 - Removed Bird/Mr.Small references. 2 - Fixed Old Duke Remix Seed enrage. 3 - Renderer Manager render state edits. 4 - Fixed lava generating in the Sunken Sea and Abyss. 5 - Fixed Brimstone Slag walls generating in incorrect locations. 6 - Mechanic Shed no longer generates in space, hopefully. --- CalPlayer/CalamityPlayer.cs | 8 -- Graphics/Renderers/RendererManager.cs | 14 ++-- Items/Accessories/Vanity/Birds_Head.png | Bin 3064 -> 0 bytes .../Vanity/Birds_Head_Extension.png | Bin 480 -> 0 bytes Items/Accessories/Vanity/Birds_Legs.png | Bin 1967 -> 0 bytes Items/Accessories/Vanity/Birds_Torso.png | Bin 4083 -> 0 bytes Items/Accessories/Vanity/CocosFeather.cs | 69 ------------------ Items/Accessories/Vanity/CocosFeather.png | Bin 753 -> 0 bytes .../DevPaintings/ThankYouPainting.cs | 1 - NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs | 4 +- World/BrimstoneCrag.cs | 6 +- World/MechanicShed.cs | 2 +- World/SulphurousSea.cs | 3 +- 13 files changed, 15 insertions(+), 92 deletions(-) delete mode 100644 Items/Accessories/Vanity/Birds_Head.png delete mode 100644 Items/Accessories/Vanity/Birds_Head_Extension.png delete mode 100644 Items/Accessories/Vanity/Birds_Legs.png delete mode 100644 Items/Accessories/Vanity/Birds_Torso.png delete mode 100644 Items/Accessories/Vanity/CocosFeather.cs delete mode 100644 Items/Accessories/Vanity/CocosFeather.png diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 084a918902..98f60d0478 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -1151,7 +1151,6 @@ public GemTechArmorState GemTechState public bool omegaBlueTransformationForce; public bool omegaBlueTransformationPower; public bool redBow; - public bool cocosFeather; #endregion #region Calamitas Enchant Effects @@ -2191,7 +2190,6 @@ public override void ResetEffects() omegaBlueTransformation = omegaBlueTransformationForce = omegaBlueTransformationPower = false; redBow = false; - cocosFeather = false; rageModeActive = false; adrenalineModeActive = false; @@ -4222,12 +4220,6 @@ public override void FrameEffects() Player.body = EquipLoader.GetEquipSlot(Mod, "RedBow", EquipType.Body); Player.head = EquipLoader.GetEquipSlot(Mod, "RedBow", EquipType.Head); } - if (cocosFeather) - { - Player.legs = EquipLoader.GetEquipSlot(Mod, "CocosFeather", EquipType.Legs); - Player.body = EquipLoader.GetEquipSlot(Mod, "CocosFeather", EquipType.Body); - Player.head = EquipLoader.GetEquipSlot(Mod, "CocosFeather", EquipType.Head); - } if (snowRuffianSet) { Player.wings = EquipLoader.GetEquipSlot(Mod, "SnowRuffianMask", EquipType.Wings); diff --git a/Graphics/Renderers/RendererManager.cs b/Graphics/Renderers/RendererManager.cs index eac7f8ce96..1505780208 100644 --- a/Graphics/Renderers/RendererManager.cs +++ b/Graphics/Renderers/RendererManager.cs @@ -124,7 +124,7 @@ private void DrawNPCRenderers(On_Main.orig_DrawNPCs orig, Main self, bool behind var renderers = Renderers.Where(renderer => renderer.ShouldDraw && renderer.Layer is DrawLayer.NPC); Main.spriteBatch.End(); - Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, Main.Rasterizer); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, RasterizerState.CullCounterClockwise); foreach (var renderer in renderers) renderer.DrawTarget(Main.spriteBatch); @@ -138,7 +138,7 @@ private void DrawProjectileRenderers(On_Main.orig_DrawProjectiles orig, Main sel var renderers = Renderers.Where(renderer => renderer.ShouldDraw && renderer.Layer is DrawLayer.Projectile); - Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, Main.Rasterizer); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, RasterizerState.CullCounterClockwise); foreach (var renderer in renderers) renderer.DrawTarget(Main.spriteBatch); @@ -152,7 +152,7 @@ private void DrawPlayerRenderers(On_Main.orig_DrawPlayers_AfterProjectiles orig, var renderers = Renderers.Where(renderer => renderer.ShouldDraw && renderer.Layer is DrawLayer.Player); - Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, Main.Rasterizer); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, RasterizerState.CullCounterClockwise); foreach (var renderer in renderers) renderer.DrawTarget(Main.spriteBatch); @@ -165,13 +165,13 @@ private void DrawBeforeTileRenderers(On_Main.orig_DrawBackgroundBlackFill orig, var renderers = Renderers.Where(renderer => renderer.ShouldDraw && renderer.Layer is DrawLayer.BeforeTiles); Main.spriteBatch.End(); - Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, Main.Rasterizer); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, RasterizerState.CullCounterClockwise); foreach (var renderer in renderers) renderer.DrawTarget(Main.spriteBatch); Main.spriteBatch.End(); - Main.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, Main.Rasterizer, null, Main.Transform); + Main.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, RasterizerState.CullCounterClockwise, null, Main.Transform); orig(self); } @@ -181,12 +181,12 @@ private void DrawAfterEverythingRenderers(On_Main.orig_DrawInfernoRings orig, Ma var renderers = Renderers.Where(renderer => renderer.ShouldDraw && renderer.Layer is DrawLayer.AfterEverything); Main.spriteBatch.End(); - Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, Main.Rasterizer); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, RasterizerState.CullCounterClockwise); foreach (var renderer in renderers) renderer.DrawTarget(Main.spriteBatch); Main.spriteBatch.End(); - Main.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, Main.Rasterizer, null, Main.Transform); + Main.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, RasterizerState.CullCounterClockwise, null, Main.Transform); orig(self); } #endregion diff --git a/Items/Accessories/Vanity/Birds_Head.png b/Items/Accessories/Vanity/Birds_Head.png deleted file mode 100644 index e475326c77aed80c24d749cbf0b0679a61ebbce4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3064 zcmeI!>sJ$J9>DRaPy|Y=fVc`J-3l0R!K1;Alxw&LA`mE0E{gRsTs$z?fI=_^ViiF# zHGmodArLNF1a$%NLSXlRQaJ$ZQu_QmdtoXNcU&CK(8 zzB4&N0X_zLJM}Oai~-5lGZ;DIFc__)n?FMSai177ki!OQu#Y>YuG>tBoM^=o4-qk# z2Q2+}-)JM}y2-u~R1D^mHuSfl1H63#gVE0;c@n=$J2Exkr~rIEdp?tAmuB6ZIc)i? z-{i>kXa2i3fAQTTldv!1V%?%B_cs%@^!+zI2-$M#xbG>s_ST#STYhYbW z=i6UDoWZjg@utq!mN@ksL(S4$$WSjbT*hr$IBcrl_yTp2*P1RDNYgZXVg{c_vCb!( zs$AyU65;lRLg||8Qt28rC%wQMz2K@-$X~KqaQ-QLM&q*fBJtdOHYCg|yvJDDC0$bb zm`lBDhwZns>T|tvs!BCL{=0wdZn>Ygs)|nyuL-}#<@b0=is7}r6LO(SIB`#k!!l+L zNN>yOIy9xl(nCV)u`9oX>}8BCWGt32R%_QL%$=)4l~l_4**w)k%o{=J?M7M*O*hxD zm%FMi+uk%2-m1}@@reDa-AYQi1CO0QQhTiQN>PU2G-E0&@cv6SoW8u4JgBt+@rKda z5~!~bX^llq80SLdEk*??z?5!h0=wf-kQ0f9x9TRYnKbxysvK$f@`{FhF;{u~CHqvk z|L{wf=r?C+*PxGuoI0{Ne6NtRQOF5}fiQzTJ~_Qy&R13nD#d=cQk0^pt|m~c{!A<* z;N#QuY51G&Ai5ne$=bv58-yJGIsX!O30L>5o#kAz!B=quD!PgD{@_=NggsOyJs#&8rGKEG3oZkIc5A><^j z!7$KmZ-IjWD+7=Sjt475=x9uxo0Bb{U{nC!3Bl3uL~>9sr*Su~hGb44&R8f#w+`y8 zM2T$>mI~2jc5i??SjD3F*B!Ra3DG2{%9IW?JPbV9PmB@5fF5$s5^ltSyJnVtAP~%1 zU(O0b-&83N>f&6|x(Ibu4B09~(R#ui=;*(1yIide1I$_5R6Q@y>awoim-P!;Cl9@kikh1cIScBt zq2X&T6$(6+BC?GU{1{i1k6hVGUmw?@?|Z(O%dv0P7IOT{2%FH^k2cOUWJ2Vimdb!K zWYzZ(NwNJr{#~o|L9J)`6@=r%W-v&ssd(2SAnfwfLwfG)i$oMKz0@eJW27pk+to(ZTY(H zM*AK5qbDlZOt^!FKg{9ZJ3_;2BloNj-Q5{>&9IVyze5(w%i{uixypsWKyaMw!E^_K z-nS+&V0RJv7#(fq_U@@&Een-aCRT4oqyOE(ju|Hlcwg+OV*{$ zQ~2`_a{D{hrA1srGwmU=<=w$U&tcp+lr`A0u%?NB@!1FrG8b7sn|`%DZRc%(an} zSFe6ZdHM+?<*MuJDNnaRQ!WzxHsx{V5~qpvlsnmoog%&F;?`4+?4|c9AEzKGFY-ZC zUgU$OJUzwQo`v4_ADQxh>b3W6M06w4E|wFFP-zhv|CR<_MWt!iqSBzNs5BV(oiu_6 zShX$HQcrT5HN2Do5s5FHLl?HWHin-{wQl<`+XS(*$v+2aQ`+vUm QBl;jnUICtU?njyb0tpZDlK=n! diff --git a/Items/Accessories/Vanity/Birds_Head_Extension.png b/Items/Accessories/Vanity/Birds_Head_Extension.png deleted file mode 100644 index 99dd209e3ebdb36cc46714ae13fb1120176efd1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 480 zcmeAS@N?(olHy`uVBq!ia0vp^8Vn392^?%d*6dv(^+1ZTILO_JVcj{Imp~3nx}&cn z1H;CC?mvmFKt5-IM`SSr1K(i~W;~w1A_b_S)YHW=q$2L^t&O~g90Xh)otaf!c5wc3 zSfrR#rLdI4YY~GM!^us|Dng$HznwBZc~4dS?y>cXTV6fScwYATO@F@M_v6>|>o&c6 zp40p9?S`F)|J}H|{q4Hh&9C2HIvbx`^i7%tXfp`RXv$MtI-3!~VOZf|KKasFD2E|r z$!yP;X)vDFrL#*)jA1;{muW$}B%!>9t`cL-yF5^y0qa$Fudgs81193OV1vu4#Zx|U zK=mz9y6fX*&J5+@(-$02yCg&&s*nMXQy9FL*m!C7!&Kt&!h`>_p0S!wxl{S_SgROF Ny{D_6%Q~loCIBHlhqwR$ diff --git a/Items/Accessories/Vanity/Birds_Legs.png b/Items/Accessories/Vanity/Birds_Legs.png deleted file mode 100644 index 87cee935482c9b8abf3f5a4a87b0d21f52093e8c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1967 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 RC23;^SlOQ~v%Gr$zW}7O#$W&d diff --git a/Items/Accessories/Vanity/CocosFeather.cs b/Items/Accessories/Vanity/CocosFeather.cs deleted file mode 100644 index 4e55c0074d..0000000000 --- a/Items/Accessories/Vanity/CocosFeather.cs +++ /dev/null @@ -1,69 +0,0 @@ -using CalamityMod; -using CalamityMod.CalPlayer; -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.Audio; -using Terraria.DataStructures; -using Terraria.ID; -using Terraria.ModLoader; - - -namespace CalamityMod.Items.Accessories.Vanity -{ - public class CocosFeather : ModItem, IExtendedHat, ILocalizedModType - { - public new string LocalizationCategory => "Items.Accessories"; - public override void Load() - { - if (Main.netMode != NetmodeID.Server) - { - EquipLoader.AddEquipTexture(Mod, "CalamityMod/Items/Accessories/Vanity/Birds_Head", EquipType.Head, this); - EquipLoader.AddEquipTexture(Mod, "CalamityMod/Items/Accessories/Vanity/Birds_Torso", EquipType.Body, this); - EquipLoader.AddEquipTexture(Mod, "CalamityMod/Items/Accessories/Vanity/Birds_Legs", EquipType.Legs, this); - } - } - - public override void SetStaticDefaults() - { - - if (Main.netMode == NetmodeID.Server) - return; - - int equipSlotHead = EquipLoader.GetEquipSlot(Mod, Name, EquipType.Head); - ArmorIDs.Head.Sets.DrawHead[equipSlotHead] = false; - - int equipSlotBody = EquipLoader.GetEquipSlot(Mod, Name, EquipType.Body); - ArmorIDs.Body.Sets.HidesTopSkin[equipSlotBody] = true; - ArmorIDs.Body.Sets.HidesArms[equipSlotBody] = true; - - int equipSlotLegs = EquipLoader.GetEquipSlot(Mod, Name, EquipType.Legs); - ArmorIDs.Legs.Sets.HidesBottomSkin[equipSlotLegs] = true; - } - - public override void SetDefaults() - { - Item.width = 42; - Item.height = 38; - Item.accessory = true; - Item.value = CalamityGlobalItem.RarityGreenBuyPrice; - Item.rare = ItemRarityID.Green; - Item.vanity = true; - Item.Calamity().devItem = true; - } - - public override void UpdateVanity(Player player) - { - player.Calamity().cocosFeather = true; - } - - public override void UpdateAccessory(Player player, bool hideVisual) - { - if (!hideVisual) - { - player.Calamity().cocosFeather = true; - } - } - public string ExtensionTexture => "CalamityMod/Items/Accessories/Vanity/Birds_Head_Extension"; - public Vector2 ExtensionSpriteOffset(PlayerDrawSet drawInfo) => new Vector2(0, -4f); - } -} diff --git a/Items/Accessories/Vanity/CocosFeather.png b/Items/Accessories/Vanity/CocosFeather.png deleted file mode 100644 index 3b69e78dca56ec1513f96169b06cb411c97bb013..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 753 zcmVPx#1ZP1_K>z@;j|==^1poj7fk{L`R9Hvtm@#M*Q5?pTGsII{lO`2StwsbX8A?S& zP!Qb%I<$j>Aa1VW=-kbMTg63O96A-D*wINRMNx_ru^hE2YLgn8#5C2^<9qi(-k*EK zp~c>7f6Mn?a*&r_zW46hcx;C-KA1-4bElEs@|R5v0-PXsJpauo4U(go0pzzz2_|n9 z?_mCP<`Htws6-mSvNoX*Y&LEveTQix<=aK!#)ox!|Dj}CW5BYZWJ<@0Q8r6&unvuKt!>iZ9NQc+^ zrvldIp9+}UXH<5P9ZVlq9gH_s2j%XiIlj&=&b)h$3||8kNROCNn)*tf^8fV{WfepU@8S4nm{sAkRk{rFohp9p@#{x=HLY`fNxU z=u4(Gqw-F|u5nJJNqI-&FXE%E#U7*bxv@W~&dHTl1xDG$Zg&zj;A0KmKvo=xAy?Dx%LYtH-^;zfTrf=katH5Nb-Gp zAsB@tpMp%-XLO>F!+<7_6$UY1Y$uU4YT`mX0dr@Z1m==|HP($tbyPDs@$oZ~oY?Qe z*y4H<*WIqF@Af3sMxKm2cz?FkzB72-3LQ&>gw-l-x%_;lf-pbgU-DSP781I z53YZ_w1)Y15h53h%*G+_V$01jnX jNoGw=04e|g00;m8000000Mb*F00000NkvXXu0mjfgzsA~ diff --git a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs index 63db3bcde1..471616bbd8 100644 --- a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs +++ b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs @@ -84,7 +84,6 @@ public override void ModifyTooltips(List tooltips) "Mercutio 'Merkalto' Takle", "Mishiro Usui", "Moonburn", - "Mr.Small", "Nycro", "Ozzatron", "Piky", diff --git a/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs b/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs index 7383afb7d4..37b8928cc3 100644 --- a/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs +++ b/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs @@ -247,14 +247,14 @@ public static void VanillaOldDukeAI(NPC npc, Mod mod) // Enrage variable bool enrage = !bossRush && - (player.position.Y < 300f || player.position.Y > Main.worldSurface * 16.0 || + (player.position.Y < 300f || player.position.Y > Main.worldSurface * 16 || (player.position.X > 8000f && player.position.X < (Main.maxTilesX * 16 - 8000))); // Check for the flipped Abyss if (Main.remixWorld) { enrage = !bossRush && - (player.position.Y < Main.UnderworldLayer * 0.8f || player.position.Y > Main.UnderworldLayer || + (player.position.Y < Main.UnderworldLayer * 16 * 0.8f || player.position.Y > Main.UnderworldLayer * 16 || (player.position.X > 8000f && player.position.X < (Main.maxTilesX * 16 - 8000))); } diff --git a/World/BrimstoneCrag.cs b/World/BrimstoneCrag.cs index 10573d76b6..01f572f27c 100644 --- a/World/BrimstoneCrag.cs +++ b/World/BrimstoneCrag.cs @@ -57,7 +57,7 @@ private static void GenCrags() for (int y = Main.maxTilesY - 90; y <= Main.maxTilesY - 5; y++) { WorldGen.PlaceTile(x, y, (ushort)ModContent.TileType()); - Main.tile[x, y + 5].WallType = (ushort)ModContent.WallType(); + Main.tile[x, y].WallType = (ushort)ModContent.WallType(); } } @@ -311,8 +311,8 @@ private static void GenCrags() } } - //settle all liquids - CalamityUtils.SettleWater(); + //DISABLED. CAUSES LAVA TO GENERATE IN THE SUNKEN SEA + //CalamityUtils.SettleWater(); //spread grass on all scorched remains with no lava above them for (int x = biomeStart; x <= biomeEdge; x++) diff --git a/World/MechanicShed.cs b/World/MechanicShed.cs index 59db3bbe80..653edd2d18 100644 --- a/World/MechanicShed.cs +++ b/World/MechanicShed.cs @@ -18,7 +18,7 @@ public static void PlaceMechanicShed(StructureMap structures) var schematic = TileMaps[mapKey]; int placementPositionX = WorldGen.genRand.Next(GenVars.snowOriginLeft + 100, GenVars.snowOriginRight - 100); - int placementPositionY = (int)Main.worldSurface - (Main.maxTilesY / 6); + int placementPositionY = (int)Main.worldSurface - (Main.maxTilesY / 12); bool foundValidGround = false; int attempts = 0; diff --git a/World/SulphurousSea.cs b/World/SulphurousSea.cs index f020932486..e43ff0d4a9 100644 --- a/World/SulphurousSea.cs +++ b/World/SulphurousSea.cs @@ -1053,7 +1053,8 @@ public static void PlaceAmbience() public static void GenerateChests(List scrapPilePositions) { GenerateTreasureChest(); - CalamityUtils.SettleWater(); + // DISABLED. CAUSES LAVA TO FILL THE ENTIRETY OF LAYER 4 + //CalamityUtils.SettleWater(); GenerateOpenAirChestChest(); GenerateScrapPileChest(scrapPilePositions); GenerateDeepWaterChest(); From 96ac61473ceff882dd42badb7b53d2bc2e728d1a Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Sat, 7 Dec 2024 17:53:58 -0600 Subject: [PATCH 213/401] Rain stoppage. --- NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs | 2 +- NPCs/Cryogen/Cryogen.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs b/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs index 37b8928cc3..aab7218ebb 100644 --- a/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs +++ b/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs @@ -70,7 +70,7 @@ public static void VanillaOldDukeAI(NPC npc, Mod mod) if (CalamityConfig.Instance.BossesStopWeather) CalamityMod.StopRain(); - else if (!Main.raining) + else if (!Main.raining && !BossRushEvent.BossRushActive) CalamityUtils.StartRain(); // Adjust stats diff --git a/NPCs/Cryogen/Cryogen.cs b/NPCs/Cryogen/Cryogen.cs index b7e63f539d..59847a9191 100644 --- a/NPCs/Cryogen/Cryogen.cs +++ b/NPCs/Cryogen/Cryogen.cs @@ -265,7 +265,7 @@ public override void AI() if (CalamityConfig.Instance.BossesStopWeather) CalamityMod.StopRain(); - else if (!Main.raining) + else if (!Main.raining && !BossRushEvent.BossRushActive) CalamityUtils.StartRain(); if (!player.active || player.dead) From 8dcbe75ebcb64121ddfc846ecb4051a06b580674 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Tue, 11 Feb 2025 03:34:13 -0600 Subject: [PATCH 214/401] 1 - Removed Yharon plush promotional messages. 2 - Actually killed coco's feather. --- CalPlayer/CalamityPlayerMiscEffects.cs | 3 ++- CalPlayer/DrawLayers/HatExtensionLayer.cs | 3 --- Items/TreasureBags/MiscGrabBags/StarterBag.cs | 10 ---------- .../en-US/Mods.CalamityMod.Items.Accessories.hjson | 5 ----- NPCs/CalamityGlobalNPCLoot.cs | 1 - description_workshop.txt | 1 - 6 files changed, 2 insertions(+), 21 deletions(-) diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index a3ed869174..cbfb750504 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -4170,7 +4170,8 @@ private void HandleTextChatMessages() } // 31OCT2024: Fabsol: Plushie message always appears. - CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.GimmeSwagPlushieCampaign"); + // 11FEB2024: Fabsol: Currently commented out because the campaign has ended. + // CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.GimmeSwagPlushieCampaign"); } --startMessageDisplayDelay; diff --git a/CalPlayer/DrawLayers/HatExtensionLayer.cs b/CalPlayer/DrawLayers/HatExtensionLayer.cs index b2231f0f0a..7b512ea262 100644 --- a/CalPlayer/DrawLayers/HatExtensionLayer.cs +++ b/CalPlayer/DrawLayers/HatExtensionLayer.cs @@ -23,9 +23,6 @@ protected override void Draw(ref PlayerDrawSet drawInfo) if (drawPlayer.armor[10].type > ItemID.None) headItem = drawPlayer.armor[10]; - if (drawPlayer.Calamity().cocosFeather) - headItem = new Item(ModContent.ItemType()); - if (ModContent.GetModItem(headItem.type) is IExtendedHat extendedHatDrawer) { string equipSlotName = extendedHatDrawer.EquipSlotName(drawPlayer) != "" ? extendedHatDrawer.EquipSlotName(drawPlayer) : headItem.ModItem.Name; diff --git a/Items/TreasureBags/MiscGrabBags/StarterBag.cs b/Items/TreasureBags/MiscGrabBags/StarterBag.cs index 54fe68cbde..9423468e0d 100644 --- a/Items/TreasureBags/MiscGrabBags/StarterBag.cs +++ b/Items/TreasureBags/MiscGrabBags/StarterBag.cs @@ -110,16 +110,6 @@ static bool getsOracleHeadphones(DropAttemptInfo info) itemLoot.AddIf(getsOracleHeadphones, ModContent.ItemType()); - // Bird dev item - // Name specific: "bird" - static bool getsSakuraFeather(DropAttemptInfo info) - { - string playerName = info.player.name; - return playerName == "bird"; - } - - itemLoot.AddIf(getsSakuraFeather, ModContent.ItemType()); - // Fabsol dev item // Name specific: "Fabsol" or "Cirrus" static bool getsCrystalHeartVodka(DropAttemptInfo info) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson index 069adda0db..4fb5ea6055 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson @@ -2026,11 +2026,6 @@ CrystalHeartVodka: { Tooltip: "'Tastes like strawberry cream liqueur (and estrogen)'" } -CocosFeather: { - DisplayName: Coco's Feather - Tooltip: "" -} - HapuFruit: { DisplayName: Ha-pu Fruit Tooltip: "'A fruit that calms your nerves (may have unintended side effects)'" diff --git a/NPCs/CalamityGlobalNPCLoot.cs b/NPCs/CalamityGlobalNPCLoot.cs index 6b875b8cad..f7b300d209 100644 --- a/NPCs/CalamityGlobalNPCLoot.cs +++ b/NPCs/CalamityGlobalNPCLoot.cs @@ -107,7 +107,6 @@ bool ShouldDropMechLore(DropAttemptInfo info) // Sky Glaze @ 3.33% IF Eye of Cthulhu dead // Essence of Sunlight @ 50% IF Hardmode and not statue spawned case NPCID.Harpy: - npcLoot.Add(ModContent.ItemType(), 1000); postEoC.Add(ModContent.ItemType(), 30); hardmode.AddIf(() => !npc.SpawnedFromStatue, ModContent.ItemType(), 2); break; diff --git a/description_workshop.txt b/description_workshop.txt index 172d508e9c..5841686264 100644 --- a/description_workshop.txt +++ b/description_workshop.txt @@ -1,6 +1,5 @@ [h1]Calamity Mod[/h1] [url=https://discord.gg/calamity]Discord[/url] [url=https://calamitymod.wiki.gg]Official Wiki[/url] -[b]LIMITED TIME![/b] [url=https://calamitymod.com/plush]Gimme Swag Plushie Campaign[/url] The Calamity Mod is a vast content mod that creates a new and refreshing experience for Terraria! From 4adf1fd67fc6dbb7fdbd433bd0f7611e9146e2bc Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 27 Dec 2024 00:11:58 -0500 Subject: [PATCH 215/401] A ton of minor tooltip and localization fixes --- CalamityConditions.cs | 2 +- Items/CalamityGlobalItemTooltip.cs | 4 ++-- Localization/en-US/Mods.CalamityMod.Buffs.hjson | 2 +- Localization/en-US/Mods.CalamityMod.Condition.hjson | 2 +- .../Mods.CalamityMod.Items.Accessories.Wings.hjson | 2 +- .../en-US/Mods.CalamityMod.Items.Accessories.hjson | 2 +- Localization/en-US/Mods.CalamityMod.Items.Ammo.hjson | 2 +- .../Mods.CalamityMod.Items.Armor.PostMoonLord.hjson | 2 +- .../en-US/Mods.CalamityMod.Items.Potions.hjson | 2 +- .../en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson | 6 +++--- .../en-US/Mods.CalamityMod.Items.Weapons.Summon.hjson | 2 +- Localization/en-US/Mods.CalamityMod.NPCs.hjson | 10 +++------- .../en-US/Mods.CalamityMod.Vanilla.Armor.hjson | 3 +-- 13 files changed, 18 insertions(+), 23 deletions(-) diff --git a/CalamityConditions.cs b/CalamityConditions.cs index 8cce78968e..f6b9acdd2d 100644 --- a/CalamityConditions.cs +++ b/CalamityConditions.cs @@ -56,7 +56,7 @@ private static Condition Create(string key, Func predicate) public static readonly Condition DownedAquaticScourge = Create("Drops.DownedAS", () => DownedBossSystem.downedAquaticScourge); public static readonly Condition DownedBrimstoneElemental = Create("Drops.DownedBrim", () => DownedBossSystem.downedBrimstoneElemental); public static readonly Condition DownedCalamitasClone = Create("Drops.DownedCal", () => DownedBossSystem.downedCalamitasClone); - public static readonly Condition DownedLeviathan = Create("Drops.DownedLebi", () => DownedBossSystem.downedLeviathan); + public static readonly Condition DownedLeviathan = Create("Drops.DownedLevi", () => DownedBossSystem.downedLeviathan); public static readonly Condition DownedAstrumAureus = Create("Drops.DownedAureus", () => DownedBossSystem.downedAstrumAureus); public static readonly Condition DownedPlaguebringer = Create("Drops.DownedPBG", () => DownedBossSystem.downedPlaguebringer); public static readonly Condition DownedRavager = Create("Drops.DownedRav", () => DownedBossSystem.downedRavager); diff --git a/Items/CalamityGlobalItemTooltip.cs b/Items/CalamityGlobalItemTooltip.cs index 9830d5d689..aee8d4caa8 100644 --- a/Items/CalamityGlobalItemTooltip.cs +++ b/Items/CalamityGlobalItemTooltip.cs @@ -640,7 +640,7 @@ void AddTooltip(string text) // Fairy Boots buff. if (item.type == ItemID.FairyBoots) EditTooltipByNum(2, (line) => line.Text += "\nFairies can spawn at any time on the surface and spawn far more frequently\n" + - "Nearby fairies grant +2 HP/s life regen, 10 defense and 10% movement speed\n" + + "Nearby fairies grant +2 HP/s life regen, 10 defense and 10% movement speed\n" + "Fairies are immune to damage and will no longer flee"); // Reduced Nightwither and Holy Flames damage, and melee speed removal. @@ -836,7 +836,7 @@ void AddTooltip(string text) // Lead if (item.type == ItemID.LeadHelmet || item.type == ItemID.LeadChainmail || item.type == ItemID.LeadGreaves) - AddTooltip("Increases damage reduction by 3%"); + AddTooltip("Increases damage reduction by 2%"); // Silver if (item.type == ItemID.SilverHelmet) diff --git a/Localization/en-US/Mods.CalamityMod.Buffs.hjson b/Localization/en-US/Mods.CalamityMod.Buffs.hjson index e7843c0e46..0bc3610158 100644 --- a/Localization/en-US/Mods.CalamityMod.Buffs.hjson +++ b/Localization/en-US/Mods.CalamityMod.Buffs.hjson @@ -100,7 +100,7 @@ Trippy: { VodkaBuff: { DisplayName: Vodka - Description: Damage and critical stike chance increased, defense and life regen reduced + Description: Damage and critical strike chance increased, defense and life regen reduced } WhiskeyBuff: { diff --git a/Localization/en-US/Mods.CalamityMod.Condition.hjson b/Localization/en-US/Mods.CalamityMod.Condition.hjson index 844e15ed3e..58b2c1a7c1 100644 --- a/Localization/en-US/Mods.CalamityMod.Condition.hjson +++ b/Localization/en-US/Mods.CalamityMod.Condition.hjson @@ -68,7 +68,7 @@ InCrag: In the Brimstone Crags InSulph: In the Sulphurous Sea InSunken: In the Sunken Sea InRev: In Revengeance Mode -IsRevOrMM: In Revengeance Mode or in Master Mode +InRevOrMM: In Revengeance Mode or in Master Mode AlcoholPoison: While inflicted with Alcohol Poisoning PostCal: After defeating Calamitas Clone PostAureus: After defeating Astrum Aureus diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.Wings.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.Wings.hjson index 6cd23de2b8..30755075f9 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.Wings.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.Wings.hjson @@ -30,7 +30,7 @@ ElysianWings: { Acceleration multiplier: 2.7 Great vertical speed Flight time: 240 - Temporary immunity to lava and 10% increased movement speed + Immunity to lava and 10% increased movement speed Blessed by the Profaned Flame ''' } diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson index 4fb5ea6055..48763168e9 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson @@ -1199,7 +1199,7 @@ OldDukeScales: { 25% increased dash velocity and length Gives you a stamina indicator on the cooldown rack Using any dash will consume 20% of your stamina - Stamina will gradually recover to 100% after not dashing for 1 second + Stamina will gradually recover to 100% after not dashing for 1.5 seconds Stamina recovers faster when you are stationary If your stamina reaches 0%, you become exhausted [c/CE0E18:While exhausted, this item's damage reduction and movement bonuses are negated] diff --git a/Localization/en-US/Mods.CalamityMod.Items.Ammo.hjson b/Localization/en-US/Mods.CalamityMod.Items.Ammo.hjson index e582fd1bcc..ac9bfdfda0 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Ammo.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Ammo.hjson @@ -23,7 +23,7 @@ BloodfireBullet: { ''' Passes through tiles and accelerates your natural life regen on hit Deals bonus damage based on your current life regen and natural life regen - This damage caps at 25 + This damage caps at 35 ''' } diff --git a/Localization/en-US/Mods.CalamityMod.Items.Armor.PostMoonLord.hjson b/Localization/en-US/Mods.CalamityMod.Items.Armor.PostMoonLord.hjson index a0c60646cb..4e56fa86e4 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Armor.PostMoonLord.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Armor.PostMoonLord.hjson @@ -520,7 +520,7 @@ TarragonHeadMelee: { DisplayName: Tarragon Helm Tooltip: ''' - 12% increased melee damage and critical strike chance + 12% increased melee damage and 10% increased melee critical strike chance 10% increased damage reduction ''' SetBonus: diff --git a/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson b/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson index 94bfd6c74c..b1e1a9437e 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson @@ -191,7 +191,7 @@ CaribbeanRum: { DisplayName: Caribbean Rum Tooltip: ''' - Increases life regen by 1 HP/s, movement speed by 10% and wing flight time by 20% + Increases life regen by 1 HP/s, movement speed by 10% Makes you floaty and reduces defense by 10% Drinking more than 3 different alcohols might not end well with your liver [c/B00BA5:'Why is the rum gone?'] diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson index bc3c0004e7..900d659de4 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson @@ -1212,11 +1212,11 @@ TheDarkMaster: { DisplayName: The Dark Master Tooltip: ''' - Fires red echo slash projectiles at full health - Projectile damage increases for every point of HP above 400 + Fires red echo slash projectiles when above 75% health + Projectile damage increases for every HP above 400 Press to spawn three shadow clones in a Delta formation The clones will mirror your sword swings and release projectiles - The clones will always fire projectiles regardless of your own HP + Projectiles are fired regardless of your own HP, but deal less damage The clones may only exist while holding this weapon 'The blade by which the shadows levy their foes with a terrible fate' ''' diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Summon.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Summon.hjson index 2fa9a00315..429815916b 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Summon.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Summon.hjson @@ -90,7 +90,7 @@ BrittleStarStaff: { Summons a small brittle starfish that will dash through enemies until it shatters Starfish will quickly regenerate after shattering Holding right click will swap starfish between dashing and circling you - When the starfish are circling, each one provides you with 3 defense + When the starfish are circling, each one provides you with 5 defense ''' } diff --git a/Localization/en-US/Mods.CalamityMod.NPCs.hjson b/Localization/en-US/Mods.CalamityMod.NPCs.hjson index 42d943f37f..2e4ed16928 100644 --- a/Localization/en-US/Mods.CalamityMod.NPCs.hjson +++ b/Localization/en-US/Mods.CalamityMod.NPCs.hjson @@ -169,9 +169,9 @@ Frogfish.DisplayName: Frogfish Horse.DisplayName: Earth Elemental IceClasper.DisplayName: Ice Clasper ImpiousImmolator.DisplayName: Impious Immolator -KingSlimeJewel.DisplayName: Ruby Jewel -KingSlimeJewel2.DisplayName: Sapphire Jewel -KingSlimeJewel3.DisplayName: Emerald Jewel +KingSlimeJewelEmerald.DisplayName: Emerald Jewel +KingSlimeJewelRuby.DisplayName: Ruby Jewel +KingSlimeJewelSapphire.DisplayName: Sapphire Jewel LavaSlimeNoLavaDrop.DisplayName: Lava Slime MantisShrimp.DisplayName: Mantis Shrimp OverloadedSoldier.DisplayName: Overloaded Soldier @@ -623,7 +623,3 @@ WITCH: { Princess_LovesNPC: "{NPCName} is always lonely, it's why I want to hang out with her, no one should be left alone like that!" } } - -KingSlimeJewelEmerald.DisplayName: King Slime Jewel Emerald -KingSlimeJewelRuby.DisplayName: King Slime Jewel Ruby -KingSlimeJewelSapphire.DisplayName: King Slime Jewel Sapphire diff --git a/Localization/en-US/Mods.CalamityMod.Vanilla.Armor.hjson b/Localization/en-US/Mods.CalamityMod.Vanilla.Armor.hjson index 3e221f5442..348b3784fe 100644 --- a/Localization/en-US/Mods.CalamityMod.Vanilla.Armor.hjson +++ b/Localization/en-US/Mods.CalamityMod.Vanilla.Armor.hjson @@ -101,8 +101,7 @@ SetBonus: { ''' Obsidian: ''' - Increases whip range by 50% and speed by 35% - Increases minion damage by 15% + {$ArmorSetBonus.ObsidianOutlaw} Grants immunity to fire blocks and temporary immunity to lava ''' Palladium: From a8cbf253c775ebf54276d04fb3b9dc31a5f35f17 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <142704082+CongratsIsTrash@users.noreply.github.com> Date: Fri, 3 Jan 2025 17:31:36 -0500 Subject: [PATCH 216/401] 1 - Fixed Artemis and Apollo charge telegraphs not appearing 2 - Fixed the yoyo burst damage exploit 3 - Fixed Mining Potion and Hand of Creation tooltips 4 - Fixed Grax's tooltip 5 - Fixed Flame Waker Boots' heat debuff multiplier not applying on projectile hits --- CalPlayer/CalamityPlayerOnHit.cs | 1 + Items/CalamityGlobalItemTooltip.cs | 10 ++++++++-- Localization/en-US/Mods.CalamityMod.Items.Tools.hjson | 2 +- Projectiles/Boss/ApolloChargeTelegraph.cs | 9 ++++----- Projectiles/Boss/ArtemisChargeTelegraph.cs | 11 ++++++----- Projectiles/CalamityGlobalProjectile.cs | 9 +++++++++ 6 files changed, 29 insertions(+), 13 deletions(-) diff --git a/CalPlayer/CalamityPlayerOnHit.cs b/CalPlayer/CalamityPlayerOnHit.cs index 2464cd250f..397a03fef3 100644 --- a/CalPlayer/CalamityPlayerOnHit.cs +++ b/CalPlayer/CalamityPlayerOnHit.cs @@ -210,6 +210,7 @@ public override void OnHitAnything(float x, float y, Entity victim) cgn.IncreasedHeatEffects_Fireball = fireball; cgn.IncreasedHeatEffects_CinnamonRoll = cinnamonRoll; + cgn.IncreasedHeatEffects_FlameWakerBoots = flameWakerBoots; cgn.IncreasedHeatEffects_HellfireTreads = hellfireTreads; cgn.IncreasedSicknessEffects_ToxicHeart = toxicHeart; diff --git a/Items/CalamityGlobalItemTooltip.cs b/Items/CalamityGlobalItemTooltip.cs index aee8d4caa8..39f43104af 100644 --- a/Items/CalamityGlobalItemTooltip.cs +++ b/Items/CalamityGlobalItemTooltip.cs @@ -602,9 +602,15 @@ void AddTooltip(string text) // Rebalances to vanilla item stats #region Vanilla Item Rebalance Tooltips - // Ancient Chisel rebalance. + // Various mining speed nerfs + if (item.type == ItemID.MiningPotion) + EditTooltipByNum(0, (line) => line.Text = line.Text.Replace("25%", "15%")); + if (item.type == ItemID.AncientChisel) - EditTooltipByNum(0, (line) => line.Text = "Increases mining speed by 15%"); + EditTooltipByNum(0, (line) => line.Text = line.Text.Replace("25%", "15%")); + + if (item.type == ItemID.HandOfCreation) + EditTooltipByNum(0, (line) => line.Text = line.Text.Replace("25%", "15%")); // Frozen Turtle Shell rebalance. if (item.type == ItemID.FrozenTurtleShell) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Tools.hjson b/Localization/en-US/Mods.CalamityMod.Items.Tools.hjson index 7d1594a478..cde8da2380 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Tools.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Tools.hjson @@ -111,7 +111,7 @@ Grax: { DisplayName: Grax Tooltip: ''' - Hitting an enemy will greatly boost your defense, melee damage and melee crit for a short time + Hitting an enemy will greatly boost your melee damage, defense, and damage reduction for a short time Press to use without hammering down walls or chopping down trees ''' } diff --git a/Projectiles/Boss/ApolloChargeTelegraph.cs b/Projectiles/Boss/ApolloChargeTelegraph.cs index 66e6f36cc1..143df6a6d3 100644 --- a/Projectiles/Boss/ApolloChargeTelegraph.cs +++ b/Projectiles/Boss/ApolloChargeTelegraph.cs @@ -118,11 +118,10 @@ public override bool PreDraw(ref Color lightColor) for (int i = ChargePositions.Length - 2; i >= 0; i--) { - Vector2[] positions = new Vector2[2] - { - ChargePositions[i], - ChargePositions[i + 1] - }; + // This is effectively a 2-point trail that is extended as Toasty's new Primitive system appears to no longer support them. + Vector2[] positions = new Vector2[5]; + for (int p = 0; p < positions.Length; p++) + positions[p] = Vector2.Lerp(ChargePositions[i], ChargePositions[i + 1], p / (positions.Length - 1f)); // Stand-in variable used to differentiate between the beams. // It is not used anywhere else. diff --git a/Projectiles/Boss/ArtemisChargeTelegraph.cs b/Projectiles/Boss/ArtemisChargeTelegraph.cs index 5370ee45f7..8f6d6cdc66 100644 --- a/Projectiles/Boss/ArtemisChargeTelegraph.cs +++ b/Projectiles/Boss/ArtemisChargeTelegraph.cs @@ -91,11 +91,12 @@ public override bool PreDraw(ref Color lightColor) { GameShaders.Misc["CalamityMod:Flame"].UseImage1("Images/Misc/Perlin"); GameShaders.Misc["CalamityMod:Flame"].UseSaturation(0.28f); - Vector2[] drawPositions = new Vector2[] - { - Projectile.Center, - Projectile.Center + Projectile.velocity.SafeNormalize(Vector2.UnitY) * TelegraphWidth - }; + + // This is effectively a 2-point trail that is extended as Toasty's new Primitive system appears to no longer support them. + Vector2[] drawPositions = new Vector2[5]; + for (int i = 0; i < drawPositions.Length; i++) + drawPositions[i] = Projectile.Center + Projectile.velocity.SafeNormalize(Vector2.UnitY) * TelegraphWidth * i / (drawPositions.Length - 1f); + PrimitiveRenderer.RenderTrail(drawPositions, new(TelegraphPrimitiveWidth, TelegraphPrimitiveColor, (_) => Projectile.Size * 0.5f, shader: GameShaders.Misc["CalamityMod:Flame"]), 87); return false; } diff --git a/Projectiles/CalamityGlobalProjectile.cs b/Projectiles/CalamityGlobalProjectile.cs index 27d65eacbf..45d77f7a00 100644 --- a/Projectiles/CalamityGlobalProjectile.cs +++ b/Projectiles/CalamityGlobalProjectile.cs @@ -269,6 +269,15 @@ public override bool PreAI(Projectile projectile) projectile.damage = (int)projectile.ai[2]; } + // This code fixes the wacky close-up burst damage bug which occurs with double yoyos and local iframes. + // Oh my good friends, do not ask me how or why this works, for I do not know! + // That being said, PLEASE DON'T REMOVE THIS, unless you think The Microwave killing Provi in 2 seconds with no effort is okay. + if (projectile.aiStyle == ProjAIStyleID.Yoyo) + { + if (projectile.ai[0] == -1) + projectile.Kill(); + } + // Chlorophyte Crystal AI rework. if (projectile.type == ProjectileID.CrystalLeaf) return ChlorophyteCrystalAI.DoChlorophyteCrystalAI(projectile); From 113dcece349814e4af80f868840cca8a5bdb500c Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <142704082+CongratsIsTrash@users.noreply.github.com> Date: Mon, 6 Jan 2025 11:21:18 -0500 Subject: [PATCH 217/401] Removed "Markie" Arms Dealer name --- NPCs/CalamityGlobalTownNPC.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/NPCs/CalamityGlobalTownNPC.cs b/NPCs/CalamityGlobalTownNPC.cs index abf91440b3..c0944a024f 100644 --- a/NPCs/CalamityGlobalTownNPC.cs +++ b/NPCs/CalamityGlobalTownNPC.cs @@ -77,7 +77,6 @@ public static float TaxYieldFactor "XiaoEn0426", // <@!440448864772816896> (xiaoen0426) "Jeffred", // <@!295362230038560768> (paladinsamuel) "The Cooler Arthur", // <@!568263512523014154> (gokuartillery) - "Markie", // <@!291141964039061504> (markie_) "Shark", // <@!874464051697172492> (congratsistrash) "Sagi", // <@!508233115781693441> (sagittariod) }; From 4cac806c321f38381bc514ce9b58ca07d9769101 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <142704082+CongratsIsTrash@users.noreply.github.com> Date: Thu, 30 Jan 2025 20:17:12 -0500 Subject: [PATCH 218/401] 1 - Fixed Craw Carapace line thorns damage being able to hit invincible enemies 2 - Fixed Altars not dropping items properly in multiplayer 3 - Fixed walls which spawn water desyncing in multiplayer 4 - Fixed Arid Artifact, Cosmolight, Martian Distress Remote, and Torrential Tear not working properly in multiplayer 5 - Fixed Caustic Tear status message and Draedon end monologue appearing multiple times per player in multiplayer 6 - Fixed Bandit refunding not working in multiplayer 7 - Fixed null reference exceptions with particle system in multiplayer 8 - Fixed Plantera Thorn Ball tile collision desyncing in multiplayer 9 - Fixed Spine Trees not dropping in multiplayer 10 - Fixed all Calamity wiring-activated mechanisms not working in multiplayer --- CalPlayer/CalamityPlayerHitHurt.cs | 21 +++++--- CalamityNetcode.cs | 39 +++++++++++++- Items/CalamityGlobalItem.cs | 12 ++++- Items/SummonItems/Invasion/CausticTear.cs | 9 ++-- .../Invasion/MartianDistressRemote.cs | 27 +++++++++- Items/Tools/ClimateChange/AridArtifact.cs | 8 +-- Items/Tools/ClimateChange/Cosmolight.cs | 9 ++-- Items/Tools/ClimateChange/TorrentialTear.cs | 8 ++- NPCs/ExoMechs/Draedon.cs | 4 +- NPCs/TownNPCs/THIEF.cs | 52 +++++++++++++----- .../Bosses/PlanteraAI.cs | 10 ++-- Particles/GeneralParticleHandler.cs | 17 +++++- Projectiles/CalamityGlobalProjectile.cs | 3 +- Tiles/CalamityGlobalTile.cs | 53 +++++++++++++------ Tiles/Crags/Tree/SpineTree.cs | 5 ++ Utilities/MiscUtils.cs | 21 ++++++-- Utilities/TileUtils.cs | 3 ++ Walls/AbyssGravelWall.cs | 2 +- Walls/EutrophicSandWall.cs | 2 +- Walls/PyreMantleWall.cs | 2 +- Walls/VoidstoneWallUnsafe.cs | 2 +- 21 files changed, 242 insertions(+), 67 deletions(-) diff --git a/CalPlayer/CalamityPlayerHitHurt.cs b/CalPlayer/CalamityPlayerHitHurt.cs index aca930da03..47ade64d1f 100644 --- a/CalPlayer/CalamityPlayerHitHurt.cs +++ b/CalPlayer/CalamityPlayerHitHurt.cs @@ -1190,8 +1190,11 @@ public override void OnHitByNPC(NPC npc, Player.HurtInfo hurtInfo) if (crawCarapace) { npc.AddBuff(ModContent.BuffType(), 900); - int onHitDamage = Player.CalcIntDamage(40); - Player.ApplyDamageToNPC(npc, onHitDamage, 0f, 0, false); + if (!npc.dontTakeDamage) + { + int onHitDamage = Player.CalcIntDamage(40); + Player.ApplyDamageToNPC(npc, onHitDamage, 0f, 0, false); + } SoundEngine.PlaySound(SoundID.NPCHit33 with { Volume = 0.5f }, Player.Center); } @@ -1199,8 +1202,11 @@ public override void OnHitByNPC(NPC npc, Player.HurtInfo hurtInfo) { npc.AddBuff(ModContent.BuffType(), 900); npc.AddBuff(ModContent.BuffType(), 900); - int onHitDamage = Player.CalcIntDamage(250); - Player.ApplyDamageToNPC(npc, onHitDamage, 0f, 0, false); + if (!npc.dontTakeDamage) + { + int onHitDamage = Player.CalcIntDamage(250); + Player.ApplyDamageToNPC(npc, onHitDamage, 0f, 0, false); + } SoundEngine.PlaySound(BaroclawHit, Player.Center); Vector2 bloodSpawnPosition = Player.Center + Main.rand.NextVector2Circular(Player.width, Player.height) * 0.04f; Vector2 splatterDirection = (Player.Center - bloodSpawnPosition).SafeNormalize(Vector2.UnitY); @@ -1220,8 +1226,11 @@ public override void OnHitByNPC(NPC npc, Player.HurtInfo hurtInfo) if (absorber) { npc.AddBuff(ModContent.BuffType(), 900); - int onHitDamage = Player.CalcIntDamage(350); - Player.ApplyDamageToNPC(npc, onHitDamage, 0f, 0, false); + if (!npc.dontTakeDamage) + { + int onHitDamage = Player.CalcIntDamage(350); + Player.ApplyDamageToNPC(npc, onHitDamage, 0f, 0, false); + } SoundEngine.PlaySound(AbsorberHit, Player.Center); Vector2 bloodSpawnPosition = Player.Center + Main.rand.NextVector2Circular(Player.width, Player.height) * 0.04f; Vector2 splatterDirection = (Player.Center - bloodSpawnPosition).SafeNormalize(Vector2.UnitY); diff --git a/CalamityNetcode.cs b/CalamityNetcode.cs index 1ddc123fe0..2bf1c92e21 100644 --- a/CalamityNetcode.cs +++ b/CalamityNetcode.cs @@ -335,6 +335,39 @@ public static void HandlePacket(Mod mod, BinaryReader reader, int whoAmI) MusicEventSystem.ReceiveSyncResponse(reader); break; + // + // Bandit refund syncs + // + case CalamityModMessageType.SomeoneGotScammedByTinkerer: + int scammedOne = reader.ReadByte(); + int stolen = reader.Read7BitEncodedInt(); + CalamityWorld.MoneyStolenByBandit += stolen; + CalamityWorld.Reforges++; + // Broadcast back for tragic event + // WorldSync DO sync the MoneyStolenByBandit and Refores variable, But spamming SyncWorld is not a ideal action + if (Main.dedServ) + { + ModPacket packet = CalamityMod.Instance.GetPacket(); + packet.Write((byte)CalamityModMessageType.SomeoneGotScammedByTinkerer); + packet.Write((byte)scammedOne); + packet.Write7BitEncodedInt(stolen); + packet.Send(ignoreClient: scammedOne); + } + break; + case CalamityModMessageType.WantToRefundReforges: + int requester = reader.ReadByte(); + // Only Server should handle this action! + if (!Main.dedServ) + break; + int banditIdx = NPC.FindFirstNPC(ModContent.NPCType()); + if (banditIdx == -1) + break; + NPC bandit = Main.npc[banditIdx]; + if (bandit == null || !bandit.active) + break; + THIEF.DoRefund(bandit); + break; + // // Default case: with no idea how long the packet is, we can't safely read data. // Throw an exception now instead of allowing the network stream to corrupt. @@ -461,6 +494,10 @@ public enum CalamityModMessageType : byte // Music events MusicEventSyncRequest, - MusicEventSyncResponse + MusicEventSyncResponse, + + // Bandit Reforge Refund + SomeoneGotScammedByTinkerer, + WantToRefundReforges } } diff --git a/Items/CalamityGlobalItem.cs b/Items/CalamityGlobalItem.cs index 077b34fc84..12531fede4 100644 --- a/Items/CalamityGlobalItem.cs +++ b/Items/CalamityGlobalItem.cs @@ -1808,11 +1808,21 @@ public override void PostReforge(Item item) ItemLoader.ReforgePrice(item, ref value, ref p.discountAvailable); // Steal 20% of that money. - CalamityWorld.MoneyStolenByBandit += value / 5; + int stolen = value / 5; + CalamityWorld.MoneyStolenByBandit += stolen; // Increment the reforge counter to allow the Bandit to refund // Also triggers Tinkerer dialogue that hints to the player that money is being stolen CalamityWorld.Reforges++; + + if (Main.netMode == NetmodeID.MultiplayerClient) + { + ModPacket packet = CalamityMod.Instance.GetPacket(); + packet.Write((byte)CalamityModMessageType.SomeoneGotScammedByTinkerer); + packet.Write((byte)p.whoAmI); + packet.Write7BitEncodedInt(stolen); + packet.Send(); + } } } #endregion diff --git a/Items/SummonItems/Invasion/CausticTear.cs b/Items/SummonItems/Invasion/CausticTear.cs index 2de57c9d47..b21039e6d5 100644 --- a/Items/SummonItems/Invasion/CausticTear.cs +++ b/Items/SummonItems/Invasion/CausticTear.cs @@ -38,9 +38,12 @@ public override bool CanUseItem(Player player) public override bool? UseItem(Player player) { - CalamityNetcode.SyncWorld(); - AcidRainEvent.TryStartEvent(true); - return true; + // Only Single Player client and Server should call this! + if (Main.netMode != NetmodeID.MultiplayerClient) + { + AcidRainEvent.TryStartEvent(forceRain: true); + // TryStartEvent already syncs the world data + } } public override void AddRecipes() diff --git a/Items/SummonItems/Invasion/MartianDistressRemote.cs b/Items/SummonItems/Invasion/MartianDistressRemote.cs index 965b1b0ff3..8b92c70260 100644 --- a/Items/SummonItems/Invasion/MartianDistressRemote.cs +++ b/Items/SummonItems/Invasion/MartianDistressRemote.cs @@ -35,11 +35,34 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite itemGroup = ContentSamples.CreativeHelper.ItemGroup.EventItem; } - public override bool CanUseItem(Player player) => Main.invasionType == InvasionID.None; + public override bool CanUseItem(Player player) + { + // Do not start new invasion when it's already on going + if (Main.invasionType != InvasionID.None) + return false; + // This is the requirement for StartInvasion for some reason + // If this part is missing MartianRemote will show DD2 invasion GUI without any enemy spawn on MP + if (!Main.player.Any(p => p.active && p.ConsumedLifeCrystals >= 5)) + return false; + return true; + } public override bool? UseItem(Player player) { - Main.StartInvasion(InvasionID.MartianMadness); + // Single Player case + if (Main.netMode == NetmodeID.SinglePlayer) + { + Main.invasionDelay = 0; + Main.StartInvasion(InvasionID.MartianMadness); + return true; + } + // MP case: only owner should send Spawn Message to Master + if (player.whoAmI == Main.myPlayer) + { + //-7.0 is hardcoded id for MartianMadness Event + NetMessage.SendData(MessageID.SpawnBossUseLicenseStartEvent, number: player.whoAmI, number2: -7.0f); + return true; + } return true; } diff --git a/Items/Tools/ClimateChange/AridArtifact.cs b/Items/Tools/ClimateChange/AridArtifact.cs index 759f43754d..2568b27f94 100644 --- a/Items/Tools/ClimateChange/AridArtifact.cs +++ b/Items/Tools/ClimateChange/AridArtifact.cs @@ -1,6 +1,7 @@ using Terraria; using Terraria.ID; using Terraria.ModLoader; +using SandstormEvent = Terraria.GameContent.Events.Sandstorm; namespace CalamityMod.Items.Tools.ClimateChange { public class AridArtifact : ModItem, ILocalizedModType @@ -27,14 +28,15 @@ public override bool CanUseItem(Player player) return DownedBossSystem.downedDesertScourge || Main.hardMode; } - // this is extremely ugly and has to be fully qualified because we add an item called Sandstorm public override bool? UseItem(Player player) { - if (Terraria.GameContent.Events.Sandstorm.Happening) + // Only SinglePlayer and Server need to sync those parameters + if (Main.netMode == NetmodeID.MultiplayerClient) + return true; + if (SandstormEvent.Happening) CalamityUtils.StopSandstorm(); else CalamityUtils.StartSandstorm(); - return true; } public override void AddRecipes() diff --git a/Items/Tools/ClimateChange/Cosmolight.cs b/Items/Tools/ClimateChange/Cosmolight.cs index 70705a1e1a..b380c4f384 100644 --- a/Items/Tools/ClimateChange/Cosmolight.cs +++ b/Items/Tools/ClimateChange/Cosmolight.cs @@ -32,10 +32,13 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite itemGroup = (ContentSamples.CreativeHelper.ItemGroup)CalamityResearchSorting.ToolsOther; } - public override bool CanUseItem(Player player) + public override bool CanUseItem(Player player) => !CalamityPlayer.areThereAnyDamnBosses; + + public override bool? UseItem(Player player) { - if (CalamityPlayer.areThereAnyDamnBosses) - return false; + //Only SinglePlayer or DedServ should change time to prevent unwanted race condition + if (Main.netMode == NetmodeID.MultiplayerClient) + return true; // Early Morning -> Noon if (Main.dayTime && Main.time < NoonCutoff) diff --git a/Items/Tools/ClimateChange/TorrentialTear.cs b/Items/Tools/ClimateChange/TorrentialTear.cs index fca095ca74..8f440f913b 100644 --- a/Items/Tools/ClimateChange/TorrentialTear.cs +++ b/Items/Tools/ClimateChange/TorrentialTear.cs @@ -31,13 +31,17 @@ public override bool CanUseItem(Player player) public override bool? UseItem(Player player) { + // Only SinglePlayer and Server need to sync those parameters + if (Main.netMode == NetmodeID.MultiplayerClient) + return true; + if (!Main.raining) { - CalamityUtils.StartRain(true); + CalamityUtils.StartRain(torrentialTear: true, worldSync: true); } else { - Main.raining = false; + CalamityUtils.StopRain(clearWeather: false, worldSync: true); } CalamityNetcode.SyncWorld(); diff --git a/NPCs/ExoMechs/Draedon.cs b/NPCs/ExoMechs/Draedon.cs index 8aaf2a126c..d0b90f2ba2 100644 --- a/NPCs/ExoMechs/Draedon.cs +++ b/NPCs/ExoMechs/Draedon.cs @@ -688,7 +688,7 @@ public void HandleDefeatStuff() ShouldStartStandingUp = true; // Different text if Exo Mechdusa - if (exoMechdusa) + if (exoMechdusa && Main.netMode != NetmodeID.MultiplayerClient) { if (DefeatTimer == DelayBeforeDefeatStandup + 50f) CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Status.Boss.DraedonMechdusaEndText1", TextColor); @@ -697,7 +697,7 @@ public void HandleDefeatStuff() CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Status.Boss.DraedonMechdusaEndText2", TextColor); } // Otherwise do normal text - else + else if (Main.netMode != NetmodeID.MultiplayerClient) { if (DefeatTimer == DelayBeforeDefeatStandup + 50f) CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Status.Boss.DraedonEndText1", TextColor); diff --git a/NPCs/TownNPCs/THIEF.cs b/NPCs/TownNPCs/THIEF.cs index ff591a3aea..94b5f94198 100644 --- a/NPCs/TownNPCs/THIEF.cs +++ b/NPCs/TownNPCs/THIEF.cs @@ -10,6 +10,7 @@ using ReLogic.Content; using Terraria; using Terraria.Audio; +using Terraria.DataStructures; using Terraria.GameContent; using Terraria.GameContent.Bestiary; using Terraria.GameContent.Events; @@ -217,20 +218,25 @@ public string Refund() int goblinIndex = NPC.FindFirstNPC(NPCID.GoblinTinkerer); if (goblinIndex != -1 && CalamityWorld.Reforges >= 1) { - CalamityWorld.Reforges = 0; - int[] coinCounts = Utils.CoinsSplit(CalamityWorld.MoneyStolenByBandit); - if (coinCounts[0] > 0) - Item.NewItem(NPC.GetSource_Loot(), NPC.Hitbox, ItemID.CopperCoin, coinCounts[0]); - if (coinCounts[1] > 0) - Item.NewItem(NPC.GetSource_Loot(), NPC.Hitbox, ItemID.SilverCoin, coinCounts[1]); - if (coinCounts[2] > 0) - Item.NewItem(NPC.GetSource_Loot(), NPC.Hitbox, ItemID.GoldCoin, coinCounts[2]); - if (coinCounts[3] > 0) - Item.NewItem(NPC.GetSource_Loot(), NPC.Hitbox, ItemID.PlatinumCoin, coinCounts[3]); - - CalamityWorld.MoneyStolenByBandit = 0; + if (Main.netMode == NetmodeID.SinglePlayer) + { + DoRefund(bandit: NPC); + } + else if (Main.netMode == NetmodeID.MultiplayerClient) + { + // Possible Bug here: Minor text bug when two players send request this simultaneously + // Which result to both player to have successful message but only one request got accepted on server + // But since this is how base gamecode works theres no way to fix this clean way (Unless someone implement net queued response for NPC dialog) + // And as this does not duplicate the coin amount, It's not that bad I think...? + // + // Other way possible is to having bandit stolen inventory per player + // But I didn't wanted to change system too much + ModPacket packet = CalamityMod.Instance.GetPacket(); + packet.Write((byte)CalamityModMessageType.WantToRefundReforges); + packet.Write((byte)Main.myPlayer); + packet.Send(); + } SoundEngine.PlaySound(SoundID.Coins); // Money dink sound - CalamityNetcode.SyncWorld(); switch (Main.rand.Next(2)) { case 0: @@ -242,6 +248,26 @@ public string Refund() return this.GetLocalizedValue("NoRefund"); } + public static void DoRefund(NPC bandit) + { + if (bandit == null) + return; + if (CalamityWorld.Reforges <= 0) + return; + int[] coinCounts = Utils.CoinsSplit(CalamityWorld.MoneyStolenByBandit); + if (coinCounts[0] > 0) + Item.NewItem(new EntitySource_Gift(bandit), bandit.Hitbox, ItemID.CopperCoin, coinCounts[0]); + if (coinCounts[1] > 0) + Item.NewItem(new EntitySource_Gift(bandit), bandit.Hitbox, ItemID.SilverCoin, coinCounts[1]); + if (coinCounts[2] > 0) + Item.NewItem(new EntitySource_Gift(bandit), bandit.Hitbox, ItemID.GoldCoin, coinCounts[2]); + if (coinCounts[3] > 0) + Item.NewItem(new EntitySource_Gift(bandit), bandit.Hitbox, ItemID.PlatinumCoin, coinCounts[3]); + CalamityWorld.MoneyStolenByBandit = 0; + CalamityWorld.Reforges = 0; + CalamityNetcode.SyncWorld(); + } + public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color drawColor) { if (Main.LocalPlayer.Calamity().trippy) diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/PlanteraAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/PlanteraAI.cs index 04d87dc3be..2a732316e9 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/PlanteraAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/PlanteraAI.cs @@ -235,9 +235,8 @@ public static bool BuffedPlanteraAI(NPC npc, Mod mod) if (Main.netMode != NetmodeID.MultiplayerClient) { - int proj = Projectile.NewProjectile(npc.GetSource_FromAI(), adjustProjectileShootLocation ? npc.Center : spawnOffset, projectileVelocity * projectileSpeed, projectileType, damage, 0f, Main.myPlayer); - if (projectileType == ProjectileID.ThornBall && (Main.rand.NextBool() || !Main.zenithWorld)) - Main.projectile[proj].tileCollide = false; + float ai2 = projectileType == ProjectileID.ThornBall && (Main.rand.NextBool() || !Main.zenithWorld) ? 1f : 0f; + Projectile.NewProjectile(npc.GetSource_FromAI(), adjustProjectileShootLocation ? npc.Center : spawnOffset, projectileVelocity * projectileSpeed, projectileType, damage, 0f, Main.myPlayer, 0f, 0f, ai2); } } } @@ -800,9 +799,10 @@ public static bool BuffedPlanteraAI(NPC npc, Mod mod) if (Main.netMode != NetmodeID.MultiplayerClient) { - int proj = Projectile.NewProjectile(npc.GetSource_FromAI(), spawnOffset, projectileVelocity * projectileSpeed, type, damage, 0f, Main.myPlayer); + float ai2 = 0f; if (Main.rand.NextBool() || !Main.zenithWorld) - Main.projectile[proj].tileCollide = false; + ai2 = 1f; + Projectile.NewProjectile(npc.GetSource_FromAI(), spawnOffset, projectileVelocity * projectileSpeed, type, damage, 0f, Main.myPlayer, 0f, 0f, ai2); } } } diff --git a/Particles/GeneralParticleHandler.cs b/Particles/GeneralParticleHandler.cs index ddcc4ff9da..acc8ebd586 100644 --- a/Particles/GeneralParticleHandler.cs +++ b/Particles/GeneralParticleHandler.cs @@ -95,6 +95,9 @@ public static void SpawnParticle(Particle particle) public static void Update() { + if (Main.dedServ) + return; + foreach (Particle particle in particles) { if (particle == null) @@ -110,11 +113,17 @@ public static void Update() public static void RemoveParticle(Particle particle) { + if (Main.dedServ) + return; + particlesToKill.Add(particle); } public static void DrawAllParticles(SpriteBatch sb) { + if (Main.dedServ) + return; + if (particles.Count == 0) return; @@ -221,7 +230,13 @@ public static int FreeSpacesAvailable() /// /// Gives you the texture of the particle type. Useful for custom drawing /// - public static Texture2D GetTexture(int type) => particleTextures[type]; + public static Texture2D GetTexture(int type) + { + if (Main.dedServ) + return null; + + return particleTextures[type]; + } #pragma warning disable CS0414 private static string noteToEveryone = "This particle system was inspired by spirit mod's own particle system, with permission granted by Yuyutsu. Love you spirit mod! -Iban"; diff --git a/Projectiles/CalamityGlobalProjectile.cs b/Projectiles/CalamityGlobalProjectile.cs index 45d77f7a00..b80b8e3805 100644 --- a/Projectiles/CalamityGlobalProjectile.cs +++ b/Projectiles/CalamityGlobalProjectile.cs @@ -2648,8 +2648,9 @@ public override bool PreAI(Projectile projectile) return false; } - else if (projectile.type == ProjectileID.ThornBall && !projectile.tileCollide) + else if (projectile.type == ProjectileID.ThornBall && projectile.ai[2] != 0) { + projectile.tileCollide = false; if (projectile.alpha > 0) { projectile.alpha -= 30; diff --git a/Tiles/CalamityGlobalTile.cs b/Tiles/CalamityGlobalTile.cs index bccfbf26c0..13fd8f4d53 100644 --- a/Tiles/CalamityGlobalTile.cs +++ b/Tiles/CalamityGlobalTile.cs @@ -395,25 +395,44 @@ void CheckShatterCrystal(int xPos, int yPos, bool dontShatter) public override void Drop(int i, int j, int type)/* tModPorter Suggestion: Use CanDrop to decide if items can drop, use this method to drop additional items. See documentation. */ { - Tile tileAtPosition = CalamityUtils.ParanoidTileRetrieval(i, j); - if (tileAtPosition.TileFrameX % 36 == 0 && tileAtPosition.TileFrameY % 36 == 0) + // Handle for Demon Altar Drops + // Drop: + // - Soul of Night (x4) (Only if Early Hardmode Progression Rework is on) + // - Evil Smasher (x1) (Every 12th altar) + if (type == TileID.DemonAltar && Main.hardMode) { - if (type == TileID.DemonAltar && Main.hardMode) + Vector2 spreadMinMax = new Vector2(-32.0f, 32.0f); + // Drop 4 Soul of Night + if (CalamityConfig.Instance.EarlyHardmodeProgressionRework) { - Vector2 pos = new Vector2(i, j) * 16; - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework) - { - WorldGen.altarCount++; - int quantity = 4; - for (int k = 0; k < quantity; k += 1) - { - pos.X += Main.rand.NextFloat(-32f, 32f); - pos.Y += Main.rand.NextFloat(-32f, 32f); - Item.NewItem(new EntitySource_TileBreak(i, j), pos, ItemID.SoulofNight); - } - } - if (WorldGen.altarCount % 12 == 0 && WorldGen.altarCount > 1) - Item.NewItem(new EntitySource_TileBreak(i, j), pos, ModContent.ItemType()); + DropItem(i, j, ItemID.SoulofNight, quantity: 4, asStack: false, spreadMinMax); + WorldGen.altarCount++; // altarCount does not update automatically if ProgressionRework is enabled! + } + // Drop Evil Smasher on every 12 alter smashed + if (WorldGen.altarCount > 1 && WorldGen.altarCount % 12 == 0) + { + DropItem(i, j, ModContent.ItemType(), quantity: 1, asStack: true); + } + } + } + + private static void DropItem(int i, int j, int itemType, int quantity, bool asStack, Vector2 spreadMinMax = default) + { + // Multiplayer Client should not spawn item themselves + if (Main.netMode == NetmodeID.MultiplayerClient) + return; + Vector2 worldPos = new Vector2(i, j) * 16.0f; + if (asStack) + { + Vector2 spawnOffset = Main.rand.NextVector2Unit(spreadMinMax.X, spreadMinMax.Y); + Item.NewItem(new EntitySource_TileBreak(i, j), worldPos + spawnOffset, itemType, Stack: quantity); + } + else + { + for (int k = 0; k < quantity; k += 1) + { + Vector2 spawnOffset = Main.rand.NextVector2Unit(spreadMinMax.X, spreadMinMax.Y); + Item.NewItem(new EntitySource_TileBreak(i, j), worldPos + spawnOffset, itemType, Stack: 1); } } } diff --git a/Tiles/Crags/Tree/SpineTree.cs b/Tiles/Crags/Tree/SpineTree.cs index a5ab31f444..fd1eb980f4 100644 --- a/Tiles/Crags/Tree/SpineTree.cs +++ b/Tiles/Crags/Tree/SpineTree.cs @@ -153,7 +153,12 @@ public override void NearbyEffects(int i, int j, bool closer) if (!Framing.GetTileSafely(i, j + 1).HasTile) { WorldGen.KillTile(i, j, false, false, false); + if (Main.netMode == NetmodeID.MultiplayerClient) + { + NetMessage.SendData(MessageID.TileManipulation, -1, -1, null, 0, i, j); + } } + } diff --git a/Utilities/MiscUtils.cs b/Utilities/MiscUtils.cs index 3654c3679a..1695877872 100644 --- a/Utilities/MiscUtils.cs +++ b/Utilities/MiscUtils.cs @@ -195,7 +195,7 @@ public static void SafeVolumeChange(ref SoundEffectInstance sfx, float volumeMul sfx.Volume = MathHelper.Clamp(sfx.Volume * volumeMultiplier, 0f, 1f); } - public static void StartRain(bool torrentialTear = false, bool maxSeverity = false) + public static void StartRain(bool torrentialTear = false, bool maxSeverity = false, bool worldSync = true) { int framesInDay = 86400; int framesInHour = framesInDay / 24; @@ -245,7 +245,19 @@ public static void StartRain(bool torrentialTear = false, bool maxSeverity = fal Main.raining = true; if (torrentialTear) TorrentialTear.AdjustRainSeverity(maxSeverity); - CalamityNetcode.SyncWorld(); + if (worldSync) + CalamityNetcode.SyncWorld(); + } + + public static void StopRain(bool clearWeather = false, bool worldSync = true) + { + if (clearWeather) + Main.StopRain(); + else + Main.raining = false; + + if (worldSync) + CalamityNetcode.SyncWorld(); } public static void StartSandstorm() @@ -277,7 +289,10 @@ public static void StartSandstorm() public static void StopSandstorm() { - Terraria.GameContent.Events.Sandstorm.Happening = false; + if (Main.netMode != NetmodeID.MultiplayerClient) + { + Terraria.GameContent.Events.Sandstorm.Happening = false; + } } public static void AddWithCondition(this List list, T type, bool condition) diff --git a/Utilities/TileUtils.cs b/Utilities/TileUtils.cs index 5b6b1e6d5b..3c387d7961 100644 --- a/Utilities/TileUtils.cs +++ b/Utilities/TileUtils.cs @@ -103,6 +103,9 @@ public static void LightHitWire(int type, int i, int j, int tileX, int tileY) Wiring.SkipWire(x + k, y + l); } } + + if (Main.netMode != NetmodeID.SinglePlayer) + NetMessage.SendTileSquare(-1, x, y, tileX, tileY); } public static void DrawFlameEffect(Texture2D flameTexture, int i, int j, int offsetX = 0, int offsetY = 0) diff --git a/Walls/AbyssGravelWall.cs b/Walls/AbyssGravelWall.cs index 6f1e832c06..44e781e3a0 100644 --- a/Walls/AbyssGravelWall.cs +++ b/Walls/AbyssGravelWall.cs @@ -20,7 +20,7 @@ public override void RandomUpdate(int i, int j) Main.tile[i, j].Get().LiquidType = LiquidID.Water; Main.tile[i, j].LiquidAmount = byte.MaxValue; WorldGen.SquareTileFrame(i, j); - if (Main.netMode == NetmodeID.MultiplayerClient) + if (Main.dedServ) NetMessage.sendWater(i, j); } } diff --git a/Walls/EutrophicSandWall.cs b/Walls/EutrophicSandWall.cs index b00ae2284b..d6b6bb71c2 100644 --- a/Walls/EutrophicSandWall.cs +++ b/Walls/EutrophicSandWall.cs @@ -20,7 +20,7 @@ public override void RandomUpdate(int i, int j) Main.tile[i, j].Get().LiquidType = LiquidID.Water; Main.tile[i, j].LiquidAmount = byte.MaxValue; WorldGen.SquareTileFrame(i, j); - if (Main.netMode == NetmodeID.MultiplayerClient) + if (Main.dedServ) NetMessage.sendWater(i, j); } } diff --git a/Walls/PyreMantleWall.cs b/Walls/PyreMantleWall.cs index 69621281e9..6ee73138b7 100644 --- a/Walls/PyreMantleWall.cs +++ b/Walls/PyreMantleWall.cs @@ -20,7 +20,7 @@ public override void RandomUpdate(int i, int j) Main.tile[i, j].Get().LiquidType = LiquidID.Water; Main.tile[i, j].LiquidAmount = byte.MaxValue; WorldGen.SquareTileFrame(i, j); - if (Main.netMode == NetmodeID.MultiplayerClient) + if (Main.dedServ) NetMessage.sendWater(i, j); } } diff --git a/Walls/VoidstoneWallUnsafe.cs b/Walls/VoidstoneWallUnsafe.cs index 0f0b24ea66..25b966c127 100644 --- a/Walls/VoidstoneWallUnsafe.cs +++ b/Walls/VoidstoneWallUnsafe.cs @@ -30,7 +30,7 @@ public override void RandomUpdate(int i, int j) Main.tile[i, j].Get().LiquidType = LiquidID.Water; Main.tile[i, j].LiquidAmount = byte.MaxValue; WorldGen.SquareTileFrame(i, j); - if (Main.netMode == NetmodeID.MultiplayerClient) + if (Main.dedServ) NetMessage.sendWater(i, j); } } From 6c32d52106c5d809401be81e7e8db64b23199129 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <142704082+CongratsIsTrash@users.noreply.github.com> Date: Fri, 31 Jan 2025 13:01:05 -0500 Subject: [PATCH 219/401] Final stuff from me: Secret seed things 1 - Celebrationmk10 is now forced to spawn on the Jungle-side Ocean to prevent spawning in the Sulphurous Sea 2 - Moved Calamity final worldgen adjustments to happen before final secret seed adjustments and Dirtiest Block gen (also fixes Forsaken Archive not being painted in secret seeds) 3 - Gravity Normalizer now negates the low gravity of Remix surface 4 - Fixed Aerialite not spawning in Remix 5 - Fixed Cloud Elemental not spawning in Remix 6 - Fixed Armored Digger GFB drops appearing in the bestiary 7 - Fixed Jungle Temple not generating on the surface in Remix 8 - Fixed Mimic and Ice Mimic loot pools in Remix 9 - Fixed Sandstorm's Core broken localization in GFB --- CalPlayer/CalamityPlayerMiscEffects.cs | 2 +- Items/SummonItems/SandstormsCore.cs | 2 +- NPCs/CalamityGlobalNPCLoot.cs | 66 +++++++++++++++++++++----- NPCs/NormalNPCs/ArmoredDiggerHead.cs | 4 +- NPCs/NormalNPCs/ThiccWaifu.cs | 2 +- Systems/WorldgenManagementSystem.cs | 28 ++++++++++- Utilities/PlayerUtils.cs | 4 +- World/AerialiteOreGen.cs | 6 +-- World/CustomTemple.cs | 26 ++++++++-- 9 files changed, 112 insertions(+), 28 deletions(-) diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index cbfb750504..695a0c7005 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -2512,7 +2512,7 @@ private void OtherBuffEffects() if (gravityNormalizer) { Player.buffImmune[BuffID.VortexDebuff] = true; - if (Player.InSpace()) + if (Player.ReducedSpaceGravity()) { Player.gravity = Player.defaultGravity; if (Player.wet) diff --git a/Items/SummonItems/SandstormsCore.cs b/Items/SummonItems/SandstormsCore.cs index 32dba4f830..63d2f7ab20 100644 --- a/Items/SummonItems/SandstormsCore.cs +++ b/Items/SummonItems/SandstormsCore.cs @@ -50,7 +50,7 @@ public override bool CanUseItem(Player player) return true; } - public override void ModifyTooltips(List list) => list.FindAndReplace("[BIOME]", Main.zenithWorld ? CalamityUtils.GetTextValue("Biomes.AstralDesert") : Language.GetTextValue("Bestiary_Biomes.Desert")); + public override void ModifyTooltips(List list) => list.FindAndReplace("[BIOME]", Main.zenithWorld ? CalamityUtils.GetTextValue("Biomes.AstralDesert.TownNPCDialogueName") : Language.GetTextValue("Bestiary_Biomes.Desert")); public override void AddRecipes() { diff --git a/NPCs/CalamityGlobalNPCLoot.cs b/NPCs/CalamityGlobalNPCLoot.cs index f7b300d209..8bfcaf8734 100644 --- a/NPCs/CalamityGlobalNPCLoot.cs +++ b/NPCs/CalamityGlobalNPCLoot.cs @@ -161,19 +161,42 @@ bool ShouldDropMechLore(DropAttemptInfo info) return false; }); - int[] mimicItems = new int[] - { + // Yes, Mimics have three separate loot tables which we must reintegrate + int[] normalMimicItems = + [ ItemID.MagicDagger, ItemID.CrossNecklace, ItemID.PhilosophersStone, ItemID.StarCloak, ItemID.TitanGlove, ItemID.DualHook - }; + ]; + int[] remixPreHardMimicItems = + [ + ItemID.BandofRegeneration, + ItemID.MagicMirror, + ItemID.CloudinaBottle, + ItemID.HermesBoots, + ItemID.ShoeSpikes, + ItemID.Mace + ]; + int[] remixHardmodeMimicItems = + [ + ItemID.WandofSparking, + ItemID.CrossNecklace, + ItemID.PhilosophersStone, + ItemID.StarCloak, + ItemID.TitanGlove, + ItemID.DualHook + ]; // Mimics will not drop any items if spawned from statues. - var notStatue = npcLoot.DefineConditionalDropSet(new Conditions.NotFromStatue()); - notStatue.Add(DropHelper.CalamityStyle(DropHelper.NormalWeaponDropRateFraction, mimicItems)); + var notRemix = npcLoot.DefineConditionalDropSet(DropHelper.If(() => !(npc.SpawnedFromStatue || Main.remixWorld))); + var remixPreHM = npcLoot.DefineConditionalDropSet(DropHelper.If(() => !npc.SpawnedFromStatue && Main.remixWorld && !Main.hardMode)); + var remixHardmode = npcLoot.DefineConditionalDropSet(DropHelper.If(() => !npc.SpawnedFromStatue && Main.remixWorld && Main.hardMode)); + notRemix.Add(DropHelper.CalamityStyle(DropHelper.NormalWeaponDropRateFraction, normalMimicItems)); + remixPreHM.Add(DropHelper.CalamityStyle(DropHelper.NormalWeaponDropRateFraction, remixPreHardMimicItems)); + remixHardmode.Add(DropHelper.CalamityStyle(DropHelper.NormalWeaponDropRateFraction, remixHardmodeMimicItems)); } catch (ArgumentNullException) { } break; @@ -224,17 +247,38 @@ bool ShouldDropMechLore(DropAttemptInfo info) return false; }); - int[] iceMimicItems = new int[] - { + // Yes, Ice Mimics have three separate loot tables which me must reintegrate + int[] normalIceMimicItems = + [ ItemID.Frostbrand, ItemID.IceBow, ItemID.FlowerofFrost - }; + ]; + int[] remixPreHardIceMimicItems = + [ + ItemID.IceBoomerang, + ItemID.IceBlade, + ItemID.IceBow, + ItemID.IceSkates, + ItemID.BlizzardinaBottle, + ItemID.FlurryBoots + ]; + int[] remixHardmodeIceMimicItems = + [ + ItemID.Frostbrand, + ItemID.SnowballCannon, + ItemID.FlowerofFrost + ]; // Ice Mimics will not drop any items if spawned from statues. - var notStatue = npcLoot.DefineConditionalDropSet(new Conditions.NotFromStatue()); - notStatue.Add(DropHelper.CalamityStyle(DropHelper.NormalWeaponDropRateFraction, iceMimicItems)); - notStatue.Add(ItemID.ToySled, 20, 1, 1); + var notRemix = npcLoot.DefineConditionalDropSet(DropHelper.If(() => !(npc.SpawnedFromStatue || Main.remixWorld))); + var remixPreHM = npcLoot.DefineConditionalDropSet(DropHelper.If(() => !npc.SpawnedFromStatue && Main.remixWorld && !Main.hardMode)); + var remixHardmode = npcLoot.DefineConditionalDropSet(DropHelper.If(() => !npc.SpawnedFromStatue && Main.remixWorld && Main.hardMode)); + notRemix.Add(DropHelper.CalamityStyle(DropHelper.NormalWeaponDropRateFraction, normalIceMimicItems)); + remixPreHM.Add(DropHelper.CalamityStyle(DropHelper.NormalWeaponDropRateFraction, remixPreHardIceMimicItems)); + remixHardmode.Add(DropHelper.CalamityStyle(DropHelper.NormalWeaponDropRateFraction, remixHardmodeIceMimicItems)); + // Independent from all of the Remix madness, Ice Mimics have a 5% chance to drop Toy Sled. + npcLoot.DefineConditionalDropSet(new Conditions.NotFromStatue()).Add(ItemID.ToySled, 20); } catch (ArgumentNullException) { } break; diff --git a/NPCs/NormalNPCs/ArmoredDiggerHead.cs b/NPCs/NormalNPCs/ArmoredDiggerHead.cs index 70fc0433aa..2d46af55bd 100644 --- a/NPCs/NormalNPCs/ArmoredDiggerHead.cs +++ b/NPCs/NormalNPCs/ArmoredDiggerHead.cs @@ -475,8 +475,8 @@ public override void ModifyNPCLoot(NPCLoot npcLoot) npcLoot.Add(ModContent.ItemType(), 1, 2, 4); npcLoot.Add(ModContent.ItemType(), 1, 4, 8); npcLoot.Add(ModContent.ItemType(), 1, 4, 8); - npcLoot.AddIf(() => Main.zenithWorld, ModContent.ItemType(), 1, 3, 6); - npcLoot.AddIf(() => Main.zenithWorld, ModContent.ItemType(), 10); + npcLoot.AddIf(() => Main.zenithWorld, ModContent.ItemType(), 1, 3, 6, ui: false); + npcLoot.AddIf(() => Main.zenithWorld, ModContent.ItemType(), 10, ui: false); } public override void ModifyTypeName(ref string typeName) diff --git a/NPCs/NormalNPCs/ThiccWaifu.cs b/NPCs/NormalNPCs/ThiccWaifu.cs index f0c7452571..79fe0ad633 100644 --- a/NPCs/NormalNPCs/ThiccWaifu.cs +++ b/NPCs/NormalNPCs/ThiccWaifu.cs @@ -451,7 +451,7 @@ public override void FindFrame(int frameHeight) public override float SpawnChance(NPCSpawnInfo spawnInfo) { - if (spawnInfo.PlayerSafe || !Main.hardMode || !Main.raining || !spawnInfo.Player.ZoneSkyHeight) + if (spawnInfo.PlayerSafe || !Main.hardMode || (!Main.raining && !Main.remixWorld) || !spawnInfo.Player.ZoneSkyHeight) return 0f; // Keep this as a separate if check, because it's a loop and we don't want to be checking it constantly. diff --git a/Systems/WorldgenManagementSystem.cs b/Systems/WorldgenManagementSystem.cs index 74be220776..49ad227e92 100644 --- a/Systems/WorldgenManagementSystem.cs +++ b/Systems/WorldgenManagementSystem.cs @@ -94,6 +94,30 @@ public override void ModifyWorldGenTasks(List tasks, ref double totalWe })); } + // Move spawn point in Celebrationmk10 to not be in the Sulphurous Sea + int spawnPointIndex = tasks.FindIndex(genpass => genpass.Name.Equals("Spawn Point")); + if (spawnPointIndex != -1 && WorldGen.tenthAnniversaryWorldGen && !WorldGen.getGoodWorldGen) + { + tasks.Insert(spawnPointIndex + 1, new PassLegacy("Fix Tenth Anniversary Spawn", (progress, config) => + { + if ((Main.spawnTileX < Main.maxTilesX / 2 && GenVars.dungeonSide == -1) || (Main.spawnTileX > Main.maxTilesX / 2 && GenVars.dungeonSide == 1)) + { + // Flip the side of the world you spawn on if it's the Dungeon side + Main.spawnTileX = Main.maxTilesX - Main.spawnTileX; + // Then fix the Y position of the spawn point + for (int i = 0; i < Main.maxTilesY; i++) + { + if (Main.tile[Main.spawnTileX, i].HasTile) + { + Main.spawnTileY = i; + break; + } + } + } + + })); + } + // Mechanic Shed int mechanicIndex = tasks.FindIndex(genpass => genpass.Name.Equals("Sunflowers")); if (mechanicIndex != -1) @@ -129,12 +153,12 @@ public override void ModifyWorldGenTasks(List tasks, ref double totalWe })); } - // All further tasks occur after vanilla worldgen is completed + // All further tasks occur right before vanilla worldgen is completed (which includes The Dirtiest Block and final secret seed adjustments) int FinalIndex = tasks.FindIndex(genpass => genpass.Name.Equals("Final Cleanup")); if (FinalIndex != -1) { // Reallocate gems so rarity corresponds to depth - int currentFinalIndex = FinalIndex; + int currentFinalIndex = FinalIndex - 1; tasks.Insert(++currentFinalIndex, new PassLegacy("Gem Depth Adjustment", (progress, config) => { progress.Message = Language.GetOrRegister("Mods.CalamityMod.UI.GemAdjustment").Value; diff --git a/Utilities/PlayerUtils.cs b/Utilities/PlayerUtils.cs index faf8ed2d66..cdead115fc 100644 --- a/Utilities/PlayerUtils.cs +++ b/Utilities/PlayerUtils.cs @@ -327,11 +327,11 @@ public static bool CheckSolidGround(this Player player, int solidGroundAhead = 0 #region Location and Biomes public static bool IsUnderwater(this Player player) => Collision.DrownCollision(player.position, player.width, player.height, player.gravDir); - public static bool InSpace(this Player player) + public static bool ReducedSpaceGravity(this Player player) { float x = Main.maxTilesX / 4200f; x *= x; - float spaceGravityMult = (float)((player.position.Y / 16f - (60f + 10f * x)) / (Main.worldSurface / 6.0)); + float spaceGravityMult = (float)((player.position.Y / 16f - (60f + 10f * x)) / (Main.worldSurface / (Main.remixWorld ? 1.0 : 6.0))); return spaceGravityMult < 1f; } diff --git a/World/AerialiteOreGen.cs b/World/AerialiteOreGen.cs index 497e2d6017..0df55e7229 100644 --- a/World/AerialiteOreGen.cs +++ b/World/AerialiteOreGen.cs @@ -30,11 +30,11 @@ public static void Generate() Tile tile = Main.tile[x, y]; // The following conditions must happen in order for aerialite to generate: - // 1. The original tile ID must be that of a cloud. + // 1. The original tile ID must be that of a Cloud, Lesion Block, or Flesh Block. // 2. The original tile must not be empty air. // 3. A random dice-roll must land correctly, to ensure that patches of ore are occasional. // If any of these conditions are not met, this loop iteration is skipped. - if (tile.TileType != TileID.Cloud || !tile.HasTile || !WorldGen.genRand.NextBool(CloudOreConversionChance)) + if (!(tile.TileType == TileID.Cloud || tile.TileType == TileID.LesionBlock || tile.TileType == TileID.FleshBlock) || !tile.HasTile || !WorldGen.genRand.NextBool(CloudOreConversionChance)) continue; int radius = (int)(WorldGen.genRand.Next(3, 5) * WorldGen.genRand.NextFloat(0.74f, 0.82f)); @@ -51,7 +51,7 @@ public static void Generate() WorldUtils.Gen(new Point(x, y), new ModShapes.All(biggerCircle), Actions.Chain(new GenAction[] { new Actions.ClearTile(), - new Actions.PlaceTile((ushort)TileID.Cloud) + new Actions.PlaceTile(tile.TileType) })); // Circle of ore. diff --git a/World/CustomTemple.cs b/World/CustomTemple.cs index 007f9721cc..1ffd63a2b0 100644 --- a/World/CustomTemple.cs +++ b/World/CustomTemple.cs @@ -26,18 +26,34 @@ public static void NewJungleTemple() int y = WorldGen.genRand.Next((int)Main.rockLayer, Main.maxTilesY - 500); - if (Main.tile[x, y].HasTile && Main.tile[x, y].TileType == 60) + if (Main.remixWorld) { - Rectangle ugDesert = GenVars.UndergroundDesertLocation; - Rectangle InflatedSunkenSeaLocation = new Rectangle(ugDesert.Left - 160, ugDesert.Center.Y - 160, ugDesert.Width + 320, ugDesert.Height / 2 + 320); - Rectangle TempleLocation = new Rectangle(x - 80, y - 80, 160, 160); + while (Main.tile[x, y].HasTile || Main.tile[x, y].WallType > 0 || y > (int)(Main.worldSurface - 5.0)) + { + y--; + } - if (!TempleLocation.Intersects(InflatedSunkenSeaLocation)) + y++; + if (Main.tile[x, y].HasTile && (Main.tile[x, y].TileType == TileID.JungleGrass || Main.tile[x, y].TileType == TileID.Mud)) { success = true; GenNewTemple(x, y); } } + else + { + if (Main.tile[x, y].HasTile && Main.tile[x, y].TileType == TileID.JungleGrass) + { + Rectangle ugDesert = GenVars.UndergroundDesertLocation; + Rectangle InflatedSunkenSeaLocation = new Rectangle(ugDesert.Left - 160, ugDesert.Center.Y - 160, ugDesert.Width + 320, ugDesert.Height / 2 + 320); + Rectangle TempleLocation = new Rectangle(x - 80, y - 80, 160, 160); + if (!TempleLocation.Intersects(InflatedSunkenSeaLocation)) + { + success = true; + GenNewTemple(x, y); + } + } + } } } From c848023a8624de913594c221c30c97a3c30f5c30 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <142704082+CongratsIsTrash@users.noreply.github.com> Date: Mon, 10 Feb 2025 18:29:57 -0500 Subject: [PATCH 220/401] Fixed Amalgam making buff duration flicker when using infinite buff features --- CalPlayer/CalamityPlayerMiscEffects.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index 695a0c7005..402ff921f3 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -3616,7 +3616,9 @@ private void OtherBuffEffects() if (amalgam) { // Every other frame, increase the buff timer by one frame. Thus, the buff lasts twice as long. - if (Player.miscCounter % 2 == 0) + // CIT 1NOV2024: Amalgam does not add to the buff time if it's at 2 or lower, + // to prevent buff duration showing when using infinite buff features from other mods. + if (Player.miscCounter % 2 == 0 && Player.buffTime[l] > 2) Player.buffTime[l] += 1; // Buffs will not go away when you die, to prevent wasting potions. From decce451ea1c1edcf02a867e1a83e7bf6e80cc15 Mon Sep 17 00:00:00 2001 From: mountaindrew10 Date: Tue, 11 Feb 2025 03:36:36 -0600 Subject: [PATCH 221/401] Version bump. --- build.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.txt b/build.txt index d398b44e3d..b2de9aca5b 100644 --- a/build.txt +++ b/build.txt @@ -1,5 +1,5 @@ author = Fabsol and the Dev Team -version = 2.0.4.005 +version = 2.0.4.006 displayName = Calamity Mod modReferences = CalamityModMusic homepage = https://discord.gg/calamity From 972e6deccd3fc77fa2a3f54c80ed08b695b7bc04 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Tue, 11 Feb 2025 13:28:49 -0500 Subject: [PATCH 222/401] Final compile error fixes --- Items/SummonItems/Invasion/CausticTear.cs | 1 + Items/SummonItems/Invasion/MartianDistressRemote.cs | 1 + Items/Tools/ClimateChange/AridArtifact.cs | 1 + 3 files changed, 3 insertions(+) diff --git a/Items/SummonItems/Invasion/CausticTear.cs b/Items/SummonItems/Invasion/CausticTear.cs index b21039e6d5..6f76b9d06b 100644 --- a/Items/SummonItems/Invasion/CausticTear.cs +++ b/Items/SummonItems/Invasion/CausticTear.cs @@ -44,6 +44,7 @@ public override bool CanUseItem(Player player) AcidRainEvent.TryStartEvent(forceRain: true); // TryStartEvent already syncs the world data } + return true; } public override void AddRecipes() diff --git a/Items/SummonItems/Invasion/MartianDistressRemote.cs b/Items/SummonItems/Invasion/MartianDistressRemote.cs index 8b92c70260..24a34211be 100644 --- a/Items/SummonItems/Invasion/MartianDistressRemote.cs +++ b/Items/SummonItems/Invasion/MartianDistressRemote.cs @@ -1,5 +1,6 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using System.Linq; using Terraria; using Terraria.ID; using Terraria.ModLoader; diff --git a/Items/Tools/ClimateChange/AridArtifact.cs b/Items/Tools/ClimateChange/AridArtifact.cs index 2568b27f94..678ca85d32 100644 --- a/Items/Tools/ClimateChange/AridArtifact.cs +++ b/Items/Tools/ClimateChange/AridArtifact.cs @@ -37,6 +37,7 @@ public override bool CanUseItem(Player player) CalamityUtils.StopSandstorm(); else CalamityUtils.StartSandstorm(); + return true; } public override void AddRecipes() From 0fbf36f5130149fd0d563569d64c0a1d7ebb99a6 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Tue, 11 Feb 2025 15:39:35 -0500 Subject: [PATCH 223/401] Minor description updates mirrored from dev branch --- description.txt | 5 +++-- description_workshop.txt | 6 +++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/description.txt b/description.txt index e72ac9e99c..e3ebef4e0b 100644 --- a/description.txt +++ b/description.txt @@ -15,10 +15,11 @@ A more detailed breakdown of the content available in Calamity: - 200+ pieces of furniture - 11 ores - 2 full difficulty settings above Expert, separate from Master +- Significant improvements and changes to Master difficulty - 50+ changes to vanilla mechanics - 30+ new recipes for vanilla items - 450+ tweaks and improvements to vanilla items -- Cross-mod support for the Thorium Mod +- Minor cross-mod support for the Thorium Mod PLEASE NOTE THAT THIS MOD REQUIRES THE CALAMITY MUSIC MOD. -You will need to install "Calamity Mod Music" from the Mod Browser or the Workshop. +You will need to install "Calamity Mod Music" from the Mod Browser or the Steam Workshop. diff --git a/description_workshop.txt b/description_workshop.txt index 5841686264..f267cc2d72 100644 --- a/description_workshop.txt +++ b/description_workshop.txt @@ -16,6 +16,9 @@ The mod additionally tweaks tons of vanilla features whilst adding new ones to a [i]Please note that this mod [b]REQUIRES[/b] Calamity's soundtrack! You will need to download the music mod to be able to play![/i] https://steamcommunity.com/sharedfiles/filedetails/?id=2824688266 +[i]For even more Calamity music, subscribe to Vanilla Calamity Mod Music![/i] +https://steamcommunity.com/sharedfiles/filedetails/?id=2816188633 + [b]Be sure to join our Discord server linked above to keep up with the latest news about upcoming updates and features.[/b] [hr] @@ -34,8 +37,9 @@ A more detailed breakdown of the content available in Calamity: [*] 200+ pieces of furniture [*] 11 ores [*] 2 full difficulty settings above Expert, separate from Master +[*] Significant improvements and changes to Master difficulty [*] 50+ changes to vanilla mechanics [*] 30+ new recipes for vanilla items [*] 450+ tweaks and improvements to vanilla items -[*] Cross-mod support for the Thorium Mod +[*] Minor cross-mod support for the Thorium Mod [/olist] \ No newline at end of file From c7c6b5e483c40cbb7fe1a3963bbac3a89119573f Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Mon, 26 May 2025 15:09:06 -0400 Subject: [PATCH 224/401] Add csproj file to interim branch --- .gitignore | 1 - CalamityMod.csproj | 13 +++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 CalamityMod.csproj diff --git a/.gitignore b/.gitignore index ceb666fef0..8301251690 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ cronpull.sh ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. -*.csproj *.sln # User-specific files diff --git a/CalamityMod.csproj b/CalamityMod.csproj new file mode 100644 index 0000000000..06a7b9a67d --- /dev/null +++ b/CalamityMod.csproj @@ -0,0 +1,13 @@ + + + + + CalamityMod + net8.0 + AnyCPU + latest + + + + + From 695b6388626d4816f947e8b22f0202fd0bc65ff6 Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Mon, 26 May 2025 12:30:15 -0700 Subject: [PATCH 225/401] Removed Cirrus 22 files changed --- CalPlayer/CalamityPlayer.cs | 4 - Items/Mounts/AlicornMount.cs | 37 - .../en-US/Mods.CalamityMod.Bestiary.hjson | 1 - .../en-US/Mods.CalamityMod.NPCs.hjson | 98 -- .../en-US/Mods.CalamityMod.Vanilla.hjson | 10 - NPCs/AstrumAureus/AstrumAureus.cs | 2 - NPCs/CalamityGlobalNPCLoot.cs | 10 +- NPCs/CalamityGlobalTownNPC.cs | 41 +- NPCs/SupremeCalamitas/SupremeCalamitas.cs | 4 +- NPCs/SupremeCalamitas/SupremeCirrus.png | Bin 9076 -> 5589 bytes NPCs/TownNPCs/FAP.cs | 963 ------------------ NPCs/TownNPCs/FAP.png | Bin 9661 -> 0 bytes NPCs/TownNPCs/FAPAlt.png | Bin 8732 -> 0 bytes NPCs/TownNPCs/FAPShimmered_Head.png | Bin 624 -> 0 bytes NPCs/TownNPCs/FAP_Head.png | Bin 632 -> 0 bytes NPCs/TownNPCs/FAP_Shimmered.png | Bin 11137 -> 0 bytes NPCs/TownNPCs/SEAHOE.cs | 4 - NPCs/TownNPCs/THIEF.cs | 5 - NPCs/TownNPCs/WITCH.cs | 4 - Systems/MiscWorldStateSystem.cs | 7 +- Tiles/Furniture/CraftingStations/SCalAltar.cs | 2 +- World/CalamityWorld.cs | 1 - 22 files changed, 18 insertions(+), 1175 deletions(-) delete mode 100644 NPCs/TownNPCs/FAP.cs delete mode 100644 NPCs/TownNPCs/FAP.png delete mode 100644 NPCs/TownNPCs/FAPAlt.png delete mode 100644 NPCs/TownNPCs/FAPShimmered_Head.png delete mode 100644 NPCs/TownNPCs/FAP_Head.png delete mode 100644 NPCs/TownNPCs/FAP_Shimmered.png diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 98f60d0478..df2c555a04 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -170,7 +170,6 @@ public partial class CalamityPlayer : ModPlayer public bool newPrincessInventory = false; public bool newSkeletonMerchantInventory = false; public bool newPermafrostInventory = false; - public bool newCirrusInventory = false; public bool newAmidiasInventory = false; public bool newBanditInventory = false; public bool newCalamitasInventory = false; @@ -1290,7 +1289,6 @@ public override void Initialize() newPrincessInventory = false; newSkeletonMerchantInventory = false; newPermafrostInventory = false; - newCirrusInventory = false; newAmidiasInventory = false; newBanditInventory = false; newCalamitasInventory = false; @@ -1342,7 +1340,6 @@ public override void SaveData(TagCompound tag) boost.AddWithCondition("newPrincessInventory", newPrincessInventory); boost.AddWithCondition("newSkeletonMerchantInventory", newSkeletonMerchantInventory); boost.AddWithCondition("newPermafrostInventory", newPermafrostInventory); - boost.AddWithCondition("newCirrusInventory", newCirrusInventory); boost.AddWithCondition("newAmidiasInventory", newAmidiasInventory); boost.AddWithCondition("newBanditInventory", newBanditInventory); boost.AddWithCondition("newCalamitasInventory", newCalamitasInventory); @@ -1432,7 +1429,6 @@ public override void LoadData(TagCompound tag) newPrincessInventory = boost.Contains("newPrincessInventory"); newSkeletonMerchantInventory = boost.Contains("newSkeletonMerchantInventory"); newPermafrostInventory = boost.Contains("newPermafrostInventory"); - newCirrusInventory = boost.Contains("newCirrusInventory"); newAmidiasInventory = boost.Contains("newAmidiasInventory"); newBanditInventory = boost.Contains("newBanditInventory"); newCalamitasInventory = boost.Contains("newCalamitasInventory"); diff --git a/Items/Mounts/AlicornMount.cs b/Items/Mounts/AlicornMount.cs index d1f8acca61..2a03f2de57 100644 --- a/Items/Mounts/AlicornMount.cs +++ b/Items/Mounts/AlicornMount.cs @@ -69,43 +69,6 @@ public override void SetStaticDefaults() } } - public override void SetMount(Player player, ref bool skipDust) - { - foreach (NPC npc in Main.ActiveNPCs) - { - if (npc.type == ModContent.NPCType()) - { - npc.active = false; - npc.netUpdate = true; - break; - } - } - } - - public override void Dismount(Player player, ref bool skipDust) - { - bool anyPlayerOnFabMount = false; - foreach (Player player2 in Main.ActivePlayers) - { - // The player that is dismounting is technically not on the mount anymore. - if (player2.Calamity().fab && player2.whoAmI != player.whoAmI) - { - anyPlayerOnFabMount = true; - break; - } - } - - // Spawn Cirrus if no other players are on the Alicorn mount. - if (!anyPlayerOnFabMount) - { - if (!NPC.AnyNPCs(ModContent.NPCType())) - { - if (Main.netMode != NetmodeID.MultiplayerClient) - NPC.NewNPC(NPC.GetSource_TownSpawn(), (int)player.Center.X, (int)player.Center.Y, ModContent.NPCType()); - } - } - } - public override void UpdateEffects(Player player) { CalamityPlayer modPlayer = player.Calamity(); diff --git a/Localization/en-US/Mods.CalamityMod.Bestiary.hjson b/Localization/en-US/Mods.CalamityMod.Bestiary.hjson index 8a8ccb1a7c..304f1ea48a 100644 --- a/Localization/en-US/Mods.CalamityMod.Bestiary.hjson +++ b/Localization/en-US/Mods.CalamityMod.Bestiary.hjson @@ -130,7 +130,6 @@ SeaSerpent: Despite being one of the few carnivorous creatures to have ever exis //Town NPCs AndroombaFriendly: Reverse-engineered Androombas that have been retrofitted to spread the Steampunker's solutions rather than clean dust and debris off of floors. They can be used to purify the world– or ruin it further, if one so desires. DILF: One of the world's foremost experts on magical theory, he is renowned for his skill with the arcane arts. In his days when he traveled with Yharim's entourage, he acted as the Godseeker's advisor, due to both his status and his distaste for actively participating in battle. -FAP: A princess from an unknown land. She drinks constantly in a vain attempt to escape the memories of her past, but is practically immune to alcohol. She makes a business of selling her mixtures, alcoholic and alchemic alike. SEAHOE: The seventeenth ruler of the constitutional monarchy of Ilmeris since the tribes of the Ilmeran Sea unified, under the Electric Goddess, Otonilou, and the elusive God of the Seas. Alas, one cannot be a ruler without subjects, and while he remains respected by those who opposed Godseeker Yharim, his kingdom is no more. THIEF: The bandit may have a bad habit of looting battlefields and taking what isn't theirs, but their actions are mostly motivated by their hatred of the obscenely rich who haven't truly earned the wealth they possess. Their methods are somewhat shady, but can always be relied upon to get a job done. WITCH: Recruited to Yharim's forces late into the war, her magic overflows with such power that she is largely incapable of casting normal spells. Yet despite her great power, Calamitas prefers not to use it, as it takes a heavy toll on her psyche. diff --git a/Localization/en-US/Mods.CalamityMod.NPCs.hjson b/Localization/en-US/Mods.CalamityMod.NPCs.hjson index 2e4ed16928..51f110691f 100644 --- a/Localization/en-US/Mods.CalamityMod.NPCs.hjson +++ b/Localization/en-US/Mods.CalamityMod.NPCs.hjson @@ -321,101 +321,6 @@ DILF: { } } -FAP: { - DisplayName: Drunk Princess - Census.SpawnCondition: Have {$Mods.CalamityMod.Items.Potions.FabsolsVodka.DisplayName} [i:CalamityMod/FabsolsVodka] in your inventory in Hardmode - Name.Cirrus: Cirrus - - Chat: { - BossAlive: Why are you talking to me right now? Shouldn't you be bumbling around and dying for my amusement? - Homeless1: I could smell my vodka from MILES away! - Homeless2: Have any spare rooms available? Preferably candle-lit with a hefty supply of booze? - BloodMoon1: I'm gonna make some Bloody Marys to relax, celery included. Want one? - BloodMoon2: If you're too lazy to craft potions normally, try Blood Orbs. Blood is fuel, dumbass. - BloodMoon3: I'm trying to not be bitchy tonight, but it's hard when everyone else won't shut up. - BloodMoonSlap: Sorry, I have no moral compass at the moment. - Normal1: I HATE WALMART! ...Anyway, what do you want this time? - Normal2: Drink something that turns you into a magical flying unicorn so you can be just like me. - Normal3: Deals so good I'll [$$!$] myself! ...Sorry, just had a minor stroke! - Normal4: Did anyone ever tell you that large assets cause back pain? Well, they were right. - Archmage: "{0} can share a drink with me any time! ...Or maybe not, I'm not sure his old heart could take it." - BrimstoneWitch: The abuse {0} went through is something I can hardly comprehend. I'd offer her a drink, but I don't think she'd enjoy it. - Tavernkeep1: My booze will always be better than {0}'s, and nobody can convince me otherwise. - Tavernkeep2: Tell {0} to stop calling me. He's not wanted. - Tavernkeep3: I've had to tell baldie where my eyes are so many times that I've lost count. - Stylist1: Ever since {0} moved in I haven't been drinking as much... a strange but not unwelcome feeling. - Stylist2: You can't stop me from trying to move in with {0}. - Stylist3: I love it when {0}'s hands get sticky from all that... wax. - Day1: I'm literally balls drunk off my sass right now, what do you want? - Day2: I'm either laughing because I'm drunk or because I've lost my mind, probably both. - Day3: When I'm drunk I'm way happier... at least until the talking worms start to appear. - Day4: I should reprogram the whole mod, while drunk, then send it back to the testers. - DayStylist1: "{0} helped me learn to accept my past. It's been rough, but I think I'm on the right track now." - DayStylist2: Might go out for a jog later with {0}. Nice day for it. - DayDrunk1: I drink to forget certain... things. What things, you might ask? Well, the point is to forget them, isn't it? - DayDrunk2: What a great day! Might just drink so much that I get poisoned again. - Night1: A perfect night to light some candles, drink some wine and relax. - Night2: Here's a challenge... take a shot for every time you've had to look at the wiki. Oh wait, you'd die. - Night3: Yes, everyone knows the mechworm is buggy. Well, not anymore, but still. - Night4: You lost or something? I don't mind company, but I'd rather be left alone at night. - Night5: Are you sure you're 21? ...Alright, fine, but don't tell anyone I sold you these. - NightStylist: I should watch some movies with {0} tonight. You could come too, but only if you bring snacks for us. - Party: You'll always find me at parties where booze is involved... well, you'll always find BOOZE where I'M involved! - AcidRain: I'm melting! Put a stop to this inclement weather this instant before it ruins my hair! - Martians: You should probably deal with those ayy lmaos before anything else, but whatever. - CryogenDefeated: God I can't wait to smash some ice again! ...For drinks, of course. - LeviathanDefeated: How could you murder such a beautiful creature!? ...The blue one, not the obese cucumber. - MoonLordDefeated: Ever wondered why the Moon Lord needed so many tentacles? Uh... on second thought, I won't answer that. - PolterghastDefeated: I saw a ghost down by the old train tracks back at my homeland once, flailing wildly at the lily pads... frightening times those were. - DoGDefeated: I hear it's amazing when the famous Devourer of Gods out in flap-jaw space, with the tuning fork, does a raw blink on Hara-kiri rock. I need scissors! 61! - HasChibii: The hell is that? Looks like something I'd carry around if I was 5 years old. - HasAnahitaTrans: Nice scales... is it hot in here or is it just me? - HasVodka: Do you like my vodka? I created it by mixing fairy dust, crystallized cave sweat and other magical crap. - HasAlicorn1: So... you found my special bottle. Hope you enjoy it, I know I will. - HasAlicorn2: Be sure to dismount me once in a while, I get tired. And besides, I can't rip you off-I mean offer you excellent deals you won't find anywhere else if you're riding me 24/7. - HasAlicorn3: Before you ask, no, I do NOT have a heart on my butt while in human form. Don't question my transformation preferences! - } - - // Death Count stuffs - DeathCountButton: Death Count + Donors - DeathCount: You have failed {0} {^0:time;times}. - Death10000: Congratulations! You are now, officially, the biggest loser in Terraria's history! Who was number two? Hell if I know. - Death5000: I'm not sure what to say this time. That you're bad and should feel bad? That much was known already. - Death2500: Bless your heart. I could dodge better than you even if I were drunk high. - Death1000: It is said the average Terrarian has a lifespan of 2 minutes or less. ...Well, not really, but I feel like you'd be part of that statistic. - Death500: Your inability to avoid dying to even the most basic of attacks is astonishing to me. - Death250: I admire your tenacity. Keep it up, your enemies are racking up quite the kill count! - Death100: Consider lowering the difficulty. If you found that statement irritating, good. - DonorShoutout: Hey {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}, {15}, {16}, {17}, {18}, {19}, {20}, {21}, {22}, {23} and {24}! You're all pretty good! - - TownNPCMood: { - Content: It's 5 o'clock somewhere. - NoHome: I need a place to crash! My drinks need to be properly cooled before they can be served! - LoveSpace: Finally, some peace and quiet. Large quantities of people tend to piss me off. - FarFromHome: I'm used to running away from home, but this is a little ridiculous. - DislikeCrowded: If one more person tells me 'it's happy hour somewhere' to try and get a discount, I'm going to snap! - HateCrowded: No amount of alcohol can drown out the noise these people make! - LoveBiome: Other unicorns? Never thought I'd see the day! This place is incredible! - LikeBiome: A good breeze to cool some heads, that's the way to deal with customers who've had a few too many drinks! - DislikeBiome: This dry air and heat isn't good for my hair, or my drinks. - HateBiome: You think I can fix this mess with a magical friendship rainbow? That's not how it works, dumbass! Get me out of here already! - LoveNPC_Stylist: "{NPCName} works wonders for my hair... among other things, hehe." - LoveNPC_BestiaryGirl: "{NPCName} is so fluffy and squishy! She also says my alicorn form is 'mega rad'." - LikeNPC_Truffle: "{NPCName} makes me so hungry... I wonder how great of a trip he'd give..." - LikeNPC_PartyGirl: "{NPCName} would make for a great bartender some day. She really knows how to liven the mood!" - DislikeNPC_DD2Bartender: "{NPCName} is so bald." - DislikeNPC_TaxCollector: "{NPCName} had best keep his distance... he wouldn't want to wake up one morning with a pipe bomb in his mailbox." - HateNPC_GoblinTinkerer: "{NPCName} was so terrible that I had to FORCE him to have a better reforge system. Why would you house me next to him? Do you enjoy watching me relive the stress he gave me!?" - HateNPC_Angler: "{NPCName} never stops blabbering about his inane fishing quests. Get me away from him before I stomp him into the ground!" - LikeNPC_Princess: You think I'd dislike {NPCName} because we're too different? Quite the contrary, there's a lot we like to talk about, over non-alcoholic drinks of course. - Princess_LovesNPC: "{NPCName} has really interesting stories to tell, I've learned a lot from her already!" - HateNPC: I hate {NPCName}. - DislikeNPC: I dislike {NPCName}. - LikeNPC: I like {NPCName}. - LoveNPC: I love {NPCName}. - } -} - SEAHOE: { DisplayName: Sea King Census.SpawnCondition: Defeat a Giant Clam after defeating the Desert Scourge @@ -434,7 +339,6 @@ SEAHOE: { Angler1: Meet me at {0}'s house at night. We will throw him to the Trashers. Angler2: Not sure how {0} has not been roasted and digested by now, hanging around the sulphuric seas for so long. Perhaps it got to his head. BrimstoneWitch: I must admit, the Witch's presence is unsettling to me. But so many years have passed, and she too has suffered much. - DrunkPrincess: Rumor has it {0} drinks to forget her troubled past. PartyGirl: "{0} asked if my nose could be used as a vuvuzela. What is a vuvuzela?" BloodMoon1: Since ancient times people have said that deities cause celestial events. Which one then, is the cause for these? BloodMoon2: I've never been keen on these nights. Such violence. @@ -541,7 +445,6 @@ THIEF: { Night1: Hm, the stars are too bright tonight. Makes sneaking around a little more difficult. Night2: You think those stars that fall occasionally would make good throwing weapons? BrimstoneWitch: Hey, hey, has {0} seriously moved in here with us? Why??? - DrunkPrincess: I learned never to steal {0}'s drinks. She doesn't appreciate me right now, so I'll go back to hiding. Merchant: Don't tell {0}, but I took some of his stuff and replaced it with Angel Statues. NurseArmsDealer: Don't tell {0} that I was responsible for {1}'s injuries. NamedLaura: The nice thing about maps is I can track anything that has fallen. @@ -600,7 +503,6 @@ WITCH: { BloodMoon2: I can't work with nights like these. The stars seem to have shrunk away in fear. Night1: These undead are horrific, I can't stand to look at them. How could anyone be satisfied with such amateur work? Night2: I don't think it's a stretch to say that astrology is utter nonsense... but it was a hobby of mine once. - DrunkPrincess: I wonder if {0} ever feels cold given how revealing her dress is. Perhaps she should cover up a bit more. SeaKing: I cannot understand the Sea King. He does not seem to want me dead. That amount of compassion I just can't understand. Party: If another person asks me if I can dance or not, I will light their hat on fire. } diff --git a/Localization/en-US/Mods.CalamityMod.Vanilla.hjson b/Localization/en-US/Mods.CalamityMod.Vanilla.hjson index 4373a9e37f..5e5e6608f7 100644 --- a/Localization/en-US/Mods.CalamityMod.Vanilla.hjson +++ b/Localization/en-US/Mods.CalamityMod.Vanilla.hjson @@ -45,7 +45,6 @@ DemolitionistChat.DoGDefeated: God Slayer Dynamite? Boy do I like the sound of t DryadChat: { DarksunEclipse: There's a dark solar energy emanating from the moths that appear during this time. What's up with moths getting stronger as you do too? Hardmode: That starborne illness sits upon this land like a blister. Do even more vile forces of corruption exist in worlds beyond? - DrunkPrincessShroom: "{0} put me up to this." Mushroom: I'm not here for any reason! Just picking up mushrooms for uh, later use. SulphurSea: My Goddess is resting deep below this sea. If you may excuse me, I wish to pay my respects to her alone. } @@ -82,7 +81,6 @@ MechanicChat: { MoonLordDefeated: What do you mean your traps aren't making the cut? Don't look at me! Eclipse: Um... should my nightlight be on? AcidRain: Maybe I should've waterproofed my gadgets... They're starting to corrode. - DrunkPrincess: Well, I like {0}, but I, ah... I have my eyes on someone else. } MerchantChat: { @@ -112,7 +110,6 @@ PainterChat: { } PartyGirlChat: { - DrunkPrincess: I have a feeling we're going to have absolutely fantastic parties with {0} around! Eclipse1: I think my light display is turning into an accidental bug zapper. At least the monsters are enjoying it. Eclipse2: Ooh! I love parties where everyone wears a scary costume! } @@ -120,7 +117,6 @@ PartyGirlChat: { PirateChat: { PreLeviathan: Aye, I've heard of a mythical creature in the oceans, singing with an alluring voice. Careful when yer fishin out there. WetScourgeDefeated: I have to thank ye again for takin' care of that sea serpent. Or was that another one... - DrunkPrincess: Twenty-nine bottles of beer on the wall... SeaKing: I remember legends about that {0}. He ain't quite how the stories make him out to be though. Ocean: Now this is a scene that I can admire any time! I feel like something is watching me though. SulphurSea1: It ain't much of a sight, but there's still life living in these waters. @@ -148,8 +144,6 @@ SteampunkerChat: { StylistChat: { Hardmode: Please don't catch space lice. Or {0} lice. Or just lice in general. - DrunkPrincess1: "{0} is always trying to brighten my mood... even if, deep down, I know she's sad..." - DrunkPrincess2: Sometimes I catch {0} sneaking up from behind me. ProfanedSoulCrystal1: They look so cute and yet, I can feel their immense power just by being near them. What are you? ProfanedSoulCrystal2: I hate to break it to you, but you don't have hair to cut or style, hun. ProfanedDonuts: Aww, they're so cute, do they have names? @@ -157,7 +151,6 @@ StylistChat: { TavernkeepChat: { FullMoon: Care for a little Moonshine? - DrunkPrincess: Sheesh, {0} is a little cruel, isn't she? I never claimed to be an expert on anything but ale! } TaxCollectorChat: { @@ -168,11 +161,8 @@ TaxCollectorChat: { Has100Plat: BAH! Doesn't seem like I'll ever be able to quarrel with the debts of the town again! } -TravellingMerchantChat.DrunkPrincessMerchant: Tell {0} I'll take up her offer and meet with her at the back of {1}'s house. - TruffleChat: { Normal: I don't feel very safe; I think there's pigs following me around and it frightens me. - DrunkPrincess: Sometimes, {0} just looks at me funny and I'm not sure how I feel about that. } WitchDoctorChat: { diff --git a/NPCs/AstrumAureus/AstrumAureus.cs b/NPCs/AstrumAureus/AstrumAureus.cs index c2222cc170..61ee4eaa34 100644 --- a/NPCs/AstrumAureus/AstrumAureus.cs +++ b/NPCs/AstrumAureus/AstrumAureus.cs @@ -425,8 +425,6 @@ public override void OnKill() { CalamityGlobalNPC.SetNewBossJustDowned(NPC); - CalamityGlobalNPC.SetNewShopVariable(new int[] { NPCID.Wizard, ModContent.NPCType() }, DownedBossSystem.downedAstrumAureus); - // If Astrum Aureus has not yet been killed, notify players of new Astral enemy drops if (!DownedBossSystem.downedAstrumAureus) { diff --git a/NPCs/CalamityGlobalNPCLoot.cs b/NPCs/CalamityGlobalNPCLoot.cs index 8bfcaf8734..df219525c4 100644 --- a/NPCs/CalamityGlobalNPCLoot.cs +++ b/NPCs/CalamityGlobalNPCLoot.cs @@ -1877,7 +1877,7 @@ public override void OnKill(NPC npc) case NPCID.TheDestroyer: SetNewShopVariable(new int[] { NPCID.DD2Bartender, NPCID.Stylist, NPCID.Truffle }, NPC.downedMechBossAny); - SetNewShopVariable(new int[] { NPCID.Stylist, ModContent.NPCType(), ModContent.NPCType(), ModContent.NPCType() }, NPC.downedMechBoss1 || !NPC.downedMechBoss2 || !NPC.downedMechBoss3); + SetNewShopVariable(new int[] { NPCID.Stylist, ModContent.NPCType(), ModContent.NPCType() }, NPC.downedMechBoss1 || !NPC.downedMechBoss2 || !NPC.downedMechBoss3); SetNewBossJustDowned(npc); if (!NPC.downedMechBoss1 && CalamityConfig.Instance.EarlyHardmodeProgressionRework) @@ -1889,7 +1889,7 @@ public override void OnKill(NPC npc) if (lastTwinStanding) { SetNewShopVariable(new int[] { NPCID.DD2Bartender, NPCID.Stylist, NPCID.Truffle }, NPC.downedMechBossAny); - SetNewShopVariable(new int[] { NPCID.Stylist, ModContent.NPCType(), ModContent.NPCType(), ModContent.NPCType() }, !NPC.downedMechBoss1 || NPC.downedMechBoss2 || !NPC.downedMechBoss3); + SetNewShopVariable(new int[] { NPCID.Stylist, ModContent.NPCType(), ModContent.NPCType() }, !NPC.downedMechBoss1 || NPC.downedMechBoss2 || !NPC.downedMechBoss3); SetNewBossJustDowned(npc); if (!NPC.downedMechBoss2 && CalamityConfig.Instance.EarlyHardmodeProgressionRework) @@ -1899,7 +1899,7 @@ public override void OnKill(NPC npc) case NPCID.SkeletronPrime: SetNewShopVariable(new int[] { NPCID.DD2Bartender, NPCID.Stylist, NPCID.Truffle }, NPC.downedMechBossAny); - SetNewShopVariable(new int[] { NPCID.Stylist, ModContent.NPCType(), ModContent.NPCType(), ModContent.NPCType() }, !NPC.downedMechBoss1 || !NPC.downedMechBoss2 || NPC.downedMechBoss3); + SetNewShopVariable(new int[] { NPCID.Stylist, ModContent.NPCType(), ModContent.NPCType() }, !NPC.downedMechBoss1 || !NPC.downedMechBoss2 || NPC.downedMechBoss3); SetNewBossJustDowned(npc); if (!NPC.downedMechBoss3 && CalamityConfig.Instance.EarlyHardmodeProgressionRework) @@ -1907,7 +1907,7 @@ public override void OnKill(NPC npc) break; case NPCID.Plantera: - SetNewShopVariable(new int[] { NPCID.WitchDoctor, NPCID.Truffle, NPCID.BestiaryGirl, ModContent.NPCType(), ModContent.NPCType() }, NPC.downedPlantBoss); + SetNewShopVariable(new int[] { NPCID.WitchDoctor, NPCID.Truffle, NPCID.BestiaryGirl, ModContent.NPCType() }, NPC.downedPlantBoss); SetNewBossJustDowned(npc); // Spawn Perennial Ore if Plantera has never been killed @@ -1943,7 +1943,7 @@ public override void OnKill(NPC npc) break; case NPCID.Golem: - SetNewShopVariable(new int[] { NPCID.ArmsDealer, NPCID.Cyborg, NPCID.Steampunker, NPCID.Wizard, NPCID.WitchDoctor, NPCID.DD2Bartender, ModContent.NPCType(), ModContent.NPCType() }, NPC.downedGolemBoss); + 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. diff --git a/NPCs/CalamityGlobalTownNPC.cs b/NPCs/CalamityGlobalTownNPC.cs index c0944a024f..ee32f2b599 100644 --- a/NPCs/CalamityGlobalTownNPC.cs +++ b/NPCs/CalamityGlobalTownNPC.cs @@ -669,7 +669,6 @@ public override void ModifyNPCNameList(NPC npc, List nameList) (NPCID.SkeletonMerchant, (Player player) => player.Calamity().newSkeletonMerchantInventory, (Player player, bool enabled) =>{ player.Calamity().newSkeletonMerchantInventory = enabled; }), (NPCType(), (Player player) => player.Calamity().newAmidiasInventory,(Player player, bool enabled) =>{ player.Calamity().newAmidiasInventory = enabled; }), (NPCType(), (Player player) => player.Calamity().newBanditInventory,(Player player, bool enabled) =>{ player.Calamity().newBanditInventory = enabled; }), - (NPCType(), (Player player) => player.Calamity().newCirrusInventory,(Player player, bool enabled) =>{ player.Calamity().newCirrusInventory = enabled; }), (NPCType(), (Player player) => player.Calamity().newPermafrostInventory,(Player player, bool enabled) =>{ player.Calamity().newPermafrostInventory = enabled; }), (NPCType(), (Player player) => player.Calamity().newCalamitasInventory,(Player player, bool enabled) =>{ player.Calamity().newCalamitasInventory = enabled; }) // lol }; @@ -749,7 +748,6 @@ public static void SetNewShopVariable(int[] types, bool alreadySet) #region NPC Chat public override void GetChat(NPC npc, ref string chat) { - int fapsol = NPC.FindFirstNPC(NPCType()); int permadong = NPC.FindFirstNPC(NPCType()); int seahorse = NPC.FindFirstNPC(NPCType()); int thief = NPC.FindFirstNPC(NPCType()); @@ -803,10 +801,7 @@ public override void GetChat(NPC npc, ref string chat) chat = CalamityUtils.GetTextValue("Vanilla.DryadChat.DarksunEclipse"); else if (Main.rand.NextBool(5) && Main.LocalPlayer.ZoneGlowshroom) { - if (Main.rand.NextBool() && fapsol != -1) - chat = CalamityUtils.GetText("Vanilla.DryadChat.DrunkPrincessShroom").Format(Main.npc[fapsol].GivenName); - else - chat = CalamityUtils.GetTextValue("Vanilla.DryadChat.Mushroom"); + chat = CalamityUtils.GetTextValue("Vanilla.DryadChat.Mushroom"); } else if (Main.rand.NextBool(5) && Main.LocalPlayer.Calamity().ZoneSulphur) chat = CalamityUtils.GetTextValue("Vanilla.DryadChat.SulphurSea"); @@ -844,8 +839,6 @@ public override void GetChat(NPC npc, ref string chat) chat = CalamityUtils.GetTextValue("Vanilla.MechanicChat.Eclipse"); else if (Main.rand.NextBool(5) && AcidRainEvent.AcidRainEventIsOngoing) chat = CalamityUtils.GetTextValue("Vanilla.MechanicChat.AcidRain"); - else if (Main.rand.NextBool(5) && fapsol != -1) - chat = CalamityUtils.GetText("Vanilla.MechanicChat.DrunkPrincess").Format(Main.npc[fapsol].GivenName); break; case NPCID.Merchant: @@ -894,8 +887,6 @@ public override void GetChat(NPC npc, ref string chat) case NPCID.PartyGirl: if (Main.rand.NextBool(4) && Main.eclipse) chat = CalamityUtils.GetTextValue("Vanilla.PartyGirlChat.Eclipse" + Main.rand.Next(1, 2 + 1)); - else if (Main.rand.NextBool(10) && fapsol != -1) - chat = CalamityUtils.GetText("Vanilla.PartyGirlChat.DrunkPrincess").Format(Main.npc[fapsol].GivenName); break; case NPCID.Pirate: @@ -903,8 +894,6 @@ public override void GetChat(NPC npc, ref string chat) chat = CalamityUtils.GetTextValue("Vanilla.PirateChat.PreLeviathan"); else if (Main.rand.NextBool(5) && DownedBossSystem.downedAquaticScourge) chat = CalamityUtils.GetTextValue("Vanilla.PirateChat.WetScourgeDefeated"); - else if (Main.rand.NextBool(5) && fapsol != -1) - chat = CalamityUtils.GetTextValue("Vanilla.PirateChat.DrunkPrincess"); else if (Main.rand.NextBool(5) && seahorse != -1) chat = CalamityUtils.GetText("Vanilla.PirateChat.SeaKing").Format(Main.npc[seahorse].GivenName); else if (Main.rand.NextBool(5) && Main.LocalPlayer.Center.ToTileCoordinates().X < 380 && !Main.LocalPlayer.Calamity().ZoneSulphur) @@ -933,8 +922,6 @@ public override void GetChat(NPC npc, ref string chat) string worldEvil = Language.GetTextValue("LegacyMisc." + (WorldGen.crimson ? 102 : 101)); if (Main.rand.NextBool(15) && Main.hardMode) chat = CalamityUtils.GetText("Vanilla.StylistChat.Hardmode").Format(worldEvil); - if (Main.rand.NextBool(15) && fapsol != -1) - chat = CalamityUtils.GetText("Vanilla.StylistChat.DrunkPrincess" + (ChildSafety.Disabled ? Main.rand.Next(1, 2 + 1) : 1)).Format(Main.npc[fapsol].GivenName); if ((Main.rand.NextBool(npc.GivenName == "Amber" ? 10 : 15)) && Main.LocalPlayer.Calamity().pSoulArtifact) { if (Main.LocalPlayer.Calamity().profanedCrystalBuffs) @@ -947,8 +934,6 @@ public override void GetChat(NPC npc, ref string chat) case NPCID.DD2Bartender: if (Main.rand.NextBool(5) && !Main.dayTime && Main.moonPhase == 0) chat = CalamityUtils.GetTextValue("Vanilla.TavernkeepChat.FullMoon"); - else if (Main.rand.NextBool(10) && fapsol != -1) - chat = CalamityUtils.GetText("Vanilla.TavernkeepChat.DrunkPrincess").Format(Main.npc[fapsol].GivenName); break; case NPCID.TaxCollector: @@ -977,15 +962,8 @@ public override void GetChat(NPC npc, ref string chat) chat = CalamityUtils.GetTextValue("Vanilla.TaxCollectorChat.Has100Plat"); break; - case NPCID.TravellingMerchant: - if (Main.rand.NextBool(5) && fapsol != -1 && angelstatue != -1) - chat = CalamityUtils.GetText("Vanilla.TravellingMerchantChat.DrunkPrincessMerchant").Format(Main.npc[fapsol].GivenName, Main.npc[angelstatue].GivenName); - break; - case NPCID.Truffle: - if (Main.rand.NextBool(4) && fapsol != -1) - chat = CalamityUtils.GetText("Vanilla.TruffleChat.DrunkPrincess").Format(Main.npc[fapsol].GivenName); - else if (Main.rand.NextBool(8)) + if (Main.rand.NextBool(8)) chat = CalamityUtils.GetTextValue("Vanilla.TruffleChat.Normal"); break; @@ -1135,8 +1113,7 @@ public override void ModifyShop(NPCShop shop) .Add(ItemType(), revengeance) .Add(ItemType(), revengeance) .AddWithCustomValue(ItemID.StylistKilLaKillScissorsIWish, Item.buyPrice(gold: 15)) - .Add(ItemType(), Condition.NpcIsPresent(NPCType()), drunk) - .AddWithCustomValue(ItemID.ChocolateChipCookie, Item.buyPrice(gold: 3), Condition.HappyEnough, Condition.NpcIsPresent(NPCType())); + .AddWithCustomValue(ItemID.ChocolateChipCookie, Item.buyPrice(gold: 3)); } if (type == NPCID.Cyborg) @@ -1225,12 +1202,12 @@ public override void ModifyShop(NPCShop shop) { shop.AddWithCustomValue(ItemID.PrincessWeapon, Item.buyPrice(gold: 50)) .Add(ItemType()) - .Add(ItemID.AppleJuice, Condition.NpcIsPresent(NPCType())) - .Add(ItemID.FruitJuice, Condition.NpcIsPresent(NPCType())) - .Add(ItemID.Lemonade, Condition.NpcIsPresent(NPCType())) - .Add(ItemID.PrismaticPunch, Condition.NpcIsPresent(NPCType())) - .Add(ItemID.SmoothieofDarkness, Condition.NpcIsPresent(NPCType())) - .Add(ItemID.TropicalSmoothie, Condition.NpcIsPresent(NPCType())); + .Add(ItemID.AppleJuice) + .Add(ItemID.FruitJuice) + .Add(ItemID.Lemonade) + .Add(ItemID.PrismaticPunch) + .Add(ItemID.SmoothieofDarkness) + .Add(ItemID.TropicalSmoothie); } if (type == NPCID.SkeletonMerchant) diff --git a/NPCs/SupremeCalamitas/SupremeCalamitas.cs b/NPCs/SupremeCalamitas/SupremeCalamitas.cs index 42f996b630..0f307b0e97 100644 --- a/NPCs/SupremeCalamitas/SupremeCalamitas.cs +++ b/NPCs/SupremeCalamitas/SupremeCalamitas.cs @@ -798,7 +798,7 @@ public override void AI() // Make the town NPC spawn. if (Main.netMode != NetmodeID.MultiplayerClient) - NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y + 12, cirrus ? ModContent.NPCType() : ModContent.NPCType()); + NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y + 12, cirrus ? ModContent.NPCType() : ModContent.NPCType()); } NPC.active = false; @@ -3447,7 +3447,7 @@ public override void OnKill() // Spawn the SCal NPC directly where the boss was if (!BossRushEvent.BossRushActive) - NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y + 12, cirrus ? ModContent.NPCType() : ModContent.NPCType()); + NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y + 12, cirrus ? ModContent.NPCType() : ModContent.NPCType()); // Mark Calamitas as defeated DownedBossSystem.downedCalamitas = true; diff --git a/NPCs/SupremeCalamitas/SupremeCirrus.png b/NPCs/SupremeCalamitas/SupremeCirrus.png index 4412c1c02b6d3fcb7f42ffb4e5359e606709af51..4e75ae0b28c07c859741ddc50a00edafe72bdd7c 100644 GIT binary patch literal 5589 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 Sj(}rPh=Z+@P31nn3;zWIRIyb6 literal 9076 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 diff --git a/NPCs/TownNPCs/FAP.cs b/NPCs/TownNPCs/FAP.cs deleted file mode 100644 index eef4a0d498..0000000000 --- a/NPCs/TownNPCs/FAP.cs +++ /dev/null @@ -1,963 +0,0 @@ -using System; -using System.Collections.Generic; -using CalamityMod.Events; -using CalamityMod.Items.Mounts; -using CalamityMod.Items.Placeables.Furniture; -using CalamityMod.Items.Potions.Alcohol; -using CalamityMod.NPCs.SupremeCalamitas; -using CalamityMod.Projectiles.Magic; -using CalamityMod.Projectiles.Summon; -using CalamityMod.World; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using ReLogic.Content; -using Terraria; -using Terraria.Audio; -using Terraria.DataStructures; -using Terraria.GameContent; -using Terraria.GameContent.Bestiary; -using Terraria.GameContent.Events; -using Terraria.GameContent.Personalities; -using Terraria.GameContent.UI; -using Terraria.ID; -using Terraria.Localization; -using Terraria.ModLoader; -using Terraria.Utilities; - -namespace CalamityMod.NPCs.TownNPCs -{ - [AutoloadHead] - public class FAP : ModNPC - { - public static Asset AltTexture; - - public override void SetStaticDefaults() - { - Main.npcFrameCount[NPC.type] = 27; - NPCID.Sets.ExtraFramesCount[NPC.type] = 9; - NPCID.Sets.AttackFrameCount[NPC.type] = 4; - NPCID.Sets.DangerDetectRange[NPC.type] = 400; - NPCID.Sets.AttackType[NPC.type] = 0; - NPCID.Sets.AttackTime[NPC.type] = 60; - NPCID.Sets.AttackAverageChance[NPC.type] = 15; - NPCID.Sets.ShimmerTownTransform[Type] = false; - NPC.Happiness - .SetBiomeAffection(AffectionLevel.Love) - .SetBiomeAffection(AffectionLevel.Like) - .SetBiomeAffection(AffectionLevel.Dislike) - .SetBiomeAffection(AffectionLevel.Hate) - .SetNPCAffection(NPCID.Stylist, AffectionLevel.Love) - .SetNPCAffection(NPCID.BestiaryGirl, AffectionLevel.Love) - .SetNPCAffection(NPCID.Truffle, AffectionLevel.Like) - .SetNPCAffection(NPCID.PartyGirl, AffectionLevel.Like) - .SetNPCAffection(NPCID.DD2Bartender, AffectionLevel.Dislike) - .SetNPCAffection(NPCID.TaxCollector, AffectionLevel.Dislike) - .SetNPCAffection(NPCID.GoblinTinkerer, AffectionLevel.Hate) - .SetNPCAffection(NPCID.Angler, AffectionLevel.Hate); - NPCID.Sets.NPCBestiaryDrawModifiers drawModifiers = new NPCID.Sets.NPCBestiaryDrawModifiers() - { - Velocity = 1f // Draws the NPC in the bestiary as if its walking +1 tiles in the x direction - }; - NPCID.Sets.NPCBestiaryDrawOffset.Add(NPC.type, drawModifiers); - if (!Main.dedServ) - { - AltTexture = ModContent.Request(Texture + "Alt", AssetRequestMode.AsyncLoad); - } - } - - public override void SetDefaults() - { - NPC.townNPC = true; - NPC.friendly = true; - NPC.lavaImmune = true; - NPC.width = 18; - NPC.height = 40; - NPC.aiStyle = NPCAIStyleID.Passive; - NPC.damage = 10; - NPC.defense = 15; - NPC.lifeMax = 20000; - NPC.HitSound = SoundID.NPCHit1; - NPC.DeathSound = SoundID.NPCDeath6; - NPC.knockBackResist = 0.5f; - //AnimationType = NPCID.Guide; - } - - public override void SetBestiary(BestiaryDatabase database, BestiaryEntry bestiaryEntry) - { - bestiaryEntry.Info.AddRange(new IBestiaryInfoElement[] - { - BestiaryDatabaseNPCsPopulator.CommonTags.SpawnConditions.Biomes.TheHallow, - new FlavorTextBestiaryInfoElement("Mods.CalamityMod.Bestiary.FAP") - }); - } - - public override void FindFrame(int frameHeight) - { - int extraFrameAmt = (NPC.isLikeATownNPC ? NPCID.Sets.ExtraFramesCount[NPC.type] : 0); - /*if (false && !Main.dedServ && TownNPCProfiles.Instance.GetProfile(this, out var profile)) - { - Asset textureNPCShouldUse = profile.GetTextureNPCShouldUse(this); - if (textureNPCShouldUse.IsLoaded) - { - num = textureNPCShouldUse.Height() / Main.npcFrameCount[type]; - frame.Width = textureNPCShouldUse.Width(); - frame.Height = num; - } - }*/ - - if (NPC.velocity.Y == 0f) - { - if (NPC.direction == 1) - NPC.spriteDirection = 1; - - if (NPC.direction == -1) - NPC.spriteDirection = -1; - - int nonAttackFrames = Main.npcFrameCount[NPC.type] - NPCID.Sets.AttackFrameCount[NPC.type]; - if (NPC.ai[0] == 23f) - { - NPC.frameCounter += 1D; - int currentFrameHeight = NPC.frame.Y / frameHeight; - int currentFrame = nonAttackFrames - currentFrameHeight; - if ((uint)(currentFrame - 1) > 1u && (uint)(currentFrame - 4) > 1u && currentFrameHeight != 0) - { - NPC.frame.Y = 0; - NPC.frameCounter = 0D; - } - - int num239 = ((!(NPC.frameCounter < 6D)) ? (nonAttackFrames - 4) : (nonAttackFrames - 5)); - if (NPC.ai[1] < 6f) - num239 = nonAttackFrames - 5; - - NPC.frame.Y = frameHeight * num239; - } - else if (NPC.ai[0] >= 20f && NPC.ai[0] <= 22f) - { - int num240 = NPC.frame.Y / frameHeight; - switch ((int)NPC.ai[0]) - { - case 20: - case 21: - case 22: - break; - } - - NPC.frame.Y = num240 * frameHeight; - } - else if (NPC.ai[0] == 2f) - { - NPC.frameCounter += 1D; - if (NPC.frame.Y / frameHeight == nonAttackFrames - 1 && NPC.frameCounter >= 5D) - { - NPC.frame.Y = 0; - NPC.frameCounter = 0D; - } - else if (NPC.frame.Y / frameHeight == 0 && NPC.frameCounter >= 40D) - { - NPC.frame.Y = frameHeight * (nonAttackFrames - 1); - NPC.frameCounter = 0D; - } - else if (NPC.frame.Y != 0 && NPC.frame.Y != frameHeight * (nonAttackFrames - 1)) - { - NPC.frame.Y = 0; - NPC.frameCounter = 0D; - } - } - else if (NPC.ai[0] == 5f) // Sitting - { - NPC.frame.Y = frameHeight * (nonAttackFrames - 3); - NPC.frameCounter = 0D; - } - else if (NPC.ai[0] == 6f) // Throwing confetti - { - NPC.frameCounter += 1D; - int confettiFrameHeight = NPC.frame.Y / frameHeight; - int currentFrame = nonAttackFrames - confettiFrameHeight; - if ((uint)(currentFrame - 1) > 1u && (uint)(currentFrame - 4) > 1u && confettiFrameHeight != 0) - { - NPC.frame.Y = 0; - NPC.frameCounter = 0D; - } - - int confettiFrame = ((!(NPC.frameCounter < 10D)) ? - ((NPC.frameCounter < 16D) ? - (nonAttackFrames - 5) : ((NPC.frameCounter < 46D) ? - (nonAttackFrames - 4) : ((NPC.frameCounter < 60D) ? - (nonAttackFrames - 5) : ((!(NPC.frameCounter < 66D)) ? - ((NPC.frameCounter < 72D) ? - (nonAttackFrames - 5) : ((NPC.frameCounter < 102D) ? - (nonAttackFrames - 4) : ((NPC.frameCounter < 108D) ? - (nonAttackFrames - 5) : ((!(NPC.frameCounter < 114D)) ? - ((NPC.frameCounter < 120D) ? - (nonAttackFrames - 5) : ((NPC.frameCounter < 150D) ? - (nonAttackFrames - 4) : ((NPC.frameCounter < 156D) ? - (nonAttackFrames - 5) : ((!(NPC.frameCounter < 162D)) ? - ((NPC.frameCounter < 168D) ? - (nonAttackFrames - 5) : ((NPC.frameCounter < 198D) ? - (nonAttackFrames - 4) : ((NPC.frameCounter < 204D) ? - (nonAttackFrames - 5) : ((!(NPC.frameCounter < 210D)) ? - ((NPC.frameCounter < 216D) ? - (nonAttackFrames - 5) : ((NPC.frameCounter < 246D) ? - (nonAttackFrames - 4) : ((NPC.frameCounter < 252D) ? - (nonAttackFrames - 5) : ((!(NPC.frameCounter < 258D)) ? - ((NPC.frameCounter < 264D) ? - (nonAttackFrames - 5) : ((NPC.frameCounter < 294D) ? - (nonAttackFrames - 4) : ((NPC.frameCounter < 300D) ? - (nonAttackFrames - 5) : 0))) : 0)))) : 0)))) : 0)))) : 0)))) : 0)))) : 0); - - if (confettiFrame == nonAttackFrames - 4 && confettiFrameHeight == nonAttackFrames - 5) - { - Vector2 vector4 = NPC.Center + new Vector2(10 * NPC.direction, -4f); - for (int n = 0; n < 8; n++) - { - int confettiDust = Main.rand.Next(139, 143); - int partyTime = Dust.NewDust(vector4, 0, 0, confettiDust, NPC.velocity.X + (float)NPC.direction, NPC.velocity.Y - 2.5f, 0, default(Color), 1.2f); - Main.dust[partyTime].velocity.X += (float)NPC.direction * 1.5f; - Dust dust = Main.dust[partyTime]; - dust.position -= new Vector2(4f); - dust = Main.dust[partyTime]; - dust.velocity *= 2f; - Main.dust[partyTime].scale = 0.7f + Main.rand.NextFloat() * 0.3f; - } - } - - NPC.frame.Y = frameHeight * confettiFrame; - if (NPC.frameCounter >= 300D) - NPC.frameCounter = 0D; - } - else if (NPC.ai[0] == 7f || NPC.ai[0] == 19f) // Talking to the player - { - NPC.frameCounter += 1D; - int playerTalkFrameHeight = NPC.frame.Y / frameHeight; - int currentFrame = nonAttackFrames - playerTalkFrameHeight; - if ((uint)(currentFrame - 1) > 1u && (uint)(currentFrame - 4) > 1u && playerTalkFrameHeight != 0) - { - NPC.frame.Y = 0; - NPC.frameCounter = 0D; - } - - int playerTalkFrame = 0; - if (NPC.frameCounter < 16D) - playerTalkFrame = 0; - else if (NPC.frameCounter == 16D) - EmoteBubble.NewBubbleNPC(new WorldUIAnchor(NPC), 112); - else if (NPC.frameCounter < 128D) - playerTalkFrame = ((NPC.frameCounter % 16D < 8D) ? (nonAttackFrames - 2) : 0); - else if (NPC.frameCounter < 160D) - playerTalkFrame = 0; - else if (NPC.frameCounter != 160D) - playerTalkFrame = ((NPC.frameCounter < 220D) ? ((NPC.frameCounter % 12D < 6D) ? (nonAttackFrames - 2) : 0) : 0); - else - EmoteBubble.NewBubbleNPC(new WorldUIAnchor(NPC), 60); - - NPC.frame.Y = frameHeight * playerTalkFrame; - if (NPC.frameCounter >= 220D) - NPC.frameCounter = 0D; - } - else if (NPC.ai[0] == 9f) - { - NPC.frameCounter += 1D; - int num251 = NPC.frame.Y / frameHeight; - int currentFrame = nonAttackFrames - num251; - if ((uint)(currentFrame - 1) > 1u && (uint)(currentFrame - 4) > 1u && num251 != 0) - { - NPC.frame.Y = 0; - NPC.frameCounter = 0D; - } - - int num252 = ((!(NPC.frameCounter < 10D)) ? ((!(NPC.frameCounter < 16D)) ? (nonAttackFrames - 4) : (nonAttackFrames - 5)) : 0); - if (NPC.ai[1] < 16f) - num252 = nonAttackFrames - 5; - - if (NPC.ai[1] < 10f) - num252 = 0; - - NPC.frame.Y = frameHeight * num252; - } - else if (NPC.ai[0] == 18f) - { - NPC.frameCounter += 1D; - int num253 = NPC.frame.Y / frameHeight; - int currentFrame = nonAttackFrames - num253; - if ((uint)(currentFrame - 1) > 1u && (uint)(currentFrame - 4) > 1u && num253 != 0) - { - NPC.frame.Y = 0; - NPC.frameCounter = 0D; - } - - int num254 = 0; - if (NPC.frameCounter < 10D) - num254 = 0; - else if (NPC.frameCounter < 16D) - num254 = nonAttackFrames - 1; - else - num254 = nonAttackFrames - 2; - - if (NPC.ai[1] < 16f) - num254 = nonAttackFrames - 1; - - if (NPC.ai[1] < 10f) - num254 = 0; - - num254 = Main.npcFrameCount[NPC.type] - 2; - NPC.frame.Y = frameHeight * num254; - } - else if (NPC.ai[0] == 10f || NPC.ai[0] == 13f) // Attacking - { - NPC.frameCounter += 1D; - int attackFrameHeight = NPC.frame.Y / frameHeight; - int currentFrame = attackFrameHeight - nonAttackFrames; - if ((uint)currentFrame > 3u && attackFrameHeight != 0) - { - NPC.frame.Y = 0; - NPC.frameCounter = 0D; - } - - int attackTimingStart = 10; - int attackFrameTiming = 6; - int attackFrame = ((!(NPC.frameCounter < (double)attackTimingStart)) ? - ((NPC.frameCounter < (double)(attackTimingStart + attackFrameTiming)) ? - nonAttackFrames : ((NPC.frameCounter < (double)(attackTimingStart + attackFrameTiming * 2)) ? - (nonAttackFrames + 1) : ((NPC.frameCounter < (double)(attackTimingStart + attackFrameTiming * 3)) ? - (nonAttackFrames + 2) : ((NPC.frameCounter < (double)(attackTimingStart + attackFrameTiming * 4)) ? - (nonAttackFrames + 3) : 0)))) : 0); - - NPC.frame.Y = frameHeight * attackFrame; - } - else if (NPC.ai[0] == 15f) - { - NPC.frameCounter += 1D; - int num259 = NPC.frame.Y / frameHeight; - int currentFrame = num259 - nonAttackFrames; - if ((uint)currentFrame > 3u && num259 != 0) - { - NPC.frame.Y = 0; - NPC.frameCounter = 0D; - } - - float num260 = NPC.ai[1] / (float)NPCID.Sets.AttackTime[NPC.type]; - int num261 = 0; - num261 = ((num260 > 0.65f) ? - nonAttackFrames : ((num260 > 0.5f) ? - (nonAttackFrames + 1) : ((num260 > 0.35f) ? - (nonAttackFrames + 2) : ((num260 > 0f) ? - (nonAttackFrames + 3) : 0)))); - - NPC.frame.Y = frameHeight * num261; - } - else if (NPC.ai[0] == 25f) - { - NPC.frame.Y = frameHeight; - } - else if (NPC.ai[0] == 12f) - { - NPC.frameCounter += 1D; - int num262 = NPC.frame.Y / frameHeight; - int currentFrame = num262 - nonAttackFrames; - if ((uint)currentFrame > 4u && num262 != 0) - { - NPC.frame.Y = 0; - NPC.frameCounter = 0D; - } - - int num263 = nonAttackFrames + NPC.GetShootingFrame(NPC.ai[2]); - NPC.frame.Y = frameHeight * num263; - } - else if (NPC.ai[0] == 14f || NPC.ai[0] == 24f) - { - NPC.frameCounter += 1D; - int num264 = NPC.frame.Y / frameHeight; - int currentFrame = num264 - nonAttackFrames; - if ((uint)currentFrame > 1u && num264 != 0) - { - NPC.frame.Y = 0; - NPC.frameCounter = 0D; - } - - int num265 = 12; - int num266 = ((NPC.frameCounter % (double)num265 * 2D < (double)num265) ? nonAttackFrames : (nonAttackFrames + 1)); - NPC.frame.Y = frameHeight * num266; - if (NPC.ai[0] == 24f) - { - if (NPC.frameCounter == 60D) - EmoteBubble.NewBubble(EmoteID.EmoteConfused, new WorldUIAnchor(NPC), 60); - - if (NPC.frameCounter == 150D) - EmoteBubble.NewBubble(EmoteID.EmotionAlert, new WorldUIAnchor(NPC), 90); - - if (NPC.frameCounter >= 240D) - NPC.frame.Y = 0; - } - } - else if (NPC.ai[0] == 1001f) - { - NPC.frame.Y = frameHeight * (nonAttackFrames - 1); - NPC.frameCounter = 0D; - } - else if (NPC.CanTalk && (NPC.ai[0] == 3f || NPC.ai[0] == 4f)) // Talking to another NPC - { - NPC.frameCounter += 1D; - int npcTalkFrameHeight = NPC.frame.Y / frameHeight; - int currentFrame = nonAttackFrames - npcTalkFrameHeight; - if ((uint)(currentFrame - 1) > 1u && (uint)(currentFrame - 4) > 1u && npcTalkFrameHeight != 0) - { - NPC.frame.Y = 0; - NPC.frameCounter = 0D; - } - - bool displayEmote = NPC.ai[0] == 3f; - int npcTalkFrame = 0; - int npcTalkHandFrame = 0; - int emoteDisplayTime = -1; - int emoteDisplayTime2 = -1; - if (NPC.frameCounter < 10D) - npcTalkFrame = 0; - else if (NPC.frameCounter < 16D) - npcTalkFrame = nonAttackFrames - 5; - else if (NPC.frameCounter < 46D) - npcTalkFrame = nonAttackFrames - 4; - else if (NPC.frameCounter < 60D) - npcTalkFrame = nonAttackFrames - 5; - else if (NPC.frameCounter < 216D) - npcTalkFrame = 0; - else if (NPC.frameCounter == 216D && Main.netMode != NetmodeID.MultiplayerClient) - emoteDisplayTime = 70; - else if (NPC.frameCounter < 286D) - npcTalkFrame = ((NPC.frameCounter % 12D < 6D) ? (nonAttackFrames - 2) : 0); - else if (NPC.frameCounter < 320D) - npcTalkFrame = 0; - else if (NPC.frameCounter != 320D || Main.netMode == NetmodeID.MultiplayerClient) - npcTalkFrame = ((NPC.frameCounter < 420D) ? ((NPC.frameCounter % 16D < 8D) ? (nonAttackFrames - 2) : 0) : 0); - else - emoteDisplayTime = 100; - - if (NPC.frameCounter < 70D) - { - npcTalkHandFrame = 0; - } - else if (NPC.frameCounter != 70D || Main.netMode == NetmodeID.MultiplayerClient) - { - npcTalkHandFrame = ((NPC.frameCounter < 160D) ? - ((NPC.frameCounter % 16D < 8D) ? - (nonAttackFrames - 2) : 0) : ((NPC.frameCounter < 166D) ? - (nonAttackFrames - 5) : ((NPC.frameCounter < 186D) ? - (nonAttackFrames - 4) : ((NPC.frameCounter < 200D) ? - (nonAttackFrames - 5) : ((!(NPC.frameCounter < 320D)) ? - ((NPC.frameCounter < 326D) ? - (nonAttackFrames - 1) : 0) : 0))))); - } - else - emoteDisplayTime2 = 90; - - if (displayEmote) - { - NPC nPC = Main.npc[(int)NPC.ai[2]]; - if (emoteDisplayTime != -1) - EmoteBubble.NewBubbleNPC(new WorldUIAnchor(NPC), emoteDisplayTime, new WorldUIAnchor(nPC)); - - if (emoteDisplayTime2 != -1 && nPC.CanTalk) - EmoteBubble.NewBubbleNPC(new WorldUIAnchor(nPC), emoteDisplayTime2, new WorldUIAnchor(NPC)); - } - - NPC.frame.Y = frameHeight * (displayEmote ? npcTalkFrame : npcTalkHandFrame); - if (NPC.frameCounter >= 420D) - NPC.frameCounter = 0D; - } - else if (NPC.CanTalk && (NPC.ai[0] == 16f || NPC.ai[0] == 17f)) // Rock Paper Scissors - { - NPC.frameCounter += 1D; - int rpsFrameHeight = NPC.frame.Y / frameHeight; - int currentFrame = nonAttackFrames - rpsFrameHeight; - if ((uint)(currentFrame - 1) > 1u && (uint)(currentFrame - 4) > 1u && rpsFrameHeight != 0) - { - NPC.frame.Y = 0; - NPC.frameCounter = 0D; - } - - bool controlsRPS = NPC.ai[0] == 16f; - int rpsFrame = 0; - int emoteDisplayTime = -1; - if (NPC.frameCounter < 10D) - rpsFrame = 0; - else if (NPC.frameCounter < 16D) - rpsFrame = nonAttackFrames - 5; - else if (NPC.frameCounter < 22D) - rpsFrame = nonAttackFrames - 4; - else if (NPC.frameCounter < 28D) - rpsFrame = nonAttackFrames - 5; - else if (NPC.frameCounter < 34D) - rpsFrame = nonAttackFrames - 4; - else if (NPC.frameCounter < 40D) - rpsFrame = nonAttackFrames - 5; - else if (NPC.frameCounter == 40D && Main.netMode != NetmodeID.MultiplayerClient) - emoteDisplayTime = 45; - else if (NPC.frameCounter < 70D) - rpsFrame = nonAttackFrames - 4; - else if (NPC.frameCounter < 76D) - rpsFrame = nonAttackFrames - 5; - else if (NPC.frameCounter < 82D) - rpsFrame = nonAttackFrames - 4; - else if (NPC.frameCounter < 88D) - rpsFrame = nonAttackFrames - 5; - else if (NPC.frameCounter < 94D) - rpsFrame = nonAttackFrames - 4; - else if (NPC.frameCounter < 100D) - rpsFrame = nonAttackFrames - 5; - else if (NPC.frameCounter == 100D && Main.netMode != NetmodeID.MultiplayerClient) - emoteDisplayTime = 45; - else if (NPC.frameCounter < 130D) - rpsFrame = nonAttackFrames - 4; - else if (NPC.frameCounter < 136D) - rpsFrame = nonAttackFrames - 5; - else if (NPC.frameCounter < 142D) - rpsFrame = nonAttackFrames - 4; - else if (NPC.frameCounter < 148D) - rpsFrame = nonAttackFrames - 5; - else if (NPC.frameCounter < 154D) - rpsFrame = nonAttackFrames - 4; - else if (NPC.frameCounter < 160D) - rpsFrame = nonAttackFrames - 5; - else if (NPC.frameCounter != 160D || Main.netMode == NetmodeID.MultiplayerClient) - rpsFrame = ((NPC.frameCounter < 220D) ? (nonAttackFrames - 4) : ((NPC.frameCounter < 226D) ? (nonAttackFrames - 5) : 0)); - else - emoteDisplayTime = 75; - - if (controlsRPS && emoteDisplayTime != -1) - { - int npcPick = (int)NPC.localAI[2]; - int npcWins = (int)NPC.localAI[3]; - int opponentWins = (int)Main.npc[(int)NPC.ai[2]].localAI[3]; - int opponentPick = (int)Main.npc[(int)NPC.ai[2]].localAI[2]; - int rpsGameEnder = 3 - npcPick - npcWins; - int numGamesPlayed = 0; - if (NPC.frameCounter == 40D) - numGamesPlayed = 1; - - if (NPC.frameCounter == 100D) - numGamesPlayed = 2; - - if (NPC.frameCounter == 160D) - numGamesPlayed = 3; - - int gameCountdown = 3 - numGamesPlayed; - int rockPaperScissorsResultType = -1; - int gameFrameTimer = 0; - while (rockPaperScissorsResultType < 0) - { - currentFrame = gameFrameTimer + 1; - gameFrameTimer = currentFrame; - if (currentFrame >= 100) - break; - - rockPaperScissorsResultType = Main.rand.Next(2); - if (rockPaperScissorsResultType == 0 && opponentPick >= npcWins) - rockPaperScissorsResultType = -1; - - if (rockPaperScissorsResultType == 1 && opponentWins >= npcPick) - rockPaperScissorsResultType = -1; - - if (rockPaperScissorsResultType == -1 && gameCountdown <= rpsGameEnder) - rockPaperScissorsResultType = 2; - } - - if (rockPaperScissorsResultType == 0) - { - Main.npc[(int)NPC.ai[2]].localAI[3] += 1f; - opponentWins++; - } - - if (rockPaperScissorsResultType == 1) - { - Main.npc[(int)NPC.ai[2]].localAI[2] += 1f; - opponentPick++; - } - - int emoteType = Utils.SelectRandom(Main.rand, EmoteID.RPSPaper, EmoteID.RPSRock, EmoteID.RPSScissors); - int emoteType2 = emoteType; - switch (rockPaperScissorsResultType) - { - case 0: - switch (emoteType) - { - case EmoteID.RPSPaper: - emoteType2 = EmoteID.RPSRock; - break; - case EmoteID.RPSRock: - emoteType2 = EmoteID.RPSScissors; - break; - case EmoteID.RPSScissors: - emoteType2 = EmoteID.RPSPaper; - break; - } - break; - case 1: - switch (emoteType) - { - case EmoteID.RPSPaper: - emoteType2 = EmoteID.RPSScissors; - break; - case EmoteID.RPSRock: - emoteType2 = EmoteID.RPSPaper; - break; - case EmoteID.RPSScissors: - emoteType2 = EmoteID.RPSRock; - break; - } - break; - } - - if (gameCountdown == 0) - { - if (opponentWins >= 2) - emoteType -= 3; - - if (opponentPick >= 2) - emoteType2 -= 3; - } - - EmoteBubble.NewBubble(emoteType, new WorldUIAnchor(NPC), emoteDisplayTime); - EmoteBubble.NewBubble(emoteType2, new WorldUIAnchor(Main.npc[(int)NPC.ai[2]]), emoteDisplayTime); - } - - NPC.frame.Y = frameHeight * (controlsRPS ? rpsFrame : rpsFrame); - if (NPC.frameCounter >= 420D) - NPC.frameCounter = 0D; - } - else if (NPC.velocity.X == 0f) - { - NPC.frame.Y = 0; - NPC.frameCounter = 0D; - } - else // Walking - { - NPC.frameCounter += Math.Abs(NPC.velocity.X) * 2f; - NPC.frameCounter += 1D; - - int walkFrameHeightLimit = frameHeight * 2; - if (NPC.frame.Y < walkFrameHeightLimit) - NPC.frame.Y = walkFrameHeightLimit; - - int walkFrameTimer = 6; - if (NPC.frameCounter > (double)walkFrameTimer) - { - NPC.frame.Y += frameHeight; - NPC.frameCounter = 0D; - } - - if (NPC.frame.Y / frameHeight >= Main.npcFrameCount[NPC.type] - extraFrameAmt) - NPC.frame.Y = walkFrameHeightLimit; - } - - return; - } - - NPC.frameCounter = 0D; - NPC.frame.Y = frameHeight; - } - - public override void AI() - { - if (!CalamityWorld.spawnedCirrus) - CalamityWorld.spawnedCirrus = true; - } - - public override bool CanTownNPCSpawn(int numTownNPCs) - { - if (NPC.AnyNPCs(ModContent.NPCType()) && Main.zenithWorld) - return false; - - if (CalamityWorld.spawnedCirrus) - return true; - - foreach (Player player in Main.ActivePlayers) - { - bool hasVodka = player.InventoryHas(ModContent.ItemType()) || player.PortableStorageHas(ModContent.ItemType()); - if (hasVodka) - return Main.hardMode; - } - return false; - } - - public override List SetNPCNameList() => new List() { this.GetLocalizedValue("Name.Cirrus") }; - - public override string GetChat() - { - Player player = Main.player[Main.myPlayer]; - if (Main.zenithWorld) - { - player.Hurt(PlayerDeathReason.ByCustomReason(CalamityUtils.GetText("Status.Death.CirrusSlap" + Main.rand.Next(1, 2 + 1)).Format(player.name)), player.statLife / 2, -player.direction, false, false, -1, false); - SoundEngine.PlaySound(CnidarianJellyfishOnTheString.SlapSound, player.Center); - } - - if (CalamityUtils.AnyBossNPCS()) - return this.GetLocalizedValue("Chat.BossAlive"); - - if (NPC.homeless) - return this.GetLocalizedValue("Chat.Homeless" + Main.rand.Next(1, 2 + 1)); - - int wife = NPC.FindFirstNPC(NPCID.Stylist); - bool wifeIsAround = wife != -1; - bool beLessDrunk = wifeIsAround && NPC.downedMoonlord; - - if (Main.bloodMoon) - { - if (Main.rand.NextBool(4)) - { - player.Hurt(PlayerDeathReason.ByCustomReason(CalamityUtils.GetText("Status.Death.CirrusSlap" + Main.rand.Next(1, 2 + 1)).Format(player.name)), player.statLife / 2, -player.direction, false, false, -1, false); ; - SoundEngine.PlaySound(CnidarianJellyfishOnTheString.SlapSound, player.Center); - return this.GetLocalizedValue("Chat.BloodMoonSlap"); - } - return this.GetLocalizedValue("Chat.BloodMoon" + Main.rand.Next(1, 3 + 1)); - } - - WeightedRandom dialogue = new WeightedRandom(); - - dialogue.Add(this.GetLocalizedValue("Chat.Normal1")); - dialogue.Add(this.GetLocalizedValue("Chat.Normal2")); - dialogue.Add(this.GetLocalizedValue("Chat.Normal3")); - if (ChildSafety.Disabled) - dialogue.Add(this.GetLocalizedValue("Chat.Normal4")); - - int tavernKeep = NPC.FindFirstNPC(NPCID.DD2Bartender); - if (tavernKeep != -1) - { - dialogue.Add(this.GetLocalization("Chat.Tavernkeep1").Format(Main.npc[tavernKeep].GivenName)); - dialogue.Add(this.GetLocalization("Chat.Tavernkeep2").Format(Main.npc[tavernKeep].GivenName)); - - if (ChildSafety.Disabled) - dialogue.Add(this.GetLocalizedValue("Chat.Tavernkeep3")); - } - - int permadong = NPC.FindFirstNPC(ModContent.NPCType()); - if (permadong != -1) - dialogue.Add(this.GetLocalization("Chat.Archmage").Format(Main.npc[permadong].GivenName)); - - int witch = NPC.FindFirstNPC(ModContent.NPCType()); - if (witch != -1) - dialogue.Add(this.GetLocalization("Chat.BrimstoneWitch").Format(Main.npc[witch].GivenName)); - - if (wifeIsAround) - { - dialogue.Add(this.GetLocalization("Chat.Stylist1").Format(Main.npc[wife].GivenName)); - if (ChildSafety.Disabled) - { - dialogue.Add(this.GetLocalization("Chat.Stylist2").Format(Main.npc[wife].GivenName)); - dialogue.Add(this.GetLocalization("Chat.Stylist3").Format(Main.npc[wife].GivenName)); - } - } - - if (Main.dayTime) - { - dialogue.Add(this.GetLocalizedValue("Chat.Day1")); - dialogue.Add(this.GetLocalizedValue("Chat.Day2")); - dialogue.Add(this.GetLocalizedValue("Chat.Day3")); - dialogue.Add(this.GetLocalizedValue("Chat.Day4")); - - if (beLessDrunk) - { - dialogue.Add(this.GetLocalization("Chat.DayStylist1").Format(Main.npc[wife].GivenName)); - dialogue.Add(this.GetLocalization("Chat.DayStylist2").Format(Main.npc[wife].GivenName)); - } - else - { - dialogue.Add(this.GetLocalizedValue("Chat.DayDrunk1")); - dialogue.Add(this.GetLocalizedValue("Chat.DayDrunk2")); - } - } - else - { - dialogue.Add(this.GetLocalizedValue("Chat.Night1")); - dialogue.Add(this.GetLocalizedValue("Chat.Night2")); - dialogue.Add(this.GetLocalizedValue("Chat.Night3")); - dialogue.Add(this.GetLocalizedValue("Chat.Night4")); - dialogue.Add(this.GetLocalizedValue("Chat.Night5")); - - if (wifeIsAround) - dialogue.Add(this.GetLocalization("Chat.NightStylist").Format(Main.npc[wife].GivenName)); - } - - if (BirthdayParty.PartyIsUp) - dialogue.Add(this.GetLocalizedValue("Chat.Party")); - - if (AcidRainEvent.AcidRainEventIsOngoing) - dialogue.Add(this.GetLocalizedValue("Chat.AcidRain")); - - if (Main.invasionType == InvasionID.MartianMadness) - dialogue.Add(this.GetLocalizedValue("Chat.Martians")); - - if (DownedBossSystem.downedCryogen && ChildSafety.Disabled) - dialogue.Add(this.GetLocalizedValue("Chat.CryogenDefeated")); - - if (DownedBossSystem.downedLeviathan) - dialogue.Add(this.GetLocalizedValue("Chat.LeviathanDefeated")); - - if (NPC.downedMoonlord) - dialogue.Add(this.GetLocalizedValue("Chat.MoonLordDefeated")); - - if (DownedBossSystem.downedPolterghast) - dialogue.Add(this.GetLocalizedValue("Chat.PolterghastDefeated")); - - if (DownedBossSystem.downedDoG) - dialogue.Add(this.GetLocalizedValue("Chat.DoGDefeated")); - - if (player.Calamity().chibii) - dialogue.Add(this.GetLocalizedValue("Chat.HasChibii")); - - if (player.Calamity().aquaticHeart && !player.Calamity().aquaticHeartHide && ChildSafety.Disabled) - dialogue.Add(this.GetLocalizedValue("Chat.HasAnahitaTrans")); - - if (player.Calamity().fabsolVodka) - dialogue.Add(this.GetLocalizedValue("Chat.HasVodka")); - - if (player.HasItem(ModContent.ItemType())) - { - dialogue.Add(this.GetLocalizedValue("Chat.HasAlicorn1")); - dialogue.Add(this.GetLocalizedValue("Chat.HasAlicorn2")); - if (ChildSafety.Disabled) - dialogue.Add(this.GetLocalizedValue("Chat.HasAlicorn3")); - } - - return dialogue; - } - - public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color drawColor) - { - if (Main.LocalPlayer.Calamity().trippy) - return false; - - var something = NPC.direction == -1 ? SpriteEffects.None : SpriteEffects.FlipHorizontally; - spriteBatch.Draw(BirthdayParty.PartyIsUp ? AltTexture.Value : TextureAssets.Npc[NPC.type].Value, NPC.Center - screenPos + new Vector2(0, NPC.gfxOffY) - new Vector2(0f, 6f), NPC.frame, drawColor, NPC.rotation, NPC.frame.Size() / 2, NPC.scale, something, 0); - return false; - } - - public string Death() - { - int deaths = Main.player[Main.myPlayer].numberOfDeathsPVE; - - string text = this.GetLocalization("DeathCount").Format(deaths); - - if (deaths > 10000) - text += " " + this.GetLocalizedValue("Death10000"); - else if (deaths > 5000) - text += " " + this.GetLocalizedValue("Death5000"); - else if (deaths > 2500) - text += " " + this.GetLocalizedValue("Death2500"); - else if (deaths > 1000) - text += " " + this.GetLocalizedValue("Death1000"); - else if (deaths > 500) - text += " " + this.GetLocalizedValue("Death500"); - else if (deaths > 250) - text += " " + this.GetLocalizedValue("Death250"); - else if (deaths > 100) - text += " " + this.GetLocalizedValue("Death100"); - - IList donorList = new List(CalamityLists.donatorList); - int maxDonorsListed = 25; - string[] donors = new string[maxDonorsListed]; - for (int i = 0; i < maxDonorsListed; i++) - { - donors[i] = donorList[Main.rand.Next(donorList.Count)]; - donorList.Remove(donors[i]); - } - - text += ("\n\n" + this.GetLocalization("DonorShoutout").Format(donors)); - - return text; - } - - public override void SetChatButtons(ref string button, ref string button2) - { - button = Language.GetTextValue("LegacyInterface.28"); - button2 = this.GetLocalizedValue("DeathCountButton"); - } - - public override void OnChatButtonClicked(bool firstButton, ref string shopName) - { - if (firstButton) - { - shopName = "Shop"; - } - else - { - Main.npcChatText = Death(); - } - } - - public override void AddShops() - { - Mod musicMod = CalamityMod.Instance.musicMod; - musicMod.TryFind("Interlude1MusicBox", out ModItem interlude1Box); - musicMod.TryFind("Interlude2MusicBox", out ModItem interlude2Box); - musicMod.TryFind("Interlude3MusicBox", out ModItem interlude3Box); - musicMod.TryFind("DevourerofGodsEulogyMusicBox", out ModItem eulogyBox); - - NPCShop shop = new(Type); - shop.AddWithCustomValue(ItemID.LovePotion, Item.buyPrice(silver: 25), CalamityConditions.PotionSellingConfig, Condition.HappyEnough) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(silver: 30)) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 1)) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 2)) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 2)) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 2)) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 3)) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 4)) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 2), Condition.DownedMechBossAll) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 6), Condition.DownedMechBossAll) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 6), Condition.DownedMechBossAll) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 8), Condition.DownedPlantera) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 8), Condition.DownedPlantera) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 8), Condition.DownedPlantera) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 8), Condition.DownedPlantera) - .AddWithCustomValue(ItemID.EmpressButterfly, Item.buyPrice(gold: 10), Condition.DownedPlantera) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 3), CalamityConditions.DownedAstrumAureus) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 4), CalamityConditions.DownedAstrumAureus, Condition.BloodMoon) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 6), CalamityConditions.DownedAstrumAureus, Condition.TimeNight) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 2), Condition.DownedGolem) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 8), Condition.DownedGolem) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 8), Condition.DownedGolem) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 10), Condition.DownedGolem) - .AddWithCustomValue(ItemID.BloodyMoscato, Item.buyPrice(gold: 1), Condition.DownedMoonLord, Condition.NpcIsPresent(NPCID.Stylist)) - .AddWithCustomValue(ItemID.BananaDaiquiri, Item.buyPrice(silver: 75), Condition.DownedMoonLord, Condition.NpcIsPresent(NPCID.Stylist)) - .AddWithCustomValue(ItemID.PeachSangria, Item.buyPrice(silver: 50), Condition.DownedMoonLord, Condition.NpcIsPresent(NPCID.Stylist)) - .AddWithCustomValue(ItemID.PinaColada, Item.buyPrice(gold: 1), Condition.DownedMoonLord, Condition.NpcIsPresent(NPCID.Stylist)) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 50)) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 50)) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 50)) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 50)) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(1)) - .AddWithCustomValue(interlude1Box.Type, Item.buyPrice(gold: 10), CalamityConditions.DownedCalamitasClone) - .AddWithCustomValue(interlude2Box.Type, Item.buyPrice(gold: 10), Condition.DownedMoonLord) - .AddWithCustomValue(interlude3Box.Type, Item.buyPrice(gold: 10), CalamityConditions.DownedYharon) - .AddWithCustomValue(eulogyBox.Type, Item.buyPrice(gold: 10), CalamityConditions.DownedDevourerOfGods) - .AddWithCustomValue(ItemID.UnicornHorn, Item.buyPrice(0, 2, 50), Condition.HappyEnough, Condition.InHallow) - .AddWithCustomValue(ItemID.Milkshake, Item.buyPrice(gold: 5), Condition.HappyEnough, Condition.InHallow, Condition.NpcIsPresent(NPCID.Stylist)) - .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 25), Condition.HappyEnough, Condition.NpcIsPresent(NPCID.Stylist), Condition.NpcIsPresent(NPCID.BestiaryGirl)) - .Register(); - } - - // Make this Town NPC teleport to the Queen statue when triggered. - public override bool CanGoToStatue(bool toKingStatue) => !toKingStatue; - - public override void TownNPCAttackStrength(ref int damage, ref float knockback) - { - damage = 15; - knockback = 2f; - } - - public override void TownNPCAttackCooldown(ref int cooldown, ref int randExtraCooldown) - { - cooldown = 180; - randExtraCooldown = 60; - } - - public override void TownNPCAttackProj(ref int projType, ref int attackDelay) - { - projType = ModContent.ProjectileType(); - attackDelay = 1; - } - - public override void TownNPCAttackProjSpeed(ref float multiplier, ref float gravityCorrection, ref float randomOffset) - { - multiplier = 11.5f; - } - } -} diff --git a/NPCs/TownNPCs/FAP.png b/NPCs/TownNPCs/FAP.png deleted file mode 100644 index adf1db2d15cf5d2fcae6049b8ab4b1295ecaf669..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9661 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 S2>6#P4!EI(LHXIMcm59}7|@~s diff --git a/NPCs/TownNPCs/FAPAlt.png b/NPCs/TownNPCs/FAPAlt.png deleted file mode 100644 index 45895728f7aa333f132a5a9b18652f8844eb2bb7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8732 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 KMNUMnLSTYxR}~`w diff --git a/NPCs/TownNPCs/FAP_Head.png b/NPCs/TownNPCs/FAP_Head.png deleted file mode 100644 index d4b8a7cb82fb5778874906ae8e8d7206a435d07e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 632 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 bfDrha9vsI%J()); - if (cirrus != -1) - dialogue.Add(this.GetLocalization("Chat.DrunkPrincess").Format(Main.npc[cirrus].GivenName)); - int partyGirl = NPC.FindFirstNPC(NPCID.PartyGirl); if (partyGirl != -1) dialogue.Add(this.GetLocalization("Chat.PartyGirl").Format(Main.npc[partyGirl].GivenName)); diff --git a/NPCs/TownNPCs/THIEF.cs b/NPCs/TownNPCs/THIEF.cs index 94b5f94198..6265925e83 100644 --- a/NPCs/TownNPCs/THIEF.cs +++ b/NPCs/TownNPCs/THIEF.cs @@ -159,11 +159,6 @@ public override string GetChat() if (witch != -1) dialogue.Add(this.GetLocalization("Chat.BrimstoneWitch").Format(Main.npc[witch].GivenName)); - //please help me I'm stuck in a children's video game - Fabsol - int cirrusIndex = NPC.FindFirstNPC(ModContent.NPCType()); - if (cirrusIndex != -1) - dialogue.Add(this.GetLocalization("Chat.DrunkPrincess").Format(Main.npc[cirrusIndex].GivenName)); - int merchantIndex = NPC.FindFirstNPC(NPCID.Merchant); if (merchantIndex != -1) dialogue.Add(this.GetLocalization("Chat.Merchant").Format(Main.npc[merchantIndex].GivenName)); diff --git a/NPCs/TownNPCs/WITCH.cs b/NPCs/TownNPCs/WITCH.cs index beefa5a4fb..cbd9fbc1ba 100644 --- a/NPCs/TownNPCs/WITCH.cs +++ b/NPCs/TownNPCs/WITCH.cs @@ -116,10 +116,6 @@ public override string GetChat() } } - int fab = NPC.FindFirstNPC(NPCType()); - if (fab != -1 && ChildSafety.Disabled) - dialogue.Add(this.GetLocalization("Chat.DrunkPrincess").Format(Main.npc[fab].GivenName), 1.45); - if (NPC.AnyNPCs(NPCType())) dialogue.Add(this.GetLocalizedValue("Chat.SeaKing"), 1.45); diff --git a/Systems/MiscWorldStateSystem.cs b/Systems/MiscWorldStateSystem.cs index 897754c9a7..d37f9529cf 100644 --- a/Systems/MiscWorldStateSystem.cs +++ b/Systems/MiscWorldStateSystem.cs @@ -57,7 +57,6 @@ public override void ClearWorld() //Abyss.AbleToUnlockChests = false; //Yet another fucking failsave for abyss chests spawnedBandit = false; - spawnedCirrus = false; foundHomePermafrost = false; catName = false; @@ -93,8 +92,6 @@ public override void SaveWorldData(TagCompound tag) downed.Add("acidRain"); if (spawnedBandit) downed.Add("bandit"); - if (spawnedCirrus) - downed.Add("drunkPrincess"); if (foundHomePermafrost) downed.Add("archmageHome"); @@ -152,7 +149,6 @@ public override void LoadWorldData(TagCompound tag) BossRushEvent.BossRushActive = downed.Contains("bossRushActive"); AcidRainEvent.AcidRainEventIsOngoing = downed.Contains("acidRain"); spawnedBandit = downed.Contains("bandit"); - spawnedCirrus = downed.Contains("drunkPrincess"); foundHomePermafrost = downed.Contains("archmageHome"); #region Load Pet Names @@ -238,7 +234,6 @@ public override void NetSend(BinaryWriter writer) BitsByte flags5 = new BitsByte(); flags5[0] = downedAstrumDeus; flags5[1] = spawnedBandit; - flags5[2] = spawnedCirrus; flags5[3] = AcidRainEvent.HasStartedAcidicDownpour; flags5[4] = false; flags5[5] = downedPolterghast; @@ -392,7 +387,7 @@ public override void NetReceive(BinaryReader reader) BitsByte flags5 = reader.ReadByte(); downedAstrumDeus = flags5[0]; spawnedBandit = flags5[1]; - spawnedCirrus = flags5[2]; + _ = flags5[2]; AcidRainEvent.HasStartedAcidicDownpour = flags5[3]; _ = flags5[4]; downedPolterghast = flags5[5]; diff --git a/Tiles/Furniture/CraftingStations/SCalAltar.cs b/Tiles/Furniture/CraftingStations/SCalAltar.cs index 36ab9cef5e..c25a770d8d 100644 --- a/Tiles/Furniture/CraftingStations/SCalAltar.cs +++ b/Tiles/Furniture/CraftingStations/SCalAltar.cs @@ -118,7 +118,7 @@ public static bool AttemptToSummonSCal(int i, int j) Main.LocalPlayer.ConsumeItem(ModContent.ItemType(), true); for (int f = 0; f < Main.maxNPCs; f++) { - if (Main.npc[f].type == ModContent.NPCType() && Main.npc[f].active) + if (Main.npc[f].type == ModContent.NPCType() && Main.npc[f].active) { Main.npc[f].active = false; } diff --git a/World/CalamityWorld.cs b/World/CalamityWorld.cs index ae21089ff5..26e75b5508 100644 --- a/World/CalamityWorld.cs +++ b/World/CalamityWorld.cs @@ -52,7 +52,6 @@ public static bool ReflectMasterMode() // Town NPC spawn/home bools public static bool spawnedBandit = false; - public static bool spawnedCirrus = false; public static bool foundHomePermafrost = false; // Town Pet name chosen bools From 3c1a3f4a5feac3e5dbfbb32242e59b45db7ce083 Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Mon, 26 May 2025 14:17:42 -0700 Subject: [PATCH 226/401] Supreme Ultramage Permafrost --- ...rusBlueCandleBuff.cs => BlueCandleBuff.cs} | 2 +- ...sBlueCandleBuff.png => BlueCandleBuff.png} | Bin ...rusPinkCandleBuff.cs => PinkCandleBuff.cs} | 2 +- ...sPinkCandleBuff.png => PinkCandleBuff.png} | Bin ...urpleCandleBuff.cs => PurpleCandleBuff.cs} | 2 +- ...pleCandleBuff.png => PurpleCandleBuff.png} | Bin ...ellowCandleBuff.cs => YellowCandleBuff.cs} | 2 +- ...lowCandleBuff.png => YellowCandleBuff.png} | Bin CalPlayer/CalamityPlayer.cs | 2 +- CalPlayer/CalamityPlayerHitHurt.cs | 4 +- CalPlayer/CalamityPlayerLifeRegen.cs | 2 +- CalPlayer/CalamityPlayerMiscEffects.cs | 2 +- Items/AlicornonaStick.png | Bin 554 -> 0 bytes ...{AlicornonaStick.cs => ColdheartIcicle.cs} | 4 +- Items/ColdheartIcicle.png | Bin 0 -> 282 bytes Items/TreasureBags/MiscGrabBags/StarterBag.cs | 10 - .../en-US/Mods.CalamityMod.Buffs.hjson | 20 + .../en-US/Mods.CalamityMod.Items.Misc.hjson | 10 +- .../en-US/Mods.CalamityMod.NPCs.hjson | 2 +- .../Mods.CalamityMod.Projectiles.Boss.hjson | 5 + .../en-US/Mods.CalamityMod.Status.Boss.hjson | 28 +- .../en-US/Mods.CalamityMod.Vanilla.hjson | 8 +- NPCs/CalamityGlobalNPC.cs | 8 +- NPCs/SupremeCalamitas/CirrusHeadIcon.png | Bin 972 -> 0 bytes NPCs/SupremeCalamitas/CirrusHeadIcon2.png | Bin 968 -> 0 bytes NPCs/SupremeCalamitas/SupremeCalamitas.cs | 490 +++++++----------- .../SupremeCirrus_Shimmered.png | Bin 5692 -> 0 bytes ...upremeCirrus.png => SupremePermafrost.png} | Bin NPCs/TownNPCs/DILF.cs | 8 +- Projectiles/Boss/BrimstoneBarrage.cs | 6 +- Projectiles/Boss/BrimstoneHellblast.cs | 6 +- Projectiles/Boss/BrimstoneHellblast2.cs | 6 +- Projectiles/Boss/BrimstoneMonster.cs | 10 +- Projectiles/Boss/BrimstoneWave.cs | 6 +- ...cs => PermafrostAbsoluteZeroProjectile.cs} | 53 +- .../{CirrusBlast.cs => PermafrostBlast.cs} | 2 +- ...{CirrusBlaster.cs => PermafrostBlaster.cs} | 6 +- ...mTooth.cs => PermafrostColdheartIcicle.cs} | 37 +- ...latileVodkaBottle.cs => PermafrostMeat.cs} | 50 +- Projectiles/Boss/SCalBrimstoneFireblast.cs | 6 +- Projectiles/Boss/SCalBrimstoneGigablast.cs | 6 +- Projectiles/Boss/SCalRitualDrama.cs | 11 +- Projectiles/CalamityGlobalProjectile.cs | 2 +- .../DrunkCrabBackgroundScene.cs | 14 +- Skies/DrunkCrabScreenShaderData.cs | 84 +-- Skies/SCalScreenShaderData.cs | 2 +- Skies/SCalSky.cs | 16 +- Tiles/Furniture/BlueCandle.cs | 12 +- Tiles/Furniture/CraftingStations/SCalAltar.cs | 15 +- Tiles/Furniture/PinkCandle.cs | 12 +- Tiles/Furniture/PurpleCandle.cs | 12 +- Tiles/Furniture/YellowCandle.cs | 12 +- 52 files changed, 429 insertions(+), 568 deletions(-) rename Buffs/Placeables/{CirrusBlueCandleBuff.cs => BlueCandleBuff.cs} (96%) rename Buffs/Placeables/{CirrusBlueCandleBuff.png => BlueCandleBuff.png} (100%) rename Buffs/Placeables/{CirrusPinkCandleBuff.cs => PinkCandleBuff.cs} (95%) rename Buffs/Placeables/{CirrusPinkCandleBuff.png => PinkCandleBuff.png} (100%) rename Buffs/Placeables/{CirrusPurpleCandleBuff.cs => PurpleCandleBuff.cs} (96%) rename Buffs/Placeables/{CirrusPurpleCandleBuff.png => PurpleCandleBuff.png} (100%) rename Buffs/Placeables/{CirrusYellowCandleBuff.cs => YellowCandleBuff.cs} (96%) rename Buffs/Placeables/{CirrusYellowCandleBuff.png => YellowCandleBuff.png} (100%) delete mode 100644 Items/AlicornonaStick.png rename Items/{AlicornonaStick.cs => ColdheartIcicle.cs} (96%) create mode 100644 Items/ColdheartIcicle.png delete mode 100644 NPCs/SupremeCalamitas/CirrusHeadIcon.png delete mode 100644 NPCs/SupremeCalamitas/CirrusHeadIcon2.png delete mode 100644 NPCs/SupremeCalamitas/SupremeCirrus_Shimmered.png rename NPCs/SupremeCalamitas/{SupremeCirrus.png => SupremePermafrost.png} (100%) rename Projectiles/Boss/{CirrusPhotonRipperProjectile.cs => PermafrostAbsoluteZeroProjectile.cs} (78%) rename Projectiles/Boss/{CirrusBlast.cs => PermafrostBlast.cs} (98%) rename Projectiles/Boss/{CirrusBlaster.cs => PermafrostBlaster.cs} (90%) rename Projectiles/Boss/{CirrusPhotonRipperPrismTooth.cs => PermafrostColdheartIcicle.cs} (81%) rename Projectiles/Boss/{CirrusVolatileVodkaBottle.cs => PermafrostMeat.cs} (55%) diff --git a/Buffs/Placeables/CirrusBlueCandleBuff.cs b/Buffs/Placeables/BlueCandleBuff.cs similarity index 96% rename from Buffs/Placeables/CirrusBlueCandleBuff.cs rename to Buffs/Placeables/BlueCandleBuff.cs index 1080599c10..349b66274c 100644 --- a/Buffs/Placeables/CirrusBlueCandleBuff.cs +++ b/Buffs/Placeables/BlueCandleBuff.cs @@ -4,7 +4,7 @@ namespace CalamityMod.Buffs.Placeables { - public class CirrusBlueCandleBuff : ModBuff + public class BlueCandleBuff : ModBuff { public static float MoveSpeedBoost = 0.1f; public static double WingTimeBoost = 0.1D; diff --git a/Buffs/Placeables/CirrusBlueCandleBuff.png b/Buffs/Placeables/BlueCandleBuff.png similarity index 100% rename from Buffs/Placeables/CirrusBlueCandleBuff.png rename to Buffs/Placeables/BlueCandleBuff.png diff --git a/Buffs/Placeables/CirrusPinkCandleBuff.cs b/Buffs/Placeables/PinkCandleBuff.cs similarity index 95% rename from Buffs/Placeables/CirrusPinkCandleBuff.cs rename to Buffs/Placeables/PinkCandleBuff.cs index 8cf6bc1437..2da9448dab 100644 --- a/Buffs/Placeables/CirrusPinkCandleBuff.cs +++ b/Buffs/Placeables/PinkCandleBuff.cs @@ -4,7 +4,7 @@ namespace CalamityMod.Buffs.Placeables { - public class CirrusPinkCandleBuff : ModBuff + public class PinkCandleBuff : ModBuff { public static double PercentHealthPerSecond = 0.004D; diff --git a/Buffs/Placeables/CirrusPinkCandleBuff.png b/Buffs/Placeables/PinkCandleBuff.png similarity index 100% rename from Buffs/Placeables/CirrusPinkCandleBuff.png rename to Buffs/Placeables/PinkCandleBuff.png diff --git a/Buffs/Placeables/CirrusPurpleCandleBuff.cs b/Buffs/Placeables/PurpleCandleBuff.cs similarity index 96% rename from Buffs/Placeables/CirrusPurpleCandleBuff.cs rename to Buffs/Placeables/PurpleCandleBuff.cs index 3ad0e23b18..34791120d6 100644 --- a/Buffs/Placeables/CirrusPurpleCandleBuff.cs +++ b/Buffs/Placeables/PurpleCandleBuff.cs @@ -4,7 +4,7 @@ namespace CalamityMod.Buffs.Placeables { - public class CirrusPurpleCandleBuff : ModBuff + public class PurpleCandleBuff : ModBuff { public static float DefenseRatioBonus = 0.1f; diff --git a/Buffs/Placeables/CirrusPurpleCandleBuff.png b/Buffs/Placeables/PurpleCandleBuff.png similarity index 100% rename from Buffs/Placeables/CirrusPurpleCandleBuff.png rename to Buffs/Placeables/PurpleCandleBuff.png diff --git a/Buffs/Placeables/CirrusYellowCandleBuff.cs b/Buffs/Placeables/YellowCandleBuff.cs similarity index 96% rename from Buffs/Placeables/CirrusYellowCandleBuff.cs rename to Buffs/Placeables/YellowCandleBuff.cs index 1b5f9a7f96..7d67f5fdcc 100644 --- a/Buffs/Placeables/CirrusYellowCandleBuff.cs +++ b/Buffs/Placeables/YellowCandleBuff.cs @@ -5,7 +5,7 @@ namespace CalamityMod.Buffs.Placeables { - public class CirrusYellowCandleBuff : ModBuff + public class YellowCandleBuff : ModBuff { public static float ExtraChipDamageRatio = 0.07f; diff --git a/Buffs/Placeables/CirrusYellowCandleBuff.png b/Buffs/Placeables/YellowCandleBuff.png similarity index 100% rename from Buffs/Placeables/CirrusYellowCandleBuff.png rename to Buffs/Placeables/YellowCandleBuff.png diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index df2c555a04..9d841079d2 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -3710,7 +3710,7 @@ public override void PostUpdateRunSpeeds() (kamiBoost ? KamiBuff.RunAccelerationBoost : 0f) + (CobaltSet ? CobaltArmorSetChange.SpeedBoostSetBonusPercentage * 0.01f : 0f) + (silvaSet ? 0.05f : 0f) + - (blueCandle ? CirrusBlueCandleBuff.AccelerationBoost : 0f) + + (blueCandle ? BlueCandleBuff.AccelerationBoost : 0f) + (planarSpeedBoost > 0 ? (0.01f * planarSpeedBoost) : 0f) + (hasteLevel * 0.05f); diff --git a/CalPlayer/CalamityPlayerHitHurt.cs b/CalPlayer/CalamityPlayerHitHurt.cs index 47ade64d1f..fbe583aae3 100644 --- a/CalPlayer/CalamityPlayerHitHurt.cs +++ b/CalPlayer/CalamityPlayerHitHurt.cs @@ -531,7 +531,7 @@ public override void ModifyHitNPCWithItem(Item item, NPC target, ref NPC.HitModi // FinalDamage cannot be used for the intended effect because there is no way to access the actual damage of the hit CalamityGlobalNPC cgn = target.Calamity(); if (yellowCandle && cgn.DR < 0.99f && target.takenDamageMultiplier > 0.05f) - modifiers.ModifyHitInfo += CirrusYellowCandleBuff.ModifyHitInfo_Spite; + modifiers.ModifyHitInfo += YellowCandleBuff.ModifyHitInfo_Spite; // Excalibur and True Excalibur deal +100% damage to targets above 75% HP. if (item.type == ItemID.Excalibur || item.type == ItemID.TrueExcalibur) @@ -605,7 +605,7 @@ public override void ModifyHitNPCWithItem(Item item, NPC target, ref NPC.HitModi // FinalDamage cannot be used for the intended effect because there is no way to access the actual damage of the hit CalamityGlobalNPC cgn = target.Calamity(); if (yellowCandle && cgn.DR < 0.99f && target.takenDamageMultiplier > 0.05f) - modifiers.ModifyHitInfo += CirrusYellowCandleBuff.ModifyHitInfo_Spite; + modifiers.ModifyHitInfo += YellowCandleBuff.ModifyHitInfo_Spite; // Stealth strike damage multipliers are applied here. // TODO -- stealth should be its own damage class and this should be applied as player StealthDamage *= XYZ diff --git a/CalPlayer/CalamityPlayerLifeRegen.cs b/CalPlayer/CalamityPlayerLifeRegen.cs index 590e89edba..0580ea0831 100644 --- a/CalPlayer/CalamityPlayerLifeRegen.cs +++ b/CalPlayer/CalamityPlayerLifeRegen.cs @@ -736,7 +736,7 @@ public override void UpdateLifeRegen() if (pinkCandle && !noLifeRegen) { // Every frame, add up 1/60th of the healing value (0.4% max HP per second) - pinkCandleHealFraction += Player.statLifeMax2 * CirrusPinkCandleBuff.PercentHealthPerSecond / 60; + pinkCandleHealFraction += Player.statLifeMax2 * PinkCandleBuff.PercentHealthPerSecond / 60; if (pinkCandleHealFraction >= 1D) { diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index 402ff921f3..1b102a7fed 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -2863,7 +2863,7 @@ private void OtherBuffEffects() (harpyRing ? 0.2 : 0D) + (reaverSpeed ? 0.1 : 0D) + (angelTreads ? 0.1 : 0D) + - (blueCandle ? CirrusBlueCandleBuff.WingTimeBoost : 0D) + + (blueCandle ? BlueCandleBuff.WingTimeBoost : 0D) + (soaring ? 0.1 : 0D) + (prismaticGreaves ? 0.1 : 0D) + (plagueReaper ? 0.05 : 0D) + diff --git a/Items/AlicornonaStick.png b/Items/AlicornonaStick.png deleted file mode 100644 index b09e99c9341220a01b3020199a91478b31917a29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 554 zcmeAS@N?(olHy`uVBq!ia0vp^T0m^X!3-p2XY8C0q!^2X+?^QKos)S9I|cZJxJq*v|6lR4sp|Ja+ddz~gb1_h!#96_DY~BEF(=XT`W3%JdOX3o z@*Nv^=lx&$;{X5uP4XRy?v{%xV)Vq>>SJ7i#+*r)ssK`AB|(0{Kn0k9f$`FTCqNaP z1s;*b3=DjSL74G){)!Z!1N}W+978<3*IsGNYgQ0xeYkp2fP1cB<^OP5`|wBGN<1&l zJF@LSdTY1VOIMZj|B;K{W``_!Epg?-yWiPU4z81C6HGoPlkBpLvtk~T%bK-UEGORX zy?i>uu=?IIuJ*)vUkl!?cKLli&`N7=`fO%%wlgm4E^_Uiul8P4nmKQ|gYFI|E;HZn zyT$yL7qkU^Xx8iA+JF3WW-iC+MdoKDUlsLf>Zo2@r>#D3`Qsbk6YjD!97=5X7kO>= z7Qcf#C0zG}%P`Fs`NSoAT;h7^?WDf%N{T5H%p2ZjE-%@zfh+h?M0lP<>)R0SQU}2Y z`B5>-SCy`^hMs8ZJH0(Pna?BLOYs8#n(6sVr=;C>>X>*=!r4#qRDI!ruqegb3+75q zJH5EJEo{Zv`Hew(wR^V*s(s*cIxhI@@z-k(|G7nCxW8#~DedvFb9ZF "Items.Misc"; public override void SetDefaults() @@ -26,6 +27,7 @@ public override void HoldItem(Player player) { int offset = player.direction == 1 ? 5 : -Item.width - 5; Rectangle itemRect = new Rectangle((int)player.Center.X + offset, (int)player.position.Y - 10, Item.width, Item.height); + player.itemRotation = player.MountedCenter.DirectionTo(Main.MouseWorld).ToRotation(); foreach (NPC npc in Main.ActiveNPCs) { if (!npc.dontTakeDamage && npc.type != ModContent.NPCType()) diff --git a/Items/ColdheartIcicle.png b/Items/ColdheartIcicle.png new file mode 100644 index 0000000000000000000000000000000000000000..a8efd6e76925b69d91a0504dcd6ad46d6db4eec8 GIT binary patch literal 282 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM3?#3wJbMaAF%}28J29*~C-V}>VM%xNb!1@J z*w6hZkrl|73-AeX)lzfPiOlKWe&+eNe*z-nf$a-(eWUxstPAq;fJ$`k1=s*7u96_X z;Quhdu<4A>d7vm~fk$L90|Vb-5N14{zaj-FnD6Q07@`r}JHeChfC3M*^8uaz{|g># zbtr8t(PQjyQC^}e@aTExQjWG)@dpj0R%zZn${~51Y2JJm<%Xks?z?a}^ceh_XRgS! zK`!Cr>>oF}=ll#XviZ1COlfIH&xALuD@*^S76~OE)mJy1US_svD|_q)zSyO8+Hydv O89ZJ6T-G@yGywp=!e(ax literal 0 HcmV?d00001 diff --git a/Items/TreasureBags/MiscGrabBags/StarterBag.cs b/Items/TreasureBags/MiscGrabBags/StarterBag.cs index 9423468e0d..9a2c56c9eb 100644 --- a/Items/TreasureBags/MiscGrabBags/StarterBag.cs +++ b/Items/TreasureBags/MiscGrabBags/StarterBag.cs @@ -109,16 +109,6 @@ static bool getsOracleHeadphones(DropAttemptInfo info) } itemLoot.AddIf(getsOracleHeadphones, ModContent.ItemType()); - - // Fabsol dev item - // Name specific: "Fabsol" or "Cirrus" - static bool getsCrystalHeartVodka(DropAttemptInfo info) - { - string playerName = info.player.name; - return playerName is "Fabsol" or "Cirrus"; - } - - itemLoot.AddIf(getsCrystalHeartVodka, ModContent.ItemType()); } } } diff --git a/Localization/en-US/Mods.CalamityMod.Buffs.hjson b/Localization/en-US/Mods.CalamityMod.Buffs.hjson index 0bc3610158..7fbe343d4c 100644 --- a/Localization/en-US/Mods.CalamityMod.Buffs.hjson +++ b/Localization/en-US/Mods.CalamityMod.Buffs.hjson @@ -1520,3 +1520,23 @@ LiliesOfFinalityBuff: { DisplayName: Finality Description: Remember our promise } + +BlueCandleBuff: { + DisplayName: Blue Candle Buff + Description: Mods.CalamityMod.Buffs.BlueCandleBuff.Description +} + +PinkCandleBuff: { + DisplayName: Pink Candle Buff + Description: Mods.CalamityMod.Buffs.PinkCandleBuff.Description +} + +PurpleCandleBuff: { + DisplayName: Purple Candle Buff + Description: Mods.CalamityMod.Buffs.PurpleCandleBuff.Description +} + +YellowCandleBuff: { + DisplayName: Yellow Candle Buff + Description: Mods.CalamityMod.Buffs.YellowCandleBuff.Description +} diff --git a/Localization/en-US/Mods.CalamityMod.Items.Misc.hjson b/Localization/en-US/Mods.CalamityMod.Items.Misc.hjson index 119da60e37..4183dc5080 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Misc.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Misc.hjson @@ -260,11 +260,6 @@ VoodooDemonVoodooDoll: { } // Uncategorized -AlicornonaStick: { - DisplayName: Alicorn on a Stick - Tooltip: "'Congratulations, you're winner! Here's my head on a stick.'" -} - BallAndChain: { DisplayName: Ball and Chain Tooltip: @@ -284,6 +279,11 @@ BrimstoneLocus: { ''' } +ColdheartIcicle: { + DisplayName: Coldheart Icicle + Tooltip: "'Congratulations, you're winner! Here's my head on a stick.'" +} + MomentumCapacitor: { DisplayName: Momentum Capacitor Tooltip: diff --git a/Localization/en-US/Mods.CalamityMod.NPCs.hjson b/Localization/en-US/Mods.CalamityMod.NPCs.hjson index 51f110691f..c3f02514c5 100644 --- a/Localization/en-US/Mods.CalamityMod.NPCs.hjson +++ b/Localization/en-US/Mods.CalamityMod.NPCs.hjson @@ -274,9 +274,9 @@ BrimstoneHeart.DisplayName: Brimstone Heart SepulcherHead.DisplayName: Sepulcher SoulSeekerSupreme.DisplayName: Soul Seeker SupremeCalamitas.DisplayName: Supreme Witch, Calamitas -SupremeCirrus: Supreme Alchemist, Cirrus SupremeCataclysm.DisplayName: Cataclysm SupremeCatastrophe.DisplayName: Catastrophe +SupremePermafrost: Supreme Ultramage, Permafrost Yharon.DisplayName: Yharon, Dragon of Rebirth YharonPhase2: Yharon, Resplendent Phoenix // Town NPCs, Pets, etc diff --git a/Localization/en-US/Mods.CalamityMod.Projectiles.Boss.hjson b/Localization/en-US/Mods.CalamityMod.Projectiles.Boss.hjson index b9a91f0fb0..515f32c9f6 100644 --- a/Localization/en-US/Mods.CalamityMod.Projectiles.Boss.hjson +++ b/Localization/en-US/Mods.CalamityMod.Projectiles.Boss.hjson @@ -158,3 +158,8 @@ YharonBulletHellVortex.DisplayName: Bullet Hell Vortex YharonFireball.DisplayName: Dragon Fireball YharonFireball2.DisplayName: Dragon Fireball THanosSideLaser.DisplayName: T Hanos Side Laser +PermafrostAbsoluteZeroProjectile.DisplayName: Permafrost Absolute Zero Projectile +PermafrostBlast.DisplayName: Permafrost Blast +PermafrostBlaster.DisplayName: Permafrost Blaster +PermafrostColdheartIcicle.DisplayName: Permafrost Coldheart Icicle +PermafrostMeat.DisplayName: Permafrost Meat diff --git a/Localization/en-US/Mods.CalamityMod.Status.Boss.hjson b/Localization/en-US/Mods.CalamityMod.Status.Boss.hjson index c138308068..7fda7a31b1 100644 --- a/Localization/en-US/Mods.CalamityMod.Status.Boss.hjson +++ b/Localization/en-US/Mods.CalamityMod.Status.Boss.hjson @@ -102,20 +102,20 @@ SCalDesparationText1Rematch: A terrific display, I concede this match to you. SCalDesparationText2Rematch: No doubt you will face enemies stronger than I. SCalDesparationText3Rematch: I trust you will not make the same mistakes he did. SCalDesparationText4Rematch: I can't imagine what your future holds now. -// Cirrus (GFB) -CirrusSummonText: Are you prepared for a task most Sisyphean? -CirrusBirbSwarmText: Those hearts are a bit too edgy. How about a swarm of birbs instead? -CirrusBH2Text: Feelin' thirsty? I can fix that! -CirrusBH3Text: Check out this cool toy I found! -CirrusDoGText: I told you the talking worms were real! But you didn't believe me! -CirrusPhase2Text: Time for a transformation! -CirrusBH4Text: It's HAGE time! -CirrusHallowBossSpamText: I have more friends than you could possibly imagine! -CirrusBH5Text: Hah! You're good, but I'm better! -CirrusSecondBirbSwarmText: Time for another swarm! -CirrusNonchalantText: I'm getting tired... -CirrusBruhText: Just kidding! Time for my special attack! -CirrusGiveUpText: Meh, whatever, I'm a bit tired of this. +// Permafrost (GFB) +PermafrostSummonText: Are you prepared for a task most Sisyphean? +PermafrostBirbSwarmText: Those hearts were a bit too brutal for my taste. How about some lovely birds instead? +PermafrostBH2Text: Getting tired from the battle, adventurer? Hungry? How does some Delicious Meat sound? +PermafrostBH3Text: Suprised at how I am holding my own again you? I did train Calamitas, after all! +PermafrostDoGText: The serpent!? How!? What is HE doing here!? Is he here to torment me further!? Kill it, adventurer! +PermafrostPhase2Text: Ha! I suppose I can no longer be "chill" about this duel! Get it? +PermafrostBH4Text: Need a break? Can you not even keep up with an old man? +PermafrostHallowBossSpamText: You truly have grown strong! Thankfully, I and Calamitas reconstructed this to assist me. +PermafrostBH5Text: Why, it has been quite long since I have had an excuse to use these magics! +PermafrostSecondBirbSwarmText: I must say, those birds earlier were rather cute! Do some more not sound nice? +PermafrostNonchalantText: I must say, I am not the mage I used to be. This is starting to tire my old body... +PermafrostBruhText: Ha! Just kidding! Watch what happens when I cast a spell I know! +PermafrostGiveUpText: Gah, I think I pulled a muscle! Ah, well. I seems that I must concede. Well fought! // April Fools AprilFools: The LORDE is approaching... AprilFoolsGFB: La Ruga is approaching... diff --git a/Localization/en-US/Mods.CalamityMod.Vanilla.hjson b/Localization/en-US/Mods.CalamityMod.Vanilla.hjson index 5e5e6608f7..be5d739521 100644 --- a/Localization/en-US/Mods.CalamityMod.Vanilla.hjson +++ b/Localization/en-US/Mods.CalamityMod.Vanilla.hjson @@ -149,9 +149,7 @@ StylistChat: { ProfanedDonuts: Aww, they're so cute, do they have names? } -TavernkeepChat: { - FullMoon: Care for a little Moonshine? -} +TavernkeepChat.FullMoon: Care for a little Moonshine? TaxCollectorChat: { DoGDefeated: Devourer of what, you said? Devourer of Funds, if its payroll is anything to go by! @@ -161,9 +159,7 @@ TaxCollectorChat: { Has100Plat: BAH! Doesn't seem like I'll ever be able to quarrel with the debts of the town again! } -TruffleChat: { - Normal: I don't feel very safe; I think there's pigs following me around and it frightens me. -} +TruffleChat.Normal: I don't feel very safe; I think there's pigs following me around and it frightens me. WitchDoctorChat: { BloodMoon: This is as good a time as any to pick up the best ingredients for potions. diff --git a/NPCs/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index b2a4ed9359..bbf18cd77c 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -3222,17 +3222,17 @@ private void ApplyDR(NPC npc, ref NPC.HitModifiers modifiers) effectiveDR = 0f; // Calculate extra DR based on kill time, similar to the Hush boss from The Binding of Isaac - // Cirrus being active makes the extra DR cease to function - bool cirrusBossActive = false; + // Permafrost being active makes the extra DR cease to function + bool permafrostBossActive = false; if (CalamityGlobalNPC.SCal != -1) { if (Main.npc[CalamityGlobalNPC.SCal].active) - cirrusBossActive = Main.npc[CalamityGlobalNPC.SCal].ModNPC().cirrus; + permafrostBossActive = Main.npc[CalamityGlobalNPC.SCal].ModNPC().permafrost; } bool nightProvi = npc.type == NPCType() && !Main.IsItDay(); bool dayEmpress = npc.type == NPCID.HallowBoss && NPC.ShouldEmpressBeEnraged(); - if (KillTime > 0 && AITimer < KillTime && !BossRushEvent.BossRushActive && !cirrusBossActive && (nightProvi || dayEmpress)) + if (KillTime > 0 && AITimer < KillTime && !BossRushEvent.BossRushActive && !permafrostBossActive && (nightProvi || dayEmpress)) { // Set the DR scaling factor float DRScalar = 10f; diff --git a/NPCs/SupremeCalamitas/CirrusHeadIcon.png b/NPCs/SupremeCalamitas/CirrusHeadIcon.png deleted file mode 100644 index b322de98ea7123c95a0c138bfd69100beebd07d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 972 zcmV;-12g=IP)Px&Y)M2xR9J=Wm`zAjQ5462QwBvJAQ5F*Ghk_2ku3`PSh$d>30ep-Fx48 z=f3;9=l$=!&qac5=JvkupY^ea%Uy|#KO>RB{)HtaDv&$vS{Pt3KLvo)HzU$PTV5ET zE7X_}($kl)TK-l6`S?wuBa8hfeCMf%L~5b~n>Kw2XC%wl?+YyhpwVnsb?9mT3cyOU zy@cX0fRQ`^#IG7tpRkh6U4Ib(qvI3+{VPvOz|6S-cufBv@4ezj6MsHO2XX1M;|NcB zbee;WX=?yT^6vp6xte6Ia7~4x65cuqZO>^>_5uJ#8*T%T_u(}F)m)j>yG&ie54a_& z;M)X%r@I+|!Lx?|SaSXb5Fx+gSrCBxeUB#e>q*ZAz%beX*h#@OC9Jty^Qh0D28sq1u5i^{0iY}- z?csCTQdp4=fU8K?K)IGsELD@N#?^i_UNoC}gw@Zvnsv)B{kH^4juvL$K2Fj*cVzJBO9*;*3H7n$2BUjesC4Ah~8I z;%myV1blbqf~CG{|2`=!6FTF0000Px&Xh}ptR9J=0m|I8`VHC%IqgL8YHoDjvM7d=Y2Ih9tEkh`}P?;1x_>f6dM2PfI z^khL~L49S@h36ctdE}KQ0Wu|0K58oWuZyKW>iuu3HobUY4 zIs5(Rd}oF=uwi4$cKecsDQmL<@OUNx5Q)4qE!(hc0NQRo{B54=E$1{l=C|zsh&Z_s zCDK#V0H|wfFb5Myj!HHFxbiXKM432Z3 zB0m@dKrCN0fSwhaITvQBG-t6x-^0OLJg1Kgy@he$|MLNLRpx;rnc z1c22!YLX^go(n*{rG!9~S(Bpt-zicmH=?!(pk+G#8j!d z(VM#mfcPO2ieLD4$SK^qMV*%F7gdV?*FXIqVL*{L%}qdbf{HCWsA--CL{H1@N6i4N zTI$nm@z*rJ*W%?A+VczCr-*d39f7Q600e9A0+8v;x2|gEouN+676@PB?XcH#jUvXn zS;qnB?=x-R8w&DlWe21C-T=|>6gxzTuDBVF@dD|cm^i~_lQq`t2B4n=Ao@#1nVFMD zSyy#x$}1bK(7TQa>)(C{pfGQmwjK(j+#}o^%Xc^<2GeWsb<(H?knskw5pDdJ889 z{3;&xg*KvC)pw5~4b?dS+%8?DIfAvH0VqCG20&k8vF4YZClshT6uEfFxj?6iFE5)3 zfd8>xN9wyr5&MF4eXv&9Wjoc*{TWSms^ayk|4IDEhVa+wJ!5}63tXefPpFh5rTEbh qhX4Qo4rN$LW=%~1DgXcg2mk;800000(o>TF0000 HoodedTexture; - public static Asset CirrusTexture; - public static Asset CirrusTexture2; + public static Asset PermafrostTexture; public static Asset ShieldTopTexture; public static Asset ShieldBottomTexture; public static Asset ForcefieldTexture; @@ -230,8 +221,7 @@ internal static void LoadHeadIcons() { string hoodedIconPath = "CalamityMod/NPCs/SupremeCalamitas/HoodedHeadIcon"; string hoodlessIconPath = "CalamityMod/NPCs/SupremeCalamitas/HoodlessHeadIcon"; - string cirrusIconPath = "CalamityMod/NPCs/SupremeCalamitas/CirrusHeadIcon"; - string cirrusIconP2Path = "CalamityMod/NPCs/SupremeCalamitas/CirrusHeadIcon2"; + string permafrostIconPath = "CalamityMod/NPCs/TownNPCs/DILF_Head"; CalamityMod.Instance.AddBossHeadTexture(hoodedIconPath, -1); hoodedHeadIconIndex = ModContent.GetModBossHeadSlot(hoodedIconPath); @@ -239,11 +229,8 @@ internal static void LoadHeadIcons() CalamityMod.Instance.AddBossHeadTexture(hoodlessIconPath, -1); hoodlessHeadIconIndex = ModContent.GetModBossHeadSlot(hoodlessIconPath); - CalamityMod.Instance.AddBossHeadTexture(cirrusIconPath, -1); - cirrusHeadIconIndex = ModContent.GetModBossHeadSlot(cirrusIconPath); - - CalamityMod.Instance.AddBossHeadTexture(cirrusIconP2Path, -1); - cirrusHeadIconP2Index = ModContent.GetModBossHeadSlot(cirrusIconP2Path); + CalamityMod.Instance.AddBossHeadTexture(permafrostIconPath, -1); + permafrostHeadIconIndex = ModContent.GetModBossHeadSlot(permafrostIconPath); } public override void SetStaticDefaults() @@ -260,8 +247,7 @@ public override void SetStaticDefaults() if (!Main.dedServ) { HoodedTexture = ModContent.Request(Texture + "Hooded", AssetRequestMode.AsyncLoad); - CirrusTexture = ModContent.Request("CalamityMod/NPCs/SupremeCalamitas/SupremeCirrus", AssetRequestMode.AsyncLoad); - CirrusTexture2 = ModContent.Request("CalamityMod/NPCs/SupremeCalamitas/SupremeCirrus_Shimmered", AssetRequestMode.AsyncLoad); + PermafrostTexture = ModContent.Request("CalamityMod/NPCs/SupremeCalamitas/SupremePermafrost", AssetRequestMode.AsyncLoad); ShieldTopTexture = ModContent.Request("CalamityMod/NPCs/SupremeCalamitas/SupremeShieldTop", AssetRequestMode.AsyncLoad); ShieldBottomTexture = ModContent.Request("CalamityMod/NPCs/SupremeCalamitas/SupremeShieldBottom", AssetRequestMode.AsyncLoad); ForcefieldTexture = ModContent.Request("CalamityMod/NPCs/SupremeCalamitas/ForcefieldTexture", AssetRequestMode.AsyncLoad); @@ -304,9 +290,9 @@ public override void SetBestiary(BestiaryDatabase database, BestiaryEntry bestia public override void BossHeadSlot(ref int index) { bool inPhase2 = NPC.ai[0] == 3f; - if (cirrus) + if (permafrost) { - index = inPhase2 ? cirrusHeadIconP2Index : cirrusHeadIconIndex; + index = permafrostHeadIconIndex; } else { @@ -319,8 +305,8 @@ public override void BossHeadSlot(ref int index) public override void ModifyTypeName(ref string typeName) { - if (cirrus) - typeName = CalamityUtils.GetTextValue("NPCs.SupremeCirrus"); + if (permafrost) + typeName = CalamityUtils.GetTextValue("NPCs.SupremePermafrost"); } public override void SendExtraAI(BinaryWriter writer) @@ -348,7 +334,7 @@ public override void SendExtraAI(BinaryWriter writer) writer.Write(spawnArena); writer.Write(hasSummonedBrothers); writer.Write(enteredBrothersPhase); - writer.Write(cirrus); + writer.Write(permafrost); writer.Write(NPC.dontTakeDamage); writer.Write(NPC.chaseable); @@ -400,7 +386,7 @@ public override void ReceiveExtraAI(BinaryReader reader) spawnArena = reader.ReadBoolean(); hasSummonedBrothers = reader.ReadBoolean(); enteredBrothersPhase = reader.ReadBoolean(); - cirrus = reader.ReadBoolean(); + permafrost = reader.ReadBoolean(); NPC.dontTakeDamage = reader.ReadBoolean(); NPC.chaseable = reader.ReadBoolean(); @@ -466,8 +452,8 @@ public override void AI() // Used for Scal's teleport at the start of brothers phase bool teleport = false; - // cirrus and zenith scal are mutually exclusive unless it's legendary - bool zenithAI = Main.zenithWorld && (!cirrus || (CalamityWorld.LegendaryMode && revenge && cirrus)); + // permafrost and zenith scal are mutually exclusive unless it's legendary + bool zenithAI = Main.zenithWorld && (!permafrost || (CalamityWorld.LegendaryMode && revenge && permafrost)); // Percent life remaining float lifeRatio = NPC.life / (float)NPC.lifeMax; @@ -522,11 +508,11 @@ public override void AI() if (!bossRush) { string key = "Mods.CalamityMod.Status.Boss.SCalSummonText"; - if (cirrus) - key = "Mods.CalamityMod.Status.Boss.CirrusSummonText"; + if (permafrost) + key = "Mods.CalamityMod.Status.Boss.PermafrostSummonText"; else if (DownedBossSystem.downedCalamitas) key += "Rematch"; - CalamityUtils.DisplayLocalizedText(key, cirrus ? cirrusTextColor : textColor); + CalamityUtils.DisplayLocalizedText(key, permafrost ? permafrostTextColor : textColor); } startText = true; } @@ -561,7 +547,7 @@ public override void AI() if (NPC.Size != hitboxSize) NPC.Size = hitboxSize; bool shouldNotUseShield = bulletHellCounter2 % BulletHellDuration != 0 || attackCastDelay > 0 || - (cirrus ? NPC.AnyNPCs(ModContent.NPCType()) : (NPC.AnyNPCs(ModContent.NPCType()) || NPC.AnyNPCs(ModContent.NPCType()))) || + (permafrost ? NPC.AnyNPCs(ModContent.NPCType()) : (NPC.AnyNPCs(ModContent.NPCType()) || NPC.AnyNPCs(ModContent.NPCType()))) || NPC.ai[0] == 1f || NPC.ai[0] == 2f; // Make the shield and forcefield fade away in SCal's acceptance phase. @@ -586,7 +572,7 @@ public override void AI() shieldRotation = shieldRotation.AngleTowards(idealRotation, 0.18f); } } - else if (!cirrus) + else if (!permafrost) { // Emit dust off the skull at the position of its eye socket. for (float num6 = 1f; num6 < 16f; num6 += 1f) @@ -712,8 +698,8 @@ public override void AI() } NPC.Calamity().CurrentlyEnraged = !player.Hitbox.Intersects(safeBox); - // Cirrus fucks mounts if you exit her arena. - if (cirrus) + // Permafrost fucks mounts if you exit his arena. + if (permafrost) { if (!player.Hitbox.Intersects(safeBox) && player.mount.Active) { @@ -793,12 +779,12 @@ public override void AI() if (DownedBossSystem.downedCalamitas && !bossRush) { // Create a teleport line effect - Dust.QuickDustLine(NPC.Center, initialRitualPosition, 500f, cirrus ? Color.Pink : Color.Red); + Dust.QuickDustLine(NPC.Center, initialRitualPosition, 500f, permafrost ? Color.Pink : Color.Red); NPC.Center = initialRitualPosition; // Make the town NPC spawn. if (Main.netMode != NetmodeID.MultiplayerClient) - NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y + 12, cirrus ? ModContent.NPCType() : ModContent.NPCType()); + NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y + 12, permafrost ? ModContent.NPCType() : ModContent.NPCType()); } NPC.active = false; @@ -808,7 +794,7 @@ public override void AI() for (int i = 0; i < MathHelper.Lerp(2f, 6f, 1f - NPC.Opacity); i++) { Dust brimstoneFire = Dust.NewDustPerfect(NPC.Center + Main.rand.NextVector2Square(-24f, 24f), DustID.Torch); - brimstoneFire.color = cirrus ? Color.Pink : Color.Red; + brimstoneFire.color = permafrost ? Color.Pink : Color.Red; brimstoneFire.velocity = Vector2.UnitY * -Main.rand.NextFloat(2f, 3.25f); brimstoneFire.scale = Main.rand.NextFloat(0.95f, 1.15f); brimstoneFire.noGravity = true; @@ -904,9 +890,9 @@ public override void AI() { attackCastDelay = sepulcherSpawnCastTime; - Particle pulse = new DirectionalPulseRing(NPC.Center, Vector2.Zero, cirrus ? Color.Pink : Color.Red, new Vector2(1f, 1f), 0, 0.1f, 5f, 15); + Particle pulse = new DirectionalPulseRing(NPC.Center, Vector2.Zero, permafrost ? Color.Pink : Color.Red, new Vector2(1f, 1f), 0, 0.1f, 5f, 15); GeneralParticleHandler.SpawnParticle(pulse); - Particle pulse2 = new DirectionalPulseRing(NPC.Center, Vector2.Zero, cirrus ? Color.Pink : Color.Lerp(Color.Red, Color.Magenta, 0.3f), new Vector2(1f, 1f), 0, 0.05f, 4f, 18); + Particle pulse2 = new DirectionalPulseRing(NPC.Center, Vector2.Zero, permafrost ? Color.Pink : Color.Lerp(Color.Red, Color.Magenta, 0.3f), new Vector2(1f, 1f), 0, 0.05f, 4f, 18); GeneralParticleHandler.SpawnParticle(pulse2); for (int i = 0; i < 100; i++) { @@ -952,9 +938,9 @@ public override void AI() failShotDust.velocity = dustVel * Main.rand.NextFloat(0.3f, 1.3f); failShotDust.scale = Main.rand.NextFloat(2f, 3.2f); } - Particle pulse = new DirectionalPulseRing(NPC.Center, Vector2.Zero, cirrus ? Color.Pink : Color.Red, new Vector2(1f, 1f), 0, 0.1f, 5f, 15); + Particle pulse = new DirectionalPulseRing(NPC.Center, Vector2.Zero, permafrost ? Color.Pink : Color.Red, new Vector2(1f, 1f), 0, 0.1f, 5f, 15); GeneralParticleHandler.SpawnParticle(pulse); - Particle pulse2 = new DirectionalPulseRing(NPC.Center, Vector2.Zero, cirrus ? Color.Pink : Color.Lerp(Color.Red, Color.Magenta, 0.3f), new Vector2(1f, 1f), 0, 0.05f, 4f, 18); + Particle pulse2 = new DirectionalPulseRing(NPC.Center, Vector2.Zero, permafrost ? Color.Pink : Color.Lerp(Color.Red, Color.Magenta, 0.3f), new Vector2(1f, 1f), 0, 0.05f, 4f, 18); GeneralParticleHandler.SpawnParticle(pulse2); SoundEngine.PlaySound(BulletHellEndSound, NPC.Center); @@ -966,14 +952,14 @@ public override void AI() if (Main.netMode != NetmodeID.MultiplayerClient) { - // Cirrus throws alcohol bottles that explode into Fabstaff Rays - if (cirrus) + // Permafrost throws delicious meat that explode into more meat which doesn't split + if (permafrost) { if (bulletHellCounter2 % 90 == 0) { float bottleSpeed = 12f; Vector2 bottleVelocity = (player.Center + player.velocity * 20f - NPC.Center).SafeNormalize(Vector2.UnitY) * bottleSpeed; - Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center, bottleVelocity * uDieLul, ModContent.ProjectileType(), 350, 0f, Main.myPlayer, 0f, 2f); + Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center, bottleVelocity * uDieLul, ModContent.ProjectileType(), 350, 0f, Main.myPlayer, 0f, 2f); } } @@ -1027,7 +1013,7 @@ public override void AI() if (!startSecondAttack && lifeRatio <= 0.75f) { // Bouncy Boulders - if (cirrus) + if (permafrost) { if (Main.netMode != NetmodeID.MultiplayerClient) { @@ -1042,12 +1028,12 @@ public override void AI() if (!bossRush) { string key = "Mods.CalamityMod.Status.Boss.SCalBH2Text"; - if (cirrus) - key = "Mods.CalamityMod.Status.Boss.CirrusBH2Text"; + if (permafrost) + key = "Mods.CalamityMod.Status.Boss.PermafrostBH2Text"; else if (DownedBossSystem.downedCalamitas) key += "Rematch"; - CalamityUtils.DisplayLocalizedText(key, cirrus ? cirrusTextColor : textColor); + CalamityUtils.DisplayLocalizedText(key, permafrost ? permafrostTextColor : textColor); } startSecondAttack = true; @@ -1083,23 +1069,23 @@ public override void AI() failShotDust.velocity = dustVel * Main.rand.NextFloat(0.3f, 1.3f); failShotDust.scale = Main.rand.NextFloat(2f, 3.2f); } - Particle pulse = new DirectionalPulseRing(NPC.Center, Vector2.Zero, cirrus ? Color.Pink : Color.Red, new Vector2(1f, 1f), 0, 0.1f, 5f, 15); + Particle pulse = new DirectionalPulseRing(NPC.Center, Vector2.Zero, permafrost ? Color.Pink : Color.Red, new Vector2(1f, 1f), 0, 0.1f, 5f, 15); GeneralParticleHandler.SpawnParticle(pulse); - Particle pulse2 = new DirectionalPulseRing(NPC.Center, Vector2.Zero, cirrus ? Color.Pink : Color.Lerp(Color.Red, Color.Magenta, 0.3f), new Vector2(1f, 1f), 0, 0.05f, 4f, 18); + Particle pulse2 = new DirectionalPulseRing(NPC.Center, Vector2.Zero, permafrost ? Color.Pink : Color.Lerp(Color.Red, Color.Magenta, 0.3f), new Vector2(1f, 1f), 0, 0.05f, 4f, 18); GeneralParticleHandler.SpawnParticle(pulse2); SoundEngine.PlaySound(BulletHellEndSound, NPC.Center); } #endregion - if (cirrus) + if (permafrost) { Vector2 destination = player.Center; Vector2 distanceFromDestination = destination - NPC.Center; - Vector2 desiredVelocity = (distanceFromDestination - NPC.velocity).SafeNormalize(Vector2.UnitY) * CirrusPhotonRipperDashVelocity; + Vector2 desiredVelocity = (distanceFromDestination - NPC.velocity).SafeNormalize(Vector2.UnitY) * PermafrostPhotonRipperDashVelocity; - if (Vector2.Distance(NPC.Center, destination) > CirrusPhotonRipperMinDistanceFromTarget) - NPC.SimpleFlyMovement(desiredVelocity * uDieLul, CirrusPhotonRipperDashAcceleration * uDieLul); + if (Vector2.Distance(NPC.Center, destination) > PermafrostPhotonRipperMinDistanceFromTarget) + NPC.SimpleFlyMovement(desiredVelocity * uDieLul, PermafrostPhotonRipperDashAcceleration * uDieLul); else NPC.velocity *= 0.9f; } @@ -1108,9 +1094,9 @@ public override void AI() if (Main.netMode != NetmodeID.MultiplayerClient) { - // Cirrus uses Photon Ripper - if (bulletHellCounter2 == SecondBulletHellEndValue + 1 && cirrus) - Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center, Vector2.One, ModContent.ProjectileType(), CirrusPhotonRipperDamage, 0f, Main.myPlayer, 0f, 0f, NPC.whoAmI); + // Permafrost uses Photon Ripper + if (bulletHellCounter2 == SecondBulletHellEndValue + 1 && permafrost) + Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center, Vector2.One, ModContent.ProjectileType(), PermafrostPhotonRipperDamage, 0f, Main.myPlayer, 0f, 0f, NPC.whoAmI); if (bulletHellCounter2 % 180 == 0) // Blasts from top Projectile.NewProjectile(NPC.GetSource_FromAI(), player.position.X + Main.rand.Next(-1000, 1001), player.position.Y - 1000f, 0f, 5f * uDieLul, fireblast, fireblastDamage, 0f, Main.myPlayer, 0f, 2f); @@ -1152,7 +1138,7 @@ public override void AI() if (!startThirdAttack && lifeRatio <= 0.5f) { // Bouncy Boulders - if (cirrus) + if (permafrost) { if (Main.netMode != NetmodeID.MultiplayerClient) { @@ -1167,12 +1153,12 @@ public override void AI() if (!bossRush) { string key = "Mods.CalamityMod.Status.Boss.SCalBH3Text"; - if (cirrus) - key = "Mods.CalamityMod.Status.Boss.CirrusBH3Text"; + if (permafrost) + key = "Mods.CalamityMod.Status.Boss.PermafrostBH3Text"; else if (DownedBossSystem.downedCalamitas) key += "Rematch"; - CalamityUtils.DisplayLocalizedText(key, cirrus ? cirrusTextColor : textColor); + CalamityUtils.DisplayLocalizedText(key, permafrost ? permafrostTextColor : textColor); } startThirdAttack = true; @@ -1195,9 +1181,9 @@ public override void AI() } if (musicSyncCounter == 0 && !postMusicHit) { - Particle pulse = new DirectionalPulseRing(NPC.Center, Vector2.Zero, cirrus ? Color.Pink : Color.Red, new Vector2(1f, 1f), 0, 0.1f, 4f, 17); + Particle pulse = new DirectionalPulseRing(NPC.Center, Vector2.Zero, permafrost ? Color.Pink : Color.Red, new Vector2(1f, 1f), 0, 0.1f, 4f, 17); GeneralParticleHandler.SpawnParticle(pulse); - Particle pulse2 = new DirectionalPulseRing(NPC.Center, Vector2.Zero, cirrus ? Color.Pink : Color.Lerp(Color.Red, Color.Magenta, 0.3f), new Vector2(1f, 1f), 0, 0.05f, 3f, 19); + Particle pulse2 = new DirectionalPulseRing(NPC.Center, Vector2.Zero, permafrost ? Color.Pink : Color.Lerp(Color.Red, Color.Magenta, 0.3f), new Vector2(1f, 1f), 0, 0.05f, 3f, 19); GeneralParticleHandler.SpawnParticle(pulse2); for (int i = 0; i < 30; i++) { @@ -1259,9 +1245,9 @@ public override void AI() failShotDust.velocity = dustVel * Main.rand.NextFloat(0.3f, 1.3f); failShotDust.scale = Main.rand.NextFloat(2f, 3.2f); } - Particle pulse = new DirectionalPulseRing(NPC.Center, Vector2.Zero, cirrus ? Color.Pink : Color.Red, new Vector2(1f, 1f), 0, 0.1f, 5f, 15); + Particle pulse = new DirectionalPulseRing(NPC.Center, Vector2.Zero, permafrost ? Color.Pink : Color.Red, new Vector2(1f, 1f), 0, 0.1f, 5f, 15); GeneralParticleHandler.SpawnParticle(pulse); - Particle pulse2 = new DirectionalPulseRing(NPC.Center, Vector2.Zero, cirrus ? Color.Pink : Color.Lerp(Color.Red, Color.Magenta, 0.3f), new Vector2(1f, 1f), 0, 0.05f, 4f, 18); + Particle pulse2 = new DirectionalPulseRing(NPC.Center, Vector2.Zero, permafrost ? Color.Pink : Color.Lerp(Color.Red, Color.Magenta, 0.3f), new Vector2(1f, 1f), 0, 0.05f, 4f, 18); GeneralParticleHandler.SpawnParticle(pulse2); SoundEngine.PlaySound(BulletHellEndSound, NPC.Center); @@ -1273,14 +1259,14 @@ public override void AI() if (Main.netMode != NetmodeID.MultiplayerClient) // More clustered attack { - // Cirrus throws alcohol bottles that explode into Fabstaff Rays - if (cirrus) + // Permafrost throws delicious meat that explode into more delicious meat that doesn't split + if (permafrost) { if (bulletHellCounter2 % 90 == 0) { float bottleSpeed = 12f; Vector2 bottleVelocity = (player.Center + player.velocity * 20f - NPC.Center).SafeNormalize(Vector2.UnitY) * bottleSpeed; - Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center, bottleVelocity * uDieLul, ModContent.ProjectileType(), 125, 0f, Main.myPlayer, 0f, 2f); + Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center, bottleVelocity * uDieLul, ModContent.ProjectileType(), 125, 0f, Main.myPlayer, 0f, 2f); } } @@ -1309,14 +1295,14 @@ public override void AI() { for (int i = 0; i < 90; i++) { - Dust spawnDust = Dust.NewDustPerfect(safeBox.Center(), cirrus ? (int)CalamityDusts.PurpleCosmilite : (int)CalamityDusts.Brimstone, new Vector2(30, 30).RotatedByRandom(100) * Main.rand.NextFloat(0.05f, 1.2f)); + Dust spawnDust = Dust.NewDustPerfect(safeBox.Center(), permafrost ? DustID.IceGolem : (int)CalamityDusts.Brimstone, new Vector2(30, 30).RotatedByRandom(100) * Main.rand.NextFloat(0.05f, 1.2f)); spawnDust.noGravity = true; spawnDust.scale = Main.rand.NextFloat(1.2f, 2.3f); } for (int i = 0; i < 40; i++) { Vector2 sparkVel = new Vector2(20, 20).RotatedByRandom(100) * Main.rand.NextFloat(0.1f, 1.1f); - GlowOrbParticle orb = new GlowOrbParticle(safeBox.Center() + sparkVel * 2, sparkVel, false, 120, Main.rand.NextFloat(1.55f, 2.75f), cirrus ? Color.Magenta : Color.Lerp(Color.Red, Color.Magenta, 0.3f), true, true); + GlowOrbParticle orb = new GlowOrbParticle(safeBox.Center() + sparkVel * 2, sparkVel, false, 120, Main.rand.NextFloat(1.55f, 2.75f), permafrost ? Color.Magenta : Color.Lerp(Color.Red, Color.Magenta, 0.3f), true, true); GeneralParticleHandler.SpawnParticle(orb); } @@ -1357,7 +1343,7 @@ public override void AI() if (!startFourthAttack && lifeRatio <= 0.3f) { // Bouncy Boulders - if (cirrus) + if (permafrost) { if (Main.netMode != NetmodeID.MultiplayerClient) { @@ -1372,12 +1358,12 @@ public override void AI() if (!bossRush) { string key = "Mods.CalamityMod.Status.Boss.SCalBH4Text"; - if (cirrus) - key = "Mods.CalamityMod.Status.Boss.CirrusBH4Text"; + if (permafrost) + key = "Mods.CalamityMod.Status.Boss.PermafrostBH4Text"; else if (DownedBossSystem.downedCalamitas) key += "Rematch"; - CalamityUtils.DisplayLocalizedText(key, cirrus ? cirrusTextColor : textColor); + CalamityUtils.DisplayLocalizedText(key, permafrost ? permafrostTextColor : textColor); } startFourthAttack = true; @@ -1413,23 +1399,23 @@ public override void AI() failShotDust.velocity = dustVel * Main.rand.NextFloat(0.3f, 1.3f); failShotDust.scale = Main.rand.NextFloat(2f, 3.2f); } - Particle pulse = new DirectionalPulseRing(NPC.Center, Vector2.Zero, cirrus ? Color.Pink : Color.Red, new Vector2(1f, 1f), 0, 0.1f, 5f, 15); + Particle pulse = new DirectionalPulseRing(NPC.Center, Vector2.Zero, permafrost ? Color.Pink : Color.Red, new Vector2(1f, 1f), 0, 0.1f, 5f, 15); GeneralParticleHandler.SpawnParticle(pulse); - Particle pulse2 = new DirectionalPulseRing(NPC.Center, Vector2.Zero, cirrus ? Color.Pink : Color.Lerp(Color.Red, Color.Magenta, 0.3f), new Vector2(1f, 1f), 0, 0.05f, 4f, 18); + Particle pulse2 = new DirectionalPulseRing(NPC.Center, Vector2.Zero, permafrost ? Color.Pink : Color.Lerp(Color.Red, Color.Magenta, 0.3f), new Vector2(1f, 1f), 0, 0.05f, 4f, 18); GeneralParticleHandler.SpawnParticle(pulse2); SoundEngine.PlaySound(BulletHellEndSound, NPC.Center); } #endregion - if (cirrus) + if (permafrost) { Vector2 destination = player.Center; Vector2 distanceFromDestination = destination - NPC.Center; - Vector2 desiredVelocity = (distanceFromDestination - NPC.velocity).SafeNormalize(Vector2.UnitY) * CirrusPhotonRipperDashVelocity; + Vector2 desiredVelocity = (distanceFromDestination - NPC.velocity).SafeNormalize(Vector2.UnitY) * PermafrostPhotonRipperDashVelocity; - if (Vector2.Distance(NPC.Center, destination) > CirrusPhotonRipperMinDistanceFromTarget) - NPC.SimpleFlyMovement(desiredVelocity * uDieLul, CirrusPhotonRipperDashAcceleration * uDieLul); + if (Vector2.Distance(NPC.Center, destination) > PermafrostPhotonRipperMinDistanceFromTarget) + NPC.SimpleFlyMovement(desiredVelocity * uDieLul, PermafrostPhotonRipperDashAcceleration * uDieLul); else NPC.velocity *= 0.9f; } @@ -1438,18 +1424,18 @@ public override void AI() if (Main.netMode != NetmodeID.MultiplayerClient) { - // Cirrus throws alcohol bottles that explode into Fabstaff Rays - if (cirrus) + // Permafrost throws delicious meat that explode into more delicious meat that doesn't split + if (permafrost) { - // Cirrus uses Photon Ripper + // Permafrost uses Photon Ripper if (bulletHellCounter2 == FourthBulletHellEndValue + 1) - Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center, Vector2.One, ModContent.ProjectileType(), CirrusPhotonRipperDamage, 0f, Main.myPlayer, 0f, 0f, NPC.whoAmI); + Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center, Vector2.One, ModContent.ProjectileType(), PermafrostPhotonRipperDamage, 0f, Main.myPlayer, 0f, 0f, NPC.whoAmI); if (bulletHellCounter2 % 90 == 0) { float bottleSpeed = 12f; Vector2 bottleVelocity = (player.Center + player.velocity * 20f - NPC.Center).SafeNormalize(Vector2.UnitY) * bottleSpeed; - Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center, bottleVelocity * uDieLul, ModContent.ProjectileType(), 125, 0f, Main.myPlayer); + Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center, bottleVelocity * uDieLul, ModContent.ProjectileType(), 125, 0f, Main.myPlayer); } } @@ -1504,7 +1490,7 @@ public override void AI() if (!startFifthAttack && lifeRatio <= 0.1f) { // Bouncy Boulders - if (cirrus) + if (permafrost) { if (Main.netMode != NetmodeID.MultiplayerClient) { @@ -1517,15 +1503,15 @@ public override void AI() } string key = "Mods.CalamityMod.Status.Boss.SCalBH5Text"; - if (cirrus) - key = "Mods.CalamityMod.Status.Boss.CirrusBH5Text"; + if (permafrost) + key = "Mods.CalamityMod.Status.Boss.PermafrostBH5Text"; if (!bossRush) { - if (DownedBossSystem.downedCalamitas && !cirrus) + if (DownedBossSystem.downedCalamitas && !permafrost) key += "Rematch"; - CalamityUtils.DisplayLocalizedText(key, cirrus ? cirrusTextColor : textColor); + CalamityUtils.DisplayLocalizedText(key, permafrost ? permafrostTextColor : textColor); } startFifthAttack = true; @@ -1537,7 +1523,7 @@ public override void AI() { if (gettingTired5) { - if (cirrus) + if (permafrost) { if (giveUpCounter > 1) { @@ -1550,7 +1536,7 @@ public override void AI() if (blasterTimer % blasterDivisor == 0) { if (Main.netMode != NetmodeID.MultiplayerClient) - Projectile.NewProjectile(NPC.GetSource_FromAI(), circleOffset, player.Center, ModContent.ProjectileType(), 350, 0f, Main.myPlayer, 0f, 1f); + Projectile.NewProjectile(NPC.GetSource_FromAI(), circleOffset, player.Center, ModContent.ProjectileType(), 350, 0f, Main.myPlayer, 0f, 1f); } int beamDivisor = 60; @@ -1565,12 +1551,13 @@ public override void AI() for (int k = 0; k < totalProjectiles; k++) { Vector2 rayVelocity = spinningPoint.RotatedBy(radians * k); - int proj = Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center + (rayVelocity).SafeNormalize(Vector2.UnitY) * 16f, rayVelocity, ModContent.ProjectileType(), 250, 0f, Main.myPlayer); + int proj = Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center + (rayVelocity).SafeNormalize(Vector2.UnitY) * 16f, rayVelocity, ModContent.ProjectileType(), 250, 0f, Main.myPlayer); if (proj.WithinBounds(Main.maxProjectiles)) { Main.projectile[proj].DamageType = DamageClass.Default; Main.projectile[proj].friendly = false; Main.projectile[proj].hostile = true; + Main.projectile[proj].tileCollide = false; } } } @@ -1585,7 +1572,7 @@ public override void AI() if (giveUpCounter == 1) { NPC.velocity = Vector2.Zero; - CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Status.Boss.CirrusGiveUpText", cirrusTextColor); + CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Status.Boss.PermafrostGiveUpText", permafrostTextColor); Dust.QuickDustLine(NPC.Center, initialRitualPosition, 500f, Color.Pink); NPC.Center = initialRitualPosition; giveUpCounter--; @@ -1605,6 +1592,13 @@ public override void AI() NPC.active = false; NPC.netUpdate = true; NPC.NPCLoot(); + + int cryo = NPC.FindFirstNPC(ModContent.NPCType()); + if (cryo > -1) + { + Main.npc[cryo].active = false; + Main.npc[cryo].netUpdate = true; + } } return; @@ -1627,7 +1621,7 @@ public override void AI() if (!hasDoneDeathAnim && !bossRush) // Scrapped death animation for Scal { attackPause = 5; - Dust.QuickDustLine(NPC.Center, safeBox.Center() + new Vector2(0, -30), 500f, cirrus ? Color.Pink : Color.Red); + Dust.QuickDustLine(NPC.Center, safeBox.Center() + new Vector2(0, -30), 500f, permafrost ? Color.Pink : Color.Red); NPC.Center = safeBox.Center() + new Vector2(0, -30); NPC.velocity = new Vector2(10 * NPC.spriteDirection, -7); hasDoneDeathAnim = true; @@ -1639,7 +1633,7 @@ public override void AI() // Teleport back to the arena on defeat if (giveUpCounter == GiveUpCounterMax) { - Dust.QuickDustLine(NPC.Center, initialRitualPosition + new Vector2(0, -30), 500f, cirrus ? Color.Pink : Color.Red); + Dust.QuickDustLine(NPC.Center, initialRitualPosition + new Vector2(0, -30), 500f, permafrost ? Color.Pink : Color.Red); NPC.Center = initialRitualPosition + new Vector2(0, -30); NPC.noTileCollide = false; NPC.noGravity = false; @@ -1729,7 +1723,7 @@ public override void AI() for (int i = 0; i < 24; i++) { Dust brimstoneFire = Dust.NewDustPerfect(NPC.Center + Main.rand.NextVector2Square(-24f, 24f), DustID.Torch); - brimstoneFire.color = cirrus ? Color.Pink : Color.Red; + brimstoneFire.color = permafrost ? Color.Pink : Color.Red; brimstoneFire.velocity = Vector2.UnitY * -Main.rand.NextFloat(2f, 3.25f); brimstoneFire.scale = Main.rand.NextFloat(0.95f, 1.15f); brimstoneFire.fadeIn = 1.25f; @@ -1766,7 +1760,7 @@ public override void AI() for (int i = 0; i < 24; i++) { Dust brimstoneFire = Dust.NewDustPerfect(NPC.Center + Main.rand.NextVector2Square(-24f, 24f), DustID.Torch); - brimstoneFire.color = cirrus ? Color.Pink : Color.Red; + brimstoneFire.color = permafrost ? Color.Pink : Color.Red; brimstoneFire.velocity = Vector2.UnitY * -Main.rand.NextFloat(2f, 3.25f); brimstoneFire.scale = Main.rand.NextFloat(0.95f, 1.15f); brimstoneFire.fadeIn = 1.25f; @@ -1819,12 +1813,12 @@ public override void AI() if (!bossRush) { string key = "Mods.CalamityMod.Status.Boss.SCalDesparationText4"; - if (cirrus) - key = "Mods.CalamityMod.Status.Boss.CirrusBruhText"; + if (permafrost) + key = "Mods.CalamityMod.Status.Boss.PermafrostBruhText"; else if (DownedBossSystem.downedCalamitas) key += "Rematch"; - CalamityUtils.DisplayLocalizedText(key, cirrus ? cirrusTextColor : textColor); + CalamityUtils.DisplayLocalizedText(key, permafrost ? permafrostTextColor : textColor); } gettingTired5 = true; @@ -1832,7 +1826,7 @@ public override void AI() } else if (!gettingTired4 && lifeRatio <= 0.02f) { - if (!bossRush && !cirrus) + if (!bossRush && !permafrost) { string key = "Mods.CalamityMod.Status.Boss.SCalDesparationText3"; if (DownedBossSystem.downedCalamitas) @@ -1846,7 +1840,7 @@ public override void AI() } else if (!gettingTired3 && lifeRatio <= 0.04f) { - if (!bossRush && !cirrus) + if (!bossRush && !permafrost) { string key = "Mods.CalamityMod.Status.Boss.SCalDesparationText2"; if (DownedBossSystem.downedCalamitas) @@ -1863,12 +1857,12 @@ public override void AI() if (!bossRush) { string key = "Mods.CalamityMod.Status.Boss.SCalDesparationText1"; - if (cirrus) - key = "Mods.CalamityMod.Status.Boss.CirrusNonchalantText"; + if (permafrost) + key = "Mods.CalamityMod.Status.Boss.PermafrostNonchalantText"; else if (DownedBossSystem.downedCalamitas) key += "Rematch"; - CalamityUtils.DisplayLocalizedText(key, cirrus ? cirrusTextColor : textColor); + CalamityUtils.DisplayLocalizedText(key, permafrost ? permafrostTextColor : textColor); } gettingTired2 = true; @@ -1879,7 +1873,7 @@ public override void AI() attackCastDelay = sepulcherSpawnCastTime; for (int i = 0; i < 40; i++) { - Dust castFire = Dust.NewDustPerfect(NPC.Center + Main.rand.NextVector2Square(-70f, 70f), cirrus ? (int)CalamityDusts.PurpleCosmilite : (int)CalamityDusts.Brimstone); + Dust castFire = Dust.NewDustPerfect(NPC.Center + Main.rand.NextVector2Square(-70f, 70f), permafrost ? DustID.IceGolem : (int)CalamityDusts.Brimstone); castFire.velocity = Vector2.UnitY.RotatedByRandom(0.08f) * -Main.rand.NextFloat(3f, 4.45f); castFire.scale = Main.rand.NextFloat(1.35f, 1.6f); castFire.fadeIn = 1.25f; @@ -1888,7 +1882,7 @@ public override void AI() for (int i = 0; i < 40; i++) { - Dust castFire = Dust.NewDustPerfect(NPC.Center + Main.rand.NextVector2Square(-70f, 70f), cirrus ? (int)CalamityDusts.PurpleCosmilite : (int)CalamityDusts.Brimstone); + Dust castFire = Dust.NewDustPerfect(NPC.Center + Main.rand.NextVector2Square(-70f, 70f), permafrost ? DustID.IceGolem : (int)CalamityDusts.Brimstone); castFire.velocity = Vector2.UnitY.RotatedByRandom(0.08f) * -Main.rand.NextFloat(3f, 4.45f); castFire.scale = Main.rand.NextFloat(1.35f, 1.6f); castFire.fadeIn = 1.25f; @@ -1929,17 +1923,17 @@ public override void AI() } #endregion #region TransformSeekerandBrotherTriggers - if (!halfLife && lifeRatio <= 0.45f && hasSummonedBrothers && (cirrus ? NPC.AnyNPCs(ModContent.NPCType()) : (NPC.AnyNPCs(ModContent.NPCType()) || NPC.AnyNPCs(ModContent.NPCType()))) == false) + if (!halfLife && lifeRatio <= 0.45f && hasSummonedBrothers && (permafrost ? NPC.AnyNPCs(ModContent.NPCType()) : (NPC.AnyNPCs(ModContent.NPCType()) || NPC.AnyNPCs(ModContent.NPCType()))) == false) { if (!bossRush) { string key = "Mods.CalamityMod.Status.Boss.SCalPhase2Text"; - if (cirrus) - key = "Mods.CalamityMod.Status.Boss.CirrusPhase2Text"; + if (permafrost) + key = "Mods.CalamityMod.Status.Boss.PermafrostPhase2Text"; else if (DownedBossSystem.downedCalamitas) key += "Rematch"; - CalamityUtils.DisplayLocalizedText(key, cirrus ? cirrusTextColor : textColor); + CalamityUtils.DisplayLocalizedText(key, permafrost ? permafrostTextColor : textColor); } halfLife = true; @@ -1952,57 +1946,26 @@ public override void AI() if (!bossRush) { string key = "Mods.CalamityMod.Status.Boss.SCalSeekerRingText"; - if (cirrus) - key = "Mods.CalamityMod.Status.Boss.CirrusHallowBossSpamText"; + if (permafrost) + key = "Mods.CalamityMod.Status.Boss.PermafrostHallowBossSpamText"; else if (DownedBossSystem.downedCalamitas) key += "Rematch"; - CalamityUtils.DisplayLocalizedText(key, cirrus ? cirrusTextColor : textColor); + CalamityUtils.DisplayLocalizedText(key, permafrost ? permafrostTextColor : textColor); } if (Main.netMode != NetmodeID.MultiplayerClient) { - if (cirrus) + if (permafrost) { - // Spawn 1 Providence, 2 Queen Slimes and 2 Empress of Lights - int maximumBullshit = 5; - int angleFromCirrus = 360 / maximumBullshit; - int distanceFromCirrus = 300; - for (int i = 0; i < maximumBullshit; i++) - { - switch (i) - { - case 0: - int npc = NPC.NewNPC(NPC.GetSource_FromAI(), - (int)(vectorCenter.X + (Math.Sin(i * angleFromCirrus) * distanceFromCirrus)), - (int)(vectorCenter.Y + (Math.Cos(i * angleFromCirrus) * distanceFromCirrus)), - ModContent.NPCType(), NPC.whoAmI); - Main.npc[npc].timeLeft *= 20; - CalamityUtils.BossAwakenMessage(npc); - break; - - case 1: - case 2: - int npc2 = NPC.NewNPC(NPC.GetSource_FromAI(), - (int)(vectorCenter.X + (Math.Sin(i * angleFromCirrus) * distanceFromCirrus)), - (int)(vectorCenter.Y + (Math.Cos(i * angleFromCirrus) * distanceFromCirrus)), - NPCID.HallowBoss, NPC.whoAmI); - Main.npc[npc2].timeLeft *= 20; - break; - - case 3: - case 4: - int npc3 = NPC.NewNPC(NPC.GetSource_FromAI(), - (int)(vectorCenter.X + (Math.Sin(i * angleFromCirrus) * distanceFromCirrus)), - (int)(vectorCenter.Y + (Math.Cos(i * angleFromCirrus) * distanceFromCirrus)), - NPCID.QueenSlimeBoss, NPC.whoAmI); - Main.npc[npc3].timeLeft *= 20; - break; - - default: - break; - } - } + // Spawn a buffed Pyrogen + int npc = NPC.NewNPC(NPC.GetSource_FromAI(), + (int)(vectorCenter.X), + (int)(vectorCenter.Y), + ModContent.NPCType(), NPC.whoAmI); + Main.npc[npc].timeLeft *= 20; + Main.npc[npc].lifeMax = Main.npc[npc].life *= 22; + CalamityUtils.BossAwakenMessage(npc); } else { @@ -2044,7 +2007,7 @@ public override void AI() NPC.netUpdate = true; if (!teleport) { - Dust.QuickDustLine(NPC.Center, player.Center + new Vector2(0, -155), 500f, cirrus ? Color.Pink : Color.Red); + Dust.QuickDustLine(NPC.Center, player.Center + new Vector2(0, -155), 500f, permafrost ? Color.Pink : Color.Red); NPC.velocity = Vector2.Zero; NPC.Center = player.Center + new Vector2(0, -175); Particle pulse = new DirectionalPulseRing(NPC.Center, Vector2.Zero, Color.Red, new Vector2(1f, 1f), 0, 0.1f, 5f, 15); @@ -2267,7 +2230,7 @@ public override void AI() for (int i = 0; i < 9; i++) // fireblasts pre laugh { Vector2 velOffset = NPC.DirectionTo(player.Center).RotatedByRandom(0.6) * Main.rand.NextFloat(5f, 13f); - GlowOrbParticle spark2 = new GlowOrbParticle(projectileSpawn + velOffset * 2f, velOffset * 0.7f, false, 30, Main.rand.NextFloat(0.4f, 0.65f), cirrus ? Color.HotPink : Main.rand.NextBool(3) ? Color.Lerp(Color.Red, Color.Magenta, 0.3f) : Color.Red); + GlowOrbParticle spark2 = new GlowOrbParticle(projectileSpawn + velOffset * 2f, velOffset * 0.7f, false, 30, Main.rand.NextFloat(0.4f, 0.65f), permafrost ? Color.HotPink : Main.rand.NextBool(3) ? Color.Lerp(Color.Red, Color.Magenta, 0.3f) : Color.Red); GeneralParticleHandler.SpawnParticle(spark2); } @@ -2286,7 +2249,7 @@ public override void AI() for (int i = 0; i < 9; i++) { Vector2 velOffset = NPC.DirectionTo(player.Center).RotatedByRandom(0.6) * Main.rand.NextFloat(5f, 13f); - GlowOrbParticle spark2 = new GlowOrbParticle(projectileSpawn + velOffset * 2f, velOffset * 0.8f, false, 30, Main.rand.NextFloat(0.4f, 0.65f), cirrus ? Color.HotPink : Main.rand.NextBool(3) ? Color.Lerp(Color.Red, Color.Magenta, 0.3f) : Color.Red); + GlowOrbParticle spark2 = new GlowOrbParticle(projectileSpawn + velOffset * 2f, velOffset * 0.8f, false, 30, Main.rand.NextFloat(0.4f, 0.65f), permafrost ? Color.HotPink : Main.rand.NextBool(3) ? Color.Lerp(Color.Red, Color.Magenta, 0.3f) : Color.Red); GeneralParticleHandler.SpawnParticle(spark2); } @@ -2308,7 +2271,7 @@ public override void AI() for (int i = 0; i < 6; i++) // Spread dust for pre laugh floating { Vector2 dustVel = (projectileVelocity * 2).RotatedByRandom(0.9) * (Main.rand.NextFloat(0.5f, 1.9f)); - GlowOrbParticle orb = new GlowOrbParticle(projectileSpawn, dustVel, false, 15, Main.rand.NextFloat(0.65f, 0.9f), cirrus ? Color.Magenta : Main.rand.NextBool() ? Color.Red : Color.Lerp(Color.Red, Color.Magenta, 0.3f)); + GlowOrbParticle orb = new GlowOrbParticle(projectileSpawn, dustVel, false, 15, Main.rand.NextFloat(0.65f, 0.9f), permafrost ? Color.Magenta : Main.rand.NextBool() ? Color.Red : Color.Lerp(Color.Red, Color.Magenta, 0.3f)); GeneralParticleHandler.SpawnParticle(orb); } @@ -2345,13 +2308,13 @@ public override void AI() NPC.netUpdate = true; SoundEngine.PlaySound(DashSound, NPC.Center); - if (cirrus) + if (permafrost) { if (Main.netMode != NetmodeID.MultiplayerClient) { SoundEngine.PlaySound(SoundID.Item60, NPC.Center); float velocity = 8; - int type = ModContent.ProjectileType(); + int type = ModContent.ProjectileType(); int damage = (int)(NPC.damage / 3); Vector2 projectileVelocity = (player.Center - NPC.Center).SafeNormalize(Vector2.UnitY) * velocity; float rotation = MathHelper.ToRadians(22); @@ -2365,6 +2328,7 @@ public override void AI() Main.projectile[p].DamageType = DamageClass.Default; Main.projectile[p].friendly = false; Main.projectile[p].hostile = true; + Main.projectile[p].tileCollide = false; } } } @@ -2480,7 +2444,7 @@ public override void AI() for (int i = 0; i < 6; i++) { Vector2 velOffset = NPC.DirectionTo(player.Center).RotatedByRandom(0.6) * Main.rand.NextFloat(5f, 13f); - PointParticle spark2 = new PointParticle(handPosition + velOffset * 2f, velOffset * 1.5f, false, 18, Main.rand.NextFloat(0.4f, 0.65f), cirrus ? Color.HotPink : Main.rand.NextBool(3) ? Color.Lerp(Color.Red, Color.Magenta, 0.3f) : Color.Red); + PointParticle spark2 = new PointParticle(handPosition + velOffset * 2f, velOffset * 1.5f, false, 18, Main.rand.NextFloat(0.4f, 0.65f), permafrost ? Color.HotPink : Main.rand.NextBool(3) ? Color.Lerp(Color.Red, Color.Magenta, 0.3f) : Color.Red); GeneralParticleHandler.SpawnParticle(spark2); } @@ -2498,7 +2462,7 @@ public override void AI() if (Main.rand.NextBool()) // Hand spray magic { - GlowOrbParticle orb = new GlowOrbParticle(handPosition, new Vector2(0, -6).RotatedByRandom(0.4) * Main.rand.NextFloat(0.8f, 1.4f), false, 15, Main.rand.NextFloat(0.85f, 1.2f), cirrus ? Color.Magenta : Main.rand.NextBool() ? Color.Red : Color.Lerp(Color.Red, Color.Magenta, 0.3f), true, true); + GlowOrbParticle orb = new GlowOrbParticle(handPosition, new Vector2(0, -6).RotatedByRandom(0.4) * Main.rand.NextFloat(0.8f, 1.4f), false, 15, Main.rand.NextFloat(0.85f, 1.2f), permafrost ? Color.Magenta : Main.rand.NextBool() ? Color.Red : Color.Lerp(Color.Red, Color.Magenta, 0.3f), true, true); GeneralParticleHandler.SpawnParticle(orb); } @@ -2549,7 +2513,7 @@ public override void AI() for (int i = 0; i < 25; i++) { Vector2 velOffset = NPC.DirectionTo(player.Center).RotatedByRandom(0.6) * Main.rand.NextFloat(5f, 13f); - GlowOrbParticle spark2 = new GlowOrbParticle(handPosition + velOffset * 2f, velOffset * 1.5f, false, 9, Main.rand.NextFloat(0.4f, 0.65f), cirrus ? Color.HotPink : Main.rand.NextBool(3) ? Color.Lerp(Color.Red, Color.Magenta, 0.3f) : Color.Red); + GlowOrbParticle spark2 = new GlowOrbParticle(handPosition + velOffset * 2f, velOffset * 1.5f, false, 9, Main.rand.NextFloat(0.4f, 0.65f), permafrost ? Color.HotPink : Main.rand.NextBool(3) ? Color.Lerp(Color.Red, Color.Magenta, 0.3f) : Color.Red); GeneralParticleHandler.SpawnParticle(spark2); } NPC.localAI[1] = 0f; @@ -2576,7 +2540,7 @@ public override void AI() } // Previously the 0.4% health threshold transition - if (lifeRatio <= 0.45f && hasSummonedBrothers && (cirrus ? NPC.AnyNPCs(ModContent.NPCType()) : (NPC.AnyNPCs(ModContent.NPCType()) || NPC.AnyNPCs(ModContent.NPCType()))) == false) + if (lifeRatio <= 0.45f && hasSummonedBrothers && (permafrost ? NPC.AnyNPCs(ModContent.NPCType()) : (NPC.AnyNPCs(ModContent.NPCType()) || NPC.AnyNPCs(ModContent.NPCType()))) == false) { NPC.ai[0] = 1f; NPC.ai[1] = 0f; @@ -2621,17 +2585,17 @@ public override void AI() { for (int i = 0; i < 90; i++) { - Dust spawnDust = Dust.NewDustPerfect(NPC.Center, cirrus ? (int)CalamityDusts.PurpleCosmilite : (int)CalamityDusts.Brimstone, new Vector2(30, 30).RotatedByRandom(100) * Main.rand.NextFloat(0.05f, 1.2f)); + Dust spawnDust = Dust.NewDustPerfect(NPC.Center, permafrost ? DustID.IceGolem : (int)CalamityDusts.Brimstone, new Vector2(30, 30).RotatedByRandom(100) * Main.rand.NextFloat(0.05f, 1.2f)); spawnDust.noGravity = true; spawnDust.scale = Main.rand.NextFloat(1.2f, 2.3f); } for (int i = 0; i < 40; i++) { Vector2 sparkVel = new Vector2(20, 20).RotatedByRandom(100) * Main.rand.NextFloat(0.1f, 1.1f); - GlowOrbParticle orb = new GlowOrbParticle(NPC.Center + sparkVel * 2, sparkVel, false, 120, Main.rand.NextFloat(1.55f, 2.75f), cirrus ? Color.Magenta : Color.Red, true, true); + GlowOrbParticle orb = new GlowOrbParticle(NPC.Center + sparkVel * 2, sparkVel, false, 120, Main.rand.NextFloat(1.55f, 2.75f), permafrost ? Color.Magenta : Color.Red, true, true); GeneralParticleHandler.SpawnParticle(orb); } - Particle pulse = new DirectionalPulseRing(NPC.Center, Vector2.Zero, cirrus ? Color.Magenta : Color.Red, new Vector2(2f, 2f), 0, 0f, 1.1f, 25); + Particle pulse = new DirectionalPulseRing(NPC.Center, Vector2.Zero, permafrost ? Color.Magenta : Color.Red, new Vector2(2f, 2f), 0, 0f, 1.1f, 25); GeneralParticleHandler.SpawnParticle(pulse); SoundEngine.PlaySound(SpawnSound, NPC.Center); @@ -2640,7 +2604,7 @@ public override void AI() for (int i = 0; i < 4; i++) { - Dust brimstoneFire = Dust.NewDustPerfect(NPC.Center + Main.rand.NextVector2Square(-24f, 24f), cirrus ? (int)CalamityDusts.PurpleCosmilite : (int)CalamityDusts.Brimstone); + Dust brimstoneFire = Dust.NewDustPerfect(NPC.Center + Main.rand.NextVector2Square(-24f, 24f), permafrost ? DustID.IceGolem : (int)CalamityDusts.Brimstone); brimstoneFire.velocity = Vector2.UnitY * -Main.rand.NextFloat(2.75f, 4.25f); brimstoneFire.noGravity = true; } @@ -2666,7 +2630,7 @@ public override void AI() } else { - if (cirrus ? NPC.AnyNPCs(ModContent.NPCType()) : NPC.AnyNPCs(ModContent.NPCType())) + if (permafrost ? NPC.AnyNPCs(ModContent.NPCType()) : NPC.AnyNPCs(ModContent.NPCType())) { NPC.dontTakeDamage = true; NPC.chaseable = false; @@ -2829,9 +2793,9 @@ public override void AI() canFireSplitingFireball = false; randomShot = gigablast; - Particle pulse = new DirectionalPulseRing(NPC.Center, projectileVelocity * 1.2f, cirrus ? Color.Pink : Color.Red, new Vector2(0.5f, 1f), projectileVelocity.ToRotation(), 0.92f, 0f, 55); + Particle pulse = new DirectionalPulseRing(NPC.Center, projectileVelocity * 1.2f, permafrost ? Color.Pink : Color.Red, new Vector2(0.5f, 1f), projectileVelocity.ToRotation(), 0.92f, 0f, 55); GeneralParticleHandler.SpawnParticle(pulse); - Particle pulse2 = new DirectionalPulseRing(NPC.Center, projectileVelocity * 1f, cirrus ? Color.Pink : Color.Magenta, new Vector2(0.5f, 1f), projectileVelocity.ToRotation(), 0.95f, 0.4f, 55); + Particle pulse2 = new DirectionalPulseRing(NPC.Center, projectileVelocity * 1f, permafrost ? Color.Pink : Color.Magenta, new Vector2(0.5f, 1f), projectileVelocity.ToRotation(), 0.95f, 0.4f, 55); GeneralParticleHandler.SpawnParticle(pulse2); if (Main.netMode != NetmodeID.MultiplayerClient) @@ -2847,9 +2811,9 @@ public override void AI() canFireSplitingFireball = false; randomShot = fireblast; - Particle pulse = new DirectionalPulseRing(NPC.Center, projectileVelocity * 1.2f, cirrus ? Color.Pink : Color.Red, new Vector2(0.5f, 1f), projectileVelocity.ToRotation(), 0.95f, 0f, 55); + Particle pulse = new DirectionalPulseRing(NPC.Center, projectileVelocity * 1.2f, permafrost ? Color.Pink : Color.Red, new Vector2(0.5f, 1f), projectileVelocity.ToRotation(), 0.95f, 0f, 55); GeneralParticleHandler.SpawnParticle(pulse); - Particle pulse2 = new DirectionalPulseRing(NPC.Center, projectileVelocity * 1f, cirrus ? Color.Pink : Color.Magenta, new Vector2(0.5f, 1f), projectileVelocity.ToRotation(), 0.98f, 0.4f, 55); + Particle pulse2 = new DirectionalPulseRing(NPC.Center, projectileVelocity * 1f, permafrost ? Color.Pink : Color.Magenta, new Vector2(0.5f, 1f), projectileVelocity.ToRotation(), 0.98f, 0.4f, 55); GeneralParticleHandler.SpawnParticle(pulse2); if (Main.netMode != NetmodeID.MultiplayerClient) @@ -2870,7 +2834,7 @@ public override void AI() for (int i = 0; i < 7; i++) // Spred dust while floating post laugh { Vector2 dustVel = (projectileVelocity * 2).RotatedByRandom(0.9) * (Main.rand.NextFloat(0.5f, 1.9f)); - GlowOrbParticle orb = new GlowOrbParticle(projectileSpawn, dustVel, false, 15, Main.rand.NextFloat(0.75f, 1f), cirrus ? Color.Magenta : Main.rand.NextBool() ? Color.Red : Color.Lerp(Color.Red, Color.Magenta, 0.3f), true, true); + GlowOrbParticle orb = new GlowOrbParticle(projectileSpawn, dustVel, false, 15, Main.rand.NextFloat(0.75f, 1f), permafrost ? Color.Magenta : Main.rand.NextBool() ? Color.Red : Color.Lerp(Color.Red, Color.Magenta, 0.3f), true, true); GeneralParticleHandler.SpawnParticle(orb); } @@ -3013,7 +2977,7 @@ public override void AI() for (int i = 0; i < 9; i++) { Vector2 velOffset = NPC.DirectionTo(player.Center).RotatedByRandom(0.6) * Main.rand.NextFloat(5f, 13f); - PointParticle spark2 = new PointParticle(handPosition + velOffset * 2f, velOffset * 1.5f, false, 9, Main.rand.NextFloat(0.5f, 0.75f), cirrus ? Color.HotPink : Main.rand.NextBool(3) ? Color.Lerp(Color.Red, Color.Magenta, 0.3f) : Color.Red); + PointParticle spark2 = new PointParticle(handPosition + velOffset * 2f, velOffset * 1.5f, false, 9, Main.rand.NextFloat(0.5f, 0.75f), permafrost ? Color.HotPink : Main.rand.NextBool(3) ? Color.Lerp(Color.Red, Color.Magenta, 0.3f) : Color.Red); GeneralParticleHandler.SpawnParticle(spark2); } @@ -3031,7 +2995,7 @@ public override void AI() if (Main.rand.NextBool()) // Hand visual post laugh { - GlowOrbParticle orb = new GlowOrbParticle(handPosition, new Vector2(0, -6).RotatedByRandom(0.4) * Main.rand.NextFloat(0.8f, 1.4f), false, 15, Main.rand.NextFloat(0.95f, 1.45f), cirrus ? Color.Magenta : Main.rand.NextBool() ? Color.Red : Color.Lerp(Color.Red, Color.Magenta, 0.5f), true, true); + GlowOrbParticle orb = new GlowOrbParticle(handPosition, new Vector2(0, -6).RotatedByRandom(0.4) * Main.rand.NextFloat(0.8f, 1.4f), false, 15, Main.rand.NextFloat(0.95f, 1.45f), permafrost ? Color.Magenta : Main.rand.NextBool() ? Color.Red : Color.Lerp(Color.Red, Color.Magenta, 0.5f), true, true); GeneralParticleHandler.SpawnParticle(orb); } Dust fust = Dust.NewDustPerfect(handPosition, Main.rand.NextBool(3) ? 60 : 114); @@ -3089,9 +3053,9 @@ public override void AI() Vector2 projectileSpawn = NPC.Center + projectileVelocity * 8f; // Release a burst of magic dust when punching. - Particle pulse = new DirectionalPulseRing(NPC.Center, projectileVelocity * 9, cirrus ? Color.Pink : Color.Red, new Vector2(0.5f, 1f), projectileVelocity.ToRotation(), 0.9f, 0f, 60); + Particle pulse = new DirectionalPulseRing(NPC.Center, projectileVelocity * 9, permafrost ? Color.Pink : Color.Red, new Vector2(0.5f, 1f), projectileVelocity.ToRotation(), 0.9f, 0f, 60); GeneralParticleHandler.SpawnParticle(pulse); - Particle pulse2 = new DirectionalPulseRing(NPC.Center, projectileVelocity * 8, cirrus ? Color.Pink : Color.Magenta, new Vector2(0.5f, 1f), projectileVelocity.ToRotation(), 0.93f, 0.4f, 60); + Particle pulse2 = new DirectionalPulseRing(NPC.Center, projectileVelocity * 8, permafrost ? Color.Pink : Color.Magenta, new Vector2(0.5f, 1f), projectileVelocity.ToRotation(), 0.93f, 0.4f, 60); GeneralParticleHandler.SpawnParticle(pulse2); NPC.localAI[1] = 0f; @@ -3174,31 +3138,31 @@ public void DoHeartsSpawningCastAnimation(Player target, bool death) castMagicDust.scale = 1.67f; castMagicDust.velocity = Main.rand.NextVector2CircularEdge(0.2f, 0.2f); castMagicDust.fadeIn = 0.67f; - castMagicDust.color = cirrus ? Color.Pink : Color.Red; + castMagicDust.color = permafrost ? Color.Pink : Color.Red; castMagicDust.noGravity = true; } if (attackCastDelay == 0) { - string key = cirrus ? "Mods.CalamityMod.Status.Boss.CirrusBirbSwarmText" : "Mods.CalamityMod.Status.Boss.SCalStartText"; + string key = permafrost ? "Mods.CalamityMod.Status.Boss.PermafrostBirbSwarmText" : "Mods.CalamityMod.Status.Boss.SCalStartText"; if (NPC.life <= NPC.lifeMax * 0.08) - key = cirrus ? "Mods.CalamityMod.Status.Boss.CirrusSecondBirbSwarmText" : "Mods.CalamityMod.Status.Boss.SCalSepulcher2Text"; + key = permafrost ? "Mods.CalamityMod.Status.Boss.PermafrostSecondBirbSwarmText" : "Mods.CalamityMod.Status.Boss.SCalSepulcher2Text"; if (!BossRushEvent.BossRushActive) { - if (DownedBossSystem.downedCalamitas && !cirrus) + if (DownedBossSystem.downedCalamitas && !permafrost) key += "Rematch"; - CalamityUtils.DisplayLocalizedText(key, cirrus ? cirrusTextColor : textColor); + CalamityUtils.DisplayLocalizedText(key, permafrost ? permafrostTextColor : textColor); } foreach (Vector2 heartSpawnPosition in heartSpawnPositions) { // Make the hearts appear in a burst of flame. - // Spawn Dragonfollies if Cirrus exists. + // Spawn Dragonfollies if Permafrost exists. for (int i = 0; i < 20; i++) { - Dust castFire = Dust.NewDustPerfect(heartSpawnPosition + Main.rand.NextVector2Square(-30f, 30f), cirrus ? (int)CalamityDusts.Necroplasm : (int)CalamityDusts.Brimstone); + Dust castFire = Dust.NewDustPerfect(heartSpawnPosition + Main.rand.NextVector2Square(-30f, 30f), permafrost ? (int)CalamityDusts.Necroplasm : (int)CalamityDusts.Brimstone); castFire.velocity = Vector2.UnitY.RotatedByRandom(0.08f) * -Main.rand.NextFloat(3f, 4.45f); castFire.scale = Main.rand.NextFloat(1.35f, 1.6f); castFire.fadeIn = 1.25f; @@ -3212,7 +3176,7 @@ public void DoHeartsSpawningCastAnimation(Player target, bool death) if (Main.netMode != NetmodeID.MultiplayerClient) { - if (cirrus) + if (permafrost) { for (int x = 0; x < 5; x++) { @@ -3280,9 +3244,9 @@ public void DoBrothersSpawningCastAnimation(int bodyWidth, int bodyHeight) Vector2 leftDustPosition = Vector2.CatmullRom(leftOfCircle + Vector2.UnitY * 1000f, leftOfCircle, catastropheSpawnPosition, catastropheSpawnPosition + Vector2.UnitY * 1000f, castCompletion); Vector2 rightDustPosition = Vector2.CatmullRom(rightOfCircle + Vector2.UnitY * 1000f, rightOfCircle, cataclysmSpawnPosition, cataclysmSpawnPosition + Vector2.UnitY * 1000f, castCompletion); - GlowOrbParticle orb = new GlowOrbParticle(leftDustPosition, Vector2.Zero, false, 20, 2.8f - attackCastDelay * 0.01f, cirrus ? Color.Pink : Color.Red, true, true); + GlowOrbParticle orb = new GlowOrbParticle(leftDustPosition, Vector2.Zero, false, 20, 2.8f - attackCastDelay * 0.01f, permafrost ? Color.Pink : Color.Red, true, true); GeneralParticleHandler.SpawnParticle(orb); - GlowOrbParticle orb2 = new GlowOrbParticle(rightDustPosition, Vector2.Zero, false, 20, 2.8f - attackCastDelay * 0.01f, cirrus ? Color.Pink : Color.Red, true, true); + GlowOrbParticle orb2 = new GlowOrbParticle(rightDustPosition, Vector2.Zero, false, 20, 2.8f - attackCastDelay * 0.01f, permafrost ? Color.Pink : Color.Red, true, true); GeneralParticleHandler.SpawnParticle(orb2); } @@ -3342,19 +3306,20 @@ public void DoBrothersSpawningCastAnimation(int bodyWidth, int bodyHeight) if (!BossRushEvent.BossRushActive) { string key = "Mods.CalamityMod.Status.Boss.SCalBrothersText"; - if (cirrus) - key = "Mods.CalamityMod.Status.Boss.CirrusDoGText"; + if (permafrost) + key = "Mods.CalamityMod.Status.Boss.PermafrostDoGText"; else if (DownedBossSystem.downedCalamitas) key += "Rematch"; - CalamityUtils.DisplayLocalizedText(key, cirrus ? cirrusTextColor : textColor); + CalamityUtils.DisplayLocalizedText(key, permafrost ? permafrostTextColor : textColor); } if (Main.netMode != NetmodeID.MultiplayerClient) { bool broDirection = Main.rand.NextBool(); - CalamityUtils.SpawnBossBetter(catastropheSpawnPosition, cirrus ? ModContent.NPCType() : ModContent.NPCType(), null, broDirection == false ? 1 : -1); - CalamityUtils.SpawnBossBetter(cataclysmSpawnPosition, cirrus ? ModContent.NPCType() : ModContent.NPCType(), null, broDirection == true ? 1 : -1); + CalamityUtils.SpawnBossBetter(catastropheSpawnPosition, permafrost ? ModContent.NPCType() : ModContent.NPCType(), null, broDirection == false ? 1 : -1); + if (!permafrost) + CalamityUtils.SpawnBossBetter(cataclysmSpawnPosition, ModContent.NPCType(), null, broDirection == true ? 1 : -1); } SoundEngine.PlaySound(new SoundStyle("CalamityMod/Sounds/NPCKilled/RavagerDeath1") with { Pitch = -0.2f }, cataclysmSpawnPosition); @@ -3447,7 +3412,7 @@ public override void OnKill() // Spawn the SCal NPC directly where the boss was if (!BossRushEvent.BossRushActive) - NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y + 12, cirrus ? ModContent.NPCType() : ModContent.NPCType()); + NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y + 12, permafrost ? ModContent.NPCType() : ModContent.NPCType()); // Mark Calamitas as defeated DownedBossSystem.downedCalamitas = true; @@ -3507,7 +3472,7 @@ public override void ModifyNPCLoot(NPCLoot npcLoot) } // Legendary seed pony on a stick upgrade - npcLoot.Add(ItemDropRule.ByCondition(DropHelper.If(info => info.npc.type == ModContent.NPCType() && info.npc.ModNPC().cirrus, false), ModContent.ItemType())); + npcLoot.Add(ItemDropRule.ByCondition(DropHelper.If(info => info.npc.type == ModContent.NPCType() && info.npc.ModNPC().permafrost, false), ModContent.ItemType())); // Lore npcLoot.AddConditionalPerPlayer(() => !DownedBossSystem.downedCalamitas, ModContent.ItemType(), desc: DropHelper.FirstKillText); @@ -3587,7 +3552,7 @@ public override void FindFrame(int frameHeight) NPC.frameCounter %= 6; NPC.frame.Y = (int)NPC.frameCounter + (int)FrameType * 6; } - if (cirrus) + if (permafrost) { alicornFrameCounter++; if (alicornFrameCounter > 6) @@ -3611,23 +3576,17 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d spriteEffects = SpriteEffects.FlipHorizontally; Texture2D texture2D15 = DownedBossSystem.downedCalamitas && !BossRushEvent.BossRushActive ? TextureAssets.Npc[NPC.type].Value : HoodedTexture.Value; - Texture2D pony = ModContent.Request("CalamityMod/Items/Mounts/AlicornMount_Front").Value; - bool inPhase2 = NPC.ai[0] >= 3f && (NPC.life > NPC.lifeMax * 0.01 || cirrus); + bool inPhase2 = NPC.ai[0] >= 3f && (NPC.life > NPC.lifeMax * 0.01 || permafrost); + + if (permafrost) + texture2D15 = PermafrostTexture.Value; - if (cirrus) - texture2D15 = inPhase2 ? CirrusTexture2.Value : CirrusTexture.Value; + Rectangle frame = texture2D15.Frame(2, Main.npcFrameCount[NPC.type], NPC.frame.Y / Main.npcFrameCount[NPC.type], NPC.frame.Y % Main.npcFrameCount[NPC.type]); Vector2 halfSizeTexture = new Vector2(texture2D15.Width / 2f, texture2D15.Height / Main.npcFrameCount[NPC.type] / 2f); - Vector2 ponyOrigin = new Vector2(pony.Width / 2f, pony.Height / 30f); int afterimageAmt = 7; - Rectangle frame = texture2D15.Frame(2, Main.npcFrameCount[NPC.type], NPC.frame.Y / Main.npcFrameCount[NPC.type], NPC.frame.Y % Main.npcFrameCount[NPC.type]); - Rectangle ponyFrame = pony.Frame(1, 15, 0, alicornFrame); - Vector2 ponyPos = NPC.Center - screenPos; - ponyPos -= new Vector2(pony.Width / 2f, pony.Height / 15) * NPC.scale / 2f; - ponyPos += ponyOrigin * NPC.scale + new Vector2(-20, NPC.gfxOffY); - - if (CalamityConfig.Instance.Afterimages && !(cirrus && NPC.ai[1] == 2f)) + if (CalamityConfig.Instance.Afterimages && !(permafrost && NPC.ai[1] == 2f)) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -3646,7 +3605,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d drawLocation -= new Vector2(texture2D15.Width / 2f, texture2D15.Height / Main.npcFrameCount[NPC.type]) * NPC.scale / 2f; drawLocation += halfSizeTexture * NPC.scale + new Vector2(0f, NPC.gfxOffY); - if (!(cirrus && NPC.ai[1] == 2f)) + if (!(permafrost && NPC.ai[1] == 2f)) { if (inPhase2) { @@ -3655,7 +3614,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d drawLocation += Main.rand.NextVector2Circular(0.25f, 0.7f); // And gain a flaming aura. - Color auraColor = NPC.GetAlpha(cirrus ? Color.Pink : Color.Red) * 0.4f; + Color auraColor = NPC.GetAlpha(permafrost ? Color.Cyan : Color.Red) * 0.4f; for (int i = 0; i < 7; i++) { Vector2 rotationalDrawOffset = (MathHelper.TwoPi * i / 7f + Main.GlobalTimeWrappedHourly * 4f).ToRotationVector2(); @@ -3669,17 +3628,6 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d if (!NPC.IsABestiaryIconDummy) { DrawForcefield(spriteBatch); - if (cirrus) - { - if (NPC.ai[1] == 2f) - { - spriteBatch.Draw(pony, ponyPos, ponyFrame, NPC.GetAlpha(drawColor), NPC.rotation, ponyOrigin, NPC.scale, spriteEffects, 0f); - } - } - else - { - DrawShield(spriteBatch); - } } return false; } @@ -3734,7 +3682,7 @@ public void DrawForcefield(SpriteBatch spriteBatch) GameShaders.Misc["CalamityMod:SupremeShield"].UseImage1("Images/Misc/Perlin"); Color forcefieldColor = Color.DarkViolet; - Color secondaryForcefieldColor = (cirrus ? Color.HotPink : Color.Red) * 1.4f; + Color secondaryForcefieldColor = (permafrost ? Color.LightBlue : Color.Red) * 1.4f; if (!NPC.dontTakeDamage && willCharge && NPC.ai[1] != 2f) { @@ -3813,7 +3761,7 @@ public override void HitEffect(NPC.HitInfo hit) for (int k = 0; k < 5; k++) { - Dust.NewDust(NPC.position, NPC.width, NPC.height, cirrus ? (int)CalamityDusts.PurpleCosmilite : (int)CalamityDusts.Brimstone, hit.HitDirection, -1f, 0, default, 1f); + Dust.NewDust(NPC.position, NPC.width, NPC.height, permafrost ? DustID.IceGolem : (int)CalamityDusts.Brimstone, hit.HitDirection, -1f, 0, default, 1f); } if (NPC.life <= 0) { @@ -3823,7 +3771,7 @@ public override void HitEffect(NPC.HitInfo hit) NPC.position.Y = NPC.position.Y - (NPC.height / 2); for (int i = 0; i < 40; i++) { - int onHitDust = Dust.NewDust(NPC.position, NPC.width, NPC.height, cirrus ? (int)CalamityDusts.PurpleCosmilite : (int)CalamityDusts.Brimstone, 0f, 0f, 100, default, 2f); + int onHitDust = Dust.NewDust(NPC.position, NPC.width, NPC.height, permafrost ? DustID.IceGolem : (int)CalamityDusts.Brimstone, 0f, 0f, 100, default, 2f); Main.dust[onHitDust].velocity *= 3f; if (Main.rand.NextBool()) { @@ -3833,10 +3781,10 @@ public override void HitEffect(NPC.HitInfo hit) } for (int j = 0; j < 70; j++) { - int onHitDust2 = Dust.NewDust(NPC.position, NPC.width, NPC.height, cirrus ? (int)CalamityDusts.PurpleCosmilite : (int)CalamityDusts.Brimstone, 0f, 0f, 100, default, 3f); + int onHitDust2 = Dust.NewDust(NPC.position, NPC.width, NPC.height, permafrost ? DustID.IceGolem : (int)CalamityDusts.Brimstone, 0f, 0f, 100, default, 3f); Main.dust[onHitDust2].noGravity = true; Main.dust[onHitDust2].velocity *= 5f; - onHitDust2 = Dust.NewDust(NPC.position, NPC.width, NPC.height, cirrus ? (int)CalamityDusts.PurpleCosmilite : (int)CalamityDusts.Brimstone, 0f, 0f, 100, default, 2f); + onHitDust2 = Dust.NewDust(NPC.position, NPC.width, NPC.height, permafrost ? DustID.IceGolem : (int)CalamityDusts.Brimstone, 0f, 0f, 100, default, 2f); Main.dust[onHitDust2].velocity *= 2f; } } @@ -3853,80 +3801,6 @@ public override void OnHitPlayer(Player target, Player.HurtInfo hurtInfo) if (hurtInfo.Damage > 0) { target.AddBuff(ModContent.BuffType(), 600); - InflictCirrusDebuffs(target); - } - } - - public void InflictCirrusDebuffs(Player target) - { - if (cirrus) - { - switch (Main.rand.Next(MaxCirrusAlcohols)) - { - case 0: - target.AddBuff(ModContent.BuffType(), MaxCirrusAlcoholDebuffDuration); - break; - case 1: - target.AddBuff(ModContent.BuffType(), MaxCirrusAlcoholDebuffDuration); - break; - case 2: - target.AddBuff(ModContent.BuffType(), MaxCirrusAlcoholDebuffDuration); - break; - case 3: - target.AddBuff(ModContent.BuffType(), MaxCirrusAlcoholDebuffDuration); - break; - case 4: - target.AddBuff(ModContent.BuffType(), MaxCirrusAlcoholDebuffDuration); - break; - case 5: - target.AddBuff(ModContent.BuffType(), MaxCirrusAlcoholDebuffDuration); - break; - case 6: - target.AddBuff(ModContent.BuffType(), MaxCirrusAlcoholDebuffDuration); - break; - case 7: - target.AddBuff(ModContent.BuffType(), MaxCirrusAlcoholDebuffDuration); - break; - case 8: - target.AddBuff(ModContent.BuffType(), MaxCirrusAlcoholDebuffDuration); - break; - case 9: - target.AddBuff(ModContent.BuffType(), MaxCirrusAlcoholDebuffDuration); - break; - case 10: - target.AddBuff(ModContent.BuffType(), MaxCirrusAlcoholDebuffDuration); - break; - case 11: - target.AddBuff(ModContent.BuffType(), MaxCirrusAlcoholDebuffDuration); - break; - case 12: - target.AddBuff(ModContent.BuffType(), MaxCirrusAlcoholDebuffDuration); - break; - case 13: - target.AddBuff(ModContent.BuffType(), MaxCirrusAlcoholDebuffDuration); - break; - case 14: - target.AddBuff(ModContent.BuffType(), MaxCirrusAlcoholDebuffDuration); - break; - case 15: - target.AddBuff(ModContent.BuffType(), MaxCirrusAlcoholDebuffDuration); - break; - case 16: - target.AddBuff(ModContent.BuffType(), MaxCirrusAlcoholDebuffDuration); - break; - case 17: - target.AddBuff(ModContent.BuffType(), MaxCirrusAlcoholDebuffDuration); - break; - case 18: - target.AddBuff(ModContent.BuffType(), MaxCirrusAlcoholDebuffDuration); - break; - case 19: - target.AddBuff(ModContent.BuffType(), MaxCirrusAlcoholDebuffDuration); - break; - case 20: - target.AddBuff(ModContent.BuffType(), MaxCirrusAlcoholDebuffDuration); - break; - } } } } diff --git a/NPCs/SupremeCalamitas/SupremeCirrus_Shimmered.png b/NPCs/SupremeCalamitas/SupremeCirrus_Shimmered.png deleted file mode 100644 index 1ce3adfdf2973fefc5da3554da04d96baafcd677..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5692 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 diff --git a/NPCs/SupremeCalamitas/SupremeCirrus.png b/NPCs/SupremeCalamitas/SupremePermafrost.png similarity index 100% rename from NPCs/SupremeCalamitas/SupremeCirrus.png rename to NPCs/SupremeCalamitas/SupremePermafrost.png diff --git a/NPCs/TownNPCs/DILF.cs b/NPCs/TownNPCs/DILF.cs index 9b2de8371c..e3f0102a49 100644 --- a/NPCs/TownNPCs/DILF.cs +++ b/NPCs/TownNPCs/DILF.cs @@ -81,7 +81,13 @@ public override void AI() } } - public override bool CanTownNPCSpawn(int numTownNPCs) => DownedBossSystem.downedCryogen; + public override bool CanTownNPCSpawn(int numTownNPCs) + { + if (NPC.AnyNPCs(ModContent.NPCType()) && Main.zenithWorld) + return false; + + return DownedBossSystem.downedCryogen; + } public override List SetNPCNameList() => new List() { this.GetLocalizedValue("Name.Permafrost") }; diff --git a/Projectiles/Boss/BrimstoneBarrage.cs b/Projectiles/Boss/BrimstoneBarrage.cs index 5c4f0f70eb..eef4c84387 100644 --- a/Projectiles/Boss/BrimstoneBarrage.cs +++ b/Projectiles/Boss/BrimstoneBarrage.cs @@ -153,8 +153,12 @@ public override bool PreDraw(ref Color lightColor) { if (Main.npc[CalamityGlobalNPC.SCal].active) { - if (Main.npc[CalamityGlobalNPC.SCal].ModNPC().cirrus) + if (Main.npc[CalamityGlobalNPC.SCal].ModNPC().permafrost) + { + lightColor.G = (byte)(255 * Projectile.Opacity); lightColor.B = (byte)(255 * Projectile.Opacity); + lightColor.R = 0; + } } } diff --git a/Projectiles/Boss/BrimstoneHellblast.cs b/Projectiles/Boss/BrimstoneHellblast.cs index c30a023c2f..a142617262 100644 --- a/Projectiles/Boss/BrimstoneHellblast.cs +++ b/Projectiles/Boss/BrimstoneHellblast.cs @@ -103,8 +103,12 @@ public override bool PreDraw(ref Color lightColor) { if (Main.npc[CalamityGlobalNPC.SCal].active) { - if (Main.npc[CalamityGlobalNPC.SCal].ModNPC().cirrus) + if (Main.npc[CalamityGlobalNPC.SCal].ModNPC().permafrost) + { + lightColor.G = (byte)(255 * Projectile.Opacity); lightColor.B = (byte)(255 * Projectile.Opacity); + lightColor.R = 0; + } } } diff --git a/Projectiles/Boss/BrimstoneHellblast2.cs b/Projectiles/Boss/BrimstoneHellblast2.cs index d34e761d03..44645f2418 100644 --- a/Projectiles/Boss/BrimstoneHellblast2.cs +++ b/Projectiles/Boss/BrimstoneHellblast2.cs @@ -84,8 +84,12 @@ public override bool PreDraw(ref Color lightColor) { if (Main.npc[CalamityGlobalNPC.SCal].active) { - if (Main.npc[CalamityGlobalNPC.SCal].ModNPC().cirrus) + if (Main.npc[CalamityGlobalNPC.SCal].ModNPC().permafrost) + { + lightColor.G = (byte)(255 * Projectile.Opacity); lightColor.B = (byte)(255 * Projectile.Opacity); + lightColor.R = 0; + } } } diff --git a/Projectiles/Boss/BrimstoneMonster.cs b/Projectiles/Boss/BrimstoneMonster.cs index 7ea0d0e4e0..21f7c6fb1e 100644 --- a/Projectiles/Boss/BrimstoneMonster.cs +++ b/Projectiles/Boss/BrimstoneMonster.cs @@ -272,7 +272,7 @@ public override bool CanHitPlayer(Player player) if (cannotBeHurt) return true; - // Applies Vulnerability Hex and/or the effects of Supreme Cirrus' HAGE faces. + // Applies Vulnerability Hex and/or the effects of Supreme Permafrost' HAGE faces. OnHitPlayer_Internal(player); // Compute distance for direct health reduction from overlap. @@ -334,12 +334,12 @@ private static void OnHitPlayer_Internal(Player target) { target.AddBuff(ModContent.BuffType(), 360, true); - // Remove all positive buffs from the player if they're hit by HAGE while Cirrus is alive. + // Remove all positive buffs from the player if they're hit by HAGE while Permafrost is alive. if (CalamityGlobalNPC.SCal != -1) { if (Main.npc[CalamityGlobalNPC.SCal].active) { - if (Main.npc[CalamityGlobalNPC.SCal].ModNPC().cirrus) + if (Main.npc[CalamityGlobalNPC.SCal].ModNPC().permafrost) { for (int l = 0; l < Player.MaxBuffs; l++) { @@ -400,8 +400,8 @@ public override bool PreDraw(ref Color lightColor) Main.spriteBatch.End(); Main.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, Main.Rasterizer, null, Main.GameViewMatrix.TransformationMatrix); - bool isCirrus = CalamityGlobalNPC.SCal != -1 && Main.npc[CalamityGlobalNPC.SCal].active && Main.npc[CalamityGlobalNPC.SCal].ModNPC().cirrus; - if (isCirrus) + bool isPermafrost = CalamityGlobalNPC.SCal != -1 && Main.npc[CalamityGlobalNPC.SCal].active && Main.npc[CalamityGlobalNPC.SCal].ModNPC().permafrost; + if (isPermafrost) { Texture2D hageTex = ModContent.Request("CalamityMod/Projectiles/Boss/BrimstoneMonsterII").Value; lightColor.B = (byte)(255 * Projectile.Opacity); diff --git a/Projectiles/Boss/BrimstoneWave.cs b/Projectiles/Boss/BrimstoneWave.cs index abb32499e3..8f8d972be0 100644 --- a/Projectiles/Boss/BrimstoneWave.cs +++ b/Projectiles/Boss/BrimstoneWave.cs @@ -87,8 +87,12 @@ public override bool PreDraw(ref Color lightColor) { if (Main.npc[CalamityGlobalNPC.SCal].active) { - if (Main.npc[CalamityGlobalNPC.SCal].ModNPC().cirrus) + if (Main.npc[CalamityGlobalNPC.SCal].ModNPC().permafrost) + { + lightColor.G = (byte)(255 * Projectile.Opacity); lightColor.B = (byte)(255 * Projectile.Opacity); + lightColor.R = 0; + } } } diff --git a/Projectiles/Boss/CirrusPhotonRipperProjectile.cs b/Projectiles/Boss/PermafrostAbsoluteZeroProjectile.cs similarity index 78% rename from Projectiles/Boss/CirrusPhotonRipperProjectile.cs rename to Projectiles/Boss/PermafrostAbsoluteZeroProjectile.cs index 8e5c509e28..8a27c303bd 100644 --- a/Projectiles/Boss/CirrusPhotonRipperProjectile.cs +++ b/Projectiles/Boss/PermafrostAbsoluteZeroProjectile.cs @@ -9,13 +9,13 @@ namespace CalamityMod.Projectiles.Boss { - public class CirrusPhotonRipperProjectile : ModProjectile, ILocalizedModType + public class PermafrostAbsoluteZeroProjectile : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Boss"; - public override string Texture => "CalamityMod/Projectiles/Melee/PhotonRipperProjectile"; + public override string Texture => "CalamityMod/Items/Weapons/Melee/AbsoluteZero"; - public NPC Cirrus => Main.npc.IndexInRange((int)Projectile.ai[2]) ? Main.npc[(int)Projectile.ai[2]] : null; + public NPC Permafrost => Main.npc.IndexInRange((int)Projectile.ai[2]) ? Main.npc[(int)Projectile.ai[2]] : null; public const float ZeroChargeDamageRatio = 0.36f; public const float ToothDamageRatio = 0.1666667f; public const int ToothShootRate = 5; // One chainsaw tooth is emitted every this many frames. @@ -44,36 +44,33 @@ public override void SetDefaults() public override bool PreDraw(ref Color lightColor) { Texture2D texture = Terraria.GameContent.TextureAssets.Projectile[Projectile.type].Value; - Texture2D glowmaskTexture = ModContent.Request("CalamityMod/Projectiles/Melee/PhotonRipperGlowmask").Value; - Rectangle glowmaskRectangle = glowmaskTexture.Frame(1, 6, 0, Projectile.frame); Vector2 origin = texture.Size() * 0.5f; Vector2 drawPosition = Projectile.Center - Main.screenPosition; SpriteEffects direction = Projectile.spriteDirection == 1 ? SpriteEffects.None : SpriteEffects.FlipHorizontally; Main.EntitySpriteDraw(texture, drawPosition, null, Projectile.GetAlpha(lightColor), Projectile.rotation, origin, Projectile.scale, direction, 0); - Main.EntitySpriteDraw(glowmaskTexture, drawPosition, glowmaskRectangle, Color.HotPink, Projectile.rotation, origin, Projectile.scale, direction, 0); return false; } public override void AI() { - // Die if Cirrus disappears. - if (Cirrus is null || !Cirrus.active) + // Die if Permafrost disappears. + if (Permafrost is null || !Permafrost.active) { Projectile.Kill(); return; } - // Die if Cirrus shouldn't be using it. - int cirrusBulletHellCounter = Cirrus.ModNPC().bulletHellCounter2; - if (!(cirrusBulletHellCounter > SupremeCalamitas.SecondBulletHellEndValue && cirrusBulletHellCounter < SupremeCalamitas.ThirdBulletHellEndValue) && - !(cirrusBulletHellCounter > SupremeCalamitas.FourthBulletHellEndValue && cirrusBulletHellCounter < SupremeCalamitas.FifthBulletHellEndValue)) + // Die if Permafrost shouldn't be using it. + int permafrostBulletHellCounter = Permafrost.ModNPC().bulletHellCounter2; + if (!(permafrostBulletHellCounter > SupremeCalamitas.SecondBulletHellEndValue && permafrostBulletHellCounter < SupremeCalamitas.ThirdBulletHellEndValue) && + !(permafrostBulletHellCounter > SupremeCalamitas.FourthBulletHellEndValue && permafrostBulletHellCounter < SupremeCalamitas.FifthBulletHellEndValue)) { Projectile.Kill(); return; } - Projectile.damage = SupremeCalamitas.CirrusPhotonRipperDamage; + Projectile.damage = SupremeCalamitas.PermafrostPhotonRipperDamage; DetermineDamage(); PlayChainsawSounds(); @@ -81,14 +78,14 @@ public override void AI() // Determines the owner's position whilst incorporating their fullRotation field. // It uses vector transformation on a Z rotation matrix based on said rotation under the hood. // This is essentially just the pure mathematical definition of the RotatedBy method. - Vector2 cirrusRotatedPosition = Cirrus.Center; - float rotation = Cirrus.rotation; - Vector2 vector = Cirrus.Bottom + new Vector2(0f, Cirrus.gfxOffY); + Vector2 permafrostRotatedPosition = Permafrost.Center; + float rotation = Permafrost.rotation; + Vector2 vector = Permafrost.Bottom + new Vector2(0f, Permafrost.gfxOffY); Vector2 vector2 = new Vector2(0f, -4f) + new Vector2(0f, 4f).RotatedBy(rotation); - cirrusRotatedPosition.Y += Cirrus.gfxOffY; - cirrusRotatedPosition = vector + (cirrusRotatedPosition - vector).RotatedBy(rotation) + vector2; - HandleMovement(cirrusRotatedPosition); - DetermineVisuals(cirrusRotatedPosition); + permafrostRotatedPosition.Y += Permafrost.gfxOffY; + permafrostRotatedPosition = vector + (permafrostRotatedPosition - vector).RotatedBy(rotation) + vector2; + HandleMovement(permafrostRotatedPosition); + DetermineVisuals(permafrostRotatedPosition); EmitPrettyDust(); if (Time % ToothShootRate == ToothShootRate - 1f) @@ -129,7 +126,7 @@ public void DetermineDamage() } } - public void DetermineVisuals(Vector2 cirrusRotatedPosition) + public void DetermineVisuals(Vector2 permafrostRotatedPosition) { float directionAngle = Projectile.velocity.ToRotation(); Projectile.rotation = directionAngle; @@ -146,8 +143,8 @@ public void DetermineVisuals(Vector2 cirrusRotatedPosition) if (Projectile.spriteDirection != oldDirection) Projectile.rotation -= MathHelper.Pi; - // Positioning close to the Cirrus' arm. - Projectile.position = cirrusRotatedPosition - Projectile.Size * 0.5f + directionAngle.ToRotationVector2() * 30f; + // Positioning close to the Permafrost's arm. + Projectile.position = permafrostRotatedPosition - Projectile.Size * 0.5f + directionAngle.ToRotationVector2() * 30f; // Update the position a tiny bit every frame at random to make it look like the saw is vibrating. // It is reset on the next frame. @@ -164,9 +161,9 @@ public void DetermineVisuals(Vector2 cirrusRotatedPosition) } } - public void HandleMovement(Vector2 cirrusRotatedPosition) + public void HandleMovement(Vector2 permafrostRotatedPosition) { - Vector2 idealAimDirection = (Main.player[Cirrus.target].Center - cirrusRotatedPosition).SafeNormalize(Vector2.UnitX * Cirrus.direction); + Vector2 idealAimDirection = (Main.player[Permafrost.target].Center - permafrostRotatedPosition).SafeNormalize(Vector2.UnitX * Permafrost.direction); float angularAimVelocity = 0.03f; float directionAngularDisparity = Projectile.velocity.AngleBetween(idealAimDirection) / MathHelper.Pi; @@ -179,7 +176,7 @@ public void HandleMovement(Vector2 cirrusRotatedPosition) else Projectile.velocity = idealAimDirection; - Projectile.velocity = Projectile.velocity.SafeNormalize(Vector2.UnitX * Cirrus.direction); + Projectile.velocity = Projectile.velocity.SafeNormalize(Vector2.UnitX * Permafrost.direction); } public void EmitPrettyDust() @@ -213,7 +210,7 @@ public void ReleasePrismTeeth() return; float shootReach = MathHelper.SmoothStep(Projectile.width * 1.8f, Projectile.width * 5.3f + 16f, ChargeUpPower); - float distanceFromTarget = Cirrus.Distance(Main.player[Cirrus.target].Center); + float distanceFromTarget = Permafrost.Distance(Main.player[Permafrost.target].Center); // If the distance to the mouse is less than the base reach, reach only to mouse. // This way the player can more directly control the crystals if they want. @@ -227,7 +224,7 @@ public void ReleasePrismTeeth() shootReach = 72f; } - Projectile.NewProjectile(Projectile.GetSource_FromThis(), Cirrus.Center, Projectile.velocity, ModContent.ProjectileType(), (int)ToothDamage, 0f, Projectile.owner, shootReach, Projectile.whoAmI, Projectile.ai[2]); + Projectile.NewProjectile(Projectile.GetSource_FromThis(), Permafrost.Center, Projectile.velocity, ModContent.ProjectileType(), (int)ToothDamage, 0f, Projectile.owner, shootReach, Projectile.whoAmI, Projectile.ai[2]); } public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) diff --git a/Projectiles/Boss/CirrusBlast.cs b/Projectiles/Boss/PermafrostBlast.cs similarity index 98% rename from Projectiles/Boss/CirrusBlast.cs rename to Projectiles/Boss/PermafrostBlast.cs index 3f0496de0d..e8b7ac1c48 100644 --- a/Projectiles/Boss/CirrusBlast.cs +++ b/Projectiles/Boss/PermafrostBlast.cs @@ -12,7 +12,7 @@ namespace CalamityMod.Projectiles.Boss { - public class CirrusBlast : BaseLaserbeamProjectile, ILocalizedModType + public class PermafrostBlast : BaseLaserbeamProjectile, ILocalizedModType { // Modified clone of Seraphim's Laser public new string LocalizationCategory => "Projectiles.Boss"; diff --git a/Projectiles/Boss/CirrusBlaster.cs b/Projectiles/Boss/PermafrostBlaster.cs similarity index 90% rename from Projectiles/Boss/CirrusBlaster.cs rename to Projectiles/Boss/PermafrostBlaster.cs index ab60a0adc6..553ba53539 100644 --- a/Projectiles/Boss/CirrusBlaster.cs +++ b/Projectiles/Boss/PermafrostBlaster.cs @@ -7,11 +7,11 @@ namespace CalamityMod.Projectiles.Boss { - public class CirrusBlaster : ModProjectile, ILocalizedModType + public class PermafrostBlaster : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Boss"; - public override string Texture => "CalamityMod/Items/Potions/Alcohol/OddMushroom"; + public override string Texture => "CalamityMod/Items/Accessories/PermafrostsConcoction"; public static readonly SoundStyle SANSCharge = new("CalamityMod/Sounds/Custom/Ravager/GasterBlasterCharge"); public static readonly SoundStyle SANSFire = new("CalamityMod/Sounds/Custom/Ravager/GasterBlasterFire"); public Vector2 storedVelocity; @@ -45,7 +45,7 @@ public override void AI() { Projectile.ai[0] = 90f; if (Projectile.owner == Main.myPlayer) - Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, storedVelocity, ModContent.ProjectileType(), Projectile.damage, 0f, Projectile.owner, Projectile.ai[1], Projectile.whoAmI); + Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, storedVelocity, ModContent.ProjectileType(), Projectile.damage, 0f, Projectile.owner, Projectile.ai[1], Projectile.whoAmI); SoundEngine.PlaySound(SANSFire, Projectile.Center); // Funny Gaster Blaster sounds #2 } diff --git a/Projectiles/Boss/CirrusPhotonRipperPrismTooth.cs b/Projectiles/Boss/PermafrostColdheartIcicle.cs similarity index 81% rename from Projectiles/Boss/CirrusPhotonRipperPrismTooth.cs rename to Projectiles/Boss/PermafrostColdheartIcicle.cs index 7465dfea8a..c8092285c9 100644 --- a/Projectiles/Boss/CirrusPhotonRipperPrismTooth.cs +++ b/Projectiles/Boss/PermafrostColdheartIcicle.cs @@ -1,5 +1,6 @@ using System; using CalamityMod.Buffs.DamageOverTime; +using CalamityMod.Buffs.StatDebuffs; using CalamityMod.Graphics.Primitives; using CalamityMod.NPCs.SupremeCalamitas; using Microsoft.Xna.Framework; @@ -12,15 +13,15 @@ namespace CalamityMod.Projectiles.Boss { - public class CirrusPhotonRipperPrismTooth : ModProjectile, ILocalizedModType + public class PermafrostColdheartIcicle : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Boss"; - public override string Texture => "CalamityMod/Projectiles/Melee/PrismTooth"; + public override string Texture => "CalamityMod/Items/ColdheartIcicle"; public const int Lifetime = 80; - public NPC Cirrus => Main.npc.IndexInRange((int)Projectile.ai[2]) ? Main.npc[(int)Projectile.ai[2]] : null; + public NPC Permafrost => Main.npc.IndexInRange((int)Projectile.ai[2]) ? Main.npc[(int)Projectile.ai[2]] : null; public ref float ShootReach => ref Projectile.ai[0]; @@ -48,17 +49,17 @@ public override void SetDefaults() public override void AI() { - // Die if Cirrus disappears. - if (Cirrus is null || !Cirrus.active) + // Die if Permafrost disappears. + if (Permafrost is null || !Permafrost.active) { Projectile.Kill(); return; } - // Die if Cirrus shouldn't be using it. - int cirrusBulletHellCounter = Cirrus.ModNPC().bulletHellCounter2; - if (!(cirrusBulletHellCounter > SupremeCalamitas.SecondBulletHellEndValue && cirrusBulletHellCounter < SupremeCalamitas.ThirdBulletHellEndValue) && - !(cirrusBulletHellCounter > SupremeCalamitas.FourthBulletHellEndValue && cirrusBulletHellCounter < SupremeCalamitas.FifthBulletHellEndValue)) + // Die if Permafrost shouldn't be using it. + int permafrostBulletHellCounter = Permafrost.ModNPC().bulletHellCounter2; + if (!(permafrostBulletHellCounter > SupremeCalamitas.SecondBulletHellEndValue && permafrostBulletHellCounter < SupremeCalamitas.ThirdBulletHellEndValue) && + !(permafrostBulletHellCounter > SupremeCalamitas.FourthBulletHellEndValue && permafrostBulletHellCounter < SupremeCalamitas.FifthBulletHellEndValue)) { Projectile.Kill(); return; @@ -82,13 +83,13 @@ public override void AI() // In this context, the velocity is simply the initial direction as a unit vector- it does not actually influence movement in any way. positionOffset = positionOffset.RotatedBy(Projectile.velocity.ToRotation() - MathHelper.PiOver2); - Vector2 cirrusRotatedPosition = Cirrus.Center; - float rotation = Cirrus.rotation; - Vector2 vector = Cirrus.Bottom + new Vector2(0f, Cirrus.gfxOffY); + Vector2 permafrostRotatedPosition = Permafrost.Center; + float rotation = Permafrost.rotation; + Vector2 vector = Permafrost.Bottom + new Vector2(0f, Permafrost.gfxOffY); Vector2 vector2 = new Vector2(0f, -4f) + new Vector2(0f, 4f).RotatedBy(rotation); - cirrusRotatedPosition.Y += Cirrus.gfxOffY; - cirrusRotatedPosition = vector + (cirrusRotatedPosition - vector).RotatedBy(rotation) + vector2; - Projectile.Center = cirrusRotatedPosition + Projectile.velocity * 42f + positionOffset; + permafrostRotatedPosition.Y += Permafrost.gfxOffY; + permafrostRotatedPosition = vector + (permafrostRotatedPosition - vector).RotatedBy(rotation) + vector2; + Projectile.Center = permafrostRotatedPosition + Projectile.velocity * 42f + positionOffset; Projectile.Opacity = Utils.GetLerpValue(0f, 12f, Time, true) * Utils.GetLerpValue(Lifetime, Lifetime - 12f, Lifetime - Projectile.timeLeft, true); // Destroy trees within the range of the past 20 oldPos positions. @@ -127,11 +128,11 @@ public void AbsolutelyFuckingAnnihilateTrees(int x, int y) AchievementsHelper.CurrentlyMining = false; } - public override Color? GetAlpha(Color lightColor) => Color.HotPink; + public override Color? GetAlpha(Color lightColor) => Color.LightCyan; internal float WidthFunction(float completionRatio) => Projectile.scale * 24f * (1f - Utils.GetLerpValue(0.7f, 1f, completionRatio, true)) + 1f; - internal Color ColorFunction(float completionRatio) => Color.HotPink * Projectile.Opacity; + internal Color ColorFunction(float completionRatio) => Color.LightCyan * Projectile.Opacity; public override bool PreDraw(ref Color lightColor) { @@ -163,6 +164,6 @@ public override bool PreDraw(ref Color lightColor) // Prevent the crystals from utilizing velocity. Their movement is entirely dependant on Center setting. public override bool ShouldUpdatePosition() => false; - public override void OnHitPlayer(Player target, Player.HurtInfo info) => target.AddBuff(ModContent.BuffType(), 300); + public override void OnHitPlayer(Player target, Player.HurtInfo info) => target.AddBuff(ModContent.BuffType(), 300); } } diff --git a/Projectiles/Boss/CirrusVolatileVodkaBottle.cs b/Projectiles/Boss/PermafrostMeat.cs similarity index 55% rename from Projectiles/Boss/CirrusVolatileVodkaBottle.cs rename to Projectiles/Boss/PermafrostMeat.cs index b4efe39513..5a560b1b7b 100644 --- a/Projectiles/Boss/CirrusVolatileVodkaBottle.cs +++ b/Projectiles/Boss/PermafrostMeat.cs @@ -12,11 +12,11 @@ namespace CalamityMod.Projectiles.Boss { - public class CirrusVolatileVodkaBottle : ModProjectile, ILocalizedModType + public class PermafrostMeat : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Boss"; - public override string Texture => "CalamityMod/Items/Potions/Alcohol/FabsolsVodka"; + public override string Texture => "CalamityMod/Items/Potions/DeliciousMeat"; public override void SetDefaults() { @@ -34,9 +34,14 @@ public override void AI() { if (Projectile.ai[0] == 0f) { - SoundEngine.PlaySound(SoundID.Item106, Projectile.Center); + SoundEngine.PlaySound(SoundID.NPCDeath43 with { Volume = SoundID.NPCDeath43.Volume * 0.35f, Pitch = 0.3f }, Projectile.position); Projectile.ai[0] = 1f; } + if (Projectile.ai[1] == 0) + { + Projectile.aiStyle = -1; + Projectile.tileCollide = false; + } } public override bool PreDraw(ref Color lightColor) @@ -48,11 +53,11 @@ public override bool PreDraw(ref Color lightColor) public override void OnKill(int timeLeft) { - SoundEngine.PlaySound(SoundID.Shatter, Projectile.Center); + SoundEngine.PlaySound(SoundID.NPCDeath43 with { Volume = SoundID.NPCDeath43.Volume * 0.35f }, Projectile.position); for (int i = 0; i < 10; i++) { - int dust = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, (int)CalamityDusts.PurpleCosmilite, 0f, 0f, 0, default, 1.2f); + int dust = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.IceGolem, 0f, 0f, 0, default, 1.2f); Main.dust[dust].velocity *= 3f; if (Main.rand.NextBool()) { @@ -63,32 +68,28 @@ public override void OnKill(int timeLeft) for (int i = 0; i < 20; i++) { - int dust = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, (int)CalamityDusts.BlueCosmilite, 0f, 0f, 0, default, 1.7f); + int dust = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.IceGolem, 0f, 0f, 0, default, 1.7f); Main.dust[dust].noGravity = true; Main.dust[dust].velocity *= 5f; - dust = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, (int)CalamityDusts.PurpleCosmilite, 0f, 0f, 0, default, 1f); - Main.dust[dust].velocity *= 2f; } - if (Projectile.owner == Main.myPlayer) + if (Projectile.ai[2] == 0) { - int totalProjectiles = 3; - float radians = MathHelper.TwoPi / totalProjectiles; - int type = ModContent.ProjectileType(); - float velocity = 8f; - double angleA = radians * 0.5; - double angleB = MathHelper.ToRadians(90f) - angleA; - float velocityX2 = (float)(velocity * Math.Sin(angleA) / Math.Sin(angleB)); - Vector2 spinningPoint = Main.rand.NextBool() ? new Vector2(0f, -velocity) : new Vector2(-velocityX2, -velocity); - for (int k = 0; k < totalProjectiles; k++) + if (Projectile.owner == Main.myPlayer) { - Vector2 velocity2 = spinningPoint.RotatedBy(radians * k); - int proj = Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center + Vector2.Normalize(velocity2) * 10f, velocity2, type, (int)Math.Round(Projectile.damage * 0.8), 0f, Main.myPlayer); - if (proj.WithinBounds(Main.maxProjectiles)) + int totalProjectiles = 3; + float radians = MathHelper.TwoPi / totalProjectiles; + float velocity = 14f; + double angleA = radians * 0.5; + double angleB = MathHelper.ToRadians(90f) - angleA; + float velocityX2 = (float)(velocity * Math.Sin(angleA) / Math.Sin(angleB)); + Vector2 spinningPoint = Main.rand.NextBool() ? new Vector2(0f, -velocity) : new Vector2(-velocityX2, -velocity); + for (int k = 0; k < totalProjectiles; k++) { - Main.projectile[proj].DamageType = DamageClass.Default; - Main.projectile[proj].friendly = false; - Main.projectile[proj].hostile = true; + Vector2 velocity2 = spinningPoint.RotatedBy(radians * k); + int p = Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center + Vector2.Normalize(velocity2) * 10f, velocity2, Type, (int)Math.Round(Projectile.damage * 0.8), 0f, Main.myPlayer, ai2: 1); + Main.projectile[p].tileCollide = false; + Main.projectile[p].aiStyle = -1; } } } @@ -97,7 +98,6 @@ public override void OnKill(int timeLeft) public override void OnHitPlayer(Player target, Player.HurtInfo info) { Projectile.Kill(); - target.AddBuff(ModContent.BuffType(), 54000); } } } diff --git a/Projectiles/Boss/SCalBrimstoneFireblast.cs b/Projectiles/Boss/SCalBrimstoneFireblast.cs index fce044dea7..3c272c6d33 100644 --- a/Projectiles/Boss/SCalBrimstoneFireblast.cs +++ b/Projectiles/Boss/SCalBrimstoneFireblast.cs @@ -168,8 +168,12 @@ public override bool PreDraw(ref Color lightColor) { if (Main.npc[CalamityGlobalNPC.SCal].active) { - if (Main.npc[CalamityGlobalNPC.SCal].ModNPC().cirrus) + if (Main.npc[CalamityGlobalNPC.SCal].ModNPC().permafrost) + { + lightColor.G = (byte)(255 * Projectile.Opacity); lightColor.B = (byte)(255 * Projectile.Opacity); + lightColor.R = 0; + } } } diff --git a/Projectiles/Boss/SCalBrimstoneGigablast.cs b/Projectiles/Boss/SCalBrimstoneGigablast.cs index c0c1fab63b..cc9fc1c8b3 100644 --- a/Projectiles/Boss/SCalBrimstoneGigablast.cs +++ b/Projectiles/Boss/SCalBrimstoneGigablast.cs @@ -153,8 +153,12 @@ public override bool PreDraw(ref Color lightColor) { if (Main.npc[CalamityGlobalNPC.SCal].active) { - if (Main.npc[CalamityGlobalNPC.SCal].ModNPC().cirrus) + if (Main.npc[CalamityGlobalNPC.SCal].ModNPC().permafrost) + { + lightColor.G = (byte)(255 * Projectile.Opacity); lightColor.B = (byte)(255 * Projectile.Opacity); + lightColor.R = 0; + } } } diff --git a/Projectiles/Boss/SCalRitualDrama.cs b/Projectiles/Boss/SCalRitualDrama.cs index f72cbabdbf..12c8d1c503 100644 --- a/Projectiles/Boss/SCalRitualDrama.cs +++ b/Projectiles/Boss/SCalRitualDrama.cs @@ -1,5 +1,6 @@ using CalamityMod.Dusts; using CalamityMod.Items.Weapons.Summon; +using CalamityMod.NPCs.Cryogen; using CalamityMod.NPCs.SupremeCalamitas; using CalamityMod.Particles; using CalamityMod.Skies; @@ -98,12 +99,12 @@ public void SummonSCal() NPC scal = CalamityUtils.SpawnBossBetter(spawnPosition, ModContent.NPCType()); if (Projectile.ai[1] == 1) { - scal.ModNPC().cirrus = true; + scal.ModNPC().permafrost = true; } } // Make a laugh sound and create a burst of brimstone dust. - SoundStyle SpawnSound = Projectile.ai[1] == 1 ? SoundID.Item107 : SupremeCalamitas.SpawnSound; + SoundStyle SpawnSound = Projectile.ai[1] == 1 ? Cryogen.DeathSound : SupremeCalamitas.SpawnSound; SoundEngine.PlaySound(SpawnSound, Projectile.Center); // Make a sudden screen shake. @@ -112,7 +113,7 @@ public void SummonSCal() // Generate a dust explosion at the ritual's position. for (int i = 0; i < 90; i++) { - Dust spawnDust = Dust.NewDustPerfect(Projectile.Center, Projectile.ai[1] == 1 ? (int)CalamityDusts.PurpleCosmilite : (int)CalamityDusts.Brimstone, new Vector2(30, 30).RotatedByRandom(100) * Main.rand.NextFloat(0.05f, 1.2f)); + Dust spawnDust = Dust.NewDustPerfect(Projectile.Center, Projectile.ai[1] == 1 ? DustID.IceGolem : (int)CalamityDusts.Brimstone, new Vector2(30, 30).RotatedByRandom(100) * Main.rand.NextFloat(0.05f, 1.2f)); spawnDust.noGravity = true; spawnDust.scale = Main.rand.NextFloat(1.2f, 2.3f); } @@ -122,9 +123,9 @@ public void SummonSCal() GlowOrbParticle orb = new GlowOrbParticle(Projectile.Center + sparkVel * 2, sparkVel, false, 120, Main.rand.NextFloat(1.55f, 2.75f), Projectile.ai[1] == 1 ? Color.Magenta : Color.Red, true, true); GeneralParticleHandler.SpawnParticle(orb); } - Particle pulse = new DirectionalPulseRing(Projectile.Center, Vector2.Zero, Projectile.ai[1] == 1 ? Color.Magenta : Color.Red, new Vector2(2f, 2f), 0, 0f, 2.7f, 60); + Particle pulse = new DirectionalPulseRing(Projectile.Center, Vector2.Zero, Projectile.ai[1] == 1 ? Color.Cyan : Color.Red, new Vector2(2f, 2f), 0, 0f, 2.7f, 60); GeneralParticleHandler.SpawnParticle(pulse); - Particle pulse2 = new DirectionalPulseRing(Projectile.Center, Vector2.Zero, Projectile.ai[1] == 1 ? Color.Magenta : new Color(121, 21, 77), new Vector2(2f, 2f), 0, 0f, 2.1f, 60); + Particle pulse2 = new DirectionalPulseRing(Projectile.Center, Vector2.Zero, Projectile.ai[1] == 1 ? Color.LightCyan : new Color(121, 21, 77), new Vector2(2f, 2f), 0, 0f, 2.1f, 60); GeneralParticleHandler.SpawnParticle(pulse2); } } diff --git a/Projectiles/CalamityGlobalProjectile.cs b/Projectiles/CalamityGlobalProjectile.cs index b80b8e3805..de055f33a7 100644 --- a/Projectiles/CalamityGlobalProjectile.cs +++ b/Projectiles/CalamityGlobalProjectile.cs @@ -1825,7 +1825,7 @@ public override bool PreAI(Projectile projectile) int maxHealAmount = 20; // If the target has more than 250 max life, incorporate their total life into the max amount to heal. - // This is done so that more powerful NPCs, such as Cirrus, do not take an eternity to receive meaningful healing benefits + // This is done so that more powerful NPCs, such as Permafrost, do not take an eternity to receive meaningful healing benefits // from the Nurse. if (npcToHeal.lifeMax > 250) maxHealAmount = (int)Math.Max(maxHealAmount, npcToHeal.lifeMax * 0.05f); diff --git a/Scenes/BossBackgroundScenes/DrunkCrabBackgroundScene.cs b/Scenes/BossBackgroundScenes/DrunkCrabBackgroundScene.cs index 5b7ee0d578..771b4e5c3b 100644 --- a/Scenes/BossBackgroundScenes/DrunkCrabBackgroundScene.cs +++ b/Scenes/BossBackgroundScenes/DrunkCrabBackgroundScene.cs @@ -17,27 +17,27 @@ public override bool IsSceneEffectActive(Player player) if (Main.zenithWorld && NPC.AnyNPCs(ModContent.NPCType())) return true; - // Case 2: Supreme Cirrus BH5. - bool cirrusSpecialAttack = false; + // Case 2: Supreme Permafrost BH5. + bool permafrostSpecialAttack = false; - // Try to find Supreme Cirrus, if she exists. She might not. + // Try to find Supreme Permafrost, if he exists. He might not. try { - // Is there an index reference to Supreme Calamitas/Cirrus available? Is it valid? I sure hope so. Thanks TML + // Is there an index reference to Supreme Calamitas/Permafrost available? Is it valid? I sure hope so. Thanks TML if (CalamityGlobalNPC.SCal >= 0 && CalamityGlobalNPC.SCal < Main.maxNPCs && Main.npc[CalamityGlobalNPC.SCal].active) { NPC npc = Main.npc[CalamityGlobalNPC.SCal]; SupremeCalamitas supremeSomeone = npc.ModNPC(); - cirrusSpecialAttack = supremeSomeone is not null && supremeSomeone.cirrus && supremeSomeone.gettingTired5; + permafrostSpecialAttack = supremeSomeone is not null && supremeSomeone.permafrost && supremeSomeone.gettingTired5; } } catch { if (Main.netMode == NetmodeID.SinglePlayer) - Main.NewText("Supreme Cirrus code attempted to crash the game. Did you do something weird?"); + Main.NewText("Supreme Permafrost code attempted to crash the game. Did you do something weird?"); } - return cirrusSpecialAttack; + return permafrostSpecialAttack; } public override void SpecialVisuals(Player player, bool isActive) diff --git a/Skies/DrunkCrabScreenShaderData.cs b/Skies/DrunkCrabScreenShaderData.cs index 2d67cb7706..bbd5110b7d 100644 --- a/Skies/DrunkCrabScreenShaderData.cs +++ b/Skies/DrunkCrabScreenShaderData.cs @@ -13,7 +13,6 @@ namespace CalamityMod.Skies public class DrunkCrabScreenShaderData : ScreenShaderData { public int CrabIndex; - public int CirrusIndex; public DrunkCrabScreenShaderData(string passName) : base(passName) @@ -23,98 +22,43 @@ public DrunkCrabScreenShaderData(string passName) public void UpdateBossIndex() { int CrabType = ModContent.NPCType(); - int CirrusType = ModContent.NPCType(); - bool shouldCheckForCirrus = false; - bool shouldForceDeactivateCirrusShader = false; + int PermafrostType = ModContent.NPCType(); + bool shouldCheckForPermafrost = false; + bool shouldForceDeactivatePermafrostShader = false; if (CalamityGlobalNPC.SCal != -1) { if (Main.npc[CalamityGlobalNPC.SCal].active) { - if (Main.npc[CalamityGlobalNPC.SCal].ModNPC().cirrus) + if (Main.npc[CalamityGlobalNPC.SCal].ModNPC().permafrost) { - shouldCheckForCirrus = Main.npc[CalamityGlobalNPC.SCal].ModNPC().gettingTired5; - shouldForceDeactivateCirrusShader = Main.npc[CalamityGlobalNPC.SCal].ModNPC().giveUpCounter <= 1; + shouldCheckForPermafrost = Main.npc[CalamityGlobalNPC.SCal].ModNPC().gettingTired5; + shouldForceDeactivatePermafrostShader = Main.npc[CalamityGlobalNPC.SCal].ModNPC().giveUpCounter <= 1; } } } - if (shouldCheckForCirrus) - { - if (CirrusIndex >= 0 && Main.npc[CirrusIndex].active && Main.npc[CirrusIndex].type == CirrusType && !shouldForceDeactivateCirrusShader) - return; - - CirrusIndex = -1; + if (CrabIndex >= 0 && Main.npc[CrabIndex].active && Main.npc[CrabIndex].type == CrabType) + return; - if (!shouldForceDeactivateCirrusShader) - { - CirrusIndex = NPC.FindFirstNPC(CirrusType); - } - } - else - { - if (CrabIndex >= 0 && Main.npc[CrabIndex].active && Main.npc[CrabIndex].type == CrabType) - return; - - CrabIndex = NPC.FindFirstNPC(CrabType); - } + CrabIndex = NPC.FindFirstNPC(CrabType); } public override void Update(GameTime gameTime) { - bool shouldCheckForCirrus = false; - if (CalamityGlobalNPC.SCal != -1) - { - if (Main.npc[CalamityGlobalNPC.SCal].active) - { - if (Main.npc[CalamityGlobalNPC.SCal].ModNPC().cirrus) - shouldCheckForCirrus = Main.npc[CalamityGlobalNPC.SCal].ModNPC().gettingTired5; - } - } - - if (shouldCheckForCirrus) - { - if (CirrusIndex == -1) - { - UpdateBossIndex(); - if (CirrusIndex == -1) - Filters.Scene["CalamityMod:DrunkCrabulon"].Deactivate(); - } - } - else + if (CrabIndex == -1 || !Main.zenithWorld) { + UpdateBossIndex(); if (CrabIndex == -1 || !Main.zenithWorld) - { - UpdateBossIndex(); - if (CrabIndex == -1 || !Main.zenithWorld) - Filters.Scene["CalamityMod:DrunkCrabulon"].Deactivate(); - } - } + Filters.Scene["CalamityMod:DrunkCrabulon"].Deactivate(); + } } public override void Apply() { UpdateBossIndex(); - bool shouldCheckForCirrus = false; - if (CalamityGlobalNPC.SCal != -1) - { - if (Main.npc[CalamityGlobalNPC.SCal].active) - { - if (Main.npc[CalamityGlobalNPC.SCal].ModNPC().cirrus) - shouldCheckForCirrus = Main.npc[CalamityGlobalNPC.SCal].ModNPC().gettingTired5; - } - } - - if (shouldCheckForCirrus) - { - if (CirrusIndex != -1) - UseTargetPosition(Main.npc[CirrusIndex].Center); - } - else - { - if (CrabIndex != -1) + if (CrabIndex != -1) UseTargetPosition(Main.npc[CrabIndex].Center); - } base.Apply(); } diff --git a/Skies/SCalScreenShaderData.cs b/Skies/SCalScreenShaderData.cs index 1e562f1683..397c16aa85 100644 --- a/Skies/SCalScreenShaderData.cs +++ b/Skies/SCalScreenShaderData.cs @@ -44,7 +44,7 @@ public override void Apply() { UseTargetPosition(Main.npc[SCalIndex].Center); - if (Main.npc[SCalIndex].ModNPC().cirrus) + if (Main.npc[SCalIndex].ModNPC().permafrost) Filters.Scene["CalamityMod:SupremeCalamitas"].GetShader().UseColor(0.9f, 0.3f, 0.9f); } base.Apply(); diff --git a/Skies/SCalSky.cs b/Skies/SCalSky.cs index 739d66cdee..1480e1012a 100644 --- a/Skies/SCalSky.cs +++ b/Skies/SCalSky.cs @@ -140,7 +140,7 @@ static Color selectCinderColor() return Color.Transparent; NPC scal = Main.npc[CalamityGlobalNPC.SCal]; - bool cirrus = scal.ModNPC().cirrus; + bool permafrost = scal.ModNPC().permafrost; float lifeRatio = scal.life / (float)scal.lifeMax; if (NPC.AnyNPCs(ModContent.NPCType()) == true && NPC.AnyNPCs(ModContent.NPCType()) == false) @@ -151,11 +151,11 @@ static Color selectCinderColor() return Color.Lerp(Color.Red, Color.IndianRed, Main.rand.NextFloat(0f, 1f)); if (lifeRatio > 0.5f) - return Color.Lerp(cirrus ? Color.Pink : Color.Red, cirrus ? Color.Violet : Color.Crimson, Main.rand.NextFloat(0f, 1f)); + return Color.Lerp(permafrost ? Color.LightBlue : Color.Red, permafrost ? Color.DarkCyan : Color.Crimson, Main.rand.NextFloat(0f, 1f)); else if (lifeRatio > 0.3f || scal.ModNPC().postMusicHit == false) - return Color.Lerp(cirrus ? Color.Cyan : Color.Red, cirrus ? Color.DarkCyan : Color.Magenta, Main.rand.NextFloat(0f, 0.7f)); + return Color.Lerp(permafrost ? Color.LightBlue : Color.Red, permafrost ? Color.DarkCyan : Color.Magenta, Main.rand.NextFloat(0f, 0.7f)); else if (lifeRatio > 0.01f) - return Color.Lerp(cirrus ? Color.Pink : Color.Red, cirrus ? Color.Green : Color.Yellow, Main.rand.NextFloat(0f, 0.88f)); + return Color.Lerp(permafrost ? Color.LightBlue : Color.Red, permafrost ? Color.MediumBlue : Color.Yellow, Main.rand.NextFloat(0f, 0.88f)); else return Color.Lerp(Color.Gray, Color.White, Main.rand.NextFloat(0f, 0.65f)); } @@ -253,15 +253,15 @@ public override void Draw(SpriteBatch spriteBatch, float minDepth, float maxDept } NPC scal = Main.npc[CalamityGlobalNPC.SCal]; - bool cirrus = scal.ModNPC().cirrus; + bool permafrost = scal.ModNPC().permafrost; float lifeRatio = scal.life / (float)scal.lifeMax; if (lifeRatio > 0.5f) - cinderColortoBe = Color.Lerp(cirrus ? Color.Pink : Color.Red, cirrus ? Color.Violet : Color.Crimson, Main.rand.NextFloat(0f, 1f)); + cinderColortoBe = Color.Lerp(permafrost ? Color.Cyan : Color.Red, permafrost ? Color.MediumBlue : Color.Crimson, Main.rand.NextFloat(0f, 1f)); else if (lifeRatio > 0.3f || scal.ModNPC().postMusicHit == false) - cinderColortoBe = Color.Lerp(cirrus ? Color.Cyan : Color.Red, cirrus ? Color.DarkCyan : Color.Magenta, Main.rand.NextFloat(0f, 0.7f)); + cinderColortoBe = Color.Lerp(permafrost ? Color.Cyan : Color.Red, permafrost ? Color.DarkCyan : Color.Magenta, Main.rand.NextFloat(0f, 0.7f)); else if (lifeRatio > 0.01f) - cinderColortoBe = Color.Lerp(cirrus ? Color.Pink : Color.Red, cirrus ? Color.Green : Color.Yellow, Main.rand.NextFloat(0f, 0.88f)); + cinderColortoBe = Color.Lerp(permafrost ? Color.Cyan : Color.Red, permafrost ? Color.DarkTurquoise : Color.Yellow, Main.rand.NextFloat(0f, 0.88f)); else cinderColortoBe = Color.Lerp(Color.Gray, Color.White, Main.rand.NextFloat(0.8f)); diff --git a/Tiles/Furniture/BlueCandle.cs b/Tiles/Furniture/BlueCandle.cs index ae874cba1a..9475eadbcd 100644 --- a/Tiles/Furniture/BlueCandle.cs +++ b/Tiles/Furniture/BlueCandle.cs @@ -12,7 +12,7 @@ namespace CalamityMod.Tiles.Furniture { public class BlueCandle : ModTile { - // TODO -- Unique sounds for each Cirrus Candle. + // TODO -- Unique sounds for each Candle. public static readonly SoundStyle ActivationSound = new("CalamityMod/Sounds/Item/LouderPhantomPhoenix2"); public override void SetStaticDefaults() @@ -36,13 +36,13 @@ public override bool RightClick(int i, int j) Player p = Main.LocalPlayer; // Forcibly remove all candle buffs. - p.ClearBuff(ModContent.BuffType()); - p.ClearBuff(ModContent.BuffType()); - p.ClearBuff(ModContent.BuffType()); - p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); // 108000 is the duration used by Ammo Box. - p.AddBuff(ModContent.BuffType(), 108000); + p.AddBuff(ModContent.BuffType(), 108000); // Play a sound. SoundEngine.PlaySound(ActivationSound, new Vector2(i * 16, j * 16)); diff --git a/Tiles/Furniture/CraftingStations/SCalAltar.cs b/Tiles/Furniture/CraftingStations/SCalAltar.cs index c25a770d8d..efef1fa84f 100644 --- a/Tiles/Furniture/CraftingStations/SCalAltar.cs +++ b/Tiles/Furniture/CraftingStations/SCalAltar.cs @@ -1,6 +1,7 @@ using CalamityMod.Events; using CalamityMod.Items.Materials; using CalamityMod.Items.Placeables.Furniture.CraftingStations; +using CalamityMod.Items.Potions; using CalamityMod.Items.Potions.Alcohol; using CalamityMod.Items.SummonItems; using CalamityMod.NPCs.SupremeCalamitas; @@ -66,10 +67,10 @@ public override bool CreateDust(int i, int j, ref int type) public static void HoverItemIcon() { - bool vodka = Main.LocalPlayer.HeldItem.type == ModContent.ItemType() && Main.zenithWorld; + bool vodka = Main.LocalPlayer.HeldItem.type == ModContent.ItemType() && Main.zenithWorld; if (vodka) { - Main.LocalPlayer.cursorItemIconID = ModContent.ItemType(); + Main.LocalPlayer.cursorItemIconID = ModContent.ItemType(); } else if (Main.LocalPlayer.HasItem(ModContent.ItemType())) { @@ -92,12 +93,12 @@ public static bool AttemptToSummonSCal(int i, int j) int top = j - tile.TileFrameY / 18; if (!Main.LocalPlayer.HasItem(ModContent.ItemType()) && - !Main.LocalPlayer.HasItem(ModContent.ItemType()) && !(Main.LocalPlayer.HeldItem.type == ModContent.ItemType() && Main.zenithWorld)) + !Main.LocalPlayer.HasItem(ModContent.ItemType()) && !(Main.LocalPlayer.HeldItem.type == ModContent.ItemType() && Main.zenithWorld)) { return true; } - bool vodka = Main.LocalPlayer.HeldItem.type == ModContent.ItemType() && Main.zenithWorld; + bool meat = Main.LocalPlayer.HeldItem.type == ModContent.ItemType() && Main.zenithWorld; if (NPC.AnyNPCs(ModContent.NPCType()) || BossRushEvent.BossRushActive) return true; @@ -111,11 +112,11 @@ public static bool AttemptToSummonSCal(int i, int j) ritualSpawnPosition += new Vector2(0f, -24f); SoundEngine.PlaySound(SummonSound, ritualSpawnPosition); - Projectile.NewProjectile(new EntitySource_WorldEvent(), ritualSpawnPosition, Vector2.Zero, ModContent.ProjectileType(), 0, 0f, Main.myPlayer, 0, vodka.ToInt()); + Projectile.NewProjectile(new EntitySource_WorldEvent(), ritualSpawnPosition, Vector2.Zero, ModContent.ProjectileType(), 0, 0f, Main.myPlayer, 0, meat.ToInt()); - if (vodka) + if (meat) { - Main.LocalPlayer.ConsumeItem(ModContent.ItemType(), true); + Main.LocalPlayer.ConsumeItem(ModContent.ItemType(), true); for (int f = 0; f < Main.maxNPCs; f++) { if (Main.npc[f].type == ModContent.NPCType() && Main.npc[f].active) diff --git a/Tiles/Furniture/PinkCandle.cs b/Tiles/Furniture/PinkCandle.cs index 3ffb8dbfab..f2b8f483c8 100644 --- a/Tiles/Furniture/PinkCandle.cs +++ b/Tiles/Furniture/PinkCandle.cs @@ -12,7 +12,7 @@ namespace CalamityMod.Tiles.Furniture { public class PinkCandle : ModTile { - // TODO -- Unique sounds for each Cirrus Candle. + // TODO -- Unique sounds for each Candle. public static readonly SoundStyle ActivationSound = new("CalamityMod/Sounds/Item/LouderPhantomPhoenix2"); public override void SetStaticDefaults() @@ -36,13 +36,13 @@ public override bool RightClick(int i, int j) Player p = Main.LocalPlayer; // Forcibly remove all candle buffs. - p.ClearBuff(ModContent.BuffType()); - p.ClearBuff(ModContent.BuffType()); - p.ClearBuff(ModContent.BuffType()); - p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); // 108000 is the duration used by Ammo Box. - p.AddBuff(ModContent.BuffType(), 108000); + p.AddBuff(ModContent.BuffType(), 108000); // Play a sound. SoundEngine.PlaySound(ActivationSound, new Vector2(i * 16, j * 16)); diff --git a/Tiles/Furniture/PurpleCandle.cs b/Tiles/Furniture/PurpleCandle.cs index 31d1864cf7..dd2a5e9886 100644 --- a/Tiles/Furniture/PurpleCandle.cs +++ b/Tiles/Furniture/PurpleCandle.cs @@ -12,7 +12,7 @@ namespace CalamityMod.Tiles.Furniture { public class PurpleCandle : ModTile { - // TODO -- Unique sounds for each Cirrus Candle. + // TODO -- Unique sounds for each Candle. public static readonly SoundStyle ActivationSound = new("CalamityMod/Sounds/Item/LouderPhantomPhoenix2"); public override void SetStaticDefaults() @@ -36,13 +36,13 @@ public override bool RightClick(int i, int j) Player p = Main.LocalPlayer; // Forcibly remove all candle buffs. - p.ClearBuff(ModContent.BuffType()); - p.ClearBuff(ModContent.BuffType()); - p.ClearBuff(ModContent.BuffType()); - p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); // 108000 is the duration used by Ammo Box. - p.AddBuff(ModContent.BuffType(), 108000); + p.AddBuff(ModContent.BuffType(), 108000); // Play a sound. SoundEngine.PlaySound(ActivationSound, new Vector2(i * 16, j * 16)); diff --git a/Tiles/Furniture/YellowCandle.cs b/Tiles/Furniture/YellowCandle.cs index 177df09292..d9780550bc 100644 --- a/Tiles/Furniture/YellowCandle.cs +++ b/Tiles/Furniture/YellowCandle.cs @@ -12,7 +12,7 @@ namespace CalamityMod.Tiles.Furniture { public class YellowCandle : ModTile { - // TODO -- Unique sounds for each Cirrus Candle. + // TODO -- Unique sounds for each Candle. public static readonly SoundStyle ActivationSound = new("CalamityMod/Sounds/Item/LouderPhantomPhoenix2"); public override void SetStaticDefaults() @@ -35,13 +35,13 @@ public override bool RightClick(int i, int j) Player p = Main.LocalPlayer; // Forcibly remove all candle buffs. - p.ClearBuff(ModContent.BuffType()); - p.ClearBuff(ModContent.BuffType()); - p.ClearBuff(ModContent.BuffType()); - p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); + p.ClearBuff(ModContent.BuffType()); // 108000 is the duration used by Ammo Box. - p.AddBuff(ModContent.BuffType(), 108000); + p.AddBuff(ModContent.BuffType(), 108000); // Play a sound. SoundEngine.PlaySound(ActivationSound, new Vector2(i * 16, j * 16)); From 792495e8f60f10caaae20f525b37d51201e5659e Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Mon, 26 May 2025 14:34:02 -0700 Subject: [PATCH 227/401] removed Crystal Heart Vodka --- CalPlayer/CalamityPlayerHitHurt.cs | 2 +- ILEditing/ILChangesLoading.cs | 2 +- ILEditing/MechanicILChanges.cs | 10 +- Items/Accessories/Vanity/CrystalHeartVodka.cs | 86 ------------------ .../Accessories/Vanity/CrystalHeartVodka.png | Bin 1058 -> 0 bytes Items/Accessories/Vanity/Fabsol_Back.png | Bin 3614 -> 0 bytes Items/Accessories/Vanity/Fabsol_Body.png | Bin 3324 -> 0 bytes Items/Accessories/Vanity/Fabsol_Head.png | Bin 2011 -> 0 bytes Items/Accessories/Vanity/Fabsol_Legs.png | Bin 2688 -> 0 bytes Items/ColdheartIcicle.cs | 6 +- Items/Potions/Alcohol/FabsolsVodka.cs | 1 - 11 files changed, 12 insertions(+), 95 deletions(-) delete mode 100644 Items/Accessories/Vanity/CrystalHeartVodka.cs delete mode 100644 Items/Accessories/Vanity/CrystalHeartVodka.png delete mode 100644 Items/Accessories/Vanity/Fabsol_Back.png delete mode 100644 Items/Accessories/Vanity/Fabsol_Body.png delete mode 100644 Items/Accessories/Vanity/Fabsol_Head.png delete mode 100644 Items/Accessories/Vanity/Fabsol_Legs.png diff --git a/CalPlayer/CalamityPlayerHitHurt.cs b/CalPlayer/CalamityPlayerHitHurt.cs index fbe583aae3..4928ad188d 100644 --- a/CalPlayer/CalamityPlayerHitHurt.cs +++ b/CalPlayer/CalamityPlayerHitHurt.cs @@ -1675,7 +1675,7 @@ public override void ModifyHurt(ref Player.HurtModifiers modifiers) SoundEngine.PlaySound(SoundID.NPCHit4, Player.Center); //metal hit noise hurtSoundTimer = 10; } - else if (((aquaticHeartPower || aquaticHeartForce) && !aquaticHeartHide) || Player.GetModPlayer().vanityEquipped) + else if (((aquaticHeartPower || aquaticHeartForce) && !aquaticHeartHide)) { modifiers.DisableSound(); SoundEngine.PlaySound(SoundID.FemaleHit, Player.Center); //female hit noise diff --git a/ILEditing/ILChangesLoading.cs b/ILEditing/ILChangesLoading.cs index c2ea95f2b1..19514830f4 100644 --- a/ILEditing/ILChangesLoading.cs +++ b/ILEditing/ILChangesLoading.cs @@ -83,7 +83,7 @@ public override void OnModLoad() IL_Wiring.HitWireSingle += AddTwinklersToStatue; On_Player.UpdateItemDye += FindCalamityItemDyeShader; On_AWorldListItem.GetDifficulty += GetDifficultyOverride; - On_Item.GetShimmered += ShimmerEffectEdits; + //On_Item.GetShimmered += ShimmerEffectEdits; // Mana Burn (Chaos Stone) and Chalice of the Blood God IL_Player.ApplyLifeAndOrMana += ManaSicknessAndChaliceBufferHeal; diff --git a/ILEditing/MechanicILChanges.cs b/ILEditing/MechanicILChanges.cs index fb4fe1510e..a46081ba42 100644 --- a/ILEditing/MechanicILChanges.cs +++ b/ILEditing/MechanicILChanges.cs @@ -1398,12 +1398,12 @@ internal static void GetDifficultyOverride(Terraria.GameContent.UI.Elements.On_A #endregion #region Shimmer effect edits - public static void ShimmerEffectEdits(Terraria.On_Item.orig_GetShimmered orig, Item self) + /*public static void ShimmerEffectEdits(Terraria.On_Item.orig_GetShimmered orig, Item self) { - // Don't keep the original stack amount when shimmering Fabsol's Vodka into Crystal Heart Vodka - if (self.type == ModContent.ItemType()) + // Currently unused. Code kept as it'll likely be needed in the future + if (self.type == 0) { - self.SetDefaults(ModContent.ItemType()); + self.SetDefaults(0); self.shimmered = true; self.shimmerWet = true; self.wet = true; @@ -1423,7 +1423,7 @@ public static void ShimmerEffectEdits(Terraria.On_Item.orig_GetShimmered orig, I { orig(self); } - } + }*/ #endregion } } diff --git a/Items/Accessories/Vanity/CrystalHeartVodka.cs b/Items/Accessories/Vanity/CrystalHeartVodka.cs deleted file mode 100644 index 880b01da73..0000000000 --- a/Items/Accessories/Vanity/CrystalHeartVodka.cs +++ /dev/null @@ -1,86 +0,0 @@ -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Items.Accessories.Vanity -{ - public class CrystalHeartVodka : ModItem, ILocalizedModType - { - public new string LocalizationCategory => "Items.Accessories"; - - public override void Load() - { - if (Main.netMode != NetmodeID.Server) - { - EquipLoader.AddEquipTexture(Mod, "CalamityMod/Items/Accessories/Vanity/Fabsol_Head", EquipType.Head, this); - EquipLoader.AddEquipTexture(Mod, "CalamityMod/Items/Accessories/Vanity/Fabsol_Body", EquipType.Body, this); - EquipLoader.AddEquipTexture(Mod, "CalamityMod/Items/Accessories/Vanity/Fabsol_Legs", EquipType.Legs, this); - EquipLoader.AddEquipTexture(Mod, "CalamityMod/Items/Accessories/Vanity/Fabsol_Back", EquipType.Back, this); - } - } - - public override void SetStaticDefaults() - { - if (Main.netMode == NetmodeID.Server) - return; - - int equipSlotHead = EquipLoader.GetEquipSlot(Mod, Name, EquipType.Head); - ArmorIDs.Head.Sets.DrawHead[equipSlotHead] = false; - - int equipSlotBody = EquipLoader.GetEquipSlot(Mod, Name, EquipType.Body); - ArmorIDs.Body.Sets.HidesTopSkin[equipSlotBody] = true; - ArmorIDs.Body.Sets.HidesArms[equipSlotBody] = true; - - int equipSlotLegs = EquipLoader.GetEquipSlot(Mod, Name, EquipType.Legs); - ArmorIDs.Legs.Sets.HidesBottomSkin[equipSlotLegs] = true; - } - - public override void SetDefaults() - { - Item.width = 22; - Item.height = 30; - Item.accessory = true; - - // Same as Fabsol's Vodka, due to the obtainment method being shimmering Fabsol's Vodka. - Item.value = Item.buyPrice(0, 2, 60, 0); - Item.rare = ItemRarityID.LightRed; - - Item.vanity = true; - Item.Calamity().devItem = true; - } - - public override void UpdateVanity(Player player) - { - player.GetModPlayer().vanityEquipped = true; - } - - public override void UpdateAccessory(Player player, bool hideVisual) - { - if (!hideVisual) - player.GetModPlayer().vanityEquipped = true; - } - } - - public class CrystalHeartVodkaPlayer : ModPlayer - { - public bool vanityEquipped = false; - - public override void ResetEffects() - { - vanityEquipped = false; - } - - public override void FrameEffects() - { - if (vanityEquipped) - { - Player.back = EquipLoader.GetEquipSlot(Mod, "CrystalHeartVodka", EquipType.Back); - Player.legs = EquipLoader.GetEquipSlot(Mod, "CrystalHeartVodka", EquipType.Legs); - Player.body = EquipLoader.GetEquipSlot(Mod, "CrystalHeartVodka", EquipType.Body); - Player.head = EquipLoader.GetEquipSlot(Mod, "CrystalHeartVodka", EquipType.Head); - - //Player.HideAccessories(); - } - } - } -} diff --git a/Items/Accessories/Vanity/CrystalHeartVodka.png b/Items/Accessories/Vanity/CrystalHeartVodka.png deleted file mode 100644 index d0faf459779b0cbfa545bbb25c50f01d2ad89d01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1058 zcmV+-1l{|IP)Px#1ZP1_K>z@;j|==^1poj8vPnciR9Hvdm|I8`Q5eT}z2qg7^^(b|n0ZM{6Eh5Z zDamdofn*vzNJdoNQlSh>dI%{$V|ygXCvE>TPBK&!RR4LzHrDH5g~b7N${`1dtDznzY#lMtekn{{+2F z*H}s%n@b_Kv(F)#b9{aCfDc$dY7Q3NZvlmvn6bprTF_r*5B5wbVUF&?FINH40G&^b zU^N*INCL$3KIVG#?ACXoE_fdg@>x8__W3;r-F`0td#%P{YR{k(>f@?9(0Yh{juIKn z=2TS!n`3-(&2qrHCJ90ccla9VdgliDKb+t$o^BxaN8xY zcAiiEgNtmynbZDsfVp>yZ>VK$42CG-=H8%tLI6mnq{17dh-P9f8I8$Qrh)YL(xZ)F zmKB?$^lX)_F^iavW(;VqjO}9kE{b5Szk6OOQj8yEfV{beDBla+MxcCa{vjs0e(ZC$$D59x@o&c@zWcEzP zR`7ZmXT0H?aNFgU|p6njG_Q{Ikl=+QCMi<-h4;-@galCK=!6R)zkuW`8(M@icAH& z`r_IReQl`cGQ`Jpj8Vv(UOpLhHPCDWt;000hUSV?A0O#mtY c000O800000007cclK=n!07*qoM6N<$f`-!c@c;k- diff --git a/Items/Accessories/Vanity/Fabsol_Back.png b/Items/Accessories/Vanity/Fabsol_Back.png deleted file mode 100644 index 1563280bdc1ccc9b9a2cab6c5fccce61317f6287..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3614 zcmd^CYgCeH9;aq%%1*PhYR+b(HY0c|bv8{W4NaG#7ezuX$4fTdFjKMhTD++j zcm1=B?UxTyYGOiADS0((W!FOStnm&BQ#0|N ze}4edU;I*_!4hJ3#&gjvQ=a=`p8rn3=9S{$fH|3j7)j8pB%*#HWJg!bJe_S0CmHN9 zAAU>@tuOHC5ZCae*mA8Ov@;JQ%n)4@Gl!!J+R*%H?&C;h%}En=entLZeYGf?L)8cC ziYRB+*7TGf4N_J>34*9y3ys+U*S3g`bo9th2F;ey==!MgUS_$J7(Z>*sB4w5*3)O~ z#scE6s(nC)2vxWxpeU%%Vk{j!MIPG?-WSxqh=8Z3sxrls*kyNAiivt7hcQa6NBh!9 zUmX@ARXj6m+@5dlB!32WmiO$Hz>532qz-~1eb+9=9(QpFHo`}8VT|v(@5(|1HeTWl$*iXqph2p0fN$1d~@KDD$h{14Gy?Z;gtfe zj(A)_S4*ybx(qG>XEm{xBewRVP=0&uPRzefbY1Ve!ai;XdH z!uVz*g&LIB)|SnAhCRMjnE$MH-<2?qI=pA0TvLPF4uxThN-XkOPBg>Fp-_cnh7%&V z-L6zegKp)}wI@#$5e?}(f6D`lN+J~0cF^?|JQfs~a-@$rs1~`^=}*MlSn&{R@0H8+-9VzLT0_luCZwt6X6ySdqt*VN|~+968_UN~ux zvuO0No3w0#@x?^8{)uY0rD3biD()|x}}B!4G*c3lRCm}evwy3atS0RkcojLIS-l|N) zfI7`|Ogd;-C8G2t54*(eh-ycY7!xraO(jyiRiKPrXq0W~l#M8-yo6ee4`ENH|Goj& z3Z9fG?Pa;fztQ8jMo;LK$kn%I8%@}m$LQ_L@7Pk$cUV!_j84~FA1_#kNgoYcj{3dQHiPn?)43OTN`+0QN7kZnLn9>LQJPmbhnnwifr!erHo$lelTHl}a%+qWQ(# z1275i>3!H9m^BLZ_u*PET_OLidhH6Es~mw!slp*<8d$%h!cY>}^c$M+55HXOL?dmO z!)dTtPn>{&-GvXk#w2chHQC=}m#@V4No(Fza9S1DZSIt15>#tlbXZ->Jb8=~pKIBz z$m~vFi;!m>O|Vq?ip)Q1cy11R&;r0R*1)MnX6;>#6=0-tFV(0#OXftz`4{~q+qvw{ zL%N?`HF}IKl~A`S8i9+6zLMC!%_3)Vv_t5rot^~d#sS@`nCE z8Qa%KBV|DYCJqsFT)1}RO6n;Z9>JOUrlVbEGIazP@rm86jr8Tc>0XIjLLhIZmkk=~ z9#j$}9OMDh9qxM?d<2tUI7P|bVetMyzXuwIlK@1_7SFUnU~)@srS*xx;0@kC+IPuv z*oU0xinYK5@B6aUk{#5tz-DBI*R@!~iY`QejIha}Y`I#Z?(oh}%LByqnk~0P#g)_{ zZ{fpkFNjsRyBSzwd&GX{A(!xyoGokg^{QF4&?IX(kRxLInU#9qz1b>XJV)e@!VoQ zA-NU`!X(JBhd4<+{un9cDT&1-8|$sYhN)vXIyOV0p{*8sEiP+kKqpMcTe;q zYknc)#@Qy8Iu1`0+A?NQFlI-aU^Lj4@q#G^&)g|)SEd3dW2A6xcctZZn)BW^)r3W) zZ1T``lbHD^)mEl>sc({~5UO zQli28-kZQ(;ZQXH^0X#xC{vL=!!^u6@zduh4lIQ8q7pcI~C}_baM1Vb99{ zVFKx;E4s@b!ge=Qz337vjV9R$u$5W5$KOXQ<~ZIjA9*_ay>3uuHGHjhk`L4;0i%Z> zki^x)oasyoOuBPU476$DBr$X&jL{9E2KBkK2uv%mJ~q0_;UK>LT#|0%7j3a3@*)EQ z!E~`l+wkJK7V%D;0{n~S+SGvh$kQqx4SQN|cHC*Wq>hU%6oL>1+IURW&43XFQUU%i zQZ7Xf+uN_f^mZ@#7%obV^%&AeCNt!L=Db3C#4&q}+%E&KSh{a=)^}rVq zK|QGIToLK?oegnqUzbRS{PG>vV4@7^e5$jNvk2jKvb(kOF2Dde0Sq3AuQ3D;*f2Px zRUZNv(is3l22&bsM{F~wpV~L4*iY|%zqu@ zY8y3|LC4PYb&;-&pdDzWB|@baBm#mevpGfftK?_EGE2K>4#Hjay-54mCPNFAt0UAm z6D4KZ$@^ikDjYto-9@JxDKq81cBl;!#r$OI1PSCmag!2OghC(>+H_bK;QWzb0zK{u zeDJTOoaE2;nF3gg+0`147d1#p@tMr&$+tcH@^gy=e{tS@sA?(dCK;OCYrxFNJ0>)x zyY_=|v2WMrPk0z*s!m=EyUZ5FtJdm74HWXkNc}C}rrJiudF_vfVGKH?zfUf`c(c21 z=8>n?DTJ1q33Vq#y&O#snk}a#g`B=qdM!D}TPtd;Ap&uX0?*5O&B*5uZ~*P)9fo-p z?j02_pC9|y*Ixc)9I9KH^ebP}1$cweTMs%5YUrW??81}+2La^F0i}Jxo$&yOKkx`q z0Jh~PT&*NE6oRl_bm4KQ5DT{Gml4EuWXK;$RAtz>ZU>A_zxA4&_ck~dE!nOu8c{Qk zN!LA&oLy)gy52q0jLf?=>Cc^|><;*YO(j4DU;4%f7M8|Ue)vh!b#5)-!25?khbTm% a?f)KXg^d*8H5|vZEztHDTx;YPr~VD?eQ=fl diff --git a/Items/Accessories/Vanity/Fabsol_Body.png b/Items/Accessories/Vanity/Fabsol_Body.png deleted file mode 100644 index d98fdec79c9e0742eef975ba24fe8b8602ea21e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3324 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 diff --git a/Items/Accessories/Vanity/Fabsol_Head.png b/Items/Accessories/Vanity/Fabsol_Head.png deleted file mode 100644 index bf96b48a95cfebd2d77a4dba9c3c5c3bd8902e1a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2011 zcmc&!eNd8j9H%R?3u=|EtPQ-Iz1d81+R=KU!>MR$X<3vhu(2TBMouw&NojUjo+*_U z8JDswM4j4B&4E6m$Egd$7hbe2(dwVt!A%4x>d0Ku1y@8?Ae&4Oz(LE$-R2#2)!^mfkmlH zo=rwQT;|ymDX%-tI@;#-Ita?QeVsa*lqGAjgv|XiZms68$*Mi5wdOUZwVTO<-N{tS z-XjD;DkCM6HEao&)Q4kbNV=q+*?N>fu}x^k?3SLf+_8}nNow6tb@fO3R>-358z&G@ zXZSA?ZseOMUS8wbbEd3A_7Z6Nduf~))k%h7GS?TMT?(DB>ah-_1BUpQI_y&y_zK%R zztr2zeG~&BoY~Y&FSE}2c-SQt`tfN^ zfwD|Uf5_|wUnHJ(;n2WE*e)6x=UVNW@jcn7++))QEvLJ8rK2O=Y*3P6GVEv?l4V;` z^qpPhFf^G*T>)B;ICpQ&zVhYLl8g!iqso9x^)DC&fHCAqOM;|A)~2hzVnNt*l#%fu zd@Wj9QaFk{&l34Tv_7SijksUl(JKaTh7+VEi5Wy)1U(G^=`HgvV6K`2o4rywiS)E~ zp&%gw=fU=O(O;gL@;3?vm7H5F(Je|8UhUxo*FRlMmyA{+i_y#mM1u!q`vhaX8nsx5 zcF}jo&R^a&!7$zy2`WWvHOhco0PKI6E*Utn;5XlRK-`tSsUKLkgx*C}5mp&;s(3-ILL=R2-7*2JiwREaTDSLaz3qz! zv)YM~n_?8(8m>Z^%MXXI{$EM2^TII}t>^;O9n>gqX&sW6h zB0})$o6Z!vd~^*z+x!#J6b%PxNjo5+vD~i(fLDB!=_)vjtPLt8shVfg!baOk$>?LU z=NvA{cEtL$k&LX_95{+>pu2|p!sw;oeTTJ~X{V}r z<%MG}$DkRt;50weq;l6+5i$y^c+$9?v6CN+Y;C${IaNt;%0WEtf5y}h@rU66T?CK= z?r94EAO~OMIujK#tEo81j*8=I328O_SXqYdQJ#gz5|Qv~zZP(%14Q74taI&kreStn zYM)ZGI}(2wbXbr8IxH~!z0E&;av*DEiJmP3;WbogNr(lDhFF_g2m7_0*5kFZlUq_W zN)0GC=4a=7yG>2#0@Ytb;~nF3|Buf|BUI6GUunr8uFS{$ydz)#`u5`nl$BrVV^%cc zyCIG_P!f&N5z^qBIFAf{zgq=$n`?%W(~G0AJAfU9*Sp)HZZ|OQSkk603_3&8pnLRo zE|c;8Rj(LdxyCJ6@Bcpr$mErpqmG4{Nk*EwkK|Oj{N%APMr0&nD_Fbk38<>WMNa); M!3TnB18F&b0-G7vEC2ui diff --git a/Items/Accessories/Vanity/Fabsol_Legs.png b/Items/Accessories/Vanity/Fabsol_Legs.png deleted file mode 100644 index 1156798b6080a3165321b4543134ce57952f36ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2688 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 J)w)K|{{%hOPo4k( diff --git a/Items/ColdheartIcicle.cs b/Items/ColdheartIcicle.cs index 65cfbab89f..7395395ec5 100644 --- a/Items/ColdheartIcicle.cs +++ b/Items/ColdheartIcicle.cs @@ -23,11 +23,15 @@ public override void SetDefaults() Item.rare = ModContent.RarityType(); } + public override void HoldStyle(Player player, Rectangle heldItemFrame) + { + player.itemRotation = player.MountedCenter.DirectionTo(Main.MouseWorld).ToRotation(); + } + public override void HoldItem(Player player) { int offset = player.direction == 1 ? 5 : -Item.width - 5; Rectangle itemRect = new Rectangle((int)player.Center.X + offset, (int)player.position.Y - 10, Item.width, Item.height); - player.itemRotation = player.MountedCenter.DirectionTo(Main.MouseWorld).ToRotation(); foreach (NPC npc in Main.ActiveNPCs) { if (!npc.dontTakeDamage && npc.type != ModContent.NPCType()) diff --git a/Items/Potions/Alcohol/FabsolsVodka.cs b/Items/Potions/Alcohol/FabsolsVodka.cs index 4ca2edb060..1b17d807a5 100644 --- a/Items/Potions/Alcohol/FabsolsVodka.cs +++ b/Items/Potions/Alcohol/FabsolsVodka.cs @@ -14,7 +14,6 @@ public class FabsolsVodka : ModItem, ILocalizedModType public override void SetStaticDefaults() { Item.ResearchUnlockCount = 5; - ItemID.Sets.ShimmerTransformToItem[Type] = ModContent.ItemType(); } public override void SetDefaults() From 6e1c917448d051ab1a5c7c5957d1f9bdc65d4215 Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Mon, 26 May 2025 14:38:57 -0700 Subject: [PATCH 228/401] Removed Cirrus Couch and Dress and TY credit, and Yharim Crystal name --- Items/Armor/CirrusDress.cs | 58 ------------------ Items/Armor/CirrusDress.png | Bin 558 -> 0 bytes Items/Armor/CirrusDress_Body.png | Bin 4574 -> 0 bytes Items/Armor/CirrusDress_Legs.png | Bin 3975 -> 0 bytes Items/Placeables/Furniture/CirrusCouch.cs | 25 -------- Items/Placeables/Furniture/CirrusCouch.png | Bin 738 -> 0 bytes .../DevPaintings/ThankYouPainting.cs | 1 - .../Mods.CalamityMod.Items.Accessories.hjson | 5 -- ...ods.CalamityMod.Items.Armor.Hardmode.hjson | 12 ---- .../en-US/Mods.CalamityMod.Items.Misc.hjson | 2 +- .../Mods.CalamityMod.Items.Placeables.hjson | 13 ++-- Projectiles/Magic/YharimsCrystalBeam.cs | 1 - Tiles/Furniture/CirrusCouch.cs | 37 ----------- Tiles/Furniture/CirrusCouch.png | Bin 1051 -> 0 bytes Tiles/Furniture/CirrusCouch_Highlight.png | Bin 476 -> 0 bytes 15 files changed, 5 insertions(+), 149 deletions(-) delete mode 100644 Items/Armor/CirrusDress.cs delete mode 100644 Items/Armor/CirrusDress.png delete mode 100644 Items/Armor/CirrusDress_Body.png delete mode 100644 Items/Armor/CirrusDress_Legs.png delete mode 100644 Items/Placeables/Furniture/CirrusCouch.cs delete mode 100644 Items/Placeables/Furniture/CirrusCouch.png delete mode 100644 Tiles/Furniture/CirrusCouch.cs delete mode 100644 Tiles/Furniture/CirrusCouch.png delete mode 100644 Tiles/Furniture/CirrusCouch_Highlight.png diff --git a/Items/Armor/CirrusDress.cs b/Items/Armor/CirrusDress.cs deleted file mode 100644 index 4da0b51cd9..0000000000 --- a/Items/Armor/CirrusDress.cs +++ /dev/null @@ -1,58 +0,0 @@ -using CalamityMod.Rarities; -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Items.Armor -{ - [AutoloadEquip(EquipType.Body)] - public class CirrusDress : ModItem, ILocalizedModType - { - public new string LocalizationCategory => "Items.Armor.Hardmode"; - /* How to obtain - * 1 - Have alcohol poisoning - * 2 - Visit the Stylist while Cirrus is alive in the world - * 3 - Open her shop to find the dress - */ - - public override void Load() - { - if (Main.netMode != NetmodeID.Server) - { - EquipLoader.AddEquipTexture(Mod, "CalamityMod/Items/Armor/CirrusDress_Legs", EquipType.Legs, this); - } - } - - public override void SetStaticDefaults() - { - - if (Main.netMode == NetmodeID.Server) - return; - int equipSlot = EquipLoader.GetEquipSlot(Mod, Name, EquipType.Body); - ArmorIDs.Body.Sets.HidesHands[equipSlot] = true; - } - - public override void SetDefaults() - { - Item.width = 18; - Item.height = 18; - Item.value = CalamityGlobalItem.RarityHotPinkBuyPrice; - Item.rare = ModContent.RarityType(); - Item.Calamity().devItem = true; - Item.defense = 8; - } - - public override void UpdateEquip(Player player) - { - player.Calamity().cirrusDress = true; - player.GetDamage() += 0.05f; - player.GetCritChance() += 5; - } - - public override void SetMatch(bool male, ref int equipSlot, ref bool robes) - { - robes = true; - equipSlot = EquipLoader.GetEquipSlot(Mod, Name, EquipType.Legs); - } - } -} diff --git a/Items/Armor/CirrusDress.png b/Items/Armor/CirrusDress.png deleted file mode 100644 index 8bd29e2f48238e5799f56c65fb8e9166a1d709a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 558 zcmV+}0@3}6P)Px$=1D|BR9HvNm%U2^K@i0~gA#~nAPB*Lu@Dplxh^0mR(66|i=beeLc~8p#3HSr zAl4$-S&4#>E(n5xg%KhF2}DUCD1P9a?{Mcb?%fHwO|zNX-PyOldpp@!UFGp);uw)>>9-CM4o?RYNTxk|b zgE>MZ64gps*+I2&6^IN-r28h7Jn2lfEg8#rA&?C+Ai~WG?{G6>9Efld=!aKCB9RFh z&rU0wy(wQ%oJf$Qcm?rtYmvU%uPJIvy)|kN;zx?t;0-*K))7xlWI}j-;4z4B5_}vd!-+`ixI`is zA_+k0*Lh=Ws7NU`A9KFEf?r#{u6XG&RtWb7NbsFWWZ;#56Y01Ryb@GWRLq^1HQM~@ z+qTZv)W6rWLG60~F14t@sHB{X$0NoG(N$VsSlZly`CS!xL?V$1!7IrpR!HP|%ejx- zC!eVGTOp;2JW?N|u9>)V?(^b diff --git a/Items/Armor/CirrusDress_Body.png b/Items/Armor/CirrusDress_Body.png deleted file mode 100644 index 779ae0e094882739ae0637e66e7953ff0e9a5874..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4574 zcma)Adpy(o|NjgnbxNl~<#x)X$fcxZuHDSgNSWNGQz62b`(@^&PRV7Ny7*XR9syq?!jtPKLTbNj*V008WS zn_sX60MKpG`}nr4qPv#=j{(sG6krQG2b9wk*Z}Zr8vMf9tD#wQOjm2C5Mt-I`oE$N z?cV>}F-`TZU;`hz`Q;jVUEghugj2QxFJH3^%6r2{VfzDyv0^^+{F5Vb&-eK}Gf!%y zTMe6+ouk{y7d|$*AHTd;2e)UwVB@PEFZ z$lWj9@fdNF|3MOnPp}fNsI0Z!lBSfS0sNR>z`5IH1bSf|?>J}jx{jAfKUqeG?s7{4wVYjue@MFYU7ux2df6%pS+axsM z`gY!eMEftsUZFxrTuw;oejW{vqq=Na;*r;EaKZ)GKO8YfJn~D;Y2q>PkJf5a>BE-5 zhlZf)?S8*|m6xyisnp9rEtBt|*U?_CqlD*I3P$_jH>N__F z82W$(S{ZyZOvCqWw^^167fu)%OSaNjvcP$96`-_K^K_&$rBCW#SFOTZI$HJs`7va` zZ*tTmXIfxF9%99Q@B039PF*1Ql%$}M z{+#M14-nK92Yo+3$F;++8ETW@8O>2QRr>G8a7^b}W5phrk9Gi&kG7L%lCLUg16TQj z(X%EV;oX}@m(Fm+lv9+({F3%%V%vBn4~(Eo7BXJ&MkZ?J&BzTGLcGNAjDPoqbJGz7 z@Hg{qNfPd6$p!Td!rUSwmg6~Si^svPnx;mEU;BVY8S+j6)71j`FNLu6M#sVX&u@L= zeV@6}c40kq{t%Fg`-TQ)=eT-5uuN`35y!A9XHbXpoP<)x+-@`eN4EkUZj_%@x75nY+Kpm5b}>XMi)2 zDvwc?)F=l_wJE`xUW2nE;>)%~uoghWBV+&u#Gc}45AIv^N*f*|2zb;rp-D-vp*{?6 z(%hKWFIDG|eTcBwI&OOMFmZ;vHsl2kOe>J{4f(umplOt<7pn6h$R9eK*yo2aGV4vr zzLhxpYEW5O7;&kW@Z^e*+Vq0gLYJ~pow@o0YB73$w1Bl_WFst`PI(h`AllYHkIOHH zAP+eoxbtBLZp0qsHLAB97q=xEwjLUq7w)Kf?+$uhHhTF!C!IfJ_9sFAp1Dm@#o?qs zzvo{8tOE5NYWH;MYqILw9B_nHH2Z8F2QO`(8qXM0;wiDeJs{3XCVjmLmZK#kTm`KV z;|ElQzGUvhc7>q(%lFHTeL9~_RjH45l~lxb?Es#fk!=03Fu{qM75dzLT95_xmxlU; ze@e9rJ?)UAoDL8F!%1LGAN6rt^{+~-{*bc>R%y6*qmnxD9YUJ-boJ;t`(FLfEcX=m zaSJM3yLR|H+b8S=$v1PM-9~K1N%0A(D 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 LaiRR&^}GKDk3aF{ diff --git a/Items/Armor/CirrusDress_Legs.png b/Items/Armor/CirrusDress_Legs.png deleted file mode 100644 index 42e4842b4384e5e43a87ecaf328e01399a57129e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3975 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 "Items.Placeables"; - public override void SetDefaults() - { - Item.width = 28; - Item.height = 20; - Item.maxStack = 9999; - Item.useTurn = true; - Item.autoReuse = true; - Item.useAnimation = 15; - Item.useTime = 10; - Item.useStyle = ItemUseStyleID.Swing; - Item.consumable = true; - Item.value = 0; - Item.createTile = ModContent.TileType(); - } - } -} diff --git a/Items/Placeables/Furniture/CirrusCouch.png b/Items/Placeables/Furniture/CirrusCouch.png deleted file mode 100644 index 3d0e1a4ba393c9753aff95bd3f6653fe07d7b53c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 738 zcmV<80v-K{P)Px%f=NU{R9J=8l}%_ zM8Tg+sXw5IRVv<6P^yO(JQRFTawsSj>cwKM#GsgpjUJ>2JqQ)zVcuBxC9!D^^4?r# zcXnsy?e}(OebgvV87eMk{~1ATBy@eKzJQYM(*$a!Ih8L?%~2g zpp+QVW+P5<@UaYL--+Kd@jF1;5qHwaJ5so2kn|2gJwapW7yxM=01!^vZ?63^G$i`~ z$TdC!AQ%bB{PGneaPat1v1f!(L#EG&lTS`a9{(Hu&YQ6NqmpzzL7$RqKGg-l=&jQL zwC%bMz{>FfptK)q^-XW-_-BHaPeVXyH_-mK5bXvaGj#!g_Oo{Z_;~L=-~oaqRouEk zNUm;M1HkB%oH#abzqOXAFX`SmT z`+=?}=nK^!E&}XawF6kJrf+kz0Q~ws4#4p4P5^qWI{@4s+iwIaynJuW{d=|<^Pbpq z@r$1UAo*$#fVy>20M>760^n;_y2tCEZvih5)Pa&z(JFSHNJWXO)Vi*JOsiNWJO9KZ zeb8xe-bp?AQbd-LO8(9~N>0V~1b+iQ!QEq0Y`8@L000hUSV?A0O#mtY000O800000 U007cclK=n!07*qoM6N<$f~XBjsQ>@~ diff --git a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs index 471616bbd8..fa0451de25 100644 --- a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs +++ b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs @@ -59,7 +59,6 @@ public override void ModifyTooltips(List tooltips) public static IList devList = new List() { - "Fabsol, the mod's founder and owner", // Fabsol gets a line to himself "Altix", "Angel", "apotofkoolaid", diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson index 48763168e9..f94aed69ad 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson @@ -2021,11 +2021,6 @@ AbandonedWulfrumHelmet: { ''' } -CrystalHeartVodka: { - DisplayName: Crystal Heart Vodka - Tooltip: "'Tastes like strawberry cream liqueur (and estrogen)'" -} - HapuFruit: { DisplayName: Ha-pu Fruit Tooltip: "'A fruit that calms your nerves (may have unintended side effects)'" diff --git a/Localization/en-US/Mods.CalamityMod.Items.Armor.Hardmode.hjson b/Localization/en-US/Mods.CalamityMod.Items.Armor.Hardmode.hjson index 675c64e604..65e8acace8 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Armor.Hardmode.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Armor.Hardmode.hjson @@ -60,18 +60,6 @@ BrimflameScowl: { ''' } -CirrusDress: { - DisplayName: Cirrus' Dress - Tooltip: - ''' - 5% increased magic damage and critical strike chance - 20% decreased movement speed and increases maximum fall speed to 61 mph - Allows for drinking 5 alcohols before your liver is poisoned - [c/B00BA5:'Here, this should help you drink a lot more than usual!'] - 'You feel thick...' - ''' -} - DaedalusBreastplate: { DisplayName: Daedalus Breastplate Tooltip: 3% increased damage and critical strike chance diff --git a/Localization/en-US/Mods.CalamityMod.Items.Misc.hjson b/Localization/en-US/Mods.CalamityMod.Items.Misc.hjson index 4183dc5080..d45b77358d 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Misc.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Misc.hjson @@ -281,7 +281,7 @@ BrimstoneLocus: { ColdheartIcicle: { DisplayName: Coldheart Icicle - Tooltip: "'Congratulations, you're winner! Here's my head on a stick.'" + Tooltip: "'Critically aclaimed vendetta'" } MomentumCapacitor: { diff --git a/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson b/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson index 4c0d8b539a..23842bd4bf 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Placeables.hjson @@ -343,11 +343,6 @@ BabyGhostBellJar: { Tooltip: "" } -CirrusCouch: { - DisplayName: Cirrus Couch - Tooltip: This shouldn't exist... -} - AquaticScourgeRelic: { DisplayName: Aquatic Scourge Relic Tooltip: A glimpse into what could have been... @@ -731,7 +726,7 @@ ResilientCandle: { ''' when placed to make defense block 10% more damage (60% in Classic, 85% in Expert, and 110% in Master) - This cannot be stacked with other Cirrus Candle buffs + This cannot be stacked with other candle buffs 'Neither rain nor wind can snuff its undying flame' ''' } @@ -752,7 +747,7 @@ SpitefulCandle: { ''' when placed to deal 1.07x damage to all enemies The extra 0.07x damage bypasses enemy defense and damage reduction - This cannot be stacked with other Cirrus Candle buffs + This cannot be stacked with other candle buffs 'Its hateful glow flickers with ire' ''' } @@ -978,7 +973,7 @@ VigorousCandle: { ''' when placed to regenerate 0.4% of your maximum health per second This regeneration is at full power even while moving and bypasses Revengeance Mode caps - This cannot be stacked with other Cirrus Candle buffs + This cannot be stacked with other candle buffs 'Its brilliant light suffuses those nearby with hope' ''' } @@ -988,7 +983,7 @@ WeightlessCandle: { Tooltip: ''' when placed to gain 10% increased movement speed, wing time and acceleration - This cannot be stacked with other Cirrus Candle buffs + This cannot be stacked with other candle buffs 'The floating flame seems to uplift your very spirit' ''' } diff --git a/Projectiles/Magic/YharimsCrystalBeam.cs b/Projectiles/Magic/YharimsCrystalBeam.cs index 9f3bf8f341..3f867c5ab8 100644 --- a/Projectiles/Magic/YharimsCrystalBeam.cs +++ b/Projectiles/Magic/YharimsCrystalBeam.cs @@ -310,7 +310,6 @@ private float GetHue(float indexing) { switch (name) { - case "Fabsol": case "Ziggums": return 2f; case "Poly": diff --git a/Tiles/Furniture/CirrusCouch.cs b/Tiles/Furniture/CirrusCouch.cs deleted file mode 100644 index 29551f8bb3..0000000000 --- a/Tiles/Furniture/CirrusCouch.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.DataStructures; -using Terraria.GameContent; -using Terraria.GameContent.ObjectInteractions; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Tiles.Furniture -{ - public class CirrusCouch : ModTile - { - public override void SetStaticDefaults() => this.SetUpSofa(ModContent.ItemType(), true); - - public override bool CreateDust(int i, int j, ref int type) - { - Dust.NewDust(new Vector2(i, j) * 16f, 16, 16, DustID.PinkFairy); - return false; - } - - public override void NumDust(int i, int j, bool fail, ref int num) - { - num = fail ? 1 : 3; - } - - public override void ModifySittingTargetInfo(int i, int j, ref TileRestingInfo info) => CalamityUtils.BenchSitInfo(i, j, ref info); - - public override bool RightClick(int i, int j) => CalamityUtils.ChairRightClick(i, j); - - public override void MouseOver(int i, int j) => CalamityUtils.BenchMouseOver(i, j, ModContent.ItemType()); - - public override bool HasSmartInteract(int i, int j, SmartInteractScanSettings settings) - { - return settings.player.IsWithinSnappngRangeToTile(i, j, PlayerSittingHelper.ChairSittingMaxDistance); - } - } -} diff --git a/Tiles/Furniture/CirrusCouch.png b/Tiles/Furniture/CirrusCouch.png deleted file mode 100644 index b494def71425cf7a6a75cb61dad275c065d52c80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1051 zcmV+$1mydPP)Px&yGcYrR9J=WmrZC?R}{y8Q!GYW7eOJN=93mXZCbSuA~Z-zAf!y8i%Mo8A&~|b zHH~!KBs48_k(!W#Bx0nyDNX7sK^KCL%3y;F1!*B4^VBSi z93@XPHa#gt%1||>093}Mo%a^3zGBXs$O2qr;Yn@5LV+#rL?Jet3RK(WGe`e;|Fm7)tmIh&Je?o#9VmOK(UEP{q9MG|3X zFna=k#lAk7_`}xQ8vhQ+RVH}SB4}h^BUjyLnbP9mVu{r>}#25gn=v7PI z_+sChFY(Ya=4VA^swCD1KziyE08*0ds7{#olR3fdiC&qgk!CjiEdV^zqN==$)ewf?Vb_6z#?>N>0c<)^Z) z!FYl)rSCYeSlai@KJKOeUT@1lm>JV7gYi+#iVBUnokilyS~F@j-*0Nkj+S2lh}Q14 z)-O5+qqQ$v{f-u!QH?2m_oXJUTKmx0*H&Z8{||%kGM2e}M)H5L+y^t}{!)fEZLJ4# zOeQA324Kece!o%Fb78m0Exc(NSjtRW{gT+)^P|R5G^XwtJ8D<6;8JEp>^ltk|6%U6 z@G_2_p^{=N_{!#q!j+Rk$Y&|H?+=tfW91avM`C(0000EWmrjOO-%qQ0000800000 V0002eQ&S diff --git a/Tiles/Furniture/CirrusCouch_Highlight.png b/Tiles/Furniture/CirrusCouch_Highlight.png deleted file mode 100644 index 37368baef24a4aa5ad43495e81d1fbdb1b916a64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 476 zcmV<20VDp2P)Px$d`Uz>R9J=Wm@!KOF%-xDuXJ&>Lv5FCrHfL(fH)~Q3SH`F5Oj9$Ea)mYiO^z4 z#lcmay6Wbnh@g9yI9y&aPq`+&%hAi-Z@RYWKQH&|Be@bhp_Ec_pWo6I0l*#(yv$$m zlDY&?T0znf5yfW9@o5_j)>w7XFY+DdJ3Y^kM2>&!K1I0`Gj~ygr7?z0xf+^Bqu<8w zT%PBM9ti+Waqg5CtTAVlCiUFm6lyq4ZJuC_S@)Q)-kS07X}pxZc1(v(y;fXf-c4yP z$D@DWm*zmQGFMznqWPHuk!E0RU)Kwg3Q=#vK8` z8fsQ~!5aHx!}Yl;Yh-=B<_Q77=zU;}3)a}I$Fkb5k|OKlx_eC+=7Kfm?X;dXavi}M zD;JhG%7x{PYG-xdeBRM4`+g?t-K_PEdc!sL@;wFsu({{2n_TT_T(=}#V|>Bp7~9jx zPCfef=>Fp@k?Ewr7+HU?#!B+W4>;7Li4?J0P5=M^4rN$LW=%~1DgXcg2mk;800000 S(o>TF0000 Date: Mon, 26 May 2025 13:01:16 -0700 Subject: [PATCH 229/401] Making all drinks craftable at kegs --- Items/Potions/Alcohol/BloodyMary.cs | 18 ++++++++++++++++++ Items/Potions/Alcohol/CaribbeanRum.cs | 17 +++++++++++++++++ Items/Potions/Alcohol/CinnamonRoll.cs | 19 +++++++++++++++++++ Items/Potions/Alcohol/Everclear.cs | 19 +++++++++++++++++++ Items/Potions/Alcohol/EvergreenGin.cs | 17 +++++++++++++++++ Items/Potions/Alcohol/Fireball.cs | 17 +++++++++++++++++ Items/Potions/Alcohol/GrapeBeer.cs | 19 +++++++++++++++++++ Items/Potions/Alcohol/Margarita.cs | 17 +++++++++++++++++ Items/Potions/Alcohol/Moonshine.cs | 18 ++++++++++++++++++ Items/Potions/Alcohol/MoscowMule.cs | 18 ++++++++++++++++++ Items/Potions/Alcohol/OldFashioned.cs | 17 +++++++++++++++++ Items/Potions/Alcohol/RedWine.cs | 18 ++++++++++++++++++ Items/Potions/Alcohol/Rum.cs | 17 +++++++++++++++++ Items/Potions/Alcohol/Screwdriver.cs | 18 ++++++++++++++++++ Items/Potions/Alcohol/StarBeamRye.cs | 18 ++++++++++++++++++ Items/Potions/Alcohol/Tequila.cs | 17 +++++++++++++++++ Items/Potions/Alcohol/TequilaSunrise.cs | 18 ++++++++++++++++++ Items/Potions/Alcohol/Vodka.cs | 18 ++++++++++++++++++ Items/Potions/Alcohol/Whiskey.cs | 17 +++++++++++++++++ Items/Potions/Alcohol/WhiteWine.cs | 18 ++++++++++++++++++ 20 files changed, 355 insertions(+) diff --git a/Items/Potions/Alcohol/BloodyMary.cs b/Items/Potions/Alcohol/BloodyMary.cs index e674edd64a..a687df2f88 100644 --- a/Items/Potions/Alcohol/BloodyMary.cs +++ b/Items/Potions/Alcohol/BloodyMary.cs @@ -1,4 +1,5 @@ using CalamityMod.Buffs.Alcohol; +using CalamityMod.Items.Materials; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -29,5 +30,22 @@ public override void SetDefaults() Item.buffTime = CalamityUtils.SecondsToFrames(480f); Item.value = Item.buyPrice(0, 2, 60, 0); } + public override void AddRecipes() + { + CreateRecipe(). + AddIngredient(ItemID.Ale). + AddIngredient(5). + AddIngredient(). + AddTile(TileID.Kegs). + Register(); + + CreateRecipe(). + AddIngredient(ItemID.BottledWater). + AddIngredient(5). + AddIngredient(). + AddTile(TileID.AlchemyTable). + Register() + .DisableDecraft(); + } } } diff --git a/Items/Potions/Alcohol/CaribbeanRum.cs b/Items/Potions/Alcohol/CaribbeanRum.cs index b8d4a37cec..f88594a85d 100644 --- a/Items/Potions/Alcohol/CaribbeanRum.cs +++ b/Items/Potions/Alcohol/CaribbeanRum.cs @@ -1,4 +1,5 @@ using CalamityMod.Buffs.Alcohol; +using CalamityMod.Items.Materials; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -29,5 +30,21 @@ public override void SetDefaults() Item.buffTime = CalamityUtils.SecondsToFrames(480f); Item.value = Item.buyPrice(0, 5, 30, 0); } + public override void AddRecipes() + { + CreateRecipe(). + AddIngredient(ItemID.Ale). + AddIngredient(). + AddTile(TileID.Kegs). + Register(); + + CreateRecipe(). + AddIngredient(ItemID.BottledWater). + AddIngredient(5). + AddIngredient(). + AddTile(TileID.AlchemyTable). + Register() + .DisableDecraft(); + } } } diff --git a/Items/Potions/Alcohol/CinnamonRoll.cs b/Items/Potions/Alcohol/CinnamonRoll.cs index 0973b19847..8d36633e52 100644 --- a/Items/Potions/Alcohol/CinnamonRoll.cs +++ b/Items/Potions/Alcohol/CinnamonRoll.cs @@ -1,4 +1,6 @@ using CalamityMod.Buffs.Alcohol; +using CalamityMod.Items.Materials; +using CalamityMod.Items.Placeables.Ores; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -29,5 +31,22 @@ public override void SetDefaults() Item.buffTime = CalamityUtils.SecondsToFrames(480f); Item.value = Item.buyPrice(0, 5, 30, 0); } + public override void AddRecipes() + { + CreateRecipe(). + AddIngredient(ItemID.Ale). + AddIngredient(3). + AddIngredient(ItemID.LivingFireBlock). + AddTile(TileID.Kegs). + Register(); + + CreateRecipe(). + AddIngredient(ItemID.BottledWater). + AddIngredient(5). + AddIngredient(). + AddTile(TileID.AlchemyTable). + Register() + .DisableDecraft(); + } } } diff --git a/Items/Potions/Alcohol/Everclear.cs b/Items/Potions/Alcohol/Everclear.cs index 677e4b775c..0e4e562e30 100644 --- a/Items/Potions/Alcohol/Everclear.cs +++ b/Items/Potions/Alcohol/Everclear.cs @@ -1,4 +1,5 @@ using CalamityMod.Buffs.Alcohol; +using CalamityMod.Items.Materials; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -29,5 +30,23 @@ public override void SetDefaults() Item.buffTime = CalamityUtils.SecondsToFrames(60f); Item.value = Item.buyPrice(0, 2, 0, 0); } + public override void AddRecipes() + { + CreateRecipe(). + AddIngredient(ItemID.Ale). + AddIngredient(ItemID.Glass, 10). + AddIngredient(). + AddTile(TileID.Kegs). + Register(); + + CreateRecipe(). + AddIngredient(ItemID.BottledWater). + AddIngredient(5). + AddIngredient(ItemID.Glass, 5). + AddIngredient(). + AddTile(TileID.AlchemyTable). + Register() + .DisableDecraft(); + } } } diff --git a/Items/Potions/Alcohol/EvergreenGin.cs b/Items/Potions/Alcohol/EvergreenGin.cs index 86db743607..10b96870b9 100644 --- a/Items/Potions/Alcohol/EvergreenGin.cs +++ b/Items/Potions/Alcohol/EvergreenGin.cs @@ -1,4 +1,5 @@ using CalamityMod.Buffs.Alcohol; +using CalamityMod.Items.Materials; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -29,5 +30,21 @@ public override void SetDefaults() Item.buffTime = CalamityUtils.SecondsToFrames(480f); Item.value = Item.buyPrice(0, 5, 30, 0); } + public override void AddRecipes() + { + CreateRecipe(). + AddIngredient(ItemID.Ale). + AddIngredient(). + AddTile(TileID.Kegs). + Register(); + + CreateRecipe(). + AddIngredient(ItemID.BottledWater). + AddIngredient(5). + AddIngredient(). + AddTile(TileID.AlchemyTable). + Register() + .DisableDecraft(); + } } } diff --git a/Items/Potions/Alcohol/Fireball.cs b/Items/Potions/Alcohol/Fireball.cs index d8b5cf82c3..fa237263d4 100644 --- a/Items/Potions/Alcohol/Fireball.cs +++ b/Items/Potions/Alcohol/Fireball.cs @@ -1,4 +1,5 @@ using CalamityMod.Buffs.Alcohol; +using CalamityMod.Items.Materials; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -29,5 +30,21 @@ public override void SetDefaults() Item.buffTime = CalamityUtils.SecondsToFrames(480f); Item.value = Item.buyPrice(0, 2, 0, 0); } + public override void AddRecipes() + { + CreateRecipe(). + AddIngredient(ItemID.Ale). + AddIngredient(ItemID.LivingFireBlock). + AddTile(TileID.Kegs). + Register(); + + CreateRecipe(). + AddIngredient(ItemID.BottledWater). + AddIngredient(5). + AddIngredient(ItemID.LivingFireBlock). + AddTile(TileID.AlchemyTable). + Register() + .DisableDecraft(); + } } } diff --git a/Items/Potions/Alcohol/GrapeBeer.cs b/Items/Potions/Alcohol/GrapeBeer.cs index 36f309e56b..ec132ad326 100644 --- a/Items/Potions/Alcohol/GrapeBeer.cs +++ b/Items/Potions/Alcohol/GrapeBeer.cs @@ -1,4 +1,5 @@ using CalamityMod.Buffs.Alcohol; +using CalamityMod.Items.Materials; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -35,5 +36,23 @@ public override void OnConsumeItem(Player player) { player.AddBuff(ModContent.BuffType(), 900); } + + public override void AddRecipes() + { + CreateRecipe(10). + AddIngredient(ItemID.Bottle, 10). + AddIngredient(ItemID.Grapes). + AddIngredient(5). + AddTile(TileID.Kegs). + Register(); + + CreateRecipe(). + AddIngredient(ItemID.BottledWater). + AddIngredient(5). + AddIngredient(). + AddTile(TileID.AlchemyTable). + Register() + .DisableDecraft(); + } } } diff --git a/Items/Potions/Alcohol/Margarita.cs b/Items/Potions/Alcohol/Margarita.cs index c3070a7bd8..8627e6ecd6 100644 --- a/Items/Potions/Alcohol/Margarita.cs +++ b/Items/Potions/Alcohol/Margarita.cs @@ -1,4 +1,5 @@ using CalamityMod.Buffs.Alcohol; +using CalamityMod.Items.Materials; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -38,5 +39,21 @@ public override void OnConsumeItem(Player player) { player.AddBuff(BuffType, BuffDuration); } + public override void AddRecipes() + { + CreateRecipe(). + AddIngredient(ItemID.Ale). + AddIngredient(). + AddTile(TileID.Kegs). + Register(); + + CreateRecipe(). + AddIngredient(ItemID.BottledWater). + AddIngredient(5). + AddIngredient(). + AddTile(TileID.AlchemyTable). + Register() + .DisableDecraft(); + } } } diff --git a/Items/Potions/Alcohol/Moonshine.cs b/Items/Potions/Alcohol/Moonshine.cs index 761978e62a..deb0a54ef5 100644 --- a/Items/Potions/Alcohol/Moonshine.cs +++ b/Items/Potions/Alcohol/Moonshine.cs @@ -1,4 +1,6 @@ using CalamityMod.Buffs.Alcohol; +using CalamityMod.Items.Materials; +using CalamityMod.Items.Placeables.Ores; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -29,5 +31,21 @@ public override void SetDefaults() Item.buffTime = CalamityUtils.SecondsToFrames(480f); Item.value = Item.buyPrice(0, 1, 30, 0); } + public override void AddRecipes() + { + CreateRecipe(). + AddIngredient(ItemID.Ale). + AddIngredient(3). + AddTile(TileID.Kegs). + Register(); + + CreateRecipe(). + AddIngredient(ItemID.BottledWater). + AddIngredient(5). + AddIngredient(). + AddTile(TileID.AlchemyTable). + Register() + .DisableDecraft(); + } } } diff --git a/Items/Potions/Alcohol/MoscowMule.cs b/Items/Potions/Alcohol/MoscowMule.cs index 68360b9557..0711a4d0f5 100644 --- a/Items/Potions/Alcohol/MoscowMule.cs +++ b/Items/Potions/Alcohol/MoscowMule.cs @@ -1,4 +1,6 @@ using CalamityMod.Buffs.Alcohol; +using CalamityMod.Items.Materials; +using CalamityMod.Items.Placeables.Ores; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -31,5 +33,21 @@ public override void SetDefaults() Item.buffTime = CalamityUtils.SecondsToFrames(480f); Item.value = Item.buyPrice(0, 5, 30, 0); } + public override void AddRecipes() + { + CreateRecipe(). + AddIngredient(ItemID.Ale). + AddIngredient(3). + AddTile(TileID.Kegs). + Register(); + + CreateRecipe(). + AddIngredient(ItemID.BottledWater). + AddIngredient(5). + AddIngredient(). + AddTile(TileID.AlchemyTable). + Register() + .DisableDecraft(); + } } } diff --git a/Items/Potions/Alcohol/OldFashioned.cs b/Items/Potions/Alcohol/OldFashioned.cs index d1a68bde36..cd56155711 100644 --- a/Items/Potions/Alcohol/OldFashioned.cs +++ b/Items/Potions/Alcohol/OldFashioned.cs @@ -1,4 +1,5 @@ using CalamityMod.Buffs.Alcohol; +using CalamityMod.Items.Materials; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -33,5 +34,21 @@ public override void SetDefaults() Item.buffTime = CalamityUtils.SecondsToFrames(360f); Item.value = Item.buyPrice(0, 5, 30, 0); } + public override void AddRecipes() + { + CreateRecipe(). + AddIngredient(ItemID.Ale). + AddIngredient(ItemID.Ectoplasm). + AddTile(TileID.Kegs). + Register(); + + CreateRecipe(). + AddIngredient(ItemID.BottledWater). + AddIngredient(5). + AddIngredient(ItemID.Ectoplasm). + AddTile(TileID.AlchemyTable). + Register() + .DisableDecraft(); + } } } diff --git a/Items/Potions/Alcohol/RedWine.cs b/Items/Potions/Alcohol/RedWine.cs index 5f3cc7a515..3be0d99555 100644 --- a/Items/Potions/Alcohol/RedWine.cs +++ b/Items/Potions/Alcohol/RedWine.cs @@ -1,4 +1,5 @@ using CalamityMod.Buffs.Alcohol; +using CalamityMod.Items.Materials; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -40,5 +41,22 @@ public override void OnConsumeItem(Player player) { player.AddBuff(ModContent.BuffType(), 900); } + public override void AddRecipes() + { + CreateRecipe(10). + AddIngredient(ItemID.Bottle, 10). + AddIngredient(ItemID.Grapes). + AddIngredient(5). + AddTile(TileID.Kegs). + Register(); + + CreateRecipe(). + AddIngredient(ItemID.BottledWater). + AddIngredient(5). + AddIngredient(). + AddTile(TileID.AlchemyTable). + Register() + .DisableDecraft(); + } } } diff --git a/Items/Potions/Alcohol/Rum.cs b/Items/Potions/Alcohol/Rum.cs index 3872d3d561..d71095c0f5 100644 --- a/Items/Potions/Alcohol/Rum.cs +++ b/Items/Potions/Alcohol/Rum.cs @@ -1,4 +1,5 @@ using CalamityMod.Buffs.Alcohol; +using CalamityMod.Items.Materials; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -29,5 +30,21 @@ public override void SetDefaults() Item.buffTime = CalamityUtils.SecondsToFrames(480f); Item.value = Item.buyPrice(0, 1, 30, 0); } + public override void AddRecipes() + { + CreateRecipe(). + AddIngredient(ItemID.Ale). + AddIngredient(5). + AddTile(TileID.Kegs). + Register(); + + CreateRecipe(). + AddIngredient(ItemID.BottledWater). + AddIngredient(5). + AddIngredient(). + AddTile(TileID.AlchemyTable). + Register() + .DisableDecraft(); + } } } diff --git a/Items/Potions/Alcohol/Screwdriver.cs b/Items/Potions/Alcohol/Screwdriver.cs index c4636851ca..d3b2e146f1 100644 --- a/Items/Potions/Alcohol/Screwdriver.cs +++ b/Items/Potions/Alcohol/Screwdriver.cs @@ -1,4 +1,6 @@ using CalamityMod.Buffs.Alcohol; +using CalamityMod.Items.Materials; +using CalamityMod.Items.Placeables.Ores; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -29,5 +31,21 @@ public override void SetDefaults() Item.buffTime = CalamityUtils.SecondsToFrames(480f); Item.value = Item.buyPrice(0, 4, 0, 0); } + public override void AddRecipes() + { + CreateRecipe(). + AddIngredient(ItemID.Ale). + AddIngredient(3). + AddTile(TileID.Kegs). + Register(); + + CreateRecipe(). + AddIngredient(ItemID.BottledWater). + AddIngredient(5). + AddIngredient(). + AddTile(TileID.AlchemyTable). + Register() + .DisableDecraft(); + } } } diff --git a/Items/Potions/Alcohol/StarBeamRye.cs b/Items/Potions/Alcohol/StarBeamRye.cs index 8c920d9a0b..7c9c585cd2 100644 --- a/Items/Potions/Alcohol/StarBeamRye.cs +++ b/Items/Potions/Alcohol/StarBeamRye.cs @@ -1,4 +1,5 @@ using CalamityMod.Buffs.Alcohol; +using CalamityMod.Items.Materials; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -29,5 +30,22 @@ public override void SetDefaults() Item.buffTime = CalamityUtils.SecondsToFrames(480f); Item.value = Item.buyPrice(0, 4, 0, 0); } + public override void AddRecipes() + { + CreateRecipe(). + AddIngredient(ItemID.Ale). + AddIngredient(5). + AddIngredient(). + AddTile(TileID.Kegs). + Register(); + + CreateRecipe(). + AddIngredient(ItemID.BottledWater). + AddIngredient(5). + AddIngredient(). + AddTile(TileID.AlchemyTable). + Register() + .DisableDecraft(); + } } } diff --git a/Items/Potions/Alcohol/Tequila.cs b/Items/Potions/Alcohol/Tequila.cs index ac1c240cc0..859263d0a1 100644 --- a/Items/Potions/Alcohol/Tequila.cs +++ b/Items/Potions/Alcohol/Tequila.cs @@ -1,4 +1,5 @@ using CalamityMod.Buffs.Alcohol; +using CalamityMod.Items.Materials; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -31,5 +32,21 @@ public override void SetDefaults() Item.buffTime = CalamityUtils.SecondsToFrames(480f); Item.value = Item.buyPrice(0, 1, 30, 0); } + public override void AddRecipes() + { + CreateRecipe(). + AddIngredient(ItemID.Ale). + AddIngredient(5). + AddTile(TileID.Kegs). + Register(); + + CreateRecipe(). + AddIngredient(ItemID.BottledWater). + AddIngredient(5). + AddIngredient(). + AddTile(TileID.AlchemyTable). + Register() + .DisableDecraft(); + } } } diff --git a/Items/Potions/Alcohol/TequilaSunrise.cs b/Items/Potions/Alcohol/TequilaSunrise.cs index c3cbf82664..ea035ff960 100644 --- a/Items/Potions/Alcohol/TequilaSunrise.cs +++ b/Items/Potions/Alcohol/TequilaSunrise.cs @@ -1,4 +1,6 @@ using CalamityMod.Buffs.Alcohol; +using CalamityMod.Items.Materials; +using CalamityMod.Items.Placeables.Ores; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -30,5 +32,21 @@ public override void SetDefaults() Item.buffTime = CalamityUtils.SecondsToFrames(480f); Item.value = Item.buyPrice(0, 6, 60, 0); } + public override void AddRecipes() + { + CreateRecipe(). + AddIngredient(ItemID.Ale). + AddIngredient(3). + AddTile(TileID.Kegs). + Register(); + + CreateRecipe(). + AddIngredient(ItemID.BottledWater). + AddIngredient(5). + AddIngredient(). + AddTile(TileID.AlchemyTable). + Register() + .DisableDecraft(); + } } } diff --git a/Items/Potions/Alcohol/Vodka.cs b/Items/Potions/Alcohol/Vodka.cs index ce5fda48ed..ad84aa3390 100644 --- a/Items/Potions/Alcohol/Vodka.cs +++ b/Items/Potions/Alcohol/Vodka.cs @@ -1,4 +1,6 @@ using CalamityMod.Buffs.Alcohol; +using CalamityMod.Items.Materials; +using CalamityMod.Items.Placeables.Ores; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -31,5 +33,21 @@ public override void SetDefaults() Item.buffTime = CalamityUtils.SecondsToFrames(480f); Item.value = Item.buyPrice(0, 1, 30, 0); } + public override void AddRecipes() + { + CreateRecipe(). + AddIngredient(ItemID.Ale). + AddIngredient(3). + AddTile(TileID.Kegs). + Register(); + + CreateRecipe(). + AddIngredient(ItemID.BottledWater). + AddIngredient(5). + AddIngredient(). + AddTile(TileID.AlchemyTable). + Register() + .DisableDecraft(); + } } } diff --git a/Items/Potions/Alcohol/Whiskey.cs b/Items/Potions/Alcohol/Whiskey.cs index 3a69589efd..6e6a0bad09 100644 --- a/Items/Potions/Alcohol/Whiskey.cs +++ b/Items/Potions/Alcohol/Whiskey.cs @@ -1,4 +1,5 @@ using CalamityMod.Buffs.Alcohol; +using CalamityMod.Items.Materials; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -31,5 +32,21 @@ public override void SetDefaults() Item.buffTime = CalamityUtils.SecondsToFrames(480f); Item.value = Item.buyPrice(0, 1, 30, 0); } + public override void AddRecipes() + { + CreateRecipe(). + AddIngredient(ItemID.Ale). + AddIngredient(5). + AddTile(TileID.Kegs). + Register(); + + CreateRecipe(). + AddIngredient(ItemID.BottledWater). + AddIngredient(5). + AddIngredient(). + AddTile(TileID.AlchemyTable). + Register() + .DisableDecraft(); + } } } diff --git a/Items/Potions/Alcohol/WhiteWine.cs b/Items/Potions/Alcohol/WhiteWine.cs index d640b9b56e..d15ade4beb 100644 --- a/Items/Potions/Alcohol/WhiteWine.cs +++ b/Items/Potions/Alcohol/WhiteWine.cs @@ -1,4 +1,6 @@ using CalamityMod.Buffs.Alcohol; +using CalamityMod.Items.Materials; +using CalamityMod.Items.Placeables.Ores; using Terraria; using Terraria.GameInput; using Terraria.ID; @@ -50,5 +52,21 @@ public override void SetDefaults() player.AddBuff(Item.buffType, Item.buffTime); return true; } + public override void AddRecipes() + { + CreateRecipe(). + AddIngredient(ItemID.Ale). + AddIngredient(3). + AddTile(TileID.Kegs). + Register(); + + CreateRecipe(). + AddIngredient(ItemID.BottledWater). + AddIngredient(5). + AddIngredient(). + AddTile(TileID.AlchemyTable). + Register() + .DisableDecraft(); + } } } From f9d9f9c186f81e1cd739f235b216550e97acfbfe Mon Sep 17 00:00:00 2001 From: sunny-raindrops Date: Mon, 26 May 2025 13:05:10 -0700 Subject: [PATCH 230/401] Removed Cirrus flavor text for drinks --- .../Mods.CalamityMod.Items.Potions.hjson | 22 +------------------ 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson b/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson index b1e1a9437e..41a4f76216 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson @@ -175,7 +175,7 @@ ZergPotion: { Tooltip: Vastly increases enemy spawn rate } -// Drunk Princess Shop Items +// Very normal Keg crafts BloodyMary: { DisplayName: Bloody Mary Tooltip: @@ -183,7 +183,6 @@ BloodyMary: { 10% increased damage and movement speed during a Blood Moon Reduces life regen by 2 HP/s and defense by 4% Drinking more than 3 different alcohols might not end well with your liver - [c/B00BA5:'Extra spicy... and bloody!'] ''' } @@ -194,7 +193,6 @@ CaribbeanRum: { Increases life regen by 1 HP/s, movement speed by 10% Makes you floaty and reduces defense by 10% Drinking more than 3 different alcohols might not end well with your liver - [c/B00BA5:'Why is the rum gone?'] ''' } @@ -205,7 +203,6 @@ CinnamonRoll: { Increases mana regeneration rate and multiplies all fire-based debuff damage by 1.5x Reduces defense by 10% Drinking more than 3 different alcohols might not end well with your liver - [c/B00BA5:'A great-tasting cinnamon whiskey with a touch of cream soda.'] ''' } @@ -217,7 +214,6 @@ Everclear: { Reduces life regen by 5 HP/s and defense by 30% Counts as 2 alcohols for Alcohol Poisoning Drinking more than 3 different alcohols might not end well with your liver - [c/B00BA5:'This is the most potent booze I have, be careful with it.'] ''' } @@ -228,7 +224,6 @@ EvergreenGin: { Multiplies all sickness and water-related debuff damage by 1.25x Reduces life regen by 0.5 HP/s Drinking more than 3 different alcohols might not end well with your liver - [c/B00BA5:'It tastes like a Christmas tree, if you can imagine that.'] ''' } @@ -250,7 +245,6 @@ Fireball: { Multiplies all fire-based debuff damage by 1.25x Reduces life regen by 0.5 HP/s Drinking more than 3 different alcohols might not end well with your liver - [c/B00BA5:'A great-tasting cinnamon whiskey.'] ''' } @@ -260,7 +254,6 @@ GrapeBeer: { ''' Reduces defense by 3% for 15 seconds Drinking more than 3 different alcohols might not end well with your liver - [c/B00BA5:'This crap is abhorrent, but you might like it.'] ''' } @@ -272,7 +265,6 @@ Margarita: { Reduces defense by 6% and life regen by 0.5 HP/s Drinking more than 3 different alcohols might not end well with your liver 3 minute duration - [c/B00BA5:'One of the best drinks ever created, enjoy it while it lasts.'] ''' } @@ -283,7 +275,6 @@ Moonshine: { Increases defense by 10 and damage reduction by 3% Reduces life regen by 0.5 HP/s Drinking more than 3 different alcohols might not end well with your liver - [c/B00BA5:'This stuff is pretty strong, but I'm sure you can handle it.'] ''' } @@ -294,7 +285,6 @@ MoscowMule: { Increases damage by 9%, knockback by 50% and critical strike chance by 3% Reduces life regen by 2 HP/s Drinking more than 3 different alcohols might not end well with your liver - [c/B00BA5:'I once heard the copper mug can be toxic and I told 'em, 'listen, dummy, I'm already poisoning myself!''] ''' } @@ -316,7 +306,6 @@ OldFashioned: { Multiplies all accessory and set bonus damage by 1.5x Decreases all damage by 25% Drinking more than 3 different alcohols might not end well with your liver - [c/B00BA5:'An old favorite of mine.'] ''' } @@ -326,7 +315,6 @@ RedWine: { ''' Reduces life regen by 0.5 HP/s for 15 seconds Drinking more than 3 different alcohols might not end well with your liver - [c/B00BA5:'Too dry for my taste.'] ''' } @@ -337,7 +325,6 @@ Rum: { Increases life regen by 1 HP/s and movement speed by 10% Reduces defense by 5% Drinking more than 3 different alcohols might not end well with your liver - [c/B00BA5:'Sweet and potent, just how I like it.'] ''' } @@ -348,7 +335,6 @@ Screwdriver: { Multiplies piercing projectile damage by 1.05x Reduces life regen by 0.5 HP/s Drinking more than 3 different alcohols might not end well with your liver - [c/B00BA5:'Do you have a screw loose?'] ''' } @@ -360,7 +346,6 @@ StarBeamRye: { and reduces mana usage by 10% Reduces defense by 6% and life regen by 1 HP/s Drinking more than 3 different alcohols might not end well with your liver - [c/B00BA5:'Made from some stuff I found near the Astral Meteor crash site. Don't worry, it's safe, trust me...'] ''' } @@ -371,7 +356,6 @@ Tequila: { Increases knockback by 10%, crit chance by 4% and defense by 5 during daytime Reduces life regen by 0.5 HP/s Drinking more than 3 different alcohols might not end well with your liver - [c/B00BA5:'Great for mixing up daytime drinks.'] ''' } @@ -382,7 +366,6 @@ TequilaSunrise: { Increases knockback by 20%, crit chance by 8% and defense by 10 during daytime Reduces life regen by 1 HP/s Drinking more than 3 different alcohols might not end well with your liver - [c/B00BA5:'The greatest daytime drink I've ever had.'] ''' } @@ -393,7 +376,6 @@ Vodka: { Increases damage by 6% and critical strike chance by 2% Reduces life regen by 0.5 HP/s and defense by 5% Drinking more than 3 different alcohols might not end well with your liver - [c/B00BA5:'The number one alcohol for creating great mixed drinks.'] ''' } @@ -404,7 +386,6 @@ Whiskey: { Increases damage by 4%, knockback by 20% and critical strike chance by 2% Reduces defense by 5% Drinking more than 3 different alcohols might not end well with your liver - [c/B00BA5:'The burning sensation makes it tastier.'] ''' } @@ -415,6 +396,5 @@ WhiteWine: { Increases magic damage by 8% Reduces defense by 6% and life regen by 0.5 HP/s Drinking more than 3 different alcohols might not end well with your liver - [c/B00BA5:'I drank a full barrel of this stuff once in one night, I couldn't remember who I was the next day.'] ''' } From 15e967ee6590a145dbd26cd88af307327c20b508 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Mon, 26 May 2025 16:09:07 -0400 Subject: [PATCH 231/401] Added homing Calamity projectiles to CultistIsResistantTo --- .../DraedonsArsenal/FrequencyManipulatorEnergy.cs | 1 + Projectiles/DraedonsArsenal/PhaseslayerBeam.cs | 1 + Projectiles/DraedonsArsenal/PulsePistolShot.cs | 1 + Projectiles/DraedonsArsenal/PulseRifleShot.cs | 1 + Projectiles/DraedonsArsenal/PulseTurretShot.cs | 1 + Projectiles/DraedonsArsenal/SnakeEyesProjectile.cs | 1 + Projectiles/DraedonsArsenal/SystemBaneLightning.cs | 1 + Projectiles/DraedonsArsenal/TeslaCannonShot.cs | 1 + Projectiles/DraedonsArsenal/TrackingDiskLaser.cs | 1 + Projectiles/Magic/ApotheosisEnergy.cs | 1 + Projectiles/Magic/ApotheosisWorm.cs | 1 + Projectiles/Magic/AstralStarMagic.cs | 1 + Projectiles/Magic/AstralachneaFang.cs | 1 + Projectiles/Magic/BeamStar.cs | 1 + Projectiles/Magic/BeamingBolt2.cs | 1 + Projectiles/Magic/BeastScythe.cs | 1 + Projectiles/Magic/BlackAnurianPlankton.cs | 2 ++ Projectiles/Magic/BlueBubble.cs | 1 + Projectiles/Magic/ChronoIcicleLarge.cs | 1 + Projectiles/Magic/ClimaxBeam.cs | 1 + Projectiles/Magic/EternityHoming.cs | 2 ++ Projectiles/Magic/EventHorizonStar.cs | 1 + Projectiles/Magic/ExoVortex.cs | 2 +- Projectiles/Magic/ExoVortex2.cs | 2 +- Projectiles/Magic/FatesRevealFlame.cs | 1 + Projectiles/Magic/ForbiddenAxeBlade.cs | 1 + Projectiles/Magic/GhastlyBlast.cs | 1 + Projectiles/Magic/GhastlyExplosionShard.cs | 2 ++ Projectiles/Magic/GleamingBolt2.cs | 2 ++ Projectiles/Magic/GraniteEnergy.cs | 1 + Projectiles/Magic/HadalUrnJellyfish.cs | 2 ++ Projectiles/Magic/HadalUrnStarfishShard.cs | 1 + Projectiles/Magic/IceBlock.cs | 1 + Projectiles/Magic/LightBead.cs | 1 + Projectiles/Magic/LightBlade.cs | 1 + Projectiles/Magic/LightningArc.cs | 1 + Projectiles/Magic/MadAlchemistsCocktailShrapnel.cs | 1 + Projectiles/Magic/MagneticBeam.cs | 1 + Projectiles/Magic/ManaBoltSmall.cs | 1 + Projectiles/Magic/NebulaCloudCore.cs | 1 + Projectiles/Magic/NightBolt.cs | 1 + Projectiles/Magic/NuclearFuryProjectile.cs | 1 + Projectiles/Magic/PhantasmalFuryProj.cs | 1 + Projectiles/Magic/Phantom.cs | 1 + Projectiles/Magic/PhotosyntheticShard.cs | 1 + Projectiles/Magic/PoseidonTyphoon.cs | 1 + Projectiles/Magic/PrinceFlameSmall.cs | 1 + Projectiles/Magic/RainbowRocket.cs | 1 + Projectiles/Magic/RedirectingFire.cs | 1 + Projectiles/Magic/RedirectingGildedSoul.cs | 1 + Projectiles/Magic/RedirectingLostSoul.cs | 1 + Projectiles/Magic/RedirectingVengefulSoul.cs | 1 + Projectiles/Magic/ShadecrystalProjectile.cs | 1 + Projectiles/Magic/Shadowbolt.cs | 1 + Projectiles/Magic/Snowflake.cs | 1 + Projectiles/Magic/SnowflakeIceStar.cs | 1 + Projectiles/Magic/SpiritCongregation.cs | 1 + Projectiles/Magic/TearsofHeavenProjectile.cs | 1 + Projectiles/Magic/UndinesRetributionSpear.cs | 1 + Projectiles/Magic/VividBolt.cs | 1 + Projectiles/Magic/VividLaser2.cs | 1 + Projectiles/Magic/WulfrumBolt.cs | 1 + Projectiles/Melee/AbyssBladeSplitProjectile.cs | 1 + Projectiles/Melee/AmidiasWhirlpool.cs | 1 + Projectiles/Melee/AncientStar.cs | 1 + Projectiles/Melee/BalefulHarvesterProjectile.cs | 1 + Projectiles/Melee/BlazingPhantomBlade.cs | 1 + Projectiles/Melee/Blood.cs | 1 + Projectiles/Melee/Blood2.cs | 1 + Projectiles/Melee/BloodScythe.cs | 1 + Projectiles/Melee/Brimlash2.cs | 1 + Projectiles/Melee/CosmicBolt.cs | 1 + Projectiles/Melee/CosmicShivBlade.cs | 1 + Projectiles/Melee/CosmicShivTrail.cs | 10 +--------- Projectiles/Melee/CrescentMoonProj.cs | 1 + Projectiles/Melee/DeathsAscensionProjectile.cs | 1 + Projectiles/Melee/DepthCrusherSplitProjectile.cs | 1 + Projectiles/Melee/DivineHatchetBoomerang.cs | 1 + Projectiles/Melee/DraconicSpark.cs | 1 + Projectiles/Melee/DragonRageFireball.cs | 1 + Projectiles/Melee/ElementBallShiv.cs | 1 + Projectiles/Melee/ElementalGlassStar.cs | 1 + Projectiles/Melee/EmpyreanKnife.cs | 1 + Projectiles/Melee/EntropicFlechette.cs | 1 + Projectiles/Melee/EntropicFlechetteLarge.cs | 1 + Projectiles/Melee/EntropicFlechetteSmall.cs | 1 + Projectiles/Melee/EonBolt.cs | 2 +- Projectiles/Melee/EssenceFlame2.cs | 1 + Projectiles/Melee/EssenceScythe.cs | 1 + Projectiles/Melee/Exobeam.cs | 1 + Projectiles/Melee/FallenPaladinsHammerEcho.cs | 1 + Projectiles/Melee/Flarefrost.cs | 1 + Projectiles/Melee/GaelSkull.cs | 1 + Projectiles/Melee/GaelSkull2.cs | 1 + Projectiles/Melee/GalaxiaBolt.cs | 1 + Projectiles/Melee/GalaxySmasherEcho.cs | 1 + Projectiles/Melee/GalileosMoon.cs | 1 + Projectiles/Melee/GhastlySoulLarge.cs | 1 + Projectiles/Melee/GhastlySoulMedium.cs | 1 + Projectiles/Melee/GhastlySoulSmall.cs | 1 + Projectiles/Melee/HolyColliderHolyFire.cs | 1 + Projectiles/Melee/IllustriousKnife.cs | 1 + Projectiles/Melee/JudgementProj.cs | 1 + Projectiles/Melee/MourningSkull.cs | 1 + Projectiles/Melee/NeptunesBountySplitProjectile.cs | 1 + Projectiles/Melee/OathswordFlame.cs | 1 + Projectiles/Melee/OrderbringerBeam.cs | 1 + Projectiles/Melee/OrderbringerRain.cs | 1 + Projectiles/Melee/PlagueSeeker.cs | 1 + Projectiles/Melee/PwnagehammerEcho.cs | 1 + Projectiles/Melee/Razorwind.cs | 1 + Projectiles/Melee/SHIV.cs | 1 + Projectiles/Melee/SandFire.cs | 1 + Projectiles/Melee/ScourgeoftheCosmosMini.cs | 2 ++ Projectiles/Melee/StellarContemptEcho.cs | 1 + Projectiles/Melee/StormBeam.cs | 1 + Projectiles/Melee/TerratomereSwordBeam.cs | 1 + Projectiles/Melee/TinyFlare.cs | 1 + Projectiles/Melee/TriactisHammerProj.cs | 1 + Projectiles/Melee/TyphonsGreedBubble.cs | 1 + Projectiles/Melee/UltimusCleaverDust.cs | 1 + Projectiles/Melee/VoidEssence.cs | 1 + Projectiles/Melee/Whiterain.cs | 1 + Projectiles/Ranged/AquashardSplit.cs | 1 + Projectiles/Ranged/AstralRound.cs | 1 + Projectiles/Ranged/AstrealFlame.cs | 1 + Projectiles/Ranged/AuricBullet.cs | 1 + Projectiles/Ranged/BlightFlames.cs | 1 + Projectiles/Ranged/BloodflareSoul.cs | 1 + Projectiles/Ranged/CardClubSplit.cs | 1 + Projectiles/Ranged/ClamorRifleProj.cs | 1 + Projectiles/Ranged/ClamorRifleProjSplit.cs | 1 + Projectiles/Ranged/CondemnationArrowHoming.cs | 1 + Projectiles/Ranged/CosmicFire.cs | 2 ++ Projectiles/Ranged/DryadsTearSplit.cs | 1 + Projectiles/Ranged/ElementalFlare.cs | 1 + Projectiles/Ranged/ElysianArrowRain.cs | 1 + Projectiles/Ranged/ExoCrystalArrow.cs | 1 + Projectiles/Ranged/ExoFlareCluster.cs | 2 ++ Projectiles/Ranged/FishronRPG.cs | 1 + Projectiles/Ranged/FlareBat.cs | 1 + Projectiles/Ranged/FungiOrb2.cs | 1 + Projectiles/Ranged/MagnomalyRocket.cs | 1 + Projectiles/Ranged/MechanicalBarracuda.cs | 1 + Projectiles/Ranged/MeowCreature.cs | 1 + Projectiles/Ranged/MiniatureFolly.cs | 1 + Projectiles/Ranged/PlagueTaintedDrone.cs | 1 + Projectiles/Ranged/PlanetaryAnnihilationProj.cs | 1 + Projectiles/Ranged/PrecisionBolt.cs | 1 + Projectiles/Ranged/PrismComet.cs | 1 + Projectiles/Ranged/RainbowBlast.cs | 1 + Projectiles/Ranged/RicoshotCoin.cs | 1 + Projectiles/Ranged/ScorchedEarthRocket.cs | 1 + Projectiles/Ranged/ScorpioLargeRocket.cs | 1 + Projectiles/Ranged/ScorpioRocket.cs | 1 + Projectiles/Ranged/SeaDragonRocket.cs | 1 + Projectiles/Ranged/Shroom.cs | 1 + Projectiles/Ranged/SicknessRound2.cs | 1 + Projectiles/Ranged/SputterCometBig.cs | 1 + Projectiles/Ranged/StarmageddonBinaryStarCenter.cs | 1 + Projectiles/Ranged/StarmageddonStar.cs | 1 + Projectiles/Ranged/StarmageddonStar2.cs | 1 + Projectiles/Ranged/SulphuricBlast.cs | 1 + Projectiles/Ranged/ThePackMinissile.cs | 1 + Projectiles/Ranged/ThePackMissile.cs | 1 + Projectiles/Ranged/UltimaSpark.cs | 2 ++ Projectiles/Ranged/VanquisherArrowProj.cs | 1 + Projectiles/Ranged/WildfireBloomFlare.cs | 1 + Projectiles/Rogue/AuroradicalStar.cs | 1 + Projectiles/Rogue/BlunderBoosterLightning.cs | 1 + Projectiles/Rogue/CelestialReaperAfterimage.cs | 2 ++ Projectiles/Rogue/CelestialReaperProjectile.cs | 2 ++ Projectiles/Rogue/CobaltEnergy.cs | 1 + Projectiles/Rogue/CorpusAvertorClone.cs | 1 + Projectiles/Rogue/CosmicScythe.cs | 1 + Projectiles/Rogue/Crushax.cs | 1 + Projectiles/Rogue/DesecratedBubble.cs | 1 + Projectiles/Rogue/DestructionBolt.cs | 1 + Projectiles/Rogue/EclipsesSmol.cs | 2 ++ Projectiles/Rogue/EnchantedAxe2.cs | 2 ++ Projectiles/Rogue/EquanimityDarkShard.cs | 1 + Projectiles/Rogue/ExecutionersBladeProj.cs | 1 + Projectiles/Rogue/FinalDawnFireball.cs | 2 ++ Projectiles/Rogue/GacruxianHome.cs | 1 + Projectiles/Rogue/GodsParanoiaProj.cs | 1 + Projectiles/Rogue/GraveGrimreaverProjectile.cs | 1 + Projectiles/Rogue/GrimreaverSkull.cs | 1 + Projectiles/Rogue/HeavenfallenEnergy.cs | 2 ++ Projectiles/Rogue/IceStarProjectile.cs | 1 + Projectiles/Rogue/LostSoulFriendly.cs | 1 + Projectiles/Rogue/LunarKunaiProj.cs | 1 + Projectiles/Rogue/MalachiteStealth.cs | 1 + Projectiles/Rogue/MeteorFistStealth.cs | 1 + Projectiles/Rogue/MoonSigil.cs | 1 + Projectiles/Rogue/NanoblackSplit.cs | 1 + Projectiles/Rogue/NanoblackStealthSplit.cs | 1 + Projectiles/Rogue/NychthemeronOrb.cs | 2 ++ Projectiles/Rogue/PenumbraSoul.cs | 1 + Projectiles/Rogue/PhantasmalSoul.cs | 1 + Projectiles/Rogue/PhantasmalSoulBlue.cs | 1 + Projectiles/Rogue/PlaguenadeBee.cs | 1 + Projectiles/Rogue/PrismRocket.cs | 1 + Projectiles/Rogue/PrismShurikenBlade.cs | 1 + Projectiles/Rogue/Prismalline3.cs | 1 + Projectiles/Rogue/ProfanedPartisanSpear.cs | 2 ++ Projectiles/Rogue/RadiantStar2.cs | 1 + Projectiles/Rogue/RealityRuptureMini.cs | 1 + Projectiles/Rogue/RegulusEnergy.cs | 2 ++ Projectiles/Rogue/RegulusRiotProj.cs | 1 + Projectiles/Rogue/ScarletDevilBullet.cs | 2 ++ Projectiles/Rogue/ScourgeoftheDesertProj.cs | 7 +------ Projectiles/Rogue/SeraphimDagger.cs | 1 + Projectiles/Rogue/ShatteredSunScorchedBlade.cs | 1 + Projectiles/Rogue/SkyfinNuke.cs | 1 + Projectiles/Rogue/SpearofDestinyProjectile.cs | 1 + Projectiles/Rogue/SphereBlue.cs | 1 + Projectiles/Rogue/StellarKnifeProj.cs | 1 + Projectiles/Rogue/SupernovaBomb.cs | 1 + Projectiles/Rogue/TheSyringeS1.cs | 1 + Projectiles/Rogue/TimeBoltKnife.cs | 1 + Projectiles/Rogue/TitaniumClone.cs | 1 + Projectiles/Rogue/ToxicantTwisterDust.cs | 1 + Projectiles/Rogue/TurbulanceWindSlash.cs | 1 + Projectiles/Rogue/Valaricicle.cs | 1 + Projectiles/Rogue/Valaricicle2.cs | 1 + Projectiles/Rogue/ValedictionBoomerang.cs | 1 + Projectiles/Rogue/VeneratedKnife.cs | 1 + Projectiles/Rogue/WrathwingSpear.cs | 1 + Projectiles/Summon/AngelBolt.cs | 1 + Projectiles/Summon/AngelRay.cs | 1 + Projectiles/Summon/AureusBomber.cs | 1 + Projectiles/Summon/BelladonnaPetal.cs | 1 + Projectiles/Summon/CalamarisLamentProjectile.cs | 1 + Projectiles/Summon/CosmicBlast.cs | 1 + Projectiles/Summon/CosmicBlastBig.cs | 1 + Projectiles/Summon/CosmicViperHomingRocket.cs | 1 + Projectiles/Summon/CosmicViperSplittingRocket.cs | 1 + Projectiles/Summon/CosmilampBeam.cs | 1 + Projectiles/Summon/DeathstareBeam.cs | 1 + Projectiles/Summon/Dreadmine.cs | 1 + Projectiles/Summon/EndoIceShard.cs | 1 + Projectiles/Summon/EnergyOrb.cs | 1 + Projectiles/Summon/FlameBlast.cs | 1 + Projectiles/Summon/FlameBurst.cs | 1 + Projectiles/Summon/FleshBlood.cs | 1 + Projectiles/Summon/ForbiddenCircletEater.cs | 2 ++ Projectiles/Summon/FrostBeam.cs | 1 + Projectiles/Summon/GammaCanister.cs | 1 + Projectiles/Summon/GhostFire.cs | 1 + Projectiles/Summon/GlacialEmbracePointyThing.cs | 1 + Projectiles/Summon/Hiveling.cs | 1 + Projectiles/Summon/HomingGammaBullet.cs | 1 + Projectiles/Summon/HowlsHeartFireball.cs | 1 + Projectiles/Summon/LanternFlame.cs | 1 + Projectiles/Summon/LiliesOfFinalityBolt.cs | 1 + Projectiles/Summon/LostSoulGiant.cs | 1 + Projectiles/Summon/LostSoulGold.cs | 1 + Projectiles/Summon/LostSoulLarge.cs | 1 + Projectiles/Summon/LostSoulSmall.cs | 1 + Projectiles/Summon/MK2RocketHoming.cs | 1 + Projectiles/Summon/MortalityBeam.cs | 1 + Projectiles/Summon/MutatedTruffleToothballSpike.cs | 6 +++++- Projectiles/Summon/OldDukeSharkVomit.cs | 1 + Projectiles/Summon/PhantomicDagger.cs | 1 + Projectiles/Summon/PlagueBeeSmall.cs | 1 + Projectiles/Summon/PlantationStaffTentacle.cs | 1 + Projectiles/Summon/PlantationStaffThornball.cs | 1 + Projectiles/Summon/ProfanedSoulCrystalProjectiles.cs | 4 ++++ Projectiles/Summon/SakuraBullet.cs | 1 + Projectiles/Summon/SarosMicrosun.cs | 1 + Projectiles/Summon/SarosSunfire.cs | 1 + Projectiles/Summon/SiriusBeam.cs | 1 + Projectiles/Summon/SlimePuppet.cs | 1 + Projectiles/Summon/SmallAresArms/MinionGaussNuke.cs | 6 +++++- Projectiles/Summon/SmallAresArms/MinionPlasmaBlast.cs | 1 + Projectiles/Summon/SolarBeam.cs | 1 + Projectiles/Summon/TundraFlameBlossomsOrb.cs | 1 + Projectiles/Summon/Umbrella/MagicBird.cs | 1 + Projectiles/Summon/VileFeederProjectile.cs | 1 + Projectiles/Summon/VoidConcentrationOrb.cs | 1 + Projectiles/Summon/WitherBolt.cs | 1 + Projectiles/Summon/WulfrumFusionBolt.cs | 2 +- Projectiles/Summon/YharonMinionFireball.cs | 1 + Projectiles/Typeless/BasicPlagueBee.cs | 1 + Projectiles/Typeless/CursorProj.cs | 1 + Projectiles/Typeless/CursorProjSplit.cs | 1 + Projectiles/Typeless/EmpyreanGlob.cs | 1 + Projectiles/Typeless/EmpyreanMarble.cs | 1 + Projectiles/Typeless/EmpyreanStellarDetritus.cs | 1 + Projectiles/Typeless/GemTechArmorGem.cs | 1 + Projectiles/Typeless/GodKiller.cs | 1 + Projectiles/Typeless/HydrothermicFlare.cs | 1 + Projectiles/Typeless/HydrothermicFlareRogue.cs | 1 + Projectiles/Typeless/HydrothermicSphere.cs | 1 + Projectiles/Typeless/KelvinCatalystStar.cs | 1 + Projectiles/Typeless/LunicBeam.cs | 1 + Projectiles/Typeless/MagnusBeam.cs | 1 + Projectiles/Typeless/MythrilFlare.cs | 1 + Projectiles/Typeless/Nanotech.cs | 1 + Projectiles/Typeless/NebulaStar.cs | 2 ++ Projectiles/Typeless/PendantProjectile3.cs | 1 + Projectiles/Typeless/StickyFeatherAero.cs | 1 + Projectiles/Typeless/SuicideBomberDemon.cs | 1 + Projectiles/Typeless/TarraEnergy.cs | 1 + 304 files changed, 336 insertions(+), 21 deletions(-) diff --git a/Projectiles/DraedonsArsenal/FrequencyManipulatorEnergy.cs b/Projectiles/DraedonsArsenal/FrequencyManipulatorEnergy.cs index c140f94636..1db526bbda 100644 --- a/Projectiles/DraedonsArsenal/FrequencyManipulatorEnergy.cs +++ b/Projectiles/DraedonsArsenal/FrequencyManipulatorEnergy.cs @@ -21,6 +21,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailingMode[Projectile.type] = 2; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 12; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/DraedonsArsenal/PhaseslayerBeam.cs b/Projectiles/DraedonsArsenal/PhaseslayerBeam.cs index 0246fc0784..c1b1ee841c 100644 --- a/Projectiles/DraedonsArsenal/PhaseslayerBeam.cs +++ b/Projectiles/DraedonsArsenal/PhaseslayerBeam.cs @@ -13,6 +13,7 @@ public class PhaseslayerBeam : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 5; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/DraedonsArsenal/PulsePistolShot.cs b/Projectiles/DraedonsArsenal/PulsePistolShot.cs index 86a4fa01e8..6f5450ad20 100644 --- a/Projectiles/DraedonsArsenal/PulsePistolShot.cs +++ b/Projectiles/DraedonsArsenal/PulsePistolShot.cs @@ -27,6 +27,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailingMode[Projectile.type] = 2; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 12; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/DraedonsArsenal/PulseRifleShot.cs b/Projectiles/DraedonsArsenal/PulseRifleShot.cs index 1f7f997a7a..5c2ca38a51 100644 --- a/Projectiles/DraedonsArsenal/PulseRifleShot.cs +++ b/Projectiles/DraedonsArsenal/PulseRifleShot.cs @@ -27,6 +27,7 @@ public class PulseRifleShot : ModProjectile, ILocalizedModType private NPC lastTarget = null; private float distance; private int timesItCanHit = 3; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 16; diff --git a/Projectiles/DraedonsArsenal/PulseTurretShot.cs b/Projectiles/DraedonsArsenal/PulseTurretShot.cs index 399d27b79d..ccd8d1458c 100644 --- a/Projectiles/DraedonsArsenal/PulseTurretShot.cs +++ b/Projectiles/DraedonsArsenal/PulseTurretShot.cs @@ -16,6 +16,7 @@ public class PulseTurretShot : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { ProjectileID.Sets.SentryShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/DraedonsArsenal/SnakeEyesProjectile.cs b/Projectiles/DraedonsArsenal/SnakeEyesProjectile.cs index affaef2451..a74104ec52 100644 --- a/Projectiles/DraedonsArsenal/SnakeEyesProjectile.cs +++ b/Projectiles/DraedonsArsenal/SnakeEyesProjectile.cs @@ -36,6 +36,7 @@ public override void SetStaticDefaults() // While this projectile doesn't have afterimages, it keeps track of old positions for its primitive drawcode. ProjectileID.Sets.TrailingMode[Type] = 2; ProjectileID.Sets.TrailCacheLength[Type] = 6; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/DraedonsArsenal/SystemBaneLightning.cs b/Projectiles/DraedonsArsenal/SystemBaneLightning.cs index 3abc224117..1f166e5b1b 100644 --- a/Projectiles/DraedonsArsenal/SystemBaneLightning.cs +++ b/Projectiles/DraedonsArsenal/SystemBaneLightning.cs @@ -28,6 +28,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailingMode[Projectile.type] = 0; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 60; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() { diff --git a/Projectiles/DraedonsArsenal/TeslaCannonShot.cs b/Projectiles/DraedonsArsenal/TeslaCannonShot.cs index d0a4e1bc1f..4192ec59b2 100644 --- a/Projectiles/DraedonsArsenal/TeslaCannonShot.cs +++ b/Projectiles/DraedonsArsenal/TeslaCannonShot.cs @@ -16,6 +16,7 @@ public class TeslaCannonShot : ModProjectile, ILocalizedModType private int arcs = 0; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 8; diff --git a/Projectiles/DraedonsArsenal/TrackingDiskLaser.cs b/Projectiles/DraedonsArsenal/TrackingDiskLaser.cs index 6ce29dbe3a..69da787310 100644 --- a/Projectiles/DraedonsArsenal/TrackingDiskLaser.cs +++ b/Projectiles/DraedonsArsenal/TrackingDiskLaser.cs @@ -14,6 +14,7 @@ public float Time get => Projectile.localAI[0]; set => Projectile.localAI[0] = value; } + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 2; diff --git a/Projectiles/Magic/ApotheosisEnergy.cs b/Projectiles/Magic/ApotheosisEnergy.cs index 9c286d69a2..8abe5771fa 100644 --- a/Projectiles/Magic/ApotheosisEnergy.cs +++ b/Projectiles/Magic/ApotheosisEnergy.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 20; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/ApotheosisWorm.cs b/Projectiles/Magic/ApotheosisWorm.cs index beb25bb0cd..defa42c58f 100644 --- a/Projectiles/Magic/ApotheosisWorm.cs +++ b/Projectiles/Magic/ApotheosisWorm.cs @@ -55,6 +55,7 @@ internal Segment(byte alpha, float rotation, Vector2 center) public override void SetStaticDefaults() { ProjectileID.Sets.DrawScreenCheckFluff[Projectile.type] = 10000; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/AstralStarMagic.cs b/Projectiles/Magic/AstralStarMagic.cs index 669f7ca602..b7344cfea4 100644 --- a/Projectiles/Magic/AstralStarMagic.cs +++ b/Projectiles/Magic/AstralStarMagic.cs @@ -21,6 +21,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/AstralachneaFang.cs b/Projectiles/Magic/AstralachneaFang.cs index 13bf333d7f..c63b2c094b 100644 --- a/Projectiles/Magic/AstralachneaFang.cs +++ b/Projectiles/Magic/AstralachneaFang.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 5; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/BeamStar.cs b/Projectiles/Magic/BeamStar.cs index 8896ef18c3..4b891445f3 100644 --- a/Projectiles/Magic/BeamStar.cs +++ b/Projectiles/Magic/BeamStar.cs @@ -15,6 +15,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/BeamingBolt2.cs b/Projectiles/Magic/BeamingBolt2.cs index 35f28eca62..013ac5f482 100644 --- a/Projectiles/Magic/BeamingBolt2.cs +++ b/Projectiles/Magic/BeamingBolt2.cs @@ -8,6 +8,7 @@ namespace CalamityMod.Projectiles.Magic public class BeamingBolt2 : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Magic"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 14; diff --git a/Projectiles/Magic/BeastScythe.cs b/Projectiles/Magic/BeastScythe.cs index 58223b592f..8ca5ef4ec2 100644 --- a/Projectiles/Magic/BeastScythe.cs +++ b/Projectiles/Magic/BeastScythe.cs @@ -15,6 +15,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 8; ProjectileID.Sets.TrailingMode[Projectile.type] = 1; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/BlackAnurianPlankton.cs b/Projectiles/Magic/BlackAnurianPlankton.cs index ca29350bbc..02bfa93279 100644 --- a/Projectiles/Magic/BlackAnurianPlankton.cs +++ b/Projectiles/Magic/BlackAnurianPlankton.cs @@ -1,6 +1,7 @@ using System; using Microsoft.Xna.Framework; using Terraria; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Magic { @@ -10,6 +11,7 @@ public class BlackAnurianPlankton : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 5; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/BlueBubble.cs b/Projectiles/Magic/BlueBubble.cs index 6470675324..3a7fa5c8c5 100644 --- a/Projectiles/Magic/BlueBubble.cs +++ b/Projectiles/Magic/BlueBubble.cs @@ -9,6 +9,7 @@ namespace CalamityMod.Projectiles.Magic public class BlueBubble : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Magic"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 10; diff --git a/Projectiles/Magic/ChronoIcicleLarge.cs b/Projectiles/Magic/ChronoIcicleLarge.cs index 79fa04c391..2e8386ceae 100644 --- a/Projectiles/Magic/ChronoIcicleLarge.cs +++ b/Projectiles/Magic/ChronoIcicleLarge.cs @@ -13,6 +13,7 @@ public class ChronoIcicleLarge : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Magic"; public static int HomingSpeed = 16; public static int IdleSpeedMax = 7; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 12; diff --git a/Projectiles/Magic/ClimaxBeam.cs b/Projectiles/Magic/ClimaxBeam.cs index 8cd668dbf0..0acd9b663f 100644 --- a/Projectiles/Magic/ClimaxBeam.cs +++ b/Projectiles/Magic/ClimaxBeam.cs @@ -11,6 +11,7 @@ public class ClimaxBeam : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Magic"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 4; diff --git a/Projectiles/Magic/EternityHoming.cs b/Projectiles/Magic/EternityHoming.cs index ebcf9fca92..1911bad441 100644 --- a/Projectiles/Magic/EternityHoming.cs +++ b/Projectiles/Magic/EternityHoming.cs @@ -2,6 +2,7 @@ using CalamityMod.Items.Weapons.Magic; using Microsoft.Xna.Framework; using Terraria; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Magic @@ -11,6 +12,7 @@ public class EternityHoming : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Magic"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 2; diff --git a/Projectiles/Magic/EventHorizonStar.cs b/Projectiles/Magic/EventHorizonStar.cs index daf819b4d6..5f8090691b 100644 --- a/Projectiles/Magic/EventHorizonStar.cs +++ b/Projectiles/Magic/EventHorizonStar.cs @@ -18,6 +18,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 3; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/ExoVortex.cs b/Projectiles/Magic/ExoVortex.cs index aba7ceed69..52edbe766b 100644 --- a/Projectiles/Magic/ExoVortex.cs +++ b/Projectiles/Magic/ExoVortex.cs @@ -8,7 +8,6 @@ using Terraria.Graphics.Shaders; using Terraria.ID; using Terraria.ModLoader; -using CalamityMod.Graphics.Primitives; namespace CalamityMod.Projectiles.Magic { @@ -28,6 +27,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailingMode[Projectile.type] = 2; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 35; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/ExoVortex2.cs b/Projectiles/Magic/ExoVortex2.cs index 594aac4474..90a5ca1ebf 100644 --- a/Projectiles/Magic/ExoVortex2.cs +++ b/Projectiles/Magic/ExoVortex2.cs @@ -8,7 +8,6 @@ using Terraria.Graphics.Shaders; using Terraria.ID; using Terraria.ModLoader; -using CalamityMod.Graphics.Primitives; namespace CalamityMod.Projectiles.Magic { @@ -28,6 +27,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailingMode[Projectile.type] = 2; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 27; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/FatesRevealFlame.cs b/Projectiles/Magic/FatesRevealFlame.cs index 28d0743a61..38bca14e6e 100644 --- a/Projectiles/Magic/FatesRevealFlame.cs +++ b/Projectiles/Magic/FatesRevealFlame.cs @@ -12,6 +12,7 @@ public class FatesRevealFlame : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 4; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/ForbiddenAxeBlade.cs b/Projectiles/Magic/ForbiddenAxeBlade.cs index d4a3f84892..d010447307 100644 --- a/Projectiles/Magic/ForbiddenAxeBlade.cs +++ b/Projectiles/Magic/ForbiddenAxeBlade.cs @@ -12,6 +12,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/GhastlyBlast.cs b/Projectiles/Magic/GhastlyBlast.cs index 20c61f0dab..d2489e78a9 100644 --- a/Projectiles/Magic/GhastlyBlast.cs +++ b/Projectiles/Magic/GhastlyBlast.cs @@ -18,6 +18,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 8; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/GhastlyExplosionShard.cs b/Projectiles/Magic/GhastlyExplosionShard.cs index e5cffcf043..36b23f3e45 100644 --- a/Projectiles/Magic/GhastlyExplosionShard.cs +++ b/Projectiles/Magic/GhastlyExplosionShard.cs @@ -1,5 +1,6 @@ using Microsoft.Xna.Framework; using Terraria; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Magic { @@ -8,6 +9,7 @@ public class GhastlyExplosionShard : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Magic"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 8; diff --git a/Projectiles/Magic/GleamingBolt2.cs b/Projectiles/Magic/GleamingBolt2.cs index a00c158bd9..c93a1c5a38 100644 --- a/Projectiles/Magic/GleamingBolt2.cs +++ b/Projectiles/Magic/GleamingBolt2.cs @@ -1,12 +1,14 @@ using System; using Microsoft.Xna.Framework; using Terraria; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Magic { public class GleamingBolt2 : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Magic"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 14; diff --git a/Projectiles/Magic/GraniteEnergy.cs b/Projectiles/Magic/GraniteEnergy.cs index 3cdddd4d79..112df41dba 100644 --- a/Projectiles/Magic/GraniteEnergy.cs +++ b/Projectiles/Magic/GraniteEnergy.cs @@ -9,6 +9,7 @@ namespace CalamityMod.Projectiles.Magic public class GraniteEnergy : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Magic"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 12; diff --git a/Projectiles/Magic/HadalUrnJellyfish.cs b/Projectiles/Magic/HadalUrnJellyfish.cs index dc57cb8008..fd7a241f3c 100644 --- a/Projectiles/Magic/HadalUrnJellyfish.cs +++ b/Projectiles/Magic/HadalUrnJellyfish.cs @@ -4,6 +4,7 @@ using Microsoft.Xna.Framework.Graphics; using Terraria; using Terraria.Audio; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Magic @@ -15,6 +16,7 @@ public class HadalUrnJellyfish : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 5; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/HadalUrnStarfishShard.cs b/Projectiles/Magic/HadalUrnStarfishShard.cs index 920f9a1dd1..da3587ed8b 100644 --- a/Projectiles/Magic/HadalUrnStarfishShard.cs +++ b/Projectiles/Magic/HadalUrnStarfishShard.cs @@ -9,6 +9,7 @@ namespace CalamityMod.Projectiles.Magic public class HadalUrnStarfishShard : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Magic"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 10; diff --git a/Projectiles/Magic/IceBlock.cs b/Projectiles/Magic/IceBlock.cs index 228677e7de..f15bdd479c 100644 --- a/Projectiles/Magic/IceBlock.cs +++ b/Projectiles/Magic/IceBlock.cs @@ -9,6 +9,7 @@ namespace CalamityMod.Projectiles.Magic public class IceBlock : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Magic"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 58; diff --git a/Projectiles/Magic/LightBead.cs b/Projectiles/Magic/LightBead.cs index 42c4ece225..0ea569c8a3 100644 --- a/Projectiles/Magic/LightBead.cs +++ b/Projectiles/Magic/LightBead.cs @@ -8,6 +8,7 @@ namespace CalamityMod.Projectiles.Magic public class LightBead : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Magic"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 8; diff --git a/Projectiles/Magic/LightBlade.cs b/Projectiles/Magic/LightBlade.cs index c53a8b7705..ec8eddd28d 100644 --- a/Projectiles/Magic/LightBlade.cs +++ b/Projectiles/Magic/LightBlade.cs @@ -25,6 +25,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = NumAfterimages; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/LightningArc.cs b/Projectiles/Magic/LightningArc.cs index 667902b6c8..cb0eefdb64 100644 --- a/Projectiles/Magic/LightningArc.cs +++ b/Projectiles/Magic/LightningArc.cs @@ -12,6 +12,7 @@ public class LightningArc : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Magic"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 8; diff --git a/Projectiles/Magic/MadAlchemistsCocktailShrapnel.cs b/Projectiles/Magic/MadAlchemistsCocktailShrapnel.cs index 36b15d16a3..711386b479 100644 --- a/Projectiles/Magic/MadAlchemistsCocktailShrapnel.cs +++ b/Projectiles/Magic/MadAlchemistsCocktailShrapnel.cs @@ -10,6 +10,7 @@ public class MadAlchemistsCocktailShrapnel : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Magic"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 8; diff --git a/Projectiles/Magic/MagneticBeam.cs b/Projectiles/Magic/MagneticBeam.cs index 0b46e5390d..9662ab8b21 100644 --- a/Projectiles/Magic/MagneticBeam.cs +++ b/Projectiles/Magic/MagneticBeam.cs @@ -11,6 +11,7 @@ public class MagneticBeam : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Magic"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 4; diff --git a/Projectiles/Magic/ManaBoltSmall.cs b/Projectiles/Magic/ManaBoltSmall.cs index 9b8c894790..303d887444 100644 --- a/Projectiles/Magic/ManaBoltSmall.cs +++ b/Projectiles/Magic/ManaBoltSmall.cs @@ -9,6 +9,7 @@ namespace CalamityMod.Projectiles.Magic public class ManaBoltSmall : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Magic"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 10; diff --git a/Projectiles/Magic/NebulaCloudCore.cs b/Projectiles/Magic/NebulaCloudCore.cs index 4543a55adc..5cdb63bbb2 100644 --- a/Projectiles/Magic/NebulaCloudCore.cs +++ b/Projectiles/Magic/NebulaCloudCore.cs @@ -19,6 +19,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/NightBolt.cs b/Projectiles/Magic/NightBolt.cs index 887a8c6869..6825f540e2 100644 --- a/Projectiles/Magic/NightBolt.cs +++ b/Projectiles/Magic/NightBolt.cs @@ -10,6 +10,7 @@ public class NightBolt : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Magic"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 4; diff --git a/Projectiles/Magic/NuclearFuryProjectile.cs b/Projectiles/Magic/NuclearFuryProjectile.cs index 6c38dbd006..03525b1711 100644 --- a/Projectiles/Magic/NuclearFuryProjectile.cs +++ b/Projectiles/Magic/NuclearFuryProjectile.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/PhantasmalFuryProj.cs b/Projectiles/Magic/PhantasmalFuryProj.cs index 806fdadff5..247114c2a1 100644 --- a/Projectiles/Magic/PhantasmalFuryProj.cs +++ b/Projectiles/Magic/PhantasmalFuryProj.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/Phantom.cs b/Projectiles/Magic/Phantom.cs index 16f456274e..e201fce931 100644 --- a/Projectiles/Magic/Phantom.cs +++ b/Projectiles/Magic/Phantom.cs @@ -8,6 +8,7 @@ namespace CalamityMod.Projectiles.Magic public class Phantom : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Magic"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 8; diff --git a/Projectiles/Magic/PhotosyntheticShard.cs b/Projectiles/Magic/PhotosyntheticShard.cs index 750b53b166..e5d82f73e6 100644 --- a/Projectiles/Magic/PhotosyntheticShard.cs +++ b/Projectiles/Magic/PhotosyntheticShard.cs @@ -9,6 +9,7 @@ public class PhotosyntheticShard : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Magic"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = Projectile.height = 20; diff --git a/Projectiles/Magic/PoseidonTyphoon.cs b/Projectiles/Magic/PoseidonTyphoon.cs index b53fafad64..2d992ffb05 100644 --- a/Projectiles/Magic/PoseidonTyphoon.cs +++ b/Projectiles/Magic/PoseidonTyphoon.cs @@ -12,6 +12,7 @@ namespace CalamityMod.Projectiles.Magic public class PoseidonTyphoon : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Magic"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 30; diff --git a/Projectiles/Magic/PrinceFlameSmall.cs b/Projectiles/Magic/PrinceFlameSmall.cs index 1e87c99216..cb0f38999e 100644 --- a/Projectiles/Magic/PrinceFlameSmall.cs +++ b/Projectiles/Magic/PrinceFlameSmall.cs @@ -16,6 +16,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 3; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/RainbowRocket.cs b/Projectiles/Magic/RainbowRocket.cs index e67fd17d8a..f5cb89c5e3 100644 --- a/Projectiles/Magic/RainbowRocket.cs +++ b/Projectiles/Magic/RainbowRocket.cs @@ -40,6 +40,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 3; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 20; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/RedirectingFire.cs b/Projectiles/Magic/RedirectingFire.cs index 8b9b9fb929..65892c59e0 100644 --- a/Projectiles/Magic/RedirectingFire.cs +++ b/Projectiles/Magic/RedirectingFire.cs @@ -14,6 +14,7 @@ public class RedirectingFire : ModProjectile, ILocalizedModType public ref float Time => ref Projectile.ai[1]; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = Projectile.height = 18; diff --git a/Projectiles/Magic/RedirectingGildedSoul.cs b/Projectiles/Magic/RedirectingGildedSoul.cs index c2ce615eb3..aa153cbc43 100644 --- a/Projectiles/Magic/RedirectingGildedSoul.cs +++ b/Projectiles/Magic/RedirectingGildedSoul.cs @@ -18,6 +18,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/RedirectingLostSoul.cs b/Projectiles/Magic/RedirectingLostSoul.cs index 979cc77c90..7919fcbb56 100644 --- a/Projectiles/Magic/RedirectingLostSoul.cs +++ b/Projectiles/Magic/RedirectingLostSoul.cs @@ -18,6 +18,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/RedirectingVengefulSoul.cs b/Projectiles/Magic/RedirectingVengefulSoul.cs index 88f6a69fbb..88871efbad 100644 --- a/Projectiles/Magic/RedirectingVengefulSoul.cs +++ b/Projectiles/Magic/RedirectingVengefulSoul.cs @@ -18,6 +18,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/ShadecrystalProjectile.cs b/Projectiles/Magic/ShadecrystalProjectile.cs index 2284b4a2da..1d9d46e80a 100644 --- a/Projectiles/Magic/ShadecrystalProjectile.cs +++ b/Projectiles/Magic/ShadecrystalProjectile.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 5; ProjectileID.Sets.TrailingMode[Projectile.type] = 1; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/Shadowbolt.cs b/Projectiles/Magic/Shadowbolt.cs index 333ed9a895..14a428c33f 100644 --- a/Projectiles/Magic/Shadowbolt.cs +++ b/Projectiles/Magic/Shadowbolt.cs @@ -10,6 +10,7 @@ public class Shadowbolt : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Magic"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 4; diff --git a/Projectiles/Magic/Snowflake.cs b/Projectiles/Magic/Snowflake.cs index 85f625591f..6e2b7cf521 100644 --- a/Projectiles/Magic/Snowflake.cs +++ b/Projectiles/Magic/Snowflake.cs @@ -15,6 +15,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/SnowflakeIceStar.cs b/Projectiles/Magic/SnowflakeIceStar.cs index 8c7f685a45..2ebc2f871b 100644 --- a/Projectiles/Magic/SnowflakeIceStar.cs +++ b/Projectiles/Magic/SnowflakeIceStar.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/SpiritCongregation.cs b/Projectiles/Magic/SpiritCongregation.cs index 71f1e234be..39b5fb76b8 100644 --- a/Projectiles/Magic/SpiritCongregation.cs +++ b/Projectiles/Magic/SpiritCongregation.cs @@ -47,6 +47,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailingMode[Projectile.type] = 2; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 8; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/TearsofHeavenProjectile.cs b/Projectiles/Magic/TearsofHeavenProjectile.cs index 55f39a937c..9bbc9a986b 100644 --- a/Projectiles/Magic/TearsofHeavenProjectile.cs +++ b/Projectiles/Magic/TearsofHeavenProjectile.cs @@ -13,6 +13,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/UndinesRetributionSpear.cs b/Projectiles/Magic/UndinesRetributionSpear.cs index 26aa156310..b55d34bf73 100644 --- a/Projectiles/Magic/UndinesRetributionSpear.cs +++ b/Projectiles/Magic/UndinesRetributionSpear.cs @@ -16,6 +16,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Magic/VividBolt.cs b/Projectiles/Magic/VividBolt.cs index 0d9ec716f5..7ed8a2f07d 100644 --- a/Projectiles/Magic/VividBolt.cs +++ b/Projectiles/Magic/VividBolt.cs @@ -11,6 +11,7 @@ public class VividBolt : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Magic"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 4; diff --git a/Projectiles/Magic/VividLaser2.cs b/Projectiles/Magic/VividLaser2.cs index 8b7fbb544b..72b1a5329b 100644 --- a/Projectiles/Magic/VividLaser2.cs +++ b/Projectiles/Magic/VividLaser2.cs @@ -11,6 +11,7 @@ public class VividLaser2 : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Magic"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 10; diff --git a/Projectiles/Magic/WulfrumBolt.cs b/Projectiles/Magic/WulfrumBolt.cs index 3565948b51..544fe8b627 100644 --- a/Projectiles/Magic/WulfrumBolt.cs +++ b/Projectiles/Magic/WulfrumBolt.cs @@ -48,6 +48,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.TrailCacheLength[Projectile.type] = 20; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/AbyssBladeSplitProjectile.cs b/Projectiles/Melee/AbyssBladeSplitProjectile.cs index bd533f5fbe..784ee240dc 100644 --- a/Projectiles/Melee/AbyssBladeSplitProjectile.cs +++ b/Projectiles/Melee/AbyssBladeSplitProjectile.cs @@ -20,6 +20,7 @@ public class AbyssBladeSplitProjectile : ModProjectile, ILocalizedModType public int randTimer; public int dustType1 = 104; public int dustType2 = 29; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 10; diff --git a/Projectiles/Melee/AmidiasWhirlpool.cs b/Projectiles/Melee/AmidiasWhirlpool.cs index bcaf24ed46..dc4167d4af 100644 --- a/Projectiles/Melee/AmidiasWhirlpool.cs +++ b/Projectiles/Melee/AmidiasWhirlpool.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 5; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/AncientStar.cs b/Projectiles/Melee/AncientStar.cs index 8da00d49e2..c3061c0a37 100644 --- a/Projectiles/Melee/AncientStar.cs +++ b/Projectiles/Melee/AncientStar.cs @@ -21,6 +21,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/BalefulHarvesterProjectile.cs b/Projectiles/Melee/BalefulHarvesterProjectile.cs index 8855fed60a..8fd5ea1af9 100644 --- a/Projectiles/Melee/BalefulHarvesterProjectile.cs +++ b/Projectiles/Melee/BalefulHarvesterProjectile.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 5; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; Main.projFrames[Projectile.type] = 5; } diff --git a/Projectiles/Melee/BlazingPhantomBlade.cs b/Projectiles/Melee/BlazingPhantomBlade.cs index 98223ec271..4030f75473 100644 --- a/Projectiles/Melee/BlazingPhantomBlade.cs +++ b/Projectiles/Melee/BlazingPhantomBlade.cs @@ -28,6 +28,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.TrailCacheLength[Projectile.type] = 20; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; ProjectileID.Sets.NoMeleeSpeedVelocityScaling[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; Main.projFrames[Projectile.type] = 4; } diff --git a/Projectiles/Melee/Blood.cs b/Projectiles/Melee/Blood.cs index c0791c05b1..a7ed0f3eaa 100644 --- a/Projectiles/Melee/Blood.cs +++ b/Projectiles/Melee/Blood.cs @@ -12,6 +12,7 @@ public class Blood : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Melee"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 4; diff --git a/Projectiles/Melee/Blood2.cs b/Projectiles/Melee/Blood2.cs index ee996f3ebe..d7a37f148f 100644 --- a/Projectiles/Melee/Blood2.cs +++ b/Projectiles/Melee/Blood2.cs @@ -11,6 +11,7 @@ public class Blood2 : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Melee"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 4; diff --git a/Projectiles/Melee/BloodScythe.cs b/Projectiles/Melee/BloodScythe.cs index 4d993b0a31..f85b09d92f 100644 --- a/Projectiles/Melee/BloodScythe.cs +++ b/Projectiles/Melee/BloodScythe.cs @@ -10,6 +10,7 @@ namespace CalamityMod.Projectiles.Melee public class BloodScythe : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Melee"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 28; diff --git a/Projectiles/Melee/Brimlash2.cs b/Projectiles/Melee/Brimlash2.cs index aab7079a2a..483adf0533 100644 --- a/Projectiles/Melee/Brimlash2.cs +++ b/Projectiles/Melee/Brimlash2.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 2; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/CosmicBolt.cs b/Projectiles/Melee/CosmicBolt.cs index 7aadbb2336..d0f6300fad 100644 --- a/Projectiles/Melee/CosmicBolt.cs +++ b/Projectiles/Melee/CosmicBolt.cs @@ -10,6 +10,7 @@ public class CosmicBolt : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Melee"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 8; diff --git a/Projectiles/Melee/CosmicShivBlade.cs b/Projectiles/Melee/CosmicShivBlade.cs index 5ae1c83de6..9553f7f309 100644 --- a/Projectiles/Melee/CosmicShivBlade.cs +++ b/Projectiles/Melee/CosmicShivBlade.cs @@ -19,6 +19,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 15; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/CosmicShivTrail.cs b/Projectiles/Melee/CosmicShivTrail.cs index df703c0e46..59dc4cc353 100644 --- a/Projectiles/Melee/CosmicShivTrail.cs +++ b/Projectiles/Melee/CosmicShivTrail.cs @@ -4,17 +4,8 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Terraria; -using Terraria.GameContent; using Terraria.ID; using Terraria.ModLoader; -using CalamityMod.Buffs.DamageOverTime; -using System.Collections.Generic; -using System.Security.Cryptography.X509Certificates; -using System.Reflection.Metadata; -using Microsoft.Xna.Framework.Graphics; -using System.Diagnostics.Contracts; -using Terraria.GameContent; -using Terraria.Audio; namespace CalamityMod.Projectiles.Melee { @@ -40,6 +31,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Type] = 15; ProjectileID.Sets.TrailingMode[Type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/CrescentMoonProj.cs b/Projectiles/Melee/CrescentMoonProj.cs index 907fa657ae..691af6c829 100644 --- a/Projectiles/Melee/CrescentMoonProj.cs +++ b/Projectiles/Melee/CrescentMoonProj.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/DeathsAscensionProjectile.cs b/Projectiles/Melee/DeathsAscensionProjectile.cs index ab1f7ba83d..4dc2af7e3c 100644 --- a/Projectiles/Melee/DeathsAscensionProjectile.cs +++ b/Projectiles/Melee/DeathsAscensionProjectile.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 1; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/DepthCrusherSplitProjectile.cs b/Projectiles/Melee/DepthCrusherSplitProjectile.cs index 4da528c2f8..5e8f73b38d 100644 --- a/Projectiles/Melee/DepthCrusherSplitProjectile.cs +++ b/Projectiles/Melee/DepthCrusherSplitProjectile.cs @@ -20,6 +20,7 @@ public class DepthCrusherSplitProjectile : ModProjectile, ILocalizedModType public int randTimer; public int dustType1 = 104; public int dustType2 = 96; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 10; diff --git a/Projectiles/Melee/DivineHatchetBoomerang.cs b/Projectiles/Melee/DivineHatchetBoomerang.cs index 7399a76afb..13449d79ea 100644 --- a/Projectiles/Melee/DivineHatchetBoomerang.cs +++ b/Projectiles/Melee/DivineHatchetBoomerang.cs @@ -24,6 +24,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 8; ProjectileID.Sets.TrailingMode[Projectile.type] = 1; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/DraconicSpark.cs b/Projectiles/Melee/DraconicSpark.cs index 2bd1719ad8..6d469b3d49 100644 --- a/Projectiles/Melee/DraconicSpark.cs +++ b/Projectiles/Melee/DraconicSpark.cs @@ -15,6 +15,7 @@ public class DraconicSpark : ModProjectile, ILocalizedModType public static float MaxHomingRange = 600f; public static float HomingVelocity = 20f; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 6; diff --git a/Projectiles/Melee/DragonRageFireball.cs b/Projectiles/Melee/DragonRageFireball.cs index 643bddf962..51789ebee6 100644 --- a/Projectiles/Melee/DragonRageFireball.cs +++ b/Projectiles/Melee/DragonRageFireball.cs @@ -17,6 +17,7 @@ public class DragonRageFireball : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 5; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/ElementBallShiv.cs b/Projectiles/Melee/ElementBallShiv.cs index 0a114c1225..fda871ca77 100644 --- a/Projectiles/Melee/ElementBallShiv.cs +++ b/Projectiles/Melee/ElementBallShiv.cs @@ -9,6 +9,7 @@ namespace CalamityMod.Projectiles.Melee public class ElementBallShiv : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Melee"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 20; diff --git a/Projectiles/Melee/ElementalGlassStar.cs b/Projectiles/Melee/ElementalGlassStar.cs index 27445e7ef2..fb3d715bb0 100644 --- a/Projectiles/Melee/ElementalGlassStar.cs +++ b/Projectiles/Melee/ElementalGlassStar.cs @@ -20,6 +20,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/EmpyreanKnife.cs b/Projectiles/Melee/EmpyreanKnife.cs index f34ef00167..02b892506b 100644 --- a/Projectiles/Melee/EmpyreanKnife.cs +++ b/Projectiles/Melee/EmpyreanKnife.cs @@ -16,6 +16,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 1; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/EntropicFlechette.cs b/Projectiles/Melee/EntropicFlechette.cs index d71aa2f35e..b03dda566a 100644 --- a/Projectiles/Melee/EntropicFlechette.cs +++ b/Projectiles/Melee/EntropicFlechette.cs @@ -12,6 +12,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 1; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/EntropicFlechetteLarge.cs b/Projectiles/Melee/EntropicFlechetteLarge.cs index b54b35ec53..37df04ec4a 100644 --- a/Projectiles/Melee/EntropicFlechetteLarge.cs +++ b/Projectiles/Melee/EntropicFlechetteLarge.cs @@ -12,6 +12,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 1; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/EntropicFlechetteSmall.cs b/Projectiles/Melee/EntropicFlechetteSmall.cs index 1db25a8648..ca44253212 100644 --- a/Projectiles/Melee/EntropicFlechetteSmall.cs +++ b/Projectiles/Melee/EntropicFlechetteSmall.cs @@ -12,6 +12,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 1; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/EonBolt.cs b/Projectiles/Melee/EonBolt.cs index ff20bd185c..b5eec39352 100644 --- a/Projectiles/Melee/EonBolt.cs +++ b/Projectiles/Melee/EonBolt.cs @@ -8,7 +8,6 @@ using Terraria.ID; using Terraria.ModLoader; using static Terraria.ModLoader.ModContent; -using CalamityMod.Graphics.Primitives; namespace CalamityMod.Projectiles.Melee { @@ -30,6 +29,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 20; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/EssenceFlame2.cs b/Projectiles/Melee/EssenceFlame2.cs index 1b4a23fa60..92b88b7c62 100644 --- a/Projectiles/Melee/EssenceFlame2.cs +++ b/Projectiles/Melee/EssenceFlame2.cs @@ -13,6 +13,7 @@ public class EssenceFlame2 : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 4; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/EssenceScythe.cs b/Projectiles/Melee/EssenceScythe.cs index 2fedb0d73e..d86f111467 100644 --- a/Projectiles/Melee/EssenceScythe.cs +++ b/Projectiles/Melee/EssenceScythe.cs @@ -15,6 +15,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 1; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/Exobeam.cs b/Projectiles/Melee/Exobeam.cs index 96b0c2a0b9..b4c1015c7f 100644 --- a/Projectiles/Melee/Exobeam.cs +++ b/Projectiles/Melee/Exobeam.cs @@ -31,6 +31,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 30; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/FallenPaladinsHammerEcho.cs b/Projectiles/Melee/FallenPaladinsHammerEcho.cs index 9105b741dd..2ea7d0c5fb 100644 --- a/Projectiles/Melee/FallenPaladinsHammerEcho.cs +++ b/Projectiles/Melee/FallenPaladinsHammerEcho.cs @@ -19,6 +19,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 15; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() { diff --git a/Projectiles/Melee/Flarefrost.cs b/Projectiles/Melee/Flarefrost.cs index 29509bde38..b29d9dba38 100644 --- a/Projectiles/Melee/Flarefrost.cs +++ b/Projectiles/Melee/Flarefrost.cs @@ -11,6 +11,7 @@ public class Flarefrost : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Melee"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 10; diff --git a/Projectiles/Melee/GaelSkull.cs b/Projectiles/Melee/GaelSkull.cs index cc8938bb6d..625167c529 100644 --- a/Projectiles/Melee/GaelSkull.cs +++ b/Projectiles/Melee/GaelSkull.cs @@ -15,6 +15,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; Main.projFrames[Projectile.type] = 5; } diff --git a/Projectiles/Melee/GaelSkull2.cs b/Projectiles/Melee/GaelSkull2.cs index 5e09a998e6..2c04fe6280 100644 --- a/Projectiles/Melee/GaelSkull2.cs +++ b/Projectiles/Melee/GaelSkull2.cs @@ -15,6 +15,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; Main.projFrames[Projectile.type] = 5; } diff --git a/Projectiles/Melee/GalaxiaBolt.cs b/Projectiles/Melee/GalaxiaBolt.cs index 1e9c160c2b..54924f6ad1 100644 --- a/Projectiles/Melee/GalaxiaBolt.cs +++ b/Projectiles/Melee/GalaxiaBolt.cs @@ -23,6 +23,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 2; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/GalaxySmasherEcho.cs b/Projectiles/Melee/GalaxySmasherEcho.cs index 2e13294fb6..1d456e4703 100644 --- a/Projectiles/Melee/GalaxySmasherEcho.cs +++ b/Projectiles/Melee/GalaxySmasherEcho.cs @@ -23,6 +23,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 15; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } //This is all copied straight from PwnagehammerEcho with some minor edits. public override void SetDefaults() diff --git a/Projectiles/Melee/GalileosMoon.cs b/Projectiles/Melee/GalileosMoon.cs index f330f94964..2ef7be5b83 100644 --- a/Projectiles/Melee/GalileosMoon.cs +++ b/Projectiles/Melee/GalileosMoon.cs @@ -16,6 +16,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/GhastlySoulLarge.cs b/Projectiles/Melee/GhastlySoulLarge.cs index 0a148d3a19..478dc2ce07 100644 --- a/Projectiles/Melee/GhastlySoulLarge.cs +++ b/Projectiles/Melee/GhastlySoulLarge.cs @@ -23,6 +23,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 5; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/GhastlySoulMedium.cs b/Projectiles/Melee/GhastlySoulMedium.cs index 41e5e9bb77..63ca2b7bc7 100644 --- a/Projectiles/Melee/GhastlySoulMedium.cs +++ b/Projectiles/Melee/GhastlySoulMedium.cs @@ -23,6 +23,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 5; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/GhastlySoulSmall.cs b/Projectiles/Melee/GhastlySoulSmall.cs index 932c6060de..ce57c77854 100644 --- a/Projectiles/Melee/GhastlySoulSmall.cs +++ b/Projectiles/Melee/GhastlySoulSmall.cs @@ -24,6 +24,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 5; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/HolyColliderHolyFire.cs b/Projectiles/Melee/HolyColliderHolyFire.cs index 381642a43f..e38b466afd 100644 --- a/Projectiles/Melee/HolyColliderHolyFire.cs +++ b/Projectiles/Melee/HolyColliderHolyFire.cs @@ -15,6 +15,7 @@ public class HolyColliderHolyFire : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 4; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/IllustriousKnife.cs b/Projectiles/Melee/IllustriousKnife.cs index 1129424d68..e603f441f7 100644 --- a/Projectiles/Melee/IllustriousKnife.cs +++ b/Projectiles/Melee/IllustriousKnife.cs @@ -16,6 +16,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/JudgementProj.cs b/Projectiles/Melee/JudgementProj.cs index 0137b32032..17d99de157 100644 --- a/Projectiles/Melee/JudgementProj.cs +++ b/Projectiles/Melee/JudgementProj.cs @@ -13,6 +13,7 @@ public class JudgementProj : ModProjectile, ILocalizedModType int whiteLightTimer = 15; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 12; diff --git a/Projectiles/Melee/MourningSkull.cs b/Projectiles/Melee/MourningSkull.cs index b709078298..b5546a580f 100644 --- a/Projectiles/Melee/MourningSkull.cs +++ b/Projectiles/Melee/MourningSkull.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/NeptunesBountySplitProjectile.cs b/Projectiles/Melee/NeptunesBountySplitProjectile.cs index 38ca92cfbe..1481bf6049 100644 --- a/Projectiles/Melee/NeptunesBountySplitProjectile.cs +++ b/Projectiles/Melee/NeptunesBountySplitProjectile.cs @@ -23,6 +23,7 @@ public class NeptunesBountySplitProjectile : ModProjectile, ILocalizedModType public int spreadDust = 0; public Color WaterColor = Main.rand.NextBool() ? Color.DodgerBlue : Color.DeepSkyBlue; public Player Owner => Main.player[Projectile.owner]; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 20; diff --git a/Projectiles/Melee/OathswordFlame.cs b/Projectiles/Melee/OathswordFlame.cs index edbcd60800..20ee12826b 100644 --- a/Projectiles/Melee/OathswordFlame.cs +++ b/Projectiles/Melee/OathswordFlame.cs @@ -9,6 +9,7 @@ namespace CalamityMod.Projectiles.Melee public class OathswordFlame : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Melee"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 20; diff --git a/Projectiles/Melee/OrderbringerBeam.cs b/Projectiles/Melee/OrderbringerBeam.cs index 72feafc6e6..d420b2ce83 100644 --- a/Projectiles/Melee/OrderbringerBeam.cs +++ b/Projectiles/Melee/OrderbringerBeam.cs @@ -16,6 +16,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/OrderbringerRain.cs b/Projectiles/Melee/OrderbringerRain.cs index 690b46cd4b..f2d332bab6 100644 --- a/Projectiles/Melee/OrderbringerRain.cs +++ b/Projectiles/Melee/OrderbringerRain.cs @@ -11,6 +11,7 @@ public class OrderbringerRain : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Melee"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 4; diff --git a/Projectiles/Melee/PlagueSeeker.cs b/Projectiles/Melee/PlagueSeeker.cs index 11487d15cc..62293378b4 100644 --- a/Projectiles/Melee/PlagueSeeker.cs +++ b/Projectiles/Melee/PlagueSeeker.cs @@ -11,6 +11,7 @@ public class PlagueSeeker : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Melee"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 4; diff --git a/Projectiles/Melee/PwnagehammerEcho.cs b/Projectiles/Melee/PwnagehammerEcho.cs index d35c179c89..b9cfdfa946 100644 --- a/Projectiles/Melee/PwnagehammerEcho.cs +++ b/Projectiles/Melee/PwnagehammerEcho.cs @@ -20,6 +20,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 7; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/Razorwind.cs b/Projectiles/Melee/Razorwind.cs index afd0ea82a5..38493a3eec 100644 --- a/Projectiles/Melee/Razorwind.cs +++ b/Projectiles/Melee/Razorwind.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 15; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/SHIV.cs b/Projectiles/Melee/SHIV.cs index 5fc14d89be..01e69bc73c 100644 --- a/Projectiles/Melee/SHIV.cs +++ b/Projectiles/Melee/SHIV.cs @@ -11,6 +11,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 15; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/SandFire.cs b/Projectiles/Melee/SandFire.cs index d55c2732c0..68e1957809 100644 --- a/Projectiles/Melee/SandFire.cs +++ b/Projectiles/Melee/SandFire.cs @@ -11,6 +11,7 @@ public class SandFire : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Melee"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 6; diff --git a/Projectiles/Melee/ScourgeoftheCosmosMini.cs b/Projectiles/Melee/ScourgeoftheCosmosMini.cs index 3660315b2e..6e95d9e0be 100644 --- a/Projectiles/Melee/ScourgeoftheCosmosMini.cs +++ b/Projectiles/Melee/ScourgeoftheCosmosMini.cs @@ -2,6 +2,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Terraria; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Melee @@ -14,6 +15,7 @@ public class ScourgeoftheCosmosMini : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/StellarContemptEcho.cs b/Projectiles/Melee/StellarContemptEcho.cs index 8532df4598..ac5c1f74ed 100644 --- a/Projectiles/Melee/StellarContemptEcho.cs +++ b/Projectiles/Melee/StellarContemptEcho.cs @@ -22,6 +22,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 15; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } // This is all copied straight from PwnagehammerEcho with some minor edits. diff --git a/Projectiles/Melee/StormBeam.cs b/Projectiles/Melee/StormBeam.cs index 5ec35d486f..6226b98ecf 100644 --- a/Projectiles/Melee/StormBeam.cs +++ b/Projectiles/Melee/StormBeam.cs @@ -12,6 +12,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 5; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/TerratomereSwordBeam.cs b/Projectiles/Melee/TerratomereSwordBeam.cs index 1343fe2c9f..80bafb1b3d 100644 --- a/Projectiles/Melee/TerratomereSwordBeam.cs +++ b/Projectiles/Melee/TerratomereSwordBeam.cs @@ -20,6 +20,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailingMode[Type] = 2; ProjectileID.Sets.TrailCacheLength[Type] = Terratomere.SlashLifetime + 1; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/TinyFlare.cs b/Projectiles/Melee/TinyFlare.cs index 325ec784cf..bfc82a166b 100644 --- a/Projectiles/Melee/TinyFlare.cs +++ b/Projectiles/Melee/TinyFlare.cs @@ -8,6 +8,7 @@ namespace CalamityMod.Projectiles.Melee public class TinyFlare : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Melee"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 6; diff --git a/Projectiles/Melee/TriactisHammerProj.cs b/Projectiles/Melee/TriactisHammerProj.cs index 37c79c6c07..3937bc6200 100644 --- a/Projectiles/Melee/TriactisHammerProj.cs +++ b/Projectiles/Melee/TriactisHammerProj.cs @@ -15,6 +15,7 @@ public class TriactisHammerProj : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { + ProjectileID.Sets.CultistIsResistantTo[Type] = true; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; } diff --git a/Projectiles/Melee/TyphonsGreedBubble.cs b/Projectiles/Melee/TyphonsGreedBubble.cs index 06fc319d0c..057ab4b520 100644 --- a/Projectiles/Melee/TyphonsGreedBubble.cs +++ b/Projectiles/Melee/TyphonsGreedBubble.cs @@ -14,6 +14,7 @@ public class TyphonsGreedBubble : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 4; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/UltimusCleaverDust.cs b/Projectiles/Melee/UltimusCleaverDust.cs index 7d99b67136..72e9ceb558 100644 --- a/Projectiles/Melee/UltimusCleaverDust.cs +++ b/Projectiles/Melee/UltimusCleaverDust.cs @@ -9,6 +9,7 @@ public class UltimusCleaverDust : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Melee"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 6; diff --git a/Projectiles/Melee/VoidEssence.cs b/Projectiles/Melee/VoidEssence.cs index 692aea191f..9cfcdb0980 100644 --- a/Projectiles/Melee/VoidEssence.cs +++ b/Projectiles/Melee/VoidEssence.cs @@ -20,6 +20,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = NumAnimationFrames; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Melee/Whiterain.cs b/Projectiles/Melee/Whiterain.cs index 0bf0617dfa..81c265bc77 100644 --- a/Projectiles/Melee/Whiterain.cs +++ b/Projectiles/Melee/Whiterain.cs @@ -10,6 +10,7 @@ public class Whiterain : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Melee"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 4; diff --git a/Projectiles/Ranged/AquashardSplit.cs b/Projectiles/Ranged/AquashardSplit.cs index 0fc3c0e6eb..a9555374d0 100644 --- a/Projectiles/Ranged/AquashardSplit.cs +++ b/Projectiles/Ranged/AquashardSplit.cs @@ -10,6 +10,7 @@ public class AquashardSplit : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Ranged"; public override string Texture => "CalamityMod/Projectiles/Ranged/Aquashard"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 10; diff --git a/Projectiles/Ranged/AstralRound.cs b/Projectiles/Ranged/AstralRound.cs index 6844252aed..f21826db32 100644 --- a/Projectiles/Ranged/AstralRound.cs +++ b/Projectiles/Ranged/AstralRound.cs @@ -15,6 +15,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/AstrealFlame.cs b/Projectiles/Ranged/AstrealFlame.cs index 6f2f999565..d29f10eb2e 100644 --- a/Projectiles/Ranged/AstrealFlame.cs +++ b/Projectiles/Ranged/AstrealFlame.cs @@ -14,6 +14,7 @@ public class AstrealFlame : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 4; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/AuricBullet.cs b/Projectiles/Ranged/AuricBullet.cs index c67e285ea7..9c3e03b465 100644 --- a/Projectiles/Ranged/AuricBullet.cs +++ b/Projectiles/Ranged/AuricBullet.cs @@ -19,6 +19,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 9; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/BlightFlames.cs b/Projectiles/Ranged/BlightFlames.cs index d56935e430..d10a150633 100644 --- a/Projectiles/Ranged/BlightFlames.cs +++ b/Projectiles/Ranged/BlightFlames.cs @@ -24,6 +24,7 @@ public class BlightFlames : ModProjectile, ILocalizedModType public bool postEnemyHit = false; public Color FogColor = new Color(30, 255, 30); + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 14; diff --git a/Projectiles/Ranged/BloodflareSoul.cs b/Projectiles/Ranged/BloodflareSoul.cs index 14cabced7a..a76dd45983 100644 --- a/Projectiles/Ranged/BloodflareSoul.cs +++ b/Projectiles/Ranged/BloodflareSoul.cs @@ -15,6 +15,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 5; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/CardClubSplit.cs b/Projectiles/Ranged/CardClubSplit.cs index 928c15967d..4a51ce4490 100644 --- a/Projectiles/Ranged/CardClubSplit.cs +++ b/Projectiles/Ranged/CardClubSplit.cs @@ -13,6 +13,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 5; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/ClamorRifleProj.cs b/Projectiles/Ranged/ClamorRifleProj.cs index c3c7a5ef6c..ce6bb0907b 100644 --- a/Projectiles/Ranged/ClamorRifleProj.cs +++ b/Projectiles/Ranged/ClamorRifleProj.cs @@ -11,6 +11,7 @@ namespace CalamityMod.Projectiles.Ranged public class ClamorRifleProj : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Ranged"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 16; diff --git a/Projectiles/Ranged/ClamorRifleProjSplit.cs b/Projectiles/Ranged/ClamorRifleProjSplit.cs index c4809556b2..3b01b45cc6 100644 --- a/Projectiles/Ranged/ClamorRifleProjSplit.cs +++ b/Projectiles/Ranged/ClamorRifleProjSplit.cs @@ -10,6 +10,7 @@ public class ClamorRifleProjSplit : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Ranged"; public override string Texture => "CalamityMod/Projectiles/Ranged/ClamorRifleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 16; diff --git a/Projectiles/Ranged/CondemnationArrowHoming.cs b/Projectiles/Ranged/CondemnationArrowHoming.cs index 85dfd6b539..63d05cb313 100644 --- a/Projectiles/Ranged/CondemnationArrowHoming.cs +++ b/Projectiles/Ranged/CondemnationArrowHoming.cs @@ -15,6 +15,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailingMode[Projectile.type] = 1; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 9; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/CosmicFire.cs b/Projectiles/Ranged/CosmicFire.cs index 83feeccb0f..46014b1fb9 100644 --- a/Projectiles/Ranged/CosmicFire.cs +++ b/Projectiles/Ranged/CosmicFire.cs @@ -5,6 +5,7 @@ using Microsoft.Xna.Framework; using Terraria; using Terraria.Audio; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Ranged @@ -19,6 +20,7 @@ public class CosmicFire : ModProjectile, ILocalizedModType public Color InnerColor = Color.LightGreen; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = Projectile.height = 16; diff --git a/Projectiles/Ranged/DryadsTearSplit.cs b/Projectiles/Ranged/DryadsTearSplit.cs index 6b712b70a2..cceea943df 100644 --- a/Projectiles/Ranged/DryadsTearSplit.cs +++ b/Projectiles/Ranged/DryadsTearSplit.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 3; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/ElementalFlare.cs b/Projectiles/Ranged/ElementalFlare.cs index c92fe7d148..001dbdf4a0 100644 --- a/Projectiles/Ranged/ElementalFlare.cs +++ b/Projectiles/Ranged/ElementalFlare.cs @@ -38,6 +38,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 18; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/ElysianArrowRain.cs b/Projectiles/Ranged/ElysianArrowRain.cs index 3053e14814..3bc948c3e1 100644 --- a/Projectiles/Ranged/ElysianArrowRain.cs +++ b/Projectiles/Ranged/ElysianArrowRain.cs @@ -27,6 +27,7 @@ public override void SetStaticDefaults() // While this projectile doesn't have afterimages, it keeps track of old positions for its primitive drawcode. ProjectileID.Sets.TrailingMode[Projectile.type] = 2; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 21; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/ExoCrystalArrow.cs b/Projectiles/Ranged/ExoCrystalArrow.cs index d8c08be6b7..875fbd33e5 100644 --- a/Projectiles/Ranged/ExoCrystalArrow.cs +++ b/Projectiles/Ranged/ExoCrystalArrow.cs @@ -26,6 +26,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailingMode[Projectile.type] = 2; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/ExoFlareCluster.cs b/Projectiles/Ranged/ExoFlareCluster.cs index ec64d7a017..ce65530ba1 100644 --- a/Projectiles/Ranged/ExoFlareCluster.cs +++ b/Projectiles/Ranged/ExoFlareCluster.cs @@ -5,6 +5,7 @@ using Microsoft.Xna.Framework; using Terraria; using Terraria.Audio; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Ranged @@ -20,6 +21,7 @@ public class ExoFlareCluster : ModProjectile, ILocalizedModType public bool PostTileHit = false; public ref int audioCooldown => ref Main.player[Projectile.owner].Calamity().PhotoAudioCooldown; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = Projectile.height = 50; diff --git a/Projectiles/Ranged/FishronRPG.cs b/Projectiles/Ranged/FishronRPG.cs index 257becbc69..2283da203f 100644 --- a/Projectiles/Ranged/FishronRPG.cs +++ b/Projectiles/Ranged/FishronRPG.cs @@ -9,6 +9,7 @@ namespace CalamityMod.Projectiles.Ranged public class FishronRPG : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Ranged"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 14; diff --git a/Projectiles/Ranged/FlareBat.cs b/Projectiles/Ranged/FlareBat.cs index 9912900d23..ec5583125c 100644 --- a/Projectiles/Ranged/FlareBat.cs +++ b/Projectiles/Ranged/FlareBat.cs @@ -11,6 +11,7 @@ public class FlareBat : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 5; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/FungiOrb2.cs b/Projectiles/Ranged/FungiOrb2.cs index d98d3f1271..8769ef68f7 100644 --- a/Projectiles/Ranged/FungiOrb2.cs +++ b/Projectiles/Ranged/FungiOrb2.cs @@ -10,6 +10,7 @@ public class FungiOrb2 : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Ranged"; public override string Texture => "CalamityMod/Projectiles/Ranged/FungiOrb"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 12; diff --git a/Projectiles/Ranged/MagnomalyRocket.cs b/Projectiles/Ranged/MagnomalyRocket.cs index 3f2f51beb3..60cf7e50b0 100644 --- a/Projectiles/Ranged/MagnomalyRocket.cs +++ b/Projectiles/Ranged/MagnomalyRocket.cs @@ -16,6 +16,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 5; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/MechanicalBarracuda.cs b/Projectiles/Ranged/MechanicalBarracuda.cs index b09a73e72c..7e5a00936f 100644 --- a/Projectiles/Ranged/MechanicalBarracuda.cs +++ b/Projectiles/Ranged/MechanicalBarracuda.cs @@ -9,6 +9,7 @@ public class MechanicalBarracuda : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 4; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/MeowCreature.cs b/Projectiles/Ranged/MeowCreature.cs index 1186139e71..ddca141738 100644 --- a/Projectiles/Ranged/MeowCreature.cs +++ b/Projectiles/Ranged/MeowCreature.cs @@ -19,6 +19,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 36; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/MiniatureFolly.cs b/Projectiles/Ranged/MiniatureFolly.cs index de31a813ef..ec89e88744 100644 --- a/Projectiles/Ranged/MiniatureFolly.cs +++ b/Projectiles/Ranged/MiniatureFolly.cs @@ -12,6 +12,7 @@ public class MiniatureFolly : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/PlagueTaintedDrone.cs b/Projectiles/Ranged/PlagueTaintedDrone.cs index 132aaf1c82..85511f3095 100644 --- a/Projectiles/Ranged/PlagueTaintedDrone.cs +++ b/Projectiles/Ranged/PlagueTaintedDrone.cs @@ -17,6 +17,7 @@ public class PlagueTaintedDrone : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 4; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/PlanetaryAnnihilationProj.cs b/Projectiles/Ranged/PlanetaryAnnihilationProj.cs index 16afcdb0b1..96e5cd5da1 100644 --- a/Projectiles/Ranged/PlanetaryAnnihilationProj.cs +++ b/Projectiles/Ranged/PlanetaryAnnihilationProj.cs @@ -14,6 +14,7 @@ public class PlanetaryAnnihilationProj : ModProjectile, ILocalizedModType private int dustType = 0; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 8; diff --git a/Projectiles/Ranged/PrecisionBolt.cs b/Projectiles/Ranged/PrecisionBolt.cs index bea7d232e5..4b11483a72 100644 --- a/Projectiles/Ranged/PrecisionBolt.cs +++ b/Projectiles/Ranged/PrecisionBolt.cs @@ -11,6 +11,7 @@ public class PrecisionBolt : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Ranged"; NPC potentialTarget = null; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 72; diff --git a/Projectiles/Ranged/PrismComet.cs b/Projectiles/Ranged/PrismComet.cs index 585c57f481..0b57357ad2 100644 --- a/Projectiles/Ranged/PrismComet.cs +++ b/Projectiles/Ranged/PrismComet.cs @@ -17,6 +17,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 5; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/RainbowBlast.cs b/Projectiles/Ranged/RainbowBlast.cs index 4fe0111b80..545dfe829c 100644 --- a/Projectiles/Ranged/RainbowBlast.cs +++ b/Projectiles/Ranged/RainbowBlast.cs @@ -12,6 +12,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/RicoshotCoin.cs b/Projectiles/Ranged/RicoshotCoin.cs index 1d62162a82..96d3acca3c 100644 --- a/Projectiles/Ranged/RicoshotCoin.cs +++ b/Projectiles/Ranged/RicoshotCoin.cs @@ -94,6 +94,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.TrailCacheLength[Projectile.type] = 60; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; Main.projFrames[Projectile.type] = 8; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/ScorchedEarthRocket.cs b/Projectiles/Ranged/ScorchedEarthRocket.cs index f3381143da..62e0ebdc55 100644 --- a/Projectiles/Ranged/ScorchedEarthRocket.cs +++ b/Projectiles/Ranged/ScorchedEarthRocket.cs @@ -13,6 +13,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 10; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 3; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/ScorpioLargeRocket.cs b/Projectiles/Ranged/ScorpioLargeRocket.cs index f4382f2726..d35bfbcd31 100644 --- a/Projectiles/Ranged/ScorpioLargeRocket.cs +++ b/Projectiles/Ranged/ScorpioLargeRocket.cs @@ -27,6 +27,7 @@ public override void SetStaticDefaults() Main.projFrames[Type] = 4; ProjectileID.Sets.TrailingMode[Type] = 2; ProjectileID.Sets.TrailCacheLength[Type] = 8; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/ScorpioRocket.cs b/Projectiles/Ranged/ScorpioRocket.cs index 309634c16a..4f9956a3e5 100644 --- a/Projectiles/Ranged/ScorpioRocket.cs +++ b/Projectiles/Ranged/ScorpioRocket.cs @@ -29,6 +29,7 @@ public override void SetStaticDefaults() Main.projFrames[Type] = 4; ProjectileID.Sets.TrailingMode[Type] = 2; ProjectileID.Sets.TrailCacheLength[Type] = 8; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/SeaDragonRocket.cs b/Projectiles/Ranged/SeaDragonRocket.cs index ee4feaeb26..570618b113 100644 --- a/Projectiles/Ranged/SeaDragonRocket.cs +++ b/Projectiles/Ranged/SeaDragonRocket.cs @@ -9,6 +9,7 @@ namespace CalamityMod.Projectiles.Ranged public class SeaDragonRocket : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Ranged"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 18; diff --git a/Projectiles/Ranged/Shroom.cs b/Projectiles/Ranged/Shroom.cs index 7952c103f4..b27be13c97 100644 --- a/Projectiles/Ranged/Shroom.cs +++ b/Projectiles/Ranged/Shroom.cs @@ -12,6 +12,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/SicknessRound2.cs b/Projectiles/Ranged/SicknessRound2.cs index a9334a32eb..76f9c676f9 100644 --- a/Projectiles/Ranged/SicknessRound2.cs +++ b/Projectiles/Ranged/SicknessRound2.cs @@ -12,6 +12,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 3; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/SputterCometBig.cs b/Projectiles/Ranged/SputterCometBig.cs index 306e29e01d..7592699873 100644 --- a/Projectiles/Ranged/SputterCometBig.cs +++ b/Projectiles/Ranged/SputterCometBig.cs @@ -15,6 +15,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 8; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/StarmageddonBinaryStarCenter.cs b/Projectiles/Ranged/StarmageddonBinaryStarCenter.cs index 045c84200e..3ad4a33eb6 100644 --- a/Projectiles/Ranged/StarmageddonBinaryStarCenter.cs +++ b/Projectiles/Ranged/StarmageddonBinaryStarCenter.cs @@ -36,6 +36,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.DrawScreenCheckFluff[Projectile.type] = 10000; ProjectileID.Sets.NeedsUUID[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/StarmageddonStar.cs b/Projectiles/Ranged/StarmageddonStar.cs index 9891b14303..d13e87ec3f 100644 --- a/Projectiles/Ranged/StarmageddonStar.cs +++ b/Projectiles/Ranged/StarmageddonStar.cs @@ -25,6 +25,7 @@ public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.DrawScreenCheckFluff[Projectile.type] = 10000; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/StarmageddonStar2.cs b/Projectiles/Ranged/StarmageddonStar2.cs index 1ed3100ebc..f4bd66e188 100644 --- a/Projectiles/Ranged/StarmageddonStar2.cs +++ b/Projectiles/Ranged/StarmageddonStar2.cs @@ -25,6 +25,7 @@ public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.DrawScreenCheckFluff[Projectile.type] = 10000; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/SulphuricBlast.cs b/Projectiles/Ranged/SulphuricBlast.cs index 5e0e660b4a..fba65d999f 100644 --- a/Projectiles/Ranged/SulphuricBlast.cs +++ b/Projectiles/Ranged/SulphuricBlast.cs @@ -15,6 +15,7 @@ public class SulphuricBlast : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 20; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/ThePackMinissile.cs b/Projectiles/Ranged/ThePackMinissile.cs index 57f02cb569..b595b2bb01 100644 --- a/Projectiles/Ranged/ThePackMinissile.cs +++ b/Projectiles/Ranged/ThePackMinissile.cs @@ -12,6 +12,7 @@ public class ThePackMinissile : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 4; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/ThePackMissile.cs b/Projectiles/Ranged/ThePackMissile.cs index 9a369c0616..c1331801e6 100644 --- a/Projectiles/Ranged/ThePackMissile.cs +++ b/Projectiles/Ranged/ThePackMissile.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Ranged/UltimaSpark.cs b/Projectiles/Ranged/UltimaSpark.cs index 1bf45cc6f3..cd80d5b268 100644 --- a/Projectiles/Ranged/UltimaSpark.cs +++ b/Projectiles/Ranged/UltimaSpark.cs @@ -1,6 +1,7 @@ using System; using Microsoft.Xna.Framework; using Terraria; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Ranged { @@ -16,6 +17,7 @@ public float Time } public const int DustType = 261; public const float MaxHomingDistance = 1200f; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = Projectile.height = 8; diff --git a/Projectiles/Ranged/VanquisherArrowProj.cs b/Projectiles/Ranged/VanquisherArrowProj.cs index d2f4555ac3..b55c99fb6c 100644 --- a/Projectiles/Ranged/VanquisherArrowProj.cs +++ b/Projectiles/Ranged/VanquisherArrowProj.cs @@ -25,6 +25,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 20; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() { diff --git a/Projectiles/Ranged/WildfireBloomFlare.cs b/Projectiles/Ranged/WildfireBloomFlare.cs index d0a4586228..933f34fd57 100644 --- a/Projectiles/Ranged/WildfireBloomFlare.cs +++ b/Projectiles/Ranged/WildfireBloomFlare.cs @@ -18,6 +18,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 18; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/AuroradicalStar.cs b/Projectiles/Rogue/AuroradicalStar.cs index 2b0acbde3b..1fe8b06701 100644 --- a/Projectiles/Rogue/AuroradicalStar.cs +++ b/Projectiles/Rogue/AuroradicalStar.cs @@ -22,6 +22,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/BlunderBoosterLightning.cs b/Projectiles/Rogue/BlunderBoosterLightning.cs index 322fa2d5f9..701937c9e9 100644 --- a/Projectiles/Rogue/BlunderBoosterLightning.cs +++ b/Projectiles/Rogue/BlunderBoosterLightning.cs @@ -17,6 +17,7 @@ public class BlunderBoosterLightning : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 4; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/CelestialReaperAfterimage.cs b/Projectiles/Rogue/CelestialReaperAfterimage.cs index 28d2198142..14c91ab91c 100644 --- a/Projectiles/Rogue/CelestialReaperAfterimage.cs +++ b/Projectiles/Rogue/CelestialReaperAfterimage.cs @@ -1,5 +1,6 @@ using Microsoft.Xna.Framework; using Terraria; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Rogue { @@ -8,6 +9,7 @@ public class CelestialReaperAfterimage : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Rogue"; public override string Texture => "CalamityMod/Items/Weapons/Rogue/CelestialReaper"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 66; diff --git a/Projectiles/Rogue/CelestialReaperProjectile.cs b/Projectiles/Rogue/CelestialReaperProjectile.cs index a75bd9ccdc..a864cf5546 100644 --- a/Projectiles/Rogue/CelestialReaperProjectile.cs +++ b/Projectiles/Rogue/CelestialReaperProjectile.cs @@ -1,6 +1,7 @@ using System; using Microsoft.Xna.Framework; using Terraria; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Rogue @@ -12,6 +13,7 @@ public class CelestialReaperProjectile : ModProjectile, ILocalizedModType public int HomingCooldown = 0; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 66; diff --git a/Projectiles/Rogue/CobaltEnergy.cs b/Projectiles/Rogue/CobaltEnergy.cs index d6ead0de25..1f74e418a9 100644 --- a/Projectiles/Rogue/CobaltEnergy.cs +++ b/Projectiles/Rogue/CobaltEnergy.cs @@ -17,6 +17,7 @@ public class CobaltEnergy : ModProjectile, ILocalizedModType private int targetNPC = -1; private List previousNPCs = new List() { -1 }; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 10; diff --git a/Projectiles/Rogue/CorpusAvertorClone.cs b/Projectiles/Rogue/CorpusAvertorClone.cs index 01589210b9..435ae23640 100644 --- a/Projectiles/Rogue/CorpusAvertorClone.cs +++ b/Projectiles/Rogue/CorpusAvertorClone.cs @@ -16,6 +16,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/CosmicScythe.cs b/Projectiles/Rogue/CosmicScythe.cs index 41d1a8092b..0ff7c146fc 100644 --- a/Projectiles/Rogue/CosmicScythe.cs +++ b/Projectiles/Rogue/CosmicScythe.cs @@ -18,6 +18,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/Crushax.cs b/Projectiles/Rogue/Crushax.cs index e4faf91f2e..dfa3b3003c 100644 --- a/Projectiles/Rogue/Crushax.cs +++ b/Projectiles/Rogue/Crushax.cs @@ -9,6 +9,7 @@ namespace CalamityMod.Projectiles.Rogue public class Crushax : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Rogue"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 30; diff --git a/Projectiles/Rogue/DesecratedBubble.cs b/Projectiles/Rogue/DesecratedBubble.cs index 6fc7447c9a..1403cef06a 100644 --- a/Projectiles/Rogue/DesecratedBubble.cs +++ b/Projectiles/Rogue/DesecratedBubble.cs @@ -8,6 +8,7 @@ namespace CalamityMod.Projectiles.Rogue public class DesecratedBubble : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Rogue"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 20; diff --git a/Projectiles/Rogue/DestructionBolt.cs b/Projectiles/Rogue/DestructionBolt.cs index 7ab9e7cc56..d5386c9178 100644 --- a/Projectiles/Rogue/DestructionBolt.cs +++ b/Projectiles/Rogue/DestructionBolt.cs @@ -15,6 +15,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 1; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/EclipsesSmol.cs b/Projectiles/Rogue/EclipsesSmol.cs index 62e45e3ebe..f6e5558869 100644 --- a/Projectiles/Rogue/EclipsesSmol.cs +++ b/Projectiles/Rogue/EclipsesSmol.cs @@ -1,6 +1,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Terraria; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Rogue @@ -8,6 +9,7 @@ namespace CalamityMod.Projectiles.Rogue public class EclipsesSmol : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Rogue"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = Projectile.height = 24; diff --git a/Projectiles/Rogue/EnchantedAxe2.cs b/Projectiles/Rogue/EnchantedAxe2.cs index 7d9ade368b..3b491e69be 100644 --- a/Projectiles/Rogue/EnchantedAxe2.cs +++ b/Projectiles/Rogue/EnchantedAxe2.cs @@ -1,6 +1,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Terraria; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Rogue { @@ -9,6 +10,7 @@ public class EnchantedAxe2 : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Rogue"; public override string Texture => "CalamityMod/Items/Weapons/Rogue/EnchantedAxe"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 10; diff --git a/Projectiles/Rogue/EquanimityDarkShard.cs b/Projectiles/Rogue/EquanimityDarkShard.cs index aa65007872..2d5cb1d87b 100644 --- a/Projectiles/Rogue/EquanimityDarkShard.cs +++ b/Projectiles/Rogue/EquanimityDarkShard.cs @@ -9,6 +9,7 @@ namespace CalamityMod.Projectiles.Rogue public class EquanimityDarkShard : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Rogue"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 12; diff --git a/Projectiles/Rogue/ExecutionersBladeProj.cs b/Projectiles/Rogue/ExecutionersBladeProj.cs index b52e8d2ad2..50b8e2c914 100644 --- a/Projectiles/Rogue/ExecutionersBladeProj.cs +++ b/Projectiles/Rogue/ExecutionersBladeProj.cs @@ -29,6 +29,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 2; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/FinalDawnFireball.cs b/Projectiles/Rogue/FinalDawnFireball.cs index cb25e37003..1071ebfb2e 100644 --- a/Projectiles/Rogue/FinalDawnFireball.cs +++ b/Projectiles/Rogue/FinalDawnFireball.cs @@ -3,6 +3,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Terraria; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Rogue @@ -15,6 +16,7 @@ public class FinalDawnFireball : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 4; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() { diff --git a/Projectiles/Rogue/GacruxianHome.cs b/Projectiles/Rogue/GacruxianHome.cs index 20e01c8cc4..6251d0f3df 100644 --- a/Projectiles/Rogue/GacruxianHome.cs +++ b/Projectiles/Rogue/GacruxianHome.cs @@ -12,6 +12,7 @@ public class GacruxianHome : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Rogue"; public override string Texture => "CalamityMod/Items/Weapons/Rogue/GacruxianMollusk"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 20; diff --git a/Projectiles/Rogue/GodsParanoiaProj.cs b/Projectiles/Rogue/GodsParanoiaProj.cs index 235c6ada4c..3624f4947b 100644 --- a/Projectiles/Rogue/GodsParanoiaProj.cs +++ b/Projectiles/Rogue/GodsParanoiaProj.cs @@ -18,6 +18,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/GraveGrimreaverProjectile.cs b/Projectiles/Rogue/GraveGrimreaverProjectile.cs index bc0b984642..667ee1a0b2 100644 --- a/Projectiles/Rogue/GraveGrimreaverProjectile.cs +++ b/Projectiles/Rogue/GraveGrimreaverProjectile.cs @@ -16,6 +16,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/GrimreaverSkull.cs b/Projectiles/Rogue/GrimreaverSkull.cs index c9a3d74a60..8cb3f3caf9 100644 --- a/Projectiles/Rogue/GrimreaverSkull.cs +++ b/Projectiles/Rogue/GrimreaverSkull.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/HeavenfallenEnergy.cs b/Projectiles/Rogue/HeavenfallenEnergy.cs index 970d99845b..74056c7f34 100644 --- a/Projectiles/Rogue/HeavenfallenEnergy.cs +++ b/Projectiles/Rogue/HeavenfallenEnergy.cs @@ -2,6 +2,7 @@ using CalamityMod.Dusts; using Microsoft.Xna.Framework; using Terraria; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Rogue { @@ -12,6 +13,7 @@ public class HeavenfallenEnergy : ModProjectile, ILocalizedModType public bool raining => Projectile.ai[1] == 0f; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 8; diff --git a/Projectiles/Rogue/IceStarProjectile.cs b/Projectiles/Rogue/IceStarProjectile.cs index 30320b7672..c30a3b9955 100644 --- a/Projectiles/Rogue/IceStarProjectile.cs +++ b/Projectiles/Rogue/IceStarProjectile.cs @@ -14,6 +14,7 @@ public class IceStarProjectile : ModProjectile, ILocalizedModType private bool initStealth = false; private Vector2 initialVelocity; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 30; diff --git a/Projectiles/Rogue/LostSoulFriendly.cs b/Projectiles/Rogue/LostSoulFriendly.cs index 8641d91ad2..10b9c2cc1b 100644 --- a/Projectiles/Rogue/LostSoulFriendly.cs +++ b/Projectiles/Rogue/LostSoulFriendly.cs @@ -12,6 +12,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/LunarKunaiProj.cs b/Projectiles/Rogue/LunarKunaiProj.cs index ae1f678100..f8afbf2ae3 100644 --- a/Projectiles/Rogue/LunarKunaiProj.cs +++ b/Projectiles/Rogue/LunarKunaiProj.cs @@ -18,6 +18,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 2; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/MalachiteStealth.cs b/Projectiles/Rogue/MalachiteStealth.cs index 77206f17f0..d69fe88d96 100644 --- a/Projectiles/Rogue/MalachiteStealth.cs +++ b/Projectiles/Rogue/MalachiteStealth.cs @@ -17,6 +17,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/MeteorFistStealth.cs b/Projectiles/Rogue/MeteorFistStealth.cs index d08caeb9a1..acedb50f6a 100644 --- a/Projectiles/Rogue/MeteorFistStealth.cs +++ b/Projectiles/Rogue/MeteorFistStealth.cs @@ -13,6 +13,7 @@ public class MeteorFistStealth : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Rogue"; public override string Texture => "CalamityMod/Projectiles/Rogue/MeteorFistProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 20; diff --git a/Projectiles/Rogue/MoonSigil.cs b/Projectiles/Rogue/MoonSigil.cs index ac6d594ff2..3527d04e0b 100644 --- a/Projectiles/Rogue/MoonSigil.cs +++ b/Projectiles/Rogue/MoonSigil.cs @@ -9,6 +9,7 @@ namespace CalamityMod.Projectiles.Rogue public class MoonSigil : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Rogue"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 20; diff --git a/Projectiles/Rogue/NanoblackSplit.cs b/Projectiles/Rogue/NanoblackSplit.cs index 6fb8f943a6..49bb109289 100644 --- a/Projectiles/Rogue/NanoblackSplit.cs +++ b/Projectiles/Rogue/NanoblackSplit.cs @@ -25,6 +25,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 3; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/NanoblackStealthSplit.cs b/Projectiles/Rogue/NanoblackStealthSplit.cs index b91da360f6..d29fe08f01 100644 --- a/Projectiles/Rogue/NanoblackStealthSplit.cs +++ b/Projectiles/Rogue/NanoblackStealthSplit.cs @@ -25,6 +25,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 7; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/NychthemeronOrb.cs b/Projectiles/Rogue/NychthemeronOrb.cs index 2c2a439121..b7230922fa 100644 --- a/Projectiles/Rogue/NychthemeronOrb.cs +++ b/Projectiles/Rogue/NychthemeronOrb.cs @@ -2,6 +2,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Terraria; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Rogue @@ -14,6 +15,7 @@ public class NychthemeronOrb : ModProjectile, ILocalizedModType private Vector2 velocity = Vector2.Zero; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 10; diff --git a/Projectiles/Rogue/PenumbraSoul.cs b/Projectiles/Rogue/PenumbraSoul.cs index c070de5b1c..6fb7ee48c0 100644 --- a/Projectiles/Rogue/PenumbraSoul.cs +++ b/Projectiles/Rogue/PenumbraSoul.cs @@ -13,6 +13,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/PhantasmalSoul.cs b/Projectiles/Rogue/PhantasmalSoul.cs index 263c73a0dd..5a20a91c00 100644 --- a/Projectiles/Rogue/PhantasmalSoul.cs +++ b/Projectiles/Rogue/PhantasmalSoul.cs @@ -20,6 +20,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 3; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/PhantasmalSoulBlue.cs b/Projectiles/Rogue/PhantasmalSoulBlue.cs index f3c196a970..c0f63d7d7a 100644 --- a/Projectiles/Rogue/PhantasmalSoulBlue.cs +++ b/Projectiles/Rogue/PhantasmalSoulBlue.cs @@ -21,6 +21,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 3; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/PlaguenadeBee.cs b/Projectiles/Rogue/PlaguenadeBee.cs index e32a981df4..a5143606fb 100644 --- a/Projectiles/Rogue/PlaguenadeBee.cs +++ b/Projectiles/Rogue/PlaguenadeBee.cs @@ -13,6 +13,7 @@ public class PlaguenadeBee : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 4; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/PrismRocket.cs b/Projectiles/Rogue/PrismRocket.cs index ad17ba775c..d92eca31a2 100644 --- a/Projectiles/Rogue/PrismRocket.cs +++ b/Projectiles/Rogue/PrismRocket.cs @@ -16,6 +16,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailingMode[Projectile.type] = 2; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 20; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/PrismShurikenBlade.cs b/Projectiles/Rogue/PrismShurikenBlade.cs index e993e01731..d6dbc41b11 100644 --- a/Projectiles/Rogue/PrismShurikenBlade.cs +++ b/Projectiles/Rogue/PrismShurikenBlade.cs @@ -8,6 +8,7 @@ namespace CalamityMod.Projectiles.Rogue public class PrismShurikenBlade : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Rogue"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = Projectile.height = 22; diff --git a/Projectiles/Rogue/Prismalline3.cs b/Projectiles/Rogue/Prismalline3.cs index 9032060ee5..b93567254b 100644 --- a/Projectiles/Rogue/Prismalline3.cs +++ b/Projectiles/Rogue/Prismalline3.cs @@ -12,6 +12,7 @@ public class Prismalline3 : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Rogue"; public override string Texture => "CalamityMod/Items/Weapons/Rogue/Prismalline"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 20; diff --git a/Projectiles/Rogue/ProfanedPartisanSpear.cs b/Projectiles/Rogue/ProfanedPartisanSpear.cs index 789a2576f9..f0f15157a0 100644 --- a/Projectiles/Rogue/ProfanedPartisanSpear.cs +++ b/Projectiles/Rogue/ProfanedPartisanSpear.cs @@ -2,6 +2,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Terraria; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Rogue @@ -11,6 +12,7 @@ public class ProfanedPartisanSpear : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Rogue"; public int timer = 0; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 10; diff --git a/Projectiles/Rogue/RadiantStar2.cs b/Projectiles/Rogue/RadiantStar2.cs index 2fc8e04e0a..f5dc40a7a4 100644 --- a/Projectiles/Rogue/RadiantStar2.cs +++ b/Projectiles/Rogue/RadiantStar2.cs @@ -18,6 +18,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/RealityRuptureMini.cs b/Projectiles/Rogue/RealityRuptureMini.cs index aa16a31513..3623abbaa4 100644 --- a/Projectiles/Rogue/RealityRuptureMini.cs +++ b/Projectiles/Rogue/RealityRuptureMini.cs @@ -17,6 +17,7 @@ public class RealityRuptureMini : ModProjectile, ILocalizedModType public int framesInAir = 0; public int SparkChance = 1; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 34; diff --git a/Projectiles/Rogue/RegulusEnergy.cs b/Projectiles/Rogue/RegulusEnergy.cs index cac9b64289..59107ae03c 100644 --- a/Projectiles/Rogue/RegulusEnergy.cs +++ b/Projectiles/Rogue/RegulusEnergy.cs @@ -2,6 +2,7 @@ using CalamityMod.Dusts; using Microsoft.Xna.Framework; using Terraria; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Rogue @@ -11,6 +12,7 @@ public class RegulusEnergy : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Rogue"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 8; diff --git a/Projectiles/Rogue/RegulusRiotProj.cs b/Projectiles/Rogue/RegulusRiotProj.cs index 34857952a4..85abf8e0ae 100644 --- a/Projectiles/Rogue/RegulusRiotProj.cs +++ b/Projectiles/Rogue/RegulusRiotProj.cs @@ -18,6 +18,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 5; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/ScarletDevilBullet.cs b/Projectiles/Rogue/ScarletDevilBullet.cs index 7dadea5643..bdd68edb7c 100644 --- a/Projectiles/Rogue/ScarletDevilBullet.cs +++ b/Projectiles/Rogue/ScarletDevilBullet.cs @@ -1,11 +1,13 @@ using Microsoft.Xna.Framework; using Terraria; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Rogue { public class ScarletDevilBullet : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Rogue"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 16; diff --git a/Projectiles/Rogue/ScourgeoftheDesertProj.cs b/Projectiles/Rogue/ScourgeoftheDesertProj.cs index 15f6029cb4..ea88a8abe0 100644 --- a/Projectiles/Rogue/ScourgeoftheDesertProj.cs +++ b/Projectiles/Rogue/ScourgeoftheDesertProj.cs @@ -1,16 +1,10 @@ using System; -using CalamityMod.Items.Weapons.Melee; -using CalamityMod.NPCs.DesertScourge; -using CalamityMod.NPCs.Ravager; using CalamityMod.Particles; -using CalamityMod.Projectiles.Magic; -using Microsoft.CodeAnalysis; using Microsoft.Xna.Framework; using Terraria; using Terraria.Audio; using Terraria.ID; using Terraria.ModLoader; -using static Humanizer.In; namespace CalamityMod.Projectiles.Rogue { @@ -32,6 +26,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 1; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/SeraphimDagger.cs b/Projectiles/Rogue/SeraphimDagger.cs index 3f1ad68265..aaea9660ad 100644 --- a/Projectiles/Rogue/SeraphimDagger.cs +++ b/Projectiles/Rogue/SeraphimDagger.cs @@ -15,6 +15,7 @@ public class SeraphimDagger : ModProjectile, ILocalizedModType public const int AimTime = 25; public ref float Time => ref Projectile.ai[0]; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 50; diff --git a/Projectiles/Rogue/ShatteredSunScorchedBlade.cs b/Projectiles/Rogue/ShatteredSunScorchedBlade.cs index ce556d1071..972b49cd90 100644 --- a/Projectiles/Rogue/ShatteredSunScorchedBlade.cs +++ b/Projectiles/Rogue/ShatteredSunScorchedBlade.cs @@ -19,6 +19,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/SkyfinNuke.cs b/Projectiles/Rogue/SkyfinNuke.cs index bc464c0284..dcb9349a07 100644 --- a/Projectiles/Rogue/SkyfinNuke.cs +++ b/Projectiles/Rogue/SkyfinNuke.cs @@ -13,6 +13,7 @@ public class SkyfinNuke : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Rogue"; public override string Texture => "CalamityMod/Items/Weapons/Rogue/SkyfinBombers"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 30; diff --git a/Projectiles/Rogue/SpearofDestinyProjectile.cs b/Projectiles/Rogue/SpearofDestinyProjectile.cs index cbec922070..f63822b705 100644 --- a/Projectiles/Rogue/SpearofDestinyProjectile.cs +++ b/Projectiles/Rogue/SpearofDestinyProjectile.cs @@ -18,6 +18,7 @@ public class SpearofDestinyProjectile : ModProjectile, ILocalizedModType private bool initialized = false; public int SparkChance = 1; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 12; diff --git a/Projectiles/Rogue/SphereBlue.cs b/Projectiles/Rogue/SphereBlue.cs index ebc771fa14..ce3cd03749 100644 --- a/Projectiles/Rogue/SphereBlue.cs +++ b/Projectiles/Rogue/SphereBlue.cs @@ -12,6 +12,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/StellarKnifeProj.cs b/Projectiles/Rogue/StellarKnifeProj.cs index 1b90218b98..be4c08274b 100644 --- a/Projectiles/Rogue/StellarKnifeProj.cs +++ b/Projectiles/Rogue/StellarKnifeProj.cs @@ -17,6 +17,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 8; ProjectileID.Sets.TrailingMode[Projectile.type] = 1; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/SupernovaBomb.cs b/Projectiles/Rogue/SupernovaBomb.cs index 8798841e8b..88952d9b3e 100644 --- a/Projectiles/Rogue/SupernovaBomb.cs +++ b/Projectiles/Rogue/SupernovaBomb.cs @@ -28,6 +28,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 5; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/TheSyringeS1.cs b/Projectiles/Rogue/TheSyringeS1.cs index 1835c30d57..8b05b75c90 100644 --- a/Projectiles/Rogue/TheSyringeS1.cs +++ b/Projectiles/Rogue/TheSyringeS1.cs @@ -13,6 +13,7 @@ public class TheSyringeS1 : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 3; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/TimeBoltKnife.cs b/Projectiles/Rogue/TimeBoltKnife.cs index 0372da7e39..684173bca7 100644 --- a/Projectiles/Rogue/TimeBoltKnife.cs +++ b/Projectiles/Rogue/TimeBoltKnife.cs @@ -21,6 +21,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/TitaniumClone.cs b/Projectiles/Rogue/TitaniumClone.cs index 5d83d1bd1d..c7755def59 100644 --- a/Projectiles/Rogue/TitaniumClone.cs +++ b/Projectiles/Rogue/TitaniumClone.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/ToxicantTwisterDust.cs b/Projectiles/Rogue/ToxicantTwisterDust.cs index e7c66ff3e9..b03b4a9023 100644 --- a/Projectiles/Rogue/ToxicantTwisterDust.cs +++ b/Projectiles/Rogue/ToxicantTwisterDust.cs @@ -10,6 +10,7 @@ public class ToxicantTwisterDust : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Rogue"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 6; diff --git a/Projectiles/Rogue/TurbulanceWindSlash.cs b/Projectiles/Rogue/TurbulanceWindSlash.cs index 59ecdedeb3..402166accd 100644 --- a/Projectiles/Rogue/TurbulanceWindSlash.cs +++ b/Projectiles/Rogue/TurbulanceWindSlash.cs @@ -12,6 +12,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 3; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/Valaricicle.cs b/Projectiles/Rogue/Valaricicle.cs index a6100f7335..a8542b667b 100644 --- a/Projectiles/Rogue/Valaricicle.cs +++ b/Projectiles/Rogue/Valaricicle.cs @@ -8,6 +8,7 @@ namespace CalamityMod.Projectiles.Rogue public class Valaricicle : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Rogue"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 10; diff --git a/Projectiles/Rogue/Valaricicle2.cs b/Projectiles/Rogue/Valaricicle2.cs index 1ccddf4d15..79ab3f78c0 100644 --- a/Projectiles/Rogue/Valaricicle2.cs +++ b/Projectiles/Rogue/Valaricicle2.cs @@ -8,6 +8,7 @@ namespace CalamityMod.Projectiles.Rogue public class Valaricicle2 : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Rogue"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 10; diff --git a/Projectiles/Rogue/ValedictionBoomerang.cs b/Projectiles/Rogue/ValedictionBoomerang.cs index 095665bff9..61a1578787 100644 --- a/Projectiles/Rogue/ValedictionBoomerang.cs +++ b/Projectiles/Rogue/ValedictionBoomerang.cs @@ -17,6 +17,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/VeneratedKnife.cs b/Projectiles/Rogue/VeneratedKnife.cs index 960c4eb363..331b6d70a9 100644 --- a/Projectiles/Rogue/VeneratedKnife.cs +++ b/Projectiles/Rogue/VeneratedKnife.cs @@ -16,6 +16,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 8; ProjectileID.Sets.TrailingMode[Projectile.type] = 1; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Rogue/WrathwingSpear.cs b/Projectiles/Rogue/WrathwingSpear.cs index 0549e21f39..cabdd4b7da 100644 --- a/Projectiles/Rogue/WrathwingSpear.cs +++ b/Projectiles/Rogue/WrathwingSpear.cs @@ -17,6 +17,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 8; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/AngelBolt.cs b/Projectiles/Summon/AngelBolt.cs index aaedab1f12..794ff48ad4 100644 --- a/Projectiles/Summon/AngelBolt.cs +++ b/Projectiles/Summon/AngelBolt.cs @@ -14,6 +14,7 @@ public class AngelBolt : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { ProjectileID.Sets.MinionShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/AngelRay.cs b/Projectiles/Summon/AngelRay.cs index bcadf072d3..80281bdd10 100644 --- a/Projectiles/Summon/AngelRay.cs +++ b/Projectiles/Summon/AngelRay.cs @@ -14,6 +14,7 @@ public class AngelRay : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { ProjectileID.Sets.MinionShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/AureusBomber.cs b/Projectiles/Summon/AureusBomber.cs index 74e448eb29..f761226840 100644 --- a/Projectiles/Summon/AureusBomber.cs +++ b/Projectiles/Summon/AureusBomber.cs @@ -19,6 +19,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.MinionTargettingFeature[Projectile.type] = true; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 1; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/BelladonnaPetal.cs b/Projectiles/Summon/BelladonnaPetal.cs index ad834aeacb..452a123fb1 100644 --- a/Projectiles/Summon/BelladonnaPetal.cs +++ b/Projectiles/Summon/BelladonnaPetal.cs @@ -26,6 +26,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.MinionShot[Projectile.type] = true; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 5; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/CalamarisLamentProjectile.cs b/Projectiles/Summon/CalamarisLamentProjectile.cs index b7c6c9e762..22843a0150 100644 --- a/Projectiles/Summon/CalamarisLamentProjectile.cs +++ b/Projectiles/Summon/CalamarisLamentProjectile.cs @@ -21,6 +21,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.MinionShot[Type] = true; ProjectileID.Sets.TrailingMode[Type] = 2; ProjectileID.Sets.TrailCacheLength[Type] = 4; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; ProjectileID.Sets.DrawScreenCheckFluff[Type] = (int)CalamarisLament.EnemyDistanceDetection; } diff --git a/Projectiles/Summon/CosmicBlast.cs b/Projectiles/Summon/CosmicBlast.cs index 1c2884860e..157243ab88 100644 --- a/Projectiles/Summon/CosmicBlast.cs +++ b/Projectiles/Summon/CosmicBlast.cs @@ -15,6 +15,7 @@ public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.MinionShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/CosmicBlastBig.cs b/Projectiles/Summon/CosmicBlastBig.cs index 46cafc7536..32a37bec78 100644 --- a/Projectiles/Summon/CosmicBlastBig.cs +++ b/Projectiles/Summon/CosmicBlastBig.cs @@ -14,6 +14,7 @@ public class CosmicBlastBig : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { ProjectileID.Sets.MinionShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/CosmicViperHomingRocket.cs b/Projectiles/Summon/CosmicViperHomingRocket.cs index c5efb9e256..55b042606f 100644 --- a/Projectiles/Summon/CosmicViperHomingRocket.cs +++ b/Projectiles/Summon/CosmicViperHomingRocket.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.MinionShot[Projectile.type] = true; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; Main.projFrames[Projectile.type] = 3; } diff --git a/Projectiles/Summon/CosmicViperSplittingRocket.cs b/Projectiles/Summon/CosmicViperSplittingRocket.cs index f439605e5f..5029284e6b 100644 --- a/Projectiles/Summon/CosmicViperSplittingRocket.cs +++ b/Projectiles/Summon/CosmicViperSplittingRocket.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.MinionShot[Projectile.type] = true; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; Main.projFrames[Projectile.type] = 3; } diff --git a/Projectiles/Summon/CosmilampBeam.cs b/Projectiles/Summon/CosmilampBeam.cs index 8bc3f2f2bb..f553c7540d 100644 --- a/Projectiles/Summon/CosmilampBeam.cs +++ b/Projectiles/Summon/CosmilampBeam.cs @@ -27,6 +27,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.MinionShot[Projectile.type] = true; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 32; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/DeathstareBeam.cs b/Projectiles/Summon/DeathstareBeam.cs index 38b884dadb..0346ee2ea4 100644 --- a/Projectiles/Summon/DeathstareBeam.cs +++ b/Projectiles/Summon/DeathstareBeam.cs @@ -14,6 +14,7 @@ public class DeathstareBeam : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { ProjectileID.Sets.MinionShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/Dreadmine.cs b/Projectiles/Summon/Dreadmine.cs index d352755434..31ba1a3c59 100644 --- a/Projectiles/Summon/Dreadmine.cs +++ b/Projectiles/Summon/Dreadmine.cs @@ -12,6 +12,7 @@ public class Dreadmine : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { ProjectileID.Sets.SentryShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/EndoIceShard.cs b/Projectiles/Summon/EndoIceShard.cs index 9d87d5f665..6edeb38bd5 100644 --- a/Projectiles/Summon/EndoIceShard.cs +++ b/Projectiles/Summon/EndoIceShard.cs @@ -15,6 +15,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; ProjectileID.Sets.MinionShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/EnergyOrb.cs b/Projectiles/Summon/EnergyOrb.cs index f31dba1688..d317fd4df4 100644 --- a/Projectiles/Summon/EnergyOrb.cs +++ b/Projectiles/Summon/EnergyOrb.cs @@ -9,6 +9,7 @@ public class EnergyOrb : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Summon"; public override string Texture => "CalamityMod/Projectiles/Magic/BlueBubble"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 14; diff --git a/Projectiles/Summon/FlameBlast.cs b/Projectiles/Summon/FlameBlast.cs index aed0a92082..58ec9363b6 100644 --- a/Projectiles/Summon/FlameBlast.cs +++ b/Projectiles/Summon/FlameBlast.cs @@ -17,6 +17,7 @@ public class FlameBlast : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { ProjectileID.Sets.SentryShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/FlameBurst.cs b/Projectiles/Summon/FlameBurst.cs index 3ddb9ff483..647f466890 100644 --- a/Projectiles/Summon/FlameBurst.cs +++ b/Projectiles/Summon/FlameBurst.cs @@ -17,6 +17,7 @@ public class FlameBurst : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { ProjectileID.Sets.SentryShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/FleshBlood.cs b/Projectiles/Summon/FleshBlood.cs index cb94a352f8..cab404b853 100644 --- a/Projectiles/Summon/FleshBlood.cs +++ b/Projectiles/Summon/FleshBlood.cs @@ -12,6 +12,7 @@ public class FleshBlood : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { ProjectileID.Sets.MinionShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/ForbiddenCircletEater.cs b/Projectiles/Summon/ForbiddenCircletEater.cs index 23a01694bd..25079382cc 100644 --- a/Projectiles/Summon/ForbiddenCircletEater.cs +++ b/Projectiles/Summon/ForbiddenCircletEater.cs @@ -1,6 +1,7 @@ using System; using Microsoft.Xna.Framework; using Terraria; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Summon @@ -13,6 +14,7 @@ public class ForbiddenCircletEater : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 4; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/FrostBeam.cs b/Projectiles/Summon/FrostBeam.cs index 4bea79a3f7..4e60263f00 100644 --- a/Projectiles/Summon/FrostBeam.cs +++ b/Projectiles/Summon/FrostBeam.cs @@ -13,6 +13,7 @@ public class FrostBeam : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { ProjectileID.Sets.MinionShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/GammaCanister.cs b/Projectiles/Summon/GammaCanister.cs index 6220b6b57f..fdd740fc5e 100644 --- a/Projectiles/Summon/GammaCanister.cs +++ b/Projectiles/Summon/GammaCanister.cs @@ -12,6 +12,7 @@ public class GammaCanister : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { ProjectileID.Sets.MinionShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/GhostFire.cs b/Projectiles/Summon/GhostFire.cs index 79aa43ef9b..9e005d4af6 100644 --- a/Projectiles/Summon/GhostFire.cs +++ b/Projectiles/Summon/GhostFire.cs @@ -20,6 +20,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.MinionShot[Projectile.type] = true; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 20; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/GlacialEmbracePointyThing.cs b/Projectiles/Summon/GlacialEmbracePointyThing.cs index a06cefa7f5..b637ce629c 100644 --- a/Projectiles/Summon/GlacialEmbracePointyThing.cs +++ b/Projectiles/Summon/GlacialEmbracePointyThing.cs @@ -54,6 +54,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailingMode[Projectile.type] = 0; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 7; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/Hiveling.cs b/Projectiles/Summon/Hiveling.cs index 6d5e1967da..169e820e89 100644 --- a/Projectiles/Summon/Hiveling.cs +++ b/Projectiles/Summon/Hiveling.cs @@ -16,6 +16,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; ProjectileID.Sets.SentryShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/HomingGammaBullet.cs b/Projectiles/Summon/HomingGammaBullet.cs index 63313ddecd..a01a4a13b7 100644 --- a/Projectiles/Summon/HomingGammaBullet.cs +++ b/Projectiles/Summon/HomingGammaBullet.cs @@ -19,6 +19,7 @@ public class HomingGammaBullet : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { ProjectileID.Sets.MinionShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/HowlsHeartFireball.cs b/Projectiles/Summon/HowlsHeartFireball.cs index d343308b61..947c20dbe2 100644 --- a/Projectiles/Summon/HowlsHeartFireball.cs +++ b/Projectiles/Summon/HowlsHeartFireball.cs @@ -13,6 +13,7 @@ public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.MinionShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/LanternFlame.cs b/Projectiles/Summon/LanternFlame.cs index 2086d4398e..ec3e3b3e10 100644 --- a/Projectiles/Summon/LanternFlame.cs +++ b/Projectiles/Summon/LanternFlame.cs @@ -15,6 +15,7 @@ public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.SentryShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/LiliesOfFinalityBolt.cs b/Projectiles/Summon/LiliesOfFinalityBolt.cs index a51698a541..1c87e0f110 100644 --- a/Projectiles/Summon/LiliesOfFinalityBolt.cs +++ b/Projectiles/Summon/LiliesOfFinalityBolt.cs @@ -31,6 +31,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.MinionShot[Type] = true; ProjectileID.Sets.TrailingMode[Type] = 2; ProjectileID.Sets.TrailCacheLength[Type] = 6; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/LostSoulGiant.cs b/Projectiles/Summon/LostSoulGiant.cs index 0db6da9464..ae4b7253ca 100644 --- a/Projectiles/Summon/LostSoulGiant.cs +++ b/Projectiles/Summon/LostSoulGiant.cs @@ -18,6 +18,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; ProjectileID.Sets.SentryShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/LostSoulGold.cs b/Projectiles/Summon/LostSoulGold.cs index e21c967adb..29db24c5ea 100644 --- a/Projectiles/Summon/LostSoulGold.cs +++ b/Projectiles/Summon/LostSoulGold.cs @@ -18,6 +18,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; ProjectileID.Sets.SentryShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/LostSoulLarge.cs b/Projectiles/Summon/LostSoulLarge.cs index 91540b2511..c1c291b8d6 100644 --- a/Projectiles/Summon/LostSoulLarge.cs +++ b/Projectiles/Summon/LostSoulLarge.cs @@ -18,6 +18,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; ProjectileID.Sets.SentryShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/LostSoulSmall.cs b/Projectiles/Summon/LostSoulSmall.cs index df8a619ad4..b5bd8a6382 100644 --- a/Projectiles/Summon/LostSoulSmall.cs +++ b/Projectiles/Summon/LostSoulSmall.cs @@ -18,6 +18,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; ProjectileID.Sets.SentryShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/MK2RocketHoming.cs b/Projectiles/Summon/MK2RocketHoming.cs index 0d1e44946f..38096a4cbd 100644 --- a/Projectiles/Summon/MK2RocketHoming.cs +++ b/Projectiles/Summon/MK2RocketHoming.cs @@ -13,6 +13,7 @@ public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 6; ProjectileID.Sets.MinionShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/MortalityBeam.cs b/Projectiles/Summon/MortalityBeam.cs index ea0b0a81bd..577dac0f75 100644 --- a/Projectiles/Summon/MortalityBeam.cs +++ b/Projectiles/Summon/MortalityBeam.cs @@ -18,6 +18,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; ProjectileID.Sets.MinionShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/MutatedTruffleToothballSpike.cs b/Projectiles/Summon/MutatedTruffleToothballSpike.cs index b71cbdcd0f..bf2e5c7401 100644 --- a/Projectiles/Summon/MutatedTruffleToothballSpike.cs +++ b/Projectiles/Summon/MutatedTruffleToothballSpike.cs @@ -16,7 +16,11 @@ public class MutatedTruffleToothballSpike : ModProjectile, ILocalizedModType public const int TimeForHitbox = 15; - public override void SetStaticDefaults() => ProjectileID.Sets.MinionShot[Type] = true; + public override void SetStaticDefaults() + { + ProjectileID.Sets.MinionShot[Type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; + } public override void SetDefaults() { diff --git a/Projectiles/Summon/OldDukeSharkVomit.cs b/Projectiles/Summon/OldDukeSharkVomit.cs index be484f33a8..c27c7a6aa4 100644 --- a/Projectiles/Summon/OldDukeSharkVomit.cs +++ b/Projectiles/Summon/OldDukeSharkVomit.cs @@ -15,6 +15,7 @@ public class OldDukeSharkVomit : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { ProjectileID.Sets.MinionShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/PhantomicDagger.cs b/Projectiles/Summon/PhantomicDagger.cs index 7ffcd03e5a..4e0f3cf94e 100644 --- a/Projectiles/Summon/PhantomicDagger.cs +++ b/Projectiles/Summon/PhantomicDagger.cs @@ -16,6 +16,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailingMode[Projectile.type] = 0; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 7; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/PlagueBeeSmall.cs b/Projectiles/Summon/PlagueBeeSmall.cs index 7a163764d3..fdc40e5225 100644 --- a/Projectiles/Summon/PlagueBeeSmall.cs +++ b/Projectiles/Summon/PlagueBeeSmall.cs @@ -15,6 +15,7 @@ public class PlagueBeeSmall : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 4; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/PlantationStaffTentacle.cs b/Projectiles/Summon/PlantationStaffTentacle.cs index a713ee71f3..cddecf05e4 100644 --- a/Projectiles/Summon/PlantationStaffTentacle.cs +++ b/Projectiles/Summon/PlantationStaffTentacle.cs @@ -43,6 +43,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.MinionShot[Type] = true; ProjectileID.Sets.TrailingMode[Type] = 2; ProjectileID.Sets.TrailCacheLength[Type] = 4; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/PlantationStaffThornball.cs b/Projectiles/Summon/PlantationStaffThornball.cs index 3ced054594..12f880bae2 100644 --- a/Projectiles/Summon/PlantationStaffThornball.cs +++ b/Projectiles/Summon/PlantationStaffThornball.cs @@ -18,6 +18,7 @@ public class PlantationStaffThornball : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { ProjectileID.Sets.MinionShot[Type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/ProfanedSoulCrystalProjectiles.cs b/Projectiles/Summon/ProfanedSoulCrystalProjectiles.cs index 5b17d39ef2..e142df4198 100644 --- a/Projectiles/Summon/ProfanedSoulCrystalProjectiles.cs +++ b/Projectiles/Summon/ProfanedSoulCrystalProjectiles.cs @@ -213,6 +213,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.MinionTargettingFeature[Projectile.type] = true; ProjectileID.Sets.SummonTagDamageMultiplier[Type] = 0.3f; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() @@ -984,6 +985,7 @@ public class ProfanedCrystalRogueShard : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { ProjectileID.Sets.SummonTagDamageMultiplier[Type] = 0.25f; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() { @@ -1690,6 +1692,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.TrailCacheLength[Type] = 2; ProjectileID.Sets.TrailingMode[Type] = 0; ProjectileID.Sets.SummonTagDamageMultiplier[Type] = 0.5f; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() @@ -2013,6 +2016,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.MinionTargettingFeature[Projectile.type] = true; ProjectileID.Sets.SummonTagDamageMultiplier[Type] = 0.3f; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/SakuraBullet.cs b/Projectiles/Summon/SakuraBullet.cs index b1d43958f6..238553190b 100644 --- a/Projectiles/Summon/SakuraBullet.cs +++ b/Projectiles/Summon/SakuraBullet.cs @@ -13,6 +13,7 @@ public class SakuraBullet : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { ProjectileID.Sets.MinionShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/SarosMicrosun.cs b/Projectiles/Summon/SarosMicrosun.cs index eba68327a0..773a7cb02c 100644 --- a/Projectiles/Summon/SarosMicrosun.cs +++ b/Projectiles/Summon/SarosMicrosun.cs @@ -17,6 +17,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 6; ProjectileID.Sets.MinionSacrificable[Projectile.type] = true; ProjectileID.Sets.MinionTargettingFeature[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/SarosSunfire.cs b/Projectiles/Summon/SarosSunfire.cs index 4e2cc361ea..5b63b91ce6 100644 --- a/Projectiles/Summon/SarosSunfire.cs +++ b/Projectiles/Summon/SarosSunfire.cs @@ -17,6 +17,7 @@ public class SarosSunfire : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { ProjectileID.Sets.MinionShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/SiriusBeam.cs b/Projectiles/Summon/SiriusBeam.cs index 52185dadfc..546a28db58 100644 --- a/Projectiles/Summon/SiriusBeam.cs +++ b/Projectiles/Summon/SiriusBeam.cs @@ -14,6 +14,7 @@ public class SiriusBeam : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { ProjectileID.Sets.MinionShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/SlimePuppet.cs b/Projectiles/Summon/SlimePuppet.cs index 2b602008f7..139d44738a 100644 --- a/Projectiles/Summon/SlimePuppet.cs +++ b/Projectiles/Summon/SlimePuppet.cs @@ -18,6 +18,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.MinionTargettingFeature[Projectile.type] = true; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 1; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/SmallAresArms/MinionGaussNuke.cs b/Projectiles/Summon/SmallAresArms/MinionGaussNuke.cs index e00c901ab2..a8162edc09 100644 --- a/Projectiles/Summon/SmallAresArms/MinionGaussNuke.cs +++ b/Projectiles/Summon/SmallAresArms/MinionGaussNuke.cs @@ -12,7 +12,11 @@ public class MinionGaussNuke : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Summon"; - public override void SetStaticDefaults() => ProjectileID.Sets.MinionShot[Projectile.type] = true; + public override void SetStaticDefaults() + { + ProjectileID.Sets.MinionShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; + } public override void SetDefaults() { diff --git a/Projectiles/Summon/SmallAresArms/MinionPlasmaBlast.cs b/Projectiles/Summon/SmallAresArms/MinionPlasmaBlast.cs index c5f1955ef0..3b2901912d 100644 --- a/Projectiles/Summon/SmallAresArms/MinionPlasmaBlast.cs +++ b/Projectiles/Summon/SmallAresArms/MinionPlasmaBlast.cs @@ -17,6 +17,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; ProjectileID.Sets.MinionShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/SolarBeam.cs b/Projectiles/Summon/SolarBeam.cs index 2cf5edbfa2..5c06c551c7 100644 --- a/Projectiles/Summon/SolarBeam.cs +++ b/Projectiles/Summon/SolarBeam.cs @@ -12,6 +12,7 @@ public class SolarBeam : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { ProjectileID.Sets.MinionShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/TundraFlameBlossomsOrb.cs b/Projectiles/Summon/TundraFlameBlossomsOrb.cs index 5c2a2bf967..4bfad33162 100644 --- a/Projectiles/Summon/TundraFlameBlossomsOrb.cs +++ b/Projectiles/Summon/TundraFlameBlossomsOrb.cs @@ -21,6 +21,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; ProjectileID.Sets.MinionShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/Umbrella/MagicBird.cs b/Projectiles/Summon/Umbrella/MagicBird.cs index 2672893275..9c6a8104bc 100644 --- a/Projectiles/Summon/Umbrella/MagicBird.cs +++ b/Projectiles/Summon/Umbrella/MagicBird.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.TrailCacheLength[Projectile.type] = 5; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; ProjectileID.Sets.MinionShot[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/VileFeederProjectile.cs b/Projectiles/Summon/VileFeederProjectile.cs index 8e0b672027..6593fee1ce 100644 --- a/Projectiles/Summon/VileFeederProjectile.cs +++ b/Projectiles/Summon/VileFeederProjectile.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() { Main.projFrames[Type] = 4; ProjectileID.Sets.MinionShot[Type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/VoidConcentrationOrb.cs b/Projectiles/Summon/VoidConcentrationOrb.cs index f1f31a7547..002de06ce7 100644 --- a/Projectiles/Summon/VoidConcentrationOrb.cs +++ b/Projectiles/Summon/VoidConcentrationOrb.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 4; ProjectileID.Sets.MinionShot[Projectile.type] = true; ProjectileID.Sets.MinionTargettingFeature[Projectile.type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/WitherBolt.cs b/Projectiles/Summon/WitherBolt.cs index cbbafe4024..844e159984 100644 --- a/Projectiles/Summon/WitherBolt.cs +++ b/Projectiles/Summon/WitherBolt.cs @@ -16,6 +16,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.TrailingMode[Type] = 2; ProjectileID.Sets.TrailCacheLength[Type] = 25; ProjectileID.Sets.MinionShot[Type] = true; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Summon/WulfrumFusionBolt.cs b/Projectiles/Summon/WulfrumFusionBolt.cs index 2007486933..056314dfca 100644 --- a/Projectiles/Summon/WulfrumFusionBolt.cs +++ b/Projectiles/Summon/WulfrumFusionBolt.cs @@ -46,7 +46,7 @@ public NPC Target public override void SetStaticDefaults() { - + ProjectileID.Sets.CultistIsResistantTo[Type] = true; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 20; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; } diff --git a/Projectiles/Summon/YharonMinionFireball.cs b/Projectiles/Summon/YharonMinionFireball.cs index 61c54b2438..a28383d96e 100644 --- a/Projectiles/Summon/YharonMinionFireball.cs +++ b/Projectiles/Summon/YharonMinionFireball.cs @@ -19,6 +19,7 @@ public override void SetStaticDefaults() ProjectileID.Sets.MinionShot[Projectile.type] = true; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 8; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Typeless/BasicPlagueBee.cs b/Projectiles/Typeless/BasicPlagueBee.cs index 6122f85d3a..c60a1d85f3 100644 --- a/Projectiles/Typeless/BasicPlagueBee.cs +++ b/Projectiles/Typeless/BasicPlagueBee.cs @@ -23,6 +23,7 @@ public class BasicPlagueBee : ModProjectile, ILocalizedModType public override void SetStaticDefaults() { Main.projFrames[Projectile.type] = 4; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Typeless/CursorProj.cs b/Projectiles/Typeless/CursorProj.cs index af813ea592..1fd093a0aa 100644 --- a/Projectiles/Typeless/CursorProj.cs +++ b/Projectiles/Typeless/CursorProj.cs @@ -14,6 +14,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 1; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Typeless/CursorProjSplit.cs b/Projectiles/Typeless/CursorProjSplit.cs index 1031a67052..af1b6d6967 100644 --- a/Projectiles/Typeless/CursorProjSplit.cs +++ b/Projectiles/Typeless/CursorProjSplit.cs @@ -16,6 +16,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 1; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Typeless/EmpyreanGlob.cs b/Projectiles/Typeless/EmpyreanGlob.cs index e37baee7dd..ca6b639559 100644 --- a/Projectiles/Typeless/EmpyreanGlob.cs +++ b/Projectiles/Typeless/EmpyreanGlob.cs @@ -8,6 +8,7 @@ namespace CalamityMod.Projectiles.Typeless public class EmpyreanGlob : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Typeless"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 20; diff --git a/Projectiles/Typeless/EmpyreanMarble.cs b/Projectiles/Typeless/EmpyreanMarble.cs index 1b778ace31..7345791cff 100644 --- a/Projectiles/Typeless/EmpyreanMarble.cs +++ b/Projectiles/Typeless/EmpyreanMarble.cs @@ -10,6 +10,7 @@ public class EmpyreanMarble : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Typeless"; public override string Texture => "CalamityMod/Projectiles/Healing/EmpyreanHealOrb"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 4; diff --git a/Projectiles/Typeless/EmpyreanStellarDetritus.cs b/Projectiles/Typeless/EmpyreanStellarDetritus.cs index 3a758b25e4..675d6cd6da 100644 --- a/Projectiles/Typeless/EmpyreanStellarDetritus.cs +++ b/Projectiles/Typeless/EmpyreanStellarDetritus.cs @@ -9,6 +9,7 @@ namespace CalamityMod.Projectiles.Typeless public class EmpyreanStellarDetritus : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Typeless"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 20; diff --git a/Projectiles/Typeless/GemTechArmorGem.cs b/Projectiles/Typeless/GemTechArmorGem.cs index 21dc514a86..0345c6d60a 100644 --- a/Projectiles/Typeless/GemTechArmorGem.cs +++ b/Projectiles/Typeless/GemTechArmorGem.cs @@ -24,6 +24,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailingMode[Projectile.type] = 1; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 20; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Typeless/GodKiller.cs b/Projectiles/Typeless/GodKiller.cs index d353152be2..d78fab94bf 100644 --- a/Projectiles/Typeless/GodKiller.cs +++ b/Projectiles/Typeless/GodKiller.cs @@ -15,6 +15,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; ProjectileID.Sets.TrailingMode[Projectile.type] = 1; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Typeless/HydrothermicFlare.cs b/Projectiles/Typeless/HydrothermicFlare.cs index ecbcaa7ab9..67236f2d47 100644 --- a/Projectiles/Typeless/HydrothermicFlare.cs +++ b/Projectiles/Typeless/HydrothermicFlare.cs @@ -10,6 +10,7 @@ public class HydrothermicFlare : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Typeless"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 8; diff --git a/Projectiles/Typeless/HydrothermicFlareRogue.cs b/Projectiles/Typeless/HydrothermicFlareRogue.cs index cc97baf05e..3b5a45c826 100644 --- a/Projectiles/Typeless/HydrothermicFlareRogue.cs +++ b/Projectiles/Typeless/HydrothermicFlareRogue.cs @@ -9,6 +9,7 @@ public class HydrothermicFlareRogue : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Typeless"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 8; diff --git a/Projectiles/Typeless/HydrothermicSphere.cs b/Projectiles/Typeless/HydrothermicSphere.cs index 4973fa9b50..2b2ef7da6b 100644 --- a/Projectiles/Typeless/HydrothermicSphere.cs +++ b/Projectiles/Typeless/HydrothermicSphere.cs @@ -10,6 +10,7 @@ public class HydrothermicSphere : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Typeless"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 4; diff --git a/Projectiles/Typeless/KelvinCatalystStar.cs b/Projectiles/Typeless/KelvinCatalystStar.cs index 184570c27d..736dfa139a 100644 --- a/Projectiles/Typeless/KelvinCatalystStar.cs +++ b/Projectiles/Typeless/KelvinCatalystStar.cs @@ -13,6 +13,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailCacheLength[Projectile.type] = 4; ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Typeless/LunicBeam.cs b/Projectiles/Typeless/LunicBeam.cs index 99360f627e..d96473fb3d 100644 --- a/Projectiles/Typeless/LunicBeam.cs +++ b/Projectiles/Typeless/LunicBeam.cs @@ -12,6 +12,7 @@ public class LunicBeam : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Typeless"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 8; diff --git a/Projectiles/Typeless/MagnusBeam.cs b/Projectiles/Typeless/MagnusBeam.cs index c5ca9718f5..e18111575e 100644 --- a/Projectiles/Typeless/MagnusBeam.cs +++ b/Projectiles/Typeless/MagnusBeam.cs @@ -14,6 +14,7 @@ namespace CalamityMod.Projectiles.Typeless public class MagnusBeam : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Typeless"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 8; diff --git a/Projectiles/Typeless/MythrilFlare.cs b/Projectiles/Typeless/MythrilFlare.cs index 56ebc10890..cce4095fac 100644 --- a/Projectiles/Typeless/MythrilFlare.cs +++ b/Projectiles/Typeless/MythrilFlare.cs @@ -20,6 +20,7 @@ public override void SetStaticDefaults() { ProjectileID.Sets.TrailingMode[Projectile.type] = 1; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 15; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Typeless/Nanotech.cs b/Projectiles/Typeless/Nanotech.cs index a5867ff07c..697c8bc0c8 100644 --- a/Projectiles/Typeless/Nanotech.cs +++ b/Projectiles/Typeless/Nanotech.cs @@ -8,6 +8,7 @@ namespace CalamityMod.Projectiles.Typeless public class Nanotech : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Typeless"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 26; diff --git a/Projectiles/Typeless/NebulaStar.cs b/Projectiles/Typeless/NebulaStar.cs index 8c988c24e1..2ef868b341 100644 --- a/Projectiles/Typeless/NebulaStar.cs +++ b/Projectiles/Typeless/NebulaStar.cs @@ -3,6 +3,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Terraria; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Typeless @@ -10,6 +11,7 @@ namespace CalamityMod.Projectiles.Typeless public class NebulaStar : BaseSporeSacProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Typeless"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = Projectile.height = 34; diff --git a/Projectiles/Typeless/PendantProjectile3.cs b/Projectiles/Typeless/PendantProjectile3.cs index cf8165e20d..9b1acd04c9 100644 --- a/Projectiles/Typeless/PendantProjectile3.cs +++ b/Projectiles/Typeless/PendantProjectile3.cs @@ -9,6 +9,7 @@ namespace CalamityMod.Projectiles.Typeless public class PendantProjectile3 : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Typeless"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 14; diff --git a/Projectiles/Typeless/StickyFeatherAero.cs b/Projectiles/Typeless/StickyFeatherAero.cs index ca6585e9d3..6da5082c5c 100644 --- a/Projectiles/Typeless/StickyFeatherAero.cs +++ b/Projectiles/Typeless/StickyFeatherAero.cs @@ -10,6 +10,7 @@ public class StickyFeatherAero : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Typeless"; public override string Texture => "CalamityMod/Projectiles/Magic/StickyFeather"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 10; diff --git a/Projectiles/Typeless/SuicideBomberDemon.cs b/Projectiles/Typeless/SuicideBomberDemon.cs index fb665cd92b..6c7210ecb6 100644 --- a/Projectiles/Typeless/SuicideBomberDemon.cs +++ b/Projectiles/Typeless/SuicideBomberDemon.cs @@ -26,6 +26,7 @@ public override void SetStaticDefaults() Main.projFrames[Projectile.type] = 12; ProjectileID.Sets.TrailingMode[Projectile.type] = 2; ProjectileID.Sets.TrailCacheLength[Projectile.type] = 11; + ProjectileID.Sets.CultistIsResistantTo[Type] = true; } public override void SetDefaults() diff --git a/Projectiles/Typeless/TarraEnergy.cs b/Projectiles/Typeless/TarraEnergy.cs index 35c30797b4..7d71c32950 100644 --- a/Projectiles/Typeless/TarraEnergy.cs +++ b/Projectiles/Typeless/TarraEnergy.cs @@ -10,6 +10,7 @@ public class TarraEnergy : ModProjectile, ILocalizedModType public new string LocalizationCategory => "Projectiles.Typeless"; public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + public override void SetStaticDefaults() => ProjectileID.Sets.CultistIsResistantTo[Type] = true; public override void SetDefaults() { Projectile.width = 4; From cf793b05fc8fa6ff9d246b88c98cf044b05820c6 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Mon, 26 May 2025 16:35:09 -0400 Subject: [PATCH 232/401] Mass fix batch #1 1 - Fixed Astral Ore oob error 2 - Fixed a grammatical error in Blast Barrel's tooltip 3 - Fixed Blood Boiler stating the wrong chance to consume HP 4 - Fixed brimstone darts having a larger hitbox than intended 4 - Fixed Brimstone Heart artery trails not appearing 5 - Fixed vanilla bug of Gold Chests being able to contain Meteorite Bars 6 - Fixed Jousting Lance damage formula 7 - Fixed Metastasis index oob error 8 - Fixed Obstructed effect not drawing when gravity is flipped 9 - Fixed exploit with Overloaded Blaster damage when piercing 10 - Fixed Statigel armor paladin minion framing 11 - Fixed SCal being able to deal contact damage on the first frame of spawning 12 - Fixed SCal being able to fire brimstone dart spreads during bros spawn animation 13 - Fixed SCal's brimstone flame skulls briefly being able to deal damage after the bullet hell ends 14 - Fixed Ultimus Cleaver being considered true melee 15 - Fixed Wulfrum Screwdriver not being considered true melee --- ILEditing/MechanicILChanges.cs | 2 +- Items/Weapons/Melee/UltimusCleaver.cs | 4 +++- Items/Weapons/Melee/WulfrumScrewdriver.cs | 2 +- .../Mods.CalamityMod.Items.Weapons.Ranged.hjson | 2 +- .../Mods.CalamityMod.Items.Weapons.Rogue.hjson | 2 +- NPCs/SupremeCalamitas/BrimstoneHeart.cs | 14 ++++++++------ NPCs/SupremeCalamitas/SupremeCalamitas.cs | 10 ++++++---- Projectiles/Boss/BrimstoneBarrage.cs | 2 +- Projectiles/Boss/BrimstoneWave.cs | 6 +++--- Projectiles/CalamityGlobalProjectile.cs | 6 +++--- Projectiles/Melee/WulfrumScrewdriverProj.cs | 2 +- Projectiles/Ranged/SlimeBolt.cs | 2 +- Projectiles/Summon/CorruptionSlimeGodMinion.cs | 13 ++++++++++++- Projectiles/Summon/CrimsonSlimeGodMinion.cs | 13 ++++++++++++- Projectiles/Summon/SepulcherMinion.cs | 4 ++-- Systems/WorldgenManagementSystem.cs | 14 ++++++++++++++ Tiles/Ores/AstralOre.cs | 3 +++ 17 files changed, 73 insertions(+), 28 deletions(-) diff --git a/ILEditing/MechanicILChanges.cs b/ILEditing/MechanicILChanges.cs index fb4fe1510e..93488e753c 100644 --- a/ILEditing/MechanicILChanges.cs +++ b/ILEditing/MechanicILChanges.cs @@ -728,7 +728,7 @@ private static void UseCoolFireCursorEffect(Terraria.On_Main.orig_DrawCursor ori private static void AdditiveDrawing(ILContext il) { ILCursor cursor = new(il); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchCall("DrawWhite"))) + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchCall("Draw"))) return; cursor.EmitDelegate(() => diff --git a/Items/Weapons/Melee/UltimusCleaver.cs b/Items/Weapons/Melee/UltimusCleaver.cs index 655d248f21..3c7b6dd96e 100644 --- a/Items/Weapons/Melee/UltimusCleaver.cs +++ b/Items/Weapons/Melee/UltimusCleaver.cs @@ -2,6 +2,7 @@ using Microsoft.Xna.Framework; using Terraria; using Terraria.Audio; +using Terraria.DataStructures; using Terraria.ID; using Terraria.ModLoader; @@ -26,8 +27,9 @@ public override void SetDefaults() Item.value = CalamityGlobalItem.RarityYellowBuyPrice; Item.autoReuse = true; Item.UseSound = SoundID.Item1; + Item.shoot = ModContent.ProjectileType(); // Dummy argument to ensure it doesn't get set to true melee } - + public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) => false; public override void OnHitNPC(Player player, NPC target, NPC.HitInfo hit, int damageDone) { target.AddBuff(BuffID.OnFire3, 360); diff --git a/Items/Weapons/Melee/WulfrumScrewdriver.cs b/Items/Weapons/Melee/WulfrumScrewdriver.cs index ad663b26d5..94b7ff804c 100644 --- a/Items/Weapons/Melee/WulfrumScrewdriver.cs +++ b/Items/Weapons/Melee/WulfrumScrewdriver.cs @@ -66,7 +66,7 @@ public override void SetDefaults() Item.width = 14; Item.height = 50; Item.damage = 12; - Item.DamageType = DamageClass.Melee; + Item.DamageType = TrueMeleeDamageClass.Instance; Item.useAnimation = DefaultTime + WulfrumScrewdriverProj.MaxTime; Item.useStyle = ItemUseStyleID.Shoot; Item.useTime = DefaultTime + WulfrumScrewdriverProj.MaxTime; diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson index d15cb408ad..2b819b79be 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson @@ -183,7 +183,7 @@ BloodBoiler: { ''' Fires twin streams of life stealing bloodfire that returns to you Uses your health as ammo - 40% chance to save health + 60% chance to save health ''' } diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Rogue.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Rogue.hjson index 69ed27ce98..13b9b83d4a 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Rogue.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Rogue.hjson @@ -64,7 +64,7 @@ BlastBarrel: { Tooltip: ''' Throws a rolling barrel that explodes on wall collision - Stealth strikes makes the barrel bounce twice before disappearing with varied effects after each bounce + Stealth strikes make the barrel bounce twice before disappearing with varied effects after each bounce 'Some people used to jump over these' ''' } diff --git a/NPCs/SupremeCalamitas/BrimstoneHeart.cs b/NPCs/SupremeCalamitas/BrimstoneHeart.cs index fd529f0e33..46a94b1db7 100644 --- a/NPCs/SupremeCalamitas/BrimstoneHeart.cs +++ b/NPCs/SupremeCalamitas/BrimstoneHeart.cs @@ -115,16 +115,18 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d if (NPC.IsABestiaryIconDummy) return true; + spriteBatch.ExitShaderRegion(); + for (int i = 0; i < ChainEndpoints.Count; i++) { - List points = new List() - { - NPC.Center, - ChainEndpoints[i] + NPC.DirectionTo(ChainEndpoints[i]) * 25f - }; + float dist = NPC.Distance(ChainEndpoints[i]); + List points = new List(); + for (int j = 0; j < 4; j++) + points.Add(NPC.Center + NPC.DirectionTo(ChainEndpoints[i]) * dist * 0.25f * j); + points.Add(ChainEndpoints[i] + NPC.DirectionTo(ChainEndpoints[i]) * 18f); + PrimitiveRenderer.RenderTrail(points, new(PrimitiveWidthFunction, PrimitiveColorFunction), 40); } - return true; } diff --git a/NPCs/SupremeCalamitas/SupremeCalamitas.cs b/NPCs/SupremeCalamitas/SupremeCalamitas.cs index 42f996b630..9904de5f8d 100644 --- a/NPCs/SupremeCalamitas/SupremeCalamitas.cs +++ b/NPCs/SupremeCalamitas/SupremeCalamitas.cs @@ -2271,7 +2271,7 @@ public override void AI() GeneralParticleHandler.SpawnParticle(spark2); } - if (Main.netMode != NetmodeID.MultiplayerClient) + if (Main.netMode != NetmodeID.MultiplayerClient && attackPause == 0) { Projectile.NewProjectile(NPC.GetSource_FromAI(), projectileSpawn, projectileVelocity, randomShot, gigablastDamage, 0f, Main.myPlayer, 0f, 2f); NPC.netUpdate = true; @@ -2290,7 +2290,7 @@ public override void AI() GeneralParticleHandler.SpawnParticle(spark2); } - if (Main.netMode != NetmodeID.MultiplayerClient) + if (Main.netMode != NetmodeID.MultiplayerClient && attackPause == 0) { Projectile.NewProjectile(NPC.GetSource_FromAI(), projectileSpawn, projectileVelocity, randomShot, fireblastDamage, 0f, Main.myPlayer, 0f, 2f); NPC.netUpdate = true; @@ -2312,7 +2312,7 @@ public override void AI() GeneralParticleHandler.SpawnParticle(orb); } - if (Main.netMode != NetmodeID.MultiplayerClient) + if (Main.netMode != NetmodeID.MultiplayerClient && attackPause == 0) { float projectileVelocityToPass = projectileVelocity.Length() * 1.3f; Vector2 perturbedSpeed = projectileVelocity.RotatedBy(MathHelper.Lerp(-rotation, rotation, j / (float)(numProj - 1))); @@ -3556,7 +3556,9 @@ public override bool CanHitPlayer(Player target, ref int cooldownSlot) float _ = 0f; bool collidingWithShield = Collision.CheckAABBvLineCollision(target.TopLeft, target.Size, shieldTop, shieldBottom, 64f, ref _) && shieldOpacity > 0.55f; - return collidingWithShield || NPC.Hitbox.Intersects(target.Hitbox); + // CIT 16MAY2025: SCal must have contact damage set on the first frame to preserve difficulty mode stat scaling, sometimes leading to people getting hit if on top of her. + // Thus, also check if the arena has spawned, since that will not be true on the first frame. + return (collidingWithShield || NPC.Hitbox.Intersects(target.Hitbox)) && spawnArena; } public override void FindFrame(int frameHeight) diff --git a/Projectiles/Boss/BrimstoneBarrage.cs b/Projectiles/Boss/BrimstoneBarrage.cs index 5c4f0f70eb..344dee7f5e 100644 --- a/Projectiles/Boss/BrimstoneBarrage.cs +++ b/Projectiles/Boss/BrimstoneBarrage.cs @@ -161,6 +161,6 @@ public override bool PreDraw(ref Color lightColor) CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], lightColor, 1); return false; } - public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) => CalamityUtils.CircularHitboxCollision(Projectile.Center, 18 * Projectile.scale, targetHitbox); + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) => CalamityUtils.CircularHitboxCollision(Projectile.Center, 10 * Projectile.scale, targetHitbox); } } diff --git a/Projectiles/Boss/BrimstoneWave.cs b/Projectiles/Boss/BrimstoneWave.cs index abb32499e3..063a83b776 100644 --- a/Projectiles/Boss/BrimstoneWave.cs +++ b/Projectiles/Boss/BrimstoneWave.cs @@ -62,10 +62,10 @@ public override void AI() if (Projectile.frame > 3) Projectile.frame = 0; - if (Projectile.timeLeft < 30) - Projectile.Opacity = MathHelper.Clamp(Projectile.timeLeft / 30f, 0f, 1f); + if (Projectile.timeLeft < 60) + Projectile.Opacity = MathHelper.Clamp(Projectile.timeLeft / 60f, 0f, 1f); else - Projectile.Opacity = MathHelper.Clamp(1f - ((Projectile.timeLeft - 1170) / 30f), 0f, 1f); + Projectile.Opacity = MathHelper.Clamp(1f - ((Projectile.timeLeft - 1140) / 60f), 0f, 1f); Lighting.AddLight(Projectile.Center, 0.5f * Projectile.Opacity, 0f, 0f); diff --git a/Projectiles/CalamityGlobalProjectile.cs b/Projectiles/CalamityGlobalProjectile.cs index b80b8e3805..5478122efc 100644 --- a/Projectiles/CalamityGlobalProjectile.cs +++ b/Projectiles/CalamityGlobalProjectile.cs @@ -4190,13 +4190,13 @@ public override void ModifyHitNPC(Projectile projectile, NPC target, ref NPC.Hit } } - // The vanilla damage Jousting Lance multiplier is as follows. Calamity overrides this with a new formula. - // damageScale = 0.1f + player.velocity.Length() / 7f * 0.9f if (projectile.type == ProjectileID.JoustingLance || projectile.type == ProjectileID.HallowJoustingLance || projectile.type == ProjectileID.ShadowJoustingLance) { + // The vanilla damage Jousting Lance multiplier is as follows. Calamity overrides this with a new formula. + float vanillaVelocityDamageMultiplier = 0.1f + player.velocity.Length() / 7f * 0.9f; float baseVelocityDamageMultiplier = 0.01f + player.velocity.Length() * 0.002f; float calamityVelocityDamageMultiplier = 100f * (1f - (1f / (1f + baseVelocityDamageMultiplier))); - modifiers.SourceDamage *= calamityVelocityDamageMultiplier; + modifiers.SourceDamage *= calamityVelocityDamageMultiplier / vanillaVelocityDamageMultiplier; } // If applicable, use ricoshot bonus damage. diff --git a/Projectiles/Melee/WulfrumScrewdriverProj.cs b/Projectiles/Melee/WulfrumScrewdriverProj.cs index e5b86eea6a..1f76e30360 100644 --- a/Projectiles/Melee/WulfrumScrewdriverProj.cs +++ b/Projectiles/Melee/WulfrumScrewdriverProj.cs @@ -33,7 +33,7 @@ public class WulfrumScrewdriverProj : ModProjectile public override void SetDefaults() { - Projectile.DamageType = DamageClass.Melee; + Projectile.DamageType = TrueMeleeDamageClass.Instance; Projectile.width = 14; Projectile.height = 50; Projectile.tileCollide = false; diff --git a/Projectiles/Ranged/SlimeBolt.cs b/Projectiles/Ranged/SlimeBolt.cs index efe0d6612b..480bb7d7d8 100644 --- a/Projectiles/Ranged/SlimeBolt.cs +++ b/Projectiles/Ranged/SlimeBolt.cs @@ -50,7 +50,7 @@ public override void AI() if (Time == EmpowerTime) { Projectile.penetrate = 1; - Projectile.damage = (int)((Projectile.damage / Math.Pow(DamageFalloff, Projectile.numHits)) * 1.6f); // 7/4 + Projectile.damage = (int)(Projectile.originalDamage * 1.6f); Projectile.velocity *= 0f; Projectile.rotation = Main.rand.NextFloat(0f, MathHelper.TwoPi); diff --git a/Projectiles/Summon/CorruptionSlimeGodMinion.cs b/Projectiles/Summon/CorruptionSlimeGodMinion.cs index 7127930079..6a2fd85620 100644 --- a/Projectiles/Summon/CorruptionSlimeGodMinion.cs +++ b/Projectiles/Summon/CorruptionSlimeGodMinion.cs @@ -1,7 +1,9 @@ using CalamityMod.Buffs.Summon; using CalamityMod.CalPlayer; using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; using Terraria; +using Terraria.GameContent; using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Summon @@ -9,11 +11,12 @@ namespace CalamityMod.Projectiles.Summon public class CorruptionSlimeGodMinion : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Summon"; + public override string Texture => "CalamityMod/Projectiles/Summon/CorroslimeMinion"; public float dust = 0f; public override void SetStaticDefaults() { - Main.projFrames[Projectile.type] = 2; + Main.projFrames[Projectile.type] = 6; ProjectileID.Sets.MinionSacrificable[Projectile.type] = true; ProjectileID.Sets.MinionTargettingFeature[Projectile.type] = true; } @@ -84,5 +87,13 @@ public override void AI() } public override bool OnTileCollide(Vector2 oldVelocity) => false; + + public override bool PreDraw(ref Color lightColor) + { + Texture2D slom = TextureAssets.Projectile[Type].Value; + Rectangle frame = slom.Frame(1, Main.projFrames[Type], 0, Projectile.frame); + Main.EntitySpriteDraw(slom, Projectile.Center - Main.screenPosition, frame, Projectile.GetAlpha(lightColor), Projectile.rotation, frame.Size() / 2f, Projectile.scale, SpriteEffects.None); + return false; + } } } diff --git a/Projectiles/Summon/CrimsonSlimeGodMinion.cs b/Projectiles/Summon/CrimsonSlimeGodMinion.cs index de7c9f436c..bf2cc01e45 100644 --- a/Projectiles/Summon/CrimsonSlimeGodMinion.cs +++ b/Projectiles/Summon/CrimsonSlimeGodMinion.cs @@ -1,7 +1,9 @@ using CalamityMod.Buffs.Summon; using CalamityMod.CalPlayer; using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; using Terraria; +using Terraria.GameContent; using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Summon @@ -9,11 +11,12 @@ namespace CalamityMod.Projectiles.Summon public class CrimsonSlimeGodMinion : ModProjectile, ILocalizedModType { public new string LocalizationCategory => "Projectiles.Summon"; + public override string Texture => "CalamityMod/Projectiles/Summon/CrimslimeMinion"; public float dust = 0f; public override void SetStaticDefaults() { - Main.projFrames[Projectile.type] = 2; + Main.projFrames[Projectile.type] = 6; ProjectileID.Sets.MinionSacrificable[Projectile.type] = true; ProjectileID.Sets.MinionTargettingFeature[Projectile.type] = true; } @@ -84,5 +87,13 @@ public override void AI() } public override bool OnTileCollide(Vector2 oldVelocity) => false; + + public override bool PreDraw(ref Color lightColor) + { + Texture2D slom = TextureAssets.Projectile[Type].Value; + Rectangle frame = slom.Frame(1, Main.projFrames[Type], 0, Projectile.frame); + Main.EntitySpriteDraw(slom, Projectile.Center - Main.screenPosition, frame, Projectile.GetAlpha(lightColor), Projectile.rotation, frame.Size() / 2f, Projectile.scale, SpriteEffects.None); + return false; + } } } diff --git a/Projectiles/Summon/SepulcherMinion.cs b/Projectiles/Summon/SepulcherMinion.cs index 93860c3ce5..e915f17f82 100644 --- a/Projectiles/Summon/SepulcherMinion.cs +++ b/Projectiles/Summon/SepulcherMinion.cs @@ -134,7 +134,7 @@ public override void SetDefaults() #region Syncing public override void SendExtraAI(BinaryWriter writer) { - if (Arms is null || Arms[0] is null) + if (Arms is null || Arms.Count == 0 || Arms[0] is null) Initialize(); writer.Write(IdleTimer); @@ -154,7 +154,7 @@ public override void SendExtraAI(BinaryWriter writer) public override void ReceiveExtraAI(BinaryReader reader) { - if (Arms is null || Arms[0] is null) + if (Arms is null || Arms.Count == 0 || Arms[0] is null) Initialize(); IdleTimer = reader.ReadInt32(); diff --git a/Systems/WorldgenManagementSystem.cs b/Systems/WorldgenManagementSystem.cs index 49ad227e92..2886021901 100644 --- a/Systems/WorldgenManagementSystem.cs +++ b/Systems/WorldgenManagementSystem.cs @@ -408,6 +408,20 @@ public override void PostWorldGen() } } + // Fix vanilla's stupidity with Gold Chests being able to have Meteorite Bars in them near the Underworld + if (isGoldChest) + { + for (int inventoryIndex = 0; inventoryIndex < 40; inventoryIndex++) + { + if (chest.item[inventoryIndex].type == ItemID.MeteoriteBar) + { + int oldStack = chest.item[inventoryIndex].stack; + chest.item[inventoryIndex].SetDefaults(WorldGen.genRand.NextBool() ? ItemID.PlatinumBar : ItemID.GoldBar); + chest.item[inventoryIndex].stack = oldStack; + } + } + } + // Give Dead Man's Chests better loot. if (isDeadManChest) { diff --git a/Tiles/Ores/AstralOre.cs b/Tiles/Ores/AstralOre.cs index 2b9da5ece9..b3d8ab14d2 100644 --- a/Tiles/Ores/AstralOre.cs +++ b/Tiles/Ores/AstralOre.cs @@ -42,6 +42,9 @@ public override void SetStaticDefaults() } public override void NearbyEffects(int i, int j, bool closer) { + if (j < 2) + return; + Tile tile = Main.tile[i, j]; Tile up = Main.tile[i, j - 1]; Tile up2 = Main.tile[i, j - 2]; From 50580e39490be93359f629f5595634edfd481559 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Mon, 26 May 2025 17:09:19 -0400 Subject: [PATCH 233/401] Mass fix batch #2 1 - Fixed Aureus Cell not granting buffs when consumed though Quick Mana 2 - Fixed Hadal Stew not giving reduced Potion Sickness when consumed though Quick Heal 3 - Fixed Red Wine's tooltip not displaying the correct heal amount with Baguette 4 - Fixed Red Wine not restoring the correct amount of health when consumed through Quick Heal with Baguette 5 - Fixed White Wine not applying its buff when consumed through Quick Mana 6 - Celestial Onion now gives Master slot, fixing issues with loadouts 7 - Fixed issues with Flight Bar drawing when the player has 0 max flight time 8 - Fixed point-blank distance check being very choppy for projectiles with extra updates 9 - Fixed Resurrection Butterfly minions disappearing when attacking; is bundled with balance changes 10 - Fixed Town NPC sells that require happiness not being sold in Remix 11 - Codebreaker can no longer be placed on Teleporters to fix game crash from breaking Teleporter with Codebreaker on it 12 - Fixed Whispering Maelstrom damage being triggered while in graze radius of graze accessories from Fargo's Souls --- Balancing/BalancingChangesManager.cs | 7 +-- ILEditing/ILChangesLoading.cs | 1 + ILEditing/MechanicILChanges.cs | 11 +++++ Items/PermanentBoosters/CelestialOnion.cs | 15 ------ Items/Potions/Alcohol/RedWine.cs | 5 +- Items/Potions/Alcohol/WhiteWine.cs | 3 +- Items/Potions/AureusCell.cs | 3 +- Items/Potions/HadalStew.cs | 3 +- Items/Weapons/Summon/ResurrectionButterfly.cs | 36 ++------------ NPCs/CalamityGlobalTownNPC.cs | 36 +++++++------- NPCs/TownNPCs/DILF.cs | 2 +- NPCs/TownNPCs/SEAHOE.cs | 4 +- NPCs/TownNPCs/THIEF.cs | 4 +- Projectiles/Boss/BrimstoneMonster.cs | 12 +++-- Projectiles/CalamityGlobalProjectile.cs | 8 ++- Projectiles/Summon/PinkButterfly.cs | 49 ++++++++++--------- Projectiles/Summon/PurpleButterfly.cs | 32 ++++++------ Tiles/DraedonSummoner/CodebreakerTile.cs | 13 +++++ UI/FlightBar/FlightBar.cs | 4 +- Utilities/GenericAIUtils.cs | 5 +- 20 files changed, 122 insertions(+), 131 deletions(-) diff --git a/Balancing/BalancingChangesManager.cs b/Balancing/BalancingChangesManager.cs index c36cc58ade..9434266367 100644 --- a/Balancing/BalancingChangesManager.cs +++ b/Balancing/BalancingChangesManager.cs @@ -216,8 +216,8 @@ bool AotCThrowCombo(Projectile p) => // 20% vulnerability to The Hive's bees. NPCSpecificBalancingChanges.Add(new NPCBalancingChange(NPCID.DukeFishron, Do(new ProjectileResistBalancingRule(1.2f, ProjectileType())))); - // 35% vulnerability to Resurrection Butterfly. - NPCSpecificBalancingChanges.Add(new NPCBalancingChange(NPCID.DukeFishron, Do(new ProjectileResistBalancingRule(1.35f, ProjectileType(), ProjectileType())))); + // 25% vulnerability to Resurrection Butterfly. + NPCSpecificBalancingChanges.Add(new NPCBalancingChange(NPCID.DukeFishron, Do(new ProjectileResistBalancingRule(1.25f, ProjectileType(), ProjectileType())))); #endregion #region Empress of Light @@ -240,9 +240,6 @@ bool AotCThrowCombo(Projectile p) => // 20% resist to Nightglow. NPCSpecificBalancingChanges.Add(new NPCBalancingChange(NPCID.CultistBoss, Do(new ProjectileResistBalancingRule(0.8f, ProjectileID.FairyQueenMagicItemShot)))); - - // 20% resist to Resurrection Butterfly. - NPCSpecificBalancingChanges.Add(new NPCBalancingChange(NPCID.CultistBoss, Do(new ProjectileResistBalancingRule(0.8f, ProjectileType(), ProjectileType())))); #endregion #region Astrum Deus diff --git a/ILEditing/ILChangesLoading.cs b/ILEditing/ILChangesLoading.cs index c2ea95f2b1..02ba8c8fab 100644 --- a/ILEditing/ILChangesLoading.cs +++ b/ILEditing/ILChangesLoading.cs @@ -84,6 +84,7 @@ public override void OnModLoad() On_Player.UpdateItemDye += FindCalamityItemDyeShader; On_AWorldListItem.GetDifficulty += GetDifficultyOverride; On_Item.GetShimmered += ShimmerEffectEdits; + On_Player.IsItemSlotUnlockedAndUsable += MasterModeCelestialOnionCheck; // Mana Burn (Chaos Stone) and Chalice of the Blood God IL_Player.ApplyLifeAndOrMana += ManaSicknessAndChaliceBufferHeal; diff --git a/ILEditing/MechanicILChanges.cs b/ILEditing/MechanicILChanges.cs index 93488e753c..dac8218ee8 100644 --- a/ILEditing/MechanicILChanges.cs +++ b/ILEditing/MechanicILChanges.cs @@ -1425,5 +1425,16 @@ public static void ShimmerEffectEdits(Terraria.On_Item.orig_GetShimmered orig, I } } #endregion + + #region Make Celestial Onion give the Master Mode slot + public static bool MasterModeCelestialOnionCheck(Terraria.On_Player.orig_IsItemSlotUnlockedAndUsable orig, Player self, int slot) + { + if ((slot == 9 || slot == 19) && self.Calamity().extraAccessoryML && !Main.gameMenu) + { + return true; + } + return orig(self, slot); + } + #endregion } } diff --git a/Items/PermanentBoosters/CelestialOnion.cs b/Items/PermanentBoosters/CelestialOnion.cs index 4db480cb29..8482d2e2a8 100644 --- a/Items/PermanentBoosters/CelestialOnion.cs +++ b/Items/PermanentBoosters/CelestialOnion.cs @@ -40,19 +40,4 @@ public override bool CanUseItem(Player player) return true; } } - - public class CelestialOnionAccessorySlot : ModAccessorySlot - { - // Celestial Onion does not work in Master Mode. - public override bool IsEnabled() - { - // GetModPlayer will throw an index error in this step of the loading process for whatever reason - // We prematurely stop it from getting to that point - if (!Player.active || Main.masterMode) - return false; - - return Player.Calamity().extraAccessoryML; - } - public override bool IsHidden() => IsEmpty && !IsEnabled(); - } } diff --git a/Items/Potions/Alcohol/RedWine.cs b/Items/Potions/Alcohol/RedWine.cs index 3be0d99555..8d784c9097 100644 --- a/Items/Potions/Alcohol/RedWine.cs +++ b/Items/Potions/Alcohol/RedWine.cs @@ -31,10 +31,9 @@ public override void SetDefaults() Item.value = Item.buyPrice(0, 0, 65, 0); } - public override bool? UseItem(Player player) + public override void GetHealLife(Player player, bool quickHeal, ref int healValue) { - Item.healLife = player.Calamity().baguette ? 250 : 200; - return null; + healValue = player.Calamity().baguette ? 250 : 200; } public override void OnConsumeItem(Player player) diff --git a/Items/Potions/Alcohol/WhiteWine.cs b/Items/Potions/Alcohol/WhiteWine.cs index d15ade4beb..e52460a926 100644 --- a/Items/Potions/Alcohol/WhiteWine.cs +++ b/Items/Potions/Alcohol/WhiteWine.cs @@ -34,7 +34,7 @@ public override void SetDefaults() Item.value = Item.buyPrice(0, 4, 0, 0); } - public override bool? UseItem(Player player) + public override void OnConsumeItem(Player player) { if (PlayerInput.Triggers.JustPressed.QuickBuff) { @@ -50,7 +50,6 @@ public override void SetDefaults() } } player.AddBuff(Item.buffType, Item.buffTime); - return true; } public override void AddRecipes() { diff --git a/Items/Potions/AureusCell.cs b/Items/Potions/AureusCell.cs index 2393b8088c..3249adefee 100644 --- a/Items/Potions/AureusCell.cs +++ b/Items/Potions/AureusCell.cs @@ -32,7 +32,7 @@ public override void SetDefaults() Item.buffTime = CalamityUtils.SecondsToFrames(360f); } - public override bool? UseItem(Player player) + public override void OnConsumeItem(Player player) { if (PlayerInput.Triggers.JustPressed.QuickBuff) { @@ -49,7 +49,6 @@ public override void SetDefaults() } player.AddBuff(BuffID.MagicPower, Item.buffTime); player.AddBuff(BuffID.ManaRegeneration, Item.buffTime); - return true; } } } diff --git a/Items/Potions/HadalStew.cs b/Items/Potions/HadalStew.cs index a901b1bcab..1fbecce577 100644 --- a/Items/Potions/HadalStew.cs +++ b/Items/Potions/HadalStew.cs @@ -52,12 +52,11 @@ public override bool CanUseItem(Player player) return player.potionDelay <= 0 && player.Calamity().potionTimer <= 0; } - public override bool? UseItem(Player player) + public override void OnConsumeItem(Player player) { player.AddBuff(BuffType, BuffDuration); // fixes hardcoded potion sickness duration from quick heal (see CalamityPlayerMiscEffects.cs) player.Calamity().potionTimer = 2; - return true; } public override void AddRecipes() diff --git a/Items/Weapons/Summon/ResurrectionButterfly.cs b/Items/Weapons/Summon/ResurrectionButterfly.cs index 67a1b45685..e5dac4aa9f 100644 --- a/Items/Weapons/Summon/ResurrectionButterfly.cs +++ b/Items/Weapons/Summon/ResurrectionButterfly.cs @@ -36,39 +36,13 @@ public override void SetDefaults() public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) { - int i = Main.myPlayer; - float projSpeed = Item.shootSpeed; - Vector2 realPlayerPos = player.RotatedRelativePoint(player.MountedCenter, true); - float mouseXDist = (float)Main.mouseX + Main.screenPosition.X - realPlayerPos.X; - float mouseYDist = (float)Main.mouseY + Main.screenPosition.Y - realPlayerPos.Y; - if (player.gravDir == -1f) - { - mouseYDist = Main.screenPosition.Y + (float)Main.screenHeight - (float)Main.mouseY - realPlayerPos.Y; - } - float mouseDistance = (float)Math.Sqrt((double)(mouseXDist * mouseXDist + mouseYDist * mouseYDist)); - if ((float.IsNaN(mouseXDist) && float.IsNaN(mouseYDist)) || (mouseXDist == 0f && mouseYDist == 0f)) - { - mouseXDist = (float)player.direction; - mouseYDist = 0f; - mouseDistance = projSpeed; - } - else - { - mouseDistance = projSpeed / mouseDistance; - } - mouseXDist *= mouseDistance; - mouseYDist *= mouseDistance; - realPlayerPos.X = (float)Main.mouseX + Main.screenPosition.X; - realPlayerPos.Y = (float)Main.mouseY + Main.screenPosition.Y; - Vector2 spinningpoint = new Vector2(mouseXDist, mouseYDist); - spinningpoint = spinningpoint.RotatedBy(1.5707963705062866, default); - int p = Projectile.NewProjectile(source, realPlayerPos.X + spinningpoint.X, realPlayerPos.Y + spinningpoint.Y, spinningpoint.X, spinningpoint.Y, ModContent.ProjectileType(), damage, knockback, i, 0f, 0f); - if (Main.projectile.IndexInRange(p)) - Main.projectile[p].originalDamage = Item.damage; - spinningpoint = spinningpoint.RotatedBy(-3.1415927410125732, default); - p = Projectile.NewProjectile(source, realPlayerPos.X + spinningpoint.X, realPlayerPos.Y + spinningpoint.Y, spinningpoint.X, spinningpoint.Y, ModContent.ProjectileType(), damage, knockback, i, 0f, 0f); + Vector2 mouseDirection = Vector2.Normalize(Main.MouseWorld - player.Center) * Item.shootSpeed; + + int p = Projectile.NewProjectile(source, Main.MouseWorld, mouseDirection.RotatedBy(MathHelper.PiOver2), ModContent.ProjectileType(), damage, knockback, Main.myPlayer, 0f, 0f); if (Main.projectile.IndexInRange(p)) Main.projectile[p].originalDamage = Item.damage; + p = Projectile.NewProjectile(source, Main.MouseWorld, mouseDirection.RotatedBy(-MathHelper.PiOver2), ModContent.ProjectileType(), damage, knockback, Main.myPlayer, 0f, 0f); + Main.projectile[p].originalDamage = Item.damage; return false; } diff --git a/NPCs/CalamityGlobalTownNPC.cs b/NPCs/CalamityGlobalTownNPC.cs index c0944a024f..49310d2251 100644 --- a/NPCs/CalamityGlobalTownNPC.cs +++ b/NPCs/CalamityGlobalTownNPC.cs @@ -1094,16 +1094,16 @@ public override void ModifyShop(NPCShop shop) if (type == NPCID.Merchant) { - shop.AddWithCustomValue(ItemID.Bottle, Item.buyPrice(copper: 20), potionSells, Condition.HappyEnough) - .AddWithCustomValue(ItemID.WormholePotion, Item.buyPrice(silver: 5), potionSells, Condition.HappyEnough); - shop.Add(ItemID.HealingPotion, potionSells, Condition.HappyEnough, Condition.DownedEowOrBoc) - .Add(ItemID.ManaPotion, potionSells, Condition.HappyEnough, Condition.DownedEowOrBoc) + shop.AddWithCustomValue(ItemID.Bottle, Item.buyPrice(copper: 20), potionSells, Condition.HappyEnoughToSellPylons) + .AddWithCustomValue(ItemID.WormholePotion, Item.buyPrice(silver: 5), potionSells, Condition.HappyEnoughToSellPylons); + shop.Add(ItemID.HealingPotion, potionSells, Condition.HappyEnoughToSellPylons, Condition.DownedEowOrBoc) + .Add(ItemID.ManaPotion, potionSells, Condition.HappyEnoughToSellPylons, Condition.DownedEowOrBoc) .Add(ItemID.Flare, hasFlareGunUpgrade) .Add(ItemID.BlueFlare, hasFlareGunUpgrade) .AddWithCustomValue(ItemID.AngelStatue, Item.buyPrice(gold: 5), Condition.NpcIsPresent(NPCType())) - .AddWithCustomValue(ItemID.Burger, Item.buyPrice(gold: 5), Condition.HappyEnough, Condition.DownedSkeletron) - .AddWithCustomValue(ItemID.Hotdog, Item.buyPrice(gold: 5), Condition.HappyEnough, Condition.DownedSkeletron) - .AddWithCustomValue(ItemID.CoffeeCup, Item.buyPrice(gold: 2), Condition.HappyEnough); + .AddWithCustomValue(ItemID.Burger, Item.buyPrice(gold: 5), Condition.HappyEnoughToSellPylons, Condition.DownedSkeletron) + .AddWithCustomValue(ItemID.Hotdog, Item.buyPrice(gold: 5), Condition.HappyEnoughToSellPylons, Condition.DownedSkeletron) + .AddWithCustomValue(ItemID.CoffeeCup, Item.buyPrice(gold: 2), Condition.HappyEnoughToSellPylons); } if (type == NPCID.DyeTrader) @@ -1136,7 +1136,7 @@ public override void ModifyShop(NPCShop shop) .Add(ItemType(), revengeance) .AddWithCustomValue(ItemID.StylistKilLaKillScissorsIWish, Item.buyPrice(gold: 15)) .Add(ItemType(), Condition.NpcIsPresent(NPCType()), drunk) - .AddWithCustomValue(ItemID.ChocolateChipCookie, Item.buyPrice(gold: 3), Condition.HappyEnough, Condition.NpcIsPresent(NPCType())); + .AddWithCustomValue(ItemID.ChocolateChipCookie, Item.buyPrice(gold: 3), Condition.HappyEnoughToSellPylons, Condition.NpcIsPresent(NPCType())); } if (type == NPCID.Cyborg) @@ -1151,21 +1151,21 @@ public override void ModifyShop(NPCShop shop) shop.AddWithCustomValue(ItemID.JungleRose, Item.buyPrice(gold: 2)) .AddWithCustomValue(ItemID.NaturesGift, Item.buyPrice(gold: 10)) .Add(ItemType()) - .AddWithCustomValue(ItemID.Grapes, Item.buyPrice(gold: 2, silver: 50), Condition.HappyEnough, Condition.DownedSkeletron) + .AddWithCustomValue(ItemID.Grapes, Item.buyPrice(gold: 2, silver: 50), Condition.HappyEnoughToSellPylons, Condition.DownedSkeletron) .Add(ItemID.CorruptSeeds, Condition.CrimsonWorld, Condition.InGraveyard) .Add(ItemID.CrimsonSeeds, Condition.CorruptWorld, Condition.InGraveyard); } if (type == NPCID.GoblinTinkerer) { - shop.AddWithCustomValue(ItemID.StinkPotion, Item.buyPrice(silver: 25), potionSells, Condition.HappyEnough) + shop.AddWithCustomValue(ItemID.StinkPotion, Item.buyPrice(silver: 25), potionSells, Condition.HappyEnoughToSellPylons) .Add(ItemType()) - .AddWithCustomValue(ItemID.Spaghetti, Item.buyPrice(gold: 5), Condition.HappyEnough, Condition.DownedSkeletron); + .AddWithCustomValue(ItemID.Spaghetti, Item.buyPrice(gold: 5), Condition.HappyEnoughToSellPylons, Condition.DownedSkeletron); } if (type == NPCID.Mechanic) { - shop.AddWithCustomValue(ItemID.BuilderPotion, Item.buyPrice(gold: 4), potionSells, Condition.HappyEnough) + shop.AddWithCustomValue(ItemID.BuilderPotion, Item.buyPrice(gold: 4), potionSells, Condition.HappyEnoughToSellPylons) .AddWithCustomValue(ItemID.CombatWrench, Item.buyPrice(gold: 10)); } @@ -1211,14 +1211,14 @@ public override void ModifyShop(NPCShop shop) .Add(ItemType()) .Add(ItemType()) .AddWithCustomValue(ItemID.ButterflyDust, Item.buyPrice(gold: 10), Condition.DownedGolem) - .AddWithCustomValue(ItemID.FriedEgg, Item.buyPrice(gold: 2, silver: 50), Condition.HappyEnough); + .AddWithCustomValue(ItemID.FriedEgg, Item.buyPrice(gold: 2, silver: 50), Condition.HappyEnoughToSellPylons); } if (type == NPCID.PartyGirl) { - shop.AddWithCustomValue(ItemID.GenderChangePotion, Item.buyPrice(silver: 25), potionSells, Condition.HappyEnough) - .AddWithCustomValue(ItemID.Pizza, Item.buyPrice(gold: 5), Condition.HappyEnough, Condition.DownedSkeletron) - .AddWithCustomValue(ItemID.CreamSoda, Item.buyPrice(gold: 2, silver: 50), Condition.HappyEnough); + shop.AddWithCustomValue(ItemID.GenderChangePotion, Item.buyPrice(silver: 25), potionSells, Condition.HappyEnoughToSellPylons) + .AddWithCustomValue(ItemID.Pizza, Item.buyPrice(gold: 5), Condition.HappyEnoughToSellPylons, Condition.DownedSkeletron) + .AddWithCustomValue(ItemID.CreamSoda, Item.buyPrice(gold: 2, silver: 50), Condition.HappyEnoughToSellPylons); } if (type == NPCID.Princess) @@ -1244,12 +1244,12 @@ public override void ModifyShop(NPCShop shop) if (type == NPCID.Golfer) { - shop.AddWithCustomValue(ItemID.PotatoChips, Item.buyPrice(gold: 1), Condition.HappyEnough); + shop.AddWithCustomValue(ItemID.PotatoChips, Item.buyPrice(gold: 1), Condition.HappyEnoughToSellPylons); } if (type == NPCID.BestiaryGirl) { - shop.AddWithCustomValue(ItemID.Steak, Item.buyPrice(gold: 5), Condition.HappyEnough, Condition.Hardmode); + shop.AddWithCustomValue(ItemID.Steak, Item.buyPrice(gold: 5), Condition.HappyEnoughToSellPylons, Condition.Hardmode); } } #endregion diff --git a/NPCs/TownNPCs/DILF.cs b/NPCs/TownNPCs/DILF.cs index 9b2de8371c..65010e191f 100644 --- a/NPCs/TownNPCs/DILF.cs +++ b/NPCs/TownNPCs/DILF.cs @@ -160,7 +160,7 @@ public override void AddShops() .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(5)) .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(5)) .Add(ModContent.ItemType(), Condition.PlayerCarriesItem(ModContent.ItemType())) - .Add(ItemID.IceCream, Condition.HappyEnough, Condition.InSnow) + .Add(ItemID.IceCream, Condition.HappyEnoughToSellPylons, Condition.InSnow) .Register(); } diff --git a/NPCs/TownNPCs/SEAHOE.cs b/NPCs/TownNPCs/SEAHOE.cs index b455f13eb2..f322cbfeb1 100644 --- a/NPCs/TownNPCs/SEAHOE.cs +++ b/NPCs/TownNPCs/SEAHOE.cs @@ -212,8 +212,8 @@ public override void AddShops() .Add(ModContent.ItemType()) .AddWithCustomValue(ItemID.TruffleWorm, Item.buyPrice(gold: 15), Condition.Hardmode) .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(2), downedOldDuke) - .AddWithCustomValue(ItemID.ShrimpPoBoy, Item.buyPrice(gold: 2, silver: 50), Condition.HappyEnough, Condition.InBeach) - .AddWithCustomValue(ItemID.Fries, Item.buyPrice(gold: 2), Condition.HappyEnough, Condition.InBeach, Condition.DownedEyeOfCthulhu) + .AddWithCustomValue(ItemID.ShrimpPoBoy, Item.buyPrice(gold: 2, silver: 50), Condition.HappyEnoughToSellPylons, Condition.InBeach) + .AddWithCustomValue(ItemID.Fries, Item.buyPrice(gold: 2), Condition.HappyEnoughToSellPylons, Condition.InBeach, Condition.DownedEyeOfCthulhu) .Register(); } diff --git a/NPCs/TownNPCs/THIEF.cs b/NPCs/TownNPCs/THIEF.cs index 94b5f94198..ba877e2e84 100644 --- a/NPCs/TownNPCs/THIEF.cs +++ b/NPCs/TownNPCs/THIEF.cs @@ -308,8 +308,8 @@ public override void AddShops() .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 9)) .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 40)) .Add(ItemID.TigerClimbingGear) - .AddWithCustomValue(ItemID.InvisibilityPotion, Item.buyPrice(silver: 25), potionSells, Condition.HappyEnough) - .AddWithCustomValue(ItemID.NightOwlPotion, Item.buyPrice(silver: 25), potionSells, Condition.HappyEnough) + .AddWithCustomValue(ItemID.InvisibilityPotion, Item.buyPrice(silver: 25), potionSells, Condition.HappyEnoughToSellPylons) + .AddWithCustomValue(ItemID.NightOwlPotion, Item.buyPrice(silver: 25), potionSells, Condition.HappyEnoughToSellPylons) .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 25)) .Add(ModContent.ItemType(), Condition.DownedPirates) .AddWithCustomValue(ModContent.ItemType(), Item.buyPrice(gold: 60), Condition.DownedMechBossAll) diff --git a/Projectiles/Boss/BrimstoneMonster.cs b/Projectiles/Boss/BrimstoneMonster.cs index 7ea0d0e4e0..0b6773fe00 100644 --- a/Projectiles/Boss/BrimstoneMonster.cs +++ b/Projectiles/Boss/BrimstoneMonster.cs @@ -272,14 +272,20 @@ public override bool CanHitPlayer(Player player) if (cannotBeHurt) return true; - // Applies Vulnerability Hex and/or the effects of Supreme Cirrus' HAGE faces. - OnHitPlayer_Internal(player); - // Compute distance for direct health reduction from overlap. float distSQ = Projectile.DistanceSQ(player.Center); float radiusSQ = CircularHitboxRadius * CircularHitboxRadius * Projectile.scale * Projectile.scale; float radiusRatio = distSQ / radiusSQ; + // If this code happens to run when the player is not colliding, don't apply any effects. + // The performance impact of verifying this is marginal, especially since there's only ever one of this projectile. + // == false is necessary since the method is a nullable. + if (Colliding(Projectile.Hitbox, player.Hitbox) == false) + return false; + + // Applies Vulnerability Hex and/or the effects of Supreme Cirrus' HAGE faces. + OnHitPlayer_Internal(player); + // Check the player's speed. If they are moving fast enough, damage them more severely; this prevents trying to rush straight through the vortex. float playerSpeed = player.velocity.LengthSquared(); float speedRatio = playerSpeed / (SpeedToForceMaxDamage * SpeedToForceMaxDamage); diff --git a/Projectiles/CalamityGlobalProjectile.cs b/Projectiles/CalamityGlobalProjectile.cs index 5478122efc..861726eb05 100644 --- a/Projectiles/CalamityGlobalProjectile.cs +++ b/Projectiles/CalamityGlobalProjectile.cs @@ -236,8 +236,6 @@ public override bool PreAI(Projectile projectile) if (pointBlankShotDuration > 0) pointBlankShotDuration--; - if (pointBlankShotDistanceTravelled < PointBlankShotDistanceLimit) - pointBlankShotDistanceTravelled += projectile.velocity.Length() * projectile.MaxUpdates; // Reduce secondary yoyo damage if the player has Yoyo Glove // Brief behavior documentation of yoyo AI: ai[0, 1] are the x, y co-ords and localAI[0] is the airtime in frames @@ -4028,6 +4026,12 @@ public override void PostAI(Projectile projectile) flatDR = 0; } + // CIT 29JUN2024: Moved from PreAI to PostAI so that it is called every update instead of every frame. + // This makes the distance traveled increment more accurately for projectiles with extra updates, as previously projectiles with extra updates + // would add the distance traveled for the whole frame on the first update, making the distance checking much choppier. + if (pointBlankShotDistanceTravelled < PointBlankShotDistanceLimit) + pointBlankShotDistanceTravelled += projectile.velocity.Length(); + // optimization to remove conversion X/Y loop for irrelevant projectiles bool isConversionProjectile = projectile.type == ProjectileID.PurificationPowder || projectile.type == ProjectileID.VilePowder diff --git a/Projectiles/Summon/PinkButterfly.cs b/Projectiles/Summon/PinkButterfly.cs index ffdfa52520..842f0cee5d 100644 --- a/Projectiles/Summon/PinkButterfly.cs +++ b/Projectiles/Summon/PinkButterfly.cs @@ -25,7 +25,7 @@ public override void SetDefaults() Projectile.netImportant = true; Projectile.friendly = true; Projectile.ignoreWater = true; - Projectile.minionSlots = 0.5f; + Projectile.minionSlots = 1f; Projectile.timeLeft = 18000; Projectile.penetrate = -1; Projectile.tileCollide = false; @@ -67,7 +67,6 @@ public override void AI() Projectile.frame = 0; } Lighting.AddLight(Projectile.Center, 0.3f, 0.2f, 0.3f); - float attackRange = 1200f; bool isMinion = Projectile.type == ModContent.ProjectileType(); player.AddBuff(ModContent.BuffType(), 3600); if (isMinion) @@ -82,44 +81,46 @@ public override void AI() } } Projectile.MinionAntiClump(); - bool returnbool = false; - if (returnbool) - { - return; - } Vector2 projPos = Projectile.position; bool canAttack = false; + float attackRange = 1200f; int targetIndex = -1; if (player.HasMinionAttackTargetNPC) { NPC npc = Main.npc[player.MinionAttackTargetNPC]; - if ((npc.CanBeChasedBy(Projectile, false) || npc.type == NPCID.DukeFishron) && npc.active) + if (npc.CanBeChasedBy(Projectile, false)) { float targetDist = Vector2.Distance(npc.Center, Projectile.Center); - if (!canAttack && targetDist < attackRange) - { - projPos = npc.Center; - canAttack = true; + if (targetDist < attackRange) targetIndex = npc.whoAmI; - } + } + if (targetIndex != -1) + { + canAttack = true; + projPos = npc.Center; } } if (!canAttack) { foreach (NPC nPC2 in Main.ActiveNPCs) { - if (nPC2.CanBeChasedBy(Projectile, false) || nPC2.type == NPCID.DukeFishron) + if (!nPC2.CanBeChasedBy(Projectile)) + continue; + + float targetDist = Vector2.Distance(nPC2.Center, Projectile.Center); + if (targetDist < attackRange) { - float targetDist = Vector2.Distance(nPC2.Center, Projectile.Center); - if (!canAttack && targetDist < attackRange) - { - attackRange = targetDist; - projPos = nPC2.Center; - canAttack = true; - targetIndex = nPC2.whoAmI; - } + attackRange = targetDist; + targetIndex = nPC2.whoAmI; + if (nPC2.type == NPCID.DukeFishron) + break; } } + if (targetIndex != -1) + { + canAttack = true; + projPos = Main.npc[targetIndex].Center; + } } float separationAnxietyDist = 1500f; if (canAttack) @@ -193,10 +194,10 @@ public override void AI() // Projectile fire timer if (Projectile.ai[1] > 0f) - Projectile.ai[1] += (float)Main.rand.Next(1, 2 + 1); + Projectile.ai[1] += Main.rand.Next(1, 2 + 1); // Reset timer - if (Projectile.ai[1] > 240f) + if (Projectile.ai[1] > 180f) { Projectile.ai[1] = 0f; Projectile.netUpdate = true; diff --git a/Projectiles/Summon/PurpleButterfly.cs b/Projectiles/Summon/PurpleButterfly.cs index 6255caab7f..ad2212ddd2 100644 --- a/Projectiles/Summon/PurpleButterfly.cs +++ b/Projectiles/Summon/PurpleButterfly.cs @@ -27,15 +27,15 @@ public override void SetDefaults() Projectile.netImportant = true; Projectile.friendly = true; Projectile.ignoreWater = true; - Projectile.minionSlots = 0.5f; + Projectile.minionSlots = 1f; Projectile.timeLeft = 18000; Projectile.penetrate = -1; Projectile.tileCollide = false; Projectile.timeLeft *= 5; Projectile.minion = true; Projectile.DamageType = DamageClass.Summon; - Projectile.usesIDStaticNPCImmunity = true; - Projectile.idStaticNPCHitCooldown = 8; + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 30; } public override void AI() @@ -55,6 +55,19 @@ public override void AI() } dust--; } + bool isMinion = Projectile.type == ModContent.ProjectileType(); + player.AddBuff(ModContent.BuffType(), 3600); + if (isMinion) + { + if (player.dead) + { + modPlayer.resButterfly = false; + } + if (modPlayer.resButterfly) + { + Projectile.timeLeft = 2; + } + } if (Math.Abs(Projectile.velocity.X) > 0.2f) { Projectile.spriteDirection = -Projectile.direction; @@ -72,19 +85,6 @@ public override void AI() } Lighting.AddLight(Projectile.Center, 0.3f, 0f, 0.5f); Projectile.ChargingMinionAI(1200f, 1500f, 2400f, 150f, 0, 25f, 20f, 9f, new Vector2(0f, -60f), 30f, 15f, true, true); - bool isMinion = Projectile.type == ModContent.ProjectileType(); - player.AddBuff(ModContent.BuffType(), 3600); - if (isMinion) - { - if (player.dead) - { - modPlayer.resButterfly = false; - } - if (modPlayer.resButterfly) - { - Projectile.timeLeft = 2; - } - } } public override bool PreDraw(ref Color lightColor) diff --git a/Tiles/DraedonSummoner/CodebreakerTile.cs b/Tiles/DraedonSummoner/CodebreakerTile.cs index c8454d49f1..013cdf7b8b 100644 --- a/Tiles/DraedonSummoner/CodebreakerTile.cs +++ b/Tiles/DraedonSummoner/CodebreakerTile.cs @@ -78,6 +78,19 @@ public override void SetStaticDefaults() public override bool CanExplode(int i, int j) => false; + public override bool CanPlace(int i, int j) + { + // Cannot be placed on Teleporters in order to prevent a critical bug. + int startOfTileCoordinateCheckX = i - 2; + for (int k = startOfTileCoordinateCheckX; k < startOfTileCoordinateCheckX + Width; k++) + { + if (Main.tile[k, j + 1].TileType == TileID.Teleporter) + return false; + } + + return true; + } + // Prevent the tile from being destroyed while it's busy decrypting. // If it's destroyed the tile entity would be too and the resources used on decryption would be lost for nothing. public override bool CanKillTile(int i, int j, ref bool blockDamaged) diff --git a/UI/FlightBar/FlightBar.cs b/UI/FlightBar/FlightBar.cs index b78ed67fcd..60ec028cfb 100644 --- a/UI/FlightBar/FlightBar.cs +++ b/UI/FlightBar/FlightBar.cs @@ -31,7 +31,7 @@ public class FlightBar private static Texture2D GetApplicableBorder(CalamityPlayer modPlayer) { - if (modPlayer.Player.equippedWings != null && modPlayer.Player.wingTimeMax == 0 && modPlayer.Player.mount._data.flightTimeMax == 0) + if (modPlayer.Player.equippedWings != null && modPlayer.Player.wingTimeMax == 0 && modPlayer.Player.mount.Active && modPlayer.Player.mount._data.flightTimeMax == 0) return disabledBarTexture; if ((modPlayer.infiniteFlight || RidingInfiniteFlightMount(modPlayer.Player)) && completedAnimation) return infiniteBarTexture; @@ -106,7 +106,7 @@ public static void Draw(SpriteBatch spriteBatch, Player player) CalamityPlayer modPlayer = player.Calamity(); // If not drawing the flight bar, save its latest position to config and leave. - if (CalamityConfig.Instance.FlightBar && (player.wingsLogic > 0 || (player.mount.Active && player.mount._data.flightTimeMax > 0) || player.carpet && !player.canCarpet)) + if (CalamityConfig.Instance.FlightBar && ((player.wingsLogic > 0 && player.wingTimeMax > 0) || (player.mount.Active && player.mount._data.flightTimeMax > 0) || player.carpet && !player.canCarpet)) { DrawFlightBar(spriteBatch, modPlayer, screenPos); } diff --git a/Utilities/GenericAIUtils.cs b/Utilities/GenericAIUtils.cs index 265c83daf3..f43806ef53 100644 --- a/Utilities/GenericAIUtils.cs +++ b/Utilities/GenericAIUtils.cs @@ -29,7 +29,10 @@ public static void ChargingMinionAI(this Projectile projectile, float range, flo projectile.ai[1] = 1f; projectile.ai[0] = 0f; projectile.extraUpdates = initialUpdates; - projectile.numUpdates = 0; + // CIT 2OCT2024: This line was breaking how the game counted minions, + // which resulted in minions being counted extra times and despawning other minions, most notoriously with Resurrection Butterfly. + // As such, I have commented it out. + // projectile.numUpdates = 0; projectile.netUpdate = true; } else From c7450c5b17308acd27ced030baf7da18910db3b2 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Mon, 26 May 2025 17:30:52 -0400 Subject: [PATCH 234/401] Fix batch #3 1 - Fixed Blazing Core and Flame-Licked Shell's parries lasting indefinitely if unequipped during the parry 2 - Fixed Radiant Ooze line life regen not scaling; includes nerf to Ampoule and Radiance life regen 3 - Fixed Gravistar Sabaton exploits from unequipping and Inner Tube --- CalPlayer/CalamityPlayer.cs | 94 ++++++++++--------- CalPlayer/CalamityPlayerLifeRegen.cs | 4 +- CalPlayer/CalamityPlayerMiscEffects.cs | 9 +- .../Mods.CalamityMod.Items.Accessories.hjson | 4 +- 4 files changed, 62 insertions(+), 49 deletions(-) diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 98f60d0478..e02c66b2b7 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -3423,58 +3423,66 @@ public override void UpdateEquips() { Player.AddBuff(ModContent.BuffType(), 60, true); } - if (gSabaton && Player.whoAmI == Main.myPlayer) + if (gSabaton) { - //While holding hotkey, but before slam, bring Y velocity closer to 0 - if (gSabatonHotkeyHoldTime < 60 && gSabatonHotkeyHoldTime != 0 && !gSabatonFalling) - { - Player.velocity.Y *= (60 - (gSabatonHotkeyHoldTime / 4f)) / 60f; - } - //Play sound a bit early so it goes in time with the fall - if (gSabatonHotkeyHoldTime == 45 && !gSabatonFalling) - { - SoundEngine.PlaySound(new("CalamityMod/Sounds/Custom/GravistarCharge") { Volume = 0.3f }); - } - //1 second passed, falling time - if (gSabatonHotkeyHoldTime == 60) - { - gSabatonFalling = true; - } - //Cancel fall and don't give 'on ground' effects if on rope, on mount, grappled, or tongued - if (Player.pulley || Player.mount.Active || Player.grappling[0] != -1 || Player.tongued) - { - gSabatonFall = 0; - gSabatonFalling = false; - } - if (gSabatonFalling) + if (Player.whoAmI == Main.myPlayer) { - SpawnGravistarParticle(); + //While holding hotkey, but before slam, bring Y velocity closer to 0 + if (gSabatonHotkeyHoldTime < 60 && gSabatonHotkeyHoldTime != 0 && !gSabatonFalling) + { + Player.velocity.Y *= (60 - (gSabatonHotkeyHoldTime / 4f)) / 60f; + } + //Play sound a bit early so it goes in time with the fall + if (gSabatonHotkeyHoldTime == 45 && !gSabatonFalling) + { + SoundEngine.PlaySound(new("CalamityMod/Sounds/Custom/GravistarCharge") { Volume = 0.3f }); + } + //1 second passed, falling time + if (gSabatonHotkeyHoldTime == 60) + { + gSabatonFalling = true; + } + //Cancel fall and don't give 'on ground' effects if on rope, on mount, grappled, or tongued + // Also cancel fall if the player has upwards Y velocity (Goodbye Inner Tube cheese) + if ((Player.gravDir == 1 && Player.velocity.Y < 0f) || (Player.gravDir == -1 && Player.velocity.Y > 1f) || Player.pulley || Player.mount.Active || Player.grappling[0] != -1 || Player.tongued) + { + gSabatonFall = 0; + gSabatonFalling = false; + } + if (gSabatonFalling) + { + SpawnGravistarParticle(); - //Cap time converted to damage at 2 seconds - if (gSabatonFall < 120) - gSabatonFall++; + //Cap time converted to damage at 2 seconds + if (gSabatonFall < 120) + gSabatonFall++; - Player.maxFallSpeed = 40f; - Player.gravity = 1.3f; - //If the player can fly during the fall, the physics gets a bit funky - Player.controlJump = false; + Player.maxFallSpeed = 40f; + Player.gravity = 1.3f; + //If the player can fly during the fall, the physics gets a bit funky + Player.controlJump = false; - //Check if player hit some form of solid resistance (the ground) - if (Player.oldVelocity.Y == Player.velocity.Y) - { - var source = Player.GetSource_Accessory(FindAccessory(ModContent.ItemType())); - //Spawn explosion. ai[0] is used for transferring the recorded falling time + //Check if player hit some form of solid resistance (the ground) + if (Player.oldVelocity.Y == Player.velocity.Y) + { + var source = Player.GetSource_Accessory(FindAccessory(ModContent.ItemType())); + //Spawn explosion. ai[0] is used for transferring the recorded falling time - int damage = Player.ApplyArmorAccDamageBonusesTo(Player.CalcIntDamage(GravistarSabaton.SlamDamage)); + int damage = Player.ApplyArmorAccDamageBonusesTo(Player.CalcIntDamage(GravistarSabaton.SlamDamage)); - Projectile.NewProjectile(source, Player.Center, Vector2.Zero, ModContent.ProjectileType(), damage, 4f, Player.whoAmI, gSabatonFall); - gSabatonFall = 0; - gSabatonFalling = false; - //Temporary jump speed is granted for 40 frames - gSabatonTempJumpSpeed = 40; + Projectile.NewProjectile(source, Player.Center, Vector2.Zero, ModContent.ProjectileType(), damage, 4f, Player.whoAmI, gSabatonFall); + gSabatonFall = 0; + gSabatonFalling = false; + //Temporary jump speed is granted for 40 frames + gSabatonTempJumpSpeed = 40; + } } } - + } + else // Reset slam effect if the accessory is unequipped + { + gSabatonFall = 0; + gSabatonFalling = false; } } #endregion diff --git a/CalPlayer/CalamityPlayerLifeRegen.cs b/CalPlayer/CalamityPlayerLifeRegen.cs index 590e89edba..94a5f3da18 100644 --- a/CalPlayer/CalamityPlayerLifeRegen.cs +++ b/CalPlayer/CalamityPlayerLifeRegen.cs @@ -422,9 +422,9 @@ void ApplyDoTDebuff(bool hasDebuff, int negativeLifeRegenToApply, bool immuneCon // Grant life regen based on missing health for Radiant Ooze, Ambrosial Ampule, and purity if (rOoze || aAmpoule || purity) { - float missingLifeRatio = (Player.statLifeMax2 - Player.statLife) / Player.statLifeMax2; + float missingLifeRatio = (Player.statLifeMax2 - Player.statLife) / (float)Player.statLifeMax2; //Ambrosial Ampule and ooze give between 2 and 6 hp/s - float lifeRegenToGive = MathHelper.Lerp(4f, 12f, missingLifeRatio); + int lifeRegenToGive = (int)Math.Round(MathHelper.Lerp((purity || aAmpoule ? 2f : 4f), (purity || aAmpoule ? 8f : 12f), missingLifeRatio)); // Rounding is needed for it to ever actually give +6 hp/s, as the integer conversion would otherwise floor it. Player.lifeRegen += (int)lifeRegenToGive; } diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index 402ff921f3..ad7655f7c3 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -1499,9 +1499,14 @@ private void MiscEffects() else if (blazingCoreParry > 0) BlazingCore.HandleParryCountdown(Player); } - else if (flameLickedShell && flameLickedShellParry > 0) + else if (blazingCoreParry > 0) + blazingCoreParry--; + else if (flameLickedShellParry > 0) { - FlameLickedShell.HandleParryCountdown(Player); + if (flameLickedShell) + FlameLickedShell.HandleParryCountdown(Player); + else + flameLickedShellParry--; } // Silver Armor "Medkit" effect diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson index 48763168e9..c0f41b9bf4 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson @@ -138,7 +138,7 @@ AmbrosialAmpoule: { Tooltip: ''' +50 max life - Grants +2 to +6 HP/s life regen based on missing health + Grants +1 to +4 HP/s life regen based on missing health Grants +1 HP/s life regen and an additional 1 HP/s life regen when inflicted with a damage debuff Standing still grants +1.5 HP/s life regen Halves how long you are afflicted with fire and sickness debuffs @@ -1322,7 +1322,7 @@ Radiance: { Tooltip: ''' +70 max life - Grants +2 to +6 HP/s life regen based on missing health + Grants +1 to +4 HP/s life regen based on missing health Grants +1 HP/s life regen and an additional 1 HP/s life regen when inflicted with a damage debuff Standing still grants +2 HP/s life regen Grants 20 defense and continuous healing while afflicted with any debuff From 84bd8b5d284253481300ac45b51e6d036462327f Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Mon, 26 May 2025 17:46:53 -0400 Subject: [PATCH 235/401] Ampoule + Radiance life regen buff --- CalPlayer/CalamityPlayerLifeRegen.cs | 2 +- Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CalPlayer/CalamityPlayerLifeRegen.cs b/CalPlayer/CalamityPlayerLifeRegen.cs index 94a5f3da18..7872000ba7 100644 --- a/CalPlayer/CalamityPlayerLifeRegen.cs +++ b/CalPlayer/CalamityPlayerLifeRegen.cs @@ -424,7 +424,7 @@ void ApplyDoTDebuff(bool hasDebuff, int negativeLifeRegenToApply, bool immuneCon { float missingLifeRatio = (Player.statLifeMax2 - Player.statLife) / (float)Player.statLifeMax2; //Ambrosial Ampule and ooze give between 2 and 6 hp/s - int lifeRegenToGive = (int)Math.Round(MathHelper.Lerp((purity || aAmpoule ? 2f : 4f), (purity || aAmpoule ? 8f : 12f), missingLifeRatio)); // Rounding is needed for it to ever actually give +6 hp/s, as the integer conversion would otherwise floor it. + int lifeRegenToGive = (int)Math.Round(MathHelper.Lerp((purity || aAmpoule ? 2f : 4f), (purity || aAmpoule ? 10f : 12f), missingLifeRatio)); // Rounding is needed for it to ever actually give +6 hp/s, as the integer conversion would otherwise floor it. Player.lifeRegen += (int)lifeRegenToGive; } diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson index c0f41b9bf4..37e8b03f1a 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson @@ -138,7 +138,7 @@ AmbrosialAmpoule: { Tooltip: ''' +50 max life - Grants +1 to +4 HP/s life regen based on missing health + Grants +1 to +5 HP/s life regen based on missing health Grants +1 HP/s life regen and an additional 1 HP/s life regen when inflicted with a damage debuff Standing still grants +1.5 HP/s life regen Halves how long you are afflicted with fire and sickness debuffs @@ -1322,7 +1322,7 @@ Radiance: { Tooltip: ''' +70 max life - Grants +1 to +4 HP/s life regen based on missing health + Grants +1 to +5 HP/s life regen based on missing health Grants +1 HP/s life regen and an additional 1 HP/s life regen when inflicted with a damage debuff Standing still grants +2 HP/s life regen Grants 20 defense and continuous healing while afflicted with any debuff From 1ecefb06a33ce40bac1df62cf36a577143ba2b6d Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Mon, 26 May 2025 15:02:31 -0700 Subject: [PATCH 236/401] coldheart hold tweaks --- Items/ColdheartIcicle.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Items/ColdheartIcicle.cs b/Items/ColdheartIcicle.cs index 7395395ec5..97ffcaadf8 100644 --- a/Items/ColdheartIcicle.cs +++ b/Items/ColdheartIcicle.cs @@ -25,7 +25,13 @@ public override void SetDefaults() public override void HoldStyle(Player player, Rectangle heldItemFrame) { - player.itemRotation = player.MountedCenter.DirectionTo(Main.MouseWorld).ToRotation(); + player.itemRotation = player.direction == -1 ? -MathHelper.PiOver4 : MathHelper.PiOver4; + player.itemLocation = player.GetBackHandPosition(Player.CompositeArmStretchAmount.Full, player.direction * MathHelper.PiOver4) + Vector2.UnitX * player.direction * 14; + } + + public override void HoldItemFrame(Player player) + { + player.SetCompositeArmBack(true, Player.CompositeArmStretchAmount.Full, -player.direction * MathHelper.PiOver4); } public override void HoldItem(Player player) From b8e9d3dbc44c2f6ebbc6abb8e38646579199d1b3 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Mon, 26 May 2025 18:04:59 -0400 Subject: [PATCH 237/401] Replace all alcohol buff icons to not have a unified pink background. All icons by Metarex. --- Buffs/Alcohol/BloodyMaryBuff.png | Bin 674 -> 653 bytes Buffs/Alcohol/CaribbeanRumBuff.png | Bin 652 -> 663 bytes Buffs/Alcohol/CinnamonRollBuff.png | Bin 674 -> 681 bytes Buffs/Alcohol/EverclearBuff.png | Bin 694 -> 712 bytes Buffs/Alcohol/EvergreenGinBuff.png | Bin 720 -> 706 bytes Buffs/Alcohol/FireballBuff.png | Bin 680 -> 700 bytes Buffs/Alcohol/GrapeBeerBuff.png | Bin 661 -> 689 bytes Buffs/Alcohol/MargaritaBuff.png | Bin 698 -> 705 bytes Buffs/Alcohol/MoonshineBuff.png | Bin 702 -> 726 bytes Buffs/Alcohol/MoscowMuleBuff.png | Bin 812 -> 792 bytes Buffs/Alcohol/OldFashionedBuff.png | Bin 691 -> 657 bytes Buffs/Alcohol/RedWineBuff.png | Bin 664 -> 696 bytes Buffs/Alcohol/RumBuff.png | Bin 739 -> 747 bytes Buffs/Alcohol/ScrewdriverBuff.png | Bin 687 -> 679 bytes Buffs/Alcohol/StarBeamRyeBuff.png | Bin 708 -> 758 bytes Buffs/Alcohol/TequilaBuff.png | Bin 686 -> 685 bytes Buffs/Alcohol/TequilaSunriseBuff.png | Bin 741 -> 741 bytes Buffs/Alcohol/VodkaBuff.png | Bin 674 -> 685 bytes Buffs/Alcohol/WhiskeyBuff.png | Bin 720 -> 740 bytes Buffs/Alcohol/WhiteWineBuff.png | Bin 667 -> 677 bytes 20 files changed, 0 insertions(+), 0 deletions(-) diff --git a/Buffs/Alcohol/BloodyMaryBuff.png b/Buffs/Alcohol/BloodyMaryBuff.png index 46cf3a0b57af7b828e93195822d30f7bfeb0de9e..670c6a0445d5fb8b3d913fb42955c6099725fe9c 100644 GIT binary patch delta 629 zcmV-*0*d{j1&sxeBYyw^b5ch_0Itp)=>Px%M@d9MR9J=WmrrODK@^9-4PtDdCDlR@ zO09P3Aw<-wCs8jsh}2SgXhpp0L2rV^KLsh&OV5JfsZbFjDjrlkgdRje6g851DbZpp z*d7!~BymBEhuP;k!^W&w$Q=A#cHf&fv-3V?-po1&k{bc|`hVklod_y>UX-w=S{I8s z0I@Y0?O!G$nY;0JtzjgY2<>p^OI5Q=UIlRI1sdllE0(YkHO&xa0Y4*@gt{_GAda3TL1fb`Ho01CN>0IWAM zAMovDx5{m9W`9u|=i1;t0FK_C18gGDNV)x^nq8>X0QgWYE62I}01S0>DErxx7XM~t z1%TZNMfl{sCtABb1SGTctH%Ho{in#?>#ApiflALyTHLKi#Yhvdhrl~kn7HAu?qg$z zw7~YmV?eMwUYxlA1euFWyP51EATmk(3jC~2&Em~v0DpRYzpNe6&bBt-w_RdrJe2}q zVoB{5`v{1H#J0Gj`R`5~4~-x6GjqGTlw)-@G;Z4P+e<(sB$z%0!0^;{ARy80SHNKZ ztNX!hRh^bn0UN311pZH;=^BWt{*Oujt@2m>T2Dak`Q!dg#jN?F^Lvf}(EIc%5bXPA znmI8V>TVyoG7H#1Kwjh&OK(>9fCb-gl8|%Wto4Q3a_9%PpFOR{^Y4_E2RW_1OqrPrX=_eHXSlNyfca`Q(%FzBYy&ENkl%zxV(&RK0kd(K##WMKXQ zOJI8K6R>UfhNY*{VT)_Byz&ZC$rFfZXPkNS*#0XoblA%AJ;y*cY6D>Z1Dy?>tuHkuuHRTvs-tE@!1z^jA< zMbNzjXp~8upkQ$9>UpIIJr#?gNYvJfkjZS@r$u)Ypwo%)VJWX)0QOwF3uF?WSpm6D zB&XIeKIl&XxdMW0vnhE3ff;zxcO#Vh>Q7(>^nuCqD%sQ0H%bSD8iiXN&$sh#(Fx7h+@Via}%kKUhVNZybl9|Uz@$rHdE lsL_t(oh1Hi$XcIvc$A24a6)XfIwNj`MRJ3AgDMTpy-UH0c+-HWmqJ6DiicWD@FNOYY6tu%B&16`OonBK z4NYPp=>B+^nYBmI{R&2Y(>6ExrANcBsh1Elrx^ z`nh;ugG6#kd!NsKtZU#x-YbC(1Wbd9JU-qR*dTF15;z^}0YC^3fR&9*T@$c}fEjt~ zzL-{VEtdrRh(CNyY5uvHs{jm)+z%XRaefkj-o7!-ZV!PmN@5 zxH*;pDo1L*D}UKTAf5gKKy2X%0N;5DKx%RhfX)*=TEkyw2LXsIy^y6>1YqdYG*Fp@ zDSHUK&86kTlq^PWoB=>=$SQ75U+2rC7Xf&@mIt7_Q`&{7Z36ZXP%=qG4Zk9ha$3rk zd`$zYd~tsG9$+H@B}Jln*FgaKFUbrU?K%v=$#T8aQ-8S|W;5#myjzwT^3(g3z<$k4 zX)gg&DsrV~6N>g+Bny&LlK@)_n!|=L4lo z@n=mFXgmRR&cAz2W~j&^c|A~n{qg=g05rQ106N+{txUQy;#iyXXIy=NhvTDx0}tPp zyJq7FsA>n5$zV^plz;ugn_GZSLWr=|!GWf5+3soem7-m;RI5m=I-1`e0_sHMOOg<) za-Gjk4+eH%W=K7vHcx(+>ZYOj+@43^zfDx00000 LNkvXXu0mjfZEG7o delta 614 zcmV-s0-61n1&jrdF@Hu$L_t(oh2@veOH@%5$3N4U6@|tuvVlyZphQFwG=xfwf_4=d z1-1;NRYL!Oo7x4g0^3DI1W_&8L{eIWQB6M=YV>eu2YpXlil$>`UQ5Q z@8-_E=bU@b`Mme;y%S+UMV3|(fMrX(XkZpafR?%=mf_6C{eOW0=Vnh^{gLFV-&%Oe zJOLaaP*Fahl{a+N1xH+vW^ZdV0LCN$7|*QKlnS!2wDl5z(D5|3?Y9 zM?j?{+E&Qh-O=3+z^2Bn0PHCFC9b^&AmzOW;Kiuykbe`r{HX-oB~UJ{Ty>*QzVoI- zs{u%Pi$W}gor?bsfr(e+R{ubs?0EVP{7CNK2f~#6`~iR~=Wko%DgO?za6eFa^VwfY zz#Re?<2{xk8m|PP^U+}dD*YG$wKWB+ee6rctus1yzN~IRF|S?gm^UpcUsv z!mjKw4>IT4=YHNbc%d1P{Lgc}_>j2ChlzW9%942=NsH)oKlq=6%NvM>V zO8q~r{|G>FTT~3Cwqh(AIPYI45c%%+|M~CuE8>m0T&>|Xw*UYD07*qoM6N<$f*q+N A$N&HU diff --git a/Buffs/Alcohol/CinnamonRollBuff.png b/Buffs/Alcohol/CinnamonRollBuff.png index 8d9ff66e261ddd2a89c905feef9dd4a226ed4262..fcd82792df5ff8d4947dba7fcccc96662e881a1a 100644 GIT binary patch delta 658 zcmV;D0&V@G1*rv)BYyw^b5ch_0Itp)=>Px%V@X6oR9J=8mrZCBK^TUg6(fk6B}%QN z#n!5&N(dJ55HNU9up&wef_Si?(kfm`Pzowu>>;3qpa&5Og7lz*hupjrNvW8FKS7Bo zDx$?k)6k#9pB@^Bhs{TrF&kqoWcyww-^}bc`#v+9{nlu0-hT+dd_G^G3Qf&stC{v! zt#G*vfMtu4?LV|!oSW`7%E09_$ID(YaBEnJv$^jJT6k(UTL32z&^yF=$D#I$7YYd> zw@?x_Ctz%9^cDaH`_BR;=a;�N`sd0XP=!10enWBLIoF<)4Q0S8tZ>m;5p=PgBha z{BZ_Ek?4H@LVuk{0l0hNIsjcah5+z;J^-+`X$t_cd&7DPMRsJIL*Pg9835@vv)E(p zb;qfL0Q}5Z_d5MqbuRJ;0ssv5Td|xaU$Cd*4LFBD76P*jPXOF)B09w5sWjr%( zIsZEGZxz$hAt26W?{xxp&V`(vmJR`NqC2-!V}rY@d9^1Xm5Ed=@>Y|#-9Ya-0L+vD zKz-f1@_(6{wku&GF$qAh7)yT9iHl*t2?XTF%$y5=SMfLier;kb8Uw%=*roI*<4-Ft zVD30<x01E&B07*qoM6N<$f?uF0g8%>k delta 651 zcmV;60(AYU1)>FzBYy&ENkljnBahi06Y!suw4dr6wK$nYl^^p9cg|rZGWLy4RbV@zA1Sag%9Io zG;Dw|@zR4g4ZxgTojVWAY@M706>0_3fs}Jq4&VFo~0$2hWQ+(_}#-hVCJRc$H8<^9wZHk z3E9DvpwNRR4S&FM0jwk};Bx@G)J#PeOrI3(0n@f2&S3iWqi0|m7a=Mq1(rIzW-pkI zn+3^T=piv^LI9&Aobc%Y*yRO~C}m&}1#=m0J$nykxCf?#>2IH|g6WsHA!!2^GB9;d zo_>O8BtQ;$F2D!@n1f*QGaXE^XFfIQ?GsL5dhmn*%*UUOe*wFU4;lhc4=^0qZ~)BI zu{4DVf$1y9Powa0abP}2mmlyDfVT&31Rg diff --git a/Buffs/Alcohol/EverclearBuff.png b/Buffs/Alcohol/EverclearBuff.png index fde2031fa3ae7582bc9b88407faefb17e16e1d21..c1e6fcc595b24fdc11fa3fff72614eb4a81f8e8d 100644 GIT binary patch delta 675 zcmV;U0$lyJ1;_=EF@J(dL_t(oh0T{;NRv?*$A1gAQEnoLCWeZAkPXrZFG3hubQOqw zK-7ZlgYK%a7+6t6ROrPZx{lI9gD#2{Qjs@-Nl{S}wGtIu4y6y)Y)x{?*2UQg&davu z2YCKB@B5tRIUmpO9G>&Orlt1P03?!ANpg^xa4up0RRW6%V1LPij5ZJD$;>Tz%N0j+ zTWi`5H&2}gz}4^@fUjes{ZSw`tBK8olb{0uV}s1x?b?>M!}R0h0Mu?d1i+K7_IWKp z9|FeAtL#%s;7HU8z{}7w0Dknn2OuyJ2jJ5E7XX}X+LU&pOn!X`WRlFhY1c&nnq4gb zlvS((pm=310Drez8Uc9N{|SKY8>*FYGLg}Tz(lv$Q~w%=642gy9e{@VNdP>@b^_3N zqz!=S(Ov*b*6jemyVnV1CSjC51pLps6i1C`PudQ59=ucR(D*O_Rprh(EkGXvQbrQi zh#!FA5wXXK_)`GBee^4FqvPT^6OCk@@Tl(w03BX2o_~G>q$G**Ij0kPB>coWQi7NqniP&y-0 z`y8+;?e*t+0OqK z!pV&PkqU+szcF(o=|v}CDya|^Y%)BM)8FwzsT^pNdBiAuTjbto}u$tcOn=-P)6 zeI1nO&?U;~5D6WN4h3F26;V)^F!7XC;Wf`3M|gdMNHEIhmM}g+}Qve#<#NM{P!ZP4N>s!qp4)+7FW_8V+iL#k1 zn4^F~Mv0){Zx{R6VcKa%2)yl>IshQiXO649I%V1J$h3QCEY4Z{3fy?!^G?UD9% zaub_W}xeD0f`jxxsuN44%$r}_?$^nx$XTa`OG+%+@lu-K=aB2P3m)iko z>l52?$E*1V(CdZy?}2~Cbn$TjdLK3cko=h5e0BH}w{x0r!4=57iu<-d(Hzc_JOB;^ z>H*kPx_=dbz=&TPmxzA_punB4*}iZq0Li+PHvW59UQp#ddjSI!$eaPiIQ~KyxYM>` z6e^HPr<4dKg4#sO3JSIH3W~8E%uztWy+ig=t-Ql?AAo(KV*pIL^-8B0XYc*grJ3{y rrzHB|)aF%Ka0MK{egB_-$3FpCZO8#H)`=hh015yANkvXXu0mjfygxM` diff --git a/Buffs/Alcohol/EvergreenGinBuff.png b/Buffs/Alcohol/EvergreenGinBuff.png index 5e41d87eb635a0b2c7cd52f1cd11632dacd6db1d..e73283e98ba6ea91076ba16c1a92a72f87f0875b 100644 GIT binary patch delta 669 zcmV;O0%HBp1;Pc8F@JnXL_t(oh1Hi|NYhai$3H(Cld~L48NbYmFLc7)x5T{{~=sfhcJJ8u~+k7JrM+8f5#5ZpH9sK5S#k;M+j4Pl)le7qDu%a)hJdmXR^|c+De&?Y0E72O zw1ml-IRLJoI}5;wSsS77JpcwQd1CFN;tCi>U7gkmi}m$dLcqHffL3#Fw{KB*M^|J_ z#p4+*e>DCXfZdri0MYr>iWAG7;yeWe^|=KA;@g@vzketq5XJ&wKJ#7KL_xn~?}Tmx z&~x$>;A90#wXmyQ*<=!cnw{-hUiytXJ=E4}dET)I@UsE}$JD^8ov;Lx(LnGB0Q)-k zXyHM(8z^@^{F{Gk0snyl=H7MlO#KmFmZHckq%U8{o z`hd*^RDWIpIge-h`haq;zt-IiK)|DFpxW1{#Rc#3QSE!wv|h6lo;Sy}B6L~#E3bh3 zu-@axdM^QR_vQ@%+7h1th^;b^{3jIVkDux9h$qqKE6(E_1s11g0gzKJdwr$9A1HS~ zVIr`0Mk}n$9jAcdZ&LStGBIoGb-Y&C)YR;Z*B0>)*(uoTzQQ<-00000NkvXXu0mjf DZ^uM! delta 683 zcmV;c0#yCN1<(bMF@K6lL_t(oh2@vuOOsI;$3M%+3ATnv@TzS^T?AT$WF@G>@M2d5 zB}5lNcLTdf@L#aHGQ2W^z>6TN&5Y<`gs`n2ODrNLQbe|y;cL0p8e%OM>*Bm;>x_3} zSNcZZo9CS8dCqyx^F7bb^Ug*Qc{Ua{fGryw)btd2fOhv8#eZ;kOBz-T56z~DnM4{lG0!BZi|4Zpp+ngAFG zM*#5ZX=THpF4i4Mr%VHOM+TL-br_J4OlZmX00a$v(0`u*z^m;RQtI`DvR-Ds_|2Sw zQdo}x34PB#F=#&|WHJfB%t5sm5Ho%?jg7)?_-Tpu-ZPsdTk zJYH7^z=+>36t0$v+sUrjcEtny6AT!4I}n%vpyA!TVot?gi$O`Pl!N8I2g)*_#l<_I zONDW_g@24CK7LYU;T@>*0M=pPrsh)&eG4G~ygNh<*qcNbl)XS=ZvBNamoKMQ@)F7} z_*?%4KStin8L<5|{y+a6{{dmm$N*hD R?DhZv002ovPDHLkV1fyDHJktd diff --git a/Buffs/Alcohol/FireballBuff.png b/Buffs/Alcohol/FireballBuff.png index 8887354d3f1a6f6db84a9b02b7545168d51e9235..37a154a295e400aa6ec0432e4bdc1644a64a1aff 100644 GIT binary patch delta 664 zcmV;J0%!fG1-u22FnJ7`m36vuy88fzPp2E|y~rlDq08Ve!#fZ$`P z;7}@#LI#C)Q*h8h1rdsaAVm=e1wn#N4uYcy;sbO@#SYerR&CSP8YrnDi8Z!y`0g=$ zm)tbgLazTMIp;gy$vyv^*EPak7XZ1XQi&RnDK6Jywjx{x27kc1HSzWjXpqRax?S4A z#rU?07cL~;Y4Sv_xT+t{6qifj1O}`Mi98s~SG=(QzF(J{)aUy`0f6fdt^g3}Jyz2L zIEMji0i(;^ zpmoB5?iK*ThXb17y_=r^I1pVAKwGq3JD*8T1MnpI6M!?fh5`G2ATz~z3b9e{pjEBfs_`&yHo%YYrS36<@hxT=Ee?GymTlA-h=pE8`T&ENmW zz@Ny4iQ^prxXc{j!{T50b3Oy3W{*!b$+X)9l$n?texuX}TLH+pH zJxN4CR9HvVmQP3&Q5?s|zZ>C-Y>}9M7OjNb)q|QE_-{k;VrU=)ib7o^h>!vg-Gb_- zbQ3QL3LZQ}-U`7#XcXcqh?WTcAKiAXWp$#}YBApTz2E2#41cm0_xXV@pSSETGxMD{ z?@f$y%#rX}fn&#F7)97w;K~c__nCBFXElgXIL|kS#fY<|t%y-%?D}V5`5K@rcQn~y zBYoY?VieADFbEI$*5NC*N_ecj3wHHBg9-T>_)sy(q+j`kv=o@|&i#Pj4Yt8{iv=b| z0s+|AfEm&>aDVCv9C!kVI<<{_b6i7GI}4D78lF(G6Nwag=0Jab50g?@p9d4{s!tM# ze=0`d%=`YquNF69;~bc*dIMKXbinei10BiLaLM(2nCM?_gsY1Z;j2aIFtOw2O^v(% zz-CPl@-{$F6N#5!z|O`@IOEn6n9#nz6eG^Yr;D&U>wkeu#@@rFw#P6be*;8k&IIhf zSq|TIU4n_dH2)z&|2vJSH=wTri)Eus zI&o=y&3valV9j0tKYDNjCd}4>?2UQ2EtjtYM99PU3dff_usjVc-J4=k_CNoElW!-% z)IhD1Kighk2sYkd`kokBID}iQL$DEf8zAUjnL%@eF#i6?6(>fV_$B^X$~i!wi8BPp dj&cKv@*iaK_ZLjwpbr25002ovPDHLkV1gv(Dscb+ diff --git a/Buffs/Alcohol/GrapeBeerBuff.png b/Buffs/Alcohol/GrapeBeerBuff.png index d951249d1297185b2dbce93f1556b9c16f4b5a01..9268f682979602022ef579041b3b3e6c7d6921af 100644 GIT binary patch delta 652 zcmV;70(1S91+fK?F@I}GL_t(oh1Hi`NRv?*$A51b7LzS2l8_)%0vn8x;f)tX7Y(7Z z!alCT3)@X~BV9BpGJ+IJL8K3rZn`PRo9H5h2n>P{gBZ9$Y%E$M2FYBMrhCOM&K}~t zZfi?num7v_@jU08=YO8}f1cOa>f8ZZsUs0la$NW{Ma5a{YE zX=BNyvNKR24Qu4C_TQRedTcWQL-G3nc&_>Ym`;6H_AbT9n~`Y%n$GRk{Ko>50JQfu zYvcA|ARi=hxqthO3r%X`U=;xFkm?5K>I<%8ja*6##d}^>MlT*=Q1g!P6?@;G8m)uVbn5Lw~^yN6)+jpyR1x+I|cOgb6{? zJe+Mc0C4u+0RUR!I{_H!2^F>B#plPhzI_?U2k+=U0G4d-MBmfV43+I3p z>yH7!`70Lyn3|Yc)dAKI1Ia~|<%8GXs)5i?V5JVEjc7>+C_e+D$^FM30Z`qbUc)-? zF3s?W-+!$d*~rH$wETNy3ruVE^p6jPMX3i~OcXuK7|gw%ScE}u{n+2l_zsyla8 zs*31w=WESR5c~KI_{)sIJ`7CEL;yHsF_05WZVYq|=Um7dvA`O+)D42NGhpo9<^>?} mD_qpy@mitQ(P)pq<3Bbn#`Q=q83+IX002ovP6b4+LSTYo)-XpUhR2k_r(GD+UiqLoIG18EWxV|#tfHd-v2gZq8VAvl%v}hH5FniLvn4_+8dC`RJFMrO*?3NGDhIH_ojs_%v zf#HQ4QRkV}lZqzPoeln;nlyOX(h7Fh94Q)qb@M*3=+L&J{=d#ZzXmSOKY@JbBP+^c zf!POd!P=8MK-H*a;NknQ-;p{ET3-cCj32k)rw1oj1BLk1)(Ki~y#ytn=LE;x(IC?l z%*LK6Ln;ebBV@*wgN-wng6G*rcCO(;?WbZsdfc8xF=}fxyD%DK)2$*$3TSjTQ-1(>kYpZpV)cew;9Ox z29?+E3|}}+AMxXNper@F88JBw9IMzIbCgt!h}lc-tqF@<=cb2wpsFc18GSB(8%DQa zgs*MAAZT-UF_OeU)N%Kn(BYVz9aVg}@;F%2zAGf;#NX8$o_V@7Ohi{^oe7R}V)+B% zuQSj;6*sTE6?6Qm@?VdGbR#3W@ggn8KyVOj2HhBx?C1C9$Mff$=Xt*8Ip_RN;_;S(w>go>%S*sx^D^82 zN+g+_gvCWg;Ny?B1`fwR=nCXB$^1aB+rA`_kA8YBr@$E|KzyAqpYhD7^e}B1*xhv1cf-`X6UC`XJX-3CP zWf>+0hJFAm3zOi(-CqRunhmWp&NDo847|81iW5Hu=0fqJCoy}E%vO0e;F{w@7b9CBl-vYaqE0w-?w)&{@XLP zfjztO>^KX~K%%@VTGR7`!#TZ<=L_ZQO5^c5z7+@Keafw<0F@JPPL_t(oh2_^!_hYJxkQ7%lmA??D2FsGO7!j-(}eUW2APIJ~~F8+Hr|JgflDSPF6^ZP%~ z^E*A?-?!iM|7B@GqrZzR==7HtZF3imFd=_&D6oC#T(JArrhkzCRnFv)J$%K@kbQYy z_p}y%`T9CCfPv1f9m&iK7UlOnl({suCKffsMzf$9bO!Mw;?P!&i+ z-~Piu?)P|Tg2?!srmu~lPnY1VYmQvQuV>#HnZv-|x{ILVRA8Sfs03w^)u8Iwdhq_^ z7x3^+9hhD`8a#de0O@C*M29nwvKCb2mW1qWUk{*#iGSMIeUP7*3pQ;$iqx4$r|t#C zmnx7!_drSpQlYNfZL~14JhBIzi5~(*z1O5QPsT8i@+SNpj$b^NR=*47L9Hk~xS`GX zzsEqspgd4NV0M%JBnZUY?w>02B>o)+9>2c_a`XT*1`Gy?UVZ;)10Bvl^F0uobUqZw z9@sTx&wqNe1(dBU5BU=(PKNBt>Yyrq+WZxCzLOn_H$3|W3Tmez0~l!5Kr-XHYac*v zlU)`Is^R|1;6I^g;+W6`D^FhqJqM2j(@TPPM9q#};Pa$U?QWpM8EDqPo%vTnf#g}G vLTin*?%!A%KKrB=GEM_oKYjn7uj3!BjK6~Rmkx8o00000NkvXXu0mjfx{XDj diff --git a/Buffs/Alcohol/MoonshineBuff.png b/Buffs/Alcohol/MoonshineBuff.png index b079231309e67f38532f48a75c75a7f6bcafc9db..0f6bc184e98ba7b7117fb59a40a11accf039de9f 100644 GIT binary patch delta 689 zcmV;i0#5zD1=a*DP7@SRR< zl+f36vweThd7k(A-uFAMHKoe{n9F9f6oAakY$4O~!sB+k0Ds(zvfJOhh%hf%;!y?; zx70Z<=pKwK?dk7xfArwY%xo4kP{8F|u~bn&m^ba*rc8Vgc?Q72K&xZF9h0fg01Qo} z0Jzx^0^s$DfZwDYg@EowbB6;D~sY8Gjdpq<~ zKwNyReZSH#%teXNnWF$a?Mnid68U0(GSCD-XLmoKqXKdY>>iMq3v;QGTlNM3i+R=h zN&sTf34g~2-iW+Z+WILVuzNt53q%?5fG9EYx)1n|YJo>`a>t2X0QB~l zom9H@QQ%wdMk5dK!x6S!q00000NkvXXu0mjfR;xf} delta 665 zcmV;K0%rZz1-=E4F@JbTL_t(oh2_^vh)!V`2k_q*2@xhUeA7g33yoZJTMWiVN+HSu zAwscmS(!3RRxT@1B$34wnNsW!W+suw#tg=N3})PKC1Wg(cfQV<&m{{^`LE9VoacSs z^Z!53dCqh4WYOX8A`iO#=jiTK;?!RG5d+?#+-p$+g^fetwrGC%)OxO!lsztKUbi$2F{ipN0xcd zOnh zzm1rOTnE1|H-C$xz`Y_x=1jP87c&>LclW3j*^+^P?vnFk;wG1H5Xw7hBgqi+?_38>_!wBVY8g1V`v@30tqk0$yNGP9guZaO`6RNrPa=H^geqRYdO^${mPx%(n&-?R9J=0mt9B{Q5462yX048rKOSi zfwY=|nP4lLP|yd26h*c#J{Uy=K`4|6MMTs?ASx6>J%kTi*@Gwu6-gz9iJ^pjAVvw6 z=n|V^8tLk`Y!AoVFw?j#B<%cOF6Yddd(Zzr=bn4VmYui)0Dr$f5F`vt_~ye2`zNC9 zb{l|wNoM;GEK|%A65@0Z>dQ(^UpUwLNM}z@&H~^+lx-Rx)&9}cKjE7Xf)x}nIu!F= z7i&#ls9zYB5{h|F>1tivx8_&?rV$02PL=_1;&!VpF5(Kyf z0FH82_u}TeHGcpcIF+LF_tXXen10a}a$&WbBCfz+HL#<6HvoC5%K<2HB>~XeaYq+- zEN?pi-X|V;-XG9CFHGA6KvRQMO|I*(X#&Q04nn(^Mc%50J5A_65y0!w(mUv zDTAE=G7yxbk!vKtodjUAIH%}K|UVR3D z$5$!=aMsiTR#ZSiG5_Sg4nS5#mCjDxBK_iZ-wgn!h6e#CDvyxB|dPaVPOu%{y41JFQz_U=@Al2?}X#=3bC0@l? zAt^(?{l01Qg}S`~Q-8!2ShN!sZ4ho^^6BNKTeJpJHmXpN-F$E})nj zVZBahta_Ds$+Z@78yOnxFYcQ7sVI?>z7f!vEp{p@7#S-V znQKZ5BCdd~I8*L&1EZs1{T(kAN*rm{_&fd$i%joMUbYru00000NkvXXu0mjfLM~d0 delta 790 zcmV+x1L^#j2CN2tllil^mjFk^4?ck%n7NDc`vXuG$;q%}J&SXn|@0B_5 zz-v-21s9Rn?SBEK`4sXj^sNLIDH*`=@SR2Z3vr@wJGlBZ0PO509eYGCp2@Dh0&uBwSY23fEUZhzVg9*&!p{Ey!Iz_}MtfuABC&2dkE;CP=OU?g*+5^SP)mWO4tOgGRu2FUjILSpTLH6DGjH;c za)*=li+|p)A0g`6OF9Eml1XF0Kf_{|#MrCA;8YSa4QSmh1nqd9hDP`+6%xXVSyqOf z=6+|8e(4CU%Q@bz%4Y@pW3K|7*}LzQ@koT`v{I=+sB@5bnac&v>t9vBfxGk8^DBUL zZG*s0mG%`^`Zi_@%07*qoM6N<$g4gYbPyhe` diff --git a/Buffs/Alcohol/OldFashionedBuff.png b/Buffs/Alcohol/OldFashionedBuff.png index 2b6e8fdaf0ad840cdf2e4da5053a08d54ad4049c..eac148a67a5cfdf21ad0bc275ae87db81867c8fa 100644 GIT binary patch delta 620 zcmV-y0+ao-1(5}iFnF=!KE6vuyO9JE7QL`6w3j%~>x@#u+bqjs{z zPC_9;P$+iLQAI&Y6cKbuDI!P%f^=xX&1z=L)gXdJGl>apwBjI2rxxPyzAxpwUehBK z?)qQe-TU6X@7|Ah@8hiDlK}89Rgb_kLS(El{;c>2Y_694uI*8 z!8R(nw*kmF4-9{F2y81=dG2wia`cNiq-;h^Lak0;UKIDpoRP*`xmI)tlwIj++pdUX zc?5vmE2(sRbbr7%fo$e302Go*V_o;aPAbh_ z0-$eDh(wRTcCuH;Hmg)BZ z0j1i+L*xF}Oc?W2MY<1i&L;pl|( z#~NTlygAU2Pzd)J2jSUaHu+XsSQ7ICOEBO4c1I@svabcU-C^@&cBCKXdqUhvNNCdz zU`oK_VLLV$46xZ8IVq_J=<~~$fb=DoITj^z&?QQs&wm1|EDkYe-(%kJG7~B3kga+d z<`bZQM@zc{zBmc2wYI~AKa8JAR#P0T(!nMv^+5kf6KvDh!Gth95OV{*qeoc5yRBG+ zFwz38z7v9$2w|m8BAA(!o`sXYj+?CvdSn114zl^?q={Z(qNH>F$Zc zQq~*CTYrae*34~KoCLh3ld`1H^dC6k=5<*2k-aih6t%$_mRm5-&*dqYKly<@tW=SR zn*c#~6%FbUg8%-BGjcv?z3f@M9w<(BqHt}x*=Rc>?&}>GBIlfdB>e-aV(KcT1E_5P p000hUSV?A0O#mtY000O800000007cclK=n!00>D%PDHLkV1lN*Ejs`J diff --git a/Buffs/Alcohol/RedWineBuff.png b/Buffs/Alcohol/RedWineBuff.png index a3e116c717ce9d106d64146ec71eb5c09915eed7..71d0f1f3d720a2b7e71143f3898dff03e67901ab 100644 GIT binary patch delta 659 zcmV;E0&M-51-J!}F@JJNL_t(oh1HkKYg0iK#(&o~Y1)`XQ%f5SrXo!!QXh1cR5x~^ zBIrNhAE2&;QgNf3qPPjVQa5f?y7IXY-J}*wTPu_<3dK}}22+cIF^`6(QH+bpY>3W? zGb3wXt7`z}SHK9nXEy*3pF9R2o%sg9;h?xb+`GRh0{@papmo?RMS!rc6Mz$L2LRUN zgMfYpIDed50X^U4-k;BjIS=^7+K}0C&GUN&M&e%q6DY9hK2XN^B%q&e!R0gn*^F>Y z=H>b&=JWe@0lI<`g_m;xyhvu1a`Pwc)ldwSWo;M2#y65KTlW7tvIDOKn3ibum5QTzab{hEC$Q zxt(*)oSE;NGmi#XMv=8e0ASr34_bB>MSz2`3!39bLr2*TSARb}1|UBDK(qIS_pfT; zuj$u-0Sbh?24UWGK329v{EA}UvEBxtEC0FT0DYIb0BFC}S=Mik0$%1dcAXaZHG9<+SaA|2BPRej6yK`_whx~Jpr!2$0EvAE z0O);m6M)Io0szy_M_}b{@WR}au-knGK=QqA4@WiuaH_Qhfboej0Ia$V0Hm|(`=?s) z!aM~8qQrd7D*&SQPR&0uavxY`ZiQ71Y`1qPzw-ou!++N0iW4wb0WYSU4*>KGz64-= zBJGLT20$U_wJZ4Dismbjb>{)tlTa_7XuSo%^=pce?1q7%K^0%C;&Jsn=D!F27PWQ* z0QVlMmr=(34#3goRse3_8C_Mrsw=Q`7rZ;tt2u(U+TU^q$Vn*sUC#bOPOW*OQPqa* zjyJB#w`*{AQOo<&QT>{RPXY!guv7!W*d0=gBBl1z*j)flPhJEdTdHnhF7RV6jQwDa z0)j}hT5IpjMG1i@CXo0%KL9B14k}0K8yX9i&0BQ^0>AzKKmQ&70zf>z0Wu&-lF1ZBD4ZxSrmUb0x-}iZhJSS#?H{yJIsDeZ?GVUzZg8|Hg~8B>5)Zg10f@$R08|?OJc+WMOKFEdKE>a@0^st2 zBmg(Y#J|1OynhLR;ovF&?x@K7dIiCJj#i`1_3P*kSk$F^-s|@RR9_1yIaNlckVf+ z4B(j>1|SkxR{96WzXSP6$UQ}S1f&jb*$Tkn_BtTr+<(;B1wdrz0gxdeHNUhIfH#vq z0DQ9{00vJB$8ER8im4d_1=j)jZaoO6({~4Q)&=xc05n<_(`_w~A&^hnCGcS-4uAu( zN4VZC0MK>ioKoj`Iu5`|tC%H^hQ!LbZ?CPW2hc8oLXys%NB0A;=nwqWIR6iUwJ&P` z^j_^#`hOokf2qXV>*@h`|8W8UeNGMd&ISI2dP4f%pYOaK4? delta 702 zcmV;v0zv)j1>*&fF@K#&L_t(oh2_`HYgI=W$MH`Z--%LgX!L4*BNDX|K@nfjR8qvQ z+CnJ`{sV4Y1l))l!G$e_)@Rr~00$=9)4c(!wS+F$3>-Zb5lBl^*7xmLapuWEm)SU_a)r+bzmieOfVf}x*cv}>p z^;!eSv_Fo@@eW#B_ewl^S!M*+kpla@Q zjFGt9aTKh{?1=o*N1#xB`P#M$wZ3uiNKw1?(m-Hg_Cdb=1YGaz9XEb@33LoT1J$O2 zra$k4EjzbIcCEjJ@A}u3VU?UZeF?1itm=&(AiV_sOG)O-H?IN@a_#>s&ig}Pq-O+t zzdJq?o_}q;81-jY%mi)!G=tpm@VIf)L*P(0e!DkyhRiCTJO|a4VKtOKDUIxg2Bt^- zsbyi`$lV+)I$>kgk6_vFUm#5cO0(hn-hXKToL?9A`r0dD?{Aqn5o9uD1tH>0`#Qr3 zDK{L>6~A?z07Gkw6G;z&L^IZf3`cH<+W$KDa5quMgjk})-mK7!)`oXwP}or?v`vcb k@_Oe4N?yADF#nGK1&ElzJY_W)3;+NC07*qoM6N<$f>g?2_W%F@ diff --git a/Buffs/Alcohol/ScrewdriverBuff.png b/Buffs/Alcohol/ScrewdriverBuff.png index 2c0984bc98063f3066432d33ed9d43ac2320c2f6..b84648d68ff3c2ce5b103e44ca55fd338facc542 100644 GIT binary patch delta 642 zcmV-|0)73j1*Zj&FnPe>F|9LGN+o5fh0Y|tNREDzPL+GX47VyEa2 zNTd=4(ZNf0D-ndCLq#1rMRkjXTBt)i%Q4`~@KCM{O3v70&_e)||^ znA}+ucKlx6d%t<_&HH}dzZor}R{}6Mn=|pCkzBw_wSrn*Hh-@Hlr2ebi%>v0*Vlw> z53aSiJ3aq+)>fYRowk+JM%Y#kjSso@Gm;CK;0FTEfO3AQ^Pnw$Gxh+0)_gg!A_!RI zzE-XWVDfnkfF1SsJq^G=1f0%ij7tE-H^`ix>;45m|0${8Iwfg!A^|{K=hX#Ylxz>AnQEuPJ zg=xT#1e6pBrH#m~H}tR@0He;`VIdv8JY{>ee+hV1MM&1l4`dDW6xrqSBk*~wJfC|D zKzQHc2C#exyec;UXeSF;B=mPO_oHt{^EHD-4WRS{)OY^Jj(Gr#x?O;E<|_s3`vI71 zdJjN0+j|EHOvEKep#3C!j^E#BuVQ>FMuysT8f! c{PB1E5By)HNWxpyt^fc407*qoM6N<$f*}bkumAu6 delta 651 zcmV;60(AYS1+N8=Fn<69XF*Lt006O%3;baP00009a7bBm000id000id0mpBsWB>pH zL`g(JR9HvVmS0FyQ5?t5RIZXTbAsT*ltE7|Ukv{}Xlf`3O56x~@g*9pB5L59Ao!B> zB8?u5o;1mbP*ha3g32_CVN#S}kuB#xtQ@jR*riyW?>WEKE`JX7#hrcN%jb7tj>>m;7g97(XL771KC@}Nl!n0gaItot7Dwfv3u&e}2KNe&qFtiO>2{a>DR*8DeiXt$%PqPY-@-njc7&TT#hXWB;KhN?sGIQtIg z*{a~F6JEG-(gUk|4tT89aOsgEnD7kN!{Z;tHrTSa!+(*7Zg}R3=)m>B&K)qL?k@0# zo*}+Z?_#nWj#3A*U({Oz@yJ^g&-lhQaYEXi$6r!#P8dF6K-d} zB)kLBbAMp2Te?gllH@1r)Em{a|A|WU+D2zyONEs&FOqu<#W~QE{OpT-YqnQ@xUGzRD zol5Y1H+Sy2=bX9c`_4Jb-KH6Ob z!2Yt=Vpy>ifPcDr(HpoIGc9Uz`msi?u;vUn+$EJ+fUbr)0Cu%hY6|UF2eo~z*#;UK z3pDv)|11DeOIv8`5Js#yp*pI47*L(?)^2&0JrnZGPB)3-zVjOa7zw8U2ps>ZIqJRS z2B2!20{|m51HjEbIkz%l8wQqC!KsK3faWS;Kt%xG0DtHkmR*oS%}(V&p{OmgTORgf zK;i!A9sqnhB-@=Ck%uN_ebBAH6{p8u0PrT@2VltY0f2`$JiyW_P_Qop3T0l2v~IH$ zc=WUEFF(}_{=!bbsVDnTk>5NS*YtYNNHrbqv}+ZtgrxcQyW<_VoRsI(|NeG^`Ac%( zK&O<6%YT&GpMmN3lHIAaOg;^1k=OWjy^NU>spqn$<397GVp;!d&w%R5q3bfSlve)$ z7AB(B<`Vz}PfD*>J>I+5tvTxM5_!{h*+&gE9|!|#B1%T)0XtTKx*4dfl}YGX(tMWf zF&3kCct+db9g_wSH4>WLwZ>LpVX|8AFR%{-Q%YaWG>)hqFE{OJleM(Ecv(m1EK{_C zid^-B#N)VjzUB-#4%L(a&>x@6>+5*6(745AkFVq3B-_<6^~0x$00000NkvXXu0mjf DgalWF delta 671 zcmV;Q0$~021;hoAF@JtZL_t(oh2@t|XcIvc#(!yp4LwM((hvP)*DN5IA-efMB)-fXw6+0L9D~pnm06I7b0% z)*wrfM7@<=( z{qeoc030#-LoZf<-}i)qa}*d{8U>*5j@b7a&H!*aD)xc1+W~kpQ3jy>)T%zy#U=n^ zyIcSmsWkxNh$4kLN;pRW1*Jr%*#@p9RYdkgQjR$>Jbzl=v&Yf_JwYmVfS^A6f6|kaYzWr|aK3gI!8_Kud6P&L=^}X!wa%B#Hu8R2g zgmm7zxql_fk7TUm0vlR@a}>Dl@6`g0{w)CXze@lRi%YLpJ>Iv!N#hR>i9fnq?6jfZ z57dq5TV6V5_{m|wNeZZnm&{hT)wD-T=Cd5gYKa}wYnq)XNCQY4b9$Z$Rk;;^U4b88 zMwt_1TA<#F6_jH2__dx!&30!RHJ)Skfa{mv{}|`j@pmW8$wYvv=vn{(002ovPDHLk FV1n=ULlXc1 diff --git a/Buffs/Alcohol/TequilaBuff.png b/Buffs/Alcohol/TequilaBuff.png index a6c233e3d1055a2f2ac91b7ec738e38100a57668..dec11238de4d7e70bc6d800d4189a4242eb13f0b 100644 GIT binary patch delta 662 zcmV;H0%`rO1+4{;BYyw^b5ch_0Itp)=>Px%XGugsR9J=8mrqC(Q5?rVQ??bmq=lwt zp?g_L@s=JkjnbeXJj6nWjL zeQ^r_UtO72-V|O0;AOA_fXx?&^BRD22xL3=RCH+#6Q4!^xD;pxAaM6B0O8pPu)6b~ zH~l&5okPG*;(t7S?=}E|ryBvdaHJi8Gk5L-urD|U*gLf&;~WArQ&9lgyyIqxx~AWS z061ql7wtHxzPa!5Gr-CPAu)Hh0f3sp(24^nIswDw-KDLB!_~h5*xOtUz=Khh?I(`b z1J*1leXa<-9)AMBR5Xe@i|D+bD7Ty=s&-x+o{lg!16PpLDS&%T}LREAE#`e-} z8GvwK3x5FRUbRwvYdZkIm5$2*)Ossd>?jpm)Z*xmBw+0YBAHExhtw&$=meH>Kt{GC z^Bgb`JO;q|;3Hu9S}$rPrN!6Au4}REo|c?OK(ai7BC)$h|K{Q-+ll0gouvI|lc=1$ wL`5fH9IsbSC+3rR{T;8BTC27?k7&$UD3(WSur&_fWPt0@Se z$jeDX#Lrwl4Hg#@vIEom(|f_Rj2Z`3JDjlOs>T^g{lHV7kB+631C{AR%X>YYG;B zg_Z`ufa5~z~o`{;0Xbki{K$~2O^@W#Rq1r+i??2UtL%YQ;J4& zfcZxm*wDoBa|d4tz}yQ9iS)OSxDE1vqyaPC9Iz4|aeoPzQZW7Q8l(=;p4SEDUwsJ) zk^2mnP}HGw25$(UyY$J^mtY|t7l_X{Or40L#Lm$Qg-DDPrXG~gisZxLO!*oWdiW=TkiHtkL#SX^FF97P_T z^XnyQU4QWW+jp>%g3F7+^shijE&KQRFEC&GgcFz^@DPBv2Vg$_bo>k0Wqi;ONavmj z=FhyJ4yJLH_0|j!pMezt37F5nTYQ5EJ%`Dl(gPj>@HB8E@Cb_2U~z>ah{S<~7)%IV x{eMShm=u_1xdGwB)D4<6015#Z7@56e06$N&=@7te&L98)002ovPDHLkV1nG~G3EdO diff --git a/Buffs/Alcohol/TequilaSunriseBuff.png b/Buffs/Alcohol/TequilaSunriseBuff.png index ef5bee8678b9c04fc69b1dcf6ddc3c7761f5e4be..37faf7b8c939dac2b10ae20526544f6100b3b6e7 100644 GIT binary patch delta 718 zcmV;<0x|vN1?2^hBYyw^b5ch_0Itp)=>Px%pGibPR9J=0mrY1iQ5462(_~5?8Y;a( zsHtI4VxpvlMTHuJ1h$BxBq`cR4S_+;qSa^w)~+cq`oy511ch2et&%`8YF1@RB{eiS zffM6IE@V^&Tikby`y6v9Vcvi9-o5vn^UnEkxc5HC=7uu>e1CsGFiQ@aN>Aiswy0d* zdI!L=C5iSQaul!IJ_~R#{8U>AzT27AAzb}N8&7=vw+}z>tOIO7V7YZdDmPm1XLSf( zSL;He=teC7-*#`*>|EO((Ob1lujn(x4^m;M?IM-at z`k~&AG60T*#(%YW`w+0|TCER&=BCvERQT4bg>n}F_in3Ud+RFzs)p70Y+EA$U;E+! zT=fkC^D7tGhrq8dlK@mk&I3^DOasu}qt=_7M%BDgpanR7Vp8+(?pX`KK3V;&tN&wDTNZdU6831>u^0OZSQD&$Rfa$pE`q7~u064cyWwjHnif;hm=a`z0 zjgP1WwXJaaZk1+lKLQ^D{QwxD9RSqrs{sCxAYNc~(Il0BGAn<4?CoFe?MFcLqQlJG zBq4HpTz^^ZW6?2fyjbNT`w|cd3Ay_ndZ>s938_5Siml2&0lDYjT5$k?BJ;eLJ%3Jn z)Z=KsIuly_`vK^hc?Q5se<14z(n-BHQi&M=Jmxt61ms0BD@A2&p!R$rarw#<0NO(B zT7VYwx%Yxe;$oTRC#A|6BJo9eC*UY7_Ra!CPDiOdUQRXZ%}07;AUqkgI{*Lx07*qoM6N<$f@#uvle?HpSeK4#5^kSP`446$BNO z5QY#Q^xz>6mJpQaExVM~Ee~}mlx#sg1a$}xTUpU@4@;=*x(lwGt*IflwruYA=9}fc z+U(>^w1@fL_rL!+|M$)R-i&!#_Lt5MH)NETxyz;vxz!(Tl7FcJ$`86PNohUh=Os>Z zb9$6RU}R}h;(tp%Cq5$8atHF&imBXl(XCE__xOY}bmCNc9`TTOkCZ?0b^&~>^)9fk zzeAcQvD^W(2VPVUpeQOYta`&Dfuo)GfrpQZyju^N!Ov9I0-qg70mq*Nfa_gs(*rpj zci`ya&u(AeFU7Qh_Z9C8MJ2BY`-$WB+$4m3a(qi+ zWpO}9$!3YCW|H7n3Oa!;C(i;Ou8I@R8v@mqZ-{eZOcURN`9X)6Fs}SNo_8k@vAhS& zlaPuR$G@R6r{MrA?msk)c-OgZLyLeGgEebcF-LlIyAPPG7vB|JZ>0SKmOEhXf?)k? zsk-$lr(;~C=BMlAXU|?>o^5&{;{bpE=YPjP0a)(Zx1g7IApigX07*qoM6N<$f{?;i AF#rGn diff --git a/Buffs/Alcohol/VodkaBuff.png b/Buffs/Alcohol/VodkaBuff.png index 485745f8055d66c02af555cec9cde56926ae420b..835b57cfbacd476be117e50897361a6f8b549c76 100644 GIT binary patch delta 662 zcmV;H0%`rC1+4{;BYyw^b5ch_0Itp)=>Px%XGugsR9J=8mr+QQQ51l`Ey1XU#a6~j z!UrKNMjJtI64WZtRZvN&j}bvo6c|NNP@qOp)RUEu5(PdODQNZ7%N~N+gRUY>vdtWu z*xZsWEqgfsP43TzYYF>3FXx_n?>YCJ??3-`f1A@?2f*BXdVhfeB%7HjWZRNrx0l%f z?8_4EKcq}mzQIwWEd*Lm<#Z_TIIG!@XV(>Va5giu09GJio=}yaZ`z;Jp|eADgUc&} z#1K$C3F{CrS6=PNY8%H=RQ|=&h;MHhlRM24Fh)6o9t2b^tb3y8syMe-6OQ z=99qEy zvyYD@G`~aje(^VY;pl^I0D8~0X#3Rsv(twGD-uwmNPisgI{?^oY_B*x8USE2_#S}p zcH2K4XeMG^0%rO9%>BDX8w4Do2mmSH)}j(vIRrk3&VOHGf71`}U+vQDSn?+TZ|}(OLFoyofy%7XuqWS%-g4yz09}_Z%0!Q-M07$6 zl!%JVjTkMNYWTd#wyd%!3+TIrt6xc+Z1TAVqH|_KVlMRbR@2= wmz;pjwc`W;sjou?eH|~CII6tX_&WXrQBt`dF%NCR{r~^~07*qoM6N<$f+;;UtpET3 delta 651 zcmV;60(AYY1)>FzBYy&ENkl|d%+CHnZ+pLFwWo!0d${pND9Cl38r73e}4m}cmH7q(>H&=1=Ek9 zd@u(Kfy?JGrGqB~U@k(Ze?0#H7J72zDVP>B(gV|BG0|YUud^FWGdzJ%q>_Ut1YUjk z2zI>8i$7rc;|oZf!+gG2X)jp3t+X9Xiz783Qf@wnrcQF0x>>)6Xo*NF^PXLSC z9xMRUFkL`nn0wWA;5bMQUrcBl0nyk z!pBuB4xJFVckT+I^SFJd7LV#-vq~-J4NC)gafi)2R z%O79Be66?SRfmHo1QtuCqeL9DBpaCD%rGBJfAfLFIZV+9Xc}Nxat$nWP53WF>N!jW zgof3EFn`g%&wqiL+9#aA^xz2rn2$dlhr}r#Gz6+{LRvog?`J|hu?9lDdHM{(fRb+@ z4JL+lXCbxXuRut<0_I~B#Ymh14*_`3=tkfXBzG||5OO&z#9*4x)&F;dw4Pz|EH@y0 ln7Toe29T?=k=Z*206#FSZNta>KmY&$07*qoL^;gF@K&(L_t(oh0T{wNK{c2#(z)8(L(w+1C2V2p(qt(32D*NpoLNk zqg4^PZsnpyVvC?=Q&6iSii{u#0->M?O0mtPX8C84IWkr<>4XhTR?bM{OpEhwah*3h zm@x0#JkGi2p8LMGKCI`ggsa(QVMNuIJK!3ryWcv>|6!Y?p4sD>j zbD!me)=MLrJ+qKp)55WMDh+l}V7WsvcQ>_JPUxl!fU}Rb0kAL^0U#D0Thj~JM}g(c z3u@13fvMm<;2(2Ooy3QFp69gC5}39qzP1MuSYF8~hJ8vsm2DppKX<&oNORUZZ5;e!B>T?uukn3+ZUP|D(+j|x$DL+`%YSmge*b;|cD4@!c2qz?RlR3W zlz5UH(8iBBhk95Yq zz$*YIrhh&H@NQW4+Uaxxkc{Y6z8dnbfU&8>NCSMh)(C*hyB&az4ypdll{)}vEPHF2 zK;03M*)RYOkDQMFpnN^wX?JV!>eg+!Jr3AFfsF3~g}YVm-vzR zA^`5@^8lpB?pn^aj{;qNGXS(v4rK0~s*P+g>NqY~`W1845j$^8XybWTz}W4U^Bey8 lJEy delta 683 zcmV;c0#yCv1<(bMF@K6lL_t(oh2@t`NK{c2$A6Q)C8J0CQnhQ&EG(VV^5ic@8l0h!wa00c@sVn=5Hh>RCl`oCzn0YF{LdCPhGFpyh$k$08m z_$@RE%vSE%S_!~l+Ym=pOC^;Iw}w0F&|P zq899|Z3bZD!+$-1ofw#iCjeMyWB^DQa^?@7)&mesitEk|TL9SMleiJnK3pu<`aXwXJC#JHoEr%@TKr70K2Ok0E7+Syot&^(jz5-qX68$*9GKf!oEt_ zoNNc+NU7Mxe!14v9Mb&C*P429@Bjd*w&wu6YrSN8lz%K}1NLJ;L3O?7ttj84Ot&_F z%=uVuT5bX`IGi$Pr1JiB+%m6vH*CIA3)qoo zeE|S^dWEqeK5F@L-wpO>Kp|p`01)g7Y2(U{#bPpGGO$qCmw`>DriYCpb7UHT_O1>9 zK8J?@_$0A!5dqBdY32JU(rw23>@7XX;diVj?>exDO6&w1Fn9snaUCJ8zWxC~zuQ!@0jVVMHJ`SN0`{lPRA%KpztWnQ zsyr9=VL-vXOTP84M{dmU@U(n5knSrJU!QCIE=+3IPxe`2fh=Yy-f1=yu78?ArAqU?*|@>cvw4a`wrY&7>U#pg#f8%C%~hJlzpC)ej5} z18`t>c>(-C1mqo`JKt%lw|)bEtEne2@hJ-wcSMr=YrORUG;dR@;f+4E7R2JqO%ISv zDET1$A$V_Ue|&hJsVuAR(YPv4Jps9q$V36-8hdsE0DsE`0P?=lnNFNXyY>S`fO_+qcRM;AS4#f*1wBs3 ZKL8`*ziWv=b9Dd!002ovPDHLkV1n)?}AGb6`4$BXV8BzTP?d+8g7z~yWH=Y717JMa3&4ZK5CEI~2Q~M;3pW60xO2reoH+~> zR$grRG{-ORzXFijGY`Pv$uIyz;c{_E*e~Ezxq>+iIN?`33Bcs*DF9N|1OTVb%e4`{ zyXBt}Fo%KZSv8IMFd+>1pUcBt3KBRg0!K zhk@|iO8{D)h`fLMUI4b1R%#PUcV$+!P+{c?<}jd;XX2B{-BlL>xYSUj`916^24HYT zWbZb;7b4Lf0BZf0mrcMt1{4$%-iZnTB4tuxNGt4;9XGy<}#q* z_en+7Rfhp63UmVS__o-`MxFr>dnd2A zeDmJ}e}mfNw(FgmzOV;Yigjlo|0<5vz0eG9OS=Eqa5DgbYIz6jE7Jq0n^4^cpQq9Q zyoo;&{ceeQ%|8 Date: Mon, 26 May 2025 15:09:45 -0700 Subject: [PATCH 238/401] removed Alicorn mount --- Buffs/Mounts/AlicornBuff.cs | 21 ---- Buffs/Mounts/AlicornBuff.png | Bin 698 -> 0 bytes CalPlayer/CalamityPlayerDashEffects.cs | 16 --- Items/Mounts/AlicornMount.cs | 113 ------------------ Items/Mounts/AlicornMountExtra.png | Bin 6218 -> 0 bytes Items/Mounts/AlicornMount_Back.png | Bin 35381 -> 0 bytes Items/Mounts/AlicornMount_Front.png | Bin 34765 -> 0 bytes Items/Mounts/Fabsol.cs | 27 ----- Items/Mounts/Fabsol.png | Bin 391 -> 0 bytes .../en-US/Mods.CalamityMod.Buffs.hjson | 5 - .../en-US/Mods.CalamityMod.Items.Mounts.hjson | 9 -- NPCs/DevourerofGods/DevourerofGodsHead.cs | 3 - 12 files changed, 194 deletions(-) delete mode 100644 Buffs/Mounts/AlicornBuff.cs delete mode 100644 Buffs/Mounts/AlicornBuff.png delete mode 100644 Items/Mounts/AlicornMount.cs delete mode 100644 Items/Mounts/AlicornMountExtra.png delete mode 100644 Items/Mounts/AlicornMount_Back.png delete mode 100644 Items/Mounts/AlicornMount_Front.png delete mode 100644 Items/Mounts/Fabsol.cs delete mode 100644 Items/Mounts/Fabsol.png diff --git a/Buffs/Mounts/AlicornBuff.cs b/Buffs/Mounts/AlicornBuff.cs deleted file mode 100644 index 34dad87b5a..0000000000 --- a/Buffs/Mounts/AlicornBuff.cs +++ /dev/null @@ -1,21 +0,0 @@ -using CalamityMod.Items.Mounts; -using Terraria; -using Terraria.ModLoader; -namespace CalamityMod.Buffs.Mounts -{ - public class AlicornBuff : ModBuff - { - public override void SetStaticDefaults() - { - Main.buffNoTimeDisplay[Type] = true; - Main.buffNoSave[Type] = true; - } - - public override void Update(Player player, ref int buffIndex) - { - player.mount.SetMount(ModContent.MountType(), player); - player.buffTime[buffIndex] = 10; - player.Calamity().fab = true; - } - } -} diff --git a/Buffs/Mounts/AlicornBuff.png b/Buffs/Mounts/AlicornBuff.png deleted file mode 100644 index f821a3a2bb71527df4ca911d380834231f53a37a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 698 zcmV;r0!96aP)Px%bV)=(R9J=OmrY1iQ51l`2@7%h!JkP)nJg*^)0jr-hlnVfs1`wk5hW!EO)axc zNwg@4R<-E|cNG=EFhVUVZDEi^q+>LLL^PCzF-#L9R1?w07WW;8`$nJBMlbYj9`C+; z&wJ6v0K87d0l5E0Wqxp-%3RC{S2r93VC}=L zfB^>bY9RY6Q_#ZVvgH6gk39h(;JX9lGA|T!3|wqJ48Uk2txf0+Tmc|DJ_JC&docjR z1CIeHFRE47<7c&XQZrH;_F53kF<{4E+5|xDN{>3STa8&u*wd z^S5hp%`qU@GZ&h?3$*hcR&Q?!ZqmlPlB#o(mRfLr0P_skar;XF2wHD}d$n3}!P?bY zta-s^b^XZkLjcrt>;+)O`lD)s)PN0h4D9MV2|zEZ^Vw@bOmHs+Kxc5@lmWBR@qc;% za|{U5^GR5pu)si(LA5tXEeIcmZ#k|r$AIi!@&&ZN@(%zZHUrc52SGBgyWXb7n+bCa z*pbdBHPIbWMtWxWI+oo~_?`LaINw|YcEm`JY6E$h3SQ45Aph%GnEWqLo95gba807*qoM6N<$g3Tf_%K!iX diff --git a/CalPlayer/CalamityPlayerDashEffects.cs b/CalPlayer/CalamityPlayerDashEffects.cs index 279dff0a6d..e66c90baa5 100644 --- a/CalPlayer/CalamityPlayerDashEffects.cs +++ b/CalPlayer/CalamityPlayerDashEffects.cs @@ -489,22 +489,6 @@ public bool DoADash(float dashSpeed) public void ModHorizontalMovement() { - if (Player.mount.Active && Player.mount.Type == ModContent.MountType() && Math.Abs(Player.velocity.X) > Player.mount.DashSpeed - Player.mount.RunSpeed / 2f) - { - Rectangle damageHitbox = Player.getRect(); - - if (Player.direction == 1) - damageHitbox.Offset(Player.width - 1, 0); - - damageHitbox.Width = 2; - damageHitbox.Inflate(6, 12); - float damage = Player.GetTotalDamage().ApplyTo(800f); - float knockback = 10f; - int NPCImmuneTime = 30; - int playerImmuneTime = 6; - DoMountDashDamage(damageHitbox, damage, knockback, NPCImmuneTime, playerImmuneTime); - } - if (Player.mount.Active && Player.mount.Type == ModContent.MountType() && Math.Abs(Player.velocity.X) > Player.mount.RunSpeed / 2f) { Rectangle damageHitbox = Player.getRect(); diff --git a/Items/Mounts/AlicornMount.cs b/Items/Mounts/AlicornMount.cs deleted file mode 100644 index 2a03f2de57..0000000000 --- a/Items/Mounts/AlicornMount.cs +++ /dev/null @@ -1,113 +0,0 @@ -using CalamityMod.Buffs.Mounts; -using CalamityMod.CalPlayer; -using CalamityMod.NPCs.TownNPCs; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using Terraria; -using Terraria.Audio; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Items.Mounts -{ - public class AlicornMount : ModMount - { - public override void SetStaticDefaults() - { - MountData.spawnDust = 234; - MountData.spawnDustNoGravity = true; - MountData.buff = ModContent.BuffType(); - MountData.heightBoost = 35; - MountData.fallDamage = 0f; - MountData.runSpeed = 5.6f; - MountData.dashSpeed = 17.6f; - MountData.flightTimeMax = 9999; - MountData.fatigueMax = 0; - MountData.jumpHeight = 12; - MountData.acceleration = 0.4f; - MountData.jumpSpeed = 9.21f; - MountData.swimSpeed = 4f; - MountData.blockExtraJumps = false; - MountData.totalFrames = 15; - MountData.constantJump = false; - int baseYOffset = 26; - int[] array = new int[MountData.totalFrames]; - for (int l = 0; l < array.Length; l++) - { - array[l] = baseYOffset; - } - array[1] = array[3] = array[5] = array[7] = array[12] = baseYOffset - 2; - MountData.playerYOffsets = array; - MountData.xOffset = -4; - MountData.bodyFrame = 3; - MountData.yOffset = 5; //-8 - MountData.playerHeadOffset = 36; //30 - MountData.standingFrameCount = 1; - MountData.standingFrameDelay = 12; - MountData.standingFrameStart = 0; - MountData.runningFrameCount = 8; //7 - MountData.runningFrameDelay = 42; //36 - MountData.runningFrameStart = 1; //9 - MountData.flyingFrameCount = 6; //0 - MountData.flyingFrameDelay = 4; //0 - MountData.flyingFrameStart = 9; //0 - MountData.inAirFrameCount = 1; //1 - MountData.inAirFrameDelay = 12; //12 - MountData.inAirFrameStart = 10; //10 - MountData.idleFrameCount = 1; //4 - MountData.idleFrameDelay = 12; //12 - MountData.idleFrameStart = 5; - MountData.idleFrameLoop = true; - MountData.swimFrameCount = MountData.inAirFrameCount; - MountData.swimFrameDelay = MountData.inAirFrameDelay; - MountData.swimFrameStart = MountData.inAirFrameStart; - if (Main.netMode != NetmodeID.Server) - { - MountData.frontTextureExtra = ModContent.Request("CalamityMod/Items/Mounts/AlicornMountExtra"); - MountData.textureWidth = MountData.backTexture.Width(); - MountData.textureHeight = MountData.backTexture.Height(); - } - } - - public override void UpdateEffects(Player player) - { - CalamityPlayer modPlayer = player.Calamity(); - if (modPlayer.fabsolVodka) - player.GetDamage() += 0.1f; - - if (player.velocity.Length() > 9f) - { - int rand = Main.rand.Next(2); - bool momo = false; - if (rand == 1) - { - momo = true; - } - Color meme; - if (momo) - { - meme = new Color(255, 68, 242); - } - else - { - meme = new Color(25, 105, 255); - } - Rectangle rect = player.getRect(); - int dust = Dust.NewDust(new Vector2(rect.X, rect.Y), rect.Width, rect.Height, DustID.BoneTorch, 0, 0, 0, meme); - Main.dust[dust].noGravity = true; - } - - if (player.velocity.Y != 0f) - { - if (player.mount.PlayerOffset == 28) - { - if (!player.flapSound) - SoundEngine.PlaySound(SoundID.Item32, player.Center); - player.flapSound = true; - } - else - player.flapSound = false; - } - } - } -} diff --git a/Items/Mounts/AlicornMountExtra.png b/Items/Mounts/AlicornMountExtra.png deleted file mode 100644 index b544a94ba8497797cd381d8ca31687e99b320948..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6218 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 W5^QWItPZ3I09c#bn_;i|{Q6Jlh$?~r diff --git a/Items/Mounts/AlicornMount_Back.png b/Items/Mounts/AlicornMount_Back.png deleted file mode 100644 index fcb20c4308f2f0e278f893a4b9bdc0ca98f46ff1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35381 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 z 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­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 "Items.Mounts"; - public override void SetDefaults() - { - Item.width = 16; - Item.height = 16; - Item.useTime = 20; - Item.useAnimation = 20; - Item.useStyle = ItemUseStyleID.Swing; - Item.UseSound = SoundID.Item3; - Item.noMelee = true; - Item.mountType = ModContent.MountType(); - - Item.value = Item.buyPrice(platinum: 3); - Item.rare = ModContent.RarityType(); - Item.Calamity().devItem = true; - } - } -} diff --git a/Items/Mounts/Fabsol.png b/Items/Mounts/Fabsol.png deleted file mode 100644 index 485a6245d0eb8358df253985d0ba485528599015..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 391 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz1!3HFCgzU0`6k~CayA#8@b22Z19F}xPUq=Rp zjs4tz5?O(K&H|6fVg?4j!ywFfJby(BP*AeOHKHUqKdq!Zu_%?HATcwqL@zJ3M8QPQ zK+n+FggLqjsOY<=i(`m~_tD841)B^c+>9CW9?X5tbnVQ8ix;cQ%EZLPriJ(=K4gm8 z$sioDtI;~(f$B5He=f@E2j9OF{qysa0{e>m&Ayj{ieq$nVs1Zu_tMv*`_iSO7G3ch zO6y~c&YnMX_D|l1$6Eh|mAsaDtFQ5X^Q}x{N6M^aOFHkywYS>XNv?Z++WkeVc+r${ zSNX7D^%((OKXk0>&GvE&7Nm6jTx)P+R+4N*!?cQm#Nb7i{d{d7oPHYJIKV65)hNQR z&N5%%5clfdMF(tdi?TiYvgzc#12%Ieco<&)Q*=g9q2+^9QwNh%-#KrlXNNgcHGYBI gG&|PjwwEo#-36=7^on@j0E2+R)78&qol`;+0C^Rd*Z=?k diff --git a/Localization/en-US/Mods.CalamityMod.Buffs.hjson b/Localization/en-US/Mods.CalamityMod.Buffs.hjson index 7fbe343d4c..15bc9cc356 100644 --- a/Localization/en-US/Mods.CalamityMod.Buffs.hjson +++ b/Localization/en-US/Mods.CalamityMod.Buffs.hjson @@ -243,11 +243,6 @@ WeakBrimstoneFlames: { Description: Using the Supreme Witch's power causes you to suffer, but makes your weapons strong } -AlicornBuff: { - DisplayName: Alicorn - Description: You beat DoG while drunk, you are truly fabulous! -} - AndromedaBuff: { DisplayName: Andromeda Description: You're controlling a piece of history diff --git a/Localization/en-US/Mods.CalamityMod.Items.Mounts.hjson b/Localization/en-US/Mods.CalamityMod.Items.Mounts.hjson index 88b741e48c..5058993fbb 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Mounts.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Mounts.hjson @@ -13,15 +13,6 @@ ExoThrone: { ''' } -Fabsol: { - DisplayName: Princess Spirit in a Bottle - Tooltip: - ''' - Summons the spirit of Cirrus, the Drunk Princess, in her alicorn form - Mounting will transform Cirrus, dismounting transforms her back - ''' -} - FollyFeed: { DisplayName: Folly Feed Tooltip: Summons a monstrosity diff --git a/NPCs/DevourerofGods/DevourerofGodsHead.cs b/NPCs/DevourerofGods/DevourerofGodsHead.cs index 085b5eff9b..c54d87f1e5 100644 --- a/NPCs/DevourerofGods/DevourerofGodsHead.cs +++ b/NPCs/DevourerofGods/DevourerofGodsHead.cs @@ -2707,9 +2707,6 @@ public override void ModifyNPCLoot(NPCLoot npcLoot) // Extraneous potions npcLoot.DefineConditionalDropSet(() => true).Add(DropHelper.PerPlayer(ModContent.ItemType(), 1, 5, 15), hideLootReport: true); // Healing Potions don't show up in the Bestiary - // Fabsol Mount - npcLoot.AddIf((info) => info.player.Calamity().fabsolVodka, ModContent.ItemType()); - // Normal drops: Everything that would otherwise be in the bag var normalOnly = npcLoot.DefineNormalOnlyDropSet(); { From 614d3aac4b68c8434fb8fde1713706b4b93abdb3 Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Mon, 26 May 2025 15:13:41 -0700 Subject: [PATCH 239/401] Pot of Pain internal rename --- Items/Potions/{Fabsoup.cs => PotofPain.cs} | 5 +++-- Items/Potions/{Fabsoup.png => PotofPain.png} | Bin NPCs/ExoMechs/Ares/AresBody.cs | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) rename Items/Potions/{Fabsoup.cs => PotofPain.cs} (93%) rename Items/Potions/{Fabsoup.png => PotofPain.png} (100%) diff --git a/Items/Potions/Fabsoup.cs b/Items/Potions/PotofPain.cs similarity index 93% rename from Items/Potions/Fabsoup.cs rename to Items/Potions/PotofPain.cs index e532b991b1..c41d88cdad 100644 --- a/Items/Potions/Fabsoup.cs +++ b/Items/Potions/PotofPain.cs @@ -8,7 +8,8 @@ namespace CalamityMod.Items.Potions { - public class Fabsoup : ModItem, ILocalizedModType + [LegacyName("Fabsoup")] + public class PotofPain : ModItem, ILocalizedModType { public new string LocalizationCategory => "Items.Potions"; public static readonly SoundStyle UseSound = new("CalamityMod/Sounds/Item/SoupConsumption"); @@ -36,7 +37,7 @@ public override void SetDefaults() public override void UseItemFrame(Player player) { - int time = CalamityUtils.SecondsToFrames(1980f); // 33 minutes + int time = CalamityUtils.SecondsToFrames(1800); // 30 minutes if (player.itemAnimation == 180) { player.AddBuff(BuffID.WellFed3, time); diff --git a/Items/Potions/Fabsoup.png b/Items/Potions/PotofPain.png similarity index 100% rename from Items/Potions/Fabsoup.png rename to Items/Potions/PotofPain.png diff --git a/NPCs/ExoMechs/Ares/AresBody.cs b/NPCs/ExoMechs/Ares/AresBody.cs index 631b09ff53..efc20d104a 100644 --- a/NPCs/ExoMechs/Ares/AresBody.cs +++ b/NPCs/ExoMechs/Ares/AresBody.cs @@ -1594,7 +1594,7 @@ public static void DefineExoMechLoot(NPC npc, NPCLoot npcLoot, int mechType) npcLoot.Add(ItemDropRule.BossBagByCondition(DropHelper.If(CanDropLoot), ModContent.ItemType())); // Legendary seed soup - mainDrops.Add(ItemDropRule.ByCondition(DropHelper.If(info => info.npc.type == ModContent.NPCType() && info.npc.ModNPC().exoMechdusa), ModContent.ItemType()), hideLootReport: true); + mainDrops.Add(ItemDropRule.ByCondition(DropHelper.If(info => info.npc.type == ModContent.NPCType() && info.npc.ModNPC().exoMechdusa), ModContent.ItemType()), hideLootReport: true); // All other drops are contained in the bag, so they only drop directly on Normal if (!Main.expertMode) From 538b8e6171e9530901471d3a298c834387cd8003 Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Mon, 26 May 2025 15:32:02 -0700 Subject: [PATCH 240/401] alicorn remnants --- CalPlayer/CalamityPlayer.cs | 3 --- CalPlayer/DrawLayers/MountsAboveOwnerLayer.cs | 2 +- Items/CalamityGlobalItemTooltip.cs | 4 ---- Items/Weapons/Summon/LiliesOfFinality.cs | 5 +---- 4 files changed, 2 insertions(+), 12 deletions(-) diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 9d841079d2..fd9d03c9ce 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -299,7 +299,6 @@ public partial class CalamityPlayer : ModPlayer #region Mount public bool onyxExcavator = false; public bool rimehound = false; - public bool fab = false; public bool crysthamyr = false; public bool ExoChair = false; public AndromedaPlayerState andromedaState; @@ -1596,7 +1595,6 @@ public override void ResetEffects() onyxExcavator = false; rimehound = false; - fab = false; crysthamyr = false; ExoChair = false; miniOldDuke = false; @@ -2413,7 +2411,6 @@ public override void UpdateDead() hallowedPower = false; onyxExcavator = false; rimehound = false; - fab = false; crysthamyr = false; ExoChair = false; abyssalDivingSuitPlates = false; diff --git a/CalPlayer/DrawLayers/MountsAboveOwnerLayer.cs b/CalPlayer/DrawLayers/MountsAboveOwnerLayer.cs index d0c1cdcc9b..06a652df22 100644 --- a/CalPlayer/DrawLayers/MountsAboveOwnerLayer.cs +++ b/CalPlayer/DrawLayers/MountsAboveOwnerLayer.cs @@ -13,7 +13,7 @@ public override bool GetDefaultVisibility(PlayerDrawSet drawInfo) { Player drawPlayer = drawInfo.drawPlayer; CalamityPlayer modPlayer = drawPlayer.Calamity(); - return drawPlayer.mount != null && (modPlayer.fab || modPlayer.crysthamyr || modPlayer.onyxExcavator); + return drawPlayer.mount != null && (modPlayer.crysthamyr || modPlayer.onyxExcavator); } protected override void Draw(ref PlayerDrawSet drawInfo) diff --git a/Items/CalamityGlobalItemTooltip.cs b/Items/CalamityGlobalItemTooltip.cs index 39f43104af..c6082a66b3 100644 --- a/Items/CalamityGlobalItemTooltip.cs +++ b/Items/CalamityGlobalItemTooltip.cs @@ -258,10 +258,6 @@ void AddTooltip(string text) // Numerous random tooltip edits which don't fit into another category #region Various Tooltip Edits - // Lilies of Finality 512 edit - if (item.type == ModContent.ItemType()) - EditTooltipByName("Damage", (line) => line.Text = LiliesOfFinality.TheNumber + " summon damage"); - // Apparently 612 is a homestuck reference if (item.type == ModContent.ItemType()) EditTooltipByName("AxePower", (line) => line.Text = line.Text.Replace("610%", "612%")); diff --git a/Items/Weapons/Summon/LiliesOfFinality.cs b/Items/Weapons/Summon/LiliesOfFinality.cs index 7e441ab524..4dd6fc07a2 100644 --- a/Items/Weapons/Summon/LiliesOfFinality.cs +++ b/Items/Weapons/Summon/LiliesOfFinality.cs @@ -32,14 +32,11 @@ public class LiliesOfFinality : ModItem, ILocalizedModType public static int Ariane_AoESize = 1050; public static float Ariane_AoEDMGMultiplier = 0.4f; - // Do not change this number, ever. - Fabsol - public const int TheNumber = 512; - #endregion public override void SetDefaults() { - Item.damage = TheNumber; + Item.damage = 512; Item.DamageType = DamageClass.Summon; Item.shoot = ProjectileType(); Item.knockBack = 5f; From 98af1dd6b623ac170c4ab53691813a954a1ac28e Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Mon, 26 May 2025 15:39:20 -0700 Subject: [PATCH 241/401] cirrus dress vestiges --- CalPlayer/CalamityPlayer.cs | 1 - CalPlayer/CalamityPlayerLifeRegen.cs | 2 +- CalPlayer/CalamityPlayerMiscEffects.cs | 5 ----- Projectiles/Boss/BrimstoneMonster.cs | 2 +- 4 files changed, 2 insertions(+), 8 deletions(-) diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 650a520ff5..19da4da9c8 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -90,7 +90,6 @@ public partial class CalamityPlayer : ModPlayer public int searedPanCounter = 0; public int searedPanTimer = 0; public int potionTimer = 0; - public bool cirrusDress = false; public bool blockAllDashes = false; public bool resetHeightandWidth = false; public bool noLifeRegen = false; diff --git a/CalPlayer/CalamityPlayerLifeRegen.cs b/CalPlayer/CalamityPlayerLifeRegen.cs index e864ba3579..64f8d4b1fc 100644 --- a/CalPlayer/CalamityPlayerLifeRegen.cs +++ b/CalPlayer/CalamityPlayerLifeRegen.cs @@ -263,7 +263,7 @@ void ApplyDoTDebuff(bool hasDebuff, int negativeLifeRegenToApply, bool immuneCon alcoholPoisonLevel++; } - if (alcoholPoisonLevel > (cirrusDress ? 5 : 3)) + if (alcoholPoisonLevel > 3) { // Independently of Calamity's nerfs to Nebula life regen, it is disabled entirely by alcohol poisoning. Player.nebulaLevelLife = 0; diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index 2f3638a3f7..c325d0efe4 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -1090,8 +1090,6 @@ private void MiscEffects() if (!Player.wet) { - if (cirrusDress) - Player.maxFallSpeed = 12f; if (aeroSet) Player.maxFallSpeed = 15f; if (Player.PortalPhysicsEnabled) @@ -2728,9 +2726,6 @@ private void OtherBuffEffects() if (Player.chilled) Player.moveSpeed *= 1f + (1f / 6f); - if (cirrusDress) - Player.moveSpeed -= 0.2f; - if (fabsolVodka) Player.GetDamage() += 0.08f; diff --git a/Projectiles/Boss/BrimstoneMonster.cs b/Projectiles/Boss/BrimstoneMonster.cs index 2c3c91a063..e0b5d5a5d3 100644 --- a/Projectiles/Boss/BrimstoneMonster.cs +++ b/Projectiles/Boss/BrimstoneMonster.cs @@ -283,7 +283,7 @@ public override bool CanHitPlayer(Player player) if (Colliding(Projectile.Hitbox, player.Hitbox) == false) return false; - // Applies Vulnerability Hex and/or the effects of Supreme Cirrus' HAGE faces. + // Applies Vulnerability Hex and/or the effects of Supreme Permafrost's HAGE faces. OnHitPlayer_Internal(player); // Check the player's speed. If they are moving fast enough, damage them more severely; this prevents trying to rush straight through the vortex. From 026f80d585c11c9f532e300a7a3166fc5cab5d83 Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Mon, 26 May 2025 16:59:33 -0700 Subject: [PATCH 242/401] ...Ozzathoth. --- Items/CalamityGlobalItemTooltip.cs | 2 ++ .../Melee/{Azathoth.cs => Ozzathoth.cs} | 3 ++- .../Melee/{Azathoth.png => Ozzathoth.png} | Bin ...Mods.CalamityMod.Items.Weapons.Melee.hjson | 20 +++++++++--------- .../{AzathothYoyo.cs => OzzathothYoyo.cs} | 4 ++-- .../{AzathothYoyo.png => OzzathothYoyo.png} | Bin 6 files changed, 16 insertions(+), 13 deletions(-) rename Items/Weapons/Melee/{Azathoth.cs => Ozzathoth.cs} (95%) rename Items/Weapons/Melee/{Azathoth.png => Ozzathoth.png} (100%) rename Projectiles/Melee/Yoyos/{AzathothYoyo.cs => OzzathothYoyo.cs} (96%) rename Projectiles/Melee/Yoyos/{AzathothYoyo.png => OzzathothYoyo.png} (100%) diff --git a/Items/CalamityGlobalItemTooltip.cs b/Items/CalamityGlobalItemTooltip.cs index c6082a66b3..62eb89a710 100644 --- a/Items/CalamityGlobalItemTooltip.cs +++ b/Items/CalamityGlobalItemTooltip.cs @@ -102,6 +102,8 @@ private void ApplyRarityColor(Item item, TooltipLine nameLine) nameLine.OverrideColor = new Color(0.34f, 0.34f + 0.66f * Main.DiscoG / 255f, 0.34f + 0.5f * Main.DiscoG / 255f); if (item.type == ModContent.ItemType()) nameLine.OverrideColor = ShatteredCommunity.GetRarityColor(); + if (item.type == ModContent.ItemType()) + nameLine.OverrideColor = ShatteredCommunity.GetRarityColor(); if (item.type == ModContent.ItemType()) nameLine.OverrideColor = CalamityUtils.ColorSwap(new Color(255, 166, 0), new Color(25, 250, 25), 6f); //alternates between emerald green and amber (BanditHueh) if (item.type == ModContent.ItemType()) diff --git a/Items/Weapons/Melee/Azathoth.cs b/Items/Weapons/Melee/Ozzathoth.cs similarity index 95% rename from Items/Weapons/Melee/Azathoth.cs rename to Items/Weapons/Melee/Ozzathoth.cs index 3685b98f2f..48dd268241 100644 --- a/Items/Weapons/Melee/Azathoth.cs +++ b/Items/Weapons/Melee/Ozzathoth.cs @@ -8,7 +8,8 @@ namespace CalamityMod.Items.Weapons.Melee { - public class Azathoth : ModItem, ILocalizedModType + [LegacyName("Azathoth")] + public class Ozzathoth : ModItem, ILocalizedModType { public new string LocalizationCategory => "Items.Weapons.Melee"; public override void SetStaticDefaults() diff --git a/Items/Weapons/Melee/Azathoth.png b/Items/Weapons/Melee/Ozzathoth.png similarity index 100% rename from Items/Weapons/Melee/Azathoth.png rename to Items/Weapons/Melee/Ozzathoth.png diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson index 900d659de4..12befb24f3 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson @@ -142,16 +142,6 @@ Avalanche: { Tooltip: Spawns ice bombs that explode after 3 seconds into ice shards on hit } -Azathoth: { - DisplayName: Azathoth - Tooltip: - ''' - Fires cosmic orbs that blast nearby enemies with lasers - An exceptionally agile yoyo - 'Destroy the universe in the blink of an eye' - ''' -} - BalefulHarvester: { DisplayName: Baleful Harvester Tooltip: Summons flaming pumpkins and skulls that split into homing fire orbs on enemy hits @@ -872,6 +862,16 @@ Orderbringer: { ''' } +Ozzathoth: { + DisplayName: Ozzathoth + Tooltip: + ''' + Fires cosmic orbs that blast nearby enemies with lasers + An exceptionally agile yoyo + 'Destroy the universe in the blink of an eye' + ''' +} + Pandemic: { DisplayName: Pandemic Tooltip: diff --git a/Projectiles/Melee/Yoyos/AzathothYoyo.cs b/Projectiles/Melee/Yoyos/OzzathothYoyo.cs similarity index 96% rename from Projectiles/Melee/Yoyos/AzathothYoyo.cs rename to Projectiles/Melee/Yoyos/OzzathothYoyo.cs index 2f99f79c09..ffa062055b 100644 --- a/Projectiles/Melee/Yoyos/AzathothYoyo.cs +++ b/Projectiles/Melee/Yoyos/OzzathothYoyo.cs @@ -7,9 +7,9 @@ namespace CalamityMod.Projectiles.Melee.Yoyos { - public class AzathothYoyo : ModProjectile + public class OzzathothYoyo : ModProjectile { - public override LocalizedText DisplayName => CalamityUtils.GetItemName(); + public override LocalizedText DisplayName => CalamityUtils.GetItemName(); public const int MaxUpdates = 3; public override void SetStaticDefaults() diff --git a/Projectiles/Melee/Yoyos/AzathothYoyo.png b/Projectiles/Melee/Yoyos/OzzathothYoyo.png similarity index 100% rename from Projectiles/Melee/Yoyos/AzathothYoyo.png rename to Projectiles/Melee/Yoyos/OzzathothYoyo.png From 36eac4e9868f17a6e118aab7e50ed567469d545d Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Mon, 26 May 2025 17:01:18 -0700 Subject: [PATCH 243/401] candle localization fix --- .../en-US/Mods.CalamityMod.Buffs.hjson | 58 ++++++------------- 1 file changed, 19 insertions(+), 39 deletions(-) diff --git a/Localization/en-US/Mods.CalamityMod.Buffs.hjson b/Localization/en-US/Mods.CalamityMod.Buffs.hjson index 15bc9cc356..2e355ab0d1 100644 --- a/Localization/en-US/Mods.CalamityMod.Buffs.hjson +++ b/Localization/en-US/Mods.CalamityMod.Buffs.hjson @@ -448,29 +448,14 @@ YharonSonBuff: { Description: You better not eat his dinner } -ChaosCandleBuff: { - DisplayName: Chaos Candle - Description: Spawn rates around the candle are boosted! -} - -CirrusBlueCandleBuff: { +BlueCandleBuff: { DisplayName: Limber Description: The floating flame seems to uplift your very spirit } -CirrusPinkCandleBuff: { - DisplayName: Vigor - Description: The brilliant light suffuses you with hope -} - -CirrusPurpleCandleBuff: { - DisplayName: Resilience - Description: Neither rain nor wind can snuff your undying flame -} - -CirrusYellowCandleBuff: { - DisplayName: Spite - Description: The hateful, flickering glow fuels your ire +ChaosCandleBuff: { + DisplayName: Chaos Candle + Description: Spawn rates around the candle are boosted! } CorruptionEffigyBuff: { @@ -488,11 +473,26 @@ EffigyOfDecayBuff: { Description: The sulphuric waters empower you } +PinkCandleBuff: { + DisplayName: Vigor + Description: The brilliant light suffuses you with hope +} + +PurpleCandleBuff: { + DisplayName: Resilience + Description: Neither rain nor wind can snuff your undying flame +} + TranquilityCandleBuff: { DisplayName: Tranquility Candle Description: Spawn rates around the candle are reduced! } +YellowCandleBuff: { + DisplayName: Spite + Description: The hateful, flickering glow fuels your ire +} + PopoBuff: { DisplayName: Popo Description: You are a snowman now! @@ -1515,23 +1515,3 @@ LiliesOfFinalityBuff: { DisplayName: Finality Description: Remember our promise } - -BlueCandleBuff: { - DisplayName: Blue Candle Buff - Description: Mods.CalamityMod.Buffs.BlueCandleBuff.Description -} - -PinkCandleBuff: { - DisplayName: Pink Candle Buff - Description: Mods.CalamityMod.Buffs.PinkCandleBuff.Description -} - -PurpleCandleBuff: { - DisplayName: Purple Candle Buff - Description: Mods.CalamityMod.Buffs.PurpleCandleBuff.Description -} - -YellowCandleBuff: { - DisplayName: Yellow Candle Buff - Description: Mods.CalamityMod.Buffs.YellowCandleBuff.Description -} From 011b83a69665e59cf1e237f323359dcc2548c968 Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Mon, 26 May 2025 17:16:57 -0700 Subject: [PATCH 244/401] Milkshake, Shroom, and Candle redistribution --- .../en-US/Mods.CalamityMod.Items.Misc.hjson | 2 +- NPCs/CalamityGlobalTownNPC.cs | 13 +++++++++++-- Utilities/CalamityRecipes.cs | 7 +++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Misc.hjson b/Localization/en-US/Mods.CalamityMod.Items.Misc.hjson index d45b77358d..35996f701a 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Misc.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Misc.hjson @@ -281,7 +281,7 @@ BrimstoneLocus: { ColdheartIcicle: { DisplayName: Coldheart Icicle - Tooltip: "'Critically aclaimed vendetta'" + Tooltip: "'N(ice) work'" } MomentumCapacitor: { diff --git a/NPCs/CalamityGlobalTownNPC.cs b/NPCs/CalamityGlobalTownNPC.cs index 46fa17050f..4b121285e5 100644 --- a/NPCs/CalamityGlobalTownNPC.cs +++ b/NPCs/CalamityGlobalTownNPC.cs @@ -4,7 +4,6 @@ using CalamityMod.Items; using CalamityMod.Items.Accessories; using CalamityMod.Items.Ammo; -using CalamityMod.Items.Armor; using CalamityMod.Items.Armor.Vanity; using CalamityMod.Items.Dyes; using CalamityMod.Items.Dyes.HairDye; @@ -12,6 +11,7 @@ using CalamityMod.Items.Placeables.Furniture; using CalamityMod.Items.Placeables.Furniture.Fountains; using CalamityMod.Items.Potions; +using CalamityMod.Items.Potions.Alcohol; using CalamityMod.Items.SummonItems.Invasion; using CalamityMod.Items.Weapons.Melee; using CalamityMod.Items.Weapons.Ranged; @@ -1177,7 +1177,11 @@ public override void ModifyShop(NPCShop shop) .AddWithCustomValue(ItemID.SpectreStaff, Item.buyPrice(gold: 25), Condition.DownedGolem) .AddWithCustomValue(ItemID.InfernoFork, Item.buyPrice(gold: 25), Condition.DownedGolem) .AddWithCustomValue(ItemID.ShadowbeamStaff, Item.buyPrice(gold: 25), Condition.DownedGolem) - .AddWithCustomValue(ItemID.MagnetSphere, Item.buyPrice(gold: 25), Condition.DownedGolem); + .AddWithCustomValue(ItemID.MagnetSphere, Item.buyPrice(gold: 25), Condition.DownedGolem) + .Add(ItemType()) + .Add(ItemType()) + .Add(ItemType()) + .Add(ItemType()); } if (type == NPCID.WitchDoctor) @@ -1228,6 +1232,11 @@ public override void ModifyShop(NPCShop shop) { shop.AddWithCustomValue(ItemID.Steak, Item.buyPrice(gold: 5), Condition.HappyEnoughToSellPylons, Condition.Hardmode); } + + if (type == NPCID.Truffle) + { + shop.Add(ItemType()); + } } #endregion } diff --git a/Utilities/CalamityRecipes.cs b/Utilities/CalamityRecipes.cs index bc4aefe0a0..85c3c4dda1 100644 --- a/Utilities/CalamityRecipes.cs +++ b/Utilities/CalamityRecipes.cs @@ -1231,6 +1231,13 @@ private static void AddCookedFood() r.Register(); r.DisableDecraft(); + r = Recipe.Create(ItemID.Milkshake); + r.AddIngredient(ItemID.IceBlock); + r.AddIngredient(ItemID.MilkCarton); + r.AddTile(TileID.IceMachine); + r.Register(); + r.DisableDecraft(); + r = Recipe.Create(ItemID.Nachos); r.AddIngredient(ItemID.PotatoChips); r.AddIngredient(ItemID.MilkCarton); From 50b34fef35e4064df02805d32f510d6d2eeebd47 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Mon, 26 May 2025 20:17:01 -0400 Subject: [PATCH 245/401] Slight update to the Old Fashioned icon by Dia --- Buffs/Alcohol/OldFashionedBuff.png | Bin 657 -> 660 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Buffs/Alcohol/OldFashionedBuff.png b/Buffs/Alcohol/OldFashionedBuff.png index eac148a67a5cfdf21ad0bc275ae87db81867c8fa..df44c6c27874f170e26edaeac97e19c9c5ca3d1b 100644 GIT binary patch delta 623 zcmV-#0+9WY1(XGlFn<69XF*Lt006O%3;baP0006cNklZAa>#GRv*$006{GOfO-**qs-p5v%Cx5`sfrwLgIvabkxgePt z!gk~jj$iZ4?sL3I_L|Q(r%Z>twJ;R?_yr#O4Ou1-nCpVQ_ujy1lz^PvH)w~gn5v$Iy;YQu8R{j_@4;HQ zn;%mn@%bOXFMnRv!2hCA*hsdW5*q$60b3=Z?m19bNbXp94$u4=fqk#u!R^u4FzEj(B@OV*03~KjLYV}vO6%y888$ud0ryRs(2dVyenz%rcRGR3w8vbJD3O#W zaOMXn(uz?`ELMx!oxg>;A8tWeakLjs?uYbAV1H3VF@Nz$48{Dn&!dvqTBR}}eG>Q^ zq6*g7P@(>5RCp+Y()=3gyrevVq?3>d*%MDfCibmbc8O$F_+>}vCt=3|>}?Ffj5_}X zw{s|g(4;)ut~tp!3Lwu@`d!CHpTN%iGT6xK(hs<F=!KE6vuyO9JE7QL`6w3j%~>x@#u+bqjs{z zPC_9;P$+iLQAI&Y6cKbuDI!P%f^=xX&1z=L)gXdJGl>apwBjI2rxxPyzAxpwUehBK z?)qQe-TU6X@7|Ah@8hiDlK}89Rgb_kLS(El{;c>2Y_694uI*8 z!8R(nw*kmF4-9{F2y81=dG2wia`cNiq-;h^Lak0;UKIDpoRP*`xmI)tlwIj++pdUX zc?5vmE2(sRbbr7%fo$e302Go*V_o;aPAbh_ z0-$eDh(wRTcCuH;Hmg)BZ z0j1i+L*xF}Oc? Date: Mon, 26 May 2025 20:30:59 -0400 Subject: [PATCH 246/401] Change TML build metadata author to The Calamity Dev Team --- build.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.txt b/build.txt index b2de9aca5b..23f413337a 100644 --- a/build.txt +++ b/build.txt @@ -1,4 +1,4 @@ -author = Fabsol and the Dev Team +author = The Calamity Dev Team version = 2.0.4.006 displayName = Calamity Mod modReferences = CalamityModMusic From a734752c8ee3718ba91130571b1228dbf7b4c751 Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Mon, 26 May 2025 18:12:58 -0700 Subject: [PATCH 247/401] renamed Fabsol's Vodka, princess sells boxes --- .../{FabsolVodkaBuff.cs => PurpleHazeBuff.cs} | 4 +-- ...FabsolVodkaBuff.png => PurpleHazeBuff.png} | Bin CalPlayer/CalamityPlayer.cs | 6 ++-- CalPlayer/CalamityPlayerLifeRegen.cs | 2 +- CalPlayer/CalamityPlayerMiscEffects.cs | 4 +-- CalamityLists.cs | 2 +- .../{FabsolsVodka.cs => PurpleHaze.cs} | 6 ++-- .../{FabsolsVodka.png => PurpleHaze.png} | Bin .../Mods.CalamityMod.Items.Potions.hjson | 22 +++++++------- NPCs/CalamityGlobalNPCLoot.cs | 4 +-- NPCs/CalamityGlobalTownNPC.cs | 12 +++++++- Projectiles/Magic/FabRay.cs | 28 ++---------------- Utilities/PlayerUtils.cs | 2 +- 13 files changed, 39 insertions(+), 53 deletions(-) rename Buffs/Alcohol/{FabsolVodkaBuff.cs => PurpleHazeBuff.cs} (83%) rename Buffs/Alcohol/{FabsolVodkaBuff.png => PurpleHazeBuff.png} (100%) rename Items/Potions/Alcohol/{FabsolsVodka.cs => PurpleHaze.cs} (90%) rename Items/Potions/Alcohol/{FabsolsVodka.png => PurpleHaze.png} (100%) diff --git a/Buffs/Alcohol/FabsolVodkaBuff.cs b/Buffs/Alcohol/PurpleHazeBuff.cs similarity index 83% rename from Buffs/Alcohol/FabsolVodkaBuff.cs rename to Buffs/Alcohol/PurpleHazeBuff.cs index b74e8639c1..9ef31ce2b1 100644 --- a/Buffs/Alcohol/FabsolVodkaBuff.cs +++ b/Buffs/Alcohol/PurpleHazeBuff.cs @@ -4,7 +4,7 @@ namespace CalamityMod.Buffs.Alcohol { - public class FabsolVodkaBuff : ModBuff + public class PurpleHazeBuff : ModBuff { public override void SetStaticDefaults() { @@ -16,7 +16,7 @@ public override void SetStaticDefaults() public override void Update(Player player, ref int buffIndex) { - player.Calamity().fabsolVodka = true; + player.Calamity().purpleHaze = true; } } } diff --git a/Buffs/Alcohol/FabsolVodkaBuff.png b/Buffs/Alcohol/PurpleHazeBuff.png similarity index 100% rename from Buffs/Alcohol/FabsolVodkaBuff.png rename to Buffs/Alcohol/PurpleHazeBuff.png diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 19da4da9c8..73799d9669 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -926,7 +926,7 @@ public GemTechArmorState GemTechState public bool zen = false; public bool isNearbyBoss = false; public bool flaskBrimstone = false; - public bool fabsolVodka = false; + public bool purpleHaze = false; public bool mushy = false; public bool PinkJellyRegen = false; public bool GreenJellyRegen = false; @@ -1990,7 +1990,7 @@ public override void ResetEffects() trippy = false; amidiasBlessing = false; flaskBrimstone = false; - fabsolVodka = false; + purpleHaze = false; shine = false; anechoicCoating = false; mushy = false; @@ -2447,7 +2447,7 @@ public override void UpdateDead() sulphurskin = false; baguette = false; flaskBrimstone = false; - fabsolVodka = false; + purpleHaze = false; shine = false; anechoicCoating = false; mushy = false; diff --git a/CalPlayer/CalamityPlayerLifeRegen.cs b/CalPlayer/CalamityPlayerLifeRegen.cs index 64f8d4b1fc..552c94e8e7 100644 --- a/CalPlayer/CalamityPlayerLifeRegen.cs +++ b/CalPlayer/CalamityPlayerLifeRegen.cs @@ -183,7 +183,7 @@ void ApplyDoTDebuff(bool hasDebuff, int negativeLifeRegenToApply, bool immuneCon { alcoholPoisonLevel++; } - if (fabsolVodka) + if (purpleHaze) { alcoholPoisonLevel++; } diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index c325d0efe4..453888b943 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -2726,7 +2726,7 @@ private void OtherBuffEffects() if (Player.chilled) Player.moveSpeed *= 1f + (1f / 6f); - if (fabsolVodka) + if (purpleHaze) Player.GetDamage() += 0.08f; if (vodka) @@ -4022,7 +4022,7 @@ private void DefenseEffects() // Multiplicative defense reductions. // These are done last because they need to be after the defense lower cap at 0. - if (fabsolVodka) + if (purpleHaze) { if (Player.statDefense > 0) Player.statDefense -= (int)(Player.statDefense * 0.05); diff --git a/CalamityLists.cs b/CalamityLists.cs index 0fba8bdfb7..06f07af2ee 100644 --- a/CalamityLists.cs +++ b/CalamityLists.cs @@ -1521,7 +1521,7 @@ public static void LoadLists() BuffType(), BuffType(), BuffType(), - BuffType(), + BuffType(), BuffType(), BuffType(), BuffType(), diff --git a/Items/Potions/Alcohol/FabsolsVodka.cs b/Items/Potions/Alcohol/PurpleHaze.cs similarity index 90% rename from Items/Potions/Alcohol/FabsolsVodka.cs rename to Items/Potions/Alcohol/PurpleHaze.cs index 1b17d807a5..bf1f06e481 100644 --- a/Items/Potions/Alcohol/FabsolsVodka.cs +++ b/Items/Potions/Alcohol/PurpleHaze.cs @@ -1,5 +1,4 @@ using CalamityMod.Buffs.Alcohol; -using CalamityMod.Items.Accessories.Vanity; using CalamityMod.Items.Materials; using Terraria; using Terraria.ID; @@ -7,7 +6,8 @@ namespace CalamityMod.Items.Potions.Alcohol { - public class FabsolsVodka : ModItem, ILocalizedModType + [LegacyName("FabsolsVodka")] + public class PurpleHaze : ModItem, ILocalizedModType { public new string LocalizationCategory => "Items.Potions"; @@ -28,7 +28,7 @@ public override void SetDefaults() Item.useStyle = ItemUseStyleID.DrinkLiquid; Item.UseSound = SoundID.Item3; Item.consumable = true; - Item.buffType = ModContent.BuffType(); + Item.buffType = ModContent.BuffType(); Item.buffTime = CalamityUtils.SecondsToFrames(900f); Item.value = Item.buyPrice(0, 2, 60, 0); } diff --git a/Items/Potions/Alcohol/FabsolsVodka.png b/Items/Potions/Alcohol/PurpleHaze.png similarity index 100% rename from Items/Potions/Alcohol/FabsolsVodka.png rename to Items/Potions/Alcohol/PurpleHaze.png diff --git a/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson b/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson index 41a4f76216..62e6e4da80 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson @@ -227,17 +227,6 @@ EvergreenGin: { ''' } -FabsolsVodka: { - DisplayName: Fabsol's Vodka - Tooltip: - ''' - 8% increased damage, but lowers defense by 5% - Increases immune time after being struck - Drinking more than 3 different alcohols might not end well with your liver - This magical liquor is highly sought by those with a refined palate - ''' -} - Fireball: { DisplayName: Fireball Tooltip: @@ -309,6 +298,17 @@ OldFashioned: { ''' } +PurpleHaze: { + DisplayName: Purple Haze + Tooltip: + ''' + 8% increased damage, but lowers defense by 5% + Increases immune time after being struck + Drinking more than 3 different alcohols might not end well with your liver + This magical liquor is highly sought by those with a refined palate + ''' +} + RedWine: { DisplayName: Red Wine Tooltip: diff --git a/NPCs/CalamityGlobalNPCLoot.cs b/NPCs/CalamityGlobalNPCLoot.cs index df219525c4..34e5d7488f 100644 --- a/NPCs/CalamityGlobalNPCLoot.cs +++ b/NPCs/CalamityGlobalNPCLoot.cs @@ -1607,8 +1607,8 @@ bool ShouldDropMechLore(DropAttemptInfo info) rev.Add(ItemID.FairyQueenMasterTrophy); rev.Add(ItemID.FairyQueenPetItem, 4); - // GFB Fabsol's Vodka and Terraformer drop - GFB.Add(ModContent.ItemType(), 1, 1, 9999, true); + // GFB Purple Haze and Terraformer drop + GFB.Add(ModContent.ItemType(), 1, 1, 9999, true); GFB.Add(ItemID.Clentaminator2, hideLootReport: true); // Lore diff --git a/NPCs/CalamityGlobalTownNPC.cs b/NPCs/CalamityGlobalTownNPC.cs index 4b121285e5..7b2ae7d317 100644 --- a/NPCs/CalamityGlobalTownNPC.cs +++ b/NPCs/CalamityGlobalTownNPC.cs @@ -1204,6 +1204,12 @@ public override void ModifyShop(NPCShop shop) if (type == NPCID.Princess) { + Mod musicMod = CalamityMod.Instance.musicMod; + musicMod.TryFind("Interlude1MusicBox", out ModItem interlude1Box); + musicMod.TryFind("Interlude2MusicBox", out ModItem interlude2Box); + musicMod.TryFind("Interlude3MusicBox", out ModItem interlude3Box); + musicMod.TryFind("DevourerofGodsEulogyMusicBox", out ModItem eulogyBox); + shop.AddWithCustomValue(ItemID.PrincessWeapon, Item.buyPrice(gold: 50)) .Add(ItemType()) .Add(ItemID.AppleJuice) @@ -1211,7 +1217,11 @@ public override void ModifyShop(NPCShop shop) .Add(ItemID.Lemonade) .Add(ItemID.PrismaticPunch) .Add(ItemID.SmoothieofDarkness) - .Add(ItemID.TropicalSmoothie); + .Add(ItemID.TropicalSmoothie) + .AddWithCustomValue(interlude1Box.Type, Item.buyPrice(gold: 10), CalamityConditions.DownedCalamitasClone) + .AddWithCustomValue(interlude2Box.Type, Item.buyPrice(gold: 10), Condition.DownedMoonLord) + .AddWithCustomValue(interlude3Box.Type, Item.buyPrice(gold: 10), CalamityConditions.DownedYharon) + .AddWithCustomValue(eulogyBox.Type, Item.buyPrice(gold: 10), CalamityConditions.DownedDevourerOfGods); } if (type == NPCID.SkeletonMerchant) diff --git a/Projectiles/Magic/FabRay.cs b/Projectiles/Magic/FabRay.cs index a58f5f7bfa..3305ae8e90 100644 --- a/Projectiles/Magic/FabRay.cs +++ b/Projectiles/Magic/FabRay.cs @@ -49,16 +49,7 @@ public override void AI() if (potentialTarget != null) { Vector2 shootVelocity = Projectile.SafeDirectionTo(potentialTarget.Center) * 13f; - int p = Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center - shootVelocity * 2.5f, shootVelocity, ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner); - if (p.WithinBounds(Main.maxProjectiles)) - { - if (Projectile.hostile) - { - Main.projectile[p].hostile = true; - Main.projectile[p].friendly = false; - Main.projectile[p].DamageType = DamageClass.Default; - } - } + Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center - shootVelocity * 2.5f, shootVelocity, ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner); } for (int i = 0; i < Projectile.oldPos.Length / 4; i += 3) @@ -67,16 +58,7 @@ public override void AI() if (potentialTarget != null) { Vector2 shootVelocity = (potentialTarget.Center - Projectile.oldPos[i]).SafeNormalize(Vector2.UnitY) * 13f; - int p = Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.oldPos[i] - shootVelocity * 2.5f, shootVelocity, ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner); - if (p.WithinBounds(Main.maxProjectiles)) - { - if (Projectile.hostile) - { - Main.projectile[p].hostile = true; - Main.projectile[p].friendly = false; - Main.projectile[p].DamageType = DamageClass.Default; - } - } + Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.oldPos[i] - shootVelocity * 2.5f, shootVelocity, ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner); break; } } @@ -130,11 +112,5 @@ public override bool OnTileCollide(Vector2 oldVelocity) } return false; } - - public override void OnHitPlayer(Player target, Player.HurtInfo info) - { - if (Projectile.hostile) - target.AddBuff(ModContent.BuffType(), 54000); - } } } diff --git a/Utilities/PlayerUtils.cs b/Utilities/PlayerUtils.cs index cdead115fc..d162e94b21 100644 --- a/Utilities/PlayerUtils.cs +++ b/Utilities/PlayerUtils.cs @@ -467,7 +467,7 @@ public static int GetExtraHitIFrames(this Player player, HurtInfo hurtInfo) if (modPlayer.rampartOfDeities && hurtInfo.Damage > 200) extraIFrames += 30; - if (modPlayer.fabsolVodka) + if (modPlayer.purpleHaze) { if (hurtInfo.Damage == 1) extraIFrames += 5; From baf68bcb91fae4a6ed7409b62ef0e3d96e302239 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Mon, 26 May 2025 21:14:19 -0400 Subject: [PATCH 248/401] Mirror removals of dedicated items on main branch (Scarlet Devil is preserved) --- Buffs/Mounts/BrimroseMount.cs | 2 +- Buffs/StatBuffs/KamiBuff.cs | 26 ---- Buffs/StatBuffs/KamiBuff.png | Bin 423 -> 0 bytes Buffs/StatDebuffs/KamiFlu.cs | 30 ----- Buffs/StatDebuffs/KamiFlu.png | Bin 514 -> 0 bytes CalPlayer/CalamityPlayer.cs | 5 - CalPlayer/CalamityPlayerMiscEffects.cs | 3 - CalPlayer/DrawLayers/YanmeiKnifeTrailLayer.cs | 46 ------- CalamityLists.cs | 16 --- Items/Mounts/Brimrose.cs | 2 +- .../{PhuppersChair.cs => BrimroseChair.cs} | 2 +- ...sChair_Back.png => BrimroseChair_Back.png} | Bin ...hair_Front.png => BrimroseChair_Front.png} | Bin .../DevPaintings/ThankYouPainting.cs | 1 - Items/Weapons/Magic/DivineRetribution.cs | 103 ---------------- Items/Weapons/Magic/DivineRetribution.png | Bin 2013 -> 0 bytes Items/Weapons/Ranged/DodusHandcannon.cs | 58 --------- Items/Weapons/Ranged/DodusHandcannon.png | Bin 761 -> 0 bytes Items/Weapons/Typeless/YanmeisKnife.cs | 70 ----------- Items/Weapons/Typeless/YanmeisKnife.png | Bin 739 -> 0 bytes .../en-US/Mods.CalamityMod.Buffs.hjson | 10 -- ...Mods.CalamityMod.Items.Weapons.Magic.hjson | 5 - ...ods.CalamityMod.Items.Weapons.Ranged.hjson | 9 -- ...s.CalamityMod.Items.Weapons.Typeless.hjson | 12 -- .../Mods.CalamityMod.Projectiles.Magic.hjson | 1 - .../Mods.CalamityMod.Projectiles.Ranged.hjson | 1 - ...ods.CalamityMod.Projectiles.Typeless.hjson | 1 - .../CalamityBossAIs/AquaticScourgeAI.cs | 1 - .../CalamityBossAIs/BumblebirbAI.cs | 1 - NPCs/CalamityGlobalNPC.cs | 23 ---- NPCs/CalamityGlobalTownNPC.cs | 1 - NPCs/Leviathan/Leviathan.cs | 1 - NPCs/NormalNPCs/SkeletronPrime2.cs | 1 - .../PlaguebringerGoliath.cs | 1 - NPCs/PrimordialWyrm/PrimordialWyrmHead.cs | 1 - .../Bosses/QueenBeeAI.cs | 1 - .../Bosses/SkeletronPrimeAI.cs | 1 - .../DraedonsArsenal/PhaseslayerBeam.cs | 2 + Projectiles/Magic/BeamingBolt2.cs | 2 + Projectiles/Magic/DivineRetributionSpear.cs | 108 ---------------- Projectiles/Magic/DivineRetributionSpear.png | Bin 633 -> 0 bytes .../Ranged/HighExplosivePeanutShell.cs | 93 -------------- Projectiles/Summon/MiniGuardianAttack.cs | 1 - Projectiles/Summon/MiniGuardianDefense.cs | 2 +- Projectiles/Summon/MiniGuardianHealer.cs | 2 +- Projectiles/Typeless/YanmeisKnifeSlash.cs | 115 ------------------ Projectiles/Typeless/YanmeisKnifeSlash.png | Bin 1646 -> 0 bytes TileEntities/TECalamityPylon.cs | 2 +- 48 files changed, 10 insertions(+), 752 deletions(-) delete mode 100644 Buffs/StatBuffs/KamiBuff.cs delete mode 100644 Buffs/StatBuffs/KamiBuff.png delete mode 100644 Buffs/StatDebuffs/KamiFlu.cs delete mode 100644 Buffs/StatDebuffs/KamiFlu.png delete mode 100644 CalPlayer/DrawLayers/YanmeiKnifeTrailLayer.cs rename Items/Mounts/{PhuppersChair.cs => BrimroseChair.cs} (98%) rename Items/Mounts/{PhuppersChair_Back.png => BrimroseChair_Back.png} (100%) rename Items/Mounts/{PhuppersChair_Front.png => BrimroseChair_Front.png} (100%) delete mode 100644 Items/Weapons/Magic/DivineRetribution.cs delete mode 100644 Items/Weapons/Magic/DivineRetribution.png delete mode 100644 Items/Weapons/Ranged/DodusHandcannon.cs delete mode 100644 Items/Weapons/Ranged/DodusHandcannon.png delete mode 100644 Items/Weapons/Typeless/YanmeisKnife.cs delete mode 100644 Items/Weapons/Typeless/YanmeisKnife.png delete mode 100644 Projectiles/Magic/DivineRetributionSpear.cs delete mode 100644 Projectiles/Magic/DivineRetributionSpear.png delete mode 100644 Projectiles/Ranged/HighExplosivePeanutShell.cs delete mode 100644 Projectiles/Typeless/YanmeisKnifeSlash.cs delete mode 100644 Projectiles/Typeless/YanmeisKnifeSlash.png diff --git a/Buffs/Mounts/BrimroseMount.cs b/Buffs/Mounts/BrimroseMount.cs index 787bc90c18..9b8cdac784 100644 --- a/Buffs/Mounts/BrimroseMount.cs +++ b/Buffs/Mounts/BrimroseMount.cs @@ -14,7 +14,7 @@ public override void SetStaticDefaults() public override void Update(Player player, ref int buffIndex) { - player.mount.SetMount(ModContent.MountType(), player); + player.mount.SetMount(ModContent.MountType(), player); player.buffTime[buffIndex] = 10; } } diff --git a/Buffs/StatBuffs/KamiBuff.cs b/Buffs/StatBuffs/KamiBuff.cs deleted file mode 100644 index 00520d718e..0000000000 --- a/Buffs/StatBuffs/KamiBuff.cs +++ /dev/null @@ -1,26 +0,0 @@ -using CalamityMod.Items.Weapons.Typeless; -using Terraria; -using Terraria.Audio; -using Terraria.ModLoader; - -namespace CalamityMod.Buffs.StatBuffs -{ - public class KamiBuff : ModBuff - { - public const float RunSpeedBoost = 0.15f; - public const float RunAccelerationBoost = 0.15f; - public override void SetStaticDefaults() - { - Main.debuff[Type] = false; - Main.pvpBuff[Type] = true; - Main.buffNoSave[Type] = true; - } - - public override void Update(Player player, ref int buffIndex) - { - player.Calamity().kamiBoost = true; - if (player.buffTime[buffIndex] == 1) - SoundEngine.PlaySound(YanmeisKnife.ExpireSound, player.Center); - } - } -} diff --git a/Buffs/StatBuffs/KamiBuff.png b/Buffs/StatBuffs/KamiBuff.png deleted file mode 100644 index 4fdc0fff94bdb960374f706ae2e70a8ec1e4650b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 423 zcmV;Y0a*TtP)Px$VM#^2fihtm2d*x4T9;x?Lxj@FPbFu4kSqe z%$2=ee*myPxvRWUCt)40o2~+Lr;4HgB5=S=Lcin5>|86cl2AJ*d<*e8APT%vEBg(2 z#c9|j-WkP@#{ub2-?xT>x_4^vq$cD!MRYmvP>zEO`&(y~H|U%Y=swrDRP({MI|3qb zz}JAD-DJml7SzfGy2_hQ$?-T~!J2|C2(RgE7{3D+^w+PcLmI6+;QsvI@h8KslGq8- RJD30f002ovPDHLkV1jW6x4i%W diff --git a/Buffs/StatDebuffs/KamiFlu.cs b/Buffs/StatDebuffs/KamiFlu.cs deleted file mode 100644 index 859091d167..0000000000 --- a/Buffs/StatDebuffs/KamiFlu.cs +++ /dev/null @@ -1,30 +0,0 @@ -using CalamityMod.NPCs; -using Terraria; -using Terraria.ModLoader; - -namespace CalamityMod.Buffs.StatDebuffs -{ - public class KamiFlu : ModBuff - { - public const float MultiplicativeDamageReduction = 0.8f; - // Hard-cap for npc speed when afflicted with this debuff. Does not affect certain NPCs and does not affect any bosses (Basically only works on boss minions). - public const float MaxNPCSpeed = 16f; - - public override void SetStaticDefaults() - { - Main.debuff[Type] = true; - Main.pvpBuff[Type] = true; - Main.buffNoSave[Type] = false; - } - - public override void Update(NPC npc, ref int buffIndex) - { - if (npc.Calamity().kamiFlu < npc.buffTime[buffIndex]) - npc.Calamity().kamiFlu = npc.buffTime[buffIndex]; - if ((CalamityLists.enemyImmunityList.Contains(npc.type) || npc.boss) && npc.Calamity().debuffResistanceTimer <= 0) - npc.Calamity().debuffResistanceTimer = CalamityGlobalNPC.slowingDebuffResistanceMin + npc.Calamity().kamiFlu; - npc.DelBuff(buffIndex); - buffIndex--; - } - } -} diff --git a/Buffs/StatDebuffs/KamiFlu.png b/Buffs/StatDebuffs/KamiFlu.png deleted file mode 100644 index df7af84f98f90a69d302de53616ccbc0d1bcf0bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 514 zcmV+d0{#7oP)Px$yh%hsR9J=Omp@1XQ5?rVS1lreE)g_DGz3M^64)PXkO+#lz&#`yn%i1*46>jI z#IdE;mLv?45+Q^va*Jw+qD3J>8p4LVUvN*)KLqxq@AB^6`@OsSe%`;|83T)B06ZLD zmuaEg!-EDuM=M`iO$JZ~2)%6o>OrAi7Xb0s5&-Ey%+~(7G-JEJ5AOpS5a{~t1Du?T zW6xYC04^)OnE0~w*N1>OagsPx;@p2_yF2@705c5*}l4UP_@HZY|p%iga8O`#LZFyqGqvvGStuq=tDpxb0Hj9 zu+^Vu?*ItwZUT_Jc?94oVz&2NB>eBER*yCzP>~U-d%k)`2Vphd*9_+ z%@=2U z9hni0?r^HqY*?f(0a3lvE!90+v)#$L=+6ll|Nigz8&FP%)cpX?WdHyG07*qoM6N<$ Ef}Wq?Q~&?~ diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index e02c66b2b7..a18b94b786 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -986,7 +986,6 @@ public GemTechArmorState GemTechState public int bloodfinTimer = 30; public bool hallowedRegen = false; public bool hallowedPower = false; - public bool kamiBoost = false; public bool avertorBonus = false; public bool divineBless = false; public bool infiniteFlight = false; @@ -1769,7 +1768,6 @@ public override void ResetEffects() phantomicArtifact = false; hallowedRegen = false; hallowedPower = false; - kamiBoost = false; tracersDust = false; elysianWingsDust = false; tracersCelestial = false; @@ -2430,7 +2428,6 @@ public override void UpdateDead() rRage = false; xRage = false; xWrath = false; - kamiBoost = false; graxDefense = false; encased = false; brutalCarnage = false; @@ -3719,7 +3716,6 @@ public override void PostUpdateRunSpeeds() (aquaticHeartWaterBuff ? 0.15f : 0f) + ((frostFlare && Player.statLife <= (int)(Player.statLifeMax2 * 0.5)) ? 0.15f : 0f) + (dragonScales ? 0.1f : 0f) + - (kamiBoost ? KamiBuff.RunAccelerationBoost : 0f) + (CobaltSet ? CobaltArmorSetChange.SpeedBoostSetBonusPercentage * 0.01f : 0f) + (silvaSet ? 0.05f : 0f) + (blueCandle ? CirrusBlueCandleBuff.AccelerationBoost : 0f) + @@ -3734,7 +3730,6 @@ public override void PostUpdateRunSpeeds() (aquaticHeartWaterBuff ? 0.15f : 0f) + ((frostFlare && Player.statLife <= (int)(Player.statLifeMax2 * 0.5)) ? 0.15f : 0f) + (dragonScales ? 0.1f : 0f) + - (kamiBoost ? KamiBuff.RunSpeedBoost : 0f) + (CobaltSet ? CobaltArmorSetChange.SpeedBoostSetBonusPercentage * 0.01f : 0f) + (silvaSet ? 0.05f : 0f) + (planarSpeedBoost > 0 ? (0.01f * planarSpeedBoost) : 0f) + diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index ad7655f7c3..578687f3d8 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -1770,9 +1770,6 @@ private void MiscEffects() if (raiderTalisman && !StealthStrikeAvailable()) Player.GetCritChance() += raiderCritBonus; - if (kamiBoost) - Player.GetDamage() += 0.15f; - if (avertorBonus) Player.GetDamage() += 0.1f; diff --git a/CalPlayer/DrawLayers/YanmeiKnifeTrailLayer.cs b/CalPlayer/DrawLayers/YanmeiKnifeTrailLayer.cs deleted file mode 100644 index 0b1ed520c6..0000000000 --- a/CalPlayer/DrawLayers/YanmeiKnifeTrailLayer.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System.Collections.Generic; -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.DataStructures; -using Terraria.ModLoader; - -namespace CalamityMod.CalPlayer.DrawLayers -{ - public class YanmeiKnifeTrail : PlayerDrawLayer - { - public override Position GetDefaultPosition() => new AfterParent(PlayerDrawLayers.BackAcc); - - public override bool GetDefaultVisibility(PlayerDrawSet drawInfo) - { - Player drawPlayer = drawInfo.drawPlayer; - if (drawInfo.shadow != 0f || drawPlayer.dead) - return false; - - return drawPlayer.Calamity().kamiBoost; - } - - protected override void Draw(ref PlayerDrawSet drawInfo) - { - Player drawPlayer = drawInfo.drawPlayer; - List existingDrawData = drawInfo.DrawDataCache; - for (int i = 0; i < drawPlayer.Calamity().OldPositions.Length; i++) - { - float completionRatio = i / (float)drawPlayer.Calamity().OldPositions.Length; - float scale = MathHelper.Lerp(1f, 0.5f, completionRatio); - float opacity = MathHelper.Lerp(0.25f, 0.08f, completionRatio); - List afterimages = new List(); - for (int j = 0; j < existingDrawData.Count; j++) - { - var drawData = existingDrawData[j]; - drawData.position = existingDrawData[j].position - drawPlayer.position + drawPlayer.oldPosition; - drawData.color = Color.Cyan * opacity; - drawData.color.G = (byte)(drawData.color.G * 1.6); - drawData.color.B = (byte)(drawData.color.B * 1.2); - drawData.scale = new Vector2(scale); - afterimages.Add(drawData); - } - drawInfo.DrawDataCache.InsertRange(0, afterimages); - } - } - } -} diff --git a/CalamityLists.cs b/CalamityLists.cs index 0fba8bdfb7..eb883fad48 100644 --- a/CalamityLists.cs +++ b/CalamityLists.cs @@ -147,8 +147,6 @@ public class CalamityLists public static List legOverrideList; - public static List kamiDebuffColorImmuneList; - public static Dictionary EncryptedSchematicIDRelationship; public static List DisabledSummonerNerfItems; @@ -179,7 +177,6 @@ public static void LoadLists() "Hans Volter", "Krankwagon", "MishiroUsui", - "pixlgray", "Arkhine", "Lodude", "DevAesthetic", @@ -193,7 +190,6 @@ public static void LoadLists() "Ein", "2Larry2", "Jenonen", - "Dodu", "Arti", "Tervastator", "Luis", @@ -246,7 +242,6 @@ public static void LoadLists() "William", "Arche", "DevilSunrise", - "Yanmei", "Chaos", "Ryan", "Fish Repairs", @@ -2603,15 +2598,6 @@ public static void LoadLists() EquipLoader.GetEquipSlot(CalamityMod.Instance, "Popo", EquipType.Legs) }; - // Duke Fishron and Old Duke phase 3 becomes way too easy if you can make him stop being invisible with Yanmei's Knife. - // This is a list so that other NPCs can be added as necessary. - // IT DOES NOT make them immune to the debuff, just stops them from being recolored. - kamiDebuffColorImmuneList = new List() - { - NPCID.DukeFishron, - NPCType() - }; - EncryptedSchematicIDRelationship = new Dictionary() { [1] = ItemType(), @@ -2708,8 +2694,6 @@ public static void UnloadLists() legOverrideList = null; - kamiDebuffColorImmuneList = null; - EncryptedSchematicIDRelationship = null; DisabledSummonerNerfItems = null; diff --git a/Items/Mounts/Brimrose.cs b/Items/Mounts/Brimrose.cs index e43938133b..016c7b3d2d 100644 --- a/Items/Mounts/Brimrose.cs +++ b/Items/Mounts/Brimrose.cs @@ -18,7 +18,7 @@ public override void SetDefaults() Item.useStyle = ItemUseStyleID.Swing; Item.UseSound = SoundID.Item3; Item.noMelee = true; - Item.mountType = ModContent.MountType(); + Item.mountType = ModContent.MountType(); Item.value = Item.buyPrice(platinum: 1, gold: 50); Item.rare = ModContent.RarityType(); diff --git a/Items/Mounts/PhuppersChair.cs b/Items/Mounts/BrimroseChair.cs similarity index 98% rename from Items/Mounts/PhuppersChair.cs rename to Items/Mounts/BrimroseChair.cs index 91f0c9d0f1..35267edfa9 100644 --- a/Items/Mounts/PhuppersChair.cs +++ b/Items/Mounts/BrimroseChair.cs @@ -6,7 +6,7 @@ namespace CalamityMod.Items.Mounts { - public class PhuppersChair : ModMount + public class BrimroseChair : ModMount { public override void SetStaticDefaults() { diff --git a/Items/Mounts/PhuppersChair_Back.png b/Items/Mounts/BrimroseChair_Back.png similarity index 100% rename from Items/Mounts/PhuppersChair_Back.png rename to Items/Mounts/BrimroseChair_Back.png diff --git a/Items/Mounts/PhuppersChair_Front.png b/Items/Mounts/BrimroseChair_Front.png similarity index 100% rename from Items/Mounts/PhuppersChair_Front.png rename to Items/Mounts/BrimroseChair_Front.png diff --git a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs index 471616bbd8..d9695e8680 100644 --- a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs +++ b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs @@ -165,7 +165,6 @@ public override void ModifyTooltips(List tooltips) "Phantasmal Deathray", "Phupperbat", "Pinkie Poss", - "pixlgray", "Poly", "Popo", "President Waluigi", diff --git a/Items/Weapons/Magic/DivineRetribution.cs b/Items/Weapons/Magic/DivineRetribution.cs deleted file mode 100644 index a345625500..0000000000 --- a/Items/Weapons/Magic/DivineRetribution.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System; -using CalamityMod.Items.Materials; -using CalamityMod.Projectiles.Magic; -using CalamityMod.Rarities; -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.DataStructures; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Items.Weapons.Magic -{ - public class DivineRetribution : ModItem, ILocalizedModType - { - public new string LocalizationCategory => "Items.Weapons.Magic"; - public override void SetStaticDefaults() - { - Item.staff[Item.type] = true; - } - - public override void SetDefaults() - { - Item.width = 66; - Item.height = 88; - Item.damage = 48; - Item.DamageType = DamageClass.Magic; - Item.mana = 15; - Item.useTime = 12; - Item.useAnimation = 12; - Item.useStyle = ItemUseStyleID.Shoot; - Item.noMelee = true; - Item.knockBack = 3.5f; - - Item.value = CalamityGlobalItem.RarityTurquoiseBuyPrice; - Item.rare = ModContent.RarityType(); - Item.Calamity().donorItem = true; - - Item.UseSound = SoundID.Item73; - Item.autoReuse = true; - Item.shootSpeed = 19f; - Item.shoot = ModContent.ProjectileType(); - } - - - public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) - { - float spearSpeed = Item.shootSpeed; - Vector2 realPlayerPos = player.RotatedRelativePoint(player.MountedCenter, true); - float mouseXDist = (float)Main.mouseX + Main.screenPosition.X - realPlayerPos.X; - float mouseYDist = (float)Main.mouseY + Main.screenPosition.Y - realPlayerPos.Y; - if (player.gravDir == -1f) - { - mouseYDist = Main.screenPosition.Y + (float)Main.screenHeight - (float)Main.mouseY - realPlayerPos.Y; - } - float mouseDistance = (float)Math.Sqrt((double)(mouseXDist * mouseXDist + mouseYDist * mouseYDist)); - if ((float.IsNaN(mouseXDist) && float.IsNaN(mouseYDist)) || (mouseXDist == 0f && mouseYDist == 0f)) - { - mouseXDist = (float)player.direction; - } - else - { - mouseDistance = spearSpeed / mouseDistance; - } - int numProjectiles = 5; - for (int i = 0; i < numProjectiles; i++) - { - realPlayerPos = new Vector2(player.position.X + (float)player.width * 0.5f + (float)(Main.rand.Next(51) * -(float)player.direction) + ((float)Main.mouseX + Main.screenPosition.X - /* - */ player.position.X), player.MountedCenter.Y + 600f); //- - realPlayerPos.X = (realPlayerPos.X + player.Center.X) / 2f + (float)Main.rand.Next(-50, 51); //200 - realPlayerPos.Y += (float)(100 * i); //-= - mouseXDist = (float)Main.mouseX + Main.screenPosition.X - realPlayerPos.X; //+ - - mouseYDist = (float)Main.mouseY + Main.screenPosition.Y - realPlayerPos.Y; //+ - - if (mouseYDist < 0f) - { - mouseYDist *= -1f; - } - if (mouseYDist < 20f) - { - mouseYDist = 20f; - } - mouseDistance = (float)Math.Sqrt((double)(mouseXDist * mouseXDist + mouseYDist * mouseYDist)); - mouseDistance = spearSpeed / mouseDistance; - mouseXDist *= mouseDistance; - mouseYDist *= mouseDistance; - float speedX6 = mouseXDist + (float)Main.rand.Next(-60, 61) * 0.02f; - float speedY7 = mouseYDist + (float)Main.rand.Next(-60, 61) * 0.02f; - float ai1 = Main.rand.NextFloat() + 0.5f; - Projectile.NewProjectile(source, realPlayerPos.X, realPlayerPos.Y, speedX6, -speedY7, type, damage, knockback, player.whoAmI, 0.0f, ai1); - } - return false; - } - - public override void AddRecipes() - { - CreateRecipe(). - AddIngredient(). - AddIngredient(8). - AddIngredient(6). - AddIngredient(10). - AddTile(TileID.LunarCraftingStation). - Register(); - } - } -} diff --git a/Items/Weapons/Magic/DivineRetribution.png b/Items/Weapons/Magic/DivineRetribution.png deleted file mode 100644 index 4a5c496127f07a7369b91e62b5837a047b3ef4b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2013 zcmV<32O{{1P)4~X?e6f~gtL5Po-Ac>J6nkXhlKWH>YVuC0! zQKBCpY79|)0YRfp5U{p_ij@Q`#afFXl@|KI7Fa)=dv>|Q4BcgEY4QHQOy* zf6lpgc0-(FnlpYP0Fx&U1fX);k*KFj2;lviZC2xep1-vIq43$hfHSS)++#qTg!kSU z2Eg0}f1PqaM}*NiLxg(6@XLn+P+b23QNJf5&>M_2e;7A9Jp{00SEuiB91%wSmWb}WVeVybTkA@Kx5iL8B8>VS z5wYrWS_uGKHq`lgL-`0HprSrKq2oFtjQR`_mlj=g%I&4OLx4C5l`#??w)&|zJb8Nr zfQtI|gwF4XFzPczsD5p*-QVj8K_sZu8(>gU=XFFF^*RyVd4Vcf61?6paYl}8Sm!(< zDfJo=N`lt|R7$|i5rctv#<(S662ud#YMOx)h)7V52%{b+B8UVfK&!_X0j7%7+QFMK zs+0tc5>+*_{IXU&VZNt-B;&YsUN^51pfgT{e&b$gW~drBX*d8os`e&CfXYjPN=fkQ zgqlNVyh48c91%u6=@H&JM@u`Z_5#7tK;t;y4UO-CaoscTpks{P5iq7mGRUug`UQZSN-qOo{OBS8TI-vWx=u%gQI8QZcG!6# zfF@2vB)RxO2|c0PL=AwEAuP;!r~8bwn7QaUwKhn}g&N1%r-4Dl zlnk}U3wAcxck-?queR1-U%lR1_mZHh+0_8R$PEAMYdj(wh7Y^hYIj5!^_WM*$cSf} zA%KBt^4-_%6YscV$`~N-_M^%QPdp5dKmCsH@wLC|)g^0yxTj1SFP>5r^ClV1-r1Jr zo8LGhjC}L%Goe{iAMkAtckBaTSo&cAnp!%d01FqDTm6)TqWnAnE*Mh`z_?<$(|KKT zhd=)2duzX2FBb1v*LoEImAn45wy#*U5PmGw+!6^si3)YfhS zAd=?4lb3}1XHKxTSO2sJfTKgFTJ7svW%=-o*#InGe22CDGBMBbxO^kcWBE!@dK6BO<1hiD+n&T)rqj$MOOt;i8gJ08GD5?$G2fE|d=cY`5|V ztr0f;xgUV#&);I5=er-|&aM39N2`6tlttG1+Rd`msPISKZr|(9%gP4e?}IIXBO<1h ziRkD&3dG}e4%t*cjT+E5F`YXhw&M~)rqdmfDv>IEvj^ZS2W3%~`JOt-dw z{Gwe`s8^_0VR9))gwbgeq4O2(?G2_SABcbB6HNSG#wy=-)eB36Ak7d`c}tf8utGa5zE75$KezVNDDti+gY-rV zRavnNT~+Uq(dpJ^iAq@+^8Vz(4#`{6LQ=zYMbA&_b2uW5lCC~=WM^=Ar#3|a9+_2U z^?PZxu^M;q(C^fTNuV zHCM@Oxss5dmj%G0hpzX%2+cI#TvL6@S?)yTh%id{TRh=yI2livaEY~DU0tPdzv-Vg zt3BurKla+E0Nh`Gh1IU4c{4~Kg}`}4%1Sx2)KO(!YE7Vol;lVa(j5s((3@+jefwz! z+4ishFK|+oBf=sof$I6_uVhm3^GWL2&05O zLhnSP?@|Ymu=HJ-&+w9vJ7}OqLQmcKAUPt8lCCuhhe(~@ctGlYuQzDi_hyZ25<;d!Lc9!zowFY_^UidPz`u zGe*r5`l=ieMzPGYyWdURl)D^&uZ>6O_<>42K}jfx$Qv<#H_J;+eKlIB91%u=wZ>c1 zg#dknRsV-!dyAV0>Mc|w07LFI@riW8x~q$$7C>afK8wmK(E-m=ea7cyG9{KpQ@ zb`^QLazq$~Cr^}TdhUY1%>O?M8F6nAA`Z35cebUjw)d~H7vzXA3RiBEXZmC^IR2~o*uMu`Wc**`h%ovOVB*FuxPnLv00000NkvXXu0mjfY=6c? diff --git a/Items/Weapons/Ranged/DodusHandcannon.cs b/Items/Weapons/Ranged/DodusHandcannon.cs deleted file mode 100644 index 6751d3d00a..0000000000 --- a/Items/Weapons/Ranged/DodusHandcannon.cs +++ /dev/null @@ -1,58 +0,0 @@ -using CalamityMod.Items.Materials; -using CalamityMod.Projectiles.Ranged; -using CalamityMod.Rarities; -using CalamityMod.Sounds; -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Items.Weapons.Ranged -{ - public class DodusHandcannon : ModItem, ILocalizedModType - { - public new string LocalizationCategory => "Items.Weapons.Ranged"; - public override void SetDefaults() - { - Item.width = 62; - Item.height = 34; - Item.damage = 1020; - Item.DamageType = DamageClass.Ranged; - Item.useTime = 30; - Item.useAnimation = 30; - Item.autoReuse = true; - Item.useStyle = ItemUseStyleID.Shoot; - Item.noMelee = true; - Item.knockBack = 6f; - - // Reduce volume to 30% so it stops destroying people's ears. - Item.UseSound = CommonCalamitySounds.LargeWeaponFireSound with { Volume = 0.3f }; - - Item.shoot = ModContent.ProjectileType(); - Item.shootSpeed = 13f; - Item.useAmmo = AmmoID.Bullet; - - Item.value = CalamityGlobalItem.RarityPureGreenBuyPrice; - Item.rare = ModContent.RarityType(); - Item.Calamity().donorItem = true; - Item.Calamity().canFirePointBlankShots = true; - } - - public override void ModifyShootStats(Player player, ref Vector2 position, ref Vector2 velocity, ref int type, ref int damage, ref float knockback) - { - type = Item.shoot; - } - - public override Vector2? HoldoutOffset() => new Vector2(-17, 5); - - public override void AddRecipes() - { - CreateRecipe(). - AddIngredient(). - AddIngredient(5). - AddIngredient(ItemID.LunarBar, 15). - AddTile(TileID.LunarCraftingStation). - Register(); - } - } -} diff --git a/Items/Weapons/Ranged/DodusHandcannon.png b/Items/Weapons/Ranged/DodusHandcannon.png deleted file mode 100644 index d78a7a37f76b8549ef8b47bb77c67be5f2ce92ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 761 zcmVPx%vq?ljRA_>2j8cebC1p?v#uX4>0xj%S3%hI9Tmv)9`D?AddE zd#zb}2V%|bSzM^Aqb=ZOT&ZZ&MlWEa6bMyDvH&~wAFv#dPE8keL89)Jw55M}SHrsI zE34nG>{#y-Pb3nG) z;8VcE#LJ~&m(_KB93KOqy`kE&zojmu*n<-@ioNnZsMvPjd!(*ju}9{!)T>ze+-KO-*4mue%<{7G}b)4^hrp#!Vu__uU z(Dp3xTvnHCu9LR&ON@6l83d>2z5x)g+oISvUVbiUK|)?v%ly2hzp0@LfXS&POZ)ty zv8j7bbo-SX{8hQxRcv;#-WdMvIB|VV4FJLZNnmwsyOmvbFVyc7H&w1Xbi(qcWJidS z8RvJF%q$v>HAvf?336Ka;oQGY`NZ`Y5b31LqUw40*C*rD)4OLY01wg?!0H>DLUV|y zv-+oEkC;pDTuv3_*X0w}C4_XsqJ`K_07545nXxZMM{^W_;b*TbPkll-x5GNx92Yop z{h=~XPvTgh5I>dHSBjn`ZhHf>7U|8iZ-IP_yOmuoDYiUI+&0G7l1}=6A?a2=as7Wb zoivE*v7U=<(=IjABA>WOZdc_~Zf5Li_)?WmTofN2SM12~qef%zZUElDcnv_xtdJsR r#Z+qYiQC0&N~?XHE9=scXNms-axD7lNTqmy00000NkvXXu0mjf+$U*` diff --git a/Items/Weapons/Typeless/YanmeisKnife.cs b/Items/Weapons/Typeless/YanmeisKnife.cs deleted file mode 100644 index 42b934e108..0000000000 --- a/Items/Weapons/Typeless/YanmeisKnife.cs +++ /dev/null @@ -1,70 +0,0 @@ -using CalamityMod.Items.Materials; -using CalamityMod.Projectiles.Typeless; -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.Audio; -using Terraria.DataStructures; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Items.Weapons.Typeless -{ - public class YanmeisKnife : ModItem, ILocalizedModType - { - public new string LocalizationCategory => "Items.Weapons.Typeless"; - public static readonly SoundStyle HitSound = new("CalamityMod/Sounds/Item/YanmeiKnifeHit"); - public static readonly SoundStyle ExpireSound = new("CalamityMod/Sounds/Custom/YanmeiKnifeExpire"); - - public override void SetDefaults() - { - Item.width = 48; - Item.height = 44; - Item.damage = 8; - Item.noMelee = true; - Item.noUseGraphic = true; - Item.useAnimation = Item.useTime = 32; - Item.useStyle = ItemUseStyleID.Shoot; - Item.knockBack = 4.5f; - Item.autoReuse = false; - Item.value = CalamityGlobalItem.RarityYellowBuyPrice; - Item.rare = ItemRarityID.Yellow; - Item.Calamity().donorItem = true; - Item.UseSound = SoundID.Item71; - Item.shoot = ModContent.ProjectileType(); - Item.shootSpeed = 24f; - } - - public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.ItemGroup itemGroup) - { - itemGroup = (ContentSamples.CreativeHelper.ItemGroup)CalamityResearchSorting.ClasslessWeapon; - } - - // Terraria seems to really dislike high crit values in SetDefaults - public override void ModifyWeaponCrit(Player player, ref float crit) => crit += 6; - - public override bool CanUseItem(Player player) - { - if (player.Calamity().KameiBladeUseDelay > 0) - return false; - return base.CanUseItem(player); - } - - public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) - { - player.Calamity().KameiBladeUseDelay = 180; - Projectile.NewProjectile(source, position, velocity, type, damage, knockback, player.whoAmI, 0f, 0f); - return false; - } - - public override void AddRecipes() - { - CreateRecipe(). - AddIngredient(ItemID.PsychoKnife). - AddIngredient(ItemID.Obsidian, 10). - AddRecipeGroup("IronBar", 20). - AddIngredient(50). - AddTile(TileID.MythrilAnvil). - Register(); - } - } -} diff --git a/Items/Weapons/Typeless/YanmeisKnife.png b/Items/Weapons/Typeless/YanmeisKnife.png deleted file mode 100644 index b7f214f8f4a07919907dab27c0d15ae78df71196..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 739 zcmV<90v!E`P)3nuQ8s&_Y^7v`UahH*J(8aMB18HyX7MX<@4% zFc(3jE&@Xk1~)T?2rm3crO1sKp7A%ldz|MuAL!iYEardDx#!-w=f~eWZ!q8#`78Lm zYyaSgm8~Um(hEg?-Xq5g9LW?op$X~jx4!I2Djt1noP~Ac1NAchWOhN+I>M#8<4keG zOhi0I-CWa{L594pBd-;2Hnb-9h4}5Ro4QnD{}WEzb^(%^$np{XC+y`}2%r$dqvTnS z$El0nf1NDZOiC~`&JsiYPuOVJ6+q0DGKP>O`S0;p8Ad05h>mRaG9@~>J1RPr_$xZs zR4%vC`6X=NaU2J)>U<~^l6(A_2U%UO$)8`sc$8ZKPm?eE_)XwJcK*|p#9=2adZRWd z+R;`g${Xv6ts|WFIe>2RQ3!JzXtL}LSz-vc{p^;M{#&q)aMn+2knmE-;=QLsAEXq| zvabGa3&XU^dOc|!;evUXUkKa=kwdaei*W;z_AHZ`yi1*Rg!A^WCVS`Mpum`)oCb>M zrR!HkHF51_FYmIMb%gWwa83C&c{aHBpbrR!Le@w+j-$yAbu>yzEEYTVOx6+3*~5^n zs<^D-8S(b7RU>Zhd1S;VCCeh~2p{Vgx^k-~TYcrCOmD6ye;M3r?{t@^#@frD-}lR0 zCeNleI2`zwuqHeF?uGRHvj3FjMzca>oDPbZ5m9+ea93wve`t@PA>- V@7HJV()] = immuneToSlowingDebuffs; npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; - npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; diff --git a/NPCs/CalamityAIs/CalamityBossAIs/BumblebirbAI.cs b/NPCs/CalamityAIs/CalamityBossAIs/BumblebirbAI.cs index 0882a65f4f..56e02b32b9 100644 --- a/NPCs/CalamityAIs/CalamityBossAIs/BumblebirbAI.cs +++ b/NPCs/CalamityAIs/CalamityBossAIs/BumblebirbAI.cs @@ -57,7 +57,6 @@ public static void VanillaBumblebirbAI(NPC npc, Mod mod) bool immuneToSlowingDebuffs = npc.ai[0] == 3f || npc.ai[0] == 3.1f || npc.ai[0] == 3.2f; npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; - npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; diff --git a/NPCs/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index b2a4ed9359..4bfb7ae124 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -278,7 +278,6 @@ public partial class CalamityGlobalNPC : GlobalNPC public int clamDebuff = 0; public int sulphurPoison = 0; public int ladHearts = 0; - public int kamiFlu = 0; public int relicOfResilienceCooldown = 0; public int relicOfResilienceWeakness = 0; public int GaussFluxTimer = 0; @@ -493,7 +492,6 @@ public override GlobalNPC Clone(NPC npc, NPC npcClone) myClone.clamDebuff = clamDebuff; myClone.sulphurPoison = sulphurPoison; myClone.ladHearts = ladHearts; - myClone.kamiFlu = kamiFlu; myClone.relicOfResilienceCooldown = relicOfResilienceCooldown; myClone.relicOfResilienceWeakness = relicOfResilienceWeakness; myClone.GaussFluxTimer = GaussFluxTimer; @@ -1052,13 +1050,6 @@ public override void UpdateLifeRegen(NPC npc, ref int damage) ApplyDPSDebuff(baseSagePoisonDoTValue, baseSagePoisonDoTValue / 5, ref npc.lifeRegen, ref damage); } - // Kami Debuff from Yanmei's Knife - if (kamiFlu > 0) - { - int baseKamiFluDoTValue = (int)(250 * sicknessDamageMult); - ApplyDPSDebuff(baseKamiFluDoTValue, baseKamiFluDoTValue / 10, ref npc.lifeRegen, ref damage); - } - //Absorber Affliction if (absorberAffliction > 0) { @@ -3270,8 +3261,6 @@ private float DefaultDRMath(NPC npc, float DR) calcDR *= 0.8f; if (npc.betsysCurse) calcDR *= 0.66f; - if (npc.Calamity().kamiFlu > 0) - calcDR *= KamiFlu.MultiplicativeDamageReduction; if (npc.Calamity().aCrunch > 0) calcDR *= ArmorCrunch.MultiplicativeDamageReductionEnemy; if (npc.Calamity().crumble > 0) @@ -5066,8 +5055,6 @@ public override void PostAI(NPC npc) webbed--; if (slowed > 0) slowed--; - if (kamiFlu > 0) - kamiFlu--; if (vaporfied > 0) vaporfied--; @@ -5124,8 +5111,6 @@ public override void PostAI(NPC npc) sulphurPoison--; if (sagePoisonTime > 0) sagePoisonTime--; - if (kamiFlu > 0) - kamiFlu--; if (relicOfResilienceCooldown > 0) relicOfResilienceCooldown--; if (relicOfResilienceWeakness > 0) @@ -5210,10 +5195,6 @@ public override void PostAI(NPC npc) { npc.velocity = Vector2.Clamp(npc.velocity, new Vector2(-Calamity.MaxNPCSpeed), new Vector2(Calamity.MaxNPCSpeed, 10f)); } - else if (kamiFlu > 420) - { - npc.velocity = Vector2.Clamp(npc.velocity, new Vector2(-KamiFlu.MaxNPCSpeed), new Vector2(KamiFlu.MaxNPCSpeed)); - } } } @@ -6555,9 +6536,6 @@ public override void DrawEffects(NPC npc, ref Color drawColor) if (npc.HasBuff()) return new Color(200, 50, 50, 255 - npc.alpha); - if (npc.Calamity().kamiFlu > 0 && !CalamityLists.kamiDebuffColorImmuneList.Contains(npc.type)) - return new Color(51, 197, 108, 255 - npc.alpha); - if (npc.type == NPCID.VileSpit || npc.type == NPCID.VileSpitEaterOfWorlds) return new Color(150, 200, 0, npc.alpha); @@ -6601,7 +6579,6 @@ public override void DrawEffects(NPC npc, ref Color drawColor) ("CalamityMod/Buffs/StatDebuffs/GalvanicCorrosion", NPC => NPC.Calamity().tesla > 0), ("CalamityMod/Buffs/StatDebuffs/GlacialState", NPC => NPC.Calamity().gState > 0), ("CalamityMod/Buffs/StatDebuffs/Irradiated", NPC => NPC.Calamity().irradiated > 0), - ("CalamityMod/Buffs/StatDebuffs/KamiFlu", NPC => NPC.Calamity().kamiFlu > 0), ("CalamityMod/Buffs/StatDebuffs/MarkedforDeath", NPC => NPC.Calamity().marked > 0), ("CalamityMod/Buffs/StatDebuffs/PearlAura", NPC => NPC.Calamity().pearlAura > 0), ("CalamityMod/Buffs/StatDebuffs/ProfanedWeakness", NPC => NPC.Calamity().relicOfResilienceWeakness > 0), diff --git a/NPCs/CalamityGlobalTownNPC.cs b/NPCs/CalamityGlobalTownNPC.cs index 49310d2251..cdad9666c1 100644 --- a/NPCs/CalamityGlobalTownNPC.cs +++ b/NPCs/CalamityGlobalTownNPC.cs @@ -231,7 +231,6 @@ public static float TaxYieldFactor }; private static readonly string[] WizardNames = { - "Mage One-Trick", // <@!340996105460514816> (pixlgray) "Inorim, son of Ivukey", "Jensen", "Merasmus", // <@!288066987819663360> (spiderprovidence) diff --git a/NPCs/Leviathan/Leviathan.cs b/NPCs/Leviathan/Leviathan.cs index ade98ce310..4a94c6e0e9 100644 --- a/NPCs/Leviathan/Leviathan.cs +++ b/NPCs/Leviathan/Leviathan.cs @@ -222,7 +222,6 @@ public override void AI() bool immuneToSlowingDebuffs = NPC.ai[0] == 2f; NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; - NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; diff --git a/NPCs/NormalNPCs/SkeletronPrime2.cs b/NPCs/NormalNPCs/SkeletronPrime2.cs index d644a5d641..5fb331870b 100644 --- a/NPCs/NormalNPCs/SkeletronPrime2.cs +++ b/NPCs/NormalNPCs/SkeletronPrime2.cs @@ -247,7 +247,6 @@ public override void AI() bool immuneToSlowingDebuffs = NPC.ai[1] == 5f; NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; - NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; diff --git a/NPCs/PlaguebringerGoliath/PlaguebringerGoliath.cs b/NPCs/PlaguebringerGoliath/PlaguebringerGoliath.cs index e1983374f1..9d570cee10 100644 --- a/NPCs/PlaguebringerGoliath/PlaguebringerGoliath.cs +++ b/NPCs/PlaguebringerGoliath/PlaguebringerGoliath.cs @@ -182,7 +182,6 @@ public override void AI() bool immuneToSlowingDebuffs = NPC.ai[0] == 0f || NPC.ai[0] == 4f; NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; - NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; diff --git a/NPCs/PrimordialWyrm/PrimordialWyrmHead.cs b/NPCs/PrimordialWyrm/PrimordialWyrmHead.cs index e0267f9335..71119e2239 100644 --- a/NPCs/PrimordialWyrm/PrimordialWyrmHead.cs +++ b/NPCs/PrimordialWyrm/PrimordialWyrmHead.cs @@ -338,7 +338,6 @@ public override void AI() bool immuneToSlowingDebuffs = AIState == (float)Phase.FinalPhase || AIState == (float)Phase.ShadowFireballSpin; NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; - NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/QueenBeeAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/QueenBeeAI.cs index f7b4de517e..2f4b89b183 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/QueenBeeAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/QueenBeeAI.cs @@ -142,7 +142,6 @@ public static bool BuffedQueenBeeAI(NPC npc, Mod mod) bool immuneToSlowingDebuffs = npc.ai[0] == 0f; npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; - npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronPrimeAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronPrimeAI.cs index a7f40acc14..fc15e166b0 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronPrimeAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronPrimeAI.cs @@ -241,7 +241,6 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) bool immuneToSlowingDebuffs = npc.ai[1] == 5f; npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; - npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; npc.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; diff --git a/Projectiles/DraedonsArsenal/PhaseslayerBeam.cs b/Projectiles/DraedonsArsenal/PhaseslayerBeam.cs index c1b1ee841c..def7cbbe40 100644 --- a/Projectiles/DraedonsArsenal/PhaseslayerBeam.cs +++ b/Projectiles/DraedonsArsenal/PhaseslayerBeam.cs @@ -3,7 +3,9 @@ using Microsoft.Xna.Framework.Graphics; using Terraria; using Terraria.DataStructures; +using Terraria.ID; using Terraria.ModLoader; + namespace CalamityMod.Projectiles.DraedonsArsenal { public class PhaseslayerBeam : ModProjectile, ILocalizedModType diff --git a/Projectiles/Magic/BeamingBolt2.cs b/Projectiles/Magic/BeamingBolt2.cs index 013ac5f482..47f0d3b390 100644 --- a/Projectiles/Magic/BeamingBolt2.cs +++ b/Projectiles/Magic/BeamingBolt2.cs @@ -2,7 +2,9 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Terraria; +using Terraria.ID; using Terraria.ModLoader; + namespace CalamityMod.Projectiles.Magic { public class BeamingBolt2 : ModProjectile, ILocalizedModType diff --git a/Projectiles/Magic/DivineRetributionSpear.cs b/Projectiles/Magic/DivineRetributionSpear.cs deleted file mode 100644 index 776538b8cb..0000000000 --- a/Projectiles/Magic/DivineRetributionSpear.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; -using CalamityMod.Buffs.DamageOverTime; -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.Audio; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Projectiles.Magic -{ - public class DivineRetributionSpear : ModProjectile, ILocalizedModType - { - public new string LocalizationCategory => "Projectiles.Magic"; - public override void SetStaticDefaults() - { - ProjectileID.Sets.TrailCacheLength[Projectile.type] = 7; - ProjectileID.Sets.TrailingMode[Projectile.type] = 0; - } - - public override void SetDefaults() - { - Projectile.width = 30; - Projectile.height = 30; - Projectile.friendly = true; - Projectile.ignoreWater = true; - Projectile.tileCollide = false; - Projectile.DamageType = DamageClass.Magic; - Projectile.extraUpdates = 1; - Projectile.penetrate = 1; - Projectile.timeLeft = 420; - } - - public override void AI() - { - float aiVelocityMult = 25f * Projectile.ai[1]; //100 - float scaleFactor = 5f * Projectile.ai[1]; //5 - float homingRange = 1000f; - - if (Projectile.velocity.X < 0f) - { - Projectile.spriteDirection = -1; - Projectile.rotation = (float)Math.Atan2((double)-(double)Projectile.velocity.Y, (double)-(double)Projectile.velocity.X); - } - else - { - Projectile.spriteDirection = 1; - Projectile.rotation = Projectile.velocity.ToRotation(); - } - - Lighting.AddLight(Projectile.Center, 0.7f, 0.3f, 0f); - if (Main.player[Projectile.owner].active && !Main.player[Projectile.owner].dead) - { - if (Projectile.Distance(Main.player[Projectile.owner].Center) > homingRange) - { - Vector2 moveDirection = Projectile.SafeDirectionTo(Main.player[Projectile.owner].Center, Vector2.UnitY); - Projectile.velocity = (Projectile.velocity * (aiVelocityMult - 1f) + moveDirection * scaleFactor) / aiVelocityMult; - return; - } - - CalamityUtils.HomeInOnNPC(Projectile, true, 200f, 9f, 20f); - } - else - { - if (Projectile.timeLeft > 30) - { - Projectile.timeLeft = 30; - } - } - } - - public override bool PreDraw(ref Color lightColor) - { - CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], lightColor, 1); - return false; - } - - public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) => target.AddBuff(ModContent.BuffType(), 180); - - public override void OnHitPlayer(Player target, Player.HurtInfo info) => target.AddBuff(ModContent.BuffType(), 180); - - public override void OnKill(int timeLeft) - { - Projectile.position = Projectile.Center; - Projectile.width = Projectile.height = 96; - Projectile.position.X = Projectile.position.X - (float)(Projectile.width / 2); - Projectile.position.Y = Projectile.position.Y - (float)(Projectile.height / 2); - Projectile.maxPenetrate = -1; - Projectile.penetrate = -1; - Projectile.usesLocalNPCImmunity = true; - Projectile.localNPCHitCooldown = 10; - Projectile.Damage(); - SoundEngine.PlaySound(SoundID.Item74, Projectile.Center); - for (int i = 0; i < 6; i++) - { - Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.CopperCoin, 0, 0); - } - for (int j = 0; j < 10; j++) - { - int divinity = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.CopperCoin, 0, 0); - Main.dust[divinity].noGravity = true; - Main.dust[divinity].velocity *= 3f; - divinity = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.CopperCoin, 0, 0); - Main.dust[divinity].velocity *= 2f; - Main.dust[divinity].noGravity = true; - } - } - } -} diff --git a/Projectiles/Magic/DivineRetributionSpear.png b/Projectiles/Magic/DivineRetributionSpear.png deleted file mode 100644 index 2e733503aa913d2e030c7c531f01d639fd7fa49d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 633 zcmV-<0*3vGP)<{92XskIMF-&u4hA|iC0EYK0000PbVXQn zQ*UN;cVTj60B~VxZgehgWpp4kE-)@JIn>s&WB>pG<4Ht8RA@u(l)-JoFbqY#Pfk5| zf{f5TI!l30(+#?kYc>Bd3T;|~U&GU{KC6QOz_B4Y6A_H=hlKj2W z0=}M4sPrk>9cS1`g+8m%3=)1|g+pvm$=72Ld6kVIUov#q`d_us7b(0Pzo5b)egI#; zdxKa+M}t92d8Dunq@%$-^7PGnBoRj{H)AG0qa^hmP{lO7qhlFA2>5{&HpnA|U(O(Z z<{cgDp^%>}1M;x08KwBrJn%kqO&M{k%&bAzx=a3UXn0tISX@UNfH)0_BL<4%)JJ(l zfB&A{aSP_PNp}CnlqtDBC8>WiD3bcimNE>Y``qwGir9kovr55^<#R&YNP`kDYf$tlc|-iY(!##Jb|Jen^||FL^jVE&P$d}P z7xTtIWDxP%Jnwh|$g6C7nn5eULOL#HWX!WanMctKdJudv7=d>CDXq;m26f#Zrk;oX T8kANp diff --git a/Projectiles/Ranged/HighExplosivePeanutShell.cs b/Projectiles/Ranged/HighExplosivePeanutShell.cs deleted file mode 100644 index 10fdaa11e0..0000000000 --- a/Projectiles/Ranged/HighExplosivePeanutShell.cs +++ /dev/null @@ -1,93 +0,0 @@ -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.Audio; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Projectiles.Ranged -{ - public class HighExplosivePeanutShell : ModProjectile, ILocalizedModType - { - public new string LocalizationCategory => "Projectiles.Ranged"; - private const int Lifetime = 180; - - public override void SetStaticDefaults() - { - ProjectileID.Sets.TrailCacheLength[Projectile.type] = 9; - ProjectileID.Sets.TrailingMode[Projectile.type] = 1; - } - - public override void SetDefaults() - { - Projectile.width = 16; - Projectile.height = 16; - Projectile.friendly = true; - Projectile.DamageType = DamageClass.Ranged; - Projectile.extraUpdates = 4; - Projectile.timeLeft = Lifetime; - } - - public override void AI() - { - Projectile.rotation = Projectile.velocity.ToRotation(); - Projectile.spriteDirection = 1; - - // Lighting - Lighting.AddLight(Projectile.Center, 0.75f, 0.65f, 0.08f); - - // Dirty dust, done dirt cheap - { - int dustID = 7; // wood flakes - float scale = Main.rand.NextFloat(1f, 1.4f); - Dust d = Dust.NewDustDirect(Projectile.position, Projectile.width, Projectile.height, dustID); - d.noGravity = true; - d.scale = scale; - - // Dust velocity is a complicated flaking function taken from Holy Fire Bullets - d.velocity *= 0.2f; - float angleDeviation = 0.17f; - float angle = Main.rand.NextFloat(-angleDeviation, angleDeviation); - Vector2 sprayVelocity = Projectile.velocity.RotatedBy(angle) * 0.6f; - d.velocity += sprayVelocity; - } - } - - public override bool PreDraw(ref Color lightColor) - { - CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], lightColor, 1); - return false; - } - - public override void OnKill(int timeLeft) - { - // Grenade Launcher + Lunar Flare sounds for maximum meaty explosion - SoundEngine.PlaySound(SoundID.Item62, Projectile.Center); - SoundEngine.PlaySound(SoundID.Item88, Projectile.Center); - - // Massively inflate the projectile's hitbox - Projectile.position = Projectile.Center; - Projectile.width = Projectile.height = 140; - Projectile.position.X = Projectile.position.X - Projectile.width / 2; - Projectile.position.Y = Projectile.position.Y - Projectile.height / 2; - - // Allow infinite piercing and ignoring iframes for this one extra hit - Projectile.maxPenetrate = -1; - Projectile.penetrate = -1; - Projectile.usesLocalNPCImmunity = true; - Projectile.localNPCHitCooldown = -1; - - // Rocket III type explosion is now a utility for convenience - Projectile.LargeFieryExplosion(); - - // Deal damage again. The explosion deals half the damage of the direct hit. - Projectile.damage /= 2; - Projectile.Damage(); - } - - public override bool OnTileCollide(Vector2 oldVelocity) - { - Collision.HitTiles(Projectile.position, Projectile.velocity, Projectile.width, Projectile.height); - return true; // the projectile does indeed die on collision - } - } -} diff --git a/Projectiles/Summon/MiniGuardianAttack.cs b/Projectiles/Summon/MiniGuardianAttack.cs index 26db5b6ad2..daee3f7146 100644 --- a/Projectiles/Summon/MiniGuardianAttack.cs +++ b/Projectiles/Summon/MiniGuardianAttack.cs @@ -155,7 +155,6 @@ private void BaseAI(NPC potentialTarget) } // Turning (wtf is this) - // idk ask phup lmao if (Projectile.velocity.X < playerDestination.X) { Projectile.velocity.X += acceleration; diff --git a/Projectiles/Summon/MiniGuardianDefense.cs b/Projectiles/Summon/MiniGuardianDefense.cs index 7f05149aa0..997a72dd9a 100644 --- a/Projectiles/Summon/MiniGuardianDefense.cs +++ b/Projectiles/Summon/MiniGuardianDefense.cs @@ -226,7 +226,7 @@ public override void AI() playerDist = returnSpeed / playerDist; playerDestination *= playerDist; - // Turning (wtf is this) (idk ask phup lmao) + // Turning (wtf is this) if (Projectile.velocity.X < playerDestination.X) { Projectile.velocity.X += acceleration; diff --git a/Projectiles/Summon/MiniGuardianHealer.cs b/Projectiles/Summon/MiniGuardianHealer.cs index bd791dc12e..26ae3f4827 100644 --- a/Projectiles/Summon/MiniGuardianHealer.cs +++ b/Projectiles/Summon/MiniGuardianHealer.cs @@ -231,7 +231,7 @@ public override void AI() playerDist = returnSpeed / playerDist; playerDestination *= playerDist; - // Turning (wtf is this) (idk ask phup lmao) + // Turning (wtf is this) if (Projectile.velocity.X < playerDestination.X) { Projectile.velocity.X += acceleration; diff --git a/Projectiles/Typeless/YanmeisKnifeSlash.cs b/Projectiles/Typeless/YanmeisKnifeSlash.cs deleted file mode 100644 index 87e3fa20ed..0000000000 --- a/Projectiles/Typeless/YanmeisKnifeSlash.cs +++ /dev/null @@ -1,115 +0,0 @@ -using System; -using CalamityMod.Buffs.StatBuffs; -using CalamityMod.Buffs.StatDebuffs; -using CalamityMod.Items.Weapons.Typeless; -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.Audio; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Projectiles.Typeless -{ - public class YanmeisKnifeSlash : ModProjectile, ILocalizedModType - { - public new string LocalizationCategory => "Projectiles.Typeless"; - - public override void SetStaticDefaults() - { - Main.projFrames[Projectile.type] = 5; - } - - public override void SetDefaults() - { - Projectile.width = 180; - Projectile.height = 96; - Projectile.friendly = true; - Projectile.penetrate = -1; - Projectile.tileCollide = false; - Projectile.ownerHitCheck = true; - Projectile.usesLocalNPCImmunity = true; - Projectile.localNPCHitCooldown = 20; - } - - public override void AI() - { - Player player = Main.player[Projectile.owner]; - - // Frames and crap - Projectile.frameCounter++; - if (Projectile.frameCounter % 7 == 0) - { - Projectile.frame++; - if (Projectile.frame >= Main.projFrames[Projectile.type]) - Projectile.Kill(); - } - - // Create idle light and dust. - Vector2 origin = Projectile.Center + Projectile.velocity * 3f; - Lighting.AddLight(origin, 0f, 1.5f, 0.1f); - - Vector2 playerRotatedPoint = player.RotatedRelativePoint(player.MountedCenter, true); - - // Rotation and directioning. - float velocityAngle = Projectile.velocity.ToRotation(); - Projectile.rotation = velocityAngle + (Projectile.spriteDirection == -1).ToInt() * MathHelper.Pi; - Projectile.direction = (Math.Cos(velocityAngle) > 0).ToDirectionInt(); - - // Positioning close to the end of the player's arm. - Projectile.position = playerRotatedPoint - Projectile.Size * 0.5f + velocityAngle.ToRotationVector2() * 80f; - - // Sprite and player directioning. - Projectile.spriteDirection = Projectile.direction; - player.ChangeDir(Projectile.direction); - - // Prevents the projectile from dying - Projectile.timeLeft = 2; - - // Player item-based field manipulation. - player.itemRotation = (Projectile.velocity * Projectile.direction).ToRotation(); - player.heldProj = Projectile.whoAmI; - player.itemTime = 2; - player.itemAnimation = 2; - } - - public void HandleAttachmentMovement(Player player, Vector2 playerRotatedPoint) - { - float speed = 1f; - if (player.ActiveItem().shoot == Projectile.type) - { - speed = player.ActiveItem().shootSpeed * Projectile.scale; - } - Vector2 newVelocity = (Main.MouseWorld - playerRotatedPoint).SafeNormalize(Vector2.UnitX * player.direction) * speed; - - // Sync if a velocity component changes. - if (Projectile.velocity.X != newVelocity.X || Projectile.velocity.Y != newVelocity.Y) - { - Projectile.netUpdate = true; - } - Projectile.velocity = newVelocity; - } - public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) - { - target.AddBuff(ModContent.BuffType(), 600); - if (!Main.dedServ) - { - for (int i = 0; i < 60; i++) - { - Dust dust = Dust.NewDustDirect(Main.player[Projectile.owner].position, Main.player[Projectile.owner].width, Main.player[Projectile.owner].height, DustID.RainbowMk2); - dust.position.X += Main.rand.NextFloat(-16f, 16f); - dust.color = Main.hslToRgb(Main.rand.NextFloat(0.26f, 0.37f), 1f, 0.75f); - dust.velocity = Main.rand.NextVector2Circular(24f, 24f); - dust.scale = Main.rand.NextFloat(1.4f, 1.8f); - dust.noGravity = true; - } - } - if (Projectile.ai[0] == 0f) - { - SoundEngine.PlaySound(YanmeisKnife.HitSound, Projectile.position); - Projectile.ai[0] = 1f; - } - Main.player[Projectile.owner].AddBuff(ModContent.BuffType(), 600); - } - public override Color? GetAlpha(Color lightColor) => new Color(0, 215, 0, 0); - } -} diff --git a/Projectiles/Typeless/YanmeisKnifeSlash.png b/Projectiles/Typeless/YanmeisKnifeSlash.png deleted file mode 100644 index e0b03d728cfe75e968220cddf7f8dc3c8996581b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1646 zcmb7EdpOg37+-Z#XG@)x(m~WHGlVCS+Zk(U$z_TdsmP^Ra%*g7RHzx_VKgO@88CB96j12qXo^pv^9YKAY|}iIeeEXc*X3ApDSs z+9Tz|ib{pYVBHI}%iH<#zRI+A);lNPNP#bn=Xe6GepZHNddv*ZN`NEGlz;ct(Z5sE zGSxD}>EYC^8Mg+m8T8C-EHVjR-Y@|0f4)@nim{zXHI@2_YA0rjbug^>fi=Bq7zGZGO}J|lj2^a&kst1DF}NXH@^ zLGnB^zFLL=yIMZSP*JDoqOLefYF>*!Ijp8_fuqptLu5Edq3DOBa}$$bvbZCs^fd_s zIjVPWK%th4BX~!jq%3YSaYKAj8L1?o*I#lA4`h}%I(VkL?=emZ>YM@m82&@CK?D3Q zik;8?7hE(e(!4LL?Qm5dE5t+iGx(SJrzTZv>4}hoPqX0?>eI@`5HHQesI@0fBM(q? znP@lY71^p+)jC1gxwE8FKd~+h7O&I;g?4zJgzI9kW9WsP#t^Fe=G@ZJSjzH%S6%36 z@jjSvV?FR9*xFvk5ZY`%^sc~T$Z$&|eo_b@?4VHiA!i~cc&8zi;s)l+QigdvwNp_3 z-G?X31SRJqL;}wGeA?AL524V6XJgiMIkKSg%1{7v1#c=J_guChEQX+QZQMeV)es^B z6duf;@H#%To?&}llF72d{_!2nhO9P6vz@U(vod6Pr4-77r8nu;n%g(4V+GgTnT?sz-VS_p-e$`x42B;1&r~89)Fp$T37C-YQ~<^seex5ADE> zuL;TZFR7D%E?Bu`_#>G{0R{b${=pjP5~)Df-rBG{@gUII+>?^17sqJ6!5Z-*CiW0R zcGR{8c|Dgd;E@6AEl6*NXgrx%weWfhP-mEh)cr_BRT#{jFqJ@|(D(xGgRT;jIVvq2bKTJ)>=&$>QR(I^YiJK6Gb%xasKYJ>gJ#*->XGVCl*huta zA)*o}yh$f`fW4fJErDE2Hj4GBlM+p;uNW-}Q`U)t-6tiUiotCkE6L81N`6`%ZqPYP zg0wT<1gb&w7g>9oOf>!3I@hZK6MlY!Bd*l4+cU37$N!}5-j`*I9YH7q3#H;Yf;afs z%+w;?7EUXY8a2>VFOv}~h^HdM9IhLaXl;m9&@XY?5jrW%r0cc1z;(y5K86nS>D&q{ z{Nu=A1Dj*bx3XJ!GD#{PJ~+MWNQ5{(UG?^RtlicQwPe3_^Yzx8ztC+ayG1BnTCn!% zjC_{EH$@qzAg@ovcWLdqkjYigi{7u5{WtG~Bk%w%$hYk+oOWb~#*~$OwI{3JITC$B z4a_u@!xvUe$;kcV$lS{*nYdx=xoYAad`IT%6tnAztojN%VDQk^=ZAw@&zfz7tK<2; /// This is an empty child class that acts exactly like the default implementation of the abstract /// class, which itself acts nearly identical to vanilla pylon TEs. This inheritance only exists so that modded pylon entities From 0c23147febb4d47d483e6bb10491d8f161baadfa Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Mon, 26 May 2025 21:35:37 -0700 Subject: [PATCH 249/401] No thank you! --- .../DevPaintings/ThankYouPainting.png | Bin 3085 -> 1790 bytes .../DevPaintings/ThankYouPaintingTile.png | Bin 3863 -> 1955 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.png b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.png index 87e86d9bcb746aa657ca0815dab453c6b3f55f26..157df9cb45873ead3b8d170ae53944af14b115cd 100644 GIT binary patch literal 1790 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 bbYXO9Z*BlFgjnqF00000NkvXXu0mjfX`=ad diff --git a/Tiles/Furniture/DevPaintings/ThankYouPaintingTile.png b/Tiles/Furniture/DevPaintings/ThankYouPaintingTile.png index 434b490237254097e64eb3cc7f70955daf159700..d1706759fe8fff48950265e9f2acc5422413a155 100644 GIT binary patch literal 1955 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 ZbZKvH05ODE?C$^o002ovPDHLkV1h`RZ)pGk From edc488c794c055710b709d685e5c9c9c04a87364 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Tue, 27 May 2025 17:14:54 -0400 Subject: [PATCH 250/401] Fixed Purple Haze buff localization --- Localization/en-US/Mods.CalamityMod.Buffs.hjson | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Localization/en-US/Mods.CalamityMod.Buffs.hjson b/Localization/en-US/Mods.CalamityMod.Buffs.hjson index 2e355ab0d1..6fc73e2912 100644 --- a/Localization/en-US/Mods.CalamityMod.Buffs.hjson +++ b/Localization/en-US/Mods.CalamityMod.Buffs.hjson @@ -28,11 +28,6 @@ EvergreenGinBuff: { Description: Sickness and water debuff damage increased, life regen reduced } -FabsolVodkaBuff: { - DisplayName: Fab - Description: You feel fabulous -} - FireballBuff: { DisplayName: Fireball Description: Fire debuff damage increased, life regen reduced @@ -63,6 +58,11 @@ OldFashionedBuff: { Description: Accessory and set bonus damage multiplied, damage reduced } +PurpleHazeBuff: { + DisplayName: Purple Haze + Description: Increases damage and gives extra immunity frames, defense reduced +} + RedWineBuff: { DisplayName: Red Wine Description: Life regen reduced From 2b7fd1cd9c8a1e9a519dfe0e8548f6c323e2c99b Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Tue, 27 May 2025 21:27:44 -0700 Subject: [PATCH 251/401] what + lava chicken fixed reversions --- CalPlayer/CalamityPlayer.cs | 1 - Items/CalamityGlobalItemTooltip.cs | 2 +- .../{PotofPain.cs => LavaChickenBroth.cs} | 4 ++-- .../{PotofPain.png => LavaChickenBroth.png} | Bin Items/Weapons/Melee/Ozzathoth.cs | 2 +- .../Mods.CalamityMod.Items.Potions.hjson | 18 +++++++++--------- NPCs/ExoMechs/Ares/AresBody.cs | 2 +- .../DraedonsArsenal/PhaseslayerBeam.cs | 1 + Projectiles/Magic/BeamingBolt2.cs | 1 + 9 files changed, 16 insertions(+), 15 deletions(-) rename Items/Potions/{PotofPain.cs => LavaChickenBroth.cs} (93%) rename Items/Potions/{PotofPain.png => LavaChickenBroth.png} (100%) diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 73799d9669..e79cea351d 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -1654,7 +1654,6 @@ public override void ResetEffects() shadowSpeed = false; dsSetBonus = false; wearingRogueArmor = false; - cirrusDress = false; blockAllDashes = false; blazingCursorDamage = false; diff --git a/Items/CalamityGlobalItemTooltip.cs b/Items/CalamityGlobalItemTooltip.cs index 62eb89a710..6b8395ea49 100644 --- a/Items/CalamityGlobalItemTooltip.cs +++ b/Items/CalamityGlobalItemTooltip.cs @@ -102,7 +102,7 @@ private void ApplyRarityColor(Item item, TooltipLine nameLine) nameLine.OverrideColor = new Color(0.34f, 0.34f + 0.66f * Main.DiscoG / 255f, 0.34f + 0.5f * Main.DiscoG / 255f); if (item.type == ModContent.ItemType()) nameLine.OverrideColor = ShatteredCommunity.GetRarityColor(); - if (item.type == ModContent.ItemType()) + if (item.type == ModContent.ItemType()) nameLine.OverrideColor = ShatteredCommunity.GetRarityColor(); if (item.type == ModContent.ItemType()) nameLine.OverrideColor = CalamityUtils.ColorSwap(new Color(255, 166, 0), new Color(25, 250, 25), 6f); //alternates between emerald green and amber (BanditHueh) diff --git a/Items/Potions/PotofPain.cs b/Items/Potions/LavaChickenBroth.cs similarity index 93% rename from Items/Potions/PotofPain.cs rename to Items/Potions/LavaChickenBroth.cs index c41d88cdad..042ad6d6c2 100644 --- a/Items/Potions/PotofPain.cs +++ b/Items/Potions/LavaChickenBroth.cs @@ -9,7 +9,7 @@ namespace CalamityMod.Items.Potions { [LegacyName("Fabsoup")] - public class PotofPain : ModItem, ILocalizedModType + public class LavaChickenBroth : ModItem, ILocalizedModType { public new string LocalizationCategory => "Items.Potions"; public static readonly SoundStyle UseSound = new("CalamityMod/Sounds/Item/SoupConsumption"); @@ -37,7 +37,7 @@ public override void SetDefaults() public override void UseItemFrame(Player player) { - int time = CalamityUtils.SecondsToFrames(1800); // 30 minutes + int time = CalamityUtils.SecondsToFrames(1525); // 25 minutes, 25 seconds if (player.itemAnimation == 180) { player.AddBuff(BuffID.WellFed3, time); diff --git a/Items/Potions/PotofPain.png b/Items/Potions/LavaChickenBroth.png similarity index 100% rename from Items/Potions/PotofPain.png rename to Items/Potions/LavaChickenBroth.png diff --git a/Items/Weapons/Melee/Ozzathoth.cs b/Items/Weapons/Melee/Ozzathoth.cs index 48dd268241..60253d28d3 100644 --- a/Items/Weapons/Melee/Ozzathoth.cs +++ b/Items/Weapons/Melee/Ozzathoth.cs @@ -36,7 +36,7 @@ public override void SetDefaults() Item.noUseGraphic = true; Item.noMelee = true; - Item.shoot = ModContent.ProjectileType(); + Item.shoot = ModContent.ProjectileType(); Item.shootSpeed = 16f; Item.autoReuse = true; diff --git a/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson b/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson index 62e6e4da80..db1553aa7f 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson @@ -56,15 +56,6 @@ DeliciousMeat: { ''' } -Fabsoup: { - DisplayName: Pot of Pain - Tooltip: - ''' - {$CommonItemTooltip.MajorStats} - 'hrngh, soup' - ''' -} - FlaskOfBrimstone: { DisplayName: Flask of Brimstone Tooltip: Melee, Whip, and Rogue attacks inflict Brimstone Flames @@ -95,6 +86,15 @@ HadalStew: { ''' } +LavaChickenBroth: { + DisplayName: Lava Chicken Broth + Tooltip: + ''' + {$CommonItemTooltip.MajorStats} + 'It's tasty as hell' + ''' +} + OmegaHealingPotion: { DisplayName: Omega Healing Potion Tooltip: "" diff --git a/NPCs/ExoMechs/Ares/AresBody.cs b/NPCs/ExoMechs/Ares/AresBody.cs index efc20d104a..60852ad353 100644 --- a/NPCs/ExoMechs/Ares/AresBody.cs +++ b/NPCs/ExoMechs/Ares/AresBody.cs @@ -1594,7 +1594,7 @@ public static void DefineExoMechLoot(NPC npc, NPCLoot npcLoot, int mechType) npcLoot.Add(ItemDropRule.BossBagByCondition(DropHelper.If(CanDropLoot), ModContent.ItemType())); // Legendary seed soup - mainDrops.Add(ItemDropRule.ByCondition(DropHelper.If(info => info.npc.type == ModContent.NPCType() && info.npc.ModNPC().exoMechdusa), ModContent.ItemType()), hideLootReport: true); + mainDrops.Add(ItemDropRule.ByCondition(DropHelper.If(info => info.npc.type == ModContent.NPCType() && info.npc.ModNPC().exoMechdusa), ModContent.ItemType()), hideLootReport: true); // All other drops are contained in the bag, so they only drop directly on Normal if (!Main.expertMode) diff --git a/Projectiles/DraedonsArsenal/PhaseslayerBeam.cs b/Projectiles/DraedonsArsenal/PhaseslayerBeam.cs index c1b1ee841c..4af4752708 100644 --- a/Projectiles/DraedonsArsenal/PhaseslayerBeam.cs +++ b/Projectiles/DraedonsArsenal/PhaseslayerBeam.cs @@ -2,6 +2,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Terraria; +using Terraria.ID; using Terraria.DataStructures; using Terraria.ModLoader; namespace CalamityMod.Projectiles.DraedonsArsenal diff --git a/Projectiles/Magic/BeamingBolt2.cs b/Projectiles/Magic/BeamingBolt2.cs index 013ac5f482..4dd05b2777 100644 --- a/Projectiles/Magic/BeamingBolt2.cs +++ b/Projectiles/Magic/BeamingBolt2.cs @@ -2,6 +2,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Terraria; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Projectiles.Magic { From 4ffb55706a39b4a1091c49394855e5356c109785 Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Tue, 27 May 2025 22:13:22 -0700 Subject: [PATCH 252/401] remove haze tip --- Localization/en-US/Mods.CalamityMod.Items.Potions.hjson | 1 - 1 file changed, 1 deletion(-) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson b/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson index db1553aa7f..1817c32878 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson @@ -305,7 +305,6 @@ PurpleHaze: { 8% increased damage, but lowers defense by 5% Increases immune time after being struck Drinking more than 3 different alcohols might not end well with your liver - This magical liquor is highly sought by those with a refined palate ''' } From 9c734770c9b127f40a468ddaa9154b6a9dd3c9ee Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Wed, 28 May 2025 12:35:05 +0700 Subject: [PATCH 253/401] Purge of B00BA5 --- Items/Accessories/TheCommunity.cs | 4 ++++ Localization/en-US/Mods.CalamityMod.Buffs.hjson | 2 +- Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Items/Accessories/TheCommunity.cs b/Items/Accessories/TheCommunity.cs index 7aeffc057c..5d819c8cc9 100644 --- a/Items/Accessories/TheCommunity.cs +++ b/Items/Accessories/TheCommunity.cs @@ -109,6 +109,10 @@ internal static float CalculatePower(bool killsOnly = false) public override void ModifyTooltips(List list) { + var ThankYouTooltip = list.FirstOrDefault(x => x.Name == "Tooltip2" && x.Mod == "Terraria"); + if (ThankYouTooltip != null) + ThankYouTooltip.OverrideColor = Main.DiscoColor; + float power = CalculatePower(); string statList = this.GetLocalization("StatsList").Format( (DamageMultiplier * power * 100).ToString("N1"), diff --git a/Localization/en-US/Mods.CalamityMod.Buffs.hjson b/Localization/en-US/Mods.CalamityMod.Buffs.hjson index 1769d39602..8f31748835 100644 --- a/Localization/en-US/Mods.CalamityMod.Buffs.hjson +++ b/Localization/en-US/Mods.CalamityMod.Buffs.hjson @@ -520,7 +520,7 @@ AstralInjectionBuff: { BaguetteBuff: { DisplayName: Baguette - Description: "[c/B00BA5:'If only I knew...' ~Cirrus]" + Description: Goes well with Red Wine } BloodfinBoost: { diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson index 37e8b03f1a..a062dc1703 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson @@ -1809,7 +1809,7 @@ TheCommunity: { ''' [STATS] 'The heart of (most of) the Terraria community' - [c/B00BA5:Thank you to all of my supporters who made this mod a reality!] + Thank you to all of my supporters who made this mod a reality! ''' StatsList: ''' From e7674bd7df2479f9757878c16367680d07e0616a Mon Sep 17 00:00:00 2001 From: Cameron Ewell Date: Wed, 28 May 2025 01:37:27 -0400 Subject: [PATCH 254/401] Supreme Permafrost projectile names --- .../en-US/Mods.CalamityMod.Projectiles.Boss.hjson | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Localization/en-US/Mods.CalamityMod.Projectiles.Boss.hjson b/Localization/en-US/Mods.CalamityMod.Projectiles.Boss.hjson index 515f32c9f6..b80a84b202 100644 --- a/Localization/en-US/Mods.CalamityMod.Projectiles.Boss.hjson +++ b/Localization/en-US/Mods.CalamityMod.Projectiles.Boss.hjson @@ -158,8 +158,8 @@ YharonBulletHellVortex.DisplayName: Bullet Hell Vortex YharonFireball.DisplayName: Dragon Fireball YharonFireball2.DisplayName: Dragon Fireball THanosSideLaser.DisplayName: T Hanos Side Laser -PermafrostAbsoluteZeroProjectile.DisplayName: Permafrost Absolute Zero Projectile -PermafrostBlast.DisplayName: Permafrost Blast -PermafrostBlaster.DisplayName: Permafrost Blaster -PermafrostColdheartIcicle.DisplayName: Permafrost Coldheart Icicle -PermafrostMeat.DisplayName: Permafrost Meat +PermafrostAbsoluteZeroProjectile.DisplayName: Absolute Ultra Zero +PermafrostBlast.DisplayName: Permafrost's Gigablast +PermafrostBlaster.DisplayName: Blaster of Unlimited Air Conditioning +PermafrostColdheartIcicle.DisplayName: Coldheart Icicle +PermafrostMeat.DisplayName: Cool Meat From c4d71a5c80fa556a95442a9805328f527860a91c Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Mon, 26 May 2025 21:34:10 -0400 Subject: [PATCH 255/401] Moved donor chat to Brimstone Witch --- .../en-US/Mods.CalamityMod.NPCs.hjson | 2 ++ NPCs/TownNPCs/WITCH.cs | 24 ++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Localization/en-US/Mods.CalamityMod.NPCs.hjson b/Localization/en-US/Mods.CalamityMod.NPCs.hjson index c3f02514c5..e8b92904e0 100644 --- a/Localization/en-US/Mods.CalamityMod.NPCs.hjson +++ b/Localization/en-US/Mods.CalamityMod.NPCs.hjson @@ -508,6 +508,8 @@ WITCH: { } EnchantButton: Enchant + DonorButton: Donors + DonorShoutout: Hey {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}, {15}, {16}, {17}, {18}, {19}, {20}, {21}, {22}, {23} and {24}. You guys are good people. TownNPCMood: { Content: I can't complain, really. diff --git a/NPCs/TownNPCs/WITCH.cs b/NPCs/TownNPCs/WITCH.cs index cbd9fbc1ba..c1524c4b84 100644 --- a/NPCs/TownNPCs/WITCH.cs +++ b/NPCs/TownNPCs/WITCH.cs @@ -125,7 +125,11 @@ public override string GetChat() return dialogue; } - public override void SetChatButtons(ref string button, ref string button2) => button = this.GetLocalizedValue("EnchantButton"); + public override void SetChatButtons(ref string button, ref string button2) + { + button = this.GetLocalizedValue("EnchantButton"); + button2 = this.GetLocalizedValue("DonorButton"); + } public override void OnChatButtonClicked(bool firstButton, ref string shopName) { @@ -141,6 +145,24 @@ public override void OnChatButtonClicked(bool firstButton, ref string shopName) Main.LocalPlayer.Calamity().GivenBrimstoneLocus = true; } } + else + { + Main.npcChatText = Donors(); + } + } + public string Donors() + { + IList donorList = new List(CalamityLists.donatorList); + int maxDonorsListed = 25; + string[] donors = new string[maxDonorsListed]; + for (int i = 0; i < maxDonorsListed; i++) + { + donors[i] = donorList[Main.rand.Next(donorList.Count)]; + donorList.Remove(donors[i]); + } + + string text = this.GetLocalization("DonorShoutout").Format(donors); + return text; } // Make this Town NPC teleport to the Queen statue when triggered. From e066ecd5978a88c6ff02172b3460987a1408f065 Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Wed, 28 May 2025 12:40:18 +0700 Subject: [PATCH 256/401] OUR mod. --- Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson index 4b8f2d679e..57bfda5f1f 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson @@ -1809,7 +1809,7 @@ TheCommunity: { ''' [STATS] 'The heart of (most of) the Terraria community' - Thank you to all of my supporters who made this mod a reality! + Thank you to all of our supporters who made this mod a reality! ''' StatsList: ''' From cb741f19bbb265a5521cf10cea344d41b9cbdd7c Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Wed, 28 May 2025 13:13:10 +0700 Subject: [PATCH 257/401] Removed trace comments --- CalPlayer/CalamityPlayer.cs | 9 +-------- CalPlayer/CalamityPlayerMiscEffects.cs | 4 ---- Events/AcidRainEvent.cs | 1 - Items/CalamityGlobalItem.cs | 1 - NPCs/CalamityGlobalNPC.cs | 18 +++--------------- Systems/WorldMiscUpdateSystem.cs | 2 +- 6 files changed, 5 insertions(+), 30 deletions(-) diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index a1aba1252b..21f1598fc2 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -4865,15 +4865,8 @@ public override void OnEnterWorld() if (CalamityConfig.Instance.SpeedrunTimer) CalamityMod.SpeedrunTimer.Restart(); - // - // 31OCT2024: Fabsol: Added a temporary message for the Gimme Swag plushie campaign. - // This message should not exist indefinitely. It is being pushed as a silent public update just for itself. - // As this message always displays and is not configurable, the previous rules about startup messages have been replaced with always-true. - // - // Set a random delay between 12 and 20 seconds. When this delay hits zero, startup messages display - bool plushieMessage = true; - if (plushieMessage || CalamityConfig.Instance.WikiStatusMessage) + if (CalamityConfig.Instance.WikiStatusMessage) { startMessageDisplayDelay = Main.rand.Next(CalamityUtils.SecondsToFrames(12), CalamityUtils.SecondsToFrames(20) + 1); } diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index 3b8a16c371..efe279743a 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -4167,10 +4167,6 @@ private void HandleTextChatMessages() CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.WikiStatus1"); CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.WikiStatus2"); } - - // 31OCT2024: Fabsol: Plushie message always appears. - // 11FEB2024: Fabsol: Currently commented out because the campaign has ended. - // CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.GimmeSwagPlushieCampaign"); } --startMessageDisplayDelay; diff --git a/Events/AcidRainEvent.cs b/Events/AcidRainEvent.cs index a56fbe8ce2..f9194e8cd6 100644 --- a/Events/AcidRainEvent.cs +++ b/Events/AcidRainEvent.cs @@ -242,7 +242,6 @@ public static void Update() if (inNaturalSeaPosition && player.Calamity().ZoneSulphur) { // Makes rain pour at its maximum intensity (but only after an idiot meanders into the Sulphurous Sea) - // You'll never catch me, Fabs, Not when I shift into MAXIMUM OVERDRIVE!! HasStartedAcidicDownpour = true; CalamityNetcode.SyncWorld(); break; diff --git a/Items/CalamityGlobalItem.cs b/Items/CalamityGlobalItem.cs index 12531fede4..0643be10da 100644 --- a/Items/CalamityGlobalItem.cs +++ b/Items/CalamityGlobalItem.cs @@ -934,7 +934,6 @@ internal float DischargeEnchantmentDamageFormula() // 10% charge = 83% damage // 0% charge = 41.33% damage // - // Fabsol - I changed this formula because it was bad and confusing, and I had promised to do so a while ago. internal float ChargeDamageFormula() { float x = MathHelper.Clamp(ChargeRatio, 0f, 1f); diff --git a/NPCs/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index 7453d73aa6..16953423cf 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -1512,8 +1512,8 @@ private void RevDeathStatChanges(NPC npc, Mod mod) #region Vulnerabilities and Resistances private void VulnerabilitiesAndResistances(NPC npc) { - // These enemies are categorized in such a way to make them easy to understand. - // Do not mess with these categories unless you ask me for permission - Fab. + // These enemies are categorized in such a way to make them easy to understand + // Regroup these if necessary, reminder to keep it comprehensive switch (npc.type) { // Regular organic desert enemies. @@ -5993,17 +5993,6 @@ public override void EditSpawnRate(Player player, ref int spawnRate, ref int max maxSpawns = (int)(maxSpawns * 5f); } - // This is horribly unoptimized, I'm leaving it commented out. - Fab - /*if (NPC.AnyNPCs(NPCType())) - { - int otherWulfrumEnemies = NPC.CountNPCS(NPCType()) + NPC.CountNPCS(NPCType()) + NPC.CountNPCS(NPCType()) + NPC.CountNPCS(NPCType()); - if (otherWulfrumEnemies < 4) - { - spawnRate = (int)(spawnRate * 0.8); - maxSpawns = (int)(maxSpawns * 1.2f); - } - }*/ - // Reductions if (Main.SceneMetrics.PeaceCandleCount > 0) { @@ -6171,8 +6160,7 @@ public override void EditSpawnPool(IDictionary pool, NPCSpawnInfo sp } } - // 12JUL2023: Ozzatron: what does this do - // 27SEP2023: Fabsol: disables vanilla spawns "a pool of [0] indicates vanilla spawning" + // Disable vanilla spawns while in the Brimstone Crag if (calamityBiomeZone) { pool[0] = 0f; diff --git a/Systems/WorldMiscUpdateSystem.cs b/Systems/WorldMiscUpdateSystem.cs index 074ff42332..2a4e9dee57 100644 --- a/Systems/WorldMiscUpdateSystem.cs +++ b/Systems/WorldMiscUpdateSystem.cs @@ -339,7 +339,7 @@ public static void HandleTileGrowth() int tileTypeToPlaceThickness = 3; bool placeLilies = true; - // Do not change this number, ever. - Fabsol + // Apparently this is a reference! int minDistanceFromOtherLilies = 66; for (int k = x - minDistanceFromOtherLilies; k < x + minDistanceFromOtherLilies; k += 2) From 1452ccfb3ef2c3fa947bb983fbb3b258f1eb8447 Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Wed, 28 May 2025 00:02:39 -0700 Subject: [PATCH 258/401] Wings of Rebirth code --- CalPlayer/DrawLayers/WingsofRebirthLayer.cs | 42 ++++++++++++++++++ Items/Accessories/Wings/DrewsWings.png | Bin 443 -> 0 bytes Items/Accessories/Wings/DrewsWings_Wings.png | Bin 3362 -> 0 bytes Items/Accessories/Wings/TracersSeraph.cs | 2 +- .../{DrewsWings.cs => WingsofRebirth.cs} | 42 ++++++++++++++++-- Items/Accessories/Wings/WingsofRebirth.png | Bin 0 -> 1021 bytes .../Wings/WingsofRebirth_Wings.png | Bin 0 -> 165 bytes .../Wings/WingsofRebirth_Wings_Real.png | Bin 0 -> 6927 bytes Items/TreasureBags/YharonBag.cs | 2 +- ....CalamityMod.Items.Accessories.Wings.hjson | 8 ++-- NPCs/Yharon/Yharon.cs | 2 +- 11 files changed, 87 insertions(+), 11 deletions(-) create mode 100644 CalPlayer/DrawLayers/WingsofRebirthLayer.cs delete mode 100644 Items/Accessories/Wings/DrewsWings.png delete mode 100644 Items/Accessories/Wings/DrewsWings_Wings.png rename Items/Accessories/Wings/{DrewsWings.cs => WingsofRebirth.cs} (58%) create mode 100644 Items/Accessories/Wings/WingsofRebirth.png create mode 100644 Items/Accessories/Wings/WingsofRebirth_Wings.png create mode 100644 Items/Accessories/Wings/WingsofRebirth_Wings_Real.png diff --git a/CalPlayer/DrawLayers/WingsofRebirthLayer.cs b/CalPlayer/DrawLayers/WingsofRebirthLayer.cs new file mode 100644 index 0000000000..0602843e13 --- /dev/null +++ b/CalPlayer/DrawLayers/WingsofRebirthLayer.cs @@ -0,0 +1,42 @@ +using CalamityMod.Items.Accessories.Wings; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Graphics.PackedVector; +using ReLogic.Content; +using Terraria; +using Terraria.DataStructures; +using Terraria.ModLoader; + +namespace CalamityMod.CalPlayer.DrawLayers +{ + public class WingsofRebirthLayer : PlayerDrawLayer + { + public static Asset yharwingTexture; + + public override void Load() + { + yharwingTexture = ModContent.Request("CalamityMod/Items/Accessories/Wings/WingsofRebirth_Wings_Real"); + } + + public override Position GetDefaultPosition() => new AfterParent(PlayerDrawLayers.Wings); + + public override bool GetDefaultVisibility(PlayerDrawSet drawInfo) => drawInfo.drawPlayer.wings == EquipLoader.GetEquipSlot(Mod, "WingsofRebirth", EquipType.Wings); + + protected override void Draw(ref PlayerDrawSet drawInfo) + { + Player drawPlayer = drawInfo.drawPlayer; + + if (drawPlayer.dead) + return; + + Texture2D texture = yharwingTexture.Value; + Vector2 Position = drawInfo.Position; + Vector2 pos = new Vector2((int)(Position.X - Main.screenPosition.X + (drawPlayer.width / 2) - (2 * drawPlayer.direction)), (int)(Position.Y - Main.screenPosition.Y + (drawPlayer.height / 2) - 2f * drawPlayer.gravDir)); + Color lightColor = Lighting.GetColor((int)drawPlayer.Center.X / 16, (int)drawPlayer.Center.Y / 16, Color.White); + Color color = lightColor * (1 - drawInfo.shadow); + DrawData d = new DrawData(texture, pos, texture.Frame(1, 8, 0, drawInfo.drawPlayer.wingFrame), drawInfo.colorArmorBody, 0f, new Vector2(texture.Width / 2, texture.Height / 16), 1f, drawInfo.playerEffect, 0); + d.shader = drawInfo.drawPlayer.cWings; + drawInfo.DrawDataCache.Add(d); + } + } +} diff --git a/Items/Accessories/Wings/DrewsWings.png b/Items/Accessories/Wings/DrewsWings.png deleted file mode 100644 index bd8707e1c3343fe56a43ee10ce9e8d9df3372bf0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 443 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 Q@%N|#*D=;E*ZL#oUrvskUjP6A diff --git a/Items/Accessories/Wings/TracersSeraph.cs b/Items/Accessories/Wings/TracersSeraph.cs index 21303ea750..50ac3c6f07 100644 --- a/Items/Accessories/Wings/TracersSeraph.cs +++ b/Items/Accessories/Wings/TracersSeraph.cs @@ -78,7 +78,7 @@ public override void AddRecipes() { CreateRecipe(). AddIngredient(). - AddIngredient(). + AddIngredient(). AddIngredient(5). AddTile(). Register(); diff --git a/Items/Accessories/Wings/DrewsWings.cs b/Items/Accessories/Wings/WingsofRebirth.cs similarity index 58% rename from Items/Accessories/Wings/DrewsWings.cs rename to Items/Accessories/Wings/WingsofRebirth.cs index 30ec3ec6d8..56ff361ccd 100644 --- a/Items/Accessories/Wings/DrewsWings.cs +++ b/Items/Accessories/Wings/WingsofRebirth.cs @@ -1,4 +1,5 @@ -using CalamityMod.Rarities; +using CalamityMod.Dusts; +using CalamityMod.Rarities; using Microsoft.Xna.Framework; using Terraria; using Terraria.DataStructures; @@ -8,14 +9,16 @@ namespace CalamityMod.Items.Accessories.Wings { + // The equip sprite is actually blank as a custom draw layer is used to draw the real sprites without any base sprites conflicting + [LegacyName("DrewsWings")] [AutoloadEquip(EquipType.Wings)] - public class DrewsWings : ModItem, ILocalizedModType + public class WingsofRebirth : ModItem, ILocalizedModType { public new string LocalizationCategory => "Items.Accessories.Wings"; public override void SetStaticDefaults() { - ArmorIDs.Wing.Sets.Stats[Item.wingSlot] = new WingStats(361, 11.5f, 2.9f); + ArmorIDs.Wing.Sets.Stats[Item.wingSlot] = new WingStats(360, 11.5f, 2.9f); } public override void SetDefaults() @@ -36,7 +39,7 @@ public override void UpdateAccessory(Player player, bool hideVisual) { dustXOffset = -40; } - int flightDust = Dust.NewDust(new Vector2(player.position.X + (float)(player.width / 2) + (float)dustXOffset, player.position.Y + (float)(player.height / 2) - 15f), 30, 30, DustID.GemDiamond, 0f, 0f, 100, default, 2.4f); + int flightDust = Dust.NewDust(new Vector2(player.position.X + (float)(player.width / 2) + (float)dustXOffset, player.position.Y + (float)(player.height / 2) - 15f), 30, 30, (int)CalamityDusts.ProfanedFire, 0f, 0f, 100, default, 2.4f); Main.dust[flightDust].noGravity = true; Main.dust[flightDust].velocity *= 0.3f; if (Main.rand.NextBool(10)) @@ -48,6 +51,37 @@ public override void UpdateAccessory(Player player, bool hideVisual) player.noFallDmg = true; } + public override bool WingUpdate(Player player, bool inUse) + { + if (player.controlJump && player.wingTime > 0 && player.velocity.Y != 0) + { + int frameRate = 5; + int maxFrames = 8; + player.wingFrameCounter++; + if (player.wingFrameCounter >= frameRate * (maxFrames - 1)) + { + player.wingFrameCounter = 0; + player.wingFrame = 0; + } + if (player.wingFrameCounter % frameRate == 0) + { + player.wingFrame++; + } + } + else + { + player.wingFrameCounter = 0; + player.wingFrame = 0; + if (player.velocity.Y != 0) + { + player.wingFrame = 1; + if (player.controlJump && player.velocity.Y > 0) + player.wingFrame = 7; + } + } + return true; + } + public override void VerticalWingSpeeds(Player player, ref float ascentWhenFalling, ref float ascentWhenRising, ref float maxCanAscendMultiplier, ref float maxAscentMultiplier, ref float constantAscend) { ascentWhenFalling = 1f; diff --git a/Items/Accessories/Wings/WingsofRebirth.png b/Items/Accessories/Wings/WingsofRebirth.png new file mode 100644 index 0000000000000000000000000000000000000000..549d22953298f869f6c2941c8438c90ccd62aebe GIT binary patch literal 1021 zcmVPx#1ZP1_K>z@;j|==^1poj5LQqUpMJ|C|2IPenGerQ$nQ#C)0AgULwgCVAEzI5p zO#mU($pHKq03;47|BWX9*eat1D%l4m|5a80hlk*30L!NU0001aYRB^c000(rQchF< z|NsC0|NsC0|NsC0|NsC0|NsC000Gj#D10qR8 zK~!i%<(Lg`sxTOZOQATV6?K>Y|5tAxPivK-*MeM4rT#s< zF-?>cq9uY_>3DV8#o+77)Kf4Z;YZL(*qu87`Qg44Sas#s0oj3 z6k|sQBy3xsAnd@s=L$96gVIB9#Fz1_(#y?< z0ZL95K+%E(6`jwRQ3}$7ZiHDC31(@hBIeUOF)2oZyTc z;97iSf$cN6@O-8(FRB-hNCF}Wv?1X~z%c=sgs1`8rW+R$o-K{1pKPdZJkrlW;7UQ? zPZNRHvZDb^=z%|4b^+(&EAaa9f;SB}8N>1e9-!c~9LISt-L_DHdtc!7( zTg0RN9{A^{iVkeqE-{I{QkGlA^W))P6mY^$+X0`ZuNctlBWb(%c?M3|vDDCZ-gBHz r-U$P1XSR%&fP4RVv3;hu;^+B49u4DO8$4x<00000NkvXXu0mjfl&#VR literal 0 HcmV?d00001 diff --git a/Items/Accessories/Wings/WingsofRebirth_Wings.png b/Items/Accessories/Wings/WingsofRebirth_Wings.png new file mode 100644 index 0000000000000000000000000000000000000000..08ddcaa27ae16f1906d6523bab897357e380ccc2 GIT binary patch literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^VL<$YgAGWQIS6I~sVq+y$B>FSZx0$W0(plPeD%-e ir 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 toXC+IW?$*>r@+4tVS-b@xZ@+(), 10); // Equipment - itemLoot.Add(ModContent.ItemType()); + itemLoot.Add(ModContent.ItemType()); itemLoot.Add(ModContent.ItemType()); itemLoot.AddRevBagAccessories(); diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.Wings.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.Wings.hjson index 30755075f9..5b2ee4f7ba 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.Wings.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.Wings.hjson @@ -10,15 +10,15 @@ AureateBooster: { ''' } -DrewsWings: { - DisplayName: Drew's Wings +WingsofRebirth: { + DisplayName: Wings of Rebirth Tooltip: ''' Horizontal speed: 11.50 Acceleration multiplier: 2.9 Excellent vertical speed - Flight time: 361 - 'Absolutely Fabulous' + Flight time: 360 + 'Resplendent to the very end' ''' } diff --git a/NPCs/Yharon/Yharon.cs b/NPCs/Yharon/Yharon.cs index 400fdceecb..f1ca77510d 100644 --- a/NPCs/Yharon/Yharon.cs +++ b/NPCs/Yharon/Yharon.cs @@ -3001,7 +3001,7 @@ public override void ModifyNPCLoot(NPCLoot npcLoot) // Equipment normalOnly.Add(DropHelper.PerPlayer(ModContent.ItemType())); - normalOnly.Add(DropHelper.PerPlayer(ModContent.ItemType())); + normalOnly.Add(DropHelper.PerPlayer(ModContent.ItemType())); } // Trophy (always directly from boss, never in bag) From af2a977101e0dedb21bb89e8734feeb9528426e4 Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Wed, 28 May 2025 12:46:29 -0700 Subject: [PATCH 259/401] Wings of Rebirth sprites --- CalPlayer/DrawLayers/WingsofRebirthLayer.cs | 3 +-- Items/Accessories/Wings/WingsofRebirth.cs | 21 ++++++++++++------ Items/Accessories/Wings/WingsofRebirth.png | Bin 1021 -> 2237 bytes .../Wings/WingsofRebirth_Wings_Real.png | Bin 6927 -> 8917 bytes 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/CalPlayer/DrawLayers/WingsofRebirthLayer.cs b/CalPlayer/DrawLayers/WingsofRebirthLayer.cs index 0602843e13..7b58f8fbd3 100644 --- a/CalPlayer/DrawLayers/WingsofRebirthLayer.cs +++ b/CalPlayer/DrawLayers/WingsofRebirthLayer.cs @@ -28,13 +28,12 @@ protected override void Draw(ref PlayerDrawSet drawInfo) if (drawPlayer.dead) return; - Texture2D texture = yharwingTexture.Value; Vector2 Position = drawInfo.Position; Vector2 pos = new Vector2((int)(Position.X - Main.screenPosition.X + (drawPlayer.width / 2) - (2 * drawPlayer.direction)), (int)(Position.Y - Main.screenPosition.Y + (drawPlayer.height / 2) - 2f * drawPlayer.gravDir)); Color lightColor = Lighting.GetColor((int)drawPlayer.Center.X / 16, (int)drawPlayer.Center.Y / 16, Color.White); Color color = lightColor * (1 - drawInfo.shadow); - DrawData d = new DrawData(texture, pos, texture.Frame(1, 8, 0, drawInfo.drawPlayer.wingFrame), drawInfo.colorArmorBody, 0f, new Vector2(texture.Width / 2, texture.Height / 16), 1f, drawInfo.playerEffect, 0); + DrawData d = new DrawData(texture, pos, texture.Frame(1, 9, 0, drawInfo.drawPlayer.wingFrame), color, 0f, new Vector2(texture.Width / 2, texture.Height / 18), 1f, drawInfo.playerEffect, 0); d.shader = drawInfo.drawPlayer.cWings; drawInfo.DrawDataCache.Add(d); } diff --git a/Items/Accessories/Wings/WingsofRebirth.cs b/Items/Accessories/Wings/WingsofRebirth.cs index 56ff361ccd..cbce428ecc 100644 --- a/Items/Accessories/Wings/WingsofRebirth.cs +++ b/Items/Accessories/Wings/WingsofRebirth.cs @@ -55,14 +55,21 @@ public override bool WingUpdate(Player player, bool inUse) { if (player.controlJump && player.wingTime > 0 && player.velocity.Y != 0) { - int frameRate = 5; - int maxFrames = 8; + int frameRate = 5; // FPS + int maxFrames = 9; // Total frames player.wingFrameCounter++; - if (player.wingFrameCounter >= frameRate * (maxFrames - 1)) + // Start flight animation with frame 7 + if (player.wingFrame == 0) + { + player.wingFrame = 7; + } + // Reset frames + if (player.wingFrame >= maxFrames) { player.wingFrameCounter = 0; - player.wingFrame = 0; + player.wingFrame = 1; } + // Animation if (player.wingFrameCounter % frameRate == 0) { player.wingFrame++; @@ -71,12 +78,12 @@ public override bool WingUpdate(Player player, bool inUse) else { player.wingFrameCounter = 0; - player.wingFrame = 0; + player.wingFrame = 0; // On ground if (player.velocity.Y != 0) { - player.wingFrame = 1; + player.wingFrame = 2; // Falling if (player.controlJump && player.velocity.Y > 0) - player.wingFrame = 7; + player.wingFrame = 1; // Gliding } } return true; diff --git a/Items/Accessories/Wings/WingsofRebirth.png b/Items/Accessories/Wings/WingsofRebirth.png index 549d22953298f869f6c2941c8438c90ccd62aebe..ee575d23ab74620529be5c319f3ab316e9a63c4c 100644 GIT binary patch delta 2232 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 diff --git a/Items/Accessories/Wings/WingsofRebirth_Wings_Real.png b/Items/Accessories/Wings/WingsofRebirth_Wings_Real.png index c77a1202d36c9bbfed2ecdae8bbdc2127228f487..df66a0fb83e5aec2c3c9778aa5c1448006b306db 100644 GIT binary patch literal 8917 zcmch7XIN8Rmv*QE(xfRxAk>5|22?=lkU}V-Nf)IB1Qh~;i1aEogcdp^p$RBPIwB~d z@u3}1e1bGVAShBTpvYuqe$M;jo#&eGJJ)s2+I5{Dd#%0ib+4UnYi-HLBf$d#f%p(` zGYnHwK_E_PE;eRq!fd;ZDOkcVmL{NJ`rAWYBPlM!d(= zYtTXf=uI6{3&`uwkP=gf;V{jAOnIpJw!d=2ZApXJsd|5;x$T$!Pe1I@B zc8K)cC{K_0h!o;*$r|yyX>)Ycnr+fS6FPOBiaV(8zLjkpAiwwOfl7nFihpdSAj;C4 z0Z}`hOs;*16DiCd1ne&B@%(#@9mS5Mp$Uln9nU^ZWL0YFf$a&^>emkh4h?OypiSDjZ zELn?p|7c3|;Ynnxo4G0M#`G=jq6BR~;p1%&TW2KRQ;m@DY%I2!kS~ZO*N`WpmFcv# zyJ&NV6P)dC-8p+#t3}L827v3|9gzbAx}JYm=w_OT1NVpC9Os*TbDY*B>YDV13_F>Z zxa9Pcx0W4Cm@qG!E;@;Yf+wwYFq|6e&OO_81dHgtx$A@!P0iL;$O+Ii-5uH1q8Ez# zkvHd1)#=&qB+KV+=GLP=f^ogbLx%VFRSz#5eJh|?C)QfHeSF>V5)i#;{n9Ak;jh=0 z%Id-I0zBH#m%D3<_WX9gThv-s<))>zKjF?>o{>9!iS-k6esIUDzP?~xoI1Xs6EgvL ztts|38-?}6MB6J@NE#F>#59-lODE$=)1PNUy3Fo8eqBBAoc&K*L>v0c560FBh&i#e z;qcGR_ZzyB)I6tvfGvWl!rw~YMHyQI1o^`snm{TWOWW*vo(ca69JuRV+q{e_u*e2Q z9UPtxCSLUU7I!+_L_W&%OhtqXP$x_$$z;vnYfb&aBZPHU?w31lP>d%X{kbSTuR682 z5%H@J$T^1JSBmQkoF*>a>X$+Fs9`bNhlh~{<#0IF<^I<@Sw4OC=D}t7tw-|>XocA?{ugHX?;G$x9=TUrHioTMF1(ky8?}auo5YXWKd4Xz8i|V>@6K;N zWc;X8EPulC?YEBAqgL`gtpVSPpIw^v`61Mj#;A_`PMSFB^qrdqfqG%fzm%5uNaU=Y z#jS1d#@oh;uNsDxm19|<^XWG$-H4P82_=rX&HW2w{uvc%Z`Yey7k_=4xN){LShp-( zw-#n{#GP8{e5b!IC^+mON%QYbM=NX(xl@2nkaWn)9)4mscRhP}|89qVd5YDS-@QOU z#}N6A5VW4XcZ$L;t?1wOeQaH1f^>?6x%GZwuY_#;5g$z87!je1_`IR_`fXGWCWR)d zaN-P9L@&hB- z$WlEg;;U=uW6QYu?VeV&w*(0>|4oA7-N9m?Cx+=y(!PGdh%57fdU(~cjoyGV4?p6u z$E+j${e3KA^`%YvPrHGth6$xpTtW$K4zEgWrs+78uG=5FV$#P zq?EDfcH#HWszuN0+I7kIxOfW$uay#eCxo}T$pyHw10i5F(hTI1%=JbA+}PXyw9z)E zRvk;oqnxe#@^&r#CjqFjyCH=6n3Tq9w%!#~?NV!W(Hq|*PGIqdYKlF-uZBjsE)%Aj zK}9zWkR{n1zUB!Z(WU265#s(#VMC!^dc`e;^!r z!Jc6>#rdRnd}IUcpZK*{QHby;~dNA6aKj7?;)Jdbb-|qE%SS2qh zCtK)QUo4gTm{M5EWIAGeT&b_P<+pyY(oIV7u}OD|V`6a)Y%Mz8>VL4zZ0*^8y z+Fo6^MI7y#Sv}RUkw;&Kd|P`u;kOgxnOE4(LwVrDh|{#CBqB_^ZX%ss4x~r2KZXt|M0+?nQ+>-G{qP7IR14^{cgk!130xxsz@>3z^`XMNkc;|)V)@G3=*c4<^ zDyu?}7qY)stqA)=f?Q2j)r0%{&VFco%|?y4$PyxMfb6CR9q7DuFNwC%>j2VhmQ{)$ zX{vJv7NrsrhtoG|gAHt>hWIKl5(?HBIRq;{K>-Zy@a%u8ZGhBw1|H<^McTh80;BaX zPU(x#oD*CE$biN)(al~;xhht|f>e@SiL#dDv`e7=L8znbLj>16L*we%H^U#v5QZT! z%E(*`edU@A=TB|f@Y?2`9^CAg@-p>VQwfNeMdY|nZ6>UP)o6QmdO8S8h4#3~Tq?$p z9RKhKn~{iQ$F*Wm7k`e|#>+|viC`c%w!+!IZpJlS3w8$*@Fp|EcFu9s$ zP+m7D`gIq6<;f)+I}J~HT^kKPuQ1X!XqLnGzE!uysQc1Q5hSx+Ui59=admlKyw#|v z$mj!s)A4wc;`h3QmsaOMyn76vsl3Yv85KZPXg1Qw_Da>8`6qkl6_MsxAn=1x`Gu3u z(AQI9fUD*)uiykFKAz*)b9|n)4T|-*WzvPnidI)-n^vsB_=ulV)-smWW>^y3IH?Py z6OpSs4dC<{OArFIya$KRU9gp)pmhpc#Em6>Rz3owU4`VZ;e012{tVYH64dx!shpV1 zh_zqF@m7%Bep= zh1Qz_RoKUp!IunME|wnBND4M;vjMwZr#0r!mR@|iX~Uf9T56MHGx`^ysJ<>I5n@bi zSO`nk@))c&)B}WMthoW)8F&+yG?2r=Mc(XmKpFC|;EhWek7c-X|ISQbKd;h!%IpG= zl+4P8Etoo#CKY60hh!-l>N+~nue3+B?B_2jq4$ZC(B7~p40d_y3pnO{Zia}sf@pu~ zg5t?BAItKeB(o`9TPjvx;L7H@29+>6sf)BVmC zhKd90uJGp%n%fLj5Mgev$%BQcaO-Qf3AlF@syv;yn2T5GTAy7HH^_P?`F`9XU_pv zF>j~^*bcFzY$aDKRZja9+&d>M!-5F%Hu)LEbOkdrgJuaUC=jq34`l;Wv0J%4nrQqV z*K_Bbw&0Snk? z1hVFvO(7|-IyD&!1h9rr;VlXHLP%mCyvXnh*;(Kwht&>WW0#hbMY~+CdT`B+c)xmq zB^LYk3N3GxZg6?b*V{4fBqO4>E&<>=QYQ8)6D&&2{sIWkOfSXv(MWy0~2@)~@cmz42I4d%5J`IQ_lEPR#2?*m(jj&AZ)^9BGb~P|`MaF6QX0Y&3 zk0iq?<{6xz+^m#iVN;!FkB@zs>!;mPFK{Y-hlDUSBCc3N5x1{0G+iMwX=m&+H1S#3D7JJj|`$dqeC%h zDP!-J2#qjmP9~4a&niR0eiMM;Pf`*^8D7)8WGk$Z3mYamg?vK`cs-RYEa$~B?4;pF z6kLqWuCX>~MqcjrTb>-c@=t@=f3QvbtEgFn7aDn;!Tip9Gc;_a!0Hh%f!QkRb=NQO z3&4`d*Xmy6e-|Il|4@&1&)AD3*N?6~XO64kW&F5}8iso*kL99_x^p790TI0Q{d6!O zvi)Q)xMebz#V>lKwx|l#u^00cS!q2YL7S=@N?pLK$J~Fu*fy|)nkl*^t}<^L2k-7- z&MxAU9x#@NIC6f=L4~nhVMI&u7h&+D4e)xYoNp<|&X;$--`&Tx?dkj`OalZ}$LW?& z!{l$E0iZ+HHv}~)*k<*Rgf>io4V|+Q#lC$`P#nP&Iz1kqHl(lRB}n-*+}x4*cZcP@ z%1STJwX&^A2Y%_ijEW_zj}&2m6CTz4Q5~PF<*k5yHkCEex>QrFr#u5?D0i{+)6&5#-P+C7(5KL8`ldl!NXJrm-(1MpswK() z@rZ?Gg>~=IbEO-s07QO-KKpga6qr%>{d;|OGhxTCc4^Hsd-$tjAVs}dwv#|ftgd#` zxUG+fZACB25TM7Cv`XHfPCYNOr1*adOM( zt0=%);H)E72hrnkc55oG5>~TqDzQPidwVxu{y3rI;d;zMowm1elmSo230VUnYf-$+z2$MgZXiIu`Ph}aWKKPt;01$rw~WEY z<$hBBEpnzt5MqehR&yyzla{9hfh%;261zuMHi93!s6kBoT@m%)k@ad78O7RVWH+Sp z<`9mI-3!?1Y>q-)}6XcsbP^jof3z6;o*Sdi_eFREv9*m{Nx{Ti}qX^&%O1Eyf#E_+^sFRSj!$POu zY(ub|sHV4{gY54X9R>{(ElPeI_^_35K51k*>3TKpM{N5eiw_??XvnGkJbrdL;ml_db?_};W z582TMuGQTc$dhA9!WSRF6X zMb$17B0;xoZXZe-PuQmH&G$>3A`A4JK!N_8f52q@A36U&YlZ4rxF|$E;cvj?lEaL6skm<(Lo-5tKm!xja0d= z$gt29cfPFGCjjy-kanovn*pu`7D3VQ+$5FR!-InzlZGYg1i;5;^Z4@b{n`atjywt^ z#?88$>$6U?v{@7YIof~zuyT-zg;|%IsGcY9ZvnGjQAjLLQH_;E<7>C(sWtM5=$haA z+nFG!9Z_!XS6>EMSXNUrU_QTM%<+z1@H#pj7+%`9l2AFJ7!!1}aV12zRI@{Z(k!-*DGN z`;bmRgIg!MepOIhOx73C?|j#xZ0rr0poms!al+QIm)p7#XX2?1Cw&o>WAOYm12b8p zfStBI-#FQ<>(&zYgzOpVVN0%cBs$uZ!rpU;5x0Ne$MdnRhb)?k8`{DWb{=^}|yx zC5w1Mo`qOB6V!KkoR{Vn)W`xo+LO<93iuMin{2Bj`nK;w{=Hab_}Z7Z%isDLDhSsG zc;I$XfpNo6N4->GIy-?ZV~Vbj=$+;FH4E4yl}G$aI%MpHzqmX4$>qSGbXO1jS1xyF z7n3IhzrP-Wn9OUM?ATk9&Ell}UWVOeLIZ21ji1~(FSCbx&wVVs$4juOQ;UbuB(xt9 zn5w|Smbsbu6;8F_FIE=-ArRCb8xp#&Jkbj9G)yAEgMtf@)V(nnS{iJk7y2f7{NC7i zx16guEBO%)61p5}?&@XJ@xXzd)1()5ASOl5y{b8an@qIaG=1h>wiYT-w8Oxy=bkF}FD2xT=v;$NTz z?3o8wYz-_mFK5zyFTjN zbNiSSu%ey@)Y+Azz#*d|DJa!MyXBPYm50^tSlZ9rGT4dUo(4xY+7t95w51$J?6fHyo`q?3`g%|LcH2VB(nXE`FFh~&NL!5&%P@T~y1ZUKVcCF%J&QZ2ty z@PQfmNU=HlQt%q01Q7XH^>mN zT3!Y$x`T>v>X!D&lcqCuWND)-X#O<^PZn!m+|p2N9-RYXY}2(w!%3HMwap;A_-lhE z%UTTrUlHj5;WwBMx(;u^g>baBcMFoZbCz!PQP{Ns(_?kMNMQ*D`SlBCFsn}jSlUCo z1-A|#cR{u~T!JS7f;Q$BmG}z~Ay5YFPk1JCkx5-@8fk)$a5CS2<>a8So)hnSzIzLF zpEU8gwEDg2Ql~N*DNo|J$dYdRaJSh>O7z+^21`7EQ6m%p+!`{>a1-$jvs^-R(U{XEFHEz zWZ2RQM+d52qO0+`Qv+uz+L+5aHE!{k@nG1o9hV=0q*>f?_eIGU<=fC*rDagUve@c( z*7s|#F;Fk9`#Jx;bkzUdA#Tn9tgy$eOe&lXa-`I@HhFjIt4LK;%-g-?G^85}c=su@+M|X_;66^((TUo5 zFj^)S2zU7YTKI)PH4MumrZwA0_%_+Joxehc&AbFO5U%-g$P(^0I}2CEMp6{CT))^# z&yI-;{g9z(88zRe{q2brR)r|&$nxgH%UX87LofIM{TLE=)~+~~T&N;*Ey~lDGETVYCYbqhGi>c5DIER$MW|Yk=bA%I||19p{nPdnl^nTZ50j1nFw-p#v{5BSjU74Axqj4;^6d+V_d0B zcAxv4BwDO8BC5Cn8Fsv9rlIUitjJ9tS%Dmt&tOG*S2PnahjhE|$S7>=XxSIMoBB!u ze}tS{-0q|j^}@fc2abEH{jtmckp!sp8lT`#Z~7p?k>5?KwoR@47DX;b(%;8Jk!P3v z&)>PEYBuVR$WKeVolof%0)!~_qP~I_HZPd0T8WS##9l1@>Lm#kL|+q(&MwA%z7)Er z#>c}ax@%l4Ll|Sy1~b9VSRR&!+;cc9Q?)#JVZF+EVpghoOL+6-EJqT4d=`}=Ull6b@g|7>XH z`ZgVkk}rF1h8BB+wfBd(1u{16mg+P=|45eedP?3r^W_blJ!RM)xe5~37>R>K+BV^NO=yiJm~oUN8>Mp45)bss`N6D*+yqRGDaAJjL>1Z`WWXnREYpM6zd#5t9< z_9xIgxe*OlR6>>L{sJ@!+c_f?HdUISP@W8pNJufVVkXSnpjBLX-ZVu-hw$-Woc3Dv z>w8ab@C9)UV=&z7`QNH|8DT2k=CAn=$Az#>s67nPu>F%_0q?r{WOY#IPtnggi>u^?d+18~jBe zJ4$hI2^Q>|Xa*q@w~RIlsZ`_WIsqL9N}3r*S}A2~DWV~0+mT6NIohSC!hD}h-} zUp>fulQ3O49g(ulm7b15UHfU)?ln-_H&*UQa?Yp zvT+@8cXQ!*n(NtYyYlY-PRlEy^S})PSQS;Y!S(s$`K3>DIa)ec9kVW}Do)B8il~X! z|6|S_?h_)aY3{n1YnpyLd*VWmHQz-YEUPgsZ6{m1GNh=baYPjuR?T&Ko~HY2BcgYu z#v9v_T3i8(4cyzQLY$naD-&X=Ng^2=NQp?`RC$GIg`7+mY=~&t>q?_OlIQyRV}0es zyC$l77EGD++P-S*8YSy=^?QxgMMpBYAju%`F-&poiGl~FEw(HB?!L;Gdbt}Orfd|* zi1V@{;&W4~kzA+-Y4<|U88pLPqr#$f?BoZ|;D#R;mY6BQ0i(D~#VlQPIr)ZhT&6M~ zdm8!1#FL)Gl6$MAPhsVeu2S5n`D@o1_Xx6w^UwZqeml~H(I0yxkP?0B^a=`|%)A-` NLYP~dwU}H<_z$r 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 toXC+IW?$*>r@+4tVS-b@xZ@+ Date: Wed, 28 May 2025 15:57:44 -0700 Subject: [PATCH 260/401] removed stink potion sell for consistency --- NPCs/CalamityGlobalTownNPC.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/NPCs/CalamityGlobalTownNPC.cs b/NPCs/CalamityGlobalTownNPC.cs index a0346d5c60..0146ad38ef 100644 --- a/NPCs/CalamityGlobalTownNPC.cs +++ b/NPCs/CalamityGlobalTownNPC.cs @@ -1134,8 +1134,7 @@ public override void ModifyShop(NPCShop shop) if (type == NPCID.GoblinTinkerer) { - shop.AddWithCustomValue(ItemID.StinkPotion, Item.buyPrice(silver: 25), potionSells, Condition.HappyEnoughToSellPylons) - .Add(ItemType()) + shop.Add(ItemType()) .AddWithCustomValue(ItemID.Spaghetti, Item.buyPrice(gold: 5), Condition.HappyEnoughToSellPylons, Condition.DownedSkeletron); } From 5f256bf4639b33baf04484f475dfc8b46c68b996 Mon Sep 17 00:00:00 2001 From: Lucille Karma <51094361+LucilleKarma@users.noreply.github.com> Date: Wed, 28 May 2025 18:20:11 -0500 Subject: [PATCH 261/401] Sylvestaff (#89) Replacement for Fabstaff --- Effects/CalamityShaders.cs | 20 +- Effects/SylvestaffProjectileShader.fx | 76 +++++ Effects/SylvestaffProjectileShader.xnb | Bin 0 -> 2832 bytes Effects/SylvestaffRibbonShader.fx | 89 ++++++ Effects/SylvestaffRibbonShader.xnb | Bin 0 -> 2608 bytes ExtraTextures/BloomCirclePinpoint.png | Bin 0 -> 12442 bytes ...abstaffStreak.png => SylvestaffStreak.png} | Bin .../Primitives/IPixelatedPrimitiveRenderer.cs | 2 +- .../Primitives/PixelationPrimitiveLayer.cs | 12 +- .../Primitives/PrimitivePixelationSystem.cs | 56 ++-- Items/CalamityGlobalItemTooltip.cs | 8 +- Items/Weapons/Magic/Fabstaff.cs | 54 ---- Items/Weapons/Magic/Fabstaff.png | Bin 1665 -> 0 bytes Items/Weapons/Magic/Sylvestaff.cs | 115 ++++++++ Items/Weapons/Magic/SylvestaffGold.png | Bin 0 -> 1188 bytes Items/Weapons/Magic/SylvestaffPlatinum.png | Bin 0 -> 1206 bytes ...Mods.CalamityMod.Items.Weapons.Magic.hjson | 14 +- .../Mods.CalamityMod.Projectiles.Magic.hjson | 4 +- Physics/Rope.cs | 229 +++++++++++++++ Physics/RopeHandle.cs | 73 +++++ Physics/RopeManagerSystem.cs | 132 +++++++++ Physics/RopeSegment.cs | 30 ++ Physics/RopeSettings.cs | 11 + .../DraedonsArsenal/SnakeEyesProjectile.cs | 2 +- Projectiles/Magic/ArtAttackStar.cs | 2 +- Projectiles/Magic/FabBolt.cs | 109 -------- Projectiles/Magic/FabRay.cs | 116 -------- Projectiles/Magic/SylvBolt.cs | 155 +++++++++++ Projectiles/Magic/SylvRay.cs | 217 +++++++++++++++ Projectiles/Magic/SylvestaffHoldout.cs | 262 ++++++++++++++++++ Projectiles/Melee/GayBeam.cs | 2 +- Projectiles/Melee/ViolenceThrownProjectile.cs | 2 +- Projectiles/Ranged/ElysianArrowRain.cs | 2 +- Projectiles/Ranged/ScorpioLargeRocket.cs | 2 +- Projectiles/Ranged/ScorpioRocket.cs | 2 +- Projectiles/Ranged/TelluricGlareArrow.cs | 2 +- Projectiles/Summon/LiliesOfEternityBullet.cs | 6 +- Projectiles/Summon/LiliesOfFinalityBullet.cs | 4 +- Sounds/Item/SylvestaffFire1.ogg | Bin 0 -> 22126 bytes Sounds/Item/SylvestaffFire2.ogg | Bin 0 -> 26358 bytes Sounds/Item/SylvestaffFire3.ogg | Bin 0 -> 23736 bytes Sounds/Item/SylvestaffProjectileBounce1.ogg | Bin 0 -> 26223 bytes Sounds/Item/SylvestaffProjectileBounce2.ogg | Bin 0 -> 24996 bytes Sounds/Item/SylvestaffProjectileBounce3.ogg | Bin 0 -> 32705 bytes Utilities/MathematicalUtils.cs | 30 ++ 45 files changed, 1505 insertions(+), 335 deletions(-) create mode 100644 Effects/SylvestaffProjectileShader.fx create mode 100644 Effects/SylvestaffProjectileShader.xnb create mode 100644 Effects/SylvestaffRibbonShader.fx create mode 100644 Effects/SylvestaffRibbonShader.xnb create mode 100644 ExtraTextures/BloomCirclePinpoint.png rename ExtraTextures/Trails/{FabstaffStreak.png => SylvestaffStreak.png} (100%) delete mode 100644 Items/Weapons/Magic/Fabstaff.cs delete mode 100644 Items/Weapons/Magic/Fabstaff.png create mode 100644 Items/Weapons/Magic/Sylvestaff.cs create mode 100644 Items/Weapons/Magic/SylvestaffGold.png create mode 100644 Items/Weapons/Magic/SylvestaffPlatinum.png create mode 100644 Physics/Rope.cs create mode 100644 Physics/RopeHandle.cs create mode 100644 Physics/RopeManagerSystem.cs create mode 100644 Physics/RopeSegment.cs create mode 100644 Physics/RopeSettings.cs delete mode 100644 Projectiles/Magic/FabBolt.cs delete mode 100644 Projectiles/Magic/FabRay.cs create mode 100644 Projectiles/Magic/SylvBolt.cs create mode 100644 Projectiles/Magic/SylvRay.cs create mode 100644 Projectiles/Magic/SylvestaffHoldout.cs create mode 100644 Sounds/Item/SylvestaffFire1.ogg create mode 100644 Sounds/Item/SylvestaffFire2.ogg create mode 100644 Sounds/Item/SylvestaffFire3.ogg create mode 100644 Sounds/Item/SylvestaffProjectileBounce1.ogg create mode 100644 Sounds/Item/SylvestaffProjectileBounce2.ogg create mode 100644 Sounds/Item/SylvestaffProjectileBounce3.ogg diff --git a/Effects/CalamityShaders.cs b/Effects/CalamityShaders.cs index c98734482d..dee18c09b3 100644 --- a/Effects/CalamityShaders.cs +++ b/Effects/CalamityShaders.cs @@ -17,9 +17,9 @@ public class CalamityShaders internal static Effect AstralFogShader; // - // All below shaders created by Dominic Karma + // All below shaders created by Lucille Karma // - #region Dominic's Shaders + #region Lucille's Shaders // The Dance of Light's Blinding Light internal static Effect DanceOfLightBlindingShader; @@ -90,7 +90,7 @@ public class CalamityShaders // Used by Dom's Bladecrest Oathsword. Appears to govern the swing animation. internal static Effect LocalLinearTransformationShader; - // UNUSED -- Probably leftover from Dominic's experiments with applying shaders to primitives (arbitrary GPU-rendered triangles) + // UNUSED -- Probably leftover from Lucille's experiments with applying shaders to primitives (arbitrary GPU-rendered triangles) internal static Effect BasicPrimitiveShader; // Artemis Ohio Beam. Also used by get fixed boi Nuclear Terror's "G-FUEL BEAM" @@ -137,6 +137,12 @@ public class CalamityShaders // Used to render the results of Navier-Stokes fluid simulations. internal static Effect FluidShaders; + + // Used by projectiles fired by the Sylvestaff. + internal static Effect SylvestaffProjectileShader; + + // Used by the ribbons on the Sylvestaff. + internal static Effect SylvestaffRibbonShader; #endregion // @@ -243,7 +249,7 @@ public static void LoadShaders() var astralPassReg = new AstralScreenShaderData(new Ref(AstralFogShader), "AstralPass").UseColor(0.18f, 0.08f, 0.24f); RegisterSceneFilter(astralPassReg, "Astral", EffectPriority.VeryHigh); - #region Loading Dominic's Shaders + #region Loading Lucille's Shaders DanceOfLightBlindingShader = LoadShader("LightBurstShader"); RegisterScreenShader(DanceOfLightBlindingShader, "BurstPass", "LightBurst"); @@ -360,6 +366,12 @@ public static void LoadShaders() // This shader is not registered with the game but is invoked directly to render the results of fluid simulation. FluidShaders = LoadShader("FluidShaders"); + + SylvestaffProjectileShader = LoadShader("SylvestaffProjectileShader"); + RegisterMiscShader(SylvestaffProjectileShader, "TrailPass", "SylvestaffProjectile"); + + SylvestaffRibbonShader = LoadShader("SylvestaffRibbonShader"); + RegisterMiscShader(SylvestaffRibbonShader, "AutoloadPass", "SylvestaffRibbon"); #endregion #region Loading Iban's Shaders diff --git a/Effects/SylvestaffProjectileShader.fx b/Effects/SylvestaffProjectileShader.fx new file mode 100644 index 0000000000..728a0f6a9a --- /dev/null +++ b/Effects/SylvestaffProjectileShader.fx @@ -0,0 +1,76 @@ +sampler uImage0 : register(s0); +sampler uImage1 : register(s1); +float3 uColor; +float3 uSecondaryColor; +float uOpacity; +float uSaturation; +float uRotation; +float uTime; +float4 uSourceRect; +float2 uWorldPosition; +float uDirection; +float3 uLightSource; +float2 uImageSize0; +float2 uImageSize1; +matrix uWorldViewProjection; +float4 uShaderSpecificData; + +struct VertexShaderInput +{ + float4 Position : POSITION0; + float4 Color : COLOR0; + float3 TextureCoordinates : TEXCOORD0; +}; + +struct VertexShaderOutput +{ + float4 Position : SV_POSITION; + float4 Color : COLOR0; + float3 TextureCoordinates : TEXCOORD0; +}; + +VertexShaderOutput VertexShaderFunction(in VertexShaderInput input) +{ + VertexShaderOutput output = (VertexShaderOutput) 0; + float4 pos = mul(input.Position, uWorldViewProjection); + output.Position = pos; + + output.Color = input.Color; + output.TextureCoordinates = input.TextureCoordinates; + + return output; +} + +float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 +{ + float4 color = input.Color; + float2 coords = input.TextureCoordinates; + + // Account for texture distortion artifacts. + coords.y = (coords.y - 0.5) / input.TextureCoordinates.z + 0.5; + + float bump = sin(coords.y * 3.141); + + // Calculate the amount of additive glow for this pixel, using a combination of a scrolling texture and an extreme + // exponential squash of the prior 0-1-0 bump, creating a "center" to the glow and ensuring that the + // ray doesn't look like just a scrolling gradient. + float streakColor = tex2D(uImage1, coords + float2(uTime * -2.75, 0)); + float glow = streakColor.r + pow(bump, 20) * 0.4; + + // Determine opacity based on a weaker exponential squash of the bump in order to create faded horizontal edges. + float opacity = pow(bump, 5); + + // Apply glow. + opacity += glow * opacity; + + return color * opacity; +} + +technique Technique1 +{ + pass TrailPass + { + VertexShader = compile vs_2_0 VertexShaderFunction(); + PixelShader = compile ps_2_0 PixelShaderFunction(); + } +} diff --git a/Effects/SylvestaffProjectileShader.xnb b/Effects/SylvestaffProjectileShader.xnb new file mode 100644 index 0000000000000000000000000000000000000000..06bc3ffb44ec19d3e996872bf6184813c527e90a GIT binary patch literal 2832 zcmb_eO>7%Q6n?vL6PKiN#gD`x5{m>(t(zSvzK&93(QnFy3(;-)nixLB7_s^K-tvBGx?rTE6Ht1JMlf=a-j-6D$aO zN%$kyQS7&Td$sO5tr6>z@LR6eoSw*!@@K>7-Dqr-N9wx|5lNAS5P;er=P_Cfx}5&VAUSKSqX zr&{B88khG#gFsSbU0&!rVgctTjlHLlO;9yRIpFYp&u=W1y_Op6^BDi z;jHUp4qkpb&#cB*b*p%Op5VBWd$k@^;v(6ncsI1z!!^e1iqBWY{S;?R#ccoU7z^^z>fRQ z=lXE1ydK`a!+t(*Ro`|SWxLga&HGgqPQB@V9Evd_&c*W|gK}9M|2$O5DHx{}z_SFc zYq$;jYYp$fzNg`bu(R3%hhY~qT!LNK@O9X?H2eeXyBdB7JFD&WFzkYcYp??ie-3+7 z!@IB_Xt;nySGE1vNo=0-`^0AYm&uyi@ZErZmEha3Z)v>5O%X(uy~*Qd6!oGPsaQQX zGYoi2HE{YT*^@La9=+ z_;e5p~YjeHmrL?9GFc)=8yd9@TI@()=18AGTOH;- z6X%gUJqF1!=VIq&&w8`}Q}`2a~e04&FB{Zro}&M`4g6ok oXK9yv2JJ{}#@I-4CdOupvoYp9kNZqHyvmcF)4(6#ZE%= feelerColorStart); + + // Band 2: Pink. + float pinkStart = feelerColorStart + colorSpacingFactor * 0.01; + color = lerp(color, float4(221, 150, 179, 255) / 255, coords.x >= pinkStart); + + // Band 3: Outline color. + float outlineAStart = pinkStart + colorSpacingFactor * 0.04; + color = lerp(color, outlineColor, coords.x >= outlineAStart); + + // Band 4: Blue. + float blueStart = outlineAStart + colorSpacingFactor * 0.01; + color = lerp(color, float4(48, 117, 222, 255) / 255, coords.x >= blueStart); + + // Band 5: Baby blue. + float babyBlueStart = blueStart + colorSpacingFactor * 0.04; + color = lerp(color, float4(167, 222, 255, 255) / 255, coords.x >= babyBlueStart); + + // Add an outline to the ends of the feeler. + float horizontalDistanceFromCenter = distance(coords.y, 0.5); + color = lerp(color, outlineColor, horizontalDistanceFromCenter >= 0.3); + color = lerp(color, outlineColor, erasePixelInterpolant >= -0.02); + + float permittedDirection = sign(uSaturation); + float direction = sign(dot(input.Position.xy - uShaderSpecificData.xy, uShaderSpecificData.zw)); + erasePixelInterpolant *= direction == permittedDirection || coords.x < 0.5; + + return color * (erasePixelInterpolant < 0) * input.Color; +} + +technique Technique1 +{ + pass AutoloadPass + { + VertexShader = compile vs_3_0 VertexShaderFunction(); + PixelShader = compile ps_3_0 PixelShaderFunction(); + } +} diff --git a/Effects/SylvestaffRibbonShader.xnb b/Effects/SylvestaffRibbonShader.xnb new file mode 100644 index 0000000000000000000000000000000000000000..d6848767d447ca2049dba6c5e5ef1b96d7e2489c GIT binary patch literal 2608 zcmb_eO>7%g5T0E-vD*e>DnJ}6VGb2RiYzxjD3M6q)M;piK_PZp3jxvASu0CiuUW52 zKtkF|Jya?O0}`ZMaKwSiIZ~BNg+bz&iX)d&f)p-A3OOOTc=_h-zV)^W917z+znOX8 z{JtNj_{yoZJ|%saNcm8C*(h0N-7MRwVpU7cS=vQ?&9qiiS+i>ERXcUMT-HnWg03y= z)^PHl&@WnAZN(_nhm+@Yt8SRpsj*a=Kf}pvqhdEKeX6QAY)h*QC+8a%Dn{ug{oR7O zs#m8b#zsozi3|FPWqmw7K0ZoJ%9TSzKOEV=l@Ox$r5tj**An78hH(2grUIm z`u7rynRAqJLTY*(LLPw?b zX$tOEa%kbX^NL!W>$=B- ze3#&zbwR!gC0~awobL;ex%c7o%e$nA4;Bs}d;MW@96*lwv*Fqw;7ANs9Rl*3$CMOC2w<4cjv@&qsubF`nO^ zUDz*U`xyvgUiy@?LMK}iFMTmqt~1a6dF+D*L9R>mDpF8sumyFeTrPM17&_KD-v3O8 z^%3ZAZ*Nas|MJ<)&v)NMKb#EfqtM^|>5a^%pFEkl@zrRc?}Ps9n>VL_-QAu3eQ$4C z;`^ch?%R{ozumhx9rhE0{+IX0I*HJZS{0*CkmZHyTDTf zJ#b<|?%6>v>=+~MRQT%m?RvVl6A>{z9MXeN*NIcR6-P|$8(c+^Z@YOEj7kb}YC~S+ zoHsc>uVcQ{ljDrJigVk-p5af}Tm^8Gke7^2h{LtXI@k}d$7%7tS|tX3i*QdEPqgdz zYykZ1CM9N@=$ooiROJ4eh#SS)9*>raoH;I$$nBD>&(krk&32opIjD*AW4)}=tD81M zHXm@0*q4VzJ1P% z(D9Odk2k=}_YK9;84ScZ`1fvWYb%13qWG|n|AXFn$Tytt1>!sMj_`fKUI+IDXS{b` zXmE$|K1T59E%qt4gMXK}$2)vJFj}6h3K{3dm!m>f1350_h&YR+BJK{b{&|Y+0N3Q5 F_!|vCw;=!k literal 0 HcmV?d00001 diff --git a/ExtraTextures/BloomCirclePinpoint.png b/ExtraTextures/BloomCirclePinpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..49c2dcdb606652d535d35033dc09712a958bdeb8 GIT binary patch literal 12442 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 /// Render primitives that use pixelation here. /// - void RenderPixelatedPrimitives(SpriteBatch spriteBatch); + void RenderPixelatedPrimitives(SpriteBatch spriteBatch, PixelationPrimitiveLayer layer); } } diff --git a/Graphics/Primitives/PixelationPrimitiveLayer.cs b/Graphics/Primitives/PixelationPrimitiveLayer.cs index 1ed0348bc8..4f05c51ef2 100644 --- a/Graphics/Primitives/PixelationPrimitiveLayer.cs +++ b/Graphics/Primitives/PixelationPrimitiveLayer.cs @@ -1,15 +1,17 @@ -using Microsoft.Xna.Framework.Graphics; +using System; namespace CalamityMod.Graphics.Primitives { /// /// Controls what layer the renders to. /// + [Flags] public enum PixelationPrimitiveLayer { - BeforeNPCs, - AfterNPCs, - BeforeProjectiles, - AfterProjectiles + BeforeNPCs = 1, + AfterNPCs = 2, + BeforeProjectiles = 4, + AfterProjectiles = 8, + AfterPlayers = 16 } } diff --git a/Graphics/Primitives/PrimitivePixelationSystem.cs b/Graphics/Primitives/PrimitivePixelationSystem.cs index 19d5fb1b5c..4d2bc635de 100644 --- a/Graphics/Primitives/PrimitivePixelationSystem.cs +++ b/Graphics/Primitives/PrimitivePixelationSystem.cs @@ -18,6 +18,8 @@ public class PrimitivePixelationSystem : ModSystem private static ManagedRenderTarget PixelationTarget_AfterProjectiles; + private static ManagedRenderTarget PixelationTarget_AfterPlayers; + private static RenderTarget2D CreatePixelTarget(int width, int height) => new(Main.instance.GraphicsDevice, width / 2, height / 2); /// @@ -36,11 +38,13 @@ public override void Load() On_Main.CheckMonoliths += DrawToTargets; On_Main.DoDraw_DrawNPCsOverTiles += DrawTarget_NPCs; On_Main.DrawProjectiles += DrawTarget_Projectiles; + On_Main.DrawPlayers_AfterProjectiles += DrawTarget_Players; PixelationTarget_BeforeNPCs = new(true, CreatePixelTarget); PixelationTarget_AfterNPCs = new(true, CreatePixelTarget); PixelationTarget_BeforeProjectiles = new(true, CreatePixelTarget); PixelationTarget_AfterProjectiles = new(true, CreatePixelTarget); + PixelationTarget_AfterPlayers = new(true, CreatePixelTarget); } public override void Unload() @@ -63,6 +67,7 @@ private void DrawToTargets(On_Main.orig_CheckMonoliths orig) var afterNPCs = new List(); var beforeProjectiles = new List(); var afterProjectiles = new List(); + var afterPlayers = new List(); // Check every active projectile. foreach (Projectile projectile in Main.ActiveProjectiles) @@ -70,14 +75,14 @@ private void DrawToTargets(On_Main.orig_CheckMonoliths orig) // If the projectile is active, a mod projectile, and uses the interface, add it to the list of primitives to draw this frame. if (projectile.ModProjectile != null && projectile.ModProjectile is IPixelatedPrimitiveRenderer pixelPrimitiveProjectile) { - var listToUse = pixelPrimitiveProjectile.LayerToRenderTo switch - { - PixelationPrimitiveLayer.BeforeNPCs => beforeNPCs, - PixelationPrimitiveLayer.AfterNPCs => afterNPCs, - PixelationPrimitiveLayer.BeforeProjectiles => beforeProjectiles, - _ => afterProjectiles - }; - listToUse.Add(pixelPrimitiveProjectile); + if (pixelPrimitiveProjectile.LayerToRenderTo.HasFlag(PixelationPrimitiveLayer.BeforeNPCs)) + beforeNPCs.Add(pixelPrimitiveProjectile); + if (pixelPrimitiveProjectile.LayerToRenderTo.HasFlag(PixelationPrimitiveLayer.AfterNPCs)) + afterNPCs.Add(pixelPrimitiveProjectile); + if (pixelPrimitiveProjectile.LayerToRenderTo.HasFlag(PixelationPrimitiveLayer.BeforeProjectiles)) + beforeProjectiles.Add(pixelPrimitiveProjectile); + if (pixelPrimitiveProjectile.LayerToRenderTo.HasFlag(PixelationPrimitiveLayer.AfterPlayers)) + afterPlayers.Add(pixelPrimitiveProjectile); } } @@ -87,23 +92,24 @@ private void DrawToTargets(On_Main.orig_CheckMonoliths orig) // If the NPC is active, a mod NPC, and uses the interface, add it to the list of primitives to draw this frame. if (npc.ModNPC != null && npc.ModNPC is IPixelatedPrimitiveRenderer pixelPrimitiveNPC) { - var listToUse = pixelPrimitiveNPC.LayerToRenderTo switch - { - PixelationPrimitiveLayer.BeforeNPCs => beforeNPCs, - PixelationPrimitiveLayer.AfterNPCs => afterNPCs, - PixelationPrimitiveLayer.BeforeProjectiles => beforeProjectiles, - _ => afterProjectiles - }; - listToUse.Add(pixelPrimitiveNPC); + if (pixelPrimitiveNPC.LayerToRenderTo.HasFlag(PixelationPrimitiveLayer.BeforeNPCs)) + beforeNPCs.Add(pixelPrimitiveNPC); + if (pixelPrimitiveNPC.LayerToRenderTo.HasFlag(PixelationPrimitiveLayer.AfterNPCs)) + afterNPCs.Add(pixelPrimitiveNPC); + if (pixelPrimitiveNPC.LayerToRenderTo.HasFlag(PixelationPrimitiveLayer.BeforeProjectiles)) + beforeProjectiles.Add(pixelPrimitiveNPC); + if (pixelPrimitiveNPC.LayerToRenderTo.HasFlag(PixelationPrimitiveLayer.AfterPlayers)) + afterPlayers.Add(pixelPrimitiveNPC); } } CurrentlyRendering = true; - DrawPrimsToRenderTarget(PixelationTarget_BeforeNPCs, beforeNPCs); - DrawPrimsToRenderTarget(PixelationTarget_AfterNPCs, afterNPCs); - DrawPrimsToRenderTarget(PixelationTarget_BeforeProjectiles, beforeProjectiles); - DrawPrimsToRenderTarget(PixelationTarget_AfterProjectiles, afterProjectiles); + DrawPrimsToRenderTarget(PixelationTarget_BeforeNPCs, PixelationPrimitiveLayer.BeforeNPCs, beforeNPCs); + DrawPrimsToRenderTarget(PixelationTarget_AfterNPCs, PixelationPrimitiveLayer.AfterNPCs, afterNPCs); + DrawPrimsToRenderTarget(PixelationTarget_BeforeProjectiles, PixelationPrimitiveLayer.BeforeProjectiles, beforeProjectiles); + DrawPrimsToRenderTarget(PixelationTarget_AfterProjectiles, PixelationPrimitiveLayer.AfterProjectiles, afterProjectiles); + DrawPrimsToRenderTarget(PixelationTarget_AfterPlayers, PixelationPrimitiveLayer.AfterPlayers, afterPlayers); Main.instance.GraphicsDevice.SetRenderTarget(null); @@ -111,7 +117,7 @@ private void DrawToTargets(On_Main.orig_CheckMonoliths orig) orig(); } - private static void DrawPrimsToRenderTarget(RenderTarget2D renderTarget, List pixelPrimitives) + private static void DrawPrimsToRenderTarget(RenderTarget2D renderTarget, PixelationPrimitiveLayer layer, List pixelPrimitives) { // Swap to the target regardless, in order to clear any leftover content from last frame. Not doing this results in the final frame lingering once it stops rendering. renderTarget.SwapTo(); @@ -121,7 +127,7 @@ private static void DrawPrimsToRenderTarget(RenderTarget2D renderTarget, List()) - nameLine.OverrideColor = new Color(Main.DiscoR, 100, 255); + if (item.type == ModContent.ItemType()) + nameLine.OverrideColor = new Color(249, 197, 255); if (item.type == ModContent.ItemType()) nameLine.OverrideColor = new Color(0, 0, 255); if (item.type == ModContent.ItemType()) @@ -445,7 +445,7 @@ void AddTooltip(string text) #region Guaranteed Dodge Tooltips string beltDodgeLine = "Grants the ability to dodge attacks\n" + "Attacks that deal less than 5% of your max life in damage will not be dodged\n" + - $"The dodge has a cooldown that ranges between {BalancingConstants.BeltDodgeCooldownMin / 60 } and {BalancingConstants.BeltDodgeCooldownMax / 60} seconds depending on the dodged attack's damage\n" + + $"The dodge has a cooldown that ranges between {BalancingConstants.BeltDodgeCooldownMin / 60} and {BalancingConstants.BeltDodgeCooldownMax / 60} seconds depending on the dodged attack's damage\n" + "The cooldown is shared with all other dodges and reflects"; if (item.type == ItemID.BlackBelt) EditTooltipByNum(0, (line) => line.Text = beltDodgeLine); @@ -620,7 +620,7 @@ void AddTooltip(string text) // Ale and Sake rebalance and Alcohol Poisoning. if (item.type == ItemID.Ale || item.type == ItemID.Sake) { - EditTooltipByNum(0, (line) => line.Text = "Increases melee damage by 10% and reduces defense by 5%\n" + + EditTooltipByNum(0, (line) => line.Text = "Increases melee damage by 10% and reduces defense by 5%\n" + "Counts as an alcohol for Alcohol Poisoning\n" + "Drinking more than 3 different alcohols might not end well with your liver"); } diff --git a/Items/Weapons/Magic/Fabstaff.cs b/Items/Weapons/Magic/Fabstaff.cs deleted file mode 100644 index 72117d510f..0000000000 --- a/Items/Weapons/Magic/Fabstaff.cs +++ /dev/null @@ -1,54 +0,0 @@ -using CalamityMod.Items.Materials; -using CalamityMod.Projectiles.Magic; -using CalamityMod.Rarities; -using CalamityMod.Tiles.Furniture.CraftingStations; -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Items.Weapons.Magic -{ - public class Fabstaff : ModItem, ILocalizedModType - { - public new string LocalizationCategory => "Items.Weapons.Magic"; - public override void SetStaticDefaults() - { - Item.staff[Item.type] = true; - } - - public override void SetDefaults() - { - Item.width = 84; - Item.height = 84; - Item.damage = 125; - Item.DamageType = DamageClass.Magic; - Item.mana = 50; - Item.useTime = 20; - Item.useAnimation = 20; - Item.useStyle = ItemUseStyleID.Shoot; - Item.noMelee = true; - Item.knockBack = 5f; - - Item.value = CalamityGlobalItem.RarityHotPinkBuyPrice; - Item.rare = ModContent.RarityType(); - Item.Calamity().devItem = true; - - Item.UseSound = SoundID.Item60; - Item.autoReuse = true; - Item.shoot = ModContent.ProjectileType(); - Item.shootSpeed = 13.5f; - } - - - public override void AddRecipes() - { - CreateRecipe(). - AddIngredient(ItemID.RainbowRod). - AddIngredient(10). - AddIngredient(5). - AddTile(). - Register(); - } - } -} diff --git a/Items/Weapons/Magic/Fabstaff.png b/Items/Weapons/Magic/Fabstaff.png deleted file mode 100644 index 6658464065a83b668b31095d2d1a96ef775887c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1665 zcmV-{27dX8P)nux%1}!&hMW4J>U2H zd+r@+4e4jc`0jsGZteX1>5&w&6|)#;F%u@M{xv)9SoV_79s6|I=wRp=s%SW%sg$fJ zXPE@l?B4Uhk{Z_@d?fsTZr_=t_;qL)8pGEC6@>PV?@G$ePtKnyk)&H7UzqqH%;c5v z^~1$b2Q>B@jGR{hcTU_MMm#ySCLA|C@pKVy9(gw$-=A3>jxf{;@VV?`_pV!V2Afap zD%s2<^H+w0p$=%5jMU)(`tsC2;nZCdg$?6#cIJBc^W5woC1!G78EQ=rFV1te1B{Gcy!*0IN1Mm7%HAB6Cuk2}6lfSA3@AfTmKSqMVul_39PXwZ&s`>Q{?@ z1=+)s4~3&LRBH&0wV^R5<$xwq$f_ExZ~YxK;PnACQEi8q#;aOKO=TwI@cxZsr~_J; zBE~o?!})RHVi>Xa*@CJ1(KuDllUY5p^=K(>wQOiC?$mi=TN}$zZL&F_HJQuG?_0Ym zXn-lle>hjtxaI!alCE&^`#*ym@|syGLs4pFM6o7dV;SmzCh;X*2qtVFEpqwE`*wz7 ztmnfO$k7iy_?2DnoUF zHKRgr<93cXpqZG78fC(|(Zc#@d`S=K=xe`(^Bc#ulo*QFXO|r|6+T ziyDJrU^dhNjV(===K&a|zV!CpK_j;FZ^;z zMwP}g)B#OoUaDBEEsP%GP-P~}!j>Yh%sX~!b2z08MIPp<4OM+szdv@ree?1TXlyAe zp0|GTE ziBr8%?+im>AYRvECg+hSe!S8u;#MtGTU8<}hp&3OePgIj%mGbYs?_IyV5ZhL$-VV* zcyrC|_5YgTq&^*zczaQ?>@G9qlM0~%YB$obfd0T>=*s9t8!w$i%ozA@B#b;ZyE z8f#HlD`GJv7LTg4vKZRs52WwI+YEI;^I+crsP$~6?m4ph))q6X?zimKdzJFQmXOQG zdOi+l+ER2lB`fZWdD&EEq9<17Tk#C#Mjg;JCPu?1bxN8$(?$Gxv3PTWe)Ng5mCCU0 z;B2)_FYkcXgLcIFi7TK~#@Sm$+}P{)an`%7!Hsf2Gh^QYC_Njiy9h%mcF_Bweu?eO z)#uK9zdcvyfM$lc4Jdlal=u!~m6=v+!+Ng0snwy(c(xqS%!o!arB`Q0!zH!pHaW4X zG!>ruW&fqs1Ij%A#;J2aGcSo*VAjoCcyXAijMRBKLj@5Bv>tUkoDyo-2n#dcnJRW} z@X@Cy*g>puY~AO5>fO%ZM>(LG*Psn3HqUyeobE-B+0bsEnaq5jeN*RvW`?>ADD}?R zn-7$!%txP|xao6w2Q&{=O{au<&B3j9^Uad0$6$9rV+d6|{~s=PkyEQpeft0a002ov LPDHLkV1fVu&vi|T diff --git a/Items/Weapons/Magic/Sylvestaff.cs b/Items/Weapons/Magic/Sylvestaff.cs new file mode 100644 index 0000000000..8ea214fff5 --- /dev/null +++ b/Items/Weapons/Magic/Sylvestaff.cs @@ -0,0 +1,115 @@ +using CalamityMod.Items.Materials; +using CalamityMod.Projectiles.Magic; +using CalamityMod.Rarities; +using CalamityMod.Tiles.Furniture.CraftingStations; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.Audio; +using Terraria.ID; +using Terraria.ModLoader; + +namespace CalamityMod.Items.Weapons.Magic +{ + [LegacyName("Fabstaff")] + public class Sylvestaff : ModItem, ILocalizedModType + { + public new string LocalizationCategory => "Items.Weapons.Magic"; + + /// + /// The amount by which the staff recoils after firing. + /// + public static float StaffRecoilForce => 0.04f; + + /// + /// The rate at which rays from the staff can release bolts. + /// + public static int RayBoltShootRate => CalamityUtils.SecondsToFrames(0.0667f); + + /// + /// The distance range that targets need to be within relative to a ray's evaluation points in order to shoot bolts. + /// + public static float RayBoltTargetingRange => 272f; + + /// + /// The turn speed interpolant that dictates how fast or slow the staff can move to aim towards the mouse. + /// + public static float TurnSpeedInterpolant => 0.276f; + + /// + /// The sound played when Sylvestaff rays are fired. + /// + public static readonly SoundStyle FireSound = new SoundStyle("CalamityMod/Sounds/Item/SylvestaffFire", 3) with { MaxInstances = 5 }; + + /// + /// The sound played when Sylvestaff rays bounce off of tiles. + /// + public static readonly SoundStyle BounceSound = new SoundStyle("CalamityMod/Sounds/Item/SylvestaffProjectileBounce", 3) with { MaxInstances = 5 }; + + public override string Texture + { + get + { + if (WorldGen.SavedOreTiers.Gold == TileID.Gold || Main.gameMenu) + return "CalamityMod/Items/Weapons/Magic/SylvestaffGold"; + + return "CalamityMod/Items/Weapons/Magic/SylvestaffPlatinum"; + } + } + + public override void SetStaticDefaults() + { + Item.staff[Item.type] = true; + } + + public override void SetDefaults() + { + Item.width = 84; + Item.height = 84; + Item.damage = 125; + Item.DamageType = DamageClass.Magic; + Item.mana = 50; + Item.useTime = 20; + Item.useAnimation = 20; + Item.useStyle = ItemUseStyleID.Shoot; + Item.noMelee = true; + Item.channel = true; + Item.noUseGraphic = true; + Item.knockBack = 5f; + + Item.value = CalamityGlobalItem.RarityHotPinkBuyPrice; + Item.rare = ModContent.RarityType(); + Item.Calamity().devItem = true; + + Item.autoReuse = true; + Item.shoot = ModContent.ProjectileType(); + Item.shootSpeed = 13.5f; + } + + public override void AddRecipes() + { + CreateRecipe(). + AddIngredient(ItemID.RainbowRod). + AddIngredient(ItemID.GenderChangePotion). + AddRecipeGroup("AnyGoldBar", 5). + AddIngredient(10). + AddIngredient(5). + AddTile(). + Register(); + } + + public override bool PreDrawInInventory(SpriteBatch spriteBatch, Vector2 position, Rectangle frame, Color drawColor, Color itemColor, Vector2 origin, float scale) + { + Texture2D texture = ModContent.Request(Texture).Value; + spriteBatch.Draw(texture, position, frame, drawColor, 0f, origin, scale, SpriteEffects.None, 0); + return false; + } + + public override bool PreDrawInWorld(SpriteBatch spriteBatch, Color lightColor, Color alphaColor, ref float rotation, ref float scale, int whoAmI) + { + Texture2D texture = ModContent.Request(Texture).Value; + spriteBatch.Draw(texture, Item.position - Main.screenPosition, null, lightColor, 0f, Vector2.Zero, scale, SpriteEffects.None, 0); + return false; + } + } +} diff --git a/Items/Weapons/Magic/SylvestaffGold.png b/Items/Weapons/Magic/SylvestaffGold.png new file mode 100644 index 0000000000000000000000000000000000000000..2cd1d31e3887c626147fbf6745167fb66659188d GIT binary patch literal 1188 zcmeAS@N?(olHy`uVBq!ia0vp^aUjgW3?%3B1jhg=#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6-z0X`wFo^j;?1yfJn{_y|*|7Ay>71nfiPo5jI=*-%E7mr^a>8wsZbCy=sOaxCZ#@k8%Z;kqEa*tM;1uf4=^nwHIp(JOB45 zxHtt~Klx#5_uTWx9vocuY-U;j&_cs**QY>Ar6kBN7-$_Kz!0Is%L`P`S>O>_%)r2R z5QG_bOw4`@6qG1&jVKAuPb(=;EJ|evNX*PD(erZ+Q83jr)HCnC_T3VwW?O26XPT#{ z76S*6!^$AV$jZP7WO)IxG?WbrH4R2)us9QtZOF*PAONJJfHtp3{*- zrD8Sfa_IKk2M=E4e`K+FUfn~zNnZlaKhHb=Uu44Ka+#p&dHFwdY)^Xbjc|Bh@_)BU zN&b#59@~@8i|_L{9aZ93BU5-+Pr=!Kw&UZ-OuOnq!MZFU?r_Y1GJC7NvddMC=HWbd-A3;+2xTh6-o z*~2B8al()e2N{x$G7IiH8JC8f#u1V?LZ35TXI;*m@+Jj0;PPZ+ylzH{5 zVvW|Hsmr(f%C;RcIeXFJ(`CBAqkHl{4Q-p*Dt^W5im)?XiJe73m!YHE^YpRvdlZPsO17dHes|4e^5 zS;e=Ir_SBv@(W|$zlf z|28L{bIa3B=Kufz literal 0 HcmV?d00001 diff --git a/Items/Weapons/Magic/SylvestaffPlatinum.png b/Items/Weapons/Magic/SylvestaffPlatinum.png new file mode 100644 index 0000000000000000000000000000000000000000..c611c58ea1de3c35192a01c09682bb86924e2c4a GIT binary patch literal 1206 zcmeAS@N?(olHy`uVBq!ia0vp^aUjgW3?%3B1jhg=#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;~0X`wFp0Q;C`BP5ZdjJ3b|7C}t7F2h1O_~$4@bsF!7mi-MKlR-|8yBB@ zd;aHDEbCf-^Mv~b-T3;LgpS{9-l%9g=q5Cj8)ugpXI1UEYpNF-W|La&HRVjs&E0D* z)D(35Z+_|Q7;yc>`zc*>&KNU4_u`2_>*B?2%shfTi; z)WTWd5n0T@z;_sg8IR|$NC65;l(KW>pcVGK% z2~@K!HNrE^(^HFq1IS@zkYZ$IU<9(ffLI#J28EyoBQsc>3CK2NWMU8i(osO1+0FtM z&jPYRAOVO$`e8Jhr3}D0n841!0#spOWNg5=0Aeag2kQceNmGDq5MTnD!vt0tWN86p zL3J4#7=UC|-RJc#HraXSU~4 z{XWxx{jxP*XNER|n>>rRuf#U}7zM}mSCSeta%L}P3}N_mRf}i(>96^>%rjD6Og-cf z_iE~`j71y=9psOTgvrci3i{G;+~|@Cx6}*9)0}z=p64BAs#Hu_woTU6vq*FLTK`E` zPi>pb@~NMH>9*U~ZhcD0p4s>{=D}y-q8GjvcQ;O1{(PZNaLtrWYa&Blm);=S<_k{em55nShecZrge&Xrb1t@gz%|m zXG}8<-Fkoe(}w{fKeYYxXWim$UAd~c?aA@QCbnCrg18RJ-+wQ1U~~z-Ua99ff7y>q zj^aYjS0_CWkmpmI#ctl}`1Q&a`=?%t90Avli`8rq=#{aJ|FLf3^DUwh9(u0z{&|lQ zBlMi>&X?k4whq=OxVK{SkTW+UH!6 z7whv6^nWO>k~$IoB>8ou9Lwyp+RP_=*7KYEFxq?9?EXq?_nF5f!}s6ZAah)j>(x}I z$FE+hd4>Or`=!y9EYtkEBTc4uQRci%%f8f_4tI|&|8yR|C={`q8>YRF*F|2_rmDB_ zi@@XOC0SwB$r-k{xC|}k|F`qmckDyewEFCOzW(kHK1&w;dAI$*hpGvw6Bb{ne)U`4 m%b;(b)E&Dw6CJ;L{bicH-o^HNl0hseA$z*|xvX + /// A 0-1 interpolant which dictates a dampning factor for velocity integration increments. + /// + private float MovementSpeedDampingCoefficient + { + get; + set; + } + + /// + /// A timer that increments in respond to wind, assuming wind response is enabled in the . + /// + private float WindTime + { + get; + set; + } + + /// + /// The set of segments that compose this rope. + /// + public RopeSegment[] Segments + { + get; + set; + } + + /// + /// The set of positions that compose this rope. + /// + public Vector2[] SegmentPositions + { + get; + private set; + } + + /// + /// The desired distance between each segment on the rope. + /// + public float DistancePerSegment + { + get; + set; + } + + /// + /// The gravity force to exert on the rope when updating. + /// + public Vector2 Gravity + { + get; + set; + } + + /// + /// The amount of steps to perform when constraining tiles to their desired lengths. Higher values equate to greater accuracy, but reduced performance. + /// + public int ConstraintSteps + { + get; + private set; + } + + /// + /// Sets of settings that dictate how this rope should behave. + /// + public RopeSettings Settings + { + get; + set; + } + + /// + /// Whether this rope should collide with tiles or not. + /// + public bool InteractWithTiles => Settings.TileColliderArea is not null; + + public Rope(Vector2 start, Vector2 end, int segmentCount, float distancePerSegment, Vector2 gravity, RopeSettings settings, int constraintSteps = 10) + { + Segments = new RopeSegment[segmentCount]; + SegmentPositions = new Vector2[segmentCount]; + for (var i = 0; i < segmentCount; i++) + { + var segmentPos = Vector2.Lerp(start, end, i / (segmentCount - 1f)); + Segments[i] = new RopeSegment(segmentPos); + } + + Segments[0].FixedInPlace = settings.StartIsFixed; + Segments[^1].FixedInPlace = settings.EndIsFixed; + RecalculateSegmentPositions(); + + DistancePerSegment = distancePerSegment; + Gravity = gravity; + ConstraintSteps = constraintSteps; + + Settings = settings; + } + + /// + /// Recalculates the cache based on positions. + /// + private void RecalculateSegmentPositions() + { + for (var i = 0; i < Segments.Length; i++) + SegmentPositions[i] = Segments[i].Position; + } + + /// + /// Moves a given position around, obeying tile interaction rules if this rope requires them. + /// + /// The position vector to move. + /// The base velocity to consider. + private void Move(ref Vector2 position, Vector2 baseVelocity) + { + // Apply standard Eulerian integration if tile interactions are not required. + if (!InteractWithTiles || Settings.TileColliderArea is null) + { + position += baseVelocity; + return; + } + + // If tile interactions *are* required, handle them before moving forward. + var width = (int)Settings.TileColliderArea.Value.X; + var height = (int)Settings.TileColliderArea.Value.Y; + var newVelocity = Collision.noSlopeCollision(position, baseVelocity, width, height + 2, true, true); + newVelocity = Collision.noSlopeCollision(position, newVelocity, width, height, true, true); + var finalVelocity = baseVelocity; + if (Math.Abs(baseVelocity.X) > Math.Abs(newVelocity.X)) + finalVelocity.X = 0f; + if (Math.Abs(baseVelocity.Y) > Math.Abs(newVelocity.Y)) + finalVelocity.Y = 0f; + + position += finalVelocity; + } + + /// + /// Updates this rope, making it move around. + /// + public void Update() + { + for (var i = 0; i < Segments.Length; i++) + { + var movementStep = (Segments[i].Position - Segments[i].OldPosition) * (1f - MovementSpeedDampingCoefficient); + if (movementStep.Length() < 0.02f) + movementStep = Vector2.Zero; + + Segments[i].OldPosition = Segments[i].Position; + + if (!Segments[i].FixedInPlace) + Move(ref Segments[i].Position, movementStep + Gravity); + } + + for (var i = 0; i < ConstraintSteps; i++) + Constrain(); + + RecalculateSegmentPositions(); + + if (Settings.RespondToEntityMovement) + HandleEntityMovementResponse(); + if (Settings.RespondToWind) + HandleWindResponse(); + } + + /// + /// Makes this rope respond to the movement of entities. + /// + private void HandleEntityMovementResponse() + { + for (var i = 0; i < Segments.Length; i++) + { + ref RopeSegment ropeSegment = ref Segments[i]; + if (ropeSegment.FixedInPlace) + continue; + + foreach (var player in Main.ActivePlayers) + { + float playerProximityInterpolant = Utils.GetLerpValue(37f, 10f, player.Distance(ropeSegment.Position), true); + ropeSegment.Position += player.velocity * playerProximityInterpolant / Settings.Mass * 0.08f; + } + } + } + + /// + /// Makes this entity respond to wind. + /// + private void HandleWindResponse() + { + WindTime += Main.windSpeedCurrent / 60f; + if (MathF.Abs(WindTime) >= 4000f) + WindTime = 0f; + + var windSpeed = Math.Clamp(Main.WindForVisuals * 2f, -1.3f, 1.3f); + var windWave = MathF.Cos(WindTime * 3.42f + Segments[0].Position.Length() * 0.06f); + var wind = Vector2.UnitX * (windWave + Main.windSpeedCurrent) * -0.2f; + + Segments[^1].Position += wind * Utils.GetLerpValue(0.3f, 0.75f, windSpeed, true) / Settings.Mass; + } + + /// + /// Constrains segments on this rope, conserving their overall length. + /// + public void Constrain() + { + for (var i = 0; i < Segments.Length - 1; i++) + { + // Determine how much each segment has to move in order to return to its desired resting distance. + var segmentLength = Segments[i].Position.Distance(Segments[i + 1].Position); + var distanceFromIdealLength = segmentLength - DistancePerSegment; + Vector2 correctiveForce = (Segments[i].Position - Segments[i + 1].Position).SafeNormalize(Vector2.Zero) * distanceFromIdealLength; + + var pinned = Segments[i].FixedInPlace; + var nextPinned = Segments[i + 1].FixedInPlace; + correctiveForce *= pinned || nextPinned ? 1f : 0.5f; + + if (!pinned) + Move(ref Segments[i].Position, -correctiveForce); + if (!nextPinned) + Move(ref Segments[i + 1].Position, correctiveForce); + } + } +} diff --git a/Physics/RopeHandle.cs b/Physics/RopeHandle.cs new file mode 100644 index 0000000000..4b5c03570f --- /dev/null +++ b/Physics/RopeHandle.cs @@ -0,0 +1,73 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Terraria.ModLoader; + +namespace CalamityMod.Physics; + +// Yes, I was silently reading over the Nightshade dev channels when learning about this. +// So, thanks Tomat and 1-3 for the idea! -Lucille +/// +/// A handle that contains a reference to a given globally managed rope instance. +/// +public readonly struct RopeHandle +{ + /// + /// The value used to identify this handle's associated rope managed by the central system. + /// + private readonly int Identifier; + + /// + /// The rope associated with this handle. + /// + private readonly Rope Rope => ModContent.GetInstance().Ropes[Identifier]!; + + /// + /// The set of all positions maintained by the underlying rope. + /// + public readonly IEnumerable Positions => Rope.SegmentPositions; + + /// + /// The amount of segments this rope has. + /// + public int SegmentCount => Rope.Segments.Length; + + /// + /// The starting position of the underlying rope. + /// + public ref Vector2 Start => ref Rope.Segments[0].Position; + + /// + /// The ending position of the underlying rope. + /// + public ref Vector2 End => ref Rope.Segments[^1].Position; + + /// + /// The gravity associated with the rope. + /// + public Vector2 Gravity + { + get => Rope.Gravity; + set => Rope.Gravity = value; + } + + internal RopeHandle(int identifier) => Identifier = identifier; + + /// + /// Forces this rope to settle by performing a series of constrained updates. + /// + public void Settle() + { + for (var i = 0; i < 20; i++) + Rope.Update(); + } + + /// + /// Indicates that the rope associated with this handle should be returned back to the pool. + /// + public void Dispose() + { + var chunkIndex = Identifier / RopeManagerSystem.BitsPerChunk; + var bitIndex = Identifier % RopeManagerSystem.BitsPerChunk; + ModContent.GetInstance().ToggleActivityIndex(chunkIndex, bitIndex); + } +} diff --git a/Physics/RopeManagerSystem.cs b/Physics/RopeManagerSystem.cs new file mode 100644 index 0000000000..0192cd3c48 --- /dev/null +++ b/Physics/RopeManagerSystem.cs @@ -0,0 +1,132 @@ +using System; +using Microsoft.Xna.Framework; +using Terraria.ModLoader; +using BitOperations = System.Numerics.BitOperations; + +namespace CalamityMod.Physics; + +public sealed class RopeManagerSystem : ModSystem +{ + /// + /// The set of all maintained ropes in the world. + /// + internal readonly Rope[] Ropes = new Rope[MaxRopeCount]; + + /// + /// The internal binary mappings that determine whether ropes are active or not. + /// + internal readonly ulong[] ActivityBitChunks = new ulong[(int)Math.Ceiling((double)MaxRopeCount / BitsPerChunk)]; + + /// + /// The maximum amount of ropes to maintain across the world. + /// + public const int MaxRopeCount = 2048; + + /// + /// The amount of bits contained within each chunk in the array. + /// + public const int BitsPerChunk = sizeof(ulong) * 8; + + public override void ClearWorld() + { + for (var i = 0; i < ActivityBitChunks.Length; i++) + ActivityBitChunks[i] = 0uL; + } + + public override void PostUpdateWorld() + { + for (var i = 0; i < Ropes.Length; i++) + { + var bitIndex = i % BitsPerChunk; + var active = (ActivityBitChunks[i / BitsPerChunk] >> bitIndex & 1) == 1; + if (active) + Ropes[i].Update(); + } + } + + /// + /// Toggles a given activity index. + /// + /// The index of the to toggle. + /// The bit index in the chunk to toggle. + internal void ToggleActivityIndex(int chunkIndex, int bitIndex) => ActivityBitChunks[chunkIndex] ^= 1uL << bitIndex; + + /// + /// Attempts to find and return the first available index for a new rope. + /// + private int? SelectFirstAvailableIndex() + { + for (var i = 0; i < ActivityBitChunks.Length; i++) + { + // This comment can be deleted later if it's deemed a bit too verbose. I'm half doing it for myself to test my understanding, half doing it for any future readers who might + // not immediately understand what the bit operations do here. -Lucille + + // As a simplified example, assume the following for the activity bits, where zero means inactive and one means active: + // 0110 1111 + + // This means the first four indices are occupied, but the fifth index is free. Note that in this case bits are counted from right to left. + // In order to find the first new index, we simply need to count the amount of ones until the first zero. + // Conveniently, BitOperations.TrailingZeroCount exists for this purpose. We just need to invert the binary in order to convert the ones into zeroes. + var offset = BitOperations.TrailingZeroCount(~ActivityBitChunks[i]); + + // Check if the index offset is equal to the amount of bits in the chunk. + // If so, that means that every single bit is a one, and that there's no available index in the chunk to use. + var allBitsAreOccupied = offset == BitsPerChunk; + if (allBitsAreOccupied) + continue; + + return offset + i * BitsPerChunk; + } + + // No valid index found across the activity bit chunks. Return null. + return null; + } + + /// + /// Requests a new rope, returning a handle to it, or null if for some reason the rope couldn't be created. + /// + public RopeHandle? RequestNew(Vector2 start, Vector2 end, int segmentCount, float distancePerSegment, Vector2 gravity, RopeSettings settings, int constraintSteps = 10) + { + var index = SelectFirstAvailableIndex(); + if (index is null) + return null; + + // Mark the newly selected index as active by toggling its activity state on. + ToggleActivityIndex(index.Value / BitsPerChunk, index.Value % BitsPerChunk); + + Ropes[index.Value] = new Rope(start, end, segmentCount, distancePerSegment, gravity, settings, constraintSteps); + + return new RopeHandle(index.Value); + } + + /// + /// Calculates the overall segment length of a rope based on the horizontal span between its two end points and a desired sag distance. + /// + public static float CalculateSegmentLength(float ropeSpan, float sag, int iterations = 12) + { + // A rope at rest is defined via a catenary curve, which exists in the following mathematical form: + // y(x) = a * cosh(x / a) + + // Furthermore, the length of a rope, given the horizontal width w for a rope, is defined as follows: + // L = 2a * sinh(w / 2a) + + // In order to use the above equation, the value of a must be determined for the catenary that this rope will form. + // To do so, a numerical solution will need to be found based on the known width and sag values. + + // Suppose the two supports are at equal height at distances -w/2 and w/2. + // From this, sag (which will be denoted with h) can be defined in the following way: h = y(w/2) - y(0) + // Reducing this results in the following equation: + + // h = a(cosh(w / 2a) - 1) + // a(cosh(w / 2a) - 1) - h = 0 + // This can be used to numerically find a. + var initialGuessA = sag; + var a = (float)CalamityUtils.IterativelySearchForRoot(x => + { + return x * (Math.Cosh(ropeSpan / (x * 2D)) - 1D) - sag; + }, initialGuessA, iterations); + + // Now that a is known, it's just a matter of plugging it back into the original equation to find L. + return MathF.Sinh(ropeSpan / a * 0.5f) * a * 2f; + } +} diff --git a/Physics/RopeSegment.cs b/Physics/RopeSegment.cs new file mode 100644 index 0000000000..81cb8708de --- /dev/null +++ b/Physics/RopeSegment.cs @@ -0,0 +1,30 @@ +using Microsoft.Xna.Framework; + +namespace CalamityMod.Physics; + +/// +/// A representation of a rope segment, containing physical data such as position, velocity, etc., as well as a value which determines whether the rope is fixed in place and not subject to standard physics. +/// +public struct RopeSegment +{ + /// + /// The current position of this segment. + /// + public Vector2 Position; + + /// + /// The previous position of this segment. + /// + public Vector2 OldPosition; + + /// + /// Whether this segment is fixed in place and not subject to standard physics, such as gravity. + /// + public bool FixedInPlace; + + public RopeSegment(Vector2 position) + { + Position = position; + OldPosition = position; + } +} diff --git a/Physics/RopeSettings.cs b/Physics/RopeSettings.cs new file mode 100644 index 0000000000..133e1bc4f0 --- /dev/null +++ b/Physics/RopeSettings.cs @@ -0,0 +1,11 @@ +using Microsoft.Xna.Framework; + +namespace CalamityMod.Physics; + +public readonly record struct RopeSettings(bool StartIsFixed, bool EndIsFixed, bool RespondToEntityMovement, bool RespondToWind, Vector2? TileColliderArea, float Mass = 1f) +{ + public RopeSettings() : this(false, false, false, false, null, 1f) + { + + } +} diff --git a/Projectiles/DraedonsArsenal/SnakeEyesProjectile.cs b/Projectiles/DraedonsArsenal/SnakeEyesProjectile.cs index a74104ec52..7eb2c5a05b 100644 --- a/Projectiles/DraedonsArsenal/SnakeEyesProjectile.cs +++ b/Projectiles/DraedonsArsenal/SnakeEyesProjectile.cs @@ -186,7 +186,7 @@ public override bool PreDraw(ref Color lightColor) Vector2 origin = frame.Size() * 0.5f; Main.EntitySpriteDraw(texture, drawPosition, frame, Projectile.GetAlpha(lightColor), Projectile.rotation, origin, Projectile.scale, SpriteEffects.None, 0); - GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/FabstaffStreak")); + GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/SylvestaffStreak")); PrimitiveRenderer.RenderTrail(Projectile.oldPos, new(PrimitiveWidthFunction, PrimitiveColorFunction, (_) => Projectile.Size * 0.5f, shader: GameShaders.Misc["CalamityMod:TrailStreak"]), 92); return false; } diff --git a/Projectiles/Magic/ArtAttackStar.cs b/Projectiles/Magic/ArtAttackStar.cs index aea6eae32c..081881e671 100644 --- a/Projectiles/Magic/ArtAttackStar.cs +++ b/Projectiles/Magic/ArtAttackStar.cs @@ -223,7 +223,7 @@ public override bool PreDraw(ref Color lightColor) Vector2 origin = texture.Size() * 0.5f; Main.spriteBatch.EnterShaderRegion(); - GameShaders.Misc["CalamityMod:ArtAttack"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/FabstaffStreak")); + GameShaders.Misc["CalamityMod:ArtAttack"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/SylvestaffStreak")); GameShaders.Misc["CalamityMod:ArtAttack"].Apply(); PrimitiveRenderer.RenderTrail(Projectile.oldPos, new(TrailWidth, TrailColor, (_) => Projectile.Size * 0.5f, shader: GameShaders.Misc["CalamityMod:ArtAttack"]), 180); diff --git a/Projectiles/Magic/FabBolt.cs b/Projectiles/Magic/FabBolt.cs deleted file mode 100644 index e31698e9c6..0000000000 --- a/Projectiles/Magic/FabBolt.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using CalamityMod.Graphics.Primitives; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using Terraria; -using Terraria.Graphics.Shaders; -using Terraria.ID; -using Terraria.ModLoader; -namespace CalamityMod.Projectiles.Magic -{ - public class FabBolt : ModProjectile, ILocalizedModType - { - public new string LocalizationCategory => "Projectiles.Magic"; - public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; - - public bool FadingOut - { - get => Projectile.ai[0] == 1f; - set => Projectile.ai[0] = value.ToInt(); - } - - public override void SetStaticDefaults() - { - ProjectileID.Sets.TrailingMode[Projectile.type] = 2; - ProjectileID.Sets.TrailCacheLength[Projectile.type] = 23; - } - - public override void SetDefaults() - { - Projectile.width = 4; - Projectile.height = 4; - Projectile.friendly = true; - Projectile.extraUpdates = 2; - Projectile.penetrate = 12; - Projectile.timeLeft = 90 * Projectile.extraUpdates; - Projectile.DamageType = DamageClass.Magic; - Projectile.ignoreWater = true; - Projectile.usesLocalNPCImmunity = true; - Projectile.localNPCHitCooldown = 0; - } - - public override void AI() - { - if (FadingOut) - { - Projectile.Opacity = MathHelper.Lerp(Projectile.Opacity, 0f, 0.27f); - if (Projectile.Opacity <= 0.05f) - Projectile.Kill(); - } - else - Projectile.velocity *= 1.004f; - Projectile.rotation = Projectile.velocity.ToRotation(); - - // Emit light. - Lighting.AddLight(Projectile.Center, Vector3.One * Projectile.Opacity * 0.45f); - } - - internal Color ColorFunction(float completionRatio) - { - float fadeToEnd = MathHelper.Lerp(0.25f, 0.5f, (float)Math.Cos(-Main.GlobalTimeWrappedHourly * 3f) * 0.5f + 0.5f); - fadeToEnd *= 1f - Utils.GetLerpValue(0.35f, 0f, completionRatio, true); - Color endColor = Color.Lerp(Color.Cyan, Color.HotPink, Projectile.identity % 2); - return Color.Lerp(Color.White, endColor, fadeToEnd) * Projectile.Opacity * 0.7f; - } - - internal float WidthFunction(float completionRatio) - { - float expansionCompletion = 1f - (float)Math.Pow(1f - Utils.GetLerpValue(0f, 0.2f, completionRatio, true), 2D); - return MathHelper.Lerp(0f, 22f, expansionCompletion) * Projectile.Opacity; - } - - public override bool PreDraw(ref Color lightColor) - { - GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/FabstaffStreak")); - PrimitiveRenderer.RenderTrail(Projectile.oldPos, new(WidthFunction, ColorFunction, (_) => Projectile.Size * 0.5f, smoothen: false, shader: GameShaders.Misc["CalamityMod:TrailStreak"]), 80); - return false; - } - - public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) - { - if (!FadingOut && Projectile.penetrate < 2) - { - FadingOut = true; - Projectile.velocity *= 0.1f; - Projectile.extraUpdates = 0; - Projectile.netUpdate = true; - } - } - - public override bool OnTileCollide(Vector2 oldVelocity) - { - if (!FadingOut) - { - FadingOut = true; - Projectile.velocity *= 0.1f; - Projectile.extraUpdates = 0; - Projectile.netUpdate = true; - } - return false; - } - - public override bool? CanDamage() - { - if (FadingOut) - return false; - return null; - } - } -} diff --git a/Projectiles/Magic/FabRay.cs b/Projectiles/Magic/FabRay.cs deleted file mode 100644 index 3305ae8e90..0000000000 --- a/Projectiles/Magic/FabRay.cs +++ /dev/null @@ -1,116 +0,0 @@ -using System; -using CalamityMod.Buffs.Alcohol; -using CalamityMod.Graphics.Primitives; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using Terraria; -using Terraria.Graphics.Shaders; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Projectiles.Magic -{ - public class FabRay : ModProjectile, ILocalizedModType - { - public new string LocalizationCategory => "Projectiles.Magic"; - - public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; - - public override void SetStaticDefaults() - { - ProjectileID.Sets.TrailCacheLength[Projectile.type] = 54; - ProjectileID.Sets.TrailingMode[Projectile.type] = 2; - } - - public override void SetDefaults() - { - Projectile.width = 4; - Projectile.height = 4; - Projectile.friendly = true; - Projectile.DamageType = DamageClass.Magic; - Projectile.ignoreWater = true; - Projectile.penetrate = 70; - Projectile.extraUpdates = 3; - Projectile.timeLeft = 60 * Projectile.extraUpdates; - Projectile.usesLocalNPCImmunity = true; - Projectile.localNPCHitCooldown = 10; - } - - public override void AI() - { - Lighting.AddLight(Projectile.Center, 0.2f, 0.01f, 0.1f); - Projectile.ai[0] += 1f; - Projectile.Opacity = Utils.GetLerpValue(0f, 10f * Projectile.MaxUpdates, Projectile.timeLeft, true); - - int shootRate = Projectile.npcProj ? 40 : 12; - if (Projectile.owner == Main.myPlayer && Projectile.ai[0] % shootRate == 0f) - { - NPC potentialTarget = Projectile.Center.ClosestNPCAt(180f, false); - if (potentialTarget != null) - { - Vector2 shootVelocity = Projectile.SafeDirectionTo(potentialTarget.Center) * 13f; - Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center - shootVelocity * 2.5f, shootVelocity, ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner); - } - - for (int i = 0; i < Projectile.oldPos.Length / 4; i += 3) - { - potentialTarget = Projectile.oldPos[i].ClosestNPCAt(280f, false); - if (potentialTarget != null) - { - Vector2 shootVelocity = (potentialTarget.Center - Projectile.oldPos[i]).SafeNormalize(Vector2.UnitY) * 13f; - Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.oldPos[i] - shootVelocity * 2.5f, shootVelocity, ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner); - break; - } - } - } - - // Emit light. - if (!Projectile.hostile) - Lighting.AddLight(Projectile.Center, Vector3.One * Projectile.Opacity * 0.7f); - } - - internal Color ColorFunction(float completionRatio) - { - float fadeToEnd = MathHelper.Lerp(0.65f, 1f, (float)Math.Cos(-Main.GlobalTimeWrappedHourly * 3f) * 0.5f + 0.5f); - float fadeOpacity = Utils.GetLerpValue(1f, 0.64f, completionRatio, true) * Projectile.Opacity; - Color endColor = Color.Lerp(Color.Cyan, Color.HotPink, (float)Math.Sin(completionRatio * MathHelper.Pi * 1.6f - Main.GlobalTimeWrappedHourly * 4f) * 0.5f + 0.5f); - return Color.Lerp(Color.White, endColor, fadeToEnd) * fadeOpacity; - } - - internal float WidthFunction(float completionRatio) - { - float expansionCompletion = 1f - (float)Math.Pow(1f - Utils.GetLerpValue(0f, 0.3f, completionRatio, true), 2D); - return MathHelper.Lerp(0f, 32f * Projectile.Opacity, expansionCompletion); - } - - internal Vector2 OffsetFunction(float completionRatio) => Projectile.Size * 0.5f; - - public override bool PreDraw(ref Color lightColor) - { - GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/ScarletDevilStreak")); - PrimitiveRenderer.RenderTrail(Projectile.oldPos, new PrimitiveSettings(WidthFunction, ColorFunction, OffsetFunction, pixelate: false, shader: GameShaders.Misc["CalamityMod:TrailStreak"]), 32); - return false; - } - - public override bool OnTileCollide(Vector2 oldVelocity) - { - Projectile.penetrate--; - if (Projectile.penetrate <= 0) - { - Projectile.Kill(); - } - else - { - if (Projectile.velocity.X != oldVelocity.X) - { - Projectile.velocity.X = -oldVelocity.X; - } - if (Projectile.velocity.Y != oldVelocity.Y) - { - Projectile.velocity.Y = -oldVelocity.Y; - } - } - return false; - } - } -} diff --git a/Projectiles/Magic/SylvBolt.cs b/Projectiles/Magic/SylvBolt.cs new file mode 100644 index 0000000000..de43d1b0f9 --- /dev/null +++ b/Projectiles/Magic/SylvBolt.cs @@ -0,0 +1,155 @@ +using System; +using CalamityMod.Graphics.Primitives; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.Graphics.Shaders; +using Terraria.ID; +using Terraria.ModLoader; +namespace CalamityMod.Projectiles.Magic +{ + public class SylvBolt : ModProjectile, ILocalizedModType + { + public new string LocalizationCategory => "Projectiles.Magic"; + + public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + + /// + /// The color hue interpolant for this bolt. + /// + public ref float HueInterpolant => ref Projectile.ai[0]; + + /// + /// How many natural frames have elapsed so far throughout the duration of this bolt's life. Extra updates do not affect this timer. + /// + public int Time + { + get => (int)Projectile.ai[1]; + set => Projectile.ai[1] = value; + } + + /// + /// Whether this bolt is vanishing due to the a collision. + /// + public bool Vanishing + { + get => Projectile.ai[2] == 1f; + set => Projectile.ai[2] = value.ToInt(); + } + + public override void SetStaticDefaults() + { + ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + ProjectileID.Sets.TrailCacheLength[Projectile.type] = 23; + } + + public override void SetDefaults() + { + Projectile.width = 4; + Projectile.height = 4; + Projectile.friendly = true; + Projectile.extraUpdates = 2; + Projectile.penetrate = 12; + Projectile.timeLeft = Projectile.extraUpdates * 90; + Projectile.DamageType = DamageClass.Magic; + Projectile.ignoreWater = true; + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 0; + } + + public override void AI() + { + Projectile.velocity *= 1.004f; + if (Vanishing) + Vanish(); + + if (Projectile.FinalExtraUpdate()) + Time++; + + Projectile.scale = Utils.GetLerpValue(0f, 7f, Time, true); + + CreateMagicDust(); + + // Emit light. + Lighting.AddLight(Projectile.Center, Vector3.One * Projectile.Opacity * 0.45f); + } + + /// + /// Makes this bolt vanish. + /// + private void Vanish() + { + Projectile.Opacity = MathHelper.Lerp(Projectile.Opacity, 0f, 0.24f); + Projectile.velocity = Vector2.Zero; + Projectile.tileCollide = false; + if (Projectile.Opacity <= 0.1f) + Projectile.Kill(); + } + + /// + /// Idly emits magic dust off this bolt. + /// + private void CreateMagicDust() + { + if (Main.rand.NextBool(4)) + { + Dust magic = Dust.NewDustPerfect(Projectile.Center, 264); + magic.color = ColorFunction(0f); + magic.scale *= 0.56f; + magic.noGravity = true; + } + } + + /// + /// The function responsible for dictating the color of this bolt. + /// + internal Color ColorFunction(float completionRatio) + { + float opacity = (1f - completionRatio) * Projectile.Opacity; + return CalamityUtils.MulticolorLerp(HueInterpolant, new Color(255, 193, 255), Color.White, new Color(127, 242, 255)) * opacity; + } + + /// + /// The function responsible for dictating the width of this bolt. + /// + internal float WidthFunction(float completionRatio) + { + float tip = 1f - MathF.Pow(1f - Utils.GetLerpValue(0.05f, 0.2f, completionRatio * Projectile.Opacity, true), 2f); + return tip * Projectile.Opacity * Projectile.scale * 22f; + } + + public override bool PreDraw(ref Color lightColor) + { + MiscShaderData boltShader = GameShaders.Misc["CalamityMod:SylvestaffProjectile"]; + + boltShader.SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/SylvestaffStreak")); + PrimitiveRenderer.RenderTrail(Projectile.oldPos, new(WidthFunction, ColorFunction, (_) => Projectile.Size * 0.5f, smoothen: false, shader: boltShader), 80); + return false; + } + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + if (!Vanishing && Projectile.penetrate < 2) + { + Vanishing = true; + Projectile.velocity *= 0.02f; + Projectile.extraUpdates = 0; + Projectile.netUpdate = true; + } + } + + public override bool OnTileCollide(Vector2 oldVelocity) + { + if (!Vanishing) + { + Vanishing = true; + Projectile.velocity = Vector2.Zero; + Projectile.extraUpdates = 0; + Projectile.netUpdate = true; + } + return false; + } + + public override bool? CanDamage() => !Vanishing; + } +} diff --git a/Projectiles/Magic/SylvRay.cs b/Projectiles/Magic/SylvRay.cs new file mode 100644 index 0000000000..84bcfc66b4 --- /dev/null +++ b/Projectiles/Magic/SylvRay.cs @@ -0,0 +1,217 @@ +using System; +using System.IO; +using CalamityMod.Graphics.Primitives; +using CalamityMod.Items.Weapons.Magic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.Audio; +using Terraria.Graphics.Shaders; +using Terraria.ID; +using Terraria.ModLoader; + +namespace CalamityMod.Projectiles.Magic +{ + public class SylvRay : ModProjectile, ILocalizedModType + { + /// + /// The position from which this ray's glow effect appears. + /// + public Vector2 GlowCenter + { + get; + set; + } + + /// + /// How many natural frames have elapsed so far throughout the duration of this ray's life. Extra updates do not affect this timer. + /// + public int Time + { + get => (int)Projectile.ai[0]; + set => Projectile.ai[0] = value; + } + + public new string LocalizationCategory => "Projectiles.Magic"; + + public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; + + public override void SetStaticDefaults() + { + ProjectileID.Sets.TrailCacheLength[Projectile.type] = 54; + ProjectileID.Sets.TrailingMode[Projectile.type] = 2; + } + + public override void SetDefaults() + { + Projectile.width = 4; + Projectile.height = 4; + Projectile.friendly = true; + Projectile.DamageType = DamageClass.Magic; + Projectile.ignoreWater = true; + Projectile.penetrate = 70; + Projectile.extraUpdates = 3; + Projectile.timeLeft = 60 * Projectile.extraUpdates; + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 10; + } + + public override void SendExtraAI(BinaryWriter writer) => writer.WriteVector2(GlowCenter); + + public override void ReceiveExtraAI(BinaryReader reader) => GlowCenter = reader.ReadVector2(); + + public override void AI() + { + if (Projectile.FinalExtraUpdate()) + Time++; + + Projectile.Opacity = Utils.GetLerpValue(0f, Projectile.MaxUpdates * 10f, Projectile.timeLeft, true); + Projectile.scale = Utils.GetLerpValue(1f, 9.5f, Time, true) * Projectile.Opacity; + + if (GlowCenter == Vector2.Zero) + GlowCenter = Projectile.Center + Projectile.velocity.SafeNormalize(Vector2.Zero) * 74f; + + HandleBoltFiring(); + CreateGlowyDust(); + + Lighting.AddLight(Projectile.Center, Vector3.One * Projectile.Opacity * 0.7f); + } + + /// + /// Handles the firing of bolts across this ray. + /// + private void HandleBoltFiring() + { + int shootRate = Sylvestaff.RayBoltShootRate; + if (Time % shootRate == 0 && Projectile.FinalExtraUpdate()) + { + int trailSearchPositions = 13; + for (int i = 0; i < trailSearchPositions; i += 3) + TryToFireBolt(Projectile.oldPos[i] + Projectile.Size * 0.5f, i / (float)trailSearchPositions); + } + } + + /// + /// Attempts to fire a given bolt projectile from a given position at the closest enemy to said position, assuming one exists. + /// + private void TryToFireBolt(Vector2 searchPosition, float hue) + { + NPC potentialTarget = searchPosition.ClosestNPCAt(Sylvestaff.RayBoltTargetingRange, false); + if (potentialTarget is null) + return; + + SoundEngine.PlaySound(Sylvestaff.BounceSound with { MaxInstances = 12, Volume = 0.4f, Pitch = 0.4f }, Projectile.Center); + + float shootSpeed = Projectile.velocity.Length(); + Vector2 shootVelocity = (potentialTarget.Center - searchPosition).SafeNormalize(Vector2.UnitY) * shootSpeed; + if (Projectile.owner == Main.myPlayer) + Projectile.NewProjectile(Projectile.GetSource_FromThis(), searchPosition, shootVelocity, ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner, hue); + + float burstSpeed = Main.rand.NextFloat(1f, 3f); + for (int i = 0; i < 4; i++) + { + Dust magicBurst = Dust.NewDustPerfect(searchPosition, 264); + magicBurst.velocity = Projectile.velocity.RotatedBy(MathHelper.TwoPi * i / 4f + MathHelper.PiOver4).SafeNormalize(Vector2.Zero) * burstSpeed; + magicBurst.color = Color.White; + magicBurst.noLight = true; + magicBurst.noGravity = true; + } + } + + /// + /// Emits dust particles at the glow center of this ray, to help sell the notion that it's appearing from a concentrated ball of queer magic energy. + /// + private void CreateGlowyDust() + { + if (Time <= 9 && Main.rand.NextBool()) + { + Color colorAccent = Main.rand.NextBool() ? Color.HotPink : Color.Aqua; + + Dust transMagic = Dust.NewDustPerfect(GlowCenter, 264); + transMagic.velocity = Main.rand.NextVector2Circular(4.6f, 4.6f) + Projectile.velocity * 0.25f; + transMagic.color = Color.Lerp(Color.White, colorAccent, Main.rand.NextFloat(0.23f)); + transMagic.scale *= 1.1f; + transMagic.fadeIn = 0.75f; + transMagic.noGravity = true; + } + } + + /// + /// The function responsible for dictating the color of this ray. + /// + internal Color ColorFunction(float completionRatio) + { + float opacity = MathF.Pow(Utils.GetLerpValue(1f, 0.64f, completionRatio, true), 3f) * Projectile.Opacity; + float colorInterpolant = MathF.Cos(MathHelper.Pi * completionRatio - Main.GlobalTimeWrappedHourly * 7.2f) * 0.5f + 0.5f; + + Color pink = new Color(255, 147, 255); + Color blue = new Color(109, 224, 255); + Color baseColor = CalamityUtils.MulticolorLerp(colorInterpolant, pink, Color.White, blue, Color.White); + + return baseColor * opacity; + } + + /// + /// The function responsible for dictating the width of this ray. + /// + internal float WidthFunction(float completionRatio) + { + float expansionCompletion = 1f - MathF.Pow(1f - Utils.GetLerpValue(0f, 0.3f, completionRatio, true), 2f); + float undulation = MathF.Cos(MathHelper.Pi * completionRatio * 5f - Main.GlobalTimeWrappedHourly * 23f) * 2.4f; + float maxWidth = undulation + 32f; + + return MathHelper.Lerp(0f, Projectile.scale * maxWidth, expansionCompletion); + } + + /// + /// The function responsible for dictating the render offset of this ray. + /// + internal Vector2 OffsetFunction(float completionRatio) => Projectile.Size * 0.5f; + + /// + /// Renders the front-glow for this ray, to help make it look like it has a defined origin of concentrated magic. + /// + private void RenderFrontGlow() + { + float glowAnimationProgress = Utils.GetLerpValue(0f, 9.5f, Time, true); + float glowBump = CalamityUtils.Convert01To010(glowAnimationProgress); + float glowRotation = Projectile.velocity.ToRotation(); + Vector2 glowScale = new Vector2(1f + glowBump * 0.8f, 1f) * glowBump; + + Vector2 startingPosition = GlowCenter - Main.screenPosition; + Texture2D lightTexture = ModContent.Request("CalamityMod/ExtraTextures/BloomCirclePinpoint").Value; + Main.spriteBatch.Draw(lightTexture, startingPosition, null, ColorFunction(0f) with { A = 0 }, glowRotation, lightTexture.Size() * 0.5f, glowScale, 0, 0f); + Main.spriteBatch.Draw(lightTexture, startingPosition, null, ColorFunction(0f) with { A = 0 }, glowRotation, lightTexture.Size() * 0.5f, glowScale * 0.4f, 0, 0f); + } + + public override bool PreDraw(ref Color lightColor) + { + RenderFrontGlow(); + + MiscShaderData rayShader = GameShaders.Misc["CalamityMod:SylvestaffProjectile"]; + rayShader.SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/ScarletDevilStreak")); + + PrimitiveRenderer.RenderTrail(Projectile.oldPos, new PrimitiveSettings(WidthFunction, ColorFunction, OffsetFunction, pixelate: false, shader: rayShader), 32); + return false; + } + + public override bool OnTileCollide(Vector2 oldVelocity) + { + Projectile.penetrate--; + if (Projectile.penetrate <= 0) + { + Projectile.Kill(); + } + else + { + SoundEngine.PlaySound(Sylvestaff.BounceSound, Projectile.Center); + + if (Projectile.velocity.X != oldVelocity.X) + Projectile.velocity.X = -oldVelocity.X; + if (Projectile.velocity.Y != oldVelocity.Y) + Projectile.velocity.Y = -oldVelocity.Y; + } + return false; + } + } +} diff --git a/Projectiles/Magic/SylvestaffHoldout.cs b/Projectiles/Magic/SylvestaffHoldout.cs new file mode 100644 index 0000000000..62fd45e760 --- /dev/null +++ b/Projectiles/Magic/SylvestaffHoldout.cs @@ -0,0 +1,262 @@ +using System; +using CalamityMod.Graphics.Primitives; +using CalamityMod.Items.Weapons.Magic; +using CalamityMod.Physics; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.Audio; +using Terraria.Graphics.Shaders; +using Terraria.Localization; +using Terraria.ModLoader; + +namespace CalamityMod.Projectiles.Magic +{ + public class SylvestaffHoldout : ModProjectile, IPixelatedPrimitiveRenderer + { + public PixelationPrimitiveLayer LayerToRenderTo => PixelationPrimitiveLayer.BeforeProjectiles | PixelationPrimitiveLayer.AfterPlayers; + + public override LocalizedText DisplayName => CalamityUtils.GetItemName(); + + /// + /// The left ribbon on this holdout. + /// + public RopeHandle? LeftRibbon; + + /// + /// The right ribbon on this holdout. + /// + public RopeHandle? RightRibbon; + + /// + /// The player owner of this holdout staff. + /// + public Player Owner => Main.player[Projectile.owner]; + + /// + /// A general purpose, ever-increment timer used by this holdout staff. + /// + public ref float Time => ref Projectile.ai[0]; + + /// + /// The point of attachment for ribbons on this staff. + /// + public Vector2 RibbonAttachPoint => Projectile.Center + Projectile.velocity * Projectile.scale * Projectile.width * 0.34f; + + /// + /// The length of ribbons attached to this staff. + /// + private static float RibbonLength => 70f; + + public override string Texture => ModContent.GetInstance().Texture; + + public override void SetDefaults() + { + Projectile.width = Projectile.height = 94; + Projectile.friendly = true; + Projectile.penetrate = -1; + Projectile.DamageType = DamageClass.Magic; + Projectile.tileCollide = false; + Projectile.ignoreWater = true; + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 10; + Projectile.timeLeft = 72000; + } + + public override void AI() + { + if (!Owner.channel) + Projectile.Kill(); + + if (LeftRibbon is null && RightRibbon is null) + InitializeRibbons(); + + AimTowardsMouse(); + HandleHoldoutLogic(); + OrientOwnerArms(); + FireAwesomeMagicRays(); + UpdateRibbon(LeftRibbon, Projectile.velocity.RotatedBy(-MathHelper.PiOver2)); + UpdateRibbon(RightRibbon, Projectile.velocity.RotatedBy(MathHelper.PiOver2)); + + Time++; + } + + /// + /// Initializes the ribbons attached to this staff. + /// + private void InitializeRibbons() + { + int ribbonSegmentCount = 12; + float distancePerSegment = RibbonLength / ribbonSegmentCount; + RopeSettings ribbonSettings = new RopeSettings() + { + StartIsFixed = true, + Mass = 0.72f, + RespondToEntityMovement = true, + RespondToWind = true + }; + LeftRibbon = ModContent.GetInstance().RequestNew(RibbonAttachPoint, Projectile.Center, ribbonSegmentCount, distancePerSegment, Vector2.Zero, ribbonSettings, 25); + RightRibbon = ModContent.GetInstance().RequestNew(RibbonAttachPoint, Projectile.Center, ribbonSegmentCount, distancePerSegment, Vector2.Zero, ribbonSettings, 25); + } + + /// + /// Handles all logic pertaining to making this staff act as a holdout projectile. + /// + private void HandleHoldoutLogic() + { + Vector2 center = Owner.MountedCenter + Vector2.UnitY * 7f + Projectile.velocity * Projectile.width * 0.31f; + + Projectile.rotation = Projectile.velocity.ToRotation(); + Projectile.Center = Owner.RotatedRelativePoint(center) - Vector2.UnitY * Owner.gfxOffY; + Projectile.spriteDirection = (Math.Cos(Projectile.rotation) > 0).ToDirectionInt(); + + // The staff is a holdout projectile; change the player's variables to reflect this. + Owner.ChangeDir(Projectile.spriteDirection); + Owner.SetDummyItemTime(2); + Owner.heldProj = Projectile.whoAmI; + + Projectile.rotation += MathHelper.PiOver4; + if (Projectile.spriteDirection == -1) + Projectile.rotation += MathHelper.PiOver2; + } + + /// + /// Orients the owner player's arm rotation to help make it look like they're actually holding the staff. + /// + private void OrientOwnerArms() + { + float baseRotation = Projectile.velocity.ToRotation() - MathHelper.PiOver2; + float directionVerticality = MathF.Abs(Projectile.velocity.X); + Owner.SetCompositeArmFront(true, Player.CompositeArmStretchAmount.Full, baseRotation + Owner.direction * directionVerticality * MathHelper.PiOver4); + Owner.SetCompositeArmBack(true, Player.CompositeArmStretchAmount.Full, baseRotation + Owner.direction * directionVerticality * 0.33f); + } + + /// + /// Makes this staff aim towards the owner's mouse. + /// + private void AimTowardsMouse() + { + if (Main.myPlayer != Projectile.owner) + return; + + Vector2 idealDirection = Projectile.SafeDirectionTo(Main.MouseWorld); + Vector2 newDirection = Vector2.Lerp(Projectile.velocity, idealDirection, Sylvestaff.TurnSpeedInterpolant).SafeNormalize(Vector2.UnitX * Owner.direction); + if (Projectile.velocity != newDirection) + { + Projectile.velocity = newDirection; + Projectile.netUpdate = true; + Projectile.netSpam = 0; + } + } + + /// + /// Updates a given ribbon. + /// + private void UpdateRibbon(RopeHandle? ribbon, Vector2 gravityDirection) + { + // Ensure that the handle is properly initialized before proceeding any further. + if (ribbon is not RopeHandle rope) + return; + + rope.Start = RibbonAttachPoint; + rope.Gravity = gravityDirection * 0.15f - Projectile.velocity * 0.4f; + } + + /// + /// Handles the firing of magic ray projectiles for this staff. + /// + private void FireAwesomeMagicRays() + { + Item heldItem = Owner.ActiveItem(); + if (heldItem is null) + return; + + if (Time % heldItem.useAnimation == 0) + { + SoundEngine.PlaySound(Sylvestaff.FireSound, Projectile.Center); + if (Main.myPlayer == Projectile.owner) + { + int damage = Owner.GetWeaponDamage(heldItem); + Vector2 shootVelocity = Projectile.velocity * heldItem.shootSpeed; + Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, shootVelocity, ModContent.ProjectileType(), damage, heldItem.knockBack, Projectile.owner); + + // Apply a minor amount of recoil. + Projectile.velocity -= Projectile.velocity.RotatedBy(Projectile.spriteDirection * MathHelper.PiOver2) * Sylvestaff.StaffRecoilForce; + } + } + } + + public void RenderPixelatedPrimitives(SpriteBatch spriteBatch, PixelationPrimitiveLayer layer) + { + bool backLayer = layer == PixelationPrimitiveLayer.BeforeProjectiles; + RenderRibbon(LeftRibbon, -1, backLayer); + RenderRibbon(RightRibbon, 1, backLayer); + } + + /// + /// The function responsible for dictating the width of this staff's ribbons. + /// + private float RibbonWidthFunction(float completionRatio) => Projectile.scale * Utils.GetLerpValue(0f, 0.2f, completionRatio, true) * 3.6f; + + /// + /// The function responsible for dictating the color of this staff's ribbons. + /// + private Color RibbonColorFunction(float completionRatio) + { + Color light = Lighting.GetColor(RibbonAttachPoint.ToTileCoordinates()); + return Projectile.GetAlpha(light); + } + + /// + /// Renders one of this staff's ribbons. + /// + private void RenderRibbon(RopeHandle? ribbon, int direction, bool backLayer) + { + // Ensure that the handle is properly initialized before proceeding any further. + if (ribbon is not RopeHandle rope) + return; + + Vector2 forwardDirection = Projectile.velocity; + Vector2 sideDirection = forwardDirection.RotatedBy(MathHelper.PiOver2 * direction); + Vector2 attachmentPoint = RibbonAttachPoint; + Vector2[] ribbonPositions = [.. rope.Positions]; + int positionCount = ribbonPositions.Length; + for (int i = 0; i < ribbonPositions.Length; i++) + { + float completionRatio = i / (float)positionCount; + float wave = MathF.Cos(MathHelper.Pi * completionRatio * 1.5f - MathHelper.TwoPi * Time / 97f) * completionRatio; + + Vector2 backwardsOffset = forwardDirection * i * -RibbonLength / positionCount; + Vector2 sideWavyOffset = sideDirection * wave * RibbonLength * 0.5f; + Vector2 rigidPosition = attachmentPoint + backwardsOffset + sideWavyOffset; + + ribbonPositions[i] = Vector2.Lerp(ribbonPositions[i], rigidPosition, 0.76f); + } + + Vector2 intersectionPosition = Vector2.Transform((Projectile.Center - Main.screenPosition) * 0.5f, Main.GameViewMatrix.TransformationMatrix); + MiscShaderData ribbonShader = GameShaders.Misc["CalamityMod:SylvestaffRibbon"]; + ribbonShader.UseShaderSpecificData(new Vector4(intersectionPosition.X, intersectionPosition.Y, sideDirection.X, sideDirection.Y)); + ribbonShader.UseSaturation(backLayer ? -1f : 1f); + + PrimitiveSettings primitiveSettings = new PrimitiveSettings(RibbonWidthFunction, RibbonColorFunction, pixelate: true, shader: ribbonShader); + PrimitiveRenderer.RenderTrail(ribbonPositions, primitiveSettings, 33); + } + + public override bool PreDraw(ref Color lightColor) + { + Texture2D texture = ModContent.Request(Texture).Value; + Vector2 drawPosition = Projectile.Center - Main.screenPosition; + SpriteEffects direction = Projectile.spriteDirection == 1 ? SpriteEffects.None : SpriteEffects.FlipHorizontally; + Main.spriteBatch.Draw(texture, drawPosition, null, Projectile.GetAlpha(lightColor), Projectile.rotation, texture.Size() * 0.5f, Projectile.scale, direction, 0f); + return false; + } + + public override void OnKill(int timeLeft) + { + LeftRibbon?.Dispose(); + RightRibbon?.Dispose(); + } + + public override bool? CanDamage() => false; + } +} diff --git a/Projectiles/Melee/GayBeam.cs b/Projectiles/Melee/GayBeam.cs index 243cf93949..8da45460d2 100644 --- a/Projectiles/Melee/GayBeam.cs +++ b/Projectiles/Melee/GayBeam.cs @@ -325,7 +325,7 @@ public override bool PreDraw(ref Color lightColor) Main.spriteBatch.EnterShaderRegion(); - GameShaders.Misc["CalamityMod:ArtAttack"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/FabstaffStreak")); + GameShaders.Misc["CalamityMod:ArtAttack"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/SylvestaffStreak")); GameShaders.Misc["CalamityMod:ArtAttack"].Apply(); PrimitiveRenderer.RenderTrail(Projectile.oldPos, new(TrailWidth, TrailColor, (_) => Projectile.Size * 0.5f, shader: GameShaders.Misc["CalamityMod:ArtAttack"]), TrailLength); diff --git a/Projectiles/Melee/ViolenceThrownProjectile.cs b/Projectiles/Melee/ViolenceThrownProjectile.cs index 393fc828d1..1c270c090e 100644 --- a/Projectiles/Melee/ViolenceThrownProjectile.cs +++ b/Projectiles/Melee/ViolenceThrownProjectile.cs @@ -197,7 +197,7 @@ internal Color PrimitiveColorFunction(float completionRatio) public override bool PreDraw(ref Color lightColor) { - GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/FabstaffStreak")); + GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/SylvestaffStreak")); Texture2D spearProjectile = Terraria.GameContent.TextureAssets.Projectile[Projectile.type].Value; diff --git a/Projectiles/Ranged/ElysianArrowRain.cs b/Projectiles/Ranged/ElysianArrowRain.cs index 3bc948c3e1..c5b4384a6b 100644 --- a/Projectiles/Ranged/ElysianArrowRain.cs +++ b/Projectiles/Ranged/ElysianArrowRain.cs @@ -109,7 +109,7 @@ private Color PrimitiveColorFunction(float completionRatio) public override bool PreDraw(ref Color lightColor) { - GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/FabstaffStreak")); + GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/SylvestaffStreak")); Vector2 overallOffset = Projectile.Size * 0.5f; overallOffset += Projectile.velocity * 1.4f; int numPoints = 46; diff --git a/Projectiles/Ranged/ScorpioLargeRocket.cs b/Projectiles/Ranged/ScorpioLargeRocket.cs index d35bfbcd31..27cb29cb0b 100644 --- a/Projectiles/Ranged/ScorpioLargeRocket.cs +++ b/Projectiles/Ranged/ScorpioLargeRocket.cs @@ -219,7 +219,7 @@ public override bool PreDraw(ref Color lightColor) Vector2 rotationPoint = frame.Size() * 0.5f; // 29FEB2024: Ozzatron: hopefully ported this correctly to the new prim system by Toasty - GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(Request("CalamityMod/ExtraTextures/Trails/FabstaffStreak")); + GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(Request("CalamityMod/ExtraTextures/Trails/SylvestaffStreak")); PrimitiveRenderer.RenderTrail(Projectile.oldPos, new(TrailWidthFunction, TrailColorFunction, (_) => Projectile.Size * 0.5f, smoothen: false, shader: GameShaders.Misc["CalamityMod:TrailStreak"]), 25); Main.EntitySpriteDraw(texture, drawPosition, frame, drawColor, drawRotation, rotationPoint, Projectile.scale, SpriteEffects.None); diff --git a/Projectiles/Ranged/ScorpioRocket.cs b/Projectiles/Ranged/ScorpioRocket.cs index 4f9956a3e5..26ba2b6e9a 100644 --- a/Projectiles/Ranged/ScorpioRocket.cs +++ b/Projectiles/Ranged/ScorpioRocket.cs @@ -170,7 +170,7 @@ public override bool PreDraw(ref Color lightColor) if (Time >= TimeToLaunch) { // 29FEB2024: Ozzatron: hopefully ported this correctly to the new prim system by Toasty - GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(Request("CalamityMod/ExtraTextures/Trails/FabstaffStreak")); + GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(Request("CalamityMod/ExtraTextures/Trails/SylvestaffStreak")); PrimitiveRenderer.RenderTrail(Projectile.oldPos, new(TrailWidthFunction, TrailColorFunction, (_) => Projectile.Size * 0.5f, smoothen: false, shader: GameShaders.Misc["CalamityMod:TrailStreak"]), 25); } diff --git a/Projectiles/Ranged/TelluricGlareArrow.cs b/Projectiles/Ranged/TelluricGlareArrow.cs index 5cfd0ef4b3..559be7fd60 100644 --- a/Projectiles/Ranged/TelluricGlareArrow.cs +++ b/Projectiles/Ranged/TelluricGlareArrow.cs @@ -100,7 +100,7 @@ private Color PrimitiveColorFunction(float completionRatio) public override bool PreDraw(ref Color lightColor) { - GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/FabstaffStreak")); + GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/SylvestaffStreak")); Vector2 overallOffset = Projectile.Size * 0.5f; overallOffset += Projectile.velocity * 1.4f; int numPoints = 92; diff --git a/Projectiles/Summon/LiliesOfEternityBullet.cs b/Projectiles/Summon/LiliesOfEternityBullet.cs index 5cbe15d4d7..12a5e0cf8c 100644 --- a/Projectiles/Summon/LiliesOfEternityBullet.cs +++ b/Projectiles/Summon/LiliesOfEternityBullet.cs @@ -11,7 +11,7 @@ namespace CalamityMod.Projectiles.Summon public class LiliesOfEternityBullet : ModProjectile, ILocalizedModType, IPixelatedPrimitiveRenderer { public new string LocalizationCategory => "Projectiles.Summon"; - + public override string Texture => "CalamityMod/Projectiles/InvisibleProj"; public override void SetStaticDefaults() @@ -60,9 +60,9 @@ private float PrimitiveWidthFunction(float completionRatio) private Color PrimitiveColorFunction(float completionRatio) => Color.Lerp(Color.DarkGoldenrod, Color.LightGoldenrodYellow, completionRatio); - public void RenderPixelatedPrimitives(SpriteBatch spriteBatch) + public void RenderPixelatedPrimitives(SpriteBatch spriteBatch, PixelationPrimitiveLayer layer) { - GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/FabstaffStreak")); + GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/SylvestaffStreak")); PrimitiveRenderer.RenderTrail(Projectile.oldPos, new(PrimitiveWidthFunction, PrimitiveColorFunction, (_) => Projectile.Size * 0.5f, pixelate: true, shader: GameShaders.Misc["CalamityMod:TrailStreak"])); } } diff --git a/Projectiles/Summon/LiliesOfFinalityBullet.cs b/Projectiles/Summon/LiliesOfFinalityBullet.cs index 7dd9798613..19a527e5d2 100644 --- a/Projectiles/Summon/LiliesOfFinalityBullet.cs +++ b/Projectiles/Summon/LiliesOfFinalityBullet.cs @@ -64,9 +64,9 @@ private float PrimitiveWidthFunction(float completionRatio) private Color PrimitiveColorFunction(float completionRatio) => Color.Lerp(Color.DarkGoldenrod, Color.LightGoldenrodYellow, completionRatio); - public void RenderPixelatedPrimitives(SpriteBatch spriteBatch) + public void RenderPixelatedPrimitives(SpriteBatch spriteBatch, PixelationPrimitiveLayer layer) { - GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/FabstaffStreak")); + GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/SylvestaffStreak")); PrimitiveRenderer.RenderTrail(Projectile.oldPos, new(PrimitiveWidthFunction, PrimitiveColorFunction, (_) => Projectile.Size * 0.5f, pixelate: true, shader: GameShaders.Misc["CalamityMod:TrailStreak"])); } } diff --git a/Sounds/Item/SylvestaffFire1.ogg b/Sounds/Item/SylvestaffFire1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..56864c877caa5bb8427684995a2ee451d1e0898a GIT binary patch literal 22126 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

v{0|gs{*+@#(Ko7*X&!Q$6S&n}jnI_kKU1Hh%Dm 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 literal 0 HcmV?d00001 diff --git a/Sounds/Item/SylvestaffFire2.ogg b/Sounds/Item/SylvestaffFire2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..79ca7e1fa9111145efc2dfef12ee8c6bf4f038e7 GIT binary patch literal 26358 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 literal 0 HcmV?d00001 diff --git a/Sounds/Item/SylvestaffProjectileBounce1.ogg b/Sounds/Item/SylvestaffProjectileBounce1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..dbe4a38b8efbf30f264b1cf8504045eb5c24b879 GIT binary patch literal 26223 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 literal 0 HcmV?d00001 diff --git a/Sounds/Item/SylvestaffProjectileBounce2.ogg b/Sounds/Item/SylvestaffProjectileBounce2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..81d1d354e493568de99177596f2e3d6db2b96976 GIT binary patch literal 24996 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 F{{sc#(jWi; literal 0 HcmV?d00001 diff --git a/Sounds/Item/SylvestaffProjectileBounce3.ogg b/Sounds/Item/SylvestaffProjectileBounce3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..4cbae2723f5cfb3d77a5879c3db9e09948af264f GIT binary patch literal 32705 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 literal 0 HcmV?d00001 diff --git a/Utilities/MathematicalUtils.cs b/Utilities/MathematicalUtils.cs index 1813494294..ebffdda57e 100644 --- a/Utilities/MathematicalUtils.cs +++ b/Utilities/MathematicalUtils.cs @@ -220,6 +220,36 @@ public static float Modulo(this float dividend, float divisor) /// The input value. public static int DirectionalSign(this float x) => (x > 0f).ToDirectionInt(); + ///

+ /// Approximates the derivative of a function at a given point based on a central-difference formula. + /// + /// The function to take the derivative of. + /// The value to evaluate the derivative at. + public static double ApproximateDerivative(this Func fx, double x) + { + double left = fx(x + 1e-7); + double right = fx(x - 1e-7); + return (left - right) * 5e6; + } + + /// + /// Searches for an approximate for a root of a given function. + /// + /// The function to find the root for. + /// The initial guess for what the root could be. + /// The amount of iterations to perform. The higher this is, the more generally accurate the result will be. + public static double IterativelySearchForRoot(Func fx, double initialGuess, int iterations) + { + double result = initialGuess; + for (int i = 0; i < iterations; i++) + { + double derivative = (float)fx.ApproximateDerivative(result); + result -= fx(result) / derivative; + } + + return result; + } + #region Easings ///
/// Gets a value from 0 to 1 and returns an eased value. From 0e6174ba7a4c289a319bdfb5be77eb3b587d116b Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Wed, 28 May 2025 21:16:52 -0400 Subject: [PATCH 262/401] Two Sylvestaff fixes 1 - Fixed the weapon not consuming mana 2 - Fixed being able to spam the weapon to fire rays faster than intended --- Projectiles/Magic/SylvestaffHoldout.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projectiles/Magic/SylvestaffHoldout.cs b/Projectiles/Magic/SylvestaffHoldout.cs index 62fd45e760..3109ae5bff 100644 --- a/Projectiles/Magic/SylvestaffHoldout.cs +++ b/Projectiles/Magic/SylvestaffHoldout.cs @@ -171,7 +171,7 @@ private void FireAwesomeMagicRays() if (heldItem is null) return; - if (Time % heldItem.useAnimation == 0) + if (Time % heldItem.useAnimation == heldItem.useAnimation - 1 && Owner.CheckMana(heldItem.mana, true)) { SoundEngine.PlaySound(Sylvestaff.FireSound, Projectile.Center); if (Main.myPlayer == Projectile.owner) From 7ffce47503f6bc694a20979b6137a82a00e71caf Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Wed, 28 May 2025 21:24:04 -0400 Subject: [PATCH 263/401] Also made it not use mana from spawning holdout --- Items/Weapons/Magic/Sylvestaff.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Items/Weapons/Magic/Sylvestaff.cs b/Items/Weapons/Magic/Sylvestaff.cs index 8ea214fff5..e905c947f1 100644 --- a/Items/Weapons/Magic/Sylvestaff.cs +++ b/Items/Weapons/Magic/Sylvestaff.cs @@ -86,6 +86,11 @@ public override void SetDefaults() Item.shootSpeed = 13.5f; } + public override void ModifyManaCost(Player player, ref float reduce, ref float mult) + { + if (player.ownedProjectileCounts[Item.shoot] <= 0) + mult *= 0; + } public override void AddRecipes() { CreateRecipe(). From 3bd4d03f11acf5ea1f485e7b814a94094f29f2ca Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Thu, 29 May 2025 21:58:30 -0400 Subject: [PATCH 264/401] Princess no longer misgenders Bandit --- Localization/en-US/Mods.CalamityMod.NPCs.hjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/en-US/Mods.CalamityMod.NPCs.hjson b/Localization/en-US/Mods.CalamityMod.NPCs.hjson index e8b92904e0..2e1b5a6a8e 100644 --- a/Localization/en-US/Mods.CalamityMod.NPCs.hjson +++ b/Localization/en-US/Mods.CalamityMod.NPCs.hjson @@ -481,7 +481,7 @@ THIEF: { LikeNPC: "{NPCName} doesn't only keep spiky balls in his pockets, he keeps a ton of cash! He's too absentminded to notice I'm stealing from him too! I like that a lot!" DislikeNPC: What a goody two shoes, {NPCName} is! I dislike her out of principle! …And because she has almost no material goods. LikeNPC_Princess: I couldn't bear to steal anything from {NPCName}, she's so cute! - Princess_LovesNPC: "{NPCName} gifts me with nice exact replicas of other's things, I wonder how she does it!" + Princess_LovesNPC: "{NPCName} gifts me with nice exact replicas of other's things, I wonder how they do it!" } } From 6f2c7e4bf52c5808fbc9febe5644a16d5284c88b Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Wed, 28 May 2025 18:05:25 -0400 Subject: [PATCH 265/401] Buzzkill --- Buffs/DamageOverTime/HeavyBleeding.cs | 74 +++++ Buffs/DamageOverTime/HeavyBleeding.png | Bin 0 -> 638 bytes CalPlayer/CalamityPlayer.cs | 3 + CalPlayer/CalamityPlayerDrawEffects.cs | 3 + CalPlayer/CalamityPlayerHitHurt.cs | 4 + CalPlayer/CalamityPlayerLifeRegen.cs | 1 + CalamityLists.cs | 2 +- Gores/BuzzkillSaw1.png | Bin 0 -> 348 bytes Gores/BuzzkillSaw2.png | Bin 0 -> 455 bytes Gores/BuzzkillSaw3.png | Bin 0 -> 591 bytes Items/Weapons/Ranged/Butcher.png | Bin 998 -> 0 bytes .../Ranged/{Butcher.cs => Buzzkill.cs} | 44 +-- Items/Weapons/Ranged/Buzzkill.png | Bin 0 -> 1951 bytes .../en-US/Mods.CalamityMod.Buffs.hjson | 5 + ...ods.CalamityMod.Items.Weapons.Ranged.hjson | 10 +- .../Mods.CalamityMod.Projectiles.Ranged.hjson | 1 + .../en-US/Mods.CalamityMod.Status.Death.hjson | 3 + ModSupport/WeakReferenceSupport.cs | 1 - NPCs/CalamityGlobalNPC.cs | 10 + Projectiles/Ranged/ButcherGun.cs | 164 ----------- Projectiles/Ranged/BuzzkillHoldout.cs | 261 ++++++++++++++++++ Projectiles/Ranged/BuzzkillHoldout.png | Bin 0 -> 3026 bytes Projectiles/Ranged/BuzzkillSaw.cs | 214 ++++++++++++++ Projectiles/Ranged/BuzzkillSaw.png | Bin 0 -> 2026 bytes Projectiles/Ranged/BuzzkillSawLargeSlash.png | Bin 0 -> 2353 bytes Projectiles/Ranged/BuzzkillSawSmallSlash.png | Bin 0 -> 1102 bytes Sounds/Custom/BuzzsawCharge.ogg | Bin 0 -> 39758 bytes Sounds/Custom/BuzzsawIdle.ogg | Bin 0 -> 94549 bytes Sounds/Custom/MetalPipeFalling.ogg | Bin 0 -> 47413 bytes Sounds/Item/SawShot1.ogg | Bin 0 -> 12254 bytes Sounds/Item/SawShot2.ogg | Bin 0 -> 12342 bytes 31 files changed, 610 insertions(+), 190 deletions(-) create mode 100644 Buffs/DamageOverTime/HeavyBleeding.cs create mode 100644 Buffs/DamageOverTime/HeavyBleeding.png create mode 100644 Gores/BuzzkillSaw1.png create mode 100644 Gores/BuzzkillSaw2.png create mode 100644 Gores/BuzzkillSaw3.png delete mode 100644 Items/Weapons/Ranged/Butcher.png rename Items/Weapons/Ranged/{Butcher.cs => Buzzkill.cs} (57%) create mode 100644 Items/Weapons/Ranged/Buzzkill.png delete mode 100644 Projectiles/Ranged/ButcherGun.cs create mode 100644 Projectiles/Ranged/BuzzkillHoldout.cs create mode 100644 Projectiles/Ranged/BuzzkillHoldout.png create mode 100644 Projectiles/Ranged/BuzzkillSaw.cs create mode 100644 Projectiles/Ranged/BuzzkillSaw.png create mode 100644 Projectiles/Ranged/BuzzkillSawLargeSlash.png create mode 100644 Projectiles/Ranged/BuzzkillSawSmallSlash.png create mode 100644 Sounds/Custom/BuzzsawCharge.ogg create mode 100644 Sounds/Custom/BuzzsawIdle.ogg create mode 100644 Sounds/Custom/MetalPipeFalling.ogg create mode 100644 Sounds/Item/SawShot1.ogg create mode 100644 Sounds/Item/SawShot2.ogg diff --git a/Buffs/DamageOverTime/HeavyBleeding.cs b/Buffs/DamageOverTime/HeavyBleeding.cs new file mode 100644 index 0000000000..340845ce9e --- /dev/null +++ b/Buffs/DamageOverTime/HeavyBleeding.cs @@ -0,0 +1,74 @@ +using CalamityMod.Particles; +using Microsoft.Xna.Framework; +using System; +using Terraria; +using Terraria.DataStructures; +using Terraria.ID; +using Terraria.ModLoader; + +namespace CalamityMod.Buffs.DamageOverTime +{ + public class HeavyBleeding : ModBuff + { + public override void SetStaticDefaults() + { + Main.debuff[Type] = true; + Main.pvpBuff[Type] = true; + Main.buffNoSave[Type] = true; + BuffID.Sets.LongerExpertDebuff[Type] = true; + } + + public override void Update(Player player, ref int buffIndex) + { + player.Calamity().heavybleeding = true; + } + + public override void Update(NPC npc, ref int buffIndex) + { + if (npc.Calamity().heavybleeding < npc.buffTime[buffIndex]) + npc.Calamity().heavybleeding = npc.buffTime[buffIndex]; + npc.DelBuff(buffIndex); + buffIndex--; + } + internal static void DrawEffects(PlayerDrawSet drawInfo) + { + Player player = drawInfo.drawPlayer; + var modPlayer = player.Calamity(); + + if (Main.rand.NextBool(3)) + { + Vector2 randVel = new Vector2(5, 5).RotatedByRandom(100) * Main.rand.NextFloat(0.3f, 1f); + Dust dust = Dust.NewDustPerfect(modPlayer.RandomDebuffVisualSpot, 5, randVel * Main.rand.NextFloat(0.1f, 0.8f), 100, default, Main.rand.NextFloat(0.6f, 0.9f)); + dust.noGravity = false; + Particle spark = new AltSparkParticle(modPlayer.RandomDebuffVisualSpot, randVel + new Vector2(0, -4), true, 12, Main.rand.NextFloat(0.25f, 0.6f), Color.DarkRed * 0.5f); + GeneralParticleHandler.SpawnParticle(spark); + } + if (Main.rand.NextBool(8)) + { + Particle spark = new GlowOrbParticle(modPlayer.RandomDebuffVisualSpot, new Vector2(0, 4) * Main.rand.NextFloat(0.5f, 0.7f), true, 16, Main.rand.NextFloat(0.55f, 0.8f), Color.DarkRed * 0.8f, false, false, false); + GeneralParticleHandler.SpawnParticle(spark); + } + } + + internal static void DrawEffects(NPC npc, ref Color drawColor) + { + Vector2 npcSize = npc.Center + new Vector2(Main.rand.NextFloat(-npc.width / 2, npc.width / 2), Main.rand.NextFloat(-npc.height / 2, npc.height / 2)); + Vector2 randVel = new Vector2(5, 5).RotatedByRandom(100) * Main.rand.NextFloat(0.3f, 1f); + if (Main.rand.NextBool(5)) + { + Particle spark = new AltSparkParticle(npcSize, randVel + new Vector2(0, -4), true, 12, Main.rand.NextFloat(0.25f, 0.6f), Color.DarkRed * 0.5f); + GeneralParticleHandler.SpawnParticle(spark); + } + else + { + Dust dust = Dust.NewDustPerfect(npcSize, 5, randVel * Main.rand.NextFloat(0.1f, 0.8f), 100, default, Main.rand.NextFloat(0.2f, 0.6f)); + dust.noGravity = false; + } + if (Main.rand.NextBool(8)) + { + Particle spark = new GlowOrbParticle(npcSize, new Vector2(0, 4) * Main.rand.NextFloat(0.5f, 0.7f), true, 16, Main.rand.NextFloat(0.55f, 0.8f), Color.DarkRed * 0.8f, false, false, false); + GeneralParticleHandler.SpawnParticle(spark); + } + } + } +} diff --git a/Buffs/DamageOverTime/HeavyBleeding.png b/Buffs/DamageOverTime/HeavyBleeding.png new file mode 100644 index 0000000000000000000000000000000000000000..b5e2e696515425a42c3db88d3650930982241092 GIT binary patch literal 638 zcmV-^0)hRBP)Px#1ZP1_K>z@;j|==^1poj74oO5oR9HvNR?XtDQTnCxYDZr_{P*)x=3+st_O z3#KpQQCM>m*{|_%ZNJ1Hy0*OA$|xa>X0Dm7lKf5Ui__w-?mxr>c&>qYMe7cX6Q5pz z6&n?3M4|&|MWDnD4a!DPq>vtC9cti`D&othKrd1|1Ub*7GMi${+1X#i`m*`WA*e|}c{PU}@X&beL>AWoTUzztLx2K2Z$UP^FS!DyUa3p3+H`R*xUB$vE1sBKLl4;N*Tmxr8{eEpn;7(7qMS)!j`Q2Z`N`Wmn%&(), ProjectileType(), ProjectileType(), - ProjectileType(), + ProjectileType(), ProjectileType(), ProjectileType(), ProjectileType(), diff --git a/Gores/BuzzkillSaw1.png b/Gores/BuzzkillSaw1.png new file mode 100644 index 0000000000000000000000000000000000000000..c79c2667d99aa4307c28d5c0ee36d5a0f102c176 GIT binary patch literal 348 zcmV-i0i*tjP)Px$7D+@wR5*>bls{|2Kp2Og6SYAR>L5Z8S`Zh%Kt6%9`z_8L`vv?89bH|L!MT%8 z1(%@TKn#KsDAEcY#7^m8F3AOg6wY^h@6Yd^`@Qd-pdh4_THdjn035! zktd^J7l8G03c&uWb=|Rk&uiStqr4}I65rR$`eJRB0Qc1z+Px$fk{L`R5*>b)GT(v8eV_&T?ZZH`z`-J{|A3Q@AtmH7u~x# z4c>j&PM}gQf%V2FI8`|o!RM`SV0dr<+`0cyr|Ri=`X5!;ZKZc!y)ptWkKY1IuOEX4 zi!U?sGiT35FkhSLC_Q*#>qk!luikzEqhoKt*u`t9ys?&%FU-v*P#rnhQF`FQXudX+ zz@_s;;Apv;5w_Q-we$@hEk4CwPgmYA=Om2dIP(=Jr($rTdZDWe7UpKb&evv?i?9$j zp@-edUOc;j%tRrN9$v3afQ?2o+5h0~?KEHi67QR+e1wIKMlETPsppl$u!-X|f5rYj@O`(H$!Gf{9WS2-t4q(pllsS;h22U+1#$RG6%YT)XHxzW xwo8Wxi=e;vP`dW@X7XA(Qix!4`=?xlzX6v(bd=AWUts_M002ovPDHLkV1m*U&XfQE literal 0 HcmV?d00001 diff --git a/Gores/BuzzkillSaw3.png b/Gores/BuzzkillSaw3.png new file mode 100644 index 0000000000000000000000000000000000000000..aa75e67d97fd526d7425c8d472d4f36901e85086 GIT binary patch literal 591 zcmV-V071Q{00001b5ch_0Itp) z=>Px%2}wjjR7i=%);~yDq{d$BO?eU`&>&Uw#!zVGup zzw<`ddoF;l6Z1J}Ozl)EX6NRkq+KZJ9~v4eIlo-2`={CeA=U@7v!|LtO)3rEzMlhe z`~}R;E##Iz*m|HTg3A}rhjFYI-kS8{NvD}#Iu1IcPNO{bd+@?|PT zH3);N_b$17x;b(Ea2xdXCq$n{o}fHoxJQW#@;FYk5zc$%y|lO^kREDF?!OQ3MswtM zc(v;|@{aWM;Z5Y#U7UAzc7jbCH&n-IRuF~=q_cDLpsscc_?(?A_`3__Px&ph-kQRA_H5f)*iSi4oCCf+&hMF8Tu^=*Oml z7J=ZZ7PW2HCWxR-i-?fGl87LqB#|J~g_&mA51Vo3wRm%!xu^H$s+qNTpUs>5-hKDp zH|KlLIrm<}Dv@g3AwRw1`z_nI8Gw=3LjVkqzFMszEsEH`9>D)j`M>J;k4?s)-w43v1(Ryub>1W->nwK*q}fk%F9*2Us`|S9A%Rb zHO@#u4os?XN69&vs!SMwPubG$Dv^IY=MmW6roFoY-+TAyIZ#kektKnGrS<)`YCqbw zojn7>*{@uC_0IW;a0r2cWKM*O%$-+dJyd-|(npNTEWX4iN zecV`5n#gz_z+ApoQ{3(#x7$`u`<{J3A!o)&=QMhFIk%Am7L@~*1dyk#4Ds-&16{7Q# zb%7 diff --git a/Items/Weapons/Ranged/Butcher.cs b/Items/Weapons/Ranged/Buzzkill.cs similarity index 57% rename from Items/Weapons/Ranged/Butcher.cs rename to Items/Weapons/Ranged/Buzzkill.cs index 48ec12ad69..b5a9e54ea7 100644 --- a/Items/Weapons/Ranged/Butcher.cs +++ b/Items/Weapons/Ranged/Buzzkill.cs @@ -1,5 +1,4 @@ -using CalamityMod.Items.Materials; -using CalamityMod.Projectiles.Ranged; +using CalamityMod.Projectiles.Ranged; using Microsoft.Xna.Framework; using Terraria; using Terraria.DataStructures; @@ -8,51 +7,56 @@ namespace CalamityMod.Items.Weapons.Ranged { - public class Butcher : ModItem, ILocalizedModType + [LegacyName("Butcher")] + public class Buzzkill : ModItem, ILocalizedModType { public new string LocalizationCategory => "Items.Weapons.Ranged"; + + public override void SetStaticDefaults() + { + ItemID.Sets.IsRangedSpecialistWeapon[Type] = true; + } + public override void SetDefaults() { - Item.width = 20; - Item.height = 12; - Item.damage = 15; - Item.useTime = 40; - Item.useAnimation = 40; + Item.width = 76; + Item.height = 42; + Item.damage = 56; + Item.useTime = 30; + Item.useAnimation = 30; Item.useStyle = ItemUseStyleID.Shoot; Item.knockBack = 1f; Item.value = CalamityGlobalItem.RarityLightRedBuyPrice; Item.rare = ItemRarityID.LightRed; - Item.UseSound = SoundID.Item38; Item.noMelee = true; Item.noUseGraphic = true; Item.DamageType = DamageClass.Ranged; Item.channel = true; Item.autoReuse = true; - Item.shoot = ModContent.ProjectileType(); - Item.shootSpeed = 12f; - Item.useAmmo = AmmoID.Bullet; + Item.shoot = ModContent.ProjectileType(); + Item.shootSpeed = 20f; Item.Calamity().canFirePointBlankShots = true; } - public override bool CanUseItem(Player player) => player.ownedProjectileCounts[Item.shoot] <= 0; + // Terraria seems to really dislike high crit values in SetDefaults + public override void ModifyWeaponCrit(Player player, ref float crit) => crit += 21; - // Spawning the holdout cannot consume ammo - public override bool CanConsumeAmmo(Item ammo, Player player) => !Main.rand.NextBool(4) && player.ownedProjectileCounts[Item.shoot] > 0; + public override bool CanUseItem(Player player) => player.ownedProjectileCounts[Item.shoot] <= 0; public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) { - Projectile.NewProjectile(source, position, velocity, ModContent.ProjectileType(), damage, knockback, player.whoAmI, 0f, 0f); + // The holdout deals 1.5x base damage. + Projectile.NewProjectile(source, position, velocity, ModContent.ProjectileType(), (int)(damage * 1.5), knockback, player.whoAmI); return false; } public override void AddRecipes() { CreateRecipe(). - AddIngredient(ItemID.Shotgun). AddIngredient(ItemID.IllegalGunParts). - AddRecipeGroup("AnyCobaltBar", 5). - AddIngredient(4). - AddTile(TileID.Anvils). + AddIngredient(ItemID.Cog, 15). + AddIngredient(ItemID.SoulofFright, 10). + AddTile(TileID.MythrilAnvil). Register(); } } diff --git a/Items/Weapons/Ranged/Buzzkill.png b/Items/Weapons/Ranged/Buzzkill.png new file mode 100644 index 0000000000000000000000000000000000000000..7ec3235634d942a28ece3098fe56322de449d833 GIT binary patch literal 1951 zcmV;Q2VnS#P)Px+SxH1eRA_D-*a8peciXke_RK%vjLcvnkpaU&j8?L{V(=#{dU-q#}>egwuItt%kRr{e$V2^QrQj;h_B&^}-ovc7!V-CUlG#Spbhc@-P6YlO_W2<~tw6TxUR-Pelk*5>jSN1|VVlH~=Q5O&Zg{ z16_RpoICpm06o8T#`J0v(vmEIhjQiuaQ4PLd0>*IL~YsvKtoeg%z5XPm%HkZR!IHu zzHI=M-TkTzSGx&-_bR`!AxhqL^A}hE&#!tC7)n||m`_rD+W?zyC zTK4|R#pA7iP2SwIFMi;9USR!h0b~#M+5juJzas;TK$gZ^WtKR6^`aZXVE}HfdIf;= zjB5bM$}MvD|NJHC?~u1<^$GxTXI*6hgc~J(Q_=#$d@9}~>%ph*1E6e4F%W$tt>L`@ zoM=A;Kv%oG!Pd^Ht^u!~CpJ&tsM?OrTN?q`@pWCyg>3KcumM8XiY@aZ%Oq-LZm#RO zDP5R z>?QTLt8e<2(i;Hij@T9=`l_JAXU}KtaVi0KPbN9Dv##@5k(B z+LA~d=Xg`oTMmi%bx)}_&By;N zZ}NGY6Rzde32DvkLcqtBAI9vKHCb$xM&kG5kmfvJ?vyQU{Xo>ltyEjHS_D9W z^Gi`OP12NTQ>M2J2=l23VY=s1@1zlVfi`d==rZ+^j(20H*s{eV1pMEr)7vUVdWR6O zZtYH2JB|AywzN~?!m=eo+Ik~_tMS#n*DQ3cbA3jJl#%R+)4?H2cLM4K_4}(de$y<* zu6oI01cdoi)Jr;92Ys_jTHHj5aMdQL_o;O1JC0lhz?L>?*Kr|s#2@NP2jI}L697z& z6I4p3c&zMzn{;ovvmd(77AH>JSXu4*J`H>JxZ3~RAerHCxEFxjT-kY~380aDSzyD) zC~Hw(p)13x@t1n3SJ!+6z_LFi{uvVInEL+v(ao$`1(n82g+hj&E7pt?a!1MlD?#Qu zO=-NA`mBr}4mY}P2su>oN|W!+Y^7=SZf{V_LTX1=RrN>;39W7dKJgWM5v z@}rFxYn;eD?eiJ{y6#>k<1I`EU{`%_%zpY@<3F7**h`L4mU%KgIZ^(H7Y60Wep9|g z&Skd>Sx3X-RhpW*0oZ+1BJJd&d?0EAzpectX1(qkcig3_7@r7S6p1^8?Jq3_qIolY z^JC3#d6A{IOQkkk_pq56R|FZ?u_#{eG%U@NNO``KQB96>cK;q^<>aKg2HL&%C;*>0 z-b!tsdasPxS6TpR>EiYJPxSzhmNZQ!a=e?Flh+ezjkrfEzho&<8sQg~J^{eyt+H!v zYd;MHg!$Hx+dDrs_SpchKRP#N2a`CpVf`2SEr8>FT{b{cVzLF$|GSXX?(8M&Lk&Rm zF2|fd2Q*-Ed1>{UCkD=15Iw!ob3^mIbR?VRWusapdqo@sblJ08xVSb0@h_wI-wPght67QpFoLbPTPo~pPFi0=K&TRCRkJPnHc9}Jsi-hB-S^Qj17v!+VE zYD!`X0IB2UmT{=N%SD{m7~4Yie`_ILq?uYUU2ZJe*UC-BDU; to rev up a buzzsaw that deals close-range damage + Release to fire the buzzsaw, which bounces off tiles and lacerates foes + Revving up the saws increases their damage and allows them to pierce more enemies + 'Not to be confused with the Sawed-On Shotgun' ''' } diff --git a/Localization/en-US/Mods.CalamityMod.Projectiles.Ranged.hjson b/Localization/en-US/Mods.CalamityMod.Projectiles.Ranged.hjson index c4e34d00a8..4d89597d45 100644 --- a/Localization/en-US/Mods.CalamityMod.Projectiles.Ranged.hjson +++ b/Localization/en-US/Mods.CalamityMod.Projectiles.Ranged.hjson @@ -35,6 +35,7 @@ BouncingShotgunPellet.DisplayName: Shotgun Pellet BrimstoneBolt.DisplayName: Brimstone Bolt BrimstoneFireFriendly.DisplayName: Brimstone Fire BubonicRoundProj.DisplayName: Bubonic Round +BuzzkillSaw.DisplayName: Buzzsaw CardClub.DisplayName: Club CardClubSplit.DisplayName: Club CardDiamond.DisplayName: Diamond diff --git a/Localization/en-US/Mods.CalamityMod.Status.Death.hjson b/Localization/en-US/Mods.CalamityMod.Status.Death.hjson index 7a65173f13..652459c985 100644 --- a/Localization/en-US/Mods.CalamityMod.Status.Death.hjson +++ b/Localization/en-US/Mods.CalamityMod.Status.Death.hjson @@ -63,6 +63,9 @@ GodSlayerInferno1: "{0} imploded into nothingness." GodSlayerInferno2: "{0}'s body slipped into oblivion." GodSlayerInferno3: "{0} ceased being a part of our universe." Goldfish: "{0} was once again impaled by Goldfish." +HeavyBleeding1: "{0} expired from heavy internal bleeding." +HeavyBleeding2: "{0} forgot that blood is supposed to stay inside the body." +HeavyBleeding3: "{0} bled profusely to their last breath." HolyFlames1: "{0} fell prey to their sins." HolyFlames2: "{0} burst into sinless ash." HolyFlames3: "{0} was purified by the profaned flame." diff --git a/ModSupport/WeakReferenceSupport.cs b/ModSupport/WeakReferenceSupport.cs index 16293e26d9..fbf4dbf23b 100644 --- a/ModSupport/WeakReferenceSupport.cs +++ b/ModSupport/WeakReferenceSupport.cs @@ -235,7 +235,6 @@ public static void WikiThisSupport() ItemRedirect(ItemType(), "Elderberry (calamity)"); ItemRedirect(ItemType(), "Pineapple (calamity)"); ItemRedirect(ItemType(), "Trash Can (pet)"); - ItemRedirect(ItemType(), "Butcher (weapon)"); ItemRedirect(ItemType(), "Sandstorm (weapon)"); ItemRedirect(ItemType(), "Thunderstorm (weapon)"); // Lore items diff --git a/NPCs/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index 16953423cf..96be2c2f7a 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -244,6 +244,7 @@ public partial class CalamityGlobalNPC : GlobalNPC public int pearlAura = 0; public int bBlood = 0; public int brainRot = 0; + public int heavybleeding = 0; public int elementalMix = 0; public int marked = 0; public int absorberAffliction = 0; @@ -462,6 +463,7 @@ public override GlobalNPC Clone(NPC npc, NPC npcClone) myClone.pearlAura = pearlAura; myClone.bBlood = bBlood; myClone.brainRot = brainRot; + myClone.heavybleeding = heavybleeding; myClone.elementalMix = elementalMix; myClone.marked = marked; myClone.absorberAffliction = absorberAffliction; @@ -1105,6 +1107,8 @@ public override void UpdateLifeRegen(NPC npc, ref int damage) ApplyDPSDebuff(40, 10, ref npc.lifeRegen, ref damage); if (brainRot > 0) ApplyDPSDebuff(40, 10, ref npc.lifeRegen, ref damage); + if (heavybleeding > 0) + ApplyDPSDebuff(80, 10, ref npc.lifeRegen, ref damage); if (elementalMix > 0) ApplyDPSDebuff(400, 80, ref npc.lifeRegen, ref damage); if (miracleBlight > 0) @@ -5066,6 +5070,8 @@ public override void PostAI(NPC npc) bBlood--; if (brainRot > 0) brainRot--; + if (heavybleeding > 0) + heavybleeding--; if (elementalMix > 0) elementalMix--; if (vulnerabilityHex > 0) @@ -6352,6 +6358,9 @@ public override void DrawEffects(NPC npc, ref Color drawColor) if (hFlames > 0 || banishingFire > 0) HolyFlames.DrawEffects(npc, ref drawColor); + if (heavybleeding > 0) + HeavyBleeding.DrawEffects(npc, ref drawColor); + // These draw effects do not include Miracle Blight's shader if (miracleBlight > 0) MiracleBlight.DrawEffects(npc, ref drawColor); @@ -6545,6 +6554,7 @@ public override void DrawEffects(NPC npc, ref Color drawColor) ("CalamityMod/Buffs/DamageOverTime/Dragonfire", NPC => NPC.Calamity().dragonFire > 0), ("CalamityMod/Buffs/DamageOverTime/ElementalMix", NPC => NPC.Calamity().elementalMix > 0), ("CalamityMod/Buffs/DamageOverTime/GodSlayerInferno", NPC => NPC.Calamity().gsInferno > 0), + ("CalamityMod/Buffs/DamageOverTime/HeavyBleeding", NPC => NPC.Calamity().heavybleeding > 0), ("CalamityMod/Buffs/DamageOverTime/HolyFlames", NPC => NPC.Calamity().hFlames > 0), ("CalamityMod/Buffs/DamageOverTime/MiracleBlight", NPC => NPC.Calamity().miracleBlight > 0), ("CalamityMod/Buffs/DamageOverTime/Nightwither", NPC => NPC.Calamity().nightwither > 0), diff --git a/Projectiles/Ranged/ButcherGun.cs b/Projectiles/Ranged/ButcherGun.cs deleted file mode 100644 index ea90fbc25e..0000000000 --- a/Projectiles/Ranged/ButcherGun.cs +++ /dev/null @@ -1,164 +0,0 @@ -using System; -using CalamityMod.Items.Weapons.Ranged; -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.Audio; -using Terraria.ID; -using Terraria.Localization; -using Terraria.ModLoader; - -namespace CalamityMod.Projectiles.Ranged -{ - public class ButcherGun : ModProjectile - { - public override LocalizedText DisplayName => CalamityUtils.GetItemName(); - public override string Texture => "CalamityMod/Items/Weapons/Ranged/Butcher"; - - public override void SetDefaults() - { - Projectile.width = 66; - Projectile.height = 32; - Projectile.friendly = true; - Projectile.penetrate = -1; - Projectile.tileCollide = false; - Projectile.DamageType = DamageClass.Ranged; - Projectile.ignoreWater = true; - } - - public override void AI() - { - Player player = Main.player[Projectile.owner]; - Projectile.ai[0] += 1f; - int incrementAmt = 0; - float spreadMult = 0.15f; - if (Projectile.ai[0] >= 80f) - { - incrementAmt++; - spreadMult = 0.13f; - } - if (Projectile.ai[0] >= 160f) - { - incrementAmt++; - spreadMult = 0.11f; - } - if (Projectile.ai[0] >= 240f) - { - incrementAmt++; - spreadMult = 0.09f; - } - if (Projectile.ai[0] >= 320f) - { - incrementAmt++; - spreadMult = 0.07f; - } - if (Projectile.ai[0] >= 400f) - { - incrementAmt++; - spreadMult = 0.05f; - } - if (Projectile.ai[0] >= 480f) - { - incrementAmt++; - spreadMult = 0.04f; - } - if (Projectile.ai[0] >= 560f) - { - incrementAmt++; - spreadMult = 0.03f; - } - if (Projectile.ai[0] >= 640f) //8 - { - incrementAmt++; - spreadMult = 0.02f; - } - int shootDelayBase = 40; - int incrementMult = 3; - Projectile.ai[1] -= 1f; - bool willShoot = false; - if (Projectile.ai[1] <= 0f) - { - Projectile.ai[1] = (float)(shootDelayBase - incrementMult * incrementAmt); - willShoot = true; - } - bool canShoot = !player.CantUseHoldout() && player.HasAmmo(player.ActiveItem()); - if (Projectile.localAI[0] > 0f) - { - Projectile.localAI[0] -= 1f; - } - if (Projectile.soundDelay <= 0 && canShoot) - { - Projectile.soundDelay = shootDelayBase - incrementMult * incrementAmt; - if (Projectile.ai[0] != 1f) - { - SoundEngine.PlaySound(SoundID.Item38, Projectile.position); - } - Projectile.localAI[0] = 12f; - } - Vector2 source = player.RotatedRelativePoint(player.MountedCenter, true); - if (willShoot && Main.myPlayer == Projectile.owner) - { - int projType = ProjectileID.Bullet; - float speedMult = 14f; - int damage = player.GetWeaponDamage(player.ActiveItem()); - float kback = player.ActiveItem().knockBack; - if (canShoot) - { - player.PickAmmo(player.ActiveItem(), out projType, out speedMult, out damage, out kback, out _); - kback = player.GetWeaponKnockback(player.ActiveItem(), kback); - float speed = player.ActiveItem().shootSpeed * Projectile.scale; - Vector2 targetPos = Main.screenPosition + new Vector2((float)Main.mouseX, (float)Main.mouseY) - source; - if (player.gravDir == -1f) - { - targetPos.Y = (float)(Main.screenHeight - Main.mouseY) + Main.screenPosition.Y - source.Y; - } - Vector2 velMult = Vector2.Normalize(targetPos); - if (float.IsNaN(velMult.X) || float.IsNaN(velMult.Y)) - { - velMult = -Vector2.UnitY; - } - velMult *= speed; - if (velMult.X != Projectile.velocity.X || velMult.Y != Projectile.velocity.Y) - { - Projectile.netUpdate = true; - } - Projectile.velocity = velMult * 0.55f; - int randomBulletCount = Main.rand.Next(3, 5); //3 to 4 bullets - for (int projIndex = 0; projIndex < randomBulletCount; projIndex++) - { - Vector2 bulletVel = Vector2.Normalize(Projectile.velocity) * speedMult * (0.6f + Main.rand.NextFloat() * spreadMult); - if (float.IsNaN(bulletVel.X) || float.IsNaN(bulletVel.Y)) - { - bulletVel = -Vector2.UnitY; - } - source += Utils.RandomVector2(Main.rand, -5f, 5f); - bulletVel.X += (float)Main.rand.Next(-15, 16) * spreadMult; - bulletVel.Y += (float)Main.rand.Next(-15, 16) * spreadMult; - int bullet = Projectile.NewProjectile(Projectile.GetSource_FromThis(), source, bulletVel, projType, damage, kback, Projectile.owner, 0f, 0f); - Main.projectile[bullet].noDropItem = true; - Main.projectile[bullet].extraUpdates += incrementAmt / 2; //0 to 4 - } - } - else - { - Projectile.Kill(); - } - } - Projectile.position = player.RotatedRelativePoint(player.MountedCenter, true) - Projectile.Size / 2f; - float rotationAmt = 0f; - if (Projectile.spriteDirection == -1) - { - rotationAmt = MathHelper.Pi; - } - Projectile.rotation = Projectile.velocity.ToRotation() + rotationAmt; - Projectile.spriteDirection = Projectile.direction; - Projectile.timeLeft = 2; - player.ChangeDir(Projectile.direction); - player.heldProj = Projectile.whoAmI; - player.itemTime = 2; - player.itemAnimation = 2; - player.itemRotation = (float)Math.Atan2((double)(Projectile.velocity.Y * (float)Projectile.direction), (double)(Projectile.velocity.X * (float)Projectile.direction)); - } - - public override bool? CanDamage() => false; - } -} diff --git a/Projectiles/Ranged/BuzzkillHoldout.cs b/Projectiles/Ranged/BuzzkillHoldout.cs new file mode 100644 index 0000000000..b91af68411 --- /dev/null +++ b/Projectiles/Ranged/BuzzkillHoldout.cs @@ -0,0 +1,261 @@ +using CalamityMod.Buffs.DamageOverTime; +using CalamityMod.Items.Weapons.Ranged; +using CalamityMod.Particles; +using CalamityMod.Projectiles.BaseProjectiles; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ReLogic.Content; +using ReLogic.Utilities; +using System; +using Terraria; +using Terraria.Audio; +using Terraria.DataStructures; +using Terraria.ID; +using Terraria.ModLoader; + +namespace CalamityMod.Projectiles.Ranged +{ + public class BuzzkillHoldout : BaseGunHoldoutProjectile + { + public override int AssociatedItemID => ModContent.ItemType(); + public override float RecoilResolveSpeed => 0.05f; + public override float MaxOffsetLengthFromArm => 30f; + public override float OffsetXUpwards => -10f; + public override float OffsetXDownwards => 5f; + public override float BaseOffsetY => -10f; + public override float OffsetYDownwards => 10f; + public override Vector2 GunTipPosition => Projectile.Center + Vector2.UnitX.RotatedBy(Projectile.rotation) * Projectile.width * 0.28f; + + public ref float Time => ref Projectile.ai[0]; + public const float ChargeupTime = 120f; + public SlotId ChargeIdle; + + // Controls the saw visually disappearing from the holdout when it fires. + public bool NoSawOnHoldout = false; + + public static Asset Holdout; + public static Asset SmallSlash; + public static Asset LargeSlash; + + public override void SetStaticDefaults() + { + Main.projFrames[Type] = 5; + } + + public override void SetDefaults() + { + base.SetDefaults(); + Projectile.friendly = true; + Projectile.penetrate = -1; + Projectile.DamageType = DamageClass.Ranged; + Projectile.ignoreWater = true; + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 10; + } + + public override void KillHoldoutLogic() + { + if (HeldItem.type != Owner.ActiveItem().type) + { + Projectile.Kill(); + Projectile.netUpdate = true; + } + } + + public override void HoldoutAI() + { + Time++; + float SawPower = MathHelper.Clamp(Time / ChargeupTime, 0f, 1f); + + if (SoundEngine.TryGetActiveSound(ChargeIdle, out var Idle) && Idle.IsPlaying) + Idle.Position = GunTipPosition; + + if (Owner.CantUseHoldout()) + { + if (Projectile.ai[1] < 1f) + { + KeepRefreshingLifetime = false; + Idle?.Stop(); + + Projectile.ai[1] = 1f; + Projectile.timeLeft = Owner.ActiveItem().useAnimation; + SoundStyle ShootSound = new("CalamityMod/Sounds/Item/SawShot", 2) { PitchVariance = 0.1f, Volume = 0.4f + SawPower * 0.5f }; + SoundEngine.PlaySound(ShootSound, GunTipPosition); + + float sawDamageMult = MathHelper.Lerp(1f, 5f, SawPower) / 1.5f; // The damage must be divided by 1.5 to offset the holdout having 1.5x base damage. + int sawPierce = (int)MathHelper.Lerp(2f, 6f, SawPower); + int sawLevel = (SawPower >= 1f).ToInt() + (SawPower >= 0.25f).ToInt(); + + Projectile buzzsaw = Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), GunTipPosition, Projectile.velocity.SafeNormalize(Vector2.UnitY) * Owner.ActiveItem().shootSpeed, ModContent.ProjectileType(), (int)(Projectile.damage * sawDamageMult), (int)(Projectile.knockBack * (sawDamageMult / 2)), Main.myPlayer, sawLevel); + buzzsaw.penetrate = sawPierce; + buzzsaw.rotation = Main.rand.NextFloat(0f, MathHelper.TwoPi); + + NoSawOnHoldout = true; + OffsetLengthFromArm -= 4f + 12f * SawPower; + + int sparkPairCount = 3 + 2 * sawLevel; + for (int s = 0; s < sparkPairCount; s++) + { + float velocityMult = Main.rand.NextFloat(5f, 8f) + Main.rand.NextFloat(4f, 7f) * sawLevel; + float scale = Main.rand.NextFloat(0.6f, 0.8f) + Main.rand.NextFloat(0.3f, 0.5f) * sawLevel; + + Vector2 sparkVelocity = Projectile.velocity.RotatedByRandom(MathHelper.PiOver4) * velocityMult; + Particle weaponShootSparks = new AltLineParticle(GunTipPosition, sparkVelocity, false, 40, scale, new Color(250, 250, 107)); + GeneralParticleHandler.SpawnParticle(weaponShootSparks); + + // re-randomize rotation for the alternate particle + sparkVelocity = Projectile.velocity.RotatedByRandom(MathHelper.PiOver4) * velocityMult; + Particle weaponShootSparks2 = new AltSparkParticle(GunTipPosition, sparkVelocity, false, 40, scale, new Color(250, 250, 107)); + GeneralParticleHandler.SpawnParticle(weaponShootSparks2); + } + } + } + + if (NoSawOnHoldout) + { + Projectile.frame = 4; + return; + } + else + { + Projectile.frameCounter++; + if (Projectile.frameCounter >= 3) + { + Projectile.frameCounter = 0; + Projectile.frame++; + if (Projectile.frame > 3) + Projectile.frame = 1; + } + } + + if (Time > 30f) + { + if (Time % 3 == 0) + { + Vector2 sparkVel = Main.rand.NextVector2CircularEdge(1f, 1f); + sparkVel.SafeNormalize(Vector2.Zero); + sparkVel *= Main.rand.NextFloat(3f, 4.5f) + (SawPower * 4); + + Particle buzzsawSparks = new AltLineParticle(GunTipPosition, sparkVel, false, 10, Utils.GetLerpValue(0.05f, 0.65f, SawPower, true), new Color(250, 250, 107)); + GeneralParticleHandler.SpawnParticle(buzzsawSparks); + } + } + + if (Time < ChargeupTime) + { + if (Time == 30f) + ChargeIdle = SoundEngine.PlaySound(new SoundStyle("CalamityMod/Sounds/Custom/BuzzsawCharge") { Volume = 0.3f }, GunTipPosition); + + if (Time > 30f && Projectile.frame == 0) + Projectile.frame = 1; + } + else + { + if ((Time + 240) % 360 == 0) + ChargeIdle = SoundEngine.PlaySound(new SoundStyle("CalamityMod/Sounds/Custom/BuzzsawIdle"), GunTipPosition); + + if (Time % 3 == 0) + { + Vector2 smokeVelocity = Vector2.UnitY * Main.rand.NextFloat(-7f, -12f); + smokeVelocity = smokeVelocity.RotatedByRandom(MathHelper.Pi / 8f); + Particle fullChargeSmoke = new HeavySmokeParticle(GunTipPosition + Main.rand.NextVector2CircularEdge(3f, 3f), smokeVelocity, Color.Gray, 30, 0.65f, 0.5f, Main.rand.NextFloat(-0.2f, 0.2f), true); + GeneralParticleHandler.SpawnParticle(fullChargeSmoke); + } + } + } + + public override void OnSpawn(IEntitySource source) + { + base.OnSpawn(source); + ExtraBackArmRotation = MathHelper.ToRadians(15f); + } + + // Failsafe because apparently the sound doesn't stop sometimes + public override void OnKill(int timeLeft) + { + if (SoundEngine.TryGetActiveSound(ChargeIdle, out var Idle)) + Idle?.Stop(); + } + + // The holdout can deal damage; you're literally spinning up a buzzsaw at the end, after all. + public override bool? CanDamage() => !NoSawOnHoldout; + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + target.AddBuff(ModContent.BuffType(), 240); + SoundEngine.PlaySound(new SoundStyle("CalamityMod/Sounds/Custom/SwiftSlice") { Volume = 0.7f }, GunTipPosition); + + int SawLevel = (Time / ChargeupTime >= 1f).ToInt() + (Time / ChargeupTime >= 0.25f).ToInt(); + int bloodCount = 4 + 3 * SawLevel; + for (int p = 0; p < bloodCount; p++) + { + float radius = Main.rand.NextFloat(6f, 10f) + Main.rand.NextFloat(4f, 10f) * SawLevel; + Vector2 velocity = Main.rand.NextVector2CircularEdge(radius, radius); + float scale = Main.rand.NextFloat(0.3f, 0.5f) + Main.rand.NextFloat(0.1f, 0.4f) * SawLevel; + Particle hitSparks = new AltLineParticle(target.Center, velocity, false, 20, scale, new Color(112, 16, 16)); + GeneralParticleHandler.SpawnParticle(hitSparks); + } + } + + public override void ModifyDamageHitbox(ref Rectangle hitbox) + { + hitbox = new Rectangle((int)GunTipPosition.X - 19, (int)GunTipPosition.Y - 20, 38, 40); + + if (Time / ChargeupTime >= 1f) + hitbox.Inflate(65, 65); + else if (Time / ChargeupTime >= 0.25f) + hitbox.Inflate(28, 28); + } + + public override bool PreDraw(ref Color lightColor) + { + Holdout ??= ModContent.Request("CalamityMod/Projectiles/Ranged/BuzzkillHoldout"); + Texture2D holdoutTexture = Holdout.Value; + LargeSlash ??= ModContent.Request("CalamityMod/Projectiles/Ranged/BuzzkillSawLargeSlash"); + Texture2D largeSlashTexture = LargeSlash.Value; + SmallSlash ??= ModContent.Request("CalamityMod/Projectiles/Ranged/BuzzkillSawSmallSlash"); + Texture2D smallSlashTexture = SmallSlash.Value; + Color slashColor = new Color(200, 200, 200, 100); + + Vector2 drawPosition = Projectile.Center - Main.screenPosition; + Rectangle frame = holdoutTexture.Frame(verticalFrames: Main.projFrames[Type], frameY: Projectile.frame); + float drawRotation = Projectile.rotation + (Projectile.spriteDirection == -1 ? MathHelper.Pi : 0f); + Vector2 rotationPoint = frame.Size() * 0.5f; + SpriteEffects flipSprite = Projectile.spriteDirection == -1 ? SpriteEffects.FlipHorizontally : SpriteEffects.None; + + if (!NoSawOnHoldout) + { + float shake = Utils.Remap(Time, 0f, ChargeupTime, 0f, 3f); + drawPosition += Main.rand.NextVector2Circular(shake, shake); + } + + Main.EntitySpriteDraw(holdoutTexture, drawPosition, frame, Projectile.GetAlpha(lightColor), drawRotation, rotationPoint, Projectile.scale, flipSprite); + + if (Time > 30f && !NoSawOnHoldout) + { + if (Time / ChargeupTime >= 1f) + Main.EntitySpriteDraw(largeSlashTexture, GunTipPosition - Main.screenPosition, null, slashColor, Time * -MathHelper.ToRadians(42f), largeSlashTexture.Size() * 0.5f, 1f, SpriteEffects.None); + + if (Time / ChargeupTime >= 0.25f) + Main.EntitySpriteDraw(smallSlashTexture, GunTipPosition - Main.screenPosition, null, slashColor, Time * MathHelper.ToRadians(42f), smallSlashTexture.Size() * 0.5f, 1f, SpriteEffects.None); + + if (!CalamityConfig.Instance.Afterimages) + return false; + + // Special afterimage drawing for the slashes only + for (int i = 1; i < 3; i++) + { + float intensity = MathHelper.Lerp(0.05f, 0.25f, 1f - i / 3f); + + if (Time / ChargeupTime >= 1f) + Main.EntitySpriteDraw(largeSlashTexture, GunTipPosition - Main.screenPosition, null, slashColor * intensity, (Time - i) * -MathHelper.ToRadians(42f), largeSlashTexture.Size() * 0.5f, 1f, SpriteEffects.None); + + if (Time / ChargeupTime >= 0.25f) + Main.EntitySpriteDraw(smallSlashTexture, GunTipPosition - Main.screenPosition, null, slashColor * intensity, (Time - i) * MathHelper.ToRadians(42f), smallSlashTexture.Size() * 0.5f, 1f, SpriteEffects.None); + } + } + + return false; + } + } +} diff --git a/Projectiles/Ranged/BuzzkillHoldout.png b/Projectiles/Ranged/BuzzkillHoldout.png new file mode 100644 index 0000000000000000000000000000000000000000..f878df53d2ff730c7b9332a4247d6ca76a688425 GIT binary patch literal 3026 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 literal 0 HcmV?d00001 diff --git a/Projectiles/Ranged/BuzzkillSaw.cs b/Projectiles/Ranged/BuzzkillSaw.cs new file mode 100644 index 0000000000..d216260e25 --- /dev/null +++ b/Projectiles/Ranged/BuzzkillSaw.cs @@ -0,0 +1,214 @@ +using CalamityMod.Buffs.DamageOverTime; +using CalamityMod.Particles; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ReLogic.Content; +using Terraria; +using Terraria.Audio; +using Terraria.GameContent; +using Terraria.ID; +using Terraria.ModLoader; + +namespace CalamityMod.Projectiles.Ranged +{ + public class BuzzkillSaw : ModProjectile, ILocalizedModType + { + public new string LocalizationCategory => "Projectiles.Ranged"; + + public static readonly SoundStyle TileCollideGFB = new("CalamityMod/Sounds/Custom/MetalPipeFalling"); + + public ref float SawLevel => ref Projectile.ai[0]; + public ref float Time => ref Projectile.ai[1]; + + public static Asset SmallSlash; + public static Asset LargeSlash; + + public override void SetStaticDefaults() + { + Main.projFrames[Type] = 4; + ProjectileID.Sets.TrailCacheLength[Type] = 6; + ProjectileID.Sets.TrailingMode[Type] = 2; + } + + public override void SetDefaults() + { + Projectile.width = Projectile.height = 40; + Projectile.friendly = true; + Projectile.DamageType = DamageClass.Ranged; + Projectile.timeLeft = 480; + Projectile.penetrate = 1; // Saw pierce is set when the saw is spawned, due to it being dynamic based on charge. + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 10; + Projectile.Calamity().pointBlankShotDuration = CalamityGlobalProjectile.DefaultPointBlankDuration; + } + + public override void AI() + { + Time++; + Projectile.rotation += MathHelper.ToRadians(6f + 18f * SawLevel); + + if (Projectile.frame < 1) + Projectile.frame = 1; + Projectile.frameCounter++; + if (Projectile.frameCounter >= 3) + { + Projectile.frameCounter = 0; + Projectile.frame++; + if (Projectile.frame > 3) + Projectile.frame = 1; + } + } + + public override bool OnTileCollide(Vector2 oldVelocity) + { + int sparkCount = 6 + 5 * (int)SawLevel; + for (int s = 0; s < sparkCount; s++) + { + Vector2 sparkVelocity = new Vector2(); + if (Projectile.velocity.X != oldVelocity.X && oldVelocity.X < 0) + sparkVelocity = Vector2.UnitX * 6.5f; + else if (Projectile.velocity.X != oldVelocity.X && oldVelocity.X >= 0) + sparkVelocity = Vector2.UnitX * -6.5f; + else if (Projectile.velocity.Y != oldVelocity.Y && oldVelocity.Y < 0) + sparkVelocity = Vector2.UnitY * 6.5f; + else if (Projectile.velocity.Y != oldVelocity.Y && oldVelocity.Y >= 0) + sparkVelocity = Vector2.UnitY * -6.5f; + + Vector2 sparkLocation = sparkVelocity.X > 0f ? Projectile.Left : (sparkVelocity.X < 0f ? Projectile.Right : (sparkVelocity.Y > 0f ? Projectile.Top : Projectile.Bottom)); + sparkVelocity = sparkVelocity.RotatedByRandom(MathHelper.PiOver2) * (Main.rand.NextFloat(0.8f, 1.2f) + (Main.rand.NextFloat(0.2f, 0.6f) * SawLevel)); + float scale = Main.rand.NextFloat(0.5f, 0.8f) + Main.rand.NextFloat(0.2f, 0.6f) * SawLevel; + Particle collisionSparks = new AltLineParticle(sparkLocation, sparkVelocity, false, 30, scale, new Color(250, 250, 107)); + GeneralParticleHandler.SpawnParticle(collisionSparks); + } + + Projectile.penetrate--; + Projectile.numHits++; + if (Projectile.penetrate <= 0) + { + Projectile.Kill(); + } + else + { + SoundEngine.PlaySound(Main.zenithWorld ? TileCollideGFB : SoundID.Item178 with { Pitch = 0.15f * Projectile.numHits }, Projectile.Center); // Placeholder sound + + if (Projectile.velocity.X != oldVelocity.X) + Projectile.velocity.X = -oldVelocity.X; + if (Projectile.velocity.Y != oldVelocity.Y) + Projectile.velocity.Y = -oldVelocity.Y; + } + + return false; + } + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + target.AddBuff(ModContent.BuffType(), 150); + SoundEngine.PlaySound(new SoundStyle("CalamityMod/Sounds/Custom/SwiftSlice") with { Pitch = 0.15f * Projectile.numHits }, Projectile.Center); + + int bloodCount = 6 + 10 * (int)SawLevel; + for (int p = 0; p < bloodCount; p++) + { + Vector2 velocity = Projectile.velocity.RotatedByRandom(MathHelper.ToRadians(30f)) * (Main.rand.NextFloat(0.4f, 0.6f) + (Main.rand.NextFloat(0.2f, 0.6f) * SawLevel)); + float scale = Main.rand.NextFloat(0.5f, 0.8f) + Main.rand.NextFloat(0.2f, 0.8f) * SawLevel; + Particle hitSparks = new AltLineParticle(target.Center, velocity, false, 30, scale, new Color(112, 16, 16)); + GeneralParticleHandler.SpawnParticle(hitSparks); + } + } + + public override void OnKill(int timeLeft) + { + SoundEngine.PlaySound(new SoundStyle("CalamityMod/Sounds/Custom/CeramicImpact", 2), Projectile.Center); + + // TODO - Change this dust + for (int d = 0; d < 8; d++) + { + Vector2 dustVel = Main.rand.NextVector2CircularEdge(1f, 1f); + dustVel.SafeNormalize(Vector2.Zero); + dustVel *= Main.rand.NextFloat(5f, 9f); + + Dust collisionDust = Dust.NewDustPerfect(Projectile.Center, 84, dustVel); + collisionDust.noGravity = true; + } + + int goreToExclude = Main.rand.Next(3); + switch (goreToExclude) + { + case 0: + Gore.NewGore(Projectile.GetSource_FromThis(), Projectile.Center, Main.rand.NextVector2Circular(4f, 4f), Mod.Find("BuzzkillSaw2").Type, 0.8f); + Gore.NewGore(Projectile.GetSource_FromThis(), Projectile.Center, Main.rand.NextVector2Circular(4f, 4f), Mod.Find("BuzzkillSaw3").Type, 0.8f); + break; + case 1: + Gore.NewGore(Projectile.GetSource_FromThis(), Projectile.Center, Main.rand.NextVector2Circular(4f, 4f), Mod.Find("BuzzkillSaw1").Type, 0.8f); + Gore.NewGore(Projectile.GetSource_FromThis(), Projectile.Center, Main.rand.NextVector2Circular(4f, 4f), Mod.Find("BuzzkillSaw3").Type, 0.8f); + break; + case 2: + Gore.NewGore(Projectile.GetSource_FromThis(), Projectile.Center, Main.rand.NextVector2Circular(4f, 4f), Mod.Find("BuzzkillSaw1").Type, 0.8f); + Gore.NewGore(Projectile.GetSource_FromThis(), Projectile.Center, Main.rand.NextVector2Circular(4f, 4f), Mod.Find("BuzzkillSaw2").Type, 0.8f); + break; + } + } + + public override void ModifyDamageHitbox(ref Rectangle hitbox) + { + if (SawLevel >= 2f) + hitbox.Inflate(65, 65); + else if (SawLevel >= 1f) + hitbox.Inflate(28, 28); + } + + public override bool PreDraw(ref Color lightColor) + { + LargeSlash ??= ModContent.Request("CalamityMod/Projectiles/Ranged/BuzzkillSawLargeSlash"); + Texture2D largeSlashTexture = LargeSlash.Value; + SmallSlash ??= ModContent.Request("CalamityMod/Projectiles/Ranged/BuzzkillSawSmallSlash"); + Texture2D smallSlashTexture = SmallSlash.Value; + Color slashColor = new Color(200, 200, 200, 100); + + if (SawLevel >= 2f) + { + Main.EntitySpriteDraw(largeSlashTexture, Projectile.Center - Main.screenPosition, null, slashColor, -Projectile.rotation, largeSlashTexture.Size() * 0.5f, 1f, SpriteEffects.None); + + if (Time % 4 == 0) + { + Vector2 randomParticleOffset = new Vector2(Main.rand.NextFloat(-Projectile.width * 1.75f, Projectile.width * 1.75f), Main.rand.NextFloat(-Projectile.width * 1.75f, Projectile.width * 1.75f)); + float randomParticleScale = Main.rand.NextFloat(0.65f, 0.95f); + Particle bloomCircle = new BloomParticle(Projectile.Center + randomParticleOffset, Projectile.velocity, Main.rand.NextBool() ? Color.White : new Color(112, 16, 16), randomParticleScale, randomParticleScale, 4, false); + GeneralParticleHandler.SpawnParticle(bloomCircle); + } + } + if (SawLevel >= 1f) + { + Main.EntitySpriteDraw(smallSlashTexture, Projectile.Center - Main.screenPosition, null, slashColor, Projectile.rotation, smallSlashTexture.Size() * 0.5f, 1f, SpriteEffects.None); + + if (Time % 4 == 0) + { + Vector2 randomParticleOffset = new Vector2(Main.rand.NextFloat(-Projectile.width, Projectile.width), Main.rand.NextFloat(-Projectile.width, Projectile.width)); + float randomParticleScale = Main.rand.NextFloat(0.35f, 0.65f); + Particle bloomCircle = new BloomParticle(Projectile.Center + randomParticleOffset, Projectile.velocity, Main.rand.NextBool() ? Color.White : new Color(112, 16, 16), randomParticleScale, randomParticleScale, 4, false); + GeneralParticleHandler.SpawnParticle(bloomCircle); + } + } + + if (!CalamityConfig.Instance.Afterimages) + return true; + + // Special afterimage drawing to include the slashes + Texture2D buzzsawTexture = TextureAssets.Projectile[Type].Value; + Rectangle frame = buzzsawTexture.Frame(1, Main.projFrames[Type], 0, Projectile.frame); + for (int i = 1; i < Projectile.oldPos.Length; i++) + { + float afterimageRot = Projectile.oldRot[i]; + Vector2 drawPos = Projectile.oldPos[i] + frame.Size() * 0.5f - Main.screenPosition; + float intensity = MathHelper.Lerp(0.1f, 0.6f, 1f - i / (float)Projectile.oldPos.Length); + + Main.EntitySpriteDraw(buzzsawTexture, drawPos, frame, lightColor * intensity, afterimageRot, frame.Size() * 0.5f, 1f, SpriteEffects.None); + + if (SawLevel >= 2f) + Main.EntitySpriteDraw(largeSlashTexture, drawPos, null, slashColor * intensity, -afterimageRot, largeSlashTexture.Size() * 0.5f, 1f, SpriteEffects.None); + if (SawLevel >= 1f) + Main.EntitySpriteDraw(smallSlashTexture, drawPos, null, slashColor * intensity, afterimageRot, smallSlashTexture.Size() * 0.5f, 1f, SpriteEffects.None); + } + return true; + } + } +} diff --git a/Projectiles/Ranged/BuzzkillSaw.png b/Projectiles/Ranged/BuzzkillSaw.png new file mode 100644 index 0000000000000000000000000000000000000000..26e13051ee471ea73464cbb51027bbfc5d1f3a26 GIT binary patch literal 2026 zcmVPx+q)9|URCt{2oKI*}R}{v-sZy|Fw24|62+@d?QN&GXy2z%bx@ZgCxfmA;-PDD& zg)T}#7lpd18|lJDY0-tV=q{jzT2VqR?Wl`N(4mNfX<%qIrfN_rw4E;Q`{vC(@15Lt zUqXAY_1jF|n?G;nmvhfO=eu{N0#DWJ^)3Kxs%`)P-0Ivxk>f_AQSrIXGrn)^-_lCg z14xK^|G+K)z}Uoo0KnO=4g&yo@A)|Q_{zl-e5ytI$kAhq5{!=+Nu4@%3P4KYh3Yl{ z776RPHuk1{oVJg_TSJ6Ir6kFB4%GQ) zF1hfD$(SOk`6M<-X6o{Tnx)NbF*eSy(Y z6N`h@H2|_?G|jdz0RUP_%yNdH!X?JoVn*+cs^pWTF=dOShKKGX&l~r;Fv;?EuzG@b zb%BtHaqeP<&g3mI`Xnjlr=qc?iPzsW`4fPUiE%V=G!9lrb04UY;;1_NO%njHbB7t7 zBp}7nC?!W{xWpJ^vVI~NW_0E$jy}c|Nu9s=WAc(O0|3S*%n=Fw*0~O#e~3_+68ACo-<^Aty)%V7+bn3pdK zJoR9o%3JFHy$+1owshal_E-}u1j4jzGl8o#J zS=&>-KED)K`%X^Y4BO|gXe+te=#%7Jnci3Io`NNo>5_`(DUw<)pI;J>hZsMx=ErM3 z|IoU>D*$kHdZ7#W`~2||W9<0){3PY_`O{qoNX{<+NC{K%5cADPn$ORea*2ec!Y3wo zG5Jcy6eZ_YIrp;S{o?p%*7L$8#txaY`tCjDUP$`tJ7xg(>ik(sqnoEd4lA&Z82WPqsJ>OpWj7LN)n*mlvz~{FKXKl&*DJ2O{vAzgDXO09vgUfW`Ln z=Sx;mULJ}@9c|z+0wb+rPvFsj48Ef$nOC3U< z$#-ce`F*41Qar?ZD;*u%=StVSg=;NVQig}@-BFrc)k!?W*ip;1B26SUu*$5=&feW% z&AHl22(QCiIhx}k#&=${LhYLYET3OWTN%+tbv(qVqH`TbpNu7~(j6YMj|UTy@vbG6 zmGt+ev^90kF!8J*9}6DD2Wqui;9b&8 z$9DM2##+(cQW`0W-CDTB_y@g%qAMf%YMYUaE%`cf4GF@l3zpcDS4K3+>crRY51$yN zky|bm_50%?M*Ua*J{3Q)rTYDx1DV;WCue13eB5;0&1Q2+`}rw3C+^t3wE_Us*KPoa zaa3xg=rmH=4!WX#KcD~MA+s|jx|NZYE>g0lmlbPzYu`_TnHoQtJLOK{*IpT~01*)D zUrTcQZjX`tJ&dJ(BZ4va-4E9*0C48(Zvg~MEVD8~amNXFH_836+AdA1sNc`~&m20| z1%RC|J|B3OBv(e{FN9F3i=7`!OWm!`QTof=vj9RSCQrzn!*p@vH?=gC-Ph02J9WGf z*;U{3s_mAg&KF{*of8X!(CSF3=OGzA)fIuKpaF~rN zFxLX3WdAk+!~cq}eET;O^}$wM^b?!Y-qvrd=9@{bHXFmXvUhtPMIDHm zP<)*{^oVq`z(^wNv36*Nq7_bQ4=dDK7TU2=updcIag+6))QxyCmXB)?>Q_%qP5jt2 znVR~(x*3=7%Kl-ZSG?mG(minv7xwKFA$<>bqmjv8v!BwTR%V2vHw0~R<63#~oti=>Sdxm!uXH)E8V z#<}V6O1GOvI)s71ZRWB&{LT~mxRxq-PVma$`#s{)1L{uP)U zOdQy!M9*q6GwCR=0jqEo8C7F6{?^QZ38qA?1{c)f5WG75^YLR?u#a-nIEsfnjS$Yz zuAm4N-kFz4$D?;PdoOjE-xDF~WBVgN1&&~-X(Ofk0KF21&9C2`IzgLdB4NRkiF*@nGpRmWOtp+LRimT}fb%20ei=`!zSSApuNfiWyxB@*zQW@Tj5g z!{$287!M&ou|JV7m}($y7RmwsXrGhf;1~JzqviP2kQ&@no;yu5JC$ayS0hqqJ{1EJ zk&&D9k|}!fVA$OjDd+O4p}4rUj2}tDQ58E<%$|;g>gX#>@PBqbI!Q015~1kpn`2Tm zy^pcH*$1|Z9!{%#+=uzkNA>5km&bQ%{HIZru}zG<_5PqpBkvA_1ph%-uw*-{tr zC7p3S+QdPd3<*9eSa1?jsNB9a?cU>nxG&3vkM`OmB*Z&KkJ!=o|oS# zZ+JXSMCtopt+UF{$nM+DWTc-q?3q-}7uiw3QoL!hUQ}>5wl2V^X833EZq0T7ORw71 z3fNow6mxZaW}PlNygLKzla75?78xehq^Pe;@#5Ogm1DT@=F?bl?ToH$e1Zm{St3#w zE0TLJ2~@(N7PfHjY`u}lu3x6RP|;$Cb^cM_V#O80`- z&(`7=|LUd`b?5(6AP7r6A&1|%iHpN20-zY&H?Vimasuk5#T##C{R?h=vpyUh}>aOGh)d4Vq9ef!X_d)xi zK%9ePp(#@T*EHMEgk03!y91&&`m17&R?G*#jb8nn3+8Eng|Hj>jY{-)(^-yc-$S=Q zic6Mi0KI4^91?NfRxAlqkckQnHAfHk9qb2*qwVY(*iK1p2EVP^0H}N|MKP4Q!j^Bi zW)XXt>)6ivagIQ!zOM{u4!RRh6^uJfyRqq`spOdT*^Fve1E*a{pcqN&ghrSa)3)!( zCbPd@%w8A$yyAanAxOTk(P#97n?wQ}F3Wz8gl0-9oZcEQ+oO z2u)k`Q3kON6z?U)6BDkp`kyd8#)NPg5iZy689woI;(3AWr0MQk zv&52z*Ue6qXzmaT={TBIE8u#W$~nV2!>F5wJT<-Q3d9{{OSH2qAXQ+I1zjGPu-r2< z<_)~EqV6JpV(dbvCXH~su{t{&qg`bPAHO591X5y`RQYvue=-%g6F}VJ7Knm;d(i0V z)?aMGn`-lO!?DqCj`iZqa$OFr3O!LMx>hk(UCmC9xZ~yg-4QNxh=djKHzODU4uMI^ zAYXE>^~?=NT>WTj2qW!00yN`86U=2~}&h6=@#zBobNx%6!lc0l02J#O6H&5)z>F5z<{ zMsT7Ts6Ke6R0AVew0SiSLz1roS*XZ~ zW!!_cvvo~Gki5-+)^y5x>!?=OK%|RkY16-_0!)BB%bV_Tkp|9~j+No$Yw2HA>p|AQ z2 F_g{5jt(^b> literal 0 HcmV?d00001 diff --git a/Projectiles/Ranged/BuzzkillSawSmallSlash.png b/Projectiles/Ranged/BuzzkillSawSmallSlash.png new file mode 100644 index 0000000000000000000000000000000000000000..8ee31d89e0599958931b07d50b435a42fc6ba5b3 GIT binary patch literal 1102 zcmeAS@N?(olHy`uVBq!ia0vp^89Nn{1`ISV`@iy0XB4ude`@%$Aj3=GVVJzX3_D&pSGwayR;6luGz*d%saqgzpc zSK1|{M&zPXa7X_+fj21|H*C0YD$Vi2At#ZR2f{o}{f8z*b;JgUG_UYfcG6MlPE&Mg z(%a$66xnm<@SN5=sby+6XIk5z{D1J_8`V&Y=a28)oVji2P{8pN%{=9aecGhGD6OK6t*6oklqw{Re zOM8vio!0uQuh;qZRvCW_{Pf|20k0Q>6pLR%^6z`r%;&S4vgXB~%EE{9QtV=1u>r$!uS5L4Fx8whFT>QnyqsTOTPt(~ z5)5zd%B-(80EO$DBVSTn|N2fir@Hm!-5>EMZDwBqDQRPRsS{KpHuJNP&x`H1?ws8T zv|rf5{!Qc(b-icj-%Ve$xg&k58ZZ{rH#mIL33?M5q9HQP=SRJop>y*A&bjh7=GL*m zR5fw;y!Uw?>_DeH$$S30`4Z5S&5!h+TfYJMF0!=zv+XKSXl}W4HB0FJ)44oAn{Vuz zsiw*dH29kypRwo6uh&ghS^|ZS>^=pGPHOdb$f+E#+4$VJu6FB zN-brXx%FP}BF6^@N|)wN6EfR9rO_+ZccxqOf|Du#m{-dD7BOY#%LkSL44$rjF6*2U FngD9?1WNz_ literal 0 HcmV?d00001 diff --git a/Sounds/Custom/BuzzsawCharge.ogg b/Sounds/Custom/BuzzsawCharge.ogg new file mode 100644 index 0000000000000000000000000000000000000000..92db8cca713465a734ecadd79bf92bb234479f20 GIT binary patch literal 39758 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

<)HX*E8kgN6U5h~!=^Jf~{#WlzQElcP( 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 azBgjU-Ll1cdey~XHMD&3?DGOrH1I!H)}%`S literal 0 HcmV?d00001 diff --git a/Sounds/Custom/MetalPipeFalling.ogg b/Sounds/Custom/MetalPipeFalling.ogg new file mode 100644 index 0000000000000000000000000000000000000000..eaddb019f39d091309a78880b8b035923cd40068 GIT binary patch literal 47413 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 literal 0 HcmV?d00001 diff --git a/Sounds/Item/SawShot1.ogg b/Sounds/Item/SawShot1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..668e88c1f012dbfd1538e7c473626a62188c7de5 GIT binary patch literal 12254 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 Mw^o(5$wG|(18gyDmjD0& literal 0 HcmV?d00001 From b22a4ac55a7a61addbb9d675c36e8c9846bfeebc Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Wed, 28 May 2025 19:58:06 -0400 Subject: [PATCH 266/401] Superradiant Slaughterer Plus apparently some Speed Blaster adjustments that also got made on the Buzzkill rework branch? --- Buffs/DamageOverTime/Laceration.cs | 74 ++++ Buffs/DamageOverTime/Laceration.png | Bin 0 -> 702 bytes CalPlayer/CalamityPlayer.cs | 26 +- CalPlayer/CalamityPlayerDashEffects.cs | 29 +- CalPlayer/CalamityPlayerHitHurt.cs | 4 + CalPlayer/CalamityPlayerLifeRegen.cs | 1 + CalPlayer/Dashes/SpeedBlasterDash.cs | 15 +- CalPlayer/Dashes/SuperradiantSawDash.cs | 43 ++ Cooldowns/SuperradiantSawBoost.cs | 18 + Cooldowns/SuperradiantSawBoost.png | Bin 0 -> 443 bytes Cooldowns/SuperradiantSawBoostOutline.png | Bin 0 -> 213 bytes Cooldowns/SuperradiantSawBoostOverlay.png | Bin 0 -> 175 bytes Items/Weapons/Ranged/ElementalBlaster.cs | 53 --- Items/Weapons/Ranged/ElementalBlaster.png | Bin 2006 -> 0 bytes Items/Weapons/Ranged/SpeedBlaster.cs | 3 +- .../Weapons/Ranged/SuperradiantSlaughterer.cs | 132 ++++++ .../Ranged/SuperradiantSlaughterer.png | Bin 0 -> 1989 bytes .../en-US/Mods.CalamityMod.Buffs.hjson | 15 +- ...ods.CalamityMod.Items.Weapons.Ranged.hjson | 41 +- .../Mods.CalamityMod.Projectiles.Ranged.hjson | 3 + .../en-US/Mods.CalamityMod.Status.Death.hjson | 3 + Localization/en-US/Mods.CalamityMod.UI.hjson | 1 + NPCs/CalamityGlobalNPC.cs | 10 + Projectiles/Ranged/BuzzkillSaw.cs | 4 + Projectiles/Ranged/RainbowBlast.cs | 65 --- Projectiles/Ranged/RainbowBlast.png | Bin 174 -> 0 bytes Projectiles/Ranged/SuperradiantBolt.cs | 96 +++++ Projectiles/Ranged/SuperradiantBolt.png | Bin 0 -> 310 bytes Projectiles/Ranged/SuperradiantSaw.cs | 389 ++++++++++++++++++ Projectiles/Ranged/SuperradiantSaw.png | Bin 0 -> 1452 bytes .../Ranged/SuperradiantSawLargeSlash.png | Bin 0 -> 1882 bytes .../Ranged/SuperradiantSawLingering.cs | 198 +++++++++ Projectiles/Ranged/SuperradiantSawOutline.png | Bin 0 -> 370 bytes .../Ranged/SuperradiantSawSmallSlash.png | Bin 0 -> 1050 bytes .../Ranged/SuperradiantSlaughtererHoldout.cs | 352 ++++++++++++++++ .../Ranged/SuperradiantSlaughtererHoldout.png | Bin 0 -> 4177 bytes .../SuperradiantSlaughtererHoldoutGlow.png | Bin 0 -> 4518 bytes .../SuperradiantSlaughtererHoldoutMiniSaw.png | Bin 0 -> 458 bytes 38 files changed, 1396 insertions(+), 179 deletions(-) create mode 100644 Buffs/DamageOverTime/Laceration.cs create mode 100644 Buffs/DamageOverTime/Laceration.png create mode 100644 CalPlayer/Dashes/SuperradiantSawDash.cs create mode 100644 Cooldowns/SuperradiantSawBoost.cs create mode 100644 Cooldowns/SuperradiantSawBoost.png create mode 100644 Cooldowns/SuperradiantSawBoostOutline.png create mode 100644 Cooldowns/SuperradiantSawBoostOverlay.png delete mode 100644 Items/Weapons/Ranged/ElementalBlaster.cs delete mode 100644 Items/Weapons/Ranged/ElementalBlaster.png create mode 100644 Items/Weapons/Ranged/SuperradiantSlaughterer.cs create mode 100644 Items/Weapons/Ranged/SuperradiantSlaughterer.png delete mode 100644 Projectiles/Ranged/RainbowBlast.cs delete mode 100644 Projectiles/Ranged/RainbowBlast.png create mode 100644 Projectiles/Ranged/SuperradiantBolt.cs create mode 100644 Projectiles/Ranged/SuperradiantBolt.png create mode 100644 Projectiles/Ranged/SuperradiantSaw.cs create mode 100644 Projectiles/Ranged/SuperradiantSaw.png create mode 100644 Projectiles/Ranged/SuperradiantSawLargeSlash.png create mode 100644 Projectiles/Ranged/SuperradiantSawLingering.cs create mode 100644 Projectiles/Ranged/SuperradiantSawOutline.png create mode 100644 Projectiles/Ranged/SuperradiantSawSmallSlash.png create mode 100644 Projectiles/Ranged/SuperradiantSlaughtererHoldout.cs create mode 100644 Projectiles/Ranged/SuperradiantSlaughtererHoldout.png create mode 100644 Projectiles/Ranged/SuperradiantSlaughtererHoldoutGlow.png create mode 100644 Projectiles/Ranged/SuperradiantSlaughtererHoldoutMiniSaw.png diff --git a/Buffs/DamageOverTime/Laceration.cs b/Buffs/DamageOverTime/Laceration.cs new file mode 100644 index 0000000000..621b51dfe4 --- /dev/null +++ b/Buffs/DamageOverTime/Laceration.cs @@ -0,0 +1,74 @@ +using CalamityMod.Particles; +using Microsoft.Xna.Framework; +using System; +using Terraria; +using Terraria.DataStructures; +using Terraria.ID; +using Terraria.ModLoader; + +namespace CalamityMod.Buffs.DamageOverTime +{ + public class Laceration : ModBuff + { + public override void SetStaticDefaults() + { + Main.debuff[Type] = true; + Main.pvpBuff[Type] = true; + Main.buffNoSave[Type] = true; + BuffID.Sets.LongerExpertDebuff[Type] = true; + } + + public override void Update(Player player, ref int buffIndex) + { + player.Calamity().laceration = true; + } + + public override void Update(NPC npc, ref int buffIndex) + { + if (npc.Calamity().laceration < npc.buffTime[buffIndex]) + npc.Calamity().laceration = npc.buffTime[buffIndex]; + npc.DelBuff(buffIndex); + buffIndex--; + } + internal static void DrawEffects(PlayerDrawSet drawInfo) + { + Player player = drawInfo.drawPlayer; + var modPlayer = player.Calamity(); + + if (Main.rand.NextBool()) + { + Vector2 randVel = new Vector2(6, 6).RotatedByRandom(100) * Main.rand.NextFloat(0.3f, 1f); + Dust dust = Dust.NewDustPerfect(modPlayer.RandomDebuffVisualSpot, 5, randVel * Main.rand.NextFloat(0.1f, 0.8f), 100, default, Main.rand.NextFloat(0.6f, 0.9f)); + dust.noGravity = false; + Particle spark = new AltSparkParticle(modPlayer.RandomDebuffVisualSpot, randVel + new Vector2(0, -4), true, 12, Main.rand.NextFloat(0.25f, 0.6f), Color.DarkRed * 0.5f); + GeneralParticleHandler.SpawnParticle(spark); + } + if (Main.rand.NextBool(8)) + { + Particle spark = new GlowOrbParticle(modPlayer.RandomDebuffVisualSpot, new Vector2(0, 4) * Main.rand.NextFloat(0.5f, 0.7f), true, 16, Main.rand.NextFloat(0.55f, 0.8f), Color.DarkRed * 0.8f, false, false, false); + GeneralParticleHandler.SpawnParticle(spark); + } + } + + internal static void DrawEffects(NPC npc, ref Color drawColor) + { + Vector2 npcSize = npc.Center + new Vector2(Main.rand.NextFloat(-npc.width / 2, npc.width / 2), Main.rand.NextFloat(-npc.height / 2, npc.height / 2)); + Vector2 randVel = new Vector2(6, 6).RotatedByRandom(100) * Main.rand.NextFloat(0.3f, 1f); + if (Main.rand.NextBool(3)) + { + Particle spark = new AltSparkParticle(npcSize, randVel + new Vector2(0, -4), true, 12, Main.rand.NextFloat(0.25f, 0.6f), Color.DarkRed * 0.5f); + GeneralParticleHandler.SpawnParticle(spark); + } + else + { + Dust dust = Dust.NewDustPerfect(npcSize, 5, randVel * Main.rand.NextFloat(0.1f, 0.8f), 100, default, Main.rand.NextFloat(0.2f, 0.6f)); + dust.noGravity = false; + } + if (Main.rand.NextBool(8)) + { + Particle spark = new GlowOrbParticle(npcSize, new Vector2(0, 4) * Main.rand.NextFloat(0.5f, 0.7f), true, 16, Main.rand.NextFloat(0.55f, 0.8f), Color.DarkRed * 0.8f, false, false, false); + GeneralParticleHandler.SpawnParticle(spark); + } + } + } +} diff --git a/Buffs/DamageOverTime/Laceration.png b/Buffs/DamageOverTime/Laceration.png new file mode 100644 index 0000000000000000000000000000000000000000..5a577ad3dc83eb67a6db2d38be0ec8eda15ac2b3 GIT binary patch literal 702 zcmV;v0zv(WP)Px#1ZP1_K>z@;j|==^1poj7PDw;TR9HvNmd{R8K@`Sk`p;ep*93}HKoVsmI~GQF zZrrl*3491&zz5(3So#hwA*@MQup}hLgs1@mgn(_aw7q)H^k>>*ZqkjJ`z4dFXXf5v z&Ud~!7yqHP=mfp`OeVZ>aiQ`5!eO(iJmYe&eTYBZ%_tW~ft6BSC*IbslrMjTlP)Yxo{>zZ&D8Eg{CPgS zUmOJhUcjxuDuY)J&icw^hyu)8uD83OuT1PKI~@9|&x0A@`j-KMwK4cn^_U%RpITlrPRL zc#(#><=t01Pha4k1D@lSY*kWa)Wlbky&%2^M*J6Y@@f7nqSn;ZLX?p~t$~fBD^Si# z>BsiKyNd6-+kWOw)4DrOYMPbAX*Hbj&E>Uw-08SISJrt~8M>P+yd&Vb)Q4|@tO>e( z?;3xa>GN5y&k)Ps6con;bS7#_4Cs7z-o_U66FMO={U^Etej!;3MI1p+CBUg`jh-@J zMI6spbLTp&(?@K7IJyZrvQEtY#qj{J_w-A() ? SuperradiantSawDash.ID : SpeedBlasterDash.ID; Player.dash = 0; } @@ -4284,20 +4288,8 @@ private void ForceVariousEffects() if (weakPetrification) WeakPetrification(); - // Disable vanilla dashes during god slayer dash - if (godSlayerDashHotKeyPressed) - { - // Set the player to have no registered vanilla dashes. - Player.dashType = 0; - - // Prevent the possibility of Shield of Cthulhu invulnerability exploits. - Player.eocHit = -1; - if (Player.eocDash != 0) - Player.eocDash = 0; - } - - // Disable vanilla dashes during god slayer dash - if (SpeedBlasterDashStarted) + // Disable vanilla dashes during God Slayer or Speed Blaster dashes + if (godSlayerDashHotKeyPressed || SpeedBlasterDashStarted) { // Set the player to have no registered vanilla dashes. Player.dashType = 0; diff --git a/CalPlayer/CalamityPlayerDashEffects.cs b/CalPlayer/CalamityPlayerDashEffects.cs index e66c90baa5..da590b45e9 100644 --- a/CalPlayer/CalamityPlayerDashEffects.cs +++ b/CalPlayer/CalamityPlayerDashEffects.cs @@ -13,8 +13,7 @@ namespace CalamityMod.CalPlayer { public partial class CalamityPlayer : ModPlayer { - public int VerticalGodslayerDashTimer; - public int VerticalSpeedBlasterDashTimer; + public int VerticalOmnidashTimer; private string dashID; //private backing variable @@ -104,16 +103,9 @@ public void ModDashMovement() } } - if (Player.dashDelay > 0) //Speed Blaster - { - VerticalSpeedBlasterDashTimer = 0; - LastUsedDashID = string.Empty; - return; - } - if (Player.dashDelay > 0) { - VerticalGodslayerDashTimer = 0; + VerticalOmnidashTimer = 0; LastUsedDashID = string.Empty; return; } @@ -137,21 +129,10 @@ public void ModDashMovement() // Handle mid-dash effects. UsedDash.MidDashEffects(Player, ref dashSpeed, ref dashSpeedDecelerationFactor, ref runSpeedDecelerationFactor); - if (UsedDash.IsOmnidirectional && VerticalGodslayerDashTimer < 25) - { - VerticalGodslayerDashTimer++; - if (VerticalGodslayerDashTimer >= 25) - { - Player.dashDelay = dashDelayToApply; - // Stop the player from going flying - Player.velocity *= 0.2f; - } - } - - if (UsedDash.IsOmnidirectional && VerticalSpeedBlasterDashTimer < 25) + if (UsedDash.IsOmnidirectional && VerticalOmnidashTimer < 25) { - VerticalSpeedBlasterDashTimer++; - if (VerticalSpeedBlasterDashTimer >= 25) + VerticalOmnidashTimer++; + if (VerticalOmnidashTimer >= 25) { Player.dashDelay = dashDelayToApply; // Stop the player from going flying diff --git a/CalPlayer/CalamityPlayerHitHurt.cs b/CalPlayer/CalamityPlayerHitHurt.cs index 2292f77770..cea12b6330 100644 --- a/CalPlayer/CalamityPlayerHitHurt.cs +++ b/CalPlayer/CalamityPlayerHitHurt.cs @@ -442,6 +442,10 @@ public override bool PreKill(double damage, int hitDirection, bool pvp, ref bool { damageSource = PlayerDeathReason.ByCustomReason(CalamityUtils.GetText("Status.Death.HeavyBleeding" + Main.rand.Next(1, 3 + 1)).ToNetworkText(Player.name)); } + if (laceration) + { + damageSource = PlayerDeathReason.ByCustomReason(CalamityUtils.GetText("Status.Death.Laceration" + Main.rand.Next(1, 3 + 1)).ToNetworkText(Player.name)); + } if (elementalMix) { damageSource = PlayerDeathReason.ByCustomReason(CalamityUtils.GetText("Status.Death.ElementalMix" + Main.rand.Next(1, 2 + 1)).Format(Player.name)); diff --git a/CalPlayer/CalamityPlayerLifeRegen.cs b/CalPlayer/CalamityPlayerLifeRegen.cs index a5ee7e9ba7..a2e2ac01bb 100644 --- a/CalPlayer/CalamityPlayerLifeRegen.cs +++ b/CalPlayer/CalamityPlayerLifeRegen.cs @@ -100,6 +100,7 @@ void ApplyDoTDebuff(bool hasDebuff, int negativeLifeRegenToApply, bool immuneCon ApplyDoTDebuff(bBlood, 8, purity); ApplyDoTDebuff(brainRot, 8, purity); ApplyDoTDebuff(heavybleeding, 16, purity); + ApplyDoTDebuff(laceration, 24, purity); ApplyDoTDebuff(elementalMix, 50, purity); ApplyDoTDebuff(vaporfied, 8, purity); ApplyDoTDebuff(bFlames, abaddon ? 10 : 30, purity); diff --git a/CalPlayer/Dashes/SpeedBlasterDash.cs b/CalPlayer/Dashes/SpeedBlasterDash.cs index 9541964367..22772ab180 100644 --- a/CalPlayer/Dashes/SpeedBlasterDash.cs +++ b/CalPlayer/Dashes/SpeedBlasterDash.cs @@ -1,7 +1,11 @@ using CalamityMod.Enums; using CalamityMod.Items.Weapons.Ranged; +using CalamityMod.Particles; +using CalamityMod.Projectiles.Ranged; +using Microsoft.Xna.Framework; using Terraria; using Terraria.Audio; +using Terraria.ID; namespace CalamityMod.CalPlayer.Dashes { @@ -12,8 +16,6 @@ public class SpeedBlasterDash : PlayerDashEffect public override bool IsOmnidirectional => true; - public bool dustOnce = true; - public override float CalculateDashSpeed(Player player) => 30f; public override void OnDashEffects(Player player) @@ -23,6 +25,15 @@ public override void OnDashEffects(Player player) public override void MidDashEffects(Player player, ref float dashSpeed, ref float dashSpeedDecelerationFactor, ref float runSpeedDecelerationFactor) { + Dust trail = Dust.NewDustPerfect(player.Center + Main.rand.NextVector2Unit() * 12f, DustID.RainbowTorch, -player.velocity * 0.2f, 150, Color.Aqua, 1.2f); + trail.noGravity = true; + + Vector2 sparkVel = player.velocity.SafeNormalize(Vector2.UnitY) * Main.rand.NextFloat(-3f, -6f); + Color sparkColor = SpeedBlasterShot.GetColor(Main.rand.Next(5)); + float scale = Main.rand.NextFloat(1f, 1.6f); // Bloom effect is double the spark's size + Particle spark = new CritSpark(player.Center + Main.rand.NextVector2Unit() * 12f, sparkVel, Color.White, sparkColor, scale, 15, 0.5f, scale * 2f); + GeneralParticleHandler.SpawnParticle(spark); + // Fall way, way, faster than usual. player.maxFallSpeed = 50f; diff --git a/CalPlayer/Dashes/SuperradiantSawDash.cs b/CalPlayer/Dashes/SuperradiantSawDash.cs new file mode 100644 index 0000000000..a434d8d652 --- /dev/null +++ b/CalPlayer/Dashes/SuperradiantSawDash.cs @@ -0,0 +1,43 @@ +using CalamityMod.Enums; +using CalamityMod.Items.Weapons.Ranged; +using CalamityMod.Particles; +using Microsoft.Xna.Framework; +using Terraria; +using Terraria.Audio; +using Terraria.ID; + +namespace CalamityMod.CalPlayer.Dashes +{ + public class SuperradiantSawDash : PlayerDashEffect + { + public static new string ID => "Superradiant Slaughterer"; + public override DashCollisionType CollisionType => DashCollisionType.NoCollision; + + public override bool IsOmnidirectional => true; + + public override float CalculateDashSpeed(Player player) => 36f; + + public override void MidDashEffects(Player player, ref float dashSpeed, ref float dashSpeedDecelerationFactor, ref float runSpeedDecelerationFactor) + { + Dust trail = Dust.NewDustPerfect(player.Center + Main.rand.NextVector2Unit() * 12f, DustID.RainbowTorch, -player.velocity * 0.2f, 150, Color.Lime, 1.2f); + trail.noGravity = true; + + Vector2 sparkVel = player.velocity.SafeNormalize(Vector2.UnitY) * Main.rand.NextFloat(-3f, -6f); + Color sparkColor = Main.hslToRgb(Main.rand.NextFloat(), 1f, 0.25f); + float scale = Main.rand.NextFloat(1.2f, 2f); // Bloom effect is double the spark's size + Particle spark = new CritSpark(player.Center + Main.rand.NextVector2Unit() * 12f, sparkVel, Color.White, sparkColor, scale, 24, 0.5f, scale * 2f); + GeneralParticleHandler.SpawnParticle(spark); + + // Fall way, way, faster than usual. + player.maxFallSpeed = 50f; + + // Dash at a much, much faster speed than the default value. + dashSpeed = 24f; + runSpeedDecelerationFactor = 0.8f; + + // Cooldown for dash. + player.Calamity().SpeedBlasterDashStarted = false; + player.Calamity().sBlasterDashActivated = false; + } + } +} diff --git a/Cooldowns/SuperradiantSawBoost.cs b/Cooldowns/SuperradiantSawBoost.cs new file mode 100644 index 0000000000..17371e2aa1 --- /dev/null +++ b/Cooldowns/SuperradiantSawBoost.cs @@ -0,0 +1,18 @@ +using Microsoft.Xna.Framework; +using System; +using Terraria; +using Terraria.Localization; + +namespace CalamityMod.Cooldowns +{ + public class SuperradiantSawBoost : CooldownHandler + { + public static new string ID => "SuperradiantSawBoost"; + public override bool ShouldDisplay => true; + public override LocalizedText DisplayName => CalamityUtils.GetText($"UI.Cooldowns.{ID}"); + public override string Texture => "CalamityMod/Cooldowns/SuperradiantSawBoost"; + public override Color OutlineColor => new Color(207, 207, 207); + public override Color CooldownStartColor => new Color(122, 240, 58); + public override Color CooldownEndColor => new Color(32, 186, 171); + } +} diff --git a/Cooldowns/SuperradiantSawBoost.png b/Cooldowns/SuperradiantSawBoost.png new file mode 100644 index 0000000000000000000000000000000000000000..1cacbc5c4a1163c8b0dfce47ece899c8cd4ee219 GIT binary patch literal 443 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%Grio-U3d7XHasjJ(nr7=0HnPx$rA^5y>oHmL;jzb7~rEsdya{`tMXJ0bKq z%hHu>5}{Z39OMa;libj2YHZf<)4<^ET8W7@q;hF{Y&Jr@mwiG{H_m=%2(+h=1 zGR8BGJq?m5_`HQ3Xhvdheveo#@0TZ4BNz$?x^mt;$ z@>#fL;)OYuJvP>B%#>JhGn+YeA=Aov`~hOjy~&c#oFoE-1KTzQFzV>!um04Sd29Ct zD=mpL74^(PRW{m!44-{tZ4R1P{V=FiozZsmlYgYxhSN9X|1*Bh6lx1lWA5TkOg#LS ze`BzMv5e2*1Ht`I6K47P^Sn6}KRvGT=a*td9)Z_E3JY9yj13qV*!;5e*8ej|1qL%; fYJ_K+uP=iZkj(+aAaE&oGKlhY^>bP0l+XkK0rRE0 literal 0 HcmV?d00001 diff --git a/Cooldowns/SuperradiantSawBoostOutline.png b/Cooldowns/SuperradiantSawBoostOutline.png new file mode 100644 index 0000000000000000000000000000000000000000..245f680cb533cfc362f84fe449a111c000e6dc01 GIT binary patch literal 213 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|N)O;`^^B#TGfW`|B=`7cQUFBWvcqxb~}r^>x0$HP?T< zTCW$)ZaT65;2MX6i~>aw47W6I1ppnumm1-j=IhI#1!QvoF$i1=o(!TqUHx3vIVCg! E03;eu2><{9 literal 0 HcmV?d00001 diff --git a/Cooldowns/SuperradiantSawBoostOverlay.png b/Cooldowns/SuperradiantSawBoostOverlay.png new file mode 100644 index 0000000000000000000000000000000000000000..da21d02b349ab032cd0b504d6ad21c0e08c882ab GIT binary patch literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VV{wqX6T`Z5GB1G~e@_?35R2aA z6bI)2K+vyu>;Mp)IB~+G$4V`yX$r%RwL5ZDL<8=(UMZ5)>0w{botR)UP1B$wY@^K& z-X#{(E_yFK`2OiZ@wS5IjH!H#b+c6jH?Fv-1vHv3HNrE^*Ovjr<^W<4xD-4YM0vXU KxvX "Items.Weapons.Ranged"; - - public override void SetStaticDefaults() - { - ItemID.Sets.IsRangedSpecialistWeapon[Item.type] = true; - } - public override void SetDefaults() - { - Item.width = 104; - Item.height = 42; - Item.damage = 67; - Item.DamageType = DamageClass.Ranged; - Item.useTime = 2; - Item.useAnimation = 6; - Item.useStyle = ItemUseStyleID.Shoot; - Item.noMelee = true; - Item.knockBack = 1.75f; - Item.value = CalamityGlobalItem.RarityPurpleBuyPrice; - Item.rare = ItemRarityID.Purple; - Item.UseSound = CommonCalamitySounds.PlasmaBoltSound; - Item.autoReuse = true; - Item.shoot = ModContent.ProjectileType(); - Item.shootSpeed = 18f; - } - - public override Vector2? HoldoutOffset() - { - return new Vector2(-15, 0); - } - - public override void AddRecipes() - { - CreateRecipe(). - AddIngredient(). - AddIngredient(ItemID.LunarBar, 5). - AddIngredient(5). - AddIngredient(5). - AddTile(TileID.LunarCraftingStation). - Register(); - } - } -} diff --git a/Items/Weapons/Ranged/ElementalBlaster.png b/Items/Weapons/Ranged/ElementalBlaster.png deleted file mode 100644 index 3ce7de1a2cecd27c3e26f6a62712788ad4cf65e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2006 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 diff --git a/Items/Weapons/Ranged/SpeedBlaster.cs b/Items/Weapons/Ranged/SpeedBlaster.cs index 83a303c0bb..a146ae3b32 100644 --- a/Items/Weapons/Ranged/SpeedBlaster.cs +++ b/Items/Weapons/Ranged/SpeedBlaster.cs @@ -94,7 +94,8 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Color ColorUsed = SpeedBlasterShot.GetColor(ColorValue); for (int i = 0; i <= 8; i++) { - CritSpark spark = new CritSpark(player.Center, player.velocity.RotatedByRandom(MathHelper.ToRadians(13f)) * Main.rand.NextFloat(-2.1f, -4.5f), Color.White, ColorUsed, 2f, 45, 2f, 2.5f); + Vector2 sparkVel = player.velocity.SafeNormalize(Vector2.UnitY).RotatedByRandom(MathHelper.ToRadians(45f)) * Main.rand.NextFloat(-28f, -36f); + CritSpark spark = new CritSpark(player.Center, sparkVel, Color.White, ColorUsed, 1.5f, 45, 0.5f, 2f); GeneralParticleHandler.SpawnParticle(spark); } } diff --git a/Items/Weapons/Ranged/SuperradiantSlaughterer.cs b/Items/Weapons/Ranged/SuperradiantSlaughterer.cs new file mode 100644 index 0000000000..45a7d7984d --- /dev/null +++ b/Items/Weapons/Ranged/SuperradiantSlaughterer.cs @@ -0,0 +1,132 @@ +using CalamityMod.Cooldowns; +using CalamityMod.Items.Materials; +using CalamityMod.Particles; +using CalamityMod.Projectiles.Ranged; +using CalamityMod.Sounds; +using Microsoft.Xna.Framework; +using System.Collections.Generic; +using System.Linq; +using Terraria; +using Terraria.Audio; +using Terraria.DataStructures; +using Terraria.ID; +using Terraria.Localization; +using Terraria.ModLoader; + +namespace CalamityMod.Items.Weapons.Ranged +{ + [LegacyName("ElementalBlaster")] + public class SuperradiantSlaughterer : ModItem, ILocalizedModType + { + public new string LocalizationCategory => "Items.Weapons.Ranged"; + + public const float ShootSpeed = 24f; + + public const int DashCooldown = 360; + + public override void ModifyTooltips(List tooltips) + { + if (tooltips == null) + return; + + Player player = Main.LocalPlayer; + if (player is null) + return; + + var mainTooltip = tooltips.FirstOrDefault(x => x.Text.Contains("[MAIN]") && x.Mod == "Terraria"); + if (mainTooltip != null) + { + mainTooltip.Text = Lang.SupportGlyphs(this.GetLocalizedValue("MainInfo")); + mainTooltip.OverrideColor = Color.Chartreuse; + } + var altTooltip = tooltips.FirstOrDefault(x => x.Text.Contains("[ALT]") && x.Mod == "Terraria"); + if (altTooltip != null) + { + altTooltip.Text = Lang.SupportGlyphs(this.GetLocalization("AltInfo").Format(DashCooldown / 60)); + altTooltip.OverrideColor = Color.SpringGreen; + } + } + + public override void SetStaticDefaults() + { + ItemID.Sets.IsRangedSpecialistWeapon[Type] = true; + } + public override void SetDefaults() + { + Item.width = 84; + Item.height = 46; + Item.damage = 127; + Item.DamageType = DamageClass.Ranged; + Item.useTime = 30; + Item.useAnimation = 30; + Item.useStyle = ItemUseStyleID.Shoot; + Item.noMelee = true; + Item.noUseGraphic = true; + Item.channel = true; + Item.knockBack = 1.75f; + Item.value = CalamityGlobalItem.RarityPurpleBuyPrice; + Item.rare = ItemRarityID.Purple; + Item.autoReuse = true; + Item.shoot = ModContent.ProjectileType(); + Item.shootSpeed = ShootSpeed; + Item.Calamity().canFirePointBlankShots = true; + } + + // Terraria seems to really dislike high crit values in SetDefaults + public override void ModifyWeaponCrit(Player player, ref float crit) => crit += 21; + public override bool AltFunctionUse(Player player) => true; + public override bool CanUseItem(Player player) + { + if (player.altFunctionUse == 2 && player.HasCooldown(SuperradiantSawBoost.ID)) + return false; + else + return player.ownedProjectileCounts[Item.shoot] <= 0; + } + + public override void HoldItem(Player player) + { + if (player.whoAmI != Main.myPlayer) + return; + + player.Calamity().mouseWorldListener = true; + player.Calamity().rightClickListener = true; + + // Right-click channeling + if (player.Calamity().mouseRight && CanUseItem(player) && !Main.mapFullscreen && !Main.blockMouse && !player.HasCooldown(SuperradiantSawBoost.ID)) + { + // Only one out at a time + if (Main.projectile.Any(n => n.active && n.type == Item.shoot && n.owner == player.whoAmI)) + return; + + int damage = (int)player.GetTotalDamage().ApplyTo(Item.damage); + float kb = player.GetTotalKnockback().ApplyTo(Item.knockBack); + + // 14NOV2024: Ozzatron: clamped mouse position unnecessary, only used for direction + Projectile.NewProjectile(Item.GetSource_FromThis(), player.Center, player.SafeDirectionTo(player.Calamity().mouseWorld), Item.shoot, damage * 2, kb, player.whoAmI, ai1: 2f); + } + } + + public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) + { + // The holdout will initially double up when right clicking otherwise + if (player.altFunctionUse == 2) + return false; + + // The holdout deals 2x base damage. + Projectile.NewProjectile(source, position, velocity, Item.shoot, damage * 2, knockback, player.whoAmI); + return false; + } + + public override void AddRecipes() + { + CreateRecipe(). + AddIngredient(). + AddIngredient(). + AddIngredient(ItemID.LunarBar, 5). + AddIngredient(5). + AddIngredient(ItemID.FragmentVortex, 5). + AddTile(TileID.MythrilAnvil). + Register(); + } + } +} diff --git a/Items/Weapons/Ranged/SuperradiantSlaughterer.png b/Items/Weapons/Ranged/SuperradiantSlaughterer.png new file mode 100644 index 0000000000000000000000000000000000000000..7dc18da67ae8fdd769eef6044dd69e8550d4841f GIT binary patch literal 1989 zcmV;$2RitPP)ge=1RHxrt4) zg#4JTWoAW5Q(C5`n7|SjGOv2CD9NYVe11I6bG)bbUbwJq@BQa@&&PYtxzBmt=bYc~ zoEsS6<0tctxmT_}(p=RCPyW7XW#IKqu)Om1)k?mP-T19~*{;DDuhl1a;#t3p*XKrT zK>vMeyatp&ZYlf@E$06!3~k+)4NJzxzMqHmxz(S+_7+nkHs22>ejITG{Whcxhs}-n z$%>pPFLU1q8++&|>@)6ESoicFff3th+SI5GXeTng4k%~DimBmqpHwEVryb3>mSxD_-MqtN`S<~okslGVNGaC=&dNT6@`~~(VZK3gy=JHlXb%B;SN?ox z)qs>s9%sBdITZPs6CYK||C+P{=@921u>0$4eVR-wMv_sHbu~)AtIi6eOrLp!1t?d1 z5^PRb5o~bKc#n@_ zl8vx?zL^f&@zGANm`Y|InNqH_OKl8oE>ZILG&V{S}Ho7KEnfZ2S1=7ds z{)DYR@7ZI~nMy4qBiU$Q$4Pu0(W<$}ZvSoc_x5leV`aJvK@-n;$Z^qh7}Q^BH+#sHy33XOZ?+JC()* z0s>OEiKj>p%4de!fU1!C4Cu7yvcbp`wFzix+_MkCE}AwQcG(x}V0SLx3`?fEvqm5t zQE?cyEiV&x`{Grw&(D7V)>S)78KH@(Ix~_pXCRC9-NB;S4U5H>pXHEMnvB(%nw=n8 z+kSbs(zI#+srS#c4QS`9-|K*qnZ+xAP#DEDXJ~z}_|heXufTE@|MaW(yn3#*=q=Ri zS6T^6Z6)(Ay4=WbX%$V4jEz<5aU7=(l;LY&ocQLAHKhuv$Y^G=ef`ZbG10_idT8@w z_CP+38fpWoLfdUXx%ku;%Kk8M&26yLcfGCjw0BMc($qp{l6Wfo=o*^$nlPEnZ2Dk3 z(jomrV7=W1=uG8)cUGb7I_R-+m%(z5i}^ZJ$L4K86|VZMzcpa6^1HSL%A2)5T-E|= zsga>JpyGo14bYS*2Ud47Cv5m*Xqz+2j&zOF>yxo$D)*UWm@?|COz+%>S}~TIsWa8- zmi_3J6B7R%^g<3ScNf$=ox%KFfh(F(e^a_d)97h&oK-_M;cLq2eAvawvTwFzs12x} z040$6%yS0yRhT}w&a}|PF~}MiC-Kqdq2k$)sbn@a)5KJIOe{}`7cJNOwOYk_7RD%2 z&eC~k$E2mK|8A|sOE*R@fGu#o3(M$~B|~jM#R2Iyp!YZup_x{zESW-v>5+Fvp}5)> zKO)g3E2cUxNL1)r`<*^KX&e`|Org(p@z2UR5`)lxAM0~h@bF6Uv=$`F8I-P_ zWa#0hNR-b^t%kjUp*Enh&GH+dRwfEI; zcqt9(e)ozte;+NUm03H~Rlh1vZh(0EAv5WN)AuF=2_W0knW^_frVbcgj3WB*DW!7b zGP(b)-WktS2=oAY#(8hVYvom#4&K|QfXPB3`O@P=rU4X9j< z@Ef3346rKKS9z=Y+k&LVqR&N(sFmEma^|CJmVxmH;ud;r(u$d6q!m-AT#f_Vnnx^rSp}CQAW;8`Et^|xcu^cvj zgTyBE{}A*TLwgEn8&E$Zt1o(7ZFysw8mBYXY8W~bS)Yugr$?E;7^C$8?}g&-=>6|BZ(J*8%+p X{d|BqM8D8C00000NkvXXu0mjfQy%t3 literal 0 HcmV?d00001 diff --git a/Localization/en-US/Mods.CalamityMod.Buffs.hjson b/Localization/en-US/Mods.CalamityMod.Buffs.hjson index 10d188ffc6..9cfdbd430a 100644 --- a/Localization/en-US/Mods.CalamityMod.Buffs.hjson +++ b/Localization/en-US/Mods.CalamityMod.Buffs.hjson @@ -168,6 +168,11 @@ GodSlayerInferno: { Description: Your flesh is burning off } +HeavyBleeding: { + DisplayName: Heavy Bleeding + Description: That's gonna need stitches +} + HolyFlames: { DisplayName: Holy Flames Description: Dissolving from holy light @@ -178,6 +183,11 @@ HolyInferno: { Description: You've gone too far from the Profaned Goddess! } +Laceration: { + DisplayName: Laceration + Description: You're a bloody mess +} + ManaBurn: { DisplayName: Mana Burn Description: The excess of mana sears your body and mind @@ -1505,8 +1515,3 @@ LiliesOfFinalityBuff: { DisplayName: Finality Description: Remember our promise } - -HeavyBleeding: { - Description: Mods.CalamityMod.Buffs.HeavyBleeding.Description - DisplayName: Heavy Bleeding -} diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson index db29caa352..f908e65ae5 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson @@ -426,15 +426,6 @@ Drataliornus: { ''' } -ElementalBlaster: { - DisplayName: Elemental Blaster - Tooltip: - ''' - Fires a storm of rainbow blasts - Does not consume ammo - ''' -} - ElementalEruption: { DisplayName: Elemental Eruption Tooltip: @@ -1153,9 +1144,10 @@ SpeedBlaster: { Tooltip: ''' Rapidly fires phosphorescent paintball shots - Press to eject a powerful glob which propels you while moving - This ability has a cooldown of {0} seconds - While under cooldown, you fire more rapidly with greater accuracy + Press to eject a powerful paint stream of a different color + Using this ability rapidly propels you in the direction you are moving + This ability has a {0} second cooldown + During this cooldown, you fire more rapidly with greater accuracy ''' } @@ -1222,6 +1214,31 @@ SulphuricAcidCannon: { Tooltip: Fires an acidic shot that sticks to enemies and dissolves them } +SuperradiantSlaughterer: { + DisplayName: Superradiant Slaughterer + Tooltip: + ''' + [MAIN] + [ALT] + [c/ad1717:'No one knows how it turns blood into rainbows...'] + ''' + MainInfo: + ''' + Hold to rev up an elemental buzzsaw that deals close-range damage + Release to fire the buzzsaw to pierce through and lacerate foes + Fired buzzsaws bounce off tiles and return to the player after winding down + When returning, the saws release extra homing bolts depending on the number of enemy and tile hits + Revving up the saws increases their damage and allows them to pierce more enemies + ''' + AltInfo: + ''' + Press to eject a lingering buzzsaw towards the cursor that fires homing bolts + Using this ability rapidly propels you in the direction you are moving + This ability has a {0} second cooldown + During this cooldown, buzzsaws home to the cursor and constantly release homing bolts while returning + ''' +} + SurgeDriver: { DisplayName: Surge Driver Tooltip: diff --git a/Localization/en-US/Mods.CalamityMod.Projectiles.Ranged.hjson b/Localization/en-US/Mods.CalamityMod.Projectiles.Ranged.hjson index 4d89597d45..846e7cd6bc 100644 --- a/Localization/en-US/Mods.CalamityMod.Projectiles.Ranged.hjson +++ b/Localization/en-US/Mods.CalamityMod.Projectiles.Ranged.hjson @@ -220,6 +220,9 @@ StarmageddonStar2.DisplayName: Starmageddon Star StormSurgeTornado.DisplayName: Surge SulphuricBlast.DisplayName: Sulphuric Blast SuperballBulletProj.DisplayName: Superball Bullet +SuperradiantBolt.DisplayName: Superradiant Bolt +SuperradiantSawLingering.DisplayName: Ultraradiant Saw +SuperradiantSaw.DisplayName: Superradiant Saw TelluricGlareArrow.DisplayName: Radiant Arrow TheMaelstromExplosion.DisplayName: Reaper Explosion TheMaelstromShark.DisplayName: Reaper Shark diff --git a/Localization/en-US/Mods.CalamityMod.Status.Death.hjson b/Localization/en-US/Mods.CalamityMod.Status.Death.hjson index 652459c985..485fdf71e0 100644 --- a/Localization/en-US/Mods.CalamityMod.Status.Death.hjson +++ b/Localization/en-US/Mods.CalamityMod.Status.Death.hjson @@ -70,6 +70,9 @@ HolyFlames1: "{0} fell prey to their sins." HolyFlames2: "{0} burst into sinless ash." HolyFlames3: "{0} was purified by the profaned flame." HolyInferno: "{0} was incinerated by the profaned backdraft." +Laceration1: "{0} was indecently smeared all over the walls." +Laceration2: "{0} was turned into a fine red mist." +Laceration3: "{0} was pulped, ribbons and rivulets of spent life spattering freely." ManaBurn: "{0}'s life was completely converted into mana." ManaConversionEnchant: "{0}'s life was fully tapped by dark magics." MiracleBlight1: "{0} was blown away by miraculous technological advancements." diff --git a/Localization/en-US/Mods.CalamityMod.UI.hjson b/Localization/en-US/Mods.CalamityMod.UI.hjson index 4037840c25..47a076ebb1 100644 --- a/Localization/en-US/Mods.CalamityMod.UI.hjson +++ b/Localization/en-US/Mods.CalamityMod.UI.hjson @@ -119,6 +119,7 @@ Cooldowns: { SpeedBlasterBoost: Speed Blaster Boost SpongeDurability: Sponge Barrier Durability SpongeRecharge: Sponge Barrier Recharge + SuperradiantSawBoost: Superradiant Saw Boost TarragonCloak: Tarragon Cloak Cooldown TarragonImmunity: Tarragon Immunity Cooldown UniverseSplitter: Universe Splitter Cooldown diff --git a/NPCs/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index 96be2c2f7a..adb0f3c8c8 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -245,6 +245,7 @@ public partial class CalamityGlobalNPC : GlobalNPC public int bBlood = 0; public int brainRot = 0; public int heavybleeding = 0; + public int laceration = 0; public int elementalMix = 0; public int marked = 0; public int absorberAffliction = 0; @@ -464,6 +465,7 @@ public override GlobalNPC Clone(NPC npc, NPC npcClone) myClone.bBlood = bBlood; myClone.brainRot = brainRot; myClone.heavybleeding = heavybleeding; + myClone.laceration = laceration; myClone.elementalMix = elementalMix; myClone.marked = marked; myClone.absorberAffliction = absorberAffliction; @@ -1109,6 +1111,8 @@ public override void UpdateLifeRegen(NPC npc, ref int damage) ApplyDPSDebuff(40, 10, ref npc.lifeRegen, ref damage); if (heavybleeding > 0) ApplyDPSDebuff(80, 10, ref npc.lifeRegen, ref damage); + if (laceration > 0) + ApplyDPSDebuff(400, 100, ref npc.lifeRegen, ref damage); if (elementalMix > 0) ApplyDPSDebuff(400, 80, ref npc.lifeRegen, ref damage); if (miracleBlight > 0) @@ -5072,6 +5076,8 @@ public override void PostAI(NPC npc) brainRot--; if (heavybleeding > 0) heavybleeding--; + if (laceration > 0) + laceration--; if (elementalMix > 0) elementalMix--; if (vulnerabilityHex > 0) @@ -6361,6 +6367,9 @@ public override void DrawEffects(NPC npc, ref Color drawColor) if (heavybleeding > 0) HeavyBleeding.DrawEffects(npc, ref drawColor); + if (laceration > 0) + Laceration.DrawEffects(npc, ref drawColor); + // These draw effects do not include Miracle Blight's shader if (miracleBlight > 0) MiracleBlight.DrawEffects(npc, ref drawColor); @@ -6556,6 +6565,7 @@ public override void DrawEffects(NPC npc, ref Color drawColor) ("CalamityMod/Buffs/DamageOverTime/GodSlayerInferno", NPC => NPC.Calamity().gsInferno > 0), ("CalamityMod/Buffs/DamageOverTime/HeavyBleeding", NPC => NPC.Calamity().heavybleeding > 0), ("CalamityMod/Buffs/DamageOverTime/HolyFlames", NPC => NPC.Calamity().hFlames > 0), + ("CalamityMod/Buffs/DamageOverTime/Laceration", NPC => NPC.Calamity().laceration > 0), ("CalamityMod/Buffs/DamageOverTime/MiracleBlight", NPC => NPC.Calamity().miracleBlight > 0), ("CalamityMod/Buffs/DamageOverTime/Nightwither", NPC => NPC.Calamity().nightwither > 0), ("CalamityMod/Buffs/DamageOverTime/Plague", NPC => NPC.Calamity().pFlames > 0), diff --git a/Projectiles/Ranged/BuzzkillSaw.cs b/Projectiles/Ranged/BuzzkillSaw.cs index d216260e25..7973eab163 100644 --- a/Projectiles/Ranged/BuzzkillSaw.cs +++ b/Projectiles/Ranged/BuzzkillSaw.cs @@ -44,6 +44,10 @@ public override void SetDefaults() public override void AI() { + // dies from cringe (Deadshot Brooch moment) + if (Projectile.MaxUpdates > 1) + Projectile.MaxUpdates = 1; + Time++; Projectile.rotation += MathHelper.ToRadians(6f + 18f * SawLevel); diff --git a/Projectiles/Ranged/RainbowBlast.cs b/Projectiles/Ranged/RainbowBlast.cs deleted file mode 100644 index 545dfe829c..0000000000 --- a/Projectiles/Ranged/RainbowBlast.cs +++ /dev/null @@ -1,65 +0,0 @@ -using CalamityMod.Buffs.DamageOverTime; -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; -namespace CalamityMod.Projectiles.Ranged -{ - public class RainbowBlast : ModProjectile, ILocalizedModType - { - public new string LocalizationCategory => "Projectiles.Ranged"; - public override void SetStaticDefaults() - { - ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; - ProjectileID.Sets.TrailingMode[Projectile.type] = 0; - ProjectileID.Sets.CultistIsResistantTo[Type] = true; - } - - public override void SetDefaults() - { - Projectile.width = 10; - Projectile.height = 10; - Projectile.friendly = true; - Projectile.penetrate = 1; - Projectile.extraUpdates = 1; - Projectile.DamageType = DamageClass.Ranged; - Projectile.timeLeft = 300; - } - - public override void AI() - { - //Rotation - Projectile.spriteDirection = Projectile.direction = (Projectile.velocity.X > 0).ToDirectionInt(); - Projectile.rotation = Projectile.velocity.ToRotation() + (Projectile.spriteDirection == 1 ? 0f : MathHelper.Pi); - - Lighting.AddLight(Projectile.Center, new Vector3(Main.DiscoR, Main.DiscoG, Main.DiscoB) * (1.5f / 255)); - - Projectile.localAI[0]++; - if (Projectile.localAI[0] > 5f) - { - Vector2 dspeed = -Projectile.velocity * 0.5f; - int rainbowDust = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.RainbowTorch, dspeed.X, dspeed.Y, 100, new Color(Main.DiscoR, Main.DiscoG, Main.DiscoB), 1.1f); - Main.dust[rainbowDust].noGravity = true; - Main.dust[rainbowDust].velocity = dspeed; - } - - CalamityUtils.HomeInOnNPC(Projectile, !Projectile.tileCollide, 200f, 12f, 20f); - } - - public override Color? GetAlpha(Color lightColor) - { - Color color = new Color(Main.DiscoR, Main.DiscoG, Main.DiscoB); - return color; - } - - public override bool PreDraw(ref Color lightColor) - { - CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], lightColor, 1); - return false; - } - public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) - { - target.AddBuff(ModContent.BuffType(), 60); - } - } -} diff --git a/Projectiles/Ranged/RainbowBlast.png b/Projectiles/Ranged/RainbowBlast.png deleted file mode 100644 index 80909384b51ec1b681389abccfe8d5a70281416e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^d_c^_!3HE-Zss2cQl*|Qjv*Qo_fAygJD?!IvfOum z!vTeYnx-Yw>~`Ext6}PQ{Jj|1-IHpYB!X868t;2s$+(d#$j;TG57? z?NKQlia891#}0O@h<~bH6vV~w{LX{w_peJ2I@I~+tYw@~%yuA3d-Y?bw;vpjzx-}L Zuar$|+8eo}ML-8Ic)I$ztaD0e0s!F*LdO6A diff --git a/Projectiles/Ranged/SuperradiantBolt.cs b/Projectiles/Ranged/SuperradiantBolt.cs new file mode 100644 index 0000000000..2ba1733524 --- /dev/null +++ b/Projectiles/Ranged/SuperradiantBolt.cs @@ -0,0 +1,96 @@ +using CalamityMod.Buffs.DamageOverTime; +using CalamityMod.Graphics.Primitives; +using CalamityMod.Particles; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using Terraria; +using Terraria.GameContent; +using Terraria.Graphics.Shaders; +using Terraria.ID; +using Terraria.ModLoader; + +namespace CalamityMod.Projectiles.Ranged +{ + public class SuperradiantBolt : ModProjectile, ILocalizedModType + { + public new string LocalizationCategory => "Projectiles.Ranged"; + + public ref float Time => ref Projectile.ai[0]; + + public override void SetStaticDefaults() + { + ProjectileID.Sets.CultistIsResistantTo[Type] = true; + ProjectileID.Sets.TrailCacheLength[Type] = 20; + ProjectileID.Sets.TrailingMode[Type] = 2; + } + + public override void SetDefaults() + { + Projectile.width = Projectile.height = 22; + Projectile.friendly = true; + Projectile.DamageType = DamageClass.Ranged; + Projectile.penetrate = 1; + Projectile.timeLeft = 120; + Projectile.tileCollide = false; + Projectile.scale = 0.85f; + } + + public override void AI() + { + Time++; + + // Solid homing + NPC potentialTarget = Projectile.Center.ClosestNPCAt(480f); + if (potentialTarget != null && Time >= 15f) + { + Vector2 idealVelocity = Projectile.SafeDirectionTo(potentialTarget.Center) * 24f; + Projectile.velocity = (Projectile.velocity * 29f + idealVelocity) / 30f; + Projectile.velocity = Projectile.velocity.MoveTowards(idealVelocity, 3f); + } + else if (Time >= 30f) + { + // Projectile decays a lot faster if there's no enemy in sight + Projectile.timeLeft -= 2; + } + + Projectile.rotation = Projectile.velocity.ToRotation(); + + // Emit light + DelegateMethods.v3_1 = Color.Lerp(Color.Lime, Color.White, 0.55f).ToVector3() * 0.35f; + Utils.PlotTileLine(Projectile.Center - Projectile.velocity * 0.5f, Projectile.Center + Projectile.velocity * 0.5f, 16f, DelegateMethods.CastLightOpen); + } + + public override bool? CanDamage() => Time >= 15f; + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) => target.AddBuff(ModContent.BuffType(), 45); + + internal float WidthFunction(float completionRatio) => (1f - completionRatio) * Projectile.scale * 20f; + internal Color ColorFunction(float completionRatio) + { + float hue = 0.4f + 0.2f * completionRatio * MathF.Sin(Main.GlobalTimeWrappedHourly * 5f); + Color trailColor = Main.hslToRgb(hue, 1f, 0.8f); + return trailColor * Projectile.Opacity; + } + + public override bool PreDraw(ref Color lightColor) + { + GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/FabstaffStreak")); + PrimitiveRenderer.RenderTrail(Projectile.oldPos, new(WidthFunction, ColorFunction, (_) => Projectile.Size * 0.5f, shader: GameShaders.Misc["CalamityMod:TrailStreak"]), 20); + Texture2D glow = TextureAssets.Projectile[Type].Value; + Main.EntitySpriteDraw(glow, Projectile.Center - Main.screenPosition, null, Color.White, Projectile.rotation, glow.Size() * 0.5f, Projectile.scale, SpriteEffects.None); + return false; + } + + public override void OnKill(int timeLeft) + { + for (int i = 0; i < 2; i++) + { + Vector2 sparkVel = Projectile.velocity.SafeNormalize(Vector2.UnitY).RotatedByRandom(MathHelper.ToRadians(24f)) * Main.rand.NextFloat(6f, 10f); + Color color = Main.hslToRgb(Main.rand.NextFloat(0.3f, 0.5f), 1f, 0.8f); + SparkParticle spark = new(Projectile.Center, sparkVel, false, 30, 1.3f, color); + GeneralParticleHandler.SpawnParticle(spark); + } + } + } +} diff --git a/Projectiles/Ranged/SuperradiantBolt.png b/Projectiles/Ranged/SuperradiantBolt.png new file mode 100644 index 0000000000000000000000000000000000000000..77ecaadda259915e3c5a50204130a2d6509d516b GIT binary patch literal 310 zcmeAS@N?(olHy`uVBq!ia0vp^CO|C4!3HGzW%geKQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@iy0XB4ude`@%$AjK*7_VE{-7)?r*0aJ99_H!yunGH&WfFPvHv!!Q46!kLB*=XTpLNppO@;i)fSY%M>3Yj`u~JaNun zA9nOTtd%%4`{Kzj(vNN*T`;dN#O2Vg8RD13CSDNxz27Oe`_5&?zU`)S)aOOEanD&L zd#68mMrQPyKTfx-FNLJVgQu&X%Q~lo FCIEh_eHs7& literal 0 HcmV?d00001 diff --git a/Projectiles/Ranged/SuperradiantSaw.cs b/Projectiles/Ranged/SuperradiantSaw.cs new file mode 100644 index 0000000000..7c2e2c695a --- /dev/null +++ b/Projectiles/Ranged/SuperradiantSaw.cs @@ -0,0 +1,389 @@ +using CalamityMod.Buffs.DamageOverTime; +using CalamityMod.Cooldowns; +using CalamityMod.Items.Weapons.Melee; +using CalamityMod.Items.Weapons.Ranged; +using CalamityMod.Particles; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ReLogic.Content; +using System; +using Terraria; +using Terraria.Audio; +using Terraria.GameContent; +using Terraria.ID; +using Terraria.ModLoader; + +namespace CalamityMod.Projectiles.Ranged +{ + public class SuperradiantSaw : ModProjectile, ILocalizedModType + { + public new string LocalizationCategory => "Projectiles.Ranged"; + public static readonly SoundStyle TileCollideGFB = new("CalamityMod/Sounds/Custom/MetalPipeFalling"); + + public ref float SawLevel => ref Projectile.ai[0]; + public ref float Time => ref Projectile.ai[1]; + public ref float PierceBeforeReturn => ref Projectile.ai[2]; + + // Hitstop timer. + public int HitstopTimer = 0; + + // Controls if the saw is returning to the player. + public bool Returning = false; + public int ReturnTimer = 0; + public const int ReturnDelay = 90; + public const int MaxBoltPairs = 7; // No more than 7 pairs per saw + + // Whether the saw is empowered by right click. + public bool Empowered = false; + + public Particle SmallSlashSmear; + public Particle LargeSlashSmear; + public static Asset SawOutline; + public static Asset SmallSlash; + public static Asset LargeSlash; + + public override void SetStaticDefaults() + { + ProjectileID.Sets.TrailCacheLength[Type] = 4; + ProjectileID.Sets.TrailingMode[Type] = 2; + } + + public override void SetDefaults() + { + Projectile.width = Projectile.height = 46; + Projectile.friendly = true; + Projectile.DamageType = DamageClass.Ranged; + Projectile.timeLeft = 600; + Projectile.penetrate = -1; // Saws only pierce a certain number of times before returning, and don't deal direct damage while returning + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 10; + Projectile.Calamity().pointBlankShotDuration = CalamityGlobalProjectile.DefaultPointBlankDuration; + } + + public override void AI() + { + // dies from cringe (Deadshot Brooch moment) + if (Projectile.MaxUpdates > 1) + Projectile.MaxUpdates = 1; + + // Timer and rotation + Time++; + Projectile.rotation += MathHelper.ToRadians(6f + 18f * SawLevel); + + // Hitstop timer + if (HitstopTimer > 0) + { + HitstopTimer--; + if (HitstopTimer == 0) + Projectile.velocity = Projectile.velocity.SafeNormalize(Vector2.UnitY) * SuperradiantSlaughterer.ShootSpeed; + } + + // Control the saw being empowered or not + Player Owner = Main.player[Projectile.owner]; + Empowered = Owner.HasCooldown(SuperradiantSawBoost.ID); + + // While empowered, the saws will slightly home in on the cursor + if (Empowered && !Returning && Time > 30) + { + float homingTurnSpeed = 0.2f; + Vector2 mouse = Owner.Calamity().mouseWorld; + Projectile.velocity = Projectile.velocity.ToRotation().AngleTowards(Projectile.SafeDirectionTo(mouse).ToRotation(), homingTurnSpeed).ToRotationVector2() * SuperradiantSlaughterer.ShootSpeed; + } + + // Saws automatically return 2 seconds after hitting an enemy + if (ReturnTimer > 0 && ReturnTimer < ReturnDelay) + { + ReturnTimer++; + if (ReturnTimer == ReturnDelay) + Returning = true; + } + + if (Returning) + { + Projectile.tileCollide = false; + if (ReturnTimer < ReturnDelay) + ReturnTimer = ReturnDelay; + + ReturnTimer++; + if (ReturnTimer < ReturnDelay + 30) + Projectile.velocity *= 0.95f; + else + { + // Spawns a burst of homing bolts when it starts returning, based on how many tiles and enemies it hit + if (ReturnTimer == ReturnDelay + 30) + { + int boltCount = Math.Min(Projectile.numHits, MaxBoltPairs) * 2; + for (int b = 0; b < boltCount; b++) + { + Vector2 randBoltVelocity = Main.rand.NextVector2Unit() * 9f; + if (Main.myPlayer == Projectile.owner) + Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, randBoltVelocity, ModContent.ProjectileType(), (int)(Projectile.damage * 0.5f), 0f, Main.myPlayer); + } + + // Extra burst of sparks for cool points + float sparkCount = 6f + 5f * SawLevel; + for (float i = 0f; i < sparkCount; i++) + { + Vector2 velocity = Main.rand.NextVector2Unit() * (12f + 10f * SawLevel); + float sparkScale = 1f + 0.25f * SawLevel; // Bloom effect is double the spark's size + Particle sparkle = new CritSpark(Projectile.Center, velocity, Color.White, Color.Lime, sparkScale, 30, 0.1f, sparkScale, Main.rand.NextFloat(0f, 0.01f)); + GeneralParticleHandler.SpawnParticle(sparkle); + } + } + + // Continuously spawn homing bolts as it returns while empowered + if (ReturnTimer % 9 == 0 && Empowered) + { + Vector2 randVelocity = -Projectile.velocity.RotatedByRandom(MathHelper.Pi / 3f) * 0.5f; + if (Main.myPlayer == Projectile.owner) + Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, randVelocity, ModContent.ProjectileType(), (int)(Projectile.damage * 0.5f), 0f, Main.myPlayer); + } + + float returnSpeed = (SuperradiantSlaughterer.ShootSpeed * 0.6f) + (0.05f * (ReturnTimer - 120)); + Vector2 ownerDist = Owner.Center - Projectile.Center; + if (ownerDist.Length() > 3000f) + Projectile.Kill(); + + ownerDist.Normalize(); + ownerDist *= returnSpeed; + + // Home back in on the player; accelerates over time + if (Projectile.velocity.X < ownerDist.X) + Projectile.velocity.X = ownerDist.X; + else if (Projectile.velocity.X > ownerDist.X) + Projectile.velocity.X = ownerDist.X; + + if (Projectile.velocity.Y < ownerDist.Y) + Projectile.velocity.Y = ownerDist.Y; + else if (Projectile.velocity.Y > ownerDist.Y) + Projectile.velocity.Y = ownerDist.Y; + + // Delete the saw if it touches its owner + if (Main.myPlayer == Projectile.owner) + { + if (Projectile.Hitbox.Intersects(Owner.Hitbox)) + Projectile.Kill(); + } + } + } + else + { + // A bit of dust while travelling + if (Main.rand.NextBool()) + { + Color dustColor = Empowered ? Main.DiscoColor : new Color(Main.DiscoR, 255, 60); + Dust trail = Dust.NewDustDirect(Projectile.position, Projectile.width, Projectile.height, DustID.RainbowTorch, Projectile.velocity.X * 0.05f, Projectile.velocity.Y * 0.05f, 150, dustColor, 1.2f); + trail.noGravity = true; + } + } + + // Rainbow smear particles which follow the path of the slashes + if (Empowered) + { + if (SawLevel >= 2f) + { + if (LargeSlashSmear == null) + { + LargeSlashSmear = new CircularSmearVFX(Projectile.Center, Color.Black, Time * -Projectile.rotation, 1.35f); + GeneralParticleHandler.SpawnParticle(LargeSlashSmear); + } + else + { + LargeSlashSmear.Rotation = -Projectile.rotation; + LargeSlashSmear.Time = 0; + LargeSlashSmear.Position = Projectile.Center; + LargeSlashSmear.Scale = 1.35f; + LargeSlashSmear.Color = Main.hslToRgb(0.5f + 0.5f * MathF.Sin(Main.GlobalTimeWrappedHourly * 5f), 1f, 0.6f) * 0.8f; + } + } + if (SawLevel >= 1f) + { + if (SmallSlashSmear == null) + { + SmallSlashSmear = new CircularSmearVFX(Projectile.Center, Color.Black, Projectile.rotation, 0.8f); + GeneralParticleHandler.SpawnParticle(SmallSlashSmear); + } + else + { + SmallSlashSmear.Rotation = Projectile.rotation; + SmallSlashSmear.Time = 0; + SmallSlashSmear.Position = Projectile.Center; + SmallSlashSmear.Scale = 0.8f; + SmallSlashSmear.Color = Main.hslToRgb(0.5f + 0.5f * MathF.Cos(Main.GlobalTimeWrappedHourly * 5f), 1f, 0.6f) * 0.6f; + } + } + } + } + + public override bool OnTileCollide(Vector2 oldVelocity) + { + int sparkCount = 6 + 5 * (int)SawLevel; + for (int s = 0; s < sparkCount; s++) + { + Vector2 sparkVelocity = new Vector2(); + if (Projectile.velocity.X != oldVelocity.X && oldVelocity.X < 0) + sparkVelocity = Vector2.UnitX * 6.5f; + else if (Projectile.velocity.X != oldVelocity.X && oldVelocity.X >= 0) + sparkVelocity = Vector2.UnitX * -6.5f; + else if (Projectile.velocity.Y != oldVelocity.Y && oldVelocity.Y < 0) + sparkVelocity = Vector2.UnitY * 6.5f; + else if (Projectile.velocity.Y != oldVelocity.Y && oldVelocity.Y >= 0) + sparkVelocity = Vector2.UnitY * -6.5f; + + Vector2 sparkLocation = sparkVelocity.X > 0f ? Projectile.Left : (sparkVelocity.X < 0f ? Projectile.Right : (sparkVelocity.Y > 0f ? Projectile.Top : Projectile.Bottom)); + sparkVelocity = sparkVelocity.RotatedByRandom(MathHelper.PiOver2) * (Main.rand.NextFloat(0.8f, 1.2f) + (Main.rand.NextFloat(0.2f, 0.6f) * SawLevel)); + float scale = Main.rand.NextFloat(0.5f, 0.8f) + Main.rand.NextFloat(0.2f, 0.6f) * SawLevel; + Particle collisionSparks = new AltLineParticle(sparkLocation, sparkVelocity, false, 30, scale, new Color(Main.DiscoR, Main.DiscoG, Main.DiscoB)); + GeneralParticleHandler.SpawnParticle(collisionSparks); + } + + SoundEngine.PlaySound(Main.zenithWorld ? TileCollideGFB : SoundID.Item178 with { Pitch = 0.1f * Projectile.numHits }, Projectile.Center); // Placeholder sound + if (Projectile.velocity.X != oldVelocity.X) + Projectile.velocity.X = -oldVelocity.X; + if (Projectile.velocity.Y != oldVelocity.Y) + Projectile.velocity.Y = -oldVelocity.Y; + + if (PierceBeforeReturn > 0) + { + PierceBeforeReturn--; + Projectile.numHits++; + if (PierceBeforeReturn <= 0) + Returning = true; + } + + return false; + } + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + target.AddBuff(ModContent.BuffType(), 180); + target.AddBuff(ModContent.BuffType(), 90); + SoundEngine.PlaySound(new SoundStyle("CalamityMod/Sounds/Custom/SwiftSlice") with { Pitch = 0.1f * Projectile.numHits }, Projectile.Center); + + // SUPER COLORFUL PARTICLE EFFECTS YEAH + int onHitSparkAmount = 7 + 10 * (int)SawLevel; + for (int s = 0; s < onHitSparkAmount; s++) + { + Vector2 sparkVel = Projectile.velocity.RotatedByRandom(MathHelper.ToRadians(30f)) * (Main.rand.NextFloat(0.4f, 0.8f) + (Main.rand.NextFloat(0.4f, 0.6f) * SawLevel)); + float sparkSize = 0.4f + Main.rand.NextFloat(0.3f, 0.6f) * SawLevel; + Color sparkColor = Main.hslToRgb(Main.rand.NextFloat(), 1f, 0.8f); + + Particle sparked = new AltLineParticle(target.Center, sparkVel, false, 30, sparkSize, sparkColor); + GeneralParticleHandler.SpawnParticle(sparked); + } + for (int sq = 0; sq < 7; sq++) + { + Vector2 squareVel = Main.rand.NextVector2CircularEdge(1f, 1f) * (Main.rand.NextFloat(10f, 16f) + 5f * SawLevel); + float squareSize = 1.6f + Main.rand.NextFloat(1f, 1.6f) * SawLevel; + Color squareColor = Main.hslToRgb(Main.rand.NextFloat(), 0.6f, 0.8f); + + Particle squared = new SquareParticle(target.Center, squareVel, true, 30, squareSize, squareColor); + GeneralParticleHandler.SpawnParticle(squared); + } + + // Hitstop effect if the saw is not returning + if (!Returning && HitstopTimer == 0) + { + HitstopTimer = 5; + Projectile.velocity = Projectile.velocity.SafeNormalize(Vector2.UnitY) / SuperradiantSlaughterer.ShootSpeed; + } + + if (Projectile.numHits < 1) + ReturnTimer = 1; + + if (PierceBeforeReturn > 0) + { + PierceBeforeReturn--; + if (PierceBeforeReturn <= 0) + Returning = true; + } + } + + public override void ModifyHitNPC(NPC target, ref NPC.HitModifiers modifiers) + { + // The saw deals less damage while returning, to prevent its damage being too crazy + if (PierceBeforeReturn <= 0) + modifiers.SourceDamage *= 0.33f; + } + + public override void OnKill(int timeLeft) + { + SoundEngine.PlaySound(new SoundStyle("CalamityMod/Sounds/Custom/CeramicImpact", 2), Projectile.Center); + } + + public override void ModifyDamageHitbox(ref Rectangle hitbox) + { + if (SawLevel >= 2f) + hitbox.Inflate(72, 72); + else if (SawLevel >= 1f) + hitbox.Inflate(32, 32); + } + + public override bool PreDraw(ref Color lightColor) + { + LargeSlash ??= ModContent.Request("CalamityMod/Projectiles/Ranged/SuperradiantSawLargeSlash"); + Texture2D largeSlashTexture = LargeSlash.Value; + SmallSlash ??= ModContent.Request("CalamityMod/Projectiles/Ranged/SuperradiantSawSmallSlash"); + Texture2D smallSlashTexture = SmallSlash.Value; + Color slashColor = new Color(200, 200, 200, 100); + + if (SawLevel >= 2f) + { + Main.EntitySpriteDraw(largeSlashTexture, Projectile.Center - Main.screenPosition, null, slashColor, -Projectile.rotation, largeSlashTexture.Size() * 0.5f, 1f, SpriteEffects.None); + + if (Time % 4 == 0) + { + Vector2 randomParticleOffset = new Vector2(Main.rand.NextFloat(-Projectile.width * 1.75f, Projectile.width * 1.75f), Main.rand.NextFloat(-Projectile.width * 1.75f, Projectile.width * 1.75f)); + float randomParticleScale = Main.rand.NextFloat(0.65f, 0.95f); + Color bloomColor = Color.Lerp(new Color(29, 120, 30), new Color(56, 255, 59), MathF.Abs(MathF.Sin(Time))); + Particle bloomCircle = new BloomParticle(Projectile.Center + randomParticleOffset, Projectile.velocity, Main.rand.NextBool() ? Color.White : bloomColor, randomParticleScale, randomParticleScale, 4, false); + GeneralParticleHandler.SpawnParticle(bloomCircle); + } + } + if (SawLevel >= 1f) + { + Main.EntitySpriteDraw(smallSlashTexture, Projectile.Center - Main.screenPosition, null, slashColor, Projectile.rotation, smallSlashTexture.Size() * 0.5f, 1f, SpriteEffects.None); + + if (Time % 4 == 0) + { + Vector2 randomParticleOffset = new Vector2(Main.rand.NextFloat(-Projectile.width, Projectile.width), Main.rand.NextFloat(-Projectile.width, Projectile.width)); + float randomParticleScale = Main.rand.NextFloat(0.35f, 0.65f); + Color bloomColor = Color.Lerp(new Color(29, 120, 30), new Color(56, 255, 59), MathF.Abs(MathF.Cos(Time))); + Particle bloomCircle = new BloomParticle(Projectile.Center + randomParticleOffset, Projectile.velocity, Main.rand.NextBool() ? Color.White : bloomColor, randomParticleScale, randomParticleScale, 4, false); + GeneralParticleHandler.SpawnParticle(bloomCircle); + } + } + + // Draw the saw itself at full brightness + Texture2D buzzsawTexture = TextureAssets.Projectile[Type].Value; + Main.EntitySpriteDraw(buzzsawTexture, Projectile.Center - Main.screenPosition, null, Color.White, Projectile.rotation, buzzsawTexture.Size() * 0.5f, 1f, SpriteEffects.None); + + if (Empowered) // Rainbow outline while empowered + { + SawOutline ??= ModContent.Request("CalamityMod/Projectiles/Ranged/SuperradiantSawOutline"); + Texture2D outline = SawOutline.Value; + Main.EntitySpriteDraw(outline, Projectile.Center - Main.screenPosition, null, Main.DiscoColor, Projectile.rotation, outline.Size() * 0.5f, 1f, SpriteEffects.None); + } + + if (!CalamityConfig.Instance.Afterimages) + return false; + + // Special afterimage drawing to include the slashes + for (int i = 1; i < Projectile.oldPos.Length; i++) + { + float afterimageRot = Projectile.oldRot[i]; + + Vector2 drawPos = Projectile.oldPos[i] + buzzsawTexture.Size() * 0.5f - Main.screenPosition; + float intensity = MathHelper.Lerp(0.1f, 0.6f, 1f - i / (float)Projectile.oldPos.Length); + + Main.EntitySpriteDraw(buzzsawTexture, drawPos, null, lightColor * intensity, afterimageRot, buzzsawTexture.Size() * 0.5f, 1f, SpriteEffects.None); + + if (SawLevel >= 2f) + Main.EntitySpriteDraw(largeSlashTexture, drawPos, null, slashColor * intensity, -afterimageRot, largeSlashTexture.Size() * 0.5f, 1f, SpriteEffects.None); + if (SawLevel >= 1f) + Main.EntitySpriteDraw(smallSlashTexture, drawPos, null, slashColor * intensity, afterimageRot, smallSlashTexture.Size() * 0.5f, 1f, SpriteEffects.None); + } + return false; + } + } +} diff --git a/Projectiles/Ranged/SuperradiantSaw.png b/Projectiles/Ranged/SuperradiantSaw.png new file mode 100644 index 0000000000000000000000000000000000000000..319c5357b2b875047085d0831f755b666eeca068 GIT binary patch literal 1452 zcmV;d1ylNoP)Px)W=TXrRA_QsEH{ggNh^yi9iG% zNYH==30`8P#PBA*U?LbV5iqpz#h{fIr$KB8+LYE(QVN|mgwmmeK!tXW59_Q>_F<-- zN6)O6cCWK<^X-4Fz0W=t30mf{r2tfpzaizUu>h>fECyhp`;?tXKjU*(SpcWP7Xb+O z-3Op%U`ovT;g`?E^rs{??f;*RiT6MWr{>)TpnU8+0BSn00S@02VjYE#01znbO=!Rq z;UzY}((Vudn+9aXHWkdU01kIvwE_0bEVBR}`$fhHth{OT<5}XC{_`;5#Q^-#(P9IP zT`YtyOuHPjqwv6f0BZ036!ZCt2`|YwC&Ehr@HMpp@T^}}uAx2$fV`;_Er6#N zTr=8vm$;ICKKD5Qe(pX!B4H(z)!AsiPGFB313pryH2f;N!(I{;OU zqOBvLd2yPW*+5r7wXbC*Uzqbakhr$vnaF=gbHXn4! z8OKdN^1ufquI&erTBEExtHxeas0{Ej@gFWY68zlLn1Ty04-9Ch07b+U_hiN|}OgjMTq((2cGdmYm4m;V9aV6D`z zTrm!ShEnOb=Z?9eZN0Z#BTKnu%J%@wyRlB(89hd=!S^3u%4F^i7he z-?>@Jy7TVbyuf%~cST}B3F}#=t>|?C=3M$({D{9S-F&-OOCI97!?nBev}*0G{2hir z;L6Vp4q0ER*{_?lduL8_&7=8F764@=8}V0W`7MavFa{s-X=b#?V3byQQz%Rs+ty$^jBBjH0o_c zcEDls2>A_|XCb%g3JuvAGQUg90r)Lz8sK5#)}jx$0+8ol2tY%A*arA(#_pI6MkBp( z=9flUP5nxKwY|q^@3!6L^5sLdy(vA-0;p^B_)XUE{djiWJ^+S710!Y^eM5?;X|;Id z-OqIe+@{$?t@6`t#+*G%eE6&~6dC~FIo~V`p!8~0Os$W}ma|B+RR=_~hTHU9y^+rn znn)l^2(Olxc}lNV0Z{NwCjb?5<(p8jRc<3ZOWblhihh(R&S>hl0czem1Vp2I(aINr zs0OQ@pMIjRE};S4WYv`L{d00xsVmxPM39F?TBHOLh$vwZnER#k<9>I)=bZPP_xR%l$u8AKz+n1|-X55M??aU1?*FwSSaqnIcS{d>Iqv9Bn^BIP;2c=K1uUV^uE02lM?c+}3Dl=4ZK~%C4IyC#z z#B*zeb)!b$njuEFWp0VL=JQl8ZmZk2@r!@Tca{z+2KwDMe-IzV;|``_MEg4x{S%Qj zZcnx-jLgmH*)!69JM)9&Pl1%0=wE1<9BIXHFIJD6^~eJprS-p$@IxR-n*+K)-5XK}N6SHZ<7WOV>99}HTDs~Z#+H<>p6C@Q!`8m?crshKLl914VJPeP!4_r#JiRE4iQ^cpv6d0_BH|gkgOlH}) zF>E5Lz;kz8xaTYQT_ZHshK_sY(v2<4nKvmC$1{Kb*LE||0oF{w&T zjSUE+Y>k@QJkd-_ZzpP)^*-aN+_8E|D))N1;NMttU{zMGYBVelkul-zM+dTAAgb2? z7~XQe*OEOm8#f4fY&+&=u%s%U-FQt-%&M~|XqfYK^>J-li<{CZDVj)D`tC^qicq?- zaU~0n^7^i2&bpgj8*tJ|NQp#gmZcO67IHiD+*%t^F9u>qYnG6f=egipSRZBraJ-i# z%q1Fx_5D43e%9)1V08|G5}W6Ffi%XWk75(@JY6o0 (-PY&GuG^^f_SX)R&Xe_(-nG+@SzIt(yA2L0VB6JC>isIv>KM zvGlIPWj+?|eyFkyh?l_h|A&Xw!pyaxhP-{4Jql3DKq7n85zwDc@yyzyE{ zX-u5l*i5XYNQOHdB{;R_^*iqBavDu|9wf5| zQh4ueoqa1LT{zCWpz-F+kJ#K#7B5WZ{cwvv_1#AT y1BhM)=nZ>Itx&7!8xN_K9E|ZE "Projectiles.Ranged"; + public override string Texture => "CalamityMod/Projectiles/Ranged/SuperradiantSaw"; + + public ref float Time => ref Projectile.ai[1]; + + public Particle SmallSlashSmear; + public Particle LargeSlashSmear; + public static Asset SawOutline; + public static Asset SmallSlash; + public static Asset LargeSlash; + + public override void SetStaticDefaults() + { + ProjectileID.Sets.TrailCacheLength[Type] = 4; + ProjectileID.Sets.TrailingMode[Type] = 2; + } + public override void SetDefaults() + { + Projectile.width = Projectile.height = 46; + Projectile.friendly = true; + Projectile.DamageType = DamageClass.Ranged; + Projectile.timeLeft = 270; + Projectile.penetrate = -1; + Projectile.tileCollide = false; + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 10; + Projectile.Calamity().pointBlankShotDuration = CalamityGlobalProjectile.DefaultPointBlankDuration; + } + + public override void AI() + { + // Timer and rotation + Time++; + Projectile.rotation += MathHelper.ToRadians(42f); + + // Make it lose velocity as it travels + Projectile.velocity *= 0.955f; + + // Continously spawn homing bolts and small saws + if (Time % 12 == 0 && Time > 30) + { + Vector2 randVelocity = Main.rand.NextVector2Unit() * Main.rand.NextFloat(7.5f, 9f); + if (Main.myPlayer == Projectile.owner) + Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, randVelocity, ModContent.ProjectileType(), (int)(Projectile.damage * 0.5f), 0f, Main.myPlayer); + } + + // Fade out at the end of its lifetime + if (Projectile.timeLeft <= 30) + { + Projectile.alpha += 8; + if (Projectile.alpha > 255) + Projectile.Kill(); + } + + // Rainbow smear particles which follow the path of the slashes + if (LargeSlashSmear == null) + { + LargeSlashSmear = new CircularSmearVFX(Projectile.Center, Color.Black, Time * -Projectile.rotation, 1.35f); + GeneralParticleHandler.SpawnParticle(LargeSlashSmear); + } + else + { + LargeSlashSmear.Rotation = -Projectile.rotation; + LargeSlashSmear.Time = 0; + LargeSlashSmear.Position = Projectile.Center; + LargeSlashSmear.Scale = 1.35f; + LargeSlashSmear.Color = Main.hslToRgb(0.5f + 0.5f * MathF.Sin(Main.GlobalTimeWrappedHourly * 5f), 1f, 0.6f) * 0.8f * Projectile.Opacity; + } + if (SmallSlashSmear == null) + { + SmallSlashSmear = new CircularSmearVFX(Projectile.Center, Color.Black, Projectile.rotation, 0.8f); + GeneralParticleHandler.SpawnParticle(SmallSlashSmear); + } + else + { + SmallSlashSmear.Rotation = Projectile.rotation; + SmallSlashSmear.Time = 0; + SmallSlashSmear.Position = Projectile.Center; + SmallSlashSmear.Scale = 0.8f; + SmallSlashSmear.Color = Main.hslToRgb(0.5f + 0.5f * MathF.Cos(Main.GlobalTimeWrappedHourly * 5f), 1f, 0.6f) * 0.6f * Projectile.Opacity; + } + } + + public override bool? CanDamage() => Projectile.timeLeft > 30; + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + target.AddBuff(ModContent.BuffType(), 180); + target.AddBuff(ModContent.BuffType(), 90); + SoundEngine.PlaySound(new SoundStyle("CalamityMod/Sounds/Custom/SwiftSlice"), Projectile.Center); + + // SUPER EPIC AND AWESOME PARTICLES + for (int s = 0; s < 12; s++) + { + Vector2 sparkVel = Main.rand.NextVector2CircularEdge(1f, 1f) * Main.rand.NextFloat(14f, 18f); + float sparkSize = Main.rand.NextFloat(1f, 1.4f); + Color sparkColor = Main.hslToRgb(Main.rand.NextFloat(), 1f, 0.8f); + + Particle sparked = new AltLineParticle(target.Center, sparkVel, false, 30, sparkSize, sparkColor); + GeneralParticleHandler.SpawnParticle(sparked); + } + for (int sq = 0; sq < 5; sq++) + { + Vector2 squareVel = Main.rand.NextVector2CircularEdge(1f, 1f) * Main.rand.NextFloat(10f, 16f); + float squareSize = Main.rand.NextFloat(3.2f, 4f); + Color squareColor = Main.hslToRgb(Main.rand.NextFloat(), 0.6f, 0.8f); + + Particle squared = new SquareParticle(target.Center, squareVel, true, 30, squareSize, squareColor); + GeneralParticleHandler.SpawnParticle(squared); + } + } + + public override void OnKill(int timeLeft) + { + SoundEngine.PlaySound(new SoundStyle("CalamityMod/Sounds/Custom/CeramicImpact", 2), Projectile.Center); + + for (int i = 0; i < 32; i++) + { + Vector2 velocity = ((MathHelper.TwoPi * i / 32f) - (MathHelper.Pi / 32f)).ToRotationVector2() * 32f; + Particle sparkle = new CritSpark(Projectile.Center, velocity, Color.White, Color.Lime, 1.5f, 30, 0.1f, 3f, Main.rand.NextFloat(0f, 0.01f)); + GeneralParticleHandler.SpawnParticle(sparkle); + } + } + + public override void ModifyDamageHitbox(ref Rectangle hitbox) => hitbox.Inflate(70, 70); + + public override bool PreDraw(ref Color lightColor) + { + LargeSlash ??= ModContent.Request("CalamityMod/Projectiles/Ranged/SuperradiantSawLargeSlash"); + Texture2D largeSlashTexture = LargeSlash.Value; + SmallSlash ??= ModContent.Request("CalamityMod/Projectiles/Ranged/SuperradiantSawSmallSlash"); + Texture2D smallSlashTexture = SmallSlash.Value; + Color slashColor = new Color(200, 200, 200, 100) * Projectile.Opacity; + + Main.EntitySpriteDraw(largeSlashTexture, Projectile.Center - Main.screenPosition, null, slashColor, -Projectile.rotation, largeSlashTexture.Size() * 0.5f, 1f, SpriteEffects.None); + + if (Time % 4 == 0) + { + Vector2 randomParticleOffset = new Vector2(Main.rand.NextFloat(-Projectile.width * 1.75f, Projectile.width * 1.75f), Main.rand.NextFloat(-Projectile.width * 1.75f, Projectile.width * 1.75f)); + float randomParticleScale = Main.rand.NextFloat(0.65f, 0.95f); + Color bloomColor = Color.Lerp(new Color(29, 120, 30), new Color(56, 255, 59), MathF.Abs(MathF.Sin(Time))); + Particle bloomCircle = new BloomParticle(Projectile.Center + randomParticleOffset, Projectile.velocity, Main.rand.NextBool() ? Color.White : bloomColor, randomParticleScale, randomParticleScale, 4, false); + GeneralParticleHandler.SpawnParticle(bloomCircle); + } + Main.EntitySpriteDraw(smallSlashTexture, Projectile.Center - Main.screenPosition, null, slashColor, Projectile.rotation, smallSlashTexture.Size() * 0.5f, 1f, SpriteEffects.None); + + if (Time % 4 == 0) + { + Vector2 randomParticleOffset = new Vector2(Main.rand.NextFloat(-Projectile.width, Projectile.width), Main.rand.NextFloat(-Projectile.width, Projectile.width)); + float randomParticleScale = Main.rand.NextFloat(0.35f, 0.65f); + Color bloomColor = Color.Lerp(new Color(29, 120, 30), new Color(56, 255, 59), MathF.Abs(MathF.Sin(Time))); + Particle bloomCircle = new BloomParticle(Projectile.Center + randomParticleOffset, Projectile.velocity, Main.rand.NextBool() ? Color.White : bloomColor, randomParticleScale, randomParticleScale, 4, false); + GeneralParticleHandler.SpawnParticle(bloomCircle); + } + + // Draw the saw itself at full brightness, glow and outline in rainbow + Texture2D buzzsawTexture = TextureAssets.Projectile[Type].Value; + Main.EntitySpriteDraw(buzzsawTexture, Projectile.Center - Main.screenPosition, null, Color.White, Projectile.rotation, buzzsawTexture.Size() * 0.5f, 1f, SpriteEffects.None); + + SawOutline ??= ModContent.Request("CalamityMod/Projectiles/Ranged/SuperradiantSawOutline"); + Texture2D outline = SawOutline.Value; + Main.EntitySpriteDraw(outline, Projectile.Center - Main.screenPosition, null, Main.DiscoColor, Projectile.rotation, outline.Size() * 0.5f, 1f, SpriteEffects.None); + + if (!CalamityConfig.Instance.Afterimages) + return false; + + // Special afterimage drawing to include the slashes + for (int i = 1; i < Projectile.oldPos.Length; i++) + { + float afterimageRot = Projectile.oldRot[i]; + Vector2 drawPos = Projectile.oldPos[i] + buzzsawTexture.Size() * 0.5f - Main.screenPosition; + float intensity = MathHelper.Lerp(0.1f, 0.6f, 1f - i / (float)Projectile.oldPos.Length); + + Main.EntitySpriteDraw(buzzsawTexture, drawPos, null, Color.White * intensity, afterimageRot, buzzsawTexture.Size() * 0.5f, 1f, SpriteEffects.None); + Main.EntitySpriteDraw(largeSlashTexture, drawPos, null, slashColor * intensity, -afterimageRot, largeSlashTexture.Size() * 0.5f, 1f, SpriteEffects.None); + Main.EntitySpriteDraw(smallSlashTexture, drawPos, null, slashColor * intensity, afterimageRot, smallSlashTexture.Size() * 0.5f, 1f, SpriteEffects.None); + } + return false; + } + } +} diff --git a/Projectiles/Ranged/SuperradiantSawOutline.png b/Projectiles/Ranged/SuperradiantSawOutline.png new file mode 100644 index 0000000000000000000000000000000000000000..87ec4554892dc17ec8ec3fc3624966b19e076e7c GIT binary patch literal 370 zcmV-&0ge8NP)Px$EJ;K`RA_QHmNRj7j zjhciFJ}i~recb)#w@PQogtOupu)fI7baedMy%!PN46l)b0e9xDnJcWZk{LcDgPBSh zh|(lW)fBH0$HY$!WZC>bcdgJEX`9!j+&%#}#VC!qBR&f~Bdk=@&nb;SnQ$1MIh00r z0Hu|P#A}7d$Q%e7O|FwxJ-hUxGO`0Lt$M8VqA@ZDg2o&O8egfUX@Htu^w(NVK<^9_ zaNdv1fuLdDA)=*Mv^Pv??= z%cQGVW$Nsyx_8e3b#^6H%j7kp6wIXiH2O;&Kc5a#66bW!AlYP^Z)<= literal 0 HcmV?d00001 diff --git a/Projectiles/Ranged/SuperradiantSawSmallSlash.png b/Projectiles/Ranged/SuperradiantSawSmallSlash.png new file mode 100644 index 0000000000000000000000000000000000000000..c8cf403c47a65de3c35c9c710c8d5f60cf878bcd GIT binary patch literal 1050 zcmV+#1m*jQP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1FuO$K~#8N?VLYr z6j2mMcUKgf6v1c^BuxahvawPttp&l(ub_oRAYBT(Kne>#fR&vf+FPlW2v#bXMgkIz zgkY!W%6r-0klf94W_O*Lm%Hb{aPyMMHpAimd2grF77sVC^usk+!i4k&5uh3vST7g} z|K`ijem`7;CDaT?!ogr-J76U22NT-`Bc0G4#IccuPqwed_1*bb6MrU*4n{g*Yt*iBze1fsszAY!g*#-e9B?O06o(jrU&9 z#lJteyoI4Hf{{)rwMe<~*Pj=0-P^enjfj7khH|+#^2i)ViZSa z-^Yk)d4Q2lNZMrkMr-8S`c{lot9gKtP8hPu=0>6ZkzJ2G!AK_zJ;P7>4$MmnLe zWMlJuG)LwMYoz)~kuuFzs2Eu<80mz<5?if`l#%y;+=y{y=6Q^t)<4E5&MuydQNO2Z ztrv`R!q`U2w8y8GV!ZuzEk>>1EiA{#Otu*?(h1#E|0v3Gq|Cecc{N7mOwDVn_M0#n z80mzujZEdp(HBb`t=N80a0(nsb6MmnL?NTJ;gq1md1S!+9B zq!TI|shp>?ILeXM%%#P-!B4xeAK45T>4eHgD(7i(liCH*2?5>5nVn|9NGFVJq_8Ih z-p)LV(e9*RWHVr-6Otzc^eyG1y=yUQ!lSo&q)bfhme5bu3r0F2d5X@OB{bo&CfeDm zzNxH954o~lFwzO7Mv7DpEZgP4%x1tyClq$rep2Syw|Q7bHH^1>)B{F3A!(%g$Y(n% zF$!xYIWG?|(h0?b3^~zOss|A!HFoX_?Sqj{C>~^}PWPUa3o};DS@&Y!9vP}oRie-y z80mzeiZj(urq15zeyZ1Y!AK_zJ;*T07*qoM6N<$f(EPSfdBvi literal 0 HcmV?d00001 diff --git a/Projectiles/Ranged/SuperradiantSlaughtererHoldout.cs b/Projectiles/Ranged/SuperradiantSlaughtererHoldout.cs new file mode 100644 index 0000000000..fd9d690fe4 --- /dev/null +++ b/Projectiles/Ranged/SuperradiantSlaughtererHoldout.cs @@ -0,0 +1,352 @@ +using CalamityMod.Buffs.DamageOverTime; +using CalamityMod.Cooldowns; +using CalamityMod.Items.Weapons.Melee; +using CalamityMod.Items.Weapons.Ranged; +using CalamityMod.Particles; +using CalamityMod.Projectiles.BaseProjectiles; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ReLogic.Content; +using ReLogic.Utilities; +using System; +using Terraria; +using Terraria.Audio; +using Terraria.DataStructures; +using Terraria.ID; +using Terraria.ModLoader; + +namespace CalamityMod.Projectiles.Ranged +{ + public class SuperradiantSlaughtererHoldout : BaseGunHoldoutProjectile + { + public override int AssociatedItemID => ModContent.ItemType(); + public override float RecoilResolveSpeed => 0.05f; + public override float MaxOffsetLengthFromArm => 36f; + public override float BaseOffsetY => -5f; + public override float OffsetYUpwards => -5f; + public override float OffsetYDownwards => 5f; + public override Vector2 GunTipPosition => Projectile.Center + Vector2.UnitX.RotatedBy(Projectile.rotation) * Projectile.width * 0.25f; + + public ref float Time => ref Projectile.ai[0]; + public const float ChargeupTime = 120f; + public SlotId ChargeIdle; + + // Controls the saw visually disappearing from the holdout when it fires. + public bool NoSawOnHoldout = false; + + public Particle SmallSlashSmear; + public Particle LargeSlashSmear; + public static Asset Holdout; + public static Asset HoldoutGlow; + public static Asset MiniSaw; + public static Asset SmallSlash; + public static Asset LargeSlash; + + public override void SetStaticDefaults() + { + Main.projFrames[Type] = 5; + } + + public override void SetDefaults() + { + base.SetDefaults(); + Projectile.friendly = true; + Projectile.DamageType = DamageClass.Ranged; + Projectile.penetrate = -1; + Projectile.ignoreWater = true; + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 10; + } + + public override void KillHoldoutLogic() + { + if (HeldItem.type != Owner.ActiveItem().type) + { + Projectile.Kill(); + Projectile.netUpdate = true; + } + } + + public override void HoldoutAI() + { + Time++; + float SawPower = MathHelper.Clamp(Time / ChargeupTime, 0f, 1f); + + if (SoundEngine.TryGetActiveSound(ChargeIdle, out var Idle) && Idle.IsPlaying) + Idle.Position = GunTipPosition; + + // Handle the right-click dash (holds priority over left-click) + if (Owner.Calamity().mouseRight && !Owner.HasCooldown(SuperradiantSawBoost.ID)) + { + Owner.AddCooldown(SuperradiantSawBoost.ID, SuperradiantSlaughterer.DashCooldown); + Owner.Calamity().sBlasterDashActivated = true; + SoundEngine.PlaySound(new SoundStyle("CalamityMod/Sounds/Custom/MeatySlash"), GunTipPosition); + + // Throws a lingering saw at the cursor that deals 3x damage (since the holdout already deals 2x) + float clampedMouseDist = MathHelper.Clamp(Vector2.Distance(GunTipPosition, Owner.Calamity().mouseWorld), 0f, 960f); + float adjustedMouseDist = clampedMouseDist / 21f; + Projectile.NewProjectile(Projectile.GetSource_FromThis(), GunTipPosition, Projectile.velocity.SafeNormalize(Vector2.UnitY) * adjustedMouseDist, ModContent.ProjectileType(), (int)(Projectile.damage * 1.5f), Projectile.knockBack, Projectile.owner); + + // Special case: right-clicking while not holding left-click + // This is to keep it friendly to use both fires at the same time, but end the animation early if not + if (Projectile.ai[1] >= 2f) + { + NoSawOnHoldout = true; + OffsetLengthFromArm -= 16f; + Projectile.timeLeft = Owner.ActiveItem().useAnimation; + KeepRefreshingLifetime = false; + Idle?.Stop(); + } + + // If moving, make particle effects when the dash activates + if (Owner.velocity != Vector2.Zero) + { + int particleAmt = 7; + for (int c = 0; c < particleAmt; c++) + { + Color sparkColor = Color.Lerp(new Color(122, 240, 58), new Color(32, 186, 171), c / (particleAmt - 1)); + Particle spark = new CritSpark(Owner.Center, Owner.velocity.RotatedByRandom(MathHelper.ToRadians(13f)) * Main.rand.NextFloat(-2.1f, -4.5f), Color.White, sparkColor, 2f, 45, 2.25f, 2f); + GeneralParticleHandler.SpawnParticle(spark); + } + for (int e = 0; e < particleAmt * 2; e++) + { + Color sparkColor2 = Color.Lerp(new Color(122, 240, 58), new Color(32, 186, 171), e / (particleAmt - 1)); + Particle spark2 = new NanoParticle(Owner.Center, Owner.velocity.RotatedByRandom(MathHelper.ToRadians(-MathHelper.PiOver4)) * Main.rand.NextFloat(2.5f, 4.5f), sparkColor2, 1f, 45, Main.rand.NextBool(3)); + GeneralParticleHandler.SpawnParticle(spark2); + } + } + } + else if (Owner.CantUseHoldout() && Projectile.ai[1] < 1f) + { + KeepRefreshingLifetime = false; + Idle?.Stop(); + + Projectile.ai[1] = 1f; + Projectile.timeLeft = Owner.ActiveItem().useAnimation; + SoundStyle ShootSound = new("CalamityMod/Sounds/Item/SawShot", 2) { PitchVariance = 0.1f, Volume = 0.4f + SawPower * 0.5f }; + SoundEngine.PlaySound(ShootSound, GunTipPosition); + + float sawDamageMult = MathHelper.Lerp(1f, 5f, SawPower) / 2f; // The damage must be divided by 2 to offset the holdout having 2x base damage. + int sawPierce = (int)MathHelper.Lerp(2f, 7f, SawPower); + int sawLevel = (SawPower >= 1f).ToInt() + (SawPower >= 0.25f).ToInt(); + + // ai[0] determines which slashes are drawn. ai[1] is the saw's timer variable. ai[2] stores the saw's pierce. + Projectile.NewProjectile(Projectile.GetSource_FromThis(), GunTipPosition, Projectile.velocity.SafeNormalize(Vector2.UnitY) * SuperradiantSlaughterer.ShootSpeed, ModContent.ProjectileType(), (int)(Projectile.damage * sawDamageMult), Projectile.knockBack, Projectile.owner, sawLevel, 0f, sawPierce); + + NoSawOnHoldout = true; + OffsetLengthFromArm -= 4f + 12f * SawPower; + + int sparkPairCount = 3 + 2 * sawLevel; + for (int s = 0; s < sparkPairCount; s++) + { + float velocityMult = Main.rand.NextFloat(5f, 8f) + Main.rand.NextFloat(4f, 7f) * sawLevel; + float scale = Main.rand.NextFloat(0.6f, 0.8f) + Main.rand.NextFloat(0.3f, 0.5f) * sawLevel; + Color color = Main.hslToRgb(Main.rand.NextFloat(), 1f, 0.8f); + + Vector2 sparkVelocity = Projectile.velocity.RotatedByRandom(MathHelper.PiOver4) * velocityMult; + Particle weaponShootSparks = new AltLineParticle(GunTipPosition, sparkVelocity, false, 40, scale, color); + GeneralParticleHandler.SpawnParticle(weaponShootSparks); + + // re-randomize rotation for the alternate particle + sparkVelocity = Projectile.velocity.RotatedByRandom(MathHelper.PiOver4) * velocityMult; + Particle weaponShootSparks2 = new AltSparkParticle(GunTipPosition, sparkVelocity, false, 40, scale, color); + GeneralParticleHandler.SpawnParticle(weaponShootSparks2); + } + } + + if (NoSawOnHoldout) + { + Projectile.frame = 4; + return; + } + else + { + Projectile.frameCounter++; + if (Projectile.frameCounter >= 3) + { + Projectile.frameCounter = 0; + Projectile.frame++; + if (Projectile.frame > 3) + Projectile.frame = 0; + } + } + + // Smear particles which follow the path of the slashes + if (SawPower >= 1f) + { + if (LargeSlashSmear == null) + { + LargeSlashSmear = new CircularSmearVFX(GunTipPosition, Color.Black, Time * -MathHelper.ToRadians(42f), 1.35f); + GeneralParticleHandler.SpawnParticle(LargeSlashSmear); + } + else + { + LargeSlashSmear.Rotation = Time * -MathHelper.ToRadians(42f); + LargeSlashSmear.Time = 0; + LargeSlashSmear.Position = GunTipPosition; + LargeSlashSmear.Scale = 1.35f; + LargeSlashSmear.Color = Main.hslToRgb(0.5f + 0.5f * MathF.Sin(Main.GlobalTimeWrappedHourly * 5f), 1f, 0.6f) * 0.8f; + } + } + if (SawPower >= 0.25f) + { + if (SmallSlashSmear == null) + { + SmallSlashSmear = new CircularSmearVFX(GunTipPosition, Color.Black, Time * MathHelper.ToRadians(42f), 0.8f); + GeneralParticleHandler.SpawnParticle(SmallSlashSmear); + } + else + { + SmallSlashSmear.Rotation = Time * MathHelper.ToRadians(42f); + SmallSlashSmear.Time = 0; + SmallSlashSmear.Position = GunTipPosition; + SmallSlashSmear.Scale = 0.8f; + SmallSlashSmear.Color = Main.hslToRgb(0.5f + 0.5f * MathF.Cos(Main.GlobalTimeWrappedHourly * 5f), 1f, 0.6f) * 0.6f; + } + } + + if (Time < ChargeupTime) + { + if (Time == 30f && !NoSawOnHoldout) + ChargeIdle = SoundEngine.PlaySound(new SoundStyle("CalamityMod/Sounds/Custom/BuzzsawCharge") { Volume = 0.3f }, GunTipPosition); + } + else + { + if ((Time + 240) % 360 == 0) + ChargeIdle = SoundEngine.PlaySound(new SoundStyle("CalamityMod/Sounds/Custom/BuzzsawIdle"), GunTipPosition); + + if (Time % 3 == 0) + { + Vector2 smokeVelocity = Vector2.UnitY * Main.rand.NextFloat(-7f, -12f); + smokeVelocity = smokeVelocity.RotatedByRandom(MathHelper.Pi / 8f); + Color smokeColor = Main.rand.NextBool() ? Main.DiscoColor : Color.Gray; + Particle fullChargeSmoke = new HeavySmokeParticle(GunTipPosition + Main.rand.NextVector2CircularEdge(3f, 3f), smokeVelocity, smokeColor, 30, 0.65f, 0.5f, Main.rand.NextFloat(-0.2f, 0.2f), true); + GeneralParticleHandler.SpawnParticle(fullChargeSmoke); + } + } + } + + public override void OnSpawn(IEntitySource source) + { + base.OnSpawn(source); + ExtraBackArmRotation = MathHelper.ToRadians(15f); + } + + // Failsafe because apparently the sound doesn't stop sometimes + public override void OnKill(int timeLeft) + { + if (SoundEngine.TryGetActiveSound(ChargeIdle, out var Idle)) + Idle?.Stop(); + } + + // The holdout can deal damage; you're literally spinning up a buzzsaw at the end, after all. + public override bool? CanDamage() => !NoSawOnHoldout; + + public override void ModifyDamageHitbox(ref Rectangle hitbox) + { + hitbox = new Rectangle((int)GunTipPosition.X - 23, (int)GunTipPosition.Y - 23, 46, 46); + + if (Time / ChargeupTime >= 1f) + hitbox.Inflate(72, 72); + else if (Time / ChargeupTime >= 0.25f) + hitbox.Inflate(32, 32); + } + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + target.AddBuff(ModContent.BuffType(), 300); + target.AddBuff(ModContent.BuffType(), 150); + SoundEngine.PlaySound(new SoundStyle("CalamityMod/Sounds/Custom/SwiftSlice") { Volume = 0.7f }, GunTipPosition); + + // EPIC AND COOL RAINBOW PARTICLES WOOOO + int SawLevel = (Time / ChargeupTime >= 1f).ToInt() + (Time / ChargeupTime >= 0.25f).ToInt(); + int onHitSparkAmount = 4 + 4 * SawLevel; + for (int s = 0; s < onHitSparkAmount; s++) + { + Vector2 sparkVel = Main.rand.NextVector2CircularEdge(1f, 1f) * (Main.rand.NextFloat(6f, 10f) + 5f * SawLevel); + float sparkSize = 0.4f + Main.rand.NextFloat(0.3f, 0.6f) * SawLevel; + Color sparkColor = Main.hslToRgb(Main.rand.NextFloat(), 1f, 0.8f); + + Particle sparked = new AltLineParticle(target.Center, sparkVel, false, 20, sparkSize, sparkColor); + GeneralParticleHandler.SpawnParticle(sparked); + } + for (int sq = 0; sq < 5; sq++) + { + Vector2 squareVel = Main.rand.NextVector2CircularEdge(1f, 1f) * (Main.rand.NextFloat(6f, 10f) + 5f * SawLevel); + float squareSize = 1.6f + Main.rand.NextFloat(1f, 1.6f) * SawLevel; + Color squareColor = Main.hslToRgb(Main.rand.NextFloat(), 0.6f, 0.8f); + + Particle squared = new SquareParticle(target.Center, squareVel, true, 20, squareSize, squareColor); + GeneralParticleHandler.SpawnParticle(squared); + } + } + + public override bool PreDraw(ref Color lightColor) + { + Holdout ??= ModContent.Request("CalamityMod/Projectiles/Ranged/SuperradiantSlaughtererHoldout"); + Texture2D holdoutTexture = Holdout.Value; + LargeSlash ??= ModContent.Request("CalamityMod/Projectiles/Ranged/SuperradiantSawLargeSlash"); + Texture2D largeSlashTexture = LargeSlash.Value; + SmallSlash ??= ModContent.Request("CalamityMod/Projectiles/Ranged/SuperradiantSawSmallSlash"); + Texture2D smallSlashTexture = SmallSlash.Value; + Color slashColor = new Color(200, 200, 200, 100); + + Vector2 drawPosition = Projectile.Center - Main.screenPosition; + Rectangle frame = holdoutTexture.Frame(verticalFrames: Main.projFrames[Type], frameY: Projectile.frame); + float drawRotation = Projectile.rotation + (Projectile.spriteDirection == -1 ? MathHelper.Pi : 0f); + Vector2 rotationPoint = frame.Size() * 0.5f; + SpriteEffects flipSprite = Projectile.spriteDirection == -1 ? SpriteEffects.FlipHorizontally : SpriteEffects.None; + + if (!NoSawOnHoldout) + { + float shake = Utils.Remap(Time, 0f, ChargeupTime, 0f, 3f); + drawPosition += Main.rand.NextVector2Circular(shake, shake); + } + + // Mini saw drawn under the gun + MiniSaw ??= ModContent.Request("CalamityMod/Projectiles/Ranged/SuperradiantSlaughtererHoldoutMiniSaw"); + Texture2D mini = MiniSaw.Value; + Vector2 verticalOffset = Vector2.UnitY.RotatedBy(Projectile.rotation); + if (Math.Cos(Projectile.rotation) < 0f) + verticalOffset *= -1f; + Vector2 miniSawPosition = drawPosition - Vector2.UnitX.RotatedBy(Projectile.rotation) * Projectile.width * 0.125f + verticalOffset * 6f; + Main.EntitySpriteDraw(mini, miniSawPosition, null, Color.White, Time * MathHelper.ToRadians(24f), mini.Size() * 0.5f, Projectile.scale, flipSprite); + + Main.EntitySpriteDraw(holdoutTexture, drawPosition, frame, Projectile.GetAlpha(lightColor), drawRotation, rotationPoint, Projectile.scale, flipSprite); + + // Glowmask + HoldoutGlow ??= ModContent.Request("CalamityMod/Projectiles/Ranged/SuperradiantSlaughtererHoldoutGlow"); + Texture2D glow = HoldoutGlow.Value; + Main.EntitySpriteDraw(glow, drawPosition, frame, Color.White, drawRotation, rotationPoint, Projectile.scale, flipSprite); + + if (NoSawOnHoldout) + return false; + + if (Time > 30f) + { + if (Time / ChargeupTime >= 1f) + Main.EntitySpriteDraw(largeSlashTexture, GunTipPosition - Main.screenPosition, null, slashColor, Time * -MathHelper.ToRadians(42f), largeSlashTexture.Size() * 0.5f, 1f, SpriteEffects.None); + + if (Time / ChargeupTime >= 0.25f) + Main.EntitySpriteDraw(smallSlashTexture, GunTipPosition - Main.screenPosition, null, slashColor, Time * MathHelper.ToRadians(42f), smallSlashTexture.Size() * 0.5f, 1f, SpriteEffects.None); + + if (!CalamityConfig.Instance.Afterimages) + return false; + + // Special afterimage drawing for the slashes only + for (int i = 1; i < 3; i++) + { + float intensity = MathHelper.Lerp(0.05f, 0.25f, 1f - i / 3f); + + if (Time / ChargeupTime >= 1f) + Main.EntitySpriteDraw(largeSlashTexture, GunTipPosition - Main.screenPosition, null, slashColor * intensity, (Time - i) * -MathHelper.ToRadians(42f), largeSlashTexture.Size() * 0.5f, 1f, SpriteEffects.None); + + if (Time / ChargeupTime >= 0.25f) + Main.EntitySpriteDraw(smallSlashTexture, GunTipPosition - Main.screenPosition, null, slashColor * intensity, (Time - i) * MathHelper.ToRadians(42f), smallSlashTexture.Size() * 0.5f, 1f, SpriteEffects.None); + } + } + + return false; + } + } +} diff --git a/Projectiles/Ranged/SuperradiantSlaughtererHoldout.png b/Projectiles/Ranged/SuperradiantSlaughtererHoldout.png new file mode 100644 index 0000000000000000000000000000000000000000..e5445246aae833a02417cc0d8a3513d6eaf6c84f GIT binary patch literal 4177 zcmYM22{e>lAHWf>CG@J1on9(~7>s=^X^bt)Fi5tP-Lx=c$=F_nGFhS+WE(WLkToMF zZ<1wfVJu}S#=eh+l=vR+_nq^d^W5j2d!BplbMJG1|KI*|aazfoo4cz6c_j|{*f#ZvqpydcbLVGP1xK4F zI;e`$?;1Mts1CVN8*$jM6EY~sxL#V~AqOcVuuJi+NfG^3R0xe}VW2T)En^ z?|SJUhC}zLZ(q1lb`G$$-20T+NX+zV*c*7iTz?v^)k-7sM|2j(FNtvUB-!%QmeJB% z)m@=CpCs;$M~S*dzrOGGWUOsWQ-90z)$ZcEgJ9f@597@zCPknfY}I`PLkL}6p%~X3 zWk`VTRVff1Lzy#6du^+8PVKx*3->4P(^B3oR%62&HAEB5=eDsmzoqicx4%AnS0bEV zrcBytY7J^7-?)G4kkC3~0pT=_Dm z+OT+M49QNh2o~Wk;whI0Kalkw2Pb_AuL)~Fz`<5MFW@R~<}QFP{v*KF{v6-Q>>Wq~Qoci*3R$_SZ<}IHS%TA4X zCxs$jF3T(=HjqIk`c02#o9(ZmZb#rQbXZs-lpdxQpuRlv(Pv zs$P(2EHSZmK94LyTDZcciZ}b=j>3w@7 zglgFZKuQtLOceOsOIht51S9$4vUV0*4abyu z#=h>mNIFAuwy}8MjvG$fV)&{}g%>-2cJzCR$w|L?-(rm>s~cdRTPiLMcz27p9JO8m z!FcHtML+SXcoyRmEm0G&0}9K>N;_r`S1ikTU*|j|=WlkulRDlL5gM|7AsyNj zt#$t&0$BP{UT~kL+MWZr)MM>ExtZsF%2JY|EI4c+Og{FQRi#%PnRvQ|y_-Plq`IGC-M_0kGf zsAIKUs_5~A98~R=lL!xVKDSfi`Izv-t2kaslkM*@x(1&IQ?MY5xCv!sArsCi7^p

~`+iUp!$o~_R~@GHun8|@ z4~Rz{zS$3!AUPZn78PT}+dU4qYs}qFuyuJ=lvtAv7S!0~%m;k2(w80|HRTx3Zc2 zxBmB253{-5m%Mf~2h~S2_#u^rO~0oMA~#l9L9lOQ;cL##A|r!Sq>OtJsf8}9 z-Jnb!H7M(7mGV#^F>8OaN(#xY$%o6B9sNsJA+Cn(Ezg^dM$WjlVa3KpJmPVrbO~j_ zAF6eg-^=dDMpf-!k(-n)~BuqjVJn*WaY|s&C!fOau)u?2hsZ&1? z7MDd83|IM;W!<&aq-{L_M=aM~RL>Y;e5Pp&wmfr^UQ}0iUwY1_fl{QH#E0>R&|-sToPA&)K~ z1k8vgcg(lUoxgqOZ$LyNqM{(bDr3hp>b=PJE_thcalGD7B^UdThBe}Vrb0O?y@yuj zw<)FcU-L$89lXwv=%ddW$=6#WU}wgqg`Ymhh4rR{Q2yTIX3y;&Yx}9Qt8eB}^N<5( zq=xE44#YNgdimQi8TV((SHl()ywA7sKPxf#A=p9qBj7H=p6hAFi&AVeTKSq7b>(TQ z6d$Q6`s=&iK`pL3mXl0|GIXg~H$bF({ZH1NCn2_%6lcXFOTQ$6Y6#~4^D&RdY!zW3 zC}p^PzQyMx?25bmU?M^Z!7&}HTlMaW7484Br2wnYU($15FR6+Dl~8*GHdJ!mlB!w@ zzv--k5H6i}=tF+@QDJ*V9s#nMFMO_wV6fW1X=9`i-EQdCF^L+gUGboeLXgi%JrV=H z%$Es6c9s2ybq`xE;kLU{z&*o(y~qJAK1=7;gC4=#uhj%SusOk;s2FcBM%HSKymjX1 zrmqI58qH(~5Jj^UnGC^dM!%YNMwV_1pixeoaDW`mT{sY$(^=#$ zu;Tu0167l@gV!~bh2 zxUih$hp528BX*&nS@rtV_9*jDKZyd*vT^%XtyHk78@!;X4+3n3AM7>w&f1pkGB+=H7EABie0%>;%)a z6AhP6S)JeBOoiRiSCh`JG`-rY>lFUC!%RcJ((05U$p=DhwQeMV1S;1|ajgeAhAky# zqe15Ic|VQId9H*q;{T(ewt*lctGzqg|EhhlMB=wP;=987^R3u4QFx34Bt_3cE2ixL9ac`{(w@hHouY+87EG^jM_vo) zv~B>%b|Y#Cc12aK?y17{0Nf{u^&`|b%r%(s+dw7{KJ!ufVw^d!?f+5^@M<`~$5FKd zZ@|J?th1`VimKo z*$6NE z{GRlof;Rd*vreus&ux@y@H*4PU#o=M*Sj#i6PlI^t4vcmhRwek???Mlt9b-Lb9FS>hJxpDAw$T2LrwKum7 zh;`|;lkd}L2LvePJBus2Yf^3?FwGPtOJ_uLC$clHpKEj4e{7aSY)ilD#jjXeUhu<+ zubS0wa=PN>egi^R^#d2*SCMm>k+tHYDrHc+1=}2}x_cj#@k8KOw|ZKyv7k*=HQ5NM zr-8sOgMzviZ_obBikQ|e6sd@5ARRh~AX~`Eiyp4V#~c-p4i=nSY!1l1a2f<1QLe?K z^dEiBl97}B?rLan40!lu0%mHG!@I2C6`FM`P`es8yT|o2{P@gwJN1>2KS0xWNN3Vl zyw06nZkSa-e`~yMzMClEoOL7La2JxXJw$56^xPuCYhBiRYkt3Q%6Lbcsf=?_*<@pP zfJi}!l?iX%^oN7P{J{MJu9I>3sztedmkc1*A3C&)fDUJfdb{dKwjNz4gBQ;#1NsdNFNm zj#oFwMsLy~ zcAd${&dNNYRoxi}>Kg>W@NFEUUWMNzH2~kGj%ZdvAb8wgGopA+ZGw9Q`c{@(be325 z8NzR!6=wR2tK1HmeZRq!us@Elc5Rgvi_`4>YJt-2PZjP{P=_6?`w?Ni`Gpy%Y#z8u zM&~lU;%CIesB_0DzM4Qln<;;<&s%%&>S9KG&odG81vTV{HM@x$VP`EJVth&dNFgg7WN|WTBN0gG!#&Bxqtv~r zNR8hvFMe%XzhWw@S6MMD9_f=eXc)P!5#-t_MO^By0nALrzs8iu%Jm;S4bS&H zvS|-a);m5`VC!$wE*xvq2mE(gt(#=*ROKUq@kq2*kIu`2Ok$o{CDAZ-!QZj6+1iw(yEFHOYy0vh%E z2MEiLAx#!cdq}>!hC76abzG?6-j q+pl+z7mWwj`rj+HgHAs9~H1co766i00Q_AKjJxqH67@7ecp?)~P^nS1u* z?6dYd-+r!d4<6Lue~X@O{UqcS&pc(@;E;G)oFtiO52iXXSP0yt z;=MM0UCH=8AKWbWpV{?9$?%g#d|U3f>~mEnoEdw3$5sh{ap_pO`fP46Lk-ZxfTH>| zU`JngcBZCNF;!zE7&WGQZRYuRZF7wB{aw`RfZE~)-k7?mI-=l|8GQB-lrLWnX6_k&EyB$IC58K=KiwY zUirQ3BiH>L(%UE3S9-^lWZcoCHp~4zqlU`$=VM39b+48;O2)@cpDiuxB?Ykl?vnwU z9S}qV3LrawI!UnP*0b}TuVgSr>wo!+V}&xyo;pjyef?M;EtskJ^uS1@8#?hF`FF;9 z&er{A>y81L3WiQT_{$Pcv!Qs7@6$Ix`#<@b0g4*Zn0m>$Wl~v)_x?Nom87eF*BMob zVCIb-dnEmL25pn;((WF)F7Nv|L+Y=M9hUhG#`bMEK<@u->ql~hO+9jw%P-V+@)tC1 zvFnFp1QqpipU=zyb!a35lxvEAry7E??VSJ0e)6bWkKdXh1LDn{m~EZGSRYekKlO?+ z)Br7$p=VssA+7Uc_bwGiT(;o%^82bY&XXK(e(V9c-Ztk)8OBWe$y|vCn+e7~e)U}v z|Kdwdlq>SpDkwC3-1;wN=0Csp_D)I4Onv^X2~oE5qdm`Lihz+6Mrdd=R2yo5IvjHY z3Lx*id=Kas?wd?*2rW0w(&>Exh5^k}kGi8p>EL9?FS$0B%U{ z#hIjk8PuBjy?C%I_k*L|mxjj4%TNO}F`%dpo~ecnJ>cw9B?>bPwiD^uhR(juF*!9e zVWa2H`Kpqlko*sMcaB`IZr>QjPy@6=fNC~K z3+L8ei=R52dlzVxnZbDOr7Op0n2On|NA|x$qMWnk7P(?}Dw?5rU(f)}i=Zcct$^hf z2F!Dwe$z!#Qnsa-6~kD6P5ZeLZ%WrgnK#26K-C$FQW&5$W~y)g^OkjP4G4d*Ww%e? zG~ggbYvs8S#_wTY{Z@vdE8iOBcZ_IW(Ktlhp=7TZ#+I9byq&$y`ekb~yog3U*6#s##BaXULf-r_ZWTD$} zvg4fjLe6N0hQ5$5o&lN{!JO%Nq@!i$W99>I{Wz2Kyo2tS-zz6Clq<&OKBj`9yax5% zd%h{@(Vwk4Lp4A++yIS5EHM85Yi|}?`p-#MmQ0~B6O7cDI_ncR8wQ)p54-Z{cO9e2 zb|PNgGZY0iKm(Z<8cl2MF^dFdF%$6|A5%FTww23=)*bhGPM|OhH9$kD7a7m@=`SAQ zGFr6Vt$|HnJG*4gJg@0{JQ#ZB7`J9L%WYg4bol!Da&3FKTdq7?RTze9w$uQPWG13> zHwvvS_M^haF~Hj6n2CrFM($qj_EKR)Yg^ z;xs&kuQ1boiWT%sl)yrSIw0}~7fNnay zeBl7qRLIrV%VRok_^~a*rO=stAM>%kj=fJ9If1dznzD?B^9#122B;J7CIgg*d_K<( zmD0iG)fU*tsd3H#p zmq!Jn_kgvZzHM%1o%@f>RJ8W@{O2|adT3RkpDZxlXq)OH9&nv zsLcDR#`N4M{cwj{cV{md>%-gS<9-wEx&(1zE`*DavUBJYL=2+i{Ydnmhi z<_|I>C)m=a*UMK8P}r7c(aS%&W`Y<;&Ce5Xfvg7oQI(+vXlch;xd9FBCi&vkN;JzO zI(XyJ^zvXTdm!WYE1RJPXlXZ@H3JkCQY)tB)yw+`Wq|fO8^miK)+kABtkZ|0fi5zST_3z_YDg|G^R&A^H5)Gh_FRa(a2huiAX5uO1B0#0-ti&eu30 zAGG?~Iy>v#k-l8t%e?m~w-4r6V9JeefR>A#k`5Zr8xC@MdDe6?L)n`RvS;6QOz=Rv>mSbLFFb|8rsC`m=;7gGB$T1>ZSv9z=X-=t{t6nFmG|nENo9a0#?>e9 ze*NUd@+96P@AIXMVu8^<)w0G&e!apm)BsJ)P-MrmUM#C&#%jgjkq_d>3c?D zMuo#o>zNo}12i$9)y}T4HniG6g+8z00W}vHp;QQrSNDKwtDahTAP&*d^2)n0dxf){ zQ2=&hq%BTHfASh&T6i>4fe8u+DDM%f_4)FeUOunyJ23X;r=OH6g_m;Q86v3nV1^o? z&h2|LKzYblFM9bgqiIY{E$>FJ0-DQL*SnKo`TQg7vcpMWSToX?8p=$@A(Y>-*|Sue7}jS8lW(#&7zlw9tu85n3?R6?ApDZ$1?Wcq>hvf&^`e! z8K7E!Qwy(^3Ymw>p?Z19ez0eM_>2vb75g3K*(lY9YCwgC8=#>`MaHWYu(5i1m^k*0 zxBI1u^2WGdGll|p12mF>q0vKu<>SyXp^Om@p2w$W`^pijmxm4Yd2K}gH+DE5c+stV zC{UsC3{XNU@1#e$@@_Bz>R=Shry@pp==t(+h=p`M&$kF)(cx4e(9>i7SM7%~^9)dj zNHRb}KW$&USa~T|TpkMr41Rx5+4n8}B3{-u4LTlKyT z&Y2+o*pGeklNKt3n>SknG%@0fo^BQIHOF^s9WZCMo$Q&G6Ejn14s$(8FcR_kED+qU zc`IKo&IV|?$SLWxPoHh*nC`Wb<6Ya_`AELMi(0eH-`+M^qVn!L99eSkCZBe zQ*gEhXfRY^5&6@HcbbidO)beNtYSX1>xq&Nz#01U|UwGkcXzYs`ps|S6 zS^S1)XtnWfctFiXMq*0UJ)qhmofe)Lug|h$;CS6!doE_F4qY-!qPBPKlxx%K*Wg%C~8(?YNgJX4+RkAi`qa(ri{!eu=1WrcJrX_iG(b-jAd>;g zHnh^`%j1)e9r>V~%uw9->Ft@}*i#RNA{@3fnY>$LYAOc=O#`SlHcmCBXWNO^d(u89 zXUr8#41N7kK5I_f2g>I)Az$ndEu3Dy;Q%d~yxVtz7gjaFFlH)7PQ2F%K1<*O58iX8 z9_#kl_iZ~tuEBfk4bTMwSZ+X@MK6Ep%JH(R54-dvOjsPpBWk+Dn$&20Gf9eDX(7s+1JKP9sT_aj*w8mE$i)--_U5nBg5uNZw5`G zW3~$Or_gdTQ+X_p6L8@zGU#ESXPE(dzrcaXk=%ghHLbDoZvOPa(7i?vk)jNp_>Nqm z&18nMX9nIgziQ`AGL~l*h>xkh)*XAGq8Vy{E-cxhuNk1R6~fEN80o+p4%<%5z_Z^a zX6m`qx}+%czId5jeL5v(>d@8~BtAZMoNi-)HY=cDG`!ZlHh!Jl0&{!}MLK3G?t`(I z|KvSP+Lx4k=ZN;e)ZqqbVno@NV&pV(SEoE_X?KrYFYcZ);FEo}^@2lxHlQu_WtwbV zJ~3Wub_S>lQF#&g(?>3_skf|ix_4f02Qv|$ecOdH6#GNl9`2T`_>8)$_e0Br@&Bm| z(7Xszdj9m`^Mm(3asSa*49$-{7`c17v(Y=wnLi*23&&6cG%-VwoloA4@YvmY7=c~0 z#O(xOol@v)6po<=XlT_|C|=!56D#!I70cEDtr)b`$+)mKv^wy_Kg9rz$85k9257AT z)fVZr@Wkb>yX>MFssW~j*Bt_h3lt2frb5Q7%c)zQlT}1sYe`)0y3Ni2Ofa19t zQ!AyHPyF5$%gz8z3~e-^%v3Hk!lc)tC_(t^!&#d3WUdCy#D`CWf@><=u(#9Atnd zMpXUen?*053ReR(6_Wk=sDS2uUZ@l??{j?VWA*ZR%VB_Ce|J(0l4dqg?beE^v3mKs zXDAA2faa|#Px@K|i(>KK_*Ac3wNJiYm|Ay$=AA`~)yt=1PPOuhW~c!=aMeTunzyE7 z_40Y2SMBr$Xkx^x4rt=?*Ijl7XyPg{Kn>8u2qezV7;1nfMj&x^#!v$^F#?IRGlm+V zi4jPgoiWq^O^iU|?2MrXXkr8sXJ-sGKocX7IJ^G=gfa7X1uzZW00000NkvXXu0mjf E0OTL&ga7~l literal 0 HcmV?d00001 diff --git a/Projectiles/Ranged/SuperradiantSlaughtererHoldoutMiniSaw.png b/Projectiles/Ranged/SuperradiantSlaughtererHoldoutMiniSaw.png new file mode 100644 index 0000000000000000000000000000000000000000..5258525907ea6bb3d251d59385b63d729d49200c GIT binary patch literal 458 zcmV;*0X6=KP)Px$gh@m}R5*>bls!m7Q51l`7ZEfR2w~x%Lm4GeP~q@;$s>mrr6Gr?p{1p*A*i61 zctb&RL`@9^)fBljR3_;V5xAJ5f-XT87&R0Py@vY?Zi7Vh&UEkjx##2jTxBA$0>J5g z%mgqxH3gvUaoePZ%v5~Rebl8Z0Cly3{vwLwXxIcukHrB<##;b*)Smzt`~2NQzT*J4 z5Z3=xbo=K4m@TdYkST9S_I;yjim5=L+ z@bfzWFoIVA>~8g%_7a}IMJ=+dMCREmNdcuPk3>2i5roU$MeHS9eGQAuMGXL>{lvvZ_jV@1-FxJ(JFT39{>OV07*qoM6N<$f&xp# AqyPW_ literal 0 HcmV?d00001 From 5bed03090fe34e23d6450f3655780f9a121e5b2e Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Wed, 28 May 2025 20:19:42 -0400 Subject: [PATCH 267/401] Rewritten tooltips --- ...ods.CalamityMod.Items.Weapons.Ranged.hjson | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson index f908e65ae5..6cf0160aa5 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson @@ -215,9 +215,9 @@ Buzzkill: { DisplayName: Buzzkill Tooltip: ''' - Hold to rev up a buzzsaw that deals close-range damage - Release to fire the buzzsaw, which bounces off tiles and lacerates foes - Revving up the saws increases their damage and allows them to pierce more enemies + Hold to rev up a close-range buzzsaw + When released, the saw bounces off tiles and lacerates foes + Revving the saw increases its damage and piercing capabilities 'Not to be confused with the Sawed-On Shotgun' ''' } @@ -1224,18 +1224,17 @@ SuperradiantSlaughterer: { ''' MainInfo: ''' - Hold to rev up an elemental buzzsaw that deals close-range damage - Release to fire the buzzsaw to pierce through and lacerate foes - Fired buzzsaws bounce off tiles and return to the player after winding down - When returning, the saws release extra homing bolts depending on the number of enemy and tile hits - Revving up the saws increases their damage and allows them to pierce more enemies + Hold to rev up a close-range elemental buzzsaw + When released, the saw bounces off tiles and lacerates foes + Fired buzzsaws eventually return to the player and release homing bolts, scaling with enemy and tile hits + Revving up the saw increases its damage and piercing capabilities ''' AltInfo: ''' - Press to eject a lingering buzzsaw towards the cursor that fires homing bolts - Using this ability rapidly propels you in the direction you are moving + Press to fire a lingering buzzsaw towards the cursor that constantly fires homing bolts + Using this ability rapidly propels you in the direction you are moving if movement keys are held This ability has a {0} second cooldown - During this cooldown, buzzsaws home to the cursor and constantly release homing bolts while returning + During this cooldown, fired buzzsaws home in on the cursor and will release homing bolts while returning ''' } From 91eacad29c37eacf02707e83cb9e0392e30a819b Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Wed, 28 May 2025 21:00:06 -0400 Subject: [PATCH 268/401] Sup Sl tol clr --- Items/Weapons/Ranged/SuperradiantSlaughterer.cs | 4 ++-- .../en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Items/Weapons/Ranged/SuperradiantSlaughterer.cs b/Items/Weapons/Ranged/SuperradiantSlaughterer.cs index 45a7d7984d..1ef8695bb6 100644 --- a/Items/Weapons/Ranged/SuperradiantSlaughterer.cs +++ b/Items/Weapons/Ranged/SuperradiantSlaughterer.cs @@ -37,13 +37,13 @@ public override void ModifyTooltips(List tooltips) if (mainTooltip != null) { mainTooltip.Text = Lang.SupportGlyphs(this.GetLocalizedValue("MainInfo")); - mainTooltip.OverrideColor = Color.Chartreuse; + mainTooltip.OverrideColor = new Color(180, 255, 0); } var altTooltip = tooltips.FirstOrDefault(x => x.Text.Contains("[ALT]") && x.Mod == "Terraria"); if (altTooltip != null) { altTooltip.Text = Lang.SupportGlyphs(this.GetLocalization("AltInfo").Format(DashCooldown / 60)); - altTooltip.OverrideColor = Color.SpringGreen; + altTooltip.OverrideColor = new Color(120, 255, 120); } } diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson index 6cf0160aa5..df009fe392 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson @@ -1220,7 +1220,7 @@ SuperradiantSlaughterer: { ''' [MAIN] [ALT] - [c/ad1717:'No one knows how it turns blood into rainbows...'] + [c/c91a1a:'No one knows how it turns blood into rainbows...'] ''' MainInfo: ''' From b2234be8066985bacc0ba0fa611a75e5fe608068 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Wed, 28 May 2025 21:34:31 -0400 Subject: [PATCH 269/401] Super Slau uses Galac Sing for consistency with public elemental set --- Items/Weapons/Ranged/SuperradiantSlaughterer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Items/Weapons/Ranged/SuperradiantSlaughterer.cs b/Items/Weapons/Ranged/SuperradiantSlaughterer.cs index 1ef8695bb6..5de64c7352 100644 --- a/Items/Weapons/Ranged/SuperradiantSlaughterer.cs +++ b/Items/Weapons/Ranged/SuperradiantSlaughterer.cs @@ -124,7 +124,7 @@ public override void AddRecipes() AddIngredient(). AddIngredient(ItemID.LunarBar, 5). AddIngredient(5). - AddIngredient(ItemID.FragmentVortex, 5). + AddIngredient(5). AddTile(TileID.MythrilAnvil). Register(); } From 39ee2da83c7ac6fc58287d540a64b8113ad4b910 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Thu, 29 May 2025 22:06:29 -0400 Subject: [PATCH 270/401] Changed texture to Sylvestaff --- Projectiles/Ranged/SuperradiantBolt.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projectiles/Ranged/SuperradiantBolt.cs b/Projectiles/Ranged/SuperradiantBolt.cs index 2ba1733524..e3eb6e744b 100644 --- a/Projectiles/Ranged/SuperradiantBolt.cs +++ b/Projectiles/Ranged/SuperradiantBolt.cs @@ -75,7 +75,7 @@ internal Color ColorFunction(float completionRatio) public override bool PreDraw(ref Color lightColor) { - GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/FabstaffStreak")); + GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/SylvestaffStreak")); PrimitiveRenderer.RenderTrail(Projectile.oldPos, new(WidthFunction, ColorFunction, (_) => Projectile.Size * 0.5f, shader: GameShaders.Misc["CalamityMod:TrailStreak"]), 20); Texture2D glow = TextureAssets.Projectile[Type].Value; Main.EntitySpriteDraw(glow, Projectile.Center - Main.screenPosition, null, Color.White, Projectile.rotation, glow.Size() * 0.5f, Projectile.scale, SpriteEffects.None); From 8c388f1139e4daa1f726dedd7b4c793652d3ce7f Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Thu, 29 May 2025 22:13:28 -0400 Subject: [PATCH 271/401] Fuck me I forgot player Laceration draw effects --- CalPlayer/CalamityPlayerDrawEffects.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CalPlayer/CalamityPlayerDrawEffects.cs b/CalPlayer/CalamityPlayerDrawEffects.cs index 555c4fc1bc..971b68da98 100644 --- a/CalPlayer/CalamityPlayerDrawEffects.cs +++ b/CalPlayer/CalamityPlayerDrawEffects.cs @@ -259,6 +259,9 @@ public override void DrawEffects(PlayerDrawSet drawInfo, ref float r, ref float else if (calamityPlayer.icarusFolly && drawInfo.shadow == 0f) IcarusFolly.DrawEffects(drawInfo); + if (calamityPlayer.laceration && drawInfo.shadow == 0f) + Laceration.DrawEffects(drawInfo); + if (calamityPlayer.miracleBlight && drawInfo.shadow == 0f) MiracleBlight.DrawEffects(drawInfo); From 2a975285d2129cd64321e810831b8be0f828bdc5 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Fri, 30 May 2025 12:25:25 -0400 Subject: [PATCH 272/401] Remove old Patreon from README and GitHub funding hook (interim) --- .github/FUNDING.yml | 1 - README.md | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 583986729d..0000000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1 +0,0 @@ -patreon: Fabsol diff --git a/README.md b/README.md index 9ae12d6b43..4b06769f4a 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ - [Steam Workshop](https://calamitymod.com/download/) - [Discord](https://discord.gg/calamity) - [Official Wiki](https://calamitymod.wiki.gg/) -- [Patreon](https://patreon.com/fabsol) +- *New Patreon currently under construction* The Calamity Mod is a vast content mod for Terraria which adds dozens of bosses and thousands of items to create an intense and varied experience. The mod must be installed using [tModLoader](https://github.com/tModLoader/tModLoader). From d6e458a8da7359b6f4fc58c14cfc782f49baeaf0 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Fri, 30 May 2025 12:39:50 -0400 Subject: [PATCH 273/401] Version bump to 2.0.5 (Permanently discarding 4th number) --- build.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.txt b/build.txt index 23f413337a..54df2bf033 100644 --- a/build.txt +++ b/build.txt @@ -1,5 +1,5 @@ author = The Calamity Dev Team -version = 2.0.4.006 +version = 2.0.5 displayName = Calamity Mod modReferences = CalamityModMusic homepage = https://discord.gg/calamity From 95c7e0d10ddc91b98bbbee27494f40a7509b0abf Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 30 May 2025 15:01:56 -0400 Subject: [PATCH 274/401] Fixed Sylvestaff displaying 0 mana cost in its tooltip --- Items/Weapons/Magic/Sylvestaff.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Items/Weapons/Magic/Sylvestaff.cs b/Items/Weapons/Magic/Sylvestaff.cs index e905c947f1..0ea7f24ea9 100644 --- a/Items/Weapons/Magic/Sylvestaff.cs +++ b/Items/Weapons/Magic/Sylvestaff.cs @@ -86,10 +86,11 @@ public override void SetDefaults() Item.shootSpeed = 13.5f; } - public override void ModifyManaCost(Player player, ref float reduce, ref float mult) + // Hacky workaround to making the holdout not consume mana + public override void OnConsumeMana(Player player, int manaConsumed) { if (player.ownedProjectileCounts[Item.shoot] <= 0) - mult *= 0; + player.statMana += manaConsumed; } public override void AddRecipes() { From c70ff68e061e79273a3ae9dbf4fa17e97b4464de Mon Sep 17 00:00:00 2001 From: apotofkoolaid <72956636+apotofkoolaid@users.noreply.github.com> Date: Fri, 30 May 2025 16:03:00 -0500 Subject: [PATCH 275/401] Sulphurous Sea Rain theme code for interim It appears this will make its way in v2.0.5 as well, given it's already in the release candidate. It's newly added music, so this should be added to its changelogs. --- BiomeManagers/SulphurousSeaBiome.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/BiomeManagers/SulphurousSeaBiome.cs b/BiomeManagers/SulphurousSeaBiome.cs index fb170f3449..d599595c19 100644 --- a/BiomeManagers/SulphurousSeaBiome.cs +++ b/BiomeManagers/SulphurousSeaBiome.cs @@ -30,6 +30,7 @@ public override int Music if (!CalamityPlayer.areThereAnyDamnBosses) { bool acidRain = AcidRainEvent.AcidRainEventIsOngoing; + bool normalRain = Main.cloudAlpha > 0f; // Acid Rain themes if (acidRain) @@ -41,9 +42,18 @@ public override int Music // Regular Sulphur Sea themes, when Acid Rain is not occurring else - music = !Main.dayTime - ? CalamityMod.Instance.GetMusicFromMusicMod("SulphurousSeaNight") ?? MusicID.Desert // Nighttime - : CalamityMod.Instance.GetMusicFromMusicMod("SulphurousSeaDay") ?? MusicID.Desert; // Daytime + { + if (normalRain) + { + music = CalamityMod.Instance.GetMusicFromMusicMod("SulphurousSeaRain") ?? MusicID.Desert; // Normal Rain + } + else + { + music = !Main.dayTime + ? CalamityMod.Instance.GetMusicFromMusicMod("SulphurousSeaNight") ?? MusicID.Desert // Nighttime + : CalamityMod.Instance.GetMusicFromMusicMod("SulphurousSeaDay") ?? MusicID.Desert; // Daytime + } + } } return music; From b0fa931331e39e86fe49aa4f1ed49727ba84f3e7 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Fri, 30 May 2025 21:03:42 -0400 Subject: [PATCH 276/401] Add new Patreon link to GitHub --- .github/FUNDING.yml | 1 + README.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000000..7d846efaeb --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +patreon: CalamityMod \ No newline at end of file diff --git a/README.md b/README.md index 4b06769f4a..fe22891c7f 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ - [Steam Workshop](https://calamitymod.com/download/) - [Discord](https://discord.gg/calamity) - [Official Wiki](https://calamitymod.wiki.gg/) -- *New Patreon currently under construction* +- [Patreon](https://patreon.com/CalamityMod) The Calamity Mod is a vast content mod for Terraria which adds dozens of bosses and thousands of items to create an intense and varied experience. The mod must be installed using [tModLoader](https://github.com/tModLoader/tModLoader). From 9cda8f5fd2864817635556c4ea75723b136367b3 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 31 May 2025 18:38:09 -0400 Subject: [PATCH 277/401] Thank You dev changes --- .../DevPaintings/ThankYouPainting.cs | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs index 87c2e42658..2c66964de0 100644 --- a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs +++ b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs @@ -65,19 +65,24 @@ public override void ModifyTooltips(List tooltips) "AquaSG", "Atalya", "Ben-TK", + "CDMusic", "Cei", "CongratsIsTrash", "Cooper", "CosmaticMango", "CrabBar", + "Dandy", "Dia", + "dozezoze", + "Eddie Spaghetti", "enamoured", "ENNWAY", - "Fluffi", + "Flowaria", + "Fluffy", + "fryzahh", "HaguriHat", "Heart Plus Up!", "Hugekraken", - "Lilac Olligoci", "LordMetarex", "Memes", "Mercutio 'Merkalto' Takle", @@ -86,13 +91,17 @@ public override void ModifyTooltips(List tooltips) "Nycro", "Ozzatron", "Piky", + "Poroboros", "PokerFace", + "Raesh", + "Sagittariod", "Shade", - "SharZz", "Shayy", "Spider Prov", "StipulateVenus", + "Tobias", "Triangle", + "TYESKI (Universe)", "Uncle Danny", "Xyk", "YuH", @@ -110,7 +119,6 @@ public override void ModifyTooltips(List tooltips) "Blockaroz", "Boffin", "Bravioli", - "CDMusic", "Chetto", "Chill Dude", "Cobalion", @@ -118,7 +126,6 @@ public override void ModifyTooltips(List tooltips) "DarkTiny", "Demik", "DM Dokuro", - "Dominic Karma", "Done", "Doog", "drh", @@ -149,7 +156,9 @@ public override void ModifyTooltips(List tooltips) "L0st", "Leon", "Leviathan", + "Lilac Olligoci", "Lompl Allimath", + "Lucille Karma", "MarieArk", "Minecat", "Mrrp", @@ -173,6 +182,7 @@ public override void ModifyTooltips(List tooltips) "Runefield", "Sargassum", "sentri", + "SharZz", "Shucks", "Silver-Lord of Ash", "SixteenInMono", From 0ed53298dc3a1565f5ebeb499c0f66eb24e79e88 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sun, 1 Jun 2025 00:16:03 -0400 Subject: [PATCH 278/401] Old Fashioned resprite --- Items/Potions/Alcohol/OldFashioned.png | Bin 822 -> 590 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Items/Potions/Alcohol/OldFashioned.png b/Items/Potions/Alcohol/OldFashioned.png index fddbd65368a53db8e26a5151d7e1716369f363ca..c46adf86ba79c427d57d300f3515816799411d2b 100644 GIT binary patch delta 522 zcmV+l0`>j22F?VKFnT2tI^bsg1UxZ(wC-m(HgU zM8raD#aa+i!NN+xBA8CDjQHDP*2(M|KeBMS*`0I#XYOPJ84L>7^7elGL>2Jm$3GF8 z80Cb|6+uUr*OBV%{^_IK_wBhKzqJty0&=70U3>1wZ-N&WHh&|P3wZC~JW?_A?fiK7 z@&-OwAY|+tNY9UlFRux{dwYvijtHPRnw}r{@$hFS*iqd3kdOwW&}wK>9<^+SOB5>u6^oYM-FtkI*2YsKRTI@RPGH@ z{Ekib=fUISl}Kd+cHCv!q%mppmVff96aQPV-(P71PJf`(ofJP_bz(wBpi)r&oSq-A z8cg6jVg#yndVaiz+tWx@e5(l=fog%)>G|xY^_Hs0)}Zj9=^P$TOgb^kRK1f z3Cuqb><)*KiV>*R>G|>UoYp-dBTy~SIz2yLE2#FsTiCbPxYhN(f%G--JJsx(e#(cS Ms{jB14wDoEB1N4JcK`qY delta 752 zcmVB=K~O;uPZkmMAXGeAP$)$dZ=yE^5Ah^Ip&kSk416(kFE;u%x ztK#4vwQlt?7xC-&Db#bhNpKEI19F`?e;Eha$tgJO=~<8ZrsZv5Gx_~~FdPnptV|{Y z-g!I*j*h+n+ZVUs4w!S?y=@Pi-n=HA7YYSX=&Ir|#X5OB9?<9W)v;JCg86*@3Q^pV zqeO1^_`q4vyno{-_iy1uDwSfVj})&{5sSr8X{KZ{sgA5eioH}sqft1IZ{JHW=h*&X z%0iWi)H4d|X|LPuwkWdMETU8@A*$8tj1dR~5d3`+Xs@Py$h>2E4%M?r4;}@2S}vEX z6qQN^;q`hE;@XT63x1l>6_n2HdhV@cXr-inUDxw_l5Jg* z@nH$)I8Lm^iD}Nb=PY)>*ID}a^tw{K?-l4E$0G^JrTB;Wdg0G=-ReIDICqRE(jP(H!DqSrw$WwQObRK5a611+Gn zWuv5;(H!{iH1SD>5;>qCrxb-RVvQ_oo)hyNM-ACfm0BFduW&H+G?N7Xj;Ut8UC;}!8uyE)A From 2c1f8b7e85515cac459d8dc3d83605f2b185afd6 Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Sat, 31 May 2025 21:54:37 -0700 Subject: [PATCH 279/401] sylvestaff sound updates --- Sounds/Item/SylvestaffFire1.ogg | Bin 22126 -> 21882 bytes Sounds/Item/SylvestaffFire2.ogg | Bin 26358 -> 25153 bytes Sounds/Item/SylvestaffFire3.ogg | Bin 23736 -> 23539 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/Sounds/Item/SylvestaffFire1.ogg b/Sounds/Item/SylvestaffFire1.ogg index 56864c877caa5bb8427684995a2ee451d1e0898a..8ab459ac0b490d564411b4d34ff66c0cda171324 100644 GIT binary patch delta 17271 zcmXVWbzD@>_x>#1-7O%YbR)G02uLa*UDAqxbl(LeR3t>{7D)+Fx>ZV28tDe85U&aHXPGiT0oo^$rTz%EN+OnOdE1^^5EuW@_)-$??Vl~p2>5Xpc4VVJJZ zf`8%?4UOrkG3R=oE>5bp-VO?4BBIiQB9ellQi)|OoNWKQ^w`1C!PCLb&OyQ6K=hfq z{Y!gOFMC^CTlMFO^I=J0u)9eeFltsw8F5h=ad9ci|2<{s@&fZhv3nA-_e3SW&B912 zq5r=9-@s<0q7LZq>pwPlf_{efLuaB3(cdt~4|ET@V^u^UVtVGeB=^oo1F5HDPLkf* z-O`0bs(hTE2qokphyA&1&drjJr!Lk_Mc*6ak|&+7zZSzXro zWqZRewN>&bWC%vI=TBhIq*y|@A;efy{Kj~7u(?i|gYmbgHF87);d&H0Zyr!amJm~x z-Xr3Pdu!3+SeRf#N%nKx#%4+A`>sX|xT1A&Pl%(U^GkbFnOGdxv-wO- zprw^K!;H}JV?IsbNVM3`>pOiBtoUMY5?RwVun4l}Y%1sRS6SbdD?D_>`bs&?mCO@Q z^`1+x-ugTFH9@&p%3m6Nj3f^F&XA2x-(#-sTHu zi$v)U+t8=Q{CeD}0Z@jtxXg8u>6!!WM4x0hY=|>P1=uK=6*z2(7XV;?Y6i8wOl}Y{ z=Uq16)o0Jp)Ug$dY~s$6NRU*kYD(`H-#W-)w_?#92$nA}=(63JdWQpLjPXcPmX|kL zr#37|KY2Mw|6J8KII6JbZQ#4`JDjC95r{B~4y)CpE=@-hI%OJh=Y(co4il#jE_Qaj zd=zAa`6m?7cd?lDIatyqRy1Ex`o@fOCYy~FKiPhrl~|x=Q__)4B1AxVPpI9f7$%D| zqxtw{X&0R6Nd%ZuSmj!S49y}{qHg(0s!f;RZ9Y(D_Ayd6vzYxxrO^Cc1M-wU+J$He^G?DgA0n11&`E*6Tk!nj6m2gNcFByc}@yTZ+^Q? zCr%z5p;qnqy;z8vQdt$pNM@LTF#D~83~Uz{VHt#5ta3swL9*!PaOB!36j&3NN&E=5 z-(5w%CFm${RWBXa6@mzw9M)2F@WJo>ZA@}k{{hCs=SrpdbG zFKka_x{xfmyx)8uBDc=B9DnZ5eSxOQEVIL zRT5C}L8IgYpQa&E7=pHnG~1IDkCqaL0*~cYm?>Q8cX2Bsj)O_{H9tp8XJdULOdy_Q zR~O&%wHbp8R=%D?V{9~!2@zxdC2qs`n}m+)S?$0-47aeI&7e&f-1#MG#dx(9Q$Sf} z!imffvk)CcxG2pV&lhKoo3>}dHbc`ta1fq_`)17y5hY_E;hk^ZRNDDHS+}!WJ3Rdd zSMh&!*Z(=S4$*II4&@|oMuh8yR_No;i3P3QlT_2|X2kD!L4rQMcXGQ+PvdJ!Y&wee zyUMEi^q<#?|4BhT&o{MC-#d)uvA*Xv1ZQvm8gG_dumdZQ-52Rf5)H>X-+gFl=ZnWF z<>$_umowo}i1lgLtkUxCy*S*&)lrX#0#XjGqL|?KeYnms>;VB@u9+2Azq6r0QL)KB z8C|A~voq#$KSkDosS54#C+jvblJ`nGwOd%#>UB1|cC?`<&HE+mR&`&Ce{8%IoYs^zR8_Zz-NUh|{J2AEIk2yS)4NKbl$RpPXc4FaQor}3mZ!f*fz;iLr2?QANXR>wpd(mXr&trh~yZ`0!ruIqvr= z6WnR8{w1~zjTHndef(v5KJ^)_-*x<9Seu~CqabUbQ#KLauOVTSCR9?o;#*lOWp4ke zFD%8XLst|ijJ9hVVn68r6lLeU`8MlN-^Q8ZcZsm|s92P}i=iZDGY12wKXXGcF2x>Z zOAzCvxk9J>?62@*DFLwUG`LbE00>wW*_$gY;0V21TUf%v0wh&LKvfymFimcQ%}L<5 z^UsI*%hVjFbgWrVbIXc2vwM~oF<@cd4u6xMn*?NFim~syB0CYJ(KF@0L~CeNvFi=$ zHjw*aqsBb8$E}t#RprMxnLhrxnsCl<0;G~SsufxXZ2eu)-9^vezAkz`@%q!BDryE4 zHbm`fnYmOn?#3d^Rb z_RWO02qz+j=$5qd^sc2Lmcx5f0#Q;Sm3(bTE<66K{_U+Ad;>D=h_5@in|Lk63u=G5eIkKtV2x;S;P}&X%qOnz9xC z>w3Azh{Q11GmhxM$m0GA<6(#KHRNC8&jv9>+VK|Eh0a@oeJTfJkHn_aT6j!9Coa1s zL)U+Q&xY+k!NY)ddBf)VH32G}E@~>qBEs^{G!E)u5cmwfu)SZVts+3(>}2^gMYgzM zbI?aI<&7w*fuSoNd3FGN$HIZb*jz2s3BqighZAP! zGUD}|3?jwvvl4$n!%u>@b)%ukk!y{GfvCMc_yhd{1H_%E@C$KZQu?3O zrsi@yCf0y^Rw%wX1yPUNsrhcKcvv;sfg=06HmmO&(Q-ipfp(gQpG}7ap;qQ--Nndt zJW>{>)pv;(0;X!H!1Gv~@GKiy-*i?l5>`J_E7j4KT3;oceVs|Kk9u1@%r|!>pf)Ry zGx||c<-4Vv+ExVAwN;qGvk?T zeebdIBj>n3SJF?rNtQ_}-?uxL^gu)9F8-sc#Td=c6H$hCIofs z@MEKDOSi7+ugR-Ms)#1T{%v1GOG=+!m{`&s3k746XNuKY{Ru+Ww-3}eq_-pzixaCt zmRcsson#XVsC}V-7Y~xYXCOp#E<8_0vyoOf?PmG7Ol!|(?$7!yhxX<2!~y&t zANg57PH}R^U`0<17G~%I4nbihFi%Jeq95eS@Jx(7li>8m?o<`I48AzpViTQt zH~uS&q@}KH(|1y$41M}ebMW*|#;Do>GLh61C zk~$5kpl!JhknttGRhQ#heN`g8{`YPj^+K|*xnX#)xw1-~l|GG?xA1IH(3m zU%%bAt17A#k_sDAEaD9EQzzmXyYJ_xAmNHKT^aL^>Xb5Y7C;JHYCax%YF+VYQg^&mv^*L-3dGzQP*43J%F#AdiZI6{Wi~(S`JaM&#?o~=}ND~2R zkNQM>c^05ZzP4JPwLkfj>Pf3mCkn3?JOkQFr71H zDx}r*+MzSZIWm$6T;G%-pZHQ7f6F#ZrRSVV7SJ^1s&Litic zJC$>%HAMF7cpLL(QW|siMpx0WN>^S0F;=?q#&!P7>x1J87O*&hO^R^C*dq=Fu-f|7 z{)((ag5$PeWT5d6dm00d*igU*eZ=)v8XwG)%^2$-oAH`RkLo~qX_BwmFr{6 zATv4sY5d>=&lGyu)%;dD-vfLzh);N#S3SjG;3WmFP@UVxQ1;-v$RKS=(v;g2fIal> zV}ykaaqKEIce5W5)puJwj=5W2X(+CvVHhn=VFdP{vA^^9kF{%k zzu{iOcUn|`8ZNZ_eEhie8Ph#0JdNBA#(7?)0`)Q_==`ALuQHzf!5kOia=!e?Ye%Q6 zQKHWj!L!w2#OC9E)9az`uQ}sdD6AWvd@n{_wWg7_a`4NvU+Zbo;ih>?G+DD1Md#J& z3&L?Q)6M}Tux42yB@zH~8=6Nq6Z{C_#?}%!(dRNWM`tP=yELHd*Jqbn{ofV~z<*K&Hs<%mTjwqs zbO*W_bJU_M(KYC5bT7IET@!loq5YM9RY#g$p|qkm&TXEF59fy_vFlT`b8l6|=}=El z?#3ntFFoX8shV=ZOcm)q15h2YVtD4m6zSY)Phtw02gUc!s=uWW`cTu?&7c-8Mi>iG zIe!EOgO|2#W_&Z$GG1=I@%UOGsPt+78=M2)D#(`J@i|y&MpM}=XZ=y{Ve}-N3 zU?B37__t~aTG(_ZI#xZ1e(Lk!ec{Ryyj;6W*0n={n{@Nq!UlLnoDbwVT^sc}5;JSACG@uLAs&*s}{o(q+2yrAX0)RYyXPu{&|no z9FPgqxn+5QO!$cq?=k)8aQg#R+Fvo4%Fg#Y`=)R)v$2he&>>xHeG8Qj{vNkE%5yyi zxR45ZT}2FI2x?G2xC4>k{3vk}_uNJ|Z9V4r=V)$Ode|f3fgZE&YgaW?T4u2-4buYD znTlTZCnf?|Wj#Zk(xN+?;!@^B1TesYLE}fp5y}~cz!m0HH< z_meq_FDdevWTrFkidML-YC}w?#0K?4XKQ&yT4`-l2>=KEXTg>`JTNf-$5g7^JsvNeqFKFz9JJ@*ahsOA_>+q~ zc)ug-d%w@8NJHkq=4Wo zux-3xgi;WDjNl2OqDYt1Z{U(FMgI(h z9VWHPcpCerU`aR^GTnm>0TC>)2tam>Lom^(GR(i=;gcT{9AQ7nLGBCRL&a$G*}D~O zT1>b{dg|dr?W9)no~%dU`%YL5lM&p?;Z1-oJ@*o;6f)Ux4hx+#*y1FLbU1{CC z=9U(Lxaotnw8YUjZfyxaSOay(K)*Bp*6y9xU7BJPayZM{9oGj-M^4|=sa$yorm13f z%*pM&!@UD#t??A8-=uR`Reu2KBCwxD>(8CBK~-~3PT-BJlcnF9En`eiQ5opz*G-~* zpXgG%hl_YN@7vwRbSDu?^wkNRh+uD-4`U80j7;P)hSavhlVuOq@*jrmNwv|2b47eT zsBN=~a!)yQc0X&Z!!xzSke5fQ_KE`J?5)U?EDOKki+?|rU~mK*$mMAZKDnxLyAR_) z4OyRG#{B#Dg7x0kQ+`4`;Ccb|x0yRmelwqwS!KqN>R5iHcnsa@+|`H0d=4W3n76XY z`bb1R6`|rLOES=V&WCT)r>fez`m`~hKNhVqdCHE zCe7O7n&;|Gr(Ruc%p^(R1Bh>eXZyQ(?@<5d%(2``|6KEanO6wSnCbszI{1RXK$ve$ zKJU}r7rohgP=T;>vICi`ui!}E{Vu285B-H>Xh*^Vt0%wJ1IWZ97Z# zKVJCUVV-QY-}pT;S6I<_UC;qbKWn=RDX!)nnqjRP6~Cy=9(=}G=u0X>=l#9??*<=s zxXM>#NmHCH;*+yYdTA61&+=FIR#h^Og5D&n%uG+Q3f96p_ zpXWaWmgEK>@i%9|I8s=!=L`kMBzI2(Nx&kRtnby$Sg|!T#tr>cZ4$?~Nw&@uz@u8! zwI5ykmG^58b^fQD7pX`YIBi{sV`TgjXqLd3#A2>FUS55G*mo3U(xZ+qQ`KvDX4oIt`lnz;l z=WUIrr_7}&@oShGDSK<<5#nWW4X|bJ4Gq*f?I5@OJlm1f_)hYHi`G zQTVcEQQ_D1y6Nj4v0JKw=0su)m3gGvw5|t)y}#90c89LrE{lc$v1DD8qsZ#k*1aV5 z{QaJ!abWN3{Xomxbq%aG?)x36!Dud@nUbXIZyZ>EsIkDv>k6`vg#(NSE-Rw%3!zOU z*;|W~yI#rSC*R1fsB@xt$>ZyFY#M}Ap&xHvCT2`lP?4z-i7(21mb?u3XSYTwy?vlv z#u%4Um*Y!s1^=0L_+({Km_T&~!<5$AnwL%ziFdvM?Lj|sGOfmE+*nrMXt-r+c=5qD zH2y*%d5wODIzd=r)=P> z1`)5C&$}zviY$z+PxTu5-U&Axcqx5nUz()Br}#SMjLX0_?b?n@0lMNLO+5oX0`L>n z%jPV!yY@6kPhyS!UEn>(Y*^`#C*Wi4TMGH-WlZI1 z23L)ARSX&acZ_zp5(Chb=LK(0a|WaEZ+;K&!o(u{_PN8J1(Ky@b9t;n1LWGl#mF;# z>}?lp2^xjbmeVhaXSbLTCP|pIQfpb+x|GV-j2Hq{+eD>kMz$&i^8WTOvUotG%bm4N zk-I@aA?4$a{b*+VbJ*fbhZp)Vu!@rzINf>^Dn(C(3na017$IlRL6p0e@4uX~2DCU< z0?qX7X>HP3A$h0Rl|qV=r0Y)7?frWh7B{S(Q)fDe2;S(|Q`E^^`!((lk}KntbgX|3 zl&}I3n@|!y1eTZe&H0{|`}GE^Y-Vev{7vB_oca!cNRS4(8M{AsyI;1IjrwxJKty(B z=rwv{!wP*1`gu9|qT#%lEkZ;?^)Qe5S%vuVGsfJq9QXZ=fs3IdR5CswMAT!V5e+vW z1FTX%ScE+j2HMe@*uk3=APSj-T+0m25cRzWJ)R~1XBW~oA^T=^4_Sq5IVN!Sz>~=6 zsa2H`YEK#_wdnMOJ!55#KyVx4Nuz9wXJU=dH=y!{!+HO^CD%XCHGS+EXOG7Fg<4X` z{jIB!w?ve=W;h=uaCUG!Ka&*}ROng64$$TgkdEQwz~MIzm6xd(&#LVDWfxbAQ1}0Q zB7Ur>G@`sP!KE+0yeU}soI|iEz^gR){!4VvY-c?AfB_}x@w&8YUJC6Rr((!oO{z@t z-?t#YIoY|!aG4OdRE?^^6HYMpOo+zKmidr8e>M%(gJAoTYq1NvQq^kXD zslQ1TM0SO;YtXvtuTl)ia~{IGPknwWHN&V`)|E(bY2Y7*knEv13B71tl~F)CO{!1B zO^bVYymV~rQ!k8<_;!QM!t`-Xi=J(+5lZ@C-b`EOC5eE6J@Qkn9QG&$xyF*$cs)w` z8a~Vb{O(d>GXB%|b(#r)ZKv-~XpFMUuD<3_a`l+t-K_qRj${AV8D)-N()olVW#z@y zLXOb-#*rKA;IV~2;?6uB^~RGNB3U3@4X_78)nVo%wLU^XWusCrGx4OGHQh%v>T z{^V`j#z|SK!6vH{*y?5X zpXi=-NBA{4ic2w|TFfPa(*1_pA;-{q^dyk!)KRjmvu>%Umk*#goK{g8+}O!aDJmIDCnE#@I(ubaz7Hah7ET%3|1KJH|LYHS zKnTcW3EMGg@z7Ln`!G7CD2Y^?M`^0B>BJH^m=we)ES+w3^{LMm&Ws-~%p>*jtkD&u z2q@9m-m8}Zf^Bn5;ALM3f9T8SLs(l--pj5uXO%hx8_K!k(4htUl(5D3USp_ z&$glOOQ!~-wc0x7Ozz7T)SPSG8r(y%rjNeL=pf$fu2qvJ^OirCRb1^%OtIN=( zZ;C=P|Kg^0X@s^Cd(Zxbb6ngt=jc@yEp}L38Va3MsytrNp#tsN#NrwBUKjH)Qk;tJ zWZ`A;)a{(CKh&;r9U-CXNW1GU3+5JaI5yd0N$|p77Y*nbO^=1(&;am8#QlXp}pY^_s<`uERyvIku)Z2#t9TU@yk@Q`#|N|gB#F1+?36?SYA7e_wV(jj=Q6x8WNienY` z@T{FLJ-zNOan8($TFbIZ2R^c5Uy{(C;E@$%aWm7sKPC5ofmNUqMxfucU-x@qn)@x^ zn;G4px4t&(kqcFVMR%8rf;@Qq>_g8{)9gHV%!(5Ncq7G1<<$H8C%%8w>%NgDNN}Fw zx%uE!ZF}zbn=SlR_QCrSEcZaGql$YqD3+-F{IAz3Iv=FlV^>@o-?ktLoDoEUNt@eR z&~jyf#7F!-yq!Y|`Lo@&a5fXau%(a~Z1LCFsyS{!=j65T=!uK*7WLbRN4YsGYdo(k zuPxCPi#Dm3`P%&1KN_B6Ed$oS**l~Nf$A(xlPJ;RS3I@mB`W3 z_Gn_W8irqb&alhPU;4*9y%l&b+yZ=nO5Q=}eycm^Y?En0I>jnmA>lSi2}!*O!ZXX%>u&whM1R)u1;^n8GbYnJU6w-9r zZ|T?9tl_+6!psq!a8NH~!7Thk+5NK%l2gddVNa9k`uNdy^vw)xqt z+%ZsRb5l__T$lqg_rnfL=uR!NmZMP~m6))CRsxYW)v~M8bT~rC)0bVIJ!~}5yVJgl zlW^{>0(Uf&Ih*HHJj_ovYv|j2ch_lhJnxiRgxpAH_+d+Q4xQy(e^`Cjv8$@o3l5?d z`ImhQ`Jj;MjZ3=4Wz&WeLpO&^jZwB!j&nM&e=&5f!v*&tSLrs4AG%*Ot|XjH-!7S( z>%0GWG^7QaWquY9LCRvY)z__<8gSFZyT?Wb5U(M;(5982^Ez#{*8;-A?J%&I*AyK^ z=G?V%k$zmKc<=13z?e4KOK~GmPao(?clZ*Oy;YXzg6yA)S9aK&9-72R}Qo6#C8|KuRreotJ`z035bj_&~?FjR-`X}UpvPBqeg0yDy-i@)RKks~JH9u?H(VgD6SA{Cn zh2MxM2s)EO$ov<~|CXIE%C)iW<9PN!JNLQ;Y)4Rnk?_jEvg18UF|l-+gOc(VIp+%I zuk(vuo_*3bcnD}}*TKsCbp^pROLRUZst+WIaif$t6w-3QF1x%b!6xUi8HF3e)GfGB z%9v$g(zIq{?=7c|%lqt6<(H(x9cAd{d(_lq;LA2q-Kbm8z1%$B=O_Ovk3=AvwmW)| zFG)gbO+p#&s9_~(0vOg8a%#2nn-ITviNy`KbyV?u^nFuZFJwbHUP(d9MG~~%z>pk` z&)e9{r$0PX#B)ev3iSk_s;MkHXn)iTo%QGKyB&+;IZR(P7E!U)1Q+5vNNQ=v)7!ty*?#Z)o~kEj zP{O-Zhx~`6YtDwsR^`eXyKj###4{u9LCobr8})tT4OsU-r5Yq$XsFHay;G>upA}-! z(MM&UB-?Llub}4ygvG1V&-(!%1GoId>&8Fg{fMygv==$qt!me&hiCiAufVRvuwAyx z&n+y(E7te?0dILf>&r%xjKEG8ZRdJzP4slJ+qJPpTu0`F*-(40_c08gg@uX%3GC5r z3;ktEGXkA?0OW_^@Bwm*XB|QRZgyDImoox-wlZfRATj(7xm9A_eF3d!wFUSdtW7=A z2l{}IF8=04#1CA=D}9S))P>2|sl*cUBHD)w!uF3Bkd04TUyyF_Tc=m^Wl| zF~h?Bfoa~)e@_ySbG!lww;I8A?Ei4G=#?h`ZyO5`x3z!Z;Jh6&?C-2{3##uis?Cy& zhO`EzJ!j^w=ZsJ#4R9T~p+&)ei9{lSctV;~TlAfgHg&G7Ffg0to%m~9QAM^6Qpz~r z_cJr;BWu#z_CE7W@&6*LY`bMHrmSu?-%Y`R{i*WsM)ij}K>!2tLncfQh6NN;e1l~J zZO31E_q5I0x!c(3q3`AH4vOmSCzF#w=QYjC!e_$pA^oWZDxZlB>^Yhf)Nv3`lOuC8 zMMs99j$ela($GO~Xua+HgaBbNe=Y8-f#{pL5vHo`cL7xC9ESlp+fsQ?-n%IqWMLwM zM}m&RxtHm<=>)l4hr!ohn%P^I2-%#Oz#>+d-jQz(evTzDod4X9gTN7Kw})U^iN4Pd zKeL;ZW3sRuEBVio;6aZf=G#2_$OU)mHlh^+qC$N19+Ls!_~zUKY~E4TZ_i(=^#76+>@Q(L8$ z;W!63*G>M(O(X2=e_JE5p>k&Qf!4Ly5ixoL7r;3Zh(T*gY;ghBp8^ChBjI_gn)J5bri{K~k?@vJYCv zU(ac_+@pV%^4^K(t-G%Dpo%{2=2hUO1qF+r zEo0|kCKlux23}+%<@j64lgVo>B{@sOTc`iMd)e?cCw&~lJ`S*3yX>Fn5W^ndzI!yB zY+u~fl$*EgeGUWK|5_~OTpL2-rf*P_@s3^p9FM6i79WibB??H-P}_Eo&?2bA6G`a- z6XG4@;v?)(ueecq7Wew?0CVQOi!1BLou_c+)3iJ+?(9`fCAYIDKVI048`%z3x!8Ap z_rTXukVIvjBOiyxMfjL$%4dZ&y4qZ>kA7{(uB{e1vBd2x=-nTpQSX;P2VJ-liLK15 zY;1o1B>wgtw{@~LOxb&9Um)6riUU25_QgAc@IVj4_5QvR73d+Y$$OR;=O^Bnl*bP% zrQ~6>@*gUO6h4&80C>lkw#R}QF%I01vhRd<_b{71QSZ`8^}X-8pP-+dhx1WrAt1u% zNFH4?etYZ(UFBJ^!vH=D$FyO-EnQ#FY;drg(msaD0i(*tWG^h}q=!N)L=}U3prp|` zOzK9;yp59!EMijt@_o647~OJi{KZo+vu@WG*sacf6a4l? z3IjO*8{cM?^mE3wFv1h(?HJN1r?U0HgaCjzk(=aS7JV%gu{hD4=8vgG%Sm*c6~agV zE2mfti3?_&z4`R(Lp!M=93nj1>l+gX4BN+Cme^EtuOhS36Phd>8;AjJ6)q0=()`8r zS2pd}i;u&WNPV}%+ZBxRH@4i0KoNg>_ESW~`Rl2{po4TRHdY>c+{NavbAumDIP~>% zZ6CDg`E4Y8tk=fWW(+A66`?HXv1O@TEb&}Z@l1mG{ z;Bs;fJEYGXYQ|TiHBG(lI&LQ37#(ofN2YRtCaIj9bsia`;dtT$04(NhDuM&8{t3bW zd?@@ho^>?EgbfP5De4}50^0faEds!+^wI37r98-~uN%(x9r->xtD;k3FfeE0y~Dz9WbF^YH*I5JHOsx@LB)TYXExhY zuAn8Y@aWQUp=+=d`v-fi*Ia=@491EUhzs-_qp=1=`dEKP3(vg+6!)dMDvJ${W}Gv- zq(4H!d`eH~7d3?xOh1nKtT$g=u)G&c+^a`dzRAJ07%$pKjVLM(k(2LBt!cHYe8 zy@UJLIs&P=Z@MBl2_WRcZq#nk{Fju!c$oOp-{|5CFAu-a(XUT*MK1gMifH5_&r-<^ zHZZ`hnrpbY$*a3j%@^N(iVdWqU_F_wM2&P8>*Wii2D!MPDz-C-&x8GH#V=Y>=ib%_ z@bu~SPEQv$aB87VF;`-Je&J{w(f}{qnTBDCF7W{BXb1@~Vv2@q%j=4GymqKZ<0@In zTF9NkMr+7@KWL5sXDDLxd$(CmA~gh$tS1c123sik{U|OT`0?9PwwPZTeRkMmF=gY{^$X#N25u$O#*59MAN9#MR9-& zKkj2E)BG2MJZ-lk|1XA`$ql%@=X2@e4s`Cphe1TfFaMA- z2MW5H;;HL}G%Ti)Sys^-BtE&ki9otS+%Q!oT=>A?@qrQJ@UJ0dN#LCTEThAE zug@2}T2ZSagzW(L3#yYa_jlSzqRR}swY#Ew$2*c?03?D+FOzPf{j4G^{`8fH3#7$yJQ`75l+AG1+u9hD8B+*6*6J`if-i1(WM z*XGt1ii-tOw;4jCWAnLxSABd!=ouG4x)nxV3hzsBxUm?}5Q6IGVj0SRI1fU<6qE+i z$t&d~{-o~icaXM*F>!k-VBP$N`I}*c>AsdKJ3`)9(2sH~c>HsGR@UwScMTr8%kIVJ zjeYT`X`0ejiD|#Gk=wBkVYlONRD>1@FT90=4!*}`;EGW^xQX_6YS$uUBwBqRZKB#j zQF=K1(|)J+bHYZYM~fT77>v&PacLXG^R1f6s!UxiOyWJ>nZ3GD8+nj4OT|{2MyAYB zEVhg-8ge-z1nb`-Xg8Ut$ON$Lv-t=i*%|%=UNm|yZ+9Z%nfjsn^~48le3(W|RKRw0 z9hb*zIg&I=zw11VAlrjn7@gP*&JlOJzQqEZ@rz-8N!kjn!reyfO7Sod+CG-z2XrQn zt{m!L{6$@cE=I}|dQc$>GzWtfoi4r!2yR1vm=_9`q&F&wY*_Gcau0o?dq4JZUF3Zh zxEYn^dlSitQ8A|R%`UNlhng$k@+ia;uC8cpK{P5vct<7wll1zGDW$yse*y)Le-Q>Y zO#4ruz&JIqWRm%s9{ma(jediUL3?42muO?O6q>Uzt*|vpyB*g_AM&Zso=6}&*T;Lj z<>BVf%{%dkEnc+^^?JQ!TJP*?S#w}MjUA@=5znG~$jS|P;K}>Y)A^RhoO}>UA_4z0 zaYZ5HFIlG}wtL9i)8;-czVk1w?ei0!(yGz|#0S;e#x21oo+)ybFb?X!DP%(( zgbk?xhll_~4x(xy=FHac^=5oP5`9n@w%%Kr4}y>Ne!O&+y|{_G8CSfLk^QoegOiT^ z^vFrCH!JrXNhKQ#VYjeqoRNnxKjjEMcOM8%BJ~JRU?A1OhKKWNrZ1!RlSk~8>x#@O z)7Ec9#fBEFgYKQ#U#-#PI8|65o>G3oYX-Ser>2(!Tf30#v?>6@2MkB`t!H+zUxKwU z#Q}P zn*p++C~wu@0&2JHGpqYuG*q+#842>tW+e%8#M-U<2QJs{X>YEaS&27|LmWbG`$M>m zoQx<>xyP=EUsASz#PX2;P8?>>Z(9Ylvs>THuaPaLX0lRRuYING@y_NaI-K|j zhX3{RGWtVH2tJH#)$%P#OwVOl#By(VOnm{8fwQjcN$DQJ8lzsB*RBCwWA0PYx@;`< zo2Ia(QBo3F4Q1;jzwc#j4fd7~usMqMAxdD01Ah6FCe8Ig8|=Jl&Pj8r;_#Wt6A^0m2HziRX7M^CI*0TXD18! z?&T$0d{$@l)ES38JuU)^oFo!)%2;NkXFlDO(AoB;u}lvGvn{QRNCN|{)ks8e`E1ypbXkpwe8KDp1NwF1_-cy92+U@ok}HMj>Sixrisi;5JIU-SH@TpH+SJ zC1&l+2eL73Hpm_A^ABFOnacIX<-x$FeDHYZoEZDVYzb>)_mzgp7-E14L1P>$FD_n& zqF0l;PllrdxMm0txc?RTCl{T#z`z9ZWmuT$V8;^FnfwbdU406z?;UEZw+bMDpM~Si zN7@I^Cf_CaEZ!vb>K3Drk5K|a`JmqK8jVl@=*?QCy;`r%I<=dztVqw=BuMay+WpK6 zVUs0yu$tB!O*y?fJk&8(+^R7(?Unv5ODS7qa4zWV_E2o-{;XFhsfLpZ;8TdDkOzn% zeW+BAr-COr9UBMG*sPiP@ai!Mk3X-}xp53_@lJ3vad960A~ujuda$tlq#fjl|8}a) z-j;*)sA3BvbJ)FMvJ2-TI#=XxV0V@T3^w!I{|rg7Qh{UCwD31cY#8u=CJWVVWHu3NUSu8+aTN&gEJ_%?J3 z>ksF|M=`rOLTkv!scb%H#oYoUzulq$Jhpp!W6}FFk9kSb?qe#)0LTT>+eWcNx^lq` zt3QAK{yvHPFWdo$*#v8(&-Bedy(xDo>F3s!+BO(;+C7m!Ut`gNc8HT!0*lQPZoF zvW|0;f!8#i)**J=P@7_CyWk5L7Ncj1*X5R1z*@%(1;7|Hi?PdkLBM;FFkmZ^wA9Yh2FqgwEt3t!rG zHY{nVd><2E!@DyNJMp2R6M=3R;KP3|^>ZWSkRAV&Jg$ub95}tf2dqX40>_zE*^exmoC8dl{F216MdR_XOAYNma4C8B-Jj=guK*_P8qiv28=9!wqtKkiuwxC8J|3#ESWkX$E;`o&px04z_!}Dc?q*-%?jzB^Wjk8!g^e< z=$V$DT&|rhJfve20R#+qH<7WgthE?o1k+0(TdFAU?^fUXaRUgOR_~K0N>^Qy2W+Mw zpBGU3*DtiW@A~3o#$EN~z@J9*!l!;Iyo}XQeL@Hr53&?jFC>S~OPVXRSsgAeO?Z;C z*Bn95>ZVFpoour&=Q zP8N7}>)r}kHjPaOf@9Gib@Ek($ADnm(7<(n&ne_e(Mw)r6psCDVx=>Q)AQmJR`FS&rK@MSC1sxxd150Jz%15Mf8HR}S<3^SHFS>KN|{ zcdVfEvT`MSmzAn`{ypTsd0r%}?%5dCxtab(pH%jb7R17=&Ly!x`^c&_SC{Y>QvvM! z;k?F|O~5rvcbOv%S51gg$7zl9=8Ll=ebu2&x>s zc~W%vw(R8}k1(#?o3kDY zLiu61nEQl~P2jubyVKD1^%pJCnqJPfxn8{93CK^D0pTfuzJz142H*Ppf+yvO5juQ@ z2SZ9s%DZfQAbpO#?Pyl_%rD(O31}Zx>S|ex&5SAu_j)Y)K>}G3#r~L5HGOa|gjJ>T z&vh8)Q-g{eq9$r*?#NU{h=0Q#J6=Yvy0f@ z4i%hUI=pu>8qh#)M4O8-8uK$!4$P&VKP{=|zE}r;%O;o2Y<>tXVBQW|BfoI$=`ak7 zO&33qAU4%6HDJ=`jO^2yZ@;>67j+lfLw)iN9BMnyW@OS`?7r$z)k<{Z@zho&N_h4V z^E@rC2K}sBmzC0o2PBW)jhTC)|uy^QH40o>rgqG8tQiaPink3+e|An#k)2H1_yU5k=Ud?k<65@jR@%tDRduW>J33QmqO&N zJw{Y*Kk9e-l~hW=ro&pz{no=LZ#oK!d%>5T&5LWB2m+15k=8?}1U^yTe0 z`Sy#-=DnVQ6CffYR59Njjmc;KJ-Rqu`u6_(37^l9oYzP2~3o0ido1D*a~TINA~pgG1b)+A2|Ey{A899 zvzIjNTjRykf_Bh9fHm=1sGuMK00000007|g_{58QxevRj^rhqHX@6Y>ks zHv+5HwGd_w_V9rA5C8%+U(XEyz;{_20OD@~0L-Vrb_M`|E!_YB0PKFadq@BP0HEjR zcL4wZ0L*>@005i;Xam3n01p5FzyY3x{4lcsP~1C`&Re@!ttnn1A7W0rpQS<*OvV3hi);0Xk z>+*j6X=oUoS~UNku33(rW-XCNi}R^GeB3RToLW_!kwo_A&tJ#-abbHi_`}DG1HI{r leJ1ZL0HEjRf1nb``--3c&xQm50BEKi-Jg>H?F6CAxd8*+d7}UT delta 17580 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 diff --git a/Sounds/Item/SylvestaffFire2.ogg b/Sounds/Item/SylvestaffFire2.ogg index 79ca7e1fa9111145efc2dfef12ee8c6bf4f038e7..4d60af5825126463ceb88f9e61fd9bbf52c1c4ca 100644 GIT binary patch delta 20583 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 PPyB&;_$`iE7`OicOC~{a delta 21818 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

cvuxN+#u&Xq6bLom+>gmNn5=N_JB9 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 delta 19251 zcmYJZbzD_Xv_3rN&>a%eh=?F5A>E)Tse*L3(g@P~h?F3WbgGnecXvpLba!{>dC&LW z`}@4}&)G41X75?E)_Tsfp5rQ5bq$PK)zb1UfP?>QN6NdhsWI-uHrulnD2yo_`dy#MyiTXl_h z$aJJXvJzR2{D+)IP9c|(y|luSbp+BoXdbT9qcJqy!NSEi0FQHhVb)IcV45J#fL2RA zg6Q=YSA|Zj{2t^}g=Q1CCqYj9D?{Z}OXGcSZQ-`_YPu%j;6IJmJc;IV zTJOHonk2t0{D$@G>K6r=W+ai1vPJL>8UtDmQtJ=b!VXfVQ3I|5%&>T(hz10CEyfI0 z)=t>!Ume#6F&?2znU-vX)Q9!GQ1|&)3eFY}`Sz!SCj9XdwQr<%SPyD(d$x{>6_j<= z(-b?O!Jg2VaSdZH$UIQuO)$ZP5hXfEj!Dw`X~}E1U458t8fna*#Q#pUUIa z9sJ+<^J?{{>bNAvx){A2*U^}ntlXtpIp5wGhHV?N#KCvf)VGHQ-*G%q94l1HYySLrHnGYn zi{~kyVMUhxua5rdsMbS?BLgT>(j=}|zwyN6)Rs2o6}QoIMF;uM%fX*Du$NjC%tCGb z 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 From e24ffff4ca7cdc1e0a2760c11ff5d073a7f3b6d9 Mon Sep 17 00:00:00 2001 From: GinYuH <72181395+GinYuH@users.noreply.github.com> Date: Sun, 1 Jun 2025 00:44:02 -0700 Subject: [PATCH 280/401] remove lillies' dedicated rarity --- Items/CalamityGlobalItemTooltip.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Items/CalamityGlobalItemTooltip.cs b/Items/CalamityGlobalItemTooltip.cs index fd8dced024..67ff14b193 100644 --- a/Items/CalamityGlobalItemTooltip.cs +++ b/Items/CalamityGlobalItemTooltip.cs @@ -86,8 +86,6 @@ public override void ModifyTooltips(Item item, List tooltips) private void ApplyRarityColor(Item item, TooltipLine nameLine) { #region Uniquely Colored Items - if (item.type == ModContent.ItemType()) - nameLine.OverrideColor = Color.Lerp(Color.Red, Color.White, (float)Math.Sin(Main.GlobalTimeWrappedHourly) / 2f + 0.5f); if (item.type == ModContent.ItemType() || item.type == ModContent.ItemType() || item.type == ModContent.ItemType()) nameLine.OverrideColor = new Color(Main.DiscoR, Main.DiscoG, Main.DiscoB); From f51931abe34e1359f3cdbabb851d2ccea58ea0e5 Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Sun, 1 Jun 2025 23:38:01 +0700 Subject: [PATCH 281/401] miniboss demotions --- description_workshop.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/description_workshop.txt b/description_workshop.txt index f267cc2d72..f12caa1faa 100644 --- a/description_workshop.txt +++ b/description_workshop.txt @@ -25,7 +25,7 @@ https://steamcommunity.com/sharedfiles/filedetails/?id=2816188633 A more detailed breakdown of the content available in Calamity: [olist] -[*] 27 bosses and 12 minibosses +[*] 27 bosses and 5 minibosses [*] 100+ enemies [*] 5 town NPCs [*] 5 biomes and many new structures From a8f7f2173cafd19c7d48c2824497e32164ad20ab Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Sun, 1 Jun 2025 23:38:31 +0700 Subject: [PATCH 282/401] oh wait its here too --- description.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/description.txt b/description.txt index e3ebef4e0b..87f552f31b 100644 --- a/description.txt +++ b/description.txt @@ -3,7 +3,7 @@ It adds two new difficulty modes, multiple entire biomes, thousands of items, hu The mod also makes hundreds of adjustments to vanilla items, features and mechanics to improve balance, quality of life and overall gameplay consistency. A more detailed breakdown of the content available in Calamity: -- 27 bosses and 12 minibosses +- 27 bosses and 5 minibosses - 100+ enemies - 5 town NPCs - 5 biomes and many new structures From a0eb720838c1326784a4953ca29c9c5f092d2bb8 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Sun, 1 Jun 2025 13:58:59 -0400 Subject: [PATCH 283/401] Port recent NPC Patreon names to hotfix --- NPCs/CalamityGlobalTownNPC.cs | 45 +++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/NPCs/CalamityGlobalTownNPC.cs b/NPCs/CalamityGlobalTownNPC.cs index 0146ad38ef..32fb1ca622 100644 --- a/NPCs/CalamityGlobalTownNPC.cs +++ b/NPCs/CalamityGlobalTownNPC.cs @@ -66,6 +66,7 @@ public static float TaxYieldFactor "Dazren", "Johnny Test", // <@!589966747977777197> (konorango) "Bling Bling Boy", // <@!522970788203069442> (phallguy) + "RICE", // <@!400107830889152524> (rice_xd.) }; private static readonly string[] ArmsDealerNames = { @@ -88,12 +89,14 @@ public static float TaxYieldFactor private static readonly string[] CyborgNames = { "Sylux", // <@!331812782183809025> (gonkachino) + "XL-39 Nemesis", // <@!1104036024063107082> (yashimayamanata) }; private static readonly string[] DemolitionistNames = { "Tavish DeGroot", // <@!442447226992721930> (magicoal) "Fimmy", // <@!407348617079160832> (darkmega5) "Dorira", // <@!215269032360804352> (crimsoncb) + "John Helldiver", // <@!614126424751603714> (exellent.) }; private static readonly string[] DryadNames = { @@ -116,6 +119,8 @@ public static float TaxYieldFactor "Him", // <@!931019614958256139> (himtheguy1) "Tooshiboots", // <@!333532730593771522> (ulmod) "Neesh", // <@!175803493464932352> (xjetty) + "Bars Boldia", // <@!332989575708540939> (careless_imp) + "Basel Raiden John Clive Fantasy 16", // <@!529392083136413696> (raiden_ii) }; private static readonly string[] GolferNames = null; private static readonly string[] GuideNames = @@ -135,7 +140,8 @@ public static float TaxYieldFactor "Alfred Rend", // <@!606301806481375255> (deadsqurp300) "Leeman", // <@!281999243168841728> (tweee) "Mihai", // <@!373941893467209730> (cmihaii.) - "Cooler Kevin", // <@!614126424751603714> (exellent.) + "Dinkleberg", // <@!581993958037520404> (hyperionzx) + "Wamy", // Fab added this name with no Discord ID. May be a donor who has no Discord account. }; private static readonly string[] MechanicNames = { @@ -143,25 +149,29 @@ public static float TaxYieldFactor "Daawn", // <@!206162323541458944> (daawnily) "Robin", // <@!654737510030639112> (altzeus) "Curly", // <@!673092101780668416> (curly4830) - "Cobalt", // <@!132962828922388481> (cobalt_44) + "Cobalt", // <@!132962828922388481> (cobalt_44) }; private static readonly string[] MerchantNames = { "Morshu", // <@!194931581826236416> (uberransy) + "Spamton G. Spamton", // <@!497146350438318101> (j.u.n.e.s) }; private static readonly string[] NurseNames = { "Farsni", "Fanny", // <@!799749125720637460> (zombiewolf511) "Mausi", // <@!194156349347594241> (sadouken) + "Fiona", // <@!475216964168450048> (thatgayguy69) }; private static readonly string[] PainterNames = { "Picasso", // <@!353316526306361347> (sconicboom -- for the late picassosbean2819) + "Bew", // <@!232291351167893505> (dmshi) }; private static readonly string[] PartyGirlNames = { "Arin", // <@!268169458302976012> (kiyotu) + "Typhäne", // <@!222064016107896832> (typhane.) }; private static readonly string[] PirateNames = { @@ -169,6 +179,7 @@ public static float TaxYieldFactor "Cap'n Deek", // "Alex N" on Patreon (No discord account) "Captain Billy Bones", // <@!699589229507772416> (djackv) "Captain J. Crackers", // <@!233232602994049024> (qyuuno) + "Gol D. Roger", // <@!256228859110752257> (xtra3678) }; private static readonly string[] PrincessNames = { @@ -178,6 +189,8 @@ public static float TaxYieldFactor "Nyavi Aceso", // <@!270260920888852480> (navigator.) "everquartz", // <@!451343554451865611> (everquartz) "Gwynevere", // <@!142752927348424704> (nuclearchaosazathoth) + "Hael", // <@!641747280944431156> (kalebtull) + "Yumesaki Mirrin", // <@!100235144744415232> (milinen) }; private static readonly string[] SantaClausNames = { @@ -187,19 +200,25 @@ public static float TaxYieldFactor { "Sans Undertale", // <@!145379091648872450> (shayy) "Papyrus Undertale", // <@!262663471189983242> (nycro) + "Gaster Undertale", // <@!924706306093379614> (enamoured) "Mr. Bones", // <@!359215912856977408> (jaybones.) + "Freakbob", // <@!377863128140087296> (jevilamv) }; private static readonly string[] SteampunkerNames = { "Vorbis", "Angel", "Mòrag Ladair", // <@!161893929485074432> (jalapeno9) + "Linn", // <@!277983612383526913> (duckycolors) + "Eira", // <@!1166136068408623234> (taela_gemetha) }; private static readonly string[] StylistNames = { "Amber", // <@!114677116473180169> (mishirousui) "Faith", // <@!509050283871961123> (toasty1007) "Xsiana", // <@!625780237489143839> (lokistic) + "Lain", // <@!655201622863118337> (literallyadeerfr) + "Hamis", // <@!608455754093035521> (haefer) }; private static readonly string[] TavernkeepNames = { @@ -211,22 +230,24 @@ public static float TaxYieldFactor private static readonly string[] TaxCollectorNames = { "Emmett", + "Casino King Gray", // <@!555512087711973390> (eternalgrayson) }; private static readonly string[] TravelingMerchantNames = { "Stan Pines", "Slap Battles", // <@!923504188615450654> (gravityglider.) + "Borgus", // <@!539127427482255376> (therealmeepman) }; private static readonly string[] TruffleNames = { "Aldrimil", // <@!413719640238194689> (Thorioum#2475) + "Wonton", // <@!1198092982923043040> (imonthatgudkush) }; private static readonly string[] WitchDoctorNames = { "Sok'ar", - "Toxin", // <@!348174404984766465> (Toxin#9598), + "Aeroni", // <@!348174404984766465> (aeroni) (previously: toxin) "Mixcoatl", // <@!284775927294984203> (.sharzz) - "Khatunz", // <@!303022375191183360> (jackshiz) "Amnesia Wapers", // <@!326821498323075073> (retardedadvicefromaretard) }; private static readonly string[] WizardNames = @@ -236,7 +257,7 @@ public static float TaxYieldFactor "Merasmus", // <@!288066987819663360> (spiderprovidence) "Habolo", // <@!163028025494077441> (hellgoat2) "Ortho", // <@!264984390910738432> (worcuus) - "Chris Tallballs", // <@!770211589076418571> (bewearium) + "Chris Tallballs", // <@!770211589076418571> (vysterx) (previously: bewearium) "Syethas", // <@!325413275066171393> (cosmicstariight) "Nextdoor Psycho", // <@!173261518572486656> (nextdoorpsycho) }; @@ -261,6 +282,8 @@ public static float TaxYieldFactor private static readonly string[] TownDogNames = { "Ozymandias", // <@!146333264871686145> (ozzatron) + "Miss Throws a Lot", // <@!799345607847182400> (oakhamsam) + "Brikwilla", // <@!543803736909414438> (lavendercobra) }; private static readonly string[] TownDogLabradorNames = { @@ -295,11 +318,13 @@ public static float TaxYieldFactor "Lucerne", // <@!271954788676141066> (lord_lucerne) "Milo", // <@!401849201597874179> (maskedmilo) "Octo", // <@!796112889353994281> (octolinggrimm) + "Chease", // <@!1039460813490102293> (parmiigianoreggiano) }; private static readonly string[] TownCatSiameseNames = null; private static readonly string[] TownCatBlackNames = { "Bear", // <@!183424826407518208> (lilac_vrt_olligoci) + "Storm", // <@!620383533516718085> (airwaveslr) }; private static readonly string[] TownCatOrangeTabbyNames = { @@ -307,7 +332,10 @@ public static float TaxYieldFactor "Tardo", // <@!739343546867384391> (midnight295) }; private static readonly string[] TownCatRussianBlueNames = null; - private static readonly string[] TownCatSilverNames = null; + private static readonly string[] TownCatSilverNames = + { + "Archie", // <@!303022375191183360> (jackshiz) + }; private static readonly string[] TownCatWhiteNames = null; private const int TownBunnyWhiteVanillaNames = 14; @@ -316,7 +344,10 @@ public static float TaxYieldFactor private const int TownBunnyFlemishVanillaNames = 12; private const int TownBunnyLopVanillaNames = 13; private const int TownBunnySilverVanillaNames = 13; - private static readonly string[] TownBunnyNames = null; + private static readonly string[] TownBunnyNames = + { + "Poco", // <@!1192261996146593872> (tostitomuncher33) + }; private static readonly string[] TownBunnyWhiteNames = null; private static readonly string[] TownBunnyAngoraNames = null; private static readonly string[] TownBunnyDutchNames = null; From cc99a855456332b76616ed44c0719a45ca9ef76d Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Sun, 1 Jun 2025 14:07:00 -0400 Subject: [PATCH 284/401] Add Bandit name Ishmael for donor (interim) --- NPCs/TownNPCs/THIEF.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/NPCs/TownNPCs/THIEF.cs b/NPCs/TownNPCs/THIEF.cs index 25b61e6880..6e81ae6084 100644 --- a/NPCs/TownNPCs/THIEF.cs +++ b/NPCs/TownNPCs/THIEF.cs @@ -112,6 +112,7 @@ public override bool CanTownNPCSpawn(int numTownNPCs) "Jackson", // <@!525827730646892549> (chowchow360) "Altarca", // <@!1140673052108128337> (altarca_27226_49175) "Jackie", // <@!353241811717718016> (jackalchan) + "Ishmael", // <@!840416568000381046> (vanillaoyster) // Original names this.GetLocalizedValue("Name.Laura"), From b587969326eeb7e34e70da6a2f2e6d0cc655795c Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Sun, 1 Jun 2025 14:49:55 -0400 Subject: [PATCH 285/401] 1 - Fix Calamitas' donor name recital. (INTERIM) 2 - Add all $10 and higher donor names to a separate list, included in the name recital. --- CalamityLists.cs | 41 ++++++++++++++++++++++++++++++++++++----- NPCs/TownNPCs/WITCH.cs | 22 +++++++++++++--------- 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/CalamityLists.cs b/CalamityLists.cs index c278d5892c..ad14568132 100644 --- a/CalamityLists.cs +++ b/CalamityLists.cs @@ -156,7 +156,40 @@ public class CalamityLists public static void LoadLists() { - donatorList = new List() + var newDonatorList = new List() + { + "Aerosyn", + "Arcxus", + "awesomechapro", + "azazel", + "BlueRay_256", + "botbot94", + "Chin", + "Cinder", + "drake093104", + "Grant Curtiss", + "Jace Ufret", + "JFL", + "MizzUltraViolet", + "Nature", + "Nick H", + "Nightinglade", + "Patch357", + "Phil Broome", + "roryoftheabyss", + "Sable", + "SakuraWinterz", + "Salted Warlock", + "Shayy", // Current dev. Listed as "Shay" on Patreon. + "SirChaos189", + "SkeletonHunter96", + "Taylor Olligoci", // also an ex-dev. Listed as "Lilac Olligoci" on Patreon. There were two "Taylor"s on the old list + "Xtra Trinity 3678", + "Zachtoplasm", + "ZoeyPlague", + }; + + var oldDonatorList = new List { "Vorbis", "SoloMael", @@ -207,7 +240,6 @@ public static void LoadLists() "MovingTarget_086", "Shiro", "Chip", - "Taylor", "ShotgunAngel", "Sandblast", "ThomasThePencil", @@ -232,7 +264,6 @@ public static void LoadLists() "Aleksanders", "TheSilverGhost", "Lucazii", - "Shay", "Prism", "BobIsNotMyRealName", "Guwahavel", @@ -346,7 +377,6 @@ public static void LoadLists() "Olkothan", "Vmar98", "Dasdruid", - "Cinder", "Brutzli", "Yhashtur", "Zekai", @@ -686,7 +716,6 @@ public static void LoadLists() "Kaledoulas", "Mohammad", "Skeli_G", - "Arcxus", "Sigil", "Dull", "DjackV", @@ -786,6 +815,8 @@ public static void LoadLists() "Patrera" }; + donatorList = [.. oldDonatorList, .. newDonatorList]; + projectileDestroyExceptionList = new List() { //holdout projectiles diff --git a/NPCs/TownNPCs/WITCH.cs b/NPCs/TownNPCs/WITCH.cs index c1524c4b84..268b87b3fd 100644 --- a/NPCs/TownNPCs/WITCH.cs +++ b/NPCs/TownNPCs/WITCH.cs @@ -147,21 +147,25 @@ public override void OnChatButtonClicked(bool firstButton, ref string shopName) } else { - Main.npcChatText = Donors(); + Main.npcChatText = GetRandomDonors(25); } } - public string Donors() + ///

+ /// Returns an arbitrary number of random donator usernames. + /// + public string GetRandomDonors(int numDonors) { - IList donorList = new List(CalamityLists.donatorList); - int maxDonorsListed = 25; - string[] donors = new string[maxDonorsListed]; - for (int i = 0; i < maxDonorsListed; i++) + IList pickingList = [.. CalamityLists.donatorList]; + + string[] pickedDonors = new string[numDonors]; + for (int i = 0; i < numDonors; ++i) { - donors[i] = donorList[Main.rand.Next(donorList.Count)]; - donorList.Remove(donors[i]); + int idxSelected = Main.rand.Next(pickingList.Count); + pickedDonors[i] = pickingList[idxSelected]; + pickingList.RemoveAt(idxSelected); } - string text = this.GetLocalization("DonorShoutout").Format(donors); + string text = this.GetLocalization("DonorShoutout").Format(pickedDonors); return text; } From 29e78c5acfb3776861a2a2548e4c1cb7586dc4af Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Sun, 1 Jun 2025 14:51:22 -0400 Subject: [PATCH 286/401] Change Cyborg donor name XL-39 Nemesis to Nemesis at donor request --- NPCs/CalamityGlobalTownNPC.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NPCs/CalamityGlobalTownNPC.cs b/NPCs/CalamityGlobalTownNPC.cs index 32fb1ca622..d6e06146e4 100644 --- a/NPCs/CalamityGlobalTownNPC.cs +++ b/NPCs/CalamityGlobalTownNPC.cs @@ -89,7 +89,7 @@ public static float TaxYieldFactor private static readonly string[] CyborgNames = { "Sylux", // <@!331812782183809025> (gonkachino) - "XL-39 Nemesis", // <@!1104036024063107082> (yashimayamanata) + "Nemesis", // <@!1104036024063107082> (yashimayamanata) }; private static readonly string[] DemolitionistNames = { From dacb2a75e07c9dc0ad326225909b8ac02fad0c83 Mon Sep 17 00:00:00 2001 From: Habble53 <87115317+Habble53@users.noreply.github.com> Date: Tue, 14 Oct 2025 16:55:30 +0300 Subject: [PATCH 287/401] Some NPC.HitModifiers.SourceDamage patches: Replaced globally available projectile instances of HitModifiers.SourceDamage modification with HitModifiers.TargetDamageMultiplier, so as to prevent it from being inherited in NPC.HitInfo.SourceDamage and doubled up in cases where other mods may spawn additional OnHit projectiles that inherit HitInfo.SourceDamage for accurate OnHit interactions. Recommended to move to HitModifiers.FinalDamage and redone as such or implement defensive mechanisms that don't let additional projectiles inherit SourceDamage, like globally tagging projectiles (and their children by chaining projectile tags with e.g. `source is EntitySource_Parent parent && parent.Entity is Projectile proj && proj.Calamity().WeaponSource`) in OnSpawn by checking EntitySource_ItemUse_WithAmmo. A few other less important examples were left as is, including Thanatos closed vent DR and GFB seed interaction(s?) like Profaned Guardians. --- CalPlayer/CalamityPlayerHitHurt.cs | 8 ++++---- NPCs/CalamityGlobalNPC.cs | 2 +- Projectiles/CalamityGlobalProjectile.cs | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CalPlayer/CalamityPlayerHitHurt.cs b/CalPlayer/CalamityPlayerHitHurt.cs index cea12b6330..b0e376259e 100644 --- a/CalPlayer/CalamityPlayerHitHurt.cs +++ b/CalPlayer/CalamityPlayerHitHurt.cs @@ -605,7 +605,7 @@ public override void ModifyHitNPCWithItem(Item item, NPC target, ref NPC.HitModi totalDamageMult += 0.6f; // Apply all Calamity multipliers as a sum total to TML New Damage in a single step - modifiers.SourceDamage *= totalDamageMult; + modifiers.TargetDamageMultiplier *= totalDamageMult; // 01JUN2024: Ozzatron: apply Yellow Candle "chip damage" as a dirty modifier // The registration of the dirty modifier is conditional to ensure it doesn't apply to "near invincible" targets @@ -613,7 +613,7 @@ public override void ModifyHitNPCWithItem(Item item, NPC target, ref NPC.HitModi // FinalDamage cannot be used for the intended effect because there is no way to access the actual damage of the hit CalamityGlobalNPC cgn = target.Calamity(); if (yellowCandle && cgn.DR < 0.99f && target.takenDamageMultiplier > 0.05f) - modifiers.ModifyHitInfo += YellowCandleBuff.ModifyHitInfo_Spite; + modifiers.TargetDamageMultiplier *= MultipliableFloat.One.Value + YellowCandleBuff.ExtraChipDamageRatio; // Stealth strike damage multipliers are applied here. // TODO -- stealth should be its own damage class and this should be applied as player StealthDamage *= XYZ @@ -662,12 +662,12 @@ public override void ModifyHitNPCWithItem(Item item, NPC target, ref NPC.HitModi if (proj.CountsAsClass()) { float meleeBoost = MathHelper.Lerp(0f, FrostArmorSetChange.ProximityBoost, 1 - DistanceInterpolant); - modifiers.SourceDamage += meleeBoost; + modifiers.TargetDamageMultiplier *= (modifiers.TargetDamageMultiplier.Value + meleeBoost) / modifiers.TargetDamageMultiplier.Value; } else if (proj.CountsAsClass()) { float rangedBoost = MathHelper.Lerp(0f, FrostArmorSetChange.ProximityBoost, DistanceInterpolant); - modifiers.SourceDamage += rangedBoost; + modifiers.TargetDamageMultiplier *= (modifiers.TargetDamageMultiplier.Value + rangedBoost) / modifiers.TargetDamageMultiplier.Value; } } diff --git a/NPCs/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index adb0f3c8c8..70de139593 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -5595,7 +5595,7 @@ public override void ModifyHitByProjectile(NPC npc, Projectile projectile, ref N if (!projectile.npcProj && !projectile.trap) { if (projectile.CountsAsClass() && modPlayer.plagueReaper && pFlames > 0) - modifiers.SourceDamage *= 1.1f; + modifiers.TargetDamageMultiplier *= 1.1f; } // Any weapons that shoot projectiles from anywhere other than the player's center aren't affected by point-blank shot damage boost. diff --git a/Projectiles/CalamityGlobalProjectile.cs b/Projectiles/CalamityGlobalProjectile.cs index d2e3661e1c..bb468974e7 100644 --- a/Projectiles/CalamityGlobalProjectile.cs +++ b/Projectiles/CalamityGlobalProjectile.cs @@ -4221,14 +4221,14 @@ public override void ModifyHitNPC(Projectile projectile, NPC target, ref NPC.Hit { float proximityDamageInterpolant = Utils.GetLerpValue(250f, 2400f, target.Distance(player.Center), true); float proximityDamageFactor = MathHelper.SmoothStep(0.7f, 1.45f, proximityDamageInterpolant); - modifiers.SourceDamage *= proximityDamageFactor; + modifiers.TargetDamageMultiplier *= proximityDamageFactor; } if (modPlayer.closeProximityRewardEnchant) { float proximityDamageInterpolant = Utils.GetLerpValue(400f, 175f, target.Distance(player.Center), true); float proximityDamageFactor = MathHelper.SmoothStep(0.75f, 1.75f, proximityDamageInterpolant); - modifiers.SourceDamage *= proximityDamageFactor; + modifiers.TargetDamageMultiplier *= proximityDamageFactor; } // Aerial Bane does 50% damage to "airborne" enemies. This is just simple math to revert that as it is a very unbalanced mechanic. From 0d3eb428559de7d0963c9a56dd1a164096db01e0 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Sun, 26 Oct 2025 19:04:15 -0400 Subject: [PATCH 288/401] delete broken & unnecessary IL edit --- ILEditing/ILChangesLoading.cs | 1 - ILEditing/MechanicILChanges.cs | 68 ---------------------------------- 2 files changed, 69 deletions(-) diff --git a/ILEditing/ILChangesLoading.cs b/ILEditing/ILChangesLoading.cs index 85c5bb9006..d30ac1320d 100644 --- a/ILEditing/ILChangesLoading.cs +++ b/ILEditing/ILChangesLoading.cs @@ -46,7 +46,6 @@ public override void OnModLoad() On_TileDrawing.DrawPartialLiquid += DrawCustomLava; On_WaterfallManager.DrawWaterfall_int_int_int_float_Vector2_Rectangle_Color_SpriteEffects += DrawCustomLavafalls; On_Main.RenderWater += CacheLavaStyle; - IL_LiquidRenderer.DrawNormalLiquids += ChangeWaterQuadColors; IL_Main.oldDrawWater += DrawCustomLava3; On_TileLightScanner.GetTileLight += MakeSulphSeaWaterBetter; On_TileDrawing.PreDrawTiles += ClearForegroundStuff; diff --git a/ILEditing/MechanicILChanges.cs b/ILEditing/MechanicILChanges.cs index f9714c4a8b..288e76a4eb 100644 --- a/ILEditing/MechanicILChanges.cs +++ b/ILEditing/MechanicILChanges.cs @@ -828,74 +828,6 @@ private static void DrawCustomLava(Terraria.GameContent.Drawing.On_TileDrawing.o } } - private static void ChangeWaterQuadColors(ILContext il) - { - ILCursor cursor = new ILCursor(il); - - if (!cursor.TryGotoNext(c => c.MatchLdfld("_liquidTextures"))) - { - LogFailure("Custom Lava Drawing", "Could not locate the liquid texture array load."); - return; - } - - // Move to the end of the get_Value() call and then use the resulting texture to check if a new one should replace it. - // Adding to the index directly would seem like a simple, direct way of achieving this since the operation is incredibly light, but - // it also unsafe due to the potential for NOP operations to appear. - if (!cursor.TryGotoNext(MoveType.After, c => c.MatchCallvirt(textureGetValueMethod))) - { - LogFailure("Custom Lava Drawing", "Could not locate the liquid texture Value call."); - return; - } - cursor.EmitDelegate>(initialTexture => SelectLavaTexture(initialTexture, LiquidTileType.Waterflow)); - - if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdloc(9))) - { - LogFailure("Custom Lava Drawing", "Could not locate the liquid light color."); - return; - } - - // Pass the texture in so that the method can ensure it is not messing around with non-lava textures. - cursor.Emit(OpCodes.Ldarg_0); - cursor.Emit(OpCodes.Ldfld, typeof(LiquidRenderer).GetField("_liquidTextures")); - cursor.Emit(OpCodes.Ldloc, 8); - cursor.Emit(OpCodes.Ldelem_Ref); - cursor.Emit(OpCodes.Ldloc, 8); - cursor.Emit(OpCodes.Ldloc, 3); - cursor.Emit(OpCodes.Ldloc, 4); - - // Caching these values can save a LOT of overhead at runtime. - ModWaterStyle sunkenSeaWater = ModContent.GetInstance(); - ModWaterStyle sulphuricWater = ModContent.GetInstance(); - ModWaterStyle sulphuricDepthsWater = ModContent.GetInstance(); - ModWaterStyle upperAbyssWater = ModContent.GetInstance(); - ModWaterStyle middleAbyssWater = ModContent.GetInstance(); - ModWaterStyle voidWater = ModContent.GetInstance(); - - cursor.EmitDelegate>((initialColor, initialTexture, liquidType, x, y) => - { - // Don't bother changing the color if the cached drawing style is null. - if (cachedLavaStyle != default) - { - initialColor = SelectLavaQuadColor(initialTexture, ref initialColor, liquidType == 1); - } - - if (liquidType == sunkenSeaWater.Slot || - liquidType == sulphuricWater.Slot || - liquidType == sulphuricDepthsWater.Slot || - liquidType == upperAbyssWater.Slot || - liquidType == middleAbyssWater.Slot || - liquidType == voidWater.Slot) - { - SelectSulphuricWaterColor(x, y, ref initialColor); - } - - // Apply any extra color conditions. - initialColor = ExtraColorChangeConditions?.Invoke(initialColor, liquidType, new(x, y)) ?? initialColor; - - return initialColor; - }); - } - private static void DrawCustomLava3(ILContext il) { ILCursor cursor = new ILCursor(il); From 8d27082ff18cb4e3511ef1a2bc57e5ee1a2eb22f Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Sun, 26 Oct 2025 19:04:27 -0400 Subject: [PATCH 289/401] version bump, title change for temporary preview build --- build.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.txt b/build.txt index 54df2bf033..6b0fe00fe8 100644 --- a/build.txt +++ b/build.txt @@ -1,6 +1,6 @@ author = The Calamity Dev Team -version = 2.0.5 -displayName = Calamity Mod +version = 2.0.6 +displayName = Calamity Mod (TML PREVIEW) modReferences = CalamityModMusic homepage = https://discord.gg/calamity buildIgnore = .vs\*, Properties\*, *.csproj, *.user, obj\*, bin\*, *.config, .git\*, .github\*, LICENSE, README.md, .editorconfig, .gitignore, .gitattributes, Effects\Compiler\* From 24a11d2c99ba70dc3b5096517f222f91180ba347 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Sun, 26 Oct 2025 19:08:49 -0400 Subject: [PATCH 290/401] remove name change because that's not how that works --- build.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.txt b/build.txt index 6b0fe00fe8..29c6d61b99 100644 --- a/build.txt +++ b/build.txt @@ -1,6 +1,6 @@ author = The Calamity Dev Team version = 2.0.6 -displayName = Calamity Mod (TML PREVIEW) +displayName = Calamity Mod modReferences = CalamityModMusic homepage = https://discord.gg/calamity buildIgnore = .vs\*, Properties\*, *.csproj, *.user, obj\*, bin\*, *.config, .git\*, .github\*, LICENSE, README.md, .editorconfig, .gitignore, .gitattributes, Effects\Compiler\* From 5979138139b2776aa8210b3c349bc335e4cf0588 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sun, 26 Oct 2025 20:32:29 -0400 Subject: [PATCH 291/401] Removed the Drunk Princess game tip --- Localization/en-US/Mods.CalamityMod.GameTips.hjson | 1 - 1 file changed, 1 deletion(-) diff --git a/Localization/en-US/Mods.CalamityMod.GameTips.hjson b/Localization/en-US/Mods.CalamityMod.GameTips.hjson index 9d69d69161..3d5faa25c4 100644 --- a/Localization/en-US/Mods.CalamityMod.GameTips.hjson +++ b/Localization/en-US/Mods.CalamityMod.GameTips.hjson @@ -4,7 +4,6 @@ PlanetoidTip: You can find Planetoids high up in Space! AbyssTip: The Abyss can be found deep below the Sulphurous Sea. Be sure to have proper diving gear when exploring it. BanditTip: The Bandit won't steal from the poor. If you want to see them, you will need a lot of money to pique their attention. RefundTip: If you've been reforging a lot with the Goblin Tinkerer, it might pay off to give the Bandit a visit. -DrunkPrincessTip: The Drunk Princess is great to party with. If you carry her favorite vodka, she might move in. SeaKingTip: The Sea King used to like clams. He changed his mind when he got eaten by one. AmidiasBlessingTip: The Sea King can provide a bubble to aid with breathing underwater to any who ask for help. ArchmageTip: The Archmage can be freed if you manage to destroy the cell he was imprisoned in. From c74b3a721c400464c549f4e614833eeda183afb5 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sun, 26 Oct 2025 20:33:17 -0400 Subject: [PATCH 292/401] Fixed Flight Bar config item icon --- Localization/en-US/Mods.CalamityMod.Configs.hjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/en-US/Mods.CalamityMod.Configs.hjson b/Localization/en-US/Mods.CalamityMod.Configs.hjson index 44503237ef..85d927e9eb 100644 --- a/Localization/en-US/Mods.CalamityMod.Configs.hjson +++ b/Localization/en-US/Mods.CalamityMod.Configs.hjson @@ -187,7 +187,7 @@ CalamityConfig: { } FlightBar: { - Label: "[i:CalamityMod/DrewsWings] Display Flight Bar" + Label: "[i:CalamityMod/WingsofRebirth] Display Flight Bar" Tooltip: ''' Enables the Flight Bar UI, which shows the player's remaining wing flight time. From 5cb32fddabcf3e13475f7b4076d46cc847a2eff7 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sun, 26 Oct 2025 20:35:55 -0400 Subject: [PATCH 293/401] Fixed Buzzkill firing multiple saws in multiplayer --- Projectiles/Ranged/BuzzkillHoldout.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Projectiles/Ranged/BuzzkillHoldout.cs b/Projectiles/Ranged/BuzzkillHoldout.cs index b91af68411..b0d329f885 100644 --- a/Projectiles/Ranged/BuzzkillHoldout.cs +++ b/Projectiles/Ranged/BuzzkillHoldout.cs @@ -82,13 +82,16 @@ public override void HoldoutAI() SoundStyle ShootSound = new("CalamityMod/Sounds/Item/SawShot", 2) { PitchVariance = 0.1f, Volume = 0.4f + SawPower * 0.5f }; SoundEngine.PlaySound(ShootSound, GunTipPosition); - float sawDamageMult = MathHelper.Lerp(1f, 5f, SawPower) / 1.5f; // The damage must be divided by 1.5 to offset the holdout having 1.5x base damage. - int sawPierce = (int)MathHelper.Lerp(2f, 6f, SawPower); int sawLevel = (SawPower >= 1f).ToInt() + (SawPower >= 0.25f).ToInt(); + if (Main.myPlayer == Projectile.owner) + { + float sawDamageMult = MathHelper.Lerp(1f, 5f, SawPower) / 1.5f; // The damage must be divided by 1.5 to offset the holdout having 1.5x base damage. + int sawPierce = (int)MathHelper.Lerp(2f, 6f, SawPower); - Projectile buzzsaw = Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), GunTipPosition, Projectile.velocity.SafeNormalize(Vector2.UnitY) * Owner.ActiveItem().shootSpeed, ModContent.ProjectileType(), (int)(Projectile.damage * sawDamageMult), (int)(Projectile.knockBack * (sawDamageMult / 2)), Main.myPlayer, sawLevel); - buzzsaw.penetrate = sawPierce; - buzzsaw.rotation = Main.rand.NextFloat(0f, MathHelper.TwoPi); + Projectile buzzsaw = Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), GunTipPosition, Projectile.velocity.SafeNormalize(Vector2.UnitY) * Owner.ActiveItem().shootSpeed, ModContent.ProjectileType(), (int)(Projectile.damage * sawDamageMult), (int)(Projectile.knockBack * (sawDamageMult / 2)), Main.myPlayer, sawLevel); + buzzsaw.penetrate = sawPierce; + buzzsaw.rotation = Main.rand.NextFloat(0f, MathHelper.TwoPi); + } NoSawOnHoldout = true; OffsetLengthFromArm -= 4f + 12f * SawPower; From 2161d19801984b0973ed6316d39d98528fad9d9e Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sun, 26 Oct 2025 20:37:29 -0400 Subject: [PATCH 294/401] Fixed Sup Slaughterer bug --- Projectiles/Ranged/SuperradiantSlaughtererHoldout.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projectiles/Ranged/SuperradiantSlaughtererHoldout.cs b/Projectiles/Ranged/SuperradiantSlaughtererHoldout.cs index fd9d690fe4..934744d2eb 100644 --- a/Projectiles/Ranged/SuperradiantSlaughtererHoldout.cs +++ b/Projectiles/Ranged/SuperradiantSlaughtererHoldout.cs @@ -60,7 +60,7 @@ public override void SetDefaults() public override void KillHoldoutLogic() { - if (HeldItem.type != Owner.ActiveItem().type) + if (HeldItem.type != Owner.ActiveItem().type || Owner.dead || !Owner.active) { Projectile.Kill(); Projectile.netUpdate = true; From e2a160834beeb77a7f9d2c0a1b4687487a0b215e Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sun, 26 Oct 2025 20:59:45 -0400 Subject: [PATCH 295/401] 1 - Fixed Coin of Deceit tooltip 2 - Fixed Glorious End wall clipping 3 - Fixed the return of Celestial Starboard stunted dash bug --- CalPlayer/CalamityPlayer.cs | 10 +++++----- CalPlayer/CalamityPlayerDashEffects.cs | 1 + ILEditing/MechanicILChanges.cs | 11 +++++------ Items/Accessories/CoinofDeceit.cs | 2 +- .../en-US/Mods.CalamityMod.Items.Accessories.hjson | 2 +- Projectiles/Magic/MeteorStar.cs | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 9137d7d2eb..69fffba179 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -285,7 +285,7 @@ public partial class CalamityPlayer : ModPlayer public bool stealthStrikeThisFrame = false; public bool stealthStrikeHalfCost = false; public bool stealthStrike75Cost = false; - public bool stealthStrike85Cost = false; + public bool stealthStrike90Cost = false; public bool wearingRogueArmor = false; public float accStealthGenBoost = 0f; @@ -4529,7 +4529,7 @@ private void ResetRogueStealth() stealthStrikeThisFrame = false; stealthStrikeHalfCost = false; stealthStrike75Cost = false; - stealthStrike85Cost = false; + stealthStrike90Cost = false; // stealthAcceleration only resets if you don't have either of the accelerator accessories equipped if (!darkGodSheath && !eclipseMirror) @@ -4716,8 +4716,8 @@ public bool StealthStrikeAvailable() consumptionMult = 0.5f; else if (stealthStrike75Cost) consumptionMult = 0.75f; - else if (stealthStrike85Cost) - consumptionMult = 0.85f; + else if (stealthStrike90Cost) + consumptionMult = 0.9f; return rogueStealth >= rogueStealthMax * consumptionMult; } @@ -4744,7 +4744,7 @@ public void ConsumeStealthByAttacking() if (rogueStealth <= 0f) rogueStealth = 0f; } - else if (stealthStrike85Cost) + else if (stealthStrike90Cost) { rogueStealth -= 0.9f * stealthToLose; if (rogueStealth <= 0f) diff --git a/CalPlayer/CalamityPlayerDashEffects.cs b/CalPlayer/CalamityPlayerDashEffects.cs index da590b45e9..aaa5820ffb 100644 --- a/CalPlayer/CalamityPlayerDashEffects.cs +++ b/CalPlayer/CalamityPlayerDashEffects.cs @@ -462,6 +462,7 @@ public bool DoADash(float dashSpeed) if (WorldGen.SolidOrSlopedTile(upwardTilePoint.X, upwardTilePoint.Y) || WorldGen.SolidOrSlopedTile(aheadTilePoint.X, aheadTilePoint.Y)) Player.velocity.X /= 2f; + Player.timeSinceLastDashStarted = 0; Player.dashDelay = -1; } diff --git a/ILEditing/MechanicILChanges.cs b/ILEditing/MechanicILChanges.cs index 288e76a4eb..1728f258ad 100644 --- a/ILEditing/MechanicILChanges.cs +++ b/ILEditing/MechanicILChanges.cs @@ -260,16 +260,14 @@ private static void ApplyDashKeybind(Terraria.On_Player.orig_DoCommonDashHandle dir = self.direction; dashing = true; - if (self.dashTime > 0) - self.dashTime--; - if (self.dashTime < 0) - self.dashTime++; - if ((self.dashTime <= 0 && self.direction == -1) || (self.dashTime >= 0 && self.direction == 1)) + // CIT 16OCT2024: Commented this code out, as there's no reason for custom dash hotkey to use Player.dashTime + // and was causing the return of Celestial Starboard's dash bug from early 1.4 versions + /*if ((self.dashTime <= 0 && self.direction == -1) || (self.dashTime >= 0 && self.direction == 1)) { self.dashTime = 15; return; - } + }*/ dashing = true; self.dashTime = 0; @@ -284,6 +282,7 @@ private static void ApplyDashKeybind(Terraria.On_Player.orig_DoCommonDashHandle { dir = 1; dashing = false; + self.dashTime = 0; } } #endregion diff --git a/Items/Accessories/CoinofDeceit.cs b/Items/Accessories/CoinofDeceit.cs index 694429bc96..1b9ac86cd6 100644 --- a/Items/Accessories/CoinofDeceit.cs +++ b/Items/Accessories/CoinofDeceit.cs @@ -18,7 +18,7 @@ public override void SetDefaults() public override void UpdateAccessory(Player player, bool hideVisual) { - player.Calamity().stealthStrike85Cost = true; + player.Calamity().stealthStrike90Cost = true; player.GetCritChance() += 6; } diff --git a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson index 57bfda5f1f..b132422b93 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Accessories.hjson @@ -391,7 +391,7 @@ CoinofDeceit: { DisplayName: Coin of Deceit Tooltip: ''' - Stealth strikes only expend 85% of your max stealth + Stealth strikes only expend 90% of your max stealth 6% increased rogue crit chance ''' } diff --git a/Projectiles/Magic/MeteorStar.cs b/Projectiles/Magic/MeteorStar.cs index c2292cb1bb..ac9a45264c 100644 --- a/Projectiles/Magic/MeteorStar.cs +++ b/Projectiles/Magic/MeteorStar.cs @@ -96,7 +96,7 @@ public override void AI() } // Die immediately if the owner of this projectile is clipping into tiles because of its movement. - if (Collision.SolidCollision(Owner.position, Owner.width, Owner.height) && Projectile.velocity != Vector2.Zero) + if (Collision.SolidCollision(Owner.position + Projectile.velocity, Owner.width, Owner.height) && Projectile.velocity != Vector2.Zero) { Owner.velocity.Y = 0f; Explode(); From 7752d55e5aff246a072b607f482f3dde3cf950a3 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sun, 26 Oct 2025 21:06:39 -0400 Subject: [PATCH 296/401] Fixed Lava Slime config --- ILEditing/ILChangesLoading.cs | 1 + ILEditing/VanillaStupidityFixingILChanges.cs | 19 +++++ .../en-US/Mods.CalamityMod.Configs.hjson | 2 +- NPCs/CalamityGlobalNPC.cs | 7 -- NPCs/NormalNPCs/LavaSlimeNoLavaDrop.cs | 75 ------------------- Systems/BestiaryRegistrySystem.cs | 1 - 6 files changed, 21 insertions(+), 84 deletions(-) delete mode 100644 NPCs/NormalNPCs/LavaSlimeNoLavaDrop.cs diff --git a/ILEditing/ILChangesLoading.cs b/ILEditing/ILChangesLoading.cs index d30ac1320d..e358b4cc5f 100644 --- a/ILEditing/ILChangesLoading.cs +++ b/ILEditing/ILChangesLoading.cs @@ -139,6 +139,7 @@ public override void OnModLoad() IL_WorldGen.MakeDungeon += ChangeDungeonSpikeQuantities; // Removal of vanilla stupidity + IL_NPC.VanillaHitEffect += PreventLavaSlimeLavaDrop; IL_Player.UpdateBuffs += RemoveFeralBiteRandomDebuffs; IL_Sandstorm.HasSufficientWind += DecreaseSandstormWindSpeedRequirement; IL_Item.TryGetPrefixStatMultipliersForItem += RelaxPrefixRequirements; diff --git a/ILEditing/VanillaStupidityFixingILChanges.cs b/ILEditing/VanillaStupidityFixingILChanges.cs index 9a430ec383..c9e5a5ee49 100644 --- a/ILEditing/VanillaStupidityFixingILChanges.cs +++ b/ILEditing/VanillaStupidityFixingILChanges.cs @@ -121,6 +121,25 @@ private static void PreventBossSlimeRainSpawns(Terraria.On_NPC.orig_SlimeRainSpa } #endregion Prevention of Slime Rain Spawns When Near Bosses + #region Prevent Lava Slime Dropping Lava + private static void PreventLavaSlimeLavaDrop(ILContext il) + { + // Disable Lava Slimes dropping lava if its respective config is enabled. + var cursor = new ILCursor(il); + + // Go to the check for Remix world. + if (!cursor.TryGotoNext(MoveType.Before, i => i.MatchLdsfld
("remixWorld"))) + { + LogFailure("Prevent Lava Slime Dropping Lava", "Could not find the check for Remix World."); + return; + } + + // Add an additional check for the config. + cursor.Remove(); + cursor.EmitDelegate>(() => CalamityConfig.Instance.RemoveLavaDropsFromLavaSlimes || Main.remixWorld); + } + #endregion + #region Remove Feral Bite Random Debuffs private static void RemoveFeralBiteRandomDebuffs(ILContext il) { diff --git a/Localization/en-US/Mods.CalamityMod.Configs.hjson b/Localization/en-US/Mods.CalamityMod.Configs.hjson index 85d927e9eb..f2c06a2a69 100644 --- a/Localization/en-US/Mods.CalamityMod.Configs.hjson +++ b/Localization/en-US/Mods.CalamityMod.Configs.hjson @@ -314,7 +314,7 @@ CalamityConfig: { RemoveLavaDropsFromLavaSlimes: { Label: "[i:LavaWaders] Remove Lava Drops From Lava Slimes" - Tooltip: When enabled, Lava Slimes will be replaced with a new Lava Slime that no longer drops lava. + Tooltip: When enabled, Lava Slimes will be prevented from dropping lava in Expert Mode. } RemoveReforgeRNG: { diff --git a/NPCs/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index adb0f3c8c8..4c896be3f3 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -6127,13 +6127,6 @@ public override void EditSpawnPool(IDictionary pool, NPCSpawnInfo sp spawnInfo.Player.Calamity().ZoneSunkenSea || (spawnInfo.Player.Calamity().ZoneAstral && !spawnInfo.Player.PillarZone()); - // Replace vanilla Lava Slimes with Calamity Lava Slimes to avoid annoying lava drops - if (spawnInfo.Player.ZoneUnderworldHeight && !calamityBiomeZone && CalamityConfig.Instance.RemoveLavaDropsFromLavaSlimes && Main.expertMode) - { - pool.Add(NPCType(), SpawnCondition.Underworld.Chance); - pool.Remove(NPCID.LavaSlime); - } - // Spawn Green Jellyfish in prehm and Blue Jellyfish in hardmode if (spawnInfo.Player.ZoneRockLayerHeight && spawnInfo.Water && !calamityBiomeZone) { diff --git a/NPCs/NormalNPCs/LavaSlimeNoLavaDrop.cs b/NPCs/NormalNPCs/LavaSlimeNoLavaDrop.cs deleted file mode 100644 index ca5764da80..0000000000 --- a/NPCs/NormalNPCs/LavaSlimeNoLavaDrop.cs +++ /dev/null @@ -1,75 +0,0 @@ -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.NPCs.NormalNPCs -{ - public class LavaSlimeNoLavaDrop : ModNPC - { - public override string Texture => $"Terraria/Images/NPC_{NPCID.LavaSlime}"; - - public override void SetStaticDefaults() - { - Main.npcFrameCount[NPC.type] = 2; - this.HideFromBestiary(); - } - - public override void SetDefaults() - { - NPC.aiStyle = NPCAIStyleID.Slime; - AIType = NPCID.LavaSlime; - AnimationType = NPCID.LavaSlime; - NPC.width = 24; - NPC.height = 18; - NPC.damage = 15; - NPC.defense = 10; - NPC.lifeMax = 50; - NPC.HitSound = SoundID.NPCHit1; - NPC.DeathSound = SoundID.NPCDeath1; - NPC.scale = 1.1f; - NPC.alpha = 50; - NPC.lavaImmune = true; - NPC.value = 120f; - if (Main.remixWorld) - { - NPC.damage = 7; - NPC.defense = 2; - NPC.lifeMax = 25; - NPC.value = 25f; - } - //Banner = NPCID.LavaSlime; - //BannerItem = ItemID.LavaSlimeBanner; - - NPC.Calamity().VulnerableToCold = true; - NPC.Calamity().VulnerableToSickness = false; - NPC.Calamity().VulnerableToHeat = false; - NPC.Calamity().VulnerableToWater = true; - - // Scale stats in Expert and Master - CalamityGlobalNPC.AdjustExpertModeStatScaling(NPC); - CalamityGlobalNPC.AdjustMasterModeStatScaling(NPC); - } - - public override void HitEffect(NPC.HitInfo hit) - { - if (NPC.life > 0) - { - for (int i = 0; (double)i < hit.Damage / (double)NPC.lifeMax * 80D; i++) - { - int dust = Dust.NewDust(NPC.position, NPC.width, NPC.height, 6, hit.HitDirection * 2, -1f, NPC.alpha, default, 1.5f); - if (Main.rand.Next(8) != 0) - Main.dust[dust].noGravity = true; - } - - return; - } - - for (int i = 0; i < 40; i++) - { - int dust = Dust.NewDust(NPC.position, NPC.width, NPC.height, 6, hit.HitDirection * 2, -1f, NPC.alpha, default, 1.5f); - if (Main.rand.Next(8) != 0) - Main.dust[dust].noGravity = true; - } - } - } -} diff --git a/Systems/BestiaryRegistrySystem.cs b/Systems/BestiaryRegistrySystem.cs index f14f47f6dc..bd95735428 100644 --- a/Systems/BestiaryRegistrySystem.cs +++ b/Systems/BestiaryRegistrySystem.cs @@ -14,7 +14,6 @@ public override void PostSetupContent() // Manually register variants post-initiailization ContentSamples.NpcBestiaryCreditIdsByNpcNetIds[NPCType()] = ContentSamples.NpcBestiaryCreditIdsByNpcNetIds[NPCType()]; ContentSamples.NpcBestiaryCreditIdsByNpcNetIds[NPCType()] = ContentSamples.NpcBestiaryCreditIdsByNpcNetIds[NPCType()]; - ContentSamples.NpcBestiaryCreditIdsByNpcNetIds[NPCType()] = ContentSamples.NpcBestiaryCreditIdsByNpcNetIds[NPCID.LavaSlime]; } } } From d6bd9c6053c3d4387bd1a05da4eaa42602ee71a2 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sun, 26 Oct 2025 21:20:04 -0400 Subject: [PATCH 297/401] Several boss fixes: - Hive Mind and Perforators only appear on Boss Checklist in worlds of their respective evil - Fixed Primordial Wyrm not being marked as defeated - Fixed SCal being able to fire projectiles in the one frame between bros dying and phase transition --- ModSupport/WeakReferenceSupport.cs | 4 ++++ NPCs/PrimordialWyrm/PrimordialWyrmHead.cs | 7 +++++++ NPCs/SupremeCalamitas/SupremeCalamitas.cs | 6 ++++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/ModSupport/WeakReferenceSupport.cs b/ModSupport/WeakReferenceSupport.cs index fbf4dbf23b..16a7083033 100644 --- a/ModSupport/WeakReferenceSupport.cs +++ b/ModSupport/WeakReferenceSupport.cs @@ -419,9 +419,11 @@ private static void AddCalamityBosses(Mod bossChecklist, Mod calamity) string entryName = "HiveMind"; BossChecklistProgressionValues.TryGetValue(entryName, out float order); int type = NPCType(); + Func IsCorruption = () => !WorldGen.crimson || Main.drunkWorld; List collection = new List() { ItemType(), ItemType(), ItemType(), ItemType(), ItemType(), ItemType() }; AddBoss(bossChecklist, calamity, entryName, order, DownedHiveMind, type, new Dictionary() { + ["availability"] = IsCorruption, ["spawnInfo"] = GetSpawnInfo(entryName), ["despawnMessage"] = GetDespawnMessage(entryName), ["spawnItems"] = ItemType(), @@ -435,9 +437,11 @@ private static void AddCalamityBosses(Mod bossChecklist, Mod calamity) string entryName = "Perforators"; BossChecklistProgressionValues.TryGetValue(entryName, out float order); int type = NPCType(); + Func IsCrimson = () => WorldGen.crimson || Main.drunkWorld; List collection = new List() { ItemType(), ItemType(), ItemType(), ItemType(), ItemType(), ItemType() }; AddBoss(bossChecklist, calamity, entryName, order, DownedPerforators, type, new Dictionary() { + ["availability"] = IsCrimson, ["displayName"] = GetDisplayName(entryName), ["spawnInfo"] = GetSpawnInfo(entryName), ["despawnMessage"] = GetDespawnMessage(entryName), diff --git a/NPCs/PrimordialWyrm/PrimordialWyrmHead.cs b/NPCs/PrimordialWyrm/PrimordialWyrmHead.cs index 71119e2239..93ff213d5f 100644 --- a/NPCs/PrimordialWyrm/PrimordialWyrmHead.cs +++ b/NPCs/PrimordialWyrm/PrimordialWyrmHead.cs @@ -1452,6 +1452,13 @@ public override void BossLoot(ref string name, ref int potionType) potionType = ModContent.ItemType(); } + public override void OnKill() + { + // Mark Primordial Wyrm as dead + DownedBossSystem.downedPrimordialWyrm = true; + CalamityNetcode.SyncWorld(); + } + public override void ModifyNPCLoot(NPCLoot npcLoot) { npcLoot.Add(ModContent.ItemType()); diff --git a/NPCs/SupremeCalamitas/SupremeCalamitas.cs b/NPCs/SupremeCalamitas/SupremeCalamitas.cs index fbddbe5da9..28b63083da 100644 --- a/NPCs/SupremeCalamitas/SupremeCalamitas.cs +++ b/NPCs/SupremeCalamitas/SupremeCalamitas.cs @@ -2063,6 +2063,7 @@ public override void AI() NPC.dontTakeDamage = true; NPC.chaseable = false; NPC.damage = 0; + attackPause = 5; if (!canDespawn) NPC.velocity *= 0.95f; @@ -2525,7 +2526,8 @@ public override void AI() Vector2 projectileSpawn = NPC.Center + projectileVelocity * 8f; projectileVelocity *= 5f * uDieLul; int projectileType = gigablast; - Projectile.NewProjectile(NPC.GetSource_FromAI(), projectileSpawn, projectileVelocity, projectileType, gigablastDamage, 0f, Main.myPlayer, 0f, 2f); + if (attackPause == 0) + Projectile.NewProjectile(NPC.GetSource_FromAI(), projectileSpawn, projectileVelocity, projectileType, gigablastDamage, 0f, Main.myPlayer, 0f, 2f); } } @@ -2539,7 +2541,7 @@ public override void AI() } } - // Previously the 0.4% health threshold transition + // Previously the 40% health threshold transition if (lifeRatio <= 0.45f && hasSummonedBrothers && (permafrost ? NPC.AnyNPCs(ModContent.NPCType()) : (NPC.AnyNPCs(ModContent.NPCType()) || NPC.AnyNPCs(ModContent.NPCType()))) == false) { NPC.ai[0] = 1f; From 07bd5eea0dc7a5e571a1baa638933db2a142d285 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sun, 26 Oct 2025 21:23:34 -0400 Subject: [PATCH 298/401] Fixed cooldown end sounds being audible through the entire world --- CalPlayer/CalamityPlayerMiscEffects.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index efe279743a..28664a61c2 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -1322,7 +1322,7 @@ private void MiscEffects() { handler.OnCompleted(); if (handler.EndSound != null && handler.ShouldPlayEndSound) - SoundEngine.PlaySound(handler.EndSound.GetValueOrDefault()); + SoundEngine.PlaySound(handler.EndSound.GetValueOrDefault(), Player.Center); expiredCooldowns.Add(id); } } From c4893f57173de64679c5246f513eea860bdd9741 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sun, 26 Oct 2025 21:27:20 -0400 Subject: [PATCH 299/401] Fixed Chalice causing more things to not proc --- CalPlayer/CalamityPlayerHitHurt.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CalPlayer/CalamityPlayerHitHurt.cs b/CalPlayer/CalamityPlayerHitHurt.cs index cea12b6330..da7ff3fcc1 100644 --- a/CalPlayer/CalamityPlayerHitHurt.cs +++ b/CalPlayer/CalamityPlayerHitHurt.cs @@ -1619,16 +1619,16 @@ public override bool ConsumableDodge(Player.HurtInfo info) return true; // Mirror evades do not work if the global dodge cooldown is active. This cooldown can be triggered by either mirror. - if (!Player.HasCooldown(GlobalDodge.ID) && info.Damage >= dodgeDamageGateValue) + if (!Player.HasCooldown(GlobalDodge.ID) && actualDamageTaken >= dodgeDamageGateValue) { if (eclipseMirror) { - EclipseMirrorDodge(dodgeDamageGateValuePercent, dodgeDamageGateValue, info.Damage); + EclipseMirrorDodge(dodgeDamageGateValuePercent, dodgeDamageGateValue, actualDamageTaken); return true; } else if (abyssalMirror) { - AbyssMirrorDodge(dodgeDamageGateValuePercent, dodgeDamageGateValue, info.Damage); + AbyssMirrorDodge(dodgeDamageGateValuePercent, dodgeDamageGateValue, actualDamageTaken); return true; } } @@ -2215,7 +2215,7 @@ public override void OnHurt(Player.HurtInfo hurtInfo) if (trinketOfChi) chiBuffTimer = 0; - if (amidiasBlessing && hurtInfo.Damage > 50) + if (amidiasBlessing && (chaliceOfTheBloodGod ? chaliceBleedoutToApplyOnHurt : hurtInfo.Damage) > 50) { Player.ClearBuff(ModContent.BuffType()); SoundEngine.PlaySound(SoundID.Item96, Player.Center); From 896991796dd12154ad024f2712203cbf5ea728e6 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Mon, 27 Oct 2025 12:34:50 -0400 Subject: [PATCH 300/401] Updated Thank You Welcome Big E Welcome back Done and Tomat Angel is now Sunny Hello-goodbye Mihaii Farewell enamoured and Hugekraken --- .../Furniture/DevPaintings/ThankYouPainting.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs index 2c66964de0..8661d1824a 100644 --- a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs +++ b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs @@ -60,11 +60,11 @@ public override void ModifyTooltips(List tooltips) public static IList devList = new List() { "Altix", - "Angel", "apotofkoolaid", "AquaSG", "Atalya", "Ben-TK", + "Big E", "CDMusic", "Cei", "CongratsIsTrash", @@ -73,16 +73,15 @@ public override void ModifyTooltips(List tooltips) "CrabBar", "Dandy", "Dia", + "Done", "dozezoze", "Eddie Spaghetti", - "enamoured", "ENNWAY", "Flowaria", "Fluffy", "fryzahh", "HaguriHat", "Heart Plus Up!", - "Hugekraken", "LordMetarex", "Memes", "Mercutio 'Merkalto' Takle", @@ -99,7 +98,9 @@ public override void ModifyTooltips(List tooltips) "Shayy", "Spider Prov", "StipulateVenus", + "Sunny", "Tobias", + "Tomat", "Triangle", "TYESKI (Universe)", "Uncle Danny", @@ -126,7 +127,6 @@ public override void ModifyTooltips(List tooltips) "DarkTiny", "Demik", "DM Dokuro", - "Done", "Doog", "drh", "dwshin", @@ -134,6 +134,7 @@ public override void ModifyTooltips(List tooltips) "Earth", "EchoDuck", "Ein", + "enamoured", "Enreden", "Epsilon", "Fargowilta", @@ -144,6 +145,7 @@ public override void ModifyTooltips(List tooltips) "Graydee", "Grox the Great", "Hectique", + "Hugekraken", "Huggles", "Ian-1KV", "IbanPlay", @@ -160,6 +162,7 @@ public override void ModifyTooltips(List tooltips) "Lompl Allimath", "Lucille Karma", "MarieArk", + "Mihaii", "Minecat", "Mrrp", "Nao", @@ -197,7 +200,6 @@ public override void ModifyTooltips(List tooltips) "ThousandFields", "TikiWiki", "Tinymanx", - "Tomat", "Trivaxy", "Uberransy", "Vaikyia", From f19c45b13e3988ee4c40415151b44fd829eb3852 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Mon, 27 Oct 2025 12:51:06 -0400 Subject: [PATCH 301/401] Updated Brimstone Witch donor list --- CalamityLists.cs | 61 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/CalamityLists.cs b/CalamityLists.cs index ad14568132..65642825e7 100644 --- a/CalamityLists.cs +++ b/CalamityLists.cs @@ -159,32 +159,80 @@ public static void LoadLists() var newDonatorList = new List() { "Aerosyn", + "Aidan Spears", + "Amandalias", "Arcxus", + "Ariallis", + "Audrey Lynn Beemus", "awesomechapro", + "Azariah", "azazel", + "Ballin", + "Barrett Turner", "BlueRay_256", "botbot94", + "Bwlstorm", + "c0d3_404", + "Carduelis", + "Careless imp", "Chin", "Cinder", + "CrazyGamer69", + "Diamond Nife", + "DOGMA", + "DogVTF", "drake093104", + "Entrian", + "Equinoxux", + "Eternal Grayson", + "goo", "Grant Curtiss", + "haefer.goat.oats", + "Halleyvetica", + "Hamsting", + "help", + "Iptktp9", "Jace Ufret", "JFL", - "MizzUltraViolet", + "Kiddorox", + "Liam Rafle", + "Mint_loll", + "MizzUltraViolet DamienTK", "Nature", + "niceguysrage", "Nick H", "Nightinglade", + "Nothin Purrsonal", + "Nova Solarius", + "NyxxyNightstar", + "OakhamSam", + "Pantyslack", "Patch357", "Phil Broome", + "Qwertz", + "Reece", "roryoftheabyss", "Sable", "SakuraWinterz", "Salted Warlock", + "schmoovi", + "Sharktank6", "Shayy", // Current dev. Listed as "Shay" on Patreon. "SirChaos189", "SkeletonHunter96", + "Taelishe", "Taylor Olligoci", // also an ex-dev. Listed as "Lilac Olligoci" on Patreon. There were two "Taylor"s on the old list + "Tethox", + "The Deer Who Sold The World", + "The Wither", + "Tsukara", + "Vanillin", + "Vertigo", + "weisslerren", "Xtra Trinity 3678", + "Xtra", + "Xzier_Tengal", + "YashimaYamanata", "Zachtoplasm", "ZoeyPlague", }; @@ -199,7 +247,6 @@ public static void LoadLists() "Littlepiggy", "LompL", "Lilith", - "Ben Shapiro", "Frederik", "Faye", "Gibb50", @@ -306,16 +353,14 @@ public static void LoadLists() "cocodezi_", "Mendzey", "GameRDheAsianSandwich", - "Tobias", + "Chigbungus", "Streakist", "Eisaya", - "Xenocrona", "RKMoon", "Eternal Silence", "Jeff", "Beta165", "DanYami", - "Xenocrona", "Ari", "cosmickalamity", "xd Ow0", @@ -413,7 +458,7 @@ public static void LoadLists() "Spider region", "WinterTire", "Nycro", - "Bewearium", + "Vyster", "William", "HellGoat2", "116taj", @@ -423,7 +468,7 @@ public static void LoadLists() "Obsoleek", "Jetpat3", "GreenTea", - "Woah", + "Sevenfold", "Ryaegos", "Popsickle Yoshi", "Arcadia", @@ -647,7 +692,7 @@ public static void LoadLists() "Steven", "Hana", "Mikabul", - "Nathaniel", + "The Evolution", "Brutus", "EdelVollMilch", "garfu", From 7b672358f47e13356ecd3ed7ca8b7da00367680c Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Mon, 27 Oct 2025 13:04:10 -0400 Subject: [PATCH 302/401] Updated donor Town NPC names --- NPCs/CalamityGlobalTownNPC.cs | 66 ++++++++++++++++++++++++++++++++--- NPCs/TownNPCs/THIEF.cs | 2 ++ 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/NPCs/CalamityGlobalTownNPC.cs b/NPCs/CalamityGlobalTownNPC.cs index d6e06146e4..67729c3e54 100644 --- a/NPCs/CalamityGlobalTownNPC.cs +++ b/NPCs/CalamityGlobalTownNPC.cs @@ -70,7 +70,6 @@ public static float TaxYieldFactor }; private static readonly string[] ArmsDealerNames = { - "Drifter", "Finchi", "Heniek", // <@!363404700445442050> (kazurgundu) "Fire", // <@!354362326947856384> (ultimatefirewaster) @@ -85,6 +84,8 @@ public static float TaxYieldFactor { "Joeseph Jostar", "Storm Havik", // <@!1013452363178197072> (fishnotduck) + "Magorfis Splunt the Greater Finklejim", // <@!147490809334333440> (eidolbyssus) + "Perrin", // <@!253764551139393537> (easyperrin) }; private static readonly string[] CyborgNames = { @@ -95,7 +96,6 @@ public static float TaxYieldFactor { "Tavish DeGroot", // <@!442447226992721930> (magicoal) "Fimmy", // <@!407348617079160832> (darkmega5) - "Dorira", // <@!215269032360804352> (crimsoncb) "John Helldiver", // <@!614126424751603714> (exellent.) }; private static readonly string[] DryadNames = @@ -105,6 +105,7 @@ public static float TaxYieldFactor "Jasmine", // <@!430532867479699456> (phantasmagoria.) "Cybil", // <@!486507232666845185> (Captain Doofus#????) "Ruth", // <@!1001307586068492388> (briny_coffee) + "Kanna", // <@!730203712898859018> (cosmoredeathwish) }; private static readonly string[] DyeTraderNames = null; private static readonly string[] GoblinTinkererNames = @@ -121,6 +122,7 @@ public static float TaxYieldFactor "Neesh", // <@!175803493464932352> (xjetty) "Bars Boldia", // <@!332989575708540939> (careless_imp) "Basel Raiden John Clive Fantasy 16", // <@!529392083136413696> (raiden_ii) + "Gobby, Destroyer of Wallets", // <@!429024941296582658> (bwlstorm) }; private static readonly string[] GolferNames = null; private static readonly string[] GuideNames = @@ -142,6 +144,7 @@ public static float TaxYieldFactor "Mihai", // <@!373941893467209730> (cmihaii.) "Dinkleberg", // <@!581993958037520404> (hyperionzx) "Wamy", // Fab added this name with no Discord ID. May be a donor who has no Discord account. + "Baggute", // <@!535140564174110720> (thebaggutegamer) }; private static readonly string[] MechanicNames = { @@ -180,10 +183,12 @@ public static float TaxYieldFactor "Captain Billy Bones", // <@!699589229507772416> (djackv) "Captain J. Crackers", // <@!233232602994049024> (qyuuno) "Gol D. Roger", // <@!256228859110752257> (xtra3678) + "Yarrim", // <@!290061123137306624> (borb9834) + "Hector Barbossa", // <@!615704209303797790> (thatrockisfullamagic) + "Blunderbeard", // <@!1039460813490102293> (parmiigianoreggiano) }; private static readonly string[] PrincessNames = { - "Catalyst", // <@!156672312425316352> (xaqult) "Nyapano", // <@!120976656826368003> (nyapano) "Jade", // <@!187395834625785869> (verymasterninja) "Nyavi Aceso", // <@!270260920888852480> (navigator.) @@ -191,10 +196,12 @@ public static float TaxYieldFactor "Gwynevere", // <@!142752927348424704> (nuclearchaosazathoth) "Hael", // <@!641747280944431156> (kalebtull) "Yumesaki Mirrin", // <@!100235144744415232> (milinen) + "Vela", // <@!208719047146209281> (nyxxynightstar) }; private static readonly string[] SantaClausNames = { "Jank", // <@!339950757472239616> (jankle_) + "Aoi Kurashiki", // <@!358411687885537291> (nothinpurrsonal) }; private static readonly string[] SkeletonMerchantNames = { @@ -211,6 +218,8 @@ public static float TaxYieldFactor "Mòrag Ladair", // <@!161893929485074432> (jalapeno9) "Linn", // <@!277983612383526913> (duckycolors) "Eira", // <@!1166136068408623234> (taela_gemetha) + "Kreutz", // <@!553445849149997056> (red_r_kreutz) + "Cathlyn", // <@!156672312425316352> (xaqult) }; private static readonly string[] StylistNames = { @@ -219,6 +228,7 @@ public static float TaxYieldFactor "Xsiana", // <@!625780237489143839> (lokistic) "Lain", // <@!655201622863118337> (literallyadeerfr) "Hamis", // <@!608455754093035521> (haefer) + "Brio Scarlet", // <@!358576903701004289> (brio_scarlet) }; private static readonly string[] TavernkeepNames = { @@ -235,13 +245,15 @@ public static float TaxYieldFactor private static readonly string[] TravelingMerchantNames = { "Stan Pines", - "Slap Battles", // <@!923504188615450654> (gravityglider.) + "Intergaze", // <@!923504188615450654> (gravityglider.) "Borgus", // <@!539127427482255376> (therealmeepman) + "Postman Hiss", // <@!454638106122125312> (karinthefairy) }; private static readonly string[] TruffleNames = { "Aldrimil", // <@!413719640238194689> (Thorioum#2475) "Wonton", // <@!1198092982923043040> (imonthatgudkush) + "Mad Lad", // <@!215269032360804352> (crimsoncb) }; private static readonly string[] WitchDoctorNames = { @@ -260,6 +272,7 @@ public static float TaxYieldFactor "Chris Tallballs", // <@!770211589076418571> (vysterx) (previously: bewearium) "Syethas", // <@!325413275066171393> (cosmicstariight) "Nextdoor Psycho", // <@!173261518572486656> (nextdoorpsycho) + "Mike Cyclops", // <@!702327497475227741> (seichoseicho) }; private static readonly string[] ZoologistNames = { @@ -267,7 +280,22 @@ public static float TaxYieldFactor "Lacuna", // <@!790746689211203604> (_lacuna_) "Mae Borowski", //<@!219158690433990656> (justakkolite) "Fera", // <@!195850711567826945> (juneark_) + "Gwenhwyvar", // <@!291342874497515531> (diamondnife) + "Daxie", // <@!465438861103988737> (daxie626) }; + // Town Slimes + private static readonly string[] ClumsySlimeNames = null; + private static readonly string[] CoolSlimeNames = null; + private static readonly string[] DivaSlimeNames = null; + private static readonly string[] ElderSlimeNames = null; + private static readonly string[] MysticSlimeNames = null; + private static readonly string[] NerdySlimeNames = + { + "Big Blungus", // <@!272759434282008577> (schmoov) + "Rimuru Tempest", // <@!806463201398358036> (c0d3_404) + }; + private static readonly string[] SquireSlimeNames = null; + private static readonly string[] SurlySlimeNames = null; // The following sets are for the 1.4 Town Pets: Town Dogs, Cats and Bunnies. // All three pet types come in numerous breeds. Each breed has its own name pool. @@ -318,7 +346,6 @@ public static float TaxYieldFactor "Lucerne", // <@!271954788676141066> (lord_lucerne) "Milo", // <@!401849201597874179> (maskedmilo) "Octo", // <@!796112889353994281> (octolinggrimm) - "Chease", // <@!1039460813490102293> (parmiigianoreggiano) }; private static readonly string[] TownCatSiameseNames = null; private static readonly string[] TownCatBlackNames = @@ -330,6 +357,8 @@ public static float TaxYieldFactor { "Felix", // <@!183424826407518208> (lilac_vrt_olligoci) "Tardo", // <@!739343546867384391> (midnight295) + "Dali", // <@!460238880436781061> (darthlego) + "Kiba", // <@!852348657072340992> (jollydragonslayer) }; private static readonly string[] TownCatRussianBlueNames = null; private static readonly string[] TownCatSilverNames = @@ -347,6 +376,7 @@ public static float TaxYieldFactor private static readonly string[] TownBunnyNames = { "Poco", // <@!1192261996146593872> (tostitomuncher33) + "Puffer", // <@!181103507711983616> (piky) }; private static readonly string[] TownBunnyWhiteNames = null; private static readonly string[] TownBunnyAngoraNames = null; @@ -585,6 +615,32 @@ public override void ModifyNPCNameList(NPC npc, List nameList) AddNewNames(nameList, ZoologistNames); break; + // Town Slimes + case NPCID.TownSlimePurple: // Clumsy Slime + AddNewNames(nameList, ClumsySlimeNames); + break; + case NPCID.TownSlimeGreen: // Cool Slime + AddNewNames(nameList, CoolSlimeNames); + break; + case NPCID.TownSlimeRainbow: // Diva Slime + AddNewNames(nameList, DivaSlimeNames); + break; + case NPCID.TownSlimeOld: // Elder Slime + AddNewNames(nameList, ElderSlimeNames); + break; + case NPCID.TownSlimeYellow: // Mystic Slime + AddNewNames(nameList, MysticSlimeNames); + break; + case NPCID.TownSlimeBlue: // Nerdy Slime + AddNewNames(nameList, NerdySlimeNames); + break; + case NPCID.TownSlimeCopper: // Squire Slime + AddNewNames(nameList, SquireSlimeNames); + break; + case NPCID.TownSlimeRed: // Surly Slime + AddNewNames(nameList, SurlySlimeNames); + break; + // This function doesn't work with Town Pets currently case NPCID.TownCat: AddNewNames(nameList, TownCatNames); diff --git a/NPCs/TownNPCs/THIEF.cs b/NPCs/TownNPCs/THIEF.cs index 6e81ae6084..7d932e7dfd 100644 --- a/NPCs/TownNPCs/THIEF.cs +++ b/NPCs/TownNPCs/THIEF.cs @@ -113,6 +113,8 @@ public override bool CanTownNPCSpawn(int numTownNPCs) "Altarca", // <@!1140673052108128337> (altarca_27226_49175) "Jackie", // <@!353241811717718016> (jackalchan) "Ishmael", // <@!840416568000381046> (vanillaoyster) + "Ariallis", // <@!518231218806980609> (ariallis) + "Shade", // <@!613133259563466755> (shade__storm) // Original names this.GetLocalizedValue("Name.Laura"), From d4e913962057eb4cfe4aeeabccfa55ee413a3b06 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Mon, 27 Oct 2025 13:06:42 -0400 Subject: [PATCH 303/401] Apparently "Vorbis" is in the donor list twice --- CalamityLists.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/CalamityLists.cs b/CalamityLists.cs index 65642825e7..fb86cac484 100644 --- a/CalamityLists.cs +++ b/CalamityLists.cs @@ -707,7 +707,6 @@ public static void LoadLists() "Saladify", "26-4-1", "VeryMasterNinja", - "Vorbis", "Nyapano", "Shadoku", "allosar", From 3daaa41dfdb964f31144864a3e2b569b31632edf Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Mon, 27 Oct 2025 13:35:58 -0400 Subject: [PATCH 304/401] Oops it's Angel Wings --- Localization/en-US/Mods.CalamityMod.Configs.hjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/en-US/Mods.CalamityMod.Configs.hjson b/Localization/en-US/Mods.CalamityMod.Configs.hjson index f2c06a2a69..c934b26403 100644 --- a/Localization/en-US/Mods.CalamityMod.Configs.hjson +++ b/Localization/en-US/Mods.CalamityMod.Configs.hjson @@ -187,7 +187,7 @@ CalamityConfig: { } FlightBar: { - Label: "[i:CalamityMod/WingsofRebirth] Display Flight Bar" + Label: "[i:AngelWings] Display Flight Bar" Tooltip: ''' Enables the Flight Bar UI, which shows the player's remaining wing flight time. From dc911ca2222804d9eae6826225b5a544823e3cfe Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <142704082+CongratsIsTrash@users.noreply.github.com> Date: Mon, 27 Oct 2025 13:53:16 -0400 Subject: [PATCH 305/401] Fixed mistakes I made with donor names --- CalamityLists.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CalamityLists.cs b/CalamityLists.cs index fb86cac484..598bf077f4 100644 --- a/CalamityLists.cs +++ b/CalamityLists.cs @@ -174,7 +174,7 @@ public static void LoadLists() "Bwlstorm", "c0d3_404", "Carduelis", - "Careless imp", + "Careless_imp", "Chin", "Cinder", "CrazyGamer69", @@ -184,7 +184,7 @@ public static void LoadLists() "drake093104", "Entrian", "Equinoxux", - "Eternal Grayson", + "EternalGrayson", "goo", "Grant Curtiss", "haefer.goat.oats", @@ -206,7 +206,7 @@ public static void LoadLists() "Nova Solarius", "NyxxyNightstar", "OakhamSam", - "Pantyslack", + "PantySlack", "Patch357", "Phil Broome", "Qwertz", From 9f56a9bb7b1b03efa37c4032a19fbe5bdd6dc5c4 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Mon, 27 Oct 2025 15:25:31 -0400 Subject: [PATCH 306/401] Fixed stealth bar saying stealth increases crit --- Localization/en-US/Mods.CalamityMod.UI.hjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/en-US/Mods.CalamityMod.UI.hjson b/Localization/en-US/Mods.CalamityMod.UI.hjson index 47a076ebb1..f7906dbc01 100644 --- a/Localization/en-US/Mods.CalamityMod.UI.hjson +++ b/Localization/en-US/Mods.CalamityMod.UI.hjson @@ -14,7 +14,7 @@ StealthInfoText: Rogue stealth builds while not attacking and slower while moving Once you have built max stealth, you will be able to perform a Stealth Strike Rogue stealth only reduces when you attack, it does not reduce while moving - The higher your rogue stealth the higher your rogue damage and crit + The higher your rogue stealth the higher your rogue damage Having more stealth regeneration slightly decreases the damage bonus from stealth This is offset by you being able to use stealth strikes far more often ''' From 3fc0cb5bf80f7761c10904f490b87f47f52c1487 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Mon, 27 Oct 2025 21:40:12 -0400 Subject: [PATCH 307/401] Updated donor list - Reorganized the former donor list - Removed "Toasty" as per what happened to them - Fix: "Commander Frostbite" had been spelled with 3 m's --- CalamityLists.cs | 1247 ++++++++++++++++++++++++---------------------- 1 file changed, 643 insertions(+), 604 deletions(-) diff --git a/CalamityLists.cs b/CalamityLists.cs index 598bf077f4..d43f7225c3 100644 --- a/CalamityLists.cs +++ b/CalamityLists.cs @@ -159,704 +159,743 @@ public static void LoadLists() var newDonatorList = new List() { "Aerosyn", - "Aidan Spears", + "always-tired", "Amandalias", + "andrew rodriguez", + "Ant Slime", + "ArcTwik", "Arcxus", + "Arialen", "Ariallis", - "Audrey Lynn Beemus", "awesomechapro", + "Axy Usagi", "Azariah", "azazel", - "Ballin", - "Barrett Turner", + "Bepzi25", "BlueRay_256", + "Boomdiada", + "Borb9834", "botbot94", - "Bwlstorm", + "Brio_Scarlet", + "Brodiero-Solar", + "Bruggs", "c0d3_404", - "Carduelis", "Careless_imp", + "Catkey", + "Charge Maniac", "Chin", - "Cinder", + "Chloe", + "Chow Chow", + "Cosmore", "CrazyGamer69", + "Creeper Hunter 2K0", + "Darthlego", "Diamond Nife", - "DOGMA", + "djsnj20", "DogVTF", - "drake093104", + "Dragev", + "Easy Perrin", "Entrian", "Equinoxux", "EternalGrayson", - "goo", + "FishBread", "Grant Curtiss", - "haefer.goat.oats", "Halleyvetica", "Hamsting", - "help", + "helptree", + "Herr Feuer", "Iptktp9", - "Jace Ufret", + "Jalapeno9", + "Jankle", "JFL", + "Johnny", + "Juneark", + "J.U.N.E.S", + "Justin", + "Kaitlyn-Kerbulon", + "KapryÅny", + "Kat Manklow", + "Kelt", "Kiddorox", + "Kiwi_lol", + "Levi Sharpe", "Liam Rafle", + "Lightedflare", + "Lolmoeven", + "Luke Wakumoto", + "Lumenos", + "Magic Love", + "Magicoal", + "MalachiteWisp", + "MarioMan84", + "mARvOEoUS", + "MaxingOut", + "Medi", "Mint_loll", + "Misterbottle8", "MizzUltraViolet DamienTK", "Nature", "niceguysrage", - "Nick H", - "Nightinglade", - "Nothin Purrsonal", + "nill bye", "Nova Solarius", "NyxxyNightstar", "OakhamSam", "PantySlack", "Patch357", "Phil Broome", - "Qwertz", - "Reece", + "Pomelo", + "Pseulamitas", + "Red", + "Red X", + "Renavo", + "Roadie Roadster", + "Robert Yaron", "roryoftheabyss", + "Rowan Shane", "Sable", - "SakuraWinterz", "Salted Warlock", - "schmoovi", "Sharktank6", "Shayy", // Current dev. Listed as "Shay" on Patreon. + "shredalert", "SirChaos189", - "SkeletonHunter96", - "Taelishe", + "SomeRandomPerson", "Taylor Olligoci", // also an ex-dev. Listed as "Lilac Olligoci" on Patreon. There were two "Taylor"s on the old list "Tethox", + "thalass", + "thanat.oshi", "The Deer Who Sold The World", - "The Wither", + "The Roborex", + "Thessyll", + "Trinity Series", "Tsukara", + "Tweee", + "twist", + "Umbara", + "Unreal Parrot", + "V00194", "Vanillin", - "Vertigo", + "Voltron284", + "WatWouldJesusDo", "weisslerren", "Xtra Trinity 3678", - "Xtra", - "Xzier_Tengal", + "Yaggitarius", "YashimaYamanata", "Zachtoplasm", + "Zackstar02", "ZoeyPlague", }; var oldDonatorList = new List { - "Vorbis", - "SoloMael", - "Chaotic Reks", - "The Buildmonger", - "YuH", - "Littlepiggy", - "LompL", - "Lilith", - "Frederik", - "Faye", - "Gibb50", - "Braden", - "Hannes", - "profoundmango69", - "Jack", - "Hans Volter", - "Krankwagon", - "MishiroUsui", - "Arkhine", - "Lodude", - "DevAesthetic", - "Mister Winchester", - "Zacky", - "Veine", - "Javyz", - "Shifter", - "Crysthamyr", - "Elfinlocks", - "Ein", + "116taj", + "26-4-1", "2Larry2", - "Jenonen", - "Arti", - "Tervastator", - "Luis", + "3en", + "3x1t_5tyl3", + "adain", + "Adamko", + "Aden C.N.", + "Aero", + "Aero (Aero#4599)", + "Æthereal", + "Afzofa", + "Aidan", + "Aidan Spears", + "Akkolite", + "Albino gonkvader", + "Alec", + "Aleksanders", + "Aleksh", + "Alex", "Alexander", + "Alexis", + "Alex N", + "Alfragiste", + "Allegro", + "allosar", + "Ally2Cute", + "Altzeus", + "anglerraptor", + "Anish", + "A_Normal_Person", + "Anton", + "Antonie", + "anything5000", + "Apotheosis", + "apotofkoolaid", + "Arcadia", + "Arche", + "Archie", + "Ari", + "Ariscottle", + "Arkhine", + "Arthur", + "Arti", + "asdf935", + "Ash", + "Ashamper", + "Asheel", + "Ashton", + "Audrey Lynn Beemus", + "Avery", + "Azura", + "Azure", + "Azzilan", "BakaQing", - "Taylor", - "Xaphlactus", - "MajinBagel", + "Ballin", + "Barbara", + "Barrett Turner", + "Ben", "Bendy", - "Rando Calrissian", - "Tails the Fox 92", + "Beta165", + "bikmin", + "Bill", + "Billy", + "Blackbluue", + "Bladesaber", + "Blobby6799", + "BobIsNotMyRealName", + "Bossy Punch", + "Braden", + "BreachNClear747", "Bread", - "Minty Candy", - "Preston", - "MovingTarget_086", - "Shiro", + "Brendan", + "Brian", + "Briny_Coffee", + "Broken Faucet", + "Bruh.PNG", + "Brutus", + "Brutzli", + "BumbleDoge", + "Buppercups - Roblox", + "Bwlstorm", + "CaineSenpai", + "Calcium Comrade", + "callisto", + "Cameron", + "Carboniferous", + "Carduelis", + "CasualNoLifer", + "Cerberus", + "Chaos", + "ChaosChaos", + "ChAoS DiScOrD", + "Chaotic Reks", + "Chaozhi", + "Charles", + "Check pins", + "Cheddar", + "Chigbungus", "Chip", - "ShotgunAngel", - "Sandblast", - "ThomasThePencil", - "Aero (Aero#4599)", - "Shirosity", // used to be GlitchOut - "Daawnz", - "CrabBar", - "Yatagarasu", - "Jarod", - "Zombieh", - "MingWhy", - "Random Weeb", - "Afzofa", - "Eragon3942", - "TheBlackHand", - "william", - "Samuel", + "ChrigTopher", "Christopher", - "DemoN K!ng", - "Malik", - "Ryan Baker-Ortiz", - "Aleksanders", - "TheSilverGhost", - "Lucazii", - "Prism", - "BobIsNotMyRealName", - "Guwahavel", - "Azura", - "Joshua", - "Doveda", - "William", - "Arche", - "DevilSunrise", - "Chaos", - "Ryan", - "Fish Repairs", - "Melvin", - "Vroomy Has -3,000 IQ", - "The Goliath", - "DaPyRo", - "Takeru", + "Cinder", "Circuit-Jay", - "Commmander Frostbite", - "cytokat", - "Cameron", - "Orudeon", - "BumbleDoge", - "Naglfar", - "Helixas", - "Vetus", - "High Charity", - "Devonte", - "Cerberus", - "Brendan", - "Victor", - "KAT-G307", - "Tombarry Expresserino", - "Drip Veezy", - "Glaid", - "Apotheosis", - "Bladesaber", - "Devon", - "Ruthoranium", "cocodezi_", - "Mendzey", - "GameRDheAsianSandwich", - "Chigbungus", - "Streakist", - "Eisaya", - "RKMoon", - "Eternal Silence", - "Jeff", - "Beta165", - "DanYami", - "Ari", - "cosmickalamity", - "xd Ow0", - "Darren", - "Florian", + "Cody", + "Cole", + "Colin", + "Colin V", + "Commander Frostbite", + "Conner", + "Coolguystorm YT", + "Corn M. Cobb", + "cosmickalamity", + "CosmicStarIight", + "CrabBar", + "Creamy", + "CrimsonCrips", + "Crippling-Ambition", + "Cristian(Mihaii)", + "Crysthamyr", + "Culex", + "Curtis", + "cytokat", + "Daawnz", + "Dakota", + "Dakota C", + "DanYami", + "DaPyRo", + "darkhawke", + "Darkus", + "Darkweb", + "Darren", + "Dasdruid", + "dawnboi", "dawn thunder", - "asdf935", - "GentSkeleton", - "Fizzlpoprock", - "Pigeon", - "Aleksh", - "Just a random guy", + "Dayne", + "ddoogg88 tdog", + "Deallly", "Dee", - "Æthereal", - "Broken Faucet", - "Sarcosuchus", - "Marissa443", - "Warlok", - "JackShizz", - "NebulaMagePlays", - "Primpy", - "Thys", - "Min", - "Wodernet", - "Pedro", + "DeLordeyeee", + "DemoN K!ng", + "dennis", "Depressed Dad Gaming", - "Snowy", - "Stormone", - "Mobian", - "Rinja", - "Check pins", - "Dakota", - "Neoplasmatic", - "False", - "Whitegiraffe", + "Derdjin", + "DESPACITO", + "Destiny Stallcup", + "Destructoid", + "DevAesthetic", + "DevilSunrise", + "Devin", + "Devon", + "Devonte", + "dexxer65", + "Dionysos", + "discokittie", + "DjackV", + "DOGMA", + "Domrinth", + "Done", + "Doodled_lynx", + "Doug", + "Doveda", + "drake093104", "Drakkece", - "Levi", - "Izuna", - "djsnj20", - "pyobbo", - "Alec", - "The Illustrious Sqouinchuousor", - "Moist Lad", - "TwanTheGOAT", - "3x1t_5tyl3", - "Will", - "SpookyNinja", - "Boomdiada", - "Culex", - "Rossadon", - "Ben", - "hubert thieblot", - "NepNep", - "Nanaki", - "CrimsonCrips", - "Lagohz", - "Timon", + "drenmus!", + "Drip Veezy", + "Driser", + "Dr. Pawsworth", + "Duck Satan", + "Dull", + "dummyAzure", + "Dylan", + "Eddie Spaghetti", + "EdelVollMilch", + "edm vibes", + "Ein", + "Eisaya", + "Ekun", + "Elementari", + "Elfinlocks", + "Elijah", + "Empress Vega", + "Eragon3942", + "Eric", + "Eternal Silence", + "Ethan", + "ethan", + "everquartz", "F00d Demon", - "Olkothan", - "Vmar98", - "Dasdruid", - "Brutzli", - "Yhashtur", - "Zekai", - "Doug", - "Uberransy", - "KurlozClown", - "Nemesis 041", - "Asheel", - "Hayden", - "Lightedflare", - "Lady Shira", - "Devin", - "Qelrin", - "Thomas", - "Ne'er Dowell", - "Potion Man", - "martyrdomination", - "Destructoid", - "Coolguystorm YT", - "Wolfmaw", - "yiumik", - "Destiny Stallcup", - "GreenBerry", - "SolsticeUnlimitd", - "darkhawke", - "oracle", - "YumeiSenshi", - "Cameron", - "Toxin", + "Face", + "FaeLoPondering", + "False", + "Fartein", + "Faye", + "Feels Fishy", + "Ferret4T", + "Finnrua", + "fire", + "Fish Repairs", + "Fizzlpoprock", + "Florian", + "Forge", + "Freakish", + "Frederik", "Fweepachino", - "DESPACITO", - "Altzeus", - "Ryan", - "Spider region", - "WinterTire", - "Nycro", - "Vyster", - "William", - "HellGoat2", - "116taj", - "CaineSenpai", - "Suicide Dreams", - "Roxas", - "Obsoleek", - "Jetpat3", + "Gameology", + "GameRDheAsianSandwich", + "Gamma Freya", + "garfu", + "GentSkeleton", + "Georgios", + "Gibb50", + "GIGA MAN", + "Gilded Gryphon", + "Glaid", + "gluten tag", + "Goblin", + "goo", + "Goober", + "Goomfrontlut", + "GP", + "GreenBerry", "GreenTea", - "Sevenfold", - "Ryaegos", - "Popsickle Yoshi", - "Arcadia", - "JensB__", - "Nuclei", - "Picasso's Bean", - "Corn M. Cobb", - "kgh8090", - "Luke", - "Barbara", - "Alexis", - "Soko", - "Albino gonkvader", - "Monic", - "Slim", - "ChaosChaos", - "Deallly", - "Jeff", - "vcf55", - "Kazurgundu", - "Jheybyrd", - "Kipluck", - "SCONICBOOM", - "Mr.Matter", - "Billy", - "jjth0m3", + "GregTheSpinarak", + "Gretchen", + "Griffin", + "Grylken", "GTW High Cube", - "Sabrina", - "Potato - Stego", - "Perditio Astrum", - "MaxingOut", - "SharZz", - "Allegro", - "hoosfire", - "Lauren", - "Ultra Succ", - "Ethan", - "Pacnysam", - "dummyAzure", - "Jaykob", - "Goblin", - "NoOneElse", - "Nicholas", - "Toasty", - "oli saer", - "Blobby6799", - "Domrinth", - "zombieseatflesh7", - "Shiny", - "Whale", - "The Infinity", - "MrCreamen", - "TemperedAether", - "LucasTwocas", + "Guwahavel", + "Habb", + "haefer.goat.oats", + "Hana", + "Handburger", + "Hannes", + "Hans Volter", + "happy thoughts", + "Hargestar", + "Hayden", + "Helixas", + "HellGoat2", + "High Charity", + "Him", + "Himakaze", + "Hokojin", + "Homunculus Derelictus", + "hoosfire", + "hubert thieblot", + "Hunter", + "Iconic Parker Gaming", + "Iguy", + "Indeciiissive", + "IsaacInsomnia", + "Izuna", + "Jace Ufret", + "Jack", + "JackShizz", + "Jackson", + "Jakob", + "James", + "Jarod", + "Javyz", + "Jaydon", + "Jaykob", + "jc.", + "Jeff", + "Jenonen", + "JensB__", + "Jersey", + "jes", + "Jessire", + "Jetpat3", + "Jheybyrd", + "jjth0m3", + "Joe", + "Joep", + "Jordan", + "Jose", + "Joshua", + "julius", + "just akkolite", + "Just a random guy", "JustLonelyPi", - "Brian", - "Ashton", - "Rolandark", - "Ally2Cute", - "Dionysos", - "Plant Waifu", - "fire", - "Charles", "Kaden", - "Dr. Pawsworth", - "Jackson", - "Freakish", - "Ashamper", + "Kaimonick", + "Kaledoulas", + "KAT-G307", + "Katherine", + "Kazurgundu", + "KeL", + "Kevin", + "kgh8090", "Kinzoku", - "Elementari", - "The Wolf Commando", - "Jordan", - "Jessire", - "Ashton", - "callisto", - "velneu", + "Kipluck", + "Kiyotu", + "KJ", + "Konorango", + "Korb Orb", + "Krankwagon", + "KugelBlitz", + "KurlozClown", + "Lacuna", + "Lady Shira", + "Lagohz", + "Lance", + "Landon", + "Larry That Barry", + "Lauren", + "Leonidas", + "Levi", + "Lilith", + "Lime-Wars l 1", + "Littlepiggy", + "Lodude", + "LompL", + "Lord_Lucerne", + "Loser", + "Lucas", + "LucasHM", + "LucasTwocas", + "Lucazii", + "Luis", + "Luke", + "LumiEvi", + "LvL-94", + "M001NG", + "Madd Cat", + "MajinBagel", + "Malik", + "Marco", + "Marissa443", + "Mark", + "Marko", + "Mars", + "martyrdomination", + "Maskedmilo", "Mathuantie", - "Robert", "Matias", - "T E R M I N A T O R", - "apotofkoolaid", "Matthew", - "Terrarian Dragon", - "Pomelo", - "Thomas", - "Iconic Parker Gaming", - "Jaydon", - "Aidan", - "Avery", - "yayoi", - "Splotchycrib", - "GIGA MAN", - "Eric", + "Max Kim", + "Mayhem", + "MeanieG", + "Melvin", + "Mendzey", + "Meow", "Merubel", - "Smug", - "Lime-Wars l 1", - "WillyDilly", - "xAqult", - "Himakaze", - "Face", - "Carboniferous", - "James", - "Taitou1", - "Yumi", + "Met Vox", + "Mikabul", + "Min", + "MingWhy", + "Minty Candy", + "MishiroUsui", + "Misinput", + "MissMudflaps", + "Mister Winchester", + "MittoMan", + "MiyoshiEira", + "Mobian", + "Mohammad", + "Moist Lad", + "Monic", + "Monti", + "Moonicento", + "MovingTarget_086", + "Mr. Bones", + "MrCreamen", + "Mr.Matter", + "MrNobody", + "n0tacat", + "Naglfar", + "Nanaki", + "Natalie", + "Nathan", + "Navigator", + "Ne'er Dowell", "NEBULA", - "Blackbluue", - "Alex", - "Ruben", - "Rixu", - "Antonie", - "Zerimore", + "NebulaMagePlays", + "Nemesis 041", + "Neoplasmatic", + "NepNep", + "Nexus", + "Nicholas", + "Nick H", + "Nightinglade", + "Nightskyflyer", + "Nitronium Productions", + "Noah", + "NoOneElse", + "Nothin Purrsonal", + "Nuclear Chaos", + "Nuclei", + "Number1piratepan", + "NuT NiTe", + "NyanLegacy215", + "Nyapano", + "Nycro", "Oblivionisbruh", - "Loser", + "Obsoleek", + "Oceanman232", + "OctolingGrimm", + "oli saer", + "Olkothan", + "OnTheAirPogs", + "oracle", + "OriginForme487", + "OrrangProto", + "Orudeon", + "Pacnysam", + "Paltham", + "Patrera", "Patrick", - "Magic Love", - "gluten tag", - "RetroRed", - "Katherine", - "SoyScoutSmasher", - "Jersey", - "Reiter splash", - "Conner", - "Ekun", - "Driser", - "bikmin", - "MittoMan", - "Pyromaniac146", - "Eddie Spaghetti", - "Colin", - "ZyferDex_", - "LumiEvi", - "Anish", - "MissMudflaps", - "Valkyrie", - "anglerraptor", - "Scribbles", + "Pedro", + "Perditio Astrum", + "Picasso's Bean", + "Pigeon", + "Plant Waifu", "Pneuma", - "OrrangProto", - "Tomat (Stevie)", - "That Katsafaros", - "PsychoGrizzly", - "Dayne", - "Hargestar", - "The Pyro", - "Lucas", - "Superbeepig", - "Larry That Barry", - "Monti", - "StarryFox", - "Kevin", + "pomp neigh", + "Ponynator", "Poopifier Poopifly", - "Lacuna", - "Nathan", - "Handburger", - "XusTingo9", - "Underlost", - "julius", - "Mark", - "Habb", + "Popsickle Yoshi", + "porglesupreme", + "Potato - Stego", + "Potion Man", + "Preston", + "Primpy", + "Prism", + "Professor Pissington", + "ProfessorWinston", + "Proffesor prostate", + "profoundmango69", + "PsychoGrizzly", + "Pusheen_", + "pyobbo", + "Pyromaniac146", + "Qelrin", + "Qwertz", + "Rando Calrissian", + "Random Weeb", + "rawpie2", + "Real mystlc", "Reanamet", - "Empress Vega", - "Team", - "GP", - "Xsiana", - "NyanLegacy215", - "ethan", - "Trinity Series", - "M001NG", - "WrathOfOlympus", - "dennis", - "Darkweb", - "Chaozhi", - "Mars", - "Elijah", - "Tezguin", - "Shpee", - "Archie", - "Meow", - "CosmicStarIight", - "Alfragiste", - "Number1piratepan", - "Noah", - "Max Kim", - "Anton", - "edm vibes", - "Hunter", - "Doodled_lynx", - "3en", - "Kiyotu", - "Aero", - "Iguy", - "병현 송", - "Tyler", - "Leonidas", - "GregTheSpinarak", - "Cheddar", - "Alex N", - "Magicoal", + "Reece", + "Reiter splash", + "RetroRed", + "Rinja", + "Rixu", + "RKMoon", + "Robert", + "RockRecker39", + "Rolandark", + "Rooki", + "Rossadon", + "Rottingwood", + "Roxas", + "Ruben", + "RuskieThe3rd", + "Ruthoranium", + "Ryaegos", + "Ryan", + "Ryan Baker-Ortiz", + "Sabrina", + "Sadouken", + "Sailor Jolt", + "SakuraWinterz", + "Saladify", + "Samuel", + "Sanctuary", + "Sandblast", + "Sarcosuchus", + "Schlarfblrfsch", + "schmoovi", + "SCONICBOOM", + "Scribbles", + "Scrumlet", "Seanツ", - "Ariscottle", - "Kevin", - "OnTheAirPogs", - "Zerafir", - "Bill", - "Starmitzy", - "FaeLoPondering", - "Brian", - "Smart2004", + "Sevenfold", + "Shadoku", + "SharZz", + "Shaun", "sherk", - "Squishy", - "Ash", - "rawpie2", - "Hokojin", + "Shifter", + "Shiny", + "Shiro", + "Shirosity", // used to be GlitchOut + "ShotgunAngel", + "Shpee", + "Sigil", "sk", - "Done", - "MeanieG", - "Sanctuary", - "Landon", - "Moonicento", - "Hayden", + "_Skeggy_", + "SkeletonHunter96", + "Skeli_G", + "Slim", + "Smart2004", + "Smug", + "Snowy", + "Soko", + "Solaire", + "SoloMael", + "SolsticeUnlimitd", + "SomeRando", + "SoyScoutSmasher", + "Spider region", + "Spirit Shield", + "Splotchycrib", + "SpookyNinja", + "Squishy", + "srxe", + "Starmitzy", + "StarryFox", "Steven", - "Hana", - "Mikabul", - "The Evolution", - "Brutus", - "EdelVollMilch", - "garfu", - "NuT NiTe", - "adain", - "Dylan", - "Lucas", - "Arthur", + "Stormone", + "Streakist", + "Suicide Dreams", + "Superbeepig", "sweatingdishes", - "pomp neigh", - "Proffesor prostate", - "Saladify", - "26-4-1", - "VeryMasterNinja", - "Nyapano", - "Shadoku", - "allosar", - "jes", - "Paltham", - "Fartein", - "Derdjin", - "A_Normal_Person", - "Duck Satan", - "Jalapeno9", - "Grylken", - "Nexus", - "KJ", - "Goober", - "ChAoS DiScOrD", - "Mayhem", - "Zombified _G", - "Madd Cat", - "Natalie", - "Solaire", - "Dakota C", - "The Davester", - "Jose", - "Him", - "Umberto", - "Lance", - "Navigator", - "Ferret4T", - "Rooki", - "LvL-94", - "Feels Fishy", - "Korb Orb", - "Calcium Comrade", + "Taelishe", + "Tails the Fox 92", + "Taitou1", + "Takeru", "Talmadge", - "ddoogg88 tdog", - "CasualNoLifer", - "Bossy Punch", - "Creamy", - "Tyler", - "topnormal", - "Gilded Gryphon", - "Nightskyflyer", - "Schlarfblrfsch", - "MrNobody", - "Aden C.N.", - "zombie wolf", - "n0tacat", - "Marko", - "dexxer65", - "DeLordeyeee", - "Kaledoulas", - "Mohammad", - "Skeli_G", - "Sigil", - "Dull", - "DjackV", - "Misinput", - "Gameology", - "KugelBlitz", + "Taylor", + "Team", + "TemperedAether", + "T E R M I N A T O R", + "Terrarian Dragon", + "Tervastator", + "Tezguin", + "That Katsafaros", + "thebettercat", + "TheBlackHand", + "The Buildmonger", + "The Davester", + "The Evolution", + "The Goliath", "TheGreatSako", - "Joep", - "Rottingwood", - "anything5000", - "Gretchen", - "Spirit Shield", - "Briny_Coffee", - "_Skeggy_", - "just akkolite", - "J.U.N.E.S", - "Bruggs", - "Vimek Xol", - "Oceanman232", - "Sadouken", - "srxe", - "ProfessorWinston", - "OctolingGrimm", - "Cole", - "Markie", - "Met Vox", - "Tweee", - "Kaimonick", - "Chow Chow", - "drenmus!", - "Nitronium Productions", - "Goomfrontlut", - "Akkolite", - "Shaun", - "Bruh.PNG", - "James", - "Lord_Lucerne", - "Ulmod", - "Adamko", - "Gamma Freya", - "Finnrua", - "Maskedmilo", - "RockRecker39", - "Konorango", - "Indeciiissive", - "Curtis", - "Ponynator", - "Crippling-Ambition", - "TitaniumLlama", - "OriginForme487", - "FishBread", - "Real mystlc", - "Levi", - "jc.", - "Medi", - "Jakob", - "Borb9834", - "Georgios", - "KeL", - "Cody", - "Cristian(Mihaii)", - "Marco", - "RuskieThe3rd", - "BreachNClear747", - "happy thoughts", - "Azure", "theHoopty", - "porglesupreme", + "The Illustrious Sqouinchuousor", + "The Infinity", + "The Pyro", + "TheSilverGhost", + "The Wither", + "The Wolf Commando", + "Thomas", + "ThomasThePencil", + "Thys", + "Timon", + "TitaniumLlama", + "Tomat (Stevie)", + "Tombarry Expresserino", + "topnormal", + "Toxin", + "TwanTheGOAT", + "Tyler", + "Uberransy", + "Ulmod", + "Ultra Succ", + "Umberto", + "Underlost", + "Valkyrie", + "vcf55", + "Veine", + "velneu", + "Vertigo", + "VeryMasterNinja", + "Vetus", + "Victor", + "Vimek Xol", + "Vmar98", + "Vorbis", + "Vroomy Has -3,000 IQ", + "Vyster", + "Warlok", + "Whale", + "Whitegiraffe", + "Will", + "William", + "william", + "WillyDilly", + "WinterTire", + "Wodernet", + "Wolfmaw", + "WrathOfOlympus", + "Xaphlactus", + "xAqult", "XDkilljoy65XX", - "Mr. Bones", - "dawnboi", - "Joe", - "Sailor Jolt", - "SomeRando", - "Nuclear Chaos", - "Jankle", - "The Roborex", - "everquartz", - "discokittie", - "IsaacInsomnia", + "xd Ow0", "xElectrix_", - "Forge", - "MiyoshiEira", - "thebettercat", - "Darthlego", - "Azzilan", - "Griffin", - "LucasHM", - "ChrigTopher", - "Colin V", - "Scrumlet", - "Darkus", - "Homunculus Derelictus", - "Professor Pissington", - "Buppercups - Roblox", - "Pusheen_", - "Patrera" + "Xsiana", + "Xtra", + "XusTingo9", + "Xzier_Tengal", + "Yatagarasu", + "yayoi", + "Yhashtur", + "yiumik", + "YuH", + "YumeiSenshi", + "Yumi", + "Zacky", + "Zekai", + "Zerafir", + "Zerimore", + "Zombieh", + "zombieseatflesh7", + "zombie wolf", + "Zombified _G", + "ZyferDex_", + "병현 송" }; donatorList = [.. oldDonatorList, .. newDonatorList]; From 11369d5ddd2a9215b89cac7d7b2aece6a0a2e4d1 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Wed, 29 Oct 2025 10:04:17 -0400 Subject: [PATCH 308/401] Fixed Difficulty Indicator text going beyond the bounds of the box --- UI/ModeIndicator/ModeIndicatorUI.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UI/ModeIndicator/ModeIndicatorUI.cs b/UI/ModeIndicator/ModeIndicatorUI.cs index 6c09b3d4c1..4e18a81e85 100644 --- a/UI/ModeIndicator/ModeIndicatorUI.cs +++ b/UI/ModeIndicator/ModeIndicatorUI.cs @@ -184,8 +184,8 @@ public static void Draw(SpriteBatch spriteBatch) if (!Main.mouseItem.IsAir) textboxStart.X += 34; - if (textboxStart.X + boxSize.X + 4f > (float)Main.screenWidth) - textboxStart.X = Main.screenWidth - boxSize.X - 4f; + if (textboxStart.X + regexedBoxSize.X + 4f > (float)Main.screenWidth) + textboxStart.X = Main.screenWidth - regexedBoxSize.X - 4f; if (textboxStart.Y + regexedBoxSize.Y + 4f > (float)Main.screenHeight) textboxStart.Y = Main.screenHeight - regexedBoxSize.Y - 4f; From cfc9ddcd28313b5426d893a7d470082e12f407b8 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Thu, 30 Oct 2025 19:06:44 -0400 Subject: [PATCH 309/401] Version bump to 2.0.6.1 (sadly required) --- build.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.txt b/build.txt index 29c6d61b99..9d4e04367c 100644 --- a/build.txt +++ b/build.txt @@ -1,5 +1,5 @@ author = The Calamity Dev Team -version = 2.0.6 +version = 2.0.6.1 displayName = Calamity Mod modReferences = CalamityModMusic homepage = https://discord.gg/calamity From 95a21d01ed752d9f8851f60e1272e303a853c558 Mon Sep 17 00:00:00 2001 From: DimHaze <3815798709@qq.com> Date: Tue, 28 Oct 2025 02:28:25 +0800 Subject: [PATCH 310/401] fixed frame 1 was never shown in wings of rebirth's animation --- Items/Accessories/Wings/WingsofRebirth.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Items/Accessories/Wings/WingsofRebirth.cs b/Items/Accessories/Wings/WingsofRebirth.cs index cbce428ecc..977ab4458d 100644 --- a/Items/Accessories/Wings/WingsofRebirth.cs +++ b/Items/Accessories/Wings/WingsofRebirth.cs @@ -63,17 +63,17 @@ public override bool WingUpdate(Player player, bool inUse) { player.wingFrame = 7; } + // Animation + if (player.wingFrameCounter % frameRate == 0) + { + player.wingFrame++; + } // Reset frames if (player.wingFrame >= maxFrames) { player.wingFrameCounter = 0; player.wingFrame = 1; } - // Animation - if (player.wingFrameCounter % frameRate == 0) - { - player.wingFrame++; - } } else { From db16ba4bf69a76de003f6c69243ada5806f6e8ba Mon Sep 17 00:00:00 2001 From: DimHaze <3815798709@qq.com> Date: Wed, 29 Oct 2025 00:47:43 +0800 Subject: [PATCH 311/401] fixed the visuals of Auralis' aurora never worked --- CalPlayer/CalamityPlayerMiscEffects.cs | 27 +++++++++++----------- CalPlayer/DrawLayers/AuralisAuroraLayer.cs | 2 +- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index 28664a61c2..2f1135a1ff 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -1485,8 +1485,16 @@ private void MiscEffects() reaverRegenCooldown++; else reaverRegenCooldown = 0; - if (auralisAurora > 0) - auralisAurora--; + if (auralisAuroraCounter > 300) + { + auralisAuroraCounter++; + } + + if (auralisAuroraCounter > 1500) + { + auralisAuroraCounter = 0; + auralisAuroraCooldown = CalamityUtils.SecondsToFrames(30f); + } if (auralisAuroraCooldown > 0) auralisAuroraCooldown--; @@ -2454,25 +2462,18 @@ private void StandingStillEffects() int chargeDuration = CalamityUtils.SecondsToFrames(5f); int auroraDuration = CalamityUtils.SecondsToFrames(20f); - if (usingScope && auralisAuroraCounter < chargeDuration + auroraDuration) + if (usingScope && auralisAuroraCounter < chargeDuration && auralisAuroraCooldown == 0) auralisAuroraCounter++; - if (auralisAuroraCounter > chargeDuration + auroraDuration) - { - auralisAuroraCounter = 0; - auralisAuroraCooldown = CalamityUtils.SecondsToFrames(30f); - } if (auralisAuroraCounter > 0 && auralisAuroraCounter < chargeDuration && !usingScope) auralisAuroraCounter--; - - if (auralisAuroraCounter > chargeDuration && auralisAuroraCounter < chargeDuration + auroraDuration && !usingScope) - auralisAuroraCounter = 0; } else { auralisStealthCounter = 0f; - auralisAuroraCounter = 0; + if (auralisAuroraCounter > 0 && auralisAuroraCounter < 300) + auralisAuroraCounter--; } if (auralisAuroraCooldown > 0) { @@ -4010,7 +4011,7 @@ private void DefenseEffects() // Apply defense damage Player.statDefense -= currentDefenseDamage; - + } // Defense can never be reduced below zero, no matter what diff --git a/CalPlayer/DrawLayers/AuralisAuroraLayer.cs b/CalPlayer/DrawLayers/AuralisAuroraLayer.cs index a6f4a4ba87..5c6629042b 100644 --- a/CalPlayer/DrawLayers/AuralisAuroraLayer.cs +++ b/CalPlayer/DrawLayers/AuralisAuroraLayer.cs @@ -17,7 +17,7 @@ public override bool GetDefaultVisibility(PlayerDrawSet drawInfo) return false; Player drawPlayer = drawInfo.drawPlayer; - return !(drawPlayer.Calamity().auralisAuroraCooldown < 300 || drawPlayer.Calamity().auralisAuroraCooldown > 0); + return !(drawPlayer.Calamity().auralisAuroraCounter < 300 || drawPlayer.Calamity().auralisAuroraCounter > 1500); } protected override void Draw(ref PlayerDrawSet drawInfo) From da19025a1bb286341d389d0745169bf36ca94e8a Mon Sep 17 00:00:00 2001 From: DimHaze <3815798709@qq.com> Date: Fri, 31 Oct 2025 00:42:56 +0800 Subject: [PATCH 312/401] fixed world ore type-based systems never worked --- Systems/WorldgenManagementSystem.cs | 8 ++++---- World/Planets/MudPlanet.cs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Systems/WorldgenManagementSystem.cs b/Systems/WorldgenManagementSystem.cs index 2886021901..7c6161d39a 100644 --- a/Systems/WorldgenManagementSystem.cs +++ b/Systems/WorldgenManagementSystem.cs @@ -548,10 +548,10 @@ public override void PostWorldGen() } // Save the set of ores that got generated - OreTypes[0] = (ushort)GenVars.copperBar; - OreTypes[1] = (ushort)GenVars.ironBar; - OreTypes[2] = (ushort)GenVars.silverBar; - OreTypes[3] = (ushort)GenVars.goldBar; + OreTypes[0] = (ushort)GenVars.copper; + OreTypes[1] = (ushort)GenVars.iron; + OreTypes[2] = (ushort)GenVars.silver; + OreTypes[3] = (ushort)GenVars.gold; } #endregion } diff --git a/World/Planets/MudPlanet.cs b/World/Planets/MudPlanet.cs index 97113e4681..8b7cfa9dee 100644 --- a/World/Planets/MudPlanet.cs +++ b/World/Planets/MudPlanet.cs @@ -212,8 +212,8 @@ public void PlacePlanet(Point origin, int radius) private int[] BarLoot = new int[] { - GenVars.copperBar == TileID.Copper ? ItemID.CopperBar : ItemID.TinBar, - GenVars.ironBar == TileID.Iron ? ItemID.IronBar : ItemID.LeadBar + GenVars.copper == TileID.Copper ? ItemID.CopperBar : ItemID.TinBar, + GenVars.iron == TileID.Iron ? ItemID.IronBar : ItemID.LeadBar }; private void FillChest(int id) From 61d1ca439c5284b5b2e05767b9033f468c4864b8 Mon Sep 17 00:00:00 2001 From: DimHaze <3815798709@qq.com> Date: Sat, 1 Nov 2025 11:21:53 +0800 Subject: [PATCH 313/401] fixed reflect dodges using a wrong incoming damage --- CalPlayer/CalamityPlayerHitHurt.cs | 32 ++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/CalPlayer/CalamityPlayerHitHurt.cs b/CalPlayer/CalamityPlayerHitHurt.cs index da7ff3fcc1..7a95048664 100644 --- a/CalPlayer/CalamityPlayerHitHurt.cs +++ b/CalPlayer/CalamityPlayerHitHurt.cs @@ -45,6 +45,7 @@ using Terraria.DataStructures; using Terraria.GameContent.Events; using Terraria.Graphics.Shaders; +using Terraria.GameContent.Creative; using Terraria.ID; using Terraria.Localization; using Terraria.ModLoader; @@ -932,8 +933,29 @@ public override void ModifyHitByProjectile(Projectile proj, ref Player.HurtModif double dodgeDamageGateValuePercent = 0.05; int dodgeDamageGateValue = (int)Math.Round(Player.statLifeMax2 * dodgeDamageGateValuePercent); + // This hook is applied before tML applies the vanilla difficulty multipliers. This means the "proj.damage" value here + // is usually significantly lower than the damage the projectile "actually" deals. + // To obtain the correct damage value for a cancelled hit, the corresponding multipliers are copied from tML + // to simulate the "actual" damage of the projectile. + // Note: Banner buffs, cold resistance, and modded modifiers are not included in this "actual" damage calculation, + // even though in real tML hooks they might be applied earlier than or together with difficulty multipliers. + int actualProjDamage = proj.damage; + if (!proj.reflected && !ProjectileID.Sets.PlayerHurtDamageIgnoresDifficultyScaling[proj.type]) + { + float damageMult = Main.GameModeInfo.EnemyDamageMultiplier; + if (Main.GameModeInfo.IsJourneyMode) + { + var power = CreativePowerManager.Instance.GetPower(); + if (power.GetIsUnlocked()) + damageMult = power.StrengthMultiplierToGiveNPCs; + } + + // in real tML, the factor 2 is applied in Projectile.Damage() + actualProjDamage = (int)Math.Floor(2 * damageMult * (float)actualProjDamage); + } + // Reflects count as dodges. They share the timer and can be disabled by Armageddon right click. - if (!disableAllDodges && !Player.HasCooldown(GlobalDodge.ID) && proj.damage >= dodgeDamageGateValue) + if (!disableAllDodges && !Player.HasCooldown(GlobalDodge.ID) && actualProjDamage >= dodgeDamageGateValue) { double maxCooldownDurationDamagePercent = 0.5; int maxCooldownDurationDamageValue = (int)Math.Round(Player.statLifeMax2 * (maxCooldownDurationDamagePercent - dodgeDamageGateValuePercent)); @@ -942,13 +964,14 @@ public override void ModifyHitByProjectile(Projectile proj, ref Player.HurtModif if (maxCooldownDurationDamageValue <= 0) maxCooldownDurationDamageValue = 1; - float cooldownDurationScalar = MathHelper.Clamp((proj.damage - dodgeDamageGateValue) / (float)maxCooldownDurationDamageValue, 0f, 1f); + float cooldownDurationScalar = MathHelper.Clamp((actualProjDamage - dodgeDamageGateValue) / (float)maxCooldownDurationDamageValue, 0f, 1f); // The Evolution if (evolution) { proj.hostile = false; proj.friendly = true; + proj.damage = 10 * actualProjDamage; proj.velocity *= -2f; proj.extraUpdates += 1; proj.penetrate = 1; @@ -1471,7 +1494,7 @@ public override void OnHitByProjectile(Projectile proj, Player.HurtInfo hurtInfo int dodgeDamageGateValue = (int)Math.Round(Player.statLifeMax2 * dodgeDamageGateValuePercent); // Reflects count as dodges. They share the timer and can be disabled by global dodge disabling effects. - if (!disableAllDodges && !Player.HasCooldown(GlobalDodge.ID) && proj.damage >= dodgeDamageGateValue) + if (!disableAllDodges && !Player.HasCooldown(GlobalDodge.ID) && hurtInfo.SourceDamage >= dodgeDamageGateValue) { double maxCooldownDurationDamagePercent = 0.5; int maxCooldownDurationDamageValue = (int)Math.Round(Player.statLifeMax2 * (maxCooldownDurationDamagePercent - dodgeDamageGateValuePercent)); @@ -1480,12 +1503,13 @@ public override void OnHitByProjectile(Projectile proj, Player.HurtInfo hurtInfo if (maxCooldownDurationDamageValue <= 0) maxCooldownDurationDamageValue = 1; - float cooldownDurationScalar = MathHelper.Clamp((proj.damage - dodgeDamageGateValue) / (float)maxCooldownDurationDamageValue, 0f, 1f); + float cooldownDurationScalar = MathHelper.Clamp((hurtInfo.SourceDamage - dodgeDamageGateValue) / (float)maxCooldownDurationDamageValue, 0f, 1f); if (daedalusReflect && !evolution) { proj.hostile = false; proj.friendly = true; + proj.damage = hurtInfo.SourceDamage; proj.velocity *= -1f; proj.penetrate = 1; From d3b11c5c258fd6b03f385103e54b2908c219e17e Mon Sep 17 00:00:00 2001 From: DimHaze <3815798709@qq.com> Date: Sat, 1 Nov 2025 11:59:46 +0800 Subject: [PATCH 314/401] Fixed enjoying rage benefits from Gael's greatsword without holding it --- CalPlayer/CalamityPlayerMiscEffects.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index 2f1135a1ff..e6a9fef611 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -186,12 +186,13 @@ public override void PostUpdateMiscEffects() Player.GetCritChance() = -spiritOriginConvertedCrit; } - if (Player.ActiveItem().type == ModContent.ItemType()) - heldGaelsLastFrame = true; - if (Player.ActiveItem().type != ModContent.ItemType()) saharaSlicersBolts = 0; + + if (Player.ActiveItem().type == ModContent.ItemType()) + heldGaelsLastFrame = true; + // De-equipping Gael's Greatsword deletes all rage. else if (heldGaelsLastFrame) { From 6721d444292a8437db15fab810397e2cc192d2d1 Mon Sep 17 00:00:00 2001 From: Flowaria Date: Sat, 1 Nov 2025 18:31:18 +0900 Subject: [PATCH 315/401] SpawnBlocker effect now sync properly --- CalPlayer/CalamityPlayer.cs | 8 +++++- Items/AntiCystOintment.cs | 48 ++++++++++++++++++++++----------- Items/AntiTumorOintment.cs | 49 +++++++++++++++++++++++----------- Items/BleachBall.cs | 44 +++++++++++++++++++++--------- Items/BrokenWaterFilter.cs | 48 ++++++++++++++++++++++----------- Items/SirenproofEarMuffs.cs | 45 +++++++++++++++++++++---------- Items/VoodooDemonVoodooDoll.cs | 49 +++++++++++++++++++++++----------- 7 files changed, 203 insertions(+), 88 deletions(-) diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 69fffba179..e20562d3e8 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -55,7 +55,6 @@ using Terraria.ID; using Terraria.ModLoader; using Terraria.ModLoader.IO; -using Terraria.Utilities.Terraria.Utilities; namespace CalamityMod.CalPlayer { @@ -2210,6 +2209,13 @@ public override void ResetEffects() infiniteFlight = false; + noStupidNaturalARSpawns = false; + disableAnahitaSpawns = false; + disableHiveCystSpawns = false; + disableNaturalScourgeSpawns = false; + disablePerfCystSpawns = false; + disableVoodooSpawns = false; + EnchantHeldItemEffects(Player, Player.Calamity(), Player.ActiveItem()); } #endregion diff --git a/Items/AntiCystOintment.cs b/Items/AntiCystOintment.cs index c109169272..9b5ba62151 100644 --- a/Items/AntiCystOintment.cs +++ b/Items/AntiCystOintment.cs @@ -1,16 +1,15 @@ -using Terraria; +using System.Collections.Generic; +using System.IO; +using Terraria; using Terraria.ID; using Terraria.ModLoader; -using System.Collections.Generic; -using Microsoft.Xna.Framework.Graphics; -using Microsoft.Xna.Framework; +using Terraria.ModLoader.IO; using static CalamityMod.CalamityUtils; namespace CalamityMod.Items { public class AntiCystOintment : ModItem, ILocalizedModType { - public static bool state = false; public new string LocalizationCategory => "Items.Misc"; public override void SetDefaults() { @@ -25,21 +24,40 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite itemGroup = (ContentSamples.CreativeHelper.ItemGroup)CalamityResearchSorting.SpawnPrevention; } + #region Toggle Feature + + public bool Enabled = true; + + public override ModItem Clone(Item item) + { + var clone = (AntiCystOintment)base.Clone(item); + clone.Enabled = Enabled; + return clone; + } + + public override void SaveData(TagCompound tag) => tag.Add("blockerEnabled", Enabled); + + public override void LoadData(TagCompound tag) => Enabled = tag.GetBool("blockerEnabled"); + + public override void NetSend(BinaryWriter writer) => writer.Write(Enabled); + + public override void NetReceive(BinaryReader reader) => Enabled = reader.ReadBoolean(); + public override bool CanRightClick() => true; + public override bool ConsumeItem(Player player) => false; + public override void RightClick(Player player) { - if (player.Calamity().disablePerfCystSpawns == true) - player.Calamity().disablePerfCystSpawns = false; - else - player.Calamity().disablePerfCystSpawns = true; + Enabled = !Enabled; Item.NetStateChanged(); - state = player.Calamity().disablePerfCystSpawns; + } + + #endregion - bool favorited = Item.favorited; - Item.SetDefaults(ModContent.ItemType()); - Item.stack++; - Item.favorited = favorited; + public override void UpdateInventory(Player player) + { + player.Calamity().disablePerfCystSpawns |= Enabled; } /* @@ -84,7 +102,7 @@ public override bool PreDrawInWorld(SpriteBatch spriteBatch, Color lightColor, C public override void ModifyTooltips(List tooltips) { string text; - if (state == true) + if (Enabled) text = GetTextValue("Items.Misc.SpawnBlockersOn"); else text = GetTextValue("Items.Misc.SpawnBlockersOff"); diff --git a/Items/AntiTumorOintment.cs b/Items/AntiTumorOintment.cs index 1ee5b62e48..5166880a05 100644 --- a/Items/AntiTumorOintment.cs +++ b/Items/AntiTumorOintment.cs @@ -1,16 +1,15 @@ -using Terraria; +using System.Collections.Generic; +using System.IO; +using Terraria; using Terraria.ID; using Terraria.ModLoader; -using Microsoft.Xna.Framework.Graphics; -using Microsoft.Xna.Framework; -using System.Collections.Generic; +using Terraria.ModLoader.IO; using static CalamityMod.CalamityUtils; namespace CalamityMod.Items { public class AntiTumorOintment : ModItem, ILocalizedModType { - public static bool state = false; public new string LocalizationCategory => "Items.Misc"; public override void SetDefaults() { @@ -25,22 +24,42 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite itemGroup = (ContentSamples.CreativeHelper.ItemGroup)CalamityResearchSorting.SpawnPrevention; } + #region Toggle Feature + + public bool Enabled = true; + + public override ModItem Clone(Item item) + { + var clone = (AntiTumorOintment)base.Clone(item); + clone.Enabled = Enabled; + return clone; + } + + public override void SaveData(TagCompound tag) => tag.Add("blockerEnabled", Enabled); + + public override void LoadData(TagCompound tag) => Enabled = tag.GetBool("blockerEnabled"); + + public override void NetSend(BinaryWriter writer) => writer.Write(Enabled); + + public override void NetReceive(BinaryReader reader) => Enabled = reader.ReadBoolean(); + public override bool CanRightClick() => true; + public override bool ConsumeItem(Player player) => false; + public override void RightClick(Player player) { - if (player.Calamity().disableHiveCystSpawns == true) - player.Calamity().disableHiveCystSpawns = false; - else - player.Calamity().disableHiveCystSpawns = true; + Enabled = !Enabled; Item.NetStateChanged(); - state = player.Calamity().disableHiveCystSpawns; + } - bool favorited = Item.favorited; - Item.SetDefaults(ModContent.ItemType()); - Item.stack++; - Item.favorited = favorited; + #endregion + + public override void UpdateInventory(Player player) + { + player.Calamity().disableHiveCystSpawns |= Enabled; } + /* public override bool PreDrawInInventory(SpriteBatch spriteBatch, Vector2 position, Rectangle frameI, Color drawColor, Color itemColor, Vector2 origin, float scale) { @@ -83,7 +102,7 @@ public override bool PreDrawInWorld(SpriteBatch spriteBatch, Color lightColor, C public override void ModifyTooltips(List tooltips) { string text; - if (state == true) + if (Enabled) text = GetTextValue("Items.Misc.SpawnBlockersOn"); else text = GetTextValue("Items.Misc.SpawnBlockersOff"); diff --git a/Items/BleachBall.cs b/Items/BleachBall.cs index 72c06d37a5..155b348a11 100644 --- a/Items/BleachBall.cs +++ b/Items/BleachBall.cs @@ -1,17 +1,16 @@ using System.Collections.Generic; +using System.IO; using CalamityMod.Items.Materials; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; using Terraria; using Terraria.ID; using Terraria.ModLoader; +using Terraria.ModLoader.IO; using static CalamityMod.CalamityUtils; namespace CalamityMod.Items { public class BleachBall : ModItem, ILocalizedModType { - public static bool state = false; public new string LocalizationCategory => "Items.Misc"; public override void SetDefaults() { @@ -26,21 +25,40 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite itemGroup = (ContentSamples.CreativeHelper.ItemGroup)CalamityResearchSorting.SpawnPrevention; } + #region Toggle Feature + + public bool Enabled = true; + + public override ModItem Clone(Item item) + { + var clone = (BleachBall)base.Clone(item); + clone.Enabled = Enabled; + return clone; + } + + public override void SaveData(TagCompound tag) => tag.Add("blockerEnabled", Enabled); + + public override void LoadData(TagCompound tag) => Enabled = tag.GetBool("blockerEnabled"); + + public override void NetSend(BinaryWriter writer) => writer.Write(Enabled); + + public override void NetReceive(BinaryReader reader) => Enabled = reader.ReadBoolean(); + public override bool CanRightClick() => true; + public override bool ConsumeItem(Player player) => false; + public override void RightClick(Player player) { - if (player.Calamity().disableNaturalScourgeSpawns == true) - player.Calamity().disableNaturalScourgeSpawns = false; - else - player.Calamity().disableNaturalScourgeSpawns = true; + Enabled = !Enabled; Item.NetStateChanged(); - state = player.Calamity().disableNaturalScourgeSpawns; + } + + #endregion - bool favorited = Item.favorited; - Item.SetDefaults(ModContent.ItemType()); - Item.stack++; - Item.favorited = favorited; + public override void UpdateInventory(Player player) + { + player.Calamity().disableNaturalScourgeSpawns |= Enabled; } /* @@ -85,7 +103,7 @@ public override bool PreDrawInWorld(SpriteBatch spriteBatch, Color lightColor, C public override void ModifyTooltips(List tooltips) { string text; - if (state == true) + if (Enabled) text = GetTextValue("Items.Misc.SpawnBlockersOn"); else text = GetTextValue("Items.Misc.SpawnBlockersOff"); diff --git a/Items/BrokenWaterFilter.cs b/Items/BrokenWaterFilter.cs index c4fe0204bc..8115636027 100644 --- a/Items/BrokenWaterFilter.cs +++ b/Items/BrokenWaterFilter.cs @@ -1,17 +1,16 @@ -using CalamityMod.Items.Materials; +using System.Collections.Generic; +using System.IO; +using CalamityMod.Items.Materials; using Terraria; using Terraria.ID; using Terraria.ModLoader; -using Microsoft.Xna.Framework.Graphics; -using Microsoft.Xna.Framework; -using System.Collections.Generic; +using Terraria.ModLoader.IO; using static CalamityMod.CalamityUtils; namespace CalamityMod.Items { public class BrokenWaterFilter : ModItem, ILocalizedModType { - public static bool state = false; public new string LocalizationCategory => "Items.Misc"; public override void SetDefaults() { @@ -26,21 +25,40 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite itemGroup = (ContentSamples.CreativeHelper.ItemGroup)CalamityResearchSorting.SpawnPrevention; } + #region Toggle Feature + + public bool Enabled = true; + + public override ModItem Clone(Item item) + { + var clone = (BrokenWaterFilter)base.Clone(item); + clone.Enabled = Enabled; + return clone; + } + + public override void SaveData(TagCompound tag) => tag.Add("blockerEnabled", Enabled); + + public override void LoadData(TagCompound tag) => Enabled = tag.GetBool("blockerEnabled"); + + public override void NetSend(BinaryWriter writer) => writer.Write(Enabled); + + public override void NetReceive(BinaryReader reader) => Enabled = reader.ReadBoolean(); + public override bool CanRightClick() => true; + public override bool ConsumeItem(Player player) => false; + public override void RightClick(Player player) { - if (player.Calamity().noStupidNaturalARSpawns == true) - player.Calamity().noStupidNaturalARSpawns = false; - else - player.Calamity().noStupidNaturalARSpawns = true; + Enabled = !Enabled; Item.NetStateChanged(); - state = player.Calamity().noStupidNaturalARSpawns; + } + + #endregion - bool favorited = Item.favorited; - Item.SetDefaults(ModContent.ItemType()); - Item.stack++; - Item.favorited = favorited; + public override void UpdateInventory(Player player) + { + player.Calamity().noStupidNaturalARSpawns |= Enabled; } /* @@ -85,7 +103,7 @@ public override bool PreDrawInWorld(SpriteBatch spriteBatch, Color lightColor, C public override void ModifyTooltips(List tooltips) { string text; - if (state == true) + if (Enabled) text = GetTextValue("Items.Misc.SpawnBlockersOn"); else text = GetTextValue("Items.Misc.SpawnBlockersOff"); diff --git a/Items/SirenproofEarMuffs.cs b/Items/SirenproofEarMuffs.cs index b05a825f31..6763eb7aff 100644 --- a/Items/SirenproofEarMuffs.cs +++ b/Items/SirenproofEarMuffs.cs @@ -1,17 +1,15 @@ using System.Collections.Generic; -using CalamityMod.Items.Materials; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; +using System.IO; using Terraria; using Terraria.ID; using Terraria.ModLoader; +using Terraria.ModLoader.IO; using static CalamityMod.CalamityUtils; namespace CalamityMod.Items { public class SirenproofEarMuffs : ModItem, ILocalizedModType { - public static bool state = false; public new string LocalizationCategory => "Items.Misc"; public override void SetDefaults() { @@ -26,21 +24,40 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite itemGroup = (ContentSamples.CreativeHelper.ItemGroup)CalamityResearchSorting.SpawnPrevention; } + #region Toggle Feature + + public bool Enabled = true; + + public override ModItem Clone(Item item) + { + var clone = (SirenproofEarMuffs)base.Clone(item); + clone.Enabled = Enabled; + return clone; + } + + public override void SaveData(TagCompound tag) => tag.Add("blockerEnabled", Enabled); + + public override void LoadData(TagCompound tag) => Enabled = tag.GetBool("blockerEnabled"); + + public override void NetSend(BinaryWriter writer) => writer.Write(Enabled); + + public override void NetReceive(BinaryReader reader) => Enabled = reader.ReadBoolean(); + public override bool CanRightClick() => true; + public override bool ConsumeItem(Player player) => false; + public override void RightClick(Player player) { - if (player.Calamity().disableAnahitaSpawns == true) - player.Calamity().disableAnahitaSpawns = false; - else - player.Calamity().disableAnahitaSpawns = true; + Enabled = !Enabled; Item.NetStateChanged(); - state = player.Calamity().disableAnahitaSpawns; + } + + #endregion - bool favorited = Item.favorited; - Item.SetDefaults(ModContent.ItemType()); - Item.stack++; - Item.favorited = favorited; + public override void UpdateInventory(Player player) + { + player.Calamity().disableAnahitaSpawns |= Enabled; } /* @@ -85,7 +102,7 @@ public override bool PreDrawInWorld(SpriteBatch spriteBatch, Color lightColor, C public override void ModifyTooltips(List tooltips) { string text; - if (state == true) + if (Enabled) text = GetTextValue("Items.Misc.SpawnBlockersOn"); else text = GetTextValue("Items.Misc.SpawnBlockersOff"); diff --git a/Items/VoodooDemonVoodooDoll.cs b/Items/VoodooDemonVoodooDoll.cs index c098d72199..236dd89600 100644 --- a/Items/VoodooDemonVoodooDoll.cs +++ b/Items/VoodooDemonVoodooDoll.cs @@ -1,16 +1,15 @@ -using Terraria; +using System.Collections.Generic; +using System.IO; +using Terraria; using Terraria.ID; using Terraria.ModLoader; -using System.Collections.Generic; -using Microsoft.Xna.Framework.Graphics; -using Microsoft.Xna.Framework; +using Terraria.ModLoader.IO; using static CalamityMod.CalamityUtils; namespace CalamityMod.Items { public class VoodooDemonVoodooDoll : ModItem, ILocalizedModType { - public static bool state = false; public new string LocalizationCategory => "Items.Misc"; public override void SetDefaults() @@ -27,20 +26,40 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite itemGroup = (ContentSamples.CreativeHelper.ItemGroup)CalamityResearchSorting.SpawnPrevention; } + #region Toggle Feature + + public bool Enabled = true; + + public override ModItem Clone(Item item) + { + var clone = (VoodooDemonVoodooDoll)base.Clone(item); + clone.Enabled = Enabled; + return clone; + } + + public override void SaveData(TagCompound tag) => tag.Add("blockerEnabled", Enabled); + + public override void LoadData(TagCompound tag) => Enabled = tag.GetBool("blockerEnabled"); + + public override void NetSend(BinaryWriter writer) => writer.Write(Enabled); + + public override void NetReceive(BinaryReader reader) => Enabled = reader.ReadBoolean(); + public override bool CanRightClick() => true; + public override bool ConsumeItem(Player player) => false; + public override void RightClick(Player player) { - if (player.Calamity().disableVoodooSpawns == true) - player.Calamity().disableVoodooSpawns = false; - else - player.Calamity().disableVoodooSpawns = true; + Enabled = !Enabled; Item.NetStateChanged(); - state = player.Calamity().disableVoodooSpawns; - bool favorited = Item.favorited; - Item.SetDefaults(ModContent.ItemType()); - Item.stack++; - Item.favorited = favorited; + } + + #endregion + + public override void UpdateInventory(Player player) + { + player.Calamity().disableVoodooSpawns |= Enabled; } /* @@ -85,7 +104,7 @@ public override bool PreDrawInWorld(SpriteBatch spriteBatch, Color lightColor, C public override void ModifyTooltips(List tooltips) { string text; - if (state == true) + if (Enabled) text = GetTextValue("Items.Misc.SpawnBlockersOn"); else text = GetTextValue("Items.Misc.SpawnBlockersOff"); From 8f8afa5ad83303340b136db6c0039ed8f746a7d2 Mon Sep 17 00:00:00 2001 From: Flowaria Date: Sat, 1 Nov 2025 18:31:56 +0900 Subject: [PATCH 316/401] Using Straightforward tooltip for SpawnBlockers --- Localization/en-US/Mods.CalamityMod.Items.Misc.hjson | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Misc.hjson b/Localization/en-US/Mods.CalamityMod.Items.Misc.hjson index 35996f701a..3520358d3c 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Misc.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Misc.hjson @@ -196,8 +196,8 @@ StarlightFuelCell: { } // Spawn Blockers -SpawnBlockersOn: Currently enabled -SpawnBlockersOff: Currently disabled +SpawnBlockersOn: Spawns are currently disabled +SpawnBlockersOff: Spawns are currently enabled AntiCystOintment: { DisplayName: Anti-Cyst Ointment From 49a0540563c90b8692b581c8a3a73e7aec16e900 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Sat, 1 Nov 2025 17:56:23 -0400 Subject: [PATCH 317/401] Version bump to 2.0.6.2. Last patch release for TML 1.4.4. --- build.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.txt b/build.txt index 9d4e04367c..8af29c4652 100644 --- a/build.txt +++ b/build.txt @@ -1,5 +1,5 @@ author = The Calamity Dev Team -version = 2.0.6.1 +version = 2.0.6.2 displayName = Calamity Mod modReferences = CalamityModMusic homepage = https://discord.gg/calamity From 2af0577f7d0ee5712a03465e2fde87346b990281 Mon Sep 17 00:00:00 2001 From: CactusDuper <58598131+CactusDuper@users.noreply.github.com> Date: Thu, 13 Nov 2025 14:07:46 -0500 Subject: [PATCH 318/401] Fix: AnySolidTileInSelection always returns false due to inverted logic (#97) Fix: Correct inverted logic in AnySolidTileInSelection --- Utilities/TileUtils.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Utilities/TileUtils.cs b/Utilities/TileUtils.cs index 3c387d7961..169e071653 100644 --- a/Utilities/TileUtils.cs +++ b/Utilities/TileUtils.cs @@ -237,7 +237,7 @@ public static bool AnySolidTileInSelection(int x, int y, int width, int height) { for (int j = y; j != y + height; j += Math.Sign(height)) { - if (WorldGen.InWorld(i, j)) + if (!WorldGen.InWorld(i, j)) continue; if (WorldGen.SolidTile(Framing.GetTileSafely(i, j))) From 91f71eab1e5a26595c2b44cf02cbbaef5fd04097 Mon Sep 17 00:00:00 2001 From: Adam Sutherland <74009107+adsuth@users.noreply.github.com> Date: Thu, 13 Nov 2025 19:08:51 +0000 Subject: [PATCH 319/401] Fix Aureate Booster and MOAB playing wing flap sounds (#90) * Added new PlayerUtil method to disable the default Item32 wing flap sound * Added comments to clarify WingFlap changes and usage --- Items/Accessories/Wings/AureateBooster.cs | 2 ++ Items/Accessories/Wings/MOAB.cs | 2 ++ Utilities/PlayerUtils.cs | 13 +++++++++++++ 3 files changed, 17 insertions(+) diff --git a/Items/Accessories/Wings/AureateBooster.cs b/Items/Accessories/Wings/AureateBooster.cs index 1207c6432b..18f75ff0a8 100644 --- a/Items/Accessories/Wings/AureateBooster.cs +++ b/Items/Accessories/Wings/AureateBooster.cs @@ -30,6 +30,8 @@ public override void SetDefaults() public override void UpdateAccessory(Player player, bool hideVisual) { + player.DisableWingFlapSound(); + if (player.controlJump && player.wingTime > 0f && player.jump == 0 && player.velocity.Y != 0f && !hideVisual) { player.rocketDelay2--; diff --git a/Items/Accessories/Wings/MOAB.cs b/Items/Accessories/Wings/MOAB.cs index 694ddaab3b..ea7b73da86 100644 --- a/Items/Accessories/Wings/MOAB.cs +++ b/Items/Accessories/Wings/MOAB.cs @@ -28,6 +28,8 @@ public override void SetDefaults() public override void UpdateAccessory(Player player, bool hideVisual) { + player.DisableWingFlapSound(); + if (player.controlJump && player.wingTime > 0f && player.jump == 0 && player.velocity.Y != 0f && !hideVisual) { player.rocketDelay2--; diff --git a/Utilities/PlayerUtils.cs b/Utilities/PlayerUtils.cs index d162e94b21..db2b613d5c 100644 --- a/Utilities/PlayerUtils.cs +++ b/Utilities/PlayerUtils.cs @@ -322,6 +322,19 @@ public static bool CheckSolidGround(this Player player, int solidGroundAhead = 0 } return ConditionMet; } + + /// + /// Disables the default wing flap sound from vanilla; this is to stop custom wings playing this sound when they shouldnt + /// This must be called each update (eg, in the wings item UpdateAccessory method) + /// + /// The Player to disable the sound on + public static void DisableWingFlapSound(this Player player) + { + // vanilla plays a flap sound for all wings barring a few hardcoded exceptions + // the flapSound flag is used to see if the sound *has been* played, so we set it to true here to prevent it from playing + player.flapSound = true; + } + #endregion #region Location and Biomes From c9b7fa48eae356a5e8e42bd517a80d887052aac1 Mon Sep 17 00:00:00 2001 From: Adam Sutherland <74009107+adsuth@users.noreply.github.com> Date: Thu, 13 Nov 2025 19:12:20 +0000 Subject: [PATCH 320/401] Fix inconsistent spacing for tooltip of the biome blade (and variants) (#91) Made spacing consistent for attunements tooltips of biome blade (and variants) --- .../en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson index 12befb24f3..cba0e65df6 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson @@ -224,7 +224,7 @@ BrokenBiomeBlade: { Hold down while standing still on flat ground to attune the weapon to the powers of the surrounding biome Pressing otherwise switches between the current attunement and an extra stored one Main Attunement : [ATT1] - Secondary Attunement: [ATT2] + Secondary Attunement : [ATT2] ''' DefaultFunction: Does nothing... yet } @@ -835,7 +835,7 @@ OmegaBiomeBlade: { Holding down for 2 seconds attunes the weapon to the powers of the surrounding biome Pressing for a shorter period of time switches your active and passive attunements around Active Attunement : [ATT1] - Passive Attunement: [ATT2] + Passive Attunement : [ATT2] ''' DefaultFunction: ''' @@ -1322,7 +1322,7 @@ TrueBiomeBlade: { Hold down while standing still on flat ground to attune the weapon to the powers of the surrounding biome Pressing otherwise switches between the current attunement and an extra stored one Main Attunement : [ATT1] - Secondary Attunement: [ATT2] + Secondary Attunement : [ATT2] ''' DefaultFunction: ''' From 70e56bd445884a4f5b914cafadef1cc6f628eaf6 Mon Sep 17 00:00:00 2001 From: Wxo <169566103+WxoGit@users.noreply.github.com> Date: Thu, 13 Nov 2025 16:13:46 -0300 Subject: [PATCH 321/401] Fix: Remove ManagedTargets reinitialization in OnModLoad (#93) Removed the unnecessary reinitialization of ManagedTargets in ModLoad because it removed some of the rendertargets on the mod that loaded before OnModLoad --- Graphics/RenderTargetManager.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Graphics/RenderTargetManager.cs b/Graphics/RenderTargetManager.cs index 5c4888044c..7d0901eecf 100644 --- a/Graphics/RenderTargetManager.cs +++ b/Graphics/RenderTargetManager.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; using Terraria; using Terraria.ModLoader; @@ -11,7 +10,7 @@ namespace CalamityMod.Graphics ///

_d$UJY!Z80)jxI-{0u)S6IJMzI=OKinVa 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 literal 0 HcmV?d00001 diff --git a/Sounds/Custom/BuzzsawIdle.ogg b/Sounds/Custom/BuzzsawIdle.ogg new file mode 100644 index 0000000000000000000000000000000000000000..a9deb638939def4027d8e3c109dd334cb796f4e6 GIT binary patch literal 94549 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

public class RenderTargetManager : ModSystem { - internal static List ManagedTargets = new(); + internal static List ManagedTargets = []; public delegate void RenderTargetUpdateDelegate(); @@ -55,7 +54,6 @@ internal static void DisposeOfTargets() public override void OnModLoad() { - ManagedTargets = new(); Main.OnPreDraw += HandleTargetUpdateLoop; Main.OnResolutionChanged += ResetTargetSizes; } From 49429af9949eacb852f21493a223f20a0aa51beb Mon Sep 17 00:00:00 2001 From: Adam Sutherland <74009107+adsuth@users.noreply.github.com> Date: Thu, 13 Nov 2025 21:47:00 +0000 Subject: [PATCH 322/401] Kill Chronomancer's Scythe projectiles on casters death (#92) --- Projectiles/Magic/ChronoIcicleLarge.cs | 4 ++++ Projectiles/Magic/ChronomancersScytheHoldout.cs | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/Projectiles/Magic/ChronoIcicleLarge.cs b/Projectiles/Magic/ChronoIcicleLarge.cs index 2e8386ceae..a13ab3c529 100644 --- a/Projectiles/Magic/ChronoIcicleLarge.cs +++ b/Projectiles/Magic/ChronoIcicleLarge.cs @@ -30,6 +30,10 @@ public override void SetDefaults() public override void AI() { + Player player = Main.player[Projectile.owner]; + if (player is null || player.dead) + Projectile.Kill(); + Projectile.ai[1]++; switch (Projectile.ai[0]) { diff --git a/Projectiles/Magic/ChronomancersScytheHoldout.cs b/Projectiles/Magic/ChronomancersScytheHoldout.cs index d5861097b5..81fda0e112 100644 --- a/Projectiles/Magic/ChronomancersScytheHoldout.cs +++ b/Projectiles/Magic/ChronomancersScytheHoldout.cs @@ -44,6 +44,10 @@ public override void AI() { Owner.ChangeDir((int)Projectile.ai[2]); + Player player = Main.player[Projectile.owner]; + if (player is null || player.dead) + Projectile.Kill(); + Projectile.velocity = Vector2.Zero; Projectile.rotation += (2 * MathHelper.Pi / 60) * Projectile.ai[2]; From 44eeae670b85bba40ea01aa87be082f0d55a6a47 Mon Sep 17 00:00:00 2001 From: Habble53 <87115317+Habble53@users.noreply.github.com> Date: Mon, 17 Nov 2025 10:51:45 +0300 Subject: [PATCH 323/401] Safety check --- CalPlayer/CalamityPlayerHitHurt.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CalPlayer/CalamityPlayerHitHurt.cs b/CalPlayer/CalamityPlayerHitHurt.cs index f8c95be76c..1c6be2ee68 100644 --- a/CalPlayer/CalamityPlayerHitHurt.cs +++ b/CalPlayer/CalamityPlayerHitHurt.cs @@ -660,12 +660,12 @@ public override void ModifyHitNPCWithItem(Item item, NPC target, ref NPC.HitModi // 0f = point blank, 1f = max range or further float DistanceInterpolant = Utils.GetLerpValue(FrostArmorSetChange.MinDistance, FrostArmorSetChange.MaxDistance, target.Distance(Main.player[Main.myPlayer].Center), true); - if (proj.CountsAsClass()) + if (proj.CountsAsClass() && modifiers.TargetDamageMultiplier.Value > 0f) { float meleeBoost = MathHelper.Lerp(0f, FrostArmorSetChange.ProximityBoost, 1 - DistanceInterpolant); modifiers.TargetDamageMultiplier *= (modifiers.TargetDamageMultiplier.Value + meleeBoost) / modifiers.TargetDamageMultiplier.Value; } - else if (proj.CountsAsClass()) + else if (proj.CountsAsClass() && modifiers.TargetDamageMultiplier.Value > 0f) { float rangedBoost = MathHelper.Lerp(0f, FrostArmorSetChange.ProximityBoost, DistanceInterpolant); modifiers.TargetDamageMultiplier *= (modifiers.TargetDamageMultiplier.Value + rangedBoost) / modifiers.TargetDamageMultiplier.Value; From 4e376c42f4c3fd7e225593df5f101bd4a6f873dc Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 21 Nov 2025 22:59:57 -0500 Subject: [PATCH 324/401] Removed Seared Pan --- CalPlayer/CalamityPlayer.cs | 4 - CalPlayer/CalamityPlayerMiscEffects.cs | 12 - Items/Weapons/Rogue/SearedPan.cs | 78 ------- Items/Weapons/Rogue/SearedPan.png | Bin 912 -> 0 bytes ...Mods.CalamityMod.Items.Weapons.Rogue.hjson | 14 -- .../Mods.CalamityMod.Projectiles.Rogue.hjson | 3 - Projectiles/Rogue/NiceCock.cs | 154 ------------- Projectiles/Rogue/NiceCock.png | Bin 4834 -> 0 bytes Projectiles/Rogue/PanSpark.cs | 139 ------------ Projectiles/Rogue/PanSpark.png | Bin 313 -> 0 bytes Projectiles/Rogue/SearedPanProjectile.cs | 206 ------------------ Projectiles/Rogue/SearedPanProjectile.png | Bin 469 -> 0 bytes 12 files changed, 610 deletions(-) delete mode 100644 Items/Weapons/Rogue/SearedPan.cs delete mode 100644 Items/Weapons/Rogue/SearedPan.png delete mode 100644 Projectiles/Rogue/NiceCock.cs delete mode 100644 Projectiles/Rogue/NiceCock.png delete mode 100644 Projectiles/Rogue/PanSpark.cs delete mode 100644 Projectiles/Rogue/PanSpark.png delete mode 100644 Projectiles/Rogue/SearedPanProjectile.cs delete mode 100644 Projectiles/Rogue/SearedPanProjectile.png diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index e20562d3e8..2bd11e6680 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -87,8 +87,6 @@ public partial class CalamityPlayer : ModPlayer public bool brimlashBusterBoost = false; public int evilSmasherBoost = 0; public int hellbornBoost = 0; - public int searedPanCounter = 0; - public int searedPanTimer = 0; public int potionTimer = 0; public bool blockAllDashes = false; public bool resetHeightandWidth = false; @@ -2647,8 +2645,6 @@ public override void UpdateDead() ascendantTrail = false; evilSmasherBoost = 0; hellbornBoost = 0; - searedPanCounter = 0; - searedPanTimer = 0; potionTimer = 0; persecutedEnchantSummonTimer = 0; momentumCapacitorTime = 0; diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index e6a9fef611..2107a4d765 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -2843,18 +2843,6 @@ private void OtherBuffEffects() if (Player.ActiveItem().type != ModContent.ItemType()) evilSmasherBoost = 0; } - if (searedPanCounter > 0) - { - if (Player.ActiveItem().type != ModContent.ItemType()) - { - searedPanCounter = 0; - searedPanTimer = 0; - } - else if (searedPanTimer < SearedPan.ConsecutiveHitOpening) - searedPanTimer++; - else - searedPanCounter = 0; - } // Flight time boosts double flightTimeMult = 1D + diff --git a/Items/Weapons/Rogue/SearedPan.cs b/Items/Weapons/Rogue/SearedPan.cs deleted file mode 100644 index 411e55ba23..0000000000 --- a/Items/Weapons/Rogue/SearedPan.cs +++ /dev/null @@ -1,78 +0,0 @@ -using CalamityMod.Items.Materials; -using CalamityMod.Projectiles.Rogue; -using CalamityMod.Rarities; -using CalamityMod.Tiles.Furniture.CraftingStations; -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.Audio; -using Terraria.DataStructures; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Items.Weapons.Rogue -{ - public class SearedPan : RogueWeapon - { - public static readonly SoundStyle SmashSound = new("CalamityMod/Sounds/Item/SearedPanSmash"); - - // Attacks must be within 40 frames of each other to count as "consecutive" hits - // This is a little less than double the use time - public static int ConsecutiveHitOpening = 40; - public override void SetDefaults() - { - Item.width = 60; - Item.height = 36; - Item.damage = 2222; - Item.DamageType = RogueDamageClass.Instance; - Item.knockBack = 10f; - Item.noMelee = true; - Item.noUseGraphic = true; - Item.useStyle = ItemUseStyleID.Swing; - Item.useTime = Item.useAnimation = 25; - Item.reuseDelay = 1; - Item.useLimitPerAnimation = 1; - Item.UseSound = SoundID.Item1; - Item.autoReuse = true; - Item.value = CalamityGlobalItem.RarityVioletBuyPrice; - Item.rare = ModContent.RarityType(); - Item.shoot = ModContent.ProjectileType(); - Item.shootSpeed = 15f; - Item.Calamity().donorItem = true; - } - - public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) - { - float mode = 1f; - if (player.Calamity().searedPanCounter >= 3) - { - player.Calamity().searedPanCounter = 0; - mode = 2f; - } - if (player.Calamity().StealthStrikeAvailable()) - { - player.Calamity().searedPanCounter = 0; - mode = 3f; - } - int pan = Projectile.NewProjectile(source, position, velocity, type, damage, knockback, player.whoAmI, mode); - if (mode > 1f && pan.WithinBounds(Main.maxProjectiles)) - { - Main.projectile[pan].extraUpdates++; - if (mode == 3f) - Main.projectile[pan].Calamity().stealthStrike = true; - } - return false; - } - - public override void AddRecipes() - { - CreateRecipe(). - AddIngredient(). - AddIngredient(5). - AddIngredient(ItemID.LifeCrystal). - AddIngredient(ItemID.Bone, 92). - // AddIngredient(ItemID.Steak). - AddTile(). - Register(); - } - } -} diff --git a/Items/Weapons/Rogue/SearedPan.png b/Items/Weapons/Rogue/SearedPan.png deleted file mode 100644 index b5bef1d2cc96f67b191cbe62923abdf606187e34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 912 zcmV;B18@9^P)Px#AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy24YJ`L;(K){{a7>y{D4^00Q1gL_t(&-tC!9PZL2HfS)xs#kRl# zu^1FVMWv!q!o`CSgHiElP*X1^k{Ayj{0sgG{SCy#cvTZI!7~99kwhe7BnSnepGZSY zIn+0G#vPW*(rC8NZFZ;cw0-uSoq5NiLiEIX0cflb0}u>{0Qfe)RM<(}!|ewxfb41# zfR$7ZfU&8!j{Wyk>IeTTSi3!dm_5|q3c%d#*8;%twkQBCr@P9E7j14<+7quw0GR%g z0HCw0!vgr3O#?9e;+fLFYS=4GW^WF~0Z1$^0x3CvR zM>j3M)pv&XdKE}=H_~7O&}4^|`zEtuXn)Irvc_AQUvP|TG9Iyu-^+J~Jlp z!rvNoLyYU_x$HZ`p5^d%@!G5&*JN6#8ul8~tXU~eoQwh094?>VX663^S-V#a3-N(L zrJc#G1CU+I0}u!V09Z|B9cxmOGqPWmwREMp9xtu~o(~Tz*ZpT$H!0Kvg8;1O^96v~ za18(p%jsV|il(pj^#IUu?1=LDHxrXeTYpdP)=Eo{`(bk zxp=g#wXA@;=~pA8fH{}FHhrP*B2da*F^pgL!&ZD?umEtSzfZYgcb-w&PoF#n{xtq_ zbZpB3^jei(Wt8frX$|c51c*^VH(O`dS^()}2JoZdo>*@I;KAJ+jvYSDd+D(p(#ect zZtI9~(+P!s-Oa4vKf{$8$St?aWnVC00sP2sDA(PdK;IeO1hFq2If$F5KmY&$5_Cma mbVXQ6MmkS&X=QG7VRUJ4ZU8ZaSnTfr0000 "Projectiles.Rogue"; - public bool homing = false; - public int Timer = 0; - private bool initialized = false; - private Color[] colors = new Color[] - { - new Color(255, 0, 0, 50), //Red - new Color(255, 128, 0, 50), //Orange - new Color(255, 255, 0, 50), //Yellow - new Color(128, 255, 0, 50), //Lime - new Color(0, 255, 0, 50), //Green - new Color(0, 255, 128, 50), //Turquoise - new Color(0, 255, 255, 50), //Cyan - new Color(0, 128, 255, 50), //Light Blue - new Color(0, 0, 255, 50), //Blue - new Color(128, 0, 255, 50), //Purple - new Color(255, 0, 255, 50), //Fuschia - new Color(255, 0, 128, 50) //Hot Pink - }; - - public override void SetStaticDefaults() - { - Main.projFrames[Projectile.type] = 5; - } - - public override void SetDefaults() - { - Projectile.width = 44; - Projectile.height = 70; - Projectile.friendly = true; - Projectile.tileCollide = false; - Projectile.DamageType = RogueDamageClass.Instance; - Projectile.timeLeft = 180; - Projectile.alpha = 255; - } - - public override void SendExtraAI(BinaryWriter writer) => writer.Write(homing); - - public override void ReceiveExtraAI(BinaryReader reader) => homing = reader.ReadBoolean(); - - public override bool? CanHitNPC(NPC target) - { - // Do not deal damage before fully opaque - if (Projectile.alpha >= 10) - return false; - int index = (int)Projectile.ai[1]; - if (Main.npc[index] is null || !Main.npc[index].active || Main.npc[index].life < 0) - return false; - // Do not deal damage to any NPC that isn't the specified target - if (index != target.whoAmI) - return false; - return null; - } - - public override void AI() - { - Player player = Main.player[Projectile.owner]; - CalamityPlayer modPlayer = player.Calamity(); - // Fireballs disappear if you can't stealth strike - if (!modPlayer.wearingRogueArmor || modPlayer.rogueStealthMax <= 0) - Projectile.Kill(); - - Projectile.alpha -= 5; - - if (!initialized) - { - // Pick a random frame to start on - Projectile.frame = Main.rand.Next(Main.projFrames[Projectile.type]); - initialized = true; - } - - Projectile.frameCounter++; - if (Projectile.frameCounter > 8) - { - Projectile.frame++; - Projectile.frameCounter = 0; - } - if (Projectile.frame >= Main.projFrames[Projectile.type]) - Projectile.frame = 0; - - int index = (int)Projectile.ai[1]; - - // If the target doesn't exist or is dead, spontaneously combust - if (Main.npc[index] is null || !Main.npc[index].active || Main.npc[index].life < 0) - Projectile.Kill(); - - // Decrement the timer. This should last a second as stealth strikes will initialize this at 61. - if (Timer > 1) - Timer--; - if (Timer == 1) - homing = true; - - NPC target = Main.npc[index]; - - if (homing) - { - // Home in on the target - Vector2 moveDirection = Projectile.SafeDirectionTo(target.Center, Vector2.UnitY); - Projectile.velocity = (Projectile.velocity * 20f + moveDirection * 15f) / 21f; - } - else - { - // Circle around the target counter-clockwise at 4 radians per frame - float height = target.getRect().Height; - float width = target.getRect().Width; - float circleDist = MathHelper.Min((height > width ? height : width) * 3f, (Main.LogicCheckScreenWidth * Main.LogicCheckScreenHeight) / 2); - if (circleDist > Main.LogicCheckScreenWidth / 3) - circleDist = Main.LogicCheckScreenWidth / 3; - Projectile.Center = target.Center + Projectile.ai[0].ToRotationVector2() * circleDist; - Projectile.ai[0] -= MathHelper.ToRadians(4f); - } - } - - public override void OnKill(int timeLeft) - { - SoundEngine.PlaySound(SoundID.Item74, Projectile.Center); - Projectile.ExpandHitboxBy(50); - - // Create into some rainbow-colored dust when dead - for (int d = 0; d < 5; d++) - { - int idx = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.RainbowMk2, 0f, 0f, 150, Main.rand.Next(colors), 2f); - Main.dust[idx].velocity *= 3f; - Main.dust[idx].noGravity = true; - if (Main.rand.NextBool()) - { - Main.dust[idx].scale = 0.5f; - Main.dust[idx].fadeIn = 1f + (float)Main.rand.Next(10) * 0.1f; - } - } - for (int d = 0; d < 8; d++) - { - int idx = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.RainbowMk2, 0f, 0f, 150, Main.rand.Next(colors), 3f); - Main.dust[idx].noGravity = true; - Main.dust[idx].velocity *= 5f; - idx = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.RainbowMk2, 0f, 0f, 150, Main.rand.Next(colors), 2f); - Main.dust[idx].velocity *= 2f; - Main.dust[idx].noGravity = true; - } - } - } -} diff --git a/Projectiles/Rogue/NiceCock.png b/Projectiles/Rogue/NiceCock.png deleted file mode 100644 index 8881462c5cacb04edbdd35914317cb73a544b010..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4834 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 "Projectiles.Rogue"; - private bool initialized = false; - - public override void SetStaticDefaults() - { - Main.projFrames[Projectile.type] = 3; - ProjectileID.Sets.TrailCacheLength[Projectile.type] = 2; - ProjectileID.Sets.TrailingMode[Projectile.type] = 0; - } - - public override void SetDefaults() - { - Projectile.width = 14; - Projectile.height = 14; - Projectile.friendly = true; - Projectile.penetrate = -1; - Projectile.timeLeft = 120; - Projectile.usesLocalNPCImmunity = true; - Projectile.localNPCHitCooldown = -1; - Projectile.DamageType = RogueDamageClass.Instance; - Projectile.ignoreWater = true; - } - - public override void AI() - { - //make it face the way it's going - if (Projectile.ai[1] > 0f) - { - Projectile.rotation = -Projectile.velocity.X * 0.05f + MathHelper.PiOver2; - } - else - { - Projectile.rotation = Projectile.velocity.ToRotation(); - } - Projectile.ai[1]--; - - //frames - if (!initialized) - { - initialized = true; - Projectile.frame = Main.rand.Next(Main.projFrames[Projectile.type]); - } - Projectile.frameCounter++; - if (Projectile.frameCounter > 6) - { - Projectile.frame++; - Projectile.frameCounter = 0; - } - if (Projectile.frame >= Main.projFrames[Projectile.type]) - { - Projectile.frame = 0; - } - - //movement - if (Projectile.velocity.X != Projectile.velocity.X) - { - Projectile.velocity.X *= -0.1f; - } - if (Projectile.velocity.X != Projectile.velocity.X) - { - Projectile.velocity.X *= -0.5f; - } - if (Projectile.velocity.Y != Projectile.velocity.Y && Projectile.velocity.Y > 1f) - { - Projectile.velocity.Y *= -0.5f; - } - Projectile.ai[0] += 1f; - if (Projectile.ai[0] > 5f) - { - Projectile.ai[0] = 5f; - if (Projectile.velocity.Y == 0f && Projectile.velocity.X != 0f) - { - Projectile.velocity.X *= 0.97f; - if (Projectile.velocity.X > -0.01f && Projectile.velocity.X < 0.01f) - { - Projectile.velocity.X = 0f; - Projectile.netUpdate = true; - } - } - Projectile.velocity.Y += 0.2f; - } - if (Projectile.velocity.Y < 0.25f && Projectile.velocity.Y > 0.15f) - { - Projectile.velocity.X *= 0.8f; - } - if (Projectile.velocity.Y > 16f) - { - Projectile.velocity.Y = 16f; - } - - //dust - if (Main.rand.NextBool(4)) - { - int fire = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.Torch, 0f, 0f, 100, default, 1f); - Dust dust = Main.dust[fire]; - dust.position.X -= 2f; - dust.position.Y += 2f; - dust.scale += (float)Main.rand.Next(50) * 0.01f; - dust.noGravity = true; - dust.velocity.Y -= 2f; - } - if (Main.rand.NextBool(10)) - { - int fire = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.Torch, 0f, 0f, 100, default, 1f); - Dust dust = Main.dust[fire]; - dust.position.X -= 2f; - dust.position.Y += 2f; - dust.scale += 0.3f + (float)Main.rand.Next(50) * 0.01f; - dust.noGravity = true; - dust.velocity *= 0.1f; - } - } - - public override bool OnTileCollide(Vector2 oldVelocity) - { - Projectile.ai[1] = 10f; - return false; - } - - public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) => target.AddBuff(BuffID.Daybreak, 90); - - public override Color? GetAlpha(Color lightColor) => new Color(255, 230, 130); - - public override bool PreDraw(ref Color lightColor) - { - CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], lightColor, 1); - return false; - } - } -} diff --git a/Projectiles/Rogue/PanSpark.png b/Projectiles/Rogue/PanSpark.png deleted file mode 100644 index c74b2ed1a70e345c163f9500d5e65b4e36833276..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 313 zcmeAS@N?(olHy`uVBq!ia0vp^GC-`w!3-p)e>g1$q!^2X+?^QKos)S9^9T5Zxc>Zq>)R2#zki~xHmU%{c1(}&2U4shL4Lvifq>!nHojn>0B3G z^JVUxKN+-QYxAkomkgb+c3D+U;BXR5`(pB7<3gF9#-|PfUJizi#M@6@zlr^bbq?o(Bb~$yMHGiVPa0MTs(X7 "Projectiles.Rogue"; - internal enum SearedPanTypes - { - VenLocket = 0, - Normal = 1, - Golden = 2, - StealthStrike = 3 - } - - internal SearedPanTypes PanType - { - get => (SearedPanTypes)(int)Projectile.ai[0]; - set => Projectile.ai[0] = (int)value; - } - - public override void SetStaticDefaults() - { - ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; - ProjectileID.Sets.TrailingMode[Projectile.type] = 0; - } - - public override void SetDefaults() - { - Projectile.width = Projectile.height = 20; - Projectile.friendly = true; - Projectile.ignoreWater = true; - Projectile.timeLeft = 420; - Projectile.DamageType = RogueDamageClass.Instance; - Projectile.extraUpdates = 2; - } - - public override void AI() - { - if (Main.rand.NextBool(5)) - { - Dust.NewDust(Projectile.position + Projectile.velocity, Projectile.width, Projectile.height, DustID.Blood, Projectile.velocity.X * 0.5f, Projectile.velocity.Y * 0.5f); - } - Projectile.spriteDirection = Projectile.direction = (Projectile.velocity.X > 0).ToDirectionInt(); - Projectile.rotation = Projectile.velocity.ToRotation() + (Projectile.spriteDirection == 1 ? 0f : MathHelper.Pi); - } - - public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) - { - // Don't increment the Seared Pan counter when hitting dummies - //&& target.type != ModContent.NPCType() this is here just in case its needed again - bool dummy = target.type != NPCID.TargetDummy; - OnHitEffects(target.whoAmI, target.life, dummy); - } - - public override void OnHitPlayer(Player target, Player.HurtInfo info) - { - target.AddBuff(BuffID.Bleeding, 300); - OnHitEffects(-1, target.statLife, true); - } - - private void OnHitEffects(int targetIndex, int health, bool specialEffects) - { - Player player = Main.player[Projectile.owner]; - CalamityPlayer modPlayer = player.Calamity(); - - // Don't spawn fireballs or increment the special effects counter if you can't even stealth strike - bool playerCanStealthStrike = modPlayer.wearingRogueArmor && modPlayer.rogueStealthMax > 0; - if (!playerCanStealthStrike) - return; - - // Increment the seared pan counter. Pans summoned via the Venerated Locket shouldn't increment the counter. - // See CalamityPlayerMiscEffects.cs for code that resets the counter after 40 frames - modPlayer.searedPanTimer = 0; - if (specialEffects && PanType != SearedPanTypes.VenLocket) - modPlayer.searedPanCounter++; - - // Pans summoned via the Venerated Locket have zero special effects - if (PanType == SearedPanTypes.StealthStrike) - { - modPlayer.searedPanCounter = 0; - // Stealth strikes spawn four golden sparks on hit - for (int t = 0; t < 4; t++) - { - Vector2 velocity = CalamityUtils.RandomVelocity(100f, 70f, 100f); - Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, velocity, ModContent.ProjectileType(), (int)(Projectile.damage * 0.2), 0f, Projectile.owner); - } - SoundEngine.PlaySound(SearedPan.SmashSound, Projectile.position); - // Stealth strikes also cause any existing fireballs to home in on their targets - FireballStuff(true); - - if (!specialEffects) - return; - // Stealth strikes then summon five fireballs to circle the hit enemy, they will home in on their own after a second. - for (int t = 0; t < 5; t++) - { - int i = Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, Vector2.Zero, ModContent.ProjectileType(), (int)(Projectile.damage * 0.1), 0f, Projectile.owner, 0f, targetIndex); - Main.projectile[i].ModProjectile().Timer = 61; - } - FireballPositions(targetIndex); - } - else if (PanType == SearedPanTypes.Golden) - { - modPlayer.searedPanCounter = 0; - SoundEngine.PlaySound(SearedPan.SmashSound, Projectile.position); - // Golden pans simply cause all fireballs to home in on their targets - FireballStuff(true); - } - else if (PanType == SearedPanTypes.Normal && targetIndex != -1 && health > 0 && specialEffects) - { - // Summon three fireballs to circle the hit enemy - for (int t = 0; t < 3; t++) - { - Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, Vector2.Zero, ModContent.ProjectileType(), (int)(Projectile.damage * 0.1), 0f, Projectile.owner, 0f, targetIndex); - } - FireballPositions(targetIndex); - } - } - - private void FireballStuff(bool activate) - { - if (Projectile.owner == Main.myPlayer) - { - foreach (Projectile p in Main.ActiveProjectiles) - { - if (p.owner != Projectile.owner) - continue; - if (p.ModProjectile is NiceCock) - { - if (!activate) - p.Kill(); - else - { - p.ModProjectile().homing = true; - p.extraUpdates += 2; - } - } - } - } - } - - private void FireballPositions(int targetIndex) - { - int fireballCount = 0; - // Count how many fireballs exist already around the given target - foreach (Projectile p in Main.ActiveProjectiles) - { - // Keep the loop as short as possible - if (p.owner != Projectile.owner || !p.CountsAsClass() || targetIndex != (int)p.ai[1]) - continue; - if (p.ModProjectile is NiceCock) - { - if (p.ModProjectile().homing) - continue; - fireballCount++; - } - } - // Adjust the angle of the existing fireballs around a target - float angleVariance = MathHelper.TwoPi / fireballCount; - float angle = 0f; - foreach (Projectile p in Main.ActiveProjectiles) - { - if (p.owner != Projectile.owner || !p.CountsAsClass() || targetIndex != (int)p.ai[1]) - continue; - if (p.ModProjectile is NiceCock) - { - if (p.ModProjectile().homing) - continue; - p.ai[0] = angle; - p.netUpdate = true; - angle += angleVariance; - } - } - } - - public override bool OnTileCollide(Vector2 oldVelocity) - { - // Kill all fireballs if you miss a stealth strike or golden pan - if (PanType == SearedPanTypes.Golden || PanType == SearedPanTypes.StealthStrike) - FireballStuff(false); - return true; - } - - public override Color? GetAlpha(Color lightColor) - { - // Stealth strikes and golden pans are golden colored - if (PanType == SearedPanTypes.Golden || PanType == SearedPanTypes.StealthStrike) - return new Color(255, 222, 0); - return null; - } - - public override bool PreDraw(ref Color lightColor) - { - CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], lightColor, 1); - return false; - } - } -} diff --git a/Projectiles/Rogue/SearedPanProjectile.png b/Projectiles/Rogue/SearedPanProjectile.png deleted file mode 100644 index 559b586cb82c928d727393035e6c31a743a3bfac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 469 zcmeAS@N?(olHy`uVBq!ia0vp^PC(4V!3HF+v1NY&QY`6?zK#qG8~eHcB(ehejKx9j zP7LeL$-D$|6p}rHd>I(3)EF2VS{N990fib~Fff!FFfhDIU|_JC!N4G1FlSew4N!tD z$=lt9;Xep2*t>i(&?IF~7sn8f(+2|u1hkik2OzuN^$y|=CDIaFS}$@$^?{RN_{_pN@e|H$1B}Tt(p8v&;P72`|BRqhhaED4Sh(f~ zoci(ioo?924Qp~l>^5pL*{a6qdVp@-bWv1qpB$j06=P?+zM7((qlx6UA^>bP0l+XkK6oR$* From 92bd7c4b3b04b35ee102bc10b47524d075d6830f Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 21 Nov 2025 23:02:05 -0500 Subject: [PATCH 325/401] Updated Thank You for all dev changes --- Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs index 8661d1824a..41b6a1cdda 100644 --- a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs +++ b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs @@ -59,7 +59,7 @@ public override void ModifyTooltips(List tooltips) public static IList devList = new List() { - "Altix", + "Altixal", "apotofkoolaid", "AquaSG", "Atalya", @@ -81,7 +81,6 @@ public override void ModifyTooltips(List tooltips) "Fluffy", "fryzahh", "HaguriHat", - "Heart Plus Up!", "LordMetarex", "Memes", "Mercutio 'Merkalto' Takle", @@ -95,11 +94,11 @@ public override void ModifyTooltips(List tooltips) "Raesh", "Sagittariod", "Shade", - "Shayy", "Spider Prov", "StipulateVenus", "Sunny", "Tobias", + "_tofu", "Tomat", "Triangle", "TYESKI (Universe)", @@ -144,6 +143,7 @@ public override void ModifyTooltips(List tooltips) "GramOfSalt", "Graydee", "Grox the Great", + "Heart Plus Up!", "Hectique", "Hugekraken", "Huggles", From b8bfef18cecfbc6ff514ada90315208464292af6 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 21 Nov 2025 23:06:15 -0500 Subject: [PATCH 326/401] Reverted Gold Chest Meteorite Bar fix --- Systems/WorldgenManagementSystem.cs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/Systems/WorldgenManagementSystem.cs b/Systems/WorldgenManagementSystem.cs index 7c6161d39a..1e7c71d05f 100644 --- a/Systems/WorldgenManagementSystem.cs +++ b/Systems/WorldgenManagementSystem.cs @@ -408,20 +408,6 @@ public override void PostWorldGen() } } - // Fix vanilla's stupidity with Gold Chests being able to have Meteorite Bars in them near the Underworld - if (isGoldChest) - { - for (int inventoryIndex = 0; inventoryIndex < 40; inventoryIndex++) - { - if (chest.item[inventoryIndex].type == ItemID.MeteoriteBar) - { - int oldStack = chest.item[inventoryIndex].stack; - chest.item[inventoryIndex].SetDefaults(WorldGen.genRand.NextBool() ? ItemID.PlatinumBar : ItemID.GoldBar); - chest.item[inventoryIndex].stack = oldStack; - } - } - } - // Give Dead Man's Chests better loot. if (isDeadManChest) { From 86d61674035d6220587bb416ce0389b1a84eded4 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 21 Nov 2025 23:08:55 -0500 Subject: [PATCH 327/401] Pharaoh's set returns to pyramids --- ILEditing/ILChangesLoading.cs | 1 - ILEditing/WorldgenILChanges.cs | 22 ---------------------- Utilities/CalamityRecipes.cs | 21 --------------------- 3 files changed, 44 deletions(-) diff --git a/ILEditing/ILChangesLoading.cs b/ILEditing/ILChangesLoading.cs index e358b4cc5f..a3a7a237e2 100644 --- a/ILEditing/ILChangesLoading.cs +++ b/ILEditing/ILChangesLoading.cs @@ -126,7 +126,6 @@ public override void OnModLoad() IL_Projectile.StatusPlayer += RemoveFrozenInflictionFromDeerclopsIceSpikes; // World generation - IL_WorldGen.Pyramid += ReplacePharaohSetInPyramids; IL_WorldGen.GrowLivingTree += BlockLivingTreesNearOcean; On_WorldGen.SmashAltar += PreventSmashAltarCode; IL_WorldGen.hardUpdateWorld += AdjustChlorophyteSpawnRate; diff --git a/ILEditing/WorldgenILChanges.cs b/ILEditing/WorldgenILChanges.cs index 67f4682353..a3e56d9c07 100644 --- a/ILEditing/WorldgenILChanges.cs +++ b/ILEditing/WorldgenILChanges.cs @@ -33,28 +33,6 @@ public static int? DungeonBaseXLimitOverride set; } - #region Replacement of Pharaoh Set in Pyramids - // Note: There is no need to replace the other Pharaoh piece, due to how the vanilla code works. - // The other Pharaoh vanity piece is added automatically if the mask is found in the chest. - private static void ReplacePharaohSetInPyramids(ILContext il) - { - var cursor = new ILCursor(il); - - // Find the instruction which loads in the item ID of the Pharaoh's Mask. - if (!cursor.TryGotoNext(MoveType.Before, i => i.MatchLdcI4(ItemID.PharaohsMask))) - { - LogFailure("Pharaoh Set Pyramid Replacement", "Could not locate the Pharaoh's Mask item ID."); - return; - } - - // Replace the Pharaoh's Mask with the Amber Hook. - // THIS INT CAST IS MANDATORY. DO NOT REMOVE IT. - // In TML's DLL, despite item IDs being shorts (16 bits), the hardcoded 848 here is a 32-bit integer literal. - // As such, it must be replaced with a 32-bit integer literal or the branches of the switch will misalign and the IL edit fails. - cursor.Next.Operand = (int)ItemID.AmberHook; - } - #endregion Replacement of Pharaoh Set in Pyramids - #region Fixing of Living Tree/Sulphurous Sea Interactions private static void BlockLivingTreesNearOcean(ILContext il) { diff --git a/Utilities/CalamityRecipes.cs b/Utilities/CalamityRecipes.cs index 85c3c4dda1..13e8b2696f 100644 --- a/Utilities/CalamityRecipes.cs +++ b/Utilities/CalamityRecipes.cs @@ -1747,19 +1747,6 @@ private static void AddArmorRecipes() r.AddTile(TileID.Loom); r.Register(); r.DisableDecraft(); - - // Pharaoh set - r = Recipe.Create(ItemID.PharaohsMask); - r.AddIngredient(ItemID.AncientCloth, 3); - r.AddTile(TileID.Loom); - r.Register(); - r.DisableDecraft(); - - r = Recipe.Create(ItemID.PharaohsRobe); - r.AddIngredient(ItemID.AncientCloth, 4); - r.AddTile(TileID.Loom); - r.Register(); - r.DisableDecraft(); } #endregion @@ -2004,14 +1991,6 @@ public static void AddShimmerRecipes() int[] convert = ItemID.Sets.ShimmerTransformToItem; InsertShimmerResult(ModContent.ItemType(), ItemID.SummonerEmblem); - - // Pyramid loot edits. There's no good way to have this not be hardcoded. - convert[ItemID.PharaohsMask] = ItemID.PharaohsRobe; - convert[ItemID.PharaohsRobe] = ItemID.PharaohsMask; - - convert[ItemID.AmberHook] = ItemID.SandstorminaBottle; - convert[ItemID.SandstorminaBottle] = ItemID.FlyingCarpet; - convert[ItemID.FlyingCarpet] = ItemID.AmberHook; } #endregion From c715526f07f37218c851ae30ec0bc127ec3b65cc Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 21 Nov 2025 23:09:56 -0500 Subject: [PATCH 328/401] Striking Moment no longer gets removed if not holding Brand of the Inferno or Sergeant United Shield --- Items/CalamityGlobalItem.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Items/CalamityGlobalItem.cs b/Items/CalamityGlobalItem.cs index 0643be10da..d06c26911e 100644 --- a/Items/CalamityGlobalItem.cs +++ b/Items/CalamityGlobalItem.cs @@ -625,15 +625,6 @@ public override bool OnPickup(Item item, Player player) player.Calamity().evilSmasherBoost = 0; } - if (player.HasBuff(BuffID.ParryDamageBuff)) - { - if (item.type != ItemID.DD2SquireDemonSword && item.type != ItemID.BouncingShield) - { - player.parryDamageBuff = false; - player.ClearBuff(BuffID.ParryDamageBuff); - } - } - // Give 1 minute of Mushy buff when consuming Mushrooms with Fungal Symbiote equipped. if (item.type == ItemID.Mushroom && player.Calamity().fungalSymbiote) player.AddBuff(ModContent.BuffType(), 3600); From 96fdde5282a7e99b7696def121d87267ee667739 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 21 Nov 2025 23:11:23 -0500 Subject: [PATCH 329/401] Vents no longer fire steam while a boss is alive --- Tiles/Abyss/SteamGeyser.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Tiles/Abyss/SteamGeyser.cs b/Tiles/Abyss/SteamGeyser.cs index 7056860026..2ebecf6c03 100644 --- a/Tiles/Abyss/SteamGeyser.cs +++ b/Tiles/Abyss/SteamGeyser.cs @@ -1,4 +1,5 @@ using System; +using CalamityMod.CalPlayer; using CalamityMod.Dusts; using CalamityMod.Projectiles.Environment; using Microsoft.Xna.Framework; @@ -52,7 +53,7 @@ public override void NearbyEffects(int i, int j, bool closer) Tile t = CalamityUtils.ParanoidTileRetrieval(i, j); Vector2 spawnPosition = new(i * 16f + 24f, j * 16f - 4f); - if (!Main.gamePaused && t.TileFrameX % 36 == 0 && t.TileFrameY % 36 == 0 && Collision.CanHitLine(spawnPosition, 1, 1, spawnPosition - Vector2.UnitY * 100f, 1, 1)) + if (!Main.gamePaused && !CalamityPlayer.areThereAnyDamnBosses && t.TileFrameX % 36 == 0 && t.TileFrameY % 36 == 0 && Collision.CanHitLine(spawnPosition, 1, 1, spawnPosition - Vector2.UnitY * 100f, 1, 1)) { float positionInterpolant = (i + j) * 0.041f % 1f; Vector2 smokeVelocity = -Vector2.UnitY.RotatedByRandom(0.11f) * MathHelper.Lerp(4.8f, 8.1f, positionInterpolant); From 54a0de8b4faebb07fbb4d9eac55f0cb76428c525 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 21 Nov 2025 23:23:34 -0500 Subject: [PATCH 330/401] All sentries have "Summons a sentry" tooltip line --- ...ityMod.Items.Weapons.DraedonsArsenal.hjson | 3 +- ...ods.CalamityMod.Items.Weapons.Summon.hjson | 72 +++++++++++++++---- 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.DraedonsArsenal.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.DraedonsArsenal.hjson index bccef2915e..248ea0cf93 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.DraedonsArsenal.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.DraedonsArsenal.hjson @@ -158,7 +158,8 @@ PulseTurretRemote: { DisplayName: Pulse Turret Remote Tooltip: ''' - Summons a pulse turret which eradicates nearby foes with focused energy blasts + {$CommonItemTooltip.Sentry} + Summons a turret to fire explosive pulse blasts at your enemies Only one pulse turret may exist at a time ''' } diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Summon.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Summon.hjson index 429815916b..5e67eebdd0 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Summon.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Summon.hjson @@ -24,7 +24,8 @@ AquasScepter: { DisplayName: Aqua's Scepter Tooltip: ''' - Summons a giant storm cloud sentry to rain down on your foes, and strike nearby enemies with overloading tesla energy + {$CommonItemTooltip.Sentry} + Summons a giant storm cloud to rain down on your foes, and strike nearby enemies with overloading tesla energy 'Captain! I think- we've got a risk of rain!' ''' } @@ -44,6 +45,7 @@ AtlasMunitionsBeacon: { DisplayName: Atlas Munitions Beacon Tooltip: ''' + {$CommonItemTooltip.Sentry} [c/F2B629:Brings forth an exo-powered, stationary cannon] [c/F2B629:The cannon will fire at enemies within its range] [c/F27049:If an enemy is in close proximity, it will enter Overdrive] @@ -96,7 +98,11 @@ BrittleStarStaff: { CadaverousCarrion: { DisplayName: Cadaverous Carrion - Tooltip: Summons a gross, shark-puking Old Duke head on the ground + Tooltip: + ''' + {$CommonItemTooltip.Sentry} + Summons a gross, shark-puking Old Duke head on the ground + ''' } CalamarisLament: { @@ -115,7 +121,11 @@ CalamarisLament: { CausticCroakerStaff: { DisplayName: Caustic Croaker Staff - Tooltip: Summons a toad that explodes if enemies are nearby + Tooltip: + ''' + {$CommonItemTooltip.Sentry} + Summons a toad that explodes if enemies are nearby + ''' } CausticStaff: { @@ -214,7 +224,8 @@ CryogenicStaff: { DisplayName: Cryogenic Staff Tooltip: ''' - Summons an animated ice construct to protect you + {$CommonItemTooltip.Sentry} + Summons an ice construct to unleash the cold upon your enemies Fire rate and range increase the longer it targets an enemy ''' } @@ -277,7 +288,11 @@ DragonbloodDisgorger: { DreadmineStaff: { DisplayName: Dreadmine Staff - Tooltip: Summons a dreadmine turret to fight for you + Tooltip: + ''' + {$CommonItemTooltip.Sentry} + Summons a turret that swarms your enemies with sea mines + ''' } ElementalAxe: { @@ -420,7 +435,8 @@ GuidelightofOblivion: { DisplayName: Guidelight of Oblivion Tooltip: ''' - Summons a lantern turret to fight for you + {$CommonItemTooltip.Sentry} + Summons a lantern that swarms your enemies with flames 'Shadows dream of endless fire, flames devour and embers swoop' ''' } @@ -437,7 +453,11 @@ HerringStaff: { HivePod: { DisplayName: Hive Pod - Tooltip: Summons an astral hive to protect you + Tooltip: + ''' + {$CommonItemTooltip.Sentry} + Summons an astral hive to spawn hivelings at your enemies + ''' } IgneousExaltation: { @@ -508,7 +528,11 @@ MirrorofKalandra: { OrthoceraShell: { DisplayName: Orthocera Shell - Tooltip: Summons a flying orthocera sentry at the mouse position + Tooltip: + ''' + {$CommonItemTooltip.Sentry} + Summons a flying orthocera to spit acid streams at your enemies + ''' } Perdition: { @@ -532,7 +556,11 @@ PlantationStaff: { PolypLauncher: { DisplayName: Polyp Launcher - Tooltip: Summons a polyp bunch that launches coral chunks at nearby enemies + Tooltip: + ''' + {$CommonItemTooltip.Sentry} + Summons a polyp bunch that launches coral chunks at nearby enemies + ''' } PuffShroom: { @@ -554,14 +582,18 @@ RustyBeaconPrototype: { DisplayName: Rusty Beacon Prototype Tooltip: ''' - Summons a long-abandoned drone to support you - The drone hovers in place and releases toxic waves that irradiate hit enemies + {$CommonItemTooltip.Sentry} + Summons a long-abandoned drone that passively emits irradiated waves ''' } SanctifiedSpark: { DisplayName: Sanctified Spark - Tooltip: Summons a profaned energy turret to fight for you + Tooltip: + ''' + {$CommonItemTooltip.Sentry} + Summons a friendly immolator to fire holy sparks at your enemies + ''' } SandSharknadoStaff: { @@ -617,17 +649,26 @@ SlimePuppetStaff: { SpikecragStaff: { DisplayName: Spikecrag Staff Tooltip: "[GFB]" - TooltipNormal: Summons a spikecrag to protect you + TooltipNormal: + ''' + {$CommonItemTooltip.Sentry} + Summons a bed of stalagmites to spray spikes at your enemies + ''' TooltipGFB: ''' - Summons a spikecrag to protect you" + {$CommonItemTooltip.Sentry} + Summons a bed of stalagmites to spray spikes at your enemies Defeating the Profaned Goddess unlocks its true power ''' } SquirrelSquireStaff: { DisplayName: Squirrel Squire Staff - Tooltip: Summons a squirrel squire to fight for you + Tooltip: + ''' + {$CommonItemTooltip.Sentry} + Summons a squirrel to throw acorns at your enemies + ''' } StaffOfNecrosteocytes: { @@ -818,6 +859,7 @@ HarvestStaff: { DisplayName: Harvest Staff Tooltip: ''' + {$CommonItemTooltip.Sentry} Grows a pumpkin patch that sprouts pumpkins nearby Pumpkins will hop out when approached by nearby creatures or players Once out, they will aggressively tackle enemies, exploding on hit From 7a88f40069050ab421a1188ad074a85616f92c5f Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 21 Nov 2025 23:29:24 -0500 Subject: [PATCH 331/401] Fixed jelly auras not triggering with Display Vanilla Cooldowns config disabled --- CalPlayer/CalamityPlayer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 2bd11e6680..9499ee5d97 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -3603,7 +3603,7 @@ public override void PreUpdateMovement() #region PostUpdateBuffs public override void PostUpdateBuffs() { - if (Player.whoAmI == Main.myPlayer && CalamityConfig.Instance.VanillaCooldownDisplay) + if (Player.whoAmI == Main.myPlayer) { if (Player.whoAmI == Main.myPlayer && Player.potionDelay != 0) potionSick = true; From eb42b0d07cc6250c0792973c1261225efa86c96b Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 21 Nov 2025 23:30:26 -0500 Subject: [PATCH 332/401] Fixed Astral Infection giving 5% flight time --- CalPlayer/CalamityPlayerMiscEffects.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index 2107a4d765..c25732a19e 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -2846,7 +2846,6 @@ private void OtherBuffEffects() // Flight time boosts double flightTimeMult = 1D + - (ZoneAstral ? 0.05 : 0D) + (harpyRing ? 0.2 : 0D) + (reaverSpeed ? 0.1 : 0D) + (angelTreads ? 0.1 : 0D) + From 911f1770c75fe4579d7ca6d7322ac45923874c43 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 21 Nov 2025 23:31:30 -0500 Subject: [PATCH 333/401] Fixed Dragon Rage spawning fireballs every eleven hits instead of ten --- Projectiles/Melee/DragonRageStaff.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projectiles/Melee/DragonRageStaff.cs b/Projectiles/Melee/DragonRageStaff.cs index 79c116440d..aecec54d38 100644 --- a/Projectiles/Melee/DragonRageStaff.cs +++ b/Projectiles/Melee/DragonRageStaff.cs @@ -158,7 +158,7 @@ private void OnHitEffects(Vector2 position) { CalamityPlayer modPlayer = Main.player[Projectile.owner].Calamity(); modPlayer.dragonRageHits++; - if (modPlayer.dragonRageHits > 10 && modPlayer.dragonRageCooldown <= 0) + if (modPlayer.dragonRageHits >= 10 && modPlayer.dragonRageCooldown <= 0) { SpawnFireballs(); modPlayer.dragonRageHits = 0; From 905017925130cf4b9d5305bab2cd828ecb1b70f7 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 21 Nov 2025 23:32:18 -0500 Subject: [PATCH 334/401] Fixed Gauss Dagger not requiring the schematic to craft --- Items/Weapons/DraedonsArsenal/GaussDagger.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Items/Weapons/DraedonsArsenal/GaussDagger.cs b/Items/Weapons/DraedonsArsenal/GaussDagger.cs index 98c8eac524..a58d032861 100644 --- a/Items/Weapons/DraedonsArsenal/GaussDagger.cs +++ b/Items/Weapons/DraedonsArsenal/GaussDagger.cs @@ -1,4 +1,6 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using CalamityMod.CustomRecipes; using CalamityMod.Items.Materials; using CalamityMod.Items.Placeables; using CalamityMod.Projectiles.DraedonsArsenal; @@ -58,6 +60,7 @@ public override void AddRecipes() AddIngredient(7). AddIngredient(4). AddIngredient(7). + AddCondition(ArsenalTierGatedRecipe.ConstructRecipeCondition(1, out Func condition), condition). AddTile(TileID.Anvils). Register(); } From b9ddd9607b4512b75019bc5ba2abd50a49d02f7b Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 21 Nov 2025 23:33:37 -0500 Subject: [PATCH 335/401] Fixed Harvest Staff not having minion targeting --- Projectiles/Summon/HarvestStaffSentry.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Projectiles/Summon/HarvestStaffSentry.cs b/Projectiles/Summon/HarvestStaffSentry.cs index 58fab16163..f4eeecaec9 100644 --- a/Projectiles/Summon/HarvestStaffSentry.cs +++ b/Projectiles/Summon/HarvestStaffSentry.cs @@ -3,6 +3,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Terraria; +using Terraria.ID; using Terraria.ModLoader; using static CalamityMod.Items.Weapons.Summon.HarvestStaff; @@ -16,7 +17,11 @@ public class HarvestStaffSentry : ModProjectile, ILocalizedModType public static float Gravity = 0.8f; public static float MaxGravity = 20f; - public override void SetStaticDefaults() => Main.projFrames[Type] = 4; + public override void SetStaticDefaults() + { + Main.projFrames[Type] = 4; + ProjectileID.Sets.MinionTargettingFeature[Type] = true; + } public override void SetDefaults() { From 7a0d2bb3ed329be3dd4b4bd66eca8d2ca9c76d59 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 21 Nov 2025 23:34:16 -0500 Subject: [PATCH 336/401] Removed a period from Plague Reaper armor tooltip --- Localization/en-US/Mods.CalamityMod.Items.Armor.Hardmode.hjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Armor.Hardmode.hjson b/Localization/en-US/Mods.CalamityMod.Items.Armor.Hardmode.hjson index 65e8acace8..60d4089e0c 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Armor.Hardmode.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Armor.Hardmode.hjson @@ -413,7 +413,7 @@ PlagueReaperMask: { Enemies receive 10% more damage from ranged projectiles when afflicted by the Plague Getting hit causes plague cinders to rain from above Press {0} to blind yourself for 5 seconds but massively boost your ranged damage - This has a 25 second cooldown. + This has a 25 second cooldown ''' } From 5ffa1e3123f628416cedf547d5d5c74d8262de1a Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 21 Nov 2025 23:35:09 -0500 Subject: [PATCH 337/401] Fixed VHex lasting half the intended duration on enemies --- NPCs/CalamityGlobalNPC.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/NPCs/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index 4c896be3f3..0e10b2ab06 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -5131,8 +5131,6 @@ public override void PostAI(NPC npc) GaussFluxTimer--; if (ladHearts > 0) ladHearts--; - if (vulnerabilityHex > 0) - vulnerabilityHex--; if (banishingFire > 0) banishingFire--; if (wither > 0) From 934a5f6e2114900786befcda73fe142303162450 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 21 Nov 2025 23:39:11 -0500 Subject: [PATCH 338/401] Fixed typo in text when unable to decrypt a schematic --- Localization/en-US/Mods.CalamityMod.UI.hjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/en-US/Mods.CalamityMod.UI.hjson b/Localization/en-US/Mods.CalamityMod.UI.hjson index f7906dbc01..745765fef4 100644 --- a/Localization/en-US/Mods.CalamityMod.UI.hjson +++ b/Localization/en-US/Mods.CalamityMod.UI.hjson @@ -138,7 +138,7 @@ Evoke: Evoke Exit: Exit Communicate: Communicate ConfirmationText: Are you sure? -UpgradesRequired: Encryption unsolveable: Upgrades required. +UpgradesRequired: Encryption unsolvable: Upgrades required. ThanatosIcon: Thanatos, a serpentine terror with impervious armor and innumerable laser turrets. AresIcon: Ares, a heavyweight, diabolical monstrosity with four Exo superweapons. ArtemisApolloIcon: Artemis and Apollo, a pair of extremely persistent automatons with unstable energy reserves. From 314368ae17ccecb507e94bbaf23b714806be99da Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Thu, 20 Nov 2025 13:10:44 -0500 Subject: [PATCH 339/401] Removed remaining instances from repo --- NPCs/CalamityGlobalTownNPC.cs | 1 - Sounds/Custom/BEES/Names.txt | 2 +- Sounds/Custom/BEES/bees8.ogg | Bin 8165 -> 0 bytes 3 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 Sounds/Custom/BEES/bees8.ogg diff --git a/NPCs/CalamityGlobalTownNPC.cs b/NPCs/CalamityGlobalTownNPC.cs index 67729c3e54..953d749bc4 100644 --- a/NPCs/CalamityGlobalTownNPC.cs +++ b/NPCs/CalamityGlobalTownNPC.cs @@ -205,7 +205,6 @@ public static float TaxYieldFactor }; private static readonly string[] SkeletonMerchantNames = { - "Sans Undertale", // <@!145379091648872450> (shayy) "Papyrus Undertale", // <@!262663471189983242> (nycro) "Gaster Undertale", // <@!924706306093379614> (enamoured) "Mr. Bones", // <@!359215912856977408> (jaybones.) diff --git a/Sounds/Custom/BEES/Names.txt b/Sounds/Custom/BEES/Names.txt index 440c8bb183..c6fa1f7e74 100644 --- a/Sounds/Custom/BEES/Names.txt +++ b/Sounds/Custom/BEES/Names.txt @@ -6,7 +6,7 @@ Names: 5 - moonburn 6 - Ozzatron 7 - Rebecca -8 - Shayy +8 - Unused 9 - StipulatedVenus 10 - Xyk 11 - Shade \ No newline at end of file diff --git a/Sounds/Custom/BEES/bees8.ogg b/Sounds/Custom/BEES/bees8.ogg deleted file mode 100644 index 677b47fc65e1183447e5b05bede81848295b2c91..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8165 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 Date: Fri, 21 Nov 2025 23:40:15 -0500 Subject: [PATCH 340/401] Fixed Abyssal Warhammer missing pixels --- Items/Tools/AbyssalWarhammer.png | Bin 1148 -> 607 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Items/Tools/AbyssalWarhammer.png b/Items/Tools/AbyssalWarhammer.png index b20edc372688de3c863ea7aff54a53d5a5d0a6eb..ec6356d7cff1ee17b2498c0cf270b52846495e08 100644 GIT binary patch delta 545 zcmV++0^a@n2;T&d83+Ra002ht61I^cAWHeo( zd_k9l)b?Mb)J1iqR77HDVRe*`o&W#3$Svtl2-p zoRpIW8k#!U7<=%2%``E+{w%`{v@{5;<>*`)ZlIxYu4>@>8sbco_h>?)Tzq4+#+`US z&uC(_*8A7Nw=@#Pdloq!h@?_(D`;p?h%CmG=DB}vfN9d!AYx&O#U~>1aLfnZ>udHs z1c^o@G}ej)&HFOzXhebrkrWIHSO_WUYl!6>lAK?!l+aRC8PV1V$UIYqDje^oYCZL4Do~*^)!6t<$wtJ#5opO8nTEqHOsQDvXq38=~Bo~r=xsTAX*keGDAfN!!wUyRv9|Rm^wcoD)iyq- jpGH6i<@6?9H2eMoen-}oy5>aj00000NkvXXu0mjf%)1S{ delta 1110 zcmV-c1gZPq1pEk)83+ad0040=;)IbQAb$yPNLh0L01m?d01m?e$8V@)000CLNklwiwv z%*>2uC2}&qe%?RqNl#Oh*$gYuW-1KFjj=KTU%#1hArL`o$8S@rF)riU3-j1lOIN^* zz!flMwoN+=W9V`VHAcX-8WXT(HlJSnFJCz9sA7I{QUa)&DPqZ#t4Mn7#PAi znpa9$b)}ec>zm({Fy`Ob6lGb;3CaiS1}N887gB;-IVqHCj6*nP3=HA5112=&=Tc%M zY8!t_31V8x&6WX7v0|wvsWAeM8v|g7Gz!6($;xcX>&Lv5r*e(o)8BZ95`VxnjB;^R zdnnZyn{jL&19J-EbEuEe2B6kF?`@~V_wm~D-q%Qpwbu9Sjg;W-)lSNmb|0l0V>6D= zd^c@Qq9;t=a)|o8_F(>k+OjKS2PG(J^;2%R7EcLa3V<=3g&L&B2)Jg9ue62w0Hy#K z17Hq};rlfJd&9jW4=IbAyMHJb+5Oaa``i68xDYc6Vxz=|;j zV1|r$62`y)|2<>0@n;%qr-bwjN`RUaJ2*y}>Ycj=lfbChI&y#1+g%l9G=anH5cx zs3CwG0r*Z}v^T+Q8Spg~<~eGNfa}I!6vCNwb;Tv>cXU1qMDQJiS*SIrC4AJuP9Q(8 z!kUWL7HQu`jS+C%7=QlG!xU-e%il@969`Z{_$r<66arp*Fn`e+V}WbNU`D&xlSKUd z`LsIfcTe|G@^dTH5*WlsBfw|8YK#Sr8N){(UQ-rp3@0zm*nipW*+vONFzPIHRjtNY z5O!m@DZFnNy!HTII~Ix>BM>%YU`G1>MC$XIY`BnWkQ!qXwtpMrmMM0l#t7JE4F0!E ziceF2wVDFd7=dLQ6KSRZHAY~`#zd+qK#dWI%JQC>qm0!WCelp-YK%b87}2lwt{ z_Z{arYRnoXXhRH4!Tl$L_v<{9 From 60bc1582716e582fb3e965015a650fc9e0664f20 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Thu, 20 Nov 2025 13:16:59 -0500 Subject: [PATCH 341/401] Restored Sans Undertale with different dedication --- NPCs/CalamityGlobalTownNPC.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/NPCs/CalamityGlobalTownNPC.cs b/NPCs/CalamityGlobalTownNPC.cs index 953d749bc4..8f84d08d61 100644 --- a/NPCs/CalamityGlobalTownNPC.cs +++ b/NPCs/CalamityGlobalTownNPC.cs @@ -205,6 +205,7 @@ public static float TaxYieldFactor }; private static readonly string[] SkeletonMerchantNames = { + "Sans Undertale", // <@!534770496038895616> (done_22_) "Papyrus Undertale", // <@!262663471189983242> (nycro) "Gaster Undertale", // <@!924706306093379614> (enamoured) "Mr. Bones", // <@!359215912856977408> (jaybones.) From 2fb7067af2d71f373246997aa5d477257229d8f9 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 21 Nov 2025 23:41:26 -0500 Subject: [PATCH 342/401] Fixed stray pixel in Photosynthesis --- Items/Weapons/Magic/PhotosynthesisGlow.png | Bin 919 -> 723 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Items/Weapons/Magic/PhotosynthesisGlow.png b/Items/Weapons/Magic/PhotosynthesisGlow.png index dc3a8eeab57c341e36a53c520ad27bb483e20595..ca021b33a518c62b2111b9d701e37287ebad82df 100644 GIT binary patch literal 723 zcmeAS@N?(olHy`uVBq!ia0vp^ejv=j3?z4!T+jznjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCilo1AIbU`9o?&D$3F>{%2V9!rq_l`_-Obe{Q`zC9Sm4XX`WBsT&np?E-*m z*;8j61X8>uL4LvikpP433#B%o1ZROqWHAE+-(e7DJf6QI1t=&{;u=vBoS#-wo>-L1 z5RjOeSEA?V8lqsTXQ*f1eeJs?P|dc~2+uT6Pb~%xAcvJfijkFp5y18GvCkft`T`sKUU=*nn{X#8i+D z)&&rgrU2O>zyvgh39K^6(gMhW>M}Gi0LiMl&+A=mvh^s?HZxBb$B+p3w>NI)9aa!% zeV7=3=C^&mrOu(XF#S5Ol(;GAmeA8vTh~mxeL|2^QPq82P!QL|Nhdx& zv|1`+wrZV%w=k=@8%S=dZ#l3%n}jz4oQ}aMV~ND9klJ z_FH1@*L}88`v3EV+Zi2iXc=U049!k9Stftvx6Cn-M4N!)0_!9u?Yp|&QfcX}vn}fK zi5g4Z+>l88VitaXN45o*ViL=WDTWeLeuv$EHcyF3!pXMpcbH|t4-S?WbH0DoU3GWv z;{$?;G4I?jJU*OxciMJ~0?mgSKZ-OzKAUHKC*F4No-COi0!cMe!g6!YZJllZ=)m85 z51(1zscE16zTmTL-oC$gN)TZu|H}N+*}ZOCT#o(szv@q-qIXW& Z$KayN>LB>zVHzkjJzf1=);T3K0RRvK_@)2= delta 879 zcmV-#1CadF1(yeq83+ad0054vARUn*Ab$yPNLh0L01m?d01m?e$8V@)0009lNkl3VO+9FUSixLJ(gu+=!msz;!LPZNpBZ@GvC@K(XQ9%V|SjJE;x|tgb z7ZpWzRT`+YD}f845V8wN36+%ukr0tq6Z4+)4fr?XOn+yX`saOMc+NouIXry-xqo={ zSR^XhE2=}zCir}@cG$5R<(T{-EY3j+%P9DU{pIBc;q$e7U>4^RXv-}A@%I3}@XKOg!1@qwBIY;5O$I4+A z=Mu&h*WSAnmeNYvJ7FoXWAY<7Yupyt*K-%%W_80GOK!l^gInR3W!It}BYzgB$v zEmJY;WL2%JwC|$aYZ>H>OC`o0xT>;Op76)nbsZK*2qDCL@>`aK!XIZhX>e85#JDSm zV4oMY^>&WIesj}X*sUuDfyHTJTygR@yn@@M2`r8fLI@#*5JCtcgb+dqA%u{$A@a;I zW6m->k6c%O1^bOf9$e#|xw;9Tt7_trcc0{q;@|#nN8W3e7X=olNu;>G{r0==^8eDZ zDj&c@_ph?JD6lw9BE_jB`rc-`lCKq-002ovPDHLk FV1jT>p{oD@ From 884b179d7e06d3b382aef95ab67ba39edb19e240 Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Sat, 22 Nov 2025 11:42:07 +0700 Subject: [PATCH 343/401] manually edited donator list in CalamityLists --- CalamityLists.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CalamityLists.cs b/CalamityLists.cs index d43f7225c3..53bc46e825 100644 --- a/CalamityLists.cs +++ b/CalamityLists.cs @@ -255,7 +255,7 @@ public static void LoadLists() "Sable", "Salted Warlock", "Sharktank6", - "Shayy", // Current dev. Listed as "Shay" on Patreon. + //"Shayy", // Removed from circulation as the user in question committed acts undeserving of recognition "shredalert", "SirChaos189", "SomeRandomPerson", From 1ccd3d6a9f958f2e636cef6cc79d30e550bc5673 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 21 Nov 2025 23:43:41 -0500 Subject: [PATCH 344/401] Fixed Vivid Clarity explosions having wrong damage type --- Projectiles/Magic/VividExplosion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projectiles/Magic/VividExplosion.cs b/Projectiles/Magic/VividExplosion.cs index 141dd92601..2ab46185d6 100644 --- a/Projectiles/Magic/VividExplosion.cs +++ b/Projectiles/Magic/VividExplosion.cs @@ -16,7 +16,7 @@ public override void SetDefaults() Projectile.friendly = true; Projectile.ignoreWater = true; Projectile.tileCollide = false; - Projectile.DamageType = RogueDamageClass.Instance; + Projectile.DamageType = DamageClass.Magic; Projectile.penetrate = -1; Projectile.usesLocalNPCImmunity = true; Projectile.localNPCHitCooldown = 6; From 6f955e7c3ade24d875e30770c2d6fc5c16f29f6a Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 21 Nov 2025 23:45:20 -0500 Subject: [PATCH 345/401] Fixed structures not being properly protected from Fargo's Mutant items --- Utilities/WorldgenUtils.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Utilities/WorldgenUtils.cs b/Utilities/WorldgenUtils.cs index 1c18796fbb..b7317bfdfd 100644 --- a/Utilities/WorldgenUtils.cs +++ b/Utilities/WorldgenUtils.cs @@ -155,6 +155,10 @@ public static void AddProtectedStructure(Rectangle area, int padding = 0) // If Fargo's Mutant Mod is loaded, add to their Indestructible Rectangle list, which prevents structures from being trashed by Fargo's terrain tools. Mod fargos = CalamityMod.Instance.fargos; + paddedArea.X *= 16; + paddedArea.Y *= 16; + paddedArea.Width *= 16; + paddedArea.Height *= 16; fargos?.Call("AddIndestructibleRectangle", paddedArea); } } From 077d9c74f12433dce6f1efd706b36f5f349b967f Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 21 Nov 2025 23:46:26 -0500 Subject: [PATCH 346/401] Fixed Brimflame Frenzy using the wrong sound --- Items/Armor/Brimflame/BrimflameScowl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Items/Armor/Brimflame/BrimflameScowl.cs b/Items/Armor/Brimflame/BrimflameScowl.cs index 3f6d5cae92..525d6f4b99 100644 --- a/Items/Armor/Brimflame/BrimflameScowl.cs +++ b/Items/Armor/Brimflame/BrimflameScowl.cs @@ -13,7 +13,7 @@ namespace CalamityMod.Items.Armor.Brimflame public class BrimflameScowl : ModItem, ILocalizedModType { public new string LocalizationCategory => "Items.Armor.Hardmode"; - public static readonly SoundStyle ActivationSound = new("CalamityMod/Sounds/Custom/AbilitySounds/AngelicAllianceActivation"); + public static readonly SoundStyle ActivationSound = new("CalamityMod/Sounds/Custom/AbilitySounds/BrimflameAbility"); // TODO -- what the fuck is this? this is not how you implement a set bonus private bool frenzy = false; From af0952f5c9e8648cdeaacda9d872bd9a64114fe2 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Fri, 21 Nov 2025 23:52:17 -0500 Subject: [PATCH 347/401] Fixed Draedon bursting into gores even if not attacked --- NPCs/ExoMechs/Draedon.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NPCs/ExoMechs/Draedon.cs b/NPCs/ExoMechs/Draedon.cs index d0b90f2ba2..4149db13cd 100644 --- a/NPCs/ExoMechs/Draedon.cs +++ b/NPCs/ExoMechs/Draedon.cs @@ -802,7 +802,7 @@ public override void HitEffect(NPC.HitInfo hit) if (NPC.life > 0) return; - if (Main.netMode != NetmodeID.Server && !HasBeenKilled) + if (Main.netMode != NetmodeID.Server && !HasBeenKilled && HologramEffectTimer > 0f) { for (int i = 1; i <= 4; i++) { From 4c045bbda249041dff72709e60f16fb8740bebc0 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 22 Nov 2025 00:01:58 -0500 Subject: [PATCH 348/401] Fixed a boatload of holdouts not having owner checks for multiplayer --- Projectiles/Magic/NanoPurgeHoldout.cs | 29 +++++++------ Projectiles/Magic/OmicronHoldout.cs | 22 ++++++---- .../Ranged/ElementalEruptionHouldout.cs | 7 ++-- Projectiles/Ranged/FlakKrakenHoldout.cs | 25 ++++++----- Projectiles/Ranged/FlakToxicannonHoldout.cs | 25 ++++++----- Projectiles/Ranged/MagnaCannonHoldout.cs | 3 +- Projectiles/Ranged/ScorpioHoldout.cs | 25 ++++++----- .../Ranged/SuperradiantSlaughtererHoldout.cs | 12 ++++-- Projectiles/Ranged/TheHiveHoldout.cs | 41 +++++++++---------- Projectiles/Ranged/WildfireBloomHoldout.cs | 5 ++- 10 files changed, 107 insertions(+), 87 deletions(-) diff --git a/Projectiles/Magic/NanoPurgeHoldout.cs b/Projectiles/Magic/NanoPurgeHoldout.cs index 4127860c0a..764a582d36 100644 --- a/Projectiles/Magic/NanoPurgeHoldout.cs +++ b/Projectiles/Magic/NanoPurgeHoldout.cs @@ -70,20 +70,23 @@ public override void HoldoutAI() { SoundEngine.PlaySound(SoundID.Item91, Projectile.Center); - int projID = ModContent.ProjectileType(); - float shootSpeed = HeldItem.shootSpeed; - float inaccuracyRatio = 0.045f; - Vector2 shootDirection = Projectile.velocity.SafeNormalize(Vector2.UnitY); - Vector2 perp = shootDirection.RotatedBy(MathHelper.PiOver2); - - // Fire a pair of lasers, one with a negative offset, one with a positive offset. - for (int i = -1; i <= 1; i += 2) + if (Main.myPlayer == Projectile.owner) { - Vector2 spread = Main.rand.NextVector2CircularEdge(shootSpeed, shootSpeed); - Vector2 shootVelocity = shootDirection * shootSpeed + inaccuracyRatio * spread; - Vector2 splitBarrelPos = GunTipPosition + i * LaserOffsetByAnimationFrame[Projectile.frame] * perp; - Projectile.NewProjectile(Projectile.GetSource_FromThis(), splitBarrelPos, shootVelocity, projID, Projectile.damage, Projectile.knockBack, Projectile.owner); - SpawnFiringDust(splitBarrelPos, shootVelocity); + int projID = ModContent.ProjectileType(); + float shootSpeed = HeldItem.shootSpeed; + float inaccuracyRatio = 0.045f; + Vector2 shootDirection = Projectile.velocity.SafeNormalize(Vector2.UnitY); + Vector2 perp = shootDirection.RotatedBy(MathHelper.PiOver2); + + // Fire a pair of lasers, one with a negative offset, one with a positive offset. + for (int i = -1; i <= 1; i += 2) + { + Vector2 spread = Main.rand.NextVector2CircularEdge(shootSpeed, shootSpeed); + Vector2 shootVelocity = shootDirection * shootSpeed + inaccuracyRatio * spread; + Vector2 splitBarrelPos = GunTipPosition + i * LaserOffsetByAnimationFrame[Projectile.frame] * perp; + Projectile.NewProjectile(Projectile.GetSource_FromThis(), splitBarrelPos, shootVelocity, projID, Projectile.damage, Projectile.knockBack, Projectile.owner); + SpawnFiringDust(splitBarrelPos, shootVelocity); + } } } } diff --git a/Projectiles/Magic/OmicronHoldout.cs b/Projectiles/Magic/OmicronHoldout.cs index 9d3aef3fb7..afbd989b7c 100644 --- a/Projectiles/Magic/OmicronHoldout.cs +++ b/Projectiles/Magic/OmicronHoldout.cs @@ -107,7 +107,8 @@ public void Shoot(bool yBeam) } Owner.Calamity().GeneralScreenShakePower = 6.5f; - Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), GunTipPosition, firingVelocity3, ModContent.ProjectileType(), Projectile.damage * 32, Projectile.knockBack, Projectile.owner, 0, 0); + if (Main.myPlayer == Projectile.owner) + Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), GunTipPosition, firingVelocity3, ModContent.ProjectileType(), Projectile.damage * 32, Projectile.knockBack, Projectile.owner, 0, 0); for (int i = 0; i < 8; i++) { @@ -120,15 +121,18 @@ public void Shoot(bool yBeam) SoundStyle fire = new("CalamityMod/Sounds/Item/ArcNovaDiffuserBigShot"); SoundEngine.PlaySound(fire with { Volume = 0.2f, Pitch = 0.9f }, Projectile.Center); - for (int i = 0; i < 5; i++) + if (Main.myPlayer == Projectile.owner) { - firingVelocity3 = (shootDirection * 10).RotatedBy((0.035f * (i + 1)) * Utils.GetLerpValue(0, 55, Windup, true)); - Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), GunTipPosition, firingVelocity3 * (1 - i * 0.1f), ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner, 0, 2); - } - for (int i = 0; i < 5; i++) - { - firingVelocity3 = (shootDirection * 10).RotatedBy((-0.035f * (i + 1)) * Utils.GetLerpValue(0, 55, Windup, true)); - Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), GunTipPosition, firingVelocity3 * (1 - i * 0.1f), ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner, 0, 2); + for (int i = 0; i < 5; i++) + { + firingVelocity3 = (shootDirection * 10).RotatedBy((0.035f * (i + 1)) * Utils.GetLerpValue(0, 55, Windup, true)); + Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), GunTipPosition, firingVelocity3 * (1 - i * 0.1f), ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner, 0, 2); + } + for (int i = 0; i < 5; i++) + { + firingVelocity3 = (shootDirection * 10).RotatedBy((-0.035f * (i + 1)) * Utils.GetLerpValue(0, 55, Windup, true)); + Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), GunTipPosition, firingVelocity3 * (1 - i * 0.1f), ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner, 0, 2); + } } Particle pulse3 = new GlowSparkParticle(GunTipPosition, shootDirection * 18, false, 6, 0.057f, EffectsColor, new Vector2(1.7f, 0.8f), true); diff --git a/Projectiles/Ranged/ElementalEruptionHouldout.cs b/Projectiles/Ranged/ElementalEruptionHouldout.cs index bb8f4c68f1..b8fb940c22 100644 --- a/Projectiles/Ranged/ElementalEruptionHouldout.cs +++ b/Projectiles/Ranged/ElementalEruptionHouldout.cs @@ -47,13 +47,14 @@ public override void HoldoutAI() { SoundEngine.PlaySound(SoundID.Item34, Projectile.Center); Owner.PickAmmo(Owner.ActiveItem(), out _, out float shootSpeed, out int damage, out float knockback, out _, Main.rand.NextFloat() < 0.70f); - for (int i = 0; i < 2; i++) + if (Main.myPlayer == Projectile.owner) { - Projectile.NewProjectile(Projectile.GetSource_FromThis(), GunTipPosition, (Projectile.velocity * 10).RotatedByRandom(0.12f), ModContent.ProjectileType(), damage, knockback, Projectile.owner); + for (int i = 0; i < 2; i++) + Projectile.NewProjectile(Projectile.GetSource_FromThis(), GunTipPosition, (Projectile.velocity * 10).RotatedByRandom(0.12f), ModContent.ProjectileType(), damage, knockback, Projectile.owner); } ShotsFired++; ShotCooldown = HeldItem.useTime; - if (FireBlobs == 0) + if (FireBlobs == 0 && Main.myPlayer == Projectile.owner) { Vector2 newVel = (Projectile.velocity * 9); Vector2 newPos = GunTipPosition + Projectile.velocity.SafeNormalize(Vector2.UnitX) * 36f; diff --git a/Projectiles/Ranged/FlakKrakenHoldout.cs b/Projectiles/Ranged/FlakKrakenHoldout.cs index 362c7e66a2..89c2ef86cd 100644 --- a/Projectiles/Ranged/FlakKrakenHoldout.cs +++ b/Projectiles/Ranged/FlakKrakenHoldout.cs @@ -72,17 +72,20 @@ public override void HoldoutAI() break; } - // Spawns the projectile. - Projectile.NewProjectileDirect( - Projectile.GetSource_FromThis(), - GunTipPosition, - direction * itemShootSpeed, - ProjectileType(), - itemDamage, - itemKnockback, - Projectile.owner, - rocketTypeShot, - ownerToMouse.Length()); + if (Main.myPlayer == Projectile.owner) + { + // Spawns the projectile. + Projectile.NewProjectileDirect( + Projectile.GetSource_FromThis(), + GunTipPosition, + direction * itemShootSpeed, + ProjectileType(), + itemDamage, + itemKnockback, + Projectile.owner, + rocketTypeShot, + ownerToMouse.Length()); + } // Applies the knockback to the player. Owner.velocity += ownerToMouse.SafeNormalize(Vector2.UnitY) * -OwnerKnockbackStrength; diff --git a/Projectiles/Ranged/FlakToxicannonHoldout.cs b/Projectiles/Ranged/FlakToxicannonHoldout.cs index 1bf6ce82a7..30e1a3e81d 100644 --- a/Projectiles/Ranged/FlakToxicannonHoldout.cs +++ b/Projectiles/Ranged/FlakToxicannonHoldout.cs @@ -69,17 +69,20 @@ public override void HoldoutAI() break; } - // Spawns the projectile. - Projectile.NewProjectileDirect( - Projectile.GetSource_FromThis(), - GunTipPosition, - direction * itemShootSpeed, - ProjectileType(), - itemDamage, - itemKnockback, - Projectile.owner, - rocketTypeShot, - ownerToMouse.Length()); + if (Main.myPlayer == Projectile.owner) + { + // Spawns the projectile. + Projectile.NewProjectileDirect( + Projectile.GetSource_FromThis(), + GunTipPosition, + direction * itemShootSpeed, + ProjectileType(), + itemDamage, + itemKnockback, + Projectile.owner, + rocketTypeShot, + ownerToMouse.Length()); + } // Applies the knockback to the player. Owner.velocity += ownerToMouse.SafeNormalize(Vector2.UnitY) * -OwnerKnockbackStrength; diff --git a/Projectiles/Ranged/MagnaCannonHoldout.cs b/Projectiles/Ranged/MagnaCannonHoldout.cs index ef4ea8c38e..cf78fee5f6 100644 --- a/Projectiles/Ranged/MagnaCannonHoldout.cs +++ b/Projectiles/Ranged/MagnaCannonHoldout.cs @@ -56,7 +56,8 @@ public override void HoldoutAI() SoundEngine.PlaySound(MagnaCannon.Fire, Projectile.position); Vector2 shootVelocity = Projectile.velocity.SafeNormalize(Vector2.UnitY) * BulletSpeed; - Projectile.NewProjectile(Projectile.GetSource_FromThis(), GunTipPosition, shootVelocity.RotatedByRandom(MathHelper.ToRadians(9f)), ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack * (FullyCharged ? 3 : 1), Projectile.owner); + if (Main.myPlayer == Projectile.owner) + Projectile.NewProjectile(Projectile.GetSource_FromThis(), GunTipPosition, shootVelocity.RotatedByRandom(MathHelper.ToRadians(9f)), ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack * (FullyCharged ? 3 : 1), Projectile.owner); for (int i = 0; i <= 3; i++) { Dust dust = Dust.NewDustPerfect(GunTipPosition, 187, shootVelocity.RotatedByRandom(MathHelper.ToRadians(15f)) * Main.rand.NextFloat(0.9f, 1.2f), 0, default, Main.rand.NextFloat(1.5f, 2.3f)); diff --git a/Projectiles/Ranged/ScorpioHoldout.cs b/Projectiles/Ranged/ScorpioHoldout.cs index 36669dd5f8..10b014a47b 100644 --- a/Projectiles/Ranged/ScorpioHoldout.cs +++ b/Projectiles/Ranged/ScorpioHoldout.cs @@ -142,17 +142,20 @@ public void ShootRocket(Item item, bool isRMB) break; } - // Spawns the projectile. - Projectile.NewProjectileDirect( - Projectile.GetSource_FromThis(), - GunTipPosition, - projectileVelocity.RotatedByRandom(isRMB ? 0f : MathHelper.PiOver4) * projSpeed * (isRMB ? 1f : Main.rand.NextFloat(0.8f, 1f)), - isRMB ? ProjectileType() : ProjectileType(), - damage, - knockback, - Projectile.owner, - rocketType, - projSpeed); + if (Main.myPlayer == Projectile.owner) + { + // Spawns the projectile. + Projectile.NewProjectileDirect( + Projectile.GetSource_FromThis(), + GunTipPosition, + projectileVelocity.RotatedByRandom(isRMB ? 0f : MathHelper.PiOver4) * projSpeed * (isRMB ? 1f : Main.rand.NextFloat(0.8f, 1f)), + isRMB ? ProjectileType() : ProjectileType(), + damage, + knockback, + Projectile.owner, + rocketType, + projSpeed); + } // Inside here go all the things that dedicated servers shouldn't spend resources on. // Like visuals and sounds. diff --git a/Projectiles/Ranged/SuperradiantSlaughtererHoldout.cs b/Projectiles/Ranged/SuperradiantSlaughtererHoldout.cs index 934744d2eb..43c104248c 100644 --- a/Projectiles/Ranged/SuperradiantSlaughtererHoldout.cs +++ b/Projectiles/Ranged/SuperradiantSlaughtererHoldout.cs @@ -83,9 +83,12 @@ public override void HoldoutAI() SoundEngine.PlaySound(new SoundStyle("CalamityMod/Sounds/Custom/MeatySlash"), GunTipPosition); // Throws a lingering saw at the cursor that deals 3x damage (since the holdout already deals 2x) - float clampedMouseDist = MathHelper.Clamp(Vector2.Distance(GunTipPosition, Owner.Calamity().mouseWorld), 0f, 960f); - float adjustedMouseDist = clampedMouseDist / 21f; - Projectile.NewProjectile(Projectile.GetSource_FromThis(), GunTipPosition, Projectile.velocity.SafeNormalize(Vector2.UnitY) * adjustedMouseDist, ModContent.ProjectileType(), (int)(Projectile.damage * 1.5f), Projectile.knockBack, Projectile.owner); + if (Main.myPlayer == Projectile.owner) + { + float clampedMouseDist = MathHelper.Clamp(Vector2.Distance(GunTipPosition, Owner.Calamity().mouseWorld), 0f, 960f); + float adjustedMouseDist = clampedMouseDist / 21f; + Projectile.NewProjectile(Projectile.GetSource_FromThis(), GunTipPosition, Projectile.velocity.SafeNormalize(Vector2.UnitY) * adjustedMouseDist, ModContent.ProjectileType(), (int)(Projectile.damage * 1.5f), Projectile.knockBack, Projectile.owner); + } // Special case: right-clicking while not holding left-click // This is to keep it friendly to use both fires at the same time, but end the animation early if not @@ -131,7 +134,8 @@ public override void HoldoutAI() int sawLevel = (SawPower >= 1f).ToInt() + (SawPower >= 0.25f).ToInt(); // ai[0] determines which slashes are drawn. ai[1] is the saw's timer variable. ai[2] stores the saw's pierce. - Projectile.NewProjectile(Projectile.GetSource_FromThis(), GunTipPosition, Projectile.velocity.SafeNormalize(Vector2.UnitY) * SuperradiantSlaughterer.ShootSpeed, ModContent.ProjectileType(), (int)(Projectile.damage * sawDamageMult), Projectile.knockBack, Projectile.owner, sawLevel, 0f, sawPierce); + if (Main.myPlayer == Projectile.owner) + Projectile.NewProjectile(Projectile.GetSource_FromThis(), GunTipPosition, Projectile.velocity.SafeNormalize(Vector2.UnitY) * SuperradiantSlaughterer.ShootSpeed, ModContent.ProjectileType(), (int)(Projectile.damage * sawDamageMult), Projectile.knockBack, Projectile.owner, sawLevel, 0f, sawPierce); NoSawOnHoldout = true; OffsetLengthFromArm -= 4f + 12f * SawPower; diff --git a/Projectiles/Ranged/TheHiveHoldout.cs b/Projectiles/Ranged/TheHiveHoldout.cs index a282f52ad9..83af0f3f97 100644 --- a/Projectiles/Ranged/TheHiveHoldout.cs +++ b/Projectiles/Ranged/TheHiveHoldout.cs @@ -140,15 +140,9 @@ public void ShootRocket() SoundStyle fire = new("CalamityMod/Sounds/Custom/PlagueSounds/PBGBarrageLaunch"); SoundEngine.PlaySound(fire with { Volume = 0.5f, Pitch = 0.1f }, Projectile.Center); - Projectile.NewProjectileDirect( - Projectile.GetSource_FromThis(), - GunTipPosition, - shootDirection * projSpeed * 0.3f, - ProjectileType(), - damage * 10, - knockback, - Projectile.owner, - rocketType); + if (Main.myPlayer == Projectile.owner) + Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), GunTipPosition, shootDirection * projSpeed * 0.3f, ProjectileType(), damage * 10, knockback, Projectile.owner, rocketType); + PostFireCooldown = 75; } else @@ -156,20 +150,23 @@ public void ShootRocket() SoundStyle fire = new("CalamityMod/Sounds/Custom/PlagueSounds/PBGBarrageLaunch"); SoundEngine.PlaySound(fire with { Volume = 0.4f, Pitch = 0.7f }, Projectile.Center); - int numProj = 4; - float rotation = MathHelper.ToRadians(MathHelper.Clamp(35 - VelocityMultiplier * 26, 2, 25)); - for (int i = 0; i < numProj; i++) + if (Main.myPlayer == Projectile.owner) { - Vector2 perturbedSpeed = (shootDirection).RotatedBy(MathHelper.Lerp(-rotation, rotation, i / (float)(numProj - 1))); - Projectile.NewProjectileDirect( - Projectile.GetSource_FromThis(), - GunTipPosition, - perturbedSpeed * projSpeed * VelocityMultiplier, - ProjectileType(), - damage, - knockback, - Projectile.owner, - rocketType); + int numProj = 4; + float rotation = MathHelper.ToRadians(MathHelper.Clamp(35 - VelocityMultiplier * 26, 2, 25)); + for (int i = 0; i < numProj; i++) + { + Vector2 perturbedSpeed = (shootDirection).RotatedBy(MathHelper.Lerp(-rotation, rotation, i / (float)(numProj - 1))); + Projectile.NewProjectileDirect( + Projectile.GetSource_FromThis(), + GunTipPosition, + perturbedSpeed * projSpeed * VelocityMultiplier, + ProjectileType(), + damage, + knockback, + Projectile.owner, + rocketType); + } } PostFireCooldown = 30; } diff --git a/Projectiles/Ranged/WildfireBloomHoldout.cs b/Projectiles/Ranged/WildfireBloomHoldout.cs index dc4086d841..ffac8c4fd9 100644 --- a/Projectiles/Ranged/WildfireBloomHoldout.cs +++ b/Projectiles/Ranged/WildfireBloomHoldout.cs @@ -41,10 +41,11 @@ public override void HoldoutAI() { SoundEngine.PlaySound(SoundID.Item34, Projectile.Center); Owner.PickAmmo(Owner.ActiveItem(), out _, out float shootSpeed, out int damage, out float knockback, out _, Main.rand.NextBool(2)); - Projectile.NewProjectile(Projectile.GetSource_FromThis(), GunTipPosition, (Projectile.velocity * 9).RotatedByRandom(0.08f), ModContent.ProjectileType(), damage, knockback, Projectile.owner); + if (Main.myPlayer == Projectile.owner) + Projectile.NewProjectile(Projectile.GetSource_FromThis(), GunTipPosition, (Projectile.velocity * 9).RotatedByRandom(0.08f), ModContent.ProjectileType(), damage, knockback, Projectile.owner); ShotsFired++; ShotCooldown = HeldItem.useTime; - if (FireBlobs == 0) + if (FireBlobs == 0 && Main.myPlayer == Projectile.owner) { float randAngle = Main.rand.NextFloat(8f, 15f); Vector2 newVel = (Projectile.velocity * 9).RotatedBy(MathHelper.ToRadians(randAngle)) * 2f; From 0549b604f2c65c9e8adf0f60eaae32051987cedd Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 22 Nov 2025 00:07:56 -0500 Subject: [PATCH 349/401] Fixed Wulfrum Treasure Pinger lighting --- Systems/TilePingerSystem.cs | 50 +++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/Systems/TilePingerSystem.cs b/Systems/TilePingerSystem.cs index f28c9cb3b1..b134b0f481 100644 --- a/Systems/TilePingerSystem.cs +++ b/Systems/TilePingerSystem.cs @@ -6,6 +6,7 @@ using Terraria; using Terraria.Audio; using Terraria.DataStructures; +using Terraria.GameContent.Drawing; using Terraria.Graphics.Effects; using Terraria.Graphics.Light; using Terraria.ID; @@ -83,6 +84,8 @@ public override void Load() pingedTiles = new Dictionary>(); pingedNonSolidTiles = new Dictionary>(); tileEffects = new Dictionary(); + + On_TileDrawing.DrawTiles_GetLightOverride += ForceSufficientLight; } public override void Unload() @@ -93,6 +96,42 @@ public override void Unload() tileEffects = null; } + private static Color ForceSufficientLight(On_TileDrawing.orig_DrawTiles_GetLightOverride orig, TileDrawing self, int j, int i, Tile tileCache, ushort typeCache, short tileFrameX, short tileFrameY, Color tileLight) + { + Color returnColor = orig(self, j, i, tileCache, typeCache, tileFrameX, tileFrameY, tileLight); + foreach (IPingedTileEffect effect in tileEffects.Values) + { + // Nothing else uses this so like should be okay + if (effect is WulfrumPingTileEffect w && effect.Active && effect.ShouldRegisterTile(i, j)) + { + float distanceFromCenter = (new Point(i, j).ToWorldCoordinates() - WulfrumPingTileEffect.PingCenter).Length(); + float currentExpansion = MathHelper.Clamp(WulfrumPingTileEffect.PingProgress * WulfrumPingTileEffect.MaxPingLife / (float)WulfrumPingTileEffect.MaxPingTravelTime, 0f, 1f) * WulfrumPingTileEffect.MaxPingRadius; + + if (distanceFromCenter - 8 > currentExpansion) + return returnColor; + + float brightness = 1f; + Tile tile = Framing.GetTileSafely(i, j); + //Counteracts slopes and half tiles being too bright + if (tile.Slope != SlopeType.Solid || tile.IsHalfBlock) + brightness = 0.64f; + + //Fade on the edges + if (distanceFromCenter + 8 > currentExpansion) + brightness *= 1 - (distanceFromCenter - currentExpansion + 8f) / 16f; + + //Fade away with the effect + brightness *= 1 - Math.Max(WulfrumPingTileEffect.PingProgress - 0.9f, 0) / (0.1f); + + if (tileLight.R < 200 * brightness) tileLight.R = (byte)(200 * brightness); + if (tileLight.G < 200 * brightness) tileLight.G = (byte)(200 * brightness); + if (tileLight.B < 200 * brightness) tileLight.B = (byte)(200 * brightness); + returnColor = tileLight; + } + } + return returnColor; + } + public static bool AddPing(string effectName, Vector2 position, Player pinger) { if (!Main.dedServ) @@ -231,11 +270,11 @@ public override void DrawEffects(int i, int j, int type, SpriteBatch spriteBatch public class WulfrumPingTileEffect : IPingedTileEffect, ILoadable { internal static Texture2D emptyFrame; - const int MaxPingLife = 350; - const int MaxPingTravelTime = 60; + public const int MaxPingLife = 350; + public const int MaxPingTravelTime = 60; const float PingWaveThickness = 50f; - const float MaxPingRadius = 1700f; + public const float MaxPingRadius = 1700f; public static Vector2 PingCenter = Vector2.Zero; public static int PingTimer = 0; public static float PingProgress => (MaxPingLife - PingTimer) / (float)MaxPingLife; @@ -316,7 +355,8 @@ public void DrawTile(Point pos) Main.spriteBatch.Draw(emptyFrame, pos.ToWorldCoordinates() - Main.screenPosition, null, Color.White, 0, new Vector2(emptyFrame.Width / 2f, emptyFrame.Height / 2f), 16f, 0, 0); } - public void EditDrawData(int i, int j, ref TileDrawInfo drawData) + // CIT 16JUL2025: Tile lighting override is now applied via an On edit; this code is duplicated there, and thus is no longer needed here. + /*public void EditDrawData(int i, int j, ref TileDrawInfo drawData) { float distanceFromCenter = (new Point(i, j).ToWorldCoordinates() - PingCenter).Length(); float currentExpansion = MathHelper.Clamp(PingProgress * MaxPingLife / (float)MaxPingTravelTime, 0f, 1f) * MaxPingRadius; @@ -340,7 +380,7 @@ public void EditDrawData(int i, int j, ref TileDrawInfo drawData) if (drawData.tileLight.R < 200 * brightness) drawData.tileLight.R = (byte)(200 * brightness); if (drawData.tileLight.G < 200 * brightness) drawData.tileLight.G = (byte)(200 * brightness); if (drawData.tileLight.B < 200 * brightness) drawData.tileLight.B = (byte)(200 * brightness); - } + }*/ public void UpdateEffect() { From 21085e95907b9209ef8f53dc6862b897e0226279 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 22 Nov 2025 00:13:43 -0500 Subject: [PATCH 350/401] Added new donor town NPC names --- NPCs/CalamityGlobalTownNPC.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NPCs/CalamityGlobalTownNPC.cs b/NPCs/CalamityGlobalTownNPC.cs index 8f84d08d61..8ed43caf88 100644 --- a/NPCs/CalamityGlobalTownNPC.cs +++ b/NPCs/CalamityGlobalTownNPC.cs @@ -273,6 +273,7 @@ public static float TaxYieldFactor "Syethas", // <@!325413275066171393> (cosmicstariight) "Nextdoor Psycho", // <@!173261518572486656> (nextdoorpsycho) "Mike Cyclops", // <@!702327497475227741> (seichoseicho) + "Derin", // <@!466703979695308820> (god_15) }; private static readonly string[] ZoologistNames = { @@ -352,6 +353,7 @@ public static float TaxYieldFactor { "Bear", // <@!183424826407518208> (lilac_vrt_olligoci) "Storm", // <@!620383533516718085> (airwaveslr) + "Hognar the Wicked", // <@!766511001356468237> (xzier_tengal) }; private static readonly string[] TownCatOrangeTabbyNames = { @@ -364,6 +366,7 @@ public static float TaxYieldFactor private static readonly string[] TownCatSilverNames = { "Archie", // <@!303022375191183360> (jackshiz) + "Hognar the Wicked", // <@!766511001356468237> (xzier_tengal) }; private static readonly string[] TownCatWhiteNames = null; From 73bab6264e42a1dddfebbff7adc3879b61d3b032 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 22 Nov 2025 00:16:17 -0500 Subject: [PATCH 351/401] Fixed Skyline Wings horizontal flight speed being hardcapped --- Items/Accessories/Wings/SkylineWings.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Items/Accessories/Wings/SkylineWings.cs b/Items/Accessories/Wings/SkylineWings.cs index 58ab67d809..9f3ffac83f 100644 --- a/Items/Accessories/Wings/SkylineWings.cs +++ b/Items/Accessories/Wings/SkylineWings.cs @@ -12,7 +12,7 @@ public class SkylineWings : ModItem, ILocalizedModType public new string LocalizationCategory => "Items.Accessories.Wings"; public override void SetStaticDefaults() { - ArmorIDs.Wing.Sets.Stats[Item.wingSlot] = new WingStats(80, 6.5f, 1f); + ArmorIDs.Wing.Sets.Stats[Item.wingSlot] = new WingStats(80, 6.25f, 1f); } public override void SetDefaults() @@ -38,11 +38,6 @@ public override void VerticalWingSpeeds(Player player, ref float ascentWhenFalli constantAscend = 0.1f; } - public override void HorizontalWingSpeeds(Player player, ref float speed, ref float acceleration) - { - speed = 6.25f; - } - public override void AddRecipes() { CreateRecipe(). From 3645027006aa188c30fcb132b307aa5c519a581b Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 22 Nov 2025 00:18:55 -0500 Subject: [PATCH 352/401] Deerclops screenshake is now affected by our screenshake config --- ILEditing/ILChangesLoading.cs | 2 ++ ILEditing/VanillaStupidityFixingILChanges.cs | 22 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/ILEditing/ILChangesLoading.cs b/ILEditing/ILChangesLoading.cs index a3a7a237e2..056dc43d69 100644 --- a/ILEditing/ILChangesLoading.cs +++ b/ILEditing/ILChangesLoading.cs @@ -12,6 +12,7 @@ using Terraria.GameContent.Liquid; using Terraria.GameContent.UI.Elements; using Terraria.GameContent.UI.States; +using Terraria.Graphics.CameraModifiers; using Terraria.Graphics.Light; using Terraria.Map; using Terraria.ModLoader; @@ -139,6 +140,7 @@ public override void OnModLoad() // Removal of vanilla stupidity IL_NPC.VanillaHitEffect += PreventLavaSlimeLavaDrop; + IL_PunchCameraModifier.Update += PunchCameraUsesScreenshakeConfig; IL_Player.UpdateBuffs += RemoveFeralBiteRandomDebuffs; IL_Sandstorm.HasSufficientWind += DecreaseSandstormWindSpeedRequirement; IL_Item.TryGetPrefixStatMultipliersForItem += RelaxPrefixRequirements; diff --git a/ILEditing/VanillaStupidityFixingILChanges.cs b/ILEditing/VanillaStupidityFixingILChanges.cs index c9e5a5ee49..4cced8ec61 100644 --- a/ILEditing/VanillaStupidityFixingILChanges.cs +++ b/ILEditing/VanillaStupidityFixingILChanges.cs @@ -158,6 +158,28 @@ private static void RemoveFeralBiteRandomDebuffs(ILContext il) } #endregion + #region Make PunchCameraModifier Affected by Screenshake Config + private static void PunchCameraUsesScreenshakeConfig(ILContext il) + { + // Allow the screenshake from PunchCameraModifier to scale based on our screenshake power config. + var cursor = new ILCursor(il); + + // There are 3 local variables that control the strength of the screenshake in separate ways, but they all get multiplied together at the end. + // Thus it doesn't matter at all which one is multiplied to. Here I chose num2. + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchStloc2())) + { + LogFailure("Make PunchCameraModifier Affected by Screenshake Config", "Could not move to the location to inject code."); + return; + } + + // Emit a delegate which grabs the value of the screenshake config. Then multiply the local variable by it. + cursor.Emit(OpCodes.Ldloc_1); + cursor.EmitDelegate>(() => CalamityConfig.Instance.ScreenshakePower); + cursor.Emit(OpCodes.Mul); + cursor.Emit(OpCodes.Stloc_1); + } + #endregion + #region Make Meteorite Explodable private static void MakeMeteoriteExplodable(ILContext il) { From e0b94474047528ed84cab23009c1c8f5c68e021b Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 22 Nov 2025 00:32:49 -0500 Subject: [PATCH 353/401] Unstrawberried Brimstone Witch --- NPCs/TownNPCs/WITCH.png | Bin 9219 -> 11531 bytes NPCs/TownNPCs/WITCH_Head.png | Bin 500 -> 499 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/NPCs/TownNPCs/WITCH.png b/NPCs/TownNPCs/WITCH.png index 7b9a6af20ed3f3460a90af58f05d37ac86ffca80..9c0c8c8b18f4eeae070b00b2a07caa960cdb7f7b 100644 GIT binary patch literal 11531 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 literal 9219 zcmbVyc{r5+|1L=)RG1n|d`d-BNMp$sLWC*Xs6ob(ER81X*!$Q@Bc*6e8cWuOnff5x zSh7sX8X|idMu=(byYn7>uk$_Eb$7#{}* zhk)_rOBUesEC&bofxUackp|1j4193pmPDg7xel&X3-CE*u=vc;idDR)G#PulBu_bj5zuC*6izIOn08DSKG=uAxLUhi-Yi znCK7NhBqY+Pp-x6Iwu&3IPYtNFl%VuA@m(#b}jkH-AO;SZ= zlOKXfTO;90q7z5@kegetmWFD7hh9n3ShZ|VmPe;-!W|4UeWm)4RFgIPb4wlJ0(#o9{PL_$%IUT>-3bk-;BQ6ZZ; z5{GEbJ%dog>S{)+LNvw~M!d6Ool8BlVQ(gn5C5|DsBUF*AY6zhjxIZe^G)fT?IdGh zp^H=2sD|#&+*t`jTNYi)bgO&*efz6}G`C;H_E4R5g~L&pV%jrANM-auRJL;WnO>bA zAKrSE%rA+b4%vK-NR>+7Up2e(R<MT-dw%#LD7OP z!P6E#5nK1u-r$S0j8S!I&G;FVm11k(QKJr5ruHcuMSEirm9-TxvO%d|Y1%HAc7H{4 z-e}^Pk=!yjs--sOk~ck|>i0Zi)qNis#bPF+6ZX@yr)T#$w}h?T=ykam|&d$Ikm*U!Ei5N+R2k8}3k zOIL~AP{J8Wl?Ff+Z2jz^eU?x9&C<2#9)$j^LtoVjZdM(~H75^B7}jq5Q#5?gaD_5Z zbC4z;zVZUqJ?nHtcL0WF{f*c)ibjRhne#-ks$^23wC0*Y@d8(Bs9hx=Wvi6= zk0LJB(=KqES)Vtd5)@_q^V|k?nblkUmU(F8de<_lqe!zYH?3q_8?~`9c7gw=Mow_` zdX?hTa(u7a?H3s_lM|1K!vUgesm4$%{9|@x8Nj8U%-A zKKRBJd$U*#m+lt*OY{>=he)n_D)e&z-x<#HxBw|xIl7&=oK?XyRObJzFLRarqXpIk zLtneGo?qgnM3l~*u$DXJfN3X*B--8d-QP~KO1v{TFPC(w)WR&-Av|xYrBCUGuMGq{=Vg((Q9MwTUkgoGodA4mwhw zTexj~)?Icfj#RT$wf#S)N2mw3K6AW~j2NBpgL6JS%2?>*vTH1PoHql_%~3z*5Hy=x zm&eHKvvr8pI{($|vGy@s&&J7`7b4NFpdqEa8b`L)*Xug{1ZE_T3`sgu%yI{WhdTWV z(UTRIOMP=-x~i|Ro>Xs$_+@^{G1_m$4rVo?SYCP4Y?5fZ^6i#;rp> z%`r8HR{|XNQC0exau)+WaQG|*2|gttGLRj2B1VGeKYP~U2|8ZAWdy>P7t+|IbqZ40 za4Cvdlp5T#h_dQZl%%ImjN)Uusd0qT-{f7X37%(eU?J7jjoRz62Nl~>t8-5ICfr~Q zz{u_okOAw~Q1vUt{H(=s($e17b15(E#0_DE6UsJ(%p-Js&oUmG;q7VOsJD!lM12Sn z&|RnbT$9eO;VIY>nC~f5?)CcTu?2Jr_Vh}yk@-H5CJX8hb|%WJe@YS&`F}F<5S>j} zqMDp&lApyU-M>u6G|tOKANS6dRM(t^L#I_O7D$}S=z<-{#70oV*S>AKTfPzWZ+LP_8Dvj5zoZ65F; zV#0dQF^|E|q=+_W;`^mpMJI{wkkb^Wl$a$P7Xwll%3r-uD_{3XL%fP^i^IF$?kzL$ zfe1&x@LY}(>4AF6%huC5^a-D-)Q)@2`M?lRoQtp>}S{E}`^ zNe!~FG>;x9O`4Y0HDgv>a8Txxv9-+Lz@W@TFFKK!cf2CWqrXcy={Thxb%C#x@<$LAD1a|lJ~nwQjUzs<}dLgzg%YjGS-oy*Qy^3 zle_|#?LIfj`wEitzA&wqL~Zf1HR|@qS$64X%Uq;9%FU6@W8JFw>?jYeyoipg%haOV z&zQll`cCo+i5#&H%0yO7Z2LB+^}G^FM(5!Be#C#tK3-uEuJfDui}R6x1z(5#x2evB z-5u8F#W~7P#remRj%v+apM3buPP?Y`yulYDrepqYa^6CVkVABue}PC~q!UCKaY z`L^+FprsTShP0iqhpVPzC#)4Gz=eB|0A-FlkpXnv;w?((vj67MPU64RT_)Bkee*PB z7lGK}bGV%pL5z*;2}1`Ri*Xg}hmmiWUW*K|Pvdz`Ks*F>74LjQSg-cF^u%QBnZ6D+ z_$>>1(6G=Iv)VwM=g51aMdY=6@|qal9?HzN`AAIn4XFf{l~XxnNIy;-ej=bfYw3uLO8*k8cDSXoNud-y)iz|!0?O0TkqfN+sBXc&G?trL^I1e}$f<1NzD~)moAuejb z6=vjsU|!*W5Bk@*!4AAdi_k5p+{(9Ki3rgLc^Fuhk+wWVsB$2dSQ+TRy`U*kyre}* zyxd)uIb=hsexT8Z=E8t3F{mp!*Yhx5_CK3}@I^dJe**X_frF{qYP7fR+l_e)k92sPez@m?4rX2@d$beZ${NpzcS8+lS+~e8Y?i{`)*=Edz^S+ zSK(rR)RU8uwZeMop+n&5BH}#oy{A*k4hB4j@DE|Fg znO{|uw5Nx~r}#+!7a8u=BsCv1|9JUqSlW%|L-a{G&>UHTpgAlq-wXYsrAe_ce$Or| zp&=94Oh9pd!=Q<&Ge5rfbSvq0VWdoylUu0%$d^4dPrEPDZg(6SnYV?x=wU`L|J6mO zR0N5LrsEzVc~m}~T#)=cb{&rBd^Hndy3nyn(09~0hE+Oy=CyMBJ({rgn3oILzN!wn zT?*Drj^KSTZoLv#5zVlwjpw2%<+$DH36Y@)%*p-Y)p8s4y1HJ??kT|_|2&4pyxf}D zHK&}6P3GkWT|FC}hmk89^k$9w|-2^Q5GwHei3zq1zj3Ok_OM)Gzd-kZ|9jIZqh=rF# z0hQ0u!A-GtUM>!d720`oKtEg^|A2;2AqXlz&Rs$gj;P%o=y2kh3mtl;mGoQe!4RU6 zfO&7KUrEz#7tA01CX6r8=(pWrOOPS1TH=Et{Rhm*?*15-C{If+!|GydB@2r0nLc)) zIsYyrmseU9jRGTvpgP+EYlI1Amk|GRVgZ;X{+o;2J7go@_hZ)u4pnb`k#F07MRot1 zqNXE%s5n^ZcFicW`lX3ON6Ep->A1-U?t&1{t+8xC-|ug`^`k&VfQPT@mCp4rF> zt^PAZ#Hr+4UBZp>VFN5gwCm>73Djy=g=Jl5tB5jk@ZI9s{n6Q^J5w6bP)QdQ5uNq7BhC<41`KC%IP@xuEg1nQQ0vgNzk${$z=AZl59Z!!m-bp=x= ztWSg9;7_tdrEJWL%mgG2Qa^i*Tcz969bb`b+1KVrh$9v*PhpcxKvF@T;&UxKAlO0T}G{N<$ zcq&QK|8J1CQ~B)rd}>DrZOUgnY@&592ygA9f?SbjHlN#QdP79N? zC_+a;aj?VWLcdV-3xx7dQ~!&=_FG>}Nc|4pJuyC#0K$E;kv3TcP%x{425EDjtwEbX zwJ68HBrWul514M}6569oBpm2Ozh)K;mi;}MA*|;>KlD!9;mZ8Kv8mAY5z7|>#u@uN z4#@o>$p_v5k}MM?w?mSnuChroZ^jNuX3xPLl6=(a@_P)pE%A}krB81jtl{Yd-Ch^WXOP#)?G(UZMFZxQh{yZ88mk2LXZ z7bj|P`BZaV9v1S7XM7nW(Q#HpL&uwq?z8Fkf2khbU1FR8NYIlluM?5J?Z1739{+$l z#$~w0dL+7B^>ApciK5ZBo1!)zG%DY4X(E9;an%V9!x*X(iA|?sJDPOuX=u3gd1jRi^Hy3#AFICZUwLHmxU5zoxhv$%| z?DBn>;UhmI{xOwUGS0AxXtN|B-Fwx3_8r}$RO;2#ifVw;bZ?3u+R^?7%N*eAj#+`L zC#;2HLoQP#N-0f1XhnZ*x15)&efHwNm}@NXUTv*i(K`g@?+I&> z9n`mRFsMmGXOu$#R6sx4q8+%q0Sq{SwHi9Z9W54Mng6l_KB4cC=7rSq~hr$tnt^R)@+d5!3 zfY5q8@eI))y2*{#?}SU=7|IEy2gUCPIMvJN=Z`Pm{nOGtglL(NiXRDjvDN&J%I9+l zYG30|-@cOO$Az2LI<6?%OnQP>TPv%ozwP?gqLR1R&Cbm7Wp}1n>>_FXx~g{We*8`U z9*w%aF7G~xdj!0DoDSHU);Vof$IWO~tI?v*{FwD{aNR=`b)&iJ!;O9>9e?tv@r-+0 z6e8Ti!64x+pM6Z46ddtE&1dfI(8wlsE?06Xf;f)RZms(JJR*;YFW49jTrcB>6<{H2 z0aKP9&w)a1FN>b#9ai3DuX|G(%G2VxjG^<<3Ii??IJmXsyVu>v3Em@WIWV`&BedsR z8h2fW=DrDRzsN36VnNgH5SVhHtnBEAvP*X8p*kBH6MwLU^UOi?~k46uip@E3n-U^=~R;Jg`KLD#sl*avWA(CP3pGH08uk*Sl;MzJC zQt_zm@25GAjBnt(@HF*f{;$&Ym2GO(fv6KwDwXs1zx`?)>u{p(WT}Vq?Osq*0KNgg zNfBXlouhz$1MdJ3g?5$J0Eipen2dSU*$-#Kvjp3cU`u(npkzyV5UD>yge~O(F$7Yc zZ7-D5Kof{0Qj>zl7QhqxXzbg%)p8b1x~^g&;gSdP+|5)kf`l^*_xDuE(&jb)(z394 zwq_?~`f*M!J(zC;dlBj;=r-UsD@H?xhd4l$%v;yyBhG=?Cu$wq(oDaU2@@O){=523 zkth31r2=*YpDV8DmcYtC`xFoCpq2TElXQMXa?Y&<*CrA;JLYwdbYWqTyIVpXG9@?#V7pcH8mshMLYv+OV_* zZKTr9{3#eK_{+=%*b~4zXQb3Y@RCH>OXo8tD^!3m1DlO4von$TKsH(!&w+@!{*~zY zZ?)MWB@_?#Dz{c@OL+rZ)MZ^PpOIP;Y%| zB?Tupu@_VD$m|^O$#rnY+FVlp92TBrYD#zXgE(xqRIhGY3mL1BeHOkiv$cstar4#s z1)tVJ@GyS%%uX1$sbx~mWqd0m>@th^d*r68-ai=A^-cDhYY&_su}&>NSx!4+;;B=T ze1_)3PUC+GJacmG)%9CrBfkC`lX;3k4(vz0>fIfxNc5{%u7P5Z5-g z zyXK*G&VeO0VSVnD3ONTL_QAw>XLc>Ri2rw+n{6YELE5WoOjK+7&J1bhwVe#;URqrG zU-I@pU4l!%)S%1=Bq3N6oTs3`d5Lh4c0o%y1bv5~vKSvhMH?ifmSZ95jB>a-T-kB| zoL@_%-=#YvfoO;EnDCnOxB+yH0knh$@Aq+sZm)hGiF%4P-_jwBd*sksAxzVND{kq? z3Tj+Z?o`JF=TPvd4Qg`fNl)-c?wW5Zr`xM$9>4Y7v`^rEnOP;)i_Uz`u+AHu2nnk% z&xDVxKT^!mKAdMyR}K3O8D)A0-5fcg$N>QTw@;7HeQk_uIAl~ScbWOzNxi{8KCS$2 z?(YDP16)DLJOso$#&2&bg9{a9)zv`+G2ch?nU{;Wwy*hoF%ZC7Y|;k^EAxRSpoo2H zJLUbJ)yHO{omx+U-4{Z0KE>B@zOhhai5X$yHsBayWX@1EHc1Wt&|8;BoqGEshV?`B z^gd}C%6C4sk#=9y&ElYq-d_BjE>RC4W?6W5gD#PlfMkXZkV!cuhDVcgzE3E%Q{B*o z?MQl`ym{QN%U6D%C)g4)Usk$pRlh!OphOgNyOlyXZopaY&ew?n{v2x&1M|+7{l3Q2 z8;i*kXr?SXlildZGa|CH@rW62D<%;(jbBd;w? zI|x0@r9{8m-(OjOd+3CVVSJGrq^}ELm(u=jyqHWr?{Sqv_0U4>jDuozk^Vld*gn)e zPu*VdEZQpe`*e?n6!6|my9|Cxrk9ZOd8;N~0>=Sk;Q0!kl9h9^wo6#4n4#-)I={g* z5}0;hfee#WzmgBrk))TXLq5IgwPF;q#vn|Opdfo>z+%L=n%>T^cxNPY=^DZE{yv1g zHd!nIeI_TRH)MG1h}j+UM&=UgJ}dT$IX9?+G(P4z*(1Qeqx5;gSAC(QczHzBQ&GNK z&r_HSrpb*9ug87M9R6A6T#v?(@5w1vOS}C-OQq**qNScG#YyT~GM7F`9uv*NLaGwE z>CGhDq1`6nPt;TD5KqGttXXqNC9SZ%m@}sk9)MJbm?C|2TK>7t7*IlgRk@{&EO& zE7h4wKT=orJ*sH^Ao>DDN@o7$ulvq5eQ6`5&LJKru|p-JOt00<(2*mC+2?c5)vvga z!}b8NAG11G8QPJQgM(M>x#gzVCmbH=9nS19qS%#xn0_}T)|gfBQhS+)lOT{|=6z&=Yt{BK*z9ry zkSWe%`jIiE^l?=+i(x&eX3Kma(vrlmw(ybb2t&MkP_-vQ?EP<2Nj~tN|LQGhq{4vP z(zlq5>{7J4qhD!1K03D{*cyfHl|oc;?FMWArY!DvPvyGjgOZ1TWgnq?thv6R z2uSBR8UIzrx*ygS)9yMKoZb@>Nt0PNVHDL#ZToBwv(^d&1f+jeRfnG|Ie9+^7l{WO zjhJXcg6{J5rTVa*J8=&&x5U0Z>-qW(Iph^v=i3FBXS(LT11-pl>%@)vq)kPk9f8{ov$hV&IlF_MbUCAWo*+Z2&X?U zNg(C(jFjDh9$m^u&-*OJwTvT`n@oafW?j(kZmv*dMUzO+a^%L~EpIKi<225B#wJ_@ zcYT}u>FM*9+G?E&^s^k)mU!>!L#I?NJipS^HB!?zhbrjz4K!$+T*|X*uk&HD1+2mT z82^emLXB(bk@|01FW%H^I=yk96tfJqUn>{qSu10hXEMegh-zrG%$#JSbz5_xMu#la zm3*_w%J*Sgk1T>d(EX(BWijXx%d(x5i~1 zX!@&7P-g=!#Vg(0R1;*RBIHmhdpdkbheEh0WOt8C;mE7p@(T zBGwM6p;w0~_4v3g$y*b&7sQS;jA`Xg;T8!v1E#d!av6RNXLpQdIiY3bI9SGvgBeK; zD6bJ}&*Mr-Sv_T$FiOm#s7?9A_zbl7M#3WILH6Da5GxVF~#ciJX$lR=K{R$C5C)XJ(D>1ff9RdUe1KP%JNGBd=OFHwl!mb zDhQnu3Y4O_p0{sI@%(4X;{vd^k${Z`B*h}ppe@@S0D7Xchs1J&H3#nj4IW-LZqu(! z&XGd175a+*zEa*RZh6RxL6g#d{Zm3!u!T{n?|g>%OW`ALD5Xdswb9X8PqeR5ihBl_ zbP085xI^876?*(@J3qa7c%FjlmQlDb&I2=-3fuTPU6*&)AZ~&KGiFsEWN*kUnp=4e zXS*>WhAnernlQY{8}?4tcP;4#;@Lem@s*f;(+@5rAyY2i&}$#~5dX3Eypbt6^0rQF oU(lQojzZ#Zy^K?^{T-e~xt?%8$=MbB;|_ZvX%Q diff --git a/NPCs/TownNPCs/WITCH_Head.png b/NPCs/TownNPCs/WITCH_Head.png index 686a9f7aa684dd2c96fef1db14a21ef3404203b7..031bd7ac2f9f883738f68d228f6adb9f1bbe7dec 100644 GIT binary patch delta 419 zcmV;U0bKs{1M>rrKmq}SkyjpnXLV?7Il2 zVLqdqk8oO4-&O<0=m3|vvZfXo;{tT^5et-tr!H8SA3S*uOryuiK^a*v4O15%9So*- z9Xti5VE`6KFhKuQ2lG)xdl{I2VB;dowV76ee&dgX)p~-g)pDd z&qwG!IkI~vn1;DT!a@g3!@!FZSD-8iC|lGArZrUL!1ThUYr*t@`3Ros$&0!+_4wgybY04z@pTpXbTr&NC^3qQDa`7W4l>uUhh zusD*0=C>7p$P0|Nk)ppsN@%U=Be000hUSV?A0O#mtY000OU000000002eQpGiAh93R7gu>WFP=cSw;Ut znIwVJzh9%6%><=s4lsPwsA7%cgU>$3P!8y8JNCt=Mk7bdGa)vhNVJS>Z6~J(0y`b_f9YkbBT|<8kmNGEe~%& zSrAaRs1JWkYpBS9>4i(zg6RSC5et-Nkdu}G(=ZpDVEGNEr>ZG}X&5;1^eUJ>zYF5> zOs5DiJ@42WFbxB+JT-7W>WV9ZvLN7WV;7i~di@$q!@zoNO$cMt2{45ohcE!khcG}t zAHi}iddZMoT@9wo3ktwAI=H%i8<<8f-C?QC+}v6eOvAvyl?*aY`d~gR)xgRuTmY8Z zU?l^3Tn}7X2Lmvl!E!vzh3IVnm^zq`lB`0&G`cz%7 Date: Thu, 29 Aug 2024 01:34:48 +1000 Subject: [PATCH 354/401] Liquid Edits Rewrite (#52) Technically a half reimplementation of the BiomeLava mod. --- CalPlayer/CalamityPlayer.cs | 4 + CalPlayer/CalamityPlayerMiscEffects.cs | 8 +- CalamityMod.cs | 35 +- Dusts/WaterSplash/AstralSplash.cs | 9 + Dusts/WaterSplash/AstralSplash.png | Bin 0 -> 245 bytes Dusts/WaterSplash/CragsLavaSplash.cs | 178 +++ Dusts/WaterSplash/CragsLavaSplash.png | Bin 0 -> 275 bytes Dusts/WaterSplash/MiddleAbyssSplash.cs | 9 + Dusts/WaterSplash/MiddleAbyssSplash.png | Bin 0 -> 246 bytes Dusts/WaterSplash/SplashDust.cs | 20 + Dusts/WaterSplash/SulphuricDepthsSplash.cs | 9 + Dusts/WaterSplash/SulphuricDepthsSplash.png | Bin 0 -> 245 bytes Dusts/WaterSplash/SulphuricSplash.cs | 9 + Dusts/WaterSplash/SulphuricSplash.png | Bin 0 -> 245 bytes Dusts/WaterSplash/SunkenSeaSplash.cs | 9 + Dusts/WaterSplash/SunkenSeaSplash.png | Bin 0 -> 241 bytes Dusts/WaterSplash/UpperAbyssSplash.cs | 9 + Dusts/WaterSplash/UpperAbyssSplash.png | Bin 0 -> 245 bytes Dusts/WaterSplash/VoidSplash.cs | 9 + Dusts/WaterSplash/VoidSplash.png | Bin 0 -> 246 bytes Gores/AstralWaterDroplet.cs | 167 --- Gores/WaterDroplet/AstralWaterDroplet.cs | 6 + .../{ => WaterDroplet}/AstralWaterDroplet.png | Bin Gores/WaterDroplet/CragsLavaDroplet.cs | 11 + Gores/WaterDroplet/CragsLavaDroplet.png | Bin 0 -> 972 bytes Gores/WaterDroplet/LiquidDropletGore.cs | 201 +++ Gores/WaterDroplet/MiddleAbyssWaterDroplet.cs | 6 + .../WaterDroplet/MiddleAbyssWaterDroplet.png | Bin 0 -> 939 bytes .../SulphuricDepthsWaterDroplet.cs | 6 + .../SulphuricDepthsWaterDroplet.png | Bin 0 -> 945 bytes Gores/WaterDroplet/SulphuricWaterDroplet.cs | 6 + Gores/WaterDroplet/SulphuricWaterDroplet.png | Bin 0 -> 948 bytes Gores/WaterDroplet/SunkenSeaWaterDroplet.cs | 6 + Gores/WaterDroplet/SunkenSeaWaterDroplet.png | Bin 0 -> 966 bytes Gores/WaterDroplet/UpperAbyssWaterDroplet.cs | 6 + Gores/WaterDroplet/UpperAbyssWaterDroplet.png | Bin 0 -> 942 bytes Gores/WaterDroplet/VoidWaterDroplet.cs | 6 + Gores/WaterDroplet/VoidWaterDroplet.png | Bin 0 -> 939 bytes ILEditing/ILChangesLoading.cs | 44 +- ILEditing/ILHelperMethods.cs | 89 +- ILEditing/MechanicILChanges.cs | 603 ++++++--- ModSupport/WeakReferenceSupport.cs | 48 + Systems/CalamityModWaterStyle.cs | 57 + Systems/LavaRendering.cs | 1159 +++++++++++++++++ Systems/ModLavaStyle.cs | 262 ++++ Utilities/MiscUtils.cs | 1 + Utilities/TileUtils.cs | 36 + Waters/AstralWater.cs | 15 +- Waters/AstralWaterflow.cs | 8 - Waters/CragsLava.cs | 38 + Waters/CragsLavaStyle.cs | 31 - Waters/CustomLavaManagement.cs | 92 -- Waters/CustomLavaStyle.cs | 51 - Waters/LiquidTileType.cs | 9 - Waters/MiddleAbyssWater.cs | 34 +- Waters/MiddleAbyssWaterflow.cs | 8 - Waters/PissWater.cs | 29 +- Waters/PissWaterflow.cs | 8 - Waters/SulphuricDepthsWater.cs | 52 +- Waters/SulphuricDepthsWaterflow.cs | 8 - Waters/SulphuricWater.cs | 101 +- Waters/SulphuricWaterflow.cs | 8 - Waters/SunkenSeaWater.cs | 71 +- Waters/UpperAbyssWater.cs | 34 +- Waters/UpperAbyssWaterflow.cs | 8 - Waters/VoidWater.cs | 34 +- Waters/VoidWaterflow.cs | 8 - 67 files changed, 2852 insertions(+), 823 deletions(-) create mode 100644 Dusts/WaterSplash/AstralSplash.cs create mode 100644 Dusts/WaterSplash/AstralSplash.png create mode 100644 Dusts/WaterSplash/CragsLavaSplash.cs create mode 100644 Dusts/WaterSplash/CragsLavaSplash.png create mode 100644 Dusts/WaterSplash/MiddleAbyssSplash.cs create mode 100644 Dusts/WaterSplash/MiddleAbyssSplash.png create mode 100644 Dusts/WaterSplash/SplashDust.cs create mode 100644 Dusts/WaterSplash/SulphuricDepthsSplash.cs create mode 100644 Dusts/WaterSplash/SulphuricDepthsSplash.png create mode 100644 Dusts/WaterSplash/SulphuricSplash.cs create mode 100644 Dusts/WaterSplash/SulphuricSplash.png create mode 100644 Dusts/WaterSplash/SunkenSeaSplash.cs create mode 100644 Dusts/WaterSplash/SunkenSeaSplash.png create mode 100644 Dusts/WaterSplash/UpperAbyssSplash.cs create mode 100644 Dusts/WaterSplash/UpperAbyssSplash.png create mode 100644 Dusts/WaterSplash/VoidSplash.cs create mode 100644 Dusts/WaterSplash/VoidSplash.png delete mode 100644 Gores/AstralWaterDroplet.cs create mode 100644 Gores/WaterDroplet/AstralWaterDroplet.cs rename Gores/{ => WaterDroplet}/AstralWaterDroplet.png (100%) create mode 100644 Gores/WaterDroplet/CragsLavaDroplet.cs create mode 100644 Gores/WaterDroplet/CragsLavaDroplet.png create mode 100644 Gores/WaterDroplet/LiquidDropletGore.cs create mode 100644 Gores/WaterDroplet/MiddleAbyssWaterDroplet.cs create mode 100644 Gores/WaterDroplet/MiddleAbyssWaterDroplet.png create mode 100644 Gores/WaterDroplet/SulphuricDepthsWaterDroplet.cs create mode 100644 Gores/WaterDroplet/SulphuricDepthsWaterDroplet.png create mode 100644 Gores/WaterDroplet/SulphuricWaterDroplet.cs create mode 100644 Gores/WaterDroplet/SulphuricWaterDroplet.png create mode 100644 Gores/WaterDroplet/SunkenSeaWaterDroplet.cs create mode 100644 Gores/WaterDroplet/SunkenSeaWaterDroplet.png create mode 100644 Gores/WaterDroplet/UpperAbyssWaterDroplet.cs create mode 100644 Gores/WaterDroplet/UpperAbyssWaterDroplet.png create mode 100644 Gores/WaterDroplet/VoidWaterDroplet.cs create mode 100644 Gores/WaterDroplet/VoidWaterDroplet.png create mode 100644 Systems/CalamityModWaterStyle.cs create mode 100644 Systems/LavaRendering.cs create mode 100644 Systems/ModLavaStyle.cs delete mode 100644 Waters/AstralWaterflow.cs create mode 100644 Waters/CragsLava.cs delete mode 100644 Waters/CragsLavaStyle.cs delete mode 100644 Waters/CustomLavaManagement.cs delete mode 100644 Waters/CustomLavaStyle.cs delete mode 100644 Waters/LiquidTileType.cs delete mode 100644 Waters/MiddleAbyssWaterflow.cs delete mode 100644 Waters/PissWaterflow.cs delete mode 100644 Waters/SulphuricDepthsWaterflow.cs delete mode 100644 Waters/SulphuricWaterflow.cs delete mode 100644 Waters/UpperAbyssWaterflow.cs delete mode 100644 Waters/VoidWaterflow.cs diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 9499ee5d97..7bb3cc576f 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -45,11 +45,15 @@ using CalamityMod.Projectiles.Rogue; using CalamityMod.Projectiles.Summon; using CalamityMod.Projectiles.Typeless; +using CalamityMod.Systems; +using CalamityMod.Waters; using CalamityMod.World; using Microsoft.Xna.Framework; using Terraria; using Terraria.Audio; using Terraria.DataStructures; +using Terraria.GameContent; +using Terraria.GameContent.Liquid; using Terraria.GameInput; using Terraria.Graphics.Shaders; using Terraria.ID; diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index c25732a19e..b480c34fa4 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -1000,13 +1000,7 @@ private void MiscEffects() } } - // Extra DoT in the lava of the crags. Negated by Flame-licked Shell. - if (Player.lavaWet) - { - if (ZoneCalamity && !flameLickedShell) - Player.AddBuff(ModContent.BuffType(), 2, false); - } - else + if (!Player.lavaWet) { if (Player.lavaImmune) { diff --git a/CalamityMod.cs b/CalamityMod.cs index 043dd624e3..8633e28d87 100644 --- a/CalamityMod.cs +++ b/CalamityMod.cs @@ -51,6 +51,7 @@ using CalamityMod.Projectiles.BaseProjectiles; using CalamityMod.Schematics; using CalamityMod.Skies; +using CalamityMod.Systems; using CalamityMod.UI; using CalamityMod.UI.CalamitasEnchants; using CalamityMod.UI.DraedonsArsenal; @@ -62,6 +63,7 @@ using Terraria; using Terraria.GameContent; using Terraria.GameContent.Dyes; +using Terraria.GameContent.Liquid; using Terraria.Graphics.Effects; using Terraria.Graphics.Shaders; using Terraria.ID; @@ -108,6 +110,21 @@ public class CalamityMod : Mod // Destroyer glowmasks public static Asset[] DestroyerGlowmasks = new Asset[3]; + // Holds the Texture Arrays for all the lava textures. + // These are used for the lava styles. They are seperate from Textureasset.Instance._liquidTexture as they will conflict with ModWaterStyle + // Can hold up to 255 lava styles (more than enough) (excluding the normal lava texture which is liquidTexture 1) + public struct LavaTextures + { + public static Asset[] liquid = new Asset[1]; + public static Asset[] slope = new Asset[1]; + public static Asset[] block = new Asset[1]; + public static Asset[] fall = new Asset[1]; + } + + public static int LavaStyle; + + public static float[] lavaAlpha = new float[1]; + // Wall of Flesh glowmasks public static Asset WallOfFleshEyeGlowmask; public static Asset WallOfFleshDemonSickleTexture; @@ -139,6 +156,7 @@ public class CalamityMod : Mod // Please keep this in alphabetical order so it's easy to read internal Mod ancientsAwakened = null; + internal Mod biomeLava = null; internal Mod bossChecklist = null; internal Mod coloredDamageTypes = null; internal Mod crouchMod = null; @@ -170,6 +188,8 @@ public override void Load() ModLoader.TryGetMod("CalamityModMusic", out musicMod); ancientsAwakened = null; ModLoader.TryGetMod("AAMod", out ancientsAwakened); + biomeLava = null; + ModLoader.TryGetMod("BiomeLava", out biomeLava); bossChecklist = null; ModLoader.TryGetMod("BossChecklist", out bossChecklist); coloredDamageTypes = null; @@ -243,7 +263,11 @@ public override void Load() SetupVanillaDR(); SetupBossKillTimes(); SchematicManager.Load(); - CustomLavaManagement.Load(); + + //lava + LavaRendering.instance = new LavaRendering(); + WeakReferenceSupport.LavaStytleToBiomeLava(); + Attunement.Load(); BalancingChangesManager.Load(); BaseIdleHoldoutProjectile.LoadAll(); @@ -301,6 +325,13 @@ private void LoadClient() DestroyerGlowmasks[1] = ModContent.Request("CalamityMod/ExtraTextures/VanillaBossGlowmasks/DestroyerBodyGlow", AssetRequestMode.AsyncLoad); DestroyerGlowmasks[2] = ModContent.Request("CalamityMod/ExtraTextures/VanillaBossGlowmasks/DestroyerTailGlow", AssetRequestMode.AsyncLoad); + // Lava Texture + LavaTextures.liquid[0] = LiquidRenderer.Instance._liquidTextures[1]; + LavaTextures.slope[0] = TextureAssets.LiquidSlope[1]; + LavaTextures.block[0] = TextureAssets.Liquid[1]; + var waterfallTexture = (Asset[])typeof(WaterfallManager).GetField("waterfallTexture", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).GetValue(Main.instance.waterfallManager); + LavaTextures.fall[0] = waterfallTexture[1]; + // Wall of Flesh glowmasks WallOfFleshEyeGlowmask = ModContent.Request("CalamityMod/ExtraTextures/VanillaBossGlowmasks/WallOfFleshEyeTelegraphGlow", AssetRequestMode.AsyncLoad); WallOfFleshDemonSickleTexture = ModContent.Request("CalamityMod/Projectiles/Melee/ForbiddenOathbladeProjectile", AssetRequestMode.AsyncLoad); @@ -416,6 +447,7 @@ public override void Unload() musicMod = null; ancientsAwakened = null; + biomeLava = null; bossChecklist = null; coloredDamageTypes = null; crouchMod = null; @@ -453,7 +485,6 @@ public override void Unload() InvasionProgressUIManager.UnloadGUIs(); BossRushEvent.Unload(); SchematicManager.Unload(); - CustomLavaManagement.Unload(); CooldownRegistry.Unload(); PlayerDashManager.Unload(); diff --git a/Dusts/WaterSplash/AstralSplash.cs b/Dusts/WaterSplash/AstralSplash.cs new file mode 100644 index 0000000000..6fcb24f6c3 --- /dev/null +++ b/Dusts/WaterSplash/AstralSplash.cs @@ -0,0 +1,9 @@ +using Terraria; +using Terraria.ModLoader; + +namespace CalamityMod.Dusts.WaterSplash +{ + public class AstralSplash : SplashDust + { + } +} diff --git a/Dusts/WaterSplash/AstralSplash.png b/Dusts/WaterSplash/AstralSplash.png new file mode 100644 index 0000000000000000000000000000000000000000..839409589de316fa0ddb15e103c118f5fdf29ae9 GIT binary patch literal 245 zcmeAS@N?(olHy`uVBq!ia0vp^AhsL_8;}$&?Kc2YjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc!7fi1#}EtuWCiXczf%9RCu)eZ8aQS)H3+&K z@R=wq${xtmAGe?7a<{oJ>*;2Oi)xD)R_!QcV7&AD#XJW-DFFq$0~eWRhla8F+_x8435KoHOx`4wXO#n8#o+1c=d#Wzp$PyYv`sGn literal 0 HcmV?d00001 diff --git a/Dusts/WaterSplash/CragsLavaSplash.cs b/Dusts/WaterSplash/CragsLavaSplash.cs new file mode 100644 index 0000000000..907f65c969 --- /dev/null +++ b/Dusts/WaterSplash/CragsLavaSplash.cs @@ -0,0 +1,178 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics.PackedVector; +using System; +using Terraria; +using Terraria.ModLoader; + +namespace CalamityMod.Dusts.WaterSplash +{ + public class CragsLavaSplash : ModDust + { + public override void OnSpawn(Dust dust) + { + dust.velocity *= 0.1f; + dust.velocity.Y = -0.5f; + } + + public override bool Update(Dust dust) + { + if (dust.scale > 10f) + { + dust.active = false; + } + Dust.lavaBubbles++; + dust.position += dust.velocity; + if (!dust.noGravity) + { + dust.velocity.Y += 0.1f; + } + if (dust.noGravity) + { + dust.scale += 0.03f; + if (dust.scale < 1f) + { + dust.velocity.Y += 0.075f; + } + dust.velocity.X *= 1.08f; + if (dust.velocity.X > 0f) + { + dust.rotation += 0.01f; + } + else + { + dust.rotation -= 0.01f; + } + float num109 = dust.scale * 0.6f; + if (num109 > 1f) + { + num109 = 1f; + } + Lighting.AddLight((int)(dust.position.X / 16f), (int)(dust.position.Y / 16f + 1f), num109 * (2.5f / 4), num109 * (1.1f / 4), num109 * (0.1f / 4)); + } + else + { + if (!Collision.WetCollision(new Vector2(dust.position.X, dust.position.Y - 8f), 4, 4)) + { + dust.scale = 0f; + } + else + { + dust.alpha += Main.rand.Next(2); + if (dust.alpha > 255) + { + dust.scale = 0f; + } + dust.velocity.Y = -0.5f; + dust.alpha++; + dust.scale -= 0.01f; + dust.velocity.Y = -0.2f; + dust.velocity.X += (float)Main.rand.Next(-10, 10) * 0.002f; + if ((double)dust.velocity.X < -0.25) + { + dust.velocity.X = -0.25f; + } + if ((double)dust.velocity.X > 0.25) + { + dust.velocity.X = 0.25f; + } + } + float num3 = dust.scale * 0.3f + 0.4f; + if (num3 > 1f) + { + num3 = 1f; + } + Lighting.AddLight((int)(dust.position.X / 16f), (int)(dust.position.Y / 16f), num3 * (2.5f / 4), num3 * (1.1f / 4), num3 * (0.1f / 4)); + } + dust.rotation += dust.velocity.X * 0.5f; + if (dust.fadeIn > 0f && dust.fadeIn < 100f) + { + dust.scale += 0.03f; + if (dust.scale > dust.fadeIn) + { + dust.fadeIn = 0f; + } + } + dust.scale -= 0.01f; + if (dust.noGravity) + { + dust.velocity *= 0.92f; + if (dust.fadeIn == 0f) + { + dust.scale -= 0.04f; + } + } + if (dust.position.Y > Main.screenPosition.Y + (float)Main.screenHeight) + { + dust.active = false; + } + float num17 = 0.1f; + if ((double)Dust.dCount == 0.5) + { + dust.scale -= 0.001f; + } + if ((double)Dust.dCount == 0.6) + { + dust.scale -= 0.0025f; + } + if ((double)Dust.dCount == 0.7) + { + dust.scale -= 0.005f; + } + if ((double)Dust.dCount == 0.8) + { + dust.scale -= 0.01f; + } + if ((double)Dust.dCount == 0.9) + { + dust.scale -= 0.02f; + } + if ((double)Dust.dCount == 0.5) + { + num17 = 0.11f; + } + if ((double)Dust.dCount == 0.6) + { + num17 = 0.13f; + } + if ((double)Dust.dCount == 0.7) + { + num17 = 0.16f; + } + if ((double)Dust.dCount == 0.8) + { + num17 = 0.22f; + } + if ((double)Dust.dCount == 0.9) + { + num17 = 0.25f; + } + if (dust.scale < num17) + { + dust.active = false; + } + return false; + } + + public override Color? GetAlpha(Dust dust, Color lightColor) + { + float num = (float)(255 - dust.alpha) / 255f; + int num4; + int num3; + int num2; + num = (num + 3f) / 4f; + num4 = (int)((int)lightColor.R * num); + num3 = (int)((int)lightColor.G * num); + num2 = (int)((int)lightColor.B * num); + int num6 = lightColor.A - dust.alpha; + if (num6 < 0) + { + num6 = 0; + } + if (num6 > 255) + { + num6 = 255; + } + return new Color(num4, num3, num2, num6); + } + } +} diff --git a/Dusts/WaterSplash/CragsLavaSplash.png b/Dusts/WaterSplash/CragsLavaSplash.png new file mode 100644 index 0000000000000000000000000000000000000000..dbe3be3c6521acbe9775d793b32377ed8913c8cb GIT binary patch literal 275 zcmeAS@N?(olHy`uVBq!ia0vp^AhsL_8;}$&?Kc2YjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc!4;k^jv*HQ$qLecX4=2D=WyOxaDZhgCzG27 zuNkL{@$20UKkN11F<#c`%uFzKnccytQTCXDsp3P!f%koCBK{k~t{i;Y`HhFWqhaQe zlq9Z25;Iz^9Q=~c#p9`V}@F9tJKg_o~{A S*yBJqGkCiCxvXW?|m| literal 0 HcmV?d00001 diff --git a/Dusts/WaterSplash/MiddleAbyssSplash.cs b/Dusts/WaterSplash/MiddleAbyssSplash.cs new file mode 100644 index 0000000000..319e596446 --- /dev/null +++ b/Dusts/WaterSplash/MiddleAbyssSplash.cs @@ -0,0 +1,9 @@ +using Terraria; +using Terraria.ModLoader; + +namespace CalamityMod.Dusts.WaterSplash +{ + public class MiddleAbyssSplash : SplashDust + { + } +} diff --git a/Dusts/WaterSplash/MiddleAbyssSplash.png b/Dusts/WaterSplash/MiddleAbyssSplash.png new file mode 100644 index 0000000000000000000000000000000000000000..b368be985f32cf9e98dc60970db5a51da2b7bdd8 GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^AhsL_8;}$&?Kc2YjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc!ER3%#}EtuWCiYsERBEci5lXp29B9c4T3HQ zd>%f3$QH;WzrTj{^6~sT?5CRK7UPMWb0o2ui0QqHNQ zFjHxvGS?!BxR^@bW&T!X4Nn~#GK2#eLho2KFubcR@mFBy4)`=a6^$s#6FJ+) lE?9ZcS=5|QA|Zi+!EcNCovJ<8{eZ4w@O1TaS?83{1OSnNPXYh{ literal 0 HcmV?d00001 diff --git a/Dusts/WaterSplash/SunkenSeaSplash.cs b/Dusts/WaterSplash/SunkenSeaSplash.cs new file mode 100644 index 0000000000..3c0e44605e --- /dev/null +++ b/Dusts/WaterSplash/SunkenSeaSplash.cs @@ -0,0 +1,9 @@ +using Terraria; +using Terraria.ModLoader; + +namespace CalamityMod.Dusts.WaterSplash +{ + public class SunkenSeaSplash : SplashDust + { + } +} diff --git a/Dusts/WaterSplash/SunkenSeaSplash.png b/Dusts/WaterSplash/SunkenSeaSplash.png new file mode 100644 index 0000000000000000000000000000000000000000..4872767ad68c3b3d8eea2faf1231c3eee743684a GIT binary patch literal 241 zcmeAS@N?(olHy`uVBq!ia0vp^AhsL_8;}$&?Kc2YjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc!8T79#}EtuWCiXQXXF0Lw=9eiIl!`%lgUkh z(fH}4m0BH17p!Zged4`%Sx+}JTvS`cuxdvk1LK|FFXlP$NeL*}9k|Fm+tH29=jGb_ z{L2#6gmaag6i=uK)O})Uy2$V`ujSH}&tDfXitGJhPu6KT@}O}R(|PR;FH8&?*ac@E hbmleZlSoKlV6c)gNeNyb@D}JI22WQ%mvv4FO#rA^Oz;2z literal 0 HcmV?d00001 diff --git a/Dusts/WaterSplash/UpperAbyssSplash.cs b/Dusts/WaterSplash/UpperAbyssSplash.cs new file mode 100644 index 0000000000..715e5467b6 --- /dev/null +++ b/Dusts/WaterSplash/UpperAbyssSplash.cs @@ -0,0 +1,9 @@ +using Terraria; +using Terraria.ModLoader; + +namespace CalamityMod.Dusts.WaterSplash +{ + public class UpperAbyssSplash : SplashDust + { + } +} diff --git a/Dusts/WaterSplash/UpperAbyssSplash.png b/Dusts/WaterSplash/UpperAbyssSplash.png new file mode 100644 index 0000000000000000000000000000000000000000..09400057b85ffca08f366382000d31bf717193ad GIT binary patch literal 245 zcmeAS@N?(olHy`uVBq!ia0vp^AhsL_8;}$&?Kc2YjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc!7fi1#}EtuWCiXGF7E%>6E(zH4IDF@8U$Sq z_#{r6#1hE!f1WM-<@#xQ?5CRd=xWr=SM|U}vu6+LbAkz)6?tje&Q@WWvxaDSOZrH=reJ=iP n?FR)V{fZTjjxjRx@GumvGF-90@cK=ls~9|8{an^LB{Ts5XAx5v literal 0 HcmV?d00001 diff --git a/Dusts/WaterSplash/VoidSplash.cs b/Dusts/WaterSplash/VoidSplash.cs new file mode 100644 index 0000000000..0e046fa962 --- /dev/null +++ b/Dusts/WaterSplash/VoidSplash.cs @@ -0,0 +1,9 @@ +using Terraria; +using Terraria.ModLoader; + +namespace CalamityMod.Dusts.WaterSplash +{ + public class VoidSplash : SplashDust + { + } +} diff --git a/Dusts/WaterSplash/VoidSplash.png b/Dusts/WaterSplash/VoidSplash.png new file mode 100644 index 0000000000000000000000000000000000000000..3177c26e7c41530ecc11eb2f3cabdd6bffb34d80 GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^AhsL_8;}$&?Kc2YjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc!ER3%#}EtuWCd=Hf)jt)6E(zH4IDF@8U$Sq z_&gK{V+-W5zju%IvV5Hl)9Gf0i)xD)R_!QcV7&AD#XJW-DFFq$0~eX29Rg&1_V3ut z>vPyg?Uu_9rwN`4e;)qzHE?4;vRlwA`26)|Ru2#Be_+!mh}jqfCseYE&DEdxuAN=5 i@}RS*IiEyA0s}+6q3#|vyGoFM7(8A5T-G@yGywn(97;w2 literal 0 HcmV?d00001 diff --git a/Gores/AstralWaterDroplet.cs b/Gores/AstralWaterDroplet.cs deleted file mode 100644 index 0022de1b56..0000000000 --- a/Gores/AstralWaterDroplet.cs +++ /dev/null @@ -1,167 +0,0 @@ -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.Audio; -using Terraria.DataStructures; -using Terraria.GameContent; -using Terraria.GameContent.Shaders; -using Terraria.Graphics.Effects; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Gores -{ - public class AstralWaterDroplet : ModGore - { - public override void SetStaticDefaults() - { - ChildSafety.SafeGore[Type] = true; - } - - public override void OnSpawn(Gore gore, IEntitySource source) - { - gore.numFrames = 15; - gore.behindTiles = true; - gore.timeLeft = Gore.goreTime * 3; - } - - public override bool Update(Gore gore) - { - if ((double)gore.position.Y < Main.worldSurface * 16.0 + 8.0) - { - gore.alpha = 0; - } - else - { - gore.alpha = 100; - } - int goreFrameDelay = 4; - gore.frameCounter++; - if (gore.frame <= 4) - { - int goreXPos = (int)(gore.position.X / 16f); - int goreYPos = (int)(gore.position.Y / 16f) - 1; - if (WorldGen.InWorld(goreXPos, goreYPos, 0) && !Main.tile[goreXPos, goreYPos].HasTile) - { - gore.active = false; - } - if (gore.frame == 0) - { - goreFrameDelay = 24 + Main.rand.Next(256); - } - if (gore.frame == 1) - { - goreFrameDelay = 24 + Main.rand.Next(256); - } - if (gore.frame == 2) - { - goreFrameDelay = 24 + Main.rand.Next(256); - } - if (gore.frame == 3) - { - goreFrameDelay = 24 + Main.rand.Next(96); - } - if (gore.frame == 5) - { - goreFrameDelay = 16 + Main.rand.Next(64); - } - if ((int)gore.frameCounter >= goreFrameDelay) - { - gore.frameCounter = 0; - gore.frame += 1; - if (gore.frame == 5 && Main.netMode != NetmodeID.Server) - { - int astralWater = Gore.NewGore(new EntitySource_Misc("0"), gore.position, gore.velocity, gore.type, 1f); - Main.gore[astralWater].frame = 9; - Main.gore[astralWater].velocity *= 0f; - } - } - } - else if (gore.frame <= 6) - { - goreFrameDelay = 8; - if ((int)gore.frameCounter >= goreFrameDelay) - { - gore.frameCounter = 0; - gore.frame += 1; - if (gore.frame == 7) - { - gore.active = false; - } - } - } - else if (gore.frame <= 9) - { - goreFrameDelay = 6; - gore.velocity.Y += 0.2f; - if ((double)gore.velocity.Y < 0.5) - { - gore.velocity.Y = 0.5f; - } - if (gore.velocity.Y > 12f) - { - gore.velocity.Y = 12f; - } - if ((int)gore.frameCounter >= goreFrameDelay) - { - gore.frameCounter = 0; - gore.frame += 1; - } - if (gore.frame > 9) - { - gore.frame = 7; - } - } - else - { - gore.velocity.Y += 0.1f; - if ((int)gore.frameCounter >= goreFrameDelay) - { - gore.frameCounter = 0; - gore.frame += 1; - } - gore.velocity *= 0f; - if (gore.frame > 14) - { - gore.active = false; - } - } - - Vector2 goreVelCheck = gore.velocity; - gore.velocity = Collision.TileCollision(gore.position, gore.velocity, 16, 14, false, false, 1); - if (gore.velocity != goreVelCheck) - { - if (gore.frame < 10) - { - gore.frame = 10; - gore.frameCounter = 0; - if (gore.type != 716 && gore.type != 717 && gore.type != 943) - { - SoundEngine.PlaySound(SoundID.Drip, gore.position + Vector2.One * 8); - } - } - } - else if (Collision.WetCollision(gore.position + gore.velocity, 16, 14)) - { - if (gore.frame < 10) - { - gore.frame = 10; - gore.frameCounter = 0; - if (gore.type != 716 && gore.type != 717 && gore.type != 943) - { - SoundEngine.PlaySound(SoundID.Drip, gore.position + Vector2.One * 8); - } - ((WaterShaderData)Filters.Scene["WaterDistortion"].GetShader()).QueueRipple(gore.position + new Vector2(8f, 8f), 1f, RippleShape.Square, 0f); - } - int goreTileX = (int)(gore.position.X + 8f) / 16; - int goreTileY = (int)(gore.position.Y + 14f) / 16; - if (Main.tile[goreTileX, goreTileY] != null && Main.tile[goreTileX, goreTileY].LiquidAmount > 0) - { - gore.velocity *= 0f; - gore.position.Y = (float)(goreTileY * 16 - (int)(Main.tile[goreTileX, goreTileY].LiquidAmount / 16)); - } - } - - return true; - } - } -} diff --git a/Gores/WaterDroplet/AstralWaterDroplet.cs b/Gores/WaterDroplet/AstralWaterDroplet.cs new file mode 100644 index 0000000000..0add03de05 --- /dev/null +++ b/Gores/WaterDroplet/AstralWaterDroplet.cs @@ -0,0 +1,6 @@ +namespace CalamityMod.Gores.WaterDroplet +{ + public class AstralWaterDroplet : LiquidDropletGore + { + } +} diff --git a/Gores/AstralWaterDroplet.png b/Gores/WaterDroplet/AstralWaterDroplet.png similarity index 100% rename from Gores/AstralWaterDroplet.png rename to Gores/WaterDroplet/AstralWaterDroplet.png diff --git a/Gores/WaterDroplet/CragsLavaDroplet.cs b/Gores/WaterDroplet/CragsLavaDroplet.cs new file mode 100644 index 0000000000..3841f789d3 --- /dev/null +++ b/Gores/WaterDroplet/CragsLavaDroplet.cs @@ -0,0 +1,11 @@ +using Microsoft.Xna.Framework; + +namespace CalamityMod.Gores.WaterDroplet +{ + public class CragsLavaDroplet : LiquidDropletGore + { + public override bool lavaDroplet => true; + + public override Vector3 lavaColor => new Vector3(2.5f, 1.1f, 0.1f); + } +} diff --git a/Gores/WaterDroplet/CragsLavaDroplet.png b/Gores/WaterDroplet/CragsLavaDroplet.png new file mode 100644 index 0000000000000000000000000000000000000000..5a62700a83a1a65835a35a29cd3f183d1c34cf5b GIT binary patch literal 972 zcmV;-12g=IP)Px&g-Jv~RCr$PT)UOjKoFGp!~o7^0U6*B1`aV`VVp$_ID~;i29U)$5Cd?_JKfd1 zw>9)t&!}fV+Fobh?zT#;n(6AE9%<)4Uq0`qX_|Jwe%`&gU-OHXi|w;_@8`SsISk0{ zf-qd%ig+cEW-&QRjx+<>BIl8VqcEur1G1dP3Gh3zg=KFJe;AOaci$o>q-HERN{%!G z+G5M|hy_g5+o-Q$_x!`h{W=?Tb_4Nv{QdTISqa?!_`dfOSNeQhHELl%I1>Qz`RSXt zk4_cy$1os0motkbM}>hc3tQ_jH*Z&m1Zlgwl1{*!NBX8rQL<2Fd+79 zzPehzLN;m6BJgZA5POzuktr@jT7&b9qCYQ9GH`3 z0~A_b(LdapmOWA)N~uLibOW)lb<4;wpyO+HYqLd;T6lsyel_BiSQ%^KKw63JEiPHJ zm3$n2)P8@uUhe(tj()hj8tC++zgx5U(l!J%tYGh+kX%=*n3I)13iNIubs#IJ%xh|y z?v|0%?2ArEIs6A0{;*rmn}MuVklN1Rowi?JQ8}7W;3V6v&2rpO3k!C76a&QFMfX?u3 zjDUcqBT4Xab2t!$%*rOL*{qnwqt!s%O!4M5F675OouLQ%{}ve{nz`gCInoShi*fVF z>OiQ@MCH+HAim=ll|5$>e3lAX3h;-=&fGvqM^%;jaA$7;GX5W_Jen5UKDdR!j27(Z&Q9;Qc{vE(Q@ u(hO*eOPWX4^CQh0zF|Omd literal 0 HcmV?d00001 diff --git a/Gores/WaterDroplet/LiquidDropletGore.cs b/Gores/WaterDroplet/LiquidDropletGore.cs new file mode 100644 index 0000000000..f99d0b6c4b --- /dev/null +++ b/Gores/WaterDroplet/LiquidDropletGore.cs @@ -0,0 +1,201 @@ +using Microsoft.Xna.Framework; +using Terraria; +using Terraria.Audio; +using Terraria.DataStructures; +using Terraria.GameContent; +using Terraria.ID; +using Terraria.ModLoader; + +namespace CalamityMod.Gores.WaterDroplet +{ + public abstract class LiquidDropletGore : ModGore + { + public virtual bool lavaDroplet => false; + + public virtual Vector3 lavaColor => new Vector3(0, 0, 0); + + public override void SetStaticDefaults() + { + ChildSafety.SafeGore[Type] = true; + } + + public override void OnSpawn(Gore gore, IEntitySource source) + { + gore.numFrames = 15; + gore.behindTiles = true; + gore.timeLeft = Gore.goreTime * 3; + } + + public override bool Update(Gore gore) + { + gore.alpha = gore.position.Y < (Main.worldSurface * 16.0) + 8.0 + ? 0 + : 100; + + int frameDuration = 4; + gore.frameCounter += 1; + if (gore.frame <= 4) + { + int tileX = (int)(gore.position.X / 16f); + int tileY = (int)(gore.position.Y / 16f) - 1; + if (WorldGen.InWorld(tileX, tileY) && !Main.tile[tileX, tileY].HasTile) + { + gore.active = false; + } + + if (gore.frame == 0 || gore.frame == 1 || gore.frame == 2) + { + frameDuration = 24 + Main.rand.Next(256); + } + + if (gore.frame == 3) + { + frameDuration = 24 + Main.rand.Next(96); + } + + if (gore.frameCounter >= frameDuration) + { + gore.frameCounter = 0; + gore.frame += 1; + if (gore.frame == 5) + { + int droplet = Gore.NewGore(new EntitySource_Misc("0"), gore.position, gore.velocity, gore.type); + Main.gore[droplet].frame = 9; + Main.gore[droplet].velocity *= 0f; + } + } + } + else if (gore.frame <= 6) + { + frameDuration = 8; + if (gore.frameCounter >= frameDuration) + { + gore.frameCounter = 0; + gore.frame += 1; + if (gore.frame == 7) + { + gore.active = false; + } + } + } + else if (gore.frame <= 9) + { + frameDuration = 6; + gore.velocity.Y += 0.2f; + if (gore.velocity.Y < 0.5f) + { + gore.velocity.Y = 0.5f; + } + + if (gore.velocity.Y > 12f) + { + gore.velocity.Y = 12f; + } + + if (gore.frameCounter >= frameDuration) + { + gore.frameCounter = 0; + gore.frame += 1; + } + + if (gore.frame > 9) + { + gore.frame = 7; + } + } + else + { + gore.velocity.Y += 0.1f; + if (gore.frameCounter >= frameDuration) + { + gore.frameCounter = 0; + gore.frame += 1; + } + + gore.velocity *= 0f; + if (gore.frame > 14) + { + gore.active = false; + } + } + + if (lavaDroplet) + { + float num24 = 1f; + float num25 = 1f; + float num26 = 1f; + float num27 = 0.6f; + num27 *= gore.frame switch + { + 0 => 0.1f, + 1 => 0.2f, + 2 => 0.3f, + 3 => 0.4f, + 4 => 0.5f, + 5 => 0.4f, + 6 => 0.2f, + 7 => 0.5f, + 8 => 0.5f, + 9 => 0.5f, + 10 => 0.5f, + 11 => 0.4f, + 12 => 0.3f, + 13 => 0.2f, + 14 => 0.1f, + _ => 0.0f, + }; + num24 = (lavaColor.X / 4) * num27; //R + num25 = (lavaColor.Y / 4) * num27; //G + num26 = (lavaColor.Z / 4) * num27; //B + Lighting.AddLight(gore.position + new Vector2(8f, 8f), num24, num25, num26); + } + + Vector2 oldVelocity = gore.velocity; + gore.velocity = Collision.TileCollision(gore.position, gore.velocity, 16, 14); + if (gore.velocity != oldVelocity) + { + if (gore.frame < 10) + { + gore.frame = 10; + gore.frameCounter = 0; + if (!lavaDroplet) + { + SoundEngine.PlaySound(SoundID.Drip, gore.position + new Vector2(8, 8)); + } + } + } + else if (Collision.WetCollision(gore.position + gore.velocity, 16, 14)) + { + if (gore.frame < 10) + { + gore.frame = 10; + gore.frameCounter = 0; + if (!lavaDroplet) + { + SoundEngine.PlaySound(SoundID.Drip, gore.position + new Vector2(8, 8)); + } + } + + int tileX = (int)(gore.position.X + 8f) / 16; + int tileY = (int)(gore.position.Y + 14f) / 16; + if (Main.tile[tileX, tileY] != null && Main.tile[tileX, tileY].LiquidAmount > 0) + { + gore.velocity *= 0f; + gore.position.Y = (tileY * 16) - (Main.tile[tileX, tileY].LiquidAmount / 16); + } + } + + gore.position += gore.velocity; + return false; + } + + public override Color? GetAlpha(Gore gore, Color lightColor) + { + if (lavaDroplet) + { + return new Color(255, 255, 255, 200); + } + return null; + } + } +} diff --git a/Gores/WaterDroplet/MiddleAbyssWaterDroplet.cs b/Gores/WaterDroplet/MiddleAbyssWaterDroplet.cs new file mode 100644 index 0000000000..73728d4332 --- /dev/null +++ b/Gores/WaterDroplet/MiddleAbyssWaterDroplet.cs @@ -0,0 +1,6 @@ +namespace CalamityMod.Gores.WaterDroplet +{ + public class MiddleAbyssWaterDroplet : LiquidDropletGore + { + } +} diff --git a/Gores/WaterDroplet/MiddleAbyssWaterDroplet.png b/Gores/WaterDroplet/MiddleAbyssWaterDroplet.png new file mode 100644 index 0000000000000000000000000000000000000000..235b55d951b1b65e308de210fae2ce0459fc2a42 GIT binary patch literal 939 zcmV;c162HpP)Px&Wl2OqRCr$Po3U;bF%X7#Ya$Rr5u%_#NHK)6s{dfF({Lk2H&lj&>-AvOoefx2J`{n+eK7G8{zW?}XzWtuV zfZQ&C;o?@rCxMv7-t7J`Af|V1kpan!B}d5- zGr$&y97kHfsNR#Ic-NBsnS!9I~+0c5`*IiJ+rjCa1;il zJ$rKUX!%RBNp%(x&$@xMXE_&{;)Y1=;M}9ppG`vs28^Te>ui!-5qqq&!+@-;VtFF= zxLTtpFYeKAHLW>|=*-&;)SZqpuWh1WKp8>la~fpRn5gpVP)w;z{{L$uXV0H4Ya{wo zEhAw-;)wu~C#c!sK$Jb)9(4nW@cA0wZgz2X!dwjt=8;r zVH3^n2Fl33i|kr1+>@GC;A0g3TCS2KW-K}C;3!OL!-1qxlmyJ~*K?9;AU$=^^Eda3 zRv1vOANdzq!nRh00r4=++0nQhc?AyBQ8!Sxu<3%mS!%6i9|GKP6b_`<(waT$1`1mk zKVTp|rkBd=$uM+Xe#T_Qt{!hpQmjUIIaS+%6Qs#3xT|onRpl)k3FBLVXUYG_4zmj!+5BS~+D^51X8HfsVQqXejEF4Il zZ0%a5HMf#Qx`A|k%@On0LgzVCvkA}yq8sUYj(%cj%7buBQF3(T9C`DZrb*vdR%Px&YDq*vRCr$Po3U;bF%X7#3nZFIP^Ctckx*VIMP7g!8XkZKYF>bX*FljeqtvND zqCuhnWziVz>`lJ0JrLjBTywhH*?-5s$N!AI_I&pK<*#X)rXROo@4noh$EQyh+b^#^ z%y-{&7?9fqFkIY<_#_asm>eZX%m7C(*1G%@y#+5_x}+<8ecz_n!hqyS z0w}*fU%tIJRLqNEKpe}NMUtb!z#$7;Z8uk!ezgyXBfGUc7LPZYOU&~c;#Ed0J9UO&8Z8(rLijsiY{d!JP4Wy?I zdj95K(Fy~~^&|fxOW4+`Fd!bLIXfDcBd@?=I_d`M7B*e5H%qOx>_dPXj>3WTT3WM5 z-9TXr;|C0+=d|*hR<`g>O*hcEdgS#C_2__syh~)rQ5cX{yV0X=Agh*iSGCqcRI}7t zf#~)qvj~^RVObFlB48^8DNWyqle^Zyd9d%#%_zSIQk7_!9`k7 T?RPN%0000Px&Y)M2xRCr$Po3U;bF%X7#X^>C~M1%4K6jUi9YTkmUpr=cho~Pg~s1XGf1y2ys zL@5vw4WKL-FuI`*ZU2$zuEA z<;8saJ%<6gT>!(yt%y$oF^kDja>NXe8?F0dZuvmdE1pMzcw)t)>fOENpeN(vCa+y zva*WhiP+<6jh?)?N59py<}9K!Z!=JLI?BAZiGl%T1f|bukWFKv%Bw>$r84>duZ=u^ z_j*|y(VuD=2?G*O1du#I%?<~m?BVvP8%QLV-aep5VL&`6))vPoBVlBR0cEch2KGR+ z$E#|!W_JslXm&SHM)u#xuI0i#sc8j1M)9xZDmh}tlA{ie!lX7FNE$^+!0diKC#eR~ zQwKeNbFXNH0p`%$gADxQ8$oPOS-FCYayyx zYOO$Ydz4v(%j2*tlA6tAd!<#|;pq1QClE8WM;v+6kTe?WBPy^E$UB*d2eP=J7ry$w z^2$eZQ4J*9@E_d#Seom7-!FS_WdHvh1|+N#piFYKC!1ai1JYB_N6$`IBUSd-R_Fe1 zAQp_>7JDQkwN1>XF=GRBqzA1QI$aX#b4aCW-9U7NN@&)~DT8{Wkk+9tH;|RT^z2CM zkiKsY1Ja=uwjH(`h^Cx$y~Gh2()EGI8VkkU7TGjrFgdypjzqiZl&WR7$s)}_RG5>3 zmSbn(K=Nd3*D9^Kl`PT?r0Z*rm_HUe&zYJ{fF=;#NY``p6GKxTgky@5qa)|Yo6j^& z`o6MSL-`DW#DEHQN)G?-6tp8`cABJSGjqvNa>NXPx&e@R3^RCr$Pn?X+9Kn#WxsaIf67u_Nj4oi49Id?9w67HT3Ghx^oId4y-SM>NMUtYc$ zD)z-NAP(k*#VJR2BNe83a>Ps~NAJne+V)s{tTdan+8SH|5(BSimUfpo3Io!f?an?; z|B`CbTt&pQZXoShu0@8Fk@u7lewNQ7XN`F(+tA(ZaahByohHc@vBy3;49Kb~mM3D5 zyES_8V$EL#WDRX~715Pl(erz@d=`So>Q6j?kl=wKB=6+5h6*+!(h~ zLids+Cz$=KyIQT;+PL7zlO3Iodhqbg^xt&uxuadUVe&iAFo;j=$I@~=g_0*ABK4b&}c zx?x`}wbr%|0ahG^1L@_|YLB{s!ZyZF7)WL(>^N)~P%5NfA-!CoLWTi(_u9~-Fd(mX zqetC9Rxj!9YIV|fx5w7ByFJP(!tHTb6-muzvb{p4?J)bjzzM`m9T7*~G9-h>H7zZQ z5y-oki3hT{pclUSzH+ombI}Ym%*XJrpZ`q5rDL(>-S&K@bePZok8wakJ9uV!QqNi# z&W~7Ky)Kr z&+I3LhWrqYDN2t1caFUEO!K7fE4wvV&k$%fphlgFLs7^uAV;WVSKCQa)-@(DIZBS0 o0k$|?9BuD}CbO~MB8;QI5rZ*W53^4g00000NkvXXu0mjf0CeZZQvd(} literal 0 HcmV?d00001 diff --git a/Gores/WaterDroplet/UpperAbyssWaterDroplet.cs b/Gores/WaterDroplet/UpperAbyssWaterDroplet.cs new file mode 100644 index 0000000000..52d68f19ea --- /dev/null +++ b/Gores/WaterDroplet/UpperAbyssWaterDroplet.cs @@ -0,0 +1,6 @@ +namespace CalamityMod.Gores.WaterDroplet +{ + public class UpperAbyssWaterDroplet : LiquidDropletGore + { + } +} diff --git a/Gores/WaterDroplet/UpperAbyssWaterDroplet.png b/Gores/WaterDroplet/UpperAbyssWaterDroplet.png new file mode 100644 index 0000000000000000000000000000000000000000..1b6552138efad6107cb3ecb2334bcbf8d03b26e7 GIT binary patch literal 942 zcmV;f15x~mP)Px&XGugsRCr$Po8OHTF$~6M;0{CsNbqze&;$+ehUfz6sz9O(bZ<0pOgDfgnx@mwU$4L1pYM+!F1A13UCh_t za~P1@1u$IPiufcDvzQzuN6Y|QWE?p-3X|F}Aj@fafLxbsVcDDA9|pwqt}QYknX%+3 zIbsIb;*jG=3mDbgQeTVRm&^C-I$P*$2GafU;QaM66S#l%VRcDY`ue_2uZ020lLSzH ze|z)x)=)7oh5>ObXBJ703Im5MY_;87UHa8NAdc+T@>o3HXf|oJ)zktc242rB?JgXJ z0cp?fJ$34K-#mMi%fAtq;_!b(df^nAp--((fD;XNv?=J*4be|R#ve* z5qn&%(UTYV=(n2IoJDlzZ3gO2N14|)Q81v4p!7KnvT00Id37kJR3`ubwUI~9Uo2}Q z`co|| z>~3Kb&F%)u$o?DIwOqI-HLbwMDE_rvB}dFya@4_5nAC;?NuwwUnBA}EB-KEA>Y(Ru z?iH;tpjISlENq1FiEkrd-trduF zk1~sJc^sBSQnQ(Cue54A9Q|J41Y)N4h$C+rl15{FL0SW5_D3cuR$)?xBfbZ4H3-@=Eg$jIa9L<&;+6z>3WWSVra^Pa7ee-&a;^ zD4!va7*L^3$>HCff_8+=PLtGZW-d8Oj+gg-e$!zSl2#cdX1Fkh%RA<9| Q00000NkvXXu0mjf048d~(f|Me literal 0 HcmV?d00001 diff --git a/Gores/WaterDroplet/VoidWaterDroplet.cs b/Gores/WaterDroplet/VoidWaterDroplet.cs new file mode 100644 index 0000000000..daf1abf2d7 --- /dev/null +++ b/Gores/WaterDroplet/VoidWaterDroplet.cs @@ -0,0 +1,6 @@ +namespace CalamityMod.Gores.WaterDroplet +{ + public class VoidWaterDroplet : LiquidDropletGore + { + } +} diff --git a/Gores/WaterDroplet/VoidWaterDroplet.png b/Gores/WaterDroplet/VoidWaterDroplet.png new file mode 100644 index 0000000000000000000000000000000000000000..caa2b6f97a5139da1c6d6d4d26c01a561a5e6c0a GIT binary patch literal 939 zcmV;c162HpP)Px&Wl2OqRCr$Po3U;bF%X7#yOcp`A|cU$loWZ1v^)uq#FNnS5)>ej1_>!ml$7Z} zSu{pFdy{W$55#vj*PQNl_TTaE@jqj)J)gh6{xwb0^mupk^yU7XoV{IaZ-0KCpT6fX zAh!!(xVRPZNg!r1IZBS00k+6Ea&QzTwP8S()A9hhF4@AeH@iO!i0NHhWI!@w$x(8| z46wx^$B`B=s<)-S7Q2VXAL}|>=xhek{c(BqVVMcse*d((q$_=W-=^2XfaFO6D8Ijc z`S@(8m>0uVuBu9mTLl(B$Zmur3Sn zXQ!_&mcJyMRA&+KtQ$ysmUEFQZiv(l&OI9a*)(Kez&IMe&L+tfvBx?)49LnVmM3D5 zt2KJ^;vW50)0(r0&b-Y)-RUUv+9nDHlo6CZr$IK2i7KxS#gxkA|GzeJdh%vj8_}O? z83_XtPXv%WLCp>aqU_=Js2fNmm)<_0M`1ubDApFoC?jEHhXG};6$bV|v&XAywPtq< zn`m}7P)7FO$gbtWJ*jC0K1T7c4oi97q~PNxYTll7?8)#fT@_L4PbihE~B{JkF49Kh9=utP2RZF_7T5BPyS!%67bbFLp zgv;ZwERvedWP7Dm+u`W<0w)kNwMQIz(~vY8>mw?#5Xd{3i3hT{pclUSzVgaPb5RW> z+wdRmzb(!6zVDa4H?seK4g(U_2~Z|E+LKMMg#qa)==r<%tC1@EYpZjAHxLWPZi_vV zk=iC^)0nY=Inskx3!N?r^*N-{v~D0eLM1e7<&;6aQAq1hmmA2+UwU?=bx7YghXLtO z3)>Fc4MbB;x?bXl4C(s7V~vI4d5dfsGngE`1V^IXbV}8-+hmbuAS%pBLCdkTa3FcI zwQH5u+)5Vd2GaF4N6a4!o##x=CO{L2Zlvou`iY?_55h4;$>zhbFVJ+afHEegpG7MOra&vMm4r N002ovPDHLkV1ghiv4sEt literal 0 HcmV?d00001 diff --git a/ILEditing/ILChangesLoading.cs b/ILEditing/ILChangesLoading.cs index 056dc43d69..ac00cb50f1 100644 --- a/ILEditing/ILChangesLoading.cs +++ b/ILEditing/ILChangesLoading.cs @@ -44,11 +44,6 @@ public override void OnModLoad() On_Main.DrawCursor += UseCoolFireCursorEffect; On_Main.SortDrawCacheWorms += DrawFusableParticles; On_Main.DrawInfernoRings += DrawForegroundParticles; - On_TileDrawing.DrawPartialLiquid += DrawCustomLava; - On_WaterfallManager.DrawWaterfall_int_int_int_float_Vector2_Rectangle_Color_SpriteEffects += DrawCustomLavafalls; - On_Main.RenderWater += CacheLavaStyle; - IL_Main.oldDrawWater += DrawCustomLava3; - On_TileLightScanner.GetTileLight += MakeSulphSeaWaterBetter; On_TileDrawing.PreDrawTiles += ClearForegroundStuff; On_TileDrawing.Draw += ClearTilePings; On_CommonCode.ModifyItemDropFromNPC += ColorBlightedGel; @@ -89,6 +84,45 @@ public override void OnModLoad() // Mana Burn (Chaos Stone) and Chalice of the Blood God IL_Player.ApplyLifeAndOrMana += ManaSicknessAndChaliceBufferHeal; + //LavaStyles + if (CalamityMod.Instance.biomeLava == null) + { + //Rendering/Drawing + IL_Main.DoDraw += DoDrawLavas; + IL_Main.RenderWater += RenderLavas; + IL_Main.RenderBackground += RenderLavaBackgrounds; + IL_Main.DrawCapture += DrawLavatoCapture; + IL_TileDrawing.Draw += AddTileLiquidDrawing; + + //Blocking + IL_LiquidRenderer.DrawNormalLiquids += BlockLavaDrawing; + On_TileDrawing.DrawTile_LiquidBehindTile += BlockLavaDrawingForSlopes; + On_TileDrawing.DrawPartialLiquid += BlockLavaDrawingForSlopes2; + On_WaterfallManager.DrawWaterfall_int_int_int_float_Vector2_Rectangle_Color_SpriteEffects += LavafallRemover; + IL_Main.oldDrawWater += BlockRetroLightingLava; + + //Replacing + IL_LiquidRenderer.InternalPrepareDraw += LavaBubbleReplacer; + IL_TileDrawing.EmitLiquidDrops += LavaDropletReplacer; + IL_NPC.Collision_WaterCollision += SplashEntityLava; + IL_Projectile.Update += SplashEntityLava; + IL_Item.MoveInWorld += SplashEntityLava; + IL_Player.Update += SplashEntityLava; + IL_Player.Update += PlayerDebuffEdit; + + //Other + On_WaterfallManager.Draw += LavaFallRedrawer; + On_WaterfallManager.StylizeColor += WaterfallGlowmaskEditor; + + //Waterfall light + On_WaterfallManager.AddLight += LavafallLightEditor; + } + + // Liquid Lighting and alpha (Liquid Viusuals) + On_TileLightScanner.ApplyLiquidLight += LiquidEmitLight; + IL_LiquidRenderer.DrawNormalLiquids += LiquidDrawColors; //Liquid Light + IL_TileDrawing.DrawTile_LiquidBehindTile += LiquidSlopeDrawColors; + // Custom grappling On_Player.GrappleMovement += CustomGrappleMovementCheck; On_Player.UpdatePettingAnimal += CustomGrapplePreDefaultMovement; diff --git a/ILEditing/ILHelperMethods.cs b/ILEditing/ILHelperMethods.cs index 01f2379f0e..fe90e30043 100644 --- a/ILEditing/ILHelperMethods.cs +++ b/ILEditing/ILHelperMethods.cs @@ -64,77 +64,8 @@ private static bool DirectlyTransformLabDoor(int doorX, int doorY, int newDoorID SoundEngine.PlaySound(SoundID.DoorClosed, new Vector2(doorX * 16, doorY * 16)); return true; } - - private static Texture2D SelectLavaTexture(Texture2D initialTexture, LiquidTileType type) - { - // Use the initial texture if it isn't lava. - if (initialTexture != CustomLavaManagement.LavaTexture && - initialTexture != CustomLavaManagement.LavaBlockTexture && - initialTexture != CustomLavaManagement.LavaSlopeTexture) - return initialTexture; - - if (cachedLavaStyle == default) - return initialTexture; - - switch (type) - { - case LiquidTileType.Block: - return cachedLavaStyle.BlockTexture; - case LiquidTileType.Waterflow: - return cachedLavaStyle.LavaTexture; - case LiquidTileType.Slope: - return cachedLavaStyle.SlopeTexture; - } - - return initialTexture; - } - private static VertexColors SelectLavaQuadColor(Texture2D initialTexture, ref VertexColors initialColor, bool forceTrue = false) - { - // We should handle the 'forceTrue' flag at this level to prevent us from checking the same thing four times. - if (!forceTrue) - { - if (initialTexture != CustomLavaManagement.LavaTexture && - initialTexture != CustomLavaManagement.LavaBlockTexture && - initialTexture != CustomLavaManagement.LavaSlopeTexture) - return initialColor; - } - - // No lava style to draw? Then skip. - if (cachedLavaStyle == default) - return initialColor; - - cachedLavaStyle.SelectLightColor(ref initialColor.TopLeftColor); - cachedLavaStyle.SelectLightColor(ref initialColor.TopRightColor); - cachedLavaStyle.SelectLightColor(ref initialColor.BottomLeftColor); - cachedLavaStyle.SelectLightColor(ref initialColor.BottomRightColor); - return initialColor; - } - - private static Color SelectLavaColor(Texture2D initialTexture, Color initialLightColor, bool forceTrue = false) - { - // Use the initial color if it isn't lava. - if (!forceTrue) - { - if (initialTexture != CustomLavaManagement.LavaTexture && - initialTexture != CustomLavaManagement.LavaBlockTexture && - initialTexture != CustomLavaManagement.LavaSlopeTexture) - return initialLightColor; - } - - foreach (CustomLavaStyle lavaStyle in CustomLavaManagement.CustomLavaStyles) - { - if (lavaStyle.ChooseLavaStyle()) - { - lavaStyle.SelectLightColor(ref initialLightColor); - return initialLightColor; - } - } - - return initialLightColor; - } - - private static void SelectSulphuricWaterColor(int x, int y, ref VertexColors initialColor) + public static void SelectSulphuricWaterColor(int x, int y, ref VertexColors initialColor, bool isSlope) { if (SulphuricWaterSafeZoneSystem.NearbySafeTiles.Count >= 1) { @@ -177,10 +108,20 @@ private static void SelectSulphuricWaterColor(int x, int y, ref VertexColors ini } } - initialColor.TopLeftColor *= 0.4f; - initialColor.TopRightColor *= 0.4f; - initialColor.BottomLeftColor *= 0.4f; - initialColor.BottomRightColor *= 0.4f; + if (isSlope) + { + initialColor.TopLeftColor *= 1f / 3; + initialColor.TopRightColor *= 1f / 3; + initialColor.BottomLeftColor *= 1f / 3; + initialColor.BottomRightColor *= 1f / 3; + } + else + { + initialColor.TopLeftColor *= 0.4f; + initialColor.TopRightColor *= 0.4f; + initialColor.BottomLeftColor *= 0.4f; + initialColor.BottomRightColor *= 0.4f; + } } public static void DumpToLog(ILContext il) => CalamityMod.Instance.Logger.Debug(il.ToString()); diff --git a/ILEditing/MechanicILChanges.cs b/ILEditing/MechanicILChanges.cs index 1728f258ad..21d60a67f9 100644 --- a/ILEditing/MechanicILChanges.cs +++ b/ILEditing/MechanicILChanges.cs @@ -1,6 +1,8 @@ using System; +using System.Diagnostics; using System.Linq; using System.Reflection; +using System.Runtime.CompilerServices; using CalamityMod.Balancing; using CalamityMod.Buffs.DamageOverTime; using CalamityMod.CalPlayer; @@ -38,6 +40,7 @@ using Terraria.GameContent.UI.Elements; using Terraria.GameInput; using Terraria.Graphics; +using Terraria.Graphics.Capture; using Terraria.Graphics.Light; using Terraria.Graphics.Shaders; using Terraria.ID; @@ -46,6 +49,7 @@ using Terraria.ModLoader; using Terraria.ModLoader.IO; using Terraria.UI.Gamepad; +using static Terraria.WaterfallManager; namespace CalamityMod.ILEditing { @@ -57,14 +61,12 @@ public partial class ILChanges private static int aLabDoorClosed = -1; private static int exoDoorOpen = -1; private static int exoDoorClosed = -1; - // Cached for use in ChangeWaterQuadColors. - private static CustomLavaStyle cachedLavaStyle = default; // Holds the vanilla game function which spawns town NPCs, wrapped in a delegate for reflection purposes. // This function is (optionally) invoked manually in an IL edit to enable NPCs to spawn at night. private static Action VanillaSpawnTownNPCs; - private static readonly MethodInfo textureGetValueMethod = typeof(Asset).GetMethod("get_Value", BindingFlags.Public | BindingFlags.Instance); + //private static readonly MethodInfo textureGetValueMethod = typeof(Asset).GetMethod("get_Value", BindingFlags.Public | BindingFlags.Instance); public static event Func ExtraColorChangeConditions; @@ -771,264 +773,497 @@ private static void DrawForegroundParticles(Terraria.On_Main.orig_DrawInfernoRin } #endregion - #region Custom Lava Visuals + #region Lava Style Edits + //Nine Layers of Hell brought to you by LIONEIGHTCAKE!! + //All new liquid rendering for lava can be found in Systems/LavaRendering.cs - private static void CacheLavaStyle(Terraria.On_Main.orig_RenderWater orig, Main self) + //To save on time, a LOT of the edits are from the BiomeLava mod (owned by myself, lion8cake). Obv every edit has been changed to reflect + //Calamity's style of IL edits and to remove any unnessesary edits not relivant to calamity. In the loading of the detours and edits + //BiomeLava is a check for whether they load or not. If BiomeLava is active all ModLavaStyles will be turned into ModCalls for BiomeLava. + + #region Lava Rendering + private void DoDrawLavas(ILContext il) { - // Immediately cache the lava drawing style. - // This will pay off in SPADES when we go to draw the tiles. - foreach (CustomLavaStyle style in CustomLavaManagement.CustomLavaStyles) + ILCursor cursor = new ILCursor(il); + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdsfld
("drawToScreen"), i => i.MatchBrfalse(out _), i => i.MatchLdarg0(), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawWaters"))) { - if (style.ChooseLavaStyle()) - { - cachedLavaStyle = style; - orig(self); - return; - } + LogFailure("DoDraw Lava", "Could not locate the drawing of Background Waters"); + return; } - - cachedLavaStyle = default; - orig(self); - } - - private static void DrawCustomLava(Terraria.GameContent.Drawing.On_TileDrawing.orig_DrawPartialLiquid orig, TileDrawing self, bool behindBlocks, Tile tileCache, ref Vector2 position, ref Rectangle liquidSize, int liquidType, ref VertexColors colors) - { - if (liquidType != 1) + cursor.EmitDelegate(() => { + LavaRendering.instance.DrawLavas(isBackground: true); + }); + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdsfld
("drawToScreen"), i => i.MatchBrfalse(out _), i => i.MatchLdarg0(), i => i.MatchLdcI4(0), i => i.MatchCall
("DrawWaters"))) { - orig(self, behindBlocks, tileCache, ref position, ref liquidSize, liquidType, ref colors); + LogFailure("DoDraw Lava", "Could not locate the drawing of Waters"); return; } + cursor.EmitDelegate(() => { + LavaRendering.instance.DrawLavas(); + }); + } - int slope = (int)tileCache.Slope; - colors = SelectLavaQuadColor(TextureAssets.LiquidSlope[liquidType].Value, ref colors, true); - if (!TileID.Sets.BlocksWaterDrawingBehindSelf[tileCache.TileType] || behindBlocks || slope == 0) + private void RenderLavas(ILContext il) + { + ILCursor cursor = new ILCursor(il); + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg0(), i => i.MatchLdcI4(0), i => i.MatchCall
("DrawWaters"))) { - Texture2D liquidTexture = SelectLavaTexture(liquidType == 1 ? CustomLavaManagement.LavaBlockTexture : TextureAssets.Liquid[liquidType].Value, LiquidTileType.Block); - Main.tileBatch.Draw(liquidTexture, position, liquidSize, colors, default(Vector2), 1f, SpriteEffects.None); + LogFailure("Render Lava", "Could not locate the drawing of Waters"); return; } + cursor.EmitDelegate(() => { + LavaRendering.instance.DrawLavas(); + }); + } - Texture2D slopeTexture = SelectLavaTexture(liquidType == 1 ? CustomLavaManagement.LavaSlopeTexture : TextureAssets.LiquidSlope[liquidType].Value, LiquidTileType.Slope); - liquidSize.X += 18 * (slope - 1); - switch (slope) + private void RenderLavaBackgrounds(ILContext il) + { + ILCursor cursor = new ILCursor(il); + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg0(), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawWaters"))) { - case 1: - Main.tileBatch.Draw(slopeTexture, position, liquidSize, colors, Vector2.Zero, 1f, SpriteEffects.None); - break; - case 2: - Main.tileBatch.Draw(slopeTexture, position, liquidSize, colors, Vector2.Zero, 1f, SpriteEffects.None); - break; - case 3: - Main.tileBatch.Draw(slopeTexture, position, liquidSize, colors, Vector2.Zero, 1f, SpriteEffects.None); - break; - case 4: - Main.tileBatch.Draw(slopeTexture, position, liquidSize, colors, Vector2.Zero, 1f, SpriteEffects.None); - break; + LogFailure("Render Lava Backgroumds", "Could not locate the drawing of Background Waters"); + return; } + cursor.EmitDelegate(() => { + LavaRendering.instance.DrawLavas(isBackground: true); + }); } - private static void DrawCustomLava3(ILContext il) + private void DrawLavatoCapture(ILContext il) { ILCursor cursor = new ILCursor(il); - - // Locate the local index for the liquid color and tile coordinates. - int xCoordLocalIndex = 0; - int yCoordLocalIndex = 0; - int liquidColorLocalIndex = 0; - MethodInfo lightingGetColorMethod = typeof(Lighting).GetMethod("GetColor", new Type[] { typeof(int), typeof(int) }); - if (!cursor.TryGotoNext(MoveType.Before, c => c.MatchCallOrCallvirt(lightingGetColorMethod))) + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdsfld
("liquidAlpha"), i => i.MatchCall(out _), i => i.MatchStloc2())) { - LogFailure("Custom Lava Drawing", "Could not lighting GetColor call."); + LogFailure("Draw lavas to captures", "Could not locate the saving of water alphas"); return; } - if (!cursor.TryGotoPrev(c => c.MatchLdloc(out xCoordLocalIndex))) + cursor.EmitDelegate(() => { + LavaRendering.alphaSave = CalamityMod.lavaAlpha.ToArray(); + }); + if (!cursor.TryGotoNext(MoveType.Before, i => i.MatchLdcI4(0), i => i.MatchStloc(34), i => i.MatchBr(out _), i => i.MatchLdloc(34), i => i.MatchLdcI4(1), i => i.MatchBeq(out _))) { - LogFailure("Custom Lava Drawing", "Could not X coordinate local variable index."); + LogFailure("Draw lavas to captures", "Could not locate the resetting of water alphas"); return; } - if (!cursor.TryGotoPrev(c => c.MatchLdloc(out yCoordLocalIndex))) + cursor.EmitLdloc(8); + cursor.EmitDelegate((CaptureBiome biome) => { + for (int i = 0; i < 1; i++) + { + CalamityMod.lavaAlpha[i] = ((i == CalamityMod.LavaStyle) ? 1f : 0f); + } + }); + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg0(), i => i.MatchLdcI4(1), i => i.MatchLdsfld
("waterStyle"), i => i.MatchLdcR4(1), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawLiquid"))) { - LogFailure("Custom Lava Drawing", "Could not Y coordinate local variable index."); + LogFailure("Draw lavas to captures", "Could not locate the background of liquid capture drawing"); return; } - if (!cursor.TryGotoNext(c => c.MatchStloc(out liquidColorLocalIndex))) + cursor.EmitDelegate(() => { + LavaRendering.instance.DrawLiquid(bg: true, CalamityMod.LavaStyle); + }); + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg0(), i => i.MatchLdcI4(1), i => i.MatchLdsfld
("bloodMoon"), i => i.MatchBrtrue(out _), i => i.MatchLdloc(8), i => i.MatchLdfld("WaterStyle"), i => i.MatchBr(out _), i => i.MatchLdcI4(9), i => i.MatchLdcR4(1), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawLiquid"))) { - LogFailure("Custom Lava Drawing", "Could not lighting GetColor local variable index."); + LogFailure("Draw lavas to captures", "Could not locate the second background of liquid capture drawing"); return; } - - // Shortly after the liquid color local is the liquid type integer. Locate it. - int liquidTypeLocalIndex = 0; - if (!cursor.TryGotoNext(MoveType.Before, c => c.MatchLdcI4(0))) + cursor.EmitDelegate(() => { + LavaRendering.instance.DrawLiquid(bg: true, CalamityMod.LavaStyle); + }); + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg0(), i => i.MatchLdcI4(0), i => i.MatchLdsfld
("waterStyle"), i => i.MatchLdcR4(1), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawLiquid"))) { - LogFailure("Custom Lava Drawing", "Could not default value for the liquid type."); + LogFailure("Draw lavas to captures", "Could not locate the liquid capture drawing"); return; } - if (!cursor.TryGotoNext(c => c.MatchStloc(out liquidTypeLocalIndex))) + cursor.EmitDelegate(() => { + LavaRendering.instance.DrawLiquid(bg: false, CalamityMod.LavaStyle); + }); + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg0(), i => i.MatchLdcI4(0), i => i.MatchLdloc(8), i => i.MatchLdfld("WaterStyle"), i => i.MatchLdcR4(1), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawLiquid"))) { - LogFailure("Custom Lava Drawing", "Could not liquid type local variable index."); + LogFailure("Draw lavas to captures", "Could not locate the second liquid capture drawing"); return; } - - // Select the lava color. - if (!cursor.TryGotoNext(MoveType.After, c => c.MatchCallOrCallvirt("get_NotRetro"))) + cursor.EmitDelegate(() => { + LavaRendering.instance.DrawLiquid(bg: false, CalamityMod.LavaStyle); + }); + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdloc2(), i => i.MatchStsfld
("liquidAlpha"))) { - LogFailure("Custom Lava Drawing", "Could not locate the retro style check."); + LogFailure("Draw lavas to captures", "Could not locate water style value returner"); return; } + cursor.EmitDelegate(() => { + CalamityMod.lavaAlpha = LavaRendering.alphaSave; + }); + } - // Pass the texture in so that the method can ensure it is not messing around with non-lava textures. - cursor.Emit(OpCodes.Ldloc, liquidColorLocalIndex); - cursor.Emit(OpCodes.Ldsfld, typeof(TextureAssets).GetField("Liquid")); - cursor.Emit(OpCodes.Ldloc, liquidTypeLocalIndex); - cursor.Emit(OpCodes.Ldelem_Ref); - cursor.Emit(OpCodes.Call, textureGetValueMethod); - cursor.Emit(OpCodes.Ldloc, xCoordLocalIndex); - cursor.Emit(OpCodes.Ldloc, yCoordLocalIndex); - cursor.EmitDelegate>((initialColor, initialTexture, x, y) => + private void AddTileLiquidDrawing(ILContext il) + { + ILCursor cursor = new ILCursor(il); + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg0(), i => i.MatchLdarg1(), i => i.MatchLdcI4(0), i => i.MatchLdarg(out _), i => i.MatchLdloc1(), i => i.MatchLdloc2(), i => i.MatchLdloc(12), i => i.MatchLdloc(13), i => i.MatchLdloc(14), i => i.MatchCall("DrawTile_LiquidBehindTile"))) { - Color c = SelectLavaColor(initialTexture, initialColor); - - if (ExtraColorChangeConditions is not null) - c = ExtraColorChangeConditions(new(c), Main.waterStyle, new(x, y)).TopLeftColor; - - return c; + LogFailure("Tile Lava Drawing", "Could not locate the drawing of Liquid Behind Tile drawing"); + return; + } + cursor.EmitLdloc1(); + cursor.EmitLdloc2(); + cursor.EmitLdloc(12); + cursor.EmitLdloc(13); + cursor.EmitLdloc(14); + cursor.EmitDelegate((Microsoft.Xna.Framework.Vector2 unscaledPosition, Microsoft.Xna.Framework.Vector2 vector, int j, int i, Terraria.Tile tile) => { + LavaRendering.instance.DrawTile_LiquidBehindTile(solidLayer: false, inFrontOfPlayers: false, -1, unscaledPosition, vector, j, i, tile); }); - cursor.Emit(OpCodes.Stloc, liquidColorLocalIndex); + } + #endregion + + #region Lava Blocking + private void BlockLavaDrawing(ILContext il) + { + //This edit to DrawNormalLiquids makes lavas in normal and white lighting draw with an alpha and with new textures + //If the parameter for the waterstyle is more than the max waterstyles then its subtracted by the max water style count and thats the lava style ID + ILCursor cursor = new ILCursor(il); - // Go back to the start and change textures as necessary. - cursor.Index = 0; + //Continue if statement, basically + //if the liquid being drawn is lava and the water style is greater than the max water styles or if the liquid is water and less than the max water styles then the draw code is ran + //otherwise the loop/s are continued for the next liquid + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchStloc(4), i => i.MatchBr(out _), i => i.MatchLdloc(2), i => i.MatchLdfld(typeof(LiquidRenderer).GetNestedType("LiquidDrawCache", BindingFlags.NonPublic), "IsVisible"))) + { + LogFailure("Liquid Renderer Drawing", "Could not locate the IsVisible boolean check"); + return; + } + cursor.EmitLdarg3(); + cursor.EmitLdloc2(); //Initiated Liquid Draw Cache (needed for the Type parameter) + cursor.EmitLdfld(typeof(LiquidRenderer).GetNestedType("LiquidDrawCache", BindingFlags.NonPublic).GetRuntimeField("Type")); + cursor.EmitDelegate>((IsVisible, style, type) => IsVisible && ((type == 1 && style >= LavaRendering.instance.WaterStyleMaxCount + 1) || (type != 1 && style <= LavaRendering.instance.WaterStyleMaxCount))); - while (cursor.TryGotoNext(c => c.MatchLdsfld(typeof(TextureAssets).GetField("Liquid")))) + //Lava alpha color, if the liquid drawn is lava, multiply num by the water alpha + if (!cursor.TryGotoNext(MoveType.Before, i => i.MatchLdloc(2), i => i.MatchLdfld(typeof(LiquidRenderer).GetNestedType("LiquidDrawCache", BindingFlags.NonPublic).GetRuntimeField("Type")), i => i.MatchStloc(8))) + { + LogFailure("Liquid Renderer Drawing", "Could not locate creation of the local variable num2 (the liquid type holder variable)"); + return; + } + cursor.EmitLdloc(8); + cursor.EmitLdloca(7); + cursor.EmitLdarg(4); + cursor.EmitDelegate((int num2, ref float num, float globalAlpha) => { - // Move to the end of the get_Value() call and then use the resulting texture to check if a new one should replace it. - // Adding to the index directly would seem like a simple, direct way of achieving this since the operation is incredibly light, but - // it is unsafe due to the potential for NOP operations to appear. - if (!cursor.TryGotoNext(MoveType.After, c => c.MatchCallvirt(textureGetValueMethod))) + if (num2 == LiquidID.Lava) { - LogFailure("Custom Lava Drawing", "Could not locate the liquid texture Value call."); - return; + num *= globalAlpha; } + }); + + //Conditionally replace the liquid texture whether the liquid is lava or water + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchCallvirt(typeof(Asset).GetMethod("get_Value", BindingFlags.Public | BindingFlags.Instance)))) + { + LogFailure("Liquid Renderer Drawing", "Could not locate the Texture2D array of liquids"); + return; + } + cursor.EmitLdarg3(); + cursor.EmitLdloc2(); //Initiated Liquid Draw Cache (needed for the Type parameter) + cursor.EmitLdfld(typeof(LiquidRenderer).GetNestedType("LiquidDrawCache", BindingFlags.NonPublic).GetRuntimeField("Type")); + cursor.EmitDelegate>((initialTexture, style, type) => (style >= LavaRendering.instance.WaterStyleMaxCount + 1 && type == LiquidID.Lava) ? CalamityMod.LavaTextures.liquid[style - LavaRendering.instance.WaterStyleMaxCount - 1].Value : initialTexture); + } - cursor.EmitDelegate>(initialTexture => SelectLavaTexture(initialTexture, LiquidTileType.Block)); + private void BlockLavaDrawingForSlopes(On_TileDrawing.orig_DrawTile_LiquidBehindTile orig, TileDrawing self, bool solidLayer, bool inFrontOfPlayers, int waterStyleOverride, Vector2 screenPosition, Vector2 screenOffset, int tileX, int tileY, Tile tileCache) + { + Tile tile = Main.tile[tileX + 1, tileY]; + Tile tile2 = Main.tile[tileX - 1, tileY]; + Tile tile3 = Main.tile[tileX, tileY - 1]; + Tile tile4 = Main.tile[tileX, tileY + 1]; + if (tileCache.LiquidType == LiquidID.Lava || tile.LiquidType == LiquidID.Lava || tile2.LiquidType == LiquidID.Lava || tile3.LiquidType == LiquidID.Lava || tile4.LiquidType == LiquidID.Lava) + { + return; + } + orig.Invoke(self, solidLayer, inFrontOfPlayers, waterStyleOverride, screenPosition, screenOffset, tileX, tileY, tileCache); + } + + private void BlockLavaDrawingForSlopes2(On_TileDrawing.orig_DrawPartialLiquid orig, TileDrawing self, bool behindBlocks, Tile tileCache, ref Vector2 position, ref Rectangle liquidSize, int liquidType, ref VertexColors colors) + { + if (liquidType == 1) + { + return; } + orig.Invoke(self, behindBlocks, tileCache, ref position, ref liquidSize, liquidType, ref colors); } - private static void DrawCustomLavafalls(Terraria.On_WaterfallManager.orig_DrawWaterfall_int_int_int_float_Vector2_Rectangle_Color_SpriteEffects orig, WaterfallManager self, int waterfallType, int x, int y, float opacity, Vector2 position, Rectangle sourceRect, Color color, SpriteEffects effects) + private void LavafallRemover(On_WaterfallManager.orig_DrawWaterfall_int_int_int_float_Vector2_Rectangle_Color_SpriteEffects orig, WaterfallManager self, int waterfallType, int x, int y, float opacity, Vector2 position, Rectangle sourceRect, Color color, SpriteEffects effects) { - waterfallType = CustomLavaManagement.SelectLavafallStyle(waterfallType); - color = CustomLavaManagement.SelectLavafallColor(waterfallType, color); + if (waterfallType == 1) + { + return; + } + orig.Invoke(self, waterfallType, x, y, opacity, position, sourceRect, color, effects); + } - orig(self, waterfallType, x, y, opacity, position, sourceRect, color, effects); + private void BlockRetroLightingLava(ILContext il) + { + ILCursor cursor = new ILCursor(il); + ILLabel target = cursor.DefineLabel(); + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchCgt(), i => i.MatchLdarg1(), i => i.MatchOr(), i => i.MatchBrfalse(out target))) + { + LogFailure("old Drawing Waters", "Could not locate the if statement that contains the check for liquid types, amounts and wether the liquid has a bg (arg1) or not"); + return; + } + if (target == null) + { + LogFailure("old Drawing Waters", "The BrFalse returned null, the boolean check getting was unsuccessful"); + return; + } + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdindU1(), i => i.MatchSub(), i => i.MatchConvR4(), i => i.MatchStloc(14))) + { + LogFailure("old Drawing Waters", "Could not locate the num3 local variable creation to put the if check after"); + return; + } + cursor.EmitLdloc(12); + cursor.EmitLdloc(11); + cursor.EmitDelegate((int i, int j) => { + return Main.tile[i, j].LiquidType == LiquidID.Lava; + }); + cursor.EmitBrtrue(target); } #endregion + + #region Lava Replacing + private void LavaBubbleReplacer(ILContext il) + { + ILCursor cursor = new ILCursor(il); + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdcI4(16), i => i.MatchLdcI4(16), i => i.MatchLdcI4(35))) + { + LogFailure("Ambient lava bubble replacer", "Could not locate the bubble newdust parameters"); + return; + } + cursor.EmitDelegate>(type => LavaRendering.dustLava()); + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdcI4(16), i => i.MatchLdcI4(8), i => i.MatchLdcI4(35))) + { + LogFailure("Ambient lava bubble replacer", "Could not locate the surface bubble newdust parameters"); + return; + } + cursor.EmitDelegate>(type2 => LavaRendering.dustLava()); + } + + private void LavaDropletReplacer(ILContext il) + { + ILCursor cursor = new ILCursor(il); + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg(out _), i => i.MatchLdcI4(374), i => i.MatchBneUn(out _), i => i.MatchLdcI4(716))) + { + LogFailure("Ambient lava droplet replacer", "Could not locate the lava droplet newgore parameters"); + return; + } + cursor.EmitDelegate>(type => LavaRendering.goreLava()); + } - #region Water Visuals - private static void MakeSulphSeaWaterBetter(Terraria.Graphics.Light.On_TileLightScanner.orig_GetTileLight orig, TileLightScanner self, int x, int y, out Vector3 outputColor) + private void SplashEntityLava(ILContext il) { - orig(self, x, y, out outputColor); - if (outputColor == Vector3.One || outputColor == new Vector3(0.25f, 0.25f, 0.25f) || outputColor == new Vector3(0.5f, 0.5f, 0.5f)) + ILCursor cursor = new ILCursor(il); + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdfld("width"), i => i.MatchLdcI4(12), i => i.MatchAdd(), i => i.MatchLdcI4(24), i => i.MatchLdcI4(35))) + { + LogFailure("Entity Lava Splashing (Item, Projectile, NPC, Player)", "Could not locate the first lava bubble splashing"); + return; + } + cursor.EmitDelegate>(type => LavaRendering.dustLava()); + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdfld("width"), i => i.MatchLdcI4(12), i => i.MatchAdd(), i => i.MatchLdcI4(24), i => i.MatchLdcI4(35))) + { + LogFailure("Entity Lava Splashing (Item, Projectile, NPC, Player)", "Could not locate the second lava bubble splashing"); return; + } + cursor.EmitDelegate>(type2 => LavaRendering.dustLava()); + } - Tile tile = CalamityUtils.ParanoidTileRetrieval(x, y); - if (tile.LiquidAmount <= 0 || tile.HasTile || (Main.waterStyle != SulphuricWater.Type && - Main.waterStyle != SulphuricDepthsWater.Type && Main.waterStyle != SunkenSeaWater.Type)) + private void PlayerDebuffEdit(ILContext il) + { + //Injects code directly at the position where the OnFire debuff is handled + ILCursor cursor = new ILCursor(il); + if (!cursor.TryGotoNext(MoveType.Before, i => i.MatchLdarg0(), i => i.MatchLdcI4(24), i => i.MatchLdloc(161), i => i.MatchLdcI4(1), i => i.MatchLdcI4(0), i => i.MatchCall("AddBuff"))) + { + LogFailure("Player Update Lava Debuff", "Could not locate the infliction of the On Fire! debuff inside the Player Update code"); return; + } + cursor.EmitLdarg0(); + cursor.EmitLdloc(161); + cursor.EmitDelegate((Player player, int onFiretime) => + { + LavaStylesLoader.InflictDebuff(player, CalamityMod.LavaStyle, onFiretime); + }); + } + #endregion - Tile above = CalamityUtils.ParanoidTileRetrieval(x, y - 1); - if (!Main.gamePaused && !above.HasTile && above.LiquidAmount <= 0 && Main.rand.NextBool(9) && - Main.waterStyle == SulphuricWater.Type) + #region Other + private Color WaterfallGlowmaskEditor(On_WaterfallManager.orig_StylizeColor orig, float alpha, int maxSteps, int waterfallType, int y, int s, Tile tileCache, Color aColor) + { + if (CalamityMod.LavaStyle != 0 && !LavaStylesLoader.Get(CalamityMod.LavaStyle).LavafallGlowmask()) { - MediumMistParticle acidFoam = new(new(x * 16f + Main.rand.NextFloat(16f), y * 16f + 8f), -Vector2.UnitY.RotatedByRandom(0.67f) * Main.rand.NextFloat(1f, 2.4f), Color.LightSeaGreen, Color.White, 0.16f, 128f, 0.02f); - GeneralParticleHandler.SpawnParticle(acidFoam); + return aColor; } + else + { + return orig.Invoke(alpha, maxSteps, waterfallType, y, s, tileCache, aColor); + } + } - if (tile.TileType != (ushort)ModContent.TileType()) + private void LavaFallRedrawer(On_WaterfallManager.orig_Draw orig, WaterfallManager self, SpriteBatch spriteBatch) + { + orig.Invoke(self, spriteBatch); + LavaRendering.instance.InitialDrawLavafall(self); + } + #endregion + + #endregion + + #region Liquid Visuals + //Contains all liquid light and liquid alpha (seethrough-ability) + private void LiquidEmitLight(On_TileLightScanner.orig_ApplyLiquidLight orig, TileLightScanner self, Tile tile, ref Vector3 lightColor) + { + orig.Invoke(self, tile, ref lightColor); + if (tile.LiquidAmount > 0 && !tile.HasTile) { - if (Main.waterStyle == SulphuricWater.Type && Main.dayTime && !Main.raining) + if (tile.LiquidType == LiquidID.Water) { - float brightness = MathHelper.Clamp(0.2f - (y / 680), 0f, 0.2f); - if (y > 580) - brightness *= 1f - (y - 580) / 100f; - - float waveScale1 = Main.GameUpdateCount * 0.014f; - float waveScale2 = Main.GameUpdateCount * 0.1f; - int scalar = x + (-y / 2); - float wave1 = waveScale1 * -50 + scalar * 15; - float wave2 = waveScale2 * -10 + scalar * 14; - float wave3 = waveScale1 * -100 + scalar * 13; - float wave4 = waveScale2 * 10 + scalar * 25; - float wave5 = waveScale1 * -70 + scalar * 5; - float wave1angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave1)); - float wave2angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave2)); - float wave3angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave3)); - float wave4angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave4)); - float wave5angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave5)); - outputColor = Vector3.Lerp(outputColor, Color.LightSeaGreen.ToVector3(), 0.41f + wave1angle + wave2angle + wave3angle + wave4angle + wave5angle); - outputColor *= brightness; + float R = 0f; + float G = 0f; + float B = 0f; + CalamityWaterLoader.ModifyLightSetup(tile.X(), tile.Y(), Main.waterStyle, ref R, ref G, ref B); + if (lightColor.X < R) + { + lightColor.X = R; + } + if (lightColor.Y < G) + { + lightColor.Y = G; + } + if (lightColor.Z < B) + { + lightColor.Z = B; + } } - - if (Main.waterStyle == SulphuricWater.Type && !Main.dayTime && !Main.raining) + else if (tile.LiquidType == LiquidID.Lava && CalamityMod.Instance.biomeLava == null) { - float brightness = MathHelper.Clamp(0.17f - (y / 680), 0f, 0.17f); - if (y > 580) - brightness *= 1f - (y - 580) / 100f; - - float waveScale1 = Main.GameUpdateCount * 0.014f; - float waveScale2 = Main.GameUpdateCount * 0.1f; - int scalar = x + (-y / 2); - float wave1 = waveScale1 * -50 + scalar * 15; - float wave2 = waveScale2 * -10 + scalar * 14; - float wave3 = waveScale1 * -100 + scalar * 13; - float wave4 = waveScale2 * 10 + scalar * 25; - float wave5 = waveScale1 * -70 + scalar * 5; - float wave1angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave1)); - float wave2angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave2)); - float wave3angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave3)); - float wave4angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave4)); - float wave5angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave5)); - outputColor = Vector3.Lerp(outputColor, Color.LightSeaGreen.ToVector3(), 0.41f + wave1angle + wave2angle + wave3angle + wave4angle + wave5angle); - outputColor *= brightness; + Vector3 lavaLight = new Vector3(0.55f, 0.33f, 0.11f); + float R = CalamityMod.LavaStyle == 0 ? lavaLight.X : 0f; + float G = CalamityMod.LavaStyle == 0 ? lavaLight.Y : 0f; + float B = CalamityMod.LavaStyle == 0 ? lavaLight.Z : 0f; + LavaStylesLoader.ModifyLightSetup(tile.X(), tile.Y(), CalamityMod.LavaStyle, ref R, ref G, ref B); + for (int j = 0; j < LavaStylesLoader.TotalCount; j++) + { + if (CalamityMod.lavaAlpha[j] > 0f && j != CalamityMod.LavaStyle) + { + float r = j == 0 ? lavaLight.X : 0f; + float g = j == 0 ? lavaLight.Y : 0f; + float b = j == 0 ? lavaLight.Z : 0f; + LavaStylesLoader.ModifyLightSetup(tile.X(), tile.Y(), j, ref r, ref g, ref b); + float r2 = CalamityMod.LavaStyle == 0 ? lavaLight.X : 0f; + float g2 = CalamityMod.LavaStyle == 0 ? lavaLight.Y : 0f; + float b2 = CalamityMod.LavaStyle == 0 ? lavaLight.Z : 0f; + LavaStylesLoader.ModifyLightSetup(tile.X(), tile.Y(), CalamityMod.LavaStyle, ref r2, ref g2, ref b2); + R = Single.Lerp(r, r2, CalamityMod.lavaAlpha[CalamityMod.LavaStyle]); + G = Single.Lerp(g, g2, CalamityMod.lavaAlpha[CalamityMod.LavaStyle]); + B = Single.Lerp(b, b2, CalamityMod.lavaAlpha[CalamityMod.LavaStyle]); + } + } + if (!(R == 0 && G == 0 && B == 0)) + { + float colorManipulator = (float)(270 - Main.mouseTextColor) / 900f; + R += colorManipulator; + G += colorManipulator; + B += colorManipulator; + } + if (lightColor.X < R) + { + lightColor.X = R; + } + if (lightColor.Y < G) + { + lightColor.Y = G; + } + if (lightColor.Z < B) + { + lightColor.Z = B; + } } + } + } - if (Main.waterStyle == SulphuricWater.Type && Main.raining) + private void LavafallLightEditor(On_WaterfallManager.orig_AddLight orig, int waterfallType, int x, int y) + { + if (waterfallType == 1) + { + float r = 0.55f; + float g = 0.33f; + float b = 0.11f; + LavaStylesLoader.ModifyLightSetup(x, y, CalamityMod.LavaStyle, ref r, ref g, ref b); + if (!(r == 0 && g == 0 && b == 0)) { - float brightness = MathHelper.Clamp(1f - (y / 680), 0f, 1f); - if (y > 580) - brightness *= 1f - (y - 580) / 100f; - - outputColor = Vector3.Lerp(outputColor, Color.LightSeaGreen.ToVector3(), 0.41f); - outputColor *= brightness; + float r8; + float num3 = (r8 = (r + (float)(270 - Main.mouseTextColor) / 900f) * 0.4f); + float g8 = num3 * g; + float b8 = num3 * b; + Lighting.AddLight(x, y, r8, g8, b8); } + return; + } + orig.Invoke(waterfallType, x, y); + } - if (Main.waterStyle == SulphuricDepthsWater.Type) - outputColor = Vector3.Lerp(outputColor, Color.MediumSeaGreen.ToVector3(), 0.18f); + private static void LiquidDrawColors(ILContext il) + { + ILCursor cursor = new ILCursor(il); + if (!cursor.TryGotoNext(MoveType.Before, c => c.MatchLdarg2(), c => c.MatchLdloc3(), c => c.MatchLdloc(4), c => c.MatchCall
("DrawTileInWater"))) + { + LogFailure("Liquid Draw Colors", "Could not locate the liquid vertex colors for drawing"); + return; + } - if (Main.waterStyle == SunkenSeaWater.Type) + cursor.Emit(OpCodes.Ldloc_3); + cursor.Emit(OpCodes.Ldloc, 4); + cursor.Emit(OpCodes.Ldloc_2); + cursor.Emit(OpCodes.Ldfld, typeof(LiquidRenderer).GetNestedType("LiquidDrawCache", BindingFlags.NonPublic).GetRuntimeField("Type")); + cursor.Emit(OpCodes.Ldloca, 9); + + cursor.EmitDelegate((int x, int y, int liquidType, ref VertexColors initialColor) => + { + if (liquidType == LiquidID.Water) { - float brightness = MathHelper.Clamp(0.07f, 0f, 0.07f); - float waveScale1 = Main.GameUpdateCount * 0.028f; - float waveScale2 = Main.GameUpdateCount * 0.1f; - int yScale = -y / 2; - int xScale = x / 15; - float wave1 = Main.GameUpdateCount * 0.024f * -50 + ((-x / 30) + (y / 30)) * 25; - float wave2 = waveScale2 * -10 + ((-xScale) + yScale) * 45; - float wave3 = waveScale1 * -100 + ((x / 7) + (y / 50)) * 25; - float wave4 = Main.GameUpdateCount * 0.15f * 10 + ((x / 3) + yScale) * 45; - float wave5 = waveScale1 * -70 + ((-x / 25) + (-y / 25)) * 20; - float wave6 = waveScale2 * -10 + (xScale + yScale) * 45; - float bigwave = Main.GameUpdateCount * 0.01f * -70 + ((-x / 2) + (-y / 40)) * 5; - float wave1angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave1)); - float wave2angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave2)); - float wave3angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave3)); - float wave4angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave4)); - float wave5angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave5)); - float wave6angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave6)); - float bigwaveangle = 0.55f + 0.80f * (float)Math.Sin(MathHelper.ToRadians(bigwave)); - outputColor = Vector3.Lerp(outputColor, Color.DeepSkyBlue.ToVector3(), 0.07f + wave1angle + wave2angle + wave3angle + wave4angle + wave5angle + wave6angle + bigwaveangle); - outputColor *= brightness; + CalamityWaterLoader.DrawColorSetup(x, y, Main.waterStyle, ref initialColor); } + else if (liquidType == LiquidID.Lava && CalamityMod.Instance.biomeLava == null) + { + LavaStylesLoader.DrawColorSetup(x, y, CalamityMod.LavaStyle, ref initialColor); + } + }); + } + + private static void LiquidSlopeDrawColors(ILContext il) + { + ILCursor cursor = new ILCursor(il); + + if (!cursor.TryGotoNext(MoveType.Before, c => c.MatchLdcI4(0), c => c.MatchStloc(19), c => c.MatchLdloc(11), c => c.MatchBrfalse(out _))) + { + LogFailure("Liquid Slope Draw Colors", "Could not locate the liquid slope vertex colors for drawing"); + return; } + + cursor.Emit(OpCodes.Ldarg, 6); + cursor.Emit(OpCodes.Ldarg, 7); + cursor.Emit(OpCodes.Ldloca, 14); + cursor.Emit(OpCodes.Ldloc, 11); + cursor.Emit(OpCodes.Ldloc, 10); + + cursor.EmitDelegate((int x, int y, ref VertexColors initialColor, bool flag6, int num2) => + { + if (flag6) + { + int totalCount = (int)typeof(Loader).GetProperty("TotalCount", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static).GetValue(LoaderManager.Get()); + for (int i = 0; i < totalCount; i++) + { + Tile tile = Main.tile[x, y]; + if (i == Main.waterStyle && tile.LiquidType == LiquidID.Water) + { + CalamityWaterLoader.DrawColorSetup(x, y, Main.waterStyle, ref initialColor, true); + } + else if ((tile.LiquidType == LiquidID.Lava || i == 1) && CalamityMod.Instance.biomeLava == null) + { + LavaStylesLoader.DrawColorSetup(x, y, CalamityMod.LavaStyle, ref initialColor); + } + } + } + }); } #endregion diff --git a/ModSupport/WeakReferenceSupport.cs b/ModSupport/WeakReferenceSupport.cs index 16a7083033..6aba7efb99 100644 --- a/ModSupport/WeakReferenceSupport.cs +++ b/ModSupport/WeakReferenceSupport.cs @@ -206,6 +206,54 @@ public static void Setup() } } + #region BiomeLava + public static void LavaStytleToBiomeLava() + { + CalamityMod calamity = GetInstance(); + Mod biomelava = calamity.biomeLava; + if (biomelava == null) + return; + + foreach (ModLavaStyle item in LavaStylesLoader.Content) + { + int type = item.Slot; + ModLavaStyle lavaStyle = LavaStylesLoader.Get(type); + if (lavaStyle != null) + { + Func GetSplashDust = lavaStyle.GetSplashDust; + Func GetDropletGore = lavaStyle.GetDropletGore; + Func ModifyLightFunc = ModifyLight; + Func IsLavaActive = lavaStyle.IsLavaActive; + Func lavafallGlowmask = lavaStyle.LavafallGlowmask; + Func InflictDebuffFunc = InflictDebuff; + Func yes = InflictsOnFire; + + Vector3 ModifyLight(int x, int y, float r, float g, float b) + { + lavaStyle.ModifyLight(x, y, ref r, ref g, ref b); + return new Vector3(r, g, b); + } + + Action InflictDebuff(Player player, NPC npc, int onfireDuration) + { + if (player != null && npc == null) + { + lavaStyle.InflictDebuff(player, onfireDuration); + } + return null; + } + + bool InflictsOnFire() + { + return true; + } + + biomelava.Call("ModLavaStyle", calamity, lavaStyle.Name, lavaStyle.Texture, lavaStyle.BlockTexture, lavaStyle.SlopeTexture, lavaStyle.WaterfallTexture, GetSplashDust, GetDropletGore, ModifyLightFunc, IsLavaActive, lavafallGlowmask, InflictDebuffFunc, yes); + } + } + } + #endregion + #region WikiThis // This is a separate function because it only runs clientside public static void WikiThisSupport() diff --git a/Systems/CalamityModWaterStyle.cs b/Systems/CalamityModWaterStyle.cs new file mode 100644 index 0000000000..66c3d6766f --- /dev/null +++ b/Systems/CalamityModWaterStyle.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using Terraria; +using Terraria.Graphics; +using Terraria.ModLoader; + +namespace CalamityMod.Systems +{ + public abstract class CalamityModWaterStyle : ModWaterStyle + { + /// + /// Allows water styles to manipulate what color the liquid is drawn to, this can allow waters to be see-throughable to see backgrounds (surface and underground backgrounds not walls) + /// + /// X position of the water + /// Y position of the water + /// The vertexColor of the water color, this is both used to get the current color and to set the color of the water + public virtual void DrawColor(int x, int y, ref VertexColors liquidColor, bool isSlope) + { + } + + /// + /// Allows you to determine how much light this water emits.
+ /// It can also let you light up the block in front of this water.
+ /// See for vanilla tile light values to use as a reference.
+ ///
+ /// The x position in tile coordinates. + /// The y position in tile coordinates. + /// The red component of light, usually a value between 0 and 1 + /// The green component of light, usually a value between 0 and 1 + /// The blue component of light, usually a value between 0 and 1 + public virtual void ModifyLight(int i, int j, ref float r, ref float g, ref float b) + { + } + } + + internal static class CalamityWaterLoader + { + internal static void ModifyLightSetup(int i, int j, int type, ref float r, ref float g, ref float b) + { + CalamityModWaterStyle styles = (CalamityModWaterStyle)LoaderManager.Get().Get(type); + if (styles != null) + { + styles?.ModifyLight(i, j, ref r, ref g, ref b); + } + } + + internal static void DrawColorSetup(int x, int y, int type, ref VertexColors liquidColor, bool isSlope = false) + { + CalamityModWaterStyle styles = (CalamityModWaterStyle)LoaderManager.Get().Get(type); + if (styles != null) + { + styles?.DrawColor(x, y, ref liquidColor, isSlope); + } + } + } +} diff --git a/Systems/LavaRendering.cs b/Systems/LavaRendering.cs new file mode 100644 index 0000000000..8dc526e169 --- /dev/null +++ b/Systems/LavaRendering.cs @@ -0,0 +1,1159 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.GameContent.Liquid; +using Terraria.Graphics; +using Terraria.ID; +using Terraria.ModLoader; +using static Terraria.WaterfallManager; + +namespace CalamityMod.Systems +{ + public class LavaRendering : ModSystem + { + //Welcome to Calamity's lava rendering. Prepare your eyes + public static LavaRendering instance; + + public int WaterStyleMaxCount = ModContent.GetContent().Count() + LoaderManager.Get().VanillaCount; + + internal static float[] alphaSave; + + public override void Load() + { + LavaRendering.alphaSave = new float[CalamityMod.lavaAlpha.Length]; + } + + public void DrawLavas(bool isBackground = false) + { + Main.drewLava = false; + if (!isBackground) + { + CalamityMod.LavaStyle = 0; + LavaStylesLoader.IsLavaActive(); + for (int i = 0; i < 1; i++) + { + if (CalamityMod.LavaStyle != i) + { + CalamityMod.lavaAlpha[i] = Math.Max(CalamityMod.lavaAlpha[i] - 0.2f, 0f); + } + else + { + CalamityMod.lavaAlpha[i] = Math.Min(CalamityMod.lavaAlpha[i] + 0.2f, 1f); + } + } + LavaStylesLoader.UpdateLiquidAlphas(); + } + bool flag = false; + for (int j = 0; j < LavaStylesLoader.TotalCount; j++) + { + if (CalamityMod.lavaAlpha[j] > 0f && j != CalamityMod.LavaStyle) + { + DrawLiquid(isBackground, j, isBackground ? 1f : CalamityMod.lavaAlpha[j], drawSinglePassLiquids: false); + flag = true; + } + } + DrawLiquid(isBackground, CalamityMod.LavaStyle, flag ? CalamityMod.lavaAlpha[CalamityMod.LavaStyle] : 1f); + } + + protected internal void DrawLiquid(bool bg = false, int lavaStyle = 0, float Alpha = 1f, bool drawSinglePassLiquids = true) + { + if (!Lighting.NotRetro) + { + oldDrawLava(bg, lavaStyle, Alpha); + return; + } + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + Vector2 drawOffset = (Vector2)(Main.drawToScreen ? Vector2.Zero : new Vector2((float)Main.offScreenRange, (float)Main.offScreenRange)) - Main.screenPosition; + if (bg) + { + DrawLiquidBehindTiles(lavaStyle); + } + LiquidRenderer.Instance.DrawNormalLiquids(Main.spriteBatch, drawOffset, lavaStyle + ModContent.GetContent().Count() + LoaderManager.Get().VanillaCount + 1, Alpha, bg); + if (!bg) + { + TimeLogger.DrawTime(4, stopwatch.Elapsed.TotalMilliseconds); + } + } + + public void oldDrawLava(bool bg = false, int Style = 0, float Alpha = 1f) + { + float num = 0f; + float num12 = 99999f; + float num23 = 99999f; + int num27 = -1; + int num28 = -1; + Vector2 vector = new((float)Main.offScreenRange, (float)Main.offScreenRange); + if (Main.drawToScreen) + { + vector = Vector2.Zero; + } + _ = new Color[4]; + int num29 = (int)(255f * (1f - Main.gfxQuality) + 40f * Main.gfxQuality); + _ = Main.gfxQuality; + _ = Main.gfxQuality; + int num30 = (int)((Main.screenPosition.X - vector.X) / 16f - 1f); + int num31 = (int)((Main.screenPosition.X + (float)Main.screenWidth + vector.X) / 16f) + 2; + int num32 = (int)((Main.screenPosition.Y - vector.Y) / 16f - 1f); + int num2 = (int)((Main.screenPosition.Y + (float)Main.screenHeight + vector.Y) / 16f) + 5; + if (num30 < 5) + { + num30 = 5; + } + if (num31 > Main.maxTilesX - 5) + { + num31 = Main.maxTilesX - 5; + } + if (num32 < 5) + { + num32 = 5; + } + if (num2 > Main.maxTilesY - 5) + { + num2 = Main.maxTilesY - 5; + } + Vector2 vector2; + Rectangle value; + Color newColor; + for (int i = num32; i < num2 + 4; i++) + { + for (int j = num30 - 2; j < num31 + 2; j++) + { + if (Main.tile[j, i].LiquidAmount <= 0 || (Main.tile[j, i].HasUnactuatedTile && Main.tileSolid[Main.tile[j, i].TileType] && !Main.tileSolidTop[Main.tile[j, i].TileType]) || !(Lighting.Brightness(j, i) > 0f || bg) || Main.tile[j, i].LiquidType != LiquidID.Lava) + { + continue; + } + Color color = Lighting.GetColor(j, i); + float num3 = 256 - Main.tile[j, i].LiquidAmount; + num3 /= 32f; + int num4 = 0; + if (Main.tile[j, i].LiquidType == LiquidID.Lava) + { + /*if (Main.drewLava) //disallows the back liquid to not draw until its alpha hits 1f apparently + { + continue; + }*/ + float num5 = Math.Abs((float)(j * 16 + 8) - (Main.screenPosition.X + (float)(Main.screenWidth / 2))); + float num6 = Math.Abs((float)(i * 16 + 8) - (Main.screenPosition.Y + (float)(Main.screenHeight / 2))); + if (num5 < (float)(Main.screenWidth * 2) && num6 < (float)(Main.screenHeight * 2)) + { + float num7 = (float)Math.Sqrt(num5 * num5 + num6 * num6); + float num8 = 1f - num7 / ((float)Main.screenWidth * 0.75f); + if (num8 > 0f) + { + num += num8; + } + } + if (num5 < num12) + { + num12 = num5; + num27 = j * 16 + 8; + } + if (num6 < num23) + { + num23 = num5; + num28 = i * 16 + 8; + } + } + if (num4 == 0) + { + num4 = Style; + } + if (Main.drewLava) + { + continue; + } + float num9 = 0.5f; + if (bg) + { + num9 = 1f; + } + num9 *= Alpha; + Main.DrawTileInWater(-Main.screenPosition + vector, j, i); //lily pads + vector2 = new((float)(j * 16), (float)(i * 16 + (int)num3 * 2)); + value = new(0, 0, 16, 16 - (int)num3 * 2); + bool flag2 = true; + if (Main.tile[j, i + 1].LiquidAmount < 245 && (!Main.tile[j, i + 1].HasUnactuatedTile || !Main.tileSolid[Main.tile[j, i + 1].TileType] || Main.tileSolidTop[Main.tile[j, i + 1].TileType])) + { + float num10 = 256 - Main.tile[j, i + 1].LiquidAmount; + num10 /= 32f; + num9 = 0.5f * (8f - num3) / 4f; + if ((double)num9 > 0.55) + { + num9 = 0.55f; + } + if ((double)num9 < 0.35) + { + num9 = 0.35f; + } + float num11 = num3 / 2f; + if (Main.tile[j, i + 1].LiquidAmount < 200) + { + if (bg) + { + continue; + } + if (Main.tile[j, i - 1].LiquidAmount > 0 && Main.tile[j, i - 1].LiquidAmount > 0) + { + value = new(0, 4, 16, 16); + num9 = 0.5f; + } + else if (Main.tile[j, i - 1].LiquidAmount > 0) + { + vector2 = new((float)(j * 16), (float)(i * 16 + 4)); + value = new(0, 4, 16, 12); + num9 = 0.5f; + } + else if (Main.tile[j, i + 1].LiquidAmount > 0) + { + vector2 = new((float)(j * 16), (float)(i * 16 + (int)num3 * 2 + (int)num10 * 2)); + value = new(0, 4, 16, 16 - (int)num3 * 2); + } + else + { + vector2 = new((float)(j * 16 + (int)num11), (float)(i * 16 + (int)num11 * 2 + (int)num10 * 2)); + value = new(0, 4, 16 - (int)num11 * 2, 16 - (int)num11 * 2); + } + } + else + { + num9 = 0.5f; + value = new(0, 4, 16, 16 - (int)num3 * 2 + (int)num10 * 2); + } + } + else if (Main.tile[j, i - 1].LiquidAmount > 32) + { + value = new(0, 4, value.Width, value.Height); + } + else if (num3 < 1f && Main.tile[j, i - 1].HasUnactuatedTile && Main.tileSolid[Main.tile[j, i - 1].TileType] && !Main.tileSolidTop[Main.tile[j, i - 1].TileType]) + { + vector2 = new((float)(j * 16), (float)(i * 16)); + value = new(0, 4, 16, 16); + } + else + { + for (int k = i + 1; k < i + 6 && (!Main.tile[j, k].HasUnactuatedTile || !Main.tileSolid[Main.tile[j, k].TileType] || Main.tileSolidTop[Main.tile[j, k].TileType]); k++) + { + if (Main.tile[j, k].LiquidAmount < 200) + { + flag2 = false; + break; + } + } + if (!flag2) + { + num9 = 0.5f; + value = new(0, 4, 16, 16); + } + else if (Main.tile[j, i - 1].LiquidAmount > 0) + { + value = new(0, 2, value.Width, value.Height); + } + } + if ((color.R > 20 || color.B > 20 || color.G > 20) && value.Y < 4) + { + int num13 = color.R; + if (color.G > num13) + { + num13 = color.G; + } + if (color.B > num13) + { + num13 = color.B; + } + num13 /= 30; + if (Main.rand.Next(20000) < num13) + { + newColor = new(255, 255, 255); + int num14 = Dust.NewDust(new Vector2((float)(j * 16), vector2.Y - 2f), 16, 8, DustID.TintableDustLighted, 0f, 0f, 254, newColor, 0.75f); + Dust obj = Main.dust[num14]; + obj.velocity *= 0f; + } + } + if (Main.tile[j, i].LiquidType == LiquidID.Lava) + { + num9 *= 1.8f; + if (num9 > 1f) + { + num9 = 1f; + } + if (Main.instance.IsActive && !Main.gamePaused && Dust.lavaBubbles < 200) + { + if (Main.tile[j, i].LiquidAmount > 200 && Main.rand.NextBool(700)) + { + Dust.NewDust(new Vector2((float)(j * 16), (float)(i * 16)), 16, 16, dustLava()); + } + if (value.Y == 0 && Main.rand.NextBool(350)) + { + int num15 = Dust.NewDust(new Vector2((float)(j * 16), (float)(i * 16) + num3 * 2f - 8f), 16, 8, dustLava(), 0f, 0f, 50, default(Color), 1.5f); + Dust obj2 = Main.dust[num15]; + obj2.velocity *= 0.8f; + Main.dust[num15].velocity.X *= 2f; + Main.dust[num15].velocity.Y -= (float)Main.rand.Next(1, 7) * 0.1f; + if (Main.rand.NextBool(10)) + { + Main.dust[num15].velocity.Y *= Main.rand.Next(2, 5); + } + Main.dust[num15].noGravity = true; + } + } + } + float num16 = (float)(int)color.R * num9; + float num17 = (float)(int)color.G * num9; + float num18 = (float)(int)color.B * num9; + float num19 = (float)(int)color.A * num9; + color = new((int)(byte)num16, (int)(byte)num17, (int)(byte)num18, (int)(byte)num19); + if (Lighting.NotRetro && !bg) + { + Color color2 = color; + if (((double)(int)color2.R > (double)num29 * 0.6 || (double)(int)color2.G > (double)num29 * 0.65 || (double)(int)color2.B > (double)num29 * 0.7)) + { + for (int l = 0; l < 4; l++) + { + int num20 = 0; + int num21 = 0; + int width = 8; + int height = 8; + Color color3 = color2; + Color color4 = Lighting.GetColor(j, i); + if (l == 0) + { + color4 = Lighting.GetColor(j - 1, i - 1); + if (value.Height < 8) + { + height = value.Height; + } + } + if (l == 1) + { + color4 = Lighting.GetColor(j + 1, i - 1); + num20 = 8; + if (value.Height < 8) + { + height = value.Height; + } + } + if (l == 2) + { + color4 = Lighting.GetColor(j - 1, i + 1); + num21 = 8; + height = 8 - (16 - value.Height); + } + if (l == 3) + { + color4 = Lighting.GetColor(j + 1, i + 1); + num20 = 8; + num21 = 8; + height = 8 - (16 - value.Height); + } + num16 = (float)(int)color4.R * num9; + num17 = (float)(int)color4.G * num9; + num18 = (float)(int)color4.B * num9; + num19 = (float)(int)color4.A * num9; + color4 = new((int)(byte)num16, (int)(byte)num17, (int)(byte)num18, (int)(byte)num19); + color3.R = (byte)((color2.R * 3 + color4.R * 2) / 5); + color3.G = (byte)((color2.G * 3 + color4.G * 2) / 5); + color3.B = (byte)((color2.B * 3 + color4.B * 2) / 5); + color3.A = (byte)((color2.A * 3 + color4.A * 2) / 5); + Main.spriteBatch.Draw(CalamityMod.LavaTextures.block[num4].Value, vector2 - Main.screenPosition + new Vector2((float)num20, (float)num21) + vector, (Rectangle?)new Rectangle(value.X + num20, value.Y + num21, width, height), color3, 0f, default(Vector2), 1f, (SpriteEffects)0, 0f); + } + } + else + { + Main.spriteBatch.Draw(CalamityMod.LavaTextures.block[num4].Value, vector2 - Main.screenPosition + vector, (Rectangle?)value, color, 0f, default(Vector2), 1f, (SpriteEffects)0, 0f); + } + } + else + { + if (value.Y < 4) + { + value.X += (int)(Main.wFrame * 18f); + } + Main.spriteBatch.Draw(CalamityMod.LavaTextures.block[num4].Value, vector2 - Main.screenPosition + vector, (Rectangle?)value, color, 0f, default(Vector2), 1f, (SpriteEffects)0, 0f); + } + if (!Main.tile[j, i + 1].IsHalfBlock) + { + continue; + } + color = Lighting.GetColor(j, i + 1); + num16 = (float)(int)color.R * num9; + num17 = (float)(int)color.G * num9; + num18 = (float)(int)color.B * num9; + num19 = (float)(int)color.A * num9; + color = new((int)(byte)num16, (int)(byte)num17, (int)(byte)num18, (int)(byte)num19); + vector2 = new((float)(j * 16), (float)(i * 16 + 16)); + Main.spriteBatch.Draw(CalamityMod.LavaTextures.block[num4].Value, vector2 - Main.screenPosition + vector, (Rectangle?)new Rectangle(0, 4, 16, 8), color, 0f, default(Vector2), 1f, (SpriteEffects)0, 0f); + float num22 = 6f; + float num24 = 0.75f; + num22 = 4f; + num24 = 0.5f; + for (int m = 0; (float)m < num22; m++) + { + int num25 = i + 2 + m; + if (WorldGen.SolidTile(j, num25)) + { + break; + } + float num26 = 1f - (float)m / num22; + num26 *= num24; + vector2 = new((float)(j * 16), (float)(num25 * 16 - 2)); + Main.spriteBatch.Draw(CalamityMod.LavaTextures.block[num4].Value, vector2 - Main.screenPosition + vector, (Rectangle?)new Rectangle(0, 18, 16, 16), color * num26, 0f, default(Vector2), 1f, (SpriteEffects)0, 0f); + } + } + } + if (!Main.drewLava) + { + Main.ambientLavaX = num27; + Main.ambientLavaY = num28; + Main.ambientLavaStrength = num; + } + Main.drewLava = true; + } + + private void DrawLiquidBehindTiles(int lavaStyleOverride = -1) + { + Vector2 unscaledPosition = Main.Camera.UnscaledPosition; + Vector2 vector = new((float)Main.offScreenRange, (float)Main.offScreenRange); + if (Main.drawToScreen) + { + vector = Vector2.Zero; + } + GetScreenDrawArea(unscaledPosition, vector + (Main.Camera.UnscaledPosition - Main.Camera.ScaledPosition), out var firstTileX, out var lastTileX, out var firstTileY, out var lastTileY); + for (int i = firstTileY; i < lastTileY + 4; i++) + { + for (int j = firstTileX - 2; j < lastTileX + 2; j++) + { + Tile tile = Main.tile[j, i]; + if (tile != null) + { + DrawTile_LiquidBehindTile(solidLayer: false, inFrontOfPlayers: false, lavaStyleOverride, unscaledPosition, vector, j, i, tile); + } + } + } + } + + private void GetScreenDrawArea(Vector2 screenPosition, Vector2 offSet, out int firstTileX, out int lastTileX, out int firstTileY, out int lastTileY) + { + firstTileX = (int)((screenPosition.X - offSet.X) / 16f - 1f); + lastTileX = (int)((screenPosition.X + (float)Main.screenWidth + offSet.X) / 16f) + 2; + firstTileY = (int)((screenPosition.Y - offSet.Y) / 16f - 1f); + lastTileY = (int)((screenPosition.Y + (float)Main.screenHeight + offSet.Y) / 16f) + 5; + if (firstTileX < 4) + { + firstTileX = 4; + } + if (lastTileX > Main.maxTilesX - 4) + { + lastTileX = Main.maxTilesX - 4; + } + if (firstTileY < 4) + { + firstTileY = 4; + } + if (lastTileY > Main.maxTilesY - 4) + { + lastTileY = Main.maxTilesY - 4; + } + if (Main.sectionManager.AnyUnfinishedSections) + { + TimeLogger.DetailedDrawReset(); + WorldGen.SectionTileFrameWithCheck(firstTileX, firstTileY, lastTileX, lastTileY); + TimeLogger.DetailedDrawTime(5); + } + if (Main.sectionManager.AnyNeedRefresh) + { + WorldGen.RefreshSections(firstTileX, firstTileY, lastTileX, lastTileY); + } + } + + public void DrawTile_LiquidBehindTile(bool solidLayer, bool inFrontOfPlayers, int waterStyleOverride, Vector2 screenPosition, Vector2 screenOffset, int tileX, int tileY, Tile tileCache) + { + Tile tile = Main.tile[tileX + 1, tileY]; + Tile tile2 = Main.tile[tileX - 1, tileY]; + Tile tile3 = Main.tile[tileX, tileY - 1]; + Tile tile4 = Main.tile[tileX, tileY + 1]; + if ((tileCache.LiquidType != LiquidID.Lava && tile.LiquidType != LiquidID.Lava && tile2.LiquidType != LiquidID.Lava && tile3.LiquidType != LiquidID.Lava && tile4.LiquidType != LiquidID.Lava)) + { + return; + } + //bool[] _tileSolidTop = (bool[])typeof(TileDrawing).GetField("_tileSolidTop", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance).GetValue(null); + if (!tileCache.HasTile || tileCache.IsActuated /*|| _tileSolidTop[tileCache.TileType]*/ || (tileCache.IsHalfBlock && (tile2.LiquidAmount > 160 || tile.LiquidAmount > 160) && Main.instance.waterfallManager.CheckForWaterfall(tileX, tileY)) || (TileID.Sets.BlocksWaterDrawingBehindSelf[tileCache.TileType] && tileCache.Slope == 0)) + { + return; + } + int num = 0; + bool flag = false; + bool flag2 = false; + bool flag3 = false; + bool flag4 = false; + bool flag5 = false; + int num2 = 0; + bool flag6 = true; + int num3 = (int)tileCache.Slope; + int num4 = (int)tileCache.BlockType; + if (tileCache.TileType == 546 && tileCache.LiquidAmount > 0) + { + flag5 = true; + flag4 = true; + flag = true; + flag2 = true; + num = tileCache.LiquidAmount; + } + else + { + if (tileCache.LiquidAmount > 0 && num4 != 0 && (num4 != 1 || tileCache.LiquidAmount > 160)) + { + flag5 = true; + if (tileCache.LiquidAmount > num) + { + num = tileCache.LiquidAmount; + } + } + if (tile2.LiquidAmount > 0 && num3 != 1 && num3 != 3) + { + flag = true; + if (tile2.LiquidAmount > num) + { + num = tile2.LiquidAmount; + } + } + if (tile.LiquidAmount > 0 && num3 != 2 && num3 != 4) + { + flag2 = true; + if (tile.LiquidAmount > num) + { + num = tile.LiquidAmount; + } + } + if (tile3.LiquidAmount > 0 && num3 != 3 && num3 != 4) + { + flag3 = true; + } + if (tile4.LiquidAmount > 0 && num3 != 1 && num3 != 2) + { + if (tile4.LiquidAmount > 240) + { + flag4 = true; + } + } + } + if (!flag3 && !flag4 && !flag && !flag2 && !flag5) + { + return; + } + if (waterStyleOverride != -1) + { + CalamityMod.LavaStyle = waterStyleOverride; + } + if (num2 == 0) + { + num2 = CalamityMod.LavaStyle; + } + Lighting.GetCornerColors(tileX, tileY, out var vertices); + Vector2 vector = new((float)(tileX * 16), (float)(tileY * 16)); + Rectangle liquidSize = new(0, 4, 16, 16); + if (flag4 && (flag || flag2)) + { + flag = true; + flag2 = true; + } + if (tileCache.HasTile && (Main.tileSolidTop[tileCache.TileType] || !Main.tileSolid[tileCache.TileType])) + { + return; + } + if ((!flag3 || !(flag || flag2)) && !(flag4 && flag3)) + { + if (flag3) + { + liquidSize = new(0, 4, 16, 4); + if (tileCache.IsHalfBlock || tileCache.Slope != 0) + { + liquidSize = new(0, 4, 16, 12); + } + } + else if (flag4 && !flag && !flag2) + { + vector = new((float)(tileX * 16), (float)(tileY * 16 + 12)); + liquidSize = new(0, 4, 16, 4); + } + else + { + float num8 = (float)(256 - num) / 32f; + int y = 4; + if (tile3.LiquidAmount == 0 && (num4 != 0 || !WorldGen.SolidTile(tileX, tileY - 1))) + { + y = 0; + } + int num5 = (int)num8 * 2; + if (tileCache.Slope != 0) + { + vector = new((float)(tileX * 16), (float)(tileY * 16 + num5)); + liquidSize = new(0, num5, 16, 16 - num5); + } + else if ((flag && flag2) || tileCache.IsHalfBlock) + { + vector = new((float)(tileX * 16), (float)(tileY * 16 + num5)); + liquidSize = new(0, y, 16, 16 - num5); + } + else if (flag) + { + vector = new((float)(tileX * 16), (float)(tileY * 16 + num5)); + liquidSize = new(0, y, 4, 16 - num5); + } + else + { + vector = new((float)(tileX * 16 + 12), (float)(tileY * 16 + num5)); + liquidSize = new(0, y, 4, 16 - num5); + } + } + } + Vector2 position = vector - screenPosition + screenOffset; + float num6 = 1f; + if ((double)tileY <= Main.worldSurface || num6 > 1f) + { + num6 = 1f; + if (tileCache.WallType == 21) + { + num6 = 0.9f; + } + else if (tileCache.WallType > 0) + { + num6 = 0.6f; + } + } + if (tileCache.IsHalfBlock && tile3.LiquidAmount > 0 && tileCache.WallType > 0) + { + num6 = 0f; + } + if (num3 == 4 && tile2.LiquidAmount == 0 && !WorldGen.SolidTile(tileX - 1, tileY)) + { + num6 = 0f; + } + if (num3 == 3 && tile.LiquidAmount == 0 && !WorldGen.SolidTile(tileX + 1, tileY)) + { + num6 = 0f; + } + ref Color bottomLeftColor = ref vertices.BottomLeftColor; + bottomLeftColor *= num6; + ref Color bottomRightColor = ref vertices.BottomRightColor; + bottomRightColor *= num6; + ref Color topLeftColor = ref vertices.TopLeftColor; + topLeftColor *= num6; + ref Color topRightColor = ref vertices.TopRightColor; + topRightColor *= num6; + bool flag7 = false; + if (flag6) + { + for (int i = 0; i < LavaStylesLoader.TotalCount; i++) + { + if (CalamityMod.lavaAlpha[i] > 0f && i != num2) + { + DrawPartialLiquid(!solidLayer, tileCache, ref position, ref liquidSize, i, ref vertices); + flag7 = true; + break; + } + } + } + VertexColors colors = vertices; + float num7 = (flag7 ? CalamityMod.lavaAlpha[num2] : 1f); + ref Color bottomLeftColor2 = ref colors.BottomLeftColor; + bottomLeftColor2 *= num7; + ref Color bottomRightColor2 = ref colors.BottomRightColor; + bottomRightColor2 *= num7; + ref Color topLeftColor2 = ref colors.TopLeftColor; + topLeftColor2 *= num7; + ref Color topRightColor2 = ref colors.TopRightColor; + topRightColor2 *= num7; + DrawPartialLiquid(!solidLayer, tileCache, ref position, ref liquidSize, num2, ref colors); + } + + private void DrawPartialLiquid(bool behindBlocks, Tile tileCache, ref Vector2 position, ref Rectangle liquidSize, int liquidType, ref VertexColors colors) + { + int num = (int)tileCache.Slope; + bool flag = !TileID.Sets.BlocksWaterDrawingBehindSelf[tileCache.TileType]; + if (!behindBlocks) + { + flag = false; + } + if (flag || num == 0) + { + Main.tileBatch.Draw(CalamityMod.LavaTextures.block[liquidType].Value, position, liquidSize, colors, default(Vector2), 1f, (SpriteEffects)0); + return; + } + liquidSize.X += 18 * (num - 1); + switch (num) + { + case 1: + Main.tileBatch.Draw(CalamityMod.LavaTextures.slope[liquidType].Value, position, liquidSize, colors, Vector2.Zero, 1f, (SpriteEffects)0); + break; + case 2: + Main.tileBatch.Draw(CalamityMod.LavaTextures.slope[liquidType].Value, position, liquidSize, colors, Vector2.Zero, 1f, (SpriteEffects)0); + break; + case 3: + Main.tileBatch.Draw(CalamityMod.LavaTextures.slope[liquidType].Value, position, liquidSize, colors, Vector2.Zero, 1f, (SpriteEffects)0); + break; + case 4: + Main.tileBatch.Draw(CalamityMod.LavaTextures.slope[liquidType].Value, position, liquidSize, colors, Vector2.Zero, 1f, (SpriteEffects)0); + break; + } + } + + public void InitialDrawLavafall(WaterfallManager waterfallManager) + { + for (int i = 0; i < LavaStylesLoader.TotalCount; i++) + { + if (CalamityMod.lavaAlpha[i] > 0f) + { + DrawLavafall(waterfallManager, i, CalamityMod.lavaAlpha[i]); + } + } + } + + internal void DrawLavafall(WaterfallManager waterfallManager, int Style = 0, float Alpha = 1f) + { + int waterfallDist = (int)typeof(WaterfallManager).GetField("waterfallDist", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance).GetValue(waterfallManager); + int rainFrameForeground = (int)typeof(WaterfallManager).GetField("rainFrameForeground", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance).GetValue(waterfallManager); + int rainFrameBackground = (int)typeof(WaterfallManager).GetField("rainFrameBackground", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance).GetValue(waterfallManager); + int snowFrameForeground = (int)typeof(WaterfallManager).GetField("snowFrameForeground", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance).GetValue(waterfallManager); + WaterfallData[] waterfalls = (WaterfallData[])typeof(WaterfallManager).GetField("waterfalls", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance).GetValue(waterfallManager); + int currentMax = (int)typeof(WaterfallManager).GetField("currentMax", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance).GetValue(waterfallManager); + int slowFrame = (int)typeof(WaterfallManager).GetField("slowFrame", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance).GetValue(waterfallManager); + Main.tileSolid[546] = false; + float num = 0f; + float num12 = 99999f; + float num23 = 99999f; + int num34 = -1; + int num45 = -1; + float num47 = 0f; + float num48 = 99999f; + float num49 = 99999f; + int num50 = -1; + int num2 = -1; + Rectangle value = default(Rectangle); + Rectangle value2 = default(Rectangle); + Vector2 origin = default(Vector2); + for (int i = 0; i < currentMax; i++) + { + if (waterfalls[i].type != 1) + { + continue; + } + int num3 = 0; + int num4 = Style; + int num5 = waterfalls[i].x; + int num6 = waterfalls[i].y; + int num7 = 0; + int num8 = 0; + int num9 = 0; + int num10 = 0; + int num11 = 0; + int num13 = 0; + int num14; + int num15; + if (waterfalls[i].stopAtStep == 0) + { + continue; + } + num14 = 32 * slowFrame; + int num22 = 0; + num15 = waterfallDist; + Color color4 = Color.White; + for (int k = 0; k < num15; k++) + { + if (num22 >= 2) + { + break; + } + typeof(WaterfallManager).GetMethod("AddLight", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static).Invoke(null, new object[] { 1, num5, num6 }); + Tile tile3 = Main.tile[num5, num6]; + if (tile3.HasUnactuatedTile && Main.tileSolid[tile3.TileType] && !Main.tileSolidTop[tile3.TileType] && !TileID.Sets.Platforms[tile3.TileType] && tile3.BlockType == 0) + { + break; + } + Tile tile4 = Main.tile[num5 - 1, num6]; + Tile tile5 = Main.tile[num5, num6 + 1]; + Tile tile6 = Main.tile[num5 + 1, num6]; + if (WorldGen.SolidTile(tile5) && !tile3.IsHalfBlock) + { + num3 = 8; + } + else if (num8 != 0) + { + num3 = 0; + } + int num24 = 0; + int num25 = num10; + int num26 = 0; + int num27 = 0; + bool flag2 = false; + if (tile5.TopSlope && !tile3.IsHalfBlock && tile5.TileType != 19) + { + flag2 = true; + if (tile5.Slope == (SlopeType)1) + { + num24 = 1; + num26 = 1; + num9 = 1; + num10 = num9; + } + else + { + num24 = -1; + num26 = -1; + num9 = -1; + num10 = num9; + } + num27 = 1; + } + else if ((!WorldGen.SolidTile(tile5) && !tile5.BottomSlope && !tile3.IsHalfBlock) || (!tile5.HasTile && !tile3.IsHalfBlock)) + { + num22 = 0; + num27 = 1; + num26 = 0; + } + else if ((WorldGen.SolidTile(tile4) || tile4.TopSlope || tile4.LiquidAmount > 0) && !WorldGen.SolidTile(tile6) && tile6.LiquidAmount == 0) + { + if (num9 == -1) + { + num22++; + } + num26 = 1; + num27 = 0; + num9 = 1; + } + else if ((WorldGen.SolidTile(tile6) || tile6.TopSlope || tile6.LiquidAmount > 0) && !WorldGen.SolidTile(tile4) && tile4.LiquidAmount == 0) + { + if (num9 == 1) + { + num22++; + } + num26 = -1; + num27 = 0; + num9 = -1; + } + else if (((!WorldGen.SolidTile(tile6) && !tile3.TopSlope) || tile6.LiquidAmount == 0) && !WorldGen.SolidTile(tile4) && !tile3.TopSlope && tile4.LiquidAmount == 0) + { + num27 = 0; + num26 = num9; + } + else + { + num22++; + num27 = 0; + num26 = 0; + } + if (num22 >= 2) + { + num9 *= -1; + num26 *= -1; + } + Color color5 = Lighting.GetColor(num5, num6); + if (k > 50) + { + typeof(WaterfallManager).GetMethod("TrySparkling", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static).Invoke(null, new object[] { num5, num6, num9, color5 }); + } + float alpha = GetLavafallAlpha(Alpha, num15, num6, k, tile3); + color5 = (Color)typeof(WaterfallManager).GetMethod("StylizeColor", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static).Invoke(null, new object[] { alpha, num15, 1, num6, k, tile3, color5 }); + float num33 = Math.Abs((float)(num5 * 16 + 8) - (Main.screenPosition.X + (float)(Main.screenWidth / 2))); + float num35 = Math.Abs((float)(num6 * 16 + 8) - (Main.screenPosition.Y + (float)(Main.screenHeight / 2))); + if (num33 < (float)(Main.screenWidth * 2) && num35 < (float)(Main.screenHeight * 2)) + { + float num36 = (float)Math.Sqrt(num33 * num33 + num35 * num35); + float num37 = 1f - num36 / ((float)Main.screenWidth * 0.75f); + if (num37 > 0f) + { + num += num37; + } + } + if (num33 < num12) + { + num12 = num33; + num34 = num5 * 16 + 8; + } + if (num35 < num23) + { + num23 = num33; + num45 = num6 * 16 + 8; + } + int num38 = tile3.LiquidAmount / 16; + if (flag2 && num9 != num25) + { + int num39 = 2; + if (num25 == 1) + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16 - 16), (float)(num6 * 16 + 16 - num39)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38 - num39), color5, (SpriteEffects)1); + } + else + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16 + 16 - num39)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38 - num39), color5, (SpriteEffects)0); + } + } + if (num7 == 0 && num24 != 0 && num8 == 1 && num9 != num10) + { + num24 = 0; + num9 = num10; + color5 = Color.White; + if (num9 == 1) + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16 - 16), (float)(num6 * 16 + 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38), color5, (SpriteEffects)1); + } + else + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16 - 16), (float)(num6 * 16 + 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38), color5, (SpriteEffects)1); + } + } + if (num11 != 0 && num26 == 0 && num27 == 1) + { + if (num9 == 1) + { + if (num13 != num4) + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16 + num3 + 8)) - Main.screenPosition, new Rectangle(num14, 0, 16, 16 - num38 - 8), color4, (SpriteEffects)1); + } + else + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16 + num3 + 8)) - Main.screenPosition, new Rectangle(num14, 0, 16, 16 - num38 - 8), color5, (SpriteEffects)1); + } + } + else + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16 + num3 + 8)) - Main.screenPosition, new Rectangle(num14, 0, 16, 16 - num38 - 8), color5, (SpriteEffects)0); + } + } + if (num3 == 8 && num8 == 1 && num11 == 0) + { + if (num10 == -1) + { + if (num13 != num4) + { + DrawLavafall(num13, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 8), color4, (SpriteEffects)0); + } + else + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 8), color5, (SpriteEffects)0); + } + } + else if (num13 != num4) + { + DrawLavafall(num13, num5, num6, alpha, new Vector2((float)(num5 * 16 - 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 8), color4, (SpriteEffects)1); + } + else + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16 - 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 8), color5, (SpriteEffects)1); + } + } + if (num24 != 0 && num7 == 0) + { + if (num25 == 1) + { + if (num13 != num4) + { + DrawLavafall(num13, num5, num6, alpha, new Vector2((float)(num5 * 16 - 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38), color4, (SpriteEffects)1); + } + else + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16 - 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38), color5, (SpriteEffects)1); + } + } + else if (num13 != num4) + { + DrawLavafall(num13, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38), color4, (SpriteEffects)0); + } + else + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38), color5, (SpriteEffects)0); + } + } + if (num27 == 1 && num24 == 0 && num11 == 0) + { + if (num9 == -1) + { + if (num8 == 0) + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16 + num3)) - Main.screenPosition, new Rectangle(num14, 0, 16, 16 - num38), color5, (SpriteEffects)0); + } + else if (num13 != num4) + { + DrawLavafall(num13, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38), color4, (SpriteEffects)0); + } + else + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38), color5, (SpriteEffects)0); + } + } + else if (num8 == 0) + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16 + num3)) - Main.screenPosition, new Rectangle(num14, 0, 16, 16 - num38), color5, (SpriteEffects)1); + } + else if (num13 != num4) + { + DrawLavafall(num13, num5, num6, alpha, new Vector2((float)(num5 * 16 - 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38), color4, (SpriteEffects)1); + } + else + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16 - 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38), color5, (SpriteEffects)1); + } + } + else + { + switch (num26) + { + case 1: + if (Main.tile[num5, num6].LiquidAmount > 0 && !Main.tile[num5, num6].IsHalfBlock) + { + break; + } + if (num24 == 1) + { + for (int m = 0; m < 8; m++) + { + int num43 = m * 2; + int num44 = 14 - m * 2; + int num46 = num43; + num3 = 8; + if (num7 == 0 && m < 2) + { + num46 = 4; + } + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16 + num43), (float)(num6 * 16 + num3 + num46)) - Main.screenPosition, new Rectangle(16 + num14 + num44, 0, 2, 16 - num3), color5, (SpriteEffects)1); + } + } + else + { + int height2 = 16; + if (TileID.Sets.BlocksWaterDrawingBehindSelf[Main.tile[num5, num6].TileType]) + { + height2 = 8; + } + else if (TileID.Sets.BlocksWaterDrawingBehindSelf[Main.tile[num5, num6 + 1].TileType]) + { + height2 = 8; + } + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16 + num3)) - Main.screenPosition, new Rectangle(16 + num14, 0, 16, height2), color5, (SpriteEffects)1); + } + break; + case -1: + if (Main.tile[num5, num6].LiquidAmount > 0 && !Main.tile[num5, num6].IsHalfBlock) + { + break; + } + if (num24 == -1) + { + for (int l = 0; l < 8; l++) + { + int num40 = l * 2; + int num41 = l * 2; + int num42 = 14 - l * 2; + num3 = 8; + if (num7 == 0 && l > 5) + { + num42 = 4; + } + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16 + num40), (float)(num6 * 16 + num3 + num42)) - Main.screenPosition, new Rectangle(16 + num14 + num41, 0, 2, 16 - num3), color5, (SpriteEffects)1); + } + } + else + { + int height = 16; + if (TileID.Sets.BlocksWaterDrawingBehindSelf[Main.tile[num5, num6].TileType]) + { + height = 8; + } + else if (TileID.Sets.BlocksWaterDrawingBehindSelf[Main.tile[num5, num6 + 1].TileType]) + { + height = 8; + } + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16 + num3)) - Main.screenPosition, new Rectangle(16 + num14, 0, 16, height), color5, (SpriteEffects)0); + } + break; + case 0: + if (num27 == 0) + { + if (Main.tile[num5, num6].LiquidAmount <= 0 || Main.tile[num5, num6].IsHalfBlock) + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16 + num3)) - Main.screenPosition, new Rectangle(16 + num14, 0, 16, 16), color5, (SpriteEffects)0); + } + k = 1000; + } + break; + } + } + if (tile3.LiquidAmount > 0 && !tile3.IsHalfBlock) + { + k = 1000; + } + num8 = num27; + num10 = num9; + num7 = num26; + num5 += num26; + num6 += num27; + num11 = num24; + color4 = color5; + if (num13 != num4) + { + num13 = num4; + } + if ((tile4.HasTile && (tile4.TileType == 189 || tile4.TileType == 196)) || (tile6.HasTile && (tile6.TileType == 189 || tile6.TileType == 196)) || (tile5.HasTile && (tile5.TileType == 189 || tile5.TileType == 196))) + { + num15 = (int)(40f * ((float)Main.maxTilesX / 4200f) * Main.gfxQuality); + } + } + } + Main.ambientWaterfallX = num34; + Main.ambientWaterfallY = num45; + Main.ambientWaterfallStrength = num; + Main.ambientLavafallX = num50; + Main.ambientLavafallY = num2; + Main.ambientLavafallStrength = num47; + Main.tileSolid[546] = true; + } + + private void DrawLavafall(int waterfallType, int x, int y, float opacity, Vector2 position, Rectangle sourceRect, Color color, SpriteEffects effects) + { + Texture2D value = CalamityMod.LavaTextures.fall[waterfallType].Value; + Main.spriteBatch.Draw(value, position, (Rectangle?)sourceRect, color, 0f, default(Vector2), 1f, effects, 0f); + } + + private static float GetLavafallAlpha(float Alpha, int maxSteps, int y, int s, Tile tileCache) + { + float num = (tileCache.WallType != 0 || !((double)y < Main.worldSurface)) ? (1f * Alpha) : Alpha; + if (s > maxSteps - 10) + { + num *= (float)(maxSteps - s) / 10f; + } + return num; + } + + public static int dustLava() + { + if (CalamityMod.LavaStyle >= 1) + { + return LavaStylesLoader.Get(CalamityMod.LavaStyle).GetSplashDust(); + } + else + { + return DustID.Lava; + } + } + + //just better as a method rather than hardcoded type values + public static int goreLava() + { + if (CalamityMod.LavaStyle >= 1) + { + return LavaStylesLoader.Get(CalamityMod.LavaStyle).GetDropletGore(); + } + else + { + return GoreID.LavaDrip; + } + } + } +} diff --git a/Systems/ModLavaStyle.cs b/Systems/ModLavaStyle.cs new file mode 100644 index 0000000000..84d229559a --- /dev/null +++ b/Systems/ModLavaStyle.cs @@ -0,0 +1,262 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.Xna.Framework.Graphics; +using ReLogic.Content; +using Terraria; +using Terraria.GameContent.Liquid; +using Terraria.GameContent; +using Terraria.Graphics; +using Terraria.ModLoader; +using System.Linq; +using Terraria.ID; +using Microsoft.Xna.Framework; +using CalamityMod.Items.Potions.Alcohol; + +namespace CalamityMod.Systems +{ + public abstract class ModLavaStyle : ModTexturedType + { + /// + /// The ID of the lava style. + /// + public int Slot { get; private set; } = -1; + + public override string Name => base.Name; + + public override string Texture => base.Texture; + + public virtual string BlockTexture => Texture + "_Block"; + + public virtual string SlopeTexture => Texture + "_Slope"; + + public virtual string WaterfallTexture => Texture + "_Waterfall"; + + protected sealed override void Register() + { + Slot = LavaStylesLoader.Register(this); + } + + public sealed override void SetupContent() + { + SetStaticDefaults(); + } + + /// + /// Allows you to determine how much light this lava emits.
+ /// It can also let you light up the block in front of this lava.
+ /// Keep in mind this also effects what color the lavafalls emit
+ /// See for vanilla tile light values to use as a reference.
+ ///
+ /// The x position in tile coordinates. + /// The y position in tile coordinates. + /// The red component of light, usually a value between 0 and 1 + /// The green component of light, usually a value between 0 and 1 + /// The blue component of light, usually a value between 0 and 1 + public virtual void ModifyLight(int i, int j, ref float r, ref float g, ref float b) + { + r = 0.55f; + g = 0.33f; + b = 0.11f; + } + + /// + /// Allows water styles to manipulate what color the liquid is drawn to, this can allow waters to be see-throughable to see backgrounds (surface and underground backgrounds not walls) + /// + /// X position of the water + /// Y position of the water + /// The vertexColor of the water color, this is both used to get the current color and to set the color of the water + public virtual void DrawColor(int x, int y, ref VertexColors liquidColor, bool isSlope) + { + } + + /// + /// The ID of the dust that is created when anything splashes in lava. + /// + public virtual int GetSplashDust() + { + return DustID.Lava; + } + + /// + /// The ID of the gore that represents droplets of lava falling down from a block. Return (or another existing droplet gore). + /// + public virtual int GetDropletGore() + { + return GoreID.LavaDrip; + } + + /// + /// Return true if the player is in the correct zone to activate the lava. + /// + /// + public virtual bool IsLavaActive() + { + return false; + } + + /// + /// Return false if the waterfall made by the lavastyle should have a glowmask + /// + /// + public virtual bool LavafallGlowmask() + { + return true; + } + + /// + /// Allows your lavastyle to inflict debuffs to Players and NPCs when they enter your lava style + /// + /// The Player that is inflicted with the debuff apon entering the lavastyle + /// The duration of the OnFire! debuff. This allows for easy replacement of OnFire + public virtual void InflictDebuff(Player player, int onfireDuration) + { + } + } + + public class LavaStylesLoader : ModSystem + { + private static readonly MethodInfo ResizeArrayMethodInfo; + + static LavaStylesLoader() + { + ResizeArrayMethodInfo = typeof(ModContent).GetMethod("ResizeArrays", BindingFlags.NonPublic | BindingFlags.Static); + } + + private static void ResizeArrays(ResizeArray_orig orig, bool unloading) + { + orig.Invoke(unloading); + int totalCount = TotalCount; + Array.Resize(ref CalamityMod.LavaTextures.liquid, totalCount); + Array.Resize(ref CalamityMod.LavaTextures.block, totalCount); + Array.Resize(ref CalamityMod.LavaTextures.slope, totalCount); + Array.Resize(ref CalamityMod.LavaTextures.fall, totalCount); + Array.Resize(ref CalamityMod.lavaAlpha, totalCount); + } + + private static readonly List _content = []; + + public static IReadOnlyList Content => _content; + + public static int VanillaCount => 1; + + public static int ModCount => _content.Count; + + public static int TotalCount => VanillaCount + ModCount; + + public override void Load() + { + if (ResizeArrayMethodInfo != null) + { + MonoModHooks.Add(ResizeArrayMethodInfo, ResizeArrays); + } + } + + public override void PostSetupContent() + { + foreach (ModLavaStyle item in Content) + { + int Slot = item.Slot; + CalamityMod.LavaTextures.liquid[Slot] = ModContent.Request(item.Texture, (AssetRequestMode)2); + CalamityMod.LavaTextures.block[Slot] = ModContent.Request(item.BlockTexture, (AssetRequestMode)2); + CalamityMod.LavaTextures.slope[Slot] = ModContent.Request(item.SlopeTexture, (AssetRequestMode)2); + CalamityMod.LavaTextures.fall[Slot] = ModContent.Request(item.WaterfallTexture, (AssetRequestMode)2); + } + } + + public static ModLavaStyle Get(int type) + { + type -= VanillaCount; + return type >= 0 && type < _content.Count ? _content[type] : null; + } + + internal static int Register(ModLavaStyle instance) + { + int type = TotalCount; + ModTypeLookup.Register(instance); + _content.Add(instance); + return type; + } + + private delegate void ResizeArray_orig(bool unloading); + + public static void UpdateLiquidAlphas() + { + if (CalamityMod.LavaStyle >= VanillaCount) + { + for (int i = 0; i < VanillaCount; i++) + { + CalamityMod.lavaAlpha[i] -= 0.2f; + if (CalamityMod.lavaAlpha[i] < 0f) + { + CalamityMod.lavaAlpha[i] = 0f; + } + } + } + foreach (ModLavaStyle item in Content) + { + int type = item.Slot; + if (CalamityMod.LavaStyle == type) + { + CalamityMod.lavaAlpha[type] += 0.2f; + if (CalamityMod.lavaAlpha[type] > 1f) + { + CalamityMod.lavaAlpha[type] = 1f; + } + } + else + { + CalamityMod.lavaAlpha[type] -= 0.2f; + if (CalamityMod.lavaAlpha[type] < 0f) + { + CalamityMod.lavaAlpha[type] = 0f; + } + } + } + } + + public static void ModifyLightSetup(int i, int j, int style, ref float r, ref float g, ref float b) + { + ModLavaStyle lavaStyle = Get(style); + if (lavaStyle != null) + { + lavaStyle?.ModifyLight(i, j, ref r, ref g, ref b); + } + } + + internal static void DrawColorSetup(int x, int y, int type, ref VertexColors liquidColor, bool isSlope = false) + { + ModLavaStyle styles = Get(type); + if (styles != null) + { + styles?.DrawColor(x, y, ref liquidColor, isSlope); + } + } + + public static void InflictDebuff(Player player, int type, int onfireDuration) + { + ModLavaStyle lavaStyle = Get(type); + if (lavaStyle != null) + { + lavaStyle?.InflictDebuff(player, onfireDuration); + } + } + + public static void IsLavaActive() + { + foreach (ModLavaStyle item in Content) + { + int type = item.Slot; + ModLavaStyle lavaStyle = Get(type); + if (lavaStyle != null) + { + bool? flag = lavaStyle?.IsLavaActive(); + if (flag != null && flag == true) + { + CalamityMod.LavaStyle = lavaStyle.Slot; + } + } + } + } + } +} diff --git a/Utilities/MiscUtils.cs b/Utilities/MiscUtils.cs index 1695877872..2fd2cd83bf 100644 --- a/Utilities/MiscUtils.cs +++ b/Utilities/MiscUtils.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using CalamityMod.Items.Tools.ClimateChange; +using CalamityMod.Systems; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Graphics; diff --git a/Utilities/TileUtils.cs b/Utilities/TileUtils.cs index 3c387d7961..1b80fcf705 100644 --- a/Utilities/TileUtils.cs +++ b/Utilities/TileUtils.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using CalamityMod.Tiles; using CalamityMod.Tiles.Abyss; using CalamityMod.Tiles.Astral; @@ -520,6 +521,41 @@ public static void MergeDecorativeTiles(int type) SetMerge(type, TileType()); } + /// + /// The X position of the Tile + /// + /// + /// + public static int X(this Tile tile) + { + TilePos(tile, out int x, out _); + return x; + } + + /// + /// The Y position of the Tile + /// + /// + /// + public static int Y(this Tile tile) + { + TilePos(tile, out _, out int y); + return y; + } + + /// + /// Gets the Position of the tile, the same values that would be inputted in Main.tile to get this Tile + /// + /// + /// The outputted X value, if you want the X by itself use Tile.X + /// The outputted Y value, if you want the Y by itself use Tile.Y + public static void TilePos(this Tile tile, out int x, out int y) + { + uint tileId = Unsafe.BitCast(tile); + x = Math.DivRem((int)tileId, Main.tile.Height, out y); //Thanks to FoxXD_ for the help with this + } + + /// /// Determines if a tile is solid ground based on whether it's active and not actuated or if the tile is solid in any way, including just the top. /// diff --git a/Waters/AstralWater.cs b/Waters/AstralWater.cs index 7064c4fadf..7928f6d6dd 100644 --- a/Waters/AstralWater.cs +++ b/Waters/AstralWater.cs @@ -1,4 +1,7 @@ -using Microsoft.Xna.Framework; +using CalamityMod.Dusts.WaterSplash; +using CalamityMod.Gores.WaterDroplet; +using CalamityMod.Systems; +using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using ReLogic.Content; using Terraria; @@ -6,13 +9,15 @@ namespace CalamityMod.Waters { - public class AstralWater : ModWaterStyle + public class AstralWaterflow : ModWaterfallStyle { } + + public class AstralWater : CalamityModWaterStyle { public override int ChooseWaterfallStyle() => ModContent.Find("CalamityMod/AstralWaterflow").Slot; - public override int GetSplashDust() => 52; //corruption water? - public override int GetDropletGore() => ModContent.Find("CalamityMod/AstralWaterDroplet").Type; + public override int GetSplashDust() => ModContent.DustType(); + public override int GetDropletGore() => ModContent.GoreType(); public override Asset GetRainTexture() => ModContent.Request("CalamityMod/Waters/AstralRain"); public override byte GetRainVariant() => (byte)Main.rand.Next(3); - public override Color BiomeHairColor() => Color.MediumPurple; + public override Color BiomeHairColor() => new Color(93, 78, 107); } } diff --git a/Waters/AstralWaterflow.cs b/Waters/AstralWaterflow.cs deleted file mode 100644 index 76e3fc81d6..0000000000 --- a/Waters/AstralWaterflow.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Terraria.ModLoader; -namespace CalamityMod.Waters -{ - public class AstralWaterflow : ModWaterfallStyle - { - - } -} diff --git a/Waters/CragsLava.cs b/Waters/CragsLava.cs new file mode 100644 index 0000000000..3654038bbd --- /dev/null +++ b/Waters/CragsLava.cs @@ -0,0 +1,38 @@ +using CalamityMod.Buffs.DamageOverTime; +using CalamityMod.CalPlayer; +using CalamityMod.Items.Accessories; +using CalamityMod.Systems; +using Microsoft.Xna.Framework; +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; +using CalamityMod.Dusts.WaterSplash; +using CalamityMod.Gores.WaterDroplet; + +namespace CalamityMod.Waters +{ + public class CragsLava : ModLavaStyle + { + public override string WaterfallTexture => "CalamityMod/Waters/CragsLavaflow"; + + public override int GetSplashDust() => ModContent.DustType(); + + public override int GetDropletGore() => ModContent.GoreType(); + + public override bool IsLavaActive() => Main.LocalPlayer.Calamity().ZoneCalamity || Main.LocalPlayer.Calamity().BrimstoneLavaFountainCounter > 0; + + public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) + { + r = 2.48f / 4; + g = 1.05f / 4; + b = 0.98f / 4; + } + + public override void InflictDebuff(Player player, int onfireDuration) + { + // Extra DoT in the lava of the crags. Negated by Flame-licked Shell. + if (!player.Calamity().flameLickedShell) + player.AddBuff(ModContent.BuffType(), 2, false); + } + } +} diff --git a/Waters/CragsLavaStyle.cs b/Waters/CragsLavaStyle.cs deleted file mode 100644 index 6ffe68bed0..0000000000 --- a/Waters/CragsLavaStyle.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.ModLoader; - -namespace CalamityMod.Waters -{ - public class CragsLavaflow : ModWaterfallStyle { } - - public class CragsLavaStyle : CustomLavaStyle - { - public override string LavaTexturePath => "CalamityMod/Waters/CragsLava"; - - public override string BlockTexturePath => LavaTexturePath + "_Block"; - - public override string SlopeTexturePath => LavaTexturePath + "_Slope"; - - public override bool ChooseLavaStyle() => Main.LocalPlayer.Calamity().ZoneCalamity || Main.LocalPlayer.Calamity().BrimstoneLavaFountainCounter > 0; - - public override int ChooseWaterfallStyle() => ModContent.Find("CalamityMod/CragsLavaflow").Slot; - - public override int GetSplashDust() => 0; - - public override int GetDropletGore() => 0; - - public override void SelectLightColor(ref Color initialLightColor) - { - initialLightColor = Color.Lerp(initialLightColor, Color.White, 0.5f); - initialLightColor.A = 255; - } - } -} diff --git a/Waters/CustomLavaManagement.cs b/Waters/CustomLavaManagement.cs deleted file mode 100644 index e4018ddb5d..0000000000 --- a/Waters/CustomLavaManagement.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using ReLogic.Content; -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; -using Terraria.ModLoader.Core; - -namespace CalamityMod.Waters -{ - // TODO -- This can be made into a ModSystem with simple OnModLoad and Unload hooks. - public static class CustomLavaManagement - { - internal static List CustomLavaStyles; - internal static Texture2D LavaBlockTexture; - internal static Texture2D LavaTexture; - internal static Texture2D LavaSlopeTexture; - - // The IL Edits are loaded separately. - internal static void Load() - { - CustomLavaStyles = new List(); - - Type[] types = AssemblyManager.GetLoadableTypes(CalamityMod.Instance.Code); - foreach (Type type in types) - { - // Ignore abstract types; they cannot have instances. - // Also ignore types which do not derive from CustomLavaStyle. - if (!type.IsSubclassOf(typeof(CustomLavaStyle)) || type.IsAbstract) - continue; - - CustomLavaStyles.Add(Activator.CreateInstance(type) as CustomLavaStyle); - CustomLavaStyles.Last().Load(); - } - - if (Main.netMode != NetmodeID.Server) - { - LavaBlockTexture = ModContent.Request("Terraria/Images/Liquid_1", AssetRequestMode.ImmediateLoad).Value; - LavaTexture = ModContent.Request("Terraria/Images/Misc/water_1", AssetRequestMode.ImmediateLoad).Value; - LavaSlopeTexture = ModContent.Request("Terraria/Images/LiquidSlope_1", AssetRequestMode.ImmediateLoad).Value; - } - } - - internal static void Unload() - { - if (CustomLavaStyles != null) - foreach (CustomLavaStyle lavaStyle in CustomLavaStyles) - lavaStyle?.Unload(); - - CustomLavaStyles = null; - LavaBlockTexture = null; - LavaTexture = null; - } - - internal static int SelectLavafallStyle(int initialLavafallStyle) - { - // Lava waterfall. - if (initialLavafallStyle != 1) - return initialLavafallStyle; - - foreach (CustomLavaStyle lavaStyle in CustomLavaStyles) - { - int waterfallStyle = lavaStyle.ChooseWaterfallStyle(); - if (lavaStyle.ChooseLavaStyle() && waterfallStyle >= 0) - return waterfallStyle; - } - - return initialLavafallStyle; - } - - internal static Color SelectLavafallColor(int initialLavafallStyle, Color initialLavafallColor) - { - // Lava waterfall. - if (initialLavafallStyle != 1) - return initialLavafallColor; - - foreach (CustomLavaStyle lavaStyle in CustomLavaStyles) - { - if (lavaStyle.ChooseLavaStyle()) - { - lavaStyle.SelectLightColor(ref initialLavafallColor); - return initialLavafallColor; - } - } - - return initialLavafallColor; - } - } -} diff --git a/Waters/CustomLavaStyle.cs b/Waters/CustomLavaStyle.cs deleted file mode 100644 index 5059a1134d..0000000000 --- a/Waters/CustomLavaStyle.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using ReLogic.Content; -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Waters -{ - public abstract class CustomLavaStyle - { - internal Texture2D LavaTexture; - internal Texture2D BlockTexture; - internal Texture2D SlopeTexture; - - internal void Load() - { - // Don't load textures serverside. - if (Main.netMode == NetmodeID.Server) - return; - - LavaTexture = ModContent.Request(LavaTexturePath, AssetRequestMode.ImmediateLoad).Value; - BlockTexture = ModContent.Request(BlockTexturePath, AssetRequestMode.ImmediateLoad).Value; - SlopeTexture = ModContent.Request(SlopeTexturePath, AssetRequestMode.ImmediateLoad).Value; - } - - internal void Unload() - { - LavaTexture = null; - BlockTexture = null; - } - - public abstract string LavaTexturePath { get; } - - public abstract string BlockTexturePath { get; } - - public abstract string SlopeTexturePath { get; } - - public virtual bool ChooseLavaStyle() => false; - - public abstract int ChooseWaterfallStyle(); - - public abstract int GetSplashDust(); - - public abstract int GetDropletGore(); - - public virtual void SelectLightColor(ref Color initialLightColor) - { - } - } -} diff --git a/Waters/LiquidTileType.cs b/Waters/LiquidTileType.cs deleted file mode 100644 index 594a74731d..0000000000 --- a/Waters/LiquidTileType.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace CalamityMod.Waters -{ - public enum LiquidTileType - { - Block, - Waterflow, - Slope - } -} diff --git a/Waters/MiddleAbyssWater.cs b/Waters/MiddleAbyssWater.cs index 1c7f8250f8..bd15111e36 100644 --- a/Waters/MiddleAbyssWater.cs +++ b/Waters/MiddleAbyssWater.cs @@ -1,28 +1,20 @@ -using Microsoft.Xna.Framework; +using CalamityMod.Dusts.WaterSplash; +using CalamityMod.Gores.WaterDroplet; +using CalamityMod.Systems; +using Microsoft.Xna.Framework; +using Terraria.Graphics; using Terraria.ModLoader; namespace CalamityMod.Waters { - public class MiddleAbyssWater : ModWaterStyle - { - public override int ChooseWaterfallStyle() - { - return ModContent.Find("CalamityMod/MiddleAbyssWaterflow").Slot; - } - - public override int GetSplashDust() - { - return 33; - } + public class MiddleAbyssWaterflow : ModWaterfallStyle { } - public override int GetDropletGore() - { - return 713; - } - - public override Color BiomeHairColor() - { - return Color.Blue; - } + public class MiddleAbyssWater : CalamityModWaterStyle + { + public override int ChooseWaterfallStyle() => ModContent.Find("CalamityMod/MiddleAbyssWaterflow").Slot; + public override int GetSplashDust() => ModContent.DustType(); + public override int GetDropletGore() => ModContent.GoreType(); + public override Color BiomeHairColor() => new Color(36, 23, 19); + public override void DrawColor(int x, int y, ref VertexColors liquidColor, bool isSlope) => ILEditing.ILChanges.SelectSulphuricWaterColor(x, y, ref liquidColor, isSlope); } } diff --git a/Waters/MiddleAbyssWaterflow.cs b/Waters/MiddleAbyssWaterflow.cs deleted file mode 100644 index 0105e3024f..0000000000 --- a/Waters/MiddleAbyssWaterflow.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Terraria.ModLoader; -namespace CalamityMod.Waters -{ - public class MiddleAbyssWaterflow : ModWaterfallStyle - { - - } -} diff --git a/Waters/PissWater.cs b/Waters/PissWater.cs index 0b315df535..629614b3fe 100644 --- a/Waters/PissWater.cs +++ b/Waters/PissWater.cs @@ -1,28 +1,17 @@ -using Microsoft.Xna.Framework; +using CalamityMod.Systems; +using Microsoft.Xna.Framework; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Waters { + public class PissWaterflow : ModWaterfallStyle { } + public class PissWater : ModWaterStyle { - public override int ChooseWaterfallStyle() - { - return ModContent.Find("CalamityMod/PissWaterflow").Slot; - } - - public override int GetSplashDust() - { - return 102; - } - - public override int GetDropletGore() - { - return 711; - } - - public override Color BiomeHairColor() - { - return Color.Yellow; - } + public override int ChooseWaterfallStyle() => ModContent.Find("CalamityMod/PissWaterflow").Slot; + public override int GetSplashDust() => DustID.Water_Desert; + public override int GetDropletGore() => GoreID.WaterDripDesert; + public override Color BiomeHairColor() => Color.Yellow; } } diff --git a/Waters/PissWaterflow.cs b/Waters/PissWaterflow.cs deleted file mode 100644 index a5189ea521..0000000000 --- a/Waters/PissWaterflow.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Terraria.ModLoader; -namespace CalamityMod.Waters -{ - public class PissWaterflow : ModWaterfallStyle - { - - } -} diff --git a/Waters/SulphuricDepthsWater.cs b/Waters/SulphuricDepthsWater.cs index 64aa588c33..4fdae19792 100644 --- a/Waters/SulphuricDepthsWater.cs +++ b/Waters/SulphuricDepthsWater.cs @@ -1,33 +1,37 @@ -using Microsoft.Xna.Framework; +using CalamityMod.Particles; +using System; +using CalamityMod.Systems; +using CalamityMod.Tiles.Abyss; +using Microsoft.Xna.Framework; +using Terraria; using Terraria.ModLoader; +using Terraria.Graphics; +using CalamityMod.Dusts.WaterSplash; +using CalamityMod.Gores.WaterDroplet; namespace CalamityMod.Waters { - public class SulphuricDepthsWater : ModWaterStyle - { - public static int Type; - public override void SetStaticDefaults() - { - Type = Slot; - } - public override int ChooseWaterfallStyle() - { - return ModContent.Find("CalamityMod/SulphuricDepthsWaterflow").Slot; - } - - public override int GetSplashDust() - { - return 33; - } - - public override int GetDropletGore() - { - return 713; - } + public class SulphuricDepthsWaterflow : ModWaterfallStyle { } - public override Color BiomeHairColor() + public class SulphuricDepthsWater : CalamityModWaterStyle + { + public override int ChooseWaterfallStyle() => ModContent.Find("CalamityMod/SulphuricDepthsWaterflow").Slot; + public override int GetSplashDust() => ModContent.DustType(); + public override int GetDropletGore() => ModContent.GoreType(); + public override Color BiomeHairColor() => new Color(35, 117, 89); + public override void DrawColor(int x, int y, ref VertexColors liquidColor, bool isSlope) => ILEditing.ILChanges.SelectSulphuricWaterColor(x, y, ref liquidColor, isSlope); + public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) { - return Color.Teal; + Vector3 outputColor = new Vector3(r, g, b); + if (outputColor == Vector3.One || outputColor == new Vector3(0.25f, 0.25f, 0.25f) || outputColor == new Vector3(0.5f, 0.5f, 0.5f)) + return; + if (CalamityUtils.ParanoidTileRetrieval(i, j).TileType != (ushort)ModContent.TileType()) + { + outputColor = Vector3.Lerp(outputColor, Color.MediumSeaGreen.ToVector3(), 0.18f); + } + r = outputColor.X; + g = outputColor.Y; + b = outputColor.Z; } } } diff --git a/Waters/SulphuricDepthsWaterflow.cs b/Waters/SulphuricDepthsWaterflow.cs deleted file mode 100644 index 5cf86274ff..0000000000 --- a/Waters/SulphuricDepthsWaterflow.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Terraria.ModLoader; -namespace CalamityMod.Waters -{ - public class SulphuricDepthsWaterflow : ModWaterfallStyle - { - - } -} diff --git a/Waters/SulphuricWater.cs b/Waters/SulphuricWater.cs index ef9ce540ea..036a6454d5 100644 --- a/Waters/SulphuricWater.cs +++ b/Waters/SulphuricWater.cs @@ -1,23 +1,104 @@ -using Microsoft.Xna.Framework; +using CalamityMod.Particles; +using System; +using CalamityMod.Systems; +using CalamityMod.Tiles.Abyss; +using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using ReLogic.Content; using Terraria; using Terraria.ModLoader; +using Terraria.Graphics; +using Terraria.ID; +using CalamityMod.Dusts.WaterSplash; +using CalamityMod.Gores.WaterDroplet; namespace CalamityMod.Waters { - public class SulphuricWater : ModWaterStyle + public class SulphuricWaterflow : ModWaterfallStyle { } + + public class SulphuricWater : CalamityModWaterStyle { - public static int Type; - public override void SetStaticDefaults() - { - Type = Slot; - } public override int ChooseWaterfallStyle() => ModContent.Find("CalamityMod/SulphuricWaterflow").Slot; - public override int GetSplashDust() => 101; - public override int GetDropletGore() => 708; + public override int GetSplashDust() => ModContent.DustType(); + public override int GetDropletGore() => ModContent.GoreType(); public override Asset GetRainTexture() => ModContent.Request("CalamityMod/Waters/SulphuricRain"); public override byte GetRainVariant() => (byte)Main.rand.Next(3); - public override Color BiomeHairColor() => Color.Turquoise; + public override Color BiomeHairColor() => new Color(43, 168, 110); + public override void DrawColor(int x, int y, ref VertexColors liquidColor, bool isSlope) => ILEditing.ILChanges.SelectSulphuricWaterColor(x, y, ref liquidColor, isSlope); + public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) + { + Vector3 outputColor = new Vector3(r, g, b); + if (outputColor == Vector3.One || outputColor == new Vector3(0.25f, 0.25f, 0.25f) || outputColor == new Vector3(0.5f, 0.5f, 0.5f)) + return; + Tile tile = CalamityUtils.ParanoidTileRetrieval(i, j); + Tile above = CalamityUtils.ParanoidTileRetrieval(i, j - 1); + if (!Main.gamePaused && !above.HasTile && above.LiquidAmount <= 0 && Main.rand.NextBool(9)) + { + MediumMistParticle acidFoam = new(new(i * 16f + Main.rand.NextFloat(16f), j * 16f + 8f), -Vector2.UnitY.RotatedByRandom(0.67f) * Main.rand.NextFloat(1f, 2.4f), Color.LightSeaGreen, Color.White, 0.16f, 128f, 0.02f); + GeneralParticleHandler.SpawnParticle(acidFoam); + } + + if (tile.TileType != (ushort)ModContent.TileType()) + { + if (Main.dayTime && !Main.raining) + { + float brightness = MathHelper.Clamp(0.2f - (j / 680), 0f, 0.2f); + if (j > 580) + brightness *= 1f - (j - 580) / 100f; + + float waveScale1 = Main.GameUpdateCount * 0.014f; + float waveScale2 = Main.GameUpdateCount * 0.1f; + int scalar = i + (-j / 2); + float wave1 = waveScale1 * -50 + scalar * 15; + float wave2 = waveScale2 * -10 + scalar * 14; + float wave3 = waveScale1 * -100 + scalar * 13; + float wave4 = waveScale2 * 10 + scalar * 25; + float wave5 = waveScale1 * -70 + scalar * 5; + float wave1angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave1)); + float wave2angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave2)); + float wave3angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave3)); + float wave4angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave4)); + float wave5angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave5)); + outputColor = Vector3.Lerp(outputColor, Color.LightSeaGreen.ToVector3(), 0.41f + wave1angle + wave2angle + wave3angle + wave4angle + wave5angle); + outputColor *= brightness; + } + + if (!Main.dayTime && !Main.raining) + { + float brightness = MathHelper.Clamp(0.17f - (j / 680), 0f, 0.17f); + if (j > 580) + brightness *= 1f - (j - 580) / 100f; + + float waveScale1 = Main.GameUpdateCount * 0.014f; + float waveScale2 = Main.GameUpdateCount * 0.1f; + int scalar = i + (-j / 2); + float wave1 = waveScale1 * -50 + scalar * 15; + float wave2 = waveScale2 * -10 + scalar * 14; + float wave3 = waveScale1 * -100 + scalar * 13; + float wave4 = waveScale2 * 10 + scalar * 25; + float wave5 = waveScale1 * -70 + scalar * 5; + float wave1angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave1)); + float wave2angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave2)); + float wave3angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave3)); + float wave4angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave4)); + float wave5angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave5)); + outputColor = Vector3.Lerp(outputColor, Color.LightSeaGreen.ToVector3(), 0.41f + wave1angle + wave2angle + wave3angle + wave4angle + wave5angle); + outputColor *= brightness; + } + + if (Main.raining) + { + float brightness = MathHelper.Clamp(1f - (j / 680), 0f, 1f); + if (j > 580) + brightness *= 1f - (j - 580) / 100f; + + outputColor = Vector3.Lerp(outputColor, Color.LightSeaGreen.ToVector3(), 0.41f); + outputColor *= brightness; + } + } + r = outputColor.X; + g = outputColor.Y; + b = outputColor.Z; + } } } diff --git a/Waters/SulphuricWaterflow.cs b/Waters/SulphuricWaterflow.cs deleted file mode 100644 index f9ed907df3..0000000000 --- a/Waters/SulphuricWaterflow.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Terraria.ModLoader; -namespace CalamityMod.Waters -{ - public class SulphuricWaterflow : ModWaterfallStyle - { - - } -} diff --git a/Waters/SunkenSeaWater.cs b/Waters/SunkenSeaWater.cs index 62c32fbd4c..4dbee891e9 100644 --- a/Waters/SunkenSeaWater.cs +++ b/Waters/SunkenSeaWater.cs @@ -1,33 +1,58 @@ -using Microsoft.Xna.Framework; +using CalamityMod.Particles; +using System; +using CalamityMod.Systems; +using CalamityMod.Tiles.Abyss; +using Microsoft.Xna.Framework; +using Terraria; using Terraria.ModLoader; +using Terraria.Graphics; +using CalamityMod.Dusts.WaterSplash; +using CalamityMod.Gores.WaterDroplet; namespace CalamityMod.Waters { - public class SunkenSeaWater : ModWaterStyle - { - public static int Type; - public override void SetStaticDefaults() - { - Type = Slot; - } - public override int ChooseWaterfallStyle() - { - return ModContent.Find("CalamityMod/SunkenSeaWaterflow").Slot; - } + public class SunkenSeaWaterflow : ModWaterfallStyle { } - public override int GetSplashDust() - { - return 33; - } - - public override int GetDropletGore() + public class SunkenSeaWater : CalamityModWaterStyle + { + public override int ChooseWaterfallStyle() => ModContent.Find("CalamityMod/SunkenSeaWaterflow").Slot; + public override int GetSplashDust() => ModContent.DustType(); + public override int GetDropletGore() => ModContent.GoreType(); + public override Color BiomeHairColor() => new Color(46, 155, 171); + public override void DrawColor(int x, int y, ref VertexColors liquidColor, bool isSlope) => ILEditing.ILChanges.SelectSulphuricWaterColor(x, y, ref liquidColor, isSlope); + public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) { - return 713; - } + Vector3 outputColor = new Vector3(r, g, b); + if (outputColor == Vector3.One || outputColor == new Vector3(0.25f, 0.25f, 0.25f) || outputColor == new Vector3(0.5f, 0.5f, 0.5f)) + return; - public override Color BiomeHairColor() - { - return Color.Blue; + if (CalamityUtils.ParanoidTileRetrieval(i, j).TileType != (ushort)ModContent.TileType()) + { + float brightness = MathHelper.Clamp(0.07f, 0f, 0.07f); + float waveScale1 = Main.GameUpdateCount * 0.028f; + float waveScale2 = Main.GameUpdateCount * 0.1f; + int yScale = -j / 2; + int xScale = i / 15; + float wave1 = Main.GameUpdateCount * 0.024f * -50 + ((-i / 30) + (j / 30)) * 25; + float wave2 = waveScale2 * -10 + ((-xScale) + yScale) * 45; + float wave3 = waveScale1 * -100 + ((i / 7) + (j / 50)) * 25; + float wave4 = Main.GameUpdateCount * 0.15f * 10 + ((i / 3) + yScale) * 45; + float wave5 = waveScale1 * -70 + ((-i / 25) + (-j / 25)) * 20; + float wave6 = waveScale2 * -10 + (xScale + yScale) * 45; + float bigwave = Main.GameUpdateCount * 0.01f * -70 + ((-i / 2) + (-j / 40)) * 5; + float wave1angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave1)); + float wave2angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave2)); + float wave3angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave3)); + float wave4angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave4)); + float wave5angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave5)); + float wave6angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave6)); + float bigwaveangle = 0.55f + 0.80f * (float)Math.Sin(MathHelper.ToRadians(bigwave)); + outputColor = Vector3.Lerp(outputColor, Color.DeepSkyBlue.ToVector3(), 0.07f + wave1angle + wave2angle + wave3angle + wave4angle + wave5angle + wave6angle + bigwaveangle); + outputColor *= brightness; + } + r = outputColor.X; + g = outputColor.Y; + b = outputColor.Z; } } } diff --git a/Waters/UpperAbyssWater.cs b/Waters/UpperAbyssWater.cs index 965861fdf7..fed3016207 100644 --- a/Waters/UpperAbyssWater.cs +++ b/Waters/UpperAbyssWater.cs @@ -1,28 +1,20 @@ -using Microsoft.Xna.Framework; +using CalamityMod.Dusts.WaterSplash; +using CalamityMod.Gores.WaterDroplet; +using CalamityMod.Systems; +using Microsoft.Xna.Framework; +using Terraria.Graphics; using Terraria.ModLoader; namespace CalamityMod.Waters { - public class UpperAbyssWater : ModWaterStyle - { - public override int ChooseWaterfallStyle() - { - return ModContent.Find("CalamityMod/UpperAbyssWaterflow").Slot; - } - - public override int GetSplashDust() - { - return 33; - } + public class UpperAbyssWaterflow : ModWaterfallStyle { } - public override int GetDropletGore() - { - return 713; - } - - public override Color BiomeHairColor() - { - return Color.Blue; - } + public class UpperAbyssWater : CalamityModWaterStyle + { + public override int ChooseWaterfallStyle() => ModContent.Find("CalamityMod/UpperAbyssWaterflow").Slot; + public override int GetSplashDust() => ModContent.DustType(); + public override int GetDropletGore() => ModContent.GoreType(); + public override Color BiomeHairColor() => new Color(9, 69, 82); + public override void DrawColor(int x, int y, ref VertexColors liquidColor, bool isSlope) => ILEditing.ILChanges.SelectSulphuricWaterColor(x, y, ref liquidColor, isSlope); } } diff --git a/Waters/UpperAbyssWaterflow.cs b/Waters/UpperAbyssWaterflow.cs deleted file mode 100644 index e61de17827..0000000000 --- a/Waters/UpperAbyssWaterflow.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Terraria.ModLoader; -namespace CalamityMod.Waters -{ - public class UpperAbyssWaterflow : ModWaterfallStyle - { - - } -} diff --git a/Waters/VoidWater.cs b/Waters/VoidWater.cs index bff3e0bf78..1ce1591140 100644 --- a/Waters/VoidWater.cs +++ b/Waters/VoidWater.cs @@ -1,28 +1,20 @@ -using Microsoft.Xna.Framework; +using CalamityMod.Dusts.WaterSplash; +using CalamityMod.Gores.WaterDroplet; +using CalamityMod.Systems; +using Microsoft.Xna.Framework; +using Terraria.Graphics; using Terraria.ModLoader; namespace CalamityMod.Waters { - public class VoidWater : ModWaterStyle - { - public override int ChooseWaterfallStyle() - { - return ModContent.Find("CalamityMod/VoidWaterflow").Slot; - } - - public override int GetSplashDust() - { - return 33; - } + public class VoidWaterflow : ModWaterfallStyle { } - public override int GetDropletGore() - { - return 713; - } - - public override Color BiomeHairColor() - { - return Color.Blue; - } + public class VoidWater : CalamityModWaterStyle + { + public override int ChooseWaterfallStyle() => ModContent.Find("CalamityMod/VoidWaterflow").Slot; + public override int GetSplashDust() => ModContent.DustType(); + public override int GetDropletGore() => ModContent.GoreType(); + public override Color BiomeHairColor() => new Color(16, 8, 30); + public override void DrawColor(int x, int y, ref VertexColors liquidColor, bool isSlope) => ILEditing.ILChanges.SelectSulphuricWaterColor(x, y, ref liquidColor, isSlope); } } diff --git a/Waters/VoidWaterflow.cs b/Waters/VoidWaterflow.cs deleted file mode 100644 index bb408bd108..0000000000 --- a/Waters/VoidWaterflow.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Terraria.ModLoader; -namespace CalamityMod.Waters -{ - public class VoidWaterflow : ModWaterfallStyle - { - - } -} From 6494ca4332347499f49d11db15d142b17472c4d9 Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Sat, 22 Nov 2025 12:56:28 +0700 Subject: [PATCH 355/401] Manual fixes to the rewrite --- Systems/ModLavaStyle.cs | 2 +- Waters/SunkenSeaWaterflow.cs | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) delete mode 100644 Waters/SunkenSeaWaterflow.cs diff --git a/Systems/ModLavaStyle.cs b/Systems/ModLavaStyle.cs index 84d229559a..a6b7d31580 100644 --- a/Systems/ModLavaStyle.cs +++ b/Systems/ModLavaStyle.cs @@ -148,7 +148,7 @@ public override void Load() { if (ResizeArrayMethodInfo != null) { - MonoModHooks.Add(ResizeArrayMethodInfo, ResizeArrays); + MonoModHooks.Add(ResizeArrayMethodInfo, Delegate.CreateDelegate(typeof(Action), typeof(LavaStylesLoader).GetMethod(nameof(ResizeArrays), BindingFlags.NonPublic | BindingFlags.Static))); } } diff --git a/Waters/SunkenSeaWaterflow.cs b/Waters/SunkenSeaWaterflow.cs deleted file mode 100644 index ae61284b07..0000000000 --- a/Waters/SunkenSeaWaterflow.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Terraria.ModLoader; -namespace CalamityMod.Waters -{ - public class SunkenSeaWaterflow : ModWaterfallStyle - { - - } -} From 338d5b42d3801c6381f8c1a0acbe30f4233cd976 Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Mon, 10 Nov 2025 13:55:59 +0700 Subject: [PATCH 356/401] cleanup on aisle local variable --- ILEditing/MechanicILChanges.cs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/ILEditing/MechanicILChanges.cs b/ILEditing/MechanicILChanges.cs index 21d60a67f9..725eefc68f 100644 --- a/ILEditing/MechanicILChanges.cs +++ b/ILEditing/MechanicILChanges.cs @@ -897,16 +897,16 @@ private void DrawLavatoCapture(ILContext il) private void AddTileLiquidDrawing(ILContext il) { ILCursor cursor = new ILCursor(il); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg0(), i => i.MatchLdarg1(), i => i.MatchLdcI4(0), i => i.MatchLdarg(out _), i => i.MatchLdloc1(), i => i.MatchLdloc2(), i => i.MatchLdloc(12), i => i.MatchLdloc(13), i => i.MatchLdloc(14), i => i.MatchCall("DrawTile_LiquidBehindTile"))) + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg0(), i => i.MatchLdarg1(), i => i.MatchLdcI4(0), i => i.MatchLdarg(out _), i => i.MatchLdloc1(), i => i.MatchLdloc2(), i => i.MatchLdloc(13), i => i.MatchLdloc(14), i => i.MatchLdloc(15), i => i.MatchCall("DrawTile_LiquidBehindTile"))) { LogFailure("Tile Lava Drawing", "Could not locate the drawing of Liquid Behind Tile drawing"); return; } cursor.EmitLdloc1(); cursor.EmitLdloc2(); - cursor.EmitLdloc(12); cursor.EmitLdloc(13); cursor.EmitLdloc(14); + cursor.EmitLdloc(15); cursor.EmitDelegate((Microsoft.Xna.Framework.Vector2 unscaledPosition, Microsoft.Xna.Framework.Vector2 vector, int j, int i, Terraria.Tile tile) => { LavaRendering.instance.DrawTile_LiquidBehindTile(solidLayer: false, inFrontOfPlayers: false, -1, unscaledPosition, vector, j, i, tile); }); @@ -923,18 +923,18 @@ private void BlockLavaDrawing(ILContext il) //Continue if statement, basically //if the liquid being drawn is lava and the water style is greater than the max water styles or if the liquid is water and less than the max water styles then the draw code is ran //otherwise the loop/s are continued for the next liquid - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchStloc(4), i => i.MatchBr(out _), i => i.MatchLdloc(2), i => i.MatchLdfld(typeof(LiquidRenderer).GetNestedType("LiquidDrawCache", BindingFlags.NonPublic), "IsVisible"))) + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchStloc(4), i => i.MatchBr(out _), i => i.MatchLdloc(2), i => i.MatchLdfld(typeof(LiquidRenderer).GetNestedType("LiquidDrawCache", BindingFlags.Public), "IsVisible"))) { LogFailure("Liquid Renderer Drawing", "Could not locate the IsVisible boolean check"); return; } cursor.EmitLdarg3(); cursor.EmitLdloc2(); //Initiated Liquid Draw Cache (needed for the Type parameter) - cursor.EmitLdfld(typeof(LiquidRenderer).GetNestedType("LiquidDrawCache", BindingFlags.NonPublic).GetRuntimeField("Type")); + cursor.EmitLdfld(typeof(LiquidRenderer).GetNestedType("LiquidDrawCache", BindingFlags.Public).GetRuntimeField("Type")); cursor.EmitDelegate>((IsVisible, style, type) => IsVisible && ((type == 1 && style >= LavaRendering.instance.WaterStyleMaxCount + 1) || (type != 1 && style <= LavaRendering.instance.WaterStyleMaxCount))); //Lava alpha color, if the liquid drawn is lava, multiply num by the water alpha - if (!cursor.TryGotoNext(MoveType.Before, i => i.MatchLdloc(2), i => i.MatchLdfld(typeof(LiquidRenderer).GetNestedType("LiquidDrawCache", BindingFlags.NonPublic).GetRuntimeField("Type")), i => i.MatchStloc(8))) + if (!cursor.TryGotoNext(MoveType.Before, i => i.MatchLdloc(2), i => i.MatchLdfld(typeof(LiquidRenderer).GetNestedType("LiquidDrawCache", BindingFlags.Public).GetRuntimeField("Type")), i => i.MatchStloc(8))) { LogFailure("Liquid Renderer Drawing", "Could not locate creation of the local variable num2 (the liquid type holder variable)"); return; @@ -958,7 +958,7 @@ private void BlockLavaDrawing(ILContext il) } cursor.EmitLdarg3(); cursor.EmitLdloc2(); //Initiated Liquid Draw Cache (needed for the Type parameter) - cursor.EmitLdfld(typeof(LiquidRenderer).GetNestedType("LiquidDrawCache", BindingFlags.NonPublic).GetRuntimeField("Type")); + cursor.EmitLdfld(typeof(LiquidRenderer).GetNestedType("LiquidDrawCache", BindingFlags.Public).GetRuntimeField("Type")); cursor.EmitDelegate>((initialTexture, style, type) => (style >= LavaRendering.instance.WaterStyleMaxCount + 1 && type == LiquidID.Lava) ? CalamityMod.LavaTextures.liquid[style - LavaRendering.instance.WaterStyleMaxCount - 1].Value : initialTexture); } @@ -1204,17 +1204,17 @@ private void LavafallLightEditor(On_WaterfallManager.orig_AddLight orig, int wat private static void LiquidDrawColors(ILContext il) { ILCursor cursor = new ILCursor(il); - if (!cursor.TryGotoNext(MoveType.Before, c => c.MatchLdarg2(), c => c.MatchLdloc3(), c => c.MatchLdloc(4), c => c.MatchCall
("DrawTileInWater"))) + if (!cursor.TryGotoNext(MoveType.Before, c => c.MatchLdarg2(), c => c.MatchLdloc(9), c => c.MatchLdloc(10), c => c.MatchCall
("DrawTileInWater"))) { LogFailure("Liquid Draw Colors", "Could not locate the liquid vertex colors for drawing"); return; } - cursor.Emit(OpCodes.Ldloc_3); - cursor.Emit(OpCodes.Ldloc, 4); + cursor.Emit(OpCodes.Ldloc, 9); + cursor.Emit(OpCodes.Ldloc, 10); cursor.Emit(OpCodes.Ldloc_2); - cursor.Emit(OpCodes.Ldfld, typeof(LiquidRenderer).GetNestedType("LiquidDrawCache", BindingFlags.NonPublic).GetRuntimeField("Type")); - cursor.Emit(OpCodes.Ldloca, 9); + cursor.Emit(OpCodes.Ldfld, typeof(LiquidRenderer).GetNestedType("LiquidDrawCache", BindingFlags.Public).GetRuntimeField("Type")); + cursor.Emit(OpCodes.Ldloca, 11); cursor.EmitDelegate((int x, int y, int liquidType, ref VertexColors initialColor) => { From 7c7838aa5f68bf2481b068bf6aa683a3ff1d3067 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 22 Nov 2025 10:09:15 -0500 Subject: [PATCH 357/401] Fixed Infinity and Svantechnical right clicks breaking certain bullets --- Items/Weapons/Ranged/Infinity.cs | 4 ++-- Items/Weapons/Ranged/Svantechnical.cs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Items/Weapons/Ranged/Infinity.cs b/Items/Weapons/Ranged/Infinity.cs index 31868841d0..553ab828a0 100644 --- a/Items/Weapons/Ranged/Infinity.cs +++ b/Items/Weapons/Ranged/Infinity.cs @@ -62,8 +62,8 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, { Vector2 helixVel1 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(sine)); Vector2 helixVel2 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(-sine)); - int shot1 = Projectile.NewProjectile(source, position.X, position.Y, helixVel1.X, helixVel1.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, 1f); - int shot2 = Projectile.NewProjectile(source, position.X, position.Y, helixVel2.X, helixVel2.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, 1f); + int shot1 = Projectile.NewProjectile(source, position.X, position.Y, helixVel1.X, helixVel1.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, player.altFunctionUse != 2 ? 1f : 0); + int shot2 = Projectile.NewProjectile(source, position.X, position.Y, helixVel2.X, helixVel2.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, player.altFunctionUse != 2 ? 1f : 0); } else if (player.altFunctionUse != 2) { diff --git a/Items/Weapons/Ranged/Svantechnical.cs b/Items/Weapons/Ranged/Svantechnical.cs index e304c42a43..6b181f0e00 100644 --- a/Items/Weapons/Ranged/Svantechnical.cs +++ b/Items/Weapons/Ranged/Svantechnical.cs @@ -63,9 +63,9 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 helixVel1 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(sine)); Vector2 helixVel2 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(-sine)); Vector2 helixVel3 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(sine2)); - int shot1 = Projectile.NewProjectile(source, position.X, position.Y, helixVel1.X, helixVel1.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, 2f); - int shot2 = Projectile.NewProjectile(source, position.X, position.Y, helixVel2.X, helixVel2.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, 4f); - int shot3 = Projectile.NewProjectile(source, position.X, position.Y, helixVel3.X, helixVel3.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, 3f); + int shot1 = Projectile.NewProjectile(source, position.X, position.Y, helixVel1.X, helixVel1.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, player.altFunctionUse != 2 ? 2f : 0f); + int shot2 = Projectile.NewProjectile(source, position.X, position.Y, helixVel2.X, helixVel2.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, player.altFunctionUse != 2 ? 4f : 0f); + int shot3 = Projectile.NewProjectile(source, position.X, position.Y, helixVel3.X, helixVel3.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, player.altFunctionUse != 2 ? 3f : 0f); } else if (player.altFunctionUse != 2) { From 5c9ba012712901ba1c92c68a32a395c8c58901da Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 22 Nov 2025 10:12:13 -0500 Subject: [PATCH 358/401] Fixed Infinity and Svantechnical not stating their chance to not consume ammo in their tooltips --- Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson index df009fe392..9fd35e7033 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson @@ -639,6 +639,7 @@ Infinity: { ''' Fires a twin stream of energy bolts that split Press to fire a barrage of normal bullets + 80% chance to save ammo 'They say infinity is neverending, yet you hold it in your hands' ''' } @@ -1253,6 +1254,7 @@ Svantechnical: { ''' Fires a trinity of energy bolts that split into beams that track your cursor Press to fire a barrage of normal bullets + 90% chance to save ammo 'The age old balance of trading damage for frames' ''' } From e08e70e1d679e7c8f7dcb81880fb4ba5bb69b9ea Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 22 Nov 2025 10:19:35 -0500 Subject: [PATCH 359/401] Fixed GSD not properly cleansing debuffs or preventing negative life regen --- CalPlayer/CalamityPlayerLifeRegen.cs | 4 ++-- CalPlayer/CalamityPlayerMiscEffects.cs | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CalPlayer/CalamityPlayerLifeRegen.cs b/CalPlayer/CalamityPlayerLifeRegen.cs index a2e2ac01bb..c939d7fc6e 100644 --- a/CalPlayer/CalamityPlayerLifeRegen.cs +++ b/CalPlayer/CalamityPlayerLifeRegen.cs @@ -3,7 +3,7 @@ using CalamityMod.Buffs.Alcohol; using CalamityMod.Buffs.DamageOverTime; using CalamityMod.Buffs.Placeables; -using CalamityMod.Cooldowns; +using CalamityMod.CalPlayer.Dashes; using CalamityMod.Items.Accessories; using CalamityMod.NPCs; using CalamityMod.Projectiles.Ranged; @@ -523,7 +523,7 @@ void ApplyDoTDebuff(bool hasDebuff, int negativeLifeRegenToApply, bool immuneCon #endregion // During Silva revive or God Slayer dash, all negative life regen is canceled - if ((silvaCountdown > 0 && hasSilvaEffect && silvaSet) || (DashID == GodSlayerDash.ID && Player.dashDelay < 0)) + if ((silvaCountdown > 0 && hasSilvaEffect && silvaSet) || (DashID == GodslayerArmorDash.ID && Player.dashDelay < 0)) { if (Player.lifeRegen < 0) Player.lifeRegen = 0; diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index b480c34fa4..63303870dd 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -8,6 +8,7 @@ using CalamityMod.Buffs.StatBuffs; using CalamityMod.Buffs.StatDebuffs; using CalamityMod.Buffs.Summon; +using CalamityMod.CalPlayer.Dashes; using CalamityMod.Cooldowns; using CalamityMod.CustomRecipes; using CalamityMod.DataStructures; @@ -1569,7 +1570,7 @@ private void MiscEffects() MiniSwamerCooldown--; // God Slayer Armor dash debuff immunity - if (DashID == GodSlayerDash.ID && Player.dashDelay < 0) + if (DashID == GodslayerArmorDash.ID && Player.dashDelay < 0) { foreach (int debuff in CalamityLists.debuffList) Player.buffImmune[debuff] = true; From ee235b4b73ce7b35ca0513fb6e7e51bf1467d507 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 22 Nov 2025 10:21:34 -0500 Subject: [PATCH 360/401] Fixed Fiery Draconid buff still giving life regen --- CalPlayer/CalamityPlayerLifeRegen.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/CalPlayer/CalamityPlayerLifeRegen.cs b/CalPlayer/CalamityPlayerLifeRegen.cs index c939d7fc6e..5139c19f45 100644 --- a/CalPlayer/CalamityPlayerLifeRegen.cs +++ b/CalPlayer/CalamityPlayerLifeRegen.cs @@ -605,9 +605,6 @@ public override void UpdateLifeRegen() if (caribbeanRum) Player.lifeRegen += 2; - if (aChicken) - Player.lifeRegen += 1; - if (mushy) Player.lifeRegen += 2; From 263135bd59237450d296b53ffeffc1b115f13051 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 22 Nov 2025 10:23:25 -0500 Subject: [PATCH 361/401] Fixed some buffs having corners on their buff icon --- Buffs/Alcohol/AlcoholPoisoning.png | Bin 446 -> 367 bytes Buffs/Summon/CosmilampBuff.png | Bin 645 -> 409 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/Buffs/Alcohol/AlcoholPoisoning.png b/Buffs/Alcohol/AlcoholPoisoning.png index 7c001df28c83367cb7fcf5345f1af91aa29359ad..224cdd155de2326b1f422534e1139d0247329a0f 100644 GIT binary patch delta 302 zcmdnT{GMroBnLAC1B1(wu45Aw6+G1gd_r7-{7k>>#;}@mn@_B1UoI*mmAW8u*0u7p z|0hdWDgXcf-?1+OsHU2ux)@0DmIV0)0|nuL!S;nx+eABw`W>Dwjv*HQODDhPJEXwl zHt~|uiQo3?=S)57JDK;<_hts$h2c)w51sB-akqSU(G^=Hkp9j*i>bp+fqN{-}80y80Ef~Rh|rE$e+f%mdKI;Vst026D1l>h($ delta 402 zcmV;D0d4;80=@%~83+OZ008_L?W2()Ab$yPNLh0L01m?d01m?e$8V@)0000PbVXQn zQ*UN;cVTj60B~VxZgehgWpp4kE-)@JGc*HRdH?_cE=fc|R7gwRl`(F@KoCWJ2_zKJ zNynyinpbU~ zXia&5w3h&0GNfku^cZjeoti9w!+$sec>MFV+5(uO97g~kecmn-STwPQE&D`k%7a1y zJ`lgMK*yS)1DYQ@FJng^ZUH`_U&GxFRieJy{ymv(?AvC}>G$`??I@Q@Bi**yb z0)wKda8TR3xEqB`28WM?hintBEGg!CFlpH}hAm}s_L~j;S& zq!bI{!GqYt?#nXMY}(t-yX=0$%s2bq%)I%w3;0ij*cRpF0Dn95Qms}2sMTr!l*{Fg z1DnfhMjRXL?btt^P6LokCILvLQh-Yeh`EqRB#d}*;kywZIC#W}8$Xtf_{8wuwiDX( zxTAp9T+B0>3;@?hvjA-G+Xuk0(<1&7^D6tE%Y z!{avr`1#3OD_)V}i7W4QbLIU~=>k>hRWaZiDGJPyEOpSSD9{LJAfL|z@bX0kfb5ki0Q%G2Ksa+76E_}s z{e2}?%YOhU%sd3(^3_uSunKprgx^u^40kAHu^zHKR?`bjYxnn!R)0YPi@ zJpUR9oJ{9gXvTILajf~*h_zQV?pkiF?FU4zKRtzw0>O z-BS=$Ks~@lACR*(e1>y{ZX=PH59}EP0_U`Sz^=61Q9w{7WBY)dZLaVI2(JfpE80Gw zyw2SPp>Xwp9Bts}MIc}#C3No#HuL@QApjanZ~PwZYeaVxP~F~wx1`LMJO;YgwX5wa zSnYzCs}fQ@pl7900US`E<%FC48Lh7L7_l5pupP92*KZ?s_RpxLKvalafpvYv*XSja Ro$mku002ovPDHLkV1iX7E_?t0 From 557d69fe3d5c5266c16138e8037942e8b10c3b85 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 22 Nov 2025 10:29:16 -0500 Subject: [PATCH 362/401] Fixed Draedon's Forge recipe unlock not being triggered when used with Magic Storage --- Items/CalamityGlobalItem.cs | 10 ++++++++++ .../Furniture/CraftingStations/DraedonsForge.cs | 13 ------------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/Items/CalamityGlobalItem.cs b/Items/CalamityGlobalItem.cs index d06c26911e..86f004346b 100644 --- a/Items/CalamityGlobalItem.cs +++ b/Items/CalamityGlobalItem.cs @@ -20,6 +20,7 @@ using CalamityMod.Projectiles.Summon; using CalamityMod.Projectiles.Typeless; using CalamityMod.Rarities; +using CalamityMod.Tiles.Furniture.CraftingStations; using CalamityMod.UI; using CalamityMod.UI.CalamitasEnchants; using CalamityMod.World; @@ -1750,10 +1751,19 @@ public override bool PreDrawInInventory(Item item, SpriteBatch spriteBatch, Vect #endregion #region On Create + private static int cachedForgeID = -1; public override void OnCreated(Item item, ItemCreationContext context) { // ChoosePrefix also happens on craft so go reset it here too storedPrefix = -1; + + // 05JUL2024: Ozzatron: Register the usage of Draedon's Forge for the purposes of his dialogue. + // This was moved out of an On edit in the DraedonsForge item for Magic Storage compatibility. + Player p = Main.LocalPlayer; + if (cachedForgeID < 0) + cachedForgeID = ModContent.TileType(); + if (context is RecipeItemCreationContext && p.adjTile[cachedForgeID]) + p.Calamity().HasCraftedDraedonsForge = true; } #endregion diff --git a/Items/Placeables/Furniture/CraftingStations/DraedonsForge.cs b/Items/Placeables/Furniture/CraftingStations/DraedonsForge.cs index 60d8f1eb10..8647af0c1a 100644 --- a/Items/Placeables/Furniture/CraftingStations/DraedonsForge.cs +++ b/Items/Placeables/Furniture/CraftingStations/DraedonsForge.cs @@ -9,19 +9,6 @@ namespace CalamityMod.Items.Placeables.Furniture.CraftingStations public class DraedonsForge : ModItem, ILocalizedModType { public new string LocalizationCategory => "Items.Placeables"; - public override void SetStaticDefaults() - { - Terraria.On_Recipe.ConsumeForCraft += DraeforgeUnlockDetour; - } - - private static bool DraeforgeUnlockDetour(On_Recipe.orig_ConsumeForCraft orig, Recipe self, Item item, Item requiredItem, ref int stackRequired) - { - if (self.HasTile(ModContent.TileType())) - { - Main.LocalPlayer.Calamity().HasCraftedDraedonsForge = true; - } - return orig(self, item, requiredItem, ref stackRequired); - } public override void SetDefaults() { From 1d9878d6350c6ec832532d7def58e24d990f332d Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 22 Nov 2025 11:07:52 -0500 Subject: [PATCH 363/401] Betsy's Curse no longer reduces enemy DR --- NPCs/CalamityGlobalNPC.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/NPCs/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index 0e10b2ab06..b9d9b5f707 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -3267,8 +3267,6 @@ private float DefaultDRMath(NPC npc, float DR) calcDR *= 0.5f; if (absorberAffliction > 0) calcDR *= 0.8f; - if (npc.betsysCurse) - calcDR *= 0.66f; if (npc.Calamity().aCrunch > 0) calcDR *= ArmorCrunch.MultiplicativeDamageReductionEnemy; if (npc.Calamity().crumble > 0) From 4cb248c6aee0b76953eb256ed2d8eb7b3d3c8d88 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 22 Nov 2025 11:43:31 -0500 Subject: [PATCH 364/401] Removed all vanilla item auto-use tweaks --- CalamityLists.cs | 24 --- Items/CalamityGlobalItem.cs | 4 - Items/CalamityGlobalItemTweaks.cs | 289 ++++++++++++------------------ 3 files changed, 119 insertions(+), 198 deletions(-) diff --git a/CalamityLists.cs b/CalamityLists.cs index 53bc46e825..774bf0f601 100644 --- a/CalamityLists.cs +++ b/CalamityLists.cs @@ -89,7 +89,6 @@ public class CalamityLists public static List fireDebuffList; public static List sicknessDebuffList; public static List alcoholList; - public static List spearAutoreuseList; public static List pumpkinMoonBuffList; public static List frostMoonBuffList; public static List eclipseBuffList; @@ -1376,28 +1375,6 @@ public static void LoadLists() BuffType() }; - spearAutoreuseList = new List() - { - ItemID.AdamantiteGlaive, - ItemID.ChlorophytePartisan, - ItemID.CobaltNaginata, - ItemID.DarkLance, - ItemID.MonkStaffT2, - ItemID.Gungnir, - ItemID.MushroomSpear, - ItemID.MythrilHalberd, - ItemID.NorthPole, - ItemID.ObsidianSwordfish, - ItemID.OrichalcumHalberd, - ItemID.PalladiumPike, - ItemID.Spear, - ItemID.Swordfish, - ItemID.TheRottedFork, - ItemID.TitaniumTrident, - ItemID.Trident, - ItemID.ThunderSpear - }; - pumpkinMoonBuffList = new List() { NPCID.Scarecrow1, @@ -2750,7 +2727,6 @@ public static void UnloadLists() fireDebuffList = null; sicknessDebuffList = null; alcoholList = null; - spearAutoreuseList = null; pumpkinMoonBuffList = null; frostMoonBuffList = null; eclipseBuffList = null; diff --git a/Items/CalamityGlobalItem.cs b/Items/CalamityGlobalItem.cs index 86f004346b..3215e277ff 100644 --- a/Items/CalamityGlobalItem.cs +++ b/Items/CalamityGlobalItem.cs @@ -842,10 +842,6 @@ public override bool CanUseItem(Item item, Player player) // Handle general use-item effects for the Gem Tech Armor. player.Calamity().GemTechState.OnItemUseEffects(item); - if (item.type == ItemID.MonkStaffT1 || CalamityLists.spearAutoreuseList.Contains(item.type)) - { - return player.ownedProjectileCounts[item.shoot] <= 0; - } if (item.type == ItemID.RodofDiscord) { if (player.chaosState) diff --git a/Items/CalamityGlobalItemTweaks.cs b/Items/CalamityGlobalItemTweaks.cs index 107986fa4e..37820cf8f3 100644 --- a/Items/CalamityGlobalItemTweaks.cs +++ b/Items/CalamityGlobalItemTweaks.cs @@ -25,7 +25,6 @@ internal static void LoadTweaks() IItemTweak[] trueMelee = Do(TrueMelee); IItemTweak[] trueMeleeNoSpeed = Do(TrueMeleeNoSpeed); IItemTweak[] pointBlank = Do(PointBlank); - IItemTweak[] autoReuse = Do(AutoReuse); IItemTweak[] nonConsumableBossSummon = Do(MaxStack(1), NotConsumable, UseTimeExact(10)); // SORTING NOTES: @@ -35,7 +34,7 @@ internal static void LoadTweaks() currentTweaks = new SortedDictionary { #region CATEGORY 1: Weapon Balancing - { ItemID.AdamantiteGlaive, Do(AutoReuse, TrueMelee, UseRatio(0.8f), DamageExact(65), ShootSpeedRatio(1.25f)) }, + { ItemID.AdamantiteGlaive, Do(TrueMelee, UseRatio(0.8f), DamageExact(65), ShootSpeedRatio(1.25f)) }, { ItemID.AdamantiteRepeater, Do(PointBlank, UseExact(14)) }, { ItemID.AdamantiteSword, Do(UseTurn, DamageExact(77)) }, { ItemID.AmberStaff, Do(UseTimeExact(15), UseAnimationExact(45), ReuseDelayExact(15)) }, @@ -50,31 +49,31 @@ internal static void LoadTweaks() { ItemID.BeesKnees, Do(PointBlank, DamageExact(24), UseExact(38)) }, { ItemID.Bladetongue, Do(UseTurn, UseRatio(0.8f), DamageExact(120)) }, { ItemID.BlizzardStaff, Do(DamageExact(41), ManaExact(7)) }, - { ItemID.BloodyMachete, Do(AutoReuse, DamageExact(24)) }, + { ItemID.BloodyMachete, Do(DamageExact(24)) }, { ItemID.Blowgun, Do(PointBlank, DamageExact(40)) }, - { ItemID.BluePhaseblade, Do(AutoReuse, UseTurn, DamageExact(32)) }, + { ItemID.BluePhaseblade, Do(UseTurn, DamageExact(32)) }, { ItemID.BluePhasesaber, Do(DamageExact(60)) }, { ItemID.BookofSkulls, Do(ManaExact(12), ShootSpeedExact(5.5f)) }, { ItemID.BookStaff, Do(ManaExact(14)) }, // Tome of Infinite Wisdom { ItemID.Boomstick, Do(PointBlank, DamageExact(11)) }, - { ItemID.BreakerBlade, Do(AutoReuse, UseTurn, DamageExact(97)) }, + { ItemID.BreakerBlade, Do(UseTurn, DamageExact(97)) }, { ItemID.CandyCornRifle, Do(PointBlank, DamageExact(66)) }, - { ItemID.Cascade, Do(AutoReuse, DamageExact(30)) }, + { ItemID.Cascade, Do(DamageExact(30)) }, { ItemID.ChainGuillotines, Do(DamageExact(100)) }, { ItemID.ChainGun, Do(PointBlank, DamageExact(35)) }, - { ItemID.ChainKnife, Do(AutoReuse, DamageRatio(1.34f)) }, // Uses ratios due to remix seed + { ItemID.ChainKnife, Do(DamageRatio(1.34f)) }, // Uses ratios due to remix seed { ItemID.ChlorophyteClaymore, Do(UseMeleeSpeed, DamageExact(176), UseExact(35), UseAnimationExact(45), ShootSpeedExact(22f)) }, - { ItemID.ChlorophytePartisan, Do(AutoReuse, UseMeleeSpeed, UseRatio(0.8f), DamageExact(70)) }, + { ItemID.ChlorophytePartisan, Do(UseMeleeSpeed, UseRatio(0.8f), DamageExact(70)) }, { ItemID.ChlorophyteSaber, Do(UseMeleeSpeed, DamageExact(80), UseExact(10)) }, - { ItemID.ChristmasTreeSword, Do(AutoReuse, UseTurn, UseMeleeSpeed, DamageExact(80), UseExact(30)) }, + { ItemID.ChristmasTreeSword, Do(UseTurn, UseMeleeSpeed, DamageExact(80), UseExact(30)) }, { ItemID.ClingerStaff, Do(DamageExact(63)) }, { ItemID.ClockworkAssaultRifle, Do(PointBlank, DamageExact(21)) }, - { ItemID.CobaltNaginata, Do(AutoReuse, TrueMelee, UseRatio(0.8f), DamageExact(90)) }, + { ItemID.CobaltNaginata, Do(TrueMelee, UseRatio(0.8f), DamageExact(90)) }, { ItemID.CobaltRepeater, Do(PointBlank, UseExact(18)) }, - { ItemID.CobaltSword, Do(UseTurn, DamageExact(80)) }, - { ItemID.Code2, Do(AutoReuse, DamageExact(43)) }, - { ItemID.CorruptYoyo, Do(AutoReuse, DamageExact(20)) }, // Malaise - { ItemID.CrimsonYoyo, Do(AutoReuse, DamageExact(20)) }, // Artery + { ItemID.CobaltSword, Do(DamageExact(80)) }, + { ItemID.Code2, Do(DamageExact(43)) }, + { ItemID.CorruptYoyo, Do(DamageExact(20)) }, // Malaise + { ItemID.CrimsonYoyo, Do(DamageExact(20)) }, // Artery { ItemID.CrystalBullet, Do(DamageExact(8)) }, { ItemID.CrystalDart, Do(DamageExact(20)) }, { ItemID.CrystalSerpent, Do(DamageExact(45)) }, @@ -84,20 +83,20 @@ internal static void LoadTweaks() { ItemID.Cutlass, Do(UseRatio(0.9f), DamageExact(90)) }, { ItemID.DaedalusStormbow, Do(DamageExact(30)) }, { ItemID.DaoofPow, Do(DamageExact(160)) }, - { ItemID.DarkLance, Do(AutoReuse, TrueMelee, DamageExact(45)) }, + { ItemID.DarkLance, Do(TrueMelee, DamageExact(45)) }, { ItemID.DartRifle, Do(PointBlank, DamageExact(58)) }, { ItemID.DayBreak, Do(DamageExact(125), UseExact(20)) }, { ItemID.DD2BetsyBow, Do(DamageExact(42)) }, // Aerial Bane's ridiculous multiplier is removed, so this compensates for that { ItemID.DD2SquireBetsySword, Do(UseMeleeSpeed, DamageExact(150)) }, // Flying Dragon { ItemID.DD2SquireDemonSword, Do(DamageExact(110), UseExact(25)) }, // Brand of the Inferno { ItemID.DeathSickle, Do(UseMeleeSpeed, DamageExact(82), ShootSpeedExact(15f)) }, - { ItemID.DemonBow, Do(PointBlank, DamageExact(12), AutoReuse) }, - { ItemID.DemonScythe, Do(AutoReuse, DamageExact(33)) }, - { ItemID.DyeTradersScimitar, Do(AutoReuse, UseTurn, DamageExact(24)) }, // Exotic Scimitar + { ItemID.DemonBow, Do(PointBlank, DamageExact(12)) }, + { ItemID.DemonScythe, Do(DamageExact(33)) }, + { ItemID.DyeTradersScimitar, Do(UseTurn, DamageExact(24)) }, // Exotic Scimitar { ItemID.ElectrosphereLauncher, Do(DamageExact(44)) }, { ItemID.ElfMelter, Do(ShootSpeedDelta(+5f)) }, { ItemID.EmeraldStaff, Do(DamageExact(27)) }, - { ItemID.EmpressBlade, Do(AutoReuse, DamageExact(60), UseExact(20)) }, // Terraprisma + { ItemID.EmpressBlade, Do(DamageExact(60), UseExact(20)) }, // Terraprisma { ItemID.EnchantedBoomerang, Do(DamageExact(24)) }, { ItemID.EnchantedSword, Do(UseMeleeSpeed, DamageExact(30), ShootSpeedExact(15f)) }, { ItemID.Excalibur, Do(TrueMelee, UseRatio(0.8f), DamageExact(125), UseAnimationExact(45)) }, @@ -109,43 +108,43 @@ internal static void LoadTweaks() { ItemID.Flamarang, Do(DamageExact(40)) }, { ItemID.Flamelash, Do(DamageExact(40)) }, { ItemID.Flamethrower, Do(DamageExact(21), ShootSpeedDelta(+3f)) }, - { ItemID.FlowerofFire, Do(AutoReuse, ManaExact(7), UseRatio(0.88f), DamageRatio(0.65f)) }, // Uses ratios due to remix seed - { ItemID.FlowerofFrost, Do(AutoReuse, ManaExact(7), UseExact(22), DamageExact(70), ShootSpeedExact(14)) }, + { ItemID.FlowerofFire, Do(ManaExact(7), UseRatio(0.88f), DamageRatio(0.65f)) }, // Uses ratios due to remix seed + { ItemID.FlowerofFrost, Do(ManaExact(7), UseExact(22), DamageExact(70), ShootSpeedExact(14)) }, { ItemID.FlyingKnife, Do(DamageExact(53)) }, { ItemID.Frostbrand, Do(UseMeleeSpeed, DamageExact(88)) }, { ItemID.FrostStaff, Do(DamageExact(160), UseExact(37), ShootSpeedExact(20f)) }, // has 1 extra update { ItemID.Gatligator, Do(PointBlank, UseExact(6)) }, { ItemID.GoldenShower, Do(DamageExact(39)) }, - { ItemID.GoldShortsword, Do(AutoReuse, TrueMelee, DamageExact(17)) }, + { ItemID.GoldShortsword, Do(TrueMelee, DamageExact(17)) }, { ItemID.GolemFist, Do(DamageExact(150)) }, - { ItemID.Gradient, Do(AutoReuse, DamageExact(39)) }, - { ItemID.GreenPhaseblade, Do(AutoReuse, UseTurn, DamageExact(32)) }, + { ItemID.Gradient, Do(DamageExact(39)) }, + { ItemID.GreenPhaseblade, Do(UseTurn, DamageExact(32)) }, { ItemID.GreenPhasesaber, Do(DamageExact(60)) }, { ItemID.GrenadeLauncher, Do(DamageExact(112)) }, - { ItemID.Gungnir, Do(AutoReuse, TrueMelee, UseRatio(0.8f), DamageExact(92), ShootSpeedRatio(1.25f)) }, + { ItemID.Gungnir, Do(TrueMelee, UseRatio(0.8f), DamageExact(92), ShootSpeedRatio(1.25f)) }, { ItemID.HallowedRepeater, Do(PointBlank, UseExact(12)) }, { ItemID.Handgun, Do(PointBlank, UseExact(22), DamageExact(36)) }, { ItemID.HellwingBow, Do(PointBlank, DamageExact(16)) }, { ItemID.HighVelocityBullet, Do(DamageExact(13)) }, - { ItemID.HiveFive, Do(AutoReuse, DamageExact(26)) }, - { ItemID.HornetStaff, Do(AutoReuse, DamageExact(18), UseExact(30)) }, + { ItemID.HiveFive, Do(DamageExact(26)) }, + { ItemID.HornetStaff, Do(DamageExact(18), UseExact(30)) }, { ItemID.IceBlade, Do(UseMeleeSpeed) }, { ItemID.IceBoomerang, Do(UseExact(25), ShootSpeedExact(9)) }, { ItemID.IceRod, Do(UseExact(6), DamageExact(30), ShootSpeedExact(20)) }, - { ItemID.IceSickle, Do(AutoReuse, UseMeleeSpeed, DamageExact(75), ShootSpeedExact(20f)) }, + { ItemID.IceSickle, Do(UseMeleeSpeed, DamageExact(75), ShootSpeedExact(20f)) }, { ItemID.IchorArrow, Do(DamageExact(13)) }, { ItemID.IchorBullet, Do(DamageExact(11)) }, - { ItemID.ImpStaff, Do(AutoReuse, UseExact(30), DamageExact(25)) }, + { ItemID.ImpStaff, Do(UseExact(30), DamageExact(25)) }, { ItemID.InfernoFork, Do(DamageExact(99), ShootSpeedExact(11)) }, { ItemID.InfluxWaver, Do(UseMeleeSpeed, DamageExact(80), UseExact(25)) }, - { ItemID.IronShortsword, Do(AutoReuse, TrueMelee, DamageExact(10)) }, + { ItemID.IronShortsword, Do(TrueMelee, DamageExact(10)) }, { ItemID.Keybrand, Do(UseTurn) }, - { ItemID.Kraken, Do(AutoReuse, DamageExact(85)) }, { ItemID.KOCannon, Do(DamageRatio(2.65f)) }, // Uses ratios due to remix seed + { ItemID.Kraken, Do(DamageExact(85)) }, { ItemID.LaserMachinegun, Do(DamageExact(49)) }, { ItemID.LaserRifle, Do(DamageExact(46), UseExact(10), ManaExact(4)) }, { ItemID.LastPrism, Do(DamageExact(57), ManaExact(10)) }, - { ItemID.LeadShortsword, Do(AutoReuse, TrueMelee, DamageExact(11)) }, + { ItemID.LeadShortsword, Do(TrueMelee, DamageExact(11)) }, { ItemID.LightDisc, Do(DamageExact(128), ShootSpeedExact(18)) }, { ItemID.LunarFlareBook, Do(DamageExact(120)) }, { ItemID.MagicalHarp, Do(DamageExact(50), ShootSpeedExact(12f)) }, @@ -159,57 +158,57 @@ internal static void LoadTweaks() { ItemID.MiniNukeI, Do(DamageExact(90)) }, { ItemID.MiniNukeII, Do(DamageExact(90)) }, { ItemID.Minishark, Do(PointBlank, DamageExact(4)) }, - { ItemID.MoltenFury, Do(PointBlank, UseExact(29), AutoReuse) }, + { ItemID.MoltenFury, Do(PointBlank, UseExact(29)) }, { ItemID.MonkStaffT1, Do(TrueMeleeNoSpeed, DamageExact(83)) }, // Sleepy Octopod - { ItemID.MonkStaffT2, Do(AutoReuse, TrueMelee, DamageExact(90)) }, // Ghastly Glaive + { ItemID.MonkStaffT2, Do(TrueMelee, DamageExact(90)) }, // Ghastly Glaive { ItemID.MonkStaffT3, Do(DamageExact(225)) }, // Sky Dragon's Fury { ItemID.MoonlordBullet, Do(DamageExact(19)) }, // Luminite Bullet { ItemID.MoonlordTurretStaff, Do(DamageExact(50), UseExact(15)) }, //Lunar Portal Staff { ItemID.Muramasa, Do(CritDelta(+20)) }, - { ItemID.MushroomSpear, Do(AutoReuse, TrueMelee, UseRatio(0.8f), DamageExact(100)) }, + { ItemID.MushroomSpear, Do(TrueMelee, UseRatio(0.8f), DamageExact(100)) }, { ItemID.Musket, Do(PointBlank, DamageExact(22)) }, - { ItemID.MythrilHalberd, Do(AutoReuse, TrueMelee, UseRatio(0.8f), DamageExact(95), ShootSpeedRatio(1.25f)) }, + { ItemID.MythrilHalberd, Do(TrueMelee, UseRatio(0.8f), DamageExact(95), ShootSpeedRatio(1.25f)) }, { ItemID.MythrilRepeater, Do(PointBlank, UseExact(16)) }, { ItemID.MythrilSword, Do(UseTurn, DamageExact(100)) }, { ItemID.NettleBurst, Do(ManaExact(10), DamageExact(70)) }, { ItemID.NightsEdge, Do(TrueMelee, DamageExact(45)) }, - { ItemID.NorthPole, Do(AutoReuse, UseMeleeSpeed) }, - { ItemID.OrangePhaseblade, Do(AutoReuse, UseTurn, DamageExact(32)) }, + { ItemID.NorthPole, Do(UseMeleeSpeed) }, + { ItemID.OrangePhaseblade, Do(UseTurn, DamageExact(32)) }, { ItemID.OrangePhasesaber, Do(DamageExact(60)) }, - { ItemID.OrichalcumHalberd, Do(AutoReuse, TrueMelee, UseRatio(0.8f), DamageExact(98), ShootSpeedRatio(1.25f)) }, + { ItemID.OrichalcumHalberd, Do(TrueMelee, UseRatio(0.8f), DamageExact(98), ShootSpeedRatio(1.25f)) }, { ItemID.OrichalcumRepeater, Do(PointBlank, DamageExact(48)) }, { ItemID.OrichalcumSword, Do(UseTurn, DamageExact(82)) }, { ItemID.PainterPaintballGun, Do(PointBlank, DamageExact(8)) }, { ItemID.PaladinsHammer, Do(DamageExact(100), ShootSpeedExact(23)) }, - { ItemID.PalladiumPike, Do(AutoReuse, TrueMelee, UseRatio(0.8f), DamageExact(96)) }, + { ItemID.PalladiumPike, Do(TrueMelee, UseRatio(0.8f), DamageExact(96)) }, { ItemID.PalladiumRepeater, Do(PointBlank, DamageExact(45)) }, - { ItemID.PalladiumSword, Do(UseTurn, DamageExact(100)) }, - { ItemID.PearlwoodBow, Do(AutoReuse, PointBlank, DamageExact(20), UseDelta(+8), ShootSpeedDelta(+3.4f), KnockbackDelta(+1f)) }, + { ItemID.PalladiumSword, Do(DamageExact(100)) }, + { ItemID.PearlwoodBow, Do(PointBlank, DamageExact(20), UseDelta(+8), ShootSpeedDelta(+3.4f), KnockbackDelta(+1f)) }, { ItemID.PearlwoodSword, Do(UseTurn, DamageExact(45)) }, { ItemID.PewMaticHorn, Do(DamageExact(25), ShootSpeedExact(15)) }, { ItemID.Phantasm, Do(PointBlank, DamageExact(48)) }, - { ItemID.PhoenixBlaster, Do(AutoReuse, PointBlank, UseExact(18)) }, + { ItemID.PhoenixBlaster, Do(PointBlank, UseExact(18)) }, { ItemID.PiranhaGun, Do(DamageExact(48)) }, { ItemID.PlatinumBow, Do(PointBlank, DamageExact(12)) }, - { ItemID.PlatinumShortsword, Do(AutoReuse, TrueMelee, DamageExact(18)) }, + { ItemID.PlatinumShortsword, Do(TrueMelee, DamageExact(18)) }, { ItemID.PoisonStaff, Do(DamageExact(57)) }, { ItemID.PossessedHatchet, Do(DamageExact(135)) }, { ItemID.PsychoKnife, Do(UseTurn, UseExact(11), DamageExact(255)) }, { ItemID.PurpleClubberfish, Do(UseTurn, KnockbackExact(10f)) }, - { ItemID.PurplePhaseblade, Do(AutoReuse, UseTurn, DamageExact(32)) }, + { ItemID.PurplePhaseblade, Do(UseTurn, DamageExact(32)) }, { ItemID.PurplePhasesaber, Do(DamageExact(60)) }, - { ItemID.PygmyStaff, Do(AutoReuse, UseExact(20), DamageExact(70)) }, + { ItemID.PygmyStaff, Do(UseExact(20), DamageExact(70)) }, { ItemID.QuadBarrelShotgun, Do(PointBlank, DamageExact(11)) }, { ItemID.RainbowRod, Do(DamageExact(35), ManaExact(15)) }, - { ItemID.Rally, Do(AutoReuse, DamageExact(18)) }, + { ItemID.Rally, Do(DamageExact(18)) }, { ItemID.RainbowGun, Do(DamageExact(60), ManaExact(40)) }, - { ItemID.RavenStaff, Do(AutoReuse, UseExact(20), DamageExact(36)) }, + { ItemID.RavenStaff, Do(UseExact(20), DamageExact(36)) }, { ItemID.RazorbladeTyphoon, Do(DamageExact(103)) }, { ItemID.Razorpine, Do(DamageExact(40)) }, - { ItemID.RedPhaseblade, Do(AutoReuse, UseTurn, DamageExact(32)) }, + { ItemID.RedPhaseblade, Do(UseTurn, DamageExact(32)) }, { ItemID.RedPhasesaber, Do(DamageExact(60)) }, { ItemID.RedRyder, Do(PointBlank, DamageExact(24)) }, - { ItemID.RedsYoyo, Do(AutoReuse, DamageExact(48)) }, // Red's Throw and Valkyrie Yoyo have the same stats + { ItemID.RedsYoyo, Do(DamageExact(48)) }, // Red's Throw and Valkyrie Yoyo have the same stats { ItemID.RocketLauncher, Do(DamageExact(70)) }, { ItemID.Sandgun, Do(PointBlank, DamageExact(22), UseExact(20)) }, { ItemID.SapphireStaff, Do(DamageExact(25)) }, @@ -219,67 +218,67 @@ internal static void LoadTweaks() { ItemID.ShadowFlameHexDoll, Do(DamageExact(40), ShootSpeedExact(30)) }, { ItemID.ShadowFlameKnife, Do(DamageExact(70)) }, { ItemID.SharpTears, Do(DamageExact(49)) }, // Blood Thorn - { ItemID.Shotgun, Do(PointBlank, DamageExact(36), AutoReuse) }, + { ItemID.Shotgun, Do(PointBlank, DamageExact(36)) }, { ItemID.Shroomerang, Do(ShootSpeedExact(11)) }, { ItemID.SilverBullet, Do(DamageExact(8)) }, - { ItemID.SilverShortsword, Do(AutoReuse, TrueMelee, DamageExact(14)) }, + { ItemID.SilverShortsword, Do(TrueMelee, DamageExact(14)) }, { ItemID.SkyFracture, Do(DamageExact(54), ShootSpeedExact(30f)) }, { ItemID.SlapHand, Do(UseTurn, DamageExact(120)) }, - { ItemID.Smolstar, Do(DamageExact(9), AutoReuse, UseExact(25)) }, // Blade Staff + { ItemID.Smolstar, Do(DamageExact(9), UseExact(25)) }, // Blade Staff { ItemID.SniperRifle, Do(PointBlank, DamageExact(215)) }, { ItemID.SolarEruption, Do(DamageExact(157)) }, { ItemID.SoulDrain, Do(DamageExact(38)) }, // Life Drain { ItemID.SpaceGun, Do(DamageExact(25)) }, - { ItemID.Spear, Do(AutoReuse, TrueMelee, DamageExact(14)) }, + { ItemID.Spear, Do(TrueMelee, DamageExact(14)) }, { ItemID.SpectreStaff, Do(DamageExact(78)) }, { ItemID.SpiritFlame, Do(UseExact(20), ManaExact(11), ShootSpeedExact(2f)) }, { ItemID.StaffofEarth, Do(DamageExact(150)) }, { ItemID.StarCannon, Do(DamageExact(25)) }, - { ItemID.StardustDragonStaff, Do(AutoReuse, DamageExact(20), UseExact(19)) }, - { ItemID.StormTigerStaff, Do(AutoReuse, DamageExact(49), UseExact(20)) }, // Desert Tiger Staff - { ItemID.StylistKilLaKillScissorsIWish, Do(AutoReuse, UseTurn, DamageExact(18)) }, // Stylish Scissors + { ItemID.StardustDragonStaff, Do(DamageExact(20), UseExact(19)) }, + { ItemID.StormTigerStaff, Do(DamageExact(49), UseExact(20)) }, // Desert Tiger Staff + { ItemID.StylistKilLaKillScissorsIWish, Do(UseTurn, DamageExact(18)) }, // Stylish Scissors { ItemID.Stynger, Do(DamageExact(75)) }, - { ItemID.Swordfish, Do(AutoReuse, TrueMelee, DamageExact(24)) }, + { ItemID.Swordfish, Do(TrueMelee, DamageExact(24)) }, { ItemID.TacticalShotgun, Do(PointBlank, DamageExact(41)) }, - { ItemID.TaxCollectorsStickOfDoom, Do(AutoReuse, UseTurn, UseRatio(0.8f), DamageExact(70)) }, // Classy Cane - { ItemID.TendonBow, Do(PointBlank, DamageExact(17), AutoReuse) }, + { ItemID.TaxCollectorsStickOfDoom, Do(UseTurn, UseRatio(0.8f), DamageExact(70)) }, // Classy Cane + { ItemID.TendonBow, Do(PointBlank, DamageExact(17)) }, { ItemID.TerraBlade, Do(DamageExact(122)) }, // Vanilla damage 190. After fixing iframes so yoyo and shots can hit simultaneously, // Terrarian is extremely overpowered and requires a heavy nerf. - { ItemID.Terrarian, Do(AutoReuse, DamageExact(86)) }, - { ItemID.TheEyeOfCthulhu, Do(AutoReuse, DamageExact(90)) }, - { ItemID.TheRottedFork, Do(AutoReuse, TrueMelee, DamageExact(20)) }, - { ItemID.TheUndertaker, Do(PointBlank, AutoReuse, DamageExact(15)) }, - { ItemID.ThunderSpear, Do(AutoReuse, UseMeleeSpeed) }, // Storm Spear + { ItemID.Terrarian, Do(DamageExact(86)) }, + { ItemID.TheEyeOfCthulhu, Do(DamageExact(90)) }, + { ItemID.TheRottedFork, Do(TrueMelee, DamageExact(20)) }, + { ItemID.TheUndertaker, Do(PointBlank, DamageExact(15)) }, + { ItemID.ThunderSpear, Do(UseMeleeSpeed) }, // Storm Spear { ItemID.ThunderStaff, Do(DamageExact(18)) }, //Thunder Zapper { ItemID.TitaniumRepeater, Do(PointBlank, DamageExact(52)) }, { ItemID.TitaniumSword, Do(UseTurn, DamageExact(77)) }, - { ItemID.TitaniumTrident, Do(AutoReuse, TrueMelee, UseRatio(0.8f), DamageExact(72), ShootSpeedRatio(1.25f)) }, + { ItemID.TitaniumTrident, Do(TrueMelee, UseRatio(0.8f), DamageExact(72), ShootSpeedRatio(1.25f)) }, { ItemID.TopazStaff, Do(ManaExact(2)) }, { ItemID.Toxikarp, Do(UseTimeExact(7), UseAnimationExact(14)) }, - { ItemID.Trident, Do(AutoReuse, TrueMelee, DamageExact(20)) }, + { ItemID.Trident, Do(TrueMelee, DamageExact(20)) }, { ItemID.Trimarang, Do(DamageExact(24)) }, { ItemID.TrueExcalibur, Do(TrueMelee, DamageExact(107)) }, { ItemID.TrueNightsEdge, Do(DamageExact(105)) }, { ItemID.Tsunami, Do(PointBlank, DamageExact(49)) }, { ItemID.TungstenBullet, Do(DamageExact(8)) }, - { ItemID.TungstenShortsword, Do(AutoReuse, TrueMelee, DamageExact(15)) }, + { ItemID.TungstenShortsword, Do(TrueMelee, DamageExact(15)) }, { ItemID.UnholyArrow, Do(DamageExact(11)) }, { ItemID.UnholyTrident, Do(ManaRatio(0.78f), DamageRatio(0.91f)) }, // Uses ratios due to remix seed { ItemID.VampireKnives, Do(DamageExact(38)) }, - { ItemID.ValkyrieYoyo, Do(AutoReuse, DamageExact(48)) }, // Red's Throw and Valkyrie Yoyo have the same stats + { ItemID.ValkyrieYoyo, Do(DamageExact(48)) }, // Red's Throw and Valkyrie Yoyo have the same stats { ItemID.VenomStaff, Do(DamageExact(55)) }, { ItemID.VenusMagnum, Do(PointBlank, DamageExact(65)) }, { ItemID.WaspGun, Do(UseExact(11), DamageExact(58)) }, { ItemID.WaterBolt, Do(DamageExact(23)) }, - { ItemID.WhitePhaseblade, Do(AutoReuse, UseTurn, DamageExact(32)) }, + { ItemID.WhitePhaseblade, Do(UseTurn, DamageExact(32)) }, { ItemID.WhitePhasesaber, Do(DamageExact(60)) }, { ItemID.WoodenBoomerang, Do(DamageExact(16), Value(Item.sellPrice(copper: 20))) }, - { ItemID.Yelets, Do(AutoReuse, DamageExact(53)) }, - { ItemID.YellowPhaseblade, Do(AutoReuse, UseTurn, DamageExact(32)) }, + { ItemID.Yelets, Do(DamageExact(53)) }, + { ItemID.YellowPhaseblade, Do(UseTurn, DamageExact(32)) }, { ItemID.YellowPhasesaber, Do(DamageExact(60)) }, { ItemID.Zenith, Do(DamageExact(210)) }, - { ItemID.ZombieArm, Do(AutoReuse, UseTurn, KnockbackExact(12f)) }, + { ItemID.ZombieArm, Do(UseTurn, KnockbackExact(12f)) }, #endregion #region CATEGORY 2: Defense Balancing @@ -418,12 +417,12 @@ internal static void LoadTweaks() #region CATEGORY 4: True Melee support { ItemID.Arkhalis, trueMeleeNoSpeed }, - { ItemID.CopperShortsword, Do(AutoReuse, TrueMelee) }, - { ItemID.Gladius, Do(AutoReuse, TrueMelee) }, + { ItemID.CopperShortsword, trueMelee }, + { ItemID.Gladius, trueMelee }, { ItemID.HallowJoustingLance, trueMelee }, { ItemID.JoustingLance, trueMelee }, { ItemID.NebulaChainsaw, trueMeleeNoSpeed }, - { ItemID.ObsidianSwordfish, Do(AutoReuse, TrueMelee) }, + { ItemID.ObsidianSwordfish, trueMelee }, { ItemID.PiercingStarlight, trueMelee }, // Starlight { ItemID.Ruler, trueMelee }, { ItemID.ShadowJoustingLance, trueMelee }, @@ -431,7 +430,7 @@ internal static void LoadTweaks() { ItemID.StardustChainsaw, trueMeleeNoSpeed }, { ItemID.Terragrim, trueMeleeNoSpeed }, { ItemID.TheHorsemansBlade, trueMelee }, - { ItemID.TinShortsword, Do(AutoReuse, TrueMelee) }, + { ItemID.TinShortsword, trueMelee }, { ItemID.VortexChainsaw, trueMeleeNoSpeed }, #endregion @@ -455,7 +454,7 @@ internal static void LoadTweaks() { ItemID.OnyxBlaster, pointBlank }, { ItemID.PalmWoodBow, pointBlank }, { ItemID.PulseBow, pointBlank }, - { ItemID.Revolver, Do(PointBlank, AutoReuse) }, + { ItemID.Revolver, pointBlank }, { ItemID.RichMahoganyBow, pointBlank }, { ItemID.SDMG, pointBlank }, { ItemID.ShadewoodBow, pointBlank }, @@ -470,90 +469,53 @@ internal static void LoadTweaks() #endregion #region CATEGORY 6: Summoner Quality of Life - { ItemID.AbigailsFlower, autoReuse }, - { ItemID.BabyBirdStaff, Do(AutoReuse, UseExact(35)) }, // Finch Staff - { ItemID.BlandWhip, autoReuse }, // Leather Whip - { ItemID.BoneWhip, autoReuse }, // Spinal Tap - { ItemID.CoolWhip, autoReuse }, - { ItemID.DD2BallistraTowerT1Popper, autoReuse }, // Ballista Tier 1 - { ItemID.DD2BallistraTowerT2Popper, Do(AutoReuse, UseExact(25)) }, // Ballista Tier 2 - { ItemID.DD2BallistraTowerT3Popper, Do(AutoReuse, UseExact(20)) }, // Ballista Tier 3 - { ItemID.DD2ExplosiveTrapT1Popper, autoReuse }, // Explosive Trap Tier 1 - { ItemID.DD2ExplosiveTrapT2Popper, Do(AutoReuse, UseExact(25)) }, // Explosive Trap Tier 2 - { ItemID.DD2ExplosiveTrapT3Popper, Do(AutoReuse, UseExact(20)) }, // Explosive Trap Tier 3 - { ItemID.DD2FlameburstTowerT1Popper, autoReuse }, // Flameburst Tier 1 - { ItemID.DD2FlameburstTowerT2Popper, Do(AutoReuse, UseExact(25)) }, // Flameburst Tier 2 - { ItemID.DD2FlameburstTowerT3Popper, Do(AutoReuse, UseExact(20)) }, // Flameburst Tier 3 - { ItemID.DD2LightningAuraT1Popper, autoReuse }, // Lightning Aura Tier 1 - { ItemID.DD2LightningAuraT2Popper, Do(AutoReuse, UseExact(25)) }, // Lightning Aura Tier 2 - { ItemID.DD2LightningAuraT3Popper, Do(AutoReuse, UseExact(20)) }, // Lightning Aura Tier 3 - { ItemID.DeadlySphereStaff, Do(AutoReuse, UseExact(20)) }, - { ItemID.FireWhip, autoReuse }, // Firecracker - { ItemID.FlinxStaff, Do(AutoReuse, UseExact(35)) }, - { ItemID.MaceWhip, autoReuse }, // Morning Star - { ItemID.OpticStaff, Do(AutoReuse, UseExact(25)) }, - { ItemID.PirateStaff, Do(AutoReuse, UseExact(25)) }, + { ItemID.BabyBirdStaff, Do(UseExact(35)) }, // Finch Staff + { ItemID.DD2BallistraTowerT2Popper, Do(UseExact(25)) }, // Ballista Tier 2 + { ItemID.DD2BallistraTowerT3Popper, Do(UseExact(20)) }, // Ballista Tier 3 + { ItemID.DD2ExplosiveTrapT2Popper, Do(UseExact(25)) }, // Explosive Trap Tier 2 + { ItemID.DD2ExplosiveTrapT3Popper, Do(UseExact(20)) }, // Explosive Trap Tier 3 + { ItemID.DD2FlameburstTowerT2Popper, Do(UseExact(25)) }, // Flameburst Tier 2 + { ItemID.DD2FlameburstTowerT3Popper, Do(UseExact(20)) }, // Flameburst Tier 3 + { ItemID.DD2LightningAuraT2Popper, Do(UseExact(25)) }, // Lightning Aura Tier 2 + { ItemID.DD2LightningAuraT3Popper, Do(UseExact(20)) }, // Lightning Aura Tier 3 + { ItemID.DeadlySphereStaff, Do(UseExact(20)) }, + { ItemID.FlinxStaff, Do(UseExact(35)) }, + { ItemID.OpticStaff, Do(UseExact(25)) }, + { ItemID.PirateStaff, Do(UseExact(25)) }, { ItemID.QueenSpiderStaff, Do(UseExact(25)) }, { ItemID.RainbowCrystalStaff, Do(UseExact(15)) }, - { ItemID.RainbowWhip, autoReuse }, // Kaleidoscope - { ItemID.SanguineStaff, Do(AutoReuse, UseExact(25)) }, - { ItemID.ScytheWhip, autoReuse }, // Dark Harvest - { ItemID.SlimeStaff, Do(AutoReuse, UseExact(30)) }, - { ItemID.SpiderStaff, Do(AutoReuse, UseExact(25)) }, + { ItemID.SanguineStaff, Do(UseExact(25)) }, + { ItemID.SlimeStaff, Do(UseExact(30)) }, + { ItemID.SpiderStaff, Do(UseExact(25)) }, { ItemID.StaffoftheFrostHydra, Do(UseExact(20)) }, - { ItemID.StardustCellStaff, Do(AutoReuse, UseExact(20)) }, - { ItemID.SwordWhip, autoReuse }, // Durendal - { ItemID.TempestStaff, Do(AutoReuse, UseExact(20)) }, - { ItemID.ThornWhip, autoReuse }, // Snapthorn - { ItemID.VampireFrogStaff, Do(AutoReuse, UseExact(30)) }, - { ItemID.XenoStaff, Do(AutoReuse, UseExact(20)) }, + { ItemID.StardustCellStaff, Do(UseExact(20)) }, + { ItemID.TempestStaff, Do(UseExact(20)) }, + { ItemID.VampireFrogStaff, Do(UseExact(30)) }, + { ItemID.XenoStaff, Do(UseExact(20)) }, #endregion - #region CATEGORY 7: Other Quality of Life (AutoReuse / UseTurn) - { ItemID.Amarok, autoReuse }, - { ItemID.BatBat, autoReuse }, - { ItemID.BladeofGrass, Do(AutoReuse, UseTurn) }, - { ItemID.BloodButcherer, Do(AutoReuse, UseTurn) }, - { ItemID.BoneSword, Do(AutoReuse, UseTurn) }, - { ItemID.BorealWoodSword, Do(AutoReuse, UseTurn) }, - { ItemID.CactusSword, Do(AutoReuse, UseTurn) }, - { ItemID.CandyCaneSword, Do(AutoReuse, UseTurn) }, - { ItemID.Chik, autoReuse }, - { ItemID.Code1, autoReuse }, - { ItemID.CopperBroadsword, Do(AutoReuse, UseTurn) }, - { ItemID.EbonwoodSword, Do(AutoReuse, UseTurn) }, - { ItemID.FieryGreatsword, Do(AutoReuse, UseTurn) }, // Volcano - { ItemID.FormatC, autoReuse }, - { ItemID.GoldBroadsword, Do(AutoReuse, UseTurn) }, - { ItemID.HelFire, autoReuse }, - { ItemID.IronBroadsword, Do(AutoReuse, UseTurn) }, - { ItemID.JungleYoyo, autoReuse }, // Amazon - { ItemID.LifeCrystal, autoReuse }, - { ItemID.LeadBroadsword, Do(AutoReuse, UseTurn) }, - { ItemID.LifeFruit, autoReuse }, - { ItemID.LightsBane, Do(AutoReuse, UseTurn) }, - { ItemID.ManaCrystal, autoReuse }, - { ItemID.PalmWoodSword, Do(AutoReuse, UseTurn) }, - { ItemID.PaperAirplaneA, autoReuse }, - { ItemID.PaperAirplaneB, autoReuse }, // White Paper Airplane - { ItemID.PlatinumBroadsword, Do(AutoReuse, UseTurn) }, - { ItemID.RichMahoganySword, Do(AutoReuse, UseTurn) }, - { ItemID.ShadewoodSword, Do(AutoReuse, UseTurn) }, - { ItemID.SilverBroadsword, Do(AutoReuse, UseTurn) }, - { ItemID.Starfury, autoReuse }, - { ItemID.TentacleSpike, autoReuse }, - { ItemID.TinBroadsword, Do(AutoReuse, UseTurn) }, - { ItemID.TragicUmbrella, autoReuse }, - { ItemID.TungstenBroadsword, Do(AutoReuse, UseTurn) }, - { ItemID.Umbrella, autoReuse }, - { ItemID.Valor, autoReuse }, - { ItemID.WandofFrosting, autoReuse }, - { ItemID.WandofSparking, autoReuse }, - { ItemID.WeatherPain, autoReuse }, - { ItemID.WoodenSword, Do(AutoReuse, UseTurn) }, - { ItemID.WoodYoyo, autoReuse }, - { ItemID.ZapinatorGray, autoReuse }, - { ItemID.ZapinatorOrange, autoReuse }, + #region CATEGORY 7: UseTurn + { ItemID.BladeofGrass, Do(UseTurn) }, + { ItemID.BloodButcherer, Do(UseTurn) }, + { ItemID.BoneSword, Do(UseTurn) }, + { ItemID.BorealWoodSword, Do(UseTurn) }, + { ItemID.CactusSword, Do(UseTurn) }, + { ItemID.CandyCaneSword, Do(UseTurn) }, + { ItemID.CopperBroadsword, Do(UseTurn) }, + { ItemID.EbonwoodSword, Do(UseTurn) }, + { ItemID.FieryGreatsword, Do(UseTurn) }, // Volcano + { ItemID.GoldBroadsword, Do(UseTurn) }, + { ItemID.IronBroadsword, Do(UseTurn) }, + { ItemID.LeadBroadsword, Do(UseTurn) }, + { ItemID.LightsBane, Do(UseTurn) }, + { ItemID.PalmWoodSword, Do(UseTurn) }, + { ItemID.PlatinumBroadsword, Do(UseTurn) }, + { ItemID.RichMahoganySword, Do(UseTurn) }, + { ItemID.ShadewoodSword, Do(UseTurn) }, + { ItemID.SilverBroadsword, Do(UseTurn) }, + { ItemID.TinBroadsword, Do(UseTurn) }, + { ItemID.TungstenBroadsword, Do(UseTurn) }, + { ItemID.WoodenSword, Do(UseTurn) }, #endregion #region CATEGORY 8: Non-consumable Quality of Life @@ -690,19 +652,6 @@ public void ApplyTweak(Item it) internal static IItemTweak AttackSpeedRatio(float f) => new AttackSpeedRatioRule(f); #endregion - #region Auto Reuse - internal class AutoReuseRule : IItemTweak - { - internal readonly bool flag = true; - - public AutoReuseRule(bool ar) => flag = ar; - public bool AppliesTo(Item it) => IsUsable(it); - public void ApplyTweak(Item it) => it.autoReuse = flag; - } - internal static IItemTweak AutoReuse => new AutoReuseRule(true); - internal static IItemTweak NoAutoReuse => new AutoReuseRule(false); - #endregion - #region Axe Power // Uses the values shown by Terraria, which are multiplied by 5, not the internal values internal class AxePowerRule : IItemTweak From faf3d7caf4eab8c17fe3c352c3a49f07f43b0e49 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 22 Nov 2025 12:14:59 -0500 Subject: [PATCH 365/401] Shredder is also missing ammo saving tooltip --- Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson | 1 + 1 file changed, 1 insertion(+) diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson index 9fd35e7033..9dd012fb50 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson @@ -1095,6 +1095,7 @@ Shredder: { ''' Fires a barrage of energy bolts that split and bounce Press to fire a barrage of normal bullets instead + 60% chance to save ammo 'The myth, the legend, the weapon that drops more frames than any other' ''' } From 8b93e4977e6642d9f5ded549e4b1eee5715c5b3d Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 22 Nov 2025 16:08:16 -0500 Subject: [PATCH 366/401] Split client and server configs --- Buffs/Potions/ShadowBuff.cs | 2 +- Buffs/StatBuffs/BossEffects.cs | 2 +- CalPlayer/CalamityPlayer.cs | 16 +- CalPlayer/CalamityPlayerDashEffects.cs | 2 +- CalPlayer/CalamityPlayerDrawEffects.cs | 2 +- CalPlayer/CalamityPlayerMiscEffects.cs | 10 +- CalamityConditions.cs | 2 +- CalamityConfig.cs | 151 +++++---- CalamityMod.cs | 2 +- Cooldowns/ChaosState.cs | 2 +- Cooldowns/PotionSickness.cs | 2 +- ILEditing/BalancingILChanges.cs | 2 +- ILEditing/MechanicILChanges.cs | 4 +- ILEditing/VanillaStupidityFixingILChanges.cs | 6 +- ILEditing/WorldgenILChanges.cs | 2 +- Items/CalamityGlobalItem.cs | 2 +- Items/CalamityGlobalItemTooltip.cs | 2 +- Items/Placeables/CelestialRemains.cs | 8 +- Items/Placeables/NovaeSlag.cs | 8 +- .../en-US/Mods.CalamityMod.Configs.hjson | 303 +++++++++--------- ModSupport/ModCalls.cs | 2 +- NPCs/AquaticScourge/AquaticScourgeBody.cs | 2 +- NPCs/AquaticScourge/AquaticScourgeBodyAlt.cs | 2 +- NPCs/AquaticScourge/AquaticScourgeHead.cs | 2 +- NPCs/AquaticScourge/AquaticScourgeTail.cs | 2 +- NPCs/AstrumAureus/AstrumAureus.cs | 6 +- NPCs/AstrumAureus/AureusSpawn.cs | 6 +- NPCs/AstrumDeus/AstrumDeusBody.cs | 2 +- NPCs/AstrumDeus/AstrumDeusHead.cs | 2 +- NPCs/AstrumDeus/AstrumDeusTail.cs | 2 +- NPCs/BrimstoneElemental/Brimling.cs | 2 +- NPCs/BrimstoneElemental/BrimstoneElemental.cs | 2 +- NPCs/Bumblebirb/Bumblefuck.cs | 8 +- NPCs/Bumblebirb/Bumblefuck2.cs | 4 +- NPCs/CalClone/CalamitasClone.cs | 6 +- NPCs/CalClone/Cataclysm.cs | 6 +- NPCs/CalClone/Catastrophe.cs | 6 +- NPCs/CalClone/SoulSeeker.cs | 6 +- .../CalamityBossAIs/CeaselessVoidAI.cs | 2 +- NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs | 2 +- NPCs/CalamityGlobalNPC.cs | 22 +- NPCs/CalamityGlobalNPCLoot.cs | 8 +- NPCs/CalamityGlobalTownNPC.cs | 2 +- NPCs/CeaselessVoid/CeaselessVoid.cs | 6 +- NPCs/CeaselessVoid/DarkEnergy.cs | 6 +- NPCs/Crabulon/CrabShroom.cs | 2 +- NPCs/Crabulon/Crabulon.cs | 2 +- NPCs/Crags/SoulSlurper.cs | 4 +- NPCs/Cryogen/Cryogen.cs | 4 +- NPCs/Cryogen/CryogenShield.cs | 2 +- NPCs/DesertScourge/DesertNuisanceBody.cs | 2 +- NPCs/DesertScourge/DesertNuisanceBodyYoung.cs | 2 +- NPCs/DesertScourge/DesertNuisanceHead.cs | 2 +- NPCs/DesertScourge/DesertNuisanceHeadYoung.cs | 2 +- NPCs/DesertScourge/DesertNuisanceTail.cs | 2 +- NPCs/DesertScourge/DesertNuisanceTailYoung.cs | 2 +- NPCs/DesertScourge/DesertScourgeBody.cs | 2 +- NPCs/DesertScourge/DesertScourgeHead.cs | 2 +- NPCs/DesertScourge/DesertScourgeTail.cs | 2 +- NPCs/DevourerofGods/CosmicGuardianBody.cs | 2 +- NPCs/DevourerofGods/CosmicGuardianHead.cs | 2 +- NPCs/DevourerofGods/CosmicGuardianTail.cs | 2 +- NPCs/DevourerofGods/DevourerofGodsBody.cs | 2 +- NPCs/DevourerofGods/DevourerofGodsHead.cs | 4 +- NPCs/DevourerofGods/DevourerofGodsTail.cs | 2 +- NPCs/ExoMechs/Apollo/Apollo.cs | 6 +- NPCs/ExoMechs/Ares/AresBody.cs | 6 +- NPCs/ExoMechs/Ares/AresGaussNuke.cs | 6 +- NPCs/ExoMechs/Ares/AresLaserCannon.cs | 6 +- NPCs/ExoMechs/Ares/AresPlasmaFlamethrower.cs | 6 +- NPCs/ExoMechs/Ares/AresTeslaCannon.cs | 6 +- NPCs/ExoMechs/Artemis/Artemis.cs | 6 +- NPCs/ExoMechs/Thanatos/ThanatosBody1.cs | 2 +- NPCs/ExoMechs/Thanatos/ThanatosBody2.cs | 2 +- NPCs/ExoMechs/Thanatos/ThanatosHead.cs | 2 +- NPCs/ExoMechs/Thanatos/ThanatosTail.cs | 2 +- NPCs/GreatSandShark/GreatSandShark.cs | 2 +- NPCs/HiveMind/DankCreeper.cs | 2 +- NPCs/HiveMind/DarkHeart.cs | 2 +- NPCs/HiveMind/HiveBlob.cs | 2 +- NPCs/HiveMind/HiveBlob2.cs | 2 +- NPCs/HiveMind/HiveMind.cs | 4 +- NPCs/Leviathan/Anahita.cs | 2 +- NPCs/Leviathan/AnahitasIceShield.cs | 2 +- NPCs/Leviathan/AquaticAberration.cs | 2 +- NPCs/Leviathan/Leviathan.cs | 2 +- NPCs/NormalNPCs/BloodlettingServant.cs | 4 +- NPCs/NormalNPCs/IceClasper.cs | 2 +- NPCs/NormalNPCs/KingSlimeJewelEmerald.cs | 2 +- NPCs/NormalNPCs/KingSlimeJewelRuby.cs | 2 +- NPCs/NormalNPCs/KingSlimeJewelSapphire.cs | 2 +- NPCs/NormalNPCs/PlanterasFreeTentacle.cs | 2 +- NPCs/NormalNPCs/SkeletronPrime2.cs | 8 +- NPCs/NormalNPCs/WildBumblefuck.cs | 2 +- NPCs/OldDuke/OldDuke.cs | 8 +- NPCs/OldDuke/OldDukeToothBall.cs | 2 +- NPCs/OldDuke/SulphurousSharkron.cs | 4 +- NPCs/Perforator/PerforatorBodyLarge.cs | 2 +- NPCs/Perforator/PerforatorBodyMedium.cs | 2 +- NPCs/Perforator/PerforatorBodySmall.cs | 2 +- NPCs/Perforator/PerforatorHeadLarge.cs | 2 +- NPCs/Perforator/PerforatorHeadMedium.cs | 2 +- NPCs/Perforator/PerforatorHeadSmall.cs | 2 +- NPCs/Perforator/PerforatorHive.cs | 2 +- NPCs/Perforator/PerforatorTailLarge.cs | 2 +- NPCs/Perforator/PerforatorTailMedium.cs | 2 +- NPCs/Perforator/PerforatorTailSmall.cs | 2 +- NPCs/PlagueEnemies/PlagueCharger.cs | 4 +- NPCs/PlagueEnemies/PlagueChargerLarge.cs | 4 +- NPCs/PlagueEnemies/PlaguebringerMiniboss.cs | 2 +- .../PlagueHomingMissile.cs | 6 +- NPCs/PlaguebringerGoliath/PlagueMine.cs | 2 +- .../PlaguebringerGoliath.cs | 6 +- NPCs/Polterghast/PhantomFuckYou.cs | 4 +- NPCs/Polterghast/PolterPhantom.cs | 6 +- NPCs/Polterghast/Polterghast.cs | 8 +- NPCs/Polterghast/PolterghastHook.cs | 4 +- NPCs/PrimordialWyrm/PrimordialWyrmBody.cs | 2 +- NPCs/PrimordialWyrm/PrimordialWyrmBodyAlt.cs | 2 +- NPCs/PrimordialWyrm/PrimordialWyrmHead.cs | 2 +- NPCs/PrimordialWyrm/PrimordialWyrmTail.cs | 2 +- .../ProfanedGuardianCommander.cs | 6 +- .../ProfanedGuardianDefender.cs | 6 +- .../ProfanedGuardianHealer.cs | 6 +- NPCs/ProfanedGuardians/ProfanedRocks.cs | 2 +- NPCs/Providence/ProvSpawnDefense.cs | 6 +- NPCs/Providence/ProvSpawnHealer.cs | 6 +- NPCs/Providence/ProvSpawnOffense.cs | 6 +- NPCs/Providence/Providence.cs | 8 +- NPCs/Ravager/FlamePillar.cs | 2 +- NPCs/Ravager/RavagerBody.cs | 2 +- NPCs/Ravager/RavagerClawLeft.cs | 2 +- NPCs/Ravager/RavagerClawRight.cs | 2 +- NPCs/Ravager/RavagerHead.cs | 2 +- NPCs/Ravager/RavagerHead2.cs | 2 +- NPCs/Ravager/RavagerLegLeft.cs | 2 +- NPCs/Ravager/RavagerLegRight.cs | 2 +- NPCs/Ravager/RockPillar.cs | 2 +- NPCs/Signus/CosmicLantern.cs | 6 +- NPCs/Signus/CosmicMine.cs | 4 +- NPCs/Signus/Signus.cs | 6 +- NPCs/SlimeGod/CorruptSlimeSpawn.cs | 2 +- NPCs/SlimeGod/CorruptSlimeSpawn2.cs | 2 +- NPCs/SlimeGod/CrimsonSlimeSpawn.cs | 2 +- NPCs/SlimeGod/CrimsonSlimeSpawn2.cs | 2 +- NPCs/SlimeGod/CrimulanPaladin.cs | 2 +- NPCs/SlimeGod/EbonianPaladin.cs | 2 +- NPCs/SlimeGod/SlimeGodCore.cs | 4 +- NPCs/SlimeGod/SplitCrimulanPaladin.cs | 2 +- NPCs/SlimeGod/SplitEbonianPaladin.cs | 2 +- NPCs/StormWeaver/StormWeaverBody.cs | 2 +- NPCs/StormWeaver/StormWeaverHead.cs | 4 +- NPCs/StormWeaver/StormWeaverTail.cs | 2 +- NPCs/SupremeCalamitas/BrimstoneHeart.cs | 2 +- NPCs/SupremeCalamitas/SepulcherArm.cs | 2 +- NPCs/SupremeCalamitas/SepulcherBody.cs | 2 +- .../SepulcherBodyEnergyBall.cs | 2 +- NPCs/SupremeCalamitas/SepulcherHead.cs | 2 +- NPCs/SupremeCalamitas/SepulcherTail.cs | 2 +- NPCs/SupremeCalamitas/SoulSeekerSupreme.cs | 6 +- NPCs/SupremeCalamitas/SupremeCalamitas.cs | 6 +- NPCs/SupremeCalamitas/SupremeCataclysm.cs | 6 +- NPCs/SupremeCalamitas/SupremeCatastrophe.cs | 6 +- .../Bosses/DestroyerAI.cs | 10 +- .../Bosses/SkeletronPrimeAI.cs | 18 +- NPCs/VanillaNPCAIOverrides/Bosses/TwinsAI.cs | 34 +- NPCs/Yharon/Yharon.cs | 10 +- Particles/GeneralParticleHandler.cs | 4 +- Projectiles/Boss/HolySpear.cs | 2 +- Projectiles/Boss/YharonFireball.cs | 2 +- .../Enemy/IceClasperEnemyProjectile.cs | 2 +- .../Melee/ArkOfTheAncients_SwungBlade.cs | 2 +- .../Melee/ArkOfTheCosmos_SwungBlade.cs | 4 +- .../Melee/ArkOfTheElements_SwungBlade.cs | 4 +- Projectiles/Melee/Galaxia_PhoenixsPride.cs | 2 +- Projectiles/Melee/GayBeam.cs | 2 +- .../Melee/MendedBiomeBlade_HeavensMight.cs | 2 +- .../Melee/TrueArkOfTheAncients_SwungBlade.cs | 2 +- .../Melee/TrueBiomeBlade_SwordsmithsPride.cs | 2 +- Projectiles/Ranged/BuzzkillHoldout.cs | 2 +- Projectiles/Ranged/BuzzkillSaw.cs | 2 +- Projectiles/Ranged/MineralMortarProjectile.cs | 2 +- Projectiles/Ranged/SuperradiantSaw.cs | 2 +- .../Ranged/SuperradiantSawLingering.cs | 2 +- .../Ranged/SuperradiantSlaughtererHoldout.cs | 2 +- Projectiles/Rogue/WrathwingFireball.cs | 2 +- Projectiles/Summon/IceClasperMinion.cs | 2 +- Projectiles/Summon/MiniGuardianRock.cs | 2 +- .../HopeShredderArrow.cs | 2 +- .../MirrorofKalandraMinions/Paradoxica.cs | 2 +- .../MirrorofKalandraMinions/Starforge.cs | 2 +- .../WindRipperArrow.cs | 2 +- Projectiles/Summon/MutatedTruffleMinion.cs | 2 +- Projectiles/Summon/PhantomicDagger.cs | 2 +- Projectiles/Summon/PlantationStaffSeed.cs | 2 +- Projectiles/Summon/PlantationStaffSummon.cs | 2 +- Projectiles/Summon/PlantationStaffTentacle.cs | 2 +- .../Summon/ProfanedSoulCrystalProjectiles.cs | 2 +- Projectiles/Summon/Umbrella/MagicHat.cs | 2 +- Projectiles/Summon/YharonMinionFireball.cs | 2 +- Systems/MusicEventSystem.cs | 8 +- Systems/NerfExpertDebuffsSystem.cs | 2 +- Systems/WorldMiscUpdateSystem.cs | 4 +- Systems/WorldgenManagementSystem.cs | 2 +- Tiles/CalamityGlobalTile.cs | 2 +- UI/CooldownRackUI.cs | 4 +- UI/DraedonsArsenal/ChargeMeterUI.cs | 24 +- UI/FlightBar/FlightBar.cs | 24 +- UI/Rippers/RipperUI.cs | 46 +-- UI/SpeedrunTimerUI.cs | 4 +- UI/StealthUI.cs | 24 +- .../SulphurousWaterMeterUI.cs | 22 +- Utilities/DrawingUtils.cs | 4 +- Utilities/DropHelper.cs | 2 +- 214 files changed, 684 insertions(+), 652 deletions(-) diff --git a/Buffs/Potions/ShadowBuff.cs b/Buffs/Potions/ShadowBuff.cs index 72ee6c1d8b..0244cb7c0b 100644 --- a/Buffs/Potions/ShadowBuff.cs +++ b/Buffs/Potions/ShadowBuff.cs @@ -15,7 +15,7 @@ public override void SetStaticDefaults() public override void Update(Player player, ref int buffIndex) { player.Calamity().shadow = true; - if (player.yoraiz0rEye < 2 && CalamityConfig.Instance.StealthInvisibility) + if (player.yoraiz0rEye < 2 && CalamityClientConfig.Instance.StealthInvisibility) player.yoraiz0rEye = 2; } } diff --git a/Buffs/StatBuffs/BossEffects.cs b/Buffs/StatBuffs/BossEffects.cs index 46022d0e27..e32088eaa6 100644 --- a/Buffs/StatBuffs/BossEffects.cs +++ b/Buffs/StatBuffs/BossEffects.cs @@ -24,7 +24,7 @@ public override void Update(Player player, ref int buffIndex) public override void ModifyBuffText(ref string buffName, ref string tip, ref int rare) { - if (CalamityConfig.Instance.BossZen) + if (CalamityServerConfig.Instance.BossZen) tip = tip.Replace(":", ":\n" + this.GetLocalizedValue("ZenDescription")); } } diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 7bb3cc576f..606e26bebd 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -2241,13 +2241,13 @@ public override void ModifyMaxStats(out StatModifier health, out StatModifier ma #region Screen Position Movements public override void ModifyScreenPosition() { - if (CalamityConfig.Instance.ScreenshakePower == 0) + if (CalamityClientConfig.Instance.ScreenshakePower == 0) return; if (GeneralScreenShakePower > 0f) { - Main.screenPosition += Main.rand.NextVector2Circular(GeneralScreenShakePower * CalamityConfig.Instance.ScreenshakePower, GeneralScreenShakePower * CalamityConfig.Instance.ScreenshakePower); - GeneralScreenShakePower = MathHelper.Clamp(GeneralScreenShakePower - 0.185f, 0f, 20f * CalamityConfig.Instance.ScreenshakePower); + Main.screenPosition += Main.rand.NextVector2Circular(GeneralScreenShakePower * CalamityClientConfig.Instance.ScreenshakePower, GeneralScreenShakePower * CalamityClientConfig.Instance.ScreenshakePower); + GeneralScreenShakePower = MathHelper.Clamp(GeneralScreenShakePower - 0.185f, 0f, 20f * CalamityClientConfig.Instance.ScreenshakePower); } } #endregion @@ -2670,7 +2670,7 @@ public override void UpdateDead() // Respawn the player faster // 3 seconds normally and configurable while a boss is alive between 15 and 60 seconds - int respawnTimerSet = areThereAnyDamnBosses ? (CalamityConfig.Instance.PlayerRespawnTime_BossAlive * 60) : 180; + int respawnTimerSet = areThereAnyDamnBosses ? (CalamityServerConfig.Instance.PlayerRespawnTime_BossAlive * 60) : 180; if (Player.respawnTimer > respawnTimerSet) Player.respawnTimer = respawnTimerSet; } @@ -3342,14 +3342,14 @@ public static void ModTeleport(Player player, Vector2 pos, bool playSound = true public override void UpdateEquips() { // TODO -- why is boss health bar code in Player.UpdateEquips and not a ModSystem - CalamityConfig.Instance.BossHealthBarExtraInfo = shouldDrawSmallText; + CalamityClientConfig.Instance.BossHealthBarExtraInfo = shouldDrawSmallText; // Putting this in GlobalItem will run multiple times for each slot, which this system already does, creating a slew of problems. VanillaArmorChangeManager.ApplyPotentialEffectsTo(Player); // If the config is enabled, vastly increase the player's base tile and wall placement speeds // This stacks with the Brick Layer and Portable Cement Mixer - if (CalamityConfig.Instance.FasterTilePlacement) + if (CalamityServerConfig.Instance.FasterTilePlacement) { Player.tileSpeed += 0.5f; Player.wallSpeed += 0.5f; @@ -4863,11 +4863,11 @@ public override void OnEnterWorld() // 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 (CalamityConfig.Instance.SpeedrunTimer) + if (CalamityClientConfig.Instance.SpeedrunTimer) CalamityMod.SpeedrunTimer.Restart(); // Set a random delay between 12 and 20 seconds. When this delay hits zero, startup messages display - if (CalamityConfig.Instance.WikiStatusMessage) + if (CalamityClientConfig.Instance.WikiStatusMessage) { startMessageDisplayDelay = Main.rand.Next(CalamityUtils.SecondsToFrames(12), CalamityUtils.SecondsToFrames(20) + 1); } diff --git a/CalPlayer/CalamityPlayerDashEffects.cs b/CalPlayer/CalamityPlayerDashEffects.cs index aaa5820ffb..7b016109cc 100644 --- a/CalPlayer/CalamityPlayerDashEffects.cs +++ b/CalPlayer/CalamityPlayerDashEffects.cs @@ -21,7 +21,7 @@ public string DashID { get { - return (String.IsNullOrEmpty(dashID) && Player.dashType == 0 && CalamityConfig.Instance.DefaultDashEnabled) ? DefaultDash.ID : dashID; //gives default dash ONLY if no custom or vanilla dash. + return (String.IsNullOrEmpty(dashID) && Player.dashType == 0 && CalamityServerConfig.Instance.DefaultDashEnabled) ? DefaultDash.ID : dashID; //gives default dash ONLY if no custom or vanilla dash. } set => dashID = value; } diff --git a/CalPlayer/CalamityPlayerDrawEffects.cs b/CalPlayer/CalamityPlayerDrawEffects.cs index 971b68da98..8b1c118372 100644 --- a/CalPlayer/CalamityPlayerDrawEffects.cs +++ b/CalPlayer/CalamityPlayerDrawEffects.cs @@ -110,7 +110,7 @@ public override void DrawEffects(PlayerDrawSet drawInfo, ref float r, ref float } // TODO -- rogue stealth visuals are an utter catastrophe and should be fully destroyed on next stealth rework - if (calamityPlayer.rogueStealth > 0f && calamityPlayer.rogueStealthMax > 0f && Player.townNPCs < 3f && CalamityConfig.Instance.StealthInvisibility) + if (calamityPlayer.rogueStealth > 0f && calamityPlayer.rogueStealthMax > 0f && Player.townNPCs < 3f && CalamityClientConfig.Instance.StealthInvisibility) { // A translucent orchid color, the rogue class color float colorValue = calamityPlayer.rogueStealth / calamityPlayer.rogueStealthMax * 0.9f; //0 to 0.9 diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index 63303870dd..98b0319d1b 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -83,7 +83,7 @@ public override void PostUpdateMiscEffects() // Give the player a 24% jump speed boost while wings are equipped, otherwise grant 4% more jump speed so that players can jump 7 tiles high if (Player.wingsLogic > 0) Player.jumpSpeedBoost += 1.2f; - else if (CalamityConfig.Instance.FasterJumpSpeed) + else if (CalamityServerConfig.Instance.FasterJumpSpeed) Player.jumpSpeedBoost += 0.2f; // Decrease the counter on Fearmonger set turbo regeneration @@ -983,7 +983,7 @@ private void MiscEffects() { Player.buffImmune[ModContent.BuffType()] = true; } - if (CalamityConfig.Instance.ChilledWaterRework) + if (CalamityServerConfig.Instance.ChilledWaterRework) { if (Main.expertMode && Player.ZoneSnow && Player.wet && !Player.lavaWet && !Player.honeyWet) { @@ -1098,7 +1098,7 @@ private void MiscEffects() Player.noFallDmg = true; } - if (CalamityConfig.Instance.FasterFallHotkey) + if (CalamityClientConfig.Instance.FasterFallHotkey) { // Allow the player to double their gravity (but NOT max fall speed!) by holding the down button while in midair. bool holdingDown = Player.controlDown && !Player.controlJump; @@ -2712,7 +2712,7 @@ private void OtherBuffEffects() // 50% movement speed bonus so that you don't feel like a snail in the early game // Disabled while Overhaul is enabled, because Overhaul does very similar things to make movement more snappy - if (CalamityMod.Instance.overhaul is null && CalamityConfig.Instance.FasterBaseSpeed) + if (CalamityMod.Instance.overhaul is null && CalamityServerConfig.Instance.FasterBaseSpeed) Player.moveSpeed += BalancingConstants.DefaultMoveSpeedBoost; // Reduce how slow Chilled makes the player, because it's cancerous right now @@ -4146,7 +4146,7 @@ private void HandleTextChatMessages() { if (startMessageDisplayDelay == 0) { - if (CalamityConfig.Instance.WikiStatusMessage) + if (CalamityClientConfig.Instance.WikiStatusMessage) { CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.WikiStatus1"); CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.WikiStatus2"); diff --git a/CalamityConditions.cs b/CalamityConditions.cs index f6b9acdd2d..603526c907 100644 --- a/CalamityConditions.cs +++ b/CalamityConditions.cs @@ -19,7 +19,7 @@ private static Condition Create(string key, Func predicate) // Config based conditions // - public static readonly Condition PotionSellingConfig = Create("PotionConfig", () => CalamityConfig.Instance.PotionSelling); + public static readonly Condition PotionSellingConfig = Create("PotionConfig", () => CalamityServerConfig.Instance.PotionSelling); // // Player conditions diff --git a/CalamityConfig.cs b/CalamityConfig.cs index 2a46a809b2..49cc222959 100644 --- a/CalamityConfig.cs +++ b/CalamityConfig.cs @@ -5,25 +5,21 @@ using CalamityMod.UI.Rippers; using CalamityMod.UI.SulphurousWaterMeter; using Terraria; +using Terraria.Localization; using Terraria.ModLoader.Config; namespace CalamityMod { [BackgroundColor(49, 32, 36, 216)] - public class CalamityConfig : ModConfig + public class CalamityClientConfig : ModConfig { - public static CalamityConfig Instance; - - // TODO -- Not all Calamity config settings should be considered client side. - // There are many configs which are server side and should stay that way. + public static CalamityClientConfig Instance; public override ConfigScope Mode => ConfigScope.ClientSide; - public override bool AcceptClientChanges(ModConfig pendingConfig, int whoAmI, ref string message) => true; // Clamps values that would cause ugly problems if loaded directly without sanitization. [OnDeserialized] internal void ClampValues(StreamingContext context) { - BossHealthBoost = Utils.Clamp(BossHealthBoost, MinBossHealthBoost, MaxBossHealthBoost); RipperMeterShake = Utils.Clamp(RipperMeterShake, MinMeterShake, MaxMeterShake); ParticleLimit = (int)Utils.Clamp(ParticleLimit, MinParticleLimit, MaxParticleLimit); } @@ -48,10 +44,6 @@ internal void ClampValues(StreamingContext context) [DefaultValue(5000)] public int ParticleLimit { get; set; } - [BackgroundColor(192, 54, 64, 192)] - [DefaultValue(false)] - public bool BossesStopWeather { get; set; } - [BackgroundColor(192, 54, 64, 192)] [SliderColor(224, 165, 56, 128)] [Range(0f, 10f)] @@ -102,6 +94,33 @@ internal void ClampValues(StreamingContext context) [DefaultValue(true)] public bool StealthMeter { get; set; } + [BackgroundColor(192, 54, 64, 192)] + [DefaultValue(true)] + public bool ChargeMeter { get; set; } + + private const float MinMeterShake = 0f; + private const float MaxMeterShake = 4f; + + [BackgroundColor(192, 54, 64, 192)] + [SliderColor(224, 165, 56, 128)] + [Range(MinMeterShake, MaxMeterShake)] + [Increment(1f)] + [DrawTicks] + [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; } + #endregion + + #region Meter Positions + [Header("MeterPositions")] + [BackgroundColor(192, 54, 64, 192)] [SliderColor(224, 165, 56, 128)] [Range(0f, 100f)] @@ -126,10 +145,6 @@ internal void ClampValues(StreamingContext context) [DefaultValue(SulphurousWaterMeterUI.DefaultPosY)] public float SulphuricWaterMeterPosY { get; set; } - [BackgroundColor(192, 54, 64, 192)] - [DefaultValue(true)] - public bool ChargeMeter { get; set; } - [BackgroundColor(192, 54, 64, 192)] [SliderColor(224, 165, 56, 128)] [Range(0f, 100f)] @@ -143,8 +158,28 @@ internal void ClampValues(StreamingContext context) public float ChargeMeterPosY { get; set; } [BackgroundColor(192, 54, 64, 192)] - [DefaultValue(false)] - public bool SpeedrunTimer { get; set; } + [SliderColor(224, 165, 56, 128)] + [Range(0f, 100f)] + [DefaultValue(RipperUI.DefaultRagePosX)] + public float RageMeterPosX { get; set; } + + [BackgroundColor(192, 54, 64, 192)] + [SliderColor(224, 165, 56, 128)] + [Range(0f, 100f)] + [DefaultValue(RipperUI.DefaultRagePosY)] + public float RageMeterPosY { get; set; } + + [BackgroundColor(192, 54, 64, 192)] + [SliderColor(224, 165, 56, 128)] + [Range(0f, 100f)] + [DefaultValue(RipperUI.DefaultAdrenPosX)] + public float AdrenalineMeterPosX { get; set; } + + [BackgroundColor(192, 54, 64, 192)] + [SliderColor(224, 165, 56, 128)] + [Range(0f, 100f)] + [DefaultValue(RipperUI.DefaultAdrenPosY)] + public float AdrenalineMeterPosY { get; set; } [BackgroundColor(192, 54, 64, 192)] [SliderColor(224, 165, 56, 128)] @@ -158,10 +193,6 @@ internal void ClampValues(StreamingContext context) [DefaultValue(SpeedrunTimerUI.DefaultTimerPosY)] public float SpeedrunTimerPosY { get; set; } - [BackgroundColor(192, 54, 64, 192)] - [DefaultValue(true)] - public bool FlightBar { get; set; } - [BackgroundColor(192, 54, 64, 192)] [SliderColor(224, 165, 56, 128)] [Range(0f, 100f)] @@ -202,6 +233,35 @@ internal void ClampValues(StreamingContext context) [BackgroundColor(192, 54, 64, 192)] [DefaultValue(true)] public bool FasterFallHotkey { get; set; } + #endregion + } + + [BackgroundColor(49, 32, 36, 216)] + public class CalamityServerConfig : ModConfig + { + public static CalamityServerConfig Instance; + public override ConfigScope Mode => ConfigScope.ServerSide; + public override bool AcceptClientChanges(ModConfig pendingConfig, int whoAmI, ref NetworkText message) + { + if (whoAmI == 0) + return true; + if (whoAmI != 0) + { + message = CalamityUtils.GetText("Configs.CalamityServerConfig.Denied").ToNetworkText(); + return false; + } + return false; + } + + // Clamp values that would cause ugly problems if loaded directly without sanitization. + [OnDeserialized] + internal void ClampValues(StreamingContext context) + { + BossHealthBoost = Utils.Clamp(BossHealthBoost, MinBossHealthBoost, MaxBossHealthBoost); + } + + #region General Gameplay Changes + [Header("Gameplay")] [BackgroundColor(192, 54, 64, 192)] [DefaultValue(true)] @@ -253,11 +313,14 @@ internal void ClampValues(StreamingContext context) [DrawTicks] [DefaultValue(MinBossHealthBoost)] public float BossHealthBoost { get; set; } + + [BackgroundColor(192, 54, 64, 192)] + [DefaultValue(false)] + public bool BossesStopWeather { get; set; } #endregion - #region Default Player Stat Boosts [Header("BaseBoosts")] - + #region Default Player Stat Boosts [BackgroundColor(192, 54, 64, 192)] [DefaultValue(true)] public bool DefaultDashEnabled { get; set; } @@ -279,9 +342,8 @@ internal void ClampValues(StreamingContext context) public bool FasterTilePlacement { get; set; } #endregion - #region Expert and Master Mode Changes [Header("ExpertMaster")] - + #region Expert and Master Mode Changes [BackgroundColor(192, 54, 64, 192)] [DefaultValue(true)] public bool NerfExpertDebuffs { get; set; } @@ -298,44 +360,5 @@ internal void ClampValues(StreamingContext context) [DefaultValue(false)] public bool ForceTownSafety { get; set; } #endregion - - #region Revengeance Mode Changes - [Header("Revengeance")] - - private const float MinMeterShake = 0f; - private const float MaxMeterShake = 4f; - - [BackgroundColor(192, 54, 64, 192)] - [SliderColor(224, 165, 56, 128)] - [Range(MinMeterShake, MaxMeterShake)] - [Increment(1f)] - [DrawTicks] - [DefaultValue(2f)] - public float RipperMeterShake { get; set; } - - [BackgroundColor(192, 54, 64, 192)] - [SliderColor(224, 165, 56, 128)] - [Range(0f, 100f)] - [DefaultValue(RipperUI.DefaultRagePosX)] - public float RageMeterPosX { get; set; } - - [BackgroundColor(192, 54, 64, 192)] - [SliderColor(224, 165, 56, 128)] - [Range(0f, 100f)] - [DefaultValue(RipperUI.DefaultRagePosY)] - public float RageMeterPosY { get; set; } - - [BackgroundColor(192, 54, 64, 192)] - [SliderColor(224, 165, 56, 128)] - [Range(0f, 100f)] - [DefaultValue(RipperUI.DefaultAdrenPosX)] - public float AdrenalineMeterPosX { get; set; } - - [BackgroundColor(192, 54, 64, 192)] - [SliderColor(224, 165, 56, 128)] - [Range(0f, 100f)] - [DefaultValue(RipperUI.DefaultAdrenPosY)] - public float AdrenalineMeterPosY { get; set; } - #endregion } } diff --git a/CalamityMod.cs b/CalamityMod.cs index 8633e28d87..83f341aeb9 100644 --- a/CalamityMod.cs +++ b/CalamityMod.cs @@ -547,7 +547,7 @@ public static void PrepareRenderTargets(GameTime gameTime) #endregion Render Target Management #region Force ModConfig save (Reflection) - internal static void SaveConfig(CalamityConfig cfg) + internal static void SaveConfig(CalamityClientConfig cfg) { // There is no current way to manually save a mod configuration file in tModLoader. // The method which saves mod config files is private in ConfigManager, so reflection is used to invoke it. diff --git a/Cooldowns/ChaosState.cs b/Cooldowns/ChaosState.cs index 4759b9b42c..a049141f3d 100644 --- a/Cooldowns/ChaosState.cs +++ b/Cooldowns/ChaosState.cs @@ -8,7 +8,7 @@ public class ChaosState : CooldownHandler { public static new string ID => "ChaosState"; - public override bool ShouldDisplay => CalamityConfig.Instance.VanillaCooldownDisplay && instance.player.chaosState; + public override bool ShouldDisplay => CalamityClientConfig.Instance.VanillaCooldownDisplay && instance.player.chaosState; public override LocalizedText DisplayName => CalamityUtils.GetText($"UI.Cooldowns.{ID}"); public override string Texture => "CalamityMod/Cooldowns/ChaosState" + skinTexture; public override Color OutlineColor => outlineColor; diff --git a/Cooldowns/PotionSickness.cs b/Cooldowns/PotionSickness.cs index 2127706e4e..d7a8708f80 100644 --- a/Cooldowns/PotionSickness.cs +++ b/Cooldowns/PotionSickness.cs @@ -7,7 +7,7 @@ namespace CalamityMod.Cooldowns public class PotionSickness : CooldownHandler { public static new string ID => "PotionSickness"; - public override bool ShouldDisplay => CalamityConfig.Instance.VanillaCooldownDisplay && instance.player.potionDelay > 0; + public override bool ShouldDisplay => CalamityClientConfig.Instance.VanillaCooldownDisplay && instance.player.potionDelay > 0; public override LocalizedText DisplayName => CalamityUtils.GetText($"UI.Cooldowns.{ID}"); public override string Texture => "CalamityMod/Cooldowns/PotionSickness"; public override Color OutlineColor => new Color(255, 142, 165); diff --git a/ILEditing/BalancingILChanges.cs b/ILEditing/BalancingILChanges.cs index ef06ec1d55..6dabd88c65 100644 --- a/ILEditing/BalancingILChanges.cs +++ b/ILEditing/BalancingILChanges.cs @@ -114,7 +114,7 @@ private static void BaseJumpHeightAdjustment(ILContext il) cursor.Remove(); // Increase by 10% if the higher jump speed is enabled. - cursor.EmitDelegate>(() => CalamityConfig.Instance.HigherJumpHeight ? BalancingConstants.ConfigBoostedBaseJumpHeight : VanillaBaseJumpHeight); + cursor.EmitDelegate>(() => CalamityServerConfig.Instance.HigherJumpHeight ? BalancingConstants.ConfigBoostedBaseJumpHeight : VanillaBaseJumpHeight); } #endregion diff --git a/ILEditing/MechanicILChanges.cs b/ILEditing/MechanicILChanges.cs index 725eefc68f..9daa4a1f1f 100644 --- a/ILEditing/MechanicILChanges.cs +++ b/ILEditing/MechanicILChanges.cs @@ -326,7 +326,7 @@ private static void PermitNighttimeTownNPCSpawning(ILContext il) { // A cached delegate is used here instead of direct reflection for performance reasons // since UpdateTime is called every frame. - if (Main.dayTime || CalamityConfig.Instance.TownNPCsSpawnAtNight) + if (Main.dayTime || CalamityServerConfig.Instance.TownNPCsSpawnAtNight) VanillaSpawnTownNPCs(); }); @@ -342,7 +342,7 @@ private static void PermitNighttimeTownNPCSpawning(ILContext il) private static void AlterTownNPCSpawnRate(Terraria.On_Main.orig_UpdateTime_SpawnTownNPCs orig) { double oldWorldRate = Main.desiredWorldTilesUpdateRate; - Main.desiredWorldTilesUpdateRate *= CalamityConfig.Instance.TownNPCSpawnRateMultiplier; + Main.desiredWorldTilesUpdateRate *= CalamityServerConfig.Instance.TownNPCSpawnRateMultiplier; orig(); Main.desiredWorldTilesUpdateRate = oldWorldRate; } diff --git a/ILEditing/VanillaStupidityFixingILChanges.cs b/ILEditing/VanillaStupidityFixingILChanges.cs index 4cced8ec61..220368f7b3 100644 --- a/ILEditing/VanillaStupidityFixingILChanges.cs +++ b/ILEditing/VanillaStupidityFixingILChanges.cs @@ -116,7 +116,7 @@ private static void RelaxPrefixRequirements(ILContext il) #region Prevention of Slime Rain Spawns When Near Bosses private static void PreventBossSlimeRainSpawns(Terraria.On_NPC.orig_SlimeRainSpawns orig, int plr) { - if (!Main.player[plr].Calamity().isNearbyBoss && CalamityConfig.Instance.BossZen) + if (!Main.player[plr].Calamity().isNearbyBoss && CalamityServerConfig.Instance.BossZen) orig(plr); } #endregion Prevention of Slime Rain Spawns When Near Bosses @@ -136,7 +136,7 @@ private static void PreventLavaSlimeLavaDrop(ILContext il) // Add an additional check for the config. cursor.Remove(); - cursor.EmitDelegate>(() => CalamityConfig.Instance.RemoveLavaDropsFromLavaSlimes || Main.remixWorld); + cursor.EmitDelegate>(() => CalamityServerConfig.Instance.RemoveLavaDropsFromLavaSlimes || Main.remixWorld); } #endregion @@ -174,7 +174,7 @@ private static void PunchCameraUsesScreenshakeConfig(ILContext il) // Emit a delegate which grabs the value of the screenshake config. Then multiply the local variable by it. cursor.Emit(OpCodes.Ldloc_1); - cursor.EmitDelegate>(() => CalamityConfig.Instance.ScreenshakePower); + cursor.EmitDelegate>(() => CalamityClientConfig.Instance.ScreenshakePower); cursor.Emit(OpCodes.Mul); cursor.Emit(OpCodes.Stloc_1); } diff --git a/ILEditing/WorldgenILChanges.cs b/ILEditing/WorldgenILChanges.cs index a3e56d9c07..d3f2523691 100644 --- a/ILEditing/WorldgenILChanges.cs +++ b/ILEditing/WorldgenILChanges.cs @@ -46,7 +46,7 @@ private static void BlockLivingTreesNearOcean(ILContext il) #region Removal of Hardmode Ore Generation from Evil Altars private static void PreventSmashAltarCode(Terraria.On_WorldGen.orig_SmashAltar orig, int i, int j) { - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework) return; orig(i, j); diff --git a/Items/CalamityGlobalItem.cs b/Items/CalamityGlobalItem.cs index 3215e277ff..90e8227993 100644 --- a/Items/CalamityGlobalItem.cs +++ b/Items/CalamityGlobalItem.cs @@ -1785,7 +1785,7 @@ public override int ChoosePrefix(Item item, UnifiedRandom rand) return keepPrefix ? prefix : 0; } - if (!CalamityConfig.Instance.RemoveReforgeRNG || Main.gameMenu || storedPrefix == -1) + if (!CalamityServerConfig.Instance.RemoveReforgeRNG || Main.gameMenu || storedPrefix == -1) return -1; // Pick a prefix using the new system. diff --git a/Items/CalamityGlobalItemTooltip.cs b/Items/CalamityGlobalItemTooltip.cs index 67ff14b193..d2fbf35303 100644 --- a/Items/CalamityGlobalItemTooltip.cs +++ b/Items/CalamityGlobalItemTooltip.cs @@ -288,7 +288,7 @@ void AddTooltip(string text) EditTooltipByNum(1, (line) => line.Text += ", including Mighty Wind"); // If Early Hardmode Rework is enabled: Remind users that ores will NOT spawn when an altar is smashed. - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && (item.type == ItemID.Pwnhammer || item.type == ItemID.Hammush)) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && (item.type == ItemID.Pwnhammer || item.type == ItemID.Hammush)) EditTooltipByNum(0, (line) => line.Text += "\nDemon Altars now drop Souls of Night instead of generating ores when destroyed" + "\nHardmode ores now generate after defeating Mechanical Bosses for the first time"); diff --git a/Items/Placeables/CelestialRemains.cs b/Items/Placeables/CelestialRemains.cs index c597021aad..91bbe5daf6 100644 --- a/Items/Placeables/CelestialRemains.cs +++ b/Items/Placeables/CelestialRemains.cs @@ -132,22 +132,22 @@ public override void ExtractinatorUse(int extractinatorBlockType, ref int result } else if (val < 85.03f) { - resultType = CalamityConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.CobaltOre : ItemID.MythrilOre) : ItemID.MythrilOre; + resultType = CalamityServerConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.CobaltOre : ItemID.MythrilOre) : ItemID.MythrilOre; resultStack = Main.rand.Next(1, 17); } else if (val < 87.03f) { - resultType = CalamityConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.PalladiumOre : ItemID.OrichalcumOre) : ItemID.OrichalcumOre; + resultType = CalamityServerConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.PalladiumOre : ItemID.OrichalcumOre) : ItemID.OrichalcumOre; resultStack = Main.rand.Next(1, 17); } else if (val < 88.78f) { - resultType = CalamityConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.CobaltOre : !twoMechsDowned ? ItemID.MythrilOre : ItemID.AdamantiteOre) : ItemID.AdamantiteOre; + resultType = CalamityServerConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.CobaltOre : !twoMechsDowned ? ItemID.MythrilOre : ItemID.AdamantiteOre) : ItemID.AdamantiteOre; resultStack = Main.rand.Next(1, 17); } else if (val < 89.53f) { - resultType = CalamityConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.PalladiumOre : !twoMechsDowned ? ItemID.OrichalcumOre : ItemID.TitaniumOre) : ItemID.TitaniumOre; + resultType = CalamityServerConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.PalladiumOre : !twoMechsDowned ? ItemID.OrichalcumOre : ItemID.TitaniumOre) : ItemID.TitaniumOre; resultStack = Main.rand.Next(1, 17); } else if (DownedBossSystem.downedAstrumDeus) diff --git a/Items/Placeables/NovaeSlag.cs b/Items/Placeables/NovaeSlag.cs index 78983dd0f0..14b3cdb79f 100644 --- a/Items/Placeables/NovaeSlag.cs +++ b/Items/Placeables/NovaeSlag.cs @@ -120,22 +120,22 @@ public override void ExtractinatorUse(int extractinatorBlockType, ref int result } else if (val < 83.03f) { - resultType = CalamityConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.CobaltOre : ItemID.MythrilOre) : ItemID.MythrilOre; + resultType = CalamityServerConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.CobaltOre : ItemID.MythrilOre) : ItemID.MythrilOre; resultStack = Main.rand.Next(1, 17); } else if (val < 85.03f) { - resultType = CalamityConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.PalladiumOre : ItemID.OrichalcumOre) : ItemID.OrichalcumOre; + resultType = CalamityServerConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.PalladiumOre : ItemID.OrichalcumOre) : ItemID.OrichalcumOre; resultStack = Main.rand.Next(1, 17); } else if (val < 86.78f) { - resultType = CalamityConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.CobaltOre : !twoMechsDowned ? ItemID.MythrilOre : ItemID.AdamantiteOre) : ItemID.AdamantiteOre; + resultType = CalamityServerConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.CobaltOre : !twoMechsDowned ? ItemID.MythrilOre : ItemID.AdamantiteOre) : ItemID.AdamantiteOre; resultStack = Main.rand.Next(1, 17); } else if (val < 88.53f) { - resultType = CalamityConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.PalladiumOre : !twoMechsDowned ? ItemID.OrichalcumOre : ItemID.TitaniumOre) : ItemID.TitaniumOre; + resultType = CalamityServerConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.PalladiumOre : !twoMechsDowned ? ItemID.OrichalcumOre : ItemID.TitaniumOre) : ItemID.TitaniumOre; resultStack = Main.rand.Next(1, 17); } else if (DownedBossSystem.downedAstrumDeus) diff --git a/Localization/en-US/Mods.CalamityMod.Configs.hjson b/Localization/en-US/Mods.CalamityMod.Configs.hjson index c934b26403..97dbe057ae 100644 --- a/Localization/en-US/Mods.CalamityMod.Configs.hjson +++ b/Localization/en-US/Mods.CalamityMod.Configs.hjson @@ -1,13 +1,11 @@ -CalamityConfig: { - DisplayName: Main Config +CalamityClientConfig: { + DisplayName: Client Config Headers: { - ExpertMaster: Expert and Master Mode Changes Gameplay: General Gameplay Changes Graphics: Graphics Changes - Revengeance: Revengeance Mode Changes + MeterPositions: Meter Positions UI: UI Changes - BaseBoosts: Base Stat Boosts MusicEvents: Music Events } @@ -38,15 +36,6 @@ CalamityConfig: { ''' } - BossesStopWeather: { - Label: "[i:CalamityMod/TorrentialTear] Bosses Stop Weather" - Tooltip: - ''' - When enabled, many late game bosses will stop all rain and related weather when spawned. - Enable if you have performance issues during late game boss fights. - ''' - } - BossHealthBarExtraInfo: { Label: "[i:CalamityMod/EncryptedSchematicPlanetoid] Boss Health Bar Extra Info" Tooltip: @@ -56,35 +45,6 @@ CalamityConfig: { ''' } - BossHealthBoost: { - Label: "[i:LifeCrystal] Boss Health Boost Percentage" - Tooltip: - ''' - Globally boosts the health of all bosses by the specified percentage. - This stacks with multiplayer boss health boosts. - Does not affect bosses that are already spawned. - ''' - } - - DefaultDashEnabled: { - Label: "[i:Tabi] Default Dash" - Tooltip: - ''' - Gives the player a very weak dash by default that requires no equipment or items to use. - This dash will be replaced by any other available dash, including those from other mods. - ''' - } - - BossZen: { - Label: "[i:CalamityMod/ZenPotion] Bosses Drastically Reduce Spawn Rates" - Tooltip: - ''' - All living bosses will drastically reduce the spawn rates of regular enemies. - This also prevents Slime Rain from occurring while a boss is alive. - Calamity is balanced around this setting being enabled. - ''' - } - ChargeMeter: { Label: "[i:CalamityMod/DraedonPowerCell] Display Charge Meter" Tooltip: @@ -112,11 +72,6 @@ CalamityConfig: { ''' } - ChilledWaterRework: { - Label: "[i:ArcticDivingGear] Chilled Water Rework" - Tooltip: When enabled, water in the Snow and Ice biomes will rapidly drain the player's breath instead of inflicting Chilled. - } - CooldownDisplay: { Label: "[i:CalamityMod/NebulousCore] Cooldown Rack Display Mode" Tooltip: @@ -136,28 +91,6 @@ CalamityConfig: { Tooltip: Plays Calamity Mod OST - "Scourge of The Universe (Eulogy for The Ego)", after The Devourer of Gods has been defeated. } - EarlyHardmodeProgressionRework: { - Label: "[i:Pwnhammer] Early Hardmode Progression Rework" - Tooltip: - ''' - Demon Altars no longer spawn ores and crimson/corruption blocks when broken. - Wall of Flesh spawns Cobalt and Palladium ore on first kill. - The first mech boss you fight has 20% (10% in Expert and Master) less HP and damage and spawns Mythril and Orichalcum ore on first kill. - The second mech boss you fight has 10% (5% in Expert and Master) less HP and damage and spawns Adamantite and Titanium ore on first kill. - The third mech boss spawns Hallowed Ore on first kill. - ''' - } - - FasterBaseSpeed: { - Label: "[i:HermesBoots] Increase Base Movement Speed" - Tooltip: - ''' - Increases the player's base movement speed substantially by always giving them +50% movement speed. - This setting does nothing if the mod Terraria Overhaul is loaded. - Calamity is balanced around this setting being enabled. - ''' - } - FasterFallHotkey: { Label: "[i:CalamityMod/BallAndChain] Enable Fast Falling" Tooltip: @@ -168,24 +101,6 @@ CalamityConfig: { ''' } - FasterJumpSpeed: { - Label: "[i:FrogLeg] Increase Base Jump Speed" - Tooltip: - ''' - Slightly increases the player's base jump speed. - Calamity is balanced around this setting being enabled. - ''' - } - - FasterTilePlacement: { - Label: "[i:ArchitectGizmoPack] Increase Base Building Speed" - Tooltip: - ''' - Substantially increases how rapidly the player can place tiles and walls. - This config stacks with the Brick Layer, Portable Cement Mixer and other accessories. - ''' - } - FlightBar: { Label: "[i:AngelWings] Display Flight Bar" Tooltip: @@ -214,24 +129,6 @@ CalamityConfig: { ''' } - ForceTownSafety: { - Label: "[i:Sunflower] Force Town Safety" - Tooltip: - ''' - Counteracts Expert and Master Mode allowing enemies to spawn near towns by vastly decreasing spawn rates. - This can have unintended side effects such as making critters difficult to find. - ''' - } - - HigherJumpHeight: { - Label: "[i:ShinyRedBalloon] Increase Base Jump Height" - Tooltip: - ''' - Increases the player's base jump height by 10% so that they can jump 7 tiles. - Calamity is balanced around this setting being enabled. - ''' - } - Interlude1: { Label: "[i:CalamityModMusic/Interlude1MusicBox] Interlude 1" Tooltip: Plays Calamity Mod OST - Interlude 1, "Silence before the storms", after Calamitas Clone has been defeated. @@ -265,15 +162,6 @@ CalamityConfig: { ''' } - NerfExpertDebuffs: { - Label: "[i:AnkhCharm] Remove Increased Debuff Duration" - Tooltip: - ''' - Disables Expert Mode doubling (and Master Mode tripling) the duration of debuffs on the player. - Calamity is balanced around this setting being enabled. - ''' - } - NewVanillaTextures: { Label: "[i:Paintbrush] New Vanilla Textures" Tooltip: @@ -312,20 +200,6 @@ CalamityConfig: { ''' } - RemoveLavaDropsFromLavaSlimes: { - Label: "[i:LavaWaders] Remove Lava Drops From Lava Slimes" - Tooltip: When enabled, Lava Slimes will be prevented from dropping lava in Expert Mode. - } - - RemoveReforgeRNG: { - Label: "[i:TinHammer] Remove Reforge RNG" - Tooltip: - ''' - Removes randomness from the Goblin Tinkerer's reforges for both weapons and accessories. - Disable this if using mods that change reforging on their own to prevent conflicts. - ''' - } - RipperMeterShake: { Label: "[i:CalamityMod/RedLightningContainer] Rage and Adrenaline Meter Shake" Tooltip: @@ -433,12 +307,138 @@ CalamityConfig: { ''' } - PotionSelling: { - Label: "[i:SpelunkerPotion] Town NPC Potion Selling" + VanillaCooldownDisplay: { + Label: "[i:HealingPotion] Display Vanilla Cooldowns" Tooltip: ''' - Allows town NPCs to sell various potions. - Certain potions are sold after specific bosses have been defeated. + Adds the vanilla debuffs Potion Sickness and Chaos State to the Cooldown Rack. + The debuffs will still appear in the buffs array, but this may help make them more visible. + ''' + } + + WikiStatusMessage: { + Label: "[i:Book] Wiki Status Message" + Tooltip: Enable or disable the status message promoting the Official Calamity Wiki that plays on world entry. + } +} + +CalamityServerConfig: { + DisplayName: Server Config + Denied: You have no permission to change this config + + Headers: { + ExpertMaster: Expert and Master Mode Changes + Gameplay: General Gameplay Changes + BaseBoosts: Base Stat Boosts + } + + BossesStopWeather: { + Label: "[i:CalamityMod/TorrentialTear] Bosses Stop Weather" + Tooltip: + ''' + When enabled, many late game bosses will stop all rain and related weather when spawned. + Enable if you have performance issues during late game boss fights. + ''' + } + + BossHealthBoost: { + Label: "[i:LifeCrystal] Boss Health Boost Percentage" + Tooltip: + ''' + Globally boosts the health of all bosses by the specified percentage. + This stacks with multiplayer boss health boosts. + Does not affect bosses that are already spawned. + ''' + } + + BossZen: { + Label: "[i:CalamityMod/ZenPotion] Bosses Drastically Reduce Spawn Rates" + Tooltip: + ''' + All living bosses will drastically reduce the spawn rates of regular enemies. + This also prevents Slime Rain from occurring while a boss is alive. + Calamity is balanced around this setting being enabled. + ''' + } + + ChilledWaterRework: { + Label: "[i:ArcticDivingGear] Chilled Water Rework" + Tooltip: When enabled, water in the Snow and Ice biomes will rapidly drain the player's breath instead of inflicting Chilled. + } + + DefaultDashEnabled: { + Label: "[i:Tabi] Default Dash" + Tooltip: + ''' + Gives the player a very weak dash by default that requires no equipment or items to use. + This dash will be replaced by any other available dash, including those from other mods. + ''' + } + + EarlyHardmodeProgressionRework: { + Label: "[i:Pwnhammer] Early Hardmode Progression Rework" + Tooltip: + ''' + Demon Altars no longer spawn ores and crimson/corruption blocks when broken. + Wall of Flesh spawns Cobalt and Palladium ore on first kill. + The first mech boss you fight has 20% (10% in Expert and Master) less HP and damage and spawns Mythril and Orichalcum ore on first kill. + The second mech boss you fight has 10% (5% in Expert and Master) less HP and damage and spawns Adamantite and Titanium ore on first kill. + The third mech boss spawns Hallowed Ore on first kill. + ''' + } + + FasterBaseSpeed: { + Label: "[i:HermesBoots] Increase Base Movement Speed" + Tooltip: + ''' + Increases the player's base movement speed substantially by always giving them +50% movement speed. + This setting does nothing if the mod Terraria Overhaul is loaded. + Calamity is balanced around this setting being enabled. + ''' + } + + FasterJumpSpeed: { + Label: "[i:FrogLeg] Increase Base Jump Speed" + Tooltip: + ''' + Slightly increases the player's base jump speed. + Calamity is balanced around this setting being enabled. + ''' + } + + FasterTilePlacement: { + Label: "[i:ArchitectGizmoPack] Increase Base Building Speed" + Tooltip: + ''' + Substantially increases how rapidly the player can place tiles and walls. + This config stacks with the Brick Layer, Portable Cement Mixer and other accessories. + ''' + } + + ForceTownSafety: { + Label: "[i:Sunflower] Force Town Safety" + Tooltip: + ''' + Counteracts Expert and Master Mode allowing enemies to spawn near towns by vastly decreasing spawn rates. + This can have unintended side effects such as making critters difficult to find. + ''' + } + + HigherJumpHeight: { + Label: "[i:ShinyRedBalloon] Increase Base Jump Height" + Tooltip: + ''' + Increases the player's base jump height by 10% so that they can jump 7 tiles. + Calamity is balanced around this setting being enabled. + ''' + } + + NerfExpertDebuffs: { + Label: "[i:AnkhCharm] Remove Increased Debuff Duration" + Tooltip: + ''' + Disables Expert Mode doubling (and Master Mode tripling) the duration of debuffs on the player. + Calamity is balanced around this setting being enabled. ''' } @@ -451,6 +451,29 @@ CalamityConfig: { ''' } + PotionSelling: { + Label: "[i:SpelunkerPotion] Town NPC Potion Selling" + Tooltip: + ''' + Allows town NPCs to sell various potions. + Certain potions are sold after specific bosses have been defeated. + ''' + } + + RemoveLavaDropsFromLavaSlimes: { + Label: "[i:LavaWaders] Remove Lava Drops From Lava Slimes" + Tooltip: When enabled, Lava Slimes will be prevented from dropping lava in Expert Mode. + } + + RemoveReforgeRNG: { + Label: "[i:TinHammer] Remove Reforge RNG" + Tooltip: + ''' + Removes randomness from the Goblin Tinkerer's reforges for both weapons and accessories. + Disable this if using mods that change reforging on their own to prevent conflicts. + ''' + } + TownNPCSpawnRateMultiplier: { Label: "[i:GuideVoodooDoll] Town NPC Spawn Rate Multiplier" Tooltip: @@ -468,18 +491,4 @@ CalamityConfig: { This includes the Old Man. ''' } - - VanillaCooldownDisplay: { - Label: "[i:HealingPotion] Display Vanilla Cooldowns" - Tooltip: - ''' - Adds the vanilla debuffs Potion Sickness and Chaos State to the Cooldown Rack. - The debuffs will still appear in the buffs array, but this may help make them more visible. - ''' - } - - WikiStatusMessage: { - Label: "[i:Book] Wiki Status Message" - Tooltip: Enable or disable the status message promoting the Official Calamity Wiki that plays on world entry. - } } diff --git a/ModSupport/ModCalls.cs b/ModSupport/ModCalls.cs index 09288e3327..3ec60468df 100644 --- a/ModSupport/ModCalls.cs +++ b/ModSupport/ModCalls.cs @@ -2163,7 +2163,7 @@ bool castID(object o, out int id) case "GetBossHealthBoost": case "BossHealthMultiplier": case "GetBossHealthMultiplier": - return CalamityConfig.Instance.BossHealthBoost; + return CalamityServerConfig.Instance.BossHealthBoost; case "HasPermanentPowerup": case "GetPermanentPowerup": diff --git a/NPCs/AquaticScourge/AquaticScourgeBody.cs b/NPCs/AquaticScourge/AquaticScourgeBody.cs index f2a7a7f31b..ffe90598c0 100644 --- a/NPCs/AquaticScourge/AquaticScourgeBody.cs +++ b/NPCs/AquaticScourge/AquaticScourgeBody.cs @@ -38,7 +38,7 @@ public override void SetDefaults() if (CalamityWorld.LegendaryMode && CalamityWorld.revenge) NPC.lifeMax *= 2; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.behindTiles = true; NPC.noGravity = true; diff --git a/NPCs/AquaticScourge/AquaticScourgeBodyAlt.cs b/NPCs/AquaticScourge/AquaticScourgeBodyAlt.cs index 85d4d29c40..920eed7664 100644 --- a/NPCs/AquaticScourge/AquaticScourgeBodyAlt.cs +++ b/NPCs/AquaticScourge/AquaticScourgeBodyAlt.cs @@ -37,7 +37,7 @@ public override void SetDefaults() if (CalamityWorld.LegendaryMode && CalamityWorld.revenge) NPC.lifeMax *= 2; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.behindTiles = true; NPC.noGravity = true; diff --git a/NPCs/AquaticScourge/AquaticScourgeHead.cs b/NPCs/AquaticScourge/AquaticScourgeHead.cs index 0b4cc334fa..eb33d7b299 100644 --- a/NPCs/AquaticScourge/AquaticScourgeHead.cs +++ b/NPCs/AquaticScourge/AquaticScourgeHead.cs @@ -65,7 +65,7 @@ public override void SetDefaults() if (CalamityWorld.LegendaryMode && CalamityWorld.revenge) NPC.lifeMax *= 2; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.value = Item.buyPrice(0, 40, 0, 0); diff --git a/NPCs/AquaticScourge/AquaticScourgeTail.cs b/NPCs/AquaticScourge/AquaticScourgeTail.cs index c7cd744e25..a147d7e144 100644 --- a/NPCs/AquaticScourge/AquaticScourgeTail.cs +++ b/NPCs/AquaticScourge/AquaticScourgeTail.cs @@ -37,7 +37,7 @@ public override void SetDefaults() if (CalamityWorld.LegendaryMode && CalamityWorld.revenge) NPC.lifeMax *= 2; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.behindTiles = true; NPC.noGravity = true; diff --git a/NPCs/AstrumAureus/AstrumAureus.cs b/NPCs/AstrumAureus/AstrumAureus.cs index 61ee4eaa34..1e5440cdd1 100644 --- a/NPCs/AstrumAureus/AstrumAureus.cs +++ b/NPCs/AstrumAureus/AstrumAureus.cs @@ -102,7 +102,7 @@ public override void SetDefaults() NPC.value = Item.buyPrice(0, 60, 0, 0); NPC.boss = true; NPC.DeathSound = DeathSound; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.Calamity().VulnerableToHeat = true; NPC.Calamity().VulnerableToSickness = false; @@ -317,7 +317,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d if (NPC.ai[0] == 3f || NPC.ai[0] == 4f) afterimageAmt = 10; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -347,7 +347,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d attackingColor = slimePhase == 0 ? Color.Violet : Color.Yellow; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/AstrumAureus/AureusSpawn.cs b/NPCs/AstrumAureus/AureusSpawn.cs index 379d8a9e6d..e9dec231b7 100644 --- a/NPCs/AstrumAureus/AureusSpawn.cs +++ b/NPCs/AstrumAureus/AureusSpawn.cs @@ -43,7 +43,7 @@ public override void SetDefaults() NPC.Opacity = 0f; NPC.defense = 10; NPC.lifeMax = 5000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.dontTakeDamage = true; @@ -246,7 +246,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color whiteColor = Color.White; int afterimageAmt = 10; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -269,7 +269,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture2D15 = GlowTexture.Value; Color afterimageColorLerp = Color.Lerp(Color.White, Color.Orange, 0.5f) * NPC.Opacity; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/AstrumDeus/AstrumDeusBody.cs b/NPCs/AstrumDeus/AstrumDeusBody.cs index 29d3848680..845ba253ca 100644 --- a/NPCs/AstrumDeus/AstrumDeusBody.cs +++ b/NPCs/AstrumDeus/AstrumDeusBody.cs @@ -53,7 +53,7 @@ public override void SetDefaults() NPC.defense = 35; NPC.DR_NERD(0.25f); NPC.LifeMaxNERB(200000, 240000, 650000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/AstrumDeus/AstrumDeusHead.cs b/NPCs/AstrumDeus/AstrumDeusHead.cs index 8ec5567827..3082f52d60 100644 --- a/NPCs/AstrumDeus/AstrumDeusHead.cs +++ b/NPCs/AstrumDeus/AstrumDeusHead.cs @@ -82,7 +82,7 @@ public override void SetDefaults() NPC.defense = 20; NPC.DR_NERD(0.1f); NPC.LifeMaxNERB(200000, 240000, 650000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/AstrumDeus/AstrumDeusTail.cs b/NPCs/AstrumDeus/AstrumDeusTail.cs index 95bb79480f..c1554947d1 100644 --- a/NPCs/AstrumDeus/AstrumDeusTail.cs +++ b/NPCs/AstrumDeus/AstrumDeusTail.cs @@ -43,7 +43,7 @@ public override void SetDefaults() NPC.defense = 50; NPC.DR_NERD(0.4f); NPC.LifeMaxNERB(200000, 240000, 650000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/BrimstoneElemental/Brimling.cs b/NPCs/BrimstoneElemental/Brimling.cs index f4fc581261..d56ca21cb8 100644 --- a/NPCs/BrimstoneElemental/Brimling.cs +++ b/NPCs/BrimstoneElemental/Brimling.cs @@ -45,7 +45,7 @@ public override void SetDefaults() { NPC.lifeMax = 10000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.Calamity().VulnerableToHeat = false; NPC.Calamity().VulnerableToCold = true; diff --git a/NPCs/BrimstoneElemental/BrimstoneElemental.cs b/NPCs/BrimstoneElemental/BrimstoneElemental.cs index 39e33068b0..c7d6d7ed6a 100644 --- a/NPCs/BrimstoneElemental/BrimstoneElemental.cs +++ b/NPCs/BrimstoneElemental/BrimstoneElemental.cs @@ -68,7 +68,7 @@ public override void SetDefaults() NPC.value = Item.buyPrice(0, 40, 0, 0); NPC.LifeMaxNERB(41000, 49200, 780000); NPC.DR_NERD(0.15f); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.aiStyle = -1; diff --git a/NPCs/Bumblebirb/Bumblefuck.cs b/NPCs/Bumblebirb/Bumblefuck.cs index e88ddfb475..12863fa314 100644 --- a/NPCs/Bumblebirb/Bumblefuck.cs +++ b/NPCs/Bumblebirb/Bumblefuck.cs @@ -71,7 +71,7 @@ public override void SetDefaults() NPC.defense = 40; NPC.DR_NERD(0.1f); NPC.LifeMaxNERB(187500, 225000, 300000); // Old HP - 227500, 252500 - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.boss = true; @@ -278,7 +278,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d color = altColor; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += afterimageIncrement) { @@ -331,7 +331,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d } } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 0; j < extraAfterimageAmt; j++) { @@ -373,7 +373,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d glowmaskColor *= glowmaskDampener; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int k = 1; k < afterimageAmt; k += afterimageIncrement) { diff --git a/NPCs/Bumblebirb/Bumblefuck2.cs b/NPCs/Bumblebirb/Bumblefuck2.cs index b79d7fb64a..b4e18592d6 100644 --- a/NPCs/Bumblebirb/Bumblefuck2.cs +++ b/NPCs/Bumblebirb/Bumblefuck2.cs @@ -33,7 +33,7 @@ public override void SetDefaults() NPC.height = 80; NPC.defense = 20; NPC.LifeMaxNERB(9375, 11250, 5000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.15f; NPC.lavaImmune = true; @@ -106,7 +106,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2(TextureAssets.Npc[NPC.type].Value.Width / 2, TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2); int afterimageAmt = NPC.ai[0] == 2.1f ? 7 : 0; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { diff --git a/NPCs/CalClone/CalamitasClone.cs b/NPCs/CalClone/CalamitasClone.cs index c3c1dd0cbc..5853969837 100644 --- a/NPCs/CalClone/CalamitasClone.cs +++ b/NPCs/CalClone/CalamitasClone.cs @@ -70,7 +70,7 @@ public override void SetDefaults() NPC.value = Item.buyPrice(0, 50, 0, 0); NPC.DR_NERD((CalamityWorld.death || BossRushEvent.BossRushActive) ? 0.075f : 0.15f); NPC.LifeMaxNERB(37500, 45000, 520000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -142,7 +142,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d float colorLerpAmt = 0.5f; int afterimageAmt = 7; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -169,7 +169,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d color = Color.CornflowerBlue; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i++) { diff --git a/NPCs/CalClone/Cataclysm.cs b/NPCs/CalClone/Cataclysm.cs index 80b173cc83..257e7143cd 100644 --- a/NPCs/CalClone/Cataclysm.cs +++ b/NPCs/CalClone/Cataclysm.cs @@ -55,7 +55,7 @@ public override void SetDefaults() NPC.defense = (CalamityWorld.death || BossRushEvent.BossRushActive) ? 15 : 10; NPC.DR_NERD((CalamityWorld.death || BossRushEvent.BossRushActive) ? 0.225f : 0.15f); NPC.LifeMaxNERB(11000, 13200, 80000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -117,7 +117,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2((float)(TextureAssets.Npc[NPC.type].Value.Width / 2), (float)(TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2)); int afterimageAmt = 7; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -140,7 +140,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture2D15 = GlowTexture.Value; Color pinkLerp = Color.Lerp(Color.White, Color.Red, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/CalClone/Catastrophe.cs b/NPCs/CalClone/Catastrophe.cs index c06986998d..a189db22f8 100644 --- a/NPCs/CalClone/Catastrophe.cs +++ b/NPCs/CalClone/Catastrophe.cs @@ -55,7 +55,7 @@ public override void SetDefaults() NPC.defense = (CalamityWorld.death || BossRushEvent.BossRushActive) ? 15 : 10; NPC.DR_NERD((CalamityWorld.death || BossRushEvent.BossRushActive) ? 0.225f : 0.15f); NPC.LifeMaxNERB(9200, 11025, 80000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -117,7 +117,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2((float)(TextureAssets.Npc[NPC.type].Value.Width / 2), (float)(TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2)); int afterimageAmt = 7; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -140,7 +140,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture2D15 = GlowTexture.Value; Color pinkLerp = Color.Lerp(Color.White, Color.Red, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/CalClone/SoulSeeker.cs b/NPCs/CalClone/SoulSeeker.cs index adbefe7503..7158e8b378 100644 --- a/NPCs/CalClone/SoulSeeker.cs +++ b/NPCs/CalClone/SoulSeeker.cs @@ -47,7 +47,7 @@ public override void SetDefaults() { NPC.lifeMax = 15000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.HitSound = SoundID.NPCHit4; NPC.DeathSound = SoundID.NPCDeath14; @@ -197,7 +197,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d float colorLerpAmt = 0.5f; int afterImageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int a = 1; a < afterImageAmt; a += 2) { @@ -220,7 +220,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture = GlowTexture.Value; Color glow = Color.Lerp(Color.White, Color.Red, colorLerpAmt); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int a = 1; a < afterImageAmt; a++) { diff --git a/NPCs/CalamityAIs/CalamityBossAIs/CeaselessVoidAI.cs b/NPCs/CalamityAIs/CalamityBossAIs/CeaselessVoidAI.cs index e33ab45fd9..4f455fd547 100644 --- a/NPCs/CalamityAIs/CalamityBossAIs/CeaselessVoidAI.cs +++ b/NPCs/CalamityAIs/CalamityBossAIs/CeaselessVoidAI.cs @@ -390,7 +390,7 @@ public static void VanillaCeaselessVoidAI(NPC npc, Mod mod) // Destroy all Dark Energies if their total HP is below 20% int darkEnergyMaxHP = bossRush ? DarkEnergy.MaxBossRushHP : DarkEnergy.MaxHP; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; darkEnergyMaxHP += (int)(darkEnergyMaxHP * HPBoost); int totalDarkEnergiesSpawned = darkEnergyAmt * 3 + 2; int totalDarkEnergyMaxHP = darkEnergyMaxHP * totalDarkEnergiesSpawned; diff --git a/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs b/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs index aab7218ebb..8f9527ab27 100644 --- a/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs +++ b/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs @@ -68,7 +68,7 @@ public static void VanillaOldDukeAI(NPC npc, Mod mod) float greenLight = (phase3AI ? 1.2f : phase2AI ? 0.8f : 0.4f) * alphaScale; Lighting.AddLight((int)((npc.position.X + (npc.width / 2)) / 16f), (int)((npc.position.Y + (npc.height / 2)) / 16f), redLight, greenLight, 0f); - if (CalamityConfig.Instance.BossesStopWeather) + if (CalamityServerConfig.Instance.BossesStopWeather) CalamityMod.StopRain(); else if (!Main.raining && !BossRushEvent.BossRushActive) CalamityUtils.StartRain(); diff --git a/NPCs/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index b9d9b5f707..30e7d1425e 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -2233,7 +2233,7 @@ private void OtherStatChanges(NPC npc) if ((npc.boss && npc.type != NPCID.MartianSaucerCore) || CalamityLists.bossHPScaleList.Contains(npc.type)) { - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; npc.lifeMax += (int)Math.Round(npc.lifeMax * HPBoost); } } @@ -2437,7 +2437,7 @@ private void OtherStatChanges(NPC npc) } // Reduce mech boss HP and damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { if (!NPC.downedMechBossAny) { @@ -3096,7 +3096,7 @@ public static void DrawAfterimage(NPC npc, SpriteBatch spriteBatch, Color starti Texture2D npcTexture = texture ?? TextureAssets.Npc[npc.type].Value; Vector2 screenOffset = npc.IsABestiaryIconDummy ? Vector2.Zero : Main.screenPosition; int afterimageCounter = 1; - while (afterimageCounter < NPCID.Sets.TrailCacheLength[npc.type] && CalamityConfig.Instance.Afterimages) + while (afterimageCounter < NPCID.Sets.TrailCacheLength[npc.type] && CalamityClientConfig.Instance.Afterimages) { Color colorToDraw = Color.Lerp(drawColor, endingColor, afterimageCounter / (float)NPCID.Sets.TrailCacheLength[npc.type]); colorToDraw *= afterimageCounter / (float)NPCID.Sets.TrailCacheLength[npc.type]; @@ -6017,12 +6017,12 @@ public override void EditSpawnRate(Player player, ref int spawnRate, ref int max spawnRate = (int)(spawnRate * 1.4); maxSpawns = (int)(maxSpawns * 0.4f); } - if (player.Calamity().zen || (CalamityConfig.Instance.ForceTownSafety && player.townNPCs > 1f && Main.expertMode)) + if (player.Calamity().zen || (CalamityServerConfig.Instance.ForceTownSafety && player.townNPCs > 1f && Main.expertMode)) { spawnRate = (int)(spawnRate * 2.5); maxSpawns = (int)(maxSpawns * 0.3f); } - if (player.Calamity().isNearbyBoss && CalamityConfig.Instance.BossZen) + if (player.Calamity().isNearbyBoss && CalamityServerConfig.Instance.BossZen) { spawnRate *= 5; maxSpawns = (int)(maxSpawns * 0.001f); @@ -6589,7 +6589,7 @@ public override bool PreDraw(NPC npc, SpriteBatch spriteBatch, Vector2 screenPos { if (npc.type != NPCID.BrainofCthulhu && (npc.type != NPCID.DukeFishron || npc.ai[0] <= 9f) && npc.active) { - if (CalamityConfig.Instance.DebuffDisplay && (npc.boss || BossHealthBarManager.MinibossHPBarList.Contains(npc.type) || BossHealthBarManager.OneToMany.ContainsKey(npc.type) || CalamityLists.needsDebuffIconDisplayList.Contains(npc.type))) + if (CalamityClientConfig.Instance.DebuffDisplay && (npc.boss || BossHealthBarManager.MinibossHPBarList.Contains(npc.type) || BossHealthBarManager.OneToMany.ContainsKey(npc.type) || CalamityLists.needsDebuffIconDisplayList.Contains(npc.type))) { List currentDebuffs = new List() { }; @@ -7115,7 +7115,7 @@ public override void PostDraw(NPC npc, SpriteBatch spriteBatch, Vector2 screenPo } } - Texture2D glowTexture = CalamityConfig.Instance.NewVanillaTextures ? CalamityMod.DestroyerGlowmasks[0].Value : TextureAssets.Dest[0].Value; + Texture2D glowTexture = CalamityClientConfig.Instance.NewVanillaTextures ? CalamityMod.DestroyerGlowmasks[0].Value : TextureAssets.Dest[0].Value; switch (npc.type) { default: @@ -7123,11 +7123,11 @@ public override void PostDraw(NPC npc, SpriteBatch spriteBatch, Vector2 screenPo break; case NPCID.TheDestroyerBody: - glowTexture = CalamityConfig.Instance.NewVanillaTextures ? CalamityMod.DestroyerGlowmasks[1].Value : TextureAssets.Dest[1].Value; + glowTexture = CalamityClientConfig.Instance.NewVanillaTextures ? CalamityMod.DestroyerGlowmasks[1].Value : TextureAssets.Dest[1].Value; break; case NPCID.TheDestroyerTail: - glowTexture = CalamityConfig.Instance.NewVanillaTextures ? CalamityMod.DestroyerGlowmasks[2].Value : TextureAssets.Dest[2].Value; + glowTexture = CalamityClientConfig.Instance.NewVanillaTextures ? CalamityMod.DestroyerGlowmasks[2].Value : TextureAssets.Dest[2].Value; break; } @@ -7429,7 +7429,7 @@ public override void PostDraw(NPC npc, SpriteBatch spriteBatch, Vector2 screenPo float eyeTelegraphGateValue = WallOfFleshAI.LaserShootGateValue - WallOfFleshAI.LaserShootTelegraphTime; if (npc.localAI[1] > eyeTelegraphGateValue || npc.localAI[2] > 0f || enraged) { - Texture2D glowTexture = CalamityConfig.Instance.NewVanillaTextures ? CalamityMod.WallOfFleshEyeGlowmask.Value : TextureAssets.Npc[npc.type].Value; + Texture2D glowTexture = CalamityClientConfig.Instance.NewVanillaTextures ? CalamityMod.WallOfFleshEyeGlowmask.Value : TextureAssets.Npc[npc.type].Value; Vector2 halfSize = npc.frame.Size() / 2; SpriteEffects spriteEffects = SpriteEffects.None; if (npc.spriteDirection == 1) @@ -7581,7 +7581,7 @@ public override void PostDraw(NPC npc, SpriteBatch spriteBatch, Vector2 screenPo float telegraphScalar = MathHelper.Clamp((Math.Abs(PlanteraAI.StopChargeGateValue) - telegraphTimer) / Math.Abs(PlanteraAI.StopChargeGateValue), 0f, 1f); Color telegraphColor = Color.Lerp(originalColor, newColor, telegraphScalar); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { int afterimageAmount = 10; int afterImageIncrement = 2; diff --git a/NPCs/CalamityGlobalNPCLoot.cs b/NPCs/CalamityGlobalNPCLoot.cs index 34e5d7488f..846f59a6e0 100644 --- a/NPCs/CalamityGlobalNPCLoot.cs +++ b/NPCs/CalamityGlobalNPCLoot.cs @@ -1856,7 +1856,7 @@ public override void OnKill(NPC npc) if (!Main.hardMode) { // Increase altar count to allow natural mech boss spawning. - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework) WorldGen.altarCount++; string key2 = "Mods.CalamityMod.Status.Progression.UglyBossText"; @@ -1880,7 +1880,7 @@ public override void OnKill(NPC npc) SetNewShopVariable(new int[] { NPCID.Stylist, ModContent.NPCType(), ModContent.NPCType() }, NPC.downedMechBoss1 || !NPC.downedMechBoss2 || !NPC.downedMechBoss3); SetNewBossJustDowned(npc); - if (!NPC.downedMechBoss1 && CalamityConfig.Instance.EarlyHardmodeProgressionRework) + if (!NPC.downedMechBoss1 && CalamityServerConfig.Instance.EarlyHardmodeProgressionRework) SpawnMechBossHardmodeOres(); break; @@ -1892,7 +1892,7 @@ public override void OnKill(NPC npc) SetNewShopVariable(new int[] { NPCID.Stylist, ModContent.NPCType(), ModContent.NPCType() }, !NPC.downedMechBoss1 || NPC.downedMechBoss2 || !NPC.downedMechBoss3); SetNewBossJustDowned(npc); - if (!NPC.downedMechBoss2 && CalamityConfig.Instance.EarlyHardmodeProgressionRework) + if (!NPC.downedMechBoss2 && CalamityServerConfig.Instance.EarlyHardmodeProgressionRework) SpawnMechBossHardmodeOres(); } break; @@ -1902,7 +1902,7 @@ public override void OnKill(NPC npc) SetNewShopVariable(new int[] { NPCID.Stylist, ModContent.NPCType(), ModContent.NPCType() }, !NPC.downedMechBoss1 || !NPC.downedMechBoss2 || NPC.downedMechBoss3); SetNewBossJustDowned(npc); - if (!NPC.downedMechBoss3 && CalamityConfig.Instance.EarlyHardmodeProgressionRework) + if (!NPC.downedMechBoss3 && CalamityServerConfig.Instance.EarlyHardmodeProgressionRework) SpawnMechBossHardmodeOres(); break; diff --git a/NPCs/CalamityGlobalTownNPC.cs b/NPCs/CalamityGlobalTownNPC.cs index 8ed43caf88..653160791d 100644 --- a/NPCs/CalamityGlobalTownNPC.cs +++ b/NPCs/CalamityGlobalTownNPC.cs @@ -764,7 +764,7 @@ public override void ModifyNPCNameList(NPC npc, List nameList) public void TownNPCAlertSystem(NPC npc, Mod mod, SpriteBatch spriteBatch) { - if (CalamityConfig.Instance.ShopNewAlert && npc.townNPC) + if (CalamityClientConfig.Instance.ShopNewAlert && npc.townNPC) { for (int i = 0; i < npcAlertList.Count; i++) { diff --git a/NPCs/CeaselessVoid/CeaselessVoid.cs b/NPCs/CeaselessVoid/CeaselessVoid.cs index b7e2cb704c..332f6b68c3 100644 --- a/NPCs/CeaselessVoid/CeaselessVoid.cs +++ b/NPCs/CeaselessVoid/CeaselessVoid.cs @@ -67,7 +67,7 @@ public override void SetDefaults() global.DR = 0.5f; NPC.LifeMaxNERB(65000, 78000, 72000); NPC.value = Item.buyPrice(2, 0, 0, 0); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -162,7 +162,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2((float)(TextureAssets.Npc[NPC.type].Value.Width / 2), (float)(TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2)); int afterimageAmt = 7; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -185,7 +185,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture2D15 = GlowTexture.Value; Color cyanLerp = Color.Lerp(Color.White, Color.Cyan, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/CeaselessVoid/DarkEnergy.cs b/NPCs/CeaselessVoid/DarkEnergy.cs index c5fee54bad..cc92e31280 100644 --- a/NPCs/CeaselessVoid/DarkEnergy.cs +++ b/NPCs/CeaselessVoid/DarkEnergy.cs @@ -51,7 +51,7 @@ public override void SetDefaults() NPC.width = NPC.height = HitboxSize; NPC.defense = 50; NPC.lifeMax = BossRushEvent.BossRushActive ? MaxBossRushHP : MaxHP; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.Opacity = 0f; @@ -230,7 +230,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d drawPos -= new Vector2(mainTexture.Width, mainTexture.Height / Main.npcFrameCount[NPC.type]) * NPC.scale / 2f; drawPos += drawOrigin * NPC.scale + new Vector2(0f, NPC.gfxOffY); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < trailCount; i += 2) { @@ -253,7 +253,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Texture2D glowTexture = GlowTexture.Value; Color glowColor = Color.Lerp(Color.White, Color.Fuchsia, 0.5f) * NPC.Opacity; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < trailCount; i++) { diff --git a/NPCs/Crabulon/CrabShroom.cs b/NPCs/Crabulon/CrabShroom.cs index af96c9a5b1..8459e0d094 100644 --- a/NPCs/Crabulon/CrabShroom.cs +++ b/NPCs/Crabulon/CrabShroom.cs @@ -40,7 +40,7 @@ public override void SetDefaults() if (Main.getGoodWorld) NPC.lifeMax *= 2; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); AIType = -1; NPC.knockBackResist = 0.5f; diff --git a/NPCs/Crabulon/Crabulon.cs b/NPCs/Crabulon/Crabulon.cs index 31653519f3..f2c049aecd 100644 --- a/NPCs/Crabulon/Crabulon.cs +++ b/NPCs/Crabulon/Crabulon.cs @@ -74,7 +74,7 @@ public override void SetDefaults() NPC.height = 196; NPC.defense = 8; NPC.LifeMaxNERB(3700, 4400, 680000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/Crags/SoulSlurper.cs b/NPCs/Crags/SoulSlurper.cs index 5ea4ea2956..8f6cd9ff70 100644 --- a/NPCs/Crags/SoulSlurper.cs +++ b/NPCs/Crags/SoulSlurper.cs @@ -254,7 +254,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2((float)(texture.Width / 2), (float)(texture.Height / 2)); int afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -277,7 +277,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture = GlowTexture.Value; Color redGlow = Color.Lerp(Color.White, Color.Red, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/Cryogen/Cryogen.cs b/NPCs/Cryogen/Cryogen.cs index 59847a9191..e13b99edae 100644 --- a/NPCs/Cryogen/Cryogen.cs +++ b/NPCs/Cryogen/Cryogen.cs @@ -102,7 +102,7 @@ public override void SetDefaults() NPC.defense = 15; NPC.DR_NERD(0.3f); NPC.LifeMaxNERB(40000, 48000, 300000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -263,7 +263,7 @@ public override void AI() NPC.localAI[1] -= 1f; } - if (CalamityConfig.Instance.BossesStopWeather) + if (CalamityServerConfig.Instance.BossesStopWeather) CalamityMod.StopRain(); else if (!Main.raining && !BossRushEvent.BossRushActive) CalamityUtils.StartRain(); diff --git a/NPCs/Cryogen/CryogenShield.cs b/NPCs/Cryogen/CryogenShield.cs index 11d6978de3..0dfc63cd5f 100644 --- a/NPCs/Cryogen/CryogenShield.cs +++ b/NPCs/Cryogen/CryogenShield.cs @@ -38,7 +38,7 @@ public override void SetDefaults() { NPC.lifeMax = 10000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.Opacity = 0f; NPC.HitSound = Cryogen.HitSound; diff --git a/NPCs/DesertScourge/DesertNuisanceBody.cs b/NPCs/DesertScourge/DesertNuisanceBody.cs index 6478a73a20..8fe58967a7 100644 --- a/NPCs/DesertScourge/DesertNuisanceBody.cs +++ b/NPCs/DesertScourge/DesertNuisanceBody.cs @@ -51,7 +51,7 @@ public override void SetDefaults() if (CalamityWorld.LegendaryMode && CalamityWorld.revenge) NPC.lifeMax = 4800; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DesertScourge/DesertNuisanceBodyYoung.cs b/NPCs/DesertScourge/DesertNuisanceBodyYoung.cs index 063bb029b5..b3906e4e5b 100644 --- a/NPCs/DesertScourge/DesertNuisanceBodyYoung.cs +++ b/NPCs/DesertScourge/DesertNuisanceBodyYoung.cs @@ -51,7 +51,7 @@ public override void SetDefaults() if (CalamityWorld.LegendaryMode && CalamityWorld.revenge) NPC.lifeMax = 4000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DesertScourge/DesertNuisanceHead.cs b/NPCs/DesertScourge/DesertNuisanceHead.cs index 329c8abea3..0a7bbce816 100644 --- a/NPCs/DesertScourge/DesertNuisanceHead.cs +++ b/NPCs/DesertScourge/DesertNuisanceHead.cs @@ -66,7 +66,7 @@ public override void SetDefaults() if (CalamityWorld.LegendaryMode && CalamityWorld.revenge) NPC.lifeMax = 4800; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs b/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs index e8ae27982d..e00b996186 100644 --- a/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs +++ b/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs @@ -58,7 +58,7 @@ public override void SetDefaults() if (CalamityWorld.LegendaryMode && CalamityWorld.revenge) NPC.lifeMax = 4000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DesertScourge/DesertNuisanceTail.cs b/NPCs/DesertScourge/DesertNuisanceTail.cs index 4b720426b8..86cd975e34 100644 --- a/NPCs/DesertScourge/DesertNuisanceTail.cs +++ b/NPCs/DesertScourge/DesertNuisanceTail.cs @@ -33,7 +33,7 @@ public override void SetDefaults() if (CalamityWorld.LegendaryMode && CalamityWorld.revenge) NPC.lifeMax = 4800; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DesertScourge/DesertNuisanceTailYoung.cs b/NPCs/DesertScourge/DesertNuisanceTailYoung.cs index ecb1eb5c0b..c0d9871de4 100644 --- a/NPCs/DesertScourge/DesertNuisanceTailYoung.cs +++ b/NPCs/DesertScourge/DesertNuisanceTailYoung.cs @@ -33,7 +33,7 @@ public override void SetDefaults() if (CalamityWorld.LegendaryMode && CalamityWorld.revenge) NPC.lifeMax = 4000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DesertScourge/DesertScourgeBody.cs b/NPCs/DesertScourge/DesertScourgeBody.cs index 2baae9ff4d..1ca33e7a01 100644 --- a/NPCs/DesertScourge/DesertScourgeBody.cs +++ b/NPCs/DesertScourge/DesertScourgeBody.cs @@ -52,7 +52,7 @@ public override void SetDefaults() if (Main.getGoodWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DesertScourge/DesertScourgeHead.cs b/NPCs/DesertScourge/DesertScourgeHead.cs index 32ed748f47..a40033c075 100644 --- a/NPCs/DesertScourge/DesertScourgeHead.cs +++ b/NPCs/DesertScourge/DesertScourgeHead.cs @@ -94,7 +94,7 @@ public override void SetDefaults() if (Main.getGoodWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DesertScourge/DesertScourgeTail.cs b/NPCs/DesertScourge/DesertScourgeTail.cs index c0cd5a1bdb..6b423a5b55 100644 --- a/NPCs/DesertScourge/DesertScourgeTail.cs +++ b/NPCs/DesertScourge/DesertScourgeTail.cs @@ -32,7 +32,7 @@ public override void SetDefaults() if (Main.getGoodWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DevourerofGods/CosmicGuardianBody.cs b/NPCs/DevourerofGods/CosmicGuardianBody.cs index a5fb60beb8..488989d80a 100644 --- a/NPCs/DevourerofGods/CosmicGuardianBody.cs +++ b/NPCs/DevourerofGods/CosmicGuardianBody.cs @@ -40,7 +40,7 @@ public override void SetDefaults() global.DR = 0.5f; global.unbreakableDR = true; NPC.lifeMax = 50000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DevourerofGods/CosmicGuardianHead.cs b/NPCs/DevourerofGods/CosmicGuardianHead.cs index a4e0e2439e..fc0c4c18e2 100644 --- a/NPCs/DevourerofGods/CosmicGuardianHead.cs +++ b/NPCs/DevourerofGods/CosmicGuardianHead.cs @@ -55,7 +55,7 @@ public override void SetDefaults() NPC.height = 76; NPC.defense = 40; NPC.lifeMax = 50000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DevourerofGods/CosmicGuardianTail.cs b/NPCs/DevourerofGods/CosmicGuardianTail.cs index 125e7eef07..ea936b503e 100644 --- a/NPCs/DevourerofGods/CosmicGuardianTail.cs +++ b/NPCs/DevourerofGods/CosmicGuardianTail.cs @@ -37,7 +37,7 @@ public override void SetDefaults() NPC.height = 50; NPC.defense = 70; NPC.lifeMax = 50000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DevourerofGods/DevourerofGodsBody.cs b/NPCs/DevourerofGods/DevourerofGodsBody.cs index c8314094d3..5936efcfac 100644 --- a/NPCs/DevourerofGods/DevourerofGodsBody.cs +++ b/NPCs/DevourerofGods/DevourerofGodsBody.cs @@ -77,7 +77,7 @@ public override void SetDefaults() NPC.chaseable = false; } NPC.LifeMaxNERB(887500, 1065000, 1500000); // Phase 1 is 355000, Phase 2 is 532500 - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DevourerofGods/DevourerofGodsHead.cs b/NPCs/DevourerofGods/DevourerofGodsHead.cs index c54d87f1e5..19d86670bb 100644 --- a/NPCs/DevourerofGods/DevourerofGodsHead.cs +++ b/NPCs/DevourerofGods/DevourerofGodsHead.cs @@ -203,7 +203,7 @@ public override void SetDefaults() NPC.height = 104; NPC.defense = 50; NPC.LifeMaxNERB(887500, 1065000, 1500000); // Phase 1 is 355000, Phase 2 is 532500 - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.takenDamageMultiplier = 1.1f; NPC.aiStyle = -1; @@ -353,7 +353,7 @@ public override void AI() CalamityGlobalNPC.DoGP2 = -1; // Stop rain - if (CalamityConfig.Instance.BossesStopWeather) + if (CalamityServerConfig.Instance.BossesStopWeather) CalamityMod.StopRain(); // Get a target (time is checked in the second check to ensure a new target isn't being set constantly) diff --git a/NPCs/DevourerofGods/DevourerofGodsTail.cs b/NPCs/DevourerofGods/DevourerofGodsTail.cs index b521baedb1..e2121c685c 100644 --- a/NPCs/DevourerofGods/DevourerofGodsTail.cs +++ b/NPCs/DevourerofGods/DevourerofGodsTail.cs @@ -74,7 +74,7 @@ public override void SetDefaults() NPC.height = 66; NPC.defense = 50; NPC.LifeMaxNERB(887500, 1065000, 1500000); // Phase 1 is 355000, Phase 2 is 532500 - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/ExoMechs/Apollo/Apollo.cs b/NPCs/ExoMechs/Apollo/Apollo.cs index 37f8031eee..921ccf2b1e 100644 --- a/NPCs/ExoMechs/Apollo/Apollo.cs +++ b/NPCs/ExoMechs/Apollo/Apollo.cs @@ -154,7 +154,7 @@ public override void SetDefaults() NPC.defense = 100; NPC.DR_NERD(0.25f); NPC.LifeMaxNERB(1250000, 1495000, 650000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -1528,7 +1528,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d // This is created to allow easy duplication of them when drawing the charge. void drawInstance(Vector2 drawOffset, Color baseColor) { - if (CalamityConfig.Instance.Afterimages && !NPC.IsABestiaryIconDummy) + if (CalamityClientConfig.Instance.Afterimages && !NPC.IsABestiaryIconDummy) { for (int i = 1; i < numAfterimages; i += 2) { @@ -1599,7 +1599,7 @@ void drawInstance(Vector2 drawOffset, Color baseColor) } texture = GlowTexture.Value; - if (CalamityConfig.Instance.Afterimages && !NPC.IsABestiaryIconDummy) + if (CalamityClientConfig.Instance.Afterimages && !NPC.IsABestiaryIconDummy) { for (int i = 1; i < numAfterimages; i += 2) { diff --git a/NPCs/ExoMechs/Ares/AresBody.cs b/NPCs/ExoMechs/Ares/AresBody.cs index 60852ad353..85b2f69e03 100644 --- a/NPCs/ExoMechs/Ares/AresBody.cs +++ b/NPCs/ExoMechs/Ares/AresBody.cs @@ -225,7 +225,7 @@ public override void SetDefaults() NPC.defense = 100; NPC.DR_NERD(0.35f); NPC.LifeMaxNERB(1250000, 1495000, 650000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -1241,7 +1241,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 vector = new Vector2(NPC.width / 2, NPC.height / 2); int numAfterimages = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < numAfterimages; i += 2) { @@ -1261,7 +1261,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture = GlowTexture.Value; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < numAfterimages; i += 2) { diff --git a/NPCs/ExoMechs/Ares/AresGaussNuke.cs b/NPCs/ExoMechs/Ares/AresGaussNuke.cs index dec6dd8459..859810bba4 100644 --- a/NPCs/ExoMechs/Ares/AresGaussNuke.cs +++ b/NPCs/ExoMechs/Ares/AresGaussNuke.cs @@ -93,7 +93,7 @@ public override void SetDefaults() NPC.defense = 100; NPC.DR_NERD(0.35f); NPC.LifeMaxNERB(1250000, 1495000, 650000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -551,7 +551,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color afterimageBaseColor = Main.npc[(int)NPC.ai[2]].localAI[1] == (float)AresBody.Enraged.Yes ? Color.Red : Color.White; int numAfterimages = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < numAfterimages; i += 2) { @@ -592,7 +592,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Texture2D glowTexture = GlowTexture.Value; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < numAfterimages; i += 2) { diff --git a/NPCs/ExoMechs/Ares/AresLaserCannon.cs b/NPCs/ExoMechs/Ares/AresLaserCannon.cs index cbaacc311a..3e3b5baa47 100644 --- a/NPCs/ExoMechs/Ares/AresLaserCannon.cs +++ b/NPCs/ExoMechs/Ares/AresLaserCannon.cs @@ -96,7 +96,7 @@ public override void SetDefaults() NPC.defense = 100; NPC.DR_NERD(0.35f); NPC.LifeMaxNERB(1250000, 1495000, 650000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -599,7 +599,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color afterimageBaseColor = Main.npc[(int)NPC.ai[2]].localAI[1] == (float)AresBody.Enraged.Yes ? Color.Red : Color.White; int numAfterimages = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < numAfterimages; i += 2) { @@ -638,7 +638,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Texture2D glowTexture = GlowTexture.Value; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < numAfterimages; i += 2) { diff --git a/NPCs/ExoMechs/Ares/AresPlasmaFlamethrower.cs b/NPCs/ExoMechs/Ares/AresPlasmaFlamethrower.cs index 9aef9f09fb..d8b6d55613 100644 --- a/NPCs/ExoMechs/Ares/AresPlasmaFlamethrower.cs +++ b/NPCs/ExoMechs/Ares/AresPlasmaFlamethrower.cs @@ -90,7 +90,7 @@ public override void SetDefaults() NPC.defense = 100; NPC.DR_NERD(0.35f); NPC.LifeMaxNERB(1250000, 1495000, 650000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -550,7 +550,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color afterimageBaseColor = Main.npc[(int)NPC.ai[2]].localAI[1] == (float)AresBody.Enraged.Yes ? Color.Red : Color.White; int numAfterimages = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < numAfterimages; i += 2) { @@ -590,7 +590,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Texture2D glowTexture = GlowTexture.Value; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < numAfterimages; i += 2) { diff --git a/NPCs/ExoMechs/Ares/AresTeslaCannon.cs b/NPCs/ExoMechs/Ares/AresTeslaCannon.cs index 09d77162ed..d9bb7d4994 100644 --- a/NPCs/ExoMechs/Ares/AresTeslaCannon.cs +++ b/NPCs/ExoMechs/Ares/AresTeslaCannon.cs @@ -91,7 +91,7 @@ public override void SetDefaults() NPC.defense = 100; NPC.DR_NERD(0.35f); NPC.LifeMaxNERB(1250000, 1495000, 650000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -545,7 +545,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color afterimageBaseColor = Main.npc[(int)NPC.ai[2]].localAI[1] == (float)AresBody.Enraged.Yes ? Color.Red : Color.White; int numAfterimages = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < numAfterimages; i += 2) { @@ -584,7 +584,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Texture2D glowTexture = GlowTexture.Value; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < numAfterimages; i += 2) { diff --git a/NPCs/ExoMechs/Artemis/Artemis.cs b/NPCs/ExoMechs/Artemis/Artemis.cs index f53b9eead4..5fa230c2a8 100644 --- a/NPCs/ExoMechs/Artemis/Artemis.cs +++ b/NPCs/ExoMechs/Artemis/Artemis.cs @@ -187,7 +187,7 @@ public override void SetDefaults() NPC.defense = 100; NPC.DR_NERD(0.25f); NPC.LifeMaxNERB(1250000, 1495000, 650000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -1423,7 +1423,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d // This is created to allow easy duplication of them when drawing the charge. void drawInstance(Vector2 drawOffset, Color baseColor) { - if (CalamityConfig.Instance.Afterimages && !NPC.IsABestiaryIconDummy) + if (CalamityClientConfig.Instance.Afterimages && !NPC.IsABestiaryIconDummy) { for (int i = 1; i < numAfterimages; i += 2) { @@ -1494,7 +1494,7 @@ void drawInstance(Vector2 drawOffset, Color baseColor) } texture = GlowTexture.Value; - if (CalamityConfig.Instance.Afterimages && !NPC.IsABestiaryIconDummy) + if (CalamityClientConfig.Instance.Afterimages && !NPC.IsABestiaryIconDummy) { for (int i = 1; i < numAfterimages; i += 2) { diff --git a/NPCs/ExoMechs/Thanatos/ThanatosBody1.cs b/NPCs/ExoMechs/Thanatos/ThanatosBody1.cs index 28eb67978c..b9e20ec96c 100644 --- a/NPCs/ExoMechs/Thanatos/ThanatosBody1.cs +++ b/NPCs/ExoMechs/Thanatos/ThanatosBody1.cs @@ -75,7 +75,7 @@ public override void SetDefaults() NPC.DR_NERD(0.9999f); NPC.Calamity().unbreakableDR = true; NPC.LifeMaxNERB(960000, 1150000, 600000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/ExoMechs/Thanatos/ThanatosBody2.cs b/NPCs/ExoMechs/Thanatos/ThanatosBody2.cs index 612ae50f89..3ae03ab9fb 100644 --- a/NPCs/ExoMechs/Thanatos/ThanatosBody2.cs +++ b/NPCs/ExoMechs/Thanatos/ThanatosBody2.cs @@ -74,7 +74,7 @@ public override void SetDefaults() NPC.DR_NERD(0.9999f); NPC.Calamity().unbreakableDR = true; NPC.LifeMaxNERB(960000, 1150000, 600000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/ExoMechs/Thanatos/ThanatosHead.cs b/NPCs/ExoMechs/Thanatos/ThanatosHead.cs index 1dcbca3bc4..410decf566 100644 --- a/NPCs/ExoMechs/Thanatos/ThanatosHead.cs +++ b/NPCs/ExoMechs/Thanatos/ThanatosHead.cs @@ -174,7 +174,7 @@ public override void SetDefaults() NPC.DR_NERD(0.9999f); NPC.Calamity().unbreakableDR = true; NPC.LifeMaxNERB(960000, 1150000, 600000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/ExoMechs/Thanatos/ThanatosTail.cs b/NPCs/ExoMechs/Thanatos/ThanatosTail.cs index 1ceb5d01bc..c16d83f33b 100644 --- a/NPCs/ExoMechs/Thanatos/ThanatosTail.cs +++ b/NPCs/ExoMechs/Thanatos/ThanatosTail.cs @@ -74,7 +74,7 @@ public override void SetDefaults() NPC.DR_NERD(0.9999f); NPC.Calamity().unbreakableDR = true; NPC.LifeMaxNERB(960000, 1150000, 600000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/GreatSandShark/GreatSandShark.cs b/NPCs/GreatSandShark/GreatSandShark.cs index 3d1673db94..c0d7469cc5 100644 --- a/NPCs/GreatSandShark/GreatSandShark.cs +++ b/NPCs/GreatSandShark/GreatSandShark.cs @@ -609,7 +609,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d int eightConst = 8; int afterimageInc = 2; int afterimageCounter = 1; - while (((afterimageInc > 0 && afterimageCounter < eightConst) || (afterimageInc < 0 && afterimageCounter > eightConst)) && CalamityConfig.Instance.Afterimages) + while (((afterimageInc > 0 && afterimageCounter < eightConst) || (afterimageInc < 0 && afterimageCounter > eightConst)) && CalamityClientConfig.Instance.Afterimages) { Color alphaAfterimageColor = NPC.GetAlpha(extraAfterimageColor); { diff --git a/NPCs/HiveMind/DankCreeper.cs b/NPCs/HiveMind/DankCreeper.cs index a6e676023c..f8615597f3 100644 --- a/NPCs/HiveMind/DankCreeper.cs +++ b/NPCs/HiveMind/DankCreeper.cs @@ -32,7 +32,7 @@ public override void SetDefaults() if (Main.getGoodWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); if ((CalamityWorld.LegendaryMode && CalamityWorld.revenge)) diff --git a/NPCs/HiveMind/DarkHeart.cs b/NPCs/HiveMind/DarkHeart.cs index 3432898fdc..f5acf1f9bb 100644 --- a/NPCs/HiveMind/DarkHeart.cs +++ b/NPCs/HiveMind/DarkHeart.cs @@ -32,7 +32,7 @@ public override void SetDefaults() if (Main.getGoodWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; diff --git a/NPCs/HiveMind/HiveBlob.cs b/NPCs/HiveMind/HiveBlob.cs index 6e7c638703..69b6b00e6f 100644 --- a/NPCs/HiveMind/HiveBlob.cs +++ b/NPCs/HiveMind/HiveBlob.cs @@ -37,7 +37,7 @@ public override void SetDefaults() if (Main.getGoodWorld) NPC.lifeMax *= 2; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.9f; diff --git a/NPCs/HiveMind/HiveBlob2.cs b/NPCs/HiveMind/HiveBlob2.cs index 9b3e44fd1f..a69f074473 100644 --- a/NPCs/HiveMind/HiveBlob2.cs +++ b/NPCs/HiveMind/HiveBlob2.cs @@ -40,7 +40,7 @@ public override void SetDefaults() if (Main.getGoodWorld) NPC.lifeMax *= 2; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.9f; diff --git a/NPCs/HiveMind/HiveMind.cs b/NPCs/HiveMind/HiveMind.cs index 868e8357c1..859b5daf63 100644 --- a/NPCs/HiveMind/HiveMind.cs +++ b/NPCs/HiveMind/HiveMind.cs @@ -121,7 +121,7 @@ public override void SetDefaults() NPC.height = 122; NPC.defense = 8; NPC.LifeMaxNERB(7700, 9200, 350000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -315,7 +315,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color afterimageBaseColor = Color.White; int numAfterimages = 5; - if (CalamityConfig.Instance.Afterimages && state != 0) + if (CalamityClientConfig.Instance.Afterimages && state != 0) { for (int i = 1; i < numAfterimages; i += 2) { diff --git a/NPCs/Leviathan/Anahita.cs b/NPCs/Leviathan/Anahita.cs index 270966cff3..f7734fff7d 100644 --- a/NPCs/Leviathan/Anahita.cs +++ b/NPCs/Leviathan/Anahita.cs @@ -66,7 +66,7 @@ public override void SetDefaults() NPC.defense = 20; NPC.DR_NERD(0.2f); NPC.LifeMaxNERB(35000, 42000, 260000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.aiStyle = -1; diff --git a/NPCs/Leviathan/AnahitasIceShield.cs b/NPCs/Leviathan/AnahitasIceShield.cs index a32c37cb9b..9ada36e218 100644 --- a/NPCs/Leviathan/AnahitasIceShield.cs +++ b/NPCs/Leviathan/AnahitasIceShield.cs @@ -39,7 +39,7 @@ public override void SetDefaults() NPC.defense = 10; NPC.DR_NERD(0.5f); NPC.lifeMax = BossRushEvent.BossRushActive ? 1000 : 650; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.alpha = 255; NPC.HitSound = SoundID.NPCHit5; diff --git a/NPCs/Leviathan/AquaticAberration.cs b/NPCs/Leviathan/AquaticAberration.cs index e98ae031d8..524778f29c 100644 --- a/NPCs/Leviathan/AquaticAberration.cs +++ b/NPCs/Leviathan/AquaticAberration.cs @@ -43,7 +43,7 @@ public override void SetDefaults() NPC.height = 50; NPC.defense = 14; NPC.lifeMax = BossRushEvent.BossRushActive ? 10000 : 600; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.2f; NPC.noGravity = true; diff --git a/NPCs/Leviathan/Leviathan.cs b/NPCs/Leviathan/Leviathan.cs index 4a94c6e0e9..87e60c6fed 100644 --- a/NPCs/Leviathan/Leviathan.cs +++ b/NPCs/Leviathan/Leviathan.cs @@ -66,7 +66,7 @@ public override void SetDefaults() NPC.defense = 40; NPC.DR_NERD(0.35f); NPC.LifeMaxNERB(60000, 72000, 600000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.aiStyle = -1; diff --git a/NPCs/NormalNPCs/BloodlettingServant.cs b/NPCs/NormalNPCs/BloodlettingServant.cs index 879a389f03..b31d1d20a2 100644 --- a/NPCs/NormalNPCs/BloodlettingServant.cs +++ b/NPCs/NormalNPCs/BloodlettingServant.cs @@ -45,7 +45,7 @@ public override void SetDefaults() NPC.defense = 5; NPC.lifeMax = 96; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; @@ -259,7 +259,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d float telegraphScalar = MathHelper.Clamp((NPC.ai[0] - ChargeTelegraphGateValue) / ChargeTelegraphGateValue, 0f, 1f); Color telegraphColor = Color.Lerp(originalColor, newColor, telegraphScalar); - if (CalamityConfig.Instance.Afterimages && NPC.ai[1] > 0f) + if (CalamityClientConfig.Instance.Afterimages && NPC.ai[1] > 0f) { int afterimageAmount = 10; int afterImageIncrement = 2; diff --git a/NPCs/NormalNPCs/IceClasper.cs b/NPCs/NormalNPCs/IceClasper.cs index fca3afe2b1..0f98304a97 100644 --- a/NPCs/NormalNPCs/IceClasper.cs +++ b/NPCs/NormalNPCs/IceClasper.cs @@ -342,7 +342,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d (MathHelper.Clamp(AITimer, 0f, TimeBeforeDash) / TimeBeforeDash); float AfterimageFade = MathHelper.Lerp(0f, 1f, interpolant); - if (CurrentState == IceClasperAIState.Dashing && CalamityConfig.Instance.Afterimages) + if (CurrentState == IceClasperAIState.Dashing && CalamityClientConfig.Instance.Afterimages) { for (int i = 0; i < NPC.oldPos.Length; i++) { diff --git a/NPCs/NormalNPCs/KingSlimeJewelEmerald.cs b/NPCs/NormalNPCs/KingSlimeJewelEmerald.cs index 5d5160792f..80fad53f46 100644 --- a/NPCs/NormalNPCs/KingSlimeJewelEmerald.cs +++ b/NPCs/NormalNPCs/KingSlimeJewelEmerald.cs @@ -36,7 +36,7 @@ public override void SetDefaults() NPC.DR_NERD(0.15f); NPC.lifeMax = 240; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.7f; diff --git a/NPCs/NormalNPCs/KingSlimeJewelRuby.cs b/NPCs/NormalNPCs/KingSlimeJewelRuby.cs index 327d1d0054..fe60d9a411 100644 --- a/NPCs/NormalNPCs/KingSlimeJewelRuby.cs +++ b/NPCs/NormalNPCs/KingSlimeJewelRuby.cs @@ -36,7 +36,7 @@ public override void SetDefaults() NPC.DR_NERD(0.1f); NPC.lifeMax = 120; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.8f; diff --git a/NPCs/NormalNPCs/KingSlimeJewelSapphire.cs b/NPCs/NormalNPCs/KingSlimeJewelSapphire.cs index a41db05782..1aa81eac91 100644 --- a/NPCs/NormalNPCs/KingSlimeJewelSapphire.cs +++ b/NPCs/NormalNPCs/KingSlimeJewelSapphire.cs @@ -35,7 +35,7 @@ public override void SetDefaults() NPC.DR_NERD(0.05f); NPC.lifeMax = 120; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.9f; diff --git a/NPCs/NormalNPCs/PlanterasFreeTentacle.cs b/NPCs/NormalNPCs/PlanterasFreeTentacle.cs index f3912e4d09..d86011b3c5 100644 --- a/NPCs/NormalNPCs/PlanterasFreeTentacle.cs +++ b/NPCs/NormalNPCs/PlanterasFreeTentacle.cs @@ -38,7 +38,7 @@ public override void SetDefaults() NPC.defense = 20; NPC.lifeMax = 500; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.4f; diff --git a/NPCs/NormalNPCs/SkeletronPrime2.cs b/NPCs/NormalNPCs/SkeletronPrime2.cs index 5fb331870b..2e7c5a641d 100644 --- a/NPCs/NormalNPCs/SkeletronPrime2.cs +++ b/NPCs/NormalNPCs/SkeletronPrime2.cs @@ -52,7 +52,7 @@ public override void SetDefaults() NPC.defense = 24; NPC.lifeMax = 28000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; @@ -399,7 +399,7 @@ public override void AI() int damage = NPC.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -664,7 +664,7 @@ public override void AI() int damage = NPC.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -732,7 +732,7 @@ public override void AI() int damage = NPC.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; diff --git a/NPCs/NormalNPCs/WildBumblefuck.cs b/NPCs/NormalNPCs/WildBumblefuck.cs index 8421f495ff..95f5122d35 100644 --- a/NPCs/NormalNPCs/WildBumblefuck.cs +++ b/NPCs/NormalNPCs/WildBumblefuck.cs @@ -129,7 +129,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2(TextureAssets.Npc[NPC.type].Value.Width / 2, TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2); int afterimageAmt = NPC.ai[0] == 2.1f ? 7 : 0; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { diff --git a/NPCs/OldDuke/OldDuke.cs b/NPCs/OldDuke/OldDuke.cs index fc8ac6e7b3..745133b9e7 100644 --- a/NPCs/OldDuke/OldDuke.cs +++ b/NPCs/OldDuke/OldDuke.cs @@ -73,7 +73,7 @@ public override void SetDefaults() NPC.defense = 90; NPC.DR_NERD(0.5f, null, null, null, true); NPC.LifeMaxNERB(500000, 600000, 400000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.noTileCollide = true; @@ -258,7 +258,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d color = drawColor; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += afterimageIncrement) { @@ -309,7 +309,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d afterimageScale = 20f; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 0; j < secondAfterimageAmt; j++) { @@ -365,7 +365,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d yellowLerpColor *= ai2Opacity; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int k = 1; k < afterimageAmt; k += afterimageIncrement) { diff --git a/NPCs/OldDuke/OldDukeToothBall.cs b/NPCs/OldDuke/OldDukeToothBall.cs index f880849a6e..83b18e5d9b 100644 --- a/NPCs/OldDuke/OldDukeToothBall.cs +++ b/NPCs/OldDuke/OldDukeToothBall.cs @@ -32,7 +32,7 @@ public override void SetDefaults() { NPC.lifeMax = 16000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.2f; NPC.HitSound = SoundID.NPCHit1; diff --git a/NPCs/OldDuke/SulphurousSharkron.cs b/NPCs/OldDuke/SulphurousSharkron.cs index f1480f9f0a..6e8113b600 100644 --- a/NPCs/OldDuke/SulphurousSharkron.cs +++ b/NPCs/OldDuke/SulphurousSharkron.cs @@ -39,7 +39,7 @@ public override void SetDefaults() { NPC.lifeMax = 10000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.HitSound = SoundID.NPCHit1; NPC.DeathSound = SoundID.NPCDeath1; @@ -245,7 +245,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2(TextureAssets.Npc[NPC.type].Value.Width / 2, TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2); int afterimageAmt = 10; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { diff --git a/NPCs/Perforator/PerforatorBodyLarge.cs b/NPCs/Perforator/PerforatorBodyLarge.cs index c824477afd..6be18b93b6 100644 --- a/NPCs/Perforator/PerforatorBodyLarge.cs +++ b/NPCs/Perforator/PerforatorBodyLarge.cs @@ -47,7 +47,7 @@ public override void SetDefaults() if (Main.zenithWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/Perforator/PerforatorBodyMedium.cs b/NPCs/Perforator/PerforatorBodyMedium.cs index 0c274ba469..ddaee3bf97 100644 --- a/NPCs/Perforator/PerforatorBodyMedium.cs +++ b/NPCs/Perforator/PerforatorBodyMedium.cs @@ -45,7 +45,7 @@ public override void SetDefaults() if (Main.zenithWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/Perforator/PerforatorBodySmall.cs b/NPCs/Perforator/PerforatorBodySmall.cs index a72dcb34be..22649de4aa 100644 --- a/NPCs/Perforator/PerforatorBodySmall.cs +++ b/NPCs/Perforator/PerforatorBodySmall.cs @@ -42,7 +42,7 @@ public override void SetDefaults() if (Main.zenithWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/Perforator/PerforatorHeadLarge.cs b/NPCs/Perforator/PerforatorHeadLarge.cs index 82a6499720..c29eb9782f 100644 --- a/NPCs/Perforator/PerforatorHeadLarge.cs +++ b/NPCs/Perforator/PerforatorHeadLarge.cs @@ -62,7 +62,7 @@ public override void SetDefaults() if (Main.zenithWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/Perforator/PerforatorHeadMedium.cs b/NPCs/Perforator/PerforatorHeadMedium.cs index 9283bbbce1..7b1858cd10 100644 --- a/NPCs/Perforator/PerforatorHeadMedium.cs +++ b/NPCs/Perforator/PerforatorHeadMedium.cs @@ -58,7 +58,7 @@ public override void SetDefaults() if (Main.zenithWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/Perforator/PerforatorHeadSmall.cs b/NPCs/Perforator/PerforatorHeadSmall.cs index acb6d6318a..a0e4994598 100644 --- a/NPCs/Perforator/PerforatorHeadSmall.cs +++ b/NPCs/Perforator/PerforatorHeadSmall.cs @@ -61,7 +61,7 @@ public override void SetDefaults() if (Main.zenithWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/Perforator/PerforatorHive.cs b/NPCs/Perforator/PerforatorHive.cs index 92c52757ba..fbeaf2b06f 100644 --- a/NPCs/Perforator/PerforatorHive.cs +++ b/NPCs/Perforator/PerforatorHive.cs @@ -72,7 +72,7 @@ public override void SetDefaults() NPC.height = 100; NPC.defense = 4; NPC.LifeMaxNERB(6000, 7200, 270000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/Perforator/PerforatorTailLarge.cs b/NPCs/Perforator/PerforatorTailLarge.cs index 2bfc0f7eef..656d1ee34e 100644 --- a/NPCs/Perforator/PerforatorTailLarge.cs +++ b/NPCs/Perforator/PerforatorTailLarge.cs @@ -42,7 +42,7 @@ public override void SetDefaults() if (Main.zenithWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/Perforator/PerforatorTailMedium.cs b/NPCs/Perforator/PerforatorTailMedium.cs index f5128e40f5..018a21c9d9 100644 --- a/NPCs/Perforator/PerforatorTailMedium.cs +++ b/NPCs/Perforator/PerforatorTailMedium.cs @@ -45,7 +45,7 @@ public override void SetDefaults() if (Main.zenithWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/Perforator/PerforatorTailSmall.cs b/NPCs/Perforator/PerforatorTailSmall.cs index 3653234a47..264bb06e18 100644 --- a/NPCs/Perforator/PerforatorTailSmall.cs +++ b/NPCs/Perforator/PerforatorTailSmall.cs @@ -42,7 +42,7 @@ public override void SetDefaults() if (Main.zenithWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/PlagueEnemies/PlagueCharger.cs b/NPCs/PlagueEnemies/PlagueCharger.cs index 1f79c757cc..94015d6530 100644 --- a/NPCs/PlagueEnemies/PlagueCharger.cs +++ b/NPCs/PlagueEnemies/PlagueCharger.cs @@ -77,7 +77,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2((float)(TextureAssets.Npc[NPC.type].Value.Width / 2), (float)(TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2)); int afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -100,7 +100,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture2D15 = GlowTexture.Value; Color redEyeColor = Color.Lerp(Color.White, Color.Red, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/PlagueEnemies/PlagueChargerLarge.cs b/NPCs/PlagueEnemies/PlagueChargerLarge.cs index c6b4e66b75..c0aadd70db 100644 --- a/NPCs/PlagueEnemies/PlagueChargerLarge.cs +++ b/NPCs/PlagueEnemies/PlagueChargerLarge.cs @@ -72,7 +72,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2((float)(TextureAssets.Npc[NPC.type].Value.Width / 2), (float)(TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2)); int afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -95,7 +95,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture2D15 = ModContent.Request("CalamityMod/NPCs/PlagueEnemies/PlagueChargerGlow").Value; Color redEyeColor = Color.Lerp(Color.White, Color.Red, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/PlagueEnemies/PlaguebringerMiniboss.cs b/NPCs/PlagueEnemies/PlaguebringerMiniboss.cs index d8abae06ac..6cae925162 100644 --- a/NPCs/PlagueEnemies/PlaguebringerMiniboss.cs +++ b/NPCs/PlagueEnemies/PlaguebringerMiniboss.cs @@ -337,7 +337,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d if (NPC.ai[0] != 0f) afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { diff --git a/NPCs/PlaguebringerGoliath/PlagueHomingMissile.cs b/NPCs/PlaguebringerGoliath/PlagueHomingMissile.cs index a01811e7b6..8b26d7e1aa 100644 --- a/NPCs/PlaguebringerGoliath/PlagueHomingMissile.cs +++ b/NPCs/PlaguebringerGoliath/PlagueHomingMissile.cs @@ -37,7 +37,7 @@ public override void SetDefaults() NPC.height = 22; NPC.defense = 20; NPC.lifeMax = BossRushEvent.BossRushActive ? 5000 : 500; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -170,7 +170,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2((float)(TextureAssets.Npc[NPC.type].Value.Width / 2), (float)(TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2)); int afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -193,7 +193,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture2D15 = GlowTexture.Value; Color redLerpColor = Color.Lerp(Color.White, Color.Red, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/PlaguebringerGoliath/PlagueMine.cs b/NPCs/PlaguebringerGoliath/PlagueMine.cs index efca4ac339..7df52f7db9 100644 --- a/NPCs/PlaguebringerGoliath/PlagueMine.cs +++ b/NPCs/PlaguebringerGoliath/PlagueMine.cs @@ -35,7 +35,7 @@ public override void SetDefaults() NPC.height = 42; NPC.defense = 20; NPC.lifeMax = BossRushEvent.BossRushActive ? 10000 : 1000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/PlaguebringerGoliath/PlaguebringerGoliath.cs b/NPCs/PlaguebringerGoliath/PlaguebringerGoliath.cs index 9d570cee10..c013757851 100644 --- a/NPCs/PlaguebringerGoliath/PlaguebringerGoliath.cs +++ b/NPCs/PlaguebringerGoliath/PlaguebringerGoliath.cs @@ -91,7 +91,7 @@ public override void SetDefaults() NPC.defense = 50; NPC.DR_NERD(0.3f); NPC.LifeMaxNERB(87500, 105000, 370000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.aiStyle = -1; @@ -1264,7 +1264,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d if (NPC.ai[0] != 0f && NPC.ai[0] != 4f) afterimageAmt = 7; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j += 2) { @@ -1286,7 +1286,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color redLerpColor = Color.Lerp(Color.White, Color.Red, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int k = 1; k < afterimageAmt; k++) { diff --git a/NPCs/Polterghast/PhantomFuckYou.cs b/NPCs/Polterghast/PhantomFuckYou.cs index 8856bddc30..e10c08cfad 100644 --- a/NPCs/Polterghast/PhantomFuckYou.cs +++ b/NPCs/Polterghast/PhantomFuckYou.cs @@ -34,7 +34,7 @@ public override void SetDefaults() NPC.noTileCollide = true; NPC.damage = 50; NPC.lifeMax = 20000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.HitSound = SoundID.NPCHit36; NPC.DeathSound = SoundID.NPCDeath39; @@ -153,7 +153,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2(TextureAssets.Npc[NPC.type].Value.Width / 2, TextureAssets.Npc[NPC.type].Value.Height / 2); int afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { diff --git a/NPCs/Polterghast/PolterPhantom.cs b/NPCs/Polterghast/PolterPhantom.cs index 6724039449..386e63a586 100644 --- a/NPCs/Polterghast/PolterPhantom.cs +++ b/NPCs/Polterghast/PolterPhantom.cs @@ -47,7 +47,7 @@ public override void SetDefaults() if (CalamityWorld.LegendaryMode && CalamityWorld.revenge) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.aiStyle = -1; @@ -454,7 +454,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color lightRed = new Color(255, 100, 100, 255) * NPC.Opacity; int afterimageAmt = 7; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -489,7 +489,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color blackWhiteLerp = Color.Lerp(Color.White, c, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/Polterghast/Polterghast.cs b/NPCs/Polterghast/Polterghast.cs index 1c8833c123..06987bfa38 100644 --- a/NPCs/Polterghast/Polterghast.cs +++ b/NPCs/Polterghast/Polterghast.cs @@ -116,7 +116,7 @@ public override void SetDefaults() NPC.defense = 90; NPC.DR_NERD(0.2f); NPC.LifeMaxNERB(350000, 420000, 325000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.aiStyle = -1; @@ -306,7 +306,7 @@ public override void AI() } // Stop rain - if (CalamityConfig.Instance.BossesStopWeather) + if (CalamityServerConfig.Instance.BossesStopWeather) CalamityMod.StopRain(); // Set time left @@ -1164,7 +1164,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2(TextureAssets.Npc[NPC.type].Value.Width / 2, TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2); int afterimageAmt = 7; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -1208,7 +1208,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color veinColor = Color.Lerp(Color.White, (NPC.ai[2] >= changeColorGateValue || NPC.Calamity().newAI[0] > changeColorGateValue) ? Color.Red : Color.Black, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/Polterghast/PolterghastHook.cs b/NPCs/Polterghast/PolterghastHook.cs index 50c6039a49..be8e568245 100644 --- a/NPCs/Polterghast/PolterghastHook.cs +++ b/NPCs/Polterghast/PolterghastHook.cs @@ -375,7 +375,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2(TextureAssets.Npc[NPC.type].Value.Width / 2, TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2); int afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -401,7 +401,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d if (Main.npc[CalamityGlobalNPC.ghostBoss].Calamity().newAI[0] > changeColorGateValue) cyanLerp2 = Color.Lerp(cyanLerp2, lightRed, MathHelper.Clamp((Main.npc[CalamityGlobalNPC.ghostBoss].Calamity().newAI[0] - changeColorGateValue) / timeToReachFullColor, 0f, 1f)); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/PrimordialWyrm/PrimordialWyrmBody.cs b/NPCs/PrimordialWyrm/PrimordialWyrmBody.cs index 1de74e9cf4..8c781cda95 100644 --- a/NPCs/PrimordialWyrm/PrimordialWyrmBody.cs +++ b/NPCs/PrimordialWyrm/PrimordialWyrmBody.cs @@ -35,7 +35,7 @@ public override void SetDefaults() NPC.height = 88; NPC.defense = 0; NPC.LifeMaxNERB(2500000, 3000000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/PrimordialWyrm/PrimordialWyrmBodyAlt.cs b/NPCs/PrimordialWyrm/PrimordialWyrmBodyAlt.cs index aa679618c5..ab0e39e298 100644 --- a/NPCs/PrimordialWyrm/PrimordialWyrmBodyAlt.cs +++ b/NPCs/PrimordialWyrm/PrimordialWyrmBodyAlt.cs @@ -34,7 +34,7 @@ public override void SetDefaults() NPC.height = 88; NPC.defense = 0; NPC.LifeMaxNERB(2500000, 3000000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/PrimordialWyrm/PrimordialWyrmHead.cs b/NPCs/PrimordialWyrm/PrimordialWyrmHead.cs index 93ff213d5f..e639fd28ab 100644 --- a/NPCs/PrimordialWyrm/PrimordialWyrmHead.cs +++ b/NPCs/PrimordialWyrm/PrimordialWyrmHead.cs @@ -112,7 +112,7 @@ public override void SetDefaults() NPC.width = 254; NPC.height = 138; NPC.LifeMaxNERB(2500000, 3000000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/PrimordialWyrm/PrimordialWyrmTail.cs b/NPCs/PrimordialWyrm/PrimordialWyrmTail.cs index 8b9b49021b..c9ab0e90ec 100644 --- a/NPCs/PrimordialWyrm/PrimordialWyrmTail.cs +++ b/NPCs/PrimordialWyrm/PrimordialWyrmTail.cs @@ -33,7 +33,7 @@ public override void SetDefaults() NPC.height = 120; NPC.defense = 0; NPC.LifeMaxNERB(2500000, 3000000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs b/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs index a98ab63273..28605cc0a8 100644 --- a/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs +++ b/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs @@ -75,7 +75,7 @@ public override void SetDefaults() NPC.defense = 40; NPC.DR_NERD(0.3f); NPC.LifeMaxNERB(100000, 120000, 200000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.noGravity = true; @@ -1015,7 +1015,7 @@ void drawGuardianInstance(Vector2 drawOffset, Color? colorOverride) if (NPC.ai[0] == 2f) afterimageAmt = 10; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -1053,7 +1053,7 @@ void drawGuardianInstance(Vector2 drawOffset, Color? colorOverride) if (colorOverride != null) timeBasedColorLerp = colorOverride.Value; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/ProfanedGuardians/ProfanedGuardianDefender.cs b/NPCs/ProfanedGuardians/ProfanedGuardianDefender.cs index b4033cedc5..465d95f646 100644 --- a/NPCs/ProfanedGuardians/ProfanedGuardianDefender.cs +++ b/NPCs/ProfanedGuardians/ProfanedGuardianDefender.cs @@ -65,7 +65,7 @@ public override void SetDefaults() NPC.defense = 50; NPC.DR_NERD(0.4f); NPC.LifeMaxNERB(40000, 48000, 35000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.noGravity = true; @@ -738,7 +738,7 @@ void drawGuardianInstance(Vector2 drawOffset, Color? colorOverride) if (NPC.ai[0] == 2f) afterimageAmt = 10; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -776,7 +776,7 @@ void drawGuardianInstance(Vector2 drawOffset, Color? colorOverride) if (colorOverride != null) timeBasedGlowColor = colorOverride.Value; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/ProfanedGuardians/ProfanedGuardianHealer.cs b/NPCs/ProfanedGuardians/ProfanedGuardianHealer.cs index 03ed34ed59..53074dc77b 100644 --- a/NPCs/ProfanedGuardians/ProfanedGuardianHealer.cs +++ b/NPCs/ProfanedGuardians/ProfanedGuardianHealer.cs @@ -78,7 +78,7 @@ public override void SetDefaults() NPC.defense = 30; NPC.DR_NERD(0.2f); NPC.LifeMaxNERB(60000, 72000, 50000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.noGravity = true; @@ -443,7 +443,7 @@ void drawGuardianInstance(Vector2 drawOffset, Color? colorOverride) Vector2 halfSizeTexture = new Vector2(TextureAssets.Npc[NPC.type].Value.Width / 2, TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2); int afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -485,7 +485,7 @@ void drawGuardianInstance(Vector2 drawOffset, Color? colorOverride) overrideColor = colorOverride.Value; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/ProfanedGuardians/ProfanedRocks.cs b/NPCs/ProfanedGuardians/ProfanedRocks.cs index 6e8de8df02..1163bdc1c3 100644 --- a/NPCs/ProfanedGuardians/ProfanedRocks.cs +++ b/NPCs/ProfanedGuardians/ProfanedRocks.cs @@ -50,7 +50,7 @@ public override void SetDefaults() NPC.height = 50; NPC.defense = 100; NPC.lifeMax = BossRushEvent.BossRushActive ? MaxBossRushHP : MaxHP; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.Opacity = 0f; diff --git a/NPCs/Providence/ProvSpawnDefense.cs b/NPCs/Providence/ProvSpawnDefense.cs index 0e2e9a8d0d..40a19d10d8 100644 --- a/NPCs/Providence/ProvSpawnDefense.cs +++ b/NPCs/Providence/ProvSpawnDefense.cs @@ -41,7 +41,7 @@ public override void SetDefaults() { NPC.lifeMax = 30000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.noGravity = true; @@ -122,7 +122,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2((float)(TextureAssets.Npc[NPC.type].Value.Width / 2), (float)(TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2)); int afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -145,7 +145,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture2D15 = ProfanedGuardianDefender.Texture_Glow.Value; Color yellowLerp = Color.Lerp(Color.White, Color.Yellow, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/Providence/ProvSpawnHealer.cs b/NPCs/Providence/ProvSpawnHealer.cs index 9d1aa49894..3988b3f8ce 100644 --- a/NPCs/Providence/ProvSpawnHealer.cs +++ b/NPCs/Providence/ProvSpawnHealer.cs @@ -40,7 +40,7 @@ public override void SetDefaults() { NPC.lifeMax = 20000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.noGravity = true; @@ -122,7 +122,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2((float)(TextureAssets.Npc[NPC.type].Value.Width / 2), (float)(TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2)); int afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -146,7 +146,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color yellowLerp = Color.Lerp(Color.White, Color.Yellow, 0.5f); Color violetLerp = Color.Lerp(Color.White, Color.Violet, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/Providence/ProvSpawnOffense.cs b/NPCs/Providence/ProvSpawnOffense.cs index faa67a7dfa..0ecc8a9d0b 100644 --- a/NPCs/Providence/ProvSpawnOffense.cs +++ b/NPCs/Providence/ProvSpawnOffense.cs @@ -41,7 +41,7 @@ public override void SetDefaults() { NPC.lifeMax = 40000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.noGravity = true; @@ -124,7 +124,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d if (NPC.ai[0] == 2f) afterimageAmt = 10; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -147,7 +147,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture2D15 = ProfanedGuardianCommander.Texture_Glow.Value; Color yellowLerpColor = Color.Lerp(Color.White, Color.Yellow, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/Providence/Providence.cs b/NPCs/Providence/Providence.cs index aeb2b7d136..470f8361fa 100644 --- a/NPCs/Providence/Providence.cs +++ b/NPCs/Providence/Providence.cs @@ -229,7 +229,7 @@ public override void SetDefaults() NPC.defense = 50; NPC.DR_NERD(normalDR); NPC.LifeMaxNERB(312500, 375000, 1250000); // Old HP - 440000, 500000 - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.aiStyle = -1; @@ -613,7 +613,7 @@ public override void AI() NPC.chaseable = normalAttackRate; // Prevent lag by stopping rain - if (CalamityConfig.Instance.BossesStopWeather) + if (CalamityServerConfig.Instance.BossesStopWeather) CalamityMod.StopRain(); // Set target biome type @@ -2206,7 +2206,7 @@ void drawProvidenceInstance(Vector2 drawOffset, Color? colorOverride) float Brightness = 0.5f; // Ranges from 0 (full vibrance) to 1 (pure white) int maxAfterimages = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < maxAfterimages; i += 2) { @@ -2270,7 +2270,7 @@ void drawProvidenceInstance(Vector2 drawOffset, Color? colorOverride) BaseCrystalColor = colorOverride.Value; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < maxAfterimages; j++) { diff --git a/NPCs/Ravager/FlamePillar.cs b/NPCs/Ravager/FlamePillar.cs index 933d5a4a8e..ca0b5a9738 100644 --- a/NPCs/Ravager/FlamePillar.cs +++ b/NPCs/Ravager/FlamePillar.cs @@ -36,7 +36,7 @@ public override void SetDefaults() NPC.DR_NERD(0.2f); NPC.chaseable = false; NPC.lifeMax = DownedBossSystem.downedProvidence ? 14000 : 3500; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.alpha = 255; NPC.aiStyle = -1; diff --git a/NPCs/Ravager/RavagerBody.cs b/NPCs/Ravager/RavagerBody.cs index 09b76c70fb..7c2a14c120 100644 --- a/NPCs/Ravager/RavagerBody.cs +++ b/NPCs/Ravager/RavagerBody.cs @@ -90,7 +90,7 @@ public override void SetDefaults() NPC.lifeMax *= 4; NPC.value *= 1.5f; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; AIType = -1; diff --git a/NPCs/Ravager/RavagerClawLeft.cs b/NPCs/Ravager/RavagerClawLeft.cs index 218826ba88..d3d52720cf 100644 --- a/NPCs/Ravager/RavagerClawLeft.cs +++ b/NPCs/Ravager/RavagerClawLeft.cs @@ -48,7 +48,7 @@ public override void SetDefaults() { NPC.lifeMax = 26000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.Calamity().VulnerableToSickness = false; NPC.Calamity().VulnerableToWater = true; diff --git a/NPCs/Ravager/RavagerClawRight.cs b/NPCs/Ravager/RavagerClawRight.cs index 360d61c8a6..20a9ef22a7 100644 --- a/NPCs/Ravager/RavagerClawRight.cs +++ b/NPCs/Ravager/RavagerClawRight.cs @@ -48,7 +48,7 @@ public override void SetDefaults() { NPC.lifeMax = 26000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.Calamity().VulnerableToSickness = false; NPC.Calamity().VulnerableToWater = true; diff --git a/NPCs/Ravager/RavagerHead.cs b/NPCs/Ravager/RavagerHead.cs index b0ff5f487d..27fa02895a 100644 --- a/NPCs/Ravager/RavagerHead.cs +++ b/NPCs/Ravager/RavagerHead.cs @@ -45,7 +45,7 @@ public override void SetDefaults() { NPC.lifeMax = 45000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.Calamity().VulnerableToSickness = false; NPC.Calamity().VulnerableToWater = true; diff --git a/NPCs/Ravager/RavagerHead2.cs b/NPCs/Ravager/RavagerHead2.cs index ccaa1b8db8..2e02f21309 100644 --- a/NPCs/Ravager/RavagerHead2.cs +++ b/NPCs/Ravager/RavagerHead2.cs @@ -44,7 +44,7 @@ public override void SetDefaults() { NPC.lifeMax = 22500; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.Calamity().VulnerableToSickness = false; NPC.Calamity().VulnerableToWater = true; diff --git a/NPCs/Ravager/RavagerLegLeft.cs b/NPCs/Ravager/RavagerLegLeft.cs index 9c1c8355b5..fcccbce5fe 100644 --- a/NPCs/Ravager/RavagerLegLeft.cs +++ b/NPCs/Ravager/RavagerLegLeft.cs @@ -41,7 +41,7 @@ public override void SetDefaults() { NPC.lifeMax = 40000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.Calamity().VulnerableToSickness = false; NPC.Calamity().VulnerableToWater = true; diff --git a/NPCs/Ravager/RavagerLegRight.cs b/NPCs/Ravager/RavagerLegRight.cs index 01ba1268f8..0278f3ad51 100644 --- a/NPCs/Ravager/RavagerLegRight.cs +++ b/NPCs/Ravager/RavagerLegRight.cs @@ -41,7 +41,7 @@ public override void SetDefaults() { NPC.lifeMax = 40000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.Calamity().VulnerableToSickness = false; NPC.Calamity().VulnerableToWater = true; diff --git a/NPCs/Ravager/RockPillar.cs b/NPCs/Ravager/RockPillar.cs index 7af3541cc5..6d14900915 100644 --- a/NPCs/Ravager/RockPillar.cs +++ b/NPCs/Ravager/RockPillar.cs @@ -28,7 +28,7 @@ public override void SetDefaults() NPC.DR_NERD(0.3f); NPC.chaseable = false; NPC.lifeMax = DownedBossSystem.downedProvidence ? 20000 : 5000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.alpha = 255; NPC.aiStyle = -1; diff --git a/NPCs/Signus/CosmicLantern.cs b/NPCs/Signus/CosmicLantern.cs index b3ba7cb89d..c0514c1009 100644 --- a/NPCs/Signus/CosmicLantern.cs +++ b/NPCs/Signus/CosmicLantern.cs @@ -36,7 +36,7 @@ public override void SetDefaults() NPC.height = 25; NPC.defense = 50; NPC.lifeMax = 25; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.alpha = 255; NPC.knockBackResist = 0.85f; @@ -133,7 +133,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2((float)(TextureAssets.Npc[NPC.type].Value.Width / 2), (float)(TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2)); int afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -156,7 +156,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture2D15 = GlowTexture.Value; Color cyanLerp = Color.Lerp(Color.White, Color.Cyan, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/Signus/CosmicMine.cs b/NPCs/Signus/CosmicMine.cs index 7a5e64484a..d4e67c6706 100644 --- a/NPCs/Signus/CosmicMine.cs +++ b/NPCs/Signus/CosmicMine.cs @@ -28,7 +28,7 @@ public override void SetDefaults() NPC.width = 30; NPC.height = 30; NPC.lifeMax = 4800; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -179,7 +179,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2(TextureAssets.Npc[NPC.type].Value.Width / 2, TextureAssets.Npc[NPC.type].Value.Height / 2); int afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { diff --git a/NPCs/Signus/Signus.cs b/NPCs/Signus/Signus.cs index 997ff5f25a..21b1df60af 100644 --- a/NPCs/Signus/Signus.cs +++ b/NPCs/Signus/Signus.cs @@ -79,7 +79,7 @@ public override void SetDefaults() NPC.defense = 60; NPC.LifeMaxNERB(300000, 360000, 320000); NPC.value = Item.buyPrice(2, 0, 0, 0); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.aiStyle = -1; @@ -851,7 +851,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d transparency = (100 - (stealthTimer - 300)) * 0.01f; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -877,7 +877,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d eyeGlowColor = Color.MediumBlue; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/SlimeGod/CorruptSlimeSpawn.cs b/NPCs/SlimeGod/CorruptSlimeSpawn.cs index b3f43e7cbd..8e84e52535 100644 --- a/NPCs/SlimeGod/CorruptSlimeSpawn.cs +++ b/NPCs/SlimeGod/CorruptSlimeSpawn.cs @@ -31,7 +31,7 @@ public override void SetDefaults() NPC.defense = 6; NPC.lifeMax = BossRushEvent.BossRushActive ? 10000 : (CalamityWorld.LegendaryMode && CalamityWorld.revenge) ? 360 : 180; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.7f; AnimationType = 121; diff --git a/NPCs/SlimeGod/CorruptSlimeSpawn2.cs b/NPCs/SlimeGod/CorruptSlimeSpawn2.cs index 9842a5070c..c13229bb4b 100644 --- a/NPCs/SlimeGod/CorruptSlimeSpawn2.cs +++ b/NPCs/SlimeGod/CorruptSlimeSpawn2.cs @@ -30,7 +30,7 @@ public override void SetDefaults() NPC.defense = 4; NPC.lifeMax = BossRushEvent.BossRushActive ? 5000 : (CalamityWorld.LegendaryMode && CalamityWorld.revenge) ? 180 : 90; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.9f; AnimationType = NPCID.CorruptSlime; diff --git a/NPCs/SlimeGod/CrimsonSlimeSpawn.cs b/NPCs/SlimeGod/CrimsonSlimeSpawn.cs index 14e3462383..7f2a7b3aa3 100644 --- a/NPCs/SlimeGod/CrimsonSlimeSpawn.cs +++ b/NPCs/SlimeGod/CrimsonSlimeSpawn.cs @@ -29,7 +29,7 @@ public override void SetDefaults() NPC.defense = 4; NPC.lifeMax = BossRushEvent.BossRushActive ? 10000 : (CalamityWorld.LegendaryMode && CalamityWorld.revenge) ? 220 : 110; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.8f; AnimationType = NPCID.CorruptSlime; diff --git a/NPCs/SlimeGod/CrimsonSlimeSpawn2.cs b/NPCs/SlimeGod/CrimsonSlimeSpawn2.cs index cec25e0cb4..de73692425 100644 --- a/NPCs/SlimeGod/CrimsonSlimeSpawn2.cs +++ b/NPCs/SlimeGod/CrimsonSlimeSpawn2.cs @@ -34,7 +34,7 @@ public override void SetDefaults() NPC.defense = 6; NPC.lifeMax = BossRushEvent.BossRushActive ? 12000 : (CalamityWorld.LegendaryMode && CalamityWorld.revenge) ? 260 : 130; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.7f; NPC.Opacity = 0.8f; diff --git a/NPCs/SlimeGod/CrimulanPaladin.cs b/NPCs/SlimeGod/CrimulanPaladin.cs index 8d7147dc4d..52c313c6fb 100644 --- a/NPCs/SlimeGod/CrimulanPaladin.cs +++ b/NPCs/SlimeGod/CrimulanPaladin.cs @@ -32,7 +32,7 @@ public override void SetDefaults() NPC.scale = 1.1f; NPC.defense = 12; NPC.LifeMaxNERB(7500, 9000, 160000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.BossBar = Main.BigBossProgressBar.NeverValid; NPC.knockBackResist = 0f; diff --git a/NPCs/SlimeGod/EbonianPaladin.cs b/NPCs/SlimeGod/EbonianPaladin.cs index fe2ae3f8a7..a3558eacc3 100644 --- a/NPCs/SlimeGod/EbonianPaladin.cs +++ b/NPCs/SlimeGod/EbonianPaladin.cs @@ -32,7 +32,7 @@ public override void SetDefaults() NPC.scale = 1.1f; NPC.defense = 10; NPC.LifeMaxNERB(8000, 9600, 220000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.BossBar = Main.BigBossProgressBar.NeverValid; NPC.aiStyle = -1; diff --git a/NPCs/SlimeGod/SlimeGodCore.cs b/NPCs/SlimeGod/SlimeGodCore.cs index d2f4e0bb7c..69d1294010 100644 --- a/NPCs/SlimeGod/SlimeGodCore.cs +++ b/NPCs/SlimeGod/SlimeGodCore.cs @@ -68,7 +68,7 @@ public override void SetDefaults() NPC.defense = 6; NPC.LifeMaxNERB(420); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPCID.Sets.TrailCacheLength[NPC.type] = 8; NPCID.Sets.TrailingMode[NPC.type] = 1; @@ -595,7 +595,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d spriteBatch.Draw(pog, NPC.Center - screenPos + new Vector2(0, NPC.gfxOffY), NPC.frame, drawColorAlpha, NPC.rotation, NPC.frame.Size() / 2, NPC.scale, spriteEffects, 0); } if (!Main.zenithWorld) - while (((twoConst > 0 && coreID < 8) || (twoConst < 0 && coreID > 8)) && CalamityConfig.Instance.Afterimages) + while (((twoConst > 0 && coreID < 8) || (twoConst < 0 && coreID > 8)) && CalamityClientConfig.Instance.Afterimages) { Color colorLightingAlpha = NPC.GetAlpha(colorLightingArea); { diff --git a/NPCs/SlimeGod/SplitCrimulanPaladin.cs b/NPCs/SlimeGod/SplitCrimulanPaladin.cs index a51706798a..360ed7d596 100644 --- a/NPCs/SlimeGod/SplitCrimulanPaladin.cs +++ b/NPCs/SlimeGod/SplitCrimulanPaladin.cs @@ -36,7 +36,7 @@ public override void SetDefaults() { NPC.Calamity().canBreakPlayerDefense = true; NPC.LifeMaxNERB(1875, 2250, 80000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.BossBar = Main.BigBossProgressBar.NeverValid; NPC.GetNPCDamage(); diff --git a/NPCs/SlimeGod/SplitEbonianPaladin.cs b/NPCs/SlimeGod/SplitEbonianPaladin.cs index fad784a39e..7544e34894 100644 --- a/NPCs/SlimeGod/SplitEbonianPaladin.cs +++ b/NPCs/SlimeGod/SplitEbonianPaladin.cs @@ -36,7 +36,7 @@ public override void SetDefaults() { NPC.Calamity().canBreakPlayerDefense = true; NPC.LifeMaxNERB(2000, 2400, 110000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.BossBar = Main.BigBossProgressBar.NeverValid; NPC.GetNPCDamage(); diff --git a/NPCs/StormWeaver/StormWeaverBody.cs b/NPCs/StormWeaver/StormWeaverBody.cs index f18c6ecfee..eec7a71b80 100644 --- a/NPCs/StormWeaver/StormWeaverBody.cs +++ b/NPCs/StormWeaver/StormWeaverBody.cs @@ -49,7 +49,7 @@ public override void SetDefaults() NPC.HitSound = SoundID.NPCHit4; NPC.DeathSound = StormWeaverHead.DeathSound; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/StormWeaver/StormWeaverHead.cs b/NPCs/StormWeaver/StormWeaverHead.cs index 91e0ac47ae..793fe208c8 100644 --- a/NPCs/StormWeaver/StormWeaverHead.cs +++ b/NPCs/StormWeaver/StormWeaverHead.cs @@ -104,7 +104,7 @@ public override void SetDefaults() NPC.HitSound = SoundID.NPCHit4; NPC.DeathSound = DeathSound; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -177,7 +177,7 @@ public override void AI() bool revenge = CalamityWorld.revenge || bossRush; bool expertMode = Main.expertMode || bossRush; - if (CalamityConfig.Instance.BossesStopWeather) + if (CalamityServerConfig.Instance.BossesStopWeather) CalamityMod.StopRain(); else if (!Main.raining && !bossRush) CalamityUtils.StartRain(); diff --git a/NPCs/StormWeaver/StormWeaverTail.cs b/NPCs/StormWeaver/StormWeaverTail.cs index 9ae676af2b..2dc41d2b10 100644 --- a/NPCs/StormWeaver/StormWeaverTail.cs +++ b/NPCs/StormWeaver/StormWeaverTail.cs @@ -48,7 +48,7 @@ public override void SetDefaults() NPC.HitSound = SoundID.NPCHit53; NPC.DeathSound = StormWeaverHead.DeathSound; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/SupremeCalamitas/BrimstoneHeart.cs b/NPCs/SupremeCalamitas/BrimstoneHeart.cs index 46a94b1db7..d006590936 100644 --- a/NPCs/SupremeCalamitas/BrimstoneHeart.cs +++ b/NPCs/SupremeCalamitas/BrimstoneHeart.cs @@ -29,7 +29,7 @@ public override void SetDefaults() NPC.height = 24; NPC.defense = 0; NPC.lifeMax = 15000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/SupremeCalamitas/SepulcherArm.cs b/NPCs/SupremeCalamitas/SepulcherArm.cs index 0897d65b50..985779582c 100644 --- a/NPCs/SupremeCalamitas/SepulcherArm.cs +++ b/NPCs/SupremeCalamitas/SepulcherArm.cs @@ -86,7 +86,7 @@ public override void SetDefaults() global.DR = 0.999999f; global.unbreakableDR = true; NPC.lifeMax = CalamityWorld.revenge ? 345000 : 300000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = AIType = -1; NPC.knockBackResist = 0f; diff --git a/NPCs/SupremeCalamitas/SepulcherBody.cs b/NPCs/SupremeCalamitas/SepulcherBody.cs index 4d092f6da2..1eed1f576a 100644 --- a/NPCs/SupremeCalamitas/SepulcherBody.cs +++ b/NPCs/SupremeCalamitas/SepulcherBody.cs @@ -40,7 +40,7 @@ public override void SetDefaults() global.DR = 0.999999f; global.unbreakableDR = true; NPC.lifeMax = CalamityWorld.revenge ? 345000 : 300000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/SupremeCalamitas/SepulcherBodyEnergyBall.cs b/NPCs/SupremeCalamitas/SepulcherBodyEnergyBall.cs index be44276128..45b35fad54 100644 --- a/NPCs/SupremeCalamitas/SepulcherBodyEnergyBall.cs +++ b/NPCs/SupremeCalamitas/SepulcherBodyEnergyBall.cs @@ -33,7 +33,7 @@ public override void SetDefaults() NPC.width = 20; NPC.height = 20; NPC.lifeMax = CalamityWorld.revenge ? 345000 : 300000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/SupremeCalamitas/SepulcherHead.cs b/NPCs/SupremeCalamitas/SepulcherHead.cs index 05100dabd8..c625e361b4 100644 --- a/NPCs/SupremeCalamitas/SepulcherHead.cs +++ b/NPCs/SupremeCalamitas/SepulcherHead.cs @@ -53,7 +53,7 @@ public override void SetDefaults() global.DR = 0.999999f; global.unbreakableDR = true; NPC.lifeMax = CalamityWorld.revenge ? 345000 : 300000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/SupremeCalamitas/SepulcherTail.cs b/NPCs/SupremeCalamitas/SepulcherTail.cs index 6798e03161..b5eb8a7c5b 100644 --- a/NPCs/SupremeCalamitas/SepulcherTail.cs +++ b/NPCs/SupremeCalamitas/SepulcherTail.cs @@ -32,7 +32,7 @@ public override void SetDefaults() global.DR = 0.999999f; global.unbreakableDR = true; NPC.lifeMax = CalamityWorld.revenge ? 345000 : 300000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/SupremeCalamitas/SoulSeekerSupreme.cs b/NPCs/SupremeCalamitas/SoulSeekerSupreme.cs index 299f2d5144..ed7d0b4a51 100644 --- a/NPCs/SupremeCalamitas/SoulSeekerSupreme.cs +++ b/NPCs/SupremeCalamitas/SoulSeekerSupreme.cs @@ -66,7 +66,7 @@ public override void SetDefaults() NPC.defense = 60; NPC.DR_NERD(NormalDR); NPC.lifeMax = 28000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.DeathSound = SoundID.DD2_SkeletonDeath; NPC.Calamity().VulnerableToHeat = false; @@ -269,7 +269,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2((float)(TextureAssets.Npc[NPC.type].Value.Width / 2), (float)(TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2)); int afterimageAmt = 2; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -292,7 +292,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture2D15 = GlowTexture.Value; Color redLerp = Color.Lerp(Color.White, Color.Red, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/SupremeCalamitas/SupremeCalamitas.cs b/NPCs/SupremeCalamitas/SupremeCalamitas.cs index 28b63083da..e43a79e26b 100644 --- a/NPCs/SupremeCalamitas/SupremeCalamitas.cs +++ b/NPCs/SupremeCalamitas/SupremeCalamitas.cs @@ -264,7 +264,7 @@ public override void SetDefaults() NPC.DR_NERD(normalDR); NPC.value = Item.buyPrice(30, 0, 0, 0); NPC.LifeMaxNERB(960000, 1150000, 900000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -441,7 +441,7 @@ public override void AI() CalamityNetcode.SyncWorld(); } - if (CalamityConfig.Instance.BossesStopWeather) + if (CalamityServerConfig.Instance.BossesStopWeather) CalamityMod.StopRain(); bool bossRush = BossRushEvent.BossRushActive; @@ -3590,7 +3590,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2(texture2D15.Width / 2f, texture2D15.Height / Main.npcFrameCount[NPC.type] / 2f); int afterimageAmt = 7; - if (CalamityConfig.Instance.Afterimages && !(permafrost && NPC.ai[1] == 2f)) + if (CalamityClientConfig.Instance.Afterimages && !(permafrost && NPC.ai[1] == 2f)) { for (int i = 1; i < afterimageAmt; i += 2) { diff --git a/NPCs/SupremeCalamitas/SupremeCataclysm.cs b/NPCs/SupremeCalamitas/SupremeCataclysm.cs index 005abccc7d..9fc1836e0d 100644 --- a/NPCs/SupremeCalamitas/SupremeCataclysm.cs +++ b/NPCs/SupremeCalamitas/SupremeCataclysm.cs @@ -84,7 +84,7 @@ public override void SetDefaults() NPC.defense = 80; NPC.DR_NERD(NormalBrothersDR); NPC.lifeMax = 138000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -476,7 +476,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 origin = NPC.frame.Size() * 0.5f; int afterimageCount = 4; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageCount; i += 2) { @@ -493,7 +493,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color primarycolor = Main.zenithWorld ? Color.Blue : Color.Red; // why? because blue fire is awesome!! Color baseGlowmaskColor = NPC.IsABestiaryIconDummy ? Color.White : Color.Lerp(Color.White, primarycolor, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageCount; i++) { diff --git a/NPCs/SupremeCalamitas/SupremeCatastrophe.cs b/NPCs/SupremeCalamitas/SupremeCatastrophe.cs index c8b5db4dd0..c19560cdd2 100644 --- a/NPCs/SupremeCalamitas/SupremeCatastrophe.cs +++ b/NPCs/SupremeCalamitas/SupremeCatastrophe.cs @@ -76,7 +76,7 @@ public override void SetDefaults() NPC.defense = 80; NPC.DR_NERD(SupremeCataclysm.NormalBrothersDR); NPC.lifeMax = 138000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -512,7 +512,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 origin = NPC.frame.Size() * 0.5f; int afterimageCount = 4; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageCount; i += 2) { @@ -528,7 +528,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture = GlowTexture.Value; Color baseGlowmaskColor = Color.Lerp(Color.White, Color.Cyan, 0.35f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageCount; i++) { diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/DestroyerAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/DestroyerAI.cs index 1308fee41f..62e5159255 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/DestroyerAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/DestroyerAI.cs @@ -406,7 +406,7 @@ public static bool BuffedDestroyerAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -598,7 +598,7 @@ public static bool BuffedDestroyerAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(projectileType); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -1301,7 +1301,7 @@ public static bool VanillaDestroyerAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Classic; double secondMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Classic; @@ -1914,7 +1914,7 @@ public static bool BuffedProbeAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -2173,7 +2173,7 @@ public static bool VanillaProbeAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Classic; double secondMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Classic; diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronPrimeAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronPrimeAI.cs index fc15e166b0..7a7965cf58 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronPrimeAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronPrimeAI.cs @@ -396,7 +396,7 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -659,7 +659,7 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -741,7 +741,7 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -949,7 +949,7 @@ public static bool BuffedPrimeLaserAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -1017,7 +1017,7 @@ public static bool BuffedPrimeLaserAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -1252,7 +1252,7 @@ public static bool BuffedPrimeCannonAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -1299,7 +1299,7 @@ public static bool BuffedPrimeCannonAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -2497,7 +2497,7 @@ public static bool VanillaPrimeLaserAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Classic; double secondMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Classic; @@ -2597,7 +2597,7 @@ public static bool VanillaPrimeLaserAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Classic; double secondMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Classic; diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/TwinsAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/TwinsAI.cs index 1647c03d42..6d2a37107f 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/TwinsAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/TwinsAI.cs @@ -307,7 +307,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -439,7 +439,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -627,7 +627,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -731,7 +731,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) int damage = (int)Math.Round(npc.GetProjectileDamage(type) * 0.75); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -847,7 +847,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -1278,7 +1278,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -1422,7 +1422,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -1605,7 +1605,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -1813,7 +1813,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -1964,7 +1964,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -2210,7 +2210,7 @@ public static bool VanillaRetinazerAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Classic; double secondMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Classic; @@ -2344,7 +2344,7 @@ public static bool VanillaRetinazerAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Classic; double secondMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Classic; @@ -2520,7 +2520,7 @@ public static bool VanillaRetinazerAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Classic; double secondMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Classic; @@ -2611,7 +2611,7 @@ public static bool VanillaRetinazerAI(NPC npc, Mod mod) int damage = (int)Math.Round(npc.GetProjectileDamage(type) * 0.75); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Classic; double secondMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Classic; @@ -2851,7 +2851,7 @@ public static bool VanillaSpazmatismAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Classic; double secondMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Classic; @@ -2984,7 +2984,7 @@ public static bool VanillaSpazmatismAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Classic; double secondMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Classic; @@ -3142,7 +3142,7 @@ public static bool VanillaSpazmatismAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Classic; double secondMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Classic; diff --git a/NPCs/Yharon/Yharon.cs b/NPCs/Yharon/Yharon.cs index f1ca77510d..ec76d46cb0 100644 --- a/NPCs/Yharon/Yharon.cs +++ b/NPCs/Yharon/Yharon.cs @@ -108,7 +108,7 @@ public override void SetDefaults() NPC.height = 200; NPC.defense = 90; NPC.LifeMaxNERB(1300000, 1560000, 740000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.aiStyle = -1; @@ -196,7 +196,7 @@ public override void AI() float lifeRatio = NPC.life / (float)NPC.lifeMax; // Stop rain - if (CalamityConfig.Instance.BossesStopWeather) + if (CalamityServerConfig.Instance.BossesStopWeather) CalamityMod.StopRain(); // Variables @@ -2767,7 +2767,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d else color = drawColor; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += afterimageIncrement) { @@ -2816,7 +2816,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d afterimageScale = 20f; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int k = 0; k < additionalAfterimageAmt; k++) { @@ -2893,7 +2893,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d blueGlowColor *= teleportGlowColorScaler; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int l = 1; l < afterimageAmt; l += afterimageIncrement) { diff --git a/Particles/GeneralParticleHandler.cs b/Particles/GeneralParticleHandler.cs index acc8ebd586..a2d1f017e5 100644 --- a/Particles/GeneralParticleHandler.cs +++ b/Particles/GeneralParticleHandler.cs @@ -86,7 +86,7 @@ public static void SpawnParticle(Particle particle) if (Main.gamePaused || Main.dedServ || particles == null) return; - if (particles.Count >= CalamityConfig.Instance.ParticleLimit && !particle.Important) + if (particles.Count >= CalamityClientConfig.Instance.ParticleLimit && !particle.Important) return; particles.Add(particle); @@ -224,7 +224,7 @@ public static int FreeSpacesAvailable() if (Main.dedServ || particles == null) return 0; - return CalamityConfig.Instance.ParticleLimit - particles.Count(); + return CalamityClientConfig.Instance.ParticleLimit - particles.Count(); } /// diff --git a/Projectiles/Boss/HolySpear.cs b/Projectiles/Boss/HolySpear.cs index 697dfa6c2a..d1b46f0654 100644 --- a/Projectiles/Boss/HolySpear.cs +++ b/Projectiles/Boss/HolySpear.cs @@ -204,7 +204,7 @@ public override bool PreDraw(ref Color lightColor) if (Projectile.spriteDirection == -1) spriteEffects = SpriteEffects.FlipHorizontally; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 0; i < Projectile.oldPos.Length; i++) { diff --git a/Projectiles/Boss/YharonFireball.cs b/Projectiles/Boss/YharonFireball.cs index aa5a68dc69..553a32d527 100644 --- a/Projectiles/Boss/YharonFireball.cs +++ b/Projectiles/Boss/YharonFireball.cs @@ -72,7 +72,7 @@ public override bool PreDraw(ref Color lightColor) int frameHeight = texture.Height / Main.projFrames[Projectile.type]; int frameY = frameHeight * Projectile.frame; Rectangle rectangle = new Rectangle(0, frameY, texture.Width, frameHeight); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 0; i < Projectile.oldPos.Length; i++) { diff --git a/Projectiles/Enemy/IceClasperEnemyProjectile.cs b/Projectiles/Enemy/IceClasperEnemyProjectile.cs index f9c5b9df8e..05065edba3 100644 --- a/Projectiles/Enemy/IceClasperEnemyProjectile.cs +++ b/Projectiles/Enemy/IceClasperEnemyProjectile.cs @@ -51,7 +51,7 @@ public override void OnKill(int timeLeft) public override bool PreDraw(ref Color lightColor) { - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], lightColor); return true; diff --git a/Projectiles/Melee/ArkOfTheAncients_SwungBlade.cs b/Projectiles/Melee/ArkOfTheAncients_SwungBlade.cs index 9e78cc627b..69c3d25b70 100644 --- a/Projectiles/Melee/ArkOfTheAncients_SwungBlade.cs +++ b/Projectiles/Melee/ArkOfTheAncients_SwungBlade.cs @@ -131,7 +131,7 @@ public override bool PreDraw(ref Color lightColor) Vector2 drawOrigin = new Vector2(Owner.direction < 0 ? sword.Width : 0f, sword.Height); Vector2 drawOffset = Owner.Center + drawAngle.ToRotationVector2() * 10f - Main.screenPosition; - if (CalamityConfig.Instance.Afterimages && Timer > ProjectileID.Sets.TrailCacheLength[Projectile.type]) + if (CalamityClientConfig.Instance.Afterimages && Timer > ProjectileID.Sets.TrailCacheLength[Projectile.type]) { for (int i = 0; i < Projectile.oldRot.Length; ++i) { diff --git a/Projectiles/Melee/ArkOfTheCosmos_SwungBlade.cs b/Projectiles/Melee/ArkOfTheCosmos_SwungBlade.cs index 5b3bb7fb7e..7ef7023edc 100644 --- a/Projectiles/Melee/ArkOfTheCosmos_SwungBlade.cs +++ b/Projectiles/Melee/ArkOfTheCosmos_SwungBlade.cs @@ -489,7 +489,7 @@ public void DrawSingleSwungScissorBlade(Color lightColor) Vector2 drawOrigin = new Vector2(flipped ? sword.Width : 0f, sword.Height); Vector2 drawOffset = Owner.Center + drawAngle.ToRotationVector2() * 10f - Main.screenPosition; - if (CalamityConfig.Instance.Afterimages && SwingTimer > ProjectileID.Sets.TrailCacheLength[Projectile.type] && Combo == 0f) + if (CalamityClientConfig.Instance.Afterimages && SwingTimer > ProjectileID.Sets.TrailCacheLength[Projectile.type] && Combo == 0f) { for (int i = 1; i < Projectile.oldRot.Length; ++i) { @@ -544,7 +544,7 @@ public void DrawSwungScissors(Color lightColor) Vector2 backScissorDrawPosition = Owner.Center + drawAngle.ToRotationVector2() * 10f + (drawAngle.ToRotationVector2() * 56f + (drawAngle - MathHelper.PiOver2).ToRotationVector2() * 11 * Owner.direction) * Projectile.scale - Main.screenPosition; //Lined up with the hole in the front blade - if (CalamityConfig.Instance.Afterimages && SwingTimer > ProjectileID.Sets.TrailCacheLength[Projectile.type]) + if (CalamityClientConfig.Instance.Afterimages && SwingTimer > ProjectileID.Sets.TrailCacheLength[Projectile.type]) { Texture2D afterimage = Request("CalamityMod/Projectiles/Melee/SunderingScissorsGlow").Value; diff --git a/Projectiles/Melee/ArkOfTheElements_SwungBlade.cs b/Projectiles/Melee/ArkOfTheElements_SwungBlade.cs index 6ad36b293e..7afe20cae8 100644 --- a/Projectiles/Melee/ArkOfTheElements_SwungBlade.cs +++ b/Projectiles/Melee/ArkOfTheElements_SwungBlade.cs @@ -308,7 +308,7 @@ public void DrawSingleSwungScissorBlade(Color lightColor) Vector2 drawOrigin = new Vector2(Combo == 1 ? sword.Width / 2f : flipped ? sword.Width : 0f, sword.Height); Vector2 drawOffset = Owner.Center + drawAngle.ToRotationVector2() * 10f - Main.screenPosition; - if (CalamityConfig.Instance.Afterimages && SwingTimer > ProjectileID.Sets.TrailCacheLength[Projectile.type]) + if (CalamityClientConfig.Instance.Afterimages && SwingTimer > ProjectileID.Sets.TrailCacheLength[Projectile.type]) { for (int i = 0; i < Projectile.oldRot.Length; ++i) { @@ -362,7 +362,7 @@ public void DrawSwungScissors(Color lightColor) Vector2 backScissorDrawPosition = Owner.Center + drawAngle.ToRotationVector2() * 10f + functionalDrawAngle.ToRotationVector2() * 70f * Projectile.scale - Main.screenPosition; //Lined up with the hole in the front blade float backScissorRotation = drawRotation + (Combo == 1 ? (!flipped ? MathHelper.PiOver4 * 0.75f : MathHelper.PiOver4 * -0.75f) : 0f); - if (CalamityConfig.Instance.Afterimages && SwingTimer > ProjectileID.Sets.TrailCacheLength[Projectile.type]) + if (CalamityClientConfig.Instance.Afterimages && SwingTimer > ProjectileID.Sets.TrailCacheLength[Projectile.type]) { for (int i = 0; i < Projectile.oldRot.Length; ++i) { diff --git a/Projectiles/Melee/Galaxia_PhoenixsPride.cs b/Projectiles/Melee/Galaxia_PhoenixsPride.cs index dea78a8c39..3bb96e5877 100644 --- a/Projectiles/Melee/Galaxia_PhoenixsPride.cs +++ b/Projectiles/Melee/Galaxia_PhoenixsPride.cs @@ -286,7 +286,7 @@ public override bool PreDraw(ref Color lightColor) Vector2 drawOffset = Projectile.Center - Main.screenPosition; //Afterimages - if (CalamityConfig.Instance.Afterimages && CurrentState == 0f && Empowerment / maxEmpowerment > 0.4f) + if (CalamityClientConfig.Instance.Afterimages && CurrentState == 0f && Empowerment / maxEmpowerment > 0.4f) { for (int i = 0; i < Projectile.oldRot.Length; ++i) { diff --git a/Projectiles/Melee/GayBeam.cs b/Projectiles/Melee/GayBeam.cs index 8da45460d2..f8bc673a97 100644 --- a/Projectiles/Melee/GayBeam.cs +++ b/Projectiles/Melee/GayBeam.cs @@ -340,7 +340,7 @@ public override bool PreDraw(ref Color lightColor) Vector2 origin = rectangle.Size() / 2f; Color alphaColor = Projectile.GetAlpha(lightColor); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { Vector2 centerOffset = Projectile.Size / 2f; int totalAfterimages = TotalAfterimages; diff --git a/Projectiles/Melee/MendedBiomeBlade_HeavensMight.cs b/Projectiles/Melee/MendedBiomeBlade_HeavensMight.cs index 10dbf2ddde..719e2b7024 100644 --- a/Projectiles/Melee/MendedBiomeBlade_HeavensMight.cs +++ b/Projectiles/Melee/MendedBiomeBlade_HeavensMight.cs @@ -215,7 +215,7 @@ public override bool PreDraw(ref Color lightColor) Vector2 drawOffset = Projectile.Center - Main.screenPosition; //Afterimages - if (CalamityConfig.Instance.Afterimages && CurrentState == 0f && Empowerment / maxEmpowerment > 0.4f) + if (CalamityClientConfig.Instance.Afterimages && CurrentState == 0f && Empowerment / maxEmpowerment > 0.4f) { for (int i = 0; i < Projectile.oldRot.Length; ++i) { diff --git a/Projectiles/Melee/TrueArkOfTheAncients_SwungBlade.cs b/Projectiles/Melee/TrueArkOfTheAncients_SwungBlade.cs index e3b784cf55..dbf5921c89 100644 --- a/Projectiles/Melee/TrueArkOfTheAncients_SwungBlade.cs +++ b/Projectiles/Melee/TrueArkOfTheAncients_SwungBlade.cs @@ -133,7 +133,7 @@ public override bool PreDraw(ref Color lightColor) Vector2 drawOrigin = new Vector2(Owner.direction < 0 ? sword.Width : 0f, sword.Height); Vector2 drawOffset = Owner.Center + drawAngle.ToRotationVector2() * 10f - Main.screenPosition; - if (CalamityConfig.Instance.Afterimages && Timer > ProjectileID.Sets.TrailCacheLength[Projectile.type]) + if (CalamityClientConfig.Instance.Afterimages && Timer > ProjectileID.Sets.TrailCacheLength[Projectile.type]) { for (int i = 0; i < Projectile.oldRot.Length; ++i) { diff --git a/Projectiles/Melee/TrueBiomeBlade_SwordsmithsPride.cs b/Projectiles/Melee/TrueBiomeBlade_SwordsmithsPride.cs index 8c8351f8f7..6404dc74ae 100644 --- a/Projectiles/Melee/TrueBiomeBlade_SwordsmithsPride.cs +++ b/Projectiles/Melee/TrueBiomeBlade_SwordsmithsPride.cs @@ -310,7 +310,7 @@ public override bool PreDraw(ref Color lightColor) drawOrigin = new Vector2(0f, blade.Height); //Afterimages - if (CalamityConfig.Instance.Afterimages && CurrentState == 0f && Empowerment / maxEmpowerment > 0.4f) + if (CalamityClientConfig.Instance.Afterimages && CurrentState == 0f && Empowerment / maxEmpowerment > 0.4f) { for (int i = 0; i < Projectile.oldRot.Length; ++i) { diff --git a/Projectiles/Ranged/BuzzkillHoldout.cs b/Projectiles/Ranged/BuzzkillHoldout.cs index b0d329f885..1191eda5d5 100644 --- a/Projectiles/Ranged/BuzzkillHoldout.cs +++ b/Projectiles/Ranged/BuzzkillHoldout.cs @@ -242,7 +242,7 @@ public override bool PreDraw(ref Color lightColor) if (Time / ChargeupTime >= 0.25f) Main.EntitySpriteDraw(smallSlashTexture, GunTipPosition - Main.screenPosition, null, slashColor, Time * MathHelper.ToRadians(42f), smallSlashTexture.Size() * 0.5f, 1f, SpriteEffects.None); - if (!CalamityConfig.Instance.Afterimages) + if (!CalamityClientConfig.Instance.Afterimages) return false; // Special afterimage drawing for the slashes only diff --git a/Projectiles/Ranged/BuzzkillSaw.cs b/Projectiles/Ranged/BuzzkillSaw.cs index 7973eab163..f97bddbd36 100644 --- a/Projectiles/Ranged/BuzzkillSaw.cs +++ b/Projectiles/Ranged/BuzzkillSaw.cs @@ -193,7 +193,7 @@ public override bool PreDraw(ref Color lightColor) } } - if (!CalamityConfig.Instance.Afterimages) + if (!CalamityClientConfig.Instance.Afterimages) return true; // Special afterimage drawing to include the slashes diff --git a/Projectiles/Ranged/MineralMortarProjectile.cs b/Projectiles/Ranged/MineralMortarProjectile.cs index bbda255676..98a7ae6fec 100644 --- a/Projectiles/Ranged/MineralMortarProjectile.cs +++ b/Projectiles/Ranged/MineralMortarProjectile.cs @@ -179,7 +179,7 @@ public override bool PreDraw(ref Color lightColor) GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/SwordSlashTexture")); PrimitiveRenderer.RenderTrail(Projectile.oldPos, new(TrailWidthFunction, ColorTrailFunction, (_) => Projectile.Size * 0.5f, shader: GameShaders.Misc["CalamityMod:TrailStreak"]), 50); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 0; i < 3; i++) { diff --git a/Projectiles/Ranged/SuperradiantSaw.cs b/Projectiles/Ranged/SuperradiantSaw.cs index 7c2e2c695a..ea4d7a7231 100644 --- a/Projectiles/Ranged/SuperradiantSaw.cs +++ b/Projectiles/Ranged/SuperradiantSaw.cs @@ -365,7 +365,7 @@ public override bool PreDraw(ref Color lightColor) Main.EntitySpriteDraw(outline, Projectile.Center - Main.screenPosition, null, Main.DiscoColor, Projectile.rotation, outline.Size() * 0.5f, 1f, SpriteEffects.None); } - if (!CalamityConfig.Instance.Afterimages) + if (!CalamityClientConfig.Instance.Afterimages) return false; // Special afterimage drawing to include the slashes diff --git a/Projectiles/Ranged/SuperradiantSawLingering.cs b/Projectiles/Ranged/SuperradiantSawLingering.cs index 4e5619a351..62806150af 100644 --- a/Projectiles/Ranged/SuperradiantSawLingering.cs +++ b/Projectiles/Ranged/SuperradiantSawLingering.cs @@ -178,7 +178,7 @@ public override bool PreDraw(ref Color lightColor) Texture2D outline = SawOutline.Value; Main.EntitySpriteDraw(outline, Projectile.Center - Main.screenPosition, null, Main.DiscoColor, Projectile.rotation, outline.Size() * 0.5f, 1f, SpriteEffects.None); - if (!CalamityConfig.Instance.Afterimages) + if (!CalamityClientConfig.Instance.Afterimages) return false; // Special afterimage drawing to include the slashes diff --git a/Projectiles/Ranged/SuperradiantSlaughtererHoldout.cs b/Projectiles/Ranged/SuperradiantSlaughtererHoldout.cs index 43c104248c..8e7bd1e6a4 100644 --- a/Projectiles/Ranged/SuperradiantSlaughtererHoldout.cs +++ b/Projectiles/Ranged/SuperradiantSlaughtererHoldout.cs @@ -334,7 +334,7 @@ public override bool PreDraw(ref Color lightColor) if (Time / ChargeupTime >= 0.25f) Main.EntitySpriteDraw(smallSlashTexture, GunTipPosition - Main.screenPosition, null, slashColor, Time * MathHelper.ToRadians(42f), smallSlashTexture.Size() * 0.5f, 1f, SpriteEffects.None); - if (!CalamityConfig.Instance.Afterimages) + if (!CalamityClientConfig.Instance.Afterimages) return false; // Special afterimage drawing for the slashes only diff --git a/Projectiles/Rogue/WrathwingFireball.cs b/Projectiles/Rogue/WrathwingFireball.cs index ea87dc0f35..2d3428e84c 100644 --- a/Projectiles/Rogue/WrathwingFireball.cs +++ b/Projectiles/Rogue/WrathwingFireball.cs @@ -57,7 +57,7 @@ public override bool PreDraw(ref Color lightColor) int frameHeight = texture.Height / Main.projFrames[Projectile.type]; int frameY = frameHeight * Projectile.frame; Rectangle rectangle = new Rectangle(0, frameY, texture.Width, frameHeight); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 0; i < Projectile.oldPos.Length; i++) { diff --git a/Projectiles/Summon/IceClasperMinion.cs b/Projectiles/Summon/IceClasperMinion.cs index 94aca8ef17..89aded9c6b 100644 --- a/Projectiles/Summon/IceClasperMinion.cs +++ b/Projectiles/Summon/IceClasperMinion.cs @@ -199,7 +199,7 @@ public override bool PreDraw(ref Color lightColor) AfterimageInterpolant = MathHelper.Clamp(AfterimageInterpolant, 0f, 1f); float AfterimageFade = MathHelper.Lerp(0f, 1f, AfterimageInterpolant); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 0; i < Projectile.oldPos.Length; i++) { diff --git a/Projectiles/Summon/MiniGuardianRock.cs b/Projectiles/Summon/MiniGuardianRock.cs index 5f7c775d22..f4030d1c70 100644 --- a/Projectiles/Summon/MiniGuardianRock.cs +++ b/Projectiles/Summon/MiniGuardianRock.cs @@ -122,7 +122,7 @@ public override bool PreDraw(ref Color lightColor) lerpVal = Utils.GetLerpValue(psc ? 87 : 57, psc ? 150 : 120, ownerDist, true); mult = MathHelper.Lerp(0.42f, 1f, lerpVal); } - if (CalamityConfig.Instance.Afterimages && Projectile.ai[0] >= 1f) //handle afterimages manually since the utility broke it and didn't render correctly + if (CalamityClientConfig.Instance.Afterimages && Projectile.ai[0] >= 1f) //handle afterimages manually since the utility broke it and didn't render correctly { for (int i = 0; i < Projectile.oldPos.Length; ++i) { diff --git a/Projectiles/Summon/MirrorofKalandraMinions/HopeShredderArrow.cs b/Projectiles/Summon/MirrorofKalandraMinions/HopeShredderArrow.cs index 5e064d63a7..1d1faac2f7 100644 --- a/Projectiles/Summon/MirrorofKalandraMinions/HopeShredderArrow.cs +++ b/Projectiles/Summon/MirrorofKalandraMinions/HopeShredderArrow.cs @@ -65,7 +65,7 @@ public override bool PreDraw(ref Color lightColor) Rectangle frame = texture.Frame(1, Main.projFrames[Type], 0, Projectile.frame); Vector2 origin = frame.Size() * 0.5f; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 0; i < Projectile.oldPos.Length; i++) { diff --git a/Projectiles/Summon/MirrorofKalandraMinions/Paradoxica.cs b/Projectiles/Summon/MirrorofKalandraMinions/Paradoxica.cs index 2ac39278e4..aae3731d65 100644 --- a/Projectiles/Summon/MirrorofKalandraMinions/Paradoxica.cs +++ b/Projectiles/Summon/MirrorofKalandraMinions/Paradoxica.cs @@ -190,7 +190,7 @@ public override bool PreDraw(ref Color lightColor) Vector2 origin = frame.Size() * 0.5f; float rotation = (Target is not null) ? Projectile.rotation : Projectile.rotation + MathHelper.PiOver4; - if (CalamityConfig.Instance.Afterimages && Target is not null) + if (CalamityClientConfig.Instance.Afterimages && Target is not null) { for (int i = 0; i < Projectile.oldPos.Length; i++) { diff --git a/Projectiles/Summon/MirrorofKalandraMinions/Starforge.cs b/Projectiles/Summon/MirrorofKalandraMinions/Starforge.cs index 2ddb451933..c2fdddd74b 100644 --- a/Projectiles/Summon/MirrorofKalandraMinions/Starforge.cs +++ b/Projectiles/Summon/MirrorofKalandraMinions/Starforge.cs @@ -138,7 +138,7 @@ public override bool PreDraw(ref Color lightColor) DrawSpin -= MathHelper.ToRadians(MirrorofKalandra.Purple_SpinSpeed); float rotation = (Target is not null) ? DrawSpin : Projectile.rotation + MathHelper.Pi - MathHelper.PiOver4; - if (CalamityConfig.Instance.Afterimages && Target is not null) + if (CalamityClientConfig.Instance.Afterimages && Target is not null) { for (int i = 0; i < Projectile.oldPos.Length; i++) { diff --git a/Projectiles/Summon/MirrorofKalandraMinions/WindRipperArrow.cs b/Projectiles/Summon/MirrorofKalandraMinions/WindRipperArrow.cs index e972745785..006b16a2e1 100644 --- a/Projectiles/Summon/MirrorofKalandraMinions/WindRipperArrow.cs +++ b/Projectiles/Summon/MirrorofKalandraMinions/WindRipperArrow.cs @@ -56,7 +56,7 @@ public override bool PreDraw(ref Color lightColor) Rectangle frame = texture.Frame(1, Main.projFrames[Type], 0, Projectile.frame); Vector2 origin = frame.Size() * 0.5f; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 0; i < Projectile.oldPos.Length; i++) { diff --git a/Projectiles/Summon/MutatedTruffleMinion.cs b/Projectiles/Summon/MutatedTruffleMinion.cs index 20ca2992a1..498383c09d 100644 --- a/Projectiles/Summon/MutatedTruffleMinion.cs +++ b/Projectiles/Summon/MutatedTruffleMinion.cs @@ -267,7 +267,7 @@ public override bool PreDraw(ref Color lightColor) float drawRotation = Projectile.rotation + (Projectile.spriteDirection == -1 && State != AIState.Idle ? MathHelper.Pi : 0f); SpriteEffects effects = (Projectile.spriteDirection == 1) ? SpriteEffects.None : SpriteEffects.FlipHorizontally; - if (CalamityConfig.Instance.Afterimages && (State == AIState.Dashing || State == AIState.Vortex)) + if (CalamityClientConfig.Instance.Afterimages && (State == AIState.Dashing || State == AIState.Vortex)) { for (int i = 0; i < Projectile.oldPos.Length; i++) { diff --git a/Projectiles/Summon/PhantomicDagger.cs b/Projectiles/Summon/PhantomicDagger.cs index 4e0f3cf94e..c7ba78c212 100644 --- a/Projectiles/Summon/PhantomicDagger.cs +++ b/Projectiles/Summon/PhantomicDagger.cs @@ -92,7 +92,7 @@ public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) public override bool PreDraw(ref Color lightColor) { - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], lightColor, 1); } diff --git a/Projectiles/Summon/PlantationStaffSeed.cs b/Projectiles/Summon/PlantationStaffSeed.cs index 86f09239fc..e891f75ec4 100644 --- a/Projectiles/Summon/PlantationStaffSeed.cs +++ b/Projectiles/Summon/PlantationStaffSeed.cs @@ -59,7 +59,7 @@ public override bool PreDraw(ref Color lightColor) Rectangle frame = texture.Frame(1, Main.projFrames[Type], 0, Projectile.frame); Vector2 origin = frame.Size() * 0.5f; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 0; i < Projectile.oldPos.Length; i++) { diff --git a/Projectiles/Summon/PlantationStaffSummon.cs b/Projectiles/Summon/PlantationStaffSummon.cs index 8e0f6380f5..7d8bd78097 100644 --- a/Projectiles/Summon/PlantationStaffSummon.cs +++ b/Projectiles/Summon/PlantationStaffSummon.cs @@ -341,7 +341,7 @@ public override bool PreDraw(ref Color lightColor) Rectangle frame = texture.Frame(1, Main.projFrames[Type], 0, Projectile.frame); Vector2 origin = frame.Size() * 0.5f; - if (State == AIState.Ramming && CalamityConfig.Instance.Afterimages) + if (State == AIState.Ramming && CalamityClientConfig.Instance.Afterimages) CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Type], lightColor); Main.EntitySpriteDraw(texture, drawPosition, frame, Projectile.GetAlpha(lightColor), Projectile.rotation, origin, Projectile.scale, SpriteEffects.None, 0); diff --git a/Projectiles/Summon/PlantationStaffTentacle.cs b/Projectiles/Summon/PlantationStaffTentacle.cs index cddecf05e4..306f069baa 100644 --- a/Projectiles/Summon/PlantationStaffTentacle.cs +++ b/Projectiles/Summon/PlantationStaffTentacle.cs @@ -230,7 +230,7 @@ public override bool PreDraw(ref Color lightColor) } } } - else if (CalamityConfig.Instance.Afterimages) + else if (CalamityClientConfig.Instance.Afterimages) CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Type], lightColor); return true; diff --git a/Projectiles/Summon/ProfanedSoulCrystalProjectiles.cs b/Projectiles/Summon/ProfanedSoulCrystalProjectiles.cs index e142df4198..03cb9aa2ed 100644 --- a/Projectiles/Summon/ProfanedSoulCrystalProjectiles.cs +++ b/Projectiles/Summon/ProfanedSoulCrystalProjectiles.cs @@ -1658,7 +1658,7 @@ public override bool PreDraw(ref Color lightColor) drawPos -= new Vector2(texture.Width, texture.Height) * Projectile.scale / 2f; drawPos += drawOrigin * Projectile.scale + new Vector2(0f, Projectile.gfxOffY); Rectangle frame = new Rectangle(0, 0, texture.Width, texture.Height); - if (CalamityConfig.Instance.Afterimages) //handle afterimages manually since the utility broke it and didn't render correctly + if (CalamityClientConfig.Instance.Afterimages) //handle afterimages manually since the utility broke it and didn't render correctly { for (int i = 0; i < Projectile.oldPos.Length; ++i) { diff --git a/Projectiles/Summon/Umbrella/MagicHat.cs b/Projectiles/Summon/Umbrella/MagicHat.cs index 663c9df9e3..3da5df70a1 100644 --- a/Projectiles/Summon/Umbrella/MagicHat.cs +++ b/Projectiles/Summon/Umbrella/MagicHat.cs @@ -128,7 +128,7 @@ public override bool PreDraw(ref Color lightColor) // Use a different texture if the player is invisible or has at least 50% stealth Texture2D texture = Terraria.GameContent.TextureAssets.Projectile[Projectile.type].Value; float stealthPercent = player.Calamity().rogueStealthMax != 0 ? (player.Calamity().rogueStealth / player.Calamity().rogueStealthMax) : 0f; //0 to 1 - bool hasStealth = player.Calamity().rogueStealth > 0f && stealthPercent > 0.5f && player.townNPCs < 3f && CalamityConfig.Instance.StealthInvisibility; + bool hasStealth = player.Calamity().rogueStealth > 0f && stealthPercent > 0.5f && player.townNPCs < 3f && CalamityClientConfig.Instance.StealthInvisibility; if (player.ShouldNotDraw || hasStealth) texture = ModContent.Request("CalamityMod/Projectiles/Summon/Umbrella/MagicHatInvis").Value; diff --git a/Projectiles/Summon/YharonMinionFireball.cs b/Projectiles/Summon/YharonMinionFireball.cs index a28383d96e..cbd9dff30f 100644 --- a/Projectiles/Summon/YharonMinionFireball.cs +++ b/Projectiles/Summon/YharonMinionFireball.cs @@ -65,7 +65,7 @@ public override bool PreDraw(ref Color lightColor) if (Projectile.spriteDirection == -1) direction = SpriteEffects.FlipHorizontally; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 0; i < Projectile.oldPos.Length; i++) { diff --git a/Systems/MusicEventSystem.cs b/Systems/MusicEventSystem.cs index 803a27df18..2b78e271c0 100644 --- a/Systems/MusicEventSystem.cs +++ b/Systems/MusicEventSystem.cs @@ -52,20 +52,20 @@ static void AddEntry(string eventId, string songName, TimeSpan length, Func DownedBossSystem.downedCalamitasClone, () => CalamityConfig.Instance.Interlude1); + () => DownedBossSystem.downedCalamitasClone, () => CalamityClientConfig.Instance.Interlude1); AddEntry("MLDefeated", "Interlude2", TimeSpan.FromSeconds(191.912d), () => NPC.downedMoonlord, - () => CalamityConfig.Instance.Interlude2, outroSilence: TimeSpan.FromSeconds(1f)); + () => CalamityClientConfig.Instance.Interlude2, outroSilence: TimeSpan.FromSeconds(1f)); // Alternative Interlude 2 -> AddEntry("MLDefeated", "Interlude2_CutIntro", TimeSpan.FromSeconds(160.989d), // () => NPC.downedMoonlord, () => CalamityConfig.Instance.Interlude2, // outroSilence: TimeSpan.FromSeconds(1f)); AddEntry("YharonDefeated", "Interlude3", TimeSpan.FromSeconds(295.932d), - () => DownedBossSystem.downedYharon, () => CalamityConfig.Instance.Interlude3); + () => DownedBossSystem.downedYharon, () => CalamityClientConfig.Instance.Interlude3); AddEntry("DoGDefeated", "DevourerofGodsEulogy", TimeSpan.FromSeconds(203.620d), - () => DownedBossSystem.downedDoG, () => CalamityConfig.Instance.DevourerofGodsEulogy, + () => DownedBossSystem.downedDoG, () => CalamityClientConfig.Instance.DevourerofGodsEulogy, introSilence: TimeSpan.FromSeconds(7.5f)); // Acceptance is NOT toggleable in the config diff --git a/Systems/NerfExpertDebuffsSystem.cs b/Systems/NerfExpertDebuffsSystem.cs index 49a6da275c..67ea9cdaaa 100644 --- a/Systems/NerfExpertDebuffsSystem.cs +++ b/Systems/NerfExpertDebuffsSystem.cs @@ -10,7 +10,7 @@ public class NerfExpertDebuffsSystem : ModSystem public override void PostUpdateTime() { // Reduce the expert+ debuff time multiplier to the normal mode multiplier - if (CalamityConfig.Instance.NerfExpertDebuffs) + if (CalamityServerConfig.Instance.NerfExpertDebuffs) { var copy = Main.RegisteredGameModes[GameModeID.Expert]; copy.DebuffTimeMultiplier = 1f; diff --git a/Systems/WorldMiscUpdateSystem.cs b/Systems/WorldMiscUpdateSystem.cs index 2a4e9dee57..85c1bed3e8 100644 --- a/Systems/WorldMiscUpdateSystem.cs +++ b/Systems/WorldMiscUpdateSystem.cs @@ -444,9 +444,9 @@ public static void TrySpawnArmoredDigger(Player player, CalamityPlayer modPlayer if (Main.SceneMetrics.WaterCandleCount > 0) spawnRate *= 0.8D; - if (modPlayer.isNearbyBoss && CalamityConfig.Instance.BossZen) + if (modPlayer.isNearbyBoss && CalamityServerConfig.Instance.BossZen) spawnRate *= 50D; - if (modPlayer.zen || (CalamityConfig.Instance.ForceTownSafety && player.townNPCs > 1f && Main.expertMode)) + if (modPlayer.zen || (CalamityServerConfig.Instance.ForceTownSafety && player.townNPCs > 1f && Main.expertMode)) spawnRate *= 2D; if (modPlayer.tranquilityCandle) spawnRate *= 1.67D; diff --git a/Systems/WorldgenManagementSystem.cs b/Systems/WorldgenManagementSystem.cs index 1e7c71d05f..1c95edcdf9 100644 --- a/Systems/WorldgenManagementSystem.cs +++ b/Systems/WorldgenManagementSystem.cs @@ -336,7 +336,7 @@ public override void ModifyHardmodeTasks(List tasks) // Disable gen pass if Early Hardmode Rework is disabled. // Could just not add/remove gen pass, but that could lead to mod conflicts // in case whatever mod targets this specific gen pass. - if (!CalamityConfig.Instance.EarlyHardmodeProgressionRework) + if (!CalamityServerConfig.Instance.EarlyHardmodeProgressionRework) { hardmodeOreT1Pass.Disable(); } diff --git a/Tiles/CalamityGlobalTile.cs b/Tiles/CalamityGlobalTile.cs index 13fd8f4d53..eee4e9752e 100644 --- a/Tiles/CalamityGlobalTile.cs +++ b/Tiles/CalamityGlobalTile.cs @@ -403,7 +403,7 @@ void CheckShatterCrystal(int xPos, int yPos, bool dontShatter) { Vector2 spreadMinMax = new Vector2(-32.0f, 32.0f); // Drop 4 Soul of Night - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework) { DropItem(i, j, ItemID.SoulofNight, quantity: 4, asStack: false, spreadMinMax); WorldGen.altarCount++; // altarCount does not update automatically if ProgressionRework is enabled! diff --git a/UI/CooldownRackUI.cs b/UI/CooldownRackUI.cs index acd23acbd4..8c0469ba29 100644 --- a/UI/CooldownRackUI.cs +++ b/UI/CooldownRackUI.cs @@ -19,7 +19,7 @@ public static bool CompactIcons get { // Option 1: Always use compact icons if configured to do so. - if (CalamityConfig.Instance.CooldownDisplay == 1) + if (CalamityClientConfig.Instance.CooldownDisplay == 1) return true; // Option 2: If there are too many cooldowns, auto switch to compact mode. @@ -43,7 +43,7 @@ public static void Draw(SpriteBatch spriteBatch) // 1 - The game isn't even on the game screen yet. // 2 - The player's inventory is open. // 3 - Cooldown display is completely disabled. - if (Main.gameMenu || Main.playerInventory || CalamityConfig.Instance.CooldownDisplay < 1) + if (Main.gameMenu || Main.playerInventory || CalamityClientConfig.Instance.CooldownDisplay < 1) return; IList cooldownsToDraw = Main.LocalPlayer.GetDisplayedCooldowns(); diff --git a/UI/DraedonsArsenal/ChargeMeterUI.cs b/UI/DraedonsArsenal/ChargeMeterUI.cs index 709f36a8dd..b3c159411e 100644 --- a/UI/DraedonsArsenal/ChargeMeterUI.cs +++ b/UI/DraedonsArsenal/ChargeMeterUI.cs @@ -38,7 +38,7 @@ internal static void Unload() public static void Draw(SpriteBatch spriteBatch, Player player) { // Sanity check the planned position before drawing - Vector2 screenRatioPosition = new Vector2(CalamityConfig.Instance.ChargeMeterPosX, CalamityConfig.Instance.ChargeMeterPosY); + Vector2 screenRatioPosition = new Vector2(CalamityClientConfig.Instance.ChargeMeterPosX, CalamityClientConfig.Instance.ChargeMeterPosY); if (screenRatioPosition.X < 0f || screenRatioPosition.X > 100f) screenRatioPosition.X = DefaultChargePosX; if (screenRatioPosition.Y < 0f || screenRatioPosition.Y > 100f) @@ -54,23 +54,23 @@ public static void Draw(SpriteBatch spriteBatch, Player player) void SavePosition() { bool changed = false; - if (CalamityConfig.Instance.ChargeMeterPosX != screenRatioPosition.X) + if (CalamityClientConfig.Instance.ChargeMeterPosX != screenRatioPosition.X) { - CalamityConfig.Instance.ChargeMeterPosX = screenRatioPosition.X; + CalamityClientConfig.Instance.ChargeMeterPosX = screenRatioPosition.X; changed = true; } - if (CalamityConfig.Instance.ChargeMeterPosY != screenRatioPosition.Y) + if (CalamityClientConfig.Instance.ChargeMeterPosY != screenRatioPosition.Y) { - CalamityConfig.Instance.ChargeMeterPosY = screenRatioPosition.Y; + CalamityClientConfig.Instance.ChargeMeterPosY = screenRatioPosition.Y; changed = true; } if (changed) - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); } // If the Charge Meter is turned off or the player is not holding an item, stop. Item heldItem = player.ActiveItem(); - if (!CalamityConfig.Instance.ChargeMeter || heldItem is null || heldItem.IsAir) + if (!CalamityClientConfig.Instance.ChargeMeter || heldItem is null || heldItem.IsAir) { Reset(); SavePosition(); @@ -96,7 +96,7 @@ void SavePosition() if (chargeBar.Intersects(mouseHitbox)) { - if (!CalamityConfig.Instance.MeterPosLock) + if (!CalamityClientConfig.Instance.MeterPosLock) Main.LocalPlayer.mouseInterface = true; // If the mouse is on top of the meter, show the exact numeric charge. @@ -106,7 +106,7 @@ void SavePosition() Vector2 newScreenRatioPosition = screenRatioPosition; // Handle mouse dragging - if (!CalamityConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) + if (!CalamityClientConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) { // If the drag offset doesn't exist yet, create it. if (!dragOffset.HasValue) @@ -124,15 +124,15 @@ void SavePosition() Vector2 delta = newScreenRatioPosition - screenRatioPosition; if (Math.Abs(delta.X) >= MouseDragEpsilon || Math.Abs(delta.Y) >= MouseDragEpsilon) { - CalamityConfig.Instance.ChargeMeterPosX = newScreenRatioPosition.X; - CalamityConfig.Instance.ChargeMeterPosY = newScreenRatioPosition.Y; + CalamityClientConfig.Instance.ChargeMeterPosX = newScreenRatioPosition.X; + CalamityClientConfig.Instance.ChargeMeterPosY = newScreenRatioPosition.Y; } // When the mouse is released, save the config and destroy the drag offset. if (ms.LeftButton == ButtonState.Released) { dragOffset = null; - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); } } } diff --git a/UI/FlightBar/FlightBar.cs b/UI/FlightBar/FlightBar.cs index 60ec028cfb..8d9d14b533 100644 --- a/UI/FlightBar/FlightBar.cs +++ b/UI/FlightBar/FlightBar.cs @@ -90,7 +90,7 @@ internal static void Unload() public static void Draw(SpriteBatch spriteBatch, Player player) { // Sanity check the planned position before drawing - Vector2 screenRatioPosition = new Vector2(CalamityConfig.Instance.FlightBarPosX, CalamityConfig.Instance.FlightBarPosY); + Vector2 screenRatioPosition = new Vector2(CalamityClientConfig.Instance.FlightBarPosX, CalamityClientConfig.Instance.FlightBarPosY); if (screenRatioPosition.X < 0f || screenRatioPosition.X > 100f) screenRatioPosition.X = DefaultFlightPosX; if (screenRatioPosition.Y < 0f || screenRatioPosition.Y > 100f) @@ -106,26 +106,26 @@ public static void Draw(SpriteBatch spriteBatch, Player player) CalamityPlayer modPlayer = player.Calamity(); // If not drawing the flight bar, save its latest position to config and leave. - if (CalamityConfig.Instance.FlightBar && ((player.wingsLogic > 0 && player.wingTimeMax > 0) || (player.mount.Active && player.mount._data.flightTimeMax > 0) || player.carpet && !player.canCarpet)) + if (CalamityClientConfig.Instance.FlightBar && ((player.wingsLogic > 0 && player.wingTimeMax > 0) || (player.mount.Active && player.mount._data.flightTimeMax > 0) || player.carpet && !player.canCarpet)) { DrawFlightBar(spriteBatch, modPlayer, screenPos); } else { bool changed = false; - if (CalamityConfig.Instance.FlightBarPosX != screenRatioPosition.X) + if (CalamityClientConfig.Instance.FlightBarPosX != screenRatioPosition.X) { - CalamityConfig.Instance.FlightBarPosX = screenRatioPosition.X; + CalamityClientConfig.Instance.FlightBarPosX = screenRatioPosition.X; changed = true; } - if (CalamityConfig.Instance.FlightBarPosY != screenRatioPosition.Y) + if (CalamityClientConfig.Instance.FlightBarPosY != screenRatioPosition.Y) { - CalamityConfig.Instance.FlightBarPosY = screenRatioPosition.Y; + CalamityClientConfig.Instance.FlightBarPosY = screenRatioPosition.Y; changed = true; } if (changed) - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); return; } @@ -138,7 +138,7 @@ public static void Draw(SpriteBatch spriteBatch, Player player) // Handle mouse dragging if (flightBar.Intersects(mouseHitbox)) { - if (!CalamityConfig.Instance.MeterPosLock) + if (!CalamityClientConfig.Instance.MeterPosLock) Main.LocalPlayer.mouseInterface = true; if (modPlayer.Player.equippedWings != null && modPlayer.Player.wingTimeMax > 0 || (player.mount.Active && modPlayer.Player.mount._data.flightTimeMax > 0) || player.carpet && !player.canCarpet) //equipped wings or riding a flying mount and max wingtime/flighttime above 0 (so not disabled bar) @@ -149,7 +149,7 @@ public static void Draw(SpriteBatch spriteBatch, Player player) Vector2 newScreenRatioPosition = screenRatioPosition; // As long as the mouse button is held down, drag the meter along with an offset. - if (!CalamityConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) + if (!CalamityClientConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) { // If the drag offset doesn't exist yet, create it. if (!dragOffset.HasValue) @@ -167,15 +167,15 @@ public static void Draw(SpriteBatch spriteBatch, Player player) Vector2 delta = newScreenRatioPosition - screenRatioPosition; if (Math.Abs(delta.X) >= MouseDragEpsilon || Math.Abs(delta.Y) >= MouseDragEpsilon) { - CalamityConfig.Instance.FlightBarPosX = newScreenRatioPosition.X; - CalamityConfig.Instance.FlightBarPosY = newScreenRatioPosition.Y; + CalamityClientConfig.Instance.FlightBarPosX = newScreenRatioPosition.X; + CalamityClientConfig.Instance.FlightBarPosY = newScreenRatioPosition.Y; } // When the mouse is released, save the config and destroy the drag offset. if (ms.LeftButton == ButtonState.Released) { dragOffset = null; - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); } } } diff --git a/UI/Rippers/RipperUI.cs b/UI/Rippers/RipperUI.cs index 6c8a3cde57..2f9cce458e 100644 --- a/UI/Rippers/RipperUI.cs +++ b/UI/Rippers/RipperUI.cs @@ -105,14 +105,14 @@ internal static void Reset() public static void Draw(SpriteBatch spriteBatch, Player player) { // Sanity check the planned Rage Meter position - Vector2 rageScreenRatioPos = new Vector2(CalamityConfig.Instance.RageMeterPosX, CalamityConfig.Instance.RageMeterPosY); + Vector2 rageScreenRatioPos = new Vector2(CalamityClientConfig.Instance.RageMeterPosX, CalamityClientConfig.Instance.RageMeterPosY); if (rageScreenRatioPos.X < 0f || rageScreenRatioPos.X > 100f) rageScreenRatioPos.X = DefaultRagePosX; if (rageScreenRatioPos.Y < 0f || rageScreenRatioPos.Y > 100f) rageScreenRatioPos.Y = DefaultRagePosY; // Sanity check the planned Adrenaline Meter position - Vector2 adrenScreenRatioPos = new Vector2(CalamityConfig.Instance.AdrenalineMeterPosX, CalamityConfig.Instance.AdrenalineMeterPosY); + Vector2 adrenScreenRatioPos = new Vector2(CalamityClientConfig.Instance.AdrenalineMeterPosX, CalamityClientConfig.Instance.AdrenalineMeterPosY); if (adrenScreenRatioPos.X < 0f || adrenScreenRatioPos.X > 100f) adrenScreenRatioPos.X = DefaultAdrenPosX; if (adrenScreenRatioPos.Y < 0f || adrenScreenRatioPos.Y > 100f) @@ -135,18 +135,18 @@ public static void Draw(SpriteBatch spriteBatch, Player player) else { bool changed = false; - if (CalamityConfig.Instance.RageMeterPosX != rageScreenRatioPos.X) + if (CalamityClientConfig.Instance.RageMeterPosX != rageScreenRatioPos.X) { - CalamityConfig.Instance.RageMeterPosX = rageScreenRatioPos.X; + CalamityClientConfig.Instance.RageMeterPosX = rageScreenRatioPos.X; changed = true; } - if (CalamityConfig.Instance.RageMeterPosY != rageScreenRatioPos.Y) + if (CalamityClientConfig.Instance.RageMeterPosY != rageScreenRatioPos.Y) { - CalamityConfig.Instance.RageMeterPosY = rageScreenRatioPos.Y; + CalamityClientConfig.Instance.RageMeterPosY = rageScreenRatioPos.Y; changed = true; } if (changed) - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); } if (modPlayer.AdrenalineEnabled) @@ -154,18 +154,18 @@ public static void Draw(SpriteBatch spriteBatch, Player player) else { bool changed = false; - if (CalamityConfig.Instance.AdrenalineMeterPosX != adrenScreenRatioPos.X) + if (CalamityClientConfig.Instance.AdrenalineMeterPosX != adrenScreenRatioPos.X) { - CalamityConfig.Instance.AdrenalineMeterPosX = adrenScreenRatioPos.X; + CalamityClientConfig.Instance.AdrenalineMeterPosX = adrenScreenRatioPos.X; changed = true; } - if (CalamityConfig.Instance.AdrenalineMeterPosY != adrenScreenRatioPos.Y) + if (CalamityClientConfig.Instance.AdrenalineMeterPosY != adrenScreenRatioPos.Y) { - CalamityConfig.Instance.AdrenalineMeterPosY = adrenScreenRatioPos.Y; + CalamityClientConfig.Instance.AdrenalineMeterPosY = adrenScreenRatioPos.Y; changed = true; } if (changed) - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); } #region Mouse Interaction @@ -190,7 +190,7 @@ public static void Draw(SpriteBatch spriteBatch, Player player) if (rageHover && !adrenHover) { // If the meter isn't locked, then the player's mouse counts as being over interface - if (!CalamityConfig.Instance.MeterPosLock) + if (!CalamityClientConfig.Instance.MeterPosLock) Main.LocalPlayer.mouseInterface = true; // Add hover text if the mouse is over Rage bar @@ -199,7 +199,7 @@ public static void Draw(SpriteBatch spriteBatch, Player player) // The bar is draggable if enabled in config. Vector2 newScreenRatioPosition = rageScreenRatioPos; - if (!CalamityConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) + if (!CalamityClientConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) { // If the drag offset doesn't exist yet, create it. if (!rageDragOffset.HasValue) @@ -217,21 +217,21 @@ public static void Draw(SpriteBatch spriteBatch, Player player) Vector2 delta = newScreenRatioPosition - rageScreenRatioPos; if (Math.Abs(delta.X) >= MouseDragEpsilon || Math.Abs(delta.Y) >= MouseDragEpsilon) { - CalamityConfig.Instance.RageMeterPosX = newScreenRatioPosition.X; - CalamityConfig.Instance.RageMeterPosY = newScreenRatioPosition.Y; + CalamityClientConfig.Instance.RageMeterPosX = newScreenRatioPosition.X; + CalamityClientConfig.Instance.RageMeterPosY = newScreenRatioPosition.Y; } // When the mouse is released, save the config and destroy the drag offset. if (ms.LeftButton == ButtonState.Released) { rageDragOffset = null; - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); } } else if (adrenHover) { // If the meter isn't locked, then the player's mouse counts as being over interface - if (!CalamityConfig.Instance.MeterPosLock) + if (!CalamityClientConfig.Instance.MeterPosLock) Main.LocalPlayer.mouseInterface = true; // Add hover text if the mouse is over the bar @@ -241,7 +241,7 @@ public static void Draw(SpriteBatch spriteBatch, Player player) // The bar is draggable if enabled in config. Vector2 newScreenRatioPosition = adrenScreenRatioPos; - if (!CalamityConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) + if (!CalamityClientConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) { // If the drag offset doesn't exist yet, create it. if (!adrenDragOffset.HasValue) @@ -259,15 +259,15 @@ public static void Draw(SpriteBatch spriteBatch, Player player) Vector2 delta = newScreenRatioPosition - adrenScreenRatioPos; if (Math.Abs(delta.X) >= MouseDragEpsilon || Math.Abs(delta.Y) >= MouseDragEpsilon) { - CalamityConfig.Instance.AdrenalineMeterPosX = newScreenRatioPosition.X; - CalamityConfig.Instance.AdrenalineMeterPosY = newScreenRatioPosition.Y; + CalamityClientConfig.Instance.AdrenalineMeterPosX = newScreenRatioPosition.X; + CalamityClientConfig.Instance.AdrenalineMeterPosY = newScreenRatioPosition.Y; } // When the mouse is released, save the config and destroy the drag offset. if (ms.LeftButton == ButtonState.Released) { adrenDragOffset = null; - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); } } #endregion @@ -446,7 +446,7 @@ private static void DrawAdrenalineBar(SpriteBatch spriteBatch, CalamityPlayer mo #endregion private static Vector2 GetShakeOffset() { - float shake = CalamityConfig.Instance.RipperMeterShake; + float shake = CalamityClientConfig.Instance.RipperMeterShake; float shakeX = Main.rand.NextFloat(-shake, shake); float shakeY = Main.rand.NextFloat(-shake, shake); return new Vector2(shakeX, shakeY); diff --git a/UI/SpeedrunTimerUI.cs b/UI/SpeedrunTimerUI.cs index 6f340be742..7835193f47 100644 --- a/UI/SpeedrunTimerUI.cs +++ b/UI/SpeedrunTimerUI.cs @@ -44,11 +44,11 @@ public class SpeedrunTimerUI public static void Draw(Player player) { - if (Main.gameMenu || !CalamityConfig.Instance.SpeedrunTimer) + if (Main.gameMenu || !CalamityClientConfig.Instance.SpeedrunTimer) return; // Sanity check the planned position before drawing - Vector2 screenRatioPosition = new Vector2(CalamityConfig.Instance.SpeedrunTimerPosX, CalamityConfig.Instance.SpeedrunTimerPosY); + 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) diff --git a/UI/StealthUI.cs b/UI/StealthUI.cs index 4562d8a1fe..5abcc3896f 100644 --- a/UI/StealthUI.cs +++ b/UI/StealthUI.cs @@ -41,7 +41,7 @@ internal static void Unload() public static void Draw(SpriteBatch spriteBatch, Player player) { // Sanity check the planned position before drawing - Vector2 screenRatioPosition = new Vector2(CalamityConfig.Instance.StealthMeterPosX, CalamityConfig.Instance.StealthMeterPosY); + Vector2 screenRatioPosition = new Vector2(CalamityClientConfig.Instance.StealthMeterPosX, CalamityClientConfig.Instance.StealthMeterPosY); if (screenRatioPosition.X < 0f || screenRatioPosition.X > 100f) screenRatioPosition.X = DefaultStealthPosX; if (screenRatioPosition.Y < 0f || screenRatioPosition.Y > 100f) @@ -57,26 +57,26 @@ public static void Draw(SpriteBatch spriteBatch, Player player) CalamityPlayer modPlayer = player.Calamity(); // If not drawing the stealth meter, save its latest position to config and leave. - if (modPlayer.stealthUIAlpha > 0f && CalamityConfig.Instance.StealthMeter && modPlayer.rogueStealthMax > 0f && modPlayer.wearingRogueArmor) + if (modPlayer.stealthUIAlpha > 0f && CalamityClientConfig.Instance.StealthMeter && modPlayer.rogueStealthMax > 0f && modPlayer.wearingRogueArmor) { DrawStealthBar(spriteBatch, modPlayer, screenPos); } else { bool changed = false; - if (CalamityConfig.Instance.StealthMeterPosX != screenRatioPosition.X) + if (CalamityClientConfig.Instance.StealthMeterPosX != screenRatioPosition.X) { - CalamityConfig.Instance.StealthMeterPosX = screenRatioPosition.X; + CalamityClientConfig.Instance.StealthMeterPosX = screenRatioPosition.X; changed = true; } - if (CalamityConfig.Instance.StealthMeterPosY != screenRatioPosition.Y) + if (CalamityClientConfig.Instance.StealthMeterPosY != screenRatioPosition.Y) { - CalamityConfig.Instance.StealthMeterPosY = screenRatioPosition.Y; + CalamityClientConfig.Instance.StealthMeterPosY = screenRatioPosition.Y; changed = true; } if (changed) - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); } Rectangle mouseHitbox = new Rectangle((int)Main.MouseScreen.X, (int)Main.MouseScreen.Y, 8, 8); @@ -88,7 +88,7 @@ public static void Draw(SpriteBatch spriteBatch, Player player) // Handle mouse dragging if (stealthBar.Intersects(mouseHitbox)) { - if (!CalamityConfig.Instance.MeterPosLock) + if (!CalamityClientConfig.Instance.MeterPosLock) Main.LocalPlayer.mouseInterface = true; // If the mouse is on top of the meter, show the player's exact numeric stealth. @@ -113,7 +113,7 @@ public static void Draw(SpriteBatch spriteBatch, Player player) Vector2 newScreenRatioPosition = screenRatioPosition; // As long as the mouse button is held down, drag the meter along with an offset. - if (!CalamityConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) + if (!CalamityClientConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) { // If the drag offset doesn't exist yet, create it. if (!dragOffset.HasValue) @@ -131,15 +131,15 @@ public static void Draw(SpriteBatch spriteBatch, Player player) Vector2 delta = newScreenRatioPosition - screenRatioPosition; if (Math.Abs(delta.X) >= MouseDragEpsilon || Math.Abs(delta.Y) >= MouseDragEpsilon) { - CalamityConfig.Instance.StealthMeterPosX = newScreenRatioPosition.X; - CalamityConfig.Instance.StealthMeterPosY = newScreenRatioPosition.Y; + CalamityClientConfig.Instance.StealthMeterPosX = newScreenRatioPosition.X; + CalamityClientConfig.Instance.StealthMeterPosY = newScreenRatioPosition.Y; } // When the mouse is released, save the config and destroy the drag offset. if (ms.LeftButton == ButtonState.Released) { dragOffset = null; - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); } } } diff --git a/UI/SulphurousWaterMeter/SulphurousWaterMeterUI.cs b/UI/SulphurousWaterMeter/SulphurousWaterMeterUI.cs index a1a4899dab..97a3df2f64 100644 --- a/UI/SulphurousWaterMeter/SulphurousWaterMeterUI.cs +++ b/UI/SulphurousWaterMeter/SulphurousWaterMeterUI.cs @@ -37,7 +37,7 @@ public override void Unload() public static void Draw(SpriteBatch spriteBatch, Player player) { // Sanity check the planned position before drawing. This is done relative. - Vector2 screenRatioPosition = new Vector2(CalamityConfig.Instance.SulphuricWaterMeterPosX, CalamityConfig.Instance.SulphuricWaterMeterPosY); + Vector2 screenRatioPosition = new Vector2(CalamityClientConfig.Instance.SulphuricWaterMeterPosX, CalamityClientConfig.Instance.SulphuricWaterMeterPosY); if (screenRatioPosition.X < 0f || screenRatioPosition.X > 100f) screenRatioPosition.X = DefaultPosX; if (screenRatioPosition.Y < 0f || screenRatioPosition.Y > 100f) @@ -58,19 +58,19 @@ public static void Draw(SpriteBatch spriteBatch, Player player) else { bool changed = false; - if (CalamityConfig.Instance.SulphuricWaterMeterPosX != screenRatioPosition.X) + if (CalamityClientConfig.Instance.SulphuricWaterMeterPosX != screenRatioPosition.X) { - CalamityConfig.Instance.SulphuricWaterMeterPosX = screenRatioPosition.X; + CalamityClientConfig.Instance.SulphuricWaterMeterPosX = screenRatioPosition.X; changed = true; } - if (CalamityConfig.Instance.SulphuricWaterMeterPosY != screenRatioPosition.Y) + if (CalamityClientConfig.Instance.SulphuricWaterMeterPosY != screenRatioPosition.Y) { - CalamityConfig.Instance.SulphuricWaterMeterPosY = screenRatioPosition.Y; + CalamityClientConfig.Instance.SulphuricWaterMeterPosY = screenRatioPosition.Y; changed = true; } if (changed) - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); } Rectangle mouseHitbox = new Rectangle((int)Main.MouseScreen.X, (int)Main.MouseScreen.Y, 8, 8); @@ -82,7 +82,7 @@ public static void Draw(SpriteBatch spriteBatch, Player player) // Handle mouse dragging if (waterBarArea.Intersects(mouseHitbox)) { - if (!CalamityConfig.Instance.MeterPosLock) + if (!CalamityClientConfig.Instance.MeterPosLock) Main.LocalPlayer.mouseInterface = true; // If the mouse is on top of the meter, show the player's accumulated sulphuric poisoning. @@ -97,7 +97,7 @@ public static void Draw(SpriteBatch spriteBatch, Player player) Vector2 newScreenRatioPosition = screenRatioPosition; // As long as the mouse button is held down, drag the meter along with an offset. - if (!CalamityConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) + if (!CalamityClientConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) { // If the drag offset doesn't exist yet, create it. if (!dragOffset.HasValue) @@ -115,15 +115,15 @@ public static void Draw(SpriteBatch spriteBatch, Player player) Vector2 delta = newScreenRatioPosition - screenRatioPosition; if (Math.Abs(delta.X) >= MouseDragEpsilon || Math.Abs(delta.Y) >= MouseDragEpsilon) { - CalamityConfig.Instance.SulphuricWaterMeterPosX = newScreenRatioPosition.X; - CalamityConfig.Instance.SulphuricWaterMeterPosY = newScreenRatioPosition.Y; + CalamityClientConfig.Instance.SulphuricWaterMeterPosX = newScreenRatioPosition.X; + CalamityClientConfig.Instance.SulphuricWaterMeterPosY = newScreenRatioPosition.Y; } // When the mouse is released, save the config and destroy the drag offset. if (ms.LeftButton == ButtonState.Released) { dragOffset = null; - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); } } else diff --git a/Utilities/DrawingUtils.cs b/Utilities/DrawingUtils.cs index 0c18da9cc3..0ef3726d81 100644 --- a/Utilities/DrawingUtils.cs +++ b/Utilities/DrawingUtils.cs @@ -72,7 +72,7 @@ public static void DrawAfterimagesCentered(Projectile proj, int mode, Color ligh // If no afterimages are drawn due to an invalid mode being specified, ensure the projectile itself is drawn anyway. bool failedToDrawAfterimages = false; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { Vector2 centerOffset = drawCentered ? proj.Size / 2f : Vector2.Zero; Color alphaColor = proj.GetAlpha(lightColor); @@ -135,7 +135,7 @@ public static void DrawAfterimagesCentered(Projectile proj, int mode, Color ligh } // Draw the projectile itself. Only do this if no afterimages are drawn because afterimage 0 is the projectile itself. - if (!CalamityConfig.Instance.Afterimages || ProjectileID.Sets.TrailCacheLength[proj.type] <= 0 || failedToDrawAfterimages) + if (!CalamityClientConfig.Instance.Afterimages || ProjectileID.Sets.TrailCacheLength[proj.type] <= 0 || failedToDrawAfterimages) { Vector2 startPos = drawCentered ? proj.Center : proj.position; Main.spriteBatch.Draw(texture, startPos - Main.screenPosition + new Vector2(0f, proj.gfxOffY), rectangle, proj.GetAlpha(lightColor), rotation, origin, scale, spriteEffects, 0f); diff --git a/Utilities/DropHelper.cs b/Utilities/DropHelper.cs index 88a518df31..0575ad5b0c 100644 --- a/Utilities/DropHelper.cs +++ b/Utilities/DropHelper.cs @@ -487,7 +487,7 @@ public static IItemDropRuleCondition If(Func lambda, Func public static IItemDropRuleCondition HallowedBarsCondition = If((info) => { // If the Early Hardmode Progression Rework is not enabled, then Hallowed Bars can always drop from Mechanical Bosses. - if (!CalamityConfig.Instance.EarlyHardmodeProgressionRework) + if (!CalamityServerConfig.Instance.EarlyHardmodeProgressionRework) return true; // If the Early Hardmode Progression Rework is enabled, then all 3 Mechanical Bosses must be defeated for Hallowed Bars to drop. From a059666398cdcb0db5b08cdaaa22aa8ac9646c9c Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 22 Nov 2025 16:24:43 -0500 Subject: [PATCH 367/401] Added VCMM status message config --- CalPlayer/CalamityPlayer.cs | 6 +++++- CalPlayer/CalamityPlayerMiscEffects.cs | 5 +++++ CalamityConfig.cs | 4 ++++ CalamityMod.cs | 12 ++++++++++++ Events/BossRushEvent.cs | 2 +- Localization/en-US/Mods.CalamityMod.Configs.hjson | 5 +++++ Localization/en-US/Mods.CalamityMod.Misc.hjson | 1 + 7 files changed, 33 insertions(+), 2 deletions(-) diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 606e26bebd..1577f7c620 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -4866,8 +4866,12 @@ public override void OnEnterWorld() if (CalamityClientConfig.Instance.SpeedrunTimer) CalamityMod.SpeedrunTimer.Restart(); + bool showWikiMessage = CalamityClientConfig.Instance.WikiStatusMessage; + bool showVCMMMessage = CalamityClientConfig.Instance.VCMMStatusMessage && !CalamityMod.Instance.VCMMAvailable; + bool showStartupMessages = showWikiMessage || showVCMMMessage; + // Set a random delay between 12 and 20 seconds. When this delay hits zero, startup messages display - if (CalamityClientConfig.Instance.WikiStatusMessage) + if (showStartupMessages) { startMessageDisplayDelay = Main.rand.Next(CalamityUtils.SecondsToFrames(12), CalamityUtils.SecondsToFrames(20) + 1); } diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index 98b0319d1b..6b1484b0e7 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -4153,6 +4153,11 @@ private void HandleTextChatMessages() } } + if (CalamityClientConfig.Instance.VCMMStatusMessage && !CalamityMod.Instance.VCMMAvailable) + { + CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.VCMMStatus"); + } + --startMessageDisplayDelay; } } diff --git a/CalamityConfig.cs b/CalamityConfig.cs index 49cc222959..77cc6af335 100644 --- a/CalamityConfig.cs +++ b/CalamityConfig.cs @@ -62,6 +62,10 @@ internal void ClampValues(StreamingContext context) [DefaultValue(true)] public bool WikiStatusMessage { get; set; } + [BackgroundColor(192, 54, 64, 192)] + [DefaultValue(true)] + public bool VCMMStatusMessage { get; set; } + [BackgroundColor(192, 54, 64, 192)] [DefaultValue(true)] public bool ShopNewAlert { get; set; } diff --git a/CalamityMod.cs b/CalamityMod.cs index 83f341aeb9..76aec0acec 100644 --- a/CalamityMod.cs +++ b/CalamityMod.cs @@ -154,6 +154,11 @@ public struct LavaTextures internal Mod musicMod = null; internal bool MusicAvailable => musicMod is not null; + // This is Vanilla Calamity Mod Music, internally named UnCalamityModMusic. + // VCMM is an official music add-on. Unlike the main music mod, it is not a dependency. + internal Mod vcmm = null; + internal bool VCMMAvailable => vcmm is not null; + // Please keep this in alphabetical order so it's easy to read internal Mod ancientsAwakened = null; internal Mod biomeLava = null; @@ -186,6 +191,8 @@ public override void Load() // If any of these mods aren't loaded, it will simply keep them as null. musicMod = null; ModLoader.TryGetMod("CalamityModMusic", out musicMod); + vcmm = null; + ModLoader.TryGetMod("UnCalamityModMusic", out vcmm); ancientsAwakened = null; ModLoader.TryGetMod("AAMod", out ancientsAwakened); biomeLava = null; @@ -445,6 +452,7 @@ private void LoadClient() public override void Unload() { musicMod = null; + vcmm = null; ancientsAwakened = null; biomeLava = null; @@ -789,6 +797,10 @@ private void SetupBossKillTimes() // This function returns an available Calamity Music Mod track, or null if the Calamity Music Mod is not available. public int? GetMusicFromMusicMod(string songFilename) => MusicAvailable ? MusicLoader.GetMusicSlot(musicMod, "Sounds/Music/" + songFilename) : null; + // This function returns an available VCMM track, or null if VCMM is not available. + // Unlike the main Music Mod, VCMM is hierarchical. + public int? GetMusicFromVCMM(string songPath) => VCMMAvailable ? MusicLoader.GetMusicSlot(vcmm, "Assets/" + songPath) : null; + #endregion #region Mod Support diff --git a/Events/BossRushEvent.cs b/Events/BossRushEvent.cs index 76b1624211..6ed24fce51 100644 --- a/Events/BossRushEvent.cs +++ b/Events/BossRushEvent.cs @@ -484,7 +484,7 @@ public static int MusicToPlay return -1; } int tier = CurrentTier; - if (CalamityMod.Instance.musicMod != null) + if (CalamityMod.Instance.MusicAvailable) { // Boss Rush music for tier 5 doesn't exist if (tier > 4) diff --git a/Localization/en-US/Mods.CalamityMod.Configs.hjson b/Localization/en-US/Mods.CalamityMod.Configs.hjson index 97dbe057ae..225ad3d480 100644 --- a/Localization/en-US/Mods.CalamityMod.Configs.hjson +++ b/Localization/en-US/Mods.CalamityMod.Configs.hjson @@ -316,6 +316,11 @@ CalamityClientConfig: { ''' } + VCMMStatusMessage: { + Label: "[i:MusicBoxMartians] VCMM Status Message" + Tooltip: Enable or disable the status message promoting the Vanilla Calamity Music Mod that plays on world entry. + } + WikiStatusMessage: { Label: "[i:Book] Wiki Status Message" Tooltip: Enable or disable the status message promoting the Official Calamity Wiki that plays on world entry. diff --git a/Localization/en-US/Mods.CalamityMod.Misc.hjson b/Localization/en-US/Mods.CalamityMod.Misc.hjson index c672e49428..44ab723e7c 100644 --- a/Localization/en-US/Mods.CalamityMod.Misc.hjson +++ b/Localization/en-US/Mods.CalamityMod.Misc.hjson @@ -21,6 +21,7 @@ RecipeGroup: { // Status WikiStatus1: "[i:Book] [c/EE4939:Note: The Fandom wiki is no longer supported by Calamity.] [i:Book]" WikiStatus2: "[i:Book] [c/EE4939:Check out the Official Calamity Mod Wiki at ][c/3989FF:calamitymod.wiki.gg][c/EE4939:!] [i:Book]" +VCMMStatus: "[i:MusicBoxMartians] [c/67F567:Check out the Vanilla Calamity Music Mod at ][c/3898FF:calamitymod.com/downloadvanillamusic][c/67F567:!] [i:MusicBoxMartians]" GimmeSwagPlushieCampaign: "[i:GreenPresent] [c/3BE022:NOW AVAILABLE! Yharon Plushie!] [c/3989FF:calamitymod.com/plush] [i:GreenPresent]" // Recipe Conditions Tier1ArsenalRecipeCondition: View an unencrypted schematic from the lab near the Sunken Sea From 00c90ece12273e0c35dc0406f0049611110c784a Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sat, 22 Nov 2025 17:00:05 -0500 Subject: [PATCH 368/401] Removed Yharon plushie message localization --- Localization/en-US/Mods.CalamityMod.Misc.hjson | 1 - 1 file changed, 1 deletion(-) diff --git a/Localization/en-US/Mods.CalamityMod.Misc.hjson b/Localization/en-US/Mods.CalamityMod.Misc.hjson index 44ab723e7c..94460c1bf3 100644 --- a/Localization/en-US/Mods.CalamityMod.Misc.hjson +++ b/Localization/en-US/Mods.CalamityMod.Misc.hjson @@ -22,7 +22,6 @@ RecipeGroup: { WikiStatus1: "[i:Book] [c/EE4939:Note: The Fandom wiki is no longer supported by Calamity.] [i:Book]" WikiStatus2: "[i:Book] [c/EE4939:Check out the Official Calamity Mod Wiki at ][c/3989FF:calamitymod.wiki.gg][c/EE4939:!] [i:Book]" VCMMStatus: "[i:MusicBoxMartians] [c/67F567:Check out the Vanilla Calamity Music Mod at ][c/3898FF:calamitymod.com/downloadvanillamusic][c/67F567:!] [i:MusicBoxMartians]" -GimmeSwagPlushieCampaign: "[i:GreenPresent] [c/3BE022:NOW AVAILABLE! Yharon Plushie!] [c/3989FF:calamitymod.com/plush] [i:GreenPresent]" // Recipe Conditions Tier1ArsenalRecipeCondition: View an unencrypted schematic from the lab near the Sunken Sea Tier2ArsenalRecipeCondition: Decrypt a schematic from the lab in the large planetoid in the sky From c87e464c76d2f298008a9b705f98551cb59c26ba Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <142704082+CongratsIsTrash@users.noreply.github.com> Date: Sat, 22 Nov 2025 23:09:45 -0500 Subject: [PATCH 369/401] Fixed Mining armor's set bonus cooldown not working --- CalPlayer/CalamityPlayer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index 1577f7c620..ae4cf52258 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -1843,7 +1843,6 @@ public override void ResetEffects() goldArmorGoldDrops = false; miningSet = false; - miningSetCooldown = 0; eskimoSet = false; //vanilla armor meteorSet = false; //vanilla armor, for Space Gun nerf From bd9799620caa80a26b1e88b9b3da4dd00ea141fe Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <142704082+CongratsIsTrash@users.noreply.github.com> Date: Sun, 23 Nov 2025 09:52:50 -0500 Subject: [PATCH 370/401] Fixed Rusty Beacon Prototype not being classified as a sentry --- Items/Weapons/Summon/RustyBeaconPrototype.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Items/Weapons/Summon/RustyBeaconPrototype.cs b/Items/Weapons/Summon/RustyBeaconPrototype.cs index e17e158a74..0e2de87298 100644 --- a/Items/Weapons/Summon/RustyBeaconPrototype.cs +++ b/Items/Weapons/Summon/RustyBeaconPrototype.cs @@ -34,6 +34,7 @@ public override void SetDefaults() Item.shoot = ModContent.ProjectileType(); Item.shootSpeed = 10f; Item.DamageType = DamageClass.Summon; + Item.sentry = true; } public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) From 6146d72cdf2c73b2ce8ba7d0af4e66c7e62152c0 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sun, 23 Nov 2025 10:36:27 -0500 Subject: [PATCH 371/401] GFB Aquatic Scourge poisoning nerf --- CalPlayer/CalamityPlayerLifeRegen.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/CalPlayer/CalamityPlayerLifeRegen.cs b/CalPlayer/CalamityPlayerLifeRegen.cs index 5139c19f45..87012aecaf 100644 --- a/CalPlayer/CalamityPlayerLifeRegen.cs +++ b/CalPlayer/CalamityPlayerLifeRegen.cs @@ -131,9 +131,13 @@ void ApplyDoTDebuff(bool hasDebuff, int negativeLifeRegenToApply, bool immuneCon if (CalamityGlobalNPC.aquaticScourge >= 0 && Main.zenithWorld) { NPC AS = Main.npc[CalamityGlobalNPC.aquaticScourge]; - //if the player is 50 blocks or more away from the head - if (AS.life < AS.lifeMax) //Only poison when damaged - ASPoisonLevel = Utils.GetLerpValue(800f, 1600f, Vector2.Distance(Player.Center, AS.Center), true); + float scoogDistance = Vector2.Distance(Player.Center, AS.Center); + // GFB Aquatic Scourge poisons you if: + // 1. You are over 50 blocks away from the head + // 2. You are under 250 blocks away from the head (so that people halfway across the world aren't getting killed for no reason) + // 3. Aquatic Scourge has been damaged + if (AS.life < AS.lifeMax && scoogDistance < 4000f) + ASPoisonLevel = Utils.GetLerpValue(800f, 1600f, scoogDistance, true); } bool ASPoisoning = ASPoisonLevel > 0f; @@ -142,7 +146,7 @@ void ApplyDoTDebuff(bool hasDebuff, int negativeLifeRegenToApply, bool immuneCon float increment = 1f / SulphSeaWaterSafetyTime; //No way to mitigate AS Poisoning if (ASPoisoning) - increment *= 4f + (8f * ASPoisonLevel); + increment *= 3f + (6f * ASPoisonLevel); if (sulphurskin && !ASPoisoning) increment *= 0.5f; if (sulphurSet && !ASPoisoning) From 3c83fb6fa4ff2e5a08f671e300ec700f47e530e7 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Sun, 23 Nov 2025 23:45:22 -0500 Subject: [PATCH 372/401] The public shall no longer suffer through Oblivion Also Skeletron Prime no longer spawns Probes, and fixed him not spinning on the first spin attack --- CalamityLists.cs | 3 - CalamityMod.cs | 8 - DataStructures/NPCStats.cs | 10 - Events/BossRushEvent.cs | 2 +- ExtraTextures/ChadPrime.png | Bin 6702 -> 0 bytes ExtraTextures/ChadPrimeHeadGlow.png | Bin 588 -> 0 bytes .../en-US/Mods.CalamityMod.Configs.hjson | 8 +- .../en-US/Mods.CalamityMod.NPCs.hjson | 1 - NPCs/CalamityGlobalNPC.cs | 145 +-- NPCs/NormalNPCs/SkeletronPrime2.cs | 910 ------------------ NPCs/NormalNPCs/SkeletronPrime2.png | Bin 6696 -> 0 bytes .../Bosses/DestroyerAI.cs | 110 +-- .../Bosses/SkeletronPrimeAI.cs | 175 +--- NPCs/VanillaNPCAIOverrides/Bosses/TwinsAI.cs | 113 +-- Projectiles/CalamityGlobalProjectile.cs | 226 +---- .../SkeletronPrimeMasterMusicScene.cs | 14 - 16 files changed, 126 insertions(+), 1599 deletions(-) delete mode 100644 ExtraTextures/ChadPrime.png delete mode 100644 ExtraTextures/ChadPrimeHeadGlow.png delete mode 100644 NPCs/NormalNPCs/SkeletronPrime2.cs delete mode 100644 NPCs/NormalNPCs/SkeletronPrime2.png delete mode 100644 Scenes/MusicScenes/SkeletronPrimeMasterMusicScene.cs diff --git a/CalamityLists.cs b/CalamityLists.cs index 774bf0f601..37f030063c 100644 --- a/CalamityLists.cs +++ b/CalamityLists.cs @@ -1031,7 +1031,6 @@ public static void LoadLists() NPCID.Retinazer, NPCID.Spazmatism, NPCID.SkeletronPrime, - NPCType(), NPCID.PrimeCannon, NPCID.PrimeSaw, NPCID.PrimeLaser, @@ -2160,7 +2159,6 @@ public static void LoadLists() SkeletronPrimeIDs = new List { NPCID.SkeletronPrime, - NPCType(), NPCID.PrimeCannon, NPCID.PrimeLaser, NPCID.PrimeSaw, @@ -2565,7 +2563,6 @@ public static void LoadLists() { NPCID.Probe, 5000 }, { NPCID.SkeletronPrime, 160000 }, // 30 seconds - { NPCType(), 160000 }, { NPCID.PrimeVice, 54000 }, { NPCID.PrimeCannon, 45000 }, { NPCID.PrimeSaw, 45000 }, diff --git a/CalamityMod.cs b/CalamityMod.cs index 76aec0acec..ca64b16be0 100644 --- a/CalamityMod.cs +++ b/CalamityMod.cs @@ -129,10 +129,6 @@ public struct LavaTextures public static Asset WallOfFleshEyeGlowmask; public static Asset WallOfFleshDemonSickleTexture; - // Master Rev+ Skeletron Prime - public static Asset ChadPrime; - public static Asset ChadPrimeEyeGlowmask; - // DR data structure public static SortedDictionary DRValues; @@ -343,10 +339,6 @@ private void LoadClient() WallOfFleshEyeGlowmask = ModContent.Request("CalamityMod/ExtraTextures/VanillaBossGlowmasks/WallOfFleshEyeTelegraphGlow", AssetRequestMode.AsyncLoad); WallOfFleshDemonSickleTexture = ModContent.Request("CalamityMod/Projectiles/Melee/ForbiddenOathbladeProjectile", AssetRequestMode.AsyncLoad); - // Master Rev+ Skeletron Prime textures - ChadPrime = ModContent.Request("CalamityMod/ExtraTextures/ChadPrime", AssetRequestMode.AsyncLoad); - ChadPrimeEyeGlowmask = ModContent.Request("CalamityMod/ExtraTextures/ChadPrimeHeadGlow", AssetRequestMode.AsyncLoad); - // TODO -- Sky shaders should probably be loaded in a ModSystem Filters.Scene["CalamityMod:DevourerofGodsHead"] = new Filter(new DoGScreenShaderData("FilterMiniTower").UseColor(0.4f, 0.1f, 1.0f).UseOpacity(0.5f), EffectPriority.VeryHigh); SkyManager.Instance["CalamityMod:DevourerofGodsHead"] = new DoGSky(); diff --git a/DataStructures/NPCStats.cs b/DataStructures/NPCStats.cs index 0aec9726b2..b2b8d4ee20 100644 --- a/DataStructures/NPCStats.cs +++ b/DataStructures/NPCStats.cs @@ -213,7 +213,6 @@ internal static void LoadEnemyStats() { ModContent.NPCType(), 0.8 }, { NPCID.SkeletronPrime, 0.85 }, - { ModContent.NPCType(), 0.85 }, { NPCID.PrimeCannon, 0.85 }, { NPCID.PrimeLaser, 0.85 }, { NPCID.PrimeSaw, 0.85 }, @@ -416,12 +415,6 @@ internal static void LoadEnemyStats() 102, // 204 while spinning 119, // 238 while spinning 153 } }, // 306 while spinning - { ModContent.NPCType(), new int[] { - 50, // 100 while spinning - 85, // 170 while spinning - 102, // 204 while spinning - 119, // 238 while spinning - 153 } }, // 306 while spinning { NPCID.PrimeVice, new int[] { 70, 102, 136, 170, 255 } }, { NPCID.PrimeSaw, new int[] { 70, 102, 136, 170, 255 } }, { NPCID.PrimeCannon, new int[] { 30, 51, 68, 85, 102 } }, @@ -663,9 +656,6 @@ internal static void LoadEnemyStats() { new Tuple(NPCID.SkeletronPrime, ProjectileID.Skull), new int[] { 50, 108, 124, 140, 210 } }, { new Tuple(NPCID.SkeletronPrime, ProjectileID.DeathLaser), new int[] { 50, 108, 124, 140, 210 } }, { new Tuple(NPCID.SkeletronPrime, ProjectileID.RocketSkeleton), new int[] { 60, 120, 148, 176, 264 } }, - { new Tuple(ModContent.NPCType(), ProjectileID.Skull), new int[] { 50, 108, 124, 140, 210 } }, - { new Tuple(ModContent.NPCType(), ProjectileID.BombSkeletronPrime), new int[] { 80, 160, 180, 200, 300 } }, - { new Tuple(ModContent.NPCType(), ProjectileID.FrostBeam), new int[] { 50, 108, 124, 140, 210 } }, { new Tuple(NPCID.PrimeCannon, ProjectileID.RocketSkeleton), new int[] { 60, 120, 148, 176, 264 } }, { new Tuple(NPCID.PrimeCannon, ProjectileID.BombSkeletronPrime), new int[] { 80, 160, 0, 0, 300 } }, { new Tuple(NPCID.PrimeLaser, ProjectileID.DeathLaser), new int[] { 50, 108, 124, 140, 210 } }, diff --git a/Events/BossRushEvent.cs b/Events/BossRushEvent.cs index 6ed24fce51..29ceb12688 100644 --- a/Events/BossRushEvent.cs +++ b/Events/BossRushEvent.cs @@ -217,7 +217,7 @@ public static void Load() new Boss(ModContent.NPCType(), TimeChangeContext.Day, permittedNPCs: ModContent.NPCType()), - new Boss(NPCID.SkeletronPrime, TimeChangeContext.Night, permittedNPCs: new int[] { ModContent.NPCType(), NPCID.PrimeCannon, NPCID.PrimeSaw, NPCID.PrimeVice, NPCID.PrimeLaser, NPCID.Probe }), + new Boss(NPCID.SkeletronPrime, TimeChangeContext.Night, permittedNPCs: new int[] { NPCID.PrimeCannon, NPCID.PrimeSaw, NPCID.PrimeVice, NPCID.PrimeLaser, NPCID.Probe }), new Boss(ModContent.NPCType(), TimeChangeContext.Night, dimnessFactor: 0.6f, permittedNPCs: new int[] { ModContent.NPCType(), ModContent.NPCType(), ModContent.NPCType() }), diff --git a/ExtraTextures/ChadPrime.png b/ExtraTextures/ChadPrime.png deleted file mode 100644 index 3bbc5902b0e0c058ca668c4ae70daf2b9f1a3967..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6702 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 diff --git a/ExtraTextures/ChadPrimeHeadGlow.png b/ExtraTextures/ChadPrimeHeadGlow.png deleted file mode 100644 index e8b25ba236320b5c71f2c9b12554aec4e055346a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 588 zcmeAS@N?(olHy`uVBq!ia0vp^Jq!$t*EraKtfh+*rGXS0K>?@Yeao-tz{`I{lJ$s+7OwE#Q*m!0w^PbYXPg1LI z_^U2`pI4S&nPr^F5h&p#(k9TV=#t1G`Dtn0^6mBg_dZ=oIz&we0nIufQ1qH%>y*zL z<*zI6&YrVzyUkXgwaf<7c9u45UpISC4*&0!OTOGa`%c$CR}B()) + else if (npc.type == NPCID.SkeletronPrime) { - // HP boosted in Master Mode due to having two heads (piercing can make them die faster than normal here since they share an HP bar) - npc.lifeMax = (int)Math.Round(npc.lifeMax * (Main.masterMode ? 1.7 : 1.2)); + npc.lifeMax = (int)Math.Round(npc.lifeMax * 1.2); npc.npcSlots = 12f; } else if (npc.type <= NPCID.PrimeLaser && npc.type >= NPCID.PrimeCannon) @@ -5728,26 +5727,6 @@ private void EditWhipTagDamage(Projectile proj, NPC npc, ref NPC.HitModifiers mo #region Check Dead public override bool CheckDead(NPC npc) { - if (npc.type == NPCID.SkeletronPrime) - { - if ((Main.masterMode || BossRushEvent.BossRushActive) && CalamityWorld.revenge) - { - // Kill the other head if he's still alive when this head dies - for (int i = 0; i < Main.maxNPCs; i++) - { - NPC nPC = Main.npc[i]; - if (nPC.active && nPC.type == ModContent.NPCType() && nPC.life > 0) - { - nPC.life = 0; - nPC.HitEffect(); - nPC.checkDead(); - nPC.active = false; - nPC.netUpdate = true; - } - } - } - } - if (npc.lifeMax > 1000 && npc.type != NPCID.DungeonSpirit && npc.type != NPCType() && npc.type != NPCType() && @@ -6306,11 +6285,11 @@ public override void OnSpawn(NPC npc, IEntitySource source) #region Drawing public override void FindFrame(NPC npc, int frameHeight) { - if (CalamityWorld.revenge || BossRushEvent.BossRushActive) + /*if (CalamityWorld.revenge || BossRushEvent.BossRushActive) { - if (npc.type == NPCID.SkeletronPrime || npc.type == ModContent.NPCType()) + if (npc.type == NPCID.SkeletronPrime) npc.frameCounter = 0D; - } + }*/ } // Debuff visuals. Alphabetical order as per usual, please @@ -6710,8 +6689,43 @@ public override bool PreDraw(NPC npc, SpriteBatch spriteBatch, Vector2 screenPos if (CalamityWorld.revenge || BossRushEvent.BossRushActive) { - if (npc.type == NPCID.SkeletronPrime || npc.type == ModContent.NPCType() || CalamityLists.DestroyerIDs.Contains(npc.type)) + if (CalamityLists.DestroyerIDs.Contains(npc.type)) return false; + + // Allows correct frames to draw in Rev+ phases + // GFB can rot for all I care + if (npc.type == NPCID.SkeletronPrime && !NPC.IsMechQueenUp) + { + int frameHeight = TextureAssets.Npc[npc.type].Value.Height / Main.npcFrameCount[npc.type]; + if (npc.ai[1] == 0f || npc.ai[1] == 4f) + { + newAI[2] += 1f; + if (newAI[2] >= 12f) + { + newAI[2] = 0f; + newAI[3] += frameHeight; + + if (newAI[3] / frameHeight >= 2f) + newAI[3] = 0f; + } + } + + // Spinning probe spawn or fly over phase + else if (npc.ai[1] == 5f || npc.ai[1] == 6f) + { + newAI[2] = 0f; + newAI[3] = frameHeight; + } + + // Spinning phase + else + { + newAI[2] = 0f; + newAI[3] = frameHeight * 2; + } + + npc.frame.Y = (int)newAI[3]; + } } if (npc.type == NPCID.GolemHeadFree) @@ -7448,83 +7462,6 @@ public override void PostDraw(NPC npc, SpriteBatch spriteBatch, Vector2 screenPo } } - // His afterimages I can't get to work, so fuck it - else if (npc.type == NPCID.SkeletronPrime || npc.type == ModContent.NPCType()) - { - Texture2D npcTexture = (masterMode && revenge && npc.type == NPCID.SkeletronPrime) ? CalamityMod.ChadPrime.Value : TextureAssets.Npc[npc.type].Value; - int frameHeight = npcTexture.Height / Main.npcFrameCount[npc.type]; - - npc.frame.Y = (int)newAI[3]; - - // Mechdusa drawing - if (NPC.IsMechQueenUp) - { - if (npc.ai[1] == 0f || npc.ai[1] == 4f) - { - newAI[2] += 1f; - if (newAI[2] >= 12f) - { - newAI[2] = 0f; - newAI[3] += frameHeight; - if (newAI[3] / frameHeight >= 5) - newAI[3] = frameHeight * 3; - } - } - else - { - newAI[2] = 0f; - newAI[3] = frameHeight * 5; - } - } - - // Floating phase - else if (npc.ai[1] == 0f || npc.ai[1] == 4f) - { - newAI[2] += 1f; - if (newAI[2] >= 12f) - { - newAI[2] = 0f; - newAI[3] += frameHeight; - - if (newAI[3] / frameHeight >= 2f) - newAI[3] = 0f; - } - } - - // Spinning probe spawn or fly over phase - else if (npc.ai[1] == 5f || npc.ai[1] == 6f) - { - newAI[2] = 0f; - newAI[3] = frameHeight; - } - - // Spinning phase - else - { - newAI[2] = 0f; - newAI[3] = frameHeight * 2; - } - - npc.frame.Y = (int)newAI[3]; - - SpriteEffects spriteEffects = SpriteEffects.None; - if (npc.spriteDirection == 1) - spriteEffects = SpriteEffects.FlipHorizontally; - - spriteBatch.Draw(npcTexture, npc.Center - screenPos + new Vector2(0, npc.gfxOffY), npc.frame, npc.GetAlpha(drawColor), npc.rotation, npc.frame.Size() / 2, npc.scale, spriteEffects, 0f); - - Color eyesColor = new Color(200, 200, 200, 0); - if (masterMode && revenge) - { - int alpha = 192; - eyesColor = npc.type == NPCType() ? new Color(150, 100, 255, alpha) : new Color(255, 255, 0, alpha); - Texture2D glowTexture = npc.type == NPCID.SkeletronPrime ? CalamityMod.ChadPrimeEyeGlowmask.Value : SkeletronPrime2.EyeTexture.Value; - spriteBatch.Draw(glowTexture, npc.Center - screenPos + new Vector2(0, npc.gfxOffY), npc.frame, eyesColor, npc.rotation, npc.frame.Size() / 2, npc.scale, spriteEffects, 0f); - } - else - spriteBatch.Draw(TextureAssets.BoneEyes.Value, npc.Center - screenPos + new Vector2(0, npc.gfxOffY), npc.frame, eyesColor, npc.rotation, npc.frame.Size() / 2, npc.scale, spriteEffects, 0f); - } - else if (npc.type == NPCID.Plantera) { // Percent life remaining diff --git a/NPCs/NormalNPCs/SkeletronPrime2.cs b/NPCs/NormalNPCs/SkeletronPrime2.cs deleted file mode 100644 index 2e7c5a641d..0000000000 --- a/NPCs/NormalNPCs/SkeletronPrime2.cs +++ /dev/null @@ -1,910 +0,0 @@ -using System; -using System.IO; -using CalamityMod.Buffs.DamageOverTime; -using CalamityMod.Buffs.StatDebuffs; -using CalamityMod.DataStructures; -using CalamityMod.Events; -using CalamityMod.World; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using ReLogic.Content; -using Terraria; -using Terraria.Audio; -using Terraria.GameContent.Bestiary; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.NPCs.NormalNPCs -{ - public class SkeletronPrime2 : ModNPC - { - public override string BossHeadTexture => $"Terraria/Images/NPC_Head_Boss_18"; - - public static Asset EyeTexture; - - public const int BombTimeLeft = 600; - - public override void SetStaticDefaults() - { - Main.npcFrameCount[NPC.type] = 6; - NPCID.Sets.NPCBestiaryDrawModifiers bestiaryData = new NPCID.Sets.NPCBestiaryDrawModifiers() { Hide = true }; - NPCID.Sets.NPCBestiaryDrawOffset.Add(Type, bestiaryData); - if (!Main.dedServ) - { - EyeTexture = ModContent.Request("CalamityMod/ExtraTextures/SkeletronPrime2HeadGlow"); - } - } - - public override void SetDefaults() - { - NPC.Calamity().canBreakPlayerDefense = true; - NPC.aiStyle = NPCAIStyleID.SkeletronPrimeHead; - NPC.GetNPCDamage(); - NPC.DR_NERD(0.2f); - - NPC.width = 80; - NPC.height = 102; - if (Main.tenthAnniversaryWorld) - NPC.scale *= 0.5f; - if (Main.getGoodWorld) - NPC.scale *= 1.1f; - - NPC.defense = 24; - - NPC.lifeMax = 28000; - double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; - NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); - - NPC.knockBackResist = 0f; - NPC.noGravity = true; - NPC.noTileCollide = true; - NPC.boss = true; - NPC.value = 200000f; - NPC.HitSound = SoundID.NPCHit4; - NPC.DeathSound = SoundID.NPCDeath14; - NPC.Calamity().VulnerableToElectricity = true; - NPC.Calamity().VulnerableToSickness = false; - AnimationType = NPCID.SkeletronPrime; - Music = MusicID.Boss3; - } - - public override void SendExtraAI(BinaryWriter writer) - { - writer.Write(NPC.localAI[0]); - writer.Write(NPC.localAI[1]); - writer.Write(NPC.localAI[2]); - writer.Write(NPC.localAI[3]); - for (int i = 0; i < 4; i++) - writer.Write(NPC.Calamity().newAI[i]); - } - - public override void ReceiveExtraAI(BinaryReader reader) - { - NPC.localAI[0] = reader.ReadSingle(); - NPC.localAI[1] = reader.ReadSingle(); - NPC.localAI[2] = reader.ReadSingle(); - NPC.localAI[3] = reader.ReadSingle(); - for (int i = 0; i < 4; i++) - NPC.Calamity().newAI[i] = reader.ReadSingle(); - } - - public override void BossHeadRotation(ref float rotation) - { - rotation = (NPC.ai[1] == 1f || NPC.ai[1] == 2f) ? NPC.rotation : 0f; - } - - public override void AI() - { - CalamityGlobalNPC calamityGlobalNPC = NPC.Calamity(); - - bool bossRush = BossRushEvent.BossRushActive; - bool death = CalamityWorld.death || bossRush; - - // Percent life remaining - float lifeRatio = NPC.life / (float)NPC.lifeMax; - - // Spawn arms - if (calamityGlobalNPC.newAI[1] == 0f) - { - calamityGlobalNPC.newAI[1] = 1f; - - if (Main.netMode != NetmodeID.MultiplayerClient) - { - // This head owns the Cannon and the Vice in Master Mode - int arm = NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y, NPCID.PrimeCannon, NPC.whoAmI); - Main.npc[arm].ai[0] = -1f; - Main.npc[arm].ai[1] = NPC.whoAmI; - Main.npc[arm].target = NPC.target; - Main.npc[arm].netUpdate = true; - - arm = NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y, NPCID.PrimeVice, NPC.whoAmI); - Main.npc[arm].ai[0] = -1f; - Main.npc[arm].ai[1] = NPC.whoAmI; - Main.npc[arm].target = NPC.target; - Main.npc[arm].ai[3] = 150f; - Main.npc[arm].netUpdate = true; - } - - NPC.SyncExtraAI(); - } - - if (!Main.npc[(int)NPC.ai[0]].active || Main.npc[(int)NPC.ai[0]].aiStyle != NPCAIStyleID.SkeletronPrimeHead) - { - NPC.life = 0; - NPC.HitEffect(); - NPC.active = false; - NPC.netUpdate = true; - } - else - { - // Link the HP of both heads - if (NPC.life > Main.npc[(int)NPC.ai[0]].life) - NPC.life = Main.npc[(int)NPC.ai[0]].life; - - // Push away from the lead head if too close, pull closer if too far, if Mechdusa isn't real - if (!NPC.IsMechQueenUp) - { - float pushVelocity = 0.25f; - if (Vector2.Distance(NPC.Center, Main.npc[(int)NPC.ai[0]].Center) < 80f * NPC.scale) - { - if (NPC.position.X < Main.npc[(int)NPC.ai[0]].position.X) - NPC.velocity.X -= pushVelocity; - else - NPC.velocity.X += pushVelocity; - - if (NPC.position.Y < Main.npc[(int)NPC.ai[0]].position.Y) - NPC.velocity.Y -= pushVelocity; - else - NPC.velocity.Y += pushVelocity; - } - else if (Vector2.Distance(NPC.Center, Main.npc[(int)NPC.ai[0]].Center) > 240f * NPC.scale) - { - if (NPC.position.X < Main.npc[(int)NPC.ai[0]].position.X) - NPC.velocity.X += pushVelocity; - else - NPC.velocity.X -= pushVelocity; - - if (NPC.position.Y < Main.npc[(int)NPC.ai[0]].position.Y) - NPC.velocity.Y += pushVelocity; - else - NPC.velocity.Y -= pushVelocity; - } - } - } - - // Check if arms are alive - bool cannonAlive = false; - bool laserAlive = false; - bool viceAlive = false; - bool sawAlive = false; - if (CalamityGlobalNPC.primeCannon != -1) - { - if (Main.npc[CalamityGlobalNPC.primeCannon].active) - cannonAlive = true; - } - if (CalamityGlobalNPC.primeLaser != -1) - { - if (Main.npc[CalamityGlobalNPC.primeLaser].active) - laserAlive = true; - } - if (CalamityGlobalNPC.primeVice != -1) - { - if (Main.npc[CalamityGlobalNPC.primeVice].active) - viceAlive = true; - } - if (CalamityGlobalNPC.primeSaw != -1) - { - if (Main.npc[CalamityGlobalNPC.primeSaw].active) - sawAlive = true; - } - bool allArmsDead = !cannonAlive && !laserAlive && !viceAlive && !sawAlive; - NPC.chaseable = allArmsDead; - - NPC.defense = NPC.defDefense; - - // Phases - bool phase2 = lifeRatio < 0.66f; - bool phase3 = lifeRatio < 0.33f; - bool spawnSpazmatism = lifeRatio < 0.5f && !bossRush && NPC.localAI[2] == 0f; - - // Spawn Spazmatism in Master Mode (just like Oblivion from Avalon) - if (spawnSpazmatism) - { - Player spazmatismSpawnPlayer = Main.player[Player.FindClosest(NPC.position, NPC.width, NPC.height)]; - SoundEngine.PlaySound(SoundID.Roar, spazmatismSpawnPlayer.Center); - if (Main.netMode != NetmodeID.MultiplayerClient) - NPC.SpawnOnPlayer(spazmatismSpawnPlayer.whoAmI, NPCID.Spazmatism); - - NPC.localAI[2] = 1f; - NPC.SyncVanillaLocalAI(); - } - - // Despawn - if (Main.npc[(int)NPC.ai[0]].ai[1] == 3f) - NPC.ai[1] = 3f; - - // Activate daytime enrage - if (Main.IsItDay() && !bossRush && NPC.ai[1] != 3f && NPC.ai[1] != 2f) - { - // Heal - if (Main.netMode != NetmodeID.MultiplayerClient) - { - int healAmt = NPC.life - 300; - if (healAmt < 0) - { - int absHeal = Math.Abs(healAmt); - NPC.life += absHeal; - NPC.HealEffect(absHeal, true); - NPC.netUpdate = true; - } - } - - NPC.ai[1] = 2f; - SoundEngine.PlaySound(SoundID.ForceRoar, NPC.Center); - } - - // Adjust slowing debuff immunity - bool immuneToSlowingDebuffs = NPC.ai[1] == 5f; - NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; - NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; - NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; - NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; - NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; - NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; - NPC.buffImmune[BuffID.Slow] = immuneToSlowingDebuffs; - NPC.buffImmune[BuffID.Webbed] = immuneToSlowingDebuffs; - - bool normalLaserRotation = NPC.localAI[1] % 2f == 0f; - - // Prevents cheap hits - bool canUseAttackInMaster = NPC.position.Y < Main.player[Main.npc[(int)NPC.ai[0]].target].position.Y - 350f; - - // Float near player - if (NPC.ai[1] == 0f || NPC.ai[1] == 4f) - { - // Avoid unfair bullshit - NPC.damage = 0; - - // Start other phases; if arms are dead, start with spin phase - bool otherHeadChargingOrSpinning = Main.npc[(int)NPC.ai[0]].ai[1] == 5f || Main.npc[(int)NPC.ai[0]].ai[1] == 1f; - - // Start spin phase after 1.875 seconds - NPC.ai[2] += phase3 ? 1.2f : 0.8f; - if (NPC.ai[2] >= (90f - (death ? 15f * (1f - lifeRatio) : 0f)) && (!otherHeadChargingOrSpinning || phase3) && canUseAttackInMaster) - { - bool shouldSpinAround = NPC.ai[1] == 4f && NPC.position.Y < Main.player[Main.npc[(int)NPC.ai[0]].target].position.Y - 400f && - Vector2.Distance(Main.player[Main.npc[(int)NPC.ai[0]].target].Center, NPC.Center) < 600f && Vector2.Distance(Main.player[Main.npc[(int)NPC.ai[0]].target].Center, NPC.Center) > 400f; - - bool shouldCharge = !phase2 && !allArmsDead && !CalamityWorld.LegendaryMode; - if (shouldCharge) - { - NPC.ai[2] = 0f; - NPC.ai[1] = 1f; - NPC.netUpdate = true; - } - else if (shouldSpinAround || NPC.ai[1] != 4f) - { - if (shouldSpinAround) - { - NPC.localAI[3] = 300f; - NPC.SyncVanillaLocalAI(); - } - - NPC.ai[2] = 0f; - NPC.ai[1] = shouldSpinAround ? 5f : 1f; - NPC.netUpdate = true; - } - } - - if (NPC.IsMechQueenUp) - NPC.rotation = NPC.rotation.AngleLerp(NPC.velocity.X / 15f * 0.5f, 0.75f); - else - NPC.rotation = NPC.velocity.X / 15f; - - float acceleration = (bossRush ? 0.2f : 0.125f) + (death ? 0.05f * (1f - lifeRatio) : 0f); - float accelerationMult = 1f; - if (!cannonAlive) - { - acceleration += 0.025f; - accelerationMult += 0.5f; - } - if (!laserAlive) - { - acceleration += 0.025f; - accelerationMult += 0.5f; - } - if (!viceAlive) - acceleration += 0.025f; - if (!sawAlive) - acceleration += 0.025f; - acceleration *= accelerationMult; - - float topVelocity = acceleration * 100f; - float deceleration = 0.7f; - - float headDecelerationUpDist = 0f; - float headDecelerationDownDist = 0f; - float headDecelerationHorizontalDist = 0f; - int headHorizontalDirection = ((!(Main.player[Main.npc[(int)NPC.ai[0]].target].Center.X < NPC.Center.X)) ? 1 : (-1)); - if (NPC.IsMechQueenUp) - { - headDecelerationHorizontalDist = -150f * (float)headHorizontalDirection; - headDecelerationUpDist = 50f; - headDecelerationDownDist = 50f; - } - - if (NPC.position.Y > Main.player[Main.npc[(int)NPC.ai[0]].target].position.Y - (400f + headDecelerationUpDist)) - { - if (NPC.velocity.Y > 0f) - NPC.velocity.Y *= deceleration; - - NPC.velocity.Y -= acceleration; - - if (NPC.velocity.Y > topVelocity) - NPC.velocity.Y = topVelocity; - } - else if (NPC.position.Y < Main.player[Main.npc[(int)NPC.ai[0]].target].position.Y - (450f + headDecelerationDownDist)) - { - if (NPC.velocity.Y < 0f) - NPC.velocity.Y *= deceleration; - - NPC.velocity.Y += acceleration; - - if (NPC.velocity.Y < -topVelocity) - NPC.velocity.Y = -topVelocity; - } - - if (NPC.Center.X > Main.player[Main.npc[(int)NPC.ai[0]].target].Center.X + (400f + headDecelerationHorizontalDist)) - { - if (NPC.velocity.X > 0f) - NPC.velocity.X *= deceleration; - - NPC.velocity.X -= acceleration; - - if (NPC.velocity.X > topVelocity) - NPC.velocity.X = topVelocity; - } - if (NPC.Center.X < Main.player[Main.npc[(int)NPC.ai[0]].target].Center.X - (400f + headDecelerationHorizontalDist)) - { - if (NPC.velocity.X < 0f) - NPC.velocity.X *= deceleration; - - NPC.velocity.X += acceleration; - - if (NPC.velocity.X < -topVelocity) - NPC.velocity.X = -topVelocity; - } - } - - else - { - // Spinning - if (NPC.ai[1] == 1f) - { - NPC.defense *= 2; - NPC.damage = NPC.defDamage * 2; - - calamityGlobalNPC.CurrentlyIncreasingDefenseOrDR = true; - - if (phase2 && Main.netMode != NetmodeID.MultiplayerClient) - { - NPC.localAI[0] += 1f; - if (NPC.localAI[0] >= 60f) - { - NPC.localAI[0] = 0f; - - int totalProjectiles = bossRush ? 20 : death ? 12 : 10; - float radians = MathHelper.TwoPi / totalProjectiles; - int type = ProjectileID.FrostBeam; - int damage = NPC.GetProjectileDamage(type); - - // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) - { - double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; - double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; - if (!NPC.downedMechBossAny) - damage = (int)(damage * firstMechMultiplier); - else if ((!NPC.downedMechBoss1 && !NPC.downedMechBoss2) || (!NPC.downedMechBoss2 && !NPC.downedMechBoss3) || (!NPC.downedMechBoss3 && !NPC.downedMechBoss1)) - damage = (int)(damage * secondMechMultiplier); - } - - float velocity = 4.5f; - double angleA = radians * 0.5; - double angleB = MathHelper.ToRadians(90f) - angleA; - float velocityX = (float)(velocity * Math.Sin(angleA) / Math.Sin(angleB)); - Vector2 spinningPoint = normalLaserRotation ? new Vector2(0f, -velocity) : new Vector2(-velocityX, -velocity); - for (int k = 0; k < totalProjectiles; k++) - { - Vector2 laserFireDirection = spinningPoint.RotatedBy(radians * k); - int proj = Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center + laserFireDirection.SafeNormalize(Vector2.UnitY) * 140f, laserFireDirection, type, damage, 0f, Main.myPlayer, 1f, 0f); - Main.projectile[proj].timeLeft = 600; - } - NPC.localAI[1] += 1f; - } - } - - NPC.ai[2] += 1f; - if (NPC.ai[2] == 2f) - SoundEngine.PlaySound(SoundID.ForceRoar, NPC.Center); - - // Spin for 3 seconds then return to floating phase - float phaseTimer = 240f; - if (phase2 && !phase3) - phaseTimer += 60f; - - if (NPC.ai[2] >= (phaseTimer - (death ? 60f * (1f - lifeRatio) : 0f))) - { - NPC.ai[2] = 0f; - NPC.ai[1] = 4f; - NPC.localAI[0] = 0f; - } - - if (NPC.IsMechQueenUp) - NPC.rotation = NPC.rotation.AngleLerp(NPC.velocity.X / 15f * 0.5f, 0.75f); - else - NPC.rotation += NPC.direction * 0.3f; - - Vector2 headPosition = NPC.Center; - float headTargetX = Main.player[Main.npc[(int)NPC.ai[0]].target].Center.X - headPosition.X; - float headTargetY = Main.player[Main.npc[(int)NPC.ai[0]].target].Center.Y - headPosition.Y; - float headTargetDistance = (float)Math.Sqrt(headTargetX * headTargetX + headTargetY * headTargetY); - - float speed = bossRush ? 12f : 8f; - if (phase2) - speed += 0.5f; - if (phase3) - speed += 0.5f; - - if (headTargetDistance > 150f) - { - float baseDistanceVelocityMult = 1f + MathHelper.Clamp((headTargetDistance - 150f) * 0.0015f, 0.05f, 1.5f); - speed *= baseDistanceVelocityMult; - } - - if (NPC.IsMechQueenUp) - { - float mechdusaSpeedMult = (NPC.npcsFoundForCheckActive[NPCID.TheDestroyerBody] ? 0.6f : 0.75f); - speed *= mechdusaSpeedMult; - } - - headTargetDistance = speed / headTargetDistance; - NPC.velocity.X = headTargetX * headTargetDistance; - NPC.velocity.Y = headTargetY * headTargetDistance; - - if (NPC.IsMechQueenUp) - { - float mechdusaAccelMult = Vector2.Distance(NPC.Center, Main.player[Main.npc[(int)NPC.ai[0]].target].Center); - if (mechdusaAccelMult < 0.1f) - mechdusaAccelMult = 0f; - - if (mechdusaAccelMult < speed) - NPC.velocity = NPC.velocity.SafeNormalize(Vector2.Zero) * mechdusaAccelMult; - } - } - - // Daytime enrage - if (NPC.ai[1] == 2f) - { - NPC.damage = 1000; - calamityGlobalNPC.DR = 0.9999f; - calamityGlobalNPC.unbreakableDR = true; - - calamityGlobalNPC.CurrentlyEnraged = true; - calamityGlobalNPC.CurrentlyIncreasingDefenseOrDR = true; - - if (NPC.IsMechQueenUp) - NPC.rotation = NPC.rotation.AngleLerp(NPC.velocity.X / 15f * 0.5f, 0.75f); - else - NPC.rotation += NPC.direction * 0.3f; - - Vector2 enragedHeadPosition = NPC.Center; - float enragedHeadTargetX = Main.player[Main.npc[(int)NPC.ai[0]].target].Center.X - enragedHeadPosition.X; - float enragedHeadTargetY = Main.player[Main.npc[(int)NPC.ai[0]].target].Center.Y - enragedHeadPosition.Y; - float enragedHeadTargetDist = (float)Math.Sqrt(enragedHeadTargetX * enragedHeadTargetX + enragedHeadTargetY * enragedHeadTargetY); - - float enragedHeadSpeed = 10f; - enragedHeadSpeed += enragedHeadTargetDist / 100f; - if (enragedHeadSpeed < 8f) - enragedHeadSpeed = 8f; - if (enragedHeadSpeed > 32f) - enragedHeadSpeed = 32f; - - enragedHeadTargetDist = enragedHeadSpeed / enragedHeadTargetDist; - NPC.velocity.X = enragedHeadTargetX * enragedHeadTargetDist; - NPC.velocity.Y = enragedHeadTargetY * enragedHeadTargetDist; - - if (Main.netMode != NetmodeID.MultiplayerClient) - { - NPC.localAI[0] += 1f; - if (NPC.localAI[0] >= 60f) - { - NPC.localAI[0] = 0f; - Vector2 headCenter = NPC.Center; - if (Collision.CanHit(headCenter, 1, 1, Main.player[Main.npc[(int)NPC.ai[0]].target].position, Main.player[Main.npc[(int)NPC.ai[0]].target].width, Main.player[Main.npc[(int)NPC.ai[0]].target].height)) - { - enragedHeadSpeed = 7f; - float enragedHeadSkullTargetX = Main.player[Main.npc[(int)NPC.ai[0]].target].Center.X - headCenter.X + Main.rand.Next(-20, 21); - float enragedHeadSkullTargetY = Main.player[Main.npc[(int)NPC.ai[0]].target].Center.Y - headCenter.Y + Main.rand.Next(-20, 21); - float enragedHeadSkullTargetDist = (float)Math.Sqrt(enragedHeadSkullTargetX * enragedHeadSkullTargetX + enragedHeadSkullTargetY * enragedHeadSkullTargetY); - enragedHeadSkullTargetDist = enragedHeadSpeed / enragedHeadSkullTargetDist; - enragedHeadSkullTargetX *= enragedHeadSkullTargetDist; - enragedHeadSkullTargetY *= enragedHeadSkullTargetDist; - - Vector2 value = new Vector2(enragedHeadSkullTargetX * 1f + Main.rand.Next(-50, 51) * 0.01f, enragedHeadSkullTargetY * 1f + Main.rand.Next(-50, 51) * 0.01f).SafeNormalize(Vector2.UnitY); - value *= enragedHeadSpeed; - value += NPC.velocity; - enragedHeadSkullTargetX = value.X; - enragedHeadSkullTargetY = value.Y; - - int type = ProjectileID.Skull; - headCenter += value * 5f; - int enragedSkulls = Projectile.NewProjectile(NPC.GetSource_FromAI(), headCenter.X, headCenter.Y, enragedHeadSkullTargetX, enragedHeadSkullTargetY, type, 250, 0f, Main.myPlayer, -1f, 0f); - Main.projectile[enragedSkulls].timeLeft = 300; - } - } - } - } - - // Despawning - if (NPC.ai[1] == 3f) - { - // Avoid unfair bullshit - NPC.damage = 0; - - if (NPC.IsMechQueenUp) - { - int mechdusaBossDespawning = NPC.FindFirstNPC(NPCID.Retinazer); - if (mechdusaBossDespawning >= 0) - Main.npc[mechdusaBossDespawning].EncourageDespawn(5); - - mechdusaBossDespawning = NPC.FindFirstNPC(NPCID.Spazmatism); - if (mechdusaBossDespawning >= 0) - Main.npc[mechdusaBossDespawning].EncourageDespawn(5); - - if (!NPC.AnyNPCs(NPCID.Retinazer) && !NPC.AnyNPCs(NPCID.Spazmatism)) - { - mechdusaBossDespawning = NPC.FindFirstNPC(NPCID.TheDestroyer); - if (mechdusaBossDespawning >= 0) - Main.npc[mechdusaBossDespawning].Transform(NPCID.TheDestroyerTail); - - NPC.EncourageDespawn(5); - } - - NPC.velocity.Y += 0.1f; - if (NPC.velocity.Y < 0f) - NPC.velocity.Y *= 0.95f; - - NPC.velocity.X *= 0.95f; - if (NPC.velocity.Y > 13f) - NPC.velocity.Y = 13f; - } - else - { - NPC.velocity.Y += 0.1f; - if (NPC.velocity.Y < 0f) - NPC.velocity.Y *= 0.9f; - - NPC.velocity.X *= 0.9f; - - if (NPC.timeLeft > 500) - NPC.timeLeft = 500; - } - } - - // Fly around in a circle - if (NPC.ai[1] == 5f) - { - // Avoid unfair bullshit - NPC.damage = 0; - - NPC.ai[2] += 1f; - - NPC.rotation = NPC.velocity.X / 50f; - - float bombSpawnDivisor = bossRush ? 14f : death ? 22f - (float)Math.Round(5f * (1f - lifeRatio)) : 22f; - float totalBombs = 6f; - int bombSpread = bossRush ? 250 : death ? 125 : 100; - - // Spin for about 3 seconds - float spinVelocity = 24f; - if (NPC.ai[2] == 2f) - { - // Play angry noise - SoundEngine.PlaySound(SoundID.ForceRoar, NPC.Center); - - // Set spin direction - if (Main.player[Main.npc[(int)NPC.ai[0]].target].velocity.X > 0f) - calamityGlobalNPC.newAI[0] = 1f; - else if (Main.player[Main.npc[(int)NPC.ai[0]].target].velocity.X < 0f) - calamityGlobalNPC.newAI[0] = -1f; - else - calamityGlobalNPC.newAI[0] = Main.player[Main.npc[(int)NPC.ai[0]].target].direction; - - // Set spin velocity - NPC.velocity.X = MathHelper.Pi * NPC.localAI[3] / spinVelocity; - NPC.velocity *= -calamityGlobalNPC.newAI[0]; - NPC.SyncExtraAI(); - NPC.netUpdate = true; - } - - // Maintain velocity and spit homing bombs - else if (NPC.ai[2] > 2f) - { - NPC.velocity = NPC.velocity.RotatedBy(MathHelper.Pi / spinVelocity * -calamityGlobalNPC.newAI[0]); - if (NPC.ai[2] == 3f) - NPC.velocity *= 0.6f; - - if (NPC.ai[2] % bombSpawnDivisor == 0f) - { - NPC.localAI[0] += 1f; - - if (Vector2.Distance(Main.player[Main.npc[(int)NPC.ai[0]].target].Center, NPC.Center) > 64f) - { - SoundEngine.PlaySound(SoundID.Item61, NPC.Center); - CreateParticles(NPC, new Vector2(NPC.Center.X + Main.rand.Next(NPC.width / 2), NPC.Center.Y + 4f)); - - if (Main.netMode != NetmodeID.MultiplayerClient) - { - Vector2 headCenter = NPC.Center; - float enragedHeadSpeed = 6f + (death ? 2f * (1f - lifeRatio) : 0f); - float enragedHeadBombTargetX = Main.player[Main.npc[(int)NPC.ai[0]].target].Center.X - headCenter.X + Main.rand.Next(-20, 21); - float enragedHeadBombTargetY = Main.player[Main.npc[(int)NPC.ai[0]].target].Center.Y - headCenter.Y + Main.rand.Next(-20, 21); - float enragedHeadBombTargetDist = (float)Math.Sqrt(enragedHeadBombTargetX * enragedHeadBombTargetX + enragedHeadBombTargetY * enragedHeadBombTargetY); - enragedHeadBombTargetDist = enragedHeadSpeed / enragedHeadBombTargetDist; - enragedHeadBombTargetX *= enragedHeadBombTargetDist; - enragedHeadBombTargetY *= enragedHeadBombTargetDist; - - Vector2 value = new Vector2(enragedHeadBombTargetX + Main.rand.Next(-bombSpread, bombSpread + 1) * 0.01f, enragedHeadBombTargetY + Main.rand.Next(-bombSpread, bombSpread + 1) * 0.01f).SafeNormalize(Vector2.UnitY); - value *= enragedHeadSpeed; - enragedHeadBombTargetX = value.X; - enragedHeadBombTargetY = value.Y; - - int type = ProjectileID.BombSkeletronPrime; - int damage = NPC.GetProjectileDamage(type); - - // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) - { - double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; - double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; - if (!NPC.downedMechBossAny) - damage = (int)(damage * firstMechMultiplier); - else if ((!NPC.downedMechBoss1 && !NPC.downedMechBoss2) || (!NPC.downedMechBoss2 && !NPC.downedMechBoss3) || (!NPC.downedMechBoss3 && !NPC.downedMechBoss1)) - damage = (int)(damage * secondMechMultiplier); - } - - int enragedBombs = Projectile.NewProjectile(NPC.GetSource_FromAI(), headCenter.X, headCenter.Y + 30f, enragedHeadBombTargetX, enragedHeadBombTargetY, type, damage, 0f, Main.myPlayer, -1f); - Main.projectile[enragedBombs].timeLeft = BombTimeLeft; - Main.projectile[enragedBombs].tileCollide = false; - } - } - - // Go to floating phase, or spinning phase if in phase 2 - if (NPC.localAI[0] >= totalBombs) - { - NPC.velocity = NPC.velocity.SafeNormalize(Vector2.UnitY); - - // Fly overhead and spit spreads of bombs into the air if on low health - NPC.ai[1] = phase3 ? 6f : 1f; - NPC.ai[2] = 0f; - NPC.localAI[3] = 0f; - NPC.localAI[0] = 0f; - calamityGlobalNPC.newAI[0] = 0f; - NPC.SyncVanillaLocalAI(); - NPC.SyncExtraAI(); - NPC.netUpdate = true; - } - } - } - } - - // Fly overhead and spit bombs - if (NPC.ai[1] == 6f) - { - // Avoid unfair bullshit - NPC.damage = 0; - - NPC.rotation = NPC.velocity.X / 15f; - - float flightVelocity = bossRush ? 32f : death ? 28f : 24f; - float flightAcceleration = bossRush ? 1.28f : death ? 1.12f : 0.96f; - - Vector2 destination = new Vector2(Main.player[Main.npc[(int)NPC.ai[0]].target].Center.X, Main.player[Main.npc[(int)NPC.ai[0]].target].Center.Y - 500f); - NPC.SimpleFlyMovement((destination - NPC.Center).SafeNormalize(Vector2.UnitY) * flightVelocity, flightAcceleration); - - // Spit bombs and then go to floating phase - NPC.localAI[3] += 1f; - if (Vector2.Distance(NPC.Center, destination) < 160f || NPC.ai[2] > 0f || NPC.localAI[3] > 120f) - { - float bombSpawnDivisor = death ? 50f : 60f; - float totalBombSpreads = 2f; - NPC.ai[2] += 1f; - if (NPC.ai[2] % bombSpawnDivisor == 0f) - { - NPC.localAI[0] += 1f; - - if (Main.netMode != NetmodeID.MultiplayerClient) - { - int totalProjectiles = bossRush ? 24 : 12; - float radians = MathHelper.TwoPi / totalProjectiles; - int type = ProjectileID.BombSkeletronPrime; - int damage = NPC.GetProjectileDamage(type); - - // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) - { - double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; - double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; - if (!NPC.downedMechBossAny) - damage = (int)(damage * firstMechMultiplier); - else if ((!NPC.downedMechBoss1 && !NPC.downedMechBoss2) || (!NPC.downedMechBoss2 && !NPC.downedMechBoss3) || (!NPC.downedMechBoss3 && !NPC.downedMechBoss1)) - damage = (int)(damage * secondMechMultiplier); - } - - float velocity = 12f; - double angleA = radians * 0.5; - double angleB = MathHelper.ToRadians(90f) - angleA; - float velocityX = (float)(velocity * Math.Sin(angleA) / Math.Sin(angleB)); - Vector2 spinningPoint = normalLaserRotation ? new Vector2(0f, -velocity) : new Vector2(-velocityX, -velocity); - Vector2 upwardVelocity = Vector2.UnitY * velocity; - for (int k = 0; k < totalProjectiles; k++) - { - Vector2 bombVelocity = spinningPoint.RotatedBy(radians * k); - int proj = Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center + Vector2.UnitY * 30f + bombVelocity.SafeNormalize(Vector2.UnitY) * 15f, bombVelocity - upwardVelocity, type, damage, 0f, Main.myPlayer, -2f); - Main.projectile[proj].timeLeft = BombTimeLeft; - Main.projectile[proj].tileCollide = false; - } - NPC.localAI[1] += 1f; - } - - SoundEngine.PlaySound(SoundID.Item62, NPC.Center); - CreateParticles(NPC, new Vector2(NPC.Center.X, NPC.Center.Y + 4f), 5); - - if (NPC.localAI[0] >= totalBombSpreads) - { - NPC.ai[1] = 0f; - NPC.ai[2] = 0f; - NPC.localAI[3] = 0f; - calamityGlobalNPC.newAI[0] = 0f; - NPC.localAI[0] = 0f; - NPC.SyncVanillaLocalAI(); - NPC.SyncExtraAI(); - NPC.netUpdate = true; - } - } - } - } - } - } - - private void CreateParticles(NPC npc, Vector2 position, int amountMultiplier = 1) - { - int firstDustCloudParticleAmount = 30 * amountMultiplier; - int secondDustCloudParticleAmount = 20 * amountMultiplier; - int goreAmount = 2 * amountMultiplier; - - for (int dustIndex = 0; dustIndex < firstDustCloudParticleAmount; dustIndex++) - { - int dust = Dust.NewDust(npc.position, npc.width, npc.height, DustID.Smoke, 0f, 0f, 100, default(Color), 1.5f); - Main.dust[dust].velocity *= 1.4f; - } - - for (int dustIndex = 0; dustIndex < secondDustCloudParticleAmount; dustIndex++) - { - int dust = Dust.NewDust(npc.position, npc.width, npc.height, DustID.Torch, 0f, 0f, 100, default(Color), 3.5f); - Main.dust[dust].noGravity = true; - Main.dust[dust].velocity *= 7f; - dust = Dust.NewDust(npc.position, npc.width, npc.height, DustID.Torch, 0f, 0f, 100, default(Color), 1.5f); - Main.dust[dust].velocity *= 3f; - } - - for (int goreIndex = 0; goreIndex < goreAmount; goreIndex++) - { - float goreVelocityMultiplier = 0.4f; - if (goreIndex >= goreAmount / 2) - goreVelocityMultiplier = 0.8f; - - int gore = Gore.NewGore(npc.GetSource_FromAI(), npc.Center, default(Vector2), Main.rand.Next(61, 64)); - Main.gore[gore].velocity *= goreVelocityMultiplier; - Main.gore[gore].velocity.X += 1f; - Main.gore[gore].velocity.Y += 1f; - gore = Gore.NewGore(npc.GetSource_FromAI(), npc.Center, default(Vector2), Main.rand.Next(61, 64)); - Main.gore[gore].velocity *= goreVelocityMultiplier; - Main.gore[gore].velocity.X -= 1f; - Main.gore[gore].velocity.Y += 1f; - gore = Gore.NewGore(npc.GetSource_FromAI(), npc.Center, default(Vector2), Main.rand.Next(61, 64)); - Main.gore[gore].velocity *= goreVelocityMultiplier; - Main.gore[gore].velocity.X += 1f; - Main.gore[gore].velocity.Y -= 1f; - gore = Gore.NewGore(npc.GetSource_FromAI(), npc.Center, default(Vector2), Main.rand.Next(61, 64)); - Main.gore[gore].velocity *= goreVelocityMultiplier; - Main.gore[gore].velocity.X -= 1f; - Main.gore[gore].velocity.Y -= 1f; - } - } - - public override void BossLoot(ref string name, ref int potionType) => potionType = ItemID.GreaterHealingPotion; - - public override void ApplyDifficultyAndPlayerScaling(int numPlayers, float balance, float bossAdjustment) - { - NPC.lifeMax = (int)(NPC.lifeMax * 0.75f * balance * bossAdjustment); - NPC.damage = (int)(NPC.damage * NPC.GetExpertDamageMultiplier()); - } - - public override bool CheckActive() => false; - - public override bool CheckDead() - { - // Kill the lead head if he's still alive when this head dies - for (int i = 0; i < Main.maxNPCs; i++) - { - NPC nPC = Main.npc[i]; - if (nPC.active && nPC.type == NPCID.SkeletronPrime && nPC.life > 0) - { - nPC.life = 0; - nPC.HitEffect(); - nPC.checkDead(); - nPC.active = false; - nPC.netUpdate = true; - } - } - - return true; - } - - public override void HitEffect(NPC.HitInfo hit) - { - if (NPC.life <= 0) - { - if (Main.netMode != NetmodeID.Server) - { - Gore.NewGore(NPC.GetSource_Death(), NPC.position, NPC.velocity, 149); - Gore.NewGore(NPC.GetSource_Death(), NPC.position, NPC.velocity, 150); - - int num802 = Gore.NewGore(NPC.GetSource_Death(), NPC.position, default(Vector2), Main.rand.Next(61, 64)); - Gore gore2 = Main.gore[num802]; - gore2.velocity *= 0.4f; - Main.gore[num802].velocity.X += 1f; - Main.gore[num802].velocity.Y += 1f; - - num802 = Gore.NewGore(NPC.GetSource_Death(), NPC.position, default(Vector2), Main.rand.Next(61, 64)); - gore2 = Main.gore[num802]; - gore2.velocity *= 0.4f; - Main.gore[num802].velocity.X -= 1f; - Main.gore[num802].velocity.Y += 1f; - - num802 = Gore.NewGore(NPC.GetSource_Death(), NPC.position, default(Vector2), Main.rand.Next(61, 64)); - gore2 = Main.gore[num802]; - gore2.velocity *= 0.4f; - Main.gore[num802].velocity.X += 1f; - Main.gore[num802].velocity.Y -= 1f; - - num802 = Gore.NewGore(NPC.GetSource_Death(), NPC.position, default(Vector2), Main.rand.Next(61, 64)); - gore2 = Main.gore[num802]; - gore2.velocity *= 0.4f; - Main.gore[num802].velocity.X -= 1f; - Main.gore[num802].velocity.Y -= 1f; - } - - for (int num798 = 0; num798 < 10; num798++) - { - int num799 = Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Smoke, 0f, 0f, 100, default(Color), 1.5f); - Dust dust = Main.dust[num799]; - dust.velocity *= 1.4f; - } - - for (int num800 = 0; num800 < 5; num800++) - { - int num801 = Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Torch, 0f, 0f, 100, default(Color), 2.5f); - Main.dust[num801].noGravity = true; - Dust dust = Main.dust[num801]; - dust.velocity *= 5f; - num801 = Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Torch, 0f, 0f, 100, default(Color), 1.5f); - dust = Main.dust[num801]; - dust.velocity *= 3f; - } - } - } - } -} diff --git a/NPCs/NormalNPCs/SkeletronPrime2.png b/NPCs/NormalNPCs/SkeletronPrime2.png deleted file mode 100644 index c019c3130896adbdecba05818d265649428f143b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6696 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 Q`40++U`)i{GxSLK4{puH6951J diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/DestroyerAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/DestroyerAI.cs index 62e5159255..c42cb72a79 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/DestroyerAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/DestroyerAI.cs @@ -150,8 +150,6 @@ public static bool BuffedDestroyerAI(NPC npc, Mod mod) } // Check if other segments are still alive, if not, die - // Check for Oblivion too, since having a max power Destroyer during that fight would be turbo cancer - bool oblivionAlive = false; if (npc.type > NPCID.TheDestroyer) { bool shouldDespawn = true; @@ -178,39 +176,13 @@ public static bool BuffedDestroyerAI(NPC npc, Mod mod) npc.active = false; } } - else - { - if (masterMode && !bossRush && npc.localAI[3] != -1f) - { - for (int i = 0; i < Main.maxNPCs; i++) - { - if (Main.npc[i].active && (Main.npc[i].type == ModContent.NPCType() || Main.npc[i].type == NPCID.SkeletronPrime)) - { - oblivionAlive = true; - break; - } - } - } - - // Set variable to force despawn when Prime dies in Master Rev+ - // Set to -1f if Prime isn't alive when summoned - if (npc.localAI[3] == 0f) - { - if (oblivionAlive) - npc.localAI[3] = 1f; - else - npc.localAI[3] = -1f; - - npc.SyncExtraAI(); - } - } // Total segment variable int totalSegments = Main.getGoodWorld ? 100 : 80; // Calculate aggression based on how many broken segments there are float brokenSegmentAggressionMultiplier = 1f; - if (npc.type == NPCID.TheDestroyer && !oblivionAlive) + if (npc.type == NPCID.TheDestroyer) { int numProbeSegments = 0; for (int i = 0; i < Main.maxNPCs; i++) @@ -236,51 +208,39 @@ public static bool BuffedDestroyerAI(NPC npc, Mod mod) // Increase velocity based on distance float velocityMultiplier = increaseSpeedMore ? 2f : increaseSpeed ? 1.5f : 1f; + noFlyZoneBoxHeight -= death ? 400 : (int)(400f * (1f - lifeRatio)); - // If Oblivion is alive, don't fly, don't spit laser spreads, use the default vanilla no fly zone, reduce segment count to 60, use base speed and use base turn speed - if (oblivionAlive) - { - calamityGlobalNPC.newAI[3] = 0f; - totalSegments = Main.getGoodWorld ? 75 : 60; - spitLaserSpreads = false; - noFlyZoneBoxHeight = 2000; - } - else - { - noFlyZoneBoxHeight -= death ? 400 : (int)(400f * (1f - lifeRatio)); + float segmentVelocityBoost = death ? (flyAtTarget ? 4.5f : 6f) * (1f - lifeRatio) : (flyAtTarget ? 3f : 4f) * (1f - lifeRatio); + float speedBoost = death ? (flyAtTarget ? 0.1125f : 0.15f) * (1f - lifeRatio) : (flyAtTarget ? 0.075f : 0.1f) * (1f - lifeRatio); + float turnSpeedBoost = death ? 0.18f * (1f - lifeRatio) : 0.12f * (1f - lifeRatio); - float segmentVelocityBoost = death ? (flyAtTarget ? 4.5f : 6f) * (1f - lifeRatio) : (flyAtTarget ? 3f : 4f) * (1f - lifeRatio); - float speedBoost = death ? (flyAtTarget ? 0.1125f : 0.15f) * (1f - lifeRatio) : (flyAtTarget ? 0.075f : 0.1f) * (1f - lifeRatio); - float turnSpeedBoost = death ? 0.18f * (1f - lifeRatio) : 0.12f * (1f - lifeRatio); + segmentVelocity += segmentVelocityBoost; + speed += speedBoost; + turnSpeed += turnSpeedBoost; - segmentVelocity += segmentVelocityBoost; - speed += speedBoost; - turnSpeed += turnSpeedBoost; + segmentVelocity += 5f * enrageScale; + speed += 0.05f * enrageScale; + turnSpeed += 0.075f * enrageScale; - segmentVelocity += 5f * enrageScale; - speed += 0.05f * enrageScale; - turnSpeed += 0.075f * enrageScale; - - if (flyAtTarget) - { - float speedMultiplier = phase5 ? 1.8f : phase4 ? 1.65f : 1.5f; - speed *= speedMultiplier; - } + if (flyAtTarget) + { + float speedMultiplier = phase5 ? 1.8f : phase4 ? 1.65f : 1.5f; + speed *= speedMultiplier; + } - segmentVelocity *= velocityMultiplier; - speed *= velocityMultiplier; - turnSpeed *= velocityMultiplier; + segmentVelocity *= velocityMultiplier; + speed *= velocityMultiplier; + turnSpeed *= velocityMultiplier; - segmentVelocity *= brokenSegmentAggressionMultiplier; - speed *= brokenSegmentAggressionMultiplier; - turnSpeed *= brokenSegmentAggressionMultiplier; + segmentVelocity *= brokenSegmentAggressionMultiplier; + speed *= brokenSegmentAggressionMultiplier; + turnSpeed *= brokenSegmentAggressionMultiplier; - if (Main.getGoodWorld) - { - segmentVelocity *= 1.2f; - speed *= 1.2f; - turnSpeed *= 1.2f; - } + if (Main.getGoodWorld) + { + segmentVelocity *= 1.2f; + speed *= 1.2f; + turnSpeed *= 1.2f; } bool probeLaunched = npc.ai[2] == 1f; @@ -780,9 +740,7 @@ public static bool BuffedDestroyerAI(NPC npc, Mod mod) } // Despawn - bool oblivionWasAlive = npc.localAI[3] == 1f && !oblivionAlive; - bool oblivionFightDespawn = (oblivionAlive && lifeRatio < 0.75f) || oblivionWasAlive; - if (player.dead || oblivionFightDespawn) + if (player.dead) { shouldFly = false; npc.velocity.Y += 2f; @@ -1045,11 +1003,10 @@ public static bool BuffedDestroyerAI(NPC npc, Mod mod) } // Force the fucker to turn around in ground phase in Master - // Turns slower if Oblivion is alive, for fairness if (npc.type == NPCID.TheDestroyer && masterMode && !flyAtTarget) { if (npc.Distance(player.Center) > 2000f) - npc.velocity += (player.Center - npc.Center).SafeNormalize(Vector2.UnitY) * (oblivionAlive ? speed : turnSpeed); + npc.velocity += (player.Center - npc.Center).SafeNormalize(Vector2.UnitY) * turnSpeed; } if (NPC.IsMechQueenUp && npc.type == NPCID.TheDestroyer) @@ -1747,7 +1704,6 @@ public static bool BuffedProbeAI(NPC npc, Mod mod) { bool bossRush = BossRushEvent.BossRushActive; bool masterMode = Main.masterMode || bossRush; - bool oblivionAlive = npc.ai[1] == 1f; // Get a target if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) @@ -1791,12 +1747,6 @@ public static bool BuffedProbeAI(NPC npc, Mod mod) for (int i = 0; i < Main.maxNPCs; i++) { - if (masterMode && !bossRush && npc.ai[1] == 0f) - { - if (Main.npc[i].active && (Main.npc[i].type == ModContent.NPCType() || Main.npc[i].type == NPCID.SkeletronPrime)) - npc.ai[1] = 1f; - } - if (i != npc.whoAmI && Main.npc[i].active && Main.npc[i].type == npc.type) { Vector2 otherProbeDist = Main.npc[i].Center - npc.Center; @@ -1924,7 +1874,7 @@ public static bool BuffedProbeAI(NPC npc, Mod mod) damage = (int)(damage * secondMechMultiplier); } - int totalProjectiles = oblivionAlive ? 2 : (CalamityWorld.death || bossRush) ? 3 : 1; + int totalProjectiles = (CalamityWorld.death || bossRush) ? 3 : 1; Vector2 npcCenter = new Vector2(probeTargetX, probeTargetY); if (NPC.IsMechQueenUp) { diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronPrimeAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronPrimeAI.cs index 7a7965cf58..020264f3cc 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronPrimeAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronPrimeAI.cs @@ -35,114 +35,42 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) // Spawn arms if (calamityGlobalNPC.newAI[1] == 0f) { + CalamityUtils.CalamityTargeting(npc, CalamityTargetingParameters.BossDefaults); calamityGlobalNPC.newAI[1] = 1f; if (Main.netMode != NetmodeID.MultiplayerClient) { - // Spawn second head in Master Mode - // The main head owns the Saw and the Laser in Master Mode - if (masterMode) - { - int head = NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType(), npc.whoAmI); - Main.npc[head].ai[0] = npc.whoAmI; - Main.npc[head].target = npc.target; - Main.npc[head].netUpdate = true; - npc.ai[0] = head; - - int arm = NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X, (int)npc.Center.Y, NPCID.PrimeSaw, npc.whoAmI); - Main.npc[arm].ai[0] = 1f; - Main.npc[arm].ai[1] = npc.whoAmI; - Main.npc[arm].target = npc.target; - Main.npc[arm].netUpdate = true; - - arm = NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X, (int)npc.Center.Y, NPCID.PrimeLaser, npc.whoAmI); - Main.npc[arm].ai[0] = 1f; - Main.npc[arm].ai[1] = npc.whoAmI; - Main.npc[arm].target = npc.target; - Main.npc[arm].netUpdate = true; - Main.npc[arm].ai[3] = 150f; - } - else - { - int arm = NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X, (int)npc.Center.Y, NPCID.PrimeCannon, npc.whoAmI); - Main.npc[arm].ai[0] = -1f; - Main.npc[arm].ai[1] = npc.whoAmI; - Main.npc[arm].target = npc.target; - Main.npc[arm].netUpdate = true; - - arm = NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X, (int)npc.Center.Y, NPCID.PrimeSaw, npc.whoAmI); - Main.npc[arm].ai[0] = 1f; - Main.npc[arm].ai[1] = npc.whoAmI; - Main.npc[arm].target = npc.target; - Main.npc[arm].netUpdate = true; - - arm = NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X, (int)npc.Center.Y, NPCID.PrimeVice, npc.whoAmI); - Main.npc[arm].ai[0] = -1f; - Main.npc[arm].ai[1] = npc.whoAmI; - Main.npc[arm].target = npc.target; - Main.npc[arm].ai[3] = 150f; - Main.npc[arm].netUpdate = true; - - arm = NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X, (int)npc.Center.Y, NPCID.PrimeLaser, npc.whoAmI); - Main.npc[arm].ai[0] = 1f; - Main.npc[arm].ai[1] = npc.whoAmI; - Main.npc[arm].target = npc.target; - Main.npc[arm].netUpdate = true; - Main.npc[arm].ai[3] = 150f; - } + int arm = NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X, (int)npc.Center.Y, NPCID.PrimeCannon, npc.whoAmI); + Main.npc[arm].ai[0] = -1f; + Main.npc[arm].ai[1] = npc.whoAmI; + Main.npc[arm].target = npc.target; + Main.npc[arm].netUpdate = true; + + arm = NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X, (int)npc.Center.Y, NPCID.PrimeSaw, npc.whoAmI); + Main.npc[arm].ai[0] = 1f; + Main.npc[arm].ai[1] = npc.whoAmI; + Main.npc[arm].target = npc.target; + Main.npc[arm].netUpdate = true; + + arm = NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X, (int)npc.Center.Y, NPCID.PrimeVice, npc.whoAmI); + Main.npc[arm].ai[0] = -1f; + Main.npc[arm].ai[1] = npc.whoAmI; + Main.npc[arm].target = npc.target; + Main.npc[arm].ai[3] = 150f; + Main.npc[arm].netUpdate = true; + + arm = NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X, (int)npc.Center.Y, NPCID.PrimeLaser, npc.whoAmI); + Main.npc[arm].ai[0] = 1f; + Main.npc[arm].ai[1] = npc.whoAmI; + Main.npc[arm].target = npc.target; + Main.npc[arm].netUpdate = true; + Main.npc[arm].ai[3] = 150f; } npc.netUpdate = true; npc.SyncExtraAI(); } - if (masterMode) - { - if (!Main.npc[(int)npc.ai[0]].active || Main.npc[(int)npc.ai[0]].aiStyle != NPCAIStyleID.SkeletronPrimeHead) - { - npc.life = 0; - npc.HitEffect(); - npc.active = false; - npc.netUpdate = true; - } - else - { - // Link the HP of both heads - if (npc.life > Main.npc[(int)npc.ai[0]].life) - npc.life = Main.npc[(int)npc.ai[0]].life; - - // Push away from the lead head if too close, pull closer if too far, if Mechdusa isn't real - if (!NPC.IsMechQueenUp) - { - float pushVelocity = 0.25f; - if (Vector2.Distance(npc.Center, Main.npc[(int)npc.ai[0]].Center) < 80f * npc.scale) - { - if (npc.position.X < Main.npc[(int)npc.ai[0]].position.X) - npc.velocity.X -= pushVelocity; - else - npc.velocity.X += pushVelocity; - - if (npc.position.Y < Main.npc[(int)npc.ai[0]].position.Y) - npc.velocity.Y -= pushVelocity; - else - npc.velocity.Y += pushVelocity; - } - else if (Vector2.Distance(npc.Center, Main.npc[(int)npc.ai[0]].Center) > 240f * npc.scale) - { - if (npc.position.X < Main.npc[(int)npc.ai[0]].position.X) - npc.velocity.X += pushVelocity; - else - npc.velocity.X -= pushVelocity; - - if (npc.position.Y < Main.npc[(int)npc.ai[0]].position.Y) - npc.velocity.Y += pushVelocity; - else - npc.velocity.Y -= pushVelocity; - } - } - } - } - // Check if arms are alive bool cannonAlive = false; bool laserAlive = false; @@ -175,33 +103,7 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) // Phases bool phase2 = lifeRatio < 0.66f; - bool spawnDestroyer = lifeRatio < 0.75f && masterMode && !bossRush && npc.localAI[2] == 0f; bool phase3 = lifeRatio < 0.33f; - bool spawnRetinazer = lifeRatio < 0.5f && masterMode && !bossRush && npc.localAI[2] == 1f; - - // Spawn The Destroyer in Master Mode (just like Oblivion from Avalon) - if (spawnDestroyer) - { - Player destroyerSpawnPlayer = Main.player[Player.FindClosest(npc.position, npc.width, npc.height)]; - SoundEngine.PlaySound(SoundID.Roar, destroyerSpawnPlayer.Center); - if (Main.netMode != NetmodeID.MultiplayerClient) - NPC.SpawnOnPlayer(destroyerSpawnPlayer.whoAmI, NPCID.TheDestroyer); - - npc.localAI[2] = 1f; - npc.SyncVanillaLocalAI(); - } - - // Spawn Retinazer in Master Mode (just like Oblivion from Avalon) - if (spawnRetinazer) - { - Player retinazerSpawnPlayer = Main.player[Player.FindClosest(npc.position, npc.width, npc.height)]; - SoundEngine.PlaySound(SoundID.Roar, retinazerSpawnPlayer.Center); - if (Main.netMode != NetmodeID.MultiplayerClient) - NPC.SpawnOnPlayer(retinazerSpawnPlayer.whoAmI, NPCID.Retinazer); - - npc.localAI[2] = 2f; - npc.SyncVanillaLocalAI(); - } // Despawn if (npc.ai[1] != 3f) @@ -250,9 +152,6 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) bool normalLaserRotation = npc.localAI[1] % 2f == 0f; - // Prevents cheap hits - bool canUseAttackInMaster = npc.position.Y < Main.player[npc.target].position.Y - 350f; - // Float near player if (npc.ai[1] == 0f || npc.ai[1] == 4f) { @@ -260,24 +159,16 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) npc.damage = 0; // Start other phases; if arms are dead, start with spin phase - bool otherHeadChargingOrSpinning = Main.npc[(int)npc.ai[0]].ai[1] == 5f || Main.npc[(int)npc.ai[0]].ai[1] == 1f; - if (phase2 || CalamityWorld.LegendaryMode || allArmsDead || masterMode) + if (phase2 || CalamityWorld.LegendaryMode || allArmsDead) { // Start spin phase after 1.5 seconds npc.ai[2] += phase3 ? 1.5f : 1f; - if (npc.ai[2] >= (90f - (death ? (masterMode ? 15f : 60f) * (1f - lifeRatio) : 0f)) && (!otherHeadChargingOrSpinning || !masterMode || phase3) && (canUseAttackInMaster || !masterMode)) + if (npc.ai[2] >= (90f - (death ? (masterMode ? 15f : 60f) * (1f - lifeRatio) : 0f))) { bool shouldSpinAround = npc.ai[1] == 4f && npc.position.Y < Main.player[npc.target].position.Y - 400f && Vector2.Distance(Main.player[npc.target].Center, npc.Center) < 600f && Vector2.Distance(Main.player[npc.target].Center, npc.Center) > 400f; - bool shouldCharge = masterMode && !phase2 && !allArmsDead && !CalamityWorld.LegendaryMode; - if (shouldCharge) - { - npc.ai[2] = 0f; - npc.ai[1] = 1f; - npc.netUpdate = true; - } - else if (shouldSpinAround || npc.ai[1] != 4f) + if (shouldSpinAround || npc.ai[1] != 4f) { if (shouldSpinAround) { @@ -287,6 +178,7 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) npc.ai[2] = 0f; npc.ai[1] = shouldSpinAround ? 5f : 1f; + CalamityUtils.CalamityTargeting(npc, CalamityTargetingParameters.BossDefaults); npc.netUpdate = true; } } @@ -669,13 +561,6 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) damage = (int)(damage * secondMechMultiplier); } - if (npc.localAI[0] % 3f == 0f) - { - int probeLimit = death ? (masterMode ? 3 : 4) : 2; - if (NPC.CountNPCS(NPCID.Probe) < probeLimit) - NPC.NewNPC(npc.GetSource_FromAI(), (int)headCenter.X, (int)headCenter.Y + 30, NPCID.Probe); - } - int enragedSkulls = Projectile.NewProjectile(npc.GetSource_FromAI(), headCenter.X, headCenter.Y + 30f, enragedHeadSkullTargetX, enragedHeadSkullTargetY, type, damage, 0f, Main.myPlayer, -3f, 0f); Main.projectile[enragedSkulls].timeLeft = 480; Main.projectile[enragedSkulls].tileCollide = false; diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/TwinsAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/TwinsAI.cs index 6d2a37107f..f27e82ee0b 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/TwinsAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/TwinsAI.cs @@ -98,34 +98,8 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) } } - // Check for Oblivion in Master Mode - bool oblivionAlive = false; - if (masterMode && !bossRush && npc.localAI[3] != -1f) - { - for (int i = 0; i < Main.maxNPCs; i++) - { - if (Main.npc[i].active && (Main.npc[i].type == ModContent.NPCType() || Main.npc[i].type == NPCID.SkeletronPrime)) - { - oblivionAlive = true; - break; - } - } - } - - // Set variable to force despawn when Prime dies in Master Rev+ - // Set to -1f if Prime isn't alive when summoned - if (npc.localAI[3] == 0f) - { - if (oblivionAlive) - npc.localAI[3] = 1f; - else - npc.localAI[3] = -1f; - - npc.SyncExtraAI(); - } - // Phase HP ratios - float phase2LifeRatio = oblivionAlive ? 0.5f : masterMode ? 0.85f : 0.7f; + float phase2LifeRatio = masterMode ? 0.85f : 0.7f; float finalPhaseLifeRatio = masterMode ? 0.4f : 0.25f; // Movement variables @@ -136,16 +110,6 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) // Phase duration variables float phase1MaxLaserPhaseDurationDecrease = masterMode ? 120f : 300f; - // If Oblivion is alive reduce aggression of all attacks - if (oblivionAlive) - { - phase1MaxSpeedIncrease = masterMode ? 1f : 2f; - phase1MaxAccelerationIncrease = masterMode ? 0.0125f : 0.025f; - phase1MaxChargeSpeedIncrease = masterMode ? 1.5f : 3f; - - phase1MaxLaserPhaseDurationDecrease = masterMode ? 60f : 150f; - } - // Phase checks bool phase2 = lifeRatio < phase2LifeRatio; bool finalPhase = lifeRatio < finalPhaseLifeRatio; @@ -165,9 +129,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) npc.reflectsProjectiles = false; // Despawn - bool oblivionWasAlive = npc.localAI[3] == 1f && !oblivionAlive; - bool oblivionFightDespawn = (oblivionAlive && lifeRatio < 0.75f) || oblivionWasAlive || (oblivionAlive && !spazAlive && lifeRatio < 0.95f); - if (Main.player[npc.target].dead || oblivionFightDespawn) + if (Main.player[npc.target].dead) { npc.velocity.Y -= 0.04f; if (npc.timeLeft > 10) @@ -206,7 +168,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) retinazerFaceDirection = -1; Vector2 retinazerPosition = npc.Center; - float distanceFromTarget = oblivionAlive ? 450f : 300f; + float distanceFromTarget = 300f; float retinazerTargetX = Main.player[npc.target].Center.X + (retinazerFaceDirection * distanceFromTarget) - retinazerPosition.X; float retinazerTargetY = Main.player[npc.target].Center.Y - distanceFromTarget - retinazerPosition.Y; @@ -268,7 +230,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) npc.ai[2] += 1f; float phaseGateValue = (masterMode ? 300f : 450f) - (death ? phase1MaxLaserPhaseDurationDecrease * ((1f - lifeRatio) / (1f - phase2LifeRatio)) : 0f); - float laserGateValue = oblivionAlive ? 60f : 30f; + float laserGateValue = 30f; if (NPC.IsMechQueenUp) { phaseGateValue = 900f; @@ -374,7 +336,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) npc.rotation = (float)Math.Atan2(npc.velocity.Y, npc.velocity.X) - MathHelper.PiOver2; float delayBeforeChargingAgain = (masterMode ? 48f : 56f) - (death ? (masterMode ? 3f : 6f) * ((1f - lifeRatio) / (1f - phase2LifeRatio)) : 0f); - if (npc.ai[2] >= delayBeforeChargingAgain + (oblivionAlive ? 15f : 0f)) + if (npc.ai[2] >= delayBeforeChargingAgain) { npc.ai[3] += 1f; npc.ai[2] = 0f; @@ -449,7 +411,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) damage = (int)(damage * secondMechMultiplier); } - Vector2 projectileVelocity = (Main.player[npc.target].Center - npc.Center).SafeNormalize(Vector2.UnitY) * (oblivionAlive ? 6f : 7f); + Vector2 projectileVelocity = (Main.player[npc.target].Center - npc.Center).SafeNormalize(Vector2.UnitY) * 7f; int numProj = shootLaser ? 6 : 2; int spread = shootLaser ? 20 : 80; float rotation = MathHelper.ToRadians(spread); @@ -538,7 +500,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) Vector2 eyePosition = npc.Center; float retinazerPhase2TargetX = Main.player[npc.target].Center.X - eyePosition.X; - float distanceFromTarget = oblivionAlive ? 480f : 420f; + float distanceFromTarget = 420f; float retinazerPhase2TargetY = Main.player[npc.target].Center.Y - 420f - eyePosition.Y; if (NPC.IsMechQueenUp) @@ -615,7 +577,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) if (Main.netMode != NetmodeID.MultiplayerClient) { npc.localAI[1] += 1f + (death ? (phase2LifeRatio - lifeRatio) / phase2LifeRatio : 0f); - if (npc.localAI[1] >= (spazAlive ? (oblivionAlive ? 76f : 52f) : 26f)) + if (npc.localAI[1] >= (spazAlive ? 52f : 26f)) { bool canHit = Collision.CanHit(npc.position, npc.width, npc.height, Main.player[npc.target].position, Main.player[npc.target].width, Main.player[npc.target].height); if (canHit || !spazAlive || finalPhase) @@ -680,7 +642,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) } Vector2 retinazerPhase2RapidFirePos = npc.Center; - float distanceFromTarget = oblivionAlive ? 480f : 420f; + float distanceFromTarget = 420f; float retinazerPhase2RapidFireTargetX = Main.player[npc.target].Center.X + (retinazerPhase2FaceDirection * distanceFromTarget) - retinazerPhase2RapidFirePos.X; float retinazerPhase2RapidFireTargetY = Main.player[npc.target].Center.Y - retinazerPhase2RapidFirePos.Y; float retinazerPhase2RapidFireTargetDist = (float)Math.Sqrt(retinazerPhase2RapidFireTargetX * retinazerPhase2RapidFireTargetX + retinazerPhase2RapidFireTargetY * retinazerPhase2RapidFireTargetY); @@ -721,7 +683,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) if (Main.netMode != NetmodeID.MultiplayerClient) { npc.localAI[1] += 1f + (death ? (phase2LifeRatio - lifeRatio) / phase2LifeRatio : 0f); - if (npc.localAI[1] > (spazAlive ? (oblivionAlive ? 30f : 20f) : 10f)) + if (npc.localAI[1] > (spazAlive ? 20f : 10f)) { bool canHit = Collision.CanHit(npc.position, npc.width, npc.height, Main.player[npc.target].position, Main.player[npc.target].width, Main.player[npc.target].height); if (canHit || !spazAlive || finalPhase) @@ -1072,34 +1034,8 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) } } - // Check for Oblivion in Master Mode - bool oblivionAlive = false; - if (masterMode && !bossRush && npc.localAI[3] != -1f) - { - for (int i = 0; i < Main.maxNPCs; i++) - { - if (Main.npc[i].active && (Main.npc[i].type == ModContent.NPCType() || Main.npc[i].type == NPCID.SkeletronPrime)) - { - oblivionAlive = true; - break; - } - } - } - - // Set variable to force despawn when Prime dies in Master Rev+ - // Set to -1f if Prime isn't alive when summoned - if (npc.localAI[3] == 0f) - { - if (oblivionAlive) - npc.localAI[3] = 1f; - else - npc.localAI[3] = -1f; - - npc.SyncExtraAI(); - } - // Phase HP ratios - float phase2LifeRatio = oblivionAlive ? 0.5f : masterMode ? 0.85f : 0.7f; + float phase2LifeRatio = masterMode ? 0.85f : 0.7f; float finalPhaseLifeRatio = masterMode ? 0.4f : 0.25f; // Movement variables @@ -1111,17 +1047,6 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) float phase1MaxCursedFlamePhaseDurationDecrease = masterMode ? 80f : 200f; float phase1MaxChargesDecrease = masterMode ? 2f : 4f; - // If Oblivion is alive reduce aggression of all attacks - if (oblivionAlive) - { - phase1MaxSpeedIncrease = masterMode ? 1.125f : 2.25f; - phase1MaxAccelerationIncrease = masterMode ? 0.0375f : 0.075f; - phase1MaxChargeSpeedIncrease = masterMode ? 1.5f : 3f; - - phase1MaxCursedFlamePhaseDurationDecrease = masterMode ? 40f : 100f; - phase1MaxChargesDecrease = masterMode ? 1f : 2f; - } - // Phase checks bool phase2 = lifeRatio < phase2LifeRatio; bool finalPhase = lifeRatio < finalPhaseLifeRatio; @@ -1141,9 +1066,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) npc.reflectsProjectiles = false; // Despawn - bool oblivionWasAlive = npc.localAI[3] == 1f && !oblivionAlive; - bool oblivionFightDespawn = (oblivionAlive && lifeRatio < 0.75f) || oblivionWasAlive || (oblivionAlive && !retAlive && lifeRatio < 0.95f); - if (Main.player[npc.target].dead || oblivionFightDespawn) + if (Main.player[npc.target].dead) { npc.velocity.Y -= 0.04f; if (npc.timeLeft > 10) @@ -1185,7 +1108,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) spazmatismFireballFaceDirection = -1; Vector2 spazmatismFireballPos = npc.Center; - float distanceFromTarget = oblivionAlive ? 480f : 400f; + float distanceFromTarget = 400f; float spazmatismFireballTargetX = Main.player[npc.target].Center.X + (spazmatismFireballFaceDirection * distanceFromTarget) - spazmatismFireballPos.X; float spazmatismFireballTargetY = Main.player[npc.target].Center.Y - spazmatismFireballPos.Y; if (NPC.IsMechQueenUp) @@ -1264,7 +1187,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) npc.ai[3] += 0.4f; } - if (npc.ai[3] >= (oblivionAlive ? 60f : 30f)) + if (npc.ai[3] >= 30f) { npc.ai[3] = 0f; spazmatismFireballPos = npc.Center; @@ -1352,7 +1275,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) // Charge 8 times float chargeTime = masterMode ? 45f : 25f; - if (npc.ai[2] >= chargeTime + (oblivionAlive ? 15f : 0f)) + if (npc.ai[2] >= chargeTime) { // Reset AI array and go to cursed fireball phase npc.ai[3] += 1f; @@ -1432,7 +1355,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) damage = (int)(damage * secondMechMultiplier); } - Vector2 projectileVelocity = (Main.player[npc.target].Center - npc.Center).SafeNormalize(Vector2.UnitY) * (oblivionAlive ? 12f : 16f) + Main.rand.NextVector2CircularEdge(3f, 3f); + Vector2 projectileVelocity = (Main.player[npc.target].Center - npc.Center).SafeNormalize(Vector2.UnitY) * 16f + Main.rand.NextVector2CircularEdge(3f, 3f); int proj = Projectile.NewProjectile(npc.GetSource_FromAI(), npc.Center + projectileVelocity.SafeNormalize(Vector2.UnitY) * 50f, projectileVelocity, type, damage, 0f, Main.myPlayer, 0f, 1f); Main.projectile[proj].tileCollide = false; } @@ -1527,7 +1450,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) { // Boost speed if too far from target if (spazmatismFlamethrowerTargetDist > flamethrowerDistance) - spazmatismFlamethrowerMaxSpeed += MathHelper.Lerp(0f, oblivionAlive ? 3f : masterMode ? 8f : 6f, MathHelper.Clamp((spazmatismFlamethrowerTargetDist - flamethrowerDistance) / 1000f, 0f, 1f)); + spazmatismFlamethrowerMaxSpeed += MathHelper.Lerp(0f, masterMode ? 8f : 6f, MathHelper.Clamp((spazmatismFlamethrowerTargetDist - flamethrowerDistance) / 1000f, 0f, 1f)); if (Main.getGoodWorld) { @@ -1728,7 +1651,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) npc.rotation = (float)Math.Atan2(npc.velocity.Y, npc.velocity.X) - MathHelper.PiOver2; // Charges 5 times - if (npc.ai[2] >= (chargeTime * 1.6f) + (oblivionAlive ? 15f : 0f)) + if (npc.ai[2] >= (chargeTime * 1.6f)) { npc.ai[3] += 1f; npc.ai[2] = 0f; diff --git a/Projectiles/CalamityGlobalProjectile.cs b/Projectiles/CalamityGlobalProjectile.cs index d2e3661e1c..e6ab9ef8be 100644 --- a/Projectiles/CalamityGlobalProjectile.cs +++ b/Projectiles/CalamityGlobalProjectile.cs @@ -2381,138 +2381,6 @@ public override bool PreAI(Projectile projectile) } } - else if (projectile.type == ProjectileID.BombSkeletronPrime && projectile.ai[0] < 0f && masterMode) - { - int num = (int)(projectile.Center.X / 16f); - int num2 = (int)(projectile.Center.Y / 16f); - if (WorldGen.InWorld(num, num2) && projectile.tileCollide) - { - Tile tile = Main.tile[num, num2]; - if (tile != null && tile.HasTile && (TileID.Sets.Platforms[tile.TileType] || tile.TileType == TileID.PlanterBox)) - { - projectile.Kill(); - return false; - } - } - - bool masterModeSkeletronPrimeHomingBomb = projectile.ai[0] == -1f; - bool masterModeSkeletronPrimeFallingBomb = projectile.ai[0] == -2f; - - int target = 0; - target = Player.FindClosest(projectile.Center, 1, 1); - - if (projectile.Hitbox.Intersects(Main.player[target].Hitbox)) - { - projectile.Kill(); - return false; - } - - if (projectile.timeLeft < SkeletronPrime2.BombTimeLeft / 2 && projectile.timeLeft > 3) - projectile.tileCollide = true; - - if (masterModeSkeletronPrimeHomingBomb) - { - projectile.ai[1] += 1f; - float homingStartTime = 20f; - float homingEndTime = death ? 140f : 110f; - - if (Vector2.Distance(projectile.Center, Main.player[target].Center) < 192f && projectile.ai[1] < homingEndTime) - projectile.ai[1] = homingEndTime; - - if (projectile.ai[1] < homingEndTime && projectile.ai[1] > homingStartTime) - { - float num134 = projectile.velocity.Length(); - Vector2 vector24 = Main.player[target].Center - projectile.Center; - vector24.Normalize(); - vector24 *= num134; - float inertia = death ? 25f : 30f; - projectile.velocity = (projectile.velocity * (inertia - 1f) + vector24) / inertia; - projectile.velocity.Normalize(); - projectile.velocity *= num134; - } - - float maxVelocity = death ? 18f : 15f; - float acceleration = 1.02f; - if (projectile.velocity.Length() < maxVelocity) - projectile.velocity *= acceleration; - } - else - { - if (projectile.velocity.Y > 10f) - projectile.velocity.Y = 10f; - } - - if (projectile.localAI[0] == 0f) - { - projectile.localAI[0] = 1f; - SoundEngine.PlaySound(SoundID.Item10, projectile.Center); - } - - projectile.frameCounter++; - if (projectile.frameCounter > 3) - { - projectile.frame++; - projectile.frameCounter = 0; - } - - if (projectile.frame > 1) - projectile.frame = 0; - - if (projectile.owner == Main.myPlayer && projectile.timeLeft <= 3) - { - projectile.tileCollide = false; - projectile.ai[2] = 0f; - projectile.alpha = 255; - } - else if (Main.rand.NextBool()) - { - int num28 = Dust.NewDust(projectile.position, projectile.width, projectile.height, DustID.Smoke, 0f, 0f, 100); - Main.dust[num28].scale = 0.1f + (float)Main.rand.Next(5) * 0.1f; - Main.dust[num28].fadeIn = 1.5f + (float)Main.rand.Next(5) * 0.1f; - Main.dust[num28].noGravity = true; - Main.dust[num28].position = projectile.Center + new Vector2(0f, -projectile.height / 2).RotatedBy(projectile.rotation) * 1.1f; - int num29 = 6; - Dust dust8 = Dust.NewDustDirect(projectile.position, projectile.width, projectile.height, num29, 0f, 0f, 100); - dust8.scale = 1f + (float)Main.rand.Next(5) * 0.1f; - dust8.noGravity = true; - dust8.position = projectile.Center + new Vector2(0f, -projectile.height / 2 - 6).RotatedBy(projectile.rotation) * 1.1f; - } - - if (masterModeSkeletronPrimeFallingBomb) - { - projectile.ai[2] += 1f; - if (projectile.ai[2] > 60f) - projectile.velocity.Y += 0.2f; - } - - projectile.rotation += projectile.velocity.X * 0.1f; - - return false; - } - - else if (projectile.type == ProjectileID.FrostBeam && projectile.ai[0] == 1f) - { - projectile.rotation = (float)Math.Atan2(projectile.velocity.Y, projectile.velocity.X) + MathHelper.PiOver2; - - Lighting.AddLight(projectile.Center, 0f, (255 - projectile.alpha) * 0.15f / 255f, (255 - projectile.alpha) * 0.6f / 255f); - - if (projectile.alpha > 0) - projectile.alpha -= 125; - if (projectile.alpha < 0) - projectile.alpha = 0; - - if (projectile.localAI[1] == 0f) - { - SoundEngine.PlaySound(SoundID.Item33, projectile.Center); - projectile.localAI[1] = 1f; - } - - if (projectile.velocity.Length() < AcceleratingBossLaserVelocityCap) - projectile.velocity *= 1.0025f; - - return false; - } - else if (projectile.type == ProjectileID.RocketSkeleton && projectile.ai[1] == 1f) { bool primeCannonProjectile = projectile.ai[1] == 2f; @@ -4653,7 +4521,6 @@ public override bool PreDraw(Projectile projectile, ref Color lightColor) #region Pre Kill public override bool PreKill(Projectile projectile, int timeLeft) { - bool masterRevSkeletronPrimeBomb = projectile.type == ProjectileID.BombSkeletronPrime && projectile.ai[0] < 0f && (Main.masterMode || BossRushEvent.BossRushActive); bool revQueenBeeBeeHive = projectile.type == ProjectileID.BeeHive && (CalamityWorld.revenge || BossRushEvent.BossRushActive) && (projectile.ai[2] == 1f || CalamityWorld.death) && projectile.wet; bool revGolemInferno = projectile.type == ProjectileID.InfernoHostileBolt && projectile.ai[2] > 0f; @@ -4675,96 +4542,7 @@ public override bool PreKill(Projectile projectile, int timeLeft) if (projectile.owner == Main.myPlayer) { - if (masterRevSkeletronPrimeBomb) - { - SoundEngine.PlaySound(SoundID.Item14, projectile.Center); - projectile.position.X += projectile.width / 2; - projectile.position.Y += projectile.height / 2; - projectile.width = projectile.height = 22; - projectile.position.X -= projectile.width / 2; - projectile.position.Y -= projectile.height / 2; - - for (int num951 = 0; num951 < 20; num951++) - { - int num952 = Dust.NewDust(projectile.position, projectile.width, projectile.height, DustID.Smoke, 0f, 0f, 100, default(Color), 1.5f); - Dust dust2 = Main.dust[num952]; - dust2.velocity *= 1.4f; - } - - int num950 = 6; - for (int num953 = 0; num953 < 10; num953++) - { - int num954 = Dust.NewDust(projectile.position, projectile.width, projectile.height, num950, 0f, 0f, 100, default(Color), 2.5f); - Main.dust[num954].noGravity = true; - Dust dust2 = Main.dust[num954]; - dust2.velocity *= 5f; - num954 = Dust.NewDust(projectile.position, projectile.width, projectile.height, num950, 0f, 0f, 100, default(Color), 1.5f); - dust2 = Main.dust[num954]; - dust2.velocity *= 3f; - } - - int num955 = Gore.NewGore(projectile.GetSource_FromAI(), projectile.position, default(Vector2), Main.rand.Next(61, 64)); - Gore gore2 = Main.gore[num955]; - gore2.velocity *= 0.4f; - Main.gore[num955].velocity.X += 1f; - Main.gore[num955].velocity.Y += 1f; - num955 = Gore.NewGore(projectile.GetSource_FromAI(), projectile.position, default(Vector2), Main.rand.Next(61, 64)); - gore2 = Main.gore[num955]; - gore2.velocity *= 0.4f; - Main.gore[num955].velocity.X -= 1f; - Main.gore[num955].velocity.Y += 1f; - num955 = Gore.NewGore(projectile.GetSource_FromAI(), projectile.position, default(Vector2), Main.rand.Next(61, 64)); - gore2 = Main.gore[num955]; - gore2.velocity *= 0.4f; - Main.gore[num955].velocity.X += 1f; - Main.gore[num955].velocity.Y -= 1f; - num955 = Gore.NewGore(projectile.GetSource_FromAI(), projectile.position, default(Vector2), Main.rand.Next(61, 64)); - gore2 = Main.gore[num955]; - gore2.velocity *= 0.4f; - Main.gore[num955].velocity.X -= 1f; - Main.gore[num955].velocity.Y -= 1f; - - Vector2 vector76 = projectile.position; - projectile.position.X += projectile.width / 2; - projectile.position.Y += projectile.height / 2; - projectile.width = projectile.height = 128; - projectile.position.X -= projectile.width / 2; - projectile.position.Y -= projectile.height / 2; - projectile.Damage(); - projectile.position = vector76; - projectile.width = projectile.height = 22; - - if (Main.getGoodWorld && !Main.remixWorld) - { - int num1011 = 4; - Vector2 center3 = projectile.position; - int num1012 = num1011; - int num1013 = num1011; - int num1014 = (int)(center3.X / 16f - (float)num1012); - int num1015 = (int)(center3.X / 16f + (float)num1012); - int num1016 = (int)(center3.Y / 16f - (float)num1013); - int num1017 = (int)(center3.Y / 16f + (float)num1013); - if (num1014 < 0) - num1014 = 0; - - if (num1015 > Main.maxTilesX) - num1015 = Main.maxTilesX; - - if (num1016 < 0) - num1016 = 0; - - if (num1017 > Main.maxTilesY) - num1017 = Main.maxTilesY; - - bool wallSplode2 = projectile.ShouldWallExplode(center3, num1011, num1014, num1015, num1016, num1017); - projectile.ExplodeTiles(center3, num1011, num1014, num1015, num1016, num1017, wallSplode2); - } - - if (Main.netMode != NetmodeID.SinglePlayer) - NetMessage.SendData(MessageID.KillProjectile, -1, -1, null, projectile.identity, projectile.owner); - } - - else if (revQueenBeeBeeHive) + if (revQueenBeeBeeHive) { if (Main.netMode != NetmodeID.MultiplayerClient) { @@ -4829,7 +4607,7 @@ public override bool PreKill(Projectile projectile, int timeLeft) } } - if (masterRevSkeletronPrimeBomb || revQueenBeeBeeHive || revGolemInferno) + if (revQueenBeeBeeHive || revGolemInferno) { projectile.active = false; return false; diff --git a/Scenes/MusicScenes/SkeletronPrimeMasterMusicScene.cs b/Scenes/MusicScenes/SkeletronPrimeMasterMusicScene.cs deleted file mode 100644 index 77398c4c76..0000000000 --- a/Scenes/MusicScenes/SkeletronPrimeMasterMusicScene.cs +++ /dev/null @@ -1,14 +0,0 @@ -using CalamityMod.World; -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Systems -{ - public class SkeletronPrimeMasterMusicScene : ModSceneEffect - { - public override int Music => MusicID.Boss3; // I spent 20 minutes trying to get this music to play while forgetting to actually override this in the first place _ YuH - public override SceneEffectPriority Priority => SceneEffectPriority.BossLow; - public override bool IsSceneEffectActive(Player player) => Main.masterMode && CalamityWorld.revenge && NPC.AnyNPCs(NPCID.SkeletronPrime) && Main.npc[NPC.FindFirstNPC(NPCID.SkeletronPrime)].Distance(player.Center) <= 525f * 16f; - } -} From 8413d077d9af5848750987601713e75c36f54afa Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Mon, 24 Nov 2025 18:10:51 -0500 Subject: [PATCH 373/401] Fixed rippers persisting forever if Revengeance is toggled off while they are active --- CalPlayer/CalamityPlayerMiscEffects.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index 6b1484b0e7..2e81c8c5cb 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -523,7 +523,8 @@ float ProxRageFromDistance(float dist) // Apply the rage change and cap rage in both directions. // Changes are only applied if the Rage mechanic is available. - if (RageEnabled) + // CIT 24NOV2025: Fixed an exploit which allowed Rage to persist forever if Revengeance is toggled off while active. + if (RageEnabled || rageDiff < 0f) { rage += rageDiff; if (rage < 0f) @@ -605,7 +606,10 @@ float ProxRageFromDistance(float dist) // Apply the adrenaline change and cap adrenaline in both directions. // Changes are only applied if the Adrenaline mechanic is available. - if (AdrenalineEnabled && adrenalinePauseTimer == 0) + // + // CIT 24NOV2025: Adrenaline cannot be exploited the same way as Rage, since difficulty cannot be changed while a boss is alive. + // Nevertheless, I will still give it the same exploit fix as Rage just in case there is some method to do it. + if ((AdrenalineEnabled || adrenalineDiff < 0f) && adrenalinePauseTimer == 0) { adrenaline += adrenalineDiff; if (adrenaline < 0f) From 6cc141c960bd2d7965015c1ca50fa20d78535673 Mon Sep 17 00:00:00 2001 From: Flowaria Date: Tue, 25 Nov 2025 09:02:19 +0900 Subject: [PATCH 374/401] Fixed LiquidDrawColors IL Edit --- ILEditing/MechanicILChanges.cs | 81 ++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 38 deletions(-) diff --git a/ILEditing/MechanicILChanges.cs b/ILEditing/MechanicILChanges.cs index 9daa4a1f1f..bb5b305649 100644 --- a/ILEditing/MechanicILChanges.cs +++ b/ILEditing/MechanicILChanges.cs @@ -1,8 +1,6 @@ using System; -using System.Diagnostics; using System.Linq; using System.Reflection; -using System.Runtime.CompilerServices; using CalamityMod.Balancing; using CalamityMod.Buffs.DamageOverTime; using CalamityMod.CalPlayer; @@ -11,9 +9,7 @@ using CalamityMod.FluidSimulation; using CalamityMod.ForegroundDrawing; using CalamityMod.Items.Accessories; -using CalamityMod.Items.Accessories.Vanity; using CalamityMod.Items.Dyes; -using CalamityMod.Items.Potions.Alcohol; using CalamityMod.NPCs; using CalamityMod.NPCs.Astral; using CalamityMod.NPCs.AstrumAureus; @@ -23,8 +19,6 @@ using CalamityMod.Projectiles; using CalamityMod.Projectiles.Typeless; using CalamityMod.Systems; -using CalamityMod.Tiles.Abyss; -using CalamityMod.Waters; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Mono.Cecil.Cil; @@ -33,7 +27,6 @@ using Terraria; using Terraria.DataStructures; using Terraria.GameContent; -using Terraria.GameContent.Achievements; using Terraria.GameContent.Drawing; using Terraria.GameContent.Events; using Terraria.GameContent.Liquid; @@ -44,12 +37,9 @@ using Terraria.Graphics.Light; using Terraria.Graphics.Shaders; using Terraria.ID; -using Terraria.IO; using Terraria.Localization; using Terraria.ModLoader; -using Terraria.ModLoader.IO; using Terraria.UI.Gamepad; -using static Terraria.WaterfallManager; namespace CalamityMod.ILEditing { @@ -790,7 +780,8 @@ private void DoDrawLavas(ILContext il) LogFailure("DoDraw Lava", "Could not locate the drawing of Background Waters"); return; } - cursor.EmitDelegate(() => { + cursor.EmitDelegate(() => + { LavaRendering.instance.DrawLavas(isBackground: true); }); if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdsfld
("drawToScreen"), i => i.MatchBrfalse(out _), i => i.MatchLdarg0(), i => i.MatchLdcI4(0), i => i.MatchCall
("DrawWaters"))) @@ -798,7 +789,8 @@ private void DoDrawLavas(ILContext il) LogFailure("DoDraw Lava", "Could not locate the drawing of Waters"); return; } - cursor.EmitDelegate(() => { + cursor.EmitDelegate(() => + { LavaRendering.instance.DrawLavas(); }); } @@ -811,7 +803,8 @@ private void RenderLavas(ILContext il) LogFailure("Render Lava", "Could not locate the drawing of Waters"); return; } - cursor.EmitDelegate(() => { + cursor.EmitDelegate(() => + { LavaRendering.instance.DrawLavas(); }); } @@ -824,7 +817,8 @@ private void RenderLavaBackgrounds(ILContext il) LogFailure("Render Lava Backgroumds", "Could not locate the drawing of Background Waters"); return; } - cursor.EmitDelegate(() => { + cursor.EmitDelegate(() => + { LavaRendering.instance.DrawLavas(isBackground: true); }); } @@ -837,7 +831,8 @@ private void DrawLavatoCapture(ILContext il) LogFailure("Draw lavas to captures", "Could not locate the saving of water alphas"); return; } - cursor.EmitDelegate(() => { + cursor.EmitDelegate(() => + { LavaRendering.alphaSave = CalamityMod.lavaAlpha.ToArray(); }); if (!cursor.TryGotoNext(MoveType.Before, i => i.MatchLdcI4(0), i => i.MatchStloc(34), i => i.MatchBr(out _), i => i.MatchLdloc(34), i => i.MatchLdcI4(1), i => i.MatchBeq(out _))) @@ -846,7 +841,8 @@ private void DrawLavatoCapture(ILContext il) return; } cursor.EmitLdloc(8); - cursor.EmitDelegate((CaptureBiome biome) => { + cursor.EmitDelegate((CaptureBiome biome) => + { for (int i = 0; i < 1; i++) { CalamityMod.lavaAlpha[i] = ((i == CalamityMod.LavaStyle) ? 1f : 0f); @@ -857,7 +853,8 @@ private void DrawLavatoCapture(ILContext il) LogFailure("Draw lavas to captures", "Could not locate the background of liquid capture drawing"); return; } - cursor.EmitDelegate(() => { + cursor.EmitDelegate(() => + { LavaRendering.instance.DrawLiquid(bg: true, CalamityMod.LavaStyle); }); if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg0(), i => i.MatchLdcI4(1), i => i.MatchLdsfld
("bloodMoon"), i => i.MatchBrtrue(out _), i => i.MatchLdloc(8), i => i.MatchLdfld("WaterStyle"), i => i.MatchBr(out _), i => i.MatchLdcI4(9), i => i.MatchLdcR4(1), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawLiquid"))) @@ -865,7 +862,8 @@ private void DrawLavatoCapture(ILContext il) LogFailure("Draw lavas to captures", "Could not locate the second background of liquid capture drawing"); return; } - cursor.EmitDelegate(() => { + cursor.EmitDelegate(() => + { LavaRendering.instance.DrawLiquid(bg: true, CalamityMod.LavaStyle); }); if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg0(), i => i.MatchLdcI4(0), i => i.MatchLdsfld
("waterStyle"), i => i.MatchLdcR4(1), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawLiquid"))) @@ -873,7 +871,8 @@ private void DrawLavatoCapture(ILContext il) LogFailure("Draw lavas to captures", "Could not locate the liquid capture drawing"); return; } - cursor.EmitDelegate(() => { + cursor.EmitDelegate(() => + { LavaRendering.instance.DrawLiquid(bg: false, CalamityMod.LavaStyle); }); if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg0(), i => i.MatchLdcI4(0), i => i.MatchLdloc(8), i => i.MatchLdfld("WaterStyle"), i => i.MatchLdcR4(1), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawLiquid"))) @@ -881,7 +880,8 @@ private void DrawLavatoCapture(ILContext il) LogFailure("Draw lavas to captures", "Could not locate the second liquid capture drawing"); return; } - cursor.EmitDelegate(() => { + cursor.EmitDelegate(() => + { LavaRendering.instance.DrawLiquid(bg: false, CalamityMod.LavaStyle); }); if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdloc2(), i => i.MatchStsfld
("liquidAlpha"))) @@ -889,7 +889,8 @@ private void DrawLavatoCapture(ILContext il) LogFailure("Draw lavas to captures", "Could not locate water style value returner"); return; } - cursor.EmitDelegate(() => { + cursor.EmitDelegate(() => + { CalamityMod.lavaAlpha = LavaRendering.alphaSave; }); } @@ -907,12 +908,13 @@ private void AddTileLiquidDrawing(ILContext il) cursor.EmitLdloc(13); cursor.EmitLdloc(14); cursor.EmitLdloc(15); - cursor.EmitDelegate((Microsoft.Xna.Framework.Vector2 unscaledPosition, Microsoft.Xna.Framework.Vector2 vector, int j, int i, Terraria.Tile tile) => { + cursor.EmitDelegate((Microsoft.Xna.Framework.Vector2 unscaledPosition, Microsoft.Xna.Framework.Vector2 vector, int j, int i, Terraria.Tile tile) => + { LavaRendering.instance.DrawTile_LiquidBehindTile(solidLayer: false, inFrontOfPlayers: false, -1, unscaledPosition, vector, j, i, tile); }); } #endregion - + #region Lava Blocking private void BlockLavaDrawing(ILContext il) { @@ -1014,13 +1016,14 @@ private void BlockRetroLightingLava(ILContext il) } cursor.EmitLdloc(12); cursor.EmitLdloc(11); - cursor.EmitDelegate((int i, int j) => { + cursor.EmitDelegate((int i, int j) => + { return Main.tile[i, j].LiquidType == LiquidID.Lava; }); cursor.EmitBrtrue(target); } #endregion - + #region Lava Replacing private void LavaBubbleReplacer(ILContext il) { @@ -1038,17 +1041,17 @@ private void LavaBubbleReplacer(ILContext il) } cursor.EmitDelegate>(type2 => LavaRendering.dustLava()); } - + private void LavaDropletReplacer(ILContext il) - { - ILCursor cursor = new ILCursor(il); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg(out _), i => i.MatchLdcI4(374), i => i.MatchBneUn(out _), i => i.MatchLdcI4(716))) + { + ILCursor cursor = new ILCursor(il); + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg(out _), i => i.MatchLdcI4(374), i => i.MatchBneUn(out _), i => i.MatchLdcI4(716))) { LogFailure("Ambient lava droplet replacer", "Could not locate the lava droplet newgore parameters"); return; } - cursor.EmitDelegate>(type => LavaRendering.goreLava()); - } + cursor.EmitDelegate>(type => LavaRendering.goreLava()); + } private void SplashEntityLava(ILContext il) { @@ -1203,20 +1206,22 @@ private void LavafallLightEditor(On_WaterfallManager.orig_AddLight orig, int wat private static void LiquidDrawColors(ILContext il) { + const string TypeFieldName = nameof(LiquidRenderer.LiquidDrawCache.Type); + ILCursor cursor = new ILCursor(il); - if (!cursor.TryGotoNext(MoveType.Before, c => c.MatchLdarg2(), c => c.MatchLdloc(9), c => c.MatchLdloc(10), c => c.MatchCall
("DrawTileInWater"))) + if (!cursor.TryGotoNext(MoveType.Before, c => c.MatchLdarg2(), c => c.MatchLdloc(3), c => c.MatchLdloc(4), c => c.MatchCall
("DrawTileInWater"))) { LogFailure("Liquid Draw Colors", "Could not locate the liquid vertex colors for drawing"); return; } - cursor.Emit(OpCodes.Ldloc, 9); - cursor.Emit(OpCodes.Ldloc, 10); + cursor.Emit(OpCodes.Ldloc, 3); + cursor.Emit(OpCodes.Ldloc, 4); cursor.Emit(OpCodes.Ldloc_2); - cursor.Emit(OpCodes.Ldfld, typeof(LiquidRenderer).GetNestedType("LiquidDrawCache", BindingFlags.Public).GetRuntimeField("Type")); - cursor.Emit(OpCodes.Ldloca, 11); + cursor.EmitLdfld(typeof(LiquidRenderer.LiquidDrawCache).GetField(TypeFieldName)); + cursor.Emit(OpCodes.Ldloca, 9); - cursor.EmitDelegate((int x, int y, int liquidType, ref VertexColors initialColor) => + cursor.EmitDelegate((int x, int y, byte liquidType, ref VertexColors initialColor) => { if (liquidType == LiquidID.Water) { @@ -1542,7 +1547,7 @@ internal static void GetDifficultyOverride(Terraria.GameContent.UI.Elements.On_A { return; } - + // Go through the World Selection Difficulty System's World Difficulty list backwards and choose the latest difficulty that applies for (int i = WorldSelectionDifficultySystem.WorldDifficulties.Count - 1; i >= 0; i--) { From f77d99a414e1c49213547cd7eb452f3ac81d912d Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Sat, 10 Aug 2024 09:27:54 +0700 Subject: [PATCH 375/401] Lantern Center syncing --- Tiles/Furniture/LanternCenterTile.cs | 20 +++++++++++++----- Tiles/Furniture/LanternCenterTile.png | Bin 6387 -> 4755 bytes .../Furniture/LanternCenterTile_Highlight.png | Bin 3408 -> 1950 bytes 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Tiles/Furniture/LanternCenterTile.cs b/Tiles/Furniture/LanternCenterTile.cs index 5d87d1aad6..6744a2c100 100644 --- a/Tiles/Furniture/LanternCenterTile.cs +++ b/Tiles/Furniture/LanternCenterTile.cs @@ -1,5 +1,6 @@ using CalamityMod.Items.Placeables.Furniture; using Microsoft.Xna.Framework; +using System; using Terraria; using Terraria.Audio; using Terraria.DataStructures; @@ -25,6 +26,8 @@ public override void SetStaticDefaults() TileObjectData.addTile(Type); AddMapEntry(new Color(99, 99, 99), CalamityUtils.GetItemName()); TileID.Sets.HasOutlines[Type] = true; + TileID.Sets.InteractibleByNPCs[Type] = true; + TileID.Sets.DisableSmartInteract[Type] = true; AnimationFrameHeight = 54; } @@ -35,12 +38,21 @@ public override void SetStaticDefaults() public override void AnimateTile(ref int frame, ref int frameCounter) { - frameCounter++; - if (frameCounter >= 6) + if (!LanternNight.LanternsUp) { - frame = (frame + 1) % 6; + frame = 0; frameCounter = 0; } + else + { + frameCounter++; + if (frameCounter >= 6) + { + frame = (frame + 1) % 7; + frameCounter = 0; + } + frame = Math.Clamp(frame, 1, 6); + } } public override void KillMultiTile(int i, int j, int frameX, int frameY) @@ -50,13 +62,11 @@ public override void KillMultiTile(int i, int j, int frameX, int frameY) public override void HitWire(int i, int j) { - CalamityUtils.LightHitWire(Type, i, j, 3, 3); LanternNight.ToggleManualLanterns(); } public override bool RightClick(int i, int j) { - CalamityUtils.LightHitWire(Type, i, j, 3, 3); LanternNight.ToggleManualLanterns(); SoundEngine.PlaySound(SoundID.Mech, new Vector2(i * 16, j * 16)); return true; diff --git a/Tiles/Furniture/LanternCenterTile.png b/Tiles/Furniture/LanternCenterTile.png index 1f8cc97ef35738bd98c3c42768f2cffc856960b5..fffbe3d12e8ca920449d87cdeab0a37b412a449a 100644 GIT binary patch literal 4755 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 literal 6387 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 BhX4Qo diff --git a/Tiles/Furniture/LanternCenterTile_Highlight.png b/Tiles/Furniture/LanternCenterTile_Highlight.png index 6e86215b5dc3de16b0d8d41b28fc2bc4b2091fc6..7c9e7546eff661ca46f49bbd5222afc324ebb4aa 100644 GIT binary patch literal 1950 zcmV;P2VwY$P)62t?ce|Iwa{%LjQBNg_a7&aI=gkUT_5D#G*n3;Oqdzu*5G>h*fPf~KH`37hnI zVJ)Fna23IDV%G?37sf*{n_N1vYlJ;Qv&oeclQ8P7_1jp)+7NpFezF_8X4v*DK$=+Z zh07Yswl5PF^&ZL+=q4s%AcjPYTx4`8lH*TnE@4?~A#0OtCMID)t7_Dd%Mpv({X=1+ zo*M<|onOMDwoqPzEV<>0dDonT9TSRdOncXkwI6FwHx$`{tOk19vG!~uj7=i<2xF0Z zL(ALGYTpkrYe%nPqy4P*!S~pxA+!45Bg~3=7743;_pC9iM?@^x16Ic?6oVb_9`0CT z);;5Pp-2m}B6i16QpcX%Ut$uL>`cwuyq{k`%GEU z>e1|WBG&V;)ic?Iya(ZX*4V0~SaRpzQtd*@N={YW)!ENFA1uUFC|X@v)K0`!xs|d4 zzn7TRL%X!Q?*z?~=~c_kTC-uqju)mXZZ_7*_Tiz3)>PHj?H*xlEwJ|<5|Q)T0lz_` zknSZ36pB_ygb70)L?_qL{#L=rjvr#9hK=@LMi>fJ^t|VYCl0le< zhs4?!-uGNH>Hp|MI}K!C_Zu|oXm)9E!}es|i!k_tUL{+ycHAe7^-yrc{S3$2vrT2r zvBJRfC(DgmpY{Y_apP!XA)lt)Y;I$Cl9vkOA!VnRUEng;@o#j+vGfM+Ko!4m-9) z85%Xt`NC!;k5NKO9<%N!yyWgB)~3(r@6`!HV#f<>V}12(X(lFN-ZVDYuRU3BU!Kn9 zfNcs`*tITUgG(cX=u0I%Ofte6OzPQ+IK2w^>5-FMJLvAz29Fk;6S zJOAA8P5LpRaAK;IX_z(8Yu~g`9CZ*%J`y(S;pqM%7VXj5d+fqBKHwng^Tf z;+!3t$WB#p&nCns6IF4GSg{9G6TI5}AqoHyJB}DazT5NrPS7kNRdKT(bG8o)#a`NN zNmeB%2}2Qq&PU#l3uxZn^K@dPpM%ncp{!>mRz=QC>^Na832W%|vLz~Zwq{jGOv0?F z2HRO3J&l-GpM)XLSv`ctiF$6eN1ArZVSPVeEb6HpC?C zDauD$tc}- zJfKjV9g1u++lE+}FgCqr6P2)!hwlqT7X3D%xSB9_&2JNm61H3N2qTuA46?`92|C-u z*72>`T3ONR(d>32HhKilCe)5EVqT9_lVa^u758jHY%Wk0w}=&cKsCYE%9mm=-RVT^ kIAW`WR+Jsbo}m8$xGW+dULUfk00000NkvXXu0mjf0D}U>p8x;= literal 3408 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 RCy5 Date: Sat, 10 Aug 2024 09:46:14 +0700 Subject: [PATCH 376/401] Plagued 'Bed' fixes --- Tiles/FurniturePlaguedPlate/PlaguedPlateBed.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Tiles/FurniturePlaguedPlate/PlaguedPlateBed.cs b/Tiles/FurniturePlaguedPlate/PlaguedPlateBed.cs index 65721061b7..6ffa949f39 100644 --- a/Tiles/FurniturePlaguedPlate/PlaguedPlateBed.cs +++ b/Tiles/FurniturePlaguedPlate/PlaguedPlateBed.cs @@ -16,14 +16,16 @@ public override void SetStaticDefaults() Main.tileFrameImportant[Type] = true; Main.tileLavaDeath[Type] = false; TileID.Sets.HasOutlines[Type] = true; + TileID.Sets.InteractibleByNPCs[mt.Type] = true; + TileID.Sets.DisableSmartCursor[Type] = true; + TileID.Sets.IsValidSpawnPoint[Type] = true; TileObjectData.newTile.CopyFrom(TileObjectData.Style3x4); //This bed has different dimensions to conventional beds, using bookcase dimentions instead TileObjectData.newTile.LavaDeath = false; TileObjectData.newTile.CoordinateHeights = new int[] { 16, 16, 16, 16 }; TileObjectData.addTile(Type); + AddToArray(ref TileID.Sets.RoomNeeds.CountsAsChair); AddMapEntry(new Color(191, 142, 111), CreateMapEntryName()); - TileID.Sets.DisableSmartCursor[Type] = true; AdjTiles = new int[] { TileID.Beds }; - AddToArray(ref TileID.Sets.RoomNeeds.CountsAsChair); } public override bool CreateDust(int i, int j, ref int type) @@ -51,12 +53,12 @@ public override bool RightClick(int i, int j) if (player.SpawnX == spawnX && player.SpawnY == spawnY) { player.RemoveSpawn(); - Main.NewText("Spawn point removed!", 255, 240, 20); + Main.NewText(Language.GetTextValue("Game.SpawnPointRemoved"), 255, 240, 20); } else if (Player.CheckSpawn(spawnX, spawnY)) { player.ChangeSpawn(spawnX, spawnY); - Main.NewText("Spawn point set!", 255, 240, 20); + Main.NewText(Language.GetTextValue("Game.SpawnPointSet"), 255, 240, 20); } return true; } From ac09e912463b55bca168aeae3dad11bc6847694a Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Wed, 8 Oct 2025 07:55:31 +0700 Subject: [PATCH 377/401] scope fix --- Items/Weapons/Ranged/Svantechnical.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Items/Weapons/Ranged/Svantechnical.cs b/Items/Weapons/Ranged/Svantechnical.cs index 6b181f0e00..28236fc11a 100644 --- a/Items/Weapons/Ranged/Svantechnical.cs +++ b/Items/Weapons/Ranged/Svantechnical.cs @@ -49,7 +49,6 @@ public override bool AltFunctionUse(Player player) { return true; } - public override void HoldItem(Player player) => player.scope = false; public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) { From abe6152413956c30fba46c8724c71be6794ed440 Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Sat, 19 Oct 2024 16:12:01 +0700 Subject: [PATCH 378/401] living fire tile drop fix --- .../LivingBrimstoneFireBlockTile.cs | 76 ++----------------- .../LivingGodSlayerFireBlockTile.cs | 75 ++---------------- Tiles/LivingFire/LivingHolyFireBlockTile.cs | 75 ++---------------- 3 files changed, 18 insertions(+), 208 deletions(-) diff --git a/Tiles/LivingFire/LivingBrimstoneFireBlockTile.cs b/Tiles/LivingFire/LivingBrimstoneFireBlockTile.cs index d47571bd64..ddaee0e086 100644 --- a/Tiles/LivingFire/LivingBrimstoneFireBlockTile.cs +++ b/Tiles/LivingFire/LivingBrimstoneFireBlockTile.cs @@ -1,83 +1,25 @@ -using System.Collections.Generic; -using CalamityMod.Dusts; -using CalamityMod.Items.Placeables.LivingFire; +using CalamityMod.Dusts; using Microsoft.Xna.Framework; using Terraria; -using Terraria.DataStructures; using Terraria.ID; using Terraria.ModLoader; -using Terraria.ObjectData; + namespace CalamityMod.Tiles.LivingFire { public class LivingBrimstoneFireBlockTile : ModTile { - //Thank you to Seraph for getting living fire blocks to work properly. public override void SetStaticDefaults() { Main.tileLighted[Type] = true; - HitSound = SoundID.Dig; + TileID.Sets.CanPlaceNextToNonSolidTile[Type] = true; + DustType = (int)CalamityDusts.Brimstone; AddMapEntry(new Color(178, 34, 34)); AnimationFrameHeight = 90; - Main.tileSolid[Type] = false; - Main.tileNoAttach[Type] = false; - Main.tileFrameImportant[Type] = false; - TileObjectData.newTile.Width = 1; - TileObjectData.newTile.Height = 1; - TileObjectData.newTile.Origin = new Point16(0, 0); - TileObjectData.newTile.CoordinateHeights = new int[] { 16 }; - TileObjectData.newTile.CoordinateWidth = 16; - TileObjectData.newTile.CoordinatePadding = 2; - TileObjectData.newTile.HookCheckIfCanPlace = new PlacementHook(CanPlaceAlter, -1, 0, true); - TileObjectData.newTile.UsesCustomCanPlace = true; - TileObjectData.newTile.HookPostPlaceMyPlayer = new PlacementHook(AfterPlacement, -1, 0, false); - - TileObjectData.addTile(Type); - } - - public int CanPlaceAlter(int i, int j, int type, int style, int direction, int alternate) => 1; - - public static int AfterPlacement(int i, int j, int type, int style, int direction, int alternate) - { - if (Main.netMode == NetmodeID.MultiplayerClient) - { - NetMessage.SendTileSquare(Main.myPlayer, i, j, 1, 1); - } - return 1; } - public override bool CanPlace(int i, int j) - { - List> around = new List> - { - new List() {i, j-1 }, - new List() {i-1, j }, - new List() {i+1, j }, - new List() {i, j+1 } - }; - //if (Main.tile[i, j]) || tile.type == Type - - //return true; //temporary for testing purposes + public override void SetDrawPositions(int i, int j, ref int width, ref int offsetY, ref int height, ref short tileFrameX, ref short tileFrameY) => offsetY = 2; - if (Main.tile[i, j].WallType != WallID.None) - { - return true; - } - - for (int k = 0; k < around.Count; ++k) - { - Tile tile = Main.tile[around[k][0], around[k][1]]; - if (tile.HasTile && (Main.tileSolid[tile.TileType] || CalamityLists.livingFireBlockList.Contains(tile.TileType))) - { - return true; - } - } - return false; - } - - public override void AnimateTile(ref int frame, ref int frameCounter) - { - frame = Main.tileFrame[TileID.LivingFire]; - } + public override void AnimateTile(ref int frame, ref int frameCounter) => frame = Main.tileFrame[TileID.LivingFire]; public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) { @@ -85,11 +27,5 @@ public override void ModifyLight(int i, int j, ref float r, ref float g, ref flo g = 0f; b = 0f; } - - public override bool CreateDust(int i, int j, ref int type) - { - Dust.NewDust(new Vector2(i, j) * 16f, 16, 16, (int)CalamityDusts.Brimstone, 0f, 0f, 1, default, 1f); - return false; - } } } diff --git a/Tiles/LivingFire/LivingGodSlayerFireBlockTile.cs b/Tiles/LivingFire/LivingGodSlayerFireBlockTile.cs index 688e1eef69..2ad8f0f689 100644 --- a/Tiles/LivingFire/LivingGodSlayerFireBlockTile.cs +++ b/Tiles/LivingFire/LivingGodSlayerFireBlockTile.cs @@ -1,12 +1,9 @@ -using System.Collections.Generic; -using CalamityMod.Dusts; -using CalamityMod.Items.Placeables.LivingFire; +using CalamityMod.Dusts; using Microsoft.Xna.Framework; using Terraria; -using Terraria.DataStructures; using Terraria.ID; using Terraria.ModLoader; -using Terraria.ObjectData; + namespace CalamityMod.Tiles.LivingFire { public class LivingGodSlayerFireBlockTile : ModTile @@ -14,69 +11,15 @@ public class LivingGodSlayerFireBlockTile : ModTile public override void SetStaticDefaults() { Main.tileLighted[Type] = true; - HitSound = SoundID.Dig; + TileID.Sets.CanPlaceNextToNonSolidTile[Type] = true; + DustType = (int)CalamityDusts.PurpleCosmilite; AddMapEntry(new Color(186, 85, 211)); AnimationFrameHeight = 90; - Main.tileSolid[Type] = false; - Main.tileNoAttach[Type] = false; - Main.tileFrameImportant[Type] = false; - TileObjectData.newTile.Width = 1; - TileObjectData.newTile.Height = 1; - TileObjectData.newTile.Origin = new Point16(0, 0); - TileObjectData.newTile.CoordinateHeights = new int[] { 16 }; - TileObjectData.newTile.CoordinateWidth = 16; - TileObjectData.newTile.CoordinatePadding = 2; - TileObjectData.newTile.HookCheckIfCanPlace = new PlacementHook(CanPlaceAlter, -1, 0, true); - TileObjectData.newTile.UsesCustomCanPlace = true; - TileObjectData.newTile.HookPostPlaceMyPlayer = new PlacementHook(AfterPlacement, -1, 0, false); - - TileObjectData.addTile(Type); - } - - public int CanPlaceAlter(int i, int j, int type, int style, int direction, int alternate) => 1; - - public static int AfterPlacement(int i, int j, int type, int style, int direction, int alternate) - { - if (Main.netMode == NetmodeID.MultiplayerClient) - { - NetMessage.SendTileSquare(Main.myPlayer, i, j, 1, 1); - } - return 1; } - public override bool CanPlace(int i, int j) - { - List> around = new List> - { - new List() {i, j-1 }, - new List() {i-1, j }, - new List() {i+1, j }, - new List() {i, j+1 } - }; - //if (Main.tile[i, j]) || tile.type == Type - - //return true; //temporary for testing purposes + public override void SetDrawPositions(int i, int j, ref int width, ref int offsetY, ref int height, ref short tileFrameX, ref short tileFrameY) => offsetY = 2; - if (Main.tile[i, j].WallType != WallID.None) - { - return true; - } - - for (int k = 0; k < around.Count; ++k) - { - Tile tile = Main.tile[around[k][0], around[k][1]]; - if (tile.HasTile && (Main.tileSolid[tile.TileType] || CalamityLists.livingFireBlockList.Contains(tile.TileType))) - { - return true; - } - } - return false; - } - - public override void AnimateTile(ref int frame, ref int frameCounter) - { - frame = Main.tileFrame[TileID.LivingFire]; - } + public override void AnimateTile(ref int frame, ref int frameCounter) => frame = Main.tileFrame[TileID.LivingFire]; public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) { @@ -84,11 +27,5 @@ public override void ModifyLight(int i, int j, ref float r, ref float g, ref flo g = 0f; b = 1f; } - - public override bool CreateDust(int i, int j, ref int type) - { - Dust.NewDust(new Vector2(i, j) * 16f, 16, 16, (int)CalamityDusts.PurpleCosmilite, 0f, 0f, 1, default, 1f); - return false; - } } } diff --git a/Tiles/LivingFire/LivingHolyFireBlockTile.cs b/Tiles/LivingFire/LivingHolyFireBlockTile.cs index 82a99923db..51d1319a34 100644 --- a/Tiles/LivingFire/LivingHolyFireBlockTile.cs +++ b/Tiles/LivingFire/LivingHolyFireBlockTile.cs @@ -1,12 +1,9 @@ -using System.Collections.Generic; -using CalamityMod.Dusts; -using CalamityMod.Items.Placeables.LivingFire; +using CalamityMod.Dusts; using Microsoft.Xna.Framework; using Terraria; -using Terraria.DataStructures; using Terraria.ID; using Terraria.ModLoader; -using Terraria.ObjectData; + namespace CalamityMod.Tiles.LivingFire { public class LivingHolyFireBlockTile : ModTile @@ -14,69 +11,15 @@ public class LivingHolyFireBlockTile : ModTile public override void SetStaticDefaults() { Main.tileLighted[Type] = true; - HitSound = SoundID.Dig; + TileID.Sets.CanPlaceNextToNonSolidTile[Type] = true; + DustType = (int)CalamityDusts.ProfanedFire; AddMapEntry(new Color(255, 215, 0)); AnimationFrameHeight = 90; - Main.tileSolid[Type] = false; - Main.tileNoAttach[Type] = false; - Main.tileFrameImportant[Type] = false; - TileObjectData.newTile.Width = 1; - TileObjectData.newTile.Height = 1; - TileObjectData.newTile.Origin = new Point16(0, 0); - TileObjectData.newTile.CoordinateHeights = new int[] { 16 }; - TileObjectData.newTile.CoordinateWidth = 16; - TileObjectData.newTile.CoordinatePadding = 2; - TileObjectData.newTile.HookCheckIfCanPlace = new PlacementHook(CanPlaceAlter, -1, 0, true); - TileObjectData.newTile.UsesCustomCanPlace = true; - TileObjectData.newTile.HookPostPlaceMyPlayer = new PlacementHook(AfterPlacement, -1, 0, false); - - TileObjectData.addTile(Type); - } - - public int CanPlaceAlter(int i, int j, int type, int style, int direction, int alternate) => 1; - - public static int AfterPlacement(int i, int j, int type, int style, int direction, int alternate) - { - if (Main.netMode == NetmodeID.MultiplayerClient) - { - NetMessage.SendTileSquare(Main.myPlayer, i, j, 1, 1); - } - return 1; } - public override bool CanPlace(int i, int j) - { - List> around = new List> - { - new List() {i, j-1 }, - new List() {i-1, j }, - new List() {i+1, j }, - new List() {i, j+1 } - }; - //if (Main.tile[i, j]) || tile.type == Type - - //return true; //temporary for testing purposes + public override void SetDrawPositions(int i, int j, ref int width, ref int offsetY, ref int height, ref short tileFrameX, ref short tileFrameY) => offsetY = 2; - if (Main.tile[i, j].WallType != WallID.None) - { - return true; - } - - for (int k = 0; k < around.Count; ++k) - { - Tile tile = Main.tile[around[k][0], around[k][1]]; - if (tile.HasTile && (Main.tileSolid[tile.TileType] || CalamityLists.livingFireBlockList.Contains(tile.TileType))) - { - return true; - } - } - return false; - } - - public override void AnimateTile(ref int frame, ref int frameCounter) - { - frame = Main.tileFrame[TileID.LivingFire]; - } + public override void AnimateTile(ref int frame, ref int frameCounter) => frame = Main.tileFrame[TileID.LivingFire]; public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) { @@ -84,11 +27,5 @@ public override void ModifyLight(int i, int j, ref float r, ref float g, ref flo g = 1f; b = 0f; } - - public override bool CreateDust(int i, int j, ref int type) - { - Dust.NewDust(new Vector2(i, j) * 16f, 16, 16, (int)CalamityDusts.ProfanedFire, 0f, 0f, 1, default, 1f); - return false; - } } } From b78a390734548a62e6dfc2d464d6a2405cb100bf Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Mon, 14 Oct 2024 18:17:03 +0700 Subject: [PATCH 379/401] fixed drill containment unit running CanUseItem by frame --- Items/CalamityGlobalItem.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Items/CalamityGlobalItem.cs b/Items/CalamityGlobalItem.cs index 90e8227993..0b62e32a86 100644 --- a/Items/CalamityGlobalItem.cs +++ b/Items/CalamityGlobalItem.cs @@ -785,6 +785,11 @@ public override bool CanUseItem(Item item, Player player) return false; // Don't use weapons if you're charging with a spear } + // If the player if using the Drill Containment Unit, ignore all this. + // It will start to check for everything below EVERY FRAME, including attacking with PSC or using Charge + if (player.mount.Type == MountID.Drill) + return base.CanUseItem(item, player); + // Conversion for Andromeda if (player.ownedProjectileCounts[ModContent.ProjectileType()] > 0) { From 12de8fd6bea172412a3e96306a6b57d7f9707134 Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Wed, 26 Nov 2025 07:54:58 +0700 Subject: [PATCH 380/401] merge gore --- Tiles/FurniturePlaguedPlate/PlaguedPlateBed.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tiles/FurniturePlaguedPlate/PlaguedPlateBed.cs b/Tiles/FurniturePlaguedPlate/PlaguedPlateBed.cs index 6ffa949f39..6e6dc45c34 100644 --- a/Tiles/FurniturePlaguedPlate/PlaguedPlateBed.cs +++ b/Tiles/FurniturePlaguedPlate/PlaguedPlateBed.cs @@ -16,7 +16,7 @@ public override void SetStaticDefaults() Main.tileFrameImportant[Type] = true; Main.tileLavaDeath[Type] = false; TileID.Sets.HasOutlines[Type] = true; - TileID.Sets.InteractibleByNPCs[mt.Type] = true; + TileID.Sets.InteractibleByNPCs[Type] = true; TileID.Sets.DisableSmartCursor[Type] = true; TileID.Sets.IsValidSpawnPoint[Type] = true; TileObjectData.newTile.CopyFrom(TileObjectData.Style3x4); //This bed has different dimensions to conventional beds, using bookcase dimentions instead From 1eff672eaa4d8b0184328bd687dc15ab93581de4 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Wed, 26 Nov 2025 05:54:35 -0500 Subject: [PATCH 381/401] Merged the three interlude configs --- CalamityConfig.cs | 10 +-------- .../en-US/Mods.CalamityMod.Configs.hjson | 22 ++++++++----------- Systems/MusicEventSystem.cs | 6 ++--- 3 files changed, 13 insertions(+), 25 deletions(-) diff --git a/CalamityConfig.cs b/CalamityConfig.cs index 77cc6af335..09da028a74 100644 --- a/CalamityConfig.cs +++ b/CalamityConfig.cs @@ -215,15 +215,7 @@ internal void ClampValues(StreamingContext context) [BackgroundColor(192, 54, 64, 192)] [DefaultValue(true)] - public bool Interlude1 { get; set; } - - [BackgroundColor(192, 54, 64, 192)] - [DefaultValue(true)] - public bool Interlude2 { get; set; } - - [BackgroundColor(192, 54, 64, 192)] - [DefaultValue(true)] - public bool Interlude3 { get; set; } + public bool Interludes { get; set; } [BackgroundColor(192, 54, 64, 192)] [DefaultValue(true)] diff --git a/Localization/en-US/Mods.CalamityMod.Configs.hjson b/Localization/en-US/Mods.CalamityMod.Configs.hjson index 8e51275640..9914cc0c2b 100644 --- a/Localization/en-US/Mods.CalamityMod.Configs.hjson +++ b/Localization/en-US/Mods.CalamityMod.Configs.hjson @@ -129,19 +129,15 @@ CalamityClientConfig: { ''' } - Interlude1: { - Label: "[i:CalamityModMusic/Interlude1MusicBox] Interlude 1" - Tooltip: Plays Calamity Mod OST - Interlude 1, "Silence before the storms", after Calamitas Clone has been defeated. - } - - Interlude2: { - Label: "[i:CalamityModMusic/Interlude2MusicBox] Interlude 2" - Tooltip: Plays Calamity Mod OST - Interlude 2, "Storms before the catastrophes", after Moon Lord has been defeated. - } - - Interlude3: { - Label: "[i:CalamityModMusic/Interlude3MusicBox] Interlude 3" - Tooltip: Plays Calamity Mod OST - Interlude 3, "Catastrophes before the calamity", after Yharon has been defeated. + Interludes: { + Label: "[i:CalamityModMusic/Interlude1MusicBox] Interludes" + Tooltip: + ''' + Enables the playing of three interlude tracks in-game: + Plays Calamity Mod OST - Interlude 1, "Silence before the storms", after Calamitas Clone has been defeated. + Plays Calamity Mod OST - "Storms before the catastrophes", after the Moon Lord has been defeated. + Plays Calamity Mod OST - "Catastrophes before the calamity", after Yharon has been defeated. + ''' } MeterPosLock: { diff --git a/Systems/MusicEventSystem.cs b/Systems/MusicEventSystem.cs index 2b78e271c0..6d38337ac7 100644 --- a/Systems/MusicEventSystem.cs +++ b/Systems/MusicEventSystem.cs @@ -52,17 +52,17 @@ static void AddEntry(string eventId, string songName, TimeSpan length, Func DownedBossSystem.downedCalamitasClone, () => CalamityClientConfig.Instance.Interlude1); + () => DownedBossSystem.downedCalamitasClone, () => CalamityClientConfig.Instance.Interludes); AddEntry("MLDefeated", "Interlude2", TimeSpan.FromSeconds(191.912d), () => NPC.downedMoonlord, - () => CalamityClientConfig.Instance.Interlude2, outroSilence: TimeSpan.FromSeconds(1f)); + () => CalamityClientConfig.Instance.Interludes, outroSilence: TimeSpan.FromSeconds(1f)); // Alternative Interlude 2 -> AddEntry("MLDefeated", "Interlude2_CutIntro", TimeSpan.FromSeconds(160.989d), // () => NPC.downedMoonlord, () => CalamityConfig.Instance.Interlude2, // outroSilence: TimeSpan.FromSeconds(1f)); AddEntry("YharonDefeated", "Interlude3", TimeSpan.FromSeconds(295.932d), - () => DownedBossSystem.downedYharon, () => CalamityClientConfig.Instance.Interlude3); + () => DownedBossSystem.downedYharon, () => CalamityClientConfig.Instance.Interludes); AddEntry("DoGDefeated", "DevourerofGodsEulogy", TimeSpan.FromSeconds(203.620d), () => DownedBossSystem.downedDoG, () => CalamityClientConfig.Instance.DevourerofGodsEulogy, From 5d15472cb729fd4e1d9b216abda3fc2abe623d98 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Wed, 26 Nov 2025 14:16:59 -0500 Subject: [PATCH 382/401] Sweeping changes to crate loot Including removal of most biome-specific material drops Includes the Hardmode ore crate bug fix at long last Also adds alternative Auric Ore obtainment method --- Enums/HardmodeCrateType.cs | 9 + Items/CalamityGlobalItemLoot.cs | 151 ++++---- Items/Fishing/AstralCatches/AstralCrate.cs | 69 +--- Items/Fishing/AstralCatches/MonolithCrate.cs | 37 +- .../BrimstoneCragCatches/BrimstoneCrate.cs | 27 +- .../Fishing/BrimstoneCragCatches/SlagCrate.cs | 35 +- .../SulphurCatches/HydrothermalCrate.cs | 83 +--- .../Fishing/SulphurCatches/SulphurousCrate.cs | 77 +--- .../SunkenSeaCatches/EutrophicCrate.cs | 47 +-- Items/Fishing/SunkenSeaCatches/PrismCrate.cs | 50 +-- Items/Placeables/Ores/AuricOre.cs | 11 +- Utilities/DropHelper.cs | 366 ++++++++++++++++-- 12 files changed, 511 insertions(+), 451 deletions(-) create mode 100644 Enums/HardmodeCrateType.cs diff --git a/Enums/HardmodeCrateType.cs b/Enums/HardmodeCrateType.cs new file mode 100644 index 0000000000..6febfd2600 --- /dev/null +++ b/Enums/HardmodeCrateType.cs @@ -0,0 +1,9 @@ +namespace CalamityMod.Enums +{ + public enum HardmodeCrateType + { + Biome, + Mythril, + Titanium + } +} diff --git a/Items/CalamityGlobalItemLoot.cs b/Items/CalamityGlobalItemLoot.cs index 12b004b8cd..e01900cf49 100644 --- a/Items/CalamityGlobalItemLoot.cs +++ b/Items/CalamityGlobalItemLoot.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using CalamityMod.Enums; using CalamityMod.Items.Accessories; using CalamityMod.Items.Materials; using CalamityMod.Items.PermanentBoosters; @@ -25,12 +26,6 @@ public class CalamityGlobalItemLoot : GlobalItem public override void ModifyItemLoot(Item item, ItemLoot loot) { Fraction fifteenPercent = new Fraction(15, 100); - static bool CryonicAvailable() - { - if (!DownedBossSystem.downedCryogen) - return false; - return (NPC.downedMechBoss1.ToInt() + NPC.downedMechBoss2.ToInt() + NPC.downedMechBoss3.ToInt()) >= 2; - } switch (item.type) { @@ -270,91 +265,47 @@ static bool CryonicAvailable() #endregion #region Fishing Crates - // TODO -- What is all this shit? case ItemID.WoodenCrate: case ItemID.WoodenCrateHard: - loot.Add(ModContent.ItemType(), 4, 3, 5); // 25% 3-5 Wulfrum Scrap + // We do not need to pop Hardmode ores out of Pearlwood Crates. They do not drop higher tier ores. break; - case ItemID.IronCrate: case ItemID.IronCrateHard: - loot.Add(ModContent.ItemType(), 4, 5, 8); // 25% 5-8 Wulfrum Scrap - loot.Add(ModContent.ItemType(), 4, 5, 8); // 25% 5-8 Ancient Bone Dust + RemoveHardmodeOresFromStandardCrates(loot); + loot.AddHardmodeOresToCrates(HardmodeCrateType.Mythril); break; - // these drops are not available in hardmode because this crate will stop dropping + // Non-crafted underground Gold Chest loot @ 20%; Individually 5% case ItemID.GoldenCrate: - loot.Add(ItemID.FlareGun, 10); // 10% Flare Gun - loot.Add(ItemID.ShoeSpikes, 10); // 10% Shoe Spikes (BUT NOT CLIMBING CLAWS?) - loot.Add(ItemID.BandofRegeneration, 10); // 10% Band of Regeneration + loot.Add(new OneFromOptionsNotScaledWithLuckDropRule(5, 1, + ItemID.FlareGun, + ItemID.Mace, + ItemID.BandofRegeneration, + ItemID.ShoeSpikes)); // Climbing Claws is in Wooden/Pearlwood (vanilla) in case you're curious break; case ItemID.GoldenCrateHard: - // Post-Yharon: 15% 30-40 Auric Ore - loot.AddIf(() => DownedBossSystem.downedYharon, ModContent.ItemType(), fifteenPercent, 30, 40); + RemoveHardmodeOresFromStandardCrates(loot); + loot.AddHardmodeOresToCrates(HardmodeCrateType.Titanium); + loot.Add(new OneFromOptionsNotScaledWithLuckDropRule(5, 1, + ItemID.FlareGun, + ItemID.Mace, + ItemID.BandofRegeneration, + ItemID.ShoeSpikes)); break; - case ItemID.CorruptFishingCrate: - case ItemID.CrimsonFishingCrate: case ItemID.CorruptFishingCrateHard: case ItemID.CrimsonFishingCrateHard: - loot.Add(ModContent.ItemType(), fifteenPercent, 5, 8); // 15% 5-8 Blighted Gel - break; - - case ItemID.HallowedFishingCrate: // WHY case ItemID.HallowedFishingCrateHard: - var postProv = loot.DefineConditionalDropSet(() => DownedBossSystem.downedProvidence); - postProv.Add(ModContent.ItemType(), fifteenPercent, 5, 10); // 15% 5-10 Unholy Essence - break; - - case ItemID.DungeonFishingCrate: case ItemID.DungeonFishingCrateHard: - loot.AddIf(() => NPC.downedPlantBoss, ItemID.Ectoplasm, 10, 1, 5); // 10% 1-5 Ectoplasm - loot.AddIf(() => DownedBossSystem.downedPolterghast, ModContent.ItemType(), 10, 1, 5); // 10% 1-5 Necroplasm - break; - - case ItemID.JungleFishingCrate: case ItemID.JungleFishingCrateHard: - loot.Add(ModContent.ItemType(), new Fraction(1, 5), 1, 3); // 20% 1-3 Murky Paste - var postPlant = loot.DefineConditionalDropSet(() => NPC.downedPlantBoss); - postPlant.Add(ModContent.ItemType(), 5, 16, 28); // 20% 16-28 Perennial Ore - postPlant.Add(ModContent.ItemType(), fifteenPercent, 4, 7); // 15% 4-7 Perennial Bar - loot.AddIf(() => NPC.downedGolemBoss, ModContent.ItemType(), 5, 3, 6); // 20% 3-6 Plague Cell Canister - var uelibloom = loot.DefineConditionalDropSet(() => DownedBossSystem.downedProvidence); - uelibloom.Add(ModContent.ItemType(), 5, 16, 28); // 20% 16-28 Uelibloom Ore - uelibloom.Add(ModContent.ItemType(), fifteenPercent, 4, 7); // 15% 4-7 Uelibloom Bar - break; - - case ItemID.FloatingIslandFishingCrate: case ItemID.FloatingIslandFishingCrateHard: - var evilBossTwo = loot.DefineConditionalDropSet(() => DownedBossSystem.downedHiveMind || DownedBossSystem.downedPerforator); - evilBossTwo.Add(ModContent.ItemType(), 5, 16, 28); // 20% 16-28 Aerialite Ore - evilBossTwo.Add(ModContent.ItemType(), fifteenPercent, 4, 7); // 15% 4-7 Aerialite Bar - loot.AddIf(() => Main.hardMode, ModContent.ItemType(), 5, 2, 4); // 20% 2-4 Essence of Sunlight - loot.AddIf(() => NPC.downedMoonlord, ModContent.ItemType(), 5, 16, 28); // 20% 16-28 Exodium Clusters - break; - - case ItemID.FrozenCrate: case ItemID.FrozenCrateHard: - var cryonic = loot.DefineConditionalDropSet(CryonicAvailable); - cryonic.Add(ModContent.ItemType(), 5, 16, 28); // 20% 16-28 Cryonic Ore - cryonic.Add(ModContent.ItemType(), fifteenPercent, 4, 7); // 15% 4-7 Cryonic Bar - loot.AddIf(() => Main.hardMode, ModContent.ItemType(), 5, 2, 4); // 20% 2-4 Essence of Eleum - break; - - case ItemID.LavaCrate: case ItemID.LavaCrateHard: - loot.AddIf(() => Main.hardMode, ModContent.ItemType(), 5, 2, 4); // 20% 2-4 Essence of Havoc - break; - - // Calamity does not touch Oasis Crates yet - case ItemID.OasisCrate: case ItemID.OasisCrateHard: - break; - - // Calamity does not touch Ocean Crates yet - case ItemID.OceanCrate: case ItemID.OceanCrateHard: + RemoveHardmodeOresFromBiomeCrates(loot); + loot.AddHardmodeOresToCrates(HardmodeCrateType.Biome); break; #endregion @@ -525,6 +476,70 @@ private static IItemDropRule FindMoonLordWeapons(ItemLoot loot) } #endregion + #region Fishing Crate Loot Rule Manipulation + private static void RemoveHardmodeOresFromStandardCrates(ItemLoot loot) + { + List rules = loot.Get(false); + + // This is the primary rule which contains every drop + AlwaysAtleastOneSuccessDropRule mainRule = null; + foreach (IItemDropRule rule in rules) + if (rule is AlwaysAtleastOneSuccessDropRule a) + mainRule = a; + if (mainRule is null) + return; + + // Find ones that are supposed to be for the ore and not the other loot + foreach (IItemDropRule rule in mainRule.rules) + { + // Hardmode ores/bars are both nested within *another* nested rule + if (rule is SequentialRulesNotScalingWithLuckRule oreRule) + { + // Confirm that this is for the ore/bar then pop the numerator for the big rule + foreach (IItemDropRule nestedRule in oreRule.rules) + { + if (nestedRule is SequentialRulesNotScalingWithLuckRule s) + { + oreRule.chanceNumerator = 0; + return; + } + } + } + } + } + + private static void RemoveHardmodeOresFromBiomeCrates(ItemLoot loot) + { + List rules = loot.Get(false); + + // This is the primary rule which contains every drop + AlwaysAtleastOneSuccessDropRule mainRule = null; + foreach (IItemDropRule rule in rules) + if (rule is AlwaysAtleastOneSuccessDropRule a) + mainRule = a; + if (mainRule is null) + return; + + // Find ones that are supposed to be for the ore and not the other loot + foreach (IItemDropRule rule in mainRule.rules) + { + // Hardmode ores/bars are both nested within *another* nested rule + if (rule is SequentialRulesNotScalingWithLuckRule oreRule) + { + // Confirm that this is for the ore/bar then pop the numerator for the big rule + foreach (IItemDropRule nestedRule in oreRule.rules) + { + if (nestedRule is OneFromRulesRule o) + { + oreRule.chanceNumerator = 0; + return; + } + } + } + } + } + #endregion + #region Goodie Bag Bat Hook private static void RemoveBatHookFromGoodieBag(ItemLoot loot) { diff --git a/Items/Fishing/AstralCatches/AstralCrate.cs b/Items/Fishing/AstralCatches/AstralCrate.cs index 690c4c8e8b..40ed274c6a 100644 --- a/Items/Fishing/AstralCatches/AstralCrate.cs +++ b/Items/Fishing/AstralCatches/AstralCrate.cs @@ -1,16 +1,6 @@ -using CalamityMod.Items.Accessories; -using CalamityMod.Items.Critters; -using CalamityMod.Items.Materials; -using CalamityMod.Items.Placeables.Ores; -using CalamityMod.Items.Potions; -using CalamityMod.Items.Weapons.Magic; -using CalamityMod.Items.Weapons.Melee; -using CalamityMod.Items.Weapons.Ranged; -using CalamityMod.Items.Weapons.Rogue; -using CalamityMod.Items.Weapons.Summon; +using CalamityMod.Items.Materials; using CalamityMod.Tiles.Astral; using Terraria; -using Terraria.GameContent.ItemDropRules; using Terraria.ID; using Terraria.ModLoader; @@ -29,18 +19,11 @@ public override void SetStaticDefaults() public override void SetDefaults() { + Item.DefaultToPlaceableTile(ModContent.TileType()); Item.width = 32; Item.height = 32; - Item.maxStack = 9999; - Item.consumable = true; - Item.rare = ItemRarityID.Green; Item.value = Item.sellPrice(gold: 1); - Item.createTile = ModContent.TileType(); - Item.useTurn = true; - Item.autoReuse = true; - Item.useAnimation = 15; - Item.useTime = 10; - Item.useStyle = ItemUseStyleID.Swing; + Item.rare = ItemRarityID.Green; } public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.ItemGroup itemGroup) @@ -51,48 +34,14 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite public override bool CanRightClick() => true; public override void ModifyItemLoot(ItemLoot itemLoot) { - var postAstrumAureus = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedAstrumAureus); - var postAstrumDeus = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedAstrumDeus); - - // Materials - itemLoot.Add(ModContent.ItemType(), 1, 5, 10); - itemLoot.Add(ItemID.FallenStar, 1, 5, 10); - itemLoot.Add(ItemID.Meteorite, 5, 10, 20); - itemLoot.Add(ItemID.MeteoriteBar, 10, 1, 3); - - postAstrumAureus.Add(ModContent.ItemType(), 5, 2, 5); - postAstrumDeus.Add(ModContent.ItemType(), 5, 10, 20); - postAstrumDeus.Add(ModContent.ItemType(), 10, 1, 3); - postAstrumDeus.Add(ModContent.ItemType(), 4, 5, 10); - - // Weapons (and Starburster Core) - postAstrumAureus.Add(new OneFromOptionsDropRule(10, 1, - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType() - )); - - // Pet - itemLoot.Add(ModContent.ItemType(), 10); - - // Bait - itemLoot.Add(ModContent.ItemType(), 5, 1, 3); - itemLoot.Add(ItemID.EnchantedNightcrawler, 5, 1, 3); - itemLoot.Add(ModContent.ItemType(), 5, 1, 3); - itemLoot.Add(ItemID.Firefly, 3, 1, 3); + // 4-10 Starblight Soot @ 50% + // This is our equivalent to Crystal Shards/Ichor + itemLoot.Add(ModContent.ItemType(), 2, 4, 10); - // Potions - postAstrumAureus.Add(ModContent.ItemType(), 10, 1, 3); - postAstrumAureus.Add(ModContent.ItemType(), 10, 1, 3); - itemLoot.AddCratePotionRules(); + // Astrophage @ 5% + itemLoot.Add(ModContent.ItemType(), 20); - // Money - itemLoot.Add(ItemID.SilverCoin, 1, 10, 90); - itemLoot.Add(ItemID.GoldCoin, 2, 1, 5); + itemLoot.AddBiomeCrateLootRules(); } } } diff --git a/Items/Fishing/AstralCatches/MonolithCrate.cs b/Items/Fishing/AstralCatches/MonolithCrate.cs index 060d03675b..726d74743f 100644 --- a/Items/Fishing/AstralCatches/MonolithCrate.cs +++ b/Items/Fishing/AstralCatches/MonolithCrate.cs @@ -1,5 +1,4 @@ -using CalamityMod.Items.Critters; -using CalamityMod.Tiles.Astral; +using CalamityMod.Tiles.Astral; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -17,18 +16,11 @@ public override void SetStaticDefaults() public override void SetDefaults() { + Item.DefaultToPlaceableTile(ModContent.TileType()); Item.width = 32; Item.height = 32; - Item.maxStack = 9999; - Item.consumable = true; - Item.rare = ItemRarityID.Green; Item.value = Item.sellPrice(gold: 1); - Item.createTile = ModContent.TileType(); - Item.useTurn = true; - Item.autoReuse = true; - Item.useAnimation = 15; - Item.useTime = 10; - Item.useStyle = ItemUseStyleID.Swing; + Item.rare = ItemRarityID.Green; } public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.ItemGroup itemGroup) @@ -39,27 +31,10 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite public override bool CanRightClick() => true; public override void ModifyItemLoot(ItemLoot itemLoot) { - // Materials - itemLoot.Add(ItemID.FallenStar, 1, 5, 10); - itemLoot.Add(ItemID.Meteorite, 5, 10, 20); - itemLoot.Add(ItemID.MeteoriteBar, 10, 1, 3); - - // Pet - itemLoot.Add(ModContent.ItemType(), 10); - - // Bait - itemLoot.Add(ModContent.ItemType(), 5, 1, 3); - itemLoot.Add(ItemID.EnchantedNightcrawler, 5, 1, 3); - itemLoot.Add(ModContent.ItemType(), 5, 1, 3); - - itemLoot.Add(ItemID.Firefly, 3, 1, 3); - - // Potions - itemLoot.AddCratePotionRules(false); + // Astrophage @ 5% + itemLoot.Add(ModContent.ItemType(), 20); - // Money - itemLoot.Add(ItemID.SilverCoin, 1, 10, 90); - itemLoot.Add(ItemID.GoldCoin, 2, 1, 5); + itemLoot.AddBiomeCrateLootRules(false); } } } diff --git a/Items/Fishing/BrimstoneCragCatches/BrimstoneCrate.cs b/Items/Fishing/BrimstoneCragCatches/BrimstoneCrate.cs index 6a0413d264..fb5785cf59 100644 --- a/Items/Fishing/BrimstoneCragCatches/BrimstoneCrate.cs +++ b/Items/Fishing/BrimstoneCragCatches/BrimstoneCrate.cs @@ -1,6 +1,4 @@ -using CalamityMod.Items.Materials; -using CalamityMod.Items.Potions; -using CalamityMod.Tiles.Crags; +using CalamityMod.Tiles.Crags; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -42,28 +40,7 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite public override bool CanRightClick() => true; public override void ModifyItemLoot(ItemLoot itemLoot) { - // Materials - itemLoot.Add(ItemID.Obsidian, 1, 2, 5); - itemLoot.Add(ItemID.Hellstone, 4, 2, 5); - itemLoot.Add(ItemID.HellstoneBar, 10, 1, 3); - itemLoot.Add(ModContent.ItemType(), 1, 1, 4); - itemLoot.AddIf(() => DownedBossSystem.downedBrimstoneElemental, ModContent.ItemType(), 10, 1, 3); - itemLoot.AddIf(() => DownedBossSystem.downedProvidence, ModContent.ItemType(), 2, 1, 3); - - // Weapons (none) - - // Bait - itemLoot.Add(ItemID.MasterBait, 10, 1, 2); - itemLoot.Add(ItemID.JourneymanBait, 5, 1, 3); - itemLoot.Add(ItemID.ApprenticeBait, 3, 2, 3); - - // Potions - itemLoot.Add(ItemID.InfernoPotion, 10, 1, 3); - itemLoot.AddCratePotionRules(); - - // Money - itemLoot.Add(ItemID.SilverCoin, 1, 10, 90); - itemLoot.Add(ItemID.GoldCoin, 2, 1, 5); + itemLoot.AddBiomeCrateLootRules(); } } } diff --git a/Items/Fishing/BrimstoneCragCatches/SlagCrate.cs b/Items/Fishing/BrimstoneCragCatches/SlagCrate.cs index 55ff0e63e7..a6259f890c 100644 --- a/Items/Fishing/BrimstoneCragCatches/SlagCrate.cs +++ b/Items/Fishing/BrimstoneCragCatches/SlagCrate.cs @@ -1,5 +1,4 @@ -using CalamityMod.Items.Materials; -using CalamityMod.Tiles.Crags; +using CalamityMod.Tiles.Crags; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -17,18 +16,11 @@ public override void SetStaticDefaults() public override void SetDefaults() { + Item.DefaultToPlaceableTile(ModContent.TileType()); Item.width = 32; Item.height = 32; - Item.maxStack = 9999; - Item.consumable = true; - Item.rare = ItemRarityID.Green; Item.value = Item.sellPrice(gold: 1); - Item.createTile = ModContent.TileType(); - Item.useTurn = true; - Item.autoReuse = true; - Item.useAnimation = 15; - Item.useTime = 10; - Item.useStyle = ItemUseStyleID.Swing; + Item.rare = ItemRarityID.Green; } public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.ItemGroup itemGroup) @@ -39,26 +31,7 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite public override bool CanRightClick() => true; public override void ModifyItemLoot(ItemLoot itemLoot) { - // Materials - itemLoot.Add(ItemID.Obsidian, 1, 2, 5); - itemLoot.Add(ItemID.Hellstone, 4, 2, 5); - itemLoot.Add(ItemID.HellstoneBar, 10, 1, 3); - itemLoot.Add(ModContent.ItemType(), 1, 1, 4); - - // Weapons (none) - - // Bait - itemLoot.Add(ItemID.MasterBait, 10, 1, 2); - itemLoot.Add(ItemID.JourneymanBait, 5, 1, 3); - itemLoot.Add(ItemID.ApprenticeBait, 3, 2, 3); - - // Potions - itemLoot.Add(ItemID.InfernoPotion, 10, 1, 3); - itemLoot.AddCratePotionRules(false); - - // Money - itemLoot.Add(ItemID.SilverCoin, 1, 10, 90); - itemLoot.Add(ItemID.GoldCoin, 2, 1, 5); + itemLoot.AddBiomeCrateLootRules(false); } } } diff --git a/Items/Fishing/SulphurCatches/HydrothermalCrate.cs b/Items/Fishing/SulphurCatches/HydrothermalCrate.cs index 52dad8a28b..547da73a7a 100644 --- a/Items/Fishing/SulphurCatches/HydrothermalCrate.cs +++ b/Items/Fishing/SulphurCatches/HydrothermalCrate.cs @@ -1,9 +1,6 @@ using CalamityMod.Items.Accessories; -using CalamityMod.Items.Materials; using CalamityMod.Items.Pets; -using CalamityMod.Items.Placeables; -using CalamityMod.Items.Placeables.Ores; -using CalamityMod.Items.Potions; +using CalamityMod.Items.Placeables.Furniture; using CalamityMod.Items.Tools.ClimateChange; using CalamityMod.Items.Weapons.Magic; using CalamityMod.Items.Weapons.Melee; @@ -31,18 +28,11 @@ public override void SetStaticDefaults() public override void SetDefaults() { + Item.DefaultToPlaceableTile(ModContent.TileType()); Item.width = 32; Item.height = 32; - Item.maxStack = 9999; - Item.consumable = true; - Item.rare = ItemRarityID.Green; Item.value = Item.sellPrice(gold: 1); - Item.createTile = ModContent.TileType(); - Item.useTurn = true; - Item.autoReuse = true; - Item.useAnimation = 15; - Item.useTime = 10; - Item.useStyle = ItemUseStyleID.Swing; + Item.rare = ItemRarityID.Green; } public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.ItemGroup itemGroup) @@ -53,51 +43,29 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite public override bool CanRightClick() => true; public override void ModifyItemLoot(ItemLoot itemLoot) { - // The contents of this crate depend massively on progression, so it uses a large number of LeadingConditionRules. - var tier1AbyssAvailable = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedSlimeGod || Main.hardMode); - var tier2AbyssAvailable = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedLeviathan); - var scoriaAvailable = itemLoot.DefineConditionalDropSet(() => NPC.downedGolemBoss); - var tier1AcidRain = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedEoCAcidRain); - var tier2AcidRain = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedAquaticScourgeAcidRain); - var tier3AcidRain = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedPolterghast && DownedBossSystem.downedBoomerDuke); - - // Materials - itemLoot.Add(ModContent.ItemType(), 1, 5, 10); - itemLoot.Add(ModContent.ItemType(), 1, 5, 10); - itemLoot.Add(ModContent.ItemType(), 1, 5, 10); - itemLoot.Add(ModContent.ItemType(), 1, 5, 10); + // 20-50 Blocks @ 100%; Individually 33.33% + itemLoot.Add(new OneFromRulesRule(1, new IItemDropRule[3] + { + ItemDropRule.NotScalingWithLuck(ModContent.ItemType(), 1, 20, 50), + ItemDropRule.NotScalingWithLuck(ModContent.ItemType(), 1, 20, 50), + ItemDropRule.NotScalingWithLuck(ModContent.ItemType(), 1, 20, 50) + })); - tier1AcidRain.Add(ModContent.ItemType(), 10, 1, 3); - tier2AcidRain.Add(ModContent.ItemType(), 10, 1, 3); - tier2AbyssAvailable.Add(ModContent.ItemType(), 5, 2, 5); - tier2AbyssAvailable.Add(ModContent.ItemType(), 5, 2, 5); - tier2AbyssAvailable.Add(ModContent.ItemType(), 5, 2, 5); - scoriaAvailable.Add(ModContent.ItemType(), 5, 16, 28); - scoriaAvailable.Add(ModContent.ItemType(), new Fraction(15, 100), 4, 7); - tier3AcidRain.Add(ModContent.ItemType(), 10, 1, 5); + // Rusty Chest Loot @ 100%; Individually 25% + itemLoot.Add(new OneFromOptionsNotScaledWithLuckDropRule(1, 1, + ModContent.ItemType(), + ModContent.ItemType(), + ModContent.ItemType(), + ModContent.ItemType() + )); // Pre-HM Abyss Weapons - tier1AbyssAvailable.Add(new OneFromOptionsDropRule(10, 1, + itemLoot.Add(new OneFromOptionsDropRule(10, 1, ModContent.ItemType(), ModContent.ItemType(), ModContent.ItemType(), ModContent.ItemType(), - ModContent.ItemType() - )); - - // Post-AS Acid Rain Weapons (and Nuclear Rod) - tier2AcidRain.Add(new OneFromOptionsDropRule(10, 1, - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType() - )); - - // Pre-HM Abyss Equipment (and Torrential Tear) - tier1AbyssAvailable.Add(new OneFromOptionsDropRule(4, 1, + ModContent.ItemType(), ModContent.ItemType(), ModContent.ItemType(), ModContent.ItemType(), @@ -105,18 +73,7 @@ public override void ModifyItemLoot(ItemLoot itemLoot) ModContent.ItemType() )); - // Bait - itemLoot.Add(ItemID.MasterBait, 10, 1, 2); - itemLoot.Add(ItemID.JourneymanBait, 5, 1, 3); - itemLoot.Add(ItemID.ApprenticeBait, 3, 2, 3); - - // Potions - itemLoot.Add(ModContent.ItemType(), 10, 1, 3); - itemLoot.AddCratePotionRules(); - - // Money - itemLoot.Add(ItemID.SilverCoin, 1, 10, 90); - itemLoot.Add(ItemID.GoldCoin, 2, 1, 5); + itemLoot.AddBiomeCrateLootRules(); } } } diff --git a/Items/Fishing/SulphurCatches/SulphurousCrate.cs b/Items/Fishing/SulphurCatches/SulphurousCrate.cs index 98d8b825e3..499fdaa098 100644 --- a/Items/Fishing/SulphurCatches/SulphurousCrate.cs +++ b/Items/Fishing/SulphurCatches/SulphurousCrate.cs @@ -1,19 +1,11 @@ using CalamityMod.Items.Accessories; -using CalamityMod.Items.Materials; -using CalamityMod.Items.Pets; -using CalamityMod.Items.Placeables; -using CalamityMod.Items.Potions; -using CalamityMod.Items.Tools.ClimateChange; -using CalamityMod.Items.Weapons.Magic; -using CalamityMod.Items.Weapons.Melee; -using CalamityMod.Items.Weapons.Ranged; -using CalamityMod.Items.Weapons.Rogue; +using CalamityMod.Items.Placeables.Furniture; using CalamityMod.Items.Weapons.Summon; +using CalamityMod.Tiles.Abyss; using Terraria; using Terraria.GameContent.ItemDropRules; using Terraria.ID; using Terraria.ModLoader; -using CrateTile = CalamityMod.Tiles.Abyss.SulphurousCrateTile; namespace CalamityMod.Items.Fishing.SulphurCatches { @@ -29,18 +21,11 @@ public override void SetStaticDefaults() public override void SetDefaults() { + Item.DefaultToPlaceableTile(ModContent.TileType()); Item.width = 32; Item.height = 32; - Item.maxStack = 9999; - Item.consumable = true; - Item.rare = ItemRarityID.Green; Item.value = Item.sellPrice(gold: 1); - Item.createTile = ModContent.TileType(); - Item.useTurn = true; - Item.autoReuse = true; - Item.useAnimation = 15; - Item.useTime = 10; - Item.useStyle = ItemUseStyleID.Swing; + Item.rare = ItemRarityID.Green; } public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.ItemGroup itemGroup) @@ -51,47 +36,23 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite public override bool CanRightClick() => true; public override void ModifyItemLoot(ItemLoot itemLoot) { - var tier1AbyssAvailable = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedSlimeGod || Main.hardMode); - var tier1AcidRain = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedEoCAcidRain); - - // Materials - itemLoot.Add(ModContent.ItemType(), 1, 5, 10); - itemLoot.Add(ModContent.ItemType(), 1, 5, 10); - itemLoot.Add(ModContent.ItemType(), 1, 5, 10); - itemLoot.Add(ModContent.ItemType(), 1, 5, 10); - - tier1AcidRain.Add(ModContent.ItemType(), 10, 1, 3); - - // Pre-HM Abyss Weapons - tier1AbyssAvailable.Add(new OneFromOptionsDropRule(10, 1, - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType() + // 20-50 Blocks @ 100%; Individually 33.33% + itemLoot.Add(new OneFromRulesRule(1, new IItemDropRule[3] + { + ItemDropRule.NotScalingWithLuck(ModContent.ItemType(), 1, 20, 50), + ItemDropRule.NotScalingWithLuck(ModContent.ItemType(), 1, 20, 50), + ItemDropRule.NotScalingWithLuck(ModContent.ItemType(), 1, 20, 50) + })); + + // Rusty Chest Loot @ 100%; Individually 25% + itemLoot.Add(new OneFromOptionsNotScaledWithLuckDropRule(1, 1, + ModContent.ItemType(), + ModContent.ItemType(), + ModContent.ItemType(), + ModContent.ItemType() )); - // Pre-HM Abyss Equipment (and Torrential Tear) - tier1AbyssAvailable.Add(new OneFromOptionsDropRule(4, 1, - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType() - )); - - // Bait - itemLoot.Add(ItemID.MasterBait, 10, 1, 2); - itemLoot.Add(ItemID.JourneymanBait, 5, 1, 3); - itemLoot.Add(ItemID.ApprenticeBait, 3, 2, 3); - - // Potions - itemLoot.Add(ModContent.ItemType(), 10, 1, 3); - itemLoot.AddCratePotionRules(false); - - // Money - itemLoot.Add(ItemID.SilverCoin, 1, 10, 90); - itemLoot.Add(ItemID.GoldCoin, 2, 1, 5); + itemLoot.AddBiomeCrateLootRules(false); } } } diff --git a/Items/Fishing/SunkenSeaCatches/EutrophicCrate.cs b/Items/Fishing/SunkenSeaCatches/EutrophicCrate.cs index c2c7f48aec..a0752f07ef 100644 --- a/Items/Fishing/SunkenSeaCatches/EutrophicCrate.cs +++ b/Items/Fishing/SunkenSeaCatches/EutrophicCrate.cs @@ -1,10 +1,4 @@ -using CalamityMod.Items.Critters; -using CalamityMod.Items.Materials; -using CalamityMod.Items.Placeables; -using CalamityMod.Items.Weapons.Magic; -using CalamityMod.Items.Weapons.Melee; -using CalamityMod.Items.Weapons.Ranged; -using CalamityMod.Items.Weapons.Summon; +using CalamityMod.Tiles.SunkenSea; using Terraria; using Terraria.GameContent.ItemDropRules; using Terraria.ID; @@ -24,18 +18,11 @@ public override void SetStaticDefaults() public override void SetDefaults() { + Item.DefaultToPlaceableTile(ModContent.TileType()); Item.width = 32; Item.height = 32; - Item.maxStack = 9999; - Item.consumable = true; - Item.rare = ItemRarityID.Green; Item.value = Item.sellPrice(gold: 1); - Item.createTile = ModContent.TileType(); - Item.useTurn = true; - Item.autoReuse = true; - Item.useAnimation = 15; - Item.useTime = 10; - Item.useStyle = ItemUseStyleID.Swing; + Item.rare = ItemRarityID.Green; } public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.ItemGroup itemGroup) @@ -46,26 +33,14 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite public override bool CanRightClick() => true; public override void ModifyItemLoot(ItemLoot itemLoot) { - var postDesertScourge = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedDesertScourge); - - // Materials - itemLoot.Add(ModContent.ItemType(), 1, 10, 30); - itemLoot.Add(ModContent.ItemType(), 1, 10, 30); - postDesertScourge.Add(ModContent.ItemType(), 1, 5, 10); - postDesertScourge.Add(ModContent.ItemType(), 5, 2, 5); - - // Bait - itemLoot.Add(ItemID.MasterBait, 10, 1, 2); - itemLoot.Add(ItemID.JourneymanBait, 5, 1, 3); - itemLoot.Add(ModContent.ItemType(), 5, 1, 3); - itemLoot.Add(ItemID.ApprenticeBait, 3, 2, 3); - - // Potions - itemLoot.AddCratePotionRules(false); - - // Money - itemLoot.Add(ItemID.SilverCoin, 1, 10, 90); - itemLoot.Add(ItemID.GoldCoin, 2, 1, 5); + // 20-50 Blocks @ 100%; Individually 50% + itemLoot.Add(new OneFromRulesRule(1, new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ModContent.ItemType(), 1, 20, 50), + ItemDropRule.NotScalingWithLuck(ModContent.ItemType(), 1, 20, 50) + })); + + itemLoot.AddBiomeCrateLootRules(false); } } } diff --git a/Items/Fishing/SunkenSeaCatches/PrismCrate.cs b/Items/Fishing/SunkenSeaCatches/PrismCrate.cs index ecf064395c..b467105250 100644 --- a/Items/Fishing/SunkenSeaCatches/PrismCrate.cs +++ b/Items/Fishing/SunkenSeaCatches/PrismCrate.cs @@ -6,6 +6,7 @@ using CalamityMod.Items.Weapons.Melee; using CalamityMod.Items.Weapons.Ranged; using CalamityMod.Items.Weapons.Summon; +using CalamityMod.Tiles.SunkenSea; using Terraria; using Terraria.GameContent.ItemDropRules; using Terraria.ID; @@ -26,18 +27,11 @@ public override void SetStaticDefaults() public override void SetDefaults() { + Item.DefaultToPlaceableTile(ModContent.TileType()); Item.width = 32; Item.height = 32; - Item.maxStack = 9999; - Item.consumable = true; - Item.rare = ItemRarityID.Green; Item.value = Item.sellPrice(gold: 1); - Item.createTile = ModContent.TileType(); - Item.useTurn = true; - Item.autoReuse = true; - Item.useAnimation = 15; - Item.useTime = 10; - Item.useStyle = ItemUseStyleID.Swing; + Item.rare = ItemRarityID.Green; } public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.ItemGroup itemGroup) @@ -48,36 +42,14 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite public override bool CanRightClick() => true; public override void ModifyItemLoot(ItemLoot itemLoot) { - var postDesertScourge = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedDesertScourge); - var postHardmodeClam = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedCLAMHardMode); - - // Materials - itemLoot.Add(ModContent.ItemType(), 1, 10, 30); - itemLoot.Add(ModContent.ItemType(), 1, 10, 30); - postDesertScourge.Add(ModContent.ItemType(), 1, 5, 10); - postDesertScourge.Add(ModContent.ItemType(), 5, 2, 5); - postHardmodeClam.Add(ModContent.ItemType(), new Fraction(12, 100), 2, 5); - - // Weapons - postHardmodeClam.Add(new OneFromOptionsNotScaledWithLuckDropRule(7, 100, - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType() - )); - - // Bait - itemLoot.Add(ItemID.MasterBait, 10, 1, 2); - itemLoot.Add(ItemID.JourneymanBait, 5, 1, 3); - itemLoot.Add(ModContent.ItemType(), 5, 1, 3); - itemLoot.Add(ItemID.ApprenticeBait, 3, 2, 3); - - // Potions - itemLoot.AddCratePotionRules(); - - // Money - itemLoot.Add(ItemID.SilverCoin, 1, 10, 90); - itemLoot.Add(ItemID.GoldCoin, 2, 1, 5); + // 20-50 Blocks @ 100%; Individually 50% + itemLoot.Add(new OneFromRulesRule(1, new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ModContent.ItemType(), 1, 20, 50), + ItemDropRule.NotScalingWithLuck(ModContent.ItemType(), 1, 20, 50) + })); + + itemLoot.AddBiomeCrateLootRules(); } } } diff --git a/Items/Placeables/Ores/AuricOre.cs b/Items/Placeables/Ores/AuricOre.cs index b1e3ec05c6..976cef7ade 100644 --- a/Items/Placeables/Ores/AuricOre.cs +++ b/Items/Placeables/Ores/AuricOre.cs @@ -1,4 +1,5 @@ -using CalamityMod.Rarities; +using CalamityMod.Items.Materials; +using CalamityMod.Rarities; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -29,5 +30,13 @@ public override void SetDefaults() Item.value = Item.sellPrice(gold: 4); Item.rare = ModContent.RarityType(); } + + public override void AddRecipes() + { + CreateRecipe(10). + AddIngredient(). + AddCondition(Condition.NearShimmer). + Register(); + } } } diff --git a/Utilities/DropHelper.cs b/Utilities/DropHelper.cs index 0575ad5b0c..b971ec69a5 100644 --- a/Utilities/DropHelper.cs +++ b/Utilities/DropHelper.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using CalamityMod.Enums; using CalamityMod.Items.Accessories; using CalamityMod.Items.Potions; using CalamityMod.NPCs.SulphurousSea; @@ -281,52 +282,320 @@ public static void AddRevBagAccessories(this ILoot loot) loot.Add(lcr); } + public static void AddBiomeCrateLootRules(this ILoot loot, bool hardMode = true) + { + if (hardMode) + loot.AddHardmodeOresToCrates(HardmodeCrateType.Biome); + else + { + // Pre-Hardmode Ore/Bar loot pools + // 20-35 Ores @ 14.29%; Individually 1.79% + IItemDropRule[] phmOres = new IItemDropRule[8] + { + ItemDropRule.NotScalingWithLuck(ItemID.CopperOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.TinOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.IronOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.LeadOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.SilverOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.TungstenOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.GoldOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.PlatinumOre, 1, 20, 35) + }; + loot.Add(new OneFromRulesRule(7, phmOres)); + + // 6-16 Bars @ 25%; Individually 4.17% + IItemDropRule[] phmBars = new IItemDropRule[6] + { + ItemDropRule.NotScalingWithLuck(ItemID.IronBar, 1, 6, 16), + ItemDropRule.NotScalingWithLuck(ItemID.LeadBar, 1, 6, 16), + ItemDropRule.NotScalingWithLuck(ItemID.SilverBar, 1, 6, 16), + ItemDropRule.NotScalingWithLuck(ItemID.TungstenBar, 1, 6, 16), + ItemDropRule.NotScalingWithLuck(ItemID.GoldBar, 1, 6, 16), + ItemDropRule.NotScalingWithLuck(ItemID.PlatinumBar, 1, 6, 16) + }; + loot.Add(new OneFromRulesRule(4, phmBars)); + } + + // 2-4 Buff Potions @ 25%; Individually 4.17% + loot.Add(new OneFromRulesRule(4, new IItemDropRule[6] + { + ItemDropRule.NotScalingWithLuck(ItemID.ObsidianSkinPotion, 1, 2, 4), + ItemDropRule.NotScalingWithLuck(ItemID.SpelunkerPotion, 1, 2, 4), + ItemDropRule.NotScalingWithLuck(ItemID.HunterPotion, 1, 2, 4), + ItemDropRule.NotScalingWithLuck(ItemID.GravitationPotion, 1, 2, 4), + ItemDropRule.NotScalingWithLuck(ItemID.MiningPotion, 1, 2, 4), + ItemDropRule.NotScalingWithLuck(ItemID.HeartreachPotion, 1, 2, 4) + })); + + // 5-17 (Regular) Recovery Potions @ 50%; 25% Healing 25% Mana + loot.Add(new OneFromRulesRule(2, new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ItemID.HealingPotion, 1, 5, 17), + ItemDropRule.NotScalingWithLuck(ItemID.ManaPotion, 1, 5, 17) + })); + + // 2-6 Bait @ 50%; 25% Master 25% Apprentice + loot.Add(new OneFromRulesRule(2, new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ItemID.MasterBait, 1, 2, 6), + ItemDropRule.NotScalingWithLuck(ItemID.ApprenticeBait, 1, 2, 6) + })); + + // 5-12 Gold Coin @ 25% + loot.Add(ItemID.GoldCoin, 4, 5, 12); + } + /// - /// Adds all the common potions for fishing crates, alongside scaling mana and regen potions + /// Adds (or re-adds) Hardmode Ores to crates with respect to Hardmode Progression rework
+ /// Drop rules replicate vanilla's rules. ///
/// The ILoot interface for the loot table. - /// Whether or not the crate is considered a hardmode crate. - public static void AddCratePotionRules(this ILoot loot, bool hardMode = true) + /// Type of crate: Mythril, Titanium, Biome + public static void AddHardmodeOresToCrates(this ILoot loot, HardmodeCrateType type) { - loot.Add(ItemID.ObsidianSkinPotion, 10, 1, 3); - loot.Add(ItemID.SwiftnessPotion, 10, 1, 3); - loot.Add(ItemID.IronskinPotion, 10, 1, 3); - loot.Add(ItemID.NightOwlPotion, 10, 1, 3); - loot.Add(ItemID.ShinePotion, 10, 1, 3); - loot.Add(ItemID.MiningPotion, 10, 1, 3); - loot.Add(ItemID.HeartreachPotion, 10, 1, 3); - loot.Add(ItemID.TrapsightPotion, 10, 1, 3); // Dangersense Potion - - // Define all the loot rules for the potion types - var supremePots = new OneFromOptionsNotScaledWithLuckDropRule(1, 1, ModContent.ItemType(), ModContent.ItemType()); - var superPots = new OneFromOptionsNotScaledWithLuckDropRule(1, 1, ItemID.SuperHealingPotion, ItemID.SuperManaPotion); - var greaterPots = new OneFromOptionsNotScaledWithLuckDropRule(1, 1, ItemID.GreaterHealingPotion, ItemID.GreaterManaPotion); - var regularPots = new OneFromOptionsNotScaledWithLuckDropRule(1, 1, ItemID.HealingPotion, ItemID.ManaPotion); - var lesserPots = new OneFromOptionsNotScaledWithLuckDropRule(1, 1, ItemID.LesserHealingPotion, ItemID.LesserManaPotion); - - // Chained LeadingConditionRules achieve the equivalent of "if killed X, else if killed Y, else if killed Z, else..." - var lcrSupremePotion = loot.DefineConditionalDropSet(() => DownedBossSystem.downedDoG); - var lcrSuperPotion = new LeadingConditionRule(If(() => DownedBossSystem.downedProvidence)); - var lcrGreaterPotion = new LeadingConditionRule(If(() => NPC.downedMechBossAny)); - var lcrRegularPotion = new LeadingConditionRule(If(() => NPC.downedBoss3)); - - // Actually chain all the LCRs together - // Greater potions upwards are only chained if the crate is marked as Hardmode - if (hardMode) + var adamantiteLCR = loot.DefineConditionalDropSet(AdamantiteCondition); + var mythrilLCR = new LeadingConditionRule(MythrilCondition); + + if (type == HardmodeCrateType.Biome) { - lcrSupremePotion.Add(supremePots); - lcrSupremePotion.OnFailedConditions(lcrSuperPotion); - lcrSuperPotion.Add(superPots); - lcrSuperPotion.OnFailedConditions(lcrGreaterPotion); - lcrGreaterPotion.Add(greaterPots); - lcrGreaterPotion.OnFailedConditions(lcrRegularPotion); + // Pre-Hardmode loot pools + // 20-35 Ores @ 7.14%; Individually 0.89% + IItemDropRule[] phmOres = new IItemDropRule[8] + { + ItemDropRule.NotScalingWithLuck(ItemID.CopperOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.TinOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.IronOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.LeadOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.SilverOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.TungstenOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.GoldOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.PlatinumOre, 1, 20, 35) + }; + // 6-16 Bars @ 8.33%; Individually 1.39% + IItemDropRule[] phmBars = new IItemDropRule[6] + { + ItemDropRule.NotScalingWithLuck(ItemID.IronBar, 1, 6, 16), + ItemDropRule.NotScalingWithLuck(ItemID.LeadBar, 1, 6, 16), + ItemDropRule.NotScalingWithLuck(ItemID.SilverBar, 1, 6, 16), + ItemDropRule.NotScalingWithLuck(ItemID.TungstenBar, 1, 6, 16), + ItemDropRule.NotScalingWithLuck(ItemID.GoldBar, 1, 6, 16), + ItemDropRule.NotScalingWithLuck(ItemID.PlatinumBar, 1, 6, 16) + }; + + // Tier 3 loot pools + // 20-35 Ores @ 7.14%; Individually 1.19% + IItemDropRule[] hmOresThree = new IItemDropRule[6] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.MythrilOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.OrichalcumOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.AdamantiteOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.TitaniumOre, 1, 20, 35) + }; + // 5-16 Bars @ 16.67%; Individually 2.78% + IItemDropRule[] hmBarsThree = new IItemDropRule[6] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltBar, 1, 5, 16), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumBar, 1, 5, 16), + ItemDropRule.NotScalingWithLuck(ItemID.MythrilBar, 1, 5, 16), + ItemDropRule.NotScalingWithLuck(ItemID.OrichalcumBar, 1, 5, 16), + ItemDropRule.NotScalingWithLuck(ItemID.AdamantiteBar, 1, 5, 16), + ItemDropRule.NotScalingWithLuck(ItemID.TitaniumBar, 1, 5, 16) + }; + var adamantiteDropsOres = new SequentialRulesNotScalingWithLuckRule(7, new OneFromRulesRule(2, hmOresThree), new OneFromRulesRule(1, phmOres)); + var adamantiteDropsBars = new SequentialRulesNotScalingWithLuckRule(4, new OneFromRulesRule(3, 2, hmBarsThree), new OneFromRulesRule(1, phmBars)); + + // Tier 2 loot pools + // 20-35 Ores @ 7.14%; Individually 1.79% + IItemDropRule[] hmOresTwo = new IItemDropRule[4] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.MythrilOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.OrichalcumOre, 1, 20, 35) + }; + // 5-16 Bars @ 16.67%; Individually 4.17% + IItemDropRule[] hmBarsTwo = new IItemDropRule[4] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltBar, 1, 5, 16), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumBar, 1, 5, 16), + ItemDropRule.NotScalingWithLuck(ItemID.MythrilBar, 1, 5, 16), + ItemDropRule.NotScalingWithLuck(ItemID.OrichalcumBar, 1, 5, 16) + }; + var mythrilDropsOres = new SequentialRulesNotScalingWithLuckRule(7, new OneFromRulesRule(2, hmOresTwo), new OneFromRulesRule(1, phmOres)); + var mythrilDropsBars = new SequentialRulesNotScalingWithLuckRule(4, new OneFromRulesRule(3, 2, hmBarsTwo), new OneFromRulesRule(1, phmBars)); + + // Tier 1 loot pools + // 20-35 Ores @ 7.14%; Individually 3.57% + IItemDropRule[] hmOresOne = new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumOre, 1, 20, 35) + }; + // 5-16 Bars @ 16.67%; Individually 8.33% + IItemDropRule[] hmBarsOne = new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltBar, 1, 5, 16), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumBar, 1, 5, 16) + }; + var cobaltDropsOres = new SequentialRulesNotScalingWithLuckRule(7, new OneFromRulesRule(2, hmOresOne), new OneFromRulesRule(1, phmOres)); + var cobaltDropsBars = new SequentialRulesNotScalingWithLuckRule(4, new OneFromRulesRule(3, 2, hmBarsOne), new OneFromRulesRule(1, phmBars)); + + adamantiteLCR.Add(adamantiteDropsOres); + adamantiteLCR.Add(adamantiteDropsBars); + adamantiteLCR.OnFailedConditions(mythrilLCR); + mythrilLCR.Add(mythrilDropsOres); + mythrilLCR.Add(mythrilDropsBars); + mythrilLCR.OnFailedConditions(cobaltDropsOres); + mythrilLCR.OnFailedConditions(cobaltDropsBars); } - lcrRegularPotion.Add(regularPots); - lcrRegularPotion.OnFailedConditions(lesserPots); - // Add the chain starting from regular potions if marked as a Pre-Hardmode crate - if (!hardMode) + else if (type == HardmodeCrateType.Mythril) { - loot.Add(lcrRegularPotion); + // Pre-Hardmode loot pools + // 12-21 Ores @ 8.33%; Individually 1.39% + IItemDropRule[] phmOres = new IItemDropRule[6] + { + ItemDropRule.NotScalingWithLuck(ItemID.CopperOre, 1, 12, 21), + ItemDropRule.NotScalingWithLuck(ItemID.TinOre, 1, 12, 21), + ItemDropRule.NotScalingWithLuck(ItemID.IronOre, 1, 12, 21), + ItemDropRule.NotScalingWithLuck(ItemID.LeadOre, 1, 12, 21), + ItemDropRule.NotScalingWithLuck(ItemID.SilverOre, 1, 12, 21), + ItemDropRule.NotScalingWithLuck(ItemID.TungstenOre, 1, 12, 21), + }; + // 4-7 Bars @ 6.94%; Individually 1.16% + IItemDropRule[] phmBars = new IItemDropRule[6] + { + ItemDropRule.NotScalingWithLuck(ItemID.CopperBar, 1, 4, 7), + ItemDropRule.NotScalingWithLuck(ItemID.TinBar, 1, 4, 7), + ItemDropRule.NotScalingWithLuck(ItemID.IronBar, 1, 4, 7), + ItemDropRule.NotScalingWithLuck(ItemID.LeadBar, 1, 4, 7), + ItemDropRule.NotScalingWithLuck(ItemID.SilverBar, 1, 4, 7), + ItemDropRule.NotScalingWithLuck(ItemID.TungstenBar, 1, 4, 7), + }; + + // Tier 2 loot pools + // 12-21 Ores @ 8.33%; Individually 2.08% + IItemDropRule[] hmOresTwo = new IItemDropRule[4] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltOre, 1, 12, 21), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumOre, 1, 12, 21), + ItemDropRule.NotScalingWithLuck(ItemID.MythrilOre, 1, 12, 21), + ItemDropRule.NotScalingWithLuck(ItemID.OrichalcumOre, 1, 12, 21) + }; + // 3-7 Bars @ 13.89%; Individually 3.47% + IItemDropRule[] hmBarsTwo = new IItemDropRule[4] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltBar, 1, 3, 7), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumBar, 1, 3, 7), + ItemDropRule.NotScalingWithLuck(ItemID.MythrilBar, 1, 3, 7), + ItemDropRule.NotScalingWithLuck(ItemID.OrichalcumBar, 1, 3, 7) + }; + var mythrilDropsOres = new SequentialRulesNotScalingWithLuckRule(6, new OneFromRulesRule(2, hmOresTwo), new OneFromRulesRule(1, phmOres)); + var mythrilDropsBars = new SequentialRulesNotScalingWithLuckRule(4, new OneFromRulesRule(3, 2, hmBarsTwo), new OneFromRulesRule(1, phmBars)); + var mythrilDrops = new SequentialRulesNotScalingWithLuckRule(1, mythrilDropsOres, mythrilDropsBars); + + // Tier 1 loot pools + // 12-21 Ores @ 8.33%; Individually 4.17% + IItemDropRule[] hmOresOne = new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltOre, 1, 12, 21), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumOre, 1, 12, 21) + }; + // 3-7 Bars @ 13.89%; Individually 6.94% + IItemDropRule[] hmBarsOne = new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltBar, 1, 3, 7), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumBar, 1, 3, 7) + }; + var cobaltDropsOres = new SequentialRulesNotScalingWithLuckRule(6, new OneFromRulesRule(2, hmOresOne), new OneFromRulesRule(1, phmOres)); + var cobaltDropsBars = new SequentialRulesNotScalingWithLuckRule(4, new OneFromRulesRule(3, 2, hmBarsOne), new OneFromRulesRule(1, phmBars)); + var cobaltDrops = new SequentialRulesNotScalingWithLuckRule(1, cobaltDropsOres, cobaltDropsBars); + + mythrilLCR.Add(mythrilDrops); + mythrilLCR.OnFailedConditions(cobaltDrops); + loot.Add(mythrilLCR); // No Adamantite LCR here so we need to add this in + } + else if (type == HardmodeCrateType.Titanium) + { + // Pre-Hardmode loot pools + // 25-34 Ores @ 10%; Individually 2.5% + IItemDropRule[] phmOres = new IItemDropRule[4] + { + ItemDropRule.NotScalingWithLuck(ItemID.SilverOre, 1, 25, 34), + ItemDropRule.NotScalingWithLuck(ItemID.TungstenOre, 1, 25, 34), + ItemDropRule.NotScalingWithLuck(ItemID.GoldOre, 1, 25, 34), + ItemDropRule.NotScalingWithLuck(ItemID.PlatinumOre, 1, 25, 34) + }; + // 8-11 Bars @ 8.89%; Individually 2.22% + IItemDropRule[] phmBars = new IItemDropRule[4] + { + ItemDropRule.NotScalingWithLuck(ItemID.SilverBar, 1, 8, 11), + ItemDropRule.NotScalingWithLuck(ItemID.TungstenBar, 1, 8, 11), + ItemDropRule.NotScalingWithLuck(ItemID.GoldBar, 1, 8, 11), + ItemDropRule.NotScalingWithLuck(ItemID.PlatinumBar, 1, 8, 11) + }; + + // Tier 3 loot pools + // 25-34 Ores @ 10%; Individually 2.5% + IItemDropRule[] hmOresThree = new IItemDropRule[4] + { + ItemDropRule.NotScalingWithLuck(ItemID.MythrilOre, 1, 25, 34), + ItemDropRule.NotScalingWithLuck(ItemID.OrichalcumOre, 1, 25, 34), + ItemDropRule.NotScalingWithLuck(ItemID.AdamantiteOre, 1, 25, 34), + ItemDropRule.NotScalingWithLuck(ItemID.TitaniumOre, 1, 25, 34) + }; + // 8-11 Bars @ 17.78%; Individually 4.44% + IItemDropRule[] hmBarsThree = new IItemDropRule[4] + { + ItemDropRule.NotScalingWithLuck(ItemID.MythrilBar, 1, 8, 11), + ItemDropRule.NotScalingWithLuck(ItemID.OrichalcumBar, 1, 8, 11), + ItemDropRule.NotScalingWithLuck(ItemID.AdamantiteBar, 1, 8, 11), + ItemDropRule.NotScalingWithLuck(ItemID.TitaniumBar, 1, 8, 11) + }; + var adamantiteDropsOres = new SequentialRulesNotScalingWithLuckRule(5, new OneFromRulesRule(2, hmOresThree), new OneFromRulesRule(1, phmOres)); + var adamantiteDropsBars = new SequentialRulesNotScalingWithLuckRule(3, new OneFromRulesRule(3, 2, hmBarsThree), new OneFromRulesRule(1, phmBars)); + var adamantiteDrops = new SequentialRulesNotScalingWithLuckRule(1, adamantiteDropsOres, adamantiteDropsBars); + + // Tier 2 loot pools + // 25-34 Ores @ 10%; Individually 5% + IItemDropRule[] hmOresTwo = new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ItemID.MythrilOre, 1, 25, 34), + ItemDropRule.NotScalingWithLuck(ItemID.OrichalcumOre, 1, 25, 34) + }; + // 8-11 Bars @ 17.78%; Individually 8.89% + IItemDropRule[] hmBarsTwo = new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ItemID.MythrilBar, 1, 8, 11), + ItemDropRule.NotScalingWithLuck(ItemID.OrichalcumBar, 1, 8, 11) + }; + var mythrilDropsOres = new SequentialRulesNotScalingWithLuckRule(5, new OneFromRulesRule(2, hmOresTwo), new OneFromRulesRule(1, phmOres)); + var mythrilDropsBars = new SequentialRulesNotScalingWithLuckRule(3, new OneFromRulesRule(3, 2, hmBarsTwo), new OneFromRulesRule(1, phmBars)); + var mythrilDrops = new SequentialRulesNotScalingWithLuckRule(1, mythrilDropsOres, mythrilDropsBars); + + // Tier 1 loot pools + // EXCEPTION: Titanium Crates do not drop Cobalt. This is added to make it not entirely useless to get early. + // 25-34 Ores @ 10%; Individually 5% + IItemDropRule[] hmOresOne = new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltOre, 1, 25, 34), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumOre, 1, 25, 34) + }; + // 8-11 Bars @ 17.78%; Individually 8.89% + IItemDropRule[] hmBarsOne = new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltBar, 1, 8, 11), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumBar, 1, 8, 11) + }; + var cobaltDropsOres = new SequentialRulesNotScalingWithLuckRule(5, new OneFromRulesRule(2, hmOresOne), new OneFromRulesRule(1, phmOres)); + var cobaltDropsBars = new SequentialRulesNotScalingWithLuckRule(3, new OneFromRulesRule(3, 2, hmBarsOne), new OneFromRulesRule(1, phmBars)); + var cobaltDrops = new SequentialRulesNotScalingWithLuckRule(1, cobaltDropsOres, cobaltDropsBars); + + adamantiteLCR.Add(adamantiteDrops); + adamantiteLCR.OnFailedConditions(mythrilLCR); + mythrilLCR.Add(mythrilDrops); + mythrilLCR.OnFailedConditions(cobaltDrops); } } #endregion @@ -484,6 +753,25 @@ public static IItemDropRuleCondition If(Func lambda, Func #endregion #region Drop Rule Conditions + public static IItemDropRuleCondition MythrilCondition = If((info) => + { + // If the Early Hardmode Progression Rework is not enabled, then Mythril/Orichalcum can always drop. + if (!CalamityServerConfig.Instance.EarlyHardmodeProgressionRework) + return true; + + // If the Early Hardmode Progression Rework is enabled, then any Mechanical Boss must be defeated for Mythril/Orichalcum to drop. + return NPC.downedMechBossAny; + }); + public static IItemDropRuleCondition AdamantiteCondition = If((info) => + { + // If the Early Hardmode Progression Rework is not enabled, then Adamantite/Titanium can always drop. + if (!CalamityServerConfig.Instance.EarlyHardmodeProgressionRework) + return true; + + // If the Early Hardmode Progression Rework is enabled, then 2 of the Mechanical Bosses must be defeated for Adamantite/Titanium to drop. + return (NPC.downedMechBoss1 && NPC.downedMechBoss2) || (NPC.downedMechBoss2 && NPC.downedMechBoss3) || (NPC.downedMechBoss1 && NPC.downedMechBoss3); + }); + public static IItemDropRuleCondition HallowedBarsCondition = If((info) => { // If the Early Hardmode Progression Rework is not enabled, then Hallowed Bars can always drop from Mechanical Bosses. From 7a827492308e63d57a7b85a0094a3033bf8534d0 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Wed, 26 Nov 2025 14:29:39 -0500 Subject: [PATCH 383/401] Correct loot rule --- Items/Fishing/SulphurCatches/HydrothermalCrate.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Items/Fishing/SulphurCatches/HydrothermalCrate.cs b/Items/Fishing/SulphurCatches/HydrothermalCrate.cs index 547da73a7a..929fa06ca1 100644 --- a/Items/Fishing/SulphurCatches/HydrothermalCrate.cs +++ b/Items/Fishing/SulphurCatches/HydrothermalCrate.cs @@ -60,7 +60,7 @@ public override void ModifyItemLoot(ItemLoot itemLoot) )); // Pre-HM Abyss Weapons - itemLoot.Add(new OneFromOptionsDropRule(10, 1, + itemLoot.Add(new OneFromOptionsNotScaledWithLuckDropRule(10, 1, ModContent.ItemType(), ModContent.ItemType(), ModContent.ItemType(), From 7e59c44200c48295acd08bdfd6470309de4e7365 Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Thu, 27 Nov 2025 02:37:26 +0700 Subject: [PATCH 384/401] double correct --- Items/Fishing/SulphurCatches/HydrothermalCrate.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Items/Fishing/SulphurCatches/HydrothermalCrate.cs b/Items/Fishing/SulphurCatches/HydrothermalCrate.cs index 929fa06ca1..a2abfc6b89 100644 --- a/Items/Fishing/SulphurCatches/HydrothermalCrate.cs +++ b/Items/Fishing/SulphurCatches/HydrothermalCrate.cs @@ -60,7 +60,7 @@ public override void ModifyItemLoot(ItemLoot itemLoot) )); // Pre-HM Abyss Weapons - itemLoot.Add(new OneFromOptionsNotScaledWithLuckDropRule(10, 1, + itemLoot.Add(new OneFromOptionsNotScaledWithLuckDropRule(1, 1, ModContent.ItemType(), ModContent.ItemType(), ModContent.ItemType(), From 9513ea5d79a10969ecf7669e56030ad53f715602 Mon Sep 17 00:00:00 2001 From: Altixal <73398287+Altixal@users.noreply.github.com> Date: Thu, 27 Nov 2025 02:38:12 +0700 Subject: [PATCH 385/401] Version 2.0.7 --- build.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.txt b/build.txt index 8af29c4652..f39d15a8a8 100644 --- a/build.txt +++ b/build.txt @@ -1,5 +1,5 @@ author = The Calamity Dev Team -version = 2.0.6.2 +version = 2.0.7 displayName = Calamity Mod modReferences = CalamityModMusic homepage = https://discord.gg/calamity From 68b083b84077da143a9ff18da6e86921f0b504d7 Mon Sep 17 00:00:00 2001 From: CongratsIsTrash <1q2w3e4dasd@gmail.com> Date: Wed, 26 Nov 2025 17:06:10 -0500 Subject: [PATCH 386/401] Fixed VCMM message spam --- CalPlayer/CalamityPlayerMiscEffects.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CalPlayer/CalamityPlayerMiscEffects.cs b/CalPlayer/CalamityPlayerMiscEffects.cs index 2e81c8c5cb..4714b21e2a 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -4155,11 +4155,11 @@ private void HandleTextChatMessages() CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.WikiStatus1"); CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.WikiStatus2"); } - } - if (CalamityClientConfig.Instance.VCMMStatusMessage && !CalamityMod.Instance.VCMMAvailable) - { - CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.VCMMStatus"); + if (CalamityClientConfig.Instance.VCMMStatusMessage && !CalamityMod.Instance.VCMMAvailable) + { + CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.VCMMStatus"); + } } --startMessageDisplayDelay; From 6cf126ce7c6b4bb841fdeac82309f15720101bed Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Wed, 26 Nov 2025 21:18:47 -0500 Subject: [PATCH 387/401] 2.0.7.1 version bump --- build.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.txt b/build.txt index f39d15a8a8..4091c92da8 100644 --- a/build.txt +++ b/build.txt @@ -1,5 +1,5 @@ author = The Calamity Dev Team -version = 2.0.7 +version = 2.0.7.1 displayName = Calamity Mod modReferences = CalamityModMusic homepage = https://discord.gg/calamity From 13abe40eac641a36a40040136012bda2260dee99 Mon Sep 17 00:00:00 2001 From: Flowaria Date: Thu, 27 Nov 2025 14:24:53 +0900 Subject: [PATCH 388/401] Fixed Type Casting Exception on CalamityModWaterStyle --- Systems/CalamityModWaterStyle.cs | 33 +++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/Systems/CalamityModWaterStyle.cs b/Systems/CalamityModWaterStyle.cs index 66c3d6766f..b44c4278f8 100644 --- a/Systems/CalamityModWaterStyle.cs +++ b/Systems/CalamityModWaterStyle.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using Terraria; -using Terraria.Graphics; +using Terraria.Graphics; using Terraria.ModLoader; namespace CalamityMod.Systems @@ -38,20 +34,35 @@ internal static class CalamityWaterLoader { internal static void ModifyLightSetup(int i, int j, int type, ref float r, ref float g, ref float b) { - CalamityModWaterStyle styles = (CalamityModWaterStyle)LoaderManager.Get().Get(type); - if (styles != null) + if (TryGetCalamityWaterStyle(type, out var styles)) { - styles?.ModifyLight(i, j, ref r, ref g, ref b); + styles.ModifyLight(i, j, ref r, ref g, ref b); } } internal static void DrawColorSetup(int x, int y, int type, ref VertexColors liquidColor, bool isSlope = false) { - CalamityModWaterStyle styles = (CalamityModWaterStyle)LoaderManager.Get().Get(type); - if (styles != null) + if (TryGetCalamityWaterStyle(type, out var styles)) { - styles?.DrawColor(x, y, ref liquidColor, isSlope); + styles.DrawColor(x, y, ref liquidColor, isSlope); } } + + internal static bool TryGetCalamityWaterStyle(int type, out CalamityModWaterStyle waterStyle) + { + waterStyle = GetCalamityWaterStyle(type); + return waterStyle != null; + } + + internal static CalamityModWaterStyle GetCalamityWaterStyle(int type) + { + var modWaterStyle = LoaderManager.Get().Get(type); + if (modWaterStyle is CalamityModWaterStyle calWaterStyle) + { + return calWaterStyle; + } + + return null; + } } } From 87035e58ae6ae73a20309d91869b74be56d6ef2c Mon Sep 17 00:00:00 2001 From: Lion8cake Date: Thu, 27 Nov 2025 19:48:21 +1100 Subject: [PATCH 389/401] Fixed IL code for stopping lava retro rendering --- ILEditing/MechanicILChanges.cs | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/ILEditing/MechanicILChanges.cs b/ILEditing/MechanicILChanges.cs index bb5b305649..54b70ebe4b 100644 --- a/ILEditing/MechanicILChanges.cs +++ b/ILEditing/MechanicILChanges.cs @@ -823,10 +823,11 @@ private void RenderLavaBackgrounds(ILContext il) }); } + //Rewrite, reuse biome lava's newer capture code private void DrawLavatoCapture(ILContext il) { ILCursor cursor = new ILCursor(il); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdsfld
("liquidAlpha"), i => i.MatchCall(out _), i => i.MatchStloc2())) + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdsfld
("liquidAlpha"), i => i.MatchCall(out _), i => i.MatchStloc(out _))) { LogFailure("Draw lavas to captures", "Could not locate the saving of water alphas"); return; @@ -895,6 +896,7 @@ private void DrawLavatoCapture(ILContext il) }); } + //Rewrite to prevent ldloc hardcoding private void AddTileLiquidDrawing(ILContext il) { ILCursor cursor = new ILCursor(il); @@ -999,26 +1001,25 @@ private void BlockRetroLightingLava(ILContext il) { ILCursor cursor = new ILCursor(il); ILLabel target = cursor.DefineLabel(); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchCgt(), i => i.MatchLdarg1(), i => i.MatchOr(), i => i.MatchBrfalse(out target))) + int tileXVar = -1; + int tileYVar = -1; + //Gets the Brfalse of the ending of "if (tile[j, i].liquid <= 0 || (tile[j, i].nactive() && tileSolid[tile[j, i].type] && !tileSolidTop[tile[j, i].type]) || !(Lighting.Brightness(j, i) > 0f || bg))", the BR false is used to prevent liquid rendering + //The X and Y from GetColor are also stored to be used in the delegate without hardcoding Ldloc numbers + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchBrfalse(out target), i => i.MatchLdloc(out tileXVar), i => i.MatchLdloc(out tileYVar), i => i.MatchCall("GetColor"), i => i.MatchStloc(out _))) { - LogFailure("old Drawing Waters", "Could not locate the if statement that contains the check for liquid types, amounts and wether the liquid has a bg (arg1) or not"); + LogFailure("old Drawing Waters", "Could not locate the initlisation of the initial color variable and the ending of the if statement preventing liquid rendering"); return; } if (target == null) { - LogFailure("old Drawing Waters", "The BrFalse returned null, the boolean check getting was unsuccessful"); + LogFailure("old Drawing Waters", "The BrFalse returned null, cannot correctly jump to skip the lava rendering"); return; } - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdindU1(), i => i.MatchSub(), i => i.MatchConvR4(), i => i.MatchStloc(14))) + cursor.EmitLdloc(tileXVar); + cursor.EmitLdloc(tileYVar); + cursor.EmitDelegate((int j, int i) => { - LogFailure("old Drawing Waters", "Could not locate the num3 local variable creation to put the if check after"); - return; - } - cursor.EmitLdloc(12); - cursor.EmitLdloc(11); - cursor.EmitDelegate((int i, int j) => - { - return Main.tile[i, j].LiquidType == LiquidID.Lava; + return Main.tile[j, i].LiquidType == LiquidID.Lava; }); cursor.EmitBrtrue(target); } From ce51e8dfc48ba59043f4048f641cca6092a099c7 Mon Sep 17 00:00:00 2001 From: Lion8cake Date: Thu, 27 Nov 2025 20:21:23 +1100 Subject: [PATCH 390/401] Fixed CalamityModWaterStyle crashing the game --- Systems/CalamityModWaterStyle.cs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Systems/CalamityModWaterStyle.cs b/Systems/CalamityModWaterStyle.cs index 66c3d6766f..8c523342fe 100644 --- a/Systems/CalamityModWaterStyle.cs +++ b/Systems/CalamityModWaterStyle.cs @@ -38,19 +38,23 @@ internal static class CalamityWaterLoader { internal static void ModifyLightSetup(int i, int j, int type, ref float r, ref float g, ref float b) { - CalamityModWaterStyle styles = (CalamityModWaterStyle)LoaderManager.Get().Get(type); - if (styles != null) + if (LoaderManager.Get().Get(type) is CalamityModWaterStyle styles) { - styles?.ModifyLight(i, j, ref r, ref g, ref b); + if (styles != null) + { + styles?.ModifyLight(i, j, ref r, ref g, ref b); + } } } internal static void DrawColorSetup(int x, int y, int type, ref VertexColors liquidColor, bool isSlope = false) { - CalamityModWaterStyle styles = (CalamityModWaterStyle)LoaderManager.Get().Get(type); - if (styles != null) + if (LoaderManager.Get().Get(type) is CalamityModWaterStyle styles) { - styles?.DrawColor(x, y, ref liquidColor, isSlope); + if (styles != null) + { + styles?.DrawColor(x, y, ref liquidColor, isSlope); + } } } } From cf3930b0c89833ca4e84a88ac14542121d6ed4a4 Mon Sep 17 00:00:00 2001 From: Lion8cake Date: Thu, 27 Nov 2025 21:55:49 +1100 Subject: [PATCH 391/401] Capture and normal rendering fixes CONTAINS UNSAFE/POINTERS, IF CALAMITY RULES THIS AS A NO-GO, THIS IS WHERE IT WAS INTRODUCED --- CalamityMod.csproj | 1 + ILEditing/MechanicILChanges.cs | 113 +++++++++++++------------------ Systems/CalamityModWaterStyle.cs | 6 +- Systems/LavaRendering.cs | 64 ++++++++++++++--- 4 files changed, 102 insertions(+), 82 deletions(-) diff --git a/CalamityMod.csproj b/CalamityMod.csproj index 06a7b9a67d..644d993a43 100644 --- a/CalamityMod.csproj +++ b/CalamityMod.csproj @@ -6,6 +6,7 @@ net8.0 AnyCPU latest + true diff --git a/ILEditing/MechanicILChanges.cs b/ILEditing/MechanicILChanges.cs index 54b70ebe4b..0caea8e342 100644 --- a/ILEditing/MechanicILChanges.cs +++ b/ILEditing/MechanicILChanges.cs @@ -40,6 +40,7 @@ using Terraria.Localization; using Terraria.ModLoader; using Terraria.UI.Gamepad; +using static Terraria.GameContent.Liquid.LiquidRenderer; namespace CalamityMod.ILEditing { @@ -823,79 +824,87 @@ private void RenderLavaBackgrounds(ILContext il) }); } - //Rewrite, reuse biome lava's newer capture code private void DrawLavatoCapture(ILContext il) { ILCursor cursor = new ILCursor(il); + //Added a new local variable to keep track of the lava alpha so we don't lose which liquid is visually active + VariableDefinition alphaSave_varDef = new(il.Import(typeof(float[]))); + il.Body.Variables.Add(alphaSave_varDef); + + //First the capture saves the initial alpha state of the lavas if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdsfld
("liquidAlpha"), i => i.MatchCall(out _), i => i.MatchStloc(out _))) { LogFailure("Draw lavas to captures", "Could not locate the saving of water alphas"); return; } - cursor.EmitDelegate(() => - { - LavaRendering.alphaSave = CalamityMod.lavaAlpha.ToArray(); + cursor.Emit(OpCodes.Ldloca, alphaSave_varDef); + cursor.EmitDelegate((ref float[] alphaSave) => { + alphaSave = CalamityMod.lavaAlpha.ToArray(); }); - if (!cursor.TryGotoNext(MoveType.Before, i => i.MatchLdcI4(0), i => i.MatchStloc(34), i => i.MatchBr(out _), i => i.MatchLdloc(34), i => i.MatchLdcI4(1), i => i.MatchBeq(out _))) + //Then it resets the alpha to be fully visible + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdcR4(0.0f), i => i.MatchStsfld
(nameof(Main.cloudAlpha)))) { - LogFailure("Draw lavas to captures", "Could not locate the resetting of water alphas"); + LogFailure("Draw lavas to captures", "Could not locate the setting lava alphas"); return; } - cursor.EmitLdloc(8); - cursor.EmitDelegate((CaptureBiome biome) => - { - for (int i = 0; i < 1; i++) + cursor.EmitLdarg(2); + cursor.EmitDelegate((CaptureSettings settings) => { + + for (int i = 0; i < 1; i++) //1 is the amount of vanilla lava styles, can be increased to include additional lava styles { CalamityMod.lavaAlpha[i] = ((i == CalamityMod.LavaStyle) ? 1f : 0f); } }); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg0(), i => i.MatchLdcI4(1), i => i.MatchLdsfld
("waterStyle"), i => i.MatchLdcR4(1), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawLiquid"))) + + //Then lavas are draw twice for backgrounds, and twice again for both the capture biome and the current lava style + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdsfld
("waterStyle"), i => i.MatchLdcR4(1), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawLiquid"))) { LogFailure("Draw lavas to captures", "Could not locate the background of liquid capture drawing"); return; } - cursor.EmitDelegate(() => - { + cursor.EmitDelegate(() => { LavaRendering.instance.DrawLiquid(bg: true, CalamityMod.LavaStyle); }); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg0(), i => i.MatchLdcI4(1), i => i.MatchLdsfld
("bloodMoon"), i => i.MatchBrtrue(out _), i => i.MatchLdloc(8), i => i.MatchLdfld("WaterStyle"), i => i.MatchBr(out _), i => i.MatchLdcI4(9), i => i.MatchLdcR4(1), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawLiquid"))) + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdcI4(9), i => i.MatchLdcR4(1), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawLiquid"))) { - LogFailure("Draw lavas to captures", "Could not locate the second background of liquid capture drawing"); + LogFailure("Draw lavas to captures", "Could not locate the capture biome background of liquid capture drawing"); return; } - cursor.EmitDelegate(() => - { + cursor.EmitLdarg(2); + cursor.EmitDelegate((CaptureSettings settings) => { LavaRendering.instance.DrawLiquid(bg: true, CalamityMod.LavaStyle); }); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg0(), i => i.MatchLdcI4(0), i => i.MatchLdsfld
("waterStyle"), i => i.MatchLdcR4(1), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawLiquid"))) + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdcI4(0), i => i.MatchLdsfld
("waterStyle"), i => i.MatchLdcR4(1), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawLiquid"))) { LogFailure("Draw lavas to captures", "Could not locate the liquid capture drawing"); return; } - cursor.EmitDelegate(() => - { + cursor.EmitDelegate(() => { LavaRendering.instance.DrawLiquid(bg: false, CalamityMod.LavaStyle); }); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg0(), i => i.MatchLdcI4(0), i => i.MatchLdloc(8), i => i.MatchLdfld("WaterStyle"), i => i.MatchLdcR4(1), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawLiquid"))) + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdcI4(0), i => i.MatchLdloc(out _), i => i.MatchLdfld("WaterStyle"), i => i.MatchLdcR4(1), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawLiquid"))) { - LogFailure("Draw lavas to captures", "Could not locate the second liquid capture drawing"); + LogFailure("Draw lavas to captures", "Could not locate the capture biome liquid capture drawing"); return; } - cursor.EmitDelegate(() => - { + cursor.EmitLdarg(2); + cursor.EmitDelegate((CaptureSettings settings) => { LavaRendering.instance.DrawLiquid(bg: false, CalamityMod.LavaStyle); }); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdloc2(), i => i.MatchStsfld
("liquidAlpha"))) + //Finally, the original alpha is returned to the lava alpha + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdloc(out _), i => i.MatchStsfld
("liquidAlpha"))) { - LogFailure("Draw lavas to captures", "Could not locate water style value returner"); + LogFailure("Draw lavas to captures", "Could not locate water style resetter"); return; } - cursor.EmitDelegate(() => - { - CalamityMod.lavaAlpha = LavaRendering.alphaSave; + cursor.Emit(OpCodes.Ldloc, alphaSave_varDef); + cursor.EmitDelegate((float[] alphaSave) => { + CalamityMod.lavaAlpha = alphaSave; }); } + + //Rewrite to prevent ldloc hardcoding private void AddTileLiquidDrawing(ILContext il) { @@ -920,50 +929,20 @@ private void AddTileLiquidDrawing(ILContext il) #region Lava Blocking private void BlockLavaDrawing(ILContext il) { - //This edit to DrawNormalLiquids makes lavas in normal and white lighting draw with an alpha and with new textures - //If the parameter for the waterstyle is more than the max waterstyles then its subtracted by the max water style count and thats the lava style ID + //Currently just prevents lava rendering, to see the new lava renderer, please see LavaRendering.DrawLava ILCursor cursor = new ILCursor(il); - - //Continue if statement, basically - //if the liquid being drawn is lava and the water style is greater than the max water styles or if the liquid is water and less than the max water styles then the draw code is ran - //otherwise the loop/s are continued for the next liquid - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchStloc(4), i => i.MatchBr(out _), i => i.MatchLdloc(2), i => i.MatchLdfld(typeof(LiquidRenderer).GetNestedType("LiquidDrawCache", BindingFlags.Public), "IsVisible"))) - { - LogFailure("Liquid Renderer Drawing", "Could not locate the IsVisible boolean check"); - return; - } - cursor.EmitLdarg3(); - cursor.EmitLdloc2(); //Initiated Liquid Draw Cache (needed for the Type parameter) - cursor.EmitLdfld(typeof(LiquidRenderer).GetNestedType("LiquidDrawCache", BindingFlags.Public).GetRuntimeField("Type")); - cursor.EmitDelegate>((IsVisible, style, type) => IsVisible && ((type == 1 && style >= LavaRendering.instance.WaterStyleMaxCount + 1) || (type != 1 && style <= LavaRendering.instance.WaterStyleMaxCount))); - - //Lava alpha color, if the liquid drawn is lava, multiply num by the water alpha - if (!cursor.TryGotoNext(MoveType.Before, i => i.MatchLdloc(2), i => i.MatchLdfld(typeof(LiquidRenderer).GetNestedType("LiquidDrawCache", BindingFlags.Public).GetRuntimeField("Type")), i => i.MatchStloc(8))) + int pointer2_varNum = -1; + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdloc(out pointer2_varNum), i => i.MatchLdfld("IsVisible"))) { - LogFailure("Liquid Renderer Drawing", "Could not locate creation of the local variable num2 (the liquid type holder variable)"); + LogFailure("Block Lava Drawing", "Could not locate the visibility check for liquid drawing"); return; } - cursor.EmitLdloc(8); - cursor.EmitLdloca(7); - cursor.EmitLdarg(4); - cursor.EmitDelegate((int num2, ref float num, float globalAlpha) => + cursor.EmitLdloc(pointer2_varNum); + cursor.EmitLdfld(typeof(LiquidDrawCache).GetField("Type")); + cursor.EmitDelegate((bool isVisibleCondition, byte type) => { - if (num2 == LiquidID.Lava) - { - num *= globalAlpha; - } + return isVisibleCondition && type != LiquidID.Lava; }); - - //Conditionally replace the liquid texture whether the liquid is lava or water - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchCallvirt(typeof(Asset).GetMethod("get_Value", BindingFlags.Public | BindingFlags.Instance)))) - { - LogFailure("Liquid Renderer Drawing", "Could not locate the Texture2D array of liquids"); - return; - } - cursor.EmitLdarg3(); - cursor.EmitLdloc2(); //Initiated Liquid Draw Cache (needed for the Type parameter) - cursor.EmitLdfld(typeof(LiquidRenderer).GetNestedType("LiquidDrawCache", BindingFlags.Public).GetRuntimeField("Type")); - cursor.EmitDelegate>((initialTexture, style, type) => (style >= LavaRendering.instance.WaterStyleMaxCount + 1 && type == LiquidID.Lava) ? CalamityMod.LavaTextures.liquid[style - LavaRendering.instance.WaterStyleMaxCount - 1].Value : initialTexture); } private void BlockLavaDrawingForSlopes(On_TileDrawing.orig_DrawTile_LiquidBehindTile orig, TileDrawing self, bool solidLayer, bool inFrontOfPlayers, int waterStyleOverride, Vector2 screenPosition, Vector2 screenOffset, int tileX, int tileY, Tile tileCache) diff --git a/Systems/CalamityModWaterStyle.cs b/Systems/CalamityModWaterStyle.cs index 8c523342fe..bd471ddbd1 100644 --- a/Systems/CalamityModWaterStyle.cs +++ b/Systems/CalamityModWaterStyle.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using Terraria; -using Terraria.Graphics; +using Terraria.Graphics; using Terraria.ModLoader; namespace CalamityMod.Systems diff --git a/Systems/LavaRendering.cs b/Systems/LavaRendering.cs index 8dc526e169..6298151daf 100644 --- a/Systems/LavaRendering.cs +++ b/Systems/LavaRendering.cs @@ -12,6 +12,7 @@ using Terraria.Graphics; using Terraria.ID; using Terraria.ModLoader; +using static Terraria.GameContent.Liquid.LiquidRenderer; using static Terraria.WaterfallManager; namespace CalamityMod.Systems @@ -21,14 +22,9 @@ public class LavaRendering : ModSystem //Welcome to Calamity's lava rendering. Prepare your eyes public static LavaRendering instance; - public int WaterStyleMaxCount = ModContent.GetContent().Count() + LoaderManager.Get().VanillaCount; - - internal static float[] alphaSave; - - public override void Load() - { - LavaRendering.alphaSave = new float[CalamityMod.lavaAlpha.Length]; - } + internal static readonly FieldInfo _drawArea = typeof(LiquidRenderer).GetField("_drawArea", BindingFlags.NonPublic | BindingFlags.Instance); + internal static readonly FieldInfo _drawCache = typeof(LiquidRenderer).GetField("_drawCache", BindingFlags.NonPublic | BindingFlags.Instance); + internal static readonly FieldInfo _animationFrame = typeof(LiquidRenderer).GetField("_animationFrame", BindingFlags.NonPublic | BindingFlags.Instance); public void DrawLavas(bool isBackground = false) { @@ -62,6 +58,7 @@ public void DrawLavas(bool isBackground = false) DrawLiquid(isBackground, CalamityMod.LavaStyle, flag ? CalamityMod.lavaAlpha[CalamityMod.LavaStyle] : 1f); } + protected internal void DrawLiquid(bool bg = false, int lavaStyle = 0, float Alpha = 1f, bool drawSinglePassLiquids = true) { if (!Lighting.NotRetro) @@ -72,17 +69,64 @@ protected internal void DrawLiquid(bool bg = false, int lavaStyle = 0, float Alp Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Vector2 drawOffset = (Vector2)(Main.drawToScreen ? Vector2.Zero : new Vector2((float)Main.offScreenRange, (float)Main.offScreenRange)) - Main.screenPosition; - if (bg) + if (bg && !LiquidEdgeRenderer.Active) { DrawLiquidBehindTiles(lavaStyle); } - LiquidRenderer.Instance.DrawNormalLiquids(Main.spriteBatch, drawOffset, lavaStyle + ModContent.GetContent().Count() + LoaderManager.Get().VanillaCount + 1, Alpha, bg); + DrawLava(Main.spriteBatch, drawOffset, lavaStyle, Alpha, bg); if (!bg) { TimeLogger.DrawTime(4, stopwatch.Elapsed.TotalMilliseconds); } } + public unsafe void DrawLava(SpriteBatch spriteBatch, Vector2 drawOffset, int LavaStyle, float globalAlpha, bool isBackgroundDraw) + { + Rectangle drawArea = (Rectangle)_drawArea.GetValue(Instance); + Main.tileBatch.Begin(); + fixed (LiquidDrawCache* ptr3 = &((LiquidDrawCache[])_drawCache.GetValue(Instance))[0]) + { + LiquidDrawCache* ptr2 = ptr3; + int cacheLength = ((LiquidDrawCache[])_drawCache.GetValue(Instance)).Length; + for (int i = drawArea.X; i < drawArea.X + drawArea.Width; i++) + { + for (int j = drawArea.Y; j < drawArea.Y + drawArea.Height; j++) + { + if (ptr2->IsVisible && ptr2->Type == LiquidID.Lava) + { + Rectangle sourceRectangle = ptr2->SourceRectangle; + if (ptr2->IsSurfaceLiquid) + { + sourceRectangle.Y = 1280; + } + else + { + sourceRectangle.Y += ((int)_animationFrame.GetValue(Instance)) * 80; + } + Vector2 liquidOffset = ptr2->LiquidOffset; + float num = ptr2->Opacity * (isBackgroundDraw ? 1f : DEFAULT_OPACITY[ptr2->Type]); + int num2 = LavaStyle; + num *= globalAlpha; + num = Math.Min(1f, num); + Lighting.GetCornerColors(i, j, out var vertices); + ref Color bottomLeftColor = ref vertices.BottomLeftColor; + bottomLeftColor *= num; + ref Color bottomRightColor = ref vertices.BottomRightColor; + bottomRightColor *= num; + ref Color topLeftColor = ref vertices.TopLeftColor; + topLeftColor *= num; + ref Color topRightColor = ref vertices.TopRightColor; + topRightColor *= num; + Main.DrawTileInWater(drawOffset, i, j); + Main.tileBatch.Draw(CalamityMod.LavaTextures.liquid[num2].Value, new Vector2((float)(i << 4), (float)(j << 4)) + drawOffset + liquidOffset, sourceRectangle, vertices, Vector2.Zero, 1f, (SpriteEffects)0); + } + ptr2++; + } + } + } + Main.tileBatch.End(); + } + public void oldDrawLava(bool bg = false, int Style = 0, float Alpha = 1f) { float num = 0f; From 62375b430832aebec8c9bba2496f42bcacb6cfcb Mon Sep 17 00:00:00 2001 From: Lion8cake Date: Thu, 27 Nov 2025 22:22:20 +1100 Subject: [PATCH 392/401] Fixed Lavafall Coloring to not be overly bright for 0 reason --- ILEditing/MechanicILChanges.cs | 11 +++-------- Systems/LavaRendering.cs | 2 +- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/ILEditing/MechanicILChanges.cs b/ILEditing/MechanicILChanges.cs index 0caea8e342..997328a9c6 100644 --- a/ILEditing/MechanicILChanges.cs +++ b/ILEditing/MechanicILChanges.cs @@ -1171,19 +1171,13 @@ private void LavafallLightEditor(On_WaterfallManager.orig_AddLight orig, int wat float g = 0.33f; float b = 0.11f; LavaStylesLoader.ModifyLightSetup(x, y, CalamityMod.LavaStyle, ref r, ref g, ref b); - if (!(r == 0 && g == 0 && b == 0)) - { - float r8; - float num3 = (r8 = (r + (float)(270 - Main.mouseTextColor) / 900f) * 0.4f); - float g8 = num3 * g; - float b8 = num3 * b; - Lighting.AddLight(x, y, r8, g8, b8); - } + Lighting.AddLight(x, y, r, g, b); return; } orig.Invoke(waterfallType, x, y); } + //update ldlocs to be dynamic private static void LiquidDrawColors(ILContext il) { const string TypeFieldName = nameof(LiquidRenderer.LiquidDrawCache.Type); @@ -1214,6 +1208,7 @@ private static void LiquidDrawColors(ILContext il) }); } + //same as above private static void LiquidSlopeDrawColors(ILContext il) { ILCursor cursor = new ILCursor(il); diff --git a/Systems/LavaRendering.cs b/Systems/LavaRendering.cs index 6298151daf..6366a07047 100644 --- a/Systems/LavaRendering.cs +++ b/Systems/LavaRendering.cs @@ -1162,7 +1162,7 @@ internal void DrawLavafall(WaterfallManager waterfallManager, int Style = 0, flo private void DrawLavafall(int waterfallType, int x, int y, float opacity, Vector2 position, Rectangle sourceRect, Color color, SpriteEffects effects) { Texture2D value = CalamityMod.LavaTextures.fall[waterfallType].Value; - Main.spriteBatch.Draw(value, position, (Rectangle?)sourceRect, color, 0f, default(Vector2), 1f, effects, 0f); + Main.spriteBatch.Draw(value, position, (Rectangle?)sourceRect, Lighting.GetColor(x, y) * opacity, 0f, default(Vector2), 1f, effects, 0f); } private static float GetLavafallAlpha(float Alpha, int maxSteps, int y, int s, Tile tileCache) From 1baa63fdd294926d7fdc552c4ce7c0fc8c692ebc Mon Sep 17 00:00:00 2001 From: Lion8cake Date: Thu, 27 Nov 2025 22:38:32 +1100 Subject: [PATCH 393/401] Fixed Lava droplets being super bright for no reason --- Gores/WaterDroplet/LiquidDropletGore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gores/WaterDroplet/LiquidDropletGore.cs b/Gores/WaterDroplet/LiquidDropletGore.cs index f99d0b6c4b..cf7064f1ec 100644 --- a/Gores/WaterDroplet/LiquidDropletGore.cs +++ b/Gores/WaterDroplet/LiquidDropletGore.cs @@ -193,7 +193,7 @@ public override bool Update(Gore gore) { if (lavaDroplet) { - return new Color(255, 255, 255, 200); + return Lighting.GetColor((int)(gore.position.X / 16), (int)(gore.position.Y / 16)) * 1f; } return null; } From 71dbc6c6f12a7930fbf97be9dc666151184e4fae Mon Sep 17 00:00:00 2001 From: Lion8cake Date: Thu, 27 Nov 2025 23:59:30 +1100 Subject: [PATCH 394/401] Future proofed some IL edits --- ILEditing/MechanicILChanges.cs | 115 ++++++++++++++++++++------------- 1 file changed, 71 insertions(+), 44 deletions(-) diff --git a/ILEditing/MechanicILChanges.cs b/ILEditing/MechanicILChanges.cs index 997328a9c6..7955635419 100644 --- a/ILEditing/MechanicILChanges.cs +++ b/ILEditing/MechanicILChanges.cs @@ -776,7 +776,7 @@ private static void DrawForegroundParticles(Terraria.On_Main.orig_DrawInfernoRin private void DoDrawLavas(ILContext il) { ILCursor cursor = new ILCursor(il); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdsfld
("drawToScreen"), i => i.MatchBrfalse(out _), i => i.MatchLdarg0(), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawWaters"))) + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdsfld
("drawToScreen"), c => c.MatchBrfalse(out _), c => c.MatchLdarg0(), c => c.MatchLdcI4(1), c => c.MatchCall
("DrawWaters"))) { LogFailure("DoDraw Lava", "Could not locate the drawing of Background Waters"); return; @@ -785,7 +785,7 @@ private void DoDrawLavas(ILContext il) { LavaRendering.instance.DrawLavas(isBackground: true); }); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdsfld
("drawToScreen"), i => i.MatchBrfalse(out _), i => i.MatchLdarg0(), i => i.MatchLdcI4(0), i => i.MatchCall
("DrawWaters"))) + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdsfld
("drawToScreen"), c => c.MatchBrfalse(out _), c => c.MatchLdarg0(), c => c.MatchLdcI4(0), c => c.MatchCall
("DrawWaters"))) { LogFailure("DoDraw Lava", "Could not locate the drawing of Waters"); return; @@ -799,7 +799,7 @@ private void DoDrawLavas(ILContext il) private void RenderLavas(ILContext il) { ILCursor cursor = new ILCursor(il); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg0(), i => i.MatchLdcI4(0), i => i.MatchCall
("DrawWaters"))) + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdarg0(), c => c.MatchLdcI4(0), c => c.MatchCall
("DrawWaters"))) { LogFailure("Render Lava", "Could not locate the drawing of Waters"); return; @@ -813,7 +813,7 @@ private void RenderLavas(ILContext il) private void RenderLavaBackgrounds(ILContext il) { ILCursor cursor = new ILCursor(il); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg0(), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawWaters"))) + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdarg0(), c => c.MatchLdcI4(1), c => c.MatchCall
("DrawWaters"))) { LogFailure("Render Lava Backgroumds", "Could not locate the drawing of Background Waters"); return; @@ -828,21 +828,21 @@ private void DrawLavatoCapture(ILContext il) { ILCursor cursor = new ILCursor(il); //Added a new local variable to keep track of the lava alpha so we don't lose which liquid is visually active - VariableDefinition alphaSave_varDef = new(il.Import(typeof(float[]))); - il.Body.Variables.Add(alphaSave_varDef); + VariableDefinition alphaSaveVar = new(il.Import(typeof(float[]))); + il.Body.Variables.Add(alphaSaveVar); //First the capture saves the initial alpha state of the lavas - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdsfld
("liquidAlpha"), i => i.MatchCall(out _), i => i.MatchStloc(out _))) + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdsfld
("liquidAlpha"), c => c.MatchCall(out _), c => c.MatchStloc(out _))) { LogFailure("Draw lavas to captures", "Could not locate the saving of water alphas"); return; } - cursor.Emit(OpCodes.Ldloca, alphaSave_varDef); + cursor.Emit(OpCodes.Ldloca, alphaSaveVar); cursor.EmitDelegate((ref float[] alphaSave) => { alphaSave = CalamityMod.lavaAlpha.ToArray(); }); //Then it resets the alpha to be fully visible - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdcR4(0.0f), i => i.MatchStsfld
(nameof(Main.cloudAlpha)))) + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdcR4(0.0f), c => c.MatchStsfld
(nameof(Main.cloudAlpha)))) { LogFailure("Draw lavas to captures", "Could not locate the setting lava alphas"); return; @@ -857,7 +857,7 @@ private void DrawLavatoCapture(ILContext il) }); //Then lavas are draw twice for backgrounds, and twice again for both the capture biome and the current lava style - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdsfld
("waterStyle"), i => i.MatchLdcR4(1), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawLiquid"))) + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdsfld
("waterStyle"), c => c.MatchLdcR4(1), c => c.MatchLdcI4(1), c => c.MatchCall
("DrawLiquid"))) { LogFailure("Draw lavas to captures", "Could not locate the background of liquid capture drawing"); return; @@ -865,7 +865,7 @@ private void DrawLavatoCapture(ILContext il) cursor.EmitDelegate(() => { LavaRendering.instance.DrawLiquid(bg: true, CalamityMod.LavaStyle); }); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdcI4(9), i => i.MatchLdcR4(1), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawLiquid"))) + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdcI4(9), c => c.MatchLdcR4(1), c => c.MatchLdcI4(1), c => c.MatchCall
("DrawLiquid"))) { LogFailure("Draw lavas to captures", "Could not locate the capture biome background of liquid capture drawing"); return; @@ -874,7 +874,7 @@ private void DrawLavatoCapture(ILContext il) cursor.EmitDelegate((CaptureSettings settings) => { LavaRendering.instance.DrawLiquid(bg: true, CalamityMod.LavaStyle); }); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdcI4(0), i => i.MatchLdsfld
("waterStyle"), i => i.MatchLdcR4(1), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawLiquid"))) + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdcI4(0), c => c.MatchLdsfld
("waterStyle"), c => c.MatchLdcR4(1), c => c.MatchLdcI4(1), c => c.MatchCall
("DrawLiquid"))) { LogFailure("Draw lavas to captures", "Could not locate the liquid capture drawing"); return; @@ -882,7 +882,7 @@ private void DrawLavatoCapture(ILContext il) cursor.EmitDelegate(() => { LavaRendering.instance.DrawLiquid(bg: false, CalamityMod.LavaStyle); }); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdcI4(0), i => i.MatchLdloc(out _), i => i.MatchLdfld("WaterStyle"), i => i.MatchLdcR4(1), i => i.MatchLdcI4(1), i => i.MatchCall
("DrawLiquid"))) + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdcI4(0), c => c.MatchLdloc(out _), c => c.MatchLdfld("WaterStyle"), c => c.MatchLdcR4(1), c => c.MatchLdcI4(1), c => c.MatchCall
("DrawLiquid"))) { LogFailure("Draw lavas to captures", "Could not locate the capture biome liquid capture drawing"); return; @@ -892,36 +892,39 @@ private void DrawLavatoCapture(ILContext il) LavaRendering.instance.DrawLiquid(bg: false, CalamityMod.LavaStyle); }); //Finally, the original alpha is returned to the lava alpha - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdloc(out _), i => i.MatchStsfld
("liquidAlpha"))) + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdloc(out _), c => c.MatchStsfld
("liquidAlpha"))) { LogFailure("Draw lavas to captures", "Could not locate water style resetter"); return; } - cursor.Emit(OpCodes.Ldloc, alphaSave_varDef); + cursor.Emit(OpCodes.Ldloc, alphaSaveVar); cursor.EmitDelegate((float[] alphaSave) => { CalamityMod.lavaAlpha = alphaSave; }); } - - - //Rewrite to prevent ldloc hardcoding private void AddTileLiquidDrawing(ILContext il) { ILCursor cursor = new ILCursor(il); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg0(), i => i.MatchLdarg1(), i => i.MatchLdcI4(0), i => i.MatchLdarg(out _), i => i.MatchLdloc1(), i => i.MatchLdloc2(), i => i.MatchLdloc(13), i => i.MatchLdloc(14), i => i.MatchLdloc(15), i => i.MatchCall("DrawTile_LiquidBehindTile"))) + int unscaledPosVar = -1; + int zeroVar = -1; + int tileXVar = -1; + int tileYVar = -1; + int tileVar = -1; + + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdarg0(), c => c.MatchLdarg1(), c => c.MatchLdcI4(0), c => c.MatchLdarg(4), c => c.MatchLdloc(out unscaledPosVar), c => c.MatchLdloc(out zeroVar), c => c.MatchLdloc(out tileXVar), c => c.MatchLdloc(out tileYVar), c => c.MatchLdloc(out tileVar), c => c.MatchCall("DrawTile_LiquidBehindTile"))) { LogFailure("Tile Lava Drawing", "Could not locate the drawing of Liquid Behind Tile drawing"); return; } - cursor.EmitLdloc1(); - cursor.EmitLdloc2(); - cursor.EmitLdloc(13); - cursor.EmitLdloc(14); - cursor.EmitLdloc(15); - cursor.EmitDelegate((Microsoft.Xna.Framework.Vector2 unscaledPosition, Microsoft.Xna.Framework.Vector2 vector, int j, int i, Terraria.Tile tile) => + cursor.EmitLdloc(unscaledPosVar); + cursor.EmitLdloc(zeroVar); + cursor.EmitLdloc(tileXVar); + cursor.EmitLdloc(tileYVar); + cursor.EmitLdloc(tileVar); + cursor.EmitDelegate((Vector2 unscaledPosition, Vector2 vector, int i, int j, Tile tile) => { - LavaRendering.instance.DrawTile_LiquidBehindTile(solidLayer: false, inFrontOfPlayers: false, -1, unscaledPosition, vector, j, i, tile); + LavaRendering.instance.DrawTile_LiquidBehindTile(solidLayer: false, inFrontOfPlayers: false, -1, unscaledPosition, vector, i, j, tile); }); } #endregion @@ -932,7 +935,7 @@ private void BlockLavaDrawing(ILContext il) //Currently just prevents lava rendering, to see the new lava renderer, please see LavaRendering.DrawLava ILCursor cursor = new ILCursor(il); int pointer2_varNum = -1; - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdloc(out pointer2_varNum), i => i.MatchLdfld("IsVisible"))) + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdloc(out pointer2_varNum), c => c.MatchLdfld("IsVisible"))) { LogFailure("Block Lava Drawing", "Could not locate the visibility check for liquid drawing"); return; @@ -984,7 +987,7 @@ private void BlockRetroLightingLava(ILContext il) int tileYVar = -1; //Gets the Brfalse of the ending of "if (tile[j, i].liquid <= 0 || (tile[j, i].nactive() && tileSolid[tile[j, i].type] && !tileSolidTop[tile[j, i].type]) || !(Lighting.Brightness(j, i) > 0f || bg))", the BR false is used to prevent liquid rendering //The X and Y from GetColor are also stored to be used in the delegate without hardcoding Ldloc numbers - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchBrfalse(out target), i => i.MatchLdloc(out tileXVar), i => i.MatchLdloc(out tileYVar), i => i.MatchCall("GetColor"), i => i.MatchStloc(out _))) + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchBrfalse(out target), c => c.MatchLdloc(out tileXVar), c => c.MatchLdloc(out tileYVar), c => c.MatchCall("GetColor"), c => c.MatchStloc(out _))) { LogFailure("old Drawing Waters", "Could not locate the initlisation of the initial color variable and the ending of the if statement preventing liquid rendering"); return; @@ -1008,13 +1011,13 @@ private void BlockRetroLightingLava(ILContext il) private void LavaBubbleReplacer(ILContext il) { ILCursor cursor = new ILCursor(il); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdcI4(16), i => i.MatchLdcI4(16), i => i.MatchLdcI4(35))) + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdcI4(16), c => c.MatchLdcI4(16), c => c.MatchLdcI4(35))) { LogFailure("Ambient lava bubble replacer", "Could not locate the bubble newdust parameters"); return; } cursor.EmitDelegate>(type => LavaRendering.dustLava()); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdcI4(16), i => i.MatchLdcI4(8), i => i.MatchLdcI4(35))) + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdcI4(16), c => c.MatchLdcI4(8), c => c.MatchLdcI4(35))) { LogFailure("Ambient lava bubble replacer", "Could not locate the surface bubble newdust parameters"); return; @@ -1025,7 +1028,7 @@ private void LavaBubbleReplacer(ILContext il) private void LavaDropletReplacer(ILContext il) { ILCursor cursor = new ILCursor(il); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdarg(out _), i => i.MatchLdcI4(374), i => i.MatchBneUn(out _), i => i.MatchLdcI4(716))) + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdarg(out _), c => c.MatchLdcI4(374), c => c.MatchBneUn(out _), c => c.MatchLdcI4(716))) { LogFailure("Ambient lava droplet replacer", "Could not locate the lava droplet newgore parameters"); return; @@ -1036,13 +1039,13 @@ private void LavaDropletReplacer(ILContext il) private void SplashEntityLava(ILContext il) { ILCursor cursor = new ILCursor(il); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdfld("width"), i => i.MatchLdcI4(12), i => i.MatchAdd(), i => i.MatchLdcI4(24), i => i.MatchLdcI4(35))) + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdfld("width"), c => c.MatchLdcI4(12), c => c.MatchAdd(), c => c.MatchLdcI4(24), c => c.MatchLdcI4(35))) { LogFailure("Entity Lava Splashing (Item, Projectile, NPC, Player)", "Could not locate the first lava bubble splashing"); return; } cursor.EmitDelegate>(type => LavaRendering.dustLava()); - if (!cursor.TryGotoNext(MoveType.After, i => i.MatchLdfld("width"), i => i.MatchLdcI4(12), i => i.MatchAdd(), i => i.MatchLdcI4(24), i => i.MatchLdcI4(35))) + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdfld("width"), c => c.MatchLdcI4(12), c => c.MatchAdd(), c => c.MatchLdcI4(24), c => c.MatchLdcI4(35))) { LogFailure("Entity Lava Splashing (Item, Projectile, NPC, Player)", "Could not locate the second lava bubble splashing"); return; @@ -1054,7 +1057,7 @@ private void PlayerDebuffEdit(ILContext il) { //Injects code directly at the position where the OnFire debuff is handled ILCursor cursor = new ILCursor(il); - if (!cursor.TryGotoNext(MoveType.Before, i => i.MatchLdarg0(), i => i.MatchLdcI4(24), i => i.MatchLdloc(161), i => i.MatchLdcI4(1), i => i.MatchLdcI4(0), i => i.MatchCall("AddBuff"))) + if (!cursor.TryGotoNext(MoveType.Before, c => c.MatchLdarg0(), c => c.MatchLdcI4(24), c => c.MatchLdloc(161), c => c.MatchLdcI4(1), c => c.MatchLdcI4(0), c => c.MatchCall("AddBuff"))) { LogFailure("Player Update Lava Debuff", "Could not locate the infliction of the On Fire! debuff inside the Player Update code"); return; @@ -1177,23 +1180,38 @@ private void LavafallLightEditor(On_WaterfallManager.orig_AddLight orig, int wat orig.Invoke(waterfallType, x, y); } - //update ldlocs to be dynamic private static void LiquidDrawColors(ILContext il) { const string TypeFieldName = nameof(LiquidRenderer.LiquidDrawCache.Type); ILCursor cursor = new ILCursor(il); - if (!cursor.TryGotoNext(MoveType.Before, c => c.MatchLdarg2(), c => c.MatchLdloc(3), c => c.MatchLdloc(4), c => c.MatchCall
("DrawTileInWater"))) + int tileXVar = -1; + int tileYVar = -1; + int pointerVar = -1; + int verticesVar = -1; + + if (!cursor.TryGotoNext(c => c.MatchLdloc(out _), c => c.MatchConvU(), c => c.MatchStloc(out pointerVar))) + { + LogFailure("Liquid Draw Colors", "Could not locate the liquid pointer local variable"); + return; + } + if (!cursor.TryGotoNext(c => c.MatchLdloca(out verticesVar), c => c.MatchLdcR4(1), c => c.MatchCall("GetCornerColors"))) + { + LogFailure("Liquid Draw Colors", "Could not locate the vertices local variable"); + return; + } + + if (!cursor.TryGotoNext(MoveType.Before, c => c.MatchLdarg2(), c => c.MatchLdloc(out tileXVar), c => c.MatchLdloc(out tileYVar), c => c.MatchCall
("DrawTileInWater"))) { LogFailure("Liquid Draw Colors", "Could not locate the liquid vertex colors for drawing"); return; } - cursor.Emit(OpCodes.Ldloc, 3); - cursor.Emit(OpCodes.Ldloc, 4); - cursor.Emit(OpCodes.Ldloc_2); + cursor.Emit(OpCodes.Ldloc, tileXVar); + cursor.Emit(OpCodes.Ldloc, tileYVar); + cursor.Emit(OpCodes.Ldloc, pointerVar); cursor.EmitLdfld(typeof(LiquidRenderer.LiquidDrawCache).GetField(TypeFieldName)); - cursor.Emit(OpCodes.Ldloca, 9); + cursor.Emit(OpCodes.Ldloca, verticesVar); cursor.EmitDelegate((int x, int y, byte liquidType, ref VertexColors initialColor) => { @@ -1212,8 +1230,17 @@ private static void LiquidDrawColors(ILContext il) private static void LiquidSlopeDrawColors(ILContext il) { ILCursor cursor = new ILCursor(il); + int vertexColorsVar = -1; + int isWaterVar = -1; + int waterStyleVar = -1; + + if (!cursor.TryGotoNext(c => c.MatchLdsfld
("waterStyle"), c => c.MatchStloc(out waterStyleVar), c => c.MatchLdarg(6), c => c.MatchLdarg(7), c => c.MatchLdloca(out vertexColorsVar), c => c.MatchLdcR4(1), c => c.MatchCall("GetCornerColors"))) + { + LogFailure("Liquid Slope Draw Colors", "Could not locate the liquid slope vertex colors for drawing"); + return; + } - if (!cursor.TryGotoNext(MoveType.Before, c => c.MatchLdcI4(0), c => c.MatchStloc(19), c => c.MatchLdloc(11), c => c.MatchBrfalse(out _))) + if (!cursor.TryGotoNext(MoveType.Before, c => c.MatchLdcI4(0), c => c.MatchStloc(out _), c => c.MatchLdloc(out isWaterVar), c => c.MatchBrfalse(out _), c => c.MatchCall(out _), c => c.MatchCallvirt("get_TotalCount"))) { LogFailure("Liquid Slope Draw Colors", "Could not locate the liquid slope vertex colors for drawing"); return; @@ -1221,9 +1248,9 @@ private static void LiquidSlopeDrawColors(ILContext il) cursor.Emit(OpCodes.Ldarg, 6); cursor.Emit(OpCodes.Ldarg, 7); - cursor.Emit(OpCodes.Ldloca, 14); - cursor.Emit(OpCodes.Ldloc, 11); - cursor.Emit(OpCodes.Ldloc, 10); + cursor.Emit(OpCodes.Ldloca, vertexColorsVar); + cursor.Emit(OpCodes.Ldloc, isWaterVar); + cursor.Emit(OpCodes.Ldloc, waterStyleVar); cursor.EmitDelegate((int x, int y, ref VertexColors initialColor, bool flag6, int num2) => { From c30911b52383c5330a91dae35c5b9970708a0692 Mon Sep 17 00:00:00 2001 From: Lion8cake Date: Fri, 28 Nov 2025 01:45:58 +1100 Subject: [PATCH 395/401] Slight touch ups --- Systems/LavaRendering.cs | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/Systems/LavaRendering.cs b/Systems/LavaRendering.cs index 6366a07047..8ea92c243d 100644 --- a/Systems/LavaRendering.cs +++ b/Systems/LavaRendering.cs @@ -26,6 +26,11 @@ public class LavaRendering : ModSystem internal static readonly FieldInfo _drawCache = typeof(LiquidRenderer).GetField("_drawCache", BindingFlags.NonPublic | BindingFlags.Instance); internal static readonly FieldInfo _animationFrame = typeof(LiquidRenderer).GetField("_animationFrame", BindingFlags.NonPublic | BindingFlags.Instance); + internal static readonly FieldInfo WaterfallDist = typeof(WaterfallManager).GetField("waterfallDist", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance); + internal static readonly FieldInfo Waterfalls = typeof(WaterfallManager).GetField("waterfalls", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance); + internal static readonly FieldInfo CurrentMax = typeof(WaterfallManager).GetField("currentMax", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance); + internal static readonly FieldInfo SlowFrame = typeof(WaterfallManager).GetField("slowFrame", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance); + public void DrawLavas(bool isBackground = false) { Main.drewLava = false; @@ -762,13 +767,10 @@ public void InitialDrawLavafall(WaterfallManager waterfallManager) internal void DrawLavafall(WaterfallManager waterfallManager, int Style = 0, float Alpha = 1f) { - int waterfallDist = (int)typeof(WaterfallManager).GetField("waterfallDist", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance).GetValue(waterfallManager); - int rainFrameForeground = (int)typeof(WaterfallManager).GetField("rainFrameForeground", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance).GetValue(waterfallManager); - int rainFrameBackground = (int)typeof(WaterfallManager).GetField("rainFrameBackground", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance).GetValue(waterfallManager); - int snowFrameForeground = (int)typeof(WaterfallManager).GetField("snowFrameForeground", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance).GetValue(waterfallManager); - WaterfallData[] waterfalls = (WaterfallData[])typeof(WaterfallManager).GetField("waterfalls", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance).GetValue(waterfallManager); - int currentMax = (int)typeof(WaterfallManager).GetField("currentMax", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance).GetValue(waterfallManager); - int slowFrame = (int)typeof(WaterfallManager).GetField("slowFrame", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance).GetValue(waterfallManager); + int waterfallDist = (int)WaterfallDist.GetValue(waterfallManager); + WaterfallData[] waterfalls = (WaterfallData[])Waterfalls.GetValue(waterfallManager); + int currentMax = (int)CurrentMax.GetValue(waterfallManager); + int slowFrame = (int)SlowFrame.GetValue(waterfallManager); Main.tileSolid[546] = false; float num = 0f; float num12 = 99999f; @@ -776,13 +778,8 @@ internal void DrawLavafall(WaterfallManager waterfallManager, int Style = 0, flo int num34 = -1; int num45 = -1; float num47 = 0f; - float num48 = 99999f; - float num49 = 99999f; int num50 = -1; int num2 = -1; - Rectangle value = default(Rectangle); - Rectangle value2 = default(Rectangle); - Vector2 origin = default(Vector2); for (int i = 0; i < currentMax; i++) { if (waterfalls[i].type != 1) From 66e7303dc36a720b25ca57641d44c8cf079b8db2 Mon Sep 17 00:00:00 2001 From: Lion8cake Date: Fri, 28 Nov 2025 02:32:27 +1100 Subject: [PATCH 396/401] attempted fixes with vertex colors and slope rendering --- ILEditing/MechanicILChanges.cs | 38 +++++++++++++++++++++++++++++----- Systems/LavaRendering.cs | 17 +++++++-------- 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/ILEditing/MechanicILChanges.cs b/ILEditing/MechanicILChanges.cs index 7955635419..daca563b41 100644 --- a/ILEditing/MechanicILChanges.cs +++ b/ILEditing/MechanicILChanges.cs @@ -1226,15 +1226,20 @@ private static void LiquidDrawColors(ILContext il) }); } - //same as above + //Somewhat broken and I have no idea + //Something during the liquid slope rewrite messed up with slope colors and now slopes for the Sulphuric Water Style is now invisible when the slope fix is toggled off + //I've been staring at this and it's orig method for about 2 hours and I geniuenly have 0 clue how or why it broke the way it did + //Attempted to fix but imo its not terribly worth it (mainly since on normal colored lighting the slopes look fine (retro aparently runs worse than colored anyways)) + //Fairly sure either HPU or Iban wrote the ILChanges.SelectSulphuricWaterColor code which im not knowledgable enough with vertex colors to mess with + //"Sprunolia is bald" private static void LiquidSlopeDrawColors(ILContext il) { ILCursor cursor = new ILCursor(il); int vertexColorsVar = -1; + int colorColorsVar = -1; int isWaterVar = -1; - int waterStyleVar = -1; - if (!cursor.TryGotoNext(c => c.MatchLdsfld
("waterStyle"), c => c.MatchStloc(out waterStyleVar), c => c.MatchLdarg(6), c => c.MatchLdarg(7), c => c.MatchLdloca(out vertexColorsVar), c => c.MatchLdcR4(1), c => c.MatchCall("GetCornerColors"))) + if (!cursor.TryGotoNext(c => c.MatchLdsfld
("waterStyle"), c => c.MatchStloc(out _), c => c.MatchLdarg(6), c => c.MatchLdarg(7), c => c.MatchLdloca(out vertexColorsVar), c => c.MatchLdcR4(1), c => c.MatchCall("GetCornerColors"))) { LogFailure("Liquid Slope Draw Colors", "Could not locate the liquid slope vertex colors for drawing"); return; @@ -1250,9 +1255,8 @@ private static void LiquidSlopeDrawColors(ILContext il) cursor.Emit(OpCodes.Ldarg, 7); cursor.Emit(OpCodes.Ldloca, vertexColorsVar); cursor.Emit(OpCodes.Ldloc, isWaterVar); - cursor.Emit(OpCodes.Ldloc, waterStyleVar); - cursor.EmitDelegate((int x, int y, ref VertexColors initialColor, bool flag6, int num2) => + cursor.EmitDelegate((int x, int y, ref VertexColors initialColor, bool flag6) => { if (flag6) { @@ -1266,11 +1270,35 @@ private static void LiquidSlopeDrawColors(ILContext il) } else if ((tile.LiquidType == LiquidID.Lava || i == 1) && CalamityMod.Instance.biomeLava == null) { + //if flag6 means that the id is water, would that mean this code never executes? LavaStylesLoader.DrawColorSetup(x, y, CalamityMod.LavaStyle, ref initialColor); } } } }); + + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdloca(out colorColorsVar), c => c.MatchLdflda("TopRightColor"), c => c.MatchDup(), c => c.MatchLdobj(), c => c.MatchLdloc(out _), c => c.MatchCall("op_Multiply"), c => c.MatchStobj())) + { + LogFailure("Liquid Slope Draw Colors", "Could not locate the liquid slope color colors for drawing"); + return; + } + + cursor.Emit(OpCodes.Ldarg, 6); + cursor.Emit(OpCodes.Ldarg, 7); + cursor.Emit(OpCodes.Ldloca, colorColorsVar); + + cursor.EmitDelegate((int x, int y, ref VertexColors initialColor) => + { + int totalCount = (int)typeof(Loader).GetProperty("TotalCount", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static).GetValue(LoaderManager.Get()); + for (int i = 0; i < totalCount; i++) + { + Tile tile = Main.tile[x, y]; + if (i == Main.waterStyle && tile.LiquidType == LiquidID.Water) + { + CalamityWaterLoader.DrawColorSetup(x, y, Main.waterStyle, ref initialColor, true); + } + } + }); } #endregion diff --git a/Systems/LavaRendering.cs b/Systems/LavaRendering.cs index 8ea92c243d..9ca4cf62af 100644 --- a/Systems/LavaRendering.cs +++ b/Systems/LavaRendering.cs @@ -63,7 +63,6 @@ public void DrawLavas(bool isBackground = false) DrawLiquid(isBackground, CalamityMod.LavaStyle, flag ? CalamityMod.lavaAlpha[CalamityMod.LavaStyle] : 1f); } - protected internal void DrawLiquid(bool bg = false, int lavaStyle = 0, float Alpha = 1f, bool drawSinglePassLiquids = true) { if (!Lighting.NotRetro) @@ -122,6 +121,7 @@ public unsafe void DrawLava(SpriteBatch spriteBatch, Vector2 drawOffset, int Lav topLeftColor *= num; ref Color topRightColor = ref vertices.TopRightColor; topRightColor *= num; + LavaStylesLoader.DrawColorSetup(i, j, CalamityMod.LavaStyle, ref vertices); Main.DrawTileInWater(drawOffset, i, j); Main.tileBatch.Draw(CalamityMod.LavaTextures.liquid[num2].Value, new Vector2((float)(i << 4), (float)(j << 4)) + drawOffset + liquidOffset, sourceRectangle, vertices, Vector2.Zero, 1f, (SpriteEffects)0); } @@ -698,16 +698,14 @@ public void DrawTile_LiquidBehindTile(bool solidLayer, bool inFrontOfPlayers, in ref Color topRightColor = ref vertices.TopRightColor; topRightColor *= num6; bool flag7 = false; - if (flag6) + LavaStylesLoader.DrawColorSetup(tileX, tileY, CalamityMod.LavaStyle, ref vertices); + for (int i = 0; i < LavaStylesLoader.TotalCount; i++) { - for (int i = 0; i < LavaStylesLoader.TotalCount; i++) + if (CalamityMod.lavaAlpha[i] > 0f && i != num2) { - if (CalamityMod.lavaAlpha[i] > 0f && i != num2) - { - DrawPartialLiquid(!solidLayer, tileCache, ref position, ref liquidSize, i, ref vertices); - flag7 = true; - break; - } + DrawPartialLiquid(!solidLayer, tileCache, ref position, ref liquidSize, i, ref vertices); + flag7 = true; + break; } } VertexColors colors = vertices; @@ -720,6 +718,7 @@ public void DrawTile_LiquidBehindTile(bool solidLayer, bool inFrontOfPlayers, in topLeftColor2 *= num7; ref Color topRightColor2 = ref colors.TopRightColor; topRightColor2 *= num7; + LavaStylesLoader.DrawColorSetup(tileX, tileY, CalamityMod.LavaStyle, ref colors); DrawPartialLiquid(!solidLayer, tileCache, ref position, ref liquidSize, num2, ref colors); } From 525155bedc3e63e465695da77a8484e5e54917aa Mon Sep 17 00:00:00 2001 From: Flowaria Date: Thu, 27 Nov 2025 16:26:28 +0900 Subject: [PATCH 397/401] merge flo's --- CalamityMod.cs | 3 --- Systems/LavaRendering.cs | 8 +++++--- Systems/ModLavaStyle.cs | 38 ++++++++------------------------------ 3 files changed, 13 insertions(+), 36 deletions(-) diff --git a/CalamityMod.cs b/CalamityMod.cs index ca64b16be0..8fc7d201d2 100644 --- a/CalamityMod.cs +++ b/CalamityMod.cs @@ -51,12 +51,10 @@ using CalamityMod.Projectiles.BaseProjectiles; using CalamityMod.Schematics; using CalamityMod.Skies; -using CalamityMod.Systems; using CalamityMod.UI; using CalamityMod.UI.CalamitasEnchants; using CalamityMod.UI.DraedonsArsenal; using CalamityMod.UI.Rippers; -using CalamityMod.Waters; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using ReLogic.Content; @@ -268,7 +266,6 @@ public override void Load() SchematicManager.Load(); //lava - LavaRendering.instance = new LavaRendering(); WeakReferenceSupport.LavaStytleToBiomeLava(); Attunement.Load(); diff --git a/Systems/LavaRendering.cs b/Systems/LavaRendering.cs index 9ca4cf62af..3c595acd90 100644 --- a/Systems/LavaRendering.cs +++ b/Systems/LavaRendering.cs @@ -1,10 +1,7 @@ using System; -using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; -using System.Text; -using System.Threading.Tasks; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Terraria; @@ -31,6 +28,11 @@ public class LavaRendering : ModSystem internal static readonly FieldInfo CurrentMax = typeof(WaterfallManager).GetField("currentMax", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance); internal static readonly FieldInfo SlowFrame = typeof(WaterfallManager).GetField("slowFrame", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance); + public override void Load() + { + instance = this; + } + public void DrawLavas(bool isBackground = false) { Main.drewLava = false; diff --git a/Systems/ModLavaStyle.cs b/Systems/ModLavaStyle.cs index a6b7d31580..b1d52e2919 100644 --- a/Systems/ModLavaStyle.cs +++ b/Systems/ModLavaStyle.cs @@ -1,17 +1,11 @@ using System; using System.Collections.Generic; -using System.Reflection; using Microsoft.Xna.Framework.Graphics; using ReLogic.Content; using Terraria; -using Terraria.GameContent.Liquid; -using Terraria.GameContent; using Terraria.Graphics; -using Terraria.ModLoader; -using System.Linq; using Terraria.ID; -using Microsoft.Xna.Framework; -using CalamityMod.Items.Potions.Alcohol; +using Terraria.ModLoader; namespace CalamityMod.Systems { @@ -116,24 +110,6 @@ public virtual void InflictDebuff(Player player, int onfireDuration) public class LavaStylesLoader : ModSystem { - private static readonly MethodInfo ResizeArrayMethodInfo; - - static LavaStylesLoader() - { - ResizeArrayMethodInfo = typeof(ModContent).GetMethod("ResizeArrays", BindingFlags.NonPublic | BindingFlags.Static); - } - - private static void ResizeArrays(ResizeArray_orig orig, bool unloading) - { - orig.Invoke(unloading); - int totalCount = TotalCount; - Array.Resize(ref CalamityMod.LavaTextures.liquid, totalCount); - Array.Resize(ref CalamityMod.LavaTextures.block, totalCount); - Array.Resize(ref CalamityMod.LavaTextures.slope, totalCount); - Array.Resize(ref CalamityMod.LavaTextures.fall, totalCount); - Array.Resize(ref CalamityMod.lavaAlpha, totalCount); - } - private static readonly List _content = []; public static IReadOnlyList Content => _content; @@ -144,12 +120,14 @@ private static void ResizeArrays(ResizeArray_orig orig, bool unloading) public static int TotalCount => VanillaCount + ModCount; - public override void Load() + public override void ResizeArrays() { - if (ResizeArrayMethodInfo != null) - { - MonoModHooks.Add(ResizeArrayMethodInfo, Delegate.CreateDelegate(typeof(Action), typeof(LavaStylesLoader).GetMethod(nameof(ResizeArrays), BindingFlags.NonPublic | BindingFlags.Static))); - } + int totalCount = TotalCount; + Array.Resize(ref CalamityMod.LavaTextures.liquid, totalCount); + Array.Resize(ref CalamityMod.LavaTextures.block, totalCount); + Array.Resize(ref CalamityMod.LavaTextures.slope, totalCount); + Array.Resize(ref CalamityMod.LavaTextures.fall, totalCount); + Array.Resize(ref CalamityMod.lavaAlpha, totalCount); } public override void PostSetupContent() From 31d29150391b09be545ce4ef5082d89f5c6ac8c9 Mon Sep 17 00:00:00 2001 From: Flowaria Date: Fri, 28 Nov 2025 10:07:58 +0900 Subject: [PATCH 398/401] Cleaning CalamityWaterLoader methods --- Systems/CalamityModWaterStyle.cs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/Systems/CalamityModWaterStyle.cs b/Systems/CalamityModWaterStyle.cs index 9ea1ec5f0f..1f52e12850 100644 --- a/Systems/CalamityModWaterStyle.cs +++ b/Systems/CalamityModWaterStyle.cs @@ -34,23 +34,17 @@ internal static class CalamityWaterLoader { internal static void ModifyLightSetup(int i, int j, int type, ref float r, ref float g, ref float b) { - if (GetCalamityWaterStyle(type) is CalamityModWaterStyle styles) + if (TryGetCalamityWaterStyle(type, out var styles)) { - if (styles != null) - { - styles?.ModifyLight(i, j, ref r, ref g, ref b); - } + styles.ModifyLight(i, j, ref r, ref g, ref b); } } internal static void DrawColorSetup(int x, int y, int type, ref VertexColors liquidColor, bool isSlope = false) { - if (GetCalamityWaterStyle(type) is CalamityModWaterStyle styles) + if (TryGetCalamityWaterStyle(type, out var styles)) { - if (styles != null) - { - styles?.DrawColor(x, y, ref liquidColor, isSlope); - } + styles.DrawColor(x, y, ref liquidColor, isSlope); } } From 652e22593b805f12967f0d6d9241ee6e11b34a5b Mon Sep 17 00:00:00 2001 From: Flowaria Date: Fri, 28 Nov 2025 10:32:13 +0900 Subject: [PATCH 399/401] Added Base System for Modifying WaterFallAlpha --- ILEditing/MechanicILChanges.cs | 28 ++++++++++++++++++++-------- Waters/IWaterfallWithAlphaChange.cs | 7 +++++++ Waters/MiddleAbyssWater.cs | 8 +++++++- Waters/SulphuricDepthsWater.cs | 17 ++++++++++------- Waters/SulphuricWater.cs | 19 ++++++++++++------- Waters/SunkenSeaWater.cs | 17 +++++++++++------ Waters/UpperAbyssWater.cs | 8 +++++++- Waters/VoidWater.cs | 8 +++++++- 8 files changed, 81 insertions(+), 31 deletions(-) create mode 100644 Waters/IWaterfallWithAlphaChange.cs diff --git a/ILEditing/MechanicILChanges.cs b/ILEditing/MechanicILChanges.cs index daca563b41..8ddf5dcbb1 100644 --- a/ILEditing/MechanicILChanges.cs +++ b/ILEditing/MechanicILChanges.cs @@ -19,11 +19,11 @@ using CalamityMod.Projectiles; using CalamityMod.Projectiles.Typeless; using CalamityMod.Systems; +using CalamityMod.Waters; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Mono.Cecil.Cil; using MonoMod.Cil; -using ReLogic.Content; using Terraria; using Terraria.DataStructures; using Terraria.GameContent; @@ -838,7 +838,8 @@ private void DrawLavatoCapture(ILContext il) return; } cursor.Emit(OpCodes.Ldloca, alphaSaveVar); - cursor.EmitDelegate((ref float[] alphaSave) => { + cursor.EmitDelegate((ref float[] alphaSave) => + { alphaSave = CalamityMod.lavaAlpha.ToArray(); }); //Then it resets the alpha to be fully visible @@ -848,7 +849,8 @@ private void DrawLavatoCapture(ILContext il) return; } cursor.EmitLdarg(2); - cursor.EmitDelegate((CaptureSettings settings) => { + cursor.EmitDelegate((CaptureSettings settings) => + { for (int i = 0; i < 1; i++) //1 is the amount of vanilla lava styles, can be increased to include additional lava styles { @@ -862,7 +864,8 @@ private void DrawLavatoCapture(ILContext il) LogFailure("Draw lavas to captures", "Could not locate the background of liquid capture drawing"); return; } - cursor.EmitDelegate(() => { + cursor.EmitDelegate(() => + { LavaRendering.instance.DrawLiquid(bg: true, CalamityMod.LavaStyle); }); if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdcI4(9), c => c.MatchLdcR4(1), c => c.MatchLdcI4(1), c => c.MatchCall
("DrawLiquid"))) @@ -871,7 +874,8 @@ private void DrawLavatoCapture(ILContext il) return; } cursor.EmitLdarg(2); - cursor.EmitDelegate((CaptureSettings settings) => { + cursor.EmitDelegate((CaptureSettings settings) => + { LavaRendering.instance.DrawLiquid(bg: true, CalamityMod.LavaStyle); }); if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdcI4(0), c => c.MatchLdsfld
("waterStyle"), c => c.MatchLdcR4(1), c => c.MatchLdcI4(1), c => c.MatchCall
("DrawLiquid"))) @@ -879,7 +883,8 @@ private void DrawLavatoCapture(ILContext il) LogFailure("Draw lavas to captures", "Could not locate the liquid capture drawing"); return; } - cursor.EmitDelegate(() => { + cursor.EmitDelegate(() => + { LavaRendering.instance.DrawLiquid(bg: false, CalamityMod.LavaStyle); }); if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdcI4(0), c => c.MatchLdloc(out _), c => c.MatchLdfld("WaterStyle"), c => c.MatchLdcR4(1), c => c.MatchLdcI4(1), c => c.MatchCall
("DrawLiquid"))) @@ -888,7 +893,8 @@ private void DrawLavatoCapture(ILContext il) return; } cursor.EmitLdarg(2); - cursor.EmitDelegate((CaptureSettings settings) => { + cursor.EmitDelegate((CaptureSettings settings) => + { LavaRendering.instance.DrawLiquid(bg: false, CalamityMod.LavaStyle); }); //Finally, the original alpha is returned to the lava alpha @@ -898,7 +904,8 @@ private void DrawLavatoCapture(ILContext il) return; } cursor.Emit(OpCodes.Ldloc, alphaSaveVar); - cursor.EmitDelegate((float[] alphaSave) => { + cursor.EmitDelegate((float[] alphaSave) => + { CalamityMod.lavaAlpha = alphaSave; }); } @@ -1078,6 +1085,11 @@ private Color WaterfallGlowmaskEditor(On_WaterfallManager.orig_StylizeColor orig { return aColor; } + else if (LoaderManager.Get().Get(waterfallType) is IWaterfallWithAlphaChange waterfallWithAlpha) + { + waterfallWithAlpha.ModifyAlpha(ref alpha); + return orig.Invoke(alpha, maxSteps, waterfallType, y, s, tileCache, aColor); + } else { return orig.Invoke(alpha, maxSteps, waterfallType, y, s, tileCache, aColor); diff --git a/Waters/IWaterfallWithAlphaChange.cs b/Waters/IWaterfallWithAlphaChange.cs new file mode 100644 index 0000000000..9c2fa326a9 --- /dev/null +++ b/Waters/IWaterfallWithAlphaChange.cs @@ -0,0 +1,7 @@ +namespace CalamityMod.Waters +{ + public interface IWaterfallWithAlphaChange + { + void ModifyAlpha(ref float a); + } +} diff --git a/Waters/MiddleAbyssWater.cs b/Waters/MiddleAbyssWater.cs index bd15111e36..bb0d27c08c 100644 --- a/Waters/MiddleAbyssWater.cs +++ b/Waters/MiddleAbyssWater.cs @@ -7,7 +7,13 @@ namespace CalamityMod.Waters { - public class MiddleAbyssWaterflow : ModWaterfallStyle { } + public class MiddleAbyssWaterflow : ModWaterfallStyle, IWaterfallWithAlphaChange + { + public void ModifyAlpha(ref float a) + { + a *= 0.333f; + } + } public class MiddleAbyssWater : CalamityModWaterStyle { diff --git a/Waters/SulphuricDepthsWater.cs b/Waters/SulphuricDepthsWater.cs index 4fdae19792..369dbd4f90 100644 --- a/Waters/SulphuricDepthsWater.cs +++ b/Waters/SulphuricDepthsWater.cs @@ -1,17 +1,20 @@ -using CalamityMod.Particles; -using System; +using CalamityMod.Dusts.WaterSplash; +using CalamityMod.Gores.WaterDroplet; using CalamityMod.Systems; using CalamityMod.Tiles.Abyss; using Microsoft.Xna.Framework; -using Terraria; -using Terraria.ModLoader; using Terraria.Graphics; -using CalamityMod.Dusts.WaterSplash; -using CalamityMod.Gores.WaterDroplet; +using Terraria.ModLoader; namespace CalamityMod.Waters { - public class SulphuricDepthsWaterflow : ModWaterfallStyle { } + public class SulphuricDepthsWaterflow : ModWaterfallStyle, IWaterfallWithAlphaChange + { + public void ModifyAlpha(ref float a) + { + a *= 0.333f; + } + } public class SulphuricDepthsWater : CalamityModWaterStyle { diff --git a/Waters/SulphuricWater.cs b/Waters/SulphuricWater.cs index 036a6454d5..6c448991b5 100644 --- a/Waters/SulphuricWater.cs +++ b/Waters/SulphuricWater.cs @@ -1,20 +1,25 @@ -using CalamityMod.Particles; -using System; +using System; +using CalamityMod.Dusts.WaterSplash; +using CalamityMod.Gores.WaterDroplet; +using CalamityMod.Particles; using CalamityMod.Systems; using CalamityMod.Tiles.Abyss; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using ReLogic.Content; using Terraria; -using Terraria.ModLoader; using Terraria.Graphics; -using Terraria.ID; -using CalamityMod.Dusts.WaterSplash; -using CalamityMod.Gores.WaterDroplet; +using Terraria.ModLoader; namespace CalamityMod.Waters { - public class SulphuricWaterflow : ModWaterfallStyle { } + public class SulphuricWaterflow : ModWaterfallStyle, IWaterfallWithAlphaChange + { + public void ModifyAlpha(ref float a) + { + a *= 0.333f; + } + } public class SulphuricWater : CalamityModWaterStyle { diff --git a/Waters/SunkenSeaWater.cs b/Waters/SunkenSeaWater.cs index 4dbee891e9..9f6e6b11cd 100644 --- a/Waters/SunkenSeaWater.cs +++ b/Waters/SunkenSeaWater.cs @@ -1,17 +1,22 @@ -using CalamityMod.Particles; -using System; +using System; +using CalamityMod.Dusts.WaterSplash; +using CalamityMod.Gores.WaterDroplet; using CalamityMod.Systems; using CalamityMod.Tiles.Abyss; using Microsoft.Xna.Framework; using Terraria; -using Terraria.ModLoader; using Terraria.Graphics; -using CalamityMod.Dusts.WaterSplash; -using CalamityMod.Gores.WaterDroplet; +using Terraria.ModLoader; namespace CalamityMod.Waters { - public class SunkenSeaWaterflow : ModWaterfallStyle { } + public class SunkenSeaWaterflow : ModWaterfallStyle, IWaterfallWithAlphaChange + { + public void ModifyAlpha(ref float a) + { + a *= 0.333f; + } + } public class SunkenSeaWater : CalamityModWaterStyle { diff --git a/Waters/UpperAbyssWater.cs b/Waters/UpperAbyssWater.cs index fed3016207..7cc733466a 100644 --- a/Waters/UpperAbyssWater.cs +++ b/Waters/UpperAbyssWater.cs @@ -7,7 +7,13 @@ namespace CalamityMod.Waters { - public class UpperAbyssWaterflow : ModWaterfallStyle { } + public class UpperAbyssWaterflow : ModWaterfallStyle, IWaterfallWithAlphaChange + { + public void ModifyAlpha(ref float a) + { + a *= 0.333f; + } + } public class UpperAbyssWater : CalamityModWaterStyle { diff --git a/Waters/VoidWater.cs b/Waters/VoidWater.cs index 1ce1591140..3f2c461d92 100644 --- a/Waters/VoidWater.cs +++ b/Waters/VoidWater.cs @@ -7,7 +7,13 @@ namespace CalamityMod.Waters { - public class VoidWaterflow : ModWaterfallStyle { } + public class VoidWaterflow : ModWaterfallStyle, IWaterfallWithAlphaChange + { + public void ModifyAlpha(ref float a) + { + a *= 0.333f; + } + } public class VoidWater : CalamityModWaterStyle { From 3366c3677c9984586ec1564810a7b3d6920ae989 Mon Sep 17 00:00:00 2001 From: Ozzatron Date: Fri, 28 Nov 2025 12:24:13 -0500 Subject: [PATCH 400/401] 2.0.7.2 version bump --- build.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.txt b/build.txt index 4091c92da8..3d4610236c 100644 --- a/build.txt +++ b/build.txt @@ -1,5 +1,5 @@ author = The Calamity Dev Team -version = 2.0.7.1 +version = 2.0.7.2 displayName = Calamity Mod modReferences = CalamityModMusic homepage = https://discord.gg/calamity From 56b1e39a8e5c03dc0b6754fa232d376d7d1b58d5 Mon Sep 17 00:00:00 2001 From: Lion8cake <69915693+Lion8cake@users.noreply.github.com> Date: Thu, 25 Dec 2025 14:31:13 +1100 Subject: [PATCH 401/401] Updates to the Sulphurous bg and sky (#104) --- Backgrounds/SulphurSeaSurfaceBGStyle.cs | 75 ++++++++++++++++++++++--- Skies/SulphurSeaSky.cs | 65 --------------------- 2 files changed, 68 insertions(+), 72 deletions(-) diff --git a/Backgrounds/SulphurSeaSurfaceBGStyle.cs b/Backgrounds/SulphurSeaSurfaceBGStyle.cs index f2f57539d6..98d9a1d64c 100644 --- a/Backgrounds/SulphurSeaSurfaceBGStyle.cs +++ b/Backgrounds/SulphurSeaSurfaceBGStyle.cs @@ -1,15 +1,14 @@ -using Terraria.ModLoader; +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.Graphics.Effects; +using Terraria.ModLoader; namespace CalamityMod.Backgrounds { public class SulphurSeaSurfaceBGStyle : ModSurfaceBackgroundStyle { - public override int ChooseCloseTexture(ref float scale, ref double parallax, ref float a, ref float b) - { - b -= 100f; - return BackgroundTextureLoader.GetBackgroundSlot("CalamityMod/Backgrounds/BlankPixel"); - } - public override void ModifyFarFades(float[] fades, float transitionSpeed) { //This just fades in the background and fades out other backgrounds. @@ -33,5 +32,67 @@ public override void ModifyFarFades(float[] fades, float transitionSpeed) } } } + + public override int ChooseCloseTexture(ref float scale, ref double parallax, ref float a, ref float b) + { + return BackgroundTextureLoader.GetBackgroundSlot("CalamityMod/Backgrounds/SulphurSeaSurfaceClose"); + } + + public override bool PreDrawCloseBackground(SpriteBatch spriteBatch) //Taken from astral bg so the sulphur sea bg doesn't overlap other backgrounds + { + float screenOff = (float)AstralSurfaceBGStyle.screenOffField.GetValue(Main.instance); + float scAdj = (float)AstralSurfaceBGStyle.scAdjField.GetValue(Main.instance); + Color ColorOfSurfaceBackgroundsModified = (Color)AstralSurfaceBGStyle.COSBMAplhaField.GetValue(null); + bool canBGDraw = false; + if ((!Main.remixWorld || (Main.gameMenu && !WorldGen.remixWorldGen)) && (!WorldGen.remixWorldGen || !WorldGen.drunkWorldGen)) + canBGDraw = true; + if (Main.mapFullscreen) + canBGDraw = false; + int offset = 30; + if (Main.gameMenu) + offset = 0; + if (WorldGen.drunkWorldGen) + offset = -180; + float surfacePosition = (float)Main.worldSurface; + if (surfacePosition == 0f) + surfacePosition = 1f; + float screenPosition = Main.screenPosition.Y + (float)(Main.screenHeight / 2) - 600f; + double backgroundTopMagicNumber = (0f - screenPosition + screenOff / 2f) / (surfacePosition * 16f); + float bgGlobalScaleMultiplier = 2f; + int pushBGTopHack; + int offset2 = -180; + int menuOffset = 0; + if (Main.gameMenu) + { + menuOffset -= offset2; + } + pushBGTopHack = menuOffset; + pushBGTopHack += offset; + pushBGTopHack += offset2; //Offsets to the background placement + if (canBGDraw) //If the background can draw (player is not in a remix world or is not in a map). This can probably be removed since backgrounds already go through these checks + { + var bgScale = 1.25f; //Scale of the furthest of the closest background layers + var bgParallax = 0.4; //The parallax of the background layer + var bgTopY = (int)(backgroundTopMagicNumber * 1800.0 + 1500.0) + (int)scAdj + pushBGTopHack; //the Y position of the background + bgScale *= bgGlobalScaleMultiplier; //Scale of the background + var bgWidthScaled = (int)((float)CalamityMod.SulphurSeaSurface.Width * bgScale); //The Width of the bg texture scaled to the correct size + SkyManager.Instance.DrawToDepth(Main.spriteBatch, 1.2f / (float)bgParallax); + var bgStartX = (int)(0.0 - Math.IEEERemainder((double)Main.screenPosition.X * bgParallax, bgWidthScaled) - (double)(bgWidthScaled / 2)); //The starting position of the background layer + if (Main.gameMenu) + bgTopY = 320 + pushBGTopHack; //increases the height in the main menu + + var bgLoops = Main.screenWidth / bgWidthScaled + 2; + if ((double)Main.screenPosition.Y < Main.worldSurface * 16.0 + 16.0) + { + for (int i = 0; i < bgLoops; i++) + { + //Draw the texture and its glowmask to each loop of the texture + Main.spriteBatch.Draw(CalamityMod.SulphurSeaSurface, new Vector2(bgStartX + bgWidthScaled * i, bgTopY + 400), new Rectangle(0, 0, CalamityMod.SulphurSeaSurface.Width, CalamityMod.SulphurSeaSurface.Height), ColorOfSurfaceBackgroundsModified, 0f, default(Vector2), bgScale, SpriteEffects.None, 0f); + Main.spriteBatch.Draw(CalamityMod.SulphurSeaSkyFront, new Vector2(bgStartX + bgWidthScaled * i, bgTopY + 400), new Rectangle(0, 0, CalamityMod.SulphurSeaSkyFront.Width, CalamityMod.SulphurSeaSkyFront.Height), new Color(Color.LightSeaGreen.R, Color.LightSeaGreen.G, Color.LightSeaGreen.B, ColorOfSurfaceBackgroundsModified.A) * 0.5f, 0f, default(Vector2), bgScale, SpriteEffects.None, 0f); + } + } + } + return false; //Stop the drawing of the base close background texture (note: does NOT stop the drawing of the Middle and Far textures because tmodloader is slight stupid :blushing:) + } } } diff --git a/Skies/SulphurSeaSky.cs b/Skies/SulphurSeaSky.cs index bd8c4f1233..6153d869e4 100644 --- a/Skies/SulphurSeaSky.cs +++ b/Skies/SulphurSeaSky.cs @@ -13,11 +13,6 @@ public class SulphurSeaSky : CustomSky private bool skyActive; private float opacity; - private const float ScreenParralaxMultiplier = 0.4f; - - // Vanila scales backgrounds to 250% size. Depending on what you might want to do you can change this if you wanted to make a non scaled bg. - private const float Scale = 2.5f; - public override void Deactivate(params object[] args) { skyActive = Main.LocalPlayer.Calamity().ZoneSulphur; @@ -42,66 +37,6 @@ public override void Draw(SpriteBatch spriteBatch, float minDepth, float maxDept { if (maxDepth >= 4f && minDepth < 4f) spriteBatch.Draw(CalamityMod.SulphurSeaSky, new Rectangle(0, (int)(-Main.screenPosition.Y / 6f) + 1300, Main.screenWidth, Main.screenHeight), Color.Lerp(Main.ColorOfTheSkies, Color.LightSeaGreen, 0.33f) * 0.2f * opacity); - - // Small worlds, default draw height - int sulphurSeaHeight = (World.SulphurousSea.YStart + (int)Main.worldSurface) / 2; - - // Medium worlds - if (Main.maxTilesX >= 6400 && Main.maxTilesX < 8400) - sulphurSeaHeight = (World.SulphurousSea.YStart + (int)Main.worldSurface) / 5; - - // Large worlds (and anything bigger) - if (Main.maxTilesX >= 8400) - sulphurSeaHeight = (World.SulphurousSea.YStart + (int)Main.worldSurface) / 140; - - // Explantion on how to use this BG code for skies. - // This changes the speed of the parralax, the closer the layer to the player the faster it should be. - if (maxDepth >= 1f && minDepth < 1f) - { - Texture2D texture = CalamityMod.SulphurSeaSkyFront; - - // Keep in mind that y paralex should always be half of x's or it will feel odd compared to how terraria does it. - // Keep in mind when you change screen parralax it affects the y offset for the bg in the world. - int x = (int)(Main.screenPosition.X * ScreenParralaxMultiplier); - x %= (int)(texture.Width * Scale); - int y = (int)(Main.screenPosition.Y * 0.5f * ScreenParralaxMultiplier); - - // Y offset to align with whatever position you want it in the world (is affected by screenParralaxMultiplier as stated before). - y -= 1800; - - float screenWidth = Main.screenWidth / 2f; - float screenHeight = Main.screenHeight / 2f; - Vector2 position = texture.Size() / 2f * Scale; - Color color = Color.LightSeaGreen * 0.5f * opacity; - - // This loops the BG horizontally. - for (int k = -1; k <= 1; k++) - { - var pos = new Vector2(screenWidth - x + texture.Width * k * Scale, screenHeight - y); - spriteBatch.Draw(texture, pos - position, null, color, 0f, new Vector2(0f, (float)sulphurSeaHeight), Scale, SpriteEffects.None, 0f); - } - } - - if (maxDepth >= 3f && minDepth < 3f) - { - Texture2D texture = CalamityMod.SulphurSeaSurface; - - int x = (int)(Main.screenPosition.X * ScreenParralaxMultiplier); - x %= (int)(texture.Width * Scale); - int y = (int)(Main.screenPosition.Y * 0.5f * ScreenParralaxMultiplier); - y -= 1800; // 1000 - - float screenWidth = Main.screenWidth / 2f; - float screenHeight = Main.screenHeight / 2f; - Vector2 position = texture.Size() / 2f * Scale; - Color color = Main.ColorOfTheSkies * opacity; - - for (int k = -1; k <= 1; k++) - { - var pos = new Vector2(screenWidth - x + texture.Width * k * Scale, screenHeight - y); - spriteBatch.Draw(texture, pos - position, null, color, 0f, new Vector2(0f, (float)sulphurSeaHeight), Scale, SpriteEffects.None, 0f); - } - } } public override void Update(GameTime gameTime)