diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 583986729d..7d846efaeb 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1 @@ -patreon: Fabsol +patreon: CalamityMod \ No newline at end of file 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/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/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; diff --git a/Buffs/Alcohol/BloodyMaryBuff.png b/Buffs/Alcohol/BloodyMaryBuff.png index 46cf3a0b57..670c6a0445 100644 Binary files a/Buffs/Alcohol/BloodyMaryBuff.png and b/Buffs/Alcohol/BloodyMaryBuff.png differ diff --git a/Buffs/Alcohol/CaribbeanRumBuff.png b/Buffs/Alcohol/CaribbeanRumBuff.png index c3e5464b05..11282f11ea 100644 Binary files a/Buffs/Alcohol/CaribbeanRumBuff.png and b/Buffs/Alcohol/CaribbeanRumBuff.png differ diff --git a/Buffs/Alcohol/CinnamonRollBuff.png b/Buffs/Alcohol/CinnamonRollBuff.png index 8d9ff66e26..fcd82792df 100644 Binary files a/Buffs/Alcohol/CinnamonRollBuff.png and b/Buffs/Alcohol/CinnamonRollBuff.png differ diff --git a/Buffs/Alcohol/EverclearBuff.png b/Buffs/Alcohol/EverclearBuff.png index fde2031fa3..c1e6fcc595 100644 Binary files a/Buffs/Alcohol/EverclearBuff.png and b/Buffs/Alcohol/EverclearBuff.png differ diff --git a/Buffs/Alcohol/EvergreenGinBuff.png b/Buffs/Alcohol/EvergreenGinBuff.png index 5e41d87eb6..e73283e98b 100644 Binary files a/Buffs/Alcohol/EvergreenGinBuff.png and b/Buffs/Alcohol/EvergreenGinBuff.png differ diff --git a/Buffs/Alcohol/FireballBuff.png b/Buffs/Alcohol/FireballBuff.png index 8887354d3f..37a154a295 100644 Binary files a/Buffs/Alcohol/FireballBuff.png and b/Buffs/Alcohol/FireballBuff.png differ diff --git a/Buffs/Alcohol/GrapeBeerBuff.png b/Buffs/Alcohol/GrapeBeerBuff.png index d951249d12..9268f68297 100644 Binary files a/Buffs/Alcohol/GrapeBeerBuff.png and b/Buffs/Alcohol/GrapeBeerBuff.png differ diff --git a/Buffs/Alcohol/MargaritaBuff.png b/Buffs/Alcohol/MargaritaBuff.png index 068aebf1e0..ca13a1ec02 100644 Binary files a/Buffs/Alcohol/MargaritaBuff.png and b/Buffs/Alcohol/MargaritaBuff.png differ diff --git a/Buffs/Alcohol/MoonshineBuff.png b/Buffs/Alcohol/MoonshineBuff.png index b079231309..0f6bc184e9 100644 Binary files a/Buffs/Alcohol/MoonshineBuff.png and b/Buffs/Alcohol/MoonshineBuff.png differ diff --git a/Buffs/Alcohol/MoscowMuleBuff.png b/Buffs/Alcohol/MoscowMuleBuff.png index 4ba5245776..fb89919273 100644 Binary files a/Buffs/Alcohol/MoscowMuleBuff.png and b/Buffs/Alcohol/MoscowMuleBuff.png differ diff --git a/Buffs/Alcohol/OldFashionedBuff.png b/Buffs/Alcohol/OldFashionedBuff.png index 2b6e8fdaf0..df44c6c278 100644 Binary files a/Buffs/Alcohol/OldFashionedBuff.png and b/Buffs/Alcohol/OldFashionedBuff.png differ 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/Buffs/Alcohol/RedWineBuff.png b/Buffs/Alcohol/RedWineBuff.png index a3e116c717..71d0f1f3d7 100644 Binary files a/Buffs/Alcohol/RedWineBuff.png and b/Buffs/Alcohol/RedWineBuff.png differ diff --git a/Buffs/Alcohol/RumBuff.png b/Buffs/Alcohol/RumBuff.png index 29f7cd9fda..56f5a40c0b 100644 Binary files a/Buffs/Alcohol/RumBuff.png and b/Buffs/Alcohol/RumBuff.png differ diff --git a/Buffs/Alcohol/ScrewdriverBuff.png b/Buffs/Alcohol/ScrewdriverBuff.png index 2c0984bc98..b84648d68f 100644 Binary files a/Buffs/Alcohol/ScrewdriverBuff.png and b/Buffs/Alcohol/ScrewdriverBuff.png differ diff --git a/Buffs/Alcohol/StarBeamRyeBuff.png b/Buffs/Alcohol/StarBeamRyeBuff.png index e678986953..f4e8971ca0 100644 Binary files a/Buffs/Alcohol/StarBeamRyeBuff.png and b/Buffs/Alcohol/StarBeamRyeBuff.png differ diff --git a/Buffs/Alcohol/TequilaBuff.png b/Buffs/Alcohol/TequilaBuff.png index a6c233e3d1..dec11238de 100644 Binary files a/Buffs/Alcohol/TequilaBuff.png and b/Buffs/Alcohol/TequilaBuff.png differ diff --git a/Buffs/Alcohol/TequilaSunriseBuff.png b/Buffs/Alcohol/TequilaSunriseBuff.png index ef5bee8678..37faf7b8c9 100644 Binary files a/Buffs/Alcohol/TequilaSunriseBuff.png and b/Buffs/Alcohol/TequilaSunriseBuff.png differ diff --git a/Buffs/Alcohol/VodkaBuff.png b/Buffs/Alcohol/VodkaBuff.png index 485745f805..835b57cfba 100644 Binary files a/Buffs/Alcohol/VodkaBuff.png and b/Buffs/Alcohol/VodkaBuff.png differ diff --git a/Buffs/Alcohol/WhiskeyBuff.png b/Buffs/Alcohol/WhiskeyBuff.png index 56f2662420..ec5721c39a 100644 Binary files a/Buffs/Alcohol/WhiskeyBuff.png and b/Buffs/Alcohol/WhiskeyBuff.png differ diff --git a/Buffs/Alcohol/WhiteWineBuff.png b/Buffs/Alcohol/WhiteWineBuff.png index 548844ed08..5a175507c2 100644 Binary files a/Buffs/Alcohol/WhiteWineBuff.png and b/Buffs/Alcohol/WhiteWineBuff.png differ 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 0000000000..b5e2e69651 Binary files /dev/null and b/Buffs/DamageOverTime/HeavyBleeding.png differ 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 0000000000..5a577ad3dc Binary files /dev/null and b/Buffs/DamageOverTime/Laceration.png differ 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 f821a3a2bb..0000000000 Binary files a/Buffs/Mounts/AlicornBuff.png and /dev/null differ 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/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/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 4fdc0fff94..0000000000 Binary files a/Buffs/StatBuffs/KamiBuff.png and /dev/null differ 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 df7af84f98..0000000000 Binary files a/Buffs/StatDebuffs/KamiFlu.png and /dev/null differ diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index cb4fca8350..9137d7d2eb 100644 --- a/CalPlayer/CalamityPlayer.cs +++ b/CalPlayer/CalamityPlayer.cs @@ -31,6 +31,7 @@ using CalamityMod.Items.VanillaArmorChanges; using CalamityMod.Items.Weapons.DraedonsArsenal; using CalamityMod.Items.Weapons.Melee; +using CalamityMod.Items.Weapons.Ranged; using CalamityMod.Items.Weapons.Rogue; using CalamityMod.Items.Weapons.Summon; using CalamityMod.NPCs; @@ -90,7 +91,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; @@ -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; @@ -300,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; @@ -882,6 +880,8 @@ public GemTechArmorState GemTechState public bool gState = false; public bool bBlood = false; public bool brainRot = false; + public bool heavybleeding = false; + public bool laceration = false; public bool elementalMix = false; public bool icarusFolly = false; public bool weakPetrification = false; @@ -929,7 +929,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; @@ -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; @@ -1151,7 +1150,6 @@ public GemTechArmorState GemTechState public bool omegaBlueTransformationForce; public bool omegaBlueTransformationPower; public bool redBow; - public bool cocosFeather; #endregion #region Calamitas Enchant Effects @@ -1291,7 +1289,6 @@ public override void Initialize() newPrincessInventory = false; newSkeletonMerchantInventory = false; newPermafrostInventory = false; - newCirrusInventory = false; newAmidiasInventory = false; newBanditInventory = false; newCalamitasInventory = false; @@ -1343,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); @@ -1433,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"); @@ -1601,7 +1596,6 @@ public override void ResetEffects() onyxExcavator = false; rimehound = false; - fab = false; crysthamyr = false; ExoChair = false; miniOldDuke = false; @@ -1662,7 +1656,6 @@ public override void ResetEffects() shadowSpeed = false; dsSetBonus = false; wearingRogueArmor = false; - cirrusDress = false; blockAllDashes = false; blazingCursorDamage = false; @@ -1770,7 +1763,6 @@ public override void ResetEffects() phantomicArtifact = false; hallowedRegen = false; hallowedPower = false; - kamiBoost = false; tracersDust = false; elysianWingsDust = false; tracersCelestial = false; @@ -1944,6 +1936,8 @@ public override void ResetEffects() gState = false; bBlood = false; brainRot = false; + heavybleeding = false; + laceration = false; elementalMix = false; icarusFolly = false; vHex = false; @@ -1998,7 +1992,7 @@ public override void ResetEffects() trippy = false; amidiasBlessing = false; flaskBrimstone = false; - fabsolVodka = false; + purpleHaze = false; shine = false; anechoicCoating = false; mushy = false; @@ -2191,7 +2185,6 @@ public override void ResetEffects() omegaBlueTransformation = omegaBlueTransformationForce = omegaBlueTransformationPower = false; redBow = false; - cocosFeather = false; rageModeActive = false; adrenalineModeActive = false; @@ -2367,6 +2360,8 @@ public override void UpdateDead() gState = false; bBlood = false; brainRot = false; + heavybleeding = false; + laceration = false; elementalMix = false; icarusFolly = false; vHex = false; @@ -2419,7 +2414,6 @@ public override void UpdateDead() hallowedPower = false; onyxExcavator = false; rimehound = false; - fab = false; crysthamyr = false; ExoChair = false; abyssalDivingSuitPlates = false; @@ -2432,7 +2426,6 @@ public override void UpdateDead() rRage = false; xRage = false; xWrath = false; - kamiBoost = false; graxDefense = false; encased = false; brutalCarnage = false; @@ -2457,7 +2450,7 @@ public override void UpdateDead() sulphurskin = false; baguette = false; flaskBrimstone = false; - fabsolVodka = false; + purpleHaze = false; shine = false; anechoicCoating = false; mushy = false; @@ -3090,16 +3083,16 @@ public override void ProcessTriggers(TriggersSet triggersSet) //Right click dash on Speed Blaster if (sBlasterDashActivated == true) { - if ((Player.controlUp || Player.controlDown || Player.controlLeft || Player.controlRight) && !Player.pulley && Player.grappling[0] == -1 && !Player.tongued && !Player.mount.Active && Player.HasCooldown(Cooldowns.SpeedBlasterBoost.ID) && Player.dashDelay == 0) + if ((Player.controlUp || Player.controlDown || Player.controlLeft || Player.controlRight) && !Player.pulley && Player.grappling[0] == -1 && !Player.tongued && !Player.mount.Active && (Player.HasCooldown(SpeedBlasterBoost.ID) || Player.HasCooldown(SuperradiantSawBoost.ID)) && Player.dashDelay == 0) { SpeedBlasterDashStarted = true; } sBlasterDashActivated = false; } - if (Player.Calamity().SpeedBlasterDashStarted || (Player.dashDelay != 0 && Player.Calamity().LastUsedDashID == SpeedBlasterDash.ID)) + if (Player.Calamity().SpeedBlasterDashStarted || (Player.dashDelay != 0 && (Player.Calamity().LastUsedDashID == SpeedBlasterDash.ID || Player.Calamity().LastUsedDashID == SuperradiantSawDash.ID))) { - Player.Calamity().DeferredDashID = SpeedBlasterDash.ID; + Player.Calamity().DeferredDashID = Player.ActiveItem().type == ModContent.ItemType() ? SuperradiantSawDash.ID : SpeedBlasterDash.ID; Player.dash = 0; } @@ -3425,58 +3418,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 @@ -3713,10 +3714,9 @@ 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) + + (blueCandle ? BlueCandleBuff.AccelerationBoost : 0f) + (planarSpeedBoost > 0 ? (0.01f * planarSpeedBoost) : 0f) + (hasteLevel * 0.05f); @@ -3728,7 +3728,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) + @@ -4222,12 +4221,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); @@ -4295,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 279dff0a6d..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 @@ -489,22 +470,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/CalPlayer/CalamityPlayerDrawEffects.cs b/CalPlayer/CalamityPlayerDrawEffects.cs index 19d13db305..971b68da98 100644 --- a/CalPlayer/CalamityPlayerDrawEffects.cs +++ b/CalPlayer/CalamityPlayerDrawEffects.cs @@ -244,6 +244,9 @@ public override void DrawEffects(PlayerDrawSet drawInfo, ref float r, ref float if (calamityPlayer.gsInferno && drawInfo.shadow == 0f) GodSlayerInferno.DrawEffects(drawInfo); + if (calamityPlayer.heavybleeding && drawInfo.shadow == 0f) + HeavyBleeding.DrawEffects(drawInfo); + // Holy Flames, Holy Inferno and Banishing Fire share the same visual effects if (drawInfo.shadow == 0f && (calamityPlayer.hFlames || calamityPlayer.hInferno || calamityPlayer.banishingFire)) { @@ -256,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); diff --git a/CalPlayer/CalamityPlayerHitHurt.cs b/CalPlayer/CalamityPlayerHitHurt.cs index aca930da03..cea12b6330 100644 --- a/CalPlayer/CalamityPlayerHitHurt.cs +++ b/CalPlayer/CalamityPlayerHitHurt.cs @@ -438,6 +438,14 @@ public override bool PreKill(double damage, int hitDirection, bool pvp, ref bool { damageSource = PlayerDeathReason.ByCustomReason(CalamityUtils.GetText("Status.Death.BrainRot" + Main.rand.Next(1, 3 + 1)).Format(Player.name)); } + if (heavybleeding) + { + 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)); @@ -531,7 +539,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 +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 += 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 @@ -1190,8 +1198,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 +1210,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 +1234,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); @@ -1666,7 +1683,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/CalPlayer/CalamityPlayerLifeRegen.cs b/CalPlayer/CalamityPlayerLifeRegen.cs index 590e89edba..a2e2ac01bb 100644 --- a/CalPlayer/CalamityPlayerLifeRegen.cs +++ b/CalPlayer/CalamityPlayerLifeRegen.cs @@ -99,6 +99,8 @@ void ApplyDoTDebuff(bool hasDebuff, int negativeLifeRegenToApply, bool immuneCon ApplyDoTDebuff(weakBrimstoneFlames, 7); 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); @@ -183,7 +185,7 @@ void ApplyDoTDebuff(bool hasDebuff, int negativeLifeRegenToApply, bool immuneCon { alcoholPoisonLevel++; } - if (fabsolVodka) + if (purpleHaze) { alcoholPoisonLevel++; } @@ -263,7 +265,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; @@ -422,9 +424,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 ? 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; } @@ -736,7 +738,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 1dac773f1d..efe279743a 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) @@ -1499,9 +1497,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 @@ -1765,9 +1768,6 @@ private void MiscEffects() if (raiderTalisman && !StealthStrikeAvailable()) Player.GetCritChance() += raiderCritBonus; - if (kamiBoost) - Player.GetDamage() += 0.15f; - if (avertorBonus) Player.GetDamage() += 0.1f; @@ -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) @@ -2723,10 +2723,7 @@ private void OtherBuffEffects() if (Player.chilled) Player.moveSpeed *= 1f + (1f / 6f); - if (cirrusDress) - Player.moveSpeed -= 0.2f; - - if (fabsolVodka) + if (purpleHaze) Player.GetDamage() += 0.08f; if (vodka) @@ -2863,7 +2860,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) + @@ -3616,7 +3613,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. @@ -4020,7 +4019,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/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/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/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/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/CalPlayer/DrawLayers/WingsofRebirthLayer.cs b/CalPlayer/DrawLayers/WingsofRebirthLayer.cs new file mode 100644 index 0000000000..7b58f8fbd3 --- /dev/null +++ b/CalPlayer/DrawLayers/WingsofRebirthLayer.cs @@ -0,0 +1,41 @@ +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, 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/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/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/CalamityLists.cs b/CalamityLists.cs index 0fba8bdfb7..ad14568132 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; @@ -158,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", @@ -179,7 +210,6 @@ public static void LoadLists() "Hans Volter", "Krankwagon", "MishiroUsui", - "pixlgray", "Arkhine", "Lodude", "DevAesthetic", @@ -193,7 +223,6 @@ public static void LoadLists() "Ein", "2Larry2", "Jenonen", - "Dodu", "Arti", "Tervastator", "Luis", @@ -211,7 +240,6 @@ public static void LoadLists() "MovingTarget_086", "Shiro", "Chip", - "Taylor", "ShotgunAngel", "Sandblast", "ThomasThePencil", @@ -236,7 +264,6 @@ public static void LoadLists() "Aleksanders", "TheSilverGhost", "Lucazii", - "Shay", "Prism", "BobIsNotMyRealName", "Guwahavel", @@ -246,7 +273,6 @@ public static void LoadLists() "William", "Arche", "DevilSunrise", - "Yanmei", "Chaos", "Ryan", "Fish Repairs", @@ -351,7 +377,6 @@ public static void LoadLists() "Olkothan", "Vmar98", "Dasdruid", - "Cinder", "Brutzli", "Yhashtur", "Zekai", @@ -691,7 +716,6 @@ public static void LoadLists() "Kaledoulas", "Mohammad", "Skeli_G", - "Arcxus", "Sigil", "Dull", "DjackV", @@ -791,6 +815,8 @@ public static void LoadLists() "Patrera" }; + donatorList = [.. oldDonatorList, .. newDonatorList]; + projectileDestroyExceptionList = new List() { //holdout projectiles @@ -842,7 +868,7 @@ public static void LoadLists() ProjectileType(), ProjectileType(), ProjectileType(), - ProjectileType(), + ProjectileType(), ProjectileType(), ProjectileType(), ProjectileType(), @@ -1521,7 +1547,7 @@ public static void LoadLists() BuffType(), BuffType(), BuffType(), - BuffType(), + BuffType(), BuffType(), BuffType(), BuffType(), @@ -2603,15 +2629,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 +2725,6 @@ public static void UnloadLists() legOverrideList = null; - kamiDebuffColorImmuneList = null; - EncryptedSchematicIDRelationship = null; DisabledSummonerNerfItems = null; 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/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 + + + + + diff --git a/CalamityNetcode.cs b/CalamityNetcode.cs index c498f8c37c..2bf1c92e21 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 // @@ -312,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. @@ -400,6 +456,7 @@ public enum CalamityModMessageType : byte // General things for entities SpawnNPCOnPlayer, SyncNPCMotionDataToServer, + SyncNPCPosAndRotOnly, // Tile Entities PowerCellFactory, @@ -437,6 +494,10 @@ public enum CalamityModMessageType : byte // Music events MusicEventSyncRequest, - MusicEventSyncResponse + MusicEventSyncResponse, + + // Bandit Reforge Refund + SomeoneGotScammedByTinkerer, + WantToRefundReforges } } 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 0000000000..1cacbc5c4a Binary files /dev/null and b/Cooldowns/SuperradiantSawBoost.png differ diff --git a/Cooldowns/SuperradiantSawBoostOutline.png b/Cooldowns/SuperradiantSawBoostOutline.png new file mode 100644 index 0000000000..245f680cb5 Binary files /dev/null and b/Cooldowns/SuperradiantSawBoostOutline.png differ diff --git a/Cooldowns/SuperradiantSawBoostOverlay.png b/Cooldowns/SuperradiantSawBoostOverlay.png new file mode 100644 index 0000000000..da21d02b34 Binary files /dev/null and b/Cooldowns/SuperradiantSawBoostOverlay.png differ 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 0000000000..06bc3ffb44 Binary files /dev/null and b/Effects/SylvestaffProjectileShader.xnb differ diff --git a/Effects/SylvestaffRibbonShader.fx b/Effects/SylvestaffRibbonShader.fx new file mode 100644 index 0000000000..3474df6d49 --- /dev/null +++ b/Effects/SylvestaffRibbonShader.fx @@ -0,0 +1,89 @@ +sampler noiseTextureA : register(s1); + +float pixelationFactor; +float uSaturation; +float4 uShaderSpecificData; +matrix uWorldViewProjection; + +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; +} + +float QuadraticBump(float x) +{ + return x * (4 - x * 4); +} + +float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 +{ + float4 color = 1; + float2 coords = input.TextureCoordinates; + coords.y = (coords.y - 0.5) / input.TextureCoordinates.z + 0.5; + + float feelerColorStart = 0.61; + float colorSpacingFactor = 1.9; + float4 outlineColor = float4(91, 114, 119, 255) / 255; + + float erasePixelInterpolant = coords.x - 0.9 - distance(coords.y, 0.5) * 0.1; + + // Band 1: Outline color. + color = lerp(color, outlineColor, coords.x >= 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 0000000000..d6848767d4 Binary files /dev/null and b/Effects/SylvestaffRibbonShader.xnb differ 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/ExtraTextures/BloomCirclePinpoint.png b/ExtraTextures/BloomCirclePinpoint.png new file mode 100644 index 0000000000..49c2dcdb60 Binary files /dev/null and b/ExtraTextures/BloomCirclePinpoint.png differ diff --git a/ExtraTextures/Trails/FabstaffStreak.png b/ExtraTextures/Trails/SylvestaffStreak.png similarity index 100% rename from ExtraTextures/Trails/FabstaffStreak.png rename to ExtraTextures/Trails/SylvestaffStreak.png diff --git a/Gores/BuzzkillSaw1.png b/Gores/BuzzkillSaw1.png new file mode 100644 index 0000000000..c79c2667d9 Binary files /dev/null and b/Gores/BuzzkillSaw1.png differ diff --git a/Gores/BuzzkillSaw2.png b/Gores/BuzzkillSaw2.png new file mode 100644 index 0000000000..aa8e09a0db Binary files /dev/null and b/Gores/BuzzkillSaw2.png differ diff --git a/Gores/BuzzkillSaw3.png b/Gores/BuzzkillSaw3.png new file mode 100644 index 0000000000..aa75e67d97 Binary files /dev/null and b/Gores/BuzzkillSaw3.png differ diff --git a/Graphics/Primitives/IPixelatedPrimitiveRenderer.cs b/Graphics/Primitives/IPixelatedPrimitiveRenderer.cs index 7270d3e93a..14edbcb506 100644 --- a/Graphics/Primitives/IPixelatedPrimitiveRenderer.cs +++ b/Graphics/Primitives/IPixelatedPrimitiveRenderer.cs @@ -15,6 +15,6 @@ public interface IPixelatedPrimitiveRenderer /// /// 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 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/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/Graphics/Renderers/RendererManager.cs b/Graphics/Renderers/RendererManager.cs index 4844fd81cb..1505780208 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); @@ -110,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); @@ -124,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); @@ -138,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); @@ -151,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); } @@ -167,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/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..6c25b66d76 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(() => @@ -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,8 @@ public static void ShimmerEffectEdits(Terraria.On_Item.orig_GetShimmered orig, I { orig(self); } - } + }*/ #endregion + } } 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/Items/Accessories/Vanity/Birds_Head.png b/Items/Accessories/Vanity/Birds_Head.png deleted file mode 100644 index e475326c77..0000000000 Binary files a/Items/Accessories/Vanity/Birds_Head.png and /dev/null differ diff --git a/Items/Accessories/Vanity/Birds_Head_Extension.png b/Items/Accessories/Vanity/Birds_Head_Extension.png deleted file mode 100644 index 99dd209e3e..0000000000 Binary files a/Items/Accessories/Vanity/Birds_Head_Extension.png and /dev/null differ diff --git a/Items/Accessories/Vanity/Birds_Legs.png b/Items/Accessories/Vanity/Birds_Legs.png deleted file mode 100644 index 87cee93548..0000000000 Binary files a/Items/Accessories/Vanity/Birds_Legs.png and /dev/null differ diff --git a/Items/Accessories/Vanity/Birds_Torso.png b/Items/Accessories/Vanity/Birds_Torso.png deleted file mode 100644 index 9a4ac6d766..0000000000 Binary files a/Items/Accessories/Vanity/Birds_Torso.png and /dev/null differ 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 3b69e78dca..0000000000 Binary files a/Items/Accessories/Vanity/CocosFeather.png and /dev/null differ 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 d0faf45977..0000000000 Binary files a/Items/Accessories/Vanity/CrystalHeartVodka.png and /dev/null differ diff --git a/Items/Accessories/Vanity/Fabsol_Back.png b/Items/Accessories/Vanity/Fabsol_Back.png deleted file mode 100644 index 1563280bdc..0000000000 Binary files a/Items/Accessories/Vanity/Fabsol_Back.png and /dev/null differ diff --git a/Items/Accessories/Vanity/Fabsol_Body.png b/Items/Accessories/Vanity/Fabsol_Body.png deleted file mode 100644 index d98fdec79c..0000000000 Binary files a/Items/Accessories/Vanity/Fabsol_Body.png and /dev/null differ diff --git a/Items/Accessories/Vanity/Fabsol_Head.png b/Items/Accessories/Vanity/Fabsol_Head.png deleted file mode 100644 index bf96b48a95..0000000000 Binary files a/Items/Accessories/Vanity/Fabsol_Head.png and /dev/null differ diff --git a/Items/Accessories/Vanity/Fabsol_Legs.png b/Items/Accessories/Vanity/Fabsol_Legs.png deleted file mode 100644 index 1156798b60..0000000000 Binary files a/Items/Accessories/Vanity/Fabsol_Legs.png and /dev/null differ diff --git a/Items/Accessories/Wings/DrewsWings.png b/Items/Accessories/Wings/DrewsWings.png deleted file mode 100644 index bd8707e1c3..0000000000 Binary files a/Items/Accessories/Wings/DrewsWings.png and /dev/null differ diff --git a/Items/Accessories/Wings/DrewsWings_Wings.png b/Items/Accessories/Wings/DrewsWings_Wings.png deleted file mode 100644 index 131487a6d7..0000000000 Binary files a/Items/Accessories/Wings/DrewsWings_Wings.png and /dev/null differ 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 54% rename from Items/Accessories/Wings/DrewsWings.cs rename to Items/Accessories/Wings/WingsofRebirth.cs index 30ec3ec6d8..cbce428ecc 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,44 @@ 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; // FPS + int maxFrames = 9; // Total frames + player.wingFrameCounter++; + // Start flight animation with frame 7 + if (player.wingFrame == 0) + { + player.wingFrame = 7; + } + // Reset frames + if (player.wingFrame >= maxFrames) + { + player.wingFrameCounter = 0; + player.wingFrame = 1; + } + // Animation + if (player.wingFrameCounter % frameRate == 0) + { + player.wingFrame++; + } + } + else + { + player.wingFrameCounter = 0; + player.wingFrame = 0; // On ground + if (player.velocity.Y != 0) + { + player.wingFrame = 2; // Falling + if (player.controlJump && player.velocity.Y > 0) + player.wingFrame = 1; // Gliding + } + } + 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 0000000000..ee575d23ab Binary files /dev/null and b/Items/Accessories/Wings/WingsofRebirth.png differ diff --git a/Items/Accessories/Wings/WingsofRebirth_Wings.png b/Items/Accessories/Wings/WingsofRebirth_Wings.png new file mode 100644 index 0000000000..08ddcaa27a Binary files /dev/null and b/Items/Accessories/Wings/WingsofRebirth_Wings.png differ diff --git a/Items/Accessories/Wings/WingsofRebirth_Wings_Real.png b/Items/Accessories/Wings/WingsofRebirth_Wings_Real.png new file mode 100644 index 0000000000..df66a0fb83 Binary files /dev/null and b/Items/Accessories/Wings/WingsofRebirth_Wings_Real.png differ diff --git a/Items/AlicornonaStick.png b/Items/AlicornonaStick.png deleted file mode 100644 index b09e99c934..0000000000 Binary files a/Items/AlicornonaStick.png and /dev/null differ 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 8bd29e2f48..0000000000 Binary files a/Items/Armor/CirrusDress.png and /dev/null differ diff --git a/Items/Armor/CirrusDress_Body.png b/Items/Armor/CirrusDress_Body.png deleted file mode 100644 index 779ae0e094..0000000000 Binary files a/Items/Armor/CirrusDress_Body.png and /dev/null differ diff --git a/Items/Armor/CirrusDress_Legs.png b/Items/Armor/CirrusDress_Legs.png deleted file mode 100644 index 42e4842b43..0000000000 Binary files a/Items/Armor/CirrusDress_Legs.png and /dev/null differ diff --git a/Items/CalamityGlobalItem.cs b/Items/CalamityGlobalItem.cs index 077b34fc84..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); @@ -1808,11 +1807,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/CalamityGlobalItemTooltip.cs b/Items/CalamityGlobalItemTooltip.cs index 9830d5d689..67ff14b193 100644 --- a/Items/CalamityGlobalItemTooltip.cs +++ b/Items/CalamityGlobalItemTooltip.cs @@ -86,14 +86,12 @@ 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); // Developer items - if (item.type == ModContent.ItemType()) - 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()) @@ -102,6 +100,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()) @@ -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%")); @@ -447,7 +443,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); @@ -602,9 +598,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) @@ -616,7 +618,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"); } @@ -640,7 +642,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 +838,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/Items/AlicornonaStick.cs b/Items/ColdheartIcicle.cs similarity index 87% rename from Items/AlicornonaStick.cs rename to Items/ColdheartIcicle.cs index 4f30a42f0b..97ffcaadf8 100644 --- a/Items/AlicornonaStick.cs +++ b/Items/ColdheartIcicle.cs @@ -10,7 +10,8 @@ namespace CalamityMod.Items { - public class AlicornonaStick : ModItem, ILocalizedModType + [LegacyName("AlicornonaStick")] + public class ColdheartIcicle : ModItem, ILocalizedModType { public new string LocalizationCategory => "Items.Misc"; public override void SetDefaults() @@ -22,6 +23,17 @@ public override void SetDefaults() Item.rare = ModContent.RarityType(); } + public override void HoldStyle(Player player, Rectangle heldItemFrame) + { + 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) { int offset = player.direction == 1 ? 5 : -Item.width - 5; diff --git a/Items/ColdheartIcicle.png b/Items/ColdheartIcicle.png new file mode 100644 index 0000000000..a8efd6e769 Binary files /dev/null and b/Items/ColdheartIcicle.png differ diff --git a/Items/Mounts/AlicornMount.cs b/Items/Mounts/AlicornMount.cs deleted file mode 100644 index d1f8acca61..0000000000 --- a/Items/Mounts/AlicornMount.cs +++ /dev/null @@ -1,150 +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 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(); - 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 b544a94ba8..0000000000 Binary files a/Items/Mounts/AlicornMountExtra.png and /dev/null differ diff --git a/Items/Mounts/AlicornMount_Back.png b/Items/Mounts/AlicornMount_Back.png deleted file mode 100644 index fcb20c4308..0000000000 Binary files a/Items/Mounts/AlicornMount_Back.png and /dev/null differ diff --git a/Items/Mounts/AlicornMount_Front.png b/Items/Mounts/AlicornMount_Front.png deleted file mode 100644 index 821fd8bbfc..0000000000 Binary files a/Items/Mounts/AlicornMount_Front.png and /dev/null differ 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/Mounts/Fabsol.cs b/Items/Mounts/Fabsol.cs deleted file mode 100644 index 781964dd61..0000000000 --- a/Items/Mounts/Fabsol.cs +++ /dev/null @@ -1,27 +0,0 @@ -using CalamityMod.Rarities; -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Items.Mounts -{ - public class Fabsol : ModItem, ILocalizedModType - { - public new string LocalizationCategory => "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 485a6245d0..0000000000 Binary files a/Items/Mounts/Fabsol.png and /dev/null differ diff --git a/Items/PermanentBoosters/CelestialOnion.cs b/Items/PermanentBoosters/CelestialOnion.cs index 4db480cb29..0e790e4617 100644 --- a/Items/PermanentBoosters/CelestialOnion.cs +++ b/Items/PermanentBoosters/CelestialOnion.cs @@ -1,5 +1,4 @@ using CalamityMod.CalPlayer; -using CalamityMod.World; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -53,6 +52,7 @@ public override bool IsEnabled() return Player.Calamity().extraAccessoryML; } + public override bool IsHidden() => IsEmpty && !IsEnabled(); } } diff --git a/Items/Placeables/Furniture/CirrusCouch.cs b/Items/Placeables/Furniture/CirrusCouch.cs deleted file mode 100644 index a7c10b5b24..0000000000 --- a/Items/Placeables/Furniture/CirrusCouch.cs +++ /dev/null @@ -1,25 +0,0 @@ -using CalamityMod.Tiles.Furniture.CraftingStations; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Items.Placeables.Furniture -{ - public class CirrusCouch : ModItem, ILocalizedModType - { - public new string LocalizationCategory => "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 3d0e1a4ba3..0000000000 Binary files a/Items/Placeables/Furniture/CirrusCouch.png and /dev/null differ diff --git a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs index 63db3bcde1..2c66964de0 100644 --- a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs +++ b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs @@ -59,42 +59,49 @@ 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", "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", "Mishiro Usui", "Moonburn", - "Mr.Small", "Nycro", "Ozzatron", "Piky", + "Poroboros", "PokerFace", + "Raesh", + "Sagittariod", "Shade", - "SharZz", "Shayy", "Spider Prov", "StipulateVenus", + "Tobias", "Triangle", + "TYESKI (Universe)", "Uncle Danny", "Xyk", "YuH", @@ -112,7 +119,6 @@ public override void ModifyTooltips(List tooltips) "Blockaroz", "Boffin", "Bravioli", - "CDMusic", "Chetto", "Chill Dude", "Cobalion", @@ -120,7 +126,6 @@ public override void ModifyTooltips(List tooltips) "DarkTiny", "Demik", "DM Dokuro", - "Dominic Karma", "Done", "Doog", "drh", @@ -151,7 +156,9 @@ public override void ModifyTooltips(List tooltips) "L0st", "Leon", "Leviathan", + "Lilac Olligoci", "Lompl Allimath", + "Lucille Karma", "MarieArk", "Minecat", "Mrrp", @@ -166,7 +173,6 @@ public override void ModifyTooltips(List tooltips) "Phantasmal Deathray", "Phupperbat", "Pinkie Poss", - "pixlgray", "Poly", "Popo", "President Waluigi", @@ -176,6 +182,7 @@ public override void ModifyTooltips(List tooltips) "Runefield", "Sargassum", "sentri", + "SharZz", "Shucks", "Silver-Lord of Ash", "SixteenInMono", diff --git a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.png b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.png index 87e86d9bcb..157df9cb45 100644 Binary files a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.png and b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.png differ 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/OldFashioned.png b/Items/Potions/Alcohol/OldFashioned.png index fddbd65368..c46adf86ba 100644 Binary files a/Items/Potions/Alcohol/OldFashioned.png and b/Items/Potions/Alcohol/OldFashioned.png differ diff --git a/Items/Potions/Alcohol/FabsolsVodka.cs b/Items/Potions/Alcohol/PurpleHaze.cs similarity index 85% rename from Items/Potions/Alcohol/FabsolsVodka.cs rename to Items/Potions/Alcohol/PurpleHaze.cs index 4ca2edb060..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,14 +6,14 @@ namespace CalamityMod.Items.Potions.Alcohol { - public class FabsolsVodka : ModItem, ILocalizedModType + [LegacyName("FabsolsVodka")] + public class PurpleHaze : ModItem, ILocalizedModType { public new string LocalizationCategory => "Items.Potions"; public override void SetStaticDefaults() { Item.ResearchUnlockCount = 5; - ItemID.Sets.ShimmerTransformToItem[Type] = ModContent.ItemType(); } public override void SetDefaults() @@ -29,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/Items/Potions/Alcohol/RedWine.cs b/Items/Potions/Alcohol/RedWine.cs index 5f3cc7a515..8d784c9097 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; @@ -30,15 +31,31 @@ 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) { 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..e52460a926 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; @@ -32,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) { @@ -48,7 +50,22 @@ 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(); } } } 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/Potions/Fabsoup.cs b/Items/Potions/LavaChickenBroth.cs similarity index 92% rename from Items/Potions/Fabsoup.cs rename to Items/Potions/LavaChickenBroth.cs index e532b991b1..042ad6d6c2 100644 --- a/Items/Potions/Fabsoup.cs +++ b/Items/Potions/LavaChickenBroth.cs @@ -8,7 +8,8 @@ namespace CalamityMod.Items.Potions { - public class Fabsoup : ModItem, ILocalizedModType + [LegacyName("Fabsoup")] + public class LavaChickenBroth : 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(1525); // 25 minutes, 25 seconds if (player.itemAnimation == 180) { player.AddBuff(BuffID.WellFed3, time); diff --git a/Items/Potions/Fabsoup.png b/Items/Potions/LavaChickenBroth.png similarity index 100% rename from Items/Potions/Fabsoup.png rename to Items/Potions/LavaChickenBroth.png diff --git a/Items/SummonItems/Invasion/CausticTear.cs b/Items/SummonItems/Invasion/CausticTear.cs index 2de57c9d47..6f76b9d06b 100644 --- a/Items/SummonItems/Invasion/CausticTear.cs +++ b/Items/SummonItems/Invasion/CausticTear.cs @@ -38,8 +38,12 @@ public override bool CanUseItem(Player player) public override bool? UseItem(Player player) { - CalamityNetcode.SyncWorld(); - AcidRainEvent.TryStartEvent(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 + } return true; } diff --git a/Items/SummonItems/Invasion/MartianDistressRemote.cs b/Items/SummonItems/Invasion/MartianDistressRemote.cs index 965b1b0ff3..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; @@ -35,11 +36,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/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/Items/Tools/ClimateChange/AridArtifact.cs b/Items/Tools/ClimateChange/AridArtifact.cs index 759f43754d..678ca85d32 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,10 +28,12 @@ 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(); 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/Items/TreasureBags/MiscGrabBags/StarterBag.cs b/Items/TreasureBags/MiscGrabBags/StarterBag.cs index 54fe68cbde..9a2c56c9eb 100644 --- a/Items/TreasureBags/MiscGrabBags/StarterBag.cs +++ b/Items/TreasureBags/MiscGrabBags/StarterBag.cs @@ -109,26 +109,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) - { - string playerName = info.player.name; - return playerName is "Fabsol" or "Cirrus"; - } - - itemLoot.AddIf(getsCrystalHeartVodka, ModContent.ItemType()); } } } diff --git a/Items/TreasureBags/YharonBag.cs b/Items/TreasureBags/YharonBag.cs index e56cc657c5..5b93ae9cd0 100644 --- a/Items/TreasureBags/YharonBag.cs +++ b/Items/TreasureBags/YharonBag.cs @@ -78,7 +78,7 @@ public override void ModifyItemLoot(ItemLoot itemLoot) itemLoot.Add(ModContent.ItemType(), 10); // Equipment - itemLoot.Add(ModContent.ItemType()); + itemLoot.Add(ModContent.ItemType()); itemLoot.Add(ModContent.ItemType()); itemLoot.AddRevBagAccessories(); 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 4a5c496127..0000000000 Binary files a/Items/Weapons/Magic/DivineRetribution.png and /dev/null differ 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 6658464065..0000000000 Binary files a/Items/Weapons/Magic/Fabstaff.png and /dev/null differ diff --git a/Items/Weapons/Magic/Sylvestaff.cs b/Items/Weapons/Magic/Sylvestaff.cs new file mode 100644 index 0000000000..0ea7f24ea9 --- /dev/null +++ b/Items/Weapons/Magic/Sylvestaff.cs @@ -0,0 +1,121 @@ +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; + } + + // Hacky workaround to making the holdout not consume mana + public override void OnConsumeMana(Player player, int manaConsumed) + { + if (player.ownedProjectileCounts[Item.shoot] <= 0) + player.statMana += manaConsumed; + } + 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 0000000000..2cd1d31e38 Binary files /dev/null and b/Items/Weapons/Magic/SylvestaffGold.png differ diff --git a/Items/Weapons/Magic/SylvestaffPlatinum.png b/Items/Weapons/Magic/SylvestaffPlatinum.png new file mode 100644 index 0000000000..c611c58ea1 Binary files /dev/null and b/Items/Weapons/Magic/SylvestaffPlatinum.png differ diff --git a/Items/Weapons/Melee/Azathoth.cs b/Items/Weapons/Melee/Ozzathoth.cs similarity index 91% rename from Items/Weapons/Melee/Azathoth.cs rename to Items/Weapons/Melee/Ozzathoth.cs index 3685b98f2f..60253d28d3 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() @@ -35,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/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/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/Items/Weapons/Ranged/Butcher.png b/Items/Weapons/Ranged/Butcher.png deleted file mode 100644 index 49ddff2d33..0000000000 Binary files a/Items/Weapons/Ranged/Butcher.png and /dev/null differ 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 0000000000..7ec3235634 Binary files /dev/null and b/Items/Weapons/Ranged/Buzzkill.png differ 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 d78a7a37f7..0000000000 Binary files a/Items/Weapons/Ranged/DodusHandcannon.png and /dev/null differ diff --git a/Items/Weapons/Ranged/ElementalBlaster.cs b/Items/Weapons/Ranged/ElementalBlaster.cs deleted file mode 100644 index 50c96f5885..0000000000 --- a/Items/Weapons/Ranged/ElementalBlaster.cs +++ /dev/null @@ -1,53 +0,0 @@ -using CalamityMod.Items.Materials; -using CalamityMod.Projectiles.Ranged; -using CalamityMod.Sounds; -using Microsoft.Xna.Framework; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Items.Weapons.Ranged -{ - public class ElementalBlaster : ModItem, ILocalizedModType - { - public new string LocalizationCategory => "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 3ce7de1a2c..0000000000 Binary files a/Items/Weapons/Ranged/ElementalBlaster.png and /dev/null differ 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..5de64c7352 --- /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 = 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 = new Color(120, 255, 120); + } + } + + 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(5). + AddTile(TileID.MythrilAnvil). + Register(); + } + } +} diff --git a/Items/Weapons/Ranged/SuperradiantSlaughterer.png b/Items/Weapons/Ranged/SuperradiantSlaughterer.png new file mode 100644 index 0000000000..7dc18da67a Binary files /dev/null and b/Items/Weapons/Ranged/SuperradiantSlaughterer.png differ 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; 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/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 b7f214f8f4..0000000000 Binary files a/Items/Weapons/Typeless/YanmeisKnife.png and /dev/null differ 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.Buffs.hjson b/Localization/en-US/Mods.CalamityMod.Buffs.hjson index e7843c0e46..9cfdbd430a 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 @@ -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: { @@ -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 @@ -243,11 +253,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 @@ -453,29 +458,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: { @@ -493,11 +483,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! @@ -520,7 +525,7 @@ AstralInjectionBuff: { BaguetteBuff: { DisplayName: Baguette - Description: "[c/B00BA5:'If only I knew...' ~Cirrus]" + Description: Goes well with Red Wine } BloodfinBoost: { @@ -763,11 +768,6 @@ IceShieldBuff: { Description: Absorbs 20% damage from the next hit you take, then shatters } -KamiBuff: { - DisplayName: Kami Injection - Description: 15% increased max movement speed, acceleration and damage -} - Mushy: { DisplayName: Mushy Description: Increased defense by 6 and life regen by 1HP/s @@ -947,11 +947,6 @@ Irradiated: { Description: Your skin is burning off } -KamiFlu: { - DisplayName: Kami Flu - Description: Defenseless and dying -} - MarkedforDeath: { DisplayName: Marked for Death Description: Damage reduction reduced 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..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' ''' } @@ -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..57bfda5f1f 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 +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 @@ -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] @@ -1322,7 +1322,7 @@ Radiance: { Tooltip: ''' +70 max life - Grants +2 to +6 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 @@ -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 our supporters who made this mod a reality! ''' StatsList: ''' @@ -2021,16 +2021,6 @@ AbandonedWulfrumHelmet: { ''' } -CrystalHeartVodka: { - DisplayName: Crystal Heart Vodka - 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/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.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.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.Misc.hjson b/Localization/en-US/Mods.CalamityMod.Items.Misc.hjson index 119da60e37..35996f701a 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: "'N(ice) work'" +} + MomentumCapacitor: { DisplayName: Momentum Capacitor Tooltip: 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/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/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson b/Localization/en-US/Mods.CalamityMod.Items.Potions.hjson index 94bfd6c74c..1817c32878 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: "" @@ -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!'] ''' } @@ -191,10 +190,9 @@ 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?'] ''' } @@ -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,18 +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.'] - ''' -} - -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 ''' } @@ -250,7 +234,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 +243,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 +254,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 +264,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 +274,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 +295,16 @@ 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.'] + ''' +} + +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 ''' } @@ -326,7 +314,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 +324,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 +334,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 +345,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 +355,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 +365,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 +375,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 +385,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 +395,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.'] ''' } 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/Localization/en-US/Mods.CalamityMod.Items.Weapons.Magic.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Magic.hjson index 9960bc50ca..8780824a1b 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Magic.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Magic.hjson @@ -224,11 +224,6 @@ DeathValleyDuster: { Tooltip: Casts a large blast of dust } -DivineRetribution: { - DisplayName: Divine Retribution - Tooltip: Mage is superior to rogue; look, we got a donor weapon to prove it! -} - Downpour: { DisplayName: Downpour Tooltip: @@ -299,11 +294,6 @@ EvergladeSpray: { Tooltip: Fires a stream of burning green ichor } -Fabstaff: { - DisplayName: Fabstaff - Tooltip: Casts a bouncing beam that splits when enemies are near it -} - FaceMelter: { DisplayName: Face Melter Tooltip: @@ -766,6 +756,15 @@ SubsumingVortex: { ''' } +Sylvestaff: { + DisplayName: Sylvestaff + Tooltip: + ''' + Casts a bouncing beam that splits when enemies are near it + 'Also known as the Karma Staff!' + ''' +} + TacticiansTrumpCard: { DisplayName: Tactician's Trump Card Tooltip: diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Melee.hjson index bc3c0004e7..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: @@ -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.Ranged.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson index d15cb408ad..df009fe392 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 ''' } @@ -211,12 +211,14 @@ BulletFilledShotgun: { ''' } -Butcher: { - DisplayName: Butcher +Buzzkill: { + DisplayName: Buzzkill Tooltip: ''' - Fires bullets faster and more accurately the longer you hold the trigger - 25% chance to save ammo + 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' ''' } @@ -400,15 +402,6 @@ Disseminator: { ''' } -DodusHandcannon: { - DisplayName: Dodu's Handcannon - Tooltip: - ''' - Fires high explosive peanut shells, literally - 'The power of the nut rests in your hands' - ''' -} - DragonsBreath: { DisplayName: Dragon's Breath Tooltip: @@ -433,15 +426,6 @@ Drataliornus: { ''' } -ElementalBlaster: { - DisplayName: Elemental Blaster - Tooltip: - ''' - Fires a storm of rainbow blasts - Does not consume ammo - ''' -} - ElementalEruption: { DisplayName: Elemental Eruption Tooltip: @@ -1160,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 ''' } @@ -1229,6 +1214,30 @@ SulphuricAcidCannon: { Tooltip: Fires an acidic shot that sticks to enemies and dissolves them } +SuperradiantSlaughterer: { + DisplayName: Superradiant Slaughterer + Tooltip: + ''' + [MAIN] + [ALT] + [c/c91a1a:'No one knows how it turns blood into rainbows...'] + ''' + MainInfo: + ''' + 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 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, fired buzzsaws home in on the cursor and will release homing bolts while returning + ''' +} + SurgeDriver: { DisplayName: Surge Driver Tooltip: 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/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.Items.Weapons.Typeless.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Typeless.hjson index b9a504451c..f04fbb07bf 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Typeless.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Typeless.hjson @@ -66,15 +66,3 @@ StarStruckWater: { DisplayName: Star Struck Water Tooltip: Spreads the Astral Infection to some blocks } - -YanmeisKnife: { - DisplayName: Yanmei's Knife - Tooltip: - ''' - Enemies you hit are crippled - Hits will also give you enhanced movement speed and damage for 10 seconds - 'A knife from an unknown world - An owner whose heart is pure and free of taint - A heart of iron and valor' - ''' -} 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/Localization/en-US/Mods.CalamityMod.NPCs.hjson b/Localization/en-US/Mods.CalamityMod.NPCs.hjson index 42d943f37f..2e1b5a6a8e 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 @@ -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 @@ -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. @@ -578,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!" } } @@ -600,12 +503,13 @@ 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. } 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. @@ -623,7 +527,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.Projectiles.Boss.hjson b/Localization/en-US/Mods.CalamityMod.Projectiles.Boss.hjson index b9a91f0fb0..b80a84b202 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: Absolute Ultra Zero +PermafrostBlast.DisplayName: Permafrost's Gigablast +PermafrostBlaster.DisplayName: Blaster of Unlimited Air Conditioning +PermafrostColdheartIcicle.DisplayName: Coldheart Icicle +PermafrostMeat.DisplayName: Cool Meat diff --git a/Localization/en-US/Mods.CalamityMod.Projectiles.Magic.hjson b/Localization/en-US/Mods.CalamityMod.Projectiles.Magic.hjson index 7c05554882..9870eb6c29 100644 --- a/Localization/en-US/Mods.CalamityMod.Projectiles.Magic.hjson +++ b/Localization/en-US/Mods.CalamityMod.Projectiles.Magic.hjson @@ -56,7 +56,6 @@ CryoBlast.DisplayName: Cryo Blast DarkSparkBeam.DisplayName: Dark Spark Beam DarkSparkPrism.DisplayName: Dark Crystal DeathhailBeam.DisplayName: Deathhail -DivineRetributionSpear.DisplayName: Divine Retribution DustProjectile.DisplayName: Death Valley Dust EelDrop.DisplayName: Acid Eel Drop EidolicWailSoundwave.DisplayName: Eidolic Wail @@ -72,8 +71,6 @@ EventHorizonStar.DisplayName: Event Horizon Star EvergladeSprayProjectile.DisplayName: Everglade Spray ExoVortex.DisplayName: Subsuming Vortex ExoVortex2.DisplayName: Subsuming Vortex -FabBolt.DisplayName: Fab Bolt -FabRay.DisplayName: Fab Ray FatesRevealFlame.DisplayName: Fate's Reveal FlamingPumpkin.DisplayName: Pumpkin FlareBoltProjectile.DisplayName: Flare Bolt @@ -221,6 +218,8 @@ StardustElementalBeam.DisplayName: Stardust Beam StickyFeather.DisplayName: Feather SupremeDustFlakProjectile.DisplayName: Earthy Dust SupremeDustProjectile.DisplayName: Earthy Dust +SylvBolt.DisplayName: Sylv Bolt +SylvRay.DisplayName: Sylv Ray TacticiansElectricBoom.DisplayName: Electric Explosion TacticiansTrumpCardProj.DisplayName: Trump Beam TearsofHeavenProjectile.DisplayName: Tears of Heaven diff --git a/Localization/en-US/Mods.CalamityMod.Projectiles.Ranged.hjson b/Localization/en-US/Mods.CalamityMod.Projectiles.Ranged.hjson index 0b711900a8..846e7cd6bc 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 @@ -103,7 +104,6 @@ GoliathRocket.DisplayName: Goliath Rocket HalleysComet.DisplayName: Halley's Comet HandheldTankShell.DisplayName: Tank Shell HeavenlyGaleProj.DisplayName: Heavenly Gale -HighExplosivePeanutShell.DisplayName: High Explosive Peanut Shell HiveBomb.DisplayName: Hive Bomb HiveMissile.DisplayName: Hive Missile HiveNuke.DisplayName: Hive Nuke @@ -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.Projectiles.Typeless.hjson b/Localization/en-US/Mods.CalamityMod.Projectiles.Typeless.hjson index f7c34ecdda..20e7061c0b 100644 --- a/Localization/en-US/Mods.CalamityMod.Projectiles.Typeless.hjson +++ b/Localization/en-US/Mods.CalamityMod.Projectiles.Typeless.hjson @@ -132,5 +132,4 @@ WulfrumBobber.DisplayName: Wulfrum Bobber WulfrumDiggingTurtleProjectile.DisplayName: Digging Turtle WulfrumHook.DisplayName: Wulfrum Slingshot WulfrumLureSignal.DisplayName: Signal -YanmeisKnifeSlash.DisplayName: Yanmei's Knife YellowLabSeeker.DisplayName: Seeking Mechanism 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.Status.Death.hjson b/Localization/en-US/Mods.CalamityMod.Status.Death.hjson index 7a65173f13..485fdf71e0 100644 --- a/Localization/en-US/Mods.CalamityMod.Status.Death.hjson +++ b/Localization/en-US/Mods.CalamityMod.Status.Death.hjson @@ -63,10 +63,16 @@ 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." 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/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: diff --git a/Localization/en-US/Mods.CalamityMod.Vanilla.hjson b/Localization/en-US/Mods.CalamityMod.Vanilla.hjson index 4373a9e37f..be5d739521 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,17 +144,12 @@ 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? } -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! -} +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! @@ -168,12 +159,7 @@ 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. -} +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/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/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/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/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/CalamityAIs/CalamityBossAIs/AquaticScourgeAI.cs b/NPCs/CalamityAIs/CalamityBossAIs/AquaticScourgeAI.cs index 2ddd4e677e..4c26323e9e 100644 --- a/NPCs/CalamityAIs/CalamityBossAIs/AquaticScourgeAI.cs +++ b/NPCs/CalamityAIs/CalamityBossAIs/AquaticScourgeAI.cs @@ -213,7 +213,6 @@ public static void VanillaAquaticScourgeAI(NPC npc, Mod mod, bool head) bool immuneToSlowingDebuffs = doSpiral || getFuckedAI; 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/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/CalamityAIs/CalamityBossAIs/OldDukeAI.cs b/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs index 7383afb7d4..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 @@ -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/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/CalamityGlobalNPC.cs b/NPCs/CalamityGlobalNPC.cs index b2a4ed9359..adb0f3c8c8 100644 --- a/NPCs/CalamityGlobalNPC.cs +++ b/NPCs/CalamityGlobalNPC.cs @@ -244,6 +244,8 @@ public partial class CalamityGlobalNPC : GlobalNPC public int pearlAura = 0; 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; @@ -278,7 +280,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; @@ -463,6 +464,8 @@ public override GlobalNPC Clone(NPC npc, NPC npcClone) myClone.pearlAura = pearlAura; myClone.bBlood = bBlood; myClone.brainRot = brainRot; + myClone.heavybleeding = heavybleeding; + myClone.laceration = laceration; myClone.elementalMix = elementalMix; myClone.marked = marked; myClone.absorberAffliction = absorberAffliction; @@ -493,7 +496,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 +1054,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) { @@ -1114,6 +1109,10 @@ 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 (laceration > 0) + ApplyDPSDebuff(400, 100, ref npc.lifeRegen, ref damage); if (elementalMix > 0) ApplyDPSDebuff(400, 80, ref npc.lifeRegen, ref damage); if (miracleBlight > 0) @@ -1521,8 +1520,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. @@ -3222,17 +3221,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; @@ -3270,8 +3269,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 +5063,6 @@ public override void PostAI(NPC npc) webbed--; if (slowed > 0) slowed--; - if (kamiFlu > 0) - kamiFlu--; if (vaporfied > 0) vaporfied--; @@ -5079,6 +5074,10 @@ public override void PostAI(NPC npc) bBlood--; if (brainRot > 0) brainRot--; + if (heavybleeding > 0) + heavybleeding--; + if (laceration > 0) + laceration--; if (elementalMix > 0) elementalMix--; if (vulnerabilityHex > 0) @@ -5124,8 +5123,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 +5207,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)); - } } } @@ -6012,17 +6005,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) { @@ -6190,8 +6172,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; @@ -6383,6 +6364,12 @@ 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); + + 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); @@ -6555,9 +6542,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); @@ -6579,7 +6563,9 @@ 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/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), @@ -6601,7 +6587,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/CalamityGlobalNPCLoot.cs b/NPCs/CalamityGlobalNPCLoot.cs index 6b875b8cad..34e5d7488f 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; @@ -162,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; @@ -225,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; @@ -1564,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 @@ -1834,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) @@ -1846,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) @@ -1856,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) @@ -1864,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 @@ -1900,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 abf91440b3..d6e06146e4 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; @@ -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 = { @@ -77,7 +78,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) }; @@ -89,12 +89,14 @@ public static float TaxYieldFactor private static readonly string[] CyborgNames = { "Sylux", // <@!331812782183809025> (gonkachino) + "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 = { @@ -117,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 = @@ -136,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 = { @@ -144,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 = { @@ -170,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 = { @@ -179,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 = { @@ -188,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 = { @@ -212,33 +230,34 @@ 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 = { - "Mage One-Trick", // <@!340996105460514816> (pixlgray) "Inorim, son of Ivukey", "Jensen", "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) }; @@ -263,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 = { @@ -297,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 = { @@ -309,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; @@ -318,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; @@ -670,7 +699,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 }; @@ -750,7 +778,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()); @@ -804,10 +831,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"); @@ -845,8 +869,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: @@ -895,8 +917,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: @@ -904,8 +924,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) @@ -934,8 +952,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) @@ -948,8 +964,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: @@ -978,15 +992,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; @@ -1095,16 +1102,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,8 +1143,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), Condition.HappyEnoughToSellPylons); } if (type == NPCID.Cyborg) @@ -1152,21 +1158,20 @@ 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) - .Add(ItemType()) - .AddWithCustomValue(ItemID.Spaghetti, Item.buyPrice(gold: 5), Condition.HappyEnough, Condition.DownedSkeletron); + shop.Add(ItemType()) + .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)); } @@ -1201,7 +1206,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) @@ -1212,26 +1221,36 @@ 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) { + 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, 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) + .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) @@ -1245,12 +1264,17 @@ 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); + } + + if (type == NPCID.Truffle) + { + shop.Add(ItemType()); } } #endregion diff --git a/NPCs/CalamityNetImportantNPC.cs b/NPCs/CalamityNetImportantNPC.cs new file mode 100644 index 0000000000..065b2138d8 --- /dev/null +++ b/NPCs/CalamityNetImportantNPC.cs @@ -0,0 +1,125 @@ +using System; +using System.Collections.Generic; +using System.CommandLine.Parsing; +using System.Linq; +using System.Reflection; +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; +using Terraria.ModLoader.Core; + +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() + { + int uniqueNetOffsetID = 0; + + #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}"); + } + } + + netOffsetTable?.Clear(); + } + + 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 static void MarkNPCToLongDistanceSync(int netUpdateTickOffset = 0) where NPCType : ModNPC + { + MarkNPCToLongDistanceSync(ModContent.NPCType(), netUpdateTickOffset); + } + + private static void MarkNPCToLongDistanceSync(int npcType, int netUpdateTickOffset = 0) + { + typesToUpdate[npcType] = netUpdateTickOffset; + } + } +} 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/NPCs/Cryogen/Cryogen.cs b/NPCs/Cryogen/Cryogen.cs index 36f0b6388c..59847a9191 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; @@ -264,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) 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..c54d87f1e5 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; @@ -2706,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(); { 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/Ares/AresBody.cs b/NPCs/ExoMechs/Ares/AresBody.cs index 631b09ff53..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/NPCs/ExoMechs/Draedon.cs b/NPCs/ExoMechs/Draedon.cs index 623673c9f1..d0b90f2ba2 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; @@ -687,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); @@ -696,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/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/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/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..2d46af55bd 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; @@ -474,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/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/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/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/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/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/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..71119e2239 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 @@ -337,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/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/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/CirrusHeadIcon.png b/NPCs/SupremeCalamitas/CirrusHeadIcon.png deleted file mode 100644 index b322de98ea..0000000000 Binary files a/NPCs/SupremeCalamitas/CirrusHeadIcon.png and /dev/null differ diff --git a/NPCs/SupremeCalamitas/CirrusHeadIcon2.png b/NPCs/SupremeCalamitas/CirrusHeadIcon2.png deleted file mode 100644 index 2052f7d75f..0000000000 Binary files a/NPCs/SupremeCalamitas/CirrusHeadIcon2.png and /dev/null differ 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; diff --git a/NPCs/SupremeCalamitas/SupremeCalamitas.cs b/NPCs/SupremeCalamitas/SupremeCalamitas.cs index 42f996b630..fbddbe5da9 100644 --- a/NPCs/SupremeCalamitas/SupremeCalamitas.cs +++ b/NPCs/SupremeCalamitas/SupremeCalamitas.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using CalamityMod.Buffs.Alcohol; using CalamityMod.Buffs.DamageOverTime; using CalamityMod.Dusts; using CalamityMod.Events; @@ -25,7 +24,6 @@ using CalamityMod.Items.Weapons.Summon; using CalamityMod.NPCs.Bumblebirb; using CalamityMod.NPCs.DevourerofGods; -using CalamityMod.NPCs.Providence; using CalamityMod.NPCs.TownNPCs; using CalamityMod.Projectiles.Boss; using CalamityMod.World; @@ -41,10 +39,7 @@ using Terraria.ID; using Terraria.ModLoader; using ReLogic.Utilities; -using CalamityMod.Projectiles.Ranged; -using Steamworks; using CalamityMod.Particles; -using Terraria.Utilities.Terraria.Utilities; namespace CalamityMod.NPCs.SupremeCalamitas { @@ -69,10 +64,10 @@ public enum FrameAnimationType public const int ThirdBulletHellEndValue = BulletHellDuration * 3; public const int FourthBulletHellEndValue = BulletHellDuration * 4; public const int FifthBulletHellEndValue = BulletHellDuration * 5; - public const int CirrusPhotonRipperDamage = 3725; - private const float CirrusPhotonRipperDashVelocity = 6f; - private const float CirrusPhotonRipperMinDistanceFromTarget = 64f; - private const float CirrusPhotonRipperDashAcceleration = 0.3f; + public const int PermafrostPhotonRipperDamage = 3725; + private const float PermafrostPhotonRipperDashVelocity = 6f; + private const float PermafrostPhotonRipperMinDistanceFromTarget = 64f; + private const float PermafrostPhotonRipperDashAcceleration = 0.3f; public float bossLife; public float uDieLul = 1f; @@ -102,7 +97,7 @@ public enum FrameAnimationType public bool spawnArena = false; public bool enteredBrothersPhase = false; public bool hasSummonedBrothers = false; - public bool cirrus = false; + public bool permafrost = false; public bool hasDoneDeathAnim = false; public bool postMusicHit = false; @@ -190,17 +185,14 @@ public bool AttackCloseToBeingOver public static int hoodedHeadIconP2Index; public static int hoodlessHeadIconIndex; public static int hoodlessHeadIconP2Index; - public static int cirrusHeadIconIndex; - public static int cirrusHeadIconP2Index; + public static int permafrostHeadIconIndex; public static float normalDR = 0.25f; public static float enragedDR = 0.9999f; public static readonly Color textColor = Color.Orange; - public static readonly Color cirrusTextColor = Color.Pink; + public static readonly Color permafrostTextColor = Color.LightCyan; public const int sepulcherSpawnCastTime = 75; public const int brothersSpawnCastTime = 150; - public const int MaxCirrusAlcohols = 20; - public const int MaxCirrusAlcoholDebuffDuration = 1500; // Sounds. public static readonly SoundStyle SpawnSound = new("CalamityMod/Sounds/Custom/SupremeCalamitasSpawn") { Volume = 1.2f }; @@ -219,8 +211,7 @@ public bool AttackCloseToBeingOver public SlotId BulletHellRumbleSlot; public static Asset 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,11 +2230,11 @@ 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); } - 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; @@ -2286,11 +2249,11 @@ 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); } - 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; @@ -2308,11 +2271,11 @@ 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); } - 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))); @@ -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); @@ -3556,7 +3521,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) @@ -3587,7 +3554,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 +3578,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 (cirrus) - texture2D15 = inPhase2 ? CirrusTexture2.Value : CirrusTexture.Value; + if (permafrost) + texture2D15 = PermafrostTexture.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 +3607,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 +3616,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 +3630,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 +3684,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 +3763,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 +3773,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 +3783,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 +3803,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.png b/NPCs/SupremeCalamitas/SupremeCirrus.png deleted file mode 100644 index 4412c1c02b..0000000000 Binary files a/NPCs/SupremeCalamitas/SupremeCirrus.png and /dev/null differ diff --git a/NPCs/SupremeCalamitas/SupremeCirrus_Shimmered.png b/NPCs/SupremeCalamitas/SupremeCirrus_Shimmered.png deleted file mode 100644 index 1ce3adfdf2..0000000000 Binary files a/NPCs/SupremeCalamitas/SupremeCirrus_Shimmered.png and /dev/null differ diff --git a/NPCs/SupremeCalamitas/SupremePermafrost.png b/NPCs/SupremeCalamitas/SupremePermafrost.png new file mode 100644 index 0000000000..4e75ae0b28 Binary files /dev/null and b/NPCs/SupremeCalamitas/SupremePermafrost.png differ diff --git a/NPCs/TownNPCs/DILF.cs b/NPCs/TownNPCs/DILF.cs index 9b2de8371c..ac0245449f 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") }; @@ -160,7 +166,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/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 adf1db2d15..0000000000 Binary files a/NPCs/TownNPCs/FAP.png and /dev/null differ diff --git a/NPCs/TownNPCs/FAPAlt.png b/NPCs/TownNPCs/FAPAlt.png deleted file mode 100644 index 45895728f7..0000000000 Binary files a/NPCs/TownNPCs/FAPAlt.png and /dev/null differ diff --git a/NPCs/TownNPCs/FAPShimmered_Head.png b/NPCs/TownNPCs/FAPShimmered_Head.png deleted file mode 100644 index 2de143f847..0000000000 Binary files a/NPCs/TownNPCs/FAPShimmered_Head.png and /dev/null differ diff --git a/NPCs/TownNPCs/FAP_Head.png b/NPCs/TownNPCs/FAP_Head.png deleted file mode 100644 index d4b8a7cb82..0000000000 Binary files a/NPCs/TownNPCs/FAP_Head.png and /dev/null differ diff --git a/NPCs/TownNPCs/FAP_Shimmered.png b/NPCs/TownNPCs/FAP_Shimmered.png deleted file mode 100644 index 14c9b9f3a0..0000000000 Binary files a/NPCs/TownNPCs/FAP_Shimmered.png and /dev/null differ diff --git a/NPCs/TownNPCs/SEAHOE.cs b/NPCs/TownNPCs/SEAHOE.cs index b455f13eb2..b4a7e1673b 100644 --- a/NPCs/TownNPCs/SEAHOE.cs +++ b/NPCs/TownNPCs/SEAHOE.cs @@ -113,10 +113,6 @@ public override string GetChat() if (witch != -1) dialogue.Add(this.GetLocalizedValue("Chat.BrimstoneWitch")); - int cirrus = NPC.FindFirstNPC(ModContent.NPCType()); - 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)); @@ -212,8 +208,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 ff591a3aea..6e81ae6084 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; @@ -111,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"), @@ -158,11 +160,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)); @@ -217,20 +214,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 +244,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) @@ -282,8 +304,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/NPCs/TownNPCs/WITCH.cs b/NPCs/TownNPCs/WITCH.cs index beefa5a4fb..268b87b3fd 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); @@ -129,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) { @@ -145,6 +145,28 @@ public override void OnChatButtonClicked(bool firstButton, ref string shopName) Main.LocalPlayer.Calamity().GivenBrimstoneLocus = true; } } + else + { + Main.npcChatText = GetRandomDonors(25); + } + } + /// + /// Returns an arbitrary number of random donator usernames. + /// + public string GetRandomDonors(int numDonors) + { + IList pickingList = [.. CalamityLists.donatorList]; + + string[] pickedDonors = new string[numDonors]; + for (int i = 0; i < numDonors; ++i) + { + int idxSelected = Main.rand.Next(pickingList.Count); + pickedDonors[i] = pickingList[idxSelected]; + pickingList.RemoveAt(idxSelected); + } + + string text = this.GetLocalization("DonorShoutout").Format(pickedDonors); + return text; } // Make this Town NPC teleport to the Queen statue when triggered. 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/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/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) 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/Physics/Rope.cs b/Physics/Rope.cs new file mode 100644 index 0000000000..746495c53a --- /dev/null +++ b/Physics/Rope.cs @@ -0,0 +1,229 @@ +using System; +using Microsoft.Xna.Framework; +using Terraria; + +namespace CalamityMod.Physics; + +internal class Rope +{ + /// + /// 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/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/Boss/BrimstoneBarrage.cs b/Projectiles/Boss/BrimstoneBarrage.cs index 5c4f0f70eb..65aa8a2ca0 100644 --- a/Projectiles/Boss/BrimstoneBarrage.cs +++ b/Projectiles/Boss/BrimstoneBarrage.cs @@ -153,14 +153,18 @@ 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; + } } } 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/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..e0b5d5a5d3 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 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. float playerSpeed = player.velocity.LengthSquared(); float speedRatio = playerSpeed / (SpeedToForceMaxDamage * SpeedToForceMaxDamage); @@ -334,12 +340,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 +406,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..2e6ac08403 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); @@ -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 27d65eacbf..d2e3661e1c 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 @@ -269,6 +267,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); @@ -1816,7 +1823,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); @@ -2639,8 +2646,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; @@ -4018,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 @@ -4180,13 +4194,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/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..ef7e4a95ec 100644 --- a/Projectiles/DraedonsArsenal/PhaseslayerBeam.cs +++ b/Projectiles/DraedonsArsenal/PhaseslayerBeam.cs @@ -2,8 +2,11 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Terraria; +using Terraria.ID; using Terraria.DataStructures; +using Terraria.ID; using Terraria.ModLoader; + namespace CalamityMod.Projectiles.DraedonsArsenal { public class PhaseslayerBeam : ModProjectile, ILocalizedModType @@ -13,6 +16,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..7eb2c5a05b 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() @@ -185,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/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/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/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..47f0d3b390 100644 --- a/Projectiles/Magic/BeamingBolt2.cs +++ b/Projectiles/Magic/BeamingBolt2.cs @@ -2,12 +2,15 @@ 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 { 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/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 2e733503aa..0000000000 Binary files a/Projectiles/Magic/DivineRetributionSpear.png and /dev/null differ 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/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 a58f5f7bfa..0000000000 --- a/Projectiles/Magic/FabRay.cs +++ /dev/null @@ -1,140 +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; - 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; - } - } - } - - 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; - 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; - } - } - 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; - } - - public override void OnHitPlayer(Player target, Player.HurtInfo info) - { - if (Projectile.hostile) - target.AddBuff(ModContent.BuffType(), 54000); - } - } -} 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/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..3109ae5bff --- /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 == heldItem.useAnimation - 1 && Owner.CheckMana(heldItem.mana, true)) + { + 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/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/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/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/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/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/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/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/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/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 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/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 0000000000..f878df53d2 Binary files /dev/null and b/Projectiles/Ranged/BuzzkillHoldout.png differ diff --git a/Projectiles/Ranged/BuzzkillSaw.cs b/Projectiles/Ranged/BuzzkillSaw.cs new file mode 100644 index 0000000000..7973eab163 --- /dev/null +++ b/Projectiles/Ranged/BuzzkillSaw.cs @@ -0,0 +1,218 @@ +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() + { + // dies from cringe (Deadshot Brooch moment) + if (Projectile.MaxUpdates > 1) + Projectile.MaxUpdates = 1; + + 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 0000000000..26e13051ee Binary files /dev/null and b/Projectiles/Ranged/BuzzkillSaw.png differ diff --git a/Projectiles/Ranged/BuzzkillSawLargeSlash.png b/Projectiles/Ranged/BuzzkillSawLargeSlash.png new file mode 100644 index 0000000000..98981fa415 Binary files /dev/null and b/Projectiles/Ranged/BuzzkillSawLargeSlash.png differ diff --git a/Projectiles/Ranged/BuzzkillSawSmallSlash.png b/Projectiles/Ranged/BuzzkillSawSmallSlash.png new file mode 100644 index 0000000000..8ee31d89e0 Binary files /dev/null and b/Projectiles/Ranged/BuzzkillSawSmallSlash.png differ 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..c5b4384a6b 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() @@ -108,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/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/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/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 deleted file mode 100644 index 4fe0111b80..0000000000 --- a/Projectiles/Ranged/RainbowBlast.cs +++ /dev/null @@ -1,64 +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; - } - - 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 80909384b5..0000000000 Binary files a/Projectiles/Ranged/RainbowBlast.png and /dev/null differ 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..27cb29cb0b 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() @@ -218,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 309634c16a..26ba2b6e9a 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() @@ -169,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/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/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/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/SuperradiantBolt.cs b/Projectiles/Ranged/SuperradiantBolt.cs new file mode 100644 index 0000000000..e3eb6e744b --- /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/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); + 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 0000000000..77ecaadda2 Binary files /dev/null and b/Projectiles/Ranged/SuperradiantBolt.png differ 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 0000000000..319c5357b2 Binary files /dev/null and b/Projectiles/Ranged/SuperradiantSaw.png differ diff --git a/Projectiles/Ranged/SuperradiantSawLargeSlash.png b/Projectiles/Ranged/SuperradiantSawLargeSlash.png new file mode 100644 index 0000000000..37ebc6a896 Binary files /dev/null and b/Projectiles/Ranged/SuperradiantSawLargeSlash.png differ diff --git a/Projectiles/Ranged/SuperradiantSawLingering.cs b/Projectiles/Ranged/SuperradiantSawLingering.cs new file mode 100644 index 0000000000..4e5619a351 --- /dev/null +++ b/Projectiles/Ranged/SuperradiantSawLingering.cs @@ -0,0 +1,198 @@ +using CalamityMod.Buffs.DamageOverTime; +using CalamityMod.Items.Weapons.Melee; +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 SuperradiantSawLingering : ModProjectile, ILocalizedModType + { + public new string LocalizationCategory => "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 0000000000..87ec455489 Binary files /dev/null and b/Projectiles/Ranged/SuperradiantSawOutline.png differ diff --git a/Projectiles/Ranged/SuperradiantSawSmallSlash.png b/Projectiles/Ranged/SuperradiantSawSmallSlash.png new file mode 100644 index 0000000000..c8cf403c47 Binary files /dev/null and b/Projectiles/Ranged/SuperradiantSawSmallSlash.png differ 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 0000000000..e5445246aa Binary files /dev/null and b/Projectiles/Ranged/SuperradiantSlaughtererHoldout.png differ diff --git a/Projectiles/Ranged/SuperradiantSlaughtererHoldoutGlow.png b/Projectiles/Ranged/SuperradiantSlaughtererHoldoutGlow.png new file mode 100644 index 0000000000..26c6b47fb4 Binary files /dev/null and b/Projectiles/Ranged/SuperradiantSlaughtererHoldoutGlow.png differ diff --git a/Projectiles/Ranged/SuperradiantSlaughtererHoldoutMiniSaw.png b/Projectiles/Ranged/SuperradiantSlaughtererHoldoutMiniSaw.png new file mode 100644 index 0000000000..5258525907 Binary files /dev/null and b/Projectiles/Ranged/SuperradiantSlaughtererHoldoutMiniSaw.png differ 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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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; 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 e0b03d728c..0000000000 Binary files a/Projectiles/Typeless/YanmeisKnifeSlash.png and /dev/null differ diff --git a/README.md b/README.md index 9ae12d6b43..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/) -- [Patreon](https://patreon.com/fabsol) +- [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). 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/Sounds/Custom/BuzzsawCharge.ogg b/Sounds/Custom/BuzzsawCharge.ogg new file mode 100644 index 0000000000..92db8cca71 Binary files /dev/null and b/Sounds/Custom/BuzzsawCharge.ogg differ diff --git a/Sounds/Custom/BuzzsawIdle.ogg b/Sounds/Custom/BuzzsawIdle.ogg new file mode 100644 index 0000000000..a9deb63893 Binary files /dev/null and b/Sounds/Custom/BuzzsawIdle.ogg differ diff --git a/Sounds/Custom/MetalPipeFalling.ogg b/Sounds/Custom/MetalPipeFalling.ogg new file mode 100644 index 0000000000..eaddb019f3 Binary files /dev/null and b/Sounds/Custom/MetalPipeFalling.ogg differ diff --git a/Sounds/Item/SawShot1.ogg b/Sounds/Item/SawShot1.ogg new file mode 100644 index 0000000000..668e88c1f0 Binary files /dev/null and b/Sounds/Item/SawShot1.ogg differ diff --git a/Sounds/Item/SawShot2.ogg b/Sounds/Item/SawShot2.ogg new file mode 100644 index 0000000000..bbbd158d76 Binary files /dev/null and b/Sounds/Item/SawShot2.ogg differ diff --git a/Sounds/Item/SylvestaffFire1.ogg b/Sounds/Item/SylvestaffFire1.ogg new file mode 100644 index 0000000000..8ab459ac0b Binary files /dev/null and b/Sounds/Item/SylvestaffFire1.ogg differ diff --git a/Sounds/Item/SylvestaffFire2.ogg b/Sounds/Item/SylvestaffFire2.ogg new file mode 100644 index 0000000000..4d60af5825 Binary files /dev/null and b/Sounds/Item/SylvestaffFire2.ogg differ diff --git a/Sounds/Item/SylvestaffFire3.ogg b/Sounds/Item/SylvestaffFire3.ogg new file mode 100644 index 0000000000..c8b78c318b Binary files /dev/null and b/Sounds/Item/SylvestaffFire3.ogg differ diff --git a/Sounds/Item/SylvestaffProjectileBounce1.ogg b/Sounds/Item/SylvestaffProjectileBounce1.ogg new file mode 100644 index 0000000000..dbe4a38b8e Binary files /dev/null and b/Sounds/Item/SylvestaffProjectileBounce1.ogg differ diff --git a/Sounds/Item/SylvestaffProjectileBounce2.ogg b/Sounds/Item/SylvestaffProjectileBounce2.ogg new file mode 100644 index 0000000000..81d1d354e4 Binary files /dev/null and b/Sounds/Item/SylvestaffProjectileBounce2.ogg differ diff --git a/Sounds/Item/SylvestaffProjectileBounce3.ogg b/Sounds/Item/SylvestaffProjectileBounce3.ogg new file mode 100644 index 0000000000..4cbae2723f Binary files /dev/null and b/Sounds/Item/SylvestaffProjectileBounce3.ogg differ 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/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) diff --git a/Systems/WorldgenManagementSystem.cs b/Systems/WorldgenManagementSystem.cs index 822a6dac34..2886021901 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) @@ -124,19 +148,17 @@ 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); })); } - // 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; @@ -386,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/TileEntities/TECalamityPylon.cs b/TileEntities/TECalamityPylon.cs index 4f9c4fe060..e1b64a6094 100644 --- a/TileEntities/TECalamityPylon.cs +++ b/TileEntities/TECalamityPylon.cs @@ -2,7 +2,7 @@ namespace CalamityMod.TileEntities { - /// Copied from ExampleMod for documentation if needed for later -pixl + /// Copied from ExampleMod for documentation if needed for later /// /// 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 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/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/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/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 b494def714..0000000000 Binary files a/Tiles/Furniture/CirrusCouch.png and /dev/null differ diff --git a/Tiles/Furniture/CirrusCouch_Highlight.png b/Tiles/Furniture/CirrusCouch_Highlight.png deleted file mode 100644 index 37368baef2..0000000000 Binary files a/Tiles/Furniture/CirrusCouch_Highlight.png and /dev/null differ diff --git a/Tiles/Furniture/CraftingStations/SCalAltar.cs b/Tiles/Furniture/CraftingStations/SCalAltar.cs index 36ab9cef5e..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,14 +112,14 @@ 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) + if (Main.npc[f].type == ModContent.NPCType() && Main.npc[f].active) { Main.npc[f].active = false; } diff --git a/Tiles/Furniture/DevPaintings/ThankYouPaintingTile.png b/Tiles/Furniture/DevPaintings/ThankYouPaintingTile.png index 434b490237..d1706759fe 100644 Binary files a/Tiles/Furniture/DevPaintings/ThankYouPaintingTile.png and b/Tiles/Furniture/DevPaintings/ThankYouPaintingTile.png differ 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)); 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]; 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/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); 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/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/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 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/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. 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/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/Utilities/PlayerUtils.cs b/Utilities/PlayerUtils.cs index faf8ed2d66..d162e94b21 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; } @@ -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; 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/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..25b966c127 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)); } @@ -27,44 +30,53 @@ 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); } } 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); + } } } 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/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/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 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); + } + } + } } } 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(); 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); diff --git a/build.txt b/build.txt index cf9028fcf7..54df2bf033 100644 --- a/build.txt +++ b/build.txt @@ -1,5 +1,5 @@ -author = Fabsol and the Dev Team -version = 2.0.4.003 +author = The Calamity Dev Team +version = 2.0.5 displayName = Calamity Mod modReferences = CalamityModMusic homepage = https://discord.gg/calamity diff --git a/description.txt b/description.txt index e72ac9e99c..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 @@ -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 172d508e9c..f12caa1faa 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! @@ -17,13 +16,16 @@ 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] 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 @@ -35,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