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/Backgrounds/SulphurSeaSurfaceBGStyle.cs b/Backgrounds/SulphurSeaSurfaceBGStyle.cs index f2f57539d6..98d9a1d64c 100644 --- a/Backgrounds/SulphurSeaSurfaceBGStyle.cs +++ b/Backgrounds/SulphurSeaSurfaceBGStyle.cs @@ -1,15 +1,14 @@ -using Terraria.ModLoader; +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.Graphics.Effects; +using Terraria.ModLoader; namespace CalamityMod.Backgrounds { public class SulphurSeaSurfaceBGStyle : ModSurfaceBackgroundStyle { - public override int ChooseCloseTexture(ref float scale, ref double parallax, ref float a, ref float b) - { - b -= 100f; - return BackgroundTextureLoader.GetBackgroundSlot("CalamityMod/Backgrounds/BlankPixel"); - } - public override void ModifyFarFades(float[] fades, float transitionSpeed) { //This just fades in the background and fades out other backgrounds. @@ -33,5 +32,67 @@ public override void ModifyFarFades(float[] fades, float transitionSpeed) } } } + + public override int ChooseCloseTexture(ref float scale, ref double parallax, ref float a, ref float b) + { + return BackgroundTextureLoader.GetBackgroundSlot("CalamityMod/Backgrounds/SulphurSeaSurfaceClose"); + } + + public override bool PreDrawCloseBackground(SpriteBatch spriteBatch) //Taken from astral bg so the sulphur sea bg doesn't overlap other backgrounds + { + float screenOff = (float)AstralSurfaceBGStyle.screenOffField.GetValue(Main.instance); + float scAdj = (float)AstralSurfaceBGStyle.scAdjField.GetValue(Main.instance); + Color ColorOfSurfaceBackgroundsModified = (Color)AstralSurfaceBGStyle.COSBMAplhaField.GetValue(null); + bool canBGDraw = false; + if ((!Main.remixWorld || (Main.gameMenu && !WorldGen.remixWorldGen)) && (!WorldGen.remixWorldGen || !WorldGen.drunkWorldGen)) + canBGDraw = true; + if (Main.mapFullscreen) + canBGDraw = false; + int offset = 30; + if (Main.gameMenu) + offset = 0; + if (WorldGen.drunkWorldGen) + offset = -180; + float surfacePosition = (float)Main.worldSurface; + if (surfacePosition == 0f) + surfacePosition = 1f; + float screenPosition = Main.screenPosition.Y + (float)(Main.screenHeight / 2) - 600f; + double backgroundTopMagicNumber = (0f - screenPosition + screenOff / 2f) / (surfacePosition * 16f); + float bgGlobalScaleMultiplier = 2f; + int pushBGTopHack; + int offset2 = -180; + int menuOffset = 0; + if (Main.gameMenu) + { + menuOffset -= offset2; + } + pushBGTopHack = menuOffset; + pushBGTopHack += offset; + pushBGTopHack += offset2; //Offsets to the background placement + if (canBGDraw) //If the background can draw (player is not in a remix world or is not in a map). This can probably be removed since backgrounds already go through these checks + { + var bgScale = 1.25f; //Scale of the furthest of the closest background layers + var bgParallax = 0.4; //The parallax of the background layer + var bgTopY = (int)(backgroundTopMagicNumber * 1800.0 + 1500.0) + (int)scAdj + pushBGTopHack; //the Y position of the background + bgScale *= bgGlobalScaleMultiplier; //Scale of the background + var bgWidthScaled = (int)((float)CalamityMod.SulphurSeaSurface.Width * bgScale); //The Width of the bg texture scaled to the correct size + SkyManager.Instance.DrawToDepth(Main.spriteBatch, 1.2f / (float)bgParallax); + var bgStartX = (int)(0.0 - Math.IEEERemainder((double)Main.screenPosition.X * bgParallax, bgWidthScaled) - (double)(bgWidthScaled / 2)); //The starting position of the background layer + if (Main.gameMenu) + bgTopY = 320 + pushBGTopHack; //increases the height in the main menu + + var bgLoops = Main.screenWidth / bgWidthScaled + 2; + if ((double)Main.screenPosition.Y < Main.worldSurface * 16.0 + 16.0) + { + for (int i = 0; i < bgLoops; i++) + { + //Draw the texture and its glowmask to each loop of the texture + Main.spriteBatch.Draw(CalamityMod.SulphurSeaSurface, new Vector2(bgStartX + bgWidthScaled * i, bgTopY + 400), new Rectangle(0, 0, CalamityMod.SulphurSeaSurface.Width, CalamityMod.SulphurSeaSurface.Height), ColorOfSurfaceBackgroundsModified, 0f, default(Vector2), bgScale, SpriteEffects.None, 0f); + Main.spriteBatch.Draw(CalamityMod.SulphurSeaSkyFront, new Vector2(bgStartX + bgWidthScaled * i, bgTopY + 400), new Rectangle(0, 0, CalamityMod.SulphurSeaSkyFront.Width, CalamityMod.SulphurSeaSkyFront.Height), new Color(Color.LightSeaGreen.R, Color.LightSeaGreen.G, Color.LightSeaGreen.B, ColorOfSurfaceBackgroundsModified.A) * 0.5f, 0f, default(Vector2), bgScale, SpriteEffects.None, 0f); + } + } + } + return false; //Stop the drawing of the base close background texture (note: does NOT stop the drawing of the Middle and Far textures because tmodloader is slight stupid :blushing:) + } } } diff --git a/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/AlcoholPoisoning.png b/Buffs/Alcohol/AlcoholPoisoning.png index 7c001df28c..224cdd155d 100644 Binary files a/Buffs/Alcohol/AlcoholPoisoning.png and b/Buffs/Alcohol/AlcoholPoisoning.png differ 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/Potions/ShadowBuff.cs b/Buffs/Potions/ShadowBuff.cs index 72ee6c1d8b..0244cb7c0b 100644 --- a/Buffs/Potions/ShadowBuff.cs +++ b/Buffs/Potions/ShadowBuff.cs @@ -15,7 +15,7 @@ public override void SetStaticDefaults() public override void Update(Player player, ref int buffIndex) { player.Calamity().shadow = true; - if (player.yoraiz0rEye < 2 && CalamityConfig.Instance.StealthInvisibility) + if (player.yoraiz0rEye < 2 && CalamityClientConfig.Instance.StealthInvisibility) player.yoraiz0rEye = 2; } } diff --git a/Buffs/StatBuffs/BossEffects.cs b/Buffs/StatBuffs/BossEffects.cs index 46022d0e27..e32088eaa6 100644 --- a/Buffs/StatBuffs/BossEffects.cs +++ b/Buffs/StatBuffs/BossEffects.cs @@ -24,7 +24,7 @@ public override void Update(Player player, ref int buffIndex) public override void ModifyBuffText(ref string buffName, ref string tip, ref int rare) { - if (CalamityConfig.Instance.BossZen) + if (CalamityServerConfig.Instance.BossZen) tip = tip.Replace(":", ":\n" + this.GetLocalizedValue("ZenDescription")); } } diff --git a/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/Buffs/Summon/CosmilampBuff.png b/Buffs/Summon/CosmilampBuff.png index 71e298b541..41a50f7e2c 100644 Binary files a/Buffs/Summon/CosmilampBuff.png and b/Buffs/Summon/CosmilampBuff.png differ diff --git a/CalPlayer/CalamityPlayer.cs b/CalPlayer/CalamityPlayer.cs index cb4fca8350..ae4cf52258 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; @@ -44,17 +45,20 @@ using CalamityMod.Projectiles.Rogue; using CalamityMod.Projectiles.Summon; using CalamityMod.Projectiles.Typeless; +using CalamityMod.Systems; +using CalamityMod.Waters; using CalamityMod.World; using Microsoft.Xna.Framework; using Terraria; using Terraria.Audio; using Terraria.DataStructures; +using Terraria.GameContent; +using Terraria.GameContent.Liquid; using Terraria.GameInput; using Terraria.Graphics.Shaders; using Terraria.ID; using Terraria.ModLoader; using Terraria.ModLoader.IO; -using Terraria.Utilities.Terraria.Utilities; namespace CalamityMod.CalPlayer { @@ -87,10 +91,7 @@ public partial class CalamityPlayer : ModPlayer public bool brimlashBusterBoost = false; public int evilSmasherBoost = 0; public int hellbornBoost = 0; - public int searedPanCounter = 0; - public int searedPanTimer = 0; public int potionTimer = 0; - public bool cirrusDress = false; public bool blockAllDashes = false; public bool resetHeightandWidth = false; public bool noLifeRegen = false; @@ -170,7 +171,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; @@ -286,7 +286,7 @@ public partial class CalamityPlayer : ModPlayer public bool stealthStrikeThisFrame = false; public bool stealthStrikeHalfCost = false; public bool stealthStrike75Cost = false; - public bool stealthStrike85Cost = false; + public bool stealthStrike90Cost = false; public bool wearingRogueArmor = false; public float accStealthGenBoost = 0f; @@ -300,7 +300,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 +881,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 +930,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 +987,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 +1151,6 @@ public GemTechArmorState GemTechState public bool omegaBlueTransformationForce; public bool omegaBlueTransformationPower; public bool redBow; - public bool cocosFeather; #endregion #region Calamitas Enchant Effects @@ -1291,7 +1290,6 @@ public override void Initialize() newPrincessInventory = false; newSkeletonMerchantInventory = false; newPermafrostInventory = false; - newCirrusInventory = false; newAmidiasInventory = false; newBanditInventory = false; newCalamitasInventory = false; @@ -1343,7 +1341,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 +1430,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 +1597,6 @@ public override void ResetEffects() onyxExcavator = false; rimehound = false; - fab = false; crysthamyr = false; ExoChair = false; miniOldDuke = false; @@ -1662,7 +1657,6 @@ public override void ResetEffects() shadowSpeed = false; dsSetBonus = false; wearingRogueArmor = false; - cirrusDress = false; blockAllDashes = false; blazingCursorDamage = false; @@ -1770,7 +1764,6 @@ public override void ResetEffects() phantomicArtifact = false; hallowedRegen = false; hallowedPower = false; - kamiBoost = false; tracersDust = false; elysianWingsDust = false; tracersCelestial = false; @@ -1850,7 +1843,6 @@ public override void ResetEffects() goldArmorGoldDrops = false; miningSet = false; - miningSetCooldown = 0; eskimoSet = false; //vanilla armor meteorSet = false; //vanilla armor, for Space Gun nerf @@ -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; @@ -2217,6 +2210,13 @@ public override void ResetEffects() infiniteFlight = false; + noStupidNaturalARSpawns = false; + disableAnahitaSpawns = false; + disableHiveCystSpawns = false; + disableNaturalScourgeSpawns = false; + disablePerfCystSpawns = false; + disableVoodooSpawns = false; + EnchantHeldItemEffects(Player, Player.Calamity(), Player.ActiveItem()); } #endregion @@ -2240,13 +2240,13 @@ public override void ModifyMaxStats(out StatModifier health, out StatModifier ma #region Screen Position Movements public override void ModifyScreenPosition() { - if (CalamityConfig.Instance.ScreenshakePower == 0) + if (CalamityClientConfig.Instance.ScreenshakePower == 0) return; if (GeneralScreenShakePower > 0f) { - Main.screenPosition += Main.rand.NextVector2Circular(GeneralScreenShakePower * CalamityConfig.Instance.ScreenshakePower, GeneralScreenShakePower * CalamityConfig.Instance.ScreenshakePower); - GeneralScreenShakePower = MathHelper.Clamp(GeneralScreenShakePower - 0.185f, 0f, 20f * CalamityConfig.Instance.ScreenshakePower); + Main.screenPosition += Main.rand.NextVector2Circular(GeneralScreenShakePower * CalamityClientConfig.Instance.ScreenshakePower, GeneralScreenShakePower * CalamityClientConfig.Instance.ScreenshakePower); + GeneralScreenShakePower = MathHelper.Clamp(GeneralScreenShakePower - 0.185f, 0f, 20f * CalamityClientConfig.Instance.ScreenshakePower); } } #endregion @@ -2367,6 +2367,8 @@ public override void UpdateDead() gState = false; bBlood = false; brainRot = false; + heavybleeding = false; + laceration = false; elementalMix = false; icarusFolly = false; vHex = false; @@ -2419,7 +2421,6 @@ public override void UpdateDead() hallowedPower = false; onyxExcavator = false; rimehound = false; - fab = false; crysthamyr = false; ExoChair = false; abyssalDivingSuitPlates = false; @@ -2432,7 +2433,6 @@ public override void UpdateDead() rRage = false; xRage = false; xWrath = false; - kamiBoost = false; graxDefense = false; encased = false; brutalCarnage = false; @@ -2457,7 +2457,7 @@ public override void UpdateDead() sulphurskin = false; baguette = false; flaskBrimstone = false; - fabsolVodka = false; + purpleHaze = false; shine = false; anechoicCoating = false; mushy = false; @@ -2648,8 +2648,6 @@ public override void UpdateDead() ascendantTrail = false; evilSmasherBoost = 0; hellbornBoost = 0; - searedPanCounter = 0; - searedPanTimer = 0; potionTimer = 0; persecutedEnchantSummonTimer = 0; momentumCapacitorTime = 0; @@ -2671,7 +2669,7 @@ public override void UpdateDead() // Respawn the player faster // 3 seconds normally and configurable while a boss is alive between 15 and 60 seconds - int respawnTimerSet = areThereAnyDamnBosses ? (CalamityConfig.Instance.PlayerRespawnTime_BossAlive * 60) : 180; + int respawnTimerSet = areThereAnyDamnBosses ? (CalamityServerConfig.Instance.PlayerRespawnTime_BossAlive * 60) : 180; if (Player.respawnTimer > respawnTimerSet) Player.respawnTimer = respawnTimerSet; } @@ -3090,16 +3088,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; } @@ -3343,14 +3341,14 @@ public static void ModTeleport(Player player, Vector2 pos, bool playSound = true public override void UpdateEquips() { // TODO -- why is boss health bar code in Player.UpdateEquips and not a ModSystem - CalamityConfig.Instance.BossHealthBarExtraInfo = shouldDrawSmallText; + CalamityClientConfig.Instance.BossHealthBarExtraInfo = shouldDrawSmallText; // Putting this in GlobalItem will run multiple times for each slot, which this system already does, creating a slew of problems. VanillaArmorChangeManager.ApplyPotentialEffectsTo(Player); // If the config is enabled, vastly increase the player's base tile and wall placement speeds // This stacks with the Brick Layer and Portable Cement Mixer - if (CalamityConfig.Instance.FasterTilePlacement) + if (CalamityServerConfig.Instance.FasterTilePlacement) { Player.tileSpeed += 0.5f; Player.wallSpeed += 0.5f; @@ -3425,58 +3423,66 @@ public override void UpdateEquips() { Player.AddBuff(ModContent.BuffType(), 60, true); } - if (gSabaton && Player.whoAmI == Main.myPlayer) + if (gSabaton) { - //While holding hotkey, but before slam, bring Y velocity closer to 0 - if (gSabatonHotkeyHoldTime < 60 && gSabatonHotkeyHoldTime != 0 && !gSabatonFalling) - { - Player.velocity.Y *= (60 - (gSabatonHotkeyHoldTime / 4f)) / 60f; - } - //Play sound a bit early so it goes in time with the fall - if (gSabatonHotkeyHoldTime == 45 && !gSabatonFalling) - { - SoundEngine.PlaySound(new("CalamityMod/Sounds/Custom/GravistarCharge") { Volume = 0.3f }); - } - //1 second passed, falling time - if (gSabatonHotkeyHoldTime == 60) - { - gSabatonFalling = true; - } - //Cancel fall and don't give 'on ground' effects if on rope, on mount, grappled, or tongued - if (Player.pulley || Player.mount.Active || Player.grappling[0] != -1 || Player.tongued) - { - gSabatonFall = 0; - gSabatonFalling = false; - } - if (gSabatonFalling) + if (Player.whoAmI == Main.myPlayer) { - SpawnGravistarParticle(); + //While holding hotkey, but before slam, bring Y velocity closer to 0 + if (gSabatonHotkeyHoldTime < 60 && gSabatonHotkeyHoldTime != 0 && !gSabatonFalling) + { + Player.velocity.Y *= (60 - (gSabatonHotkeyHoldTime / 4f)) / 60f; + } + //Play sound a bit early so it goes in time with the fall + if (gSabatonHotkeyHoldTime == 45 && !gSabatonFalling) + { + SoundEngine.PlaySound(new("CalamityMod/Sounds/Custom/GravistarCharge") { Volume = 0.3f }); + } + //1 second passed, falling time + if (gSabatonHotkeyHoldTime == 60) + { + gSabatonFalling = true; + } + //Cancel fall and don't give 'on ground' effects if on rope, on mount, grappled, or tongued + // Also cancel fall if the player has upwards Y velocity (Goodbye Inner Tube cheese) + if ((Player.gravDir == 1 && Player.velocity.Y < 0f) || (Player.gravDir == -1 && Player.velocity.Y > 1f) || Player.pulley || Player.mount.Active || Player.grappling[0] != -1 || Player.tongued) + { + gSabatonFall = 0; + gSabatonFalling = false; + } + if (gSabatonFalling) + { + SpawnGravistarParticle(); - //Cap time converted to damage at 2 seconds - if (gSabatonFall < 120) - gSabatonFall++; + //Cap time converted to damage at 2 seconds + if (gSabatonFall < 120) + gSabatonFall++; - Player.maxFallSpeed = 40f; - Player.gravity = 1.3f; - //If the player can fly during the fall, the physics gets a bit funky - Player.controlJump = false; + Player.maxFallSpeed = 40f; + Player.gravity = 1.3f; + //If the player can fly during the fall, the physics gets a bit funky + Player.controlJump = false; - //Check if player hit some form of solid resistance (the ground) - if (Player.oldVelocity.Y == Player.velocity.Y) - { - var source = Player.GetSource_Accessory(FindAccessory(ModContent.ItemType())); - //Spawn explosion. ai[0] is used for transferring the recorded falling time + //Check if player hit some form of solid resistance (the ground) + if (Player.oldVelocity.Y == Player.velocity.Y) + { + var source = Player.GetSource_Accessory(FindAccessory(ModContent.ItemType())); + //Spawn explosion. ai[0] is used for transferring the recorded falling time - int damage = Player.ApplyArmorAccDamageBonusesTo(Player.CalcIntDamage(GravistarSabaton.SlamDamage)); + int damage = Player.ApplyArmorAccDamageBonusesTo(Player.CalcIntDamage(GravistarSabaton.SlamDamage)); - Projectile.NewProjectile(source, Player.Center, Vector2.Zero, ModContent.ProjectileType(), damage, 4f, Player.whoAmI, gSabatonFall); - gSabatonFall = 0; - gSabatonFalling = false; - //Temporary jump speed is granted for 40 frames - gSabatonTempJumpSpeed = 40; + Projectile.NewProjectile(source, Player.Center, Vector2.Zero, ModContent.ProjectileType(), damage, 4f, Player.whoAmI, gSabatonFall); + gSabatonFall = 0; + gSabatonFalling = false; + //Temporary jump speed is granted for 40 frames + gSabatonTempJumpSpeed = 40; + } } } - + } + else // Reset slam effect if the accessory is unequipped + { + gSabatonFall = 0; + gSabatonFalling = false; } } #endregion @@ -3600,7 +3606,7 @@ public override void PreUpdateMovement() #region PostUpdateBuffs public override void PostUpdateBuffs() { - if (Player.whoAmI == Main.myPlayer && CalamityConfig.Instance.VanillaCooldownDisplay) + if (Player.whoAmI == Main.myPlayer) { if (Player.whoAmI == Main.myPlayer && Player.potionDelay != 0) potionSick = true; @@ -3713,10 +3719,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 +3733,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 +4226,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 +4293,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; @@ -4548,7 +4534,7 @@ private void ResetRogueStealth() stealthStrikeThisFrame = false; stealthStrikeHalfCost = false; stealthStrike75Cost = false; - stealthStrike85Cost = false; + stealthStrike90Cost = false; // stealthAcceleration only resets if you don't have either of the accelerator accessories equipped if (!darkGodSheath && !eclipseMirror) @@ -4735,8 +4721,8 @@ public bool StealthStrikeAvailable() consumptionMult = 0.5f; else if (stealthStrike75Cost) consumptionMult = 0.75f; - else if (stealthStrike85Cost) - consumptionMult = 0.85f; + else if (stealthStrike90Cost) + consumptionMult = 0.9f; return rogueStealth >= rogueStealthMax * consumptionMult; } @@ -4763,7 +4749,7 @@ public void ConsumeStealthByAttacking() if (rogueStealth <= 0f) rogueStealth = 0f; } - else if (stealthStrike85Cost) + else if (stealthStrike90Cost) { rogueStealth -= 0.9f * stealthToLose; if (rogueStealth <= 0f) @@ -4876,11 +4862,15 @@ public override void OnEnterWorld() // Enabling the config while a player is loaded will show the timer immediately. // But it won't start running until you save and quit and re-enter a world. - if (CalamityConfig.Instance.SpeedrunTimer) + if (CalamityClientConfig.Instance.SpeedrunTimer) CalamityMod.SpeedrunTimer.Restart(); + bool showWikiMessage = CalamityClientConfig.Instance.WikiStatusMessage; + bool showVCMMMessage = CalamityClientConfig.Instance.VCMMStatusMessage && !CalamityMod.Instance.VCMMAvailable; + bool showStartupMessages = showWikiMessage || showVCMMMessage; + // Set a random delay between 12 and 20 seconds. When this delay hits zero, startup messages display - if (CalamityConfig.Instance.WikiStatusMessage) + if (showStartupMessages) { startMessageDisplayDelay = Main.rand.Next(CalamityUtils.SecondsToFrames(12), CalamityUtils.SecondsToFrames(20) + 1); } diff --git a/CalPlayer/CalamityPlayerDashEffects.cs b/CalPlayer/CalamityPlayerDashEffects.cs index 279dff0a6d..7b016109cc 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 @@ -22,7 +21,7 @@ public string DashID { get { - return (String.IsNullOrEmpty(dashID) && Player.dashType == 0 && CalamityConfig.Instance.DefaultDashEnabled) ? DefaultDash.ID : dashID; //gives default dash ONLY if no custom or vanilla dash. + return (String.IsNullOrEmpty(dashID) && Player.dashType == 0 && CalamityServerConfig.Instance.DefaultDashEnabled) ? DefaultDash.ID : dashID; //gives default dash ONLY if no custom or vanilla dash. } set => dashID = value; } @@ -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 @@ -481,6 +462,7 @@ public bool DoADash(float dashSpeed) if (WorldGen.SolidOrSlopedTile(upwardTilePoint.X, upwardTilePoint.Y) || WorldGen.SolidOrSlopedTile(aheadTilePoint.X, aheadTilePoint.Y)) Player.velocity.X /= 2f; + Player.timeSinceLastDashStarted = 0; Player.dashDelay = -1; } @@ -489,22 +471,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..8b1c118372 100644 --- a/CalPlayer/CalamityPlayerDrawEffects.cs +++ b/CalPlayer/CalamityPlayerDrawEffects.cs @@ -110,7 +110,7 @@ public override void DrawEffects(PlayerDrawSet drawInfo, ref float r, ref float } // TODO -- rogue stealth visuals are an utter catastrophe and should be fully destroyed on next stealth rework - if (calamityPlayer.rogueStealth > 0f && calamityPlayer.rogueStealthMax > 0f && Player.townNPCs < 3f && CalamityConfig.Instance.StealthInvisibility) + if (calamityPlayer.rogueStealth > 0f && calamityPlayer.rogueStealthMax > 0f && Player.townNPCs < 3f && CalamityClientConfig.Instance.StealthInvisibility) { // A translucent orchid color, the rogue class color float colorValue = calamityPlayer.rogueStealth / calamityPlayer.rogueStealthMax * 0.9f; //0 to 0.9 @@ -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..1c6be2ee68 100644 --- a/CalPlayer/CalamityPlayerHitHurt.cs +++ b/CalPlayer/CalamityPlayerHitHurt.cs @@ -45,6 +45,7 @@ using Terraria.DataStructures; using Terraria.GameContent.Events; using Terraria.Graphics.Shaders; +using Terraria.GameContent.Creative; using Terraria.ID; using Terraria.Localization; using Terraria.ModLoader; @@ -438,6 +439,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 +540,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) @@ -597,7 +606,7 @@ public override void ModifyHitNPCWithItem(Item item, NPC target, ref NPC.HitModi totalDamageMult += 0.6f; // Apply all Calamity multipliers as a sum total to TML New Damage in a single step - modifiers.SourceDamage *= totalDamageMult; + modifiers.TargetDamageMultiplier *= totalDamageMult; // 01JUN2024: Ozzatron: apply Yellow Candle "chip damage" as a dirty modifier // The registration of the dirty modifier is conditional to ensure it doesn't apply to "near invincible" targets @@ -605,7 +614,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.TargetDamageMultiplier *= MultipliableFloat.One.Value + YellowCandleBuff.ExtraChipDamageRatio; // Stealth strike damage multipliers are applied here. // TODO -- stealth should be its own damage class and this should be applied as player StealthDamage *= XYZ @@ -651,15 +660,15 @@ public override void ModifyHitNPCWithItem(Item item, NPC target, ref NPC.HitModi // 0f = point blank, 1f = max range or further float DistanceInterpolant = Utils.GetLerpValue(FrostArmorSetChange.MinDistance, FrostArmorSetChange.MaxDistance, target.Distance(Main.player[Main.myPlayer].Center), true); - if (proj.CountsAsClass()) + if (proj.CountsAsClass() && modifiers.TargetDamageMultiplier.Value > 0f) { float meleeBoost = MathHelper.Lerp(0f, FrostArmorSetChange.ProximityBoost, 1 - DistanceInterpolant); - modifiers.SourceDamage += meleeBoost; + modifiers.TargetDamageMultiplier *= (modifiers.TargetDamageMultiplier.Value + meleeBoost) / modifiers.TargetDamageMultiplier.Value; } - else if (proj.CountsAsClass()) + else if (proj.CountsAsClass() && modifiers.TargetDamageMultiplier.Value > 0f) { float rangedBoost = MathHelper.Lerp(0f, FrostArmorSetChange.ProximityBoost, DistanceInterpolant); - modifiers.SourceDamage += rangedBoost; + modifiers.TargetDamageMultiplier *= (modifiers.TargetDamageMultiplier.Value + rangedBoost) / modifiers.TargetDamageMultiplier.Value; } } @@ -924,8 +933,29 @@ public override void ModifyHitByProjectile(Projectile proj, ref Player.HurtModif double dodgeDamageGateValuePercent = 0.05; int dodgeDamageGateValue = (int)Math.Round(Player.statLifeMax2 * dodgeDamageGateValuePercent); + // This hook is applied before tML applies the vanilla difficulty multipliers. This means the "proj.damage" value here + // is usually significantly lower than the damage the projectile "actually" deals. + // To obtain the correct damage value for a cancelled hit, the corresponding multipliers are copied from tML + // to simulate the "actual" damage of the projectile. + // Note: Banner buffs, cold resistance, and modded modifiers are not included in this "actual" damage calculation, + // even though in real tML hooks they might be applied earlier than or together with difficulty multipliers. + int actualProjDamage = proj.damage; + if (!proj.reflected && !ProjectileID.Sets.PlayerHurtDamageIgnoresDifficultyScaling[proj.type]) + { + float damageMult = Main.GameModeInfo.EnemyDamageMultiplier; + if (Main.GameModeInfo.IsJourneyMode) + { + var power = CreativePowerManager.Instance.GetPower(); + if (power.GetIsUnlocked()) + damageMult = power.StrengthMultiplierToGiveNPCs; + } + + // in real tML, the factor 2 is applied in Projectile.Damage() + actualProjDamage = (int)Math.Floor(2 * damageMult * (float)actualProjDamage); + } + // Reflects count as dodges. They share the timer and can be disabled by Armageddon right click. - if (!disableAllDodges && !Player.HasCooldown(GlobalDodge.ID) && proj.damage >= dodgeDamageGateValue) + if (!disableAllDodges && !Player.HasCooldown(GlobalDodge.ID) && actualProjDamage >= dodgeDamageGateValue) { double maxCooldownDurationDamagePercent = 0.5; int maxCooldownDurationDamageValue = (int)Math.Round(Player.statLifeMax2 * (maxCooldownDurationDamagePercent - dodgeDamageGateValuePercent)); @@ -934,13 +964,14 @@ public override void ModifyHitByProjectile(Projectile proj, ref Player.HurtModif if (maxCooldownDurationDamageValue <= 0) maxCooldownDurationDamageValue = 1; - float cooldownDurationScalar = MathHelper.Clamp((proj.damage - dodgeDamageGateValue) / (float)maxCooldownDurationDamageValue, 0f, 1f); + float cooldownDurationScalar = MathHelper.Clamp((actualProjDamage - dodgeDamageGateValue) / (float)maxCooldownDurationDamageValue, 0f, 1f); // The Evolution if (evolution) { proj.hostile = false; proj.friendly = true; + proj.damage = 10 * actualProjDamage; proj.velocity *= -2f; proj.extraUpdates += 1; proj.penetrate = 1; @@ -1190,8 +1221,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 +1233,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 +1257,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); @@ -1454,7 +1494,7 @@ public override void OnHitByProjectile(Projectile proj, Player.HurtInfo hurtInfo int dodgeDamageGateValue = (int)Math.Round(Player.statLifeMax2 * dodgeDamageGateValuePercent); // Reflects count as dodges. They share the timer and can be disabled by global dodge disabling effects. - if (!disableAllDodges && !Player.HasCooldown(GlobalDodge.ID) && proj.damage >= dodgeDamageGateValue) + if (!disableAllDodges && !Player.HasCooldown(GlobalDodge.ID) && hurtInfo.SourceDamage >= dodgeDamageGateValue) { double maxCooldownDurationDamagePercent = 0.5; int maxCooldownDurationDamageValue = (int)Math.Round(Player.statLifeMax2 * (maxCooldownDurationDamagePercent - dodgeDamageGateValuePercent)); @@ -1463,12 +1503,13 @@ public override void OnHitByProjectile(Projectile proj, Player.HurtInfo hurtInfo if (maxCooldownDurationDamageValue <= 0) maxCooldownDurationDamageValue = 1; - float cooldownDurationScalar = MathHelper.Clamp((proj.damage - dodgeDamageGateValue) / (float)maxCooldownDurationDamageValue, 0f, 1f); + float cooldownDurationScalar = MathHelper.Clamp((hurtInfo.SourceDamage - dodgeDamageGateValue) / (float)maxCooldownDurationDamageValue, 0f, 1f); if (daedalusReflect && !evolution) { proj.hostile = false; proj.friendly = true; + proj.damage = hurtInfo.SourceDamage; proj.velocity *= -1f; proj.penetrate = 1; @@ -1602,16 +1643,16 @@ public override bool ConsumableDodge(Player.HurtInfo info) return true; // Mirror evades do not work if the global dodge cooldown is active. This cooldown can be triggered by either mirror. - if (!Player.HasCooldown(GlobalDodge.ID) && info.Damage >= dodgeDamageGateValue) + if (!Player.HasCooldown(GlobalDodge.ID) && actualDamageTaken >= dodgeDamageGateValue) { if (eclipseMirror) { - EclipseMirrorDodge(dodgeDamageGateValuePercent, dodgeDamageGateValue, info.Damage); + EclipseMirrorDodge(dodgeDamageGateValuePercent, dodgeDamageGateValue, actualDamageTaken); return true; } else if (abyssalMirror) { - AbyssMirrorDodge(dodgeDamageGateValuePercent, dodgeDamageGateValue, info.Damage); + AbyssMirrorDodge(dodgeDamageGateValuePercent, dodgeDamageGateValue, actualDamageTaken); return true; } } @@ -1666,7 +1707,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 @@ -2198,7 +2239,7 @@ public override void OnHurt(Player.HurtInfo hurtInfo) if (trinketOfChi) chiBuffTimer = 0; - if (amidiasBlessing && hurtInfo.Damage > 50) + if (amidiasBlessing && (chaliceOfTheBloodGod ? chaliceBleedoutToApplyOnHurt : hurtInfo.Damage) > 50) { Player.ClearBuff(ModContent.BuffType()); SoundEngine.PlaySound(SoundID.Item96, Player.Center); diff --git a/CalPlayer/CalamityPlayerLifeRegen.cs b/CalPlayer/CalamityPlayerLifeRegen.cs index 590e89edba..87012aecaf 100644 --- a/CalPlayer/CalamityPlayerLifeRegen.cs +++ b/CalPlayer/CalamityPlayerLifeRegen.cs @@ -3,7 +3,7 @@ using CalamityMod.Buffs.Alcohol; using CalamityMod.Buffs.DamageOverTime; using CalamityMod.Buffs.Placeables; -using CalamityMod.Cooldowns; +using CalamityMod.CalPlayer.Dashes; using CalamityMod.Items.Accessories; using CalamityMod.NPCs; using CalamityMod.Projectiles.Ranged; @@ -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); @@ -129,9 +131,13 @@ void ApplyDoTDebuff(bool hasDebuff, int negativeLifeRegenToApply, bool immuneCon if (CalamityGlobalNPC.aquaticScourge >= 0 && Main.zenithWorld) { NPC AS = Main.npc[CalamityGlobalNPC.aquaticScourge]; - //if the player is 50 blocks or more away from the head - if (AS.life < AS.lifeMax) //Only poison when damaged - ASPoisonLevel = Utils.GetLerpValue(800f, 1600f, Vector2.Distance(Player.Center, AS.Center), true); + float scoogDistance = Vector2.Distance(Player.Center, AS.Center); + // GFB Aquatic Scourge poisons you if: + // 1. You are over 50 blocks away from the head + // 2. You are under 250 blocks away from the head (so that people halfway across the world aren't getting killed for no reason) + // 3. Aquatic Scourge has been damaged + if (AS.life < AS.lifeMax && scoogDistance < 4000f) + ASPoisonLevel = Utils.GetLerpValue(800f, 1600f, scoogDistance, true); } bool ASPoisoning = ASPoisonLevel > 0f; @@ -140,7 +146,7 @@ void ApplyDoTDebuff(bool hasDebuff, int negativeLifeRegenToApply, bool immuneCon float increment = 1f / SulphSeaWaterSafetyTime; //No way to mitigate AS Poisoning if (ASPoisoning) - increment *= 4f + (8f * ASPoisonLevel); + increment *= 3f + (6f * ASPoisonLevel); if (sulphurskin && !ASPoisoning) increment *= 0.5f; if (sulphurSet && !ASPoisoning) @@ -183,7 +189,7 @@ void ApplyDoTDebuff(bool hasDebuff, int negativeLifeRegenToApply, bool immuneCon { alcoholPoisonLevel++; } - if (fabsolVodka) + if (purpleHaze) { alcoholPoisonLevel++; } @@ -263,7 +269,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 +428,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; } @@ -521,7 +527,7 @@ void ApplyDoTDebuff(bool hasDebuff, int negativeLifeRegenToApply, bool immuneCon #endregion // During Silva revive or God Slayer dash, all negative life regen is canceled - if ((silvaCountdown > 0 && hasSilvaEffect && silvaSet) || (DashID == GodSlayerDash.ID && Player.dashDelay < 0)) + if ((silvaCountdown > 0 && hasSilvaEffect && silvaSet) || (DashID == GodslayerArmorDash.ID && Player.dashDelay < 0)) { if (Player.lifeRegen < 0) Player.lifeRegen = 0; @@ -603,9 +609,6 @@ public override void UpdateLifeRegen() if (caribbeanRum) Player.lifeRegen += 2; - if (aChicken) - Player.lifeRegen += 1; - if (mushy) Player.lifeRegen += 2; @@ -736,7 +739,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..4714b21e2a 100644 --- a/CalPlayer/CalamityPlayerMiscEffects.cs +++ b/CalPlayer/CalamityPlayerMiscEffects.cs @@ -8,6 +8,7 @@ using CalamityMod.Buffs.StatBuffs; using CalamityMod.Buffs.StatDebuffs; using CalamityMod.Buffs.Summon; +using CalamityMod.CalPlayer.Dashes; using CalamityMod.Cooldowns; using CalamityMod.CustomRecipes; using CalamityMod.DataStructures; @@ -82,7 +83,7 @@ public override void PostUpdateMiscEffects() // Give the player a 24% jump speed boost while wings are equipped, otherwise grant 4% more jump speed so that players can jump 7 tiles high if (Player.wingsLogic > 0) Player.jumpSpeedBoost += 1.2f; - else if (CalamityConfig.Instance.FasterJumpSpeed) + else if (CalamityServerConfig.Instance.FasterJumpSpeed) Player.jumpSpeedBoost += 0.2f; // Decrease the counter on Fearmonger set turbo regeneration @@ -186,12 +187,13 @@ public override void PostUpdateMiscEffects() Player.GetCritChance() = -spiritOriginConvertedCrit; } - if (Player.ActiveItem().type == ModContent.ItemType()) - heldGaelsLastFrame = true; - if (Player.ActiveItem().type != ModContent.ItemType()) saharaSlicersBolts = 0; + + if (Player.ActiveItem().type == ModContent.ItemType()) + heldGaelsLastFrame = true; + // De-equipping Gael's Greatsword deletes all rage. else if (heldGaelsLastFrame) { @@ -521,7 +523,8 @@ float ProxRageFromDistance(float dist) // Apply the rage change and cap rage in both directions. // Changes are only applied if the Rage mechanic is available. - if (RageEnabled) + // CIT 24NOV2025: Fixed an exploit which allowed Rage to persist forever if Revengeance is toggled off while active. + if (RageEnabled || rageDiff < 0f) { rage += rageDiff; if (rage < 0f) @@ -603,7 +606,10 @@ float ProxRageFromDistance(float dist) // Apply the adrenaline change and cap adrenaline in both directions. // Changes are only applied if the Adrenaline mechanic is available. - if (AdrenalineEnabled && adrenalinePauseTimer == 0) + // + // CIT 24NOV2025: Adrenaline cannot be exploited the same way as Rage, since difficulty cannot be changed while a boss is alive. + // Nevertheless, I will still give it the same exploit fix as Rage just in case there is some method to do it. + if ((AdrenalineEnabled || adrenalineDiff < 0f) && adrenalinePauseTimer == 0) { adrenaline += adrenalineDiff; if (adrenaline < 0f) @@ -981,7 +987,7 @@ private void MiscEffects() { Player.buffImmune[ModContent.BuffType()] = true; } - if (CalamityConfig.Instance.ChilledWaterRework) + if (CalamityServerConfig.Instance.ChilledWaterRework) { if (Main.expertMode && Player.ZoneSnow && Player.wet && !Player.lavaWet && !Player.honeyWet) { @@ -999,13 +1005,7 @@ private void MiscEffects() } } - // Extra DoT in the lava of the crags. Negated by Flame-licked Shell. - if (Player.lavaWet) - { - if (ZoneCalamity && !flameLickedShell) - Player.AddBuff(ModContent.BuffType(), 2, false); - } - else + if (!Player.lavaWet) { if (Player.lavaImmune) { @@ -1090,8 +1090,6 @@ private void MiscEffects() if (!Player.wet) { - if (cirrusDress) - Player.maxFallSpeed = 12f; if (aeroSet) Player.maxFallSpeed = 15f; if (Player.PortalPhysicsEnabled) @@ -1104,7 +1102,7 @@ private void MiscEffects() Player.noFallDmg = true; } - if (CalamityConfig.Instance.FasterFallHotkey) + if (CalamityClientConfig.Instance.FasterFallHotkey) { // Allow the player to double their gravity (but NOT max fall speed!) by holding the down button while in midair. bool holdingDown = Player.controlDown && !Player.controlJump; @@ -1324,7 +1322,7 @@ private void MiscEffects() { handler.OnCompleted(); if (handler.EndSound != null && handler.ShouldPlayEndSound) - SoundEngine.PlaySound(handler.EndSound.GetValueOrDefault()); + SoundEngine.PlaySound(handler.EndSound.GetValueOrDefault(), Player.Center); expiredCooldowns.Add(id); } } @@ -1487,8 +1485,16 @@ private void MiscEffects() reaverRegenCooldown++; else reaverRegenCooldown = 0; - if (auralisAurora > 0) - auralisAurora--; + if (auralisAuroraCounter > 300) + { + auralisAuroraCounter++; + } + + if (auralisAuroraCounter > 1500) + { + auralisAuroraCounter = 0; + auralisAuroraCooldown = CalamityUtils.SecondsToFrames(30f); + } if (auralisAuroraCooldown > 0) auralisAuroraCooldown--; @@ -1499,9 +1505,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 @@ -1563,7 +1574,7 @@ private void MiscEffects() MiniSwamerCooldown--; // God Slayer Armor dash debuff immunity - if (DashID == GodSlayerDash.ID && Player.dashDelay < 0) + if (DashID == GodslayerArmorDash.ID && Player.dashDelay < 0) { foreach (int debuff in CalamityLists.debuffList) Player.buffImmune[debuff] = true; @@ -1765,9 +1776,6 @@ private void MiscEffects() if (raiderTalisman && !StealthStrikeAvailable()) Player.GetCritChance() += raiderCritBonus; - if (kamiBoost) - Player.GetDamage() += 0.15f; - if (avertorBonus) Player.GetDamage() += 0.1f; @@ -2454,25 +2462,18 @@ private void StandingStillEffects() int chargeDuration = CalamityUtils.SecondsToFrames(5f); int auroraDuration = CalamityUtils.SecondsToFrames(20f); - if (usingScope && auralisAuroraCounter < chargeDuration + auroraDuration) + if (usingScope && auralisAuroraCounter < chargeDuration && auralisAuroraCooldown == 0) auralisAuroraCounter++; - if (auralisAuroraCounter > chargeDuration + auroraDuration) - { - auralisAuroraCounter = 0; - auralisAuroraCooldown = CalamityUtils.SecondsToFrames(30f); - } if (auralisAuroraCounter > 0 && auralisAuroraCounter < chargeDuration && !usingScope) auralisAuroraCounter--; - - if (auralisAuroraCounter > chargeDuration && auralisAuroraCounter < chargeDuration + auroraDuration && !usingScope) - auralisAuroraCounter = 0; } else { auralisStealthCounter = 0f; - auralisAuroraCounter = 0; + if (auralisAuroraCounter > 0 && auralisAuroraCounter < 300) + auralisAuroraCounter--; } if (auralisAuroraCooldown > 0) { @@ -2512,7 +2513,7 @@ private void OtherBuffEffects() if (gravityNormalizer) { Player.buffImmune[BuffID.VortexDebuff] = true; - if (Player.InSpace()) + if (Player.ReducedSpaceGravity()) { Player.gravity = Player.defaultGravity; if (Player.wet) @@ -2715,7 +2716,7 @@ private void OtherBuffEffects() // 50% movement speed bonus so that you don't feel like a snail in the early game // Disabled while Overhaul is enabled, because Overhaul does very similar things to make movement more snappy - if (CalamityMod.Instance.overhaul is null && CalamityConfig.Instance.FasterBaseSpeed) + if (CalamityMod.Instance.overhaul is null && CalamityServerConfig.Instance.FasterBaseSpeed) Player.moveSpeed += BalancingConstants.DefaultMoveSpeedBoost; // Reduce how slow Chilled makes the player, because it's cancerous right now @@ -2723,10 +2724,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) @@ -2844,26 +2842,13 @@ private void OtherBuffEffects() if (Player.ActiveItem().type != ModContent.ItemType()) evilSmasherBoost = 0; } - if (searedPanCounter > 0) - { - if (Player.ActiveItem().type != ModContent.ItemType()) - { - searedPanCounter = 0; - searedPanTimer = 0; - } - else if (searedPanTimer < SearedPan.ConsecutiveHitOpening) - searedPanTimer++; - else - searedPanCounter = 0; - } // Flight time boosts double flightTimeMult = 1D + - (ZoneAstral ? 0.05 : 0D) + (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 +3601,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. @@ -4011,7 +3998,7 @@ private void DefenseEffects() // Apply defense damage Player.statDefense -= currentDefenseDamage; - + } // Defense can never be reduced below zero, no matter what @@ -4020,7 +4007,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); @@ -4163,11 +4150,16 @@ private void HandleTextChatMessages() { if (startMessageDisplayDelay == 0) { - if (CalamityConfig.Instance.WikiStatusMessage) + if (CalamityClientConfig.Instance.WikiStatusMessage) { CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.WikiStatus1"); CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.WikiStatus2"); } + + if (CalamityClientConfig.Instance.VCMMStatusMessage && !CalamityMod.Instance.VCMMAvailable) + { + CalamityUtils.DisplayLocalizedText("Mods.CalamityMod.Misc.VCMMStatus"); + } } --startMessageDisplayDelay; 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/AuralisAuroraLayer.cs b/CalPlayer/DrawLayers/AuralisAuroraLayer.cs index a6f4a4ba87..5c6629042b 100644 --- a/CalPlayer/DrawLayers/AuralisAuroraLayer.cs +++ b/CalPlayer/DrawLayers/AuralisAuroraLayer.cs @@ -17,7 +17,7 @@ public override bool GetDefaultVisibility(PlayerDrawSet drawInfo) return false; Player drawPlayer = drawInfo.drawPlayer; - return !(drawPlayer.Calamity().auralisAuroraCooldown < 300 || drawPlayer.Calamity().auralisAuroraCooldown > 0); + return !(drawPlayer.Calamity().auralisAuroraCounter < 300 || drawPlayer.Calamity().auralisAuroraCounter > 1500); } protected override void Draw(ref PlayerDrawSet drawInfo) 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..603526c907 100644 --- a/CalamityConditions.cs +++ b/CalamityConditions.cs @@ -19,7 +19,7 @@ private static Condition Create(string key, Func predicate) // Config based conditions // - public static readonly Condition PotionSellingConfig = Create("PotionConfig", () => CalamityConfig.Instance.PotionSelling); + public static readonly Condition PotionSellingConfig = Create("PotionConfig", () => CalamityServerConfig.Instance.PotionSelling); // // Player conditions @@ -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/CalamityConfig.cs b/CalamityConfig.cs index 2a46a809b2..09da028a74 100644 --- a/CalamityConfig.cs +++ b/CalamityConfig.cs @@ -5,25 +5,21 @@ using CalamityMod.UI.Rippers; using CalamityMod.UI.SulphurousWaterMeter; using Terraria; +using Terraria.Localization; using Terraria.ModLoader.Config; namespace CalamityMod { [BackgroundColor(49, 32, 36, 216)] - public class CalamityConfig : ModConfig + public class CalamityClientConfig : ModConfig { - public static CalamityConfig Instance; - - // TODO -- Not all Calamity config settings should be considered client side. - // There are many configs which are server side and should stay that way. + public static CalamityClientConfig Instance; public override ConfigScope Mode => ConfigScope.ClientSide; - public override bool AcceptClientChanges(ModConfig pendingConfig, int whoAmI, ref string message) => true; // Clamps values that would cause ugly problems if loaded directly without sanitization. [OnDeserialized] internal void ClampValues(StreamingContext context) { - BossHealthBoost = Utils.Clamp(BossHealthBoost, MinBossHealthBoost, MaxBossHealthBoost); RipperMeterShake = Utils.Clamp(RipperMeterShake, MinMeterShake, MaxMeterShake); ParticleLimit = (int)Utils.Clamp(ParticleLimit, MinParticleLimit, MaxParticleLimit); } @@ -48,10 +44,6 @@ internal void ClampValues(StreamingContext context) [DefaultValue(5000)] public int ParticleLimit { get; set; } - [BackgroundColor(192, 54, 64, 192)] - [DefaultValue(false)] - public bool BossesStopWeather { get; set; } - [BackgroundColor(192, 54, 64, 192)] [SliderColor(224, 165, 56, 128)] [Range(0f, 10f)] @@ -70,6 +62,10 @@ internal void ClampValues(StreamingContext context) [DefaultValue(true)] public bool WikiStatusMessage { get; set; } + [BackgroundColor(192, 54, 64, 192)] + [DefaultValue(true)] + public bool VCMMStatusMessage { get; set; } + [BackgroundColor(192, 54, 64, 192)] [DefaultValue(true)] public bool ShopNewAlert { get; set; } @@ -102,6 +98,33 @@ internal void ClampValues(StreamingContext context) [DefaultValue(true)] public bool StealthMeter { get; set; } + [BackgroundColor(192, 54, 64, 192)] + [DefaultValue(true)] + public bool ChargeMeter { get; set; } + + private const float MinMeterShake = 0f; + private const float MaxMeterShake = 4f; + + [BackgroundColor(192, 54, 64, 192)] + [SliderColor(224, 165, 56, 128)] + [Range(MinMeterShake, MaxMeterShake)] + [Increment(1f)] + [DrawTicks] + [DefaultValue(2f)] + public float RipperMeterShake { get; set; } + + [BackgroundColor(192, 54, 64, 192)] + [DefaultValue(false)] + public bool SpeedrunTimer { get; set; } + + [BackgroundColor(192, 54, 64, 192)] + [DefaultValue(true)] + public bool FlightBar { get; set; } + #endregion + + #region Meter Positions + [Header("MeterPositions")] + [BackgroundColor(192, 54, 64, 192)] [SliderColor(224, 165, 56, 128)] [Range(0f, 100f)] @@ -126,10 +149,6 @@ internal void ClampValues(StreamingContext context) [DefaultValue(SulphurousWaterMeterUI.DefaultPosY)] public float SulphuricWaterMeterPosY { get; set; } - [BackgroundColor(192, 54, 64, 192)] - [DefaultValue(true)] - public bool ChargeMeter { get; set; } - [BackgroundColor(192, 54, 64, 192)] [SliderColor(224, 165, 56, 128)] [Range(0f, 100f)] @@ -143,8 +162,28 @@ internal void ClampValues(StreamingContext context) public float ChargeMeterPosY { get; set; } [BackgroundColor(192, 54, 64, 192)] - [DefaultValue(false)] - public bool SpeedrunTimer { get; set; } + [SliderColor(224, 165, 56, 128)] + [Range(0f, 100f)] + [DefaultValue(RipperUI.DefaultRagePosX)] + public float RageMeterPosX { get; set; } + + [BackgroundColor(192, 54, 64, 192)] + [SliderColor(224, 165, 56, 128)] + [Range(0f, 100f)] + [DefaultValue(RipperUI.DefaultRagePosY)] + public float RageMeterPosY { get; set; } + + [BackgroundColor(192, 54, 64, 192)] + [SliderColor(224, 165, 56, 128)] + [Range(0f, 100f)] + [DefaultValue(RipperUI.DefaultAdrenPosX)] + public float AdrenalineMeterPosX { get; set; } + + [BackgroundColor(192, 54, 64, 192)] + [SliderColor(224, 165, 56, 128)] + [Range(0f, 100f)] + [DefaultValue(RipperUI.DefaultAdrenPosY)] + public float AdrenalineMeterPosY { get; set; } [BackgroundColor(192, 54, 64, 192)] [SliderColor(224, 165, 56, 128)] @@ -158,10 +197,6 @@ internal void ClampValues(StreamingContext context) [DefaultValue(SpeedrunTimerUI.DefaultTimerPosY)] public float SpeedrunTimerPosY { get; set; } - [BackgroundColor(192, 54, 64, 192)] - [DefaultValue(true)] - public bool FlightBar { get; set; } - [BackgroundColor(192, 54, 64, 192)] [SliderColor(224, 165, 56, 128)] [Range(0f, 100f)] @@ -180,15 +215,7 @@ internal void ClampValues(StreamingContext context) [BackgroundColor(192, 54, 64, 192)] [DefaultValue(true)] - public bool Interlude1 { get; set; } - - [BackgroundColor(192, 54, 64, 192)] - [DefaultValue(true)] - public bool Interlude2 { get; set; } - - [BackgroundColor(192, 54, 64, 192)] - [DefaultValue(true)] - public bool Interlude3 { get; set; } + public bool Interludes { get; set; } [BackgroundColor(192, 54, 64, 192)] [DefaultValue(true)] @@ -202,6 +229,35 @@ internal void ClampValues(StreamingContext context) [BackgroundColor(192, 54, 64, 192)] [DefaultValue(true)] public bool FasterFallHotkey { get; set; } + #endregion + } + + [BackgroundColor(49, 32, 36, 216)] + public class CalamityServerConfig : ModConfig + { + public static CalamityServerConfig Instance; + public override ConfigScope Mode => ConfigScope.ServerSide; + public override bool AcceptClientChanges(ModConfig pendingConfig, int whoAmI, ref NetworkText message) + { + if (whoAmI == 0) + return true; + if (whoAmI != 0) + { + message = CalamityUtils.GetText("Configs.CalamityServerConfig.Denied").ToNetworkText(); + return false; + } + return false; + } + + // Clamp values that would cause ugly problems if loaded directly without sanitization. + [OnDeserialized] + internal void ClampValues(StreamingContext context) + { + BossHealthBoost = Utils.Clamp(BossHealthBoost, MinBossHealthBoost, MaxBossHealthBoost); + } + + #region General Gameplay Changes + [Header("Gameplay")] [BackgroundColor(192, 54, 64, 192)] [DefaultValue(true)] @@ -253,11 +309,14 @@ internal void ClampValues(StreamingContext context) [DrawTicks] [DefaultValue(MinBossHealthBoost)] public float BossHealthBoost { get; set; } + + [BackgroundColor(192, 54, 64, 192)] + [DefaultValue(false)] + public bool BossesStopWeather { get; set; } #endregion - #region Default Player Stat Boosts [Header("BaseBoosts")] - + #region Default Player Stat Boosts [BackgroundColor(192, 54, 64, 192)] [DefaultValue(true)] public bool DefaultDashEnabled { get; set; } @@ -279,9 +338,8 @@ internal void ClampValues(StreamingContext context) public bool FasterTilePlacement { get; set; } #endregion - #region Expert and Master Mode Changes [Header("ExpertMaster")] - + #region Expert and Master Mode Changes [BackgroundColor(192, 54, 64, 192)] [DefaultValue(true)] public bool NerfExpertDebuffs { get; set; } @@ -298,44 +356,5 @@ internal void ClampValues(StreamingContext context) [DefaultValue(false)] public bool ForceTownSafety { get; set; } #endregion - - #region Revengeance Mode Changes - [Header("Revengeance")] - - private const float MinMeterShake = 0f; - private const float MaxMeterShake = 4f; - - [BackgroundColor(192, 54, 64, 192)] - [SliderColor(224, 165, 56, 128)] - [Range(MinMeterShake, MaxMeterShake)] - [Increment(1f)] - [DrawTicks] - [DefaultValue(2f)] - public float RipperMeterShake { get; set; } - - [BackgroundColor(192, 54, 64, 192)] - [SliderColor(224, 165, 56, 128)] - [Range(0f, 100f)] - [DefaultValue(RipperUI.DefaultRagePosX)] - public float RageMeterPosX { get; set; } - - [BackgroundColor(192, 54, 64, 192)] - [SliderColor(224, 165, 56, 128)] - [Range(0f, 100f)] - [DefaultValue(RipperUI.DefaultRagePosY)] - public float RageMeterPosY { get; set; } - - [BackgroundColor(192, 54, 64, 192)] - [SliderColor(224, 165, 56, 128)] - [Range(0f, 100f)] - [DefaultValue(RipperUI.DefaultAdrenPosX)] - public float AdrenalineMeterPosX { get; set; } - - [BackgroundColor(192, 54, 64, 192)] - [SliderColor(224, 165, 56, 128)] - [Range(0f, 100f)] - [DefaultValue(RipperUI.DefaultAdrenPosY)] - public float AdrenalineMeterPosY { get; set; } - #endregion } } diff --git a/CalamityLists.cs b/CalamityLists.cs index 0fba8bdfb7..37f030063c 100644 --- a/CalamityLists.cs +++ b/CalamityLists.cs @@ -89,7 +89,6 @@ public class CalamityLists public static List fireDebuffList; public static List sicknessDebuffList; public static List alcoholList; - public static List spearAutoreuseList; public static List pumpkinMoonBuffList; public static List frostMoonBuffList; public static List eclipseBuffList; @@ -147,8 +146,6 @@ public class CalamityLists public static List legOverrideList; - public static List kamiDebuffColorImmuneList; - public static Dictionary EncryptedSchematicIDRelationship; public static List DisabledSummonerNerfItems; @@ -158,639 +155,750 @@ public class CalamityLists public static void LoadLists() { - donatorList = new List() + var newDonatorList = new List() + { + "Aerosyn", + "always-tired", + "Amandalias", + "andrew rodriguez", + "Ant Slime", + "ArcTwik", + "Arcxus", + "Arialen", + "Ariallis", + "awesomechapro", + "Axy Usagi", + "Azariah", + "azazel", + "Bepzi25", + "BlueRay_256", + "Boomdiada", + "Borb9834", + "botbot94", + "Brio_Scarlet", + "Brodiero-Solar", + "Bruggs", + "c0d3_404", + "Careless_imp", + "Catkey", + "Charge Maniac", + "Chin", + "Chloe", + "Chow Chow", + "Cosmore", + "CrazyGamer69", + "Creeper Hunter 2K0", + "Darthlego", + "Diamond Nife", + "djsnj20", + "DogVTF", + "Dragev", + "Easy Perrin", + "Entrian", + "Equinoxux", + "EternalGrayson", + "FishBread", + "Grant Curtiss", + "Halleyvetica", + "Hamsting", + "helptree", + "Herr Feuer", + "Iptktp9", + "Jalapeno9", + "Jankle", + "JFL", + "Johnny", + "Juneark", + "J.U.N.E.S", + "Justin", + "Kaitlyn-Kerbulon", + "KapryÅny", + "Kat Manklow", + "Kelt", + "Kiddorox", + "Kiwi_lol", + "Levi Sharpe", + "Liam Rafle", + "Lightedflare", + "Lolmoeven", + "Luke Wakumoto", + "Lumenos", + "Magic Love", + "Magicoal", + "MalachiteWisp", + "MarioMan84", + "mARvOEoUS", + "MaxingOut", + "Medi", + "Mint_loll", + "Misterbottle8", + "MizzUltraViolet DamienTK", + "Nature", + "niceguysrage", + "nill bye", + "Nova Solarius", + "NyxxyNightstar", + "OakhamSam", + "PantySlack", + "Patch357", + "Phil Broome", + "Pomelo", + "Pseulamitas", + "Red", + "Red X", + "Renavo", + "Roadie Roadster", + "Robert Yaron", + "roryoftheabyss", + "Rowan Shane", + "Sable", + "Salted Warlock", + "Sharktank6", + //"Shayy", // Removed from circulation as the user in question committed acts undeserving of recognition + "shredalert", + "SirChaos189", + "SomeRandomPerson", + "Taylor Olligoci", // also an ex-dev. Listed as "Lilac Olligoci" on Patreon. There were two "Taylor"s on the old list + "Tethox", + "thalass", + "thanat.oshi", + "The Deer Who Sold The World", + "The Roborex", + "Thessyll", + "Trinity Series", + "Tsukara", + "Tweee", + "twist", + "Umbara", + "Unreal Parrot", + "V00194", + "Vanillin", + "Voltron284", + "WatWouldJesusDo", + "weisslerren", + "Xtra Trinity 3678", + "Yaggitarius", + "YashimaYamanata", + "Zachtoplasm", + "Zackstar02", + "ZoeyPlague", + }; + + var oldDonatorList = new List { - "Vorbis", - "SoloMael", - "Chaotic Reks", - "The Buildmonger", - "YuH", - "Littlepiggy", - "LompL", - "Lilith", - "Ben Shapiro", - "Frederik", - "Faye", - "Gibb50", - "Braden", - "Hannes", - "profoundmango69", - "Jack", - "Hans Volter", - "Krankwagon", - "MishiroUsui", - "pixlgray", - "Arkhine", - "Lodude", - "DevAesthetic", - "Mister Winchester", - "Zacky", - "Veine", - "Javyz", - "Shifter", - "Crysthamyr", - "Elfinlocks", - "Ein", + "116taj", + "26-4-1", "2Larry2", - "Jenonen", - "Dodu", - "Arti", - "Tervastator", - "Luis", + "3en", + "3x1t_5tyl3", + "adain", + "Adamko", + "Aden C.N.", + "Aero", + "Aero (Aero#4599)", + "Æthereal", + "Afzofa", + "Aidan", + "Aidan Spears", + "Akkolite", + "Albino gonkvader", + "Alec", + "Aleksanders", + "Aleksh", + "Alex", "Alexander", + "Alexis", + "Alex N", + "Alfragiste", + "Allegro", + "allosar", + "Ally2Cute", + "Altzeus", + "anglerraptor", + "Anish", + "A_Normal_Person", + "Anton", + "Antonie", + "anything5000", + "Apotheosis", + "apotofkoolaid", + "Arcadia", + "Arche", + "Archie", + "Ari", + "Ariscottle", + "Arkhine", + "Arthur", + "Arti", + "asdf935", + "Ash", + "Ashamper", + "Asheel", + "Ashton", + "Audrey Lynn Beemus", + "Avery", + "Azura", + "Azure", + "Azzilan", "BakaQing", - "Taylor", - "Xaphlactus", - "MajinBagel", + "Ballin", + "Barbara", + "Barrett Turner", + "Ben", "Bendy", - "Rando Calrissian", - "Tails the Fox 92", + "Beta165", + "bikmin", + "Bill", + "Billy", + "Blackbluue", + "Bladesaber", + "Blobby6799", + "BobIsNotMyRealName", + "Bossy Punch", + "Braden", + "BreachNClear747", "Bread", - "Minty Candy", - "Preston", - "MovingTarget_086", - "Shiro", + "Brendan", + "Brian", + "Briny_Coffee", + "Broken Faucet", + "Bruh.PNG", + "Brutus", + "Brutzli", + "BumbleDoge", + "Buppercups - Roblox", + "Bwlstorm", + "CaineSenpai", + "Calcium Comrade", + "callisto", + "Cameron", + "Carboniferous", + "Carduelis", + "CasualNoLifer", + "Cerberus", + "Chaos", + "ChaosChaos", + "ChAoS DiScOrD", + "Chaotic Reks", + "Chaozhi", + "Charles", + "Check pins", + "Cheddar", + "Chigbungus", "Chip", - "Taylor", - "ShotgunAngel", - "Sandblast", - "ThomasThePencil", - "Aero (Aero#4599)", - "Shirosity", // used to be GlitchOut - "Daawnz", - "CrabBar", - "Yatagarasu", - "Jarod", - "Zombieh", - "MingWhy", - "Random Weeb", - "Afzofa", - "Eragon3942", - "TheBlackHand", - "william", - "Samuel", + "ChrigTopher", "Christopher", - "DemoN K!ng", - "Malik", - "Ryan Baker-Ortiz", - "Aleksanders", - "TheSilverGhost", - "Lucazii", - "Shay", - "Prism", - "BobIsNotMyRealName", - "Guwahavel", - "Azura", - "Joshua", - "Doveda", - "William", - "Arche", - "DevilSunrise", - "Yanmei", - "Chaos", - "Ryan", - "Fish Repairs", - "Melvin", - "Vroomy Has -3,000 IQ", - "The Goliath", - "DaPyRo", - "Takeru", + "Cinder", "Circuit-Jay", - "Commmander Frostbite", - "cytokat", - "Cameron", - "Orudeon", - "BumbleDoge", - "Naglfar", - "Helixas", - "Vetus", - "High Charity", - "Devonte", - "Cerberus", - "Brendan", - "Victor", - "KAT-G307", - "Tombarry Expresserino", - "Drip Veezy", - "Glaid", - "Apotheosis", - "Bladesaber", - "Devon", - "Ruthoranium", "cocodezi_", - "Mendzey", - "GameRDheAsianSandwich", - "Tobias", - "Streakist", - "Eisaya", - "Xenocrona", - "RKMoon", - "Eternal Silence", - "Jeff", - "Beta165", - "DanYami", - "Xenocrona", - "Ari", + "Cody", + "Cole", + "Colin", + "Colin V", + "Commander Frostbite", + "Conner", + "Coolguystorm YT", + "Corn M. Cobb", "cosmickalamity", - "xd Ow0", + "CosmicStarIight", + "CrabBar", + "Creamy", + "CrimsonCrips", + "Crippling-Ambition", + "Cristian(Mihaii)", + "Crysthamyr", + "Culex", + "Curtis", + "cytokat", + "Daawnz", + "Dakota", + "Dakota C", + "DanYami", + "DaPyRo", + "darkhawke", + "Darkus", + "Darkweb", "Darren", - "Florian", + "Dasdruid", + "dawnboi", "dawn thunder", - "asdf935", - "GentSkeleton", - "Fizzlpoprock", - "Pigeon", - "Aleksh", - "Just a random guy", + "Dayne", + "ddoogg88 tdog", + "Deallly", "Dee", - "Æthereal", - "Broken Faucet", - "Sarcosuchus", - "Marissa443", - "Warlok", - "JackShizz", - "NebulaMagePlays", - "Primpy", - "Thys", - "Min", - "Wodernet", - "Pedro", + "DeLordeyeee", + "DemoN K!ng", + "dennis", "Depressed Dad Gaming", - "Snowy", - "Stormone", - "Mobian", - "Rinja", - "Check pins", - "Dakota", - "Neoplasmatic", - "False", - "Whitegiraffe", + "Derdjin", + "DESPACITO", + "Destiny Stallcup", + "Destructoid", + "DevAesthetic", + "DevilSunrise", + "Devin", + "Devon", + "Devonte", + "dexxer65", + "Dionysos", + "discokittie", + "DjackV", + "DOGMA", + "Domrinth", + "Done", + "Doodled_lynx", + "Doug", + "Doveda", + "drake093104", "Drakkece", - "Levi", - "Izuna", - "djsnj20", - "pyobbo", - "Alec", - "The Illustrious Sqouinchuousor", - "Moist Lad", - "TwanTheGOAT", - "3x1t_5tyl3", - "Will", - "SpookyNinja", - "Boomdiada", - "Culex", - "Rossadon", - "Ben", - "hubert thieblot", - "NepNep", - "Nanaki", - "CrimsonCrips", - "Lagohz", - "Timon", + "drenmus!", + "Drip Veezy", + "Driser", + "Dr. Pawsworth", + "Duck Satan", + "Dull", + "dummyAzure", + "Dylan", + "Eddie Spaghetti", + "EdelVollMilch", + "edm vibes", + "Ein", + "Eisaya", + "Ekun", + "Elementari", + "Elfinlocks", + "Elijah", + "Empress Vega", + "Eragon3942", + "Eric", + "Eternal Silence", + "Ethan", + "ethan", + "everquartz", "F00d Demon", - "Olkothan", - "Vmar98", - "Dasdruid", - "Cinder", - "Brutzli", - "Yhashtur", - "Zekai", - "Doug", - "Uberransy", - "KurlozClown", - "Nemesis 041", - "Asheel", - "Hayden", - "Lightedflare", - "Lady Shira", - "Devin", - "Qelrin", - "Thomas", - "Ne'er Dowell", - "Potion Man", - "martyrdomination", - "Destructoid", - "Coolguystorm YT", - "Wolfmaw", - "yiumik", - "Destiny Stallcup", - "GreenBerry", - "SolsticeUnlimitd", - "darkhawke", - "oracle", - "YumeiSenshi", - "Cameron", - "Toxin", + "Face", + "FaeLoPondering", + "False", + "Fartein", + "Faye", + "Feels Fishy", + "Ferret4T", + "Finnrua", + "fire", + "Fish Repairs", + "Fizzlpoprock", + "Florian", + "Forge", + "Freakish", + "Frederik", "Fweepachino", - "DESPACITO", - "Altzeus", - "Ryan", - "Spider region", - "WinterTire", - "Nycro", - "Bewearium", - "William", - "HellGoat2", - "116taj", - "CaineSenpai", - "Suicide Dreams", - "Roxas", - "Obsoleek", - "Jetpat3", + "Gameology", + "GameRDheAsianSandwich", + "Gamma Freya", + "garfu", + "GentSkeleton", + "Georgios", + "Gibb50", + "GIGA MAN", + "Gilded Gryphon", + "Glaid", + "gluten tag", + "Goblin", + "goo", + "Goober", + "Goomfrontlut", + "GP", + "GreenBerry", "GreenTea", - "Woah", - "Ryaegos", - "Popsickle Yoshi", - "Arcadia", - "JensB__", - "Nuclei", - "Picasso's Bean", - "Corn M. Cobb", - "kgh8090", - "Luke", - "Barbara", - "Alexis", - "Soko", - "Albino gonkvader", - "Monic", - "Slim", - "ChaosChaos", - "Deallly", - "Jeff", - "vcf55", - "Kazurgundu", - "Jheybyrd", - "Kipluck", - "SCONICBOOM", - "Mr.Matter", - "Billy", - "jjth0m3", + "GregTheSpinarak", + "Gretchen", + "Griffin", + "Grylken", "GTW High Cube", - "Sabrina", - "Potato - Stego", - "Perditio Astrum", - "MaxingOut", - "SharZz", - "Allegro", + "Guwahavel", + "Habb", + "haefer.goat.oats", + "Hana", + "Handburger", + "Hannes", + "Hans Volter", + "happy thoughts", + "Hargestar", + "Hayden", + "Helixas", + "HellGoat2", + "High Charity", + "Him", + "Himakaze", + "Hokojin", + "Homunculus Derelictus", "hoosfire", - "Lauren", - "Ultra Succ", - "Ethan", - "Pacnysam", - "dummyAzure", + "hubert thieblot", + "Hunter", + "Iconic Parker Gaming", + "Iguy", + "Indeciiissive", + "IsaacInsomnia", + "Izuna", + "Jace Ufret", + "Jack", + "JackShizz", + "Jackson", + "Jakob", + "James", + "Jarod", + "Javyz", + "Jaydon", "Jaykob", - "Goblin", - "NoOneElse", - "Nicholas", - "Toasty", - "oli saer", - "Blobby6799", - "Domrinth", - "zombieseatflesh7", - "Shiny", - "Whale", - "The Infinity", - "MrCreamen", - "TemperedAether", - "LucasTwocas", + "jc.", + "Jeff", + "Jenonen", + "JensB__", + "Jersey", + "jes", + "Jessire", + "Jetpat3", + "Jheybyrd", + "jjth0m3", + "Joe", + "Joep", + "Jordan", + "Jose", + "Joshua", + "julius", + "just akkolite", + "Just a random guy", "JustLonelyPi", - "Brian", - "Ashton", - "Rolandark", - "Ally2Cute", - "Dionysos", - "Plant Waifu", - "fire", - "Charles", "Kaden", - "Dr. Pawsworth", - "Jackson", - "Freakish", - "Ashamper", - "Kinzoku", - "Elementari", - "The Wolf Commando", - "Jordan", - "Jessire", - "Ashton", - "callisto", - "velneu", - "Mathuantie", - "Robert", - "Matias", - "T E R M I N A T O R", - "apotofkoolaid", - "Matthew", - "Terrarian Dragon", - "Pomelo", - "Thomas", - "Iconic Parker Gaming", - "Jaydon", - "Aidan", - "Avery", - "yayoi", - "Splotchycrib", - "GIGA MAN", - "Eric", - "Merubel", - "Smug", - "Lime-Wars l 1", - "WillyDilly", - "xAqult", - "Himakaze", - "Face", - "Carboniferous", - "James", - "Taitou1", - "Yumi", - "NEBULA", - "Blackbluue", - "Alex", - "Ruben", - "Rixu", - "Antonie", - "Zerimore", - "Oblivionisbruh", - "Loser", - "Patrick", - "Magic Love", - "gluten tag", - "RetroRed", + "Kaimonick", + "Kaledoulas", + "KAT-G307", "Katherine", - "SoyScoutSmasher", - "Jersey", - "Reiter splash", - "Conner", - "Ekun", - "Driser", - "bikmin", - "MittoMan", - "Pyromaniac146", - "Eddie Spaghetti", - "Colin", - "ZyferDex_", - "LumiEvi", - "Anish", - "MissMudflaps", - "Valkyrie", - "anglerraptor", - "Scribbles", - "Pneuma", - "OrrangProto", - "Tomat (Stevie)", - "That Katsafaros", - "PsychoGrizzly", - "Dayne", - "Hargestar", - "The Pyro", - "Lucas", - "Superbeepig", - "Larry That Barry", - "Monti", - "StarryFox", + "Kazurgundu", + "KeL", "Kevin", - "Poopifier Poopifly", + "kgh8090", + "Kinzoku", + "Kipluck", + "Kiyotu", + "KJ", + "Konorango", + "Korb Orb", + "Krankwagon", + "KugelBlitz", + "KurlozClown", "Lacuna", - "Nathan", - "Handburger", - "XusTingo9", - "Underlost", - "julius", - "Mark", - "Habb", - "Reanamet", - "Empress Vega", - "Team", - "GP", - "Xsiana", - "NyanLegacy215", - "ethan", - "Trinity Series", + "Lady Shira", + "Lagohz", + "Lance", + "Landon", + "Larry That Barry", + "Lauren", + "Leonidas", + "Levi", + "Lilith", + "Lime-Wars l 1", + "Littlepiggy", + "Lodude", + "LompL", + "Lord_Lucerne", + "Loser", + "Lucas", + "LucasHM", + "LucasTwocas", + "Lucazii", + "Luis", + "Luke", + "LumiEvi", + "LvL-94", "M001NG", - "WrathOfOlympus", - "dennis", - "Darkweb", - "Chaozhi", + "Madd Cat", + "MajinBagel", + "Malik", + "Marco", + "Marissa443", + "Mark", + "Marko", "Mars", - "Elijah", - "Tezguin", - "Shpee", - "Archie", - "Meow", - "CosmicStarIight", - "Alfragiste", - "Number1piratepan", - "Noah", + "martyrdomination", + "Maskedmilo", + "Mathuantie", + "Matias", + "Matthew", "Max Kim", - "Anton", - "edm vibes", - "Hunter", - "Doodled_lynx", - "3en", - "Kiyotu", - "Aero", - "Iguy", - "병현 송", - "Tyler", - "Leonidas", - "GregTheSpinarak", - "Cheddar", - "Alex N", - "Magicoal", - "Seanツ", - "Ariscottle", - "Kevin", - "OnTheAirPogs", - "Zerafir", - "Bill", - "Starmitzy", - "FaeLoPondering", - "Brian", - "Smart2004", - "sherk", - "Squishy", - "Ash", - "rawpie2", - "Hokojin", - "sk", - "Done", + "Mayhem", "MeanieG", - "Sanctuary", - "Landon", - "Moonicento", - "Hayden", - "Steven", - "Hana", + "Melvin", + "Mendzey", + "Meow", + "Merubel", + "Met Vox", "Mikabul", - "Nathaniel", - "Brutus", - "EdelVollMilch", - "garfu", - "NuT NiTe", - "adain", - "Dylan", - "Lucas", - "Arthur", - "sweatingdishes", - "pomp neigh", - "Proffesor prostate", - "Saladify", - "26-4-1", - "VeryMasterNinja", - "Vorbis", - "Nyapano", - "Shadoku", - "allosar", - "jes", - "Paltham", - "Fartein", - "Derdjin", - "A_Normal_Person", - "Duck Satan", - "Jalapeno9", - "Grylken", - "Nexus", - "KJ", - "Goober", - "ChAoS DiScOrD", - "Mayhem", - "Zombified _G", - "Madd Cat", + "Min", + "MingWhy", + "Minty Candy", + "MishiroUsui", + "Misinput", + "MissMudflaps", + "Mister Winchester", + "MittoMan", + "MiyoshiEira", + "Mobian", + "Mohammad", + "Moist Lad", + "Monic", + "Monti", + "Moonicento", + "MovingTarget_086", + "Mr. Bones", + "MrCreamen", + "Mr.Matter", + "MrNobody", + "n0tacat", + "Naglfar", + "Nanaki", "Natalie", - "Solaire", - "Dakota C", - "The Davester", - "Jose", - "Him", - "Umberto", - "Lance", + "Nathan", "Navigator", - "Ferret4T", - "Rooki", - "LvL-94", - "Feels Fishy", - "Korb Orb", - "Calcium Comrade", - "Talmadge", - "ddoogg88 tdog", - "CasualNoLifer", - "Bossy Punch", - "Creamy", - "Tyler", - "topnormal", - "Gilded Gryphon", + "Ne'er Dowell", + "NEBULA", + "NebulaMagePlays", + "Nemesis 041", + "Neoplasmatic", + "NepNep", + "Nexus", + "Nicholas", + "Nick H", + "Nightinglade", "Nightskyflyer", + "Nitronium Productions", + "Noah", + "NoOneElse", + "Nothin Purrsonal", + "Nuclear Chaos", + "Nuclei", + "Number1piratepan", + "NuT NiTe", + "NyanLegacy215", + "Nyapano", + "Nycro", + "Oblivionisbruh", + "Obsoleek", + "Oceanman232", + "OctolingGrimm", + "oli saer", + "Olkothan", + "OnTheAirPogs", + "oracle", + "OriginForme487", + "OrrangProto", + "Orudeon", + "Pacnysam", + "Paltham", + "Patrera", + "Patrick", + "Pedro", + "Perditio Astrum", + "Picasso's Bean", + "Pigeon", + "Plant Waifu", + "Pneuma", + "pomp neigh", + "Ponynator", + "Poopifier Poopifly", + "Popsickle Yoshi", + "porglesupreme", + "Potato - Stego", + "Potion Man", + "Preston", + "Primpy", + "Prism", + "Professor Pissington", + "ProfessorWinston", + "Proffesor prostate", + "profoundmango69", + "PsychoGrizzly", + "Pusheen_", + "pyobbo", + "Pyromaniac146", + "Qelrin", + "Qwertz", + "Rando Calrissian", + "Random Weeb", + "rawpie2", + "Real mystlc", + "Reanamet", + "Reece", + "Reiter splash", + "RetroRed", + "Rinja", + "Rixu", + "RKMoon", + "Robert", + "RockRecker39", + "Rolandark", + "Rooki", + "Rossadon", + "Rottingwood", + "Roxas", + "Ruben", + "RuskieThe3rd", + "Ruthoranium", + "Ryaegos", + "Ryan", + "Ryan Baker-Ortiz", + "Sabrina", + "Sadouken", + "Sailor Jolt", + "SakuraWinterz", + "Saladify", + "Samuel", + "Sanctuary", + "Sandblast", + "Sarcosuchus", "Schlarfblrfsch", - "MrNobody", - "Aden C.N.", - "zombie wolf", - "n0tacat", - "Marko", - "dexxer65", - "DeLordeyeee", - "Kaledoulas", - "Mohammad", - "Skeli_G", - "Arcxus", + "schmoovi", + "SCONICBOOM", + "Scribbles", + "Scrumlet", + "Seanツ", + "Sevenfold", + "Shadoku", + "SharZz", + "Shaun", + "sherk", + "Shifter", + "Shiny", + "Shiro", + "Shirosity", // used to be GlitchOut + "ShotgunAngel", + "Shpee", "Sigil", - "Dull", - "DjackV", - "Misinput", - "Gameology", - "KugelBlitz", - "TheGreatSako", - "Joep", - "Rottingwood", - "anything5000", - "Gretchen", - "Spirit Shield", - "Briny_Coffee", + "sk", "_Skeggy_", - "just akkolite", - "J.U.N.E.S", - "Bruggs", - "Vimek Xol", - "Oceanman232", - "Sadouken", + "SkeletonHunter96", + "Skeli_G", + "Slim", + "Smart2004", + "Smug", + "Snowy", + "Soko", + "Solaire", + "SoloMael", + "SolsticeUnlimitd", + "SomeRando", + "SoyScoutSmasher", + "Spider region", + "Spirit Shield", + "Splotchycrib", + "SpookyNinja", + "Squishy", "srxe", - "ProfessorWinston", - "OctolingGrimm", - "Cole", - "Markie", - "Met Vox", - "Tweee", - "Kaimonick", - "Chow Chow", - "drenmus!", - "Nitronium Productions", - "Goomfrontlut", - "Akkolite", - "Shaun", - "Bruh.PNG", - "James", - "Lord_Lucerne", - "Ulmod", - "Adamko", - "Gamma Freya", - "Finnrua", - "Maskedmilo", - "RockRecker39", - "Konorango", - "Indeciiissive", - "Curtis", - "Ponynator", - "Crippling-Ambition", - "TitaniumLlama", - "OriginForme487", - "FishBread", - "Real mystlc", - "Levi", - "jc.", - "Medi", - "Jakob", - "Borb9834", - "Georgios", - "KeL", - "Cody", - "Cristian(Mihaii)", - "Marco", - "RuskieThe3rd", - "BreachNClear747", - "happy thoughts", - "Azure", + "Starmitzy", + "StarryFox", + "Steven", + "Stormone", + "Streakist", + "Suicide Dreams", + "Superbeepig", + "sweatingdishes", + "Taelishe", + "Tails the Fox 92", + "Taitou1", + "Takeru", + "Talmadge", + "Taylor", + "Team", + "TemperedAether", + "T E R M I N A T O R", + "Terrarian Dragon", + "Tervastator", + "Tezguin", + "That Katsafaros", + "thebettercat", + "TheBlackHand", + "The Buildmonger", + "The Davester", + "The Evolution", + "The Goliath", + "TheGreatSako", "theHoopty", - "porglesupreme", + "The Illustrious Sqouinchuousor", + "The Infinity", + "The Pyro", + "TheSilverGhost", + "The Wither", + "The Wolf Commando", + "Thomas", + "ThomasThePencil", + "Thys", + "Timon", + "TitaniumLlama", + "Tomat (Stevie)", + "Tombarry Expresserino", + "topnormal", + "Toxin", + "TwanTheGOAT", + "Tyler", + "Uberransy", + "Ulmod", + "Ultra Succ", + "Umberto", + "Underlost", + "Valkyrie", + "vcf55", + "Veine", + "velneu", + "Vertigo", + "VeryMasterNinja", + "Vetus", + "Victor", + "Vimek Xol", + "Vmar98", + "Vorbis", + "Vroomy Has -3,000 IQ", + "Vyster", + "Warlok", + "Whale", + "Whitegiraffe", + "Will", + "William", + "william", + "WillyDilly", + "WinterTire", + "Wodernet", + "Wolfmaw", + "WrathOfOlympus", + "Xaphlactus", + "xAqult", "XDkilljoy65XX", - "Mr. Bones", - "dawnboi", - "Joe", - "Sailor Jolt", - "SomeRando", - "Nuclear Chaos", - "Jankle", - "The Roborex", - "everquartz", - "discokittie", - "IsaacInsomnia", + "xd Ow0", "xElectrix_", - "Forge", - "MiyoshiEira", - "thebettercat", - "Darthlego", - "Azzilan", - "Griffin", - "LucasHM", - "ChrigTopher", - "Colin V", - "Scrumlet", - "Darkus", - "Homunculus Derelictus", - "Professor Pissington", - "Buppercups - Roblox", - "Pusheen_", - "Patrera" + "Xsiana", + "Xtra", + "XusTingo9", + "Xzier_Tengal", + "Yatagarasu", + "yayoi", + "Yhashtur", + "yiumik", + "YuH", + "YumeiSenshi", + "Yumi", + "Zacky", + "Zekai", + "Zerafir", + "Zerimore", + "Zombieh", + "zombieseatflesh7", + "zombie wolf", + "Zombified _G", + "ZyferDex_", + "병현 송" }; + donatorList = [.. oldDonatorList, .. newDonatorList]; + projectileDestroyExceptionList = new List() { //holdout projectiles @@ -842,7 +950,7 @@ public static void LoadLists() ProjectileType(), ProjectileType(), ProjectileType(), - ProjectileType(), + ProjectileType(), ProjectileType(), ProjectileType(), ProjectileType(), @@ -923,7 +1031,6 @@ public static void LoadLists() NPCID.Retinazer, NPCID.Spazmatism, NPCID.SkeletronPrime, - NPCType(), NPCID.PrimeCannon, NPCID.PrimeSaw, NPCID.PrimeLaser, @@ -1267,28 +1374,6 @@ public static void LoadLists() BuffType() }; - spearAutoreuseList = new List() - { - ItemID.AdamantiteGlaive, - ItemID.ChlorophytePartisan, - ItemID.CobaltNaginata, - ItemID.DarkLance, - ItemID.MonkStaffT2, - ItemID.Gungnir, - ItemID.MushroomSpear, - ItemID.MythrilHalberd, - ItemID.NorthPole, - ItemID.ObsidianSwordfish, - ItemID.OrichalcumHalberd, - ItemID.PalladiumPike, - ItemID.Spear, - ItemID.Swordfish, - ItemID.TheRottedFork, - ItemID.TitaniumTrident, - ItemID.Trident, - ItemID.ThunderSpear - }; - pumpkinMoonBuffList = new List() { NPCID.Scarecrow1, @@ -1521,7 +1606,7 @@ public static void LoadLists() BuffType(), BuffType(), BuffType(), - BuffType(), + BuffType(), BuffType(), BuffType(), BuffType(), @@ -2074,7 +2159,6 @@ public static void LoadLists() SkeletronPrimeIDs = new List { NPCID.SkeletronPrime, - NPCType(), NPCID.PrimeCannon, NPCID.PrimeLaser, NPCID.PrimeSaw, @@ -2479,7 +2563,6 @@ public static void LoadLists() { NPCID.Probe, 5000 }, { NPCID.SkeletronPrime, 160000 }, // 30 seconds - { NPCType(), 160000 }, { NPCID.PrimeVice, 54000 }, { NPCID.PrimeCannon, 45000 }, { NPCID.PrimeSaw, 45000 }, @@ -2603,15 +2686,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(), @@ -2650,7 +2724,6 @@ public static void UnloadLists() fireDebuffList = null; sicknessDebuffList = null; alcoholList = null; - spearAutoreuseList = null; pumpkinMoonBuffList = null; frostMoonBuffList = null; eclipseBuffList = null; @@ -2708,8 +2781,6 @@ public static void UnloadLists() legOverrideList = null; - kamiDebuffColorImmuneList = null; - EncryptedSchematicIDRelationship = null; DisabledSummonerNerfItems = null; diff --git a/CalamityMod.cs b/CalamityMod.cs index 7ac3568177..8fc7d201d2 100644 --- a/CalamityMod.cs +++ b/CalamityMod.cs @@ -55,13 +55,13 @@ using CalamityMod.UI.CalamitasEnchants; using CalamityMod.UI.DraedonsArsenal; using CalamityMod.UI.Rippers; -using CalamityMod.Waters; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using ReLogic.Content; using Terraria; using Terraria.GameContent; using Terraria.GameContent.Dyes; +using Terraria.GameContent.Liquid; using Terraria.Graphics.Effects; using Terraria.Graphics.Shaders; using Terraria.ID; @@ -108,14 +108,25 @@ public class CalamityMod : Mod // Destroyer glowmasks public static Asset[] DestroyerGlowmasks = new Asset[3]; + // Holds the Texture Arrays for all the lava textures. + // These are used for the lava styles. They are seperate from Textureasset.Instance._liquidTexture as they will conflict with ModWaterStyle + // Can hold up to 255 lava styles (more than enough) (excluding the normal lava texture which is liquidTexture 1) + public struct LavaTextures + { + public static Asset[] liquid = new Asset[1]; + public static Asset[] slope = new Asset[1]; + public static Asset[] block = new Asset[1]; + public static Asset[] fall = new Asset[1]; + } + + public static int LavaStyle; + + public static float[] lavaAlpha = new float[1]; + // Wall of Flesh glowmasks public static Asset WallOfFleshEyeGlowmask; public static Asset WallOfFleshDemonSickleTexture; - // Master Rev+ Skeletron Prime - public static Asset ChadPrime; - public static Asset ChadPrimeEyeGlowmask; - // DR data structure public static SortedDictionary DRValues; @@ -137,8 +148,14 @@ public class CalamityMod : Mod internal Mod musicMod = null; internal bool MusicAvailable => musicMod is not null; + // This is Vanilla Calamity Mod Music, internally named UnCalamityModMusic. + // VCMM is an official music add-on. Unlike the main music mod, it is not a dependency. + internal Mod vcmm = null; + internal bool VCMMAvailable => vcmm is not null; + // Please keep this in alphabetical order so it's easy to read internal Mod ancientsAwakened = null; + internal Mod biomeLava = null; internal Mod bossChecklist = null; internal Mod coloredDamageTypes = null; internal Mod crouchMod = null; @@ -168,8 +185,12 @@ public override void Load() // If any of these mods aren't loaded, it will simply keep them as null. musicMod = null; ModLoader.TryGetMod("CalamityModMusic", out musicMod); + vcmm = null; + ModLoader.TryGetMod("UnCalamityModMusic", out vcmm); ancientsAwakened = null; ModLoader.TryGetMod("AAMod", out ancientsAwakened); + biomeLava = null; + ModLoader.TryGetMod("BiomeLava", out biomeLava); bossChecklist = null; ModLoader.TryGetMod("BossChecklist", out bossChecklist); coloredDamageTypes = null; @@ -243,7 +264,10 @@ public override void Load() SetupVanillaDR(); SetupBossKillTimes(); SchematicManager.Load(); - CustomLavaManagement.Load(); + + //lava + WeakReferenceSupport.LavaStytleToBiomeLava(); + Attunement.Load(); BalancingChangesManager.Load(); BaseIdleHoldoutProjectile.LoadAll(); @@ -301,14 +325,17 @@ private void LoadClient() DestroyerGlowmasks[1] = ModContent.Request("CalamityMod/ExtraTextures/VanillaBossGlowmasks/DestroyerBodyGlow", AssetRequestMode.AsyncLoad); DestroyerGlowmasks[2] = ModContent.Request("CalamityMod/ExtraTextures/VanillaBossGlowmasks/DestroyerTailGlow", AssetRequestMode.AsyncLoad); + // Lava Texture + LavaTextures.liquid[0] = LiquidRenderer.Instance._liquidTextures[1]; + LavaTextures.slope[0] = TextureAssets.LiquidSlope[1]; + LavaTextures.block[0] = TextureAssets.Liquid[1]; + var waterfallTexture = (Asset[])typeof(WaterfallManager).GetField("waterfallTexture", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).GetValue(Main.instance.waterfallManager); + LavaTextures.fall[0] = waterfallTexture[1]; + // Wall of Flesh glowmasks WallOfFleshEyeGlowmask = ModContent.Request("CalamityMod/ExtraTextures/VanillaBossGlowmasks/WallOfFleshEyeTelegraphGlow", AssetRequestMode.AsyncLoad); WallOfFleshDemonSickleTexture = ModContent.Request("CalamityMod/Projectiles/Melee/ForbiddenOathbladeProjectile", AssetRequestMode.AsyncLoad); - // Master Rev+ Skeletron Prime textures - ChadPrime = ModContent.Request("CalamityMod/ExtraTextures/ChadPrime", AssetRequestMode.AsyncLoad); - ChadPrimeEyeGlowmask = ModContent.Request("CalamityMod/ExtraTextures/ChadPrimeHeadGlow", AssetRequestMode.AsyncLoad); - // TODO -- Sky shaders should probably be loaded in a ModSystem Filters.Scene["CalamityMod:DevourerofGodsHead"] = new Filter(new DoGScreenShaderData("FilterMiniTower").UseColor(0.4f, 0.1f, 1.0f).UseOpacity(0.5f), EffectPriority.VeryHigh); SkyManager.Instance["CalamityMod:DevourerofGodsHead"] = new DoGSky(); @@ -414,8 +441,10 @@ private void LoadClient() public override void Unload() { musicMod = null; + vcmm = null; ancientsAwakened = null; + biomeLava = null; bossChecklist = null; coloredDamageTypes = null; crouchMod = null; @@ -447,12 +476,12 @@ public override void Unload() NPCStats.Unload(); CalamityGlobalItem.UnloadTweaks(); CalamityGlobalProjectile.UnloadTweaks(); + FramedGlowMask.UnloadTexCache(); PopupGUIManager.UnloadGUIs(); InvasionProgressUIManager.UnloadGUIs(); BossRushEvent.Unload(); SchematicManager.Unload(); - CustomLavaManagement.Unload(); CooldownRegistry.Unload(); PlayerDashManager.Unload(); @@ -515,7 +544,7 @@ public static void PrepareRenderTargets(GameTime gameTime) #endregion Render Target Management #region Force ModConfig save (Reflection) - internal static void SaveConfig(CalamityConfig cfg) + internal static void SaveConfig(CalamityClientConfig cfg) { // There is no current way to manually save a mod configuration file in tModLoader. // The method which saves mod config files is private in ConfigManager, so reflection is used to invoke it. @@ -757,6 +786,10 @@ private void SetupBossKillTimes() // This function returns an available Calamity Music Mod track, or null if the Calamity Music Mod is not available. public int? GetMusicFromMusicMod(string songFilename) => MusicAvailable ? MusicLoader.GetMusicSlot(musicMod, "Sounds/Music/" + songFilename) : null; + // This function returns an available VCMM track, or null if VCMM is not available. + // Unlike the main Music Mod, VCMM is hierarchical. + public int? GetMusicFromVCMM(string songPath) => VCMMAvailable ? MusicLoader.GetMusicSlot(vcmm, "Assets/" + songPath) : null; + #endregion #region Mod Support diff --git a/CalamityMod.csproj b/CalamityMod.csproj new file mode 100644 index 0000000000..644d993a43 --- /dev/null +++ b/CalamityMod.csproj @@ -0,0 +1,14 @@ + + + + + CalamityMod + net8.0 + AnyCPU + latest + true + + + + + 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/ChaosState.cs b/Cooldowns/ChaosState.cs index 4759b9b42c..a049141f3d 100644 --- a/Cooldowns/ChaosState.cs +++ b/Cooldowns/ChaosState.cs @@ -8,7 +8,7 @@ public class ChaosState : CooldownHandler { public static new string ID => "ChaosState"; - public override bool ShouldDisplay => CalamityConfig.Instance.VanillaCooldownDisplay && instance.player.chaosState; + public override bool ShouldDisplay => CalamityClientConfig.Instance.VanillaCooldownDisplay && instance.player.chaosState; public override LocalizedText DisplayName => CalamityUtils.GetText($"UI.Cooldowns.{ID}"); public override string Texture => "CalamityMod/Cooldowns/ChaosState" + skinTexture; public override Color OutlineColor => outlineColor; diff --git a/Cooldowns/PotionSickness.cs b/Cooldowns/PotionSickness.cs index 2127706e4e..d7a8708f80 100644 --- a/Cooldowns/PotionSickness.cs +++ b/Cooldowns/PotionSickness.cs @@ -7,7 +7,7 @@ namespace CalamityMod.Cooldowns public class PotionSickness : CooldownHandler { public static new string ID => "PotionSickness"; - public override bool ShouldDisplay => CalamityConfig.Instance.VanillaCooldownDisplay && instance.player.potionDelay > 0; + public override bool ShouldDisplay => CalamityClientConfig.Instance.VanillaCooldownDisplay && instance.player.potionDelay > 0; public override LocalizedText DisplayName => CalamityUtils.GetText($"UI.Cooldowns.{ID}"); public override string Texture => "CalamityMod/Cooldowns/PotionSickness"; public override Color OutlineColor => new Color(255, 142, 165); diff --git a/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/DataStructures/NPCStats.cs b/DataStructures/NPCStats.cs index 0aec9726b2..b2b8d4ee20 100644 --- a/DataStructures/NPCStats.cs +++ b/DataStructures/NPCStats.cs @@ -213,7 +213,6 @@ internal static void LoadEnemyStats() { ModContent.NPCType(), 0.8 }, { NPCID.SkeletronPrime, 0.85 }, - { ModContent.NPCType(), 0.85 }, { NPCID.PrimeCannon, 0.85 }, { NPCID.PrimeLaser, 0.85 }, { NPCID.PrimeSaw, 0.85 }, @@ -416,12 +415,6 @@ internal static void LoadEnemyStats() 102, // 204 while spinning 119, // 238 while spinning 153 } }, // 306 while spinning - { ModContent.NPCType(), new int[] { - 50, // 100 while spinning - 85, // 170 while spinning - 102, // 204 while spinning - 119, // 238 while spinning - 153 } }, // 306 while spinning { NPCID.PrimeVice, new int[] { 70, 102, 136, 170, 255 } }, { NPCID.PrimeSaw, new int[] { 70, 102, 136, 170, 255 } }, { NPCID.PrimeCannon, new int[] { 30, 51, 68, 85, 102 } }, @@ -663,9 +656,6 @@ internal static void LoadEnemyStats() { new Tuple(NPCID.SkeletronPrime, ProjectileID.Skull), new int[] { 50, 108, 124, 140, 210 } }, { new Tuple(NPCID.SkeletronPrime, ProjectileID.DeathLaser), new int[] { 50, 108, 124, 140, 210 } }, { new Tuple(NPCID.SkeletronPrime, ProjectileID.RocketSkeleton), new int[] { 60, 120, 148, 176, 264 } }, - { new Tuple(ModContent.NPCType(), ProjectileID.Skull), new int[] { 50, 108, 124, 140, 210 } }, - { new Tuple(ModContent.NPCType(), ProjectileID.BombSkeletronPrime), new int[] { 80, 160, 180, 200, 300 } }, - { new Tuple(ModContent.NPCType(), ProjectileID.FrostBeam), new int[] { 50, 108, 124, 140, 210 } }, { new Tuple(NPCID.PrimeCannon, ProjectileID.RocketSkeleton), new int[] { 60, 120, 148, 176, 264 } }, { new Tuple(NPCID.PrimeCannon, ProjectileID.BombSkeletronPrime), new int[] { 80, 160, 0, 0, 300 } }, { new Tuple(NPCID.PrimeLaser, ProjectileID.DeathLaser), new int[] { 50, 108, 124, 140, 210 } }, diff --git a/Dusts/WaterSplash/AstralSplash.cs b/Dusts/WaterSplash/AstralSplash.cs new file mode 100644 index 0000000000..6fcb24f6c3 --- /dev/null +++ b/Dusts/WaterSplash/AstralSplash.cs @@ -0,0 +1,9 @@ +using Terraria; +using Terraria.ModLoader; + +namespace CalamityMod.Dusts.WaterSplash +{ + public class AstralSplash : SplashDust + { + } +} diff --git a/Dusts/WaterSplash/AstralSplash.png b/Dusts/WaterSplash/AstralSplash.png new file mode 100644 index 0000000000..839409589d Binary files /dev/null and b/Dusts/WaterSplash/AstralSplash.png differ diff --git a/Dusts/WaterSplash/CragsLavaSplash.cs b/Dusts/WaterSplash/CragsLavaSplash.cs new file mode 100644 index 0000000000..907f65c969 --- /dev/null +++ b/Dusts/WaterSplash/CragsLavaSplash.cs @@ -0,0 +1,178 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics.PackedVector; +using System; +using Terraria; +using Terraria.ModLoader; + +namespace CalamityMod.Dusts.WaterSplash +{ + public class CragsLavaSplash : ModDust + { + public override void OnSpawn(Dust dust) + { + dust.velocity *= 0.1f; + dust.velocity.Y = -0.5f; + } + + public override bool Update(Dust dust) + { + if (dust.scale > 10f) + { + dust.active = false; + } + Dust.lavaBubbles++; + dust.position += dust.velocity; + if (!dust.noGravity) + { + dust.velocity.Y += 0.1f; + } + if (dust.noGravity) + { + dust.scale += 0.03f; + if (dust.scale < 1f) + { + dust.velocity.Y += 0.075f; + } + dust.velocity.X *= 1.08f; + if (dust.velocity.X > 0f) + { + dust.rotation += 0.01f; + } + else + { + dust.rotation -= 0.01f; + } + float num109 = dust.scale * 0.6f; + if (num109 > 1f) + { + num109 = 1f; + } + Lighting.AddLight((int)(dust.position.X / 16f), (int)(dust.position.Y / 16f + 1f), num109 * (2.5f / 4), num109 * (1.1f / 4), num109 * (0.1f / 4)); + } + else + { + if (!Collision.WetCollision(new Vector2(dust.position.X, dust.position.Y - 8f), 4, 4)) + { + dust.scale = 0f; + } + else + { + dust.alpha += Main.rand.Next(2); + if (dust.alpha > 255) + { + dust.scale = 0f; + } + dust.velocity.Y = -0.5f; + dust.alpha++; + dust.scale -= 0.01f; + dust.velocity.Y = -0.2f; + dust.velocity.X += (float)Main.rand.Next(-10, 10) * 0.002f; + if ((double)dust.velocity.X < -0.25) + { + dust.velocity.X = -0.25f; + } + if ((double)dust.velocity.X > 0.25) + { + dust.velocity.X = 0.25f; + } + } + float num3 = dust.scale * 0.3f + 0.4f; + if (num3 > 1f) + { + num3 = 1f; + } + Lighting.AddLight((int)(dust.position.X / 16f), (int)(dust.position.Y / 16f), num3 * (2.5f / 4), num3 * (1.1f / 4), num3 * (0.1f / 4)); + } + dust.rotation += dust.velocity.X * 0.5f; + if (dust.fadeIn > 0f && dust.fadeIn < 100f) + { + dust.scale += 0.03f; + if (dust.scale > dust.fadeIn) + { + dust.fadeIn = 0f; + } + } + dust.scale -= 0.01f; + if (dust.noGravity) + { + dust.velocity *= 0.92f; + if (dust.fadeIn == 0f) + { + dust.scale -= 0.04f; + } + } + if (dust.position.Y > Main.screenPosition.Y + (float)Main.screenHeight) + { + dust.active = false; + } + float num17 = 0.1f; + if ((double)Dust.dCount == 0.5) + { + dust.scale -= 0.001f; + } + if ((double)Dust.dCount == 0.6) + { + dust.scale -= 0.0025f; + } + if ((double)Dust.dCount == 0.7) + { + dust.scale -= 0.005f; + } + if ((double)Dust.dCount == 0.8) + { + dust.scale -= 0.01f; + } + if ((double)Dust.dCount == 0.9) + { + dust.scale -= 0.02f; + } + if ((double)Dust.dCount == 0.5) + { + num17 = 0.11f; + } + if ((double)Dust.dCount == 0.6) + { + num17 = 0.13f; + } + if ((double)Dust.dCount == 0.7) + { + num17 = 0.16f; + } + if ((double)Dust.dCount == 0.8) + { + num17 = 0.22f; + } + if ((double)Dust.dCount == 0.9) + { + num17 = 0.25f; + } + if (dust.scale < num17) + { + dust.active = false; + } + return false; + } + + public override Color? GetAlpha(Dust dust, Color lightColor) + { + float num = (float)(255 - dust.alpha) / 255f; + int num4; + int num3; + int num2; + num = (num + 3f) / 4f; + num4 = (int)((int)lightColor.R * num); + num3 = (int)((int)lightColor.G * num); + num2 = (int)((int)lightColor.B * num); + int num6 = lightColor.A - dust.alpha; + if (num6 < 0) + { + num6 = 0; + } + if (num6 > 255) + { + num6 = 255; + } + return new Color(num4, num3, num2, num6); + } + } +} diff --git a/Dusts/WaterSplash/CragsLavaSplash.png b/Dusts/WaterSplash/CragsLavaSplash.png new file mode 100644 index 0000000000..dbe3be3c65 Binary files /dev/null and b/Dusts/WaterSplash/CragsLavaSplash.png differ diff --git a/Dusts/WaterSplash/MiddleAbyssSplash.cs b/Dusts/WaterSplash/MiddleAbyssSplash.cs new file mode 100644 index 0000000000..319e596446 --- /dev/null +++ b/Dusts/WaterSplash/MiddleAbyssSplash.cs @@ -0,0 +1,9 @@ +using Terraria; +using Terraria.ModLoader; + +namespace CalamityMod.Dusts.WaterSplash +{ + public class MiddleAbyssSplash : SplashDust + { + } +} diff --git a/Dusts/WaterSplash/MiddleAbyssSplash.png b/Dusts/WaterSplash/MiddleAbyssSplash.png new file mode 100644 index 0000000000..b368be985f Binary files /dev/null and b/Dusts/WaterSplash/MiddleAbyssSplash.png differ diff --git a/Dusts/WaterSplash/SplashDust.cs b/Dusts/WaterSplash/SplashDust.cs new file mode 100644 index 0000000000..f74eac1125 --- /dev/null +++ b/Dusts/WaterSplash/SplashDust.cs @@ -0,0 +1,20 @@ +using Terraria; +using Terraria.ModLoader; + +namespace CalamityMod.Dusts.WaterSplash +{ + public abstract class SplashDust : ModDust + { + public override void SetStaticDefaults() + { + UpdateType = 33; + } + + public override void OnSpawn(Dust dust) + { + dust.alpha = 170; + dust.velocity *= 0.5f; + dust.velocity.Y += 1f; + } + } +} diff --git a/Dusts/WaterSplash/SulphuricDepthsSplash.cs b/Dusts/WaterSplash/SulphuricDepthsSplash.cs new file mode 100644 index 0000000000..840863230f --- /dev/null +++ b/Dusts/WaterSplash/SulphuricDepthsSplash.cs @@ -0,0 +1,9 @@ +using Terraria; +using Terraria.ModLoader; + +namespace CalamityMod.Dusts.WaterSplash +{ + public class SulphuricDepthsSplash : SplashDust + { + } +} diff --git a/Dusts/WaterSplash/SulphuricDepthsSplash.png b/Dusts/WaterSplash/SulphuricDepthsSplash.png new file mode 100644 index 0000000000..c5a9a06c5d Binary files /dev/null and b/Dusts/WaterSplash/SulphuricDepthsSplash.png differ diff --git a/Dusts/WaterSplash/SulphuricSplash.cs b/Dusts/WaterSplash/SulphuricSplash.cs new file mode 100644 index 0000000000..0cd8705c76 --- /dev/null +++ b/Dusts/WaterSplash/SulphuricSplash.cs @@ -0,0 +1,9 @@ +using Terraria; +using Terraria.ModLoader; + +namespace CalamityMod.Dusts.WaterSplash +{ + public class SulphuricSplash : SplashDust + { + } +} diff --git a/Dusts/WaterSplash/SulphuricSplash.png b/Dusts/WaterSplash/SulphuricSplash.png new file mode 100644 index 0000000000..580c4485fc Binary files /dev/null and b/Dusts/WaterSplash/SulphuricSplash.png differ diff --git a/Dusts/WaterSplash/SunkenSeaSplash.cs b/Dusts/WaterSplash/SunkenSeaSplash.cs new file mode 100644 index 0000000000..3c0e44605e --- /dev/null +++ b/Dusts/WaterSplash/SunkenSeaSplash.cs @@ -0,0 +1,9 @@ +using Terraria; +using Terraria.ModLoader; + +namespace CalamityMod.Dusts.WaterSplash +{ + public class SunkenSeaSplash : SplashDust + { + } +} diff --git a/Dusts/WaterSplash/SunkenSeaSplash.png b/Dusts/WaterSplash/SunkenSeaSplash.png new file mode 100644 index 0000000000..4872767ad6 Binary files /dev/null and b/Dusts/WaterSplash/SunkenSeaSplash.png differ diff --git a/Dusts/WaterSplash/UpperAbyssSplash.cs b/Dusts/WaterSplash/UpperAbyssSplash.cs new file mode 100644 index 0000000000..715e5467b6 --- /dev/null +++ b/Dusts/WaterSplash/UpperAbyssSplash.cs @@ -0,0 +1,9 @@ +using Terraria; +using Terraria.ModLoader; + +namespace CalamityMod.Dusts.WaterSplash +{ + public class UpperAbyssSplash : SplashDust + { + } +} diff --git a/Dusts/WaterSplash/UpperAbyssSplash.png b/Dusts/WaterSplash/UpperAbyssSplash.png new file mode 100644 index 0000000000..09400057b8 Binary files /dev/null and b/Dusts/WaterSplash/UpperAbyssSplash.png differ diff --git a/Dusts/WaterSplash/VoidSplash.cs b/Dusts/WaterSplash/VoidSplash.cs new file mode 100644 index 0000000000..0e046fa962 --- /dev/null +++ b/Dusts/WaterSplash/VoidSplash.cs @@ -0,0 +1,9 @@ +using Terraria; +using Terraria.ModLoader; + +namespace CalamityMod.Dusts.WaterSplash +{ + public class VoidSplash : SplashDust + { + } +} diff --git a/Dusts/WaterSplash/VoidSplash.png b/Dusts/WaterSplash/VoidSplash.png new file mode 100644 index 0000000000..3177c26e7c Binary files /dev/null and b/Dusts/WaterSplash/VoidSplash.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/Enums/HardmodeCrateType.cs b/Enums/HardmodeCrateType.cs new file mode 100644 index 0000000000..6febfd2600 --- /dev/null +++ b/Enums/HardmodeCrateType.cs @@ -0,0 +1,9 @@ +namespace CalamityMod.Enums +{ + public enum HardmodeCrateType + { + Biome, + Mythril, + Titanium + } +} diff --git a/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/Events/BossRushEvent.cs b/Events/BossRushEvent.cs index 76b1624211..29ceb12688 100644 --- a/Events/BossRushEvent.cs +++ b/Events/BossRushEvent.cs @@ -217,7 +217,7 @@ public static void Load() new Boss(ModContent.NPCType(), TimeChangeContext.Day, permittedNPCs: ModContent.NPCType()), - new Boss(NPCID.SkeletronPrime, TimeChangeContext.Night, permittedNPCs: new int[] { ModContent.NPCType(), NPCID.PrimeCannon, NPCID.PrimeSaw, NPCID.PrimeVice, NPCID.PrimeLaser, NPCID.Probe }), + new Boss(NPCID.SkeletronPrime, TimeChangeContext.Night, permittedNPCs: new int[] { NPCID.PrimeCannon, NPCID.PrimeSaw, NPCID.PrimeVice, NPCID.PrimeLaser, NPCID.Probe }), new Boss(ModContent.NPCType(), TimeChangeContext.Night, dimnessFactor: 0.6f, permittedNPCs: new int[] { ModContent.NPCType(), ModContent.NPCType(), ModContent.NPCType() }), @@ -484,7 +484,7 @@ public static int MusicToPlay return -1; } int tier = CurrentTier; - if (CalamityMod.Instance.musicMod != null) + if (CalamityMod.Instance.MusicAvailable) { // Boss Rush music for tier 5 doesn't exist if (tier > 4) diff --git a/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/ChadPrime.png b/ExtraTextures/ChadPrime.png deleted file mode 100644 index 3bbc5902b0..0000000000 Binary files a/ExtraTextures/ChadPrime.png and /dev/null differ diff --git a/ExtraTextures/ChadPrimeHeadGlow.png b/ExtraTextures/ChadPrimeHeadGlow.png deleted file mode 100644 index e8b25ba236..0000000000 Binary files a/ExtraTextures/ChadPrimeHeadGlow.png and /dev/null 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/AstralWaterDroplet.cs b/Gores/AstralWaterDroplet.cs deleted file mode 100644 index 0022de1b56..0000000000 --- a/Gores/AstralWaterDroplet.cs +++ /dev/null @@ -1,167 +0,0 @@ -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.Audio; -using Terraria.DataStructures; -using Terraria.GameContent; -using Terraria.GameContent.Shaders; -using Terraria.Graphics.Effects; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Gores -{ - public class AstralWaterDroplet : ModGore - { - public override void SetStaticDefaults() - { - ChildSafety.SafeGore[Type] = true; - } - - public override void OnSpawn(Gore gore, IEntitySource source) - { - gore.numFrames = 15; - gore.behindTiles = true; - gore.timeLeft = Gore.goreTime * 3; - } - - public override bool Update(Gore gore) - { - if ((double)gore.position.Y < Main.worldSurface * 16.0 + 8.0) - { - gore.alpha = 0; - } - else - { - gore.alpha = 100; - } - int goreFrameDelay = 4; - gore.frameCounter++; - if (gore.frame <= 4) - { - int goreXPos = (int)(gore.position.X / 16f); - int goreYPos = (int)(gore.position.Y / 16f) - 1; - if (WorldGen.InWorld(goreXPos, goreYPos, 0) && !Main.tile[goreXPos, goreYPos].HasTile) - { - gore.active = false; - } - if (gore.frame == 0) - { - goreFrameDelay = 24 + Main.rand.Next(256); - } - if (gore.frame == 1) - { - goreFrameDelay = 24 + Main.rand.Next(256); - } - if (gore.frame == 2) - { - goreFrameDelay = 24 + Main.rand.Next(256); - } - if (gore.frame == 3) - { - goreFrameDelay = 24 + Main.rand.Next(96); - } - if (gore.frame == 5) - { - goreFrameDelay = 16 + Main.rand.Next(64); - } - if ((int)gore.frameCounter >= goreFrameDelay) - { - gore.frameCounter = 0; - gore.frame += 1; - if (gore.frame == 5 && Main.netMode != NetmodeID.Server) - { - int astralWater = Gore.NewGore(new EntitySource_Misc("0"), gore.position, gore.velocity, gore.type, 1f); - Main.gore[astralWater].frame = 9; - Main.gore[astralWater].velocity *= 0f; - } - } - } - else if (gore.frame <= 6) - { - goreFrameDelay = 8; - if ((int)gore.frameCounter >= goreFrameDelay) - { - gore.frameCounter = 0; - gore.frame += 1; - if (gore.frame == 7) - { - gore.active = false; - } - } - } - else if (gore.frame <= 9) - { - goreFrameDelay = 6; - gore.velocity.Y += 0.2f; - if ((double)gore.velocity.Y < 0.5) - { - gore.velocity.Y = 0.5f; - } - if (gore.velocity.Y > 12f) - { - gore.velocity.Y = 12f; - } - if ((int)gore.frameCounter >= goreFrameDelay) - { - gore.frameCounter = 0; - gore.frame += 1; - } - if (gore.frame > 9) - { - gore.frame = 7; - } - } - else - { - gore.velocity.Y += 0.1f; - if ((int)gore.frameCounter >= goreFrameDelay) - { - gore.frameCounter = 0; - gore.frame += 1; - } - gore.velocity *= 0f; - if (gore.frame > 14) - { - gore.active = false; - } - } - - Vector2 goreVelCheck = gore.velocity; - gore.velocity = Collision.TileCollision(gore.position, gore.velocity, 16, 14, false, false, 1); - if (gore.velocity != goreVelCheck) - { - if (gore.frame < 10) - { - gore.frame = 10; - gore.frameCounter = 0; - if (gore.type != 716 && gore.type != 717 && gore.type != 943) - { - SoundEngine.PlaySound(SoundID.Drip, gore.position + Vector2.One * 8); - } - } - } - else if (Collision.WetCollision(gore.position + gore.velocity, 16, 14)) - { - if (gore.frame < 10) - { - gore.frame = 10; - gore.frameCounter = 0; - if (gore.type != 716 && gore.type != 717 && gore.type != 943) - { - SoundEngine.PlaySound(SoundID.Drip, gore.position + Vector2.One * 8); - } - ((WaterShaderData)Filters.Scene["WaterDistortion"].GetShader()).QueueRipple(gore.position + new Vector2(8f, 8f), 1f, RippleShape.Square, 0f); - } - int goreTileX = (int)(gore.position.X + 8f) / 16; - int goreTileY = (int)(gore.position.Y + 14f) / 16; - if (Main.tile[goreTileX, goreTileY] != null && Main.tile[goreTileX, goreTileY].LiquidAmount > 0) - { - gore.velocity *= 0f; - gore.position.Y = (float)(goreTileY * 16 - (int)(Main.tile[goreTileX, goreTileY].LiquidAmount / 16)); - } - } - - return true; - } - } -} diff --git a/Gores/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/Gores/WaterDroplet/AstralWaterDroplet.cs b/Gores/WaterDroplet/AstralWaterDroplet.cs new file mode 100644 index 0000000000..0add03de05 --- /dev/null +++ b/Gores/WaterDroplet/AstralWaterDroplet.cs @@ -0,0 +1,6 @@ +namespace CalamityMod.Gores.WaterDroplet +{ + public class AstralWaterDroplet : LiquidDropletGore + { + } +} diff --git a/Gores/AstralWaterDroplet.png b/Gores/WaterDroplet/AstralWaterDroplet.png similarity index 100% rename from Gores/AstralWaterDroplet.png rename to Gores/WaterDroplet/AstralWaterDroplet.png diff --git a/Gores/WaterDroplet/CragsLavaDroplet.cs b/Gores/WaterDroplet/CragsLavaDroplet.cs new file mode 100644 index 0000000000..3841f789d3 --- /dev/null +++ b/Gores/WaterDroplet/CragsLavaDroplet.cs @@ -0,0 +1,11 @@ +using Microsoft.Xna.Framework; + +namespace CalamityMod.Gores.WaterDroplet +{ + public class CragsLavaDroplet : LiquidDropletGore + { + public override bool lavaDroplet => true; + + public override Vector3 lavaColor => new Vector3(2.5f, 1.1f, 0.1f); + } +} diff --git a/Gores/WaterDroplet/CragsLavaDroplet.png b/Gores/WaterDroplet/CragsLavaDroplet.png new file mode 100644 index 0000000000..5a62700a83 Binary files /dev/null and b/Gores/WaterDroplet/CragsLavaDroplet.png differ diff --git a/Gores/WaterDroplet/LiquidDropletGore.cs b/Gores/WaterDroplet/LiquidDropletGore.cs new file mode 100644 index 0000000000..cf7064f1ec --- /dev/null +++ b/Gores/WaterDroplet/LiquidDropletGore.cs @@ -0,0 +1,201 @@ +using Microsoft.Xna.Framework; +using Terraria; +using Terraria.Audio; +using Terraria.DataStructures; +using Terraria.GameContent; +using Terraria.ID; +using Terraria.ModLoader; + +namespace CalamityMod.Gores.WaterDroplet +{ + public abstract class LiquidDropletGore : ModGore + { + public virtual bool lavaDroplet => false; + + public virtual Vector3 lavaColor => new Vector3(0, 0, 0); + + public override void SetStaticDefaults() + { + ChildSafety.SafeGore[Type] = true; + } + + public override void OnSpawn(Gore gore, IEntitySource source) + { + gore.numFrames = 15; + gore.behindTiles = true; + gore.timeLeft = Gore.goreTime * 3; + } + + public override bool Update(Gore gore) + { + gore.alpha = gore.position.Y < (Main.worldSurface * 16.0) + 8.0 + ? 0 + : 100; + + int frameDuration = 4; + gore.frameCounter += 1; + if (gore.frame <= 4) + { + int tileX = (int)(gore.position.X / 16f); + int tileY = (int)(gore.position.Y / 16f) - 1; + if (WorldGen.InWorld(tileX, tileY) && !Main.tile[tileX, tileY].HasTile) + { + gore.active = false; + } + + if (gore.frame == 0 || gore.frame == 1 || gore.frame == 2) + { + frameDuration = 24 + Main.rand.Next(256); + } + + if (gore.frame == 3) + { + frameDuration = 24 + Main.rand.Next(96); + } + + if (gore.frameCounter >= frameDuration) + { + gore.frameCounter = 0; + gore.frame += 1; + if (gore.frame == 5) + { + int droplet = Gore.NewGore(new EntitySource_Misc("0"), gore.position, gore.velocity, gore.type); + Main.gore[droplet].frame = 9; + Main.gore[droplet].velocity *= 0f; + } + } + } + else if (gore.frame <= 6) + { + frameDuration = 8; + if (gore.frameCounter >= frameDuration) + { + gore.frameCounter = 0; + gore.frame += 1; + if (gore.frame == 7) + { + gore.active = false; + } + } + } + else if (gore.frame <= 9) + { + frameDuration = 6; + gore.velocity.Y += 0.2f; + if (gore.velocity.Y < 0.5f) + { + gore.velocity.Y = 0.5f; + } + + if (gore.velocity.Y > 12f) + { + gore.velocity.Y = 12f; + } + + if (gore.frameCounter >= frameDuration) + { + gore.frameCounter = 0; + gore.frame += 1; + } + + if (gore.frame > 9) + { + gore.frame = 7; + } + } + else + { + gore.velocity.Y += 0.1f; + if (gore.frameCounter >= frameDuration) + { + gore.frameCounter = 0; + gore.frame += 1; + } + + gore.velocity *= 0f; + if (gore.frame > 14) + { + gore.active = false; + } + } + + if (lavaDroplet) + { + float num24 = 1f; + float num25 = 1f; + float num26 = 1f; + float num27 = 0.6f; + num27 *= gore.frame switch + { + 0 => 0.1f, + 1 => 0.2f, + 2 => 0.3f, + 3 => 0.4f, + 4 => 0.5f, + 5 => 0.4f, + 6 => 0.2f, + 7 => 0.5f, + 8 => 0.5f, + 9 => 0.5f, + 10 => 0.5f, + 11 => 0.4f, + 12 => 0.3f, + 13 => 0.2f, + 14 => 0.1f, + _ => 0.0f, + }; + num24 = (lavaColor.X / 4) * num27; //R + num25 = (lavaColor.Y / 4) * num27; //G + num26 = (lavaColor.Z / 4) * num27; //B + Lighting.AddLight(gore.position + new Vector2(8f, 8f), num24, num25, num26); + } + + Vector2 oldVelocity = gore.velocity; + gore.velocity = Collision.TileCollision(gore.position, gore.velocity, 16, 14); + if (gore.velocity != oldVelocity) + { + if (gore.frame < 10) + { + gore.frame = 10; + gore.frameCounter = 0; + if (!lavaDroplet) + { + SoundEngine.PlaySound(SoundID.Drip, gore.position + new Vector2(8, 8)); + } + } + } + else if (Collision.WetCollision(gore.position + gore.velocity, 16, 14)) + { + if (gore.frame < 10) + { + gore.frame = 10; + gore.frameCounter = 0; + if (!lavaDroplet) + { + SoundEngine.PlaySound(SoundID.Drip, gore.position + new Vector2(8, 8)); + } + } + + int tileX = (int)(gore.position.X + 8f) / 16; + int tileY = (int)(gore.position.Y + 14f) / 16; + if (Main.tile[tileX, tileY] != null && Main.tile[tileX, tileY].LiquidAmount > 0) + { + gore.velocity *= 0f; + gore.position.Y = (tileY * 16) - (Main.tile[tileX, tileY].LiquidAmount / 16); + } + } + + gore.position += gore.velocity; + return false; + } + + public override Color? GetAlpha(Gore gore, Color lightColor) + { + if (lavaDroplet) + { + return Lighting.GetColor((int)(gore.position.X / 16), (int)(gore.position.Y / 16)) * 1f; + } + return null; + } + } +} diff --git a/Gores/WaterDroplet/MiddleAbyssWaterDroplet.cs b/Gores/WaterDroplet/MiddleAbyssWaterDroplet.cs new file mode 100644 index 0000000000..73728d4332 --- /dev/null +++ b/Gores/WaterDroplet/MiddleAbyssWaterDroplet.cs @@ -0,0 +1,6 @@ +namespace CalamityMod.Gores.WaterDroplet +{ + public class MiddleAbyssWaterDroplet : LiquidDropletGore + { + } +} diff --git a/Gores/WaterDroplet/MiddleAbyssWaterDroplet.png b/Gores/WaterDroplet/MiddleAbyssWaterDroplet.png new file mode 100644 index 0000000000..235b55d951 Binary files /dev/null and b/Gores/WaterDroplet/MiddleAbyssWaterDroplet.png differ diff --git a/Gores/WaterDroplet/SulphuricDepthsWaterDroplet.cs b/Gores/WaterDroplet/SulphuricDepthsWaterDroplet.cs new file mode 100644 index 0000000000..9ec9af54e6 --- /dev/null +++ b/Gores/WaterDroplet/SulphuricDepthsWaterDroplet.cs @@ -0,0 +1,6 @@ +namespace CalamityMod.Gores.WaterDroplet +{ + public class SulphuricDepthsWaterDroplet : LiquidDropletGore + { + } +} diff --git a/Gores/WaterDroplet/SulphuricDepthsWaterDroplet.png b/Gores/WaterDroplet/SulphuricDepthsWaterDroplet.png new file mode 100644 index 0000000000..62e2e4e345 Binary files /dev/null and b/Gores/WaterDroplet/SulphuricDepthsWaterDroplet.png differ diff --git a/Gores/WaterDroplet/SulphuricWaterDroplet.cs b/Gores/WaterDroplet/SulphuricWaterDroplet.cs new file mode 100644 index 0000000000..e99e2fcc07 --- /dev/null +++ b/Gores/WaterDroplet/SulphuricWaterDroplet.cs @@ -0,0 +1,6 @@ +namespace CalamityMod.Gores.WaterDroplet +{ + public class SulphuricWaterDroplet : LiquidDropletGore + { + } +} diff --git a/Gores/WaterDroplet/SulphuricWaterDroplet.png b/Gores/WaterDroplet/SulphuricWaterDroplet.png new file mode 100644 index 0000000000..4a72522aff Binary files /dev/null and b/Gores/WaterDroplet/SulphuricWaterDroplet.png differ diff --git a/Gores/WaterDroplet/SunkenSeaWaterDroplet.cs b/Gores/WaterDroplet/SunkenSeaWaterDroplet.cs new file mode 100644 index 0000000000..9d446c75f2 --- /dev/null +++ b/Gores/WaterDroplet/SunkenSeaWaterDroplet.cs @@ -0,0 +1,6 @@ +namespace CalamityMod.Gores.WaterDroplet +{ + public class SunkenSeaWaterDroplet : LiquidDropletGore + { + } +} diff --git a/Gores/WaterDroplet/SunkenSeaWaterDroplet.png b/Gores/WaterDroplet/SunkenSeaWaterDroplet.png new file mode 100644 index 0000000000..d9e772241d Binary files /dev/null and b/Gores/WaterDroplet/SunkenSeaWaterDroplet.png differ diff --git a/Gores/WaterDroplet/UpperAbyssWaterDroplet.cs b/Gores/WaterDroplet/UpperAbyssWaterDroplet.cs new file mode 100644 index 0000000000..52d68f19ea --- /dev/null +++ b/Gores/WaterDroplet/UpperAbyssWaterDroplet.cs @@ -0,0 +1,6 @@ +namespace CalamityMod.Gores.WaterDroplet +{ + public class UpperAbyssWaterDroplet : LiquidDropletGore + { + } +} diff --git a/Gores/WaterDroplet/UpperAbyssWaterDroplet.png b/Gores/WaterDroplet/UpperAbyssWaterDroplet.png new file mode 100644 index 0000000000..1b6552138e Binary files /dev/null and b/Gores/WaterDroplet/UpperAbyssWaterDroplet.png differ diff --git a/Gores/WaterDroplet/VoidWaterDroplet.cs b/Gores/WaterDroplet/VoidWaterDroplet.cs new file mode 100644 index 0000000000..daf1abf2d7 --- /dev/null +++ b/Gores/WaterDroplet/VoidWaterDroplet.cs @@ -0,0 +1,6 @@ +namespace CalamityMod.Gores.WaterDroplet +{ + public class VoidWaterDroplet : LiquidDropletGore + { + } +} diff --git a/Gores/WaterDroplet/VoidWaterDroplet.png b/Gores/WaterDroplet/VoidWaterDroplet.png new file mode 100644 index 0000000000..caa2b6f97a Binary files /dev/null and b/Gores/WaterDroplet/VoidWaterDroplet.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 public class RenderTargetManager : ModSystem { - internal static List ManagedTargets = new(); + internal static List ManagedTargets = []; public delegate void RenderTargetUpdateDelegate(); @@ -55,7 +54,6 @@ internal static void DisposeOfTargets() public override void OnModLoad() { - ManagedTargets = new(); Main.OnPreDraw += HandleTargetUpdateLoop; Main.OnResolutionChanged += ResetTargetSizes; } diff --git a/Graphics/Renderers/CalamityRenderers/DyeableShadersRenderer.cs b/Graphics/Renderers/CalamityRenderers/DyeableShadersRenderer.cs index f01c539a2f..d0570d372e 100644 --- a/Graphics/Renderers/CalamityRenderers/DyeableShadersRenderer.cs +++ b/Graphics/Renderers/CalamityRenderers/DyeableShadersRenderer.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using CalamityMod.DataStructures; @@ -36,19 +37,13 @@ public static Dictionary Dyes #region Loading public override void Load() { - if (Main.netMode == NetmodeID.Server) - return; - - Targets = new(); - Dyes = new(); - RenderersToDrawThisFrame = new(); + Targets = []; + Dyes = []; + RenderersToDrawThisFrame = []; } public override void Unload() { - if (Main.netMode == NetmodeID.Server) - return; - Targets = null; Dyes = null; RenderersToDrawThisFrame = null; @@ -60,6 +55,9 @@ internal static void FindDyesDetour(On_Player.orig_UpdateItemDye orig, Player se { orig(self, isNotInVanitySlot, isSetToHidden, armorItem, dyeItem); + if (Main.dedServ) + return; + if (armorItem.ModItem is not IDyeableShaderRenderer drawer) return; @@ -70,12 +68,20 @@ internal static void FindDyesDetour(On_Player.orig_UpdateItemDye orig, Player se internal static void CheckVanityDetour(On_Player.orig_ApplyEquipVanity_Item orig, Player self, Item currentItem) { orig(self, currentItem); + + if (Main.dedServ) + return; + CheckIfEquipIsValid(currentItem, false); } internal static void CheckAccessoryDetour(On_Player.orig_ApplyEquipFunctional orig, Player self, Item currentItem, bool hideVisual) { orig(self, currentItem, hideVisual); + + if (Main.dedServ) + return; + CheckIfEquipIsValid(currentItem, hideVisual); } @@ -83,6 +89,9 @@ internal static void CheckArmorSetsDetour(On_Player.orig_UpdateArmorSets orig, P { orig(self, i); + if (Main.dedServ) + return; + // Check each armor piece in the same manner as tMod. // If the entire set is equipped, and it is a renderer, it will be marked as valid. Item head = self.armor[0]; @@ -103,6 +112,9 @@ internal static void CheckArmorSetsDetour(On_Player.orig_UpdateArmorSets orig, P private static void CheckIfEquipIsValid(Item item, bool hideVisual) { + if (Main.dedServ) + return; + // Difficulty mode checks. if ((item.expertOnly && !Main.expertMode) || (item.masterOnly && !Main.masterMode)) return; @@ -120,9 +132,15 @@ private static void CheckIfEquipIsValid(Item item, bool hideVisual) private static void MarkAsValid(IDyeableShaderRenderer renderer) { - // If it doesn't have a dictonary entry, create one. - if (!Targets.ContainsKey(renderer)) - Main.QueueMainThreadAction(() => Targets[renderer] = new(true, ManagedRenderTarget.CreateScreenSizedTarget)); + if (Main.dedServ) + return; + + Main.QueueMainThreadAction(() => + { + // If it doesn't have a dictonary entry, create one. + if (!Targets.ContainsKey(renderer)) + Main.QueueMainThreadAction(() => Targets[renderer] = new(true, ManagedRenderTarget.CreateScreenSizedTarget)); + }); // Mark this item as drawable this frame. RenderersToDrawThisFrame.AddWithCondition(renderer, renderer.ShouldDrawDyeableShader); @@ -131,10 +149,13 @@ private static void MarkAsValid(IDyeableShaderRenderer renderer) #region Updates/Drawing // Clear the list at the beginning of each update, to ensure its only populated by correct ones. - public override void PreUpdate() => RenderersToDrawThisFrame.Clear(); + public override void PreUpdate() => RenderersToDrawThisFrame?.Clear(); public override void DrawToTarget(SpriteBatch spriteBatch) { + if (Main.dedServ) + return; + // Leave if nothing to draw. if (!RenderersToDrawThisFrame.Any()) return; @@ -155,6 +176,9 @@ public override void DrawToTarget(SpriteBatch spriteBatch) public override void DrawTarget(SpriteBatch spriteBatch) { + if (Main.dedServ) + return; + // Leave if nothing to draw. if (!RenderersToDrawThisFrame.Any()) return; diff --git a/Graphics/Renderers/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/BalancingILChanges.cs b/ILEditing/BalancingILChanges.cs index ef06ec1d55..6dabd88c65 100644 --- a/ILEditing/BalancingILChanges.cs +++ b/ILEditing/BalancingILChanges.cs @@ -114,7 +114,7 @@ private static void BaseJumpHeightAdjustment(ILContext il) cursor.Remove(); // Increase by 10% if the higher jump speed is enabled. - cursor.EmitDelegate>(() => CalamityConfig.Instance.HigherJumpHeight ? BalancingConstants.ConfigBoostedBaseJumpHeight : VanillaBaseJumpHeight); + cursor.EmitDelegate>(() => CalamityServerConfig.Instance.HigherJumpHeight ? BalancingConstants.ConfigBoostedBaseJumpHeight : VanillaBaseJumpHeight); } #endregion diff --git a/ILEditing/ILChangesLoading.cs b/ILEditing/ILChangesLoading.cs index c2ea95f2b1..ac00cb50f1 100644 --- a/ILEditing/ILChangesLoading.cs +++ b/ILEditing/ILChangesLoading.cs @@ -12,6 +12,7 @@ using Terraria.GameContent.Liquid; using Terraria.GameContent.UI.Elements; using Terraria.GameContent.UI.States; +using Terraria.Graphics.CameraModifiers; using Terraria.Graphics.Light; using Terraria.Map; using Terraria.ModLoader; @@ -43,12 +44,6 @@ public override void OnModLoad() On_Main.DrawCursor += UseCoolFireCursorEffect; On_Main.SortDrawCacheWorms += DrawFusableParticles; On_Main.DrawInfernoRings += DrawForegroundParticles; - On_TileDrawing.DrawPartialLiquid += DrawCustomLava; - On_WaterfallManager.DrawWaterfall_int_int_int_float_Vector2_Rectangle_Color_SpriteEffects += DrawCustomLavafalls; - On_Main.RenderWater += CacheLavaStyle; - IL_LiquidRenderer.DrawNormalLiquids += ChangeWaterQuadColors; - IL_Main.oldDrawWater += DrawCustomLava3; - On_TileLightScanner.GetTileLight += MakeSulphSeaWaterBetter; On_TileDrawing.PreDrawTiles += ClearForegroundStuff; On_TileDrawing.Draw += ClearTilePings; On_CommonCode.ModifyItemDropFromNPC += ColorBlightedGel; @@ -83,11 +78,51 @@ public override void OnModLoad() IL_Wiring.HitWireSingle += AddTwinklersToStatue; On_Player.UpdateItemDye += FindCalamityItemDyeShader; On_AWorldListItem.GetDifficulty += GetDifficultyOverride; - On_Item.GetShimmered += ShimmerEffectEdits; + //On_Item.GetShimmered += ShimmerEffectEdits; + On_Player.IsItemSlotUnlockedAndUsable += MasterModeCelestialOnionCheck; // Mana Burn (Chaos Stone) and Chalice of the Blood God IL_Player.ApplyLifeAndOrMana += ManaSicknessAndChaliceBufferHeal; + //LavaStyles + if (CalamityMod.Instance.biomeLava == null) + { + //Rendering/Drawing + IL_Main.DoDraw += DoDrawLavas; + IL_Main.RenderWater += RenderLavas; + IL_Main.RenderBackground += RenderLavaBackgrounds; + IL_Main.DrawCapture += DrawLavatoCapture; + IL_TileDrawing.Draw += AddTileLiquidDrawing; + + //Blocking + IL_LiquidRenderer.DrawNormalLiquids += BlockLavaDrawing; + On_TileDrawing.DrawTile_LiquidBehindTile += BlockLavaDrawingForSlopes; + On_TileDrawing.DrawPartialLiquid += BlockLavaDrawingForSlopes2; + On_WaterfallManager.DrawWaterfall_int_int_int_float_Vector2_Rectangle_Color_SpriteEffects += LavafallRemover; + IL_Main.oldDrawWater += BlockRetroLightingLava; + + //Replacing + IL_LiquidRenderer.InternalPrepareDraw += LavaBubbleReplacer; + IL_TileDrawing.EmitLiquidDrops += LavaDropletReplacer; + IL_NPC.Collision_WaterCollision += SplashEntityLava; + IL_Projectile.Update += SplashEntityLava; + IL_Item.MoveInWorld += SplashEntityLava; + IL_Player.Update += SplashEntityLava; + IL_Player.Update += PlayerDebuffEdit; + + //Other + On_WaterfallManager.Draw += LavaFallRedrawer; + On_WaterfallManager.StylizeColor += WaterfallGlowmaskEditor; + + //Waterfall light + On_WaterfallManager.AddLight += LavafallLightEditor; + } + + // Liquid Lighting and alpha (Liquid Viusuals) + On_TileLightScanner.ApplyLiquidLight += LiquidEmitLight; + IL_LiquidRenderer.DrawNormalLiquids += LiquidDrawColors; //Liquid Light + IL_TileDrawing.DrawTile_LiquidBehindTile += LiquidSlopeDrawColors; + // Custom grappling On_Player.GrappleMovement += CustomGrappleMovementCheck; On_Player.UpdatePettingAnimal += CustomGrapplePreDefaultMovement; @@ -126,7 +161,6 @@ public override void OnModLoad() IL_Projectile.StatusPlayer += RemoveFrozenInflictionFromDeerclopsIceSpikes; // World generation - IL_WorldGen.Pyramid += ReplacePharaohSetInPyramids; IL_WorldGen.GrowLivingTree += BlockLivingTreesNearOcean; On_WorldGen.SmashAltar += PreventSmashAltarCode; IL_WorldGen.hardUpdateWorld += AdjustChlorophyteSpawnRate; @@ -139,6 +173,8 @@ public override void OnModLoad() IL_WorldGen.MakeDungeon += ChangeDungeonSpikeQuantities; // Removal of vanilla stupidity + IL_NPC.VanillaHitEffect += PreventLavaSlimeLavaDrop; + IL_PunchCameraModifier.Update += PunchCameraUsesScreenshakeConfig; IL_Player.UpdateBuffs += RemoveFeralBiteRandomDebuffs; IL_Sandstorm.HasSufficientWind += DecreaseSandstormWindSpeedRequirement; IL_Item.TryGetPrefixStatMultipliersForItem += RelaxPrefixRequirements; diff --git a/ILEditing/ILHelperMethods.cs b/ILEditing/ILHelperMethods.cs index 01f2379f0e..fe90e30043 100644 --- a/ILEditing/ILHelperMethods.cs +++ b/ILEditing/ILHelperMethods.cs @@ -64,77 +64,8 @@ private static bool DirectlyTransformLabDoor(int doorX, int doorY, int newDoorID SoundEngine.PlaySound(SoundID.DoorClosed, new Vector2(doorX * 16, doorY * 16)); return true; } - - private static Texture2D SelectLavaTexture(Texture2D initialTexture, LiquidTileType type) - { - // Use the initial texture if it isn't lava. - if (initialTexture != CustomLavaManagement.LavaTexture && - initialTexture != CustomLavaManagement.LavaBlockTexture && - initialTexture != CustomLavaManagement.LavaSlopeTexture) - return initialTexture; - - if (cachedLavaStyle == default) - return initialTexture; - - switch (type) - { - case LiquidTileType.Block: - return cachedLavaStyle.BlockTexture; - case LiquidTileType.Waterflow: - return cachedLavaStyle.LavaTexture; - case LiquidTileType.Slope: - return cachedLavaStyle.SlopeTexture; - } - - return initialTexture; - } - private static VertexColors SelectLavaQuadColor(Texture2D initialTexture, ref VertexColors initialColor, bool forceTrue = false) - { - // We should handle the 'forceTrue' flag at this level to prevent us from checking the same thing four times. - if (!forceTrue) - { - if (initialTexture != CustomLavaManagement.LavaTexture && - initialTexture != CustomLavaManagement.LavaBlockTexture && - initialTexture != CustomLavaManagement.LavaSlopeTexture) - return initialColor; - } - - // No lava style to draw? Then skip. - if (cachedLavaStyle == default) - return initialColor; - - cachedLavaStyle.SelectLightColor(ref initialColor.TopLeftColor); - cachedLavaStyle.SelectLightColor(ref initialColor.TopRightColor); - cachedLavaStyle.SelectLightColor(ref initialColor.BottomLeftColor); - cachedLavaStyle.SelectLightColor(ref initialColor.BottomRightColor); - return initialColor; - } - - private static Color SelectLavaColor(Texture2D initialTexture, Color initialLightColor, bool forceTrue = false) - { - // Use the initial color if it isn't lava. - if (!forceTrue) - { - if (initialTexture != CustomLavaManagement.LavaTexture && - initialTexture != CustomLavaManagement.LavaBlockTexture && - initialTexture != CustomLavaManagement.LavaSlopeTexture) - return initialLightColor; - } - - foreach (CustomLavaStyle lavaStyle in CustomLavaManagement.CustomLavaStyles) - { - if (lavaStyle.ChooseLavaStyle()) - { - lavaStyle.SelectLightColor(ref initialLightColor); - return initialLightColor; - } - } - - return initialLightColor; - } - - private static void SelectSulphuricWaterColor(int x, int y, ref VertexColors initialColor) + public static void SelectSulphuricWaterColor(int x, int y, ref VertexColors initialColor, bool isSlope) { if (SulphuricWaterSafeZoneSystem.NearbySafeTiles.Count >= 1) { @@ -177,10 +108,20 @@ private static void SelectSulphuricWaterColor(int x, int y, ref VertexColors ini } } - initialColor.TopLeftColor *= 0.4f; - initialColor.TopRightColor *= 0.4f; - initialColor.BottomLeftColor *= 0.4f; - initialColor.BottomRightColor *= 0.4f; + if (isSlope) + { + initialColor.TopLeftColor *= 1f / 3; + initialColor.TopRightColor *= 1f / 3; + initialColor.BottomLeftColor *= 1f / 3; + initialColor.BottomRightColor *= 1f / 3; + } + else + { + initialColor.TopLeftColor *= 0.4f; + initialColor.TopRightColor *= 0.4f; + initialColor.BottomLeftColor *= 0.4f; + initialColor.BottomRightColor *= 0.4f; + } } public static void DumpToLog(ILContext il) => CalamityMod.Instance.Logger.Debug(il.ToString()); diff --git a/ILEditing/MechanicILChanges.cs b/ILEditing/MechanicILChanges.cs index fb4fe1510e..8ddf5dcbb1 100644 --- a/ILEditing/MechanicILChanges.cs +++ b/ILEditing/MechanicILChanges.cs @@ -9,9 +9,7 @@ using CalamityMod.FluidSimulation; using CalamityMod.ForegroundDrawing; using CalamityMod.Items.Accessories; -using CalamityMod.Items.Accessories.Vanity; using CalamityMod.Items.Dyes; -using CalamityMod.Items.Potions.Alcohol; using CalamityMod.NPCs; using CalamityMod.NPCs.Astral; using CalamityMod.NPCs.AstrumAureus; @@ -21,31 +19,28 @@ using CalamityMod.Projectiles; using CalamityMod.Projectiles.Typeless; using CalamityMod.Systems; -using CalamityMod.Tiles.Abyss; using CalamityMod.Waters; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Mono.Cecil.Cil; using MonoMod.Cil; -using ReLogic.Content; using Terraria; using Terraria.DataStructures; using Terraria.GameContent; -using Terraria.GameContent.Achievements; using Terraria.GameContent.Drawing; using Terraria.GameContent.Events; using Terraria.GameContent.Liquid; using Terraria.GameContent.UI.Elements; using Terraria.GameInput; using Terraria.Graphics; +using Terraria.Graphics.Capture; using Terraria.Graphics.Light; using Terraria.Graphics.Shaders; using Terraria.ID; -using Terraria.IO; using Terraria.Localization; using Terraria.ModLoader; -using Terraria.ModLoader.IO; using Terraria.UI.Gamepad; +using static Terraria.GameContent.Liquid.LiquidRenderer; namespace CalamityMod.ILEditing { @@ -57,14 +52,12 @@ public partial class ILChanges private static int aLabDoorClosed = -1; private static int exoDoorOpen = -1; private static int exoDoorClosed = -1; - // Cached for use in ChangeWaterQuadColors. - private static CustomLavaStyle cachedLavaStyle = default; // Holds the vanilla game function which spawns town NPCs, wrapped in a delegate for reflection purposes. // This function is (optionally) invoked manually in an IL edit to enable NPCs to spawn at night. private static Action VanillaSpawnTownNPCs; - private static readonly MethodInfo textureGetValueMethod = typeof(Asset).GetMethod("get_Value", BindingFlags.Public | BindingFlags.Instance); + //private static readonly MethodInfo textureGetValueMethod = typeof(Asset).GetMethod("get_Value", BindingFlags.Public | BindingFlags.Instance); public static event Func ExtraColorChangeConditions; @@ -260,16 +253,14 @@ private static void ApplyDashKeybind(Terraria.On_Player.orig_DoCommonDashHandle dir = self.direction; dashing = true; - if (self.dashTime > 0) - self.dashTime--; - if (self.dashTime < 0) - self.dashTime++; - if ((self.dashTime <= 0 && self.direction == -1) || (self.dashTime >= 0 && self.direction == 1)) + // CIT 16OCT2024: Commented this code out, as there's no reason for custom dash hotkey to use Player.dashTime + // and was causing the return of Celestial Starboard's dash bug from early 1.4 versions + /*if ((self.dashTime <= 0 && self.direction == -1) || (self.dashTime >= 0 && self.direction == 1)) { self.dashTime = 15; return; - } + }*/ dashing = true; self.dashTime = 0; @@ -284,6 +275,7 @@ private static void ApplyDashKeybind(Terraria.On_Player.orig_DoCommonDashHandle { dir = 1; dashing = false; + self.dashTime = 0; } } #endregion @@ -325,7 +317,7 @@ private static void PermitNighttimeTownNPCSpawning(ILContext il) { // A cached delegate is used here instead of direct reflection for performance reasons // since UpdateTime is called every frame. - if (Main.dayTime || CalamityConfig.Instance.TownNPCsSpawnAtNight) + if (Main.dayTime || CalamityServerConfig.Instance.TownNPCsSpawnAtNight) VanillaSpawnTownNPCs(); }); @@ -341,7 +333,7 @@ private static void PermitNighttimeTownNPCSpawning(ILContext il) private static void AlterTownNPCSpawnRate(Terraria.On_Main.orig_UpdateTime_SpawnTownNPCs orig) { double oldWorldRate = Main.desiredWorldTilesUpdateRate; - Main.desiredWorldTilesUpdateRate *= CalamityConfig.Instance.TownNPCSpawnRateMultiplier; + Main.desiredWorldTilesUpdateRate *= CalamityServerConfig.Instance.TownNPCSpawnRateMultiplier; orig(); Main.desiredWorldTilesUpdateRate = oldWorldRate; } @@ -728,7 +720,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(() => @@ -772,332 +764,553 @@ private static void DrawForegroundParticles(Terraria.On_Main.orig_DrawInfernoRin } #endregion - #region Custom Lava Visuals + #region Lava Style Edits + //Nine Layers of Hell brought to you by LIONEIGHTCAKE!! + //All new liquid rendering for lava can be found in Systems/LavaRendering.cs - private static void CacheLavaStyle(Terraria.On_Main.orig_RenderWater orig, Main self) + //To save on time, a LOT of the edits are from the BiomeLava mod (owned by myself, lion8cake). Obv every edit has been changed to reflect + //Calamity's style of IL edits and to remove any unnessesary edits not relivant to calamity. In the loading of the detours and edits + //BiomeLava is a check for whether they load or not. If BiomeLava is active all ModLavaStyles will be turned into ModCalls for BiomeLava. + + #region Lava Rendering + private void DoDrawLavas(ILContext il) { - // Immediately cache the lava drawing style. - // This will pay off in SPADES when we go to draw the tiles. - foreach (CustomLavaStyle style in CustomLavaManagement.CustomLavaStyles) + ILCursor cursor = new ILCursor(il); + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdsfld
("drawToScreen"), c => c.MatchBrfalse(out _), c => c.MatchLdarg0(), c => c.MatchLdcI4(1), c => c.MatchCall
("DrawWaters"))) { - if (style.ChooseLavaStyle()) - { - cachedLavaStyle = style; - orig(self); - return; - } + LogFailure("DoDraw Lava", "Could not locate the drawing of Background Waters"); + return; } - - cachedLavaStyle = default; - orig(self); + cursor.EmitDelegate(() => + { + LavaRendering.instance.DrawLavas(isBackground: true); + }); + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdsfld
("drawToScreen"), c => c.MatchBrfalse(out _), c => c.MatchLdarg0(), c => c.MatchLdcI4(0), c => c.MatchCall
("DrawWaters"))) + { + LogFailure("DoDraw Lava", "Could not locate the drawing of Waters"); + return; + } + cursor.EmitDelegate(() => + { + LavaRendering.instance.DrawLavas(); + }); } - private static void DrawCustomLava(Terraria.GameContent.Drawing.On_TileDrawing.orig_DrawPartialLiquid orig, TileDrawing self, bool behindBlocks, Tile tileCache, ref Vector2 position, ref Rectangle liquidSize, int liquidType, ref VertexColors colors) + private void RenderLavas(ILContext il) { - if (liquidType != 1) + ILCursor cursor = new ILCursor(il); + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdarg0(), c => c.MatchLdcI4(0), c => c.MatchCall
("DrawWaters"))) { - orig(self, behindBlocks, tileCache, ref position, ref liquidSize, liquidType, ref colors); + LogFailure("Render Lava", "Could not locate the drawing of Waters"); return; } + cursor.EmitDelegate(() => + { + LavaRendering.instance.DrawLavas(); + }); + } - int slope = (int)tileCache.Slope; - colors = SelectLavaQuadColor(TextureAssets.LiquidSlope[liquidType].Value, ref colors, true); - if (!TileID.Sets.BlocksWaterDrawingBehindSelf[tileCache.TileType] || behindBlocks || slope == 0) + private void RenderLavaBackgrounds(ILContext il) + { + ILCursor cursor = new ILCursor(il); + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdarg0(), c => c.MatchLdcI4(1), c => c.MatchCall
("DrawWaters"))) { - Texture2D liquidTexture = SelectLavaTexture(liquidType == 1 ? CustomLavaManagement.LavaBlockTexture : TextureAssets.Liquid[liquidType].Value, LiquidTileType.Block); - Main.tileBatch.Draw(liquidTexture, position, liquidSize, colors, default(Vector2), 1f, SpriteEffects.None); + LogFailure("Render Lava Backgroumds", "Could not locate the drawing of Background Waters"); return; } - - Texture2D slopeTexture = SelectLavaTexture(liquidType == 1 ? CustomLavaManagement.LavaSlopeTexture : TextureAssets.LiquidSlope[liquidType].Value, LiquidTileType.Slope); - liquidSize.X += 18 * (slope - 1); - switch (slope) + cursor.EmitDelegate(() => { - case 1: - Main.tileBatch.Draw(slopeTexture, position, liquidSize, colors, Vector2.Zero, 1f, SpriteEffects.None); - break; - case 2: - Main.tileBatch.Draw(slopeTexture, position, liquidSize, colors, Vector2.Zero, 1f, SpriteEffects.None); - break; - case 3: - Main.tileBatch.Draw(slopeTexture, position, liquidSize, colors, Vector2.Zero, 1f, SpriteEffects.None); - break; - case 4: - Main.tileBatch.Draw(slopeTexture, position, liquidSize, colors, Vector2.Zero, 1f, SpriteEffects.None); - break; - } + LavaRendering.instance.DrawLavas(isBackground: true); + }); } - private static void ChangeWaterQuadColors(ILContext il) + private void DrawLavatoCapture(ILContext il) { ILCursor cursor = new ILCursor(il); + //Added a new local variable to keep track of the lava alpha so we don't lose which liquid is visually active + VariableDefinition alphaSaveVar = new(il.Import(typeof(float[]))); + il.Body.Variables.Add(alphaSaveVar); - if (!cursor.TryGotoNext(c => c.MatchLdfld("_liquidTextures"))) + //First the capture saves the initial alpha state of the lavas + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdsfld
("liquidAlpha"), c => c.MatchCall(out _), c => c.MatchStloc(out _))) { - LogFailure("Custom Lava Drawing", "Could not locate the liquid texture array load."); + LogFailure("Draw lavas to captures", "Could not locate the saving of water alphas"); return; } - - // Move to the end of the get_Value() call and then use the resulting texture to check if a new one should replace it. - // Adding to the index directly would seem like a simple, direct way of achieving this since the operation is incredibly light, but - // it also unsafe due to the potential for NOP operations to appear. - if (!cursor.TryGotoNext(MoveType.After, c => c.MatchCallvirt(textureGetValueMethod))) + cursor.Emit(OpCodes.Ldloca, alphaSaveVar); + cursor.EmitDelegate((ref float[] alphaSave) => { - LogFailure("Custom Lava Drawing", "Could not locate the liquid texture Value call."); - return; - } - cursor.EmitDelegate>(initialTexture => SelectLavaTexture(initialTexture, LiquidTileType.Waterflow)); - - if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdloc(9))) + alphaSave = CalamityMod.lavaAlpha.ToArray(); + }); + //Then it resets the alpha to be fully visible + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdcR4(0.0f), c => c.MatchStsfld
(nameof(Main.cloudAlpha)))) { - LogFailure("Custom Lava Drawing", "Could not locate the liquid light color."); + LogFailure("Draw lavas to captures", "Could not locate the setting lava alphas"); return; } + cursor.EmitLdarg(2); + cursor.EmitDelegate((CaptureSettings settings) => + { - // Pass the texture in so that the method can ensure it is not messing around with non-lava textures. - cursor.Emit(OpCodes.Ldarg_0); - cursor.Emit(OpCodes.Ldfld, typeof(LiquidRenderer).GetField("_liquidTextures")); - cursor.Emit(OpCodes.Ldloc, 8); - cursor.Emit(OpCodes.Ldelem_Ref); - cursor.Emit(OpCodes.Ldloc, 8); - cursor.Emit(OpCodes.Ldloc, 3); - cursor.Emit(OpCodes.Ldloc, 4); - - // Caching these values can save a LOT of overhead at runtime. - ModWaterStyle sunkenSeaWater = ModContent.GetInstance(); - ModWaterStyle sulphuricWater = ModContent.GetInstance(); - ModWaterStyle sulphuricDepthsWater = ModContent.GetInstance(); - ModWaterStyle upperAbyssWater = ModContent.GetInstance(); - ModWaterStyle middleAbyssWater = ModContent.GetInstance(); - ModWaterStyle voidWater = ModContent.GetInstance(); - - cursor.EmitDelegate>((initialColor, initialTexture, liquidType, x, y) => - { - // Don't bother changing the color if the cached drawing style is null. - if (cachedLavaStyle != default) + for (int i = 0; i < 1; i++) //1 is the amount of vanilla lava styles, can be increased to include additional lava styles { - initialColor = SelectLavaQuadColor(initialTexture, ref initialColor, liquidType == 1); + CalamityMod.lavaAlpha[i] = ((i == CalamityMod.LavaStyle) ? 1f : 0f); } + }); - if (liquidType == sunkenSeaWater.Slot || - liquidType == sulphuricWater.Slot || - liquidType == sulphuricDepthsWater.Slot || - liquidType == upperAbyssWater.Slot || - liquidType == middleAbyssWater.Slot || - liquidType == voidWater.Slot) - { - SelectSulphuricWaterColor(x, y, ref initialColor); - } + //Then lavas are draw twice for backgrounds, and twice again for both the capture biome and the current lava style + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdsfld
("waterStyle"), c => c.MatchLdcR4(1), c => c.MatchLdcI4(1), c => c.MatchCall
("DrawLiquid"))) + { + LogFailure("Draw lavas to captures", "Could not locate the background of liquid capture drawing"); + return; + } + cursor.EmitDelegate(() => + { + LavaRendering.instance.DrawLiquid(bg: true, CalamityMod.LavaStyle); + }); + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdcI4(9), c => c.MatchLdcR4(1), c => c.MatchLdcI4(1), c => c.MatchCall
("DrawLiquid"))) + { + LogFailure("Draw lavas to captures", "Could not locate the capture biome background of liquid capture drawing"); + return; + } + cursor.EmitLdarg(2); + cursor.EmitDelegate((CaptureSettings settings) => + { + LavaRendering.instance.DrawLiquid(bg: true, CalamityMod.LavaStyle); + }); + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdcI4(0), c => c.MatchLdsfld
("waterStyle"), c => c.MatchLdcR4(1), c => c.MatchLdcI4(1), c => c.MatchCall
("DrawLiquid"))) + { + LogFailure("Draw lavas to captures", "Could not locate the liquid capture drawing"); + return; + } + cursor.EmitDelegate(() => + { + LavaRendering.instance.DrawLiquid(bg: false, CalamityMod.LavaStyle); + }); + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdcI4(0), c => c.MatchLdloc(out _), c => c.MatchLdfld("WaterStyle"), c => c.MatchLdcR4(1), c => c.MatchLdcI4(1), c => c.MatchCall
("DrawLiquid"))) + { + LogFailure("Draw lavas to captures", "Could not locate the capture biome liquid capture drawing"); + return; + } + cursor.EmitLdarg(2); + cursor.EmitDelegate((CaptureSettings settings) => + { + LavaRendering.instance.DrawLiquid(bg: false, CalamityMod.LavaStyle); + }); + //Finally, the original alpha is returned to the lava alpha + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdloc(out _), c => c.MatchStsfld
("liquidAlpha"))) + { + LogFailure("Draw lavas to captures", "Could not locate water style resetter"); + return; + } + cursor.Emit(OpCodes.Ldloc, alphaSaveVar); + cursor.EmitDelegate((float[] alphaSave) => + { + CalamityMod.lavaAlpha = alphaSave; + }); + } - // Apply any extra color conditions. - initialColor = ExtraColorChangeConditions?.Invoke(initialColor, liquidType, new(x, y)) ?? initialColor; + private void AddTileLiquidDrawing(ILContext il) + { + ILCursor cursor = new ILCursor(il); + int unscaledPosVar = -1; + int zeroVar = -1; + int tileXVar = -1; + int tileYVar = -1; + int tileVar = -1; - return initialColor; + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdarg0(), c => c.MatchLdarg1(), c => c.MatchLdcI4(0), c => c.MatchLdarg(4), c => c.MatchLdloc(out unscaledPosVar), c => c.MatchLdloc(out zeroVar), c => c.MatchLdloc(out tileXVar), c => c.MatchLdloc(out tileYVar), c => c.MatchLdloc(out tileVar), c => c.MatchCall("DrawTile_LiquidBehindTile"))) + { + LogFailure("Tile Lava Drawing", "Could not locate the drawing of Liquid Behind Tile drawing"); + return; + } + cursor.EmitLdloc(unscaledPosVar); + cursor.EmitLdloc(zeroVar); + cursor.EmitLdloc(tileXVar); + cursor.EmitLdloc(tileYVar); + cursor.EmitLdloc(tileVar); + cursor.EmitDelegate((Vector2 unscaledPosition, Vector2 vector, int i, int j, Tile tile) => + { + LavaRendering.instance.DrawTile_LiquidBehindTile(solidLayer: false, inFrontOfPlayers: false, -1, unscaledPosition, vector, i, j, tile); }); } + #endregion - private static void DrawCustomLava3(ILContext il) + #region Lava Blocking + private void BlockLavaDrawing(ILContext il) { + //Currently just prevents lava rendering, to see the new lava renderer, please see LavaRendering.DrawLava ILCursor cursor = new ILCursor(il); + int pointer2_varNum = -1; + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdloc(out pointer2_varNum), c => c.MatchLdfld("IsVisible"))) + { + LogFailure("Block Lava Drawing", "Could not locate the visibility check for liquid drawing"); + return; + } + cursor.EmitLdloc(pointer2_varNum); + cursor.EmitLdfld(typeof(LiquidDrawCache).GetField("Type")); + cursor.EmitDelegate((bool isVisibleCondition, byte type) => + { + return isVisibleCondition && type != LiquidID.Lava; + }); + } - // Locate the local index for the liquid color and tile coordinates. - int xCoordLocalIndex = 0; - int yCoordLocalIndex = 0; - int liquidColorLocalIndex = 0; - MethodInfo lightingGetColorMethod = typeof(Lighting).GetMethod("GetColor", new Type[] { typeof(int), typeof(int) }); - if (!cursor.TryGotoNext(MoveType.Before, c => c.MatchCallOrCallvirt(lightingGetColorMethod))) + private void BlockLavaDrawingForSlopes(On_TileDrawing.orig_DrawTile_LiquidBehindTile orig, TileDrawing self, bool solidLayer, bool inFrontOfPlayers, int waterStyleOverride, Vector2 screenPosition, Vector2 screenOffset, int tileX, int tileY, Tile tileCache) + { + Tile tile = Main.tile[tileX + 1, tileY]; + Tile tile2 = Main.tile[tileX - 1, tileY]; + Tile tile3 = Main.tile[tileX, tileY - 1]; + Tile tile4 = Main.tile[tileX, tileY + 1]; + if (tileCache.LiquidType == LiquidID.Lava || tile.LiquidType == LiquidID.Lava || tile2.LiquidType == LiquidID.Lava || tile3.LiquidType == LiquidID.Lava || tile4.LiquidType == LiquidID.Lava) { - LogFailure("Custom Lava Drawing", "Could not lighting GetColor call."); return; } - if (!cursor.TryGotoPrev(c => c.MatchLdloc(out xCoordLocalIndex))) + orig.Invoke(self, solidLayer, inFrontOfPlayers, waterStyleOverride, screenPosition, screenOffset, tileX, tileY, tileCache); + } + + private void BlockLavaDrawingForSlopes2(On_TileDrawing.orig_DrawPartialLiquid orig, TileDrawing self, bool behindBlocks, Tile tileCache, ref Vector2 position, ref Rectangle liquidSize, int liquidType, ref VertexColors colors) + { + if (liquidType == 1) { - LogFailure("Custom Lava Drawing", "Could not X coordinate local variable index."); return; } - if (!cursor.TryGotoPrev(c => c.MatchLdloc(out yCoordLocalIndex))) + orig.Invoke(self, behindBlocks, tileCache, ref position, ref liquidSize, liquidType, ref colors); + } + + private void LavafallRemover(On_WaterfallManager.orig_DrawWaterfall_int_int_int_float_Vector2_Rectangle_Color_SpriteEffects orig, WaterfallManager self, int waterfallType, int x, int y, float opacity, Vector2 position, Rectangle sourceRect, Color color, SpriteEffects effects) + { + if (waterfallType == 1) { - LogFailure("Custom Lava Drawing", "Could not Y coordinate local variable index."); return; } - if (!cursor.TryGotoNext(c => c.MatchStloc(out liquidColorLocalIndex))) + orig.Invoke(self, waterfallType, x, y, opacity, position, sourceRect, color, effects); + } + + private void BlockRetroLightingLava(ILContext il) + { + ILCursor cursor = new ILCursor(il); + ILLabel target = cursor.DefineLabel(); + int tileXVar = -1; + int tileYVar = -1; + //Gets the Brfalse of the ending of "if (tile[j, i].liquid <= 0 || (tile[j, i].nactive() && tileSolid[tile[j, i].type] && !tileSolidTop[tile[j, i].type]) || !(Lighting.Brightness(j, i) > 0f || bg))", the BR false is used to prevent liquid rendering + //The X and Y from GetColor are also stored to be used in the delegate without hardcoding Ldloc numbers + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchBrfalse(out target), c => c.MatchLdloc(out tileXVar), c => c.MatchLdloc(out tileYVar), c => c.MatchCall("GetColor"), c => c.MatchStloc(out _))) + { + LogFailure("old Drawing Waters", "Could not locate the initlisation of the initial color variable and the ending of the if statement preventing liquid rendering"); + return; + } + if (target == null) { - LogFailure("Custom Lava Drawing", "Could not lighting GetColor local variable index."); + LogFailure("old Drawing Waters", "The BrFalse returned null, cannot correctly jump to skip the lava rendering"); return; } + cursor.EmitLdloc(tileXVar); + cursor.EmitLdloc(tileYVar); + cursor.EmitDelegate((int j, int i) => + { + return Main.tile[j, i].LiquidType == LiquidID.Lava; + }); + cursor.EmitBrtrue(target); + } + #endregion - // Shortly after the liquid color local is the liquid type integer. Locate it. - int liquidTypeLocalIndex = 0; - if (!cursor.TryGotoNext(MoveType.Before, c => c.MatchLdcI4(0))) + #region Lava Replacing + private void LavaBubbleReplacer(ILContext il) + { + ILCursor cursor = new ILCursor(il); + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdcI4(16), c => c.MatchLdcI4(16), c => c.MatchLdcI4(35))) { - LogFailure("Custom Lava Drawing", "Could not default value for the liquid type."); + LogFailure("Ambient lava bubble replacer", "Could not locate the bubble newdust parameters"); return; } - if (!cursor.TryGotoNext(c => c.MatchStloc(out liquidTypeLocalIndex))) + cursor.EmitDelegate>(type => LavaRendering.dustLava()); + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdcI4(16), c => c.MatchLdcI4(8), c => c.MatchLdcI4(35))) { - LogFailure("Custom Lava Drawing", "Could not liquid type local variable index."); + LogFailure("Ambient lava bubble replacer", "Could not locate the surface bubble newdust parameters"); return; } + cursor.EmitDelegate>(type2 => LavaRendering.dustLava()); + } - // Select the lava color. - if (!cursor.TryGotoNext(MoveType.After, c => c.MatchCallOrCallvirt("get_NotRetro"))) + private void LavaDropletReplacer(ILContext il) + { + ILCursor cursor = new ILCursor(il); + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdarg(out _), c => c.MatchLdcI4(374), c => c.MatchBneUn(out _), c => c.MatchLdcI4(716))) { - LogFailure("Custom Lava Drawing", "Could not locate the retro style check."); + LogFailure("Ambient lava droplet replacer", "Could not locate the lava droplet newgore parameters"); return; } + cursor.EmitDelegate>(type => LavaRendering.goreLava()); + } - // Pass the texture in so that the method can ensure it is not messing around with non-lava textures. - cursor.Emit(OpCodes.Ldloc, liquidColorLocalIndex); - cursor.Emit(OpCodes.Ldsfld, typeof(TextureAssets).GetField("Liquid")); - cursor.Emit(OpCodes.Ldloc, liquidTypeLocalIndex); - cursor.Emit(OpCodes.Ldelem_Ref); - cursor.Emit(OpCodes.Call, textureGetValueMethod); - cursor.Emit(OpCodes.Ldloc, xCoordLocalIndex); - cursor.Emit(OpCodes.Ldloc, yCoordLocalIndex); - cursor.EmitDelegate>((initialColor, initialTexture, x, y) => + private void SplashEntityLava(ILContext il) + { + ILCursor cursor = new ILCursor(il); + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdfld("width"), c => c.MatchLdcI4(12), c => c.MatchAdd(), c => c.MatchLdcI4(24), c => c.MatchLdcI4(35))) { - Color c = SelectLavaColor(initialTexture, initialColor); - - if (ExtraColorChangeConditions is not null) - c = ExtraColorChangeConditions(new(c), Main.waterStyle, new(x, y)).TopLeftColor; + LogFailure("Entity Lava Splashing (Item, Projectile, NPC, Player)", "Could not locate the first lava bubble splashing"); + return; + } + cursor.EmitDelegate>(type => LavaRendering.dustLava()); + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdfld("width"), c => c.MatchLdcI4(12), c => c.MatchAdd(), c => c.MatchLdcI4(24), c => c.MatchLdcI4(35))) + { + LogFailure("Entity Lava Splashing (Item, Projectile, NPC, Player)", "Could not locate the second lava bubble splashing"); + return; + } + cursor.EmitDelegate>(type2 => LavaRendering.dustLava()); + } - return c; + private void PlayerDebuffEdit(ILContext il) + { + //Injects code directly at the position where the OnFire debuff is handled + ILCursor cursor = new ILCursor(il); + if (!cursor.TryGotoNext(MoveType.Before, c => c.MatchLdarg0(), c => c.MatchLdcI4(24), c => c.MatchLdloc(161), c => c.MatchLdcI4(1), c => c.MatchLdcI4(0), c => c.MatchCall("AddBuff"))) + { + LogFailure("Player Update Lava Debuff", "Could not locate the infliction of the On Fire! debuff inside the Player Update code"); + return; + } + cursor.EmitLdarg0(); + cursor.EmitLdloc(161); + cursor.EmitDelegate((Player player, int onFiretime) => + { + LavaStylesLoader.InflictDebuff(player, CalamityMod.LavaStyle, onFiretime); }); - cursor.Emit(OpCodes.Stloc, liquidColorLocalIndex); + } + #endregion + + #region Other + private Color WaterfallGlowmaskEditor(On_WaterfallManager.orig_StylizeColor orig, float alpha, int maxSteps, int waterfallType, int y, int s, Tile tileCache, Color aColor) + { + if (CalamityMod.LavaStyle != 0 && !LavaStylesLoader.Get(CalamityMod.LavaStyle).LavafallGlowmask()) + { + return aColor; + } + else if (LoaderManager.Get().Get(waterfallType) is IWaterfallWithAlphaChange waterfallWithAlpha) + { + waterfallWithAlpha.ModifyAlpha(ref alpha); + return orig.Invoke(alpha, maxSteps, waterfallType, y, s, tileCache, aColor); + } + else + { + return orig.Invoke(alpha, maxSteps, waterfallType, y, s, tileCache, aColor); + } + } - // Go back to the start and change textures as necessary. - cursor.Index = 0; + private void LavaFallRedrawer(On_WaterfallManager.orig_Draw orig, WaterfallManager self, SpriteBatch spriteBatch) + { + orig.Invoke(self, spriteBatch); + LavaRendering.instance.InitialDrawLavafall(self); + } + #endregion - while (cursor.TryGotoNext(c => c.MatchLdsfld(typeof(TextureAssets).GetField("Liquid")))) + #endregion + + #region Liquid Visuals + //Contains all liquid light and liquid alpha (seethrough-ability) + private void LiquidEmitLight(On_TileLightScanner.orig_ApplyLiquidLight orig, TileLightScanner self, Tile tile, ref Vector3 lightColor) + { + orig.Invoke(self, tile, ref lightColor); + if (tile.LiquidAmount > 0 && !tile.HasTile) { - // Move to the end of the get_Value() call and then use the resulting texture to check if a new one should replace it. - // Adding to the index directly would seem like a simple, direct way of achieving this since the operation is incredibly light, but - // it is unsafe due to the potential for NOP operations to appear. - if (!cursor.TryGotoNext(MoveType.After, c => c.MatchCallvirt(textureGetValueMethod))) + if (tile.LiquidType == LiquidID.Water) { - LogFailure("Custom Lava Drawing", "Could not locate the liquid texture Value call."); - return; + float R = 0f; + float G = 0f; + float B = 0f; + CalamityWaterLoader.ModifyLightSetup(tile.X(), tile.Y(), Main.waterStyle, ref R, ref G, ref B); + if (lightColor.X < R) + { + lightColor.X = R; + } + if (lightColor.Y < G) + { + lightColor.Y = G; + } + if (lightColor.Z < B) + { + lightColor.Z = B; + } + } + else if (tile.LiquidType == LiquidID.Lava && CalamityMod.Instance.biomeLava == null) + { + Vector3 lavaLight = new Vector3(0.55f, 0.33f, 0.11f); + float R = CalamityMod.LavaStyle == 0 ? lavaLight.X : 0f; + float G = CalamityMod.LavaStyle == 0 ? lavaLight.Y : 0f; + float B = CalamityMod.LavaStyle == 0 ? lavaLight.Z : 0f; + LavaStylesLoader.ModifyLightSetup(tile.X(), tile.Y(), CalamityMod.LavaStyle, ref R, ref G, ref B); + for (int j = 0; j < LavaStylesLoader.TotalCount; j++) + { + if (CalamityMod.lavaAlpha[j] > 0f && j != CalamityMod.LavaStyle) + { + float r = j == 0 ? lavaLight.X : 0f; + float g = j == 0 ? lavaLight.Y : 0f; + float b = j == 0 ? lavaLight.Z : 0f; + LavaStylesLoader.ModifyLightSetup(tile.X(), tile.Y(), j, ref r, ref g, ref b); + float r2 = CalamityMod.LavaStyle == 0 ? lavaLight.X : 0f; + float g2 = CalamityMod.LavaStyle == 0 ? lavaLight.Y : 0f; + float b2 = CalamityMod.LavaStyle == 0 ? lavaLight.Z : 0f; + LavaStylesLoader.ModifyLightSetup(tile.X(), tile.Y(), CalamityMod.LavaStyle, ref r2, ref g2, ref b2); + R = Single.Lerp(r, r2, CalamityMod.lavaAlpha[CalamityMod.LavaStyle]); + G = Single.Lerp(g, g2, CalamityMod.lavaAlpha[CalamityMod.LavaStyle]); + B = Single.Lerp(b, b2, CalamityMod.lavaAlpha[CalamityMod.LavaStyle]); + } + } + if (!(R == 0 && G == 0 && B == 0)) + { + float colorManipulator = (float)(270 - Main.mouseTextColor) / 900f; + R += colorManipulator; + G += colorManipulator; + B += colorManipulator; + } + if (lightColor.X < R) + { + lightColor.X = R; + } + if (lightColor.Y < G) + { + lightColor.Y = G; + } + if (lightColor.Z < B) + { + lightColor.Z = B; + } } - - cursor.EmitDelegate>(initialTexture => SelectLavaTexture(initialTexture, LiquidTileType.Block)); } } - private static void DrawCustomLavafalls(Terraria.On_WaterfallManager.orig_DrawWaterfall_int_int_int_float_Vector2_Rectangle_Color_SpriteEffects orig, WaterfallManager self, int waterfallType, int x, int y, float opacity, Vector2 position, Rectangle sourceRect, Color color, SpriteEffects effects) + private void LavafallLightEditor(On_WaterfallManager.orig_AddLight orig, int waterfallType, int x, int y) { - waterfallType = CustomLavaManagement.SelectLavafallStyle(waterfallType); - color = CustomLavaManagement.SelectLavafallColor(waterfallType, color); - - orig(self, waterfallType, x, y, opacity, position, sourceRect, color, effects); + if (waterfallType == 1) + { + float r = 0.55f; + float g = 0.33f; + float b = 0.11f; + LavaStylesLoader.ModifyLightSetup(x, y, CalamityMod.LavaStyle, ref r, ref g, ref b); + Lighting.AddLight(x, y, r, g, b); + return; + } + orig.Invoke(waterfallType, x, y); } - #endregion - #region Water Visuals - private static void MakeSulphSeaWaterBetter(Terraria.Graphics.Light.On_TileLightScanner.orig_GetTileLight orig, TileLightScanner self, int x, int y, out Vector3 outputColor) + private static void LiquidDrawColors(ILContext il) { - orig(self, x, y, out outputColor); - if (outputColor == Vector3.One || outputColor == new Vector3(0.25f, 0.25f, 0.25f) || outputColor == new Vector3(0.5f, 0.5f, 0.5f)) - return; + const string TypeFieldName = nameof(LiquidRenderer.LiquidDrawCache.Type); + + ILCursor cursor = new ILCursor(il); + int tileXVar = -1; + int tileYVar = -1; + int pointerVar = -1; + int verticesVar = -1; - Tile tile = CalamityUtils.ParanoidTileRetrieval(x, y); - if (tile.LiquidAmount <= 0 || tile.HasTile || (Main.waterStyle != SulphuricWater.Type && - Main.waterStyle != SulphuricDepthsWater.Type && Main.waterStyle != SunkenSeaWater.Type)) + if (!cursor.TryGotoNext(c => c.MatchLdloc(out _), c => c.MatchConvU(), c => c.MatchStloc(out pointerVar))) + { + LogFailure("Liquid Draw Colors", "Could not locate the liquid pointer local variable"); return; + } + if (!cursor.TryGotoNext(c => c.MatchLdloca(out verticesVar), c => c.MatchLdcR4(1), c => c.MatchCall("GetCornerColors"))) + { + LogFailure("Liquid Draw Colors", "Could not locate the vertices local variable"); + return; + } - Tile above = CalamityUtils.ParanoidTileRetrieval(x, y - 1); - if (!Main.gamePaused && !above.HasTile && above.LiquidAmount <= 0 && Main.rand.NextBool(9) && - Main.waterStyle == SulphuricWater.Type) + if (!cursor.TryGotoNext(MoveType.Before, c => c.MatchLdarg2(), c => c.MatchLdloc(out tileXVar), c => c.MatchLdloc(out tileYVar), c => c.MatchCall
("DrawTileInWater"))) { - MediumMistParticle acidFoam = new(new(x * 16f + Main.rand.NextFloat(16f), y * 16f + 8f), -Vector2.UnitY.RotatedByRandom(0.67f) * Main.rand.NextFloat(1f, 2.4f), Color.LightSeaGreen, Color.White, 0.16f, 128f, 0.02f); - GeneralParticleHandler.SpawnParticle(acidFoam); + LogFailure("Liquid Draw Colors", "Could not locate the liquid vertex colors for drawing"); + return; } - if (tile.TileType != (ushort)ModContent.TileType()) + cursor.Emit(OpCodes.Ldloc, tileXVar); + cursor.Emit(OpCodes.Ldloc, tileYVar); + cursor.Emit(OpCodes.Ldloc, pointerVar); + cursor.EmitLdfld(typeof(LiquidRenderer.LiquidDrawCache).GetField(TypeFieldName)); + cursor.Emit(OpCodes.Ldloca, verticesVar); + + cursor.EmitDelegate((int x, int y, byte liquidType, ref VertexColors initialColor) => { - if (Main.waterStyle == SulphuricWater.Type && Main.dayTime && !Main.raining) + if (liquidType == LiquidID.Water) { - float brightness = MathHelper.Clamp(0.2f - (y / 680), 0f, 0.2f); - if (y > 580) - brightness *= 1f - (y - 580) / 100f; - - float waveScale1 = Main.GameUpdateCount * 0.014f; - float waveScale2 = Main.GameUpdateCount * 0.1f; - int scalar = x + (-y / 2); - float wave1 = waveScale1 * -50 + scalar * 15; - float wave2 = waveScale2 * -10 + scalar * 14; - float wave3 = waveScale1 * -100 + scalar * 13; - float wave4 = waveScale2 * 10 + scalar * 25; - float wave5 = waveScale1 * -70 + scalar * 5; - float wave1angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave1)); - float wave2angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave2)); - float wave3angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave3)); - float wave4angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave4)); - float wave5angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave5)); - outputColor = Vector3.Lerp(outputColor, Color.LightSeaGreen.ToVector3(), 0.41f + wave1angle + wave2angle + wave3angle + wave4angle + wave5angle); - outputColor *= brightness; + CalamityWaterLoader.DrawColorSetup(x, y, Main.waterStyle, ref initialColor); } - - if (Main.waterStyle == SulphuricWater.Type && !Main.dayTime && !Main.raining) + else if (liquidType == LiquidID.Lava && CalamityMod.Instance.biomeLava == null) { - float brightness = MathHelper.Clamp(0.17f - (y / 680), 0f, 0.17f); - if (y > 580) - brightness *= 1f - (y - 580) / 100f; - - float waveScale1 = Main.GameUpdateCount * 0.014f; - float waveScale2 = Main.GameUpdateCount * 0.1f; - int scalar = x + (-y / 2); - float wave1 = waveScale1 * -50 + scalar * 15; - float wave2 = waveScale2 * -10 + scalar * 14; - float wave3 = waveScale1 * -100 + scalar * 13; - float wave4 = waveScale2 * 10 + scalar * 25; - float wave5 = waveScale1 * -70 + scalar * 5; - float wave1angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave1)); - float wave2angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave2)); - float wave3angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave3)); - float wave4angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave4)); - float wave5angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave5)); - outputColor = Vector3.Lerp(outputColor, Color.LightSeaGreen.ToVector3(), 0.41f + wave1angle + wave2angle + wave3angle + wave4angle + wave5angle); - outputColor *= brightness; + LavaStylesLoader.DrawColorSetup(x, y, CalamityMod.LavaStyle, ref initialColor); } + }); + } - if (Main.waterStyle == SulphuricWater.Type && Main.raining) - { - float brightness = MathHelper.Clamp(1f - (y / 680), 0f, 1f); - if (y > 580) - brightness *= 1f - (y - 580) / 100f; + //Somewhat broken and I have no idea + //Something during the liquid slope rewrite messed up with slope colors and now slopes for the Sulphuric Water Style is now invisible when the slope fix is toggled off + //I've been staring at this and it's orig method for about 2 hours and I geniuenly have 0 clue how or why it broke the way it did + //Attempted to fix but imo its not terribly worth it (mainly since on normal colored lighting the slopes look fine (retro aparently runs worse than colored anyways)) + //Fairly sure either HPU or Iban wrote the ILChanges.SelectSulphuricWaterColor code which im not knowledgable enough with vertex colors to mess with + //"Sprunolia is bald" + private static void LiquidSlopeDrawColors(ILContext il) + { + ILCursor cursor = new ILCursor(il); + int vertexColorsVar = -1; + int colorColorsVar = -1; + int isWaterVar = -1; - outputColor = Vector3.Lerp(outputColor, Color.LightSeaGreen.ToVector3(), 0.41f); - outputColor *= brightness; - } + if (!cursor.TryGotoNext(c => c.MatchLdsfld
("waterStyle"), c => c.MatchStloc(out _), c => c.MatchLdarg(6), c => c.MatchLdarg(7), c => c.MatchLdloca(out vertexColorsVar), c => c.MatchLdcR4(1), c => c.MatchCall("GetCornerColors"))) + { + LogFailure("Liquid Slope Draw Colors", "Could not locate the liquid slope vertex colors for drawing"); + return; + } + + if (!cursor.TryGotoNext(MoveType.Before, c => c.MatchLdcI4(0), c => c.MatchStloc(out _), c => c.MatchLdloc(out isWaterVar), c => c.MatchBrfalse(out _), c => c.MatchCall(out _), c => c.MatchCallvirt("get_TotalCount"))) + { + LogFailure("Liquid Slope Draw Colors", "Could not locate the liquid slope vertex colors for drawing"); + return; + } - if (Main.waterStyle == SulphuricDepthsWater.Type) - outputColor = Vector3.Lerp(outputColor, Color.MediumSeaGreen.ToVector3(), 0.18f); + cursor.Emit(OpCodes.Ldarg, 6); + cursor.Emit(OpCodes.Ldarg, 7); + cursor.Emit(OpCodes.Ldloca, vertexColorsVar); + cursor.Emit(OpCodes.Ldloc, isWaterVar); - if (Main.waterStyle == SunkenSeaWater.Type) + cursor.EmitDelegate((int x, int y, ref VertexColors initialColor, bool flag6) => + { + if (flag6) { - float brightness = MathHelper.Clamp(0.07f, 0f, 0.07f); - float waveScale1 = Main.GameUpdateCount * 0.028f; - float waveScale2 = Main.GameUpdateCount * 0.1f; - int yScale = -y / 2; - int xScale = x / 15; - float wave1 = Main.GameUpdateCount * 0.024f * -50 + ((-x / 30) + (y / 30)) * 25; - float wave2 = waveScale2 * -10 + ((-xScale) + yScale) * 45; - float wave3 = waveScale1 * -100 + ((x / 7) + (y / 50)) * 25; - float wave4 = Main.GameUpdateCount * 0.15f * 10 + ((x / 3) + yScale) * 45; - float wave5 = waveScale1 * -70 + ((-x / 25) + (-y / 25)) * 20; - float wave6 = waveScale2 * -10 + (xScale + yScale) * 45; - float bigwave = Main.GameUpdateCount * 0.01f * -70 + ((-x / 2) + (-y / 40)) * 5; - float wave1angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave1)); - float wave2angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave2)); - float wave3angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave3)); - float wave4angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave4)); - float wave5angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave5)); - float wave6angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave6)); - float bigwaveangle = 0.55f + 0.80f * (float)Math.Sin(MathHelper.ToRadians(bigwave)); - outputColor = Vector3.Lerp(outputColor, Color.DeepSkyBlue.ToVector3(), 0.07f + wave1angle + wave2angle + wave3angle + wave4angle + wave5angle + wave6angle + bigwaveangle); - outputColor *= brightness; + int totalCount = (int)typeof(Loader).GetProperty("TotalCount", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static).GetValue(LoaderManager.Get()); + for (int i = 0; i < totalCount; i++) + { + Tile tile = Main.tile[x, y]; + if (i == Main.waterStyle && tile.LiquidType == LiquidID.Water) + { + CalamityWaterLoader.DrawColorSetup(x, y, Main.waterStyle, ref initialColor, true); + } + else if ((tile.LiquidType == LiquidID.Lava || i == 1) && CalamityMod.Instance.biomeLava == null) + { + //if flag6 means that the id is water, would that mean this code never executes? + LavaStylesLoader.DrawColorSetup(x, y, CalamityMod.LavaStyle, ref initialColor); + } + } } + }); + + if (!cursor.TryGotoNext(MoveType.After, c => c.MatchLdloca(out colorColorsVar), c => c.MatchLdflda("TopRightColor"), c => c.MatchDup(), c => c.MatchLdobj(), c => c.MatchLdloc(out _), c => c.MatchCall("op_Multiply"), c => c.MatchStobj())) + { + LogFailure("Liquid Slope Draw Colors", "Could not locate the liquid slope color colors for drawing"); + return; } + + cursor.Emit(OpCodes.Ldarg, 6); + cursor.Emit(OpCodes.Ldarg, 7); + cursor.Emit(OpCodes.Ldloca, colorColorsVar); + + cursor.EmitDelegate((int x, int y, ref VertexColors initialColor) => + { + int totalCount = (int)typeof(Loader).GetProperty("TotalCount", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static).GetValue(LoaderManager.Get()); + for (int i = 0; i < totalCount; i++) + { + Tile tile = Main.tile[x, y]; + if (i == Main.waterStyle && tile.LiquidType == LiquidID.Water) + { + CalamityWaterLoader.DrawColorSetup(x, y, Main.waterStyle, ref initialColor, true); + } + } + }); } #endregion @@ -1376,7 +1589,7 @@ internal static void GetDifficultyOverride(Terraria.GameContent.UI.Elements.On_A { return; } - + // Go through the World Selection Difficulty System's World Difficulty list backwards and choose the latest difficulty that applies for (int i = WorldSelectionDifficultySystem.WorldDifficulties.Count - 1; i >= 0; i--) { @@ -1398,12 +1611,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,6 +1636,17 @@ public static void ShimmerEffectEdits(Terraria.On_Item.orig_GetShimmered orig, I { orig(self); } + }*/ + #endregion + + #region Make Celestial Onion give the Master Mode slot + public static bool MasterModeCelestialOnionCheck(Terraria.On_Player.orig_IsItemSlotUnlockedAndUsable orig, Player self, int slot) + { + if ((slot == 9 || slot == 19) && self.Calamity().extraAccessoryML && !Main.gameMenu) + { + return true; + } + return orig(self, slot); } #endregion } diff --git a/ILEditing/VanillaStupidityFixingILChanges.cs b/ILEditing/VanillaStupidityFixingILChanges.cs index 9a430ec383..220368f7b3 100644 --- a/ILEditing/VanillaStupidityFixingILChanges.cs +++ b/ILEditing/VanillaStupidityFixingILChanges.cs @@ -116,11 +116,30 @@ private static void RelaxPrefixRequirements(ILContext il) #region Prevention of Slime Rain Spawns When Near Bosses private static void PreventBossSlimeRainSpawns(Terraria.On_NPC.orig_SlimeRainSpawns orig, int plr) { - if (!Main.player[plr].Calamity().isNearbyBoss && CalamityConfig.Instance.BossZen) + if (!Main.player[plr].Calamity().isNearbyBoss && CalamityServerConfig.Instance.BossZen) orig(plr); } #endregion Prevention of Slime Rain Spawns When Near Bosses + #region Prevent Lava Slime Dropping Lava + private static void PreventLavaSlimeLavaDrop(ILContext il) + { + // Disable Lava Slimes dropping lava if its respective config is enabled. + var cursor = new ILCursor(il); + + // Go to the check for Remix world. + if (!cursor.TryGotoNext(MoveType.Before, i => i.MatchLdsfld
("remixWorld"))) + { + LogFailure("Prevent Lava Slime Dropping Lava", "Could not find the check for Remix World."); + return; + } + + // Add an additional check for the config. + cursor.Remove(); + cursor.EmitDelegate>(() => CalamityServerConfig.Instance.RemoveLavaDropsFromLavaSlimes || Main.remixWorld); + } + #endregion + #region Remove Feral Bite Random Debuffs private static void RemoveFeralBiteRandomDebuffs(ILContext il) { @@ -139,6 +158,28 @@ private static void RemoveFeralBiteRandomDebuffs(ILContext il) } #endregion + #region Make PunchCameraModifier Affected by Screenshake Config + private static void PunchCameraUsesScreenshakeConfig(ILContext il) + { + // Allow the screenshake from PunchCameraModifier to scale based on our screenshake power config. + var cursor = new ILCursor(il); + + // There are 3 local variables that control the strength of the screenshake in separate ways, but they all get multiplied together at the end. + // Thus it doesn't matter at all which one is multiplied to. Here I chose num2. + if (!cursor.TryGotoNext(MoveType.After, i => i.MatchStloc2())) + { + LogFailure("Make PunchCameraModifier Affected by Screenshake Config", "Could not move to the location to inject code."); + return; + } + + // Emit a delegate which grabs the value of the screenshake config. Then multiply the local variable by it. + cursor.Emit(OpCodes.Ldloc_1); + cursor.EmitDelegate>(() => CalamityClientConfig.Instance.ScreenshakePower); + cursor.Emit(OpCodes.Mul); + cursor.Emit(OpCodes.Stloc_1); + } + #endregion + #region Make Meteorite Explodable private static void MakeMeteoriteExplodable(ILContext il) { diff --git a/ILEditing/WorldgenILChanges.cs b/ILEditing/WorldgenILChanges.cs index 67f4682353..d3f2523691 100644 --- a/ILEditing/WorldgenILChanges.cs +++ b/ILEditing/WorldgenILChanges.cs @@ -33,28 +33,6 @@ public static int? DungeonBaseXLimitOverride set; } - #region Replacement of Pharaoh Set in Pyramids - // Note: There is no need to replace the other Pharaoh piece, due to how the vanilla code works. - // The other Pharaoh vanity piece is added automatically if the mask is found in the chest. - private static void ReplacePharaohSetInPyramids(ILContext il) - { - var cursor = new ILCursor(il); - - // Find the instruction which loads in the item ID of the Pharaoh's Mask. - if (!cursor.TryGotoNext(MoveType.Before, i => i.MatchLdcI4(ItemID.PharaohsMask))) - { - LogFailure("Pharaoh Set Pyramid Replacement", "Could not locate the Pharaoh's Mask item ID."); - return; - } - - // Replace the Pharaoh's Mask with the Amber Hook. - // THIS INT CAST IS MANDATORY. DO NOT REMOVE IT. - // In TML's DLL, despite item IDs being shorts (16 bits), the hardcoded 848 here is a 32-bit integer literal. - // As such, it must be replaced with a 32-bit integer literal or the branches of the switch will misalign and the IL edit fails. - cursor.Next.Operand = (int)ItemID.AmberHook; - } - #endregion Replacement of Pharaoh Set in Pyramids - #region Fixing of Living Tree/Sulphurous Sea Interactions private static void BlockLivingTreesNearOcean(ILContext il) { @@ -68,7 +46,7 @@ private static void BlockLivingTreesNearOcean(ILContext il) #region Removal of Hardmode Ore Generation from Evil Altars private static void PreventSmashAltarCode(Terraria.On_WorldGen.orig_SmashAltar orig, int i, int j) { - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework) return; orig(i, j); diff --git a/Items/Accessories/CoinofDeceit.cs b/Items/Accessories/CoinofDeceit.cs index 694429bc96..1b9ac86cd6 100644 --- a/Items/Accessories/CoinofDeceit.cs +++ b/Items/Accessories/CoinofDeceit.cs @@ -18,7 +18,7 @@ public override void SetDefaults() public override void UpdateAccessory(Player player, bool hideVisual) { - player.Calamity().stealthStrike85Cost = true; + player.Calamity().stealthStrike90Cost = true; player.GetCritChance() += 6; } diff --git a/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/AureateBooster.cs b/Items/Accessories/Wings/AureateBooster.cs index 1207c6432b..18f75ff0a8 100644 --- a/Items/Accessories/Wings/AureateBooster.cs +++ b/Items/Accessories/Wings/AureateBooster.cs @@ -30,6 +30,8 @@ public override void SetDefaults() public override void UpdateAccessory(Player player, bool hideVisual) { + player.DisableWingFlapSound(); + if (player.controlJump && player.wingTime > 0f && player.jump == 0 && player.velocity.Y != 0f && !hideVisual) { player.rocketDelay2--; diff --git a/Items/Accessories/Wings/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/MOAB.cs b/Items/Accessories/Wings/MOAB.cs index 694ddaab3b..ea7b73da86 100644 --- a/Items/Accessories/Wings/MOAB.cs +++ b/Items/Accessories/Wings/MOAB.cs @@ -28,6 +28,8 @@ public override void SetDefaults() public override void UpdateAccessory(Player player, bool hideVisual) { + player.DisableWingFlapSound(); + if (player.controlJump && player.wingTime > 0f && player.jump == 0 && player.velocity.Y != 0f && !hideVisual) { player.rocketDelay2--; diff --git a/Items/Accessories/Wings/SkylineWings.cs b/Items/Accessories/Wings/SkylineWings.cs index 58ab67d809..9f3ffac83f 100644 --- a/Items/Accessories/Wings/SkylineWings.cs +++ b/Items/Accessories/Wings/SkylineWings.cs @@ -12,7 +12,7 @@ public class SkylineWings : ModItem, ILocalizedModType public new string LocalizationCategory => "Items.Accessories.Wings"; public override void SetStaticDefaults() { - ArmorIDs.Wing.Sets.Stats[Item.wingSlot] = new WingStats(80, 6.5f, 1f); + ArmorIDs.Wing.Sets.Stats[Item.wingSlot] = new WingStats(80, 6.25f, 1f); } public override void SetDefaults() @@ -38,11 +38,6 @@ public override void VerticalWingSpeeds(Player player, ref float ascentWhenFalli constantAscend = 0.1f; } - public override void HorizontalWingSpeeds(Player player, ref float speed, ref float acceleration) - { - speed = 6.25f; - } - public override void AddRecipes() { CreateRecipe(). 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..977ab4458d 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; + } + // Animation + if (player.wingFrameCounter % frameRate == 0) + { + player.wingFrame++; + } + // Reset frames + if (player.wingFrame >= maxFrames) + { + player.wingFrameCounter = 0; + player.wingFrame = 1; + } + } + 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/AntiCystOintment.cs b/Items/AntiCystOintment.cs index c109169272..9b5ba62151 100644 --- a/Items/AntiCystOintment.cs +++ b/Items/AntiCystOintment.cs @@ -1,16 +1,15 @@ -using Terraria; +using System.Collections.Generic; +using System.IO; +using Terraria; using Terraria.ID; using Terraria.ModLoader; -using System.Collections.Generic; -using Microsoft.Xna.Framework.Graphics; -using Microsoft.Xna.Framework; +using Terraria.ModLoader.IO; using static CalamityMod.CalamityUtils; namespace CalamityMod.Items { public class AntiCystOintment : ModItem, ILocalizedModType { - public static bool state = false; public new string LocalizationCategory => "Items.Misc"; public override void SetDefaults() { @@ -25,21 +24,40 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite itemGroup = (ContentSamples.CreativeHelper.ItemGroup)CalamityResearchSorting.SpawnPrevention; } + #region Toggle Feature + + public bool Enabled = true; + + public override ModItem Clone(Item item) + { + var clone = (AntiCystOintment)base.Clone(item); + clone.Enabled = Enabled; + return clone; + } + + public override void SaveData(TagCompound tag) => tag.Add("blockerEnabled", Enabled); + + public override void LoadData(TagCompound tag) => Enabled = tag.GetBool("blockerEnabled"); + + public override void NetSend(BinaryWriter writer) => writer.Write(Enabled); + + public override void NetReceive(BinaryReader reader) => Enabled = reader.ReadBoolean(); + public override bool CanRightClick() => true; + public override bool ConsumeItem(Player player) => false; + public override void RightClick(Player player) { - if (player.Calamity().disablePerfCystSpawns == true) - player.Calamity().disablePerfCystSpawns = false; - else - player.Calamity().disablePerfCystSpawns = true; + Enabled = !Enabled; Item.NetStateChanged(); - state = player.Calamity().disablePerfCystSpawns; + } + + #endregion - bool favorited = Item.favorited; - Item.SetDefaults(ModContent.ItemType()); - Item.stack++; - Item.favorited = favorited; + public override void UpdateInventory(Player player) + { + player.Calamity().disablePerfCystSpawns |= Enabled; } /* @@ -84,7 +102,7 @@ public override bool PreDrawInWorld(SpriteBatch spriteBatch, Color lightColor, C public override void ModifyTooltips(List tooltips) { string text; - if (state == true) + if (Enabled) text = GetTextValue("Items.Misc.SpawnBlockersOn"); else text = GetTextValue("Items.Misc.SpawnBlockersOff"); diff --git a/Items/AntiTumorOintment.cs b/Items/AntiTumorOintment.cs index 1ee5b62e48..5166880a05 100644 --- a/Items/AntiTumorOintment.cs +++ b/Items/AntiTumorOintment.cs @@ -1,16 +1,15 @@ -using Terraria; +using System.Collections.Generic; +using System.IO; +using Terraria; using Terraria.ID; using Terraria.ModLoader; -using Microsoft.Xna.Framework.Graphics; -using Microsoft.Xna.Framework; -using System.Collections.Generic; +using Terraria.ModLoader.IO; using static CalamityMod.CalamityUtils; namespace CalamityMod.Items { public class AntiTumorOintment : ModItem, ILocalizedModType { - public static bool state = false; public new string LocalizationCategory => "Items.Misc"; public override void SetDefaults() { @@ -25,22 +24,42 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite itemGroup = (ContentSamples.CreativeHelper.ItemGroup)CalamityResearchSorting.SpawnPrevention; } + #region Toggle Feature + + public bool Enabled = true; + + public override ModItem Clone(Item item) + { + var clone = (AntiTumorOintment)base.Clone(item); + clone.Enabled = Enabled; + return clone; + } + + public override void SaveData(TagCompound tag) => tag.Add("blockerEnabled", Enabled); + + public override void LoadData(TagCompound tag) => Enabled = tag.GetBool("blockerEnabled"); + + public override void NetSend(BinaryWriter writer) => writer.Write(Enabled); + + public override void NetReceive(BinaryReader reader) => Enabled = reader.ReadBoolean(); + public override bool CanRightClick() => true; + public override bool ConsumeItem(Player player) => false; + public override void RightClick(Player player) { - if (player.Calamity().disableHiveCystSpawns == true) - player.Calamity().disableHiveCystSpawns = false; - else - player.Calamity().disableHiveCystSpawns = true; + Enabled = !Enabled; Item.NetStateChanged(); - state = player.Calamity().disableHiveCystSpawns; + } - bool favorited = Item.favorited; - Item.SetDefaults(ModContent.ItemType()); - Item.stack++; - Item.favorited = favorited; + #endregion + + public override void UpdateInventory(Player player) + { + player.Calamity().disableHiveCystSpawns |= Enabled; } + /* public override bool PreDrawInInventory(SpriteBatch spriteBatch, Vector2 position, Rectangle frameI, Color drawColor, Color itemColor, Vector2 origin, float scale) { @@ -83,7 +102,7 @@ public override bool PreDrawInWorld(SpriteBatch spriteBatch, Color lightColor, C public override void ModifyTooltips(List tooltips) { string text; - if (state == true) + if (Enabled) text = GetTextValue("Items.Misc.SpawnBlockersOn"); else text = GetTextValue("Items.Misc.SpawnBlockersOff"); diff --git a/Items/Armor/Brimflame/BrimflameScowl.cs b/Items/Armor/Brimflame/BrimflameScowl.cs index 3f6d5cae92..525d6f4b99 100644 --- a/Items/Armor/Brimflame/BrimflameScowl.cs +++ b/Items/Armor/Brimflame/BrimflameScowl.cs @@ -13,7 +13,7 @@ namespace CalamityMod.Items.Armor.Brimflame public class BrimflameScowl : ModItem, ILocalizedModType { public new string LocalizationCategory => "Items.Armor.Hardmode"; - public static readonly SoundStyle ActivationSound = new("CalamityMod/Sounds/Custom/AbilitySounds/AngelicAllianceActivation"); + public static readonly SoundStyle ActivationSound = new("CalamityMod/Sounds/Custom/AbilitySounds/BrimflameAbility"); // TODO -- what the fuck is this? this is not how you implement a set bonus private bool frenzy = false; 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/BleachBall.cs b/Items/BleachBall.cs index 72c06d37a5..155b348a11 100644 --- a/Items/BleachBall.cs +++ b/Items/BleachBall.cs @@ -1,17 +1,16 @@ using System.Collections.Generic; +using System.IO; using CalamityMod.Items.Materials; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; using Terraria; using Terraria.ID; using Terraria.ModLoader; +using Terraria.ModLoader.IO; using static CalamityMod.CalamityUtils; namespace CalamityMod.Items { public class BleachBall : ModItem, ILocalizedModType { - public static bool state = false; public new string LocalizationCategory => "Items.Misc"; public override void SetDefaults() { @@ -26,21 +25,40 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite itemGroup = (ContentSamples.CreativeHelper.ItemGroup)CalamityResearchSorting.SpawnPrevention; } + #region Toggle Feature + + public bool Enabled = true; + + public override ModItem Clone(Item item) + { + var clone = (BleachBall)base.Clone(item); + clone.Enabled = Enabled; + return clone; + } + + public override void SaveData(TagCompound tag) => tag.Add("blockerEnabled", Enabled); + + public override void LoadData(TagCompound tag) => Enabled = tag.GetBool("blockerEnabled"); + + public override void NetSend(BinaryWriter writer) => writer.Write(Enabled); + + public override void NetReceive(BinaryReader reader) => Enabled = reader.ReadBoolean(); + public override bool CanRightClick() => true; + public override bool ConsumeItem(Player player) => false; + public override void RightClick(Player player) { - if (player.Calamity().disableNaturalScourgeSpawns == true) - player.Calamity().disableNaturalScourgeSpawns = false; - else - player.Calamity().disableNaturalScourgeSpawns = true; + Enabled = !Enabled; Item.NetStateChanged(); - state = player.Calamity().disableNaturalScourgeSpawns; + } + + #endregion - bool favorited = Item.favorited; - Item.SetDefaults(ModContent.ItemType()); - Item.stack++; - Item.favorited = favorited; + public override void UpdateInventory(Player player) + { + player.Calamity().disableNaturalScourgeSpawns |= Enabled; } /* @@ -85,7 +103,7 @@ public override bool PreDrawInWorld(SpriteBatch spriteBatch, Color lightColor, C public override void ModifyTooltips(List tooltips) { string text; - if (state == true) + if (Enabled) text = GetTextValue("Items.Misc.SpawnBlockersOn"); else text = GetTextValue("Items.Misc.SpawnBlockersOff"); diff --git a/Items/BrokenWaterFilter.cs b/Items/BrokenWaterFilter.cs index c4fe0204bc..8115636027 100644 --- a/Items/BrokenWaterFilter.cs +++ b/Items/BrokenWaterFilter.cs @@ -1,17 +1,16 @@ -using CalamityMod.Items.Materials; +using System.Collections.Generic; +using System.IO; +using CalamityMod.Items.Materials; using Terraria; using Terraria.ID; using Terraria.ModLoader; -using Microsoft.Xna.Framework.Graphics; -using Microsoft.Xna.Framework; -using System.Collections.Generic; +using Terraria.ModLoader.IO; using static CalamityMod.CalamityUtils; namespace CalamityMod.Items { public class BrokenWaterFilter : ModItem, ILocalizedModType { - public static bool state = false; public new string LocalizationCategory => "Items.Misc"; public override void SetDefaults() { @@ -26,21 +25,40 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite itemGroup = (ContentSamples.CreativeHelper.ItemGroup)CalamityResearchSorting.SpawnPrevention; } + #region Toggle Feature + + public bool Enabled = true; + + public override ModItem Clone(Item item) + { + var clone = (BrokenWaterFilter)base.Clone(item); + clone.Enabled = Enabled; + return clone; + } + + public override void SaveData(TagCompound tag) => tag.Add("blockerEnabled", Enabled); + + public override void LoadData(TagCompound tag) => Enabled = tag.GetBool("blockerEnabled"); + + public override void NetSend(BinaryWriter writer) => writer.Write(Enabled); + + public override void NetReceive(BinaryReader reader) => Enabled = reader.ReadBoolean(); + public override bool CanRightClick() => true; + public override bool ConsumeItem(Player player) => false; + public override void RightClick(Player player) { - if (player.Calamity().noStupidNaturalARSpawns == true) - player.Calamity().noStupidNaturalARSpawns = false; - else - player.Calamity().noStupidNaturalARSpawns = true; + Enabled = !Enabled; Item.NetStateChanged(); - state = player.Calamity().noStupidNaturalARSpawns; + } + + #endregion - bool favorited = Item.favorited; - Item.SetDefaults(ModContent.ItemType()); - Item.stack++; - Item.favorited = favorited; + public override void UpdateInventory(Player player) + { + player.Calamity().noStupidNaturalARSpawns |= Enabled; } /* @@ -85,7 +103,7 @@ public override bool PreDrawInWorld(SpriteBatch spriteBatch, Color lightColor, C public override void ModifyTooltips(List tooltips) { string text; - if (state == true) + if (Enabled) text = GetTextValue("Items.Misc.SpawnBlockersOn"); else text = GetTextValue("Items.Misc.SpawnBlockersOff"); diff --git a/Items/CalamityGlobalItem.cs b/Items/CalamityGlobalItem.cs index 077b34fc84..0b62e32a86 100644 --- a/Items/CalamityGlobalItem.cs +++ b/Items/CalamityGlobalItem.cs @@ -20,6 +20,7 @@ using CalamityMod.Projectiles.Summon; using CalamityMod.Projectiles.Typeless; using CalamityMod.Rarities; +using CalamityMod.Tiles.Furniture.CraftingStations; using CalamityMod.UI; using CalamityMod.UI.CalamitasEnchants; using CalamityMod.World; @@ -625,15 +626,6 @@ public override bool OnPickup(Item item, Player player) player.Calamity().evilSmasherBoost = 0; } - if (player.HasBuff(BuffID.ParryDamageBuff)) - { - if (item.type != ItemID.DD2SquireDemonSword && item.type != ItemID.BouncingShield) - { - player.parryDamageBuff = false; - player.ClearBuff(BuffID.ParryDamageBuff); - } - } - // Give 1 minute of Mushy buff when consuming Mushrooms with Fungal Symbiote equipped. if (item.type == ItemID.Mushroom && player.Calamity().fungalSymbiote) player.AddBuff(ModContent.BuffType(), 3600); @@ -793,6 +785,11 @@ public override bool CanUseItem(Item item, Player player) return false; // Don't use weapons if you're charging with a spear } + // If the player if using the Drill Containment Unit, ignore all this. + // It will start to check for everything below EVERY FRAME, including attacking with PSC or using Charge + if (player.mount.Type == MountID.Drill) + return base.CanUseItem(item, player); + // Conversion for Andromeda if (player.ownedProjectileCounts[ModContent.ProjectileType()] > 0) { @@ -850,10 +847,6 @@ public override bool CanUseItem(Item item, Player player) // Handle general use-item effects for the Gem Tech Armor. player.Calamity().GemTechState.OnItemUseEffects(item); - if (item.type == ItemID.MonkStaffT1 || CalamityLists.spearAutoreuseList.Contains(item.type)) - { - return player.ownedProjectileCounts[item.shoot] <= 0; - } if (item.type == ItemID.RodofDiscord) { if (player.chaosState) @@ -934,7 +927,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); @@ -1760,10 +1752,19 @@ public override bool PreDrawInInventory(Item item, SpriteBatch spriteBatch, Vect #endregion #region On Create + private static int cachedForgeID = -1; public override void OnCreated(Item item, ItemCreationContext context) { // ChoosePrefix also happens on craft so go reset it here too storedPrefix = -1; + + // 05JUL2024: Ozzatron: Register the usage of Draedon's Forge for the purposes of his dialogue. + // This was moved out of an On edit in the DraedonsForge item for Magic Storage compatibility. + Player p = Main.LocalPlayer; + if (cachedForgeID < 0) + cachedForgeID = ModContent.TileType(); + if (context is RecipeItemCreationContext && p.adjTile[cachedForgeID]) + p.Calamity().HasCraftedDraedonsForge = true; } #endregion @@ -1789,7 +1790,7 @@ public override int ChoosePrefix(Item item, UnifiedRandom rand) return keepPrefix ? prefix : 0; } - if (!CalamityConfig.Instance.RemoveReforgeRNG || Main.gameMenu || storedPrefix == -1) + if (!CalamityServerConfig.Instance.RemoveReforgeRNG || Main.gameMenu || storedPrefix == -1) return -1; // Pick a prefix using the new system. @@ -1808,11 +1809,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/CalamityGlobalItemLoot.cs b/Items/CalamityGlobalItemLoot.cs index 12b004b8cd..e01900cf49 100644 --- a/Items/CalamityGlobalItemLoot.cs +++ b/Items/CalamityGlobalItemLoot.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using CalamityMod.Enums; using CalamityMod.Items.Accessories; using CalamityMod.Items.Materials; using CalamityMod.Items.PermanentBoosters; @@ -25,12 +26,6 @@ public class CalamityGlobalItemLoot : GlobalItem public override void ModifyItemLoot(Item item, ItemLoot loot) { Fraction fifteenPercent = new Fraction(15, 100); - static bool CryonicAvailable() - { - if (!DownedBossSystem.downedCryogen) - return false; - return (NPC.downedMechBoss1.ToInt() + NPC.downedMechBoss2.ToInt() + NPC.downedMechBoss3.ToInt()) >= 2; - } switch (item.type) { @@ -270,91 +265,47 @@ static bool CryonicAvailable() #endregion #region Fishing Crates - // TODO -- What is all this shit? case ItemID.WoodenCrate: case ItemID.WoodenCrateHard: - loot.Add(ModContent.ItemType(), 4, 3, 5); // 25% 3-5 Wulfrum Scrap + // We do not need to pop Hardmode ores out of Pearlwood Crates. They do not drop higher tier ores. break; - case ItemID.IronCrate: case ItemID.IronCrateHard: - loot.Add(ModContent.ItemType(), 4, 5, 8); // 25% 5-8 Wulfrum Scrap - loot.Add(ModContent.ItemType(), 4, 5, 8); // 25% 5-8 Ancient Bone Dust + RemoveHardmodeOresFromStandardCrates(loot); + loot.AddHardmodeOresToCrates(HardmodeCrateType.Mythril); break; - // these drops are not available in hardmode because this crate will stop dropping + // Non-crafted underground Gold Chest loot @ 20%; Individually 5% case ItemID.GoldenCrate: - loot.Add(ItemID.FlareGun, 10); // 10% Flare Gun - loot.Add(ItemID.ShoeSpikes, 10); // 10% Shoe Spikes (BUT NOT CLIMBING CLAWS?) - loot.Add(ItemID.BandofRegeneration, 10); // 10% Band of Regeneration + loot.Add(new OneFromOptionsNotScaledWithLuckDropRule(5, 1, + ItemID.FlareGun, + ItemID.Mace, + ItemID.BandofRegeneration, + ItemID.ShoeSpikes)); // Climbing Claws is in Wooden/Pearlwood (vanilla) in case you're curious break; case ItemID.GoldenCrateHard: - // Post-Yharon: 15% 30-40 Auric Ore - loot.AddIf(() => DownedBossSystem.downedYharon, ModContent.ItemType(), fifteenPercent, 30, 40); + RemoveHardmodeOresFromStandardCrates(loot); + loot.AddHardmodeOresToCrates(HardmodeCrateType.Titanium); + loot.Add(new OneFromOptionsNotScaledWithLuckDropRule(5, 1, + ItemID.FlareGun, + ItemID.Mace, + ItemID.BandofRegeneration, + ItemID.ShoeSpikes)); break; - case ItemID.CorruptFishingCrate: - case ItemID.CrimsonFishingCrate: case ItemID.CorruptFishingCrateHard: case ItemID.CrimsonFishingCrateHard: - loot.Add(ModContent.ItemType(), fifteenPercent, 5, 8); // 15% 5-8 Blighted Gel - break; - - case ItemID.HallowedFishingCrate: // WHY case ItemID.HallowedFishingCrateHard: - var postProv = loot.DefineConditionalDropSet(() => DownedBossSystem.downedProvidence); - postProv.Add(ModContent.ItemType(), fifteenPercent, 5, 10); // 15% 5-10 Unholy Essence - break; - - case ItemID.DungeonFishingCrate: case ItemID.DungeonFishingCrateHard: - loot.AddIf(() => NPC.downedPlantBoss, ItemID.Ectoplasm, 10, 1, 5); // 10% 1-5 Ectoplasm - loot.AddIf(() => DownedBossSystem.downedPolterghast, ModContent.ItemType(), 10, 1, 5); // 10% 1-5 Necroplasm - break; - - case ItemID.JungleFishingCrate: case ItemID.JungleFishingCrateHard: - loot.Add(ModContent.ItemType(), new Fraction(1, 5), 1, 3); // 20% 1-3 Murky Paste - var postPlant = loot.DefineConditionalDropSet(() => NPC.downedPlantBoss); - postPlant.Add(ModContent.ItemType(), 5, 16, 28); // 20% 16-28 Perennial Ore - postPlant.Add(ModContent.ItemType(), fifteenPercent, 4, 7); // 15% 4-7 Perennial Bar - loot.AddIf(() => NPC.downedGolemBoss, ModContent.ItemType(), 5, 3, 6); // 20% 3-6 Plague Cell Canister - var uelibloom = loot.DefineConditionalDropSet(() => DownedBossSystem.downedProvidence); - uelibloom.Add(ModContent.ItemType(), 5, 16, 28); // 20% 16-28 Uelibloom Ore - uelibloom.Add(ModContent.ItemType(), fifteenPercent, 4, 7); // 15% 4-7 Uelibloom Bar - break; - - case ItemID.FloatingIslandFishingCrate: case ItemID.FloatingIslandFishingCrateHard: - var evilBossTwo = loot.DefineConditionalDropSet(() => DownedBossSystem.downedHiveMind || DownedBossSystem.downedPerforator); - evilBossTwo.Add(ModContent.ItemType(), 5, 16, 28); // 20% 16-28 Aerialite Ore - evilBossTwo.Add(ModContent.ItemType(), fifteenPercent, 4, 7); // 15% 4-7 Aerialite Bar - loot.AddIf(() => Main.hardMode, ModContent.ItemType(), 5, 2, 4); // 20% 2-4 Essence of Sunlight - loot.AddIf(() => NPC.downedMoonlord, ModContent.ItemType(), 5, 16, 28); // 20% 16-28 Exodium Clusters - break; - - case ItemID.FrozenCrate: case ItemID.FrozenCrateHard: - var cryonic = loot.DefineConditionalDropSet(CryonicAvailable); - cryonic.Add(ModContent.ItemType(), 5, 16, 28); // 20% 16-28 Cryonic Ore - cryonic.Add(ModContent.ItemType(), fifteenPercent, 4, 7); // 15% 4-7 Cryonic Bar - loot.AddIf(() => Main.hardMode, ModContent.ItemType(), 5, 2, 4); // 20% 2-4 Essence of Eleum - break; - - case ItemID.LavaCrate: case ItemID.LavaCrateHard: - loot.AddIf(() => Main.hardMode, ModContent.ItemType(), 5, 2, 4); // 20% 2-4 Essence of Havoc - break; - - // Calamity does not touch Oasis Crates yet - case ItemID.OasisCrate: case ItemID.OasisCrateHard: - break; - - // Calamity does not touch Ocean Crates yet - case ItemID.OceanCrate: case ItemID.OceanCrateHard: + RemoveHardmodeOresFromBiomeCrates(loot); + loot.AddHardmodeOresToCrates(HardmodeCrateType.Biome); break; #endregion @@ -525,6 +476,70 @@ private static IItemDropRule FindMoonLordWeapons(ItemLoot loot) } #endregion + #region Fishing Crate Loot Rule Manipulation + private static void RemoveHardmodeOresFromStandardCrates(ItemLoot loot) + { + List rules = loot.Get(false); + + // This is the primary rule which contains every drop + AlwaysAtleastOneSuccessDropRule mainRule = null; + foreach (IItemDropRule rule in rules) + if (rule is AlwaysAtleastOneSuccessDropRule a) + mainRule = a; + if (mainRule is null) + return; + + // Find ones that are supposed to be for the ore and not the other loot + foreach (IItemDropRule rule in mainRule.rules) + { + // Hardmode ores/bars are both nested within *another* nested rule + if (rule is SequentialRulesNotScalingWithLuckRule oreRule) + { + // Confirm that this is for the ore/bar then pop the numerator for the big rule + foreach (IItemDropRule nestedRule in oreRule.rules) + { + if (nestedRule is SequentialRulesNotScalingWithLuckRule s) + { + oreRule.chanceNumerator = 0; + return; + } + } + } + } + } + + private static void RemoveHardmodeOresFromBiomeCrates(ItemLoot loot) + { + List rules = loot.Get(false); + + // This is the primary rule which contains every drop + AlwaysAtleastOneSuccessDropRule mainRule = null; + foreach (IItemDropRule rule in rules) + if (rule is AlwaysAtleastOneSuccessDropRule a) + mainRule = a; + if (mainRule is null) + return; + + // Find ones that are supposed to be for the ore and not the other loot + foreach (IItemDropRule rule in mainRule.rules) + { + // Hardmode ores/bars are both nested within *another* nested rule + if (rule is SequentialRulesNotScalingWithLuckRule oreRule) + { + // Confirm that this is for the ore/bar then pop the numerator for the big rule + foreach (IItemDropRule nestedRule in oreRule.rules) + { + if (nestedRule is OneFromRulesRule o) + { + oreRule.chanceNumerator = 0; + return; + } + } + } + } + } + #endregion + #region Goodie Bag Bat Hook private static void RemoveBatHookFromGoodieBag(ItemLoot loot) { diff --git a/Items/CalamityGlobalItemTooltip.cs b/Items/CalamityGlobalItemTooltip.cs index 9830d5d689..d2fbf35303 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%")); @@ -292,7 +288,7 @@ void AddTooltip(string text) EditTooltipByNum(1, (line) => line.Text += ", including Mighty Wind"); // If Early Hardmode Rework is enabled: Remind users that ores will NOT spawn when an altar is smashed. - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && (item.type == ItemID.Pwnhammer || item.type == ItemID.Hammush)) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && (item.type == ItemID.Pwnhammer || item.type == ItemID.Hammush)) EditTooltipByNum(0, (line) => line.Text += "\nDemon Altars now drop Souls of Night instead of generating ores when destroyed" + "\nHardmode ores now generate after defeating Mechanical Bosses for the first time"); @@ -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/CalamityGlobalItemTweaks.cs b/Items/CalamityGlobalItemTweaks.cs index 107986fa4e..37820cf8f3 100644 --- a/Items/CalamityGlobalItemTweaks.cs +++ b/Items/CalamityGlobalItemTweaks.cs @@ -25,7 +25,6 @@ internal static void LoadTweaks() IItemTweak[] trueMelee = Do(TrueMelee); IItemTweak[] trueMeleeNoSpeed = Do(TrueMeleeNoSpeed); IItemTweak[] pointBlank = Do(PointBlank); - IItemTweak[] autoReuse = Do(AutoReuse); IItemTweak[] nonConsumableBossSummon = Do(MaxStack(1), NotConsumable, UseTimeExact(10)); // SORTING NOTES: @@ -35,7 +34,7 @@ internal static void LoadTweaks() currentTweaks = new SortedDictionary { #region CATEGORY 1: Weapon Balancing - { ItemID.AdamantiteGlaive, Do(AutoReuse, TrueMelee, UseRatio(0.8f), DamageExact(65), ShootSpeedRatio(1.25f)) }, + { ItemID.AdamantiteGlaive, Do(TrueMelee, UseRatio(0.8f), DamageExact(65), ShootSpeedRatio(1.25f)) }, { ItemID.AdamantiteRepeater, Do(PointBlank, UseExact(14)) }, { ItemID.AdamantiteSword, Do(UseTurn, DamageExact(77)) }, { ItemID.AmberStaff, Do(UseTimeExact(15), UseAnimationExact(45), ReuseDelayExact(15)) }, @@ -50,31 +49,31 @@ internal static void LoadTweaks() { ItemID.BeesKnees, Do(PointBlank, DamageExact(24), UseExact(38)) }, { ItemID.Bladetongue, Do(UseTurn, UseRatio(0.8f), DamageExact(120)) }, { ItemID.BlizzardStaff, Do(DamageExact(41), ManaExact(7)) }, - { ItemID.BloodyMachete, Do(AutoReuse, DamageExact(24)) }, + { ItemID.BloodyMachete, Do(DamageExact(24)) }, { ItemID.Blowgun, Do(PointBlank, DamageExact(40)) }, - { ItemID.BluePhaseblade, Do(AutoReuse, UseTurn, DamageExact(32)) }, + { ItemID.BluePhaseblade, Do(UseTurn, DamageExact(32)) }, { ItemID.BluePhasesaber, Do(DamageExact(60)) }, { ItemID.BookofSkulls, Do(ManaExact(12), ShootSpeedExact(5.5f)) }, { ItemID.BookStaff, Do(ManaExact(14)) }, // Tome of Infinite Wisdom { ItemID.Boomstick, Do(PointBlank, DamageExact(11)) }, - { ItemID.BreakerBlade, Do(AutoReuse, UseTurn, DamageExact(97)) }, + { ItemID.BreakerBlade, Do(UseTurn, DamageExact(97)) }, { ItemID.CandyCornRifle, Do(PointBlank, DamageExact(66)) }, - { ItemID.Cascade, Do(AutoReuse, DamageExact(30)) }, + { ItemID.Cascade, Do(DamageExact(30)) }, { ItemID.ChainGuillotines, Do(DamageExact(100)) }, { ItemID.ChainGun, Do(PointBlank, DamageExact(35)) }, - { ItemID.ChainKnife, Do(AutoReuse, DamageRatio(1.34f)) }, // Uses ratios due to remix seed + { ItemID.ChainKnife, Do(DamageRatio(1.34f)) }, // Uses ratios due to remix seed { ItemID.ChlorophyteClaymore, Do(UseMeleeSpeed, DamageExact(176), UseExact(35), UseAnimationExact(45), ShootSpeedExact(22f)) }, - { ItemID.ChlorophytePartisan, Do(AutoReuse, UseMeleeSpeed, UseRatio(0.8f), DamageExact(70)) }, + { ItemID.ChlorophytePartisan, Do(UseMeleeSpeed, UseRatio(0.8f), DamageExact(70)) }, { ItemID.ChlorophyteSaber, Do(UseMeleeSpeed, DamageExact(80), UseExact(10)) }, - { ItemID.ChristmasTreeSword, Do(AutoReuse, UseTurn, UseMeleeSpeed, DamageExact(80), UseExact(30)) }, + { ItemID.ChristmasTreeSword, Do(UseTurn, UseMeleeSpeed, DamageExact(80), UseExact(30)) }, { ItemID.ClingerStaff, Do(DamageExact(63)) }, { ItemID.ClockworkAssaultRifle, Do(PointBlank, DamageExact(21)) }, - { ItemID.CobaltNaginata, Do(AutoReuse, TrueMelee, UseRatio(0.8f), DamageExact(90)) }, + { ItemID.CobaltNaginata, Do(TrueMelee, UseRatio(0.8f), DamageExact(90)) }, { ItemID.CobaltRepeater, Do(PointBlank, UseExact(18)) }, - { ItemID.CobaltSword, Do(UseTurn, DamageExact(80)) }, - { ItemID.Code2, Do(AutoReuse, DamageExact(43)) }, - { ItemID.CorruptYoyo, Do(AutoReuse, DamageExact(20)) }, // Malaise - { ItemID.CrimsonYoyo, Do(AutoReuse, DamageExact(20)) }, // Artery + { ItemID.CobaltSword, Do(DamageExact(80)) }, + { ItemID.Code2, Do(DamageExact(43)) }, + { ItemID.CorruptYoyo, Do(DamageExact(20)) }, // Malaise + { ItemID.CrimsonYoyo, Do(DamageExact(20)) }, // Artery { ItemID.CrystalBullet, Do(DamageExact(8)) }, { ItemID.CrystalDart, Do(DamageExact(20)) }, { ItemID.CrystalSerpent, Do(DamageExact(45)) }, @@ -84,20 +83,20 @@ internal static void LoadTweaks() { ItemID.Cutlass, Do(UseRatio(0.9f), DamageExact(90)) }, { ItemID.DaedalusStormbow, Do(DamageExact(30)) }, { ItemID.DaoofPow, Do(DamageExact(160)) }, - { ItemID.DarkLance, Do(AutoReuse, TrueMelee, DamageExact(45)) }, + { ItemID.DarkLance, Do(TrueMelee, DamageExact(45)) }, { ItemID.DartRifle, Do(PointBlank, DamageExact(58)) }, { ItemID.DayBreak, Do(DamageExact(125), UseExact(20)) }, { ItemID.DD2BetsyBow, Do(DamageExact(42)) }, // Aerial Bane's ridiculous multiplier is removed, so this compensates for that { ItemID.DD2SquireBetsySword, Do(UseMeleeSpeed, DamageExact(150)) }, // Flying Dragon { ItemID.DD2SquireDemonSword, Do(DamageExact(110), UseExact(25)) }, // Brand of the Inferno { ItemID.DeathSickle, Do(UseMeleeSpeed, DamageExact(82), ShootSpeedExact(15f)) }, - { ItemID.DemonBow, Do(PointBlank, DamageExact(12), AutoReuse) }, - { ItemID.DemonScythe, Do(AutoReuse, DamageExact(33)) }, - { ItemID.DyeTradersScimitar, Do(AutoReuse, UseTurn, DamageExact(24)) }, // Exotic Scimitar + { ItemID.DemonBow, Do(PointBlank, DamageExact(12)) }, + { ItemID.DemonScythe, Do(DamageExact(33)) }, + { ItemID.DyeTradersScimitar, Do(UseTurn, DamageExact(24)) }, // Exotic Scimitar { ItemID.ElectrosphereLauncher, Do(DamageExact(44)) }, { ItemID.ElfMelter, Do(ShootSpeedDelta(+5f)) }, { ItemID.EmeraldStaff, Do(DamageExact(27)) }, - { ItemID.EmpressBlade, Do(AutoReuse, DamageExact(60), UseExact(20)) }, // Terraprisma + { ItemID.EmpressBlade, Do(DamageExact(60), UseExact(20)) }, // Terraprisma { ItemID.EnchantedBoomerang, Do(DamageExact(24)) }, { ItemID.EnchantedSword, Do(UseMeleeSpeed, DamageExact(30), ShootSpeedExact(15f)) }, { ItemID.Excalibur, Do(TrueMelee, UseRatio(0.8f), DamageExact(125), UseAnimationExact(45)) }, @@ -109,43 +108,43 @@ internal static void LoadTweaks() { ItemID.Flamarang, Do(DamageExact(40)) }, { ItemID.Flamelash, Do(DamageExact(40)) }, { ItemID.Flamethrower, Do(DamageExact(21), ShootSpeedDelta(+3f)) }, - { ItemID.FlowerofFire, Do(AutoReuse, ManaExact(7), UseRatio(0.88f), DamageRatio(0.65f)) }, // Uses ratios due to remix seed - { ItemID.FlowerofFrost, Do(AutoReuse, ManaExact(7), UseExact(22), DamageExact(70), ShootSpeedExact(14)) }, + { ItemID.FlowerofFire, Do(ManaExact(7), UseRatio(0.88f), DamageRatio(0.65f)) }, // Uses ratios due to remix seed + { ItemID.FlowerofFrost, Do(ManaExact(7), UseExact(22), DamageExact(70), ShootSpeedExact(14)) }, { ItemID.FlyingKnife, Do(DamageExact(53)) }, { ItemID.Frostbrand, Do(UseMeleeSpeed, DamageExact(88)) }, { ItemID.FrostStaff, Do(DamageExact(160), UseExact(37), ShootSpeedExact(20f)) }, // has 1 extra update { ItemID.Gatligator, Do(PointBlank, UseExact(6)) }, { ItemID.GoldenShower, Do(DamageExact(39)) }, - { ItemID.GoldShortsword, Do(AutoReuse, TrueMelee, DamageExact(17)) }, + { ItemID.GoldShortsword, Do(TrueMelee, DamageExact(17)) }, { ItemID.GolemFist, Do(DamageExact(150)) }, - { ItemID.Gradient, Do(AutoReuse, DamageExact(39)) }, - { ItemID.GreenPhaseblade, Do(AutoReuse, UseTurn, DamageExact(32)) }, + { ItemID.Gradient, Do(DamageExact(39)) }, + { ItemID.GreenPhaseblade, Do(UseTurn, DamageExact(32)) }, { ItemID.GreenPhasesaber, Do(DamageExact(60)) }, { ItemID.GrenadeLauncher, Do(DamageExact(112)) }, - { ItemID.Gungnir, Do(AutoReuse, TrueMelee, UseRatio(0.8f), DamageExact(92), ShootSpeedRatio(1.25f)) }, + { ItemID.Gungnir, Do(TrueMelee, UseRatio(0.8f), DamageExact(92), ShootSpeedRatio(1.25f)) }, { ItemID.HallowedRepeater, Do(PointBlank, UseExact(12)) }, { ItemID.Handgun, Do(PointBlank, UseExact(22), DamageExact(36)) }, { ItemID.HellwingBow, Do(PointBlank, DamageExact(16)) }, { ItemID.HighVelocityBullet, Do(DamageExact(13)) }, - { ItemID.HiveFive, Do(AutoReuse, DamageExact(26)) }, - { ItemID.HornetStaff, Do(AutoReuse, DamageExact(18), UseExact(30)) }, + { ItemID.HiveFive, Do(DamageExact(26)) }, + { ItemID.HornetStaff, Do(DamageExact(18), UseExact(30)) }, { ItemID.IceBlade, Do(UseMeleeSpeed) }, { ItemID.IceBoomerang, Do(UseExact(25), ShootSpeedExact(9)) }, { ItemID.IceRod, Do(UseExact(6), DamageExact(30), ShootSpeedExact(20)) }, - { ItemID.IceSickle, Do(AutoReuse, UseMeleeSpeed, DamageExact(75), ShootSpeedExact(20f)) }, + { ItemID.IceSickle, Do(UseMeleeSpeed, DamageExact(75), ShootSpeedExact(20f)) }, { ItemID.IchorArrow, Do(DamageExact(13)) }, { ItemID.IchorBullet, Do(DamageExact(11)) }, - { ItemID.ImpStaff, Do(AutoReuse, UseExact(30), DamageExact(25)) }, + { ItemID.ImpStaff, Do(UseExact(30), DamageExact(25)) }, { ItemID.InfernoFork, Do(DamageExact(99), ShootSpeedExact(11)) }, { ItemID.InfluxWaver, Do(UseMeleeSpeed, DamageExact(80), UseExact(25)) }, - { ItemID.IronShortsword, Do(AutoReuse, TrueMelee, DamageExact(10)) }, + { ItemID.IronShortsword, Do(TrueMelee, DamageExact(10)) }, { ItemID.Keybrand, Do(UseTurn) }, - { ItemID.Kraken, Do(AutoReuse, DamageExact(85)) }, { ItemID.KOCannon, Do(DamageRatio(2.65f)) }, // Uses ratios due to remix seed + { ItemID.Kraken, Do(DamageExact(85)) }, { ItemID.LaserMachinegun, Do(DamageExact(49)) }, { ItemID.LaserRifle, Do(DamageExact(46), UseExact(10), ManaExact(4)) }, { ItemID.LastPrism, Do(DamageExact(57), ManaExact(10)) }, - { ItemID.LeadShortsword, Do(AutoReuse, TrueMelee, DamageExact(11)) }, + { ItemID.LeadShortsword, Do(TrueMelee, DamageExact(11)) }, { ItemID.LightDisc, Do(DamageExact(128), ShootSpeedExact(18)) }, { ItemID.LunarFlareBook, Do(DamageExact(120)) }, { ItemID.MagicalHarp, Do(DamageExact(50), ShootSpeedExact(12f)) }, @@ -159,57 +158,57 @@ internal static void LoadTweaks() { ItemID.MiniNukeI, Do(DamageExact(90)) }, { ItemID.MiniNukeII, Do(DamageExact(90)) }, { ItemID.Minishark, Do(PointBlank, DamageExact(4)) }, - { ItemID.MoltenFury, Do(PointBlank, UseExact(29), AutoReuse) }, + { ItemID.MoltenFury, Do(PointBlank, UseExact(29)) }, { ItemID.MonkStaffT1, Do(TrueMeleeNoSpeed, DamageExact(83)) }, // Sleepy Octopod - { ItemID.MonkStaffT2, Do(AutoReuse, TrueMelee, DamageExact(90)) }, // Ghastly Glaive + { ItemID.MonkStaffT2, Do(TrueMelee, DamageExact(90)) }, // Ghastly Glaive { ItemID.MonkStaffT3, Do(DamageExact(225)) }, // Sky Dragon's Fury { ItemID.MoonlordBullet, Do(DamageExact(19)) }, // Luminite Bullet { ItemID.MoonlordTurretStaff, Do(DamageExact(50), UseExact(15)) }, //Lunar Portal Staff { ItemID.Muramasa, Do(CritDelta(+20)) }, - { ItemID.MushroomSpear, Do(AutoReuse, TrueMelee, UseRatio(0.8f), DamageExact(100)) }, + { ItemID.MushroomSpear, Do(TrueMelee, UseRatio(0.8f), DamageExact(100)) }, { ItemID.Musket, Do(PointBlank, DamageExact(22)) }, - { ItemID.MythrilHalberd, Do(AutoReuse, TrueMelee, UseRatio(0.8f), DamageExact(95), ShootSpeedRatio(1.25f)) }, + { ItemID.MythrilHalberd, Do(TrueMelee, UseRatio(0.8f), DamageExact(95), ShootSpeedRatio(1.25f)) }, { ItemID.MythrilRepeater, Do(PointBlank, UseExact(16)) }, { ItemID.MythrilSword, Do(UseTurn, DamageExact(100)) }, { ItemID.NettleBurst, Do(ManaExact(10), DamageExact(70)) }, { ItemID.NightsEdge, Do(TrueMelee, DamageExact(45)) }, - { ItemID.NorthPole, Do(AutoReuse, UseMeleeSpeed) }, - { ItemID.OrangePhaseblade, Do(AutoReuse, UseTurn, DamageExact(32)) }, + { ItemID.NorthPole, Do(UseMeleeSpeed) }, + { ItemID.OrangePhaseblade, Do(UseTurn, DamageExact(32)) }, { ItemID.OrangePhasesaber, Do(DamageExact(60)) }, - { ItemID.OrichalcumHalberd, Do(AutoReuse, TrueMelee, UseRatio(0.8f), DamageExact(98), ShootSpeedRatio(1.25f)) }, + { ItemID.OrichalcumHalberd, Do(TrueMelee, UseRatio(0.8f), DamageExact(98), ShootSpeedRatio(1.25f)) }, { ItemID.OrichalcumRepeater, Do(PointBlank, DamageExact(48)) }, { ItemID.OrichalcumSword, Do(UseTurn, DamageExact(82)) }, { ItemID.PainterPaintballGun, Do(PointBlank, DamageExact(8)) }, { ItemID.PaladinsHammer, Do(DamageExact(100), ShootSpeedExact(23)) }, - { ItemID.PalladiumPike, Do(AutoReuse, TrueMelee, UseRatio(0.8f), DamageExact(96)) }, + { ItemID.PalladiumPike, Do(TrueMelee, UseRatio(0.8f), DamageExact(96)) }, { ItemID.PalladiumRepeater, Do(PointBlank, DamageExact(45)) }, - { ItemID.PalladiumSword, Do(UseTurn, DamageExact(100)) }, - { ItemID.PearlwoodBow, Do(AutoReuse, PointBlank, DamageExact(20), UseDelta(+8), ShootSpeedDelta(+3.4f), KnockbackDelta(+1f)) }, + { ItemID.PalladiumSword, Do(DamageExact(100)) }, + { ItemID.PearlwoodBow, Do(PointBlank, DamageExact(20), UseDelta(+8), ShootSpeedDelta(+3.4f), KnockbackDelta(+1f)) }, { ItemID.PearlwoodSword, Do(UseTurn, DamageExact(45)) }, { ItemID.PewMaticHorn, Do(DamageExact(25), ShootSpeedExact(15)) }, { ItemID.Phantasm, Do(PointBlank, DamageExact(48)) }, - { ItemID.PhoenixBlaster, Do(AutoReuse, PointBlank, UseExact(18)) }, + { ItemID.PhoenixBlaster, Do(PointBlank, UseExact(18)) }, { ItemID.PiranhaGun, Do(DamageExact(48)) }, { ItemID.PlatinumBow, Do(PointBlank, DamageExact(12)) }, - { ItemID.PlatinumShortsword, Do(AutoReuse, TrueMelee, DamageExact(18)) }, + { ItemID.PlatinumShortsword, Do(TrueMelee, DamageExact(18)) }, { ItemID.PoisonStaff, Do(DamageExact(57)) }, { ItemID.PossessedHatchet, Do(DamageExact(135)) }, { ItemID.PsychoKnife, Do(UseTurn, UseExact(11), DamageExact(255)) }, { ItemID.PurpleClubberfish, Do(UseTurn, KnockbackExact(10f)) }, - { ItemID.PurplePhaseblade, Do(AutoReuse, UseTurn, DamageExact(32)) }, + { ItemID.PurplePhaseblade, Do(UseTurn, DamageExact(32)) }, { ItemID.PurplePhasesaber, Do(DamageExact(60)) }, - { ItemID.PygmyStaff, Do(AutoReuse, UseExact(20), DamageExact(70)) }, + { ItemID.PygmyStaff, Do(UseExact(20), DamageExact(70)) }, { ItemID.QuadBarrelShotgun, Do(PointBlank, DamageExact(11)) }, { ItemID.RainbowRod, Do(DamageExact(35), ManaExact(15)) }, - { ItemID.Rally, Do(AutoReuse, DamageExact(18)) }, + { ItemID.Rally, Do(DamageExact(18)) }, { ItemID.RainbowGun, Do(DamageExact(60), ManaExact(40)) }, - { ItemID.RavenStaff, Do(AutoReuse, UseExact(20), DamageExact(36)) }, + { ItemID.RavenStaff, Do(UseExact(20), DamageExact(36)) }, { ItemID.RazorbladeTyphoon, Do(DamageExact(103)) }, { ItemID.Razorpine, Do(DamageExact(40)) }, - { ItemID.RedPhaseblade, Do(AutoReuse, UseTurn, DamageExact(32)) }, + { ItemID.RedPhaseblade, Do(UseTurn, DamageExact(32)) }, { ItemID.RedPhasesaber, Do(DamageExact(60)) }, { ItemID.RedRyder, Do(PointBlank, DamageExact(24)) }, - { ItemID.RedsYoyo, Do(AutoReuse, DamageExact(48)) }, // Red's Throw and Valkyrie Yoyo have the same stats + { ItemID.RedsYoyo, Do(DamageExact(48)) }, // Red's Throw and Valkyrie Yoyo have the same stats { ItemID.RocketLauncher, Do(DamageExact(70)) }, { ItemID.Sandgun, Do(PointBlank, DamageExact(22), UseExact(20)) }, { ItemID.SapphireStaff, Do(DamageExact(25)) }, @@ -219,67 +218,67 @@ internal static void LoadTweaks() { ItemID.ShadowFlameHexDoll, Do(DamageExact(40), ShootSpeedExact(30)) }, { ItemID.ShadowFlameKnife, Do(DamageExact(70)) }, { ItemID.SharpTears, Do(DamageExact(49)) }, // Blood Thorn - { ItemID.Shotgun, Do(PointBlank, DamageExact(36), AutoReuse) }, + { ItemID.Shotgun, Do(PointBlank, DamageExact(36)) }, { ItemID.Shroomerang, Do(ShootSpeedExact(11)) }, { ItemID.SilverBullet, Do(DamageExact(8)) }, - { ItemID.SilverShortsword, Do(AutoReuse, TrueMelee, DamageExact(14)) }, + { ItemID.SilverShortsword, Do(TrueMelee, DamageExact(14)) }, { ItemID.SkyFracture, Do(DamageExact(54), ShootSpeedExact(30f)) }, { ItemID.SlapHand, Do(UseTurn, DamageExact(120)) }, - { ItemID.Smolstar, Do(DamageExact(9), AutoReuse, UseExact(25)) }, // Blade Staff + { ItemID.Smolstar, Do(DamageExact(9), UseExact(25)) }, // Blade Staff { ItemID.SniperRifle, Do(PointBlank, DamageExact(215)) }, { ItemID.SolarEruption, Do(DamageExact(157)) }, { ItemID.SoulDrain, Do(DamageExact(38)) }, // Life Drain { ItemID.SpaceGun, Do(DamageExact(25)) }, - { ItemID.Spear, Do(AutoReuse, TrueMelee, DamageExact(14)) }, + { ItemID.Spear, Do(TrueMelee, DamageExact(14)) }, { ItemID.SpectreStaff, Do(DamageExact(78)) }, { ItemID.SpiritFlame, Do(UseExact(20), ManaExact(11), ShootSpeedExact(2f)) }, { ItemID.StaffofEarth, Do(DamageExact(150)) }, { ItemID.StarCannon, Do(DamageExact(25)) }, - { ItemID.StardustDragonStaff, Do(AutoReuse, DamageExact(20), UseExact(19)) }, - { ItemID.StormTigerStaff, Do(AutoReuse, DamageExact(49), UseExact(20)) }, // Desert Tiger Staff - { ItemID.StylistKilLaKillScissorsIWish, Do(AutoReuse, UseTurn, DamageExact(18)) }, // Stylish Scissors + { ItemID.StardustDragonStaff, Do(DamageExact(20), UseExact(19)) }, + { ItemID.StormTigerStaff, Do(DamageExact(49), UseExact(20)) }, // Desert Tiger Staff + { ItemID.StylistKilLaKillScissorsIWish, Do(UseTurn, DamageExact(18)) }, // Stylish Scissors { ItemID.Stynger, Do(DamageExact(75)) }, - { ItemID.Swordfish, Do(AutoReuse, TrueMelee, DamageExact(24)) }, + { ItemID.Swordfish, Do(TrueMelee, DamageExact(24)) }, { ItemID.TacticalShotgun, Do(PointBlank, DamageExact(41)) }, - { ItemID.TaxCollectorsStickOfDoom, Do(AutoReuse, UseTurn, UseRatio(0.8f), DamageExact(70)) }, // Classy Cane - { ItemID.TendonBow, Do(PointBlank, DamageExact(17), AutoReuse) }, + { ItemID.TaxCollectorsStickOfDoom, Do(UseTurn, UseRatio(0.8f), DamageExact(70)) }, // Classy Cane + { ItemID.TendonBow, Do(PointBlank, DamageExact(17)) }, { ItemID.TerraBlade, Do(DamageExact(122)) }, // Vanilla damage 190. After fixing iframes so yoyo and shots can hit simultaneously, // Terrarian is extremely overpowered and requires a heavy nerf. - { ItemID.Terrarian, Do(AutoReuse, DamageExact(86)) }, - { ItemID.TheEyeOfCthulhu, Do(AutoReuse, DamageExact(90)) }, - { ItemID.TheRottedFork, Do(AutoReuse, TrueMelee, DamageExact(20)) }, - { ItemID.TheUndertaker, Do(PointBlank, AutoReuse, DamageExact(15)) }, - { ItemID.ThunderSpear, Do(AutoReuse, UseMeleeSpeed) }, // Storm Spear + { ItemID.Terrarian, Do(DamageExact(86)) }, + { ItemID.TheEyeOfCthulhu, Do(DamageExact(90)) }, + { ItemID.TheRottedFork, Do(TrueMelee, DamageExact(20)) }, + { ItemID.TheUndertaker, Do(PointBlank, DamageExact(15)) }, + { ItemID.ThunderSpear, Do(UseMeleeSpeed) }, // Storm Spear { ItemID.ThunderStaff, Do(DamageExact(18)) }, //Thunder Zapper { ItemID.TitaniumRepeater, Do(PointBlank, DamageExact(52)) }, { ItemID.TitaniumSword, Do(UseTurn, DamageExact(77)) }, - { ItemID.TitaniumTrident, Do(AutoReuse, TrueMelee, UseRatio(0.8f), DamageExact(72), ShootSpeedRatio(1.25f)) }, + { ItemID.TitaniumTrident, Do(TrueMelee, UseRatio(0.8f), DamageExact(72), ShootSpeedRatio(1.25f)) }, { ItemID.TopazStaff, Do(ManaExact(2)) }, { ItemID.Toxikarp, Do(UseTimeExact(7), UseAnimationExact(14)) }, - { ItemID.Trident, Do(AutoReuse, TrueMelee, DamageExact(20)) }, + { ItemID.Trident, Do(TrueMelee, DamageExact(20)) }, { ItemID.Trimarang, Do(DamageExact(24)) }, { ItemID.TrueExcalibur, Do(TrueMelee, DamageExact(107)) }, { ItemID.TrueNightsEdge, Do(DamageExact(105)) }, { ItemID.Tsunami, Do(PointBlank, DamageExact(49)) }, { ItemID.TungstenBullet, Do(DamageExact(8)) }, - { ItemID.TungstenShortsword, Do(AutoReuse, TrueMelee, DamageExact(15)) }, + { ItemID.TungstenShortsword, Do(TrueMelee, DamageExact(15)) }, { ItemID.UnholyArrow, Do(DamageExact(11)) }, { ItemID.UnholyTrident, Do(ManaRatio(0.78f), DamageRatio(0.91f)) }, // Uses ratios due to remix seed { ItemID.VampireKnives, Do(DamageExact(38)) }, - { ItemID.ValkyrieYoyo, Do(AutoReuse, DamageExact(48)) }, // Red's Throw and Valkyrie Yoyo have the same stats + { ItemID.ValkyrieYoyo, Do(DamageExact(48)) }, // Red's Throw and Valkyrie Yoyo have the same stats { ItemID.VenomStaff, Do(DamageExact(55)) }, { ItemID.VenusMagnum, Do(PointBlank, DamageExact(65)) }, { ItemID.WaspGun, Do(UseExact(11), DamageExact(58)) }, { ItemID.WaterBolt, Do(DamageExact(23)) }, - { ItemID.WhitePhaseblade, Do(AutoReuse, UseTurn, DamageExact(32)) }, + { ItemID.WhitePhaseblade, Do(UseTurn, DamageExact(32)) }, { ItemID.WhitePhasesaber, Do(DamageExact(60)) }, { ItemID.WoodenBoomerang, Do(DamageExact(16), Value(Item.sellPrice(copper: 20))) }, - { ItemID.Yelets, Do(AutoReuse, DamageExact(53)) }, - { ItemID.YellowPhaseblade, Do(AutoReuse, UseTurn, DamageExact(32)) }, + { ItemID.Yelets, Do(DamageExact(53)) }, + { ItemID.YellowPhaseblade, Do(UseTurn, DamageExact(32)) }, { ItemID.YellowPhasesaber, Do(DamageExact(60)) }, { ItemID.Zenith, Do(DamageExact(210)) }, - { ItemID.ZombieArm, Do(AutoReuse, UseTurn, KnockbackExact(12f)) }, + { ItemID.ZombieArm, Do(UseTurn, KnockbackExact(12f)) }, #endregion #region CATEGORY 2: Defense Balancing @@ -418,12 +417,12 @@ internal static void LoadTweaks() #region CATEGORY 4: True Melee support { ItemID.Arkhalis, trueMeleeNoSpeed }, - { ItemID.CopperShortsword, Do(AutoReuse, TrueMelee) }, - { ItemID.Gladius, Do(AutoReuse, TrueMelee) }, + { ItemID.CopperShortsword, trueMelee }, + { ItemID.Gladius, trueMelee }, { ItemID.HallowJoustingLance, trueMelee }, { ItemID.JoustingLance, trueMelee }, { ItemID.NebulaChainsaw, trueMeleeNoSpeed }, - { ItemID.ObsidianSwordfish, Do(AutoReuse, TrueMelee) }, + { ItemID.ObsidianSwordfish, trueMelee }, { ItemID.PiercingStarlight, trueMelee }, // Starlight { ItemID.Ruler, trueMelee }, { ItemID.ShadowJoustingLance, trueMelee }, @@ -431,7 +430,7 @@ internal static void LoadTweaks() { ItemID.StardustChainsaw, trueMeleeNoSpeed }, { ItemID.Terragrim, trueMeleeNoSpeed }, { ItemID.TheHorsemansBlade, trueMelee }, - { ItemID.TinShortsword, Do(AutoReuse, TrueMelee) }, + { ItemID.TinShortsword, trueMelee }, { ItemID.VortexChainsaw, trueMeleeNoSpeed }, #endregion @@ -455,7 +454,7 @@ internal static void LoadTweaks() { ItemID.OnyxBlaster, pointBlank }, { ItemID.PalmWoodBow, pointBlank }, { ItemID.PulseBow, pointBlank }, - { ItemID.Revolver, Do(PointBlank, AutoReuse) }, + { ItemID.Revolver, pointBlank }, { ItemID.RichMahoganyBow, pointBlank }, { ItemID.SDMG, pointBlank }, { ItemID.ShadewoodBow, pointBlank }, @@ -470,90 +469,53 @@ internal static void LoadTweaks() #endregion #region CATEGORY 6: Summoner Quality of Life - { ItemID.AbigailsFlower, autoReuse }, - { ItemID.BabyBirdStaff, Do(AutoReuse, UseExact(35)) }, // Finch Staff - { ItemID.BlandWhip, autoReuse }, // Leather Whip - { ItemID.BoneWhip, autoReuse }, // Spinal Tap - { ItemID.CoolWhip, autoReuse }, - { ItemID.DD2BallistraTowerT1Popper, autoReuse }, // Ballista Tier 1 - { ItemID.DD2BallistraTowerT2Popper, Do(AutoReuse, UseExact(25)) }, // Ballista Tier 2 - { ItemID.DD2BallistraTowerT3Popper, Do(AutoReuse, UseExact(20)) }, // Ballista Tier 3 - { ItemID.DD2ExplosiveTrapT1Popper, autoReuse }, // Explosive Trap Tier 1 - { ItemID.DD2ExplosiveTrapT2Popper, Do(AutoReuse, UseExact(25)) }, // Explosive Trap Tier 2 - { ItemID.DD2ExplosiveTrapT3Popper, Do(AutoReuse, UseExact(20)) }, // Explosive Trap Tier 3 - { ItemID.DD2FlameburstTowerT1Popper, autoReuse }, // Flameburst Tier 1 - { ItemID.DD2FlameburstTowerT2Popper, Do(AutoReuse, UseExact(25)) }, // Flameburst Tier 2 - { ItemID.DD2FlameburstTowerT3Popper, Do(AutoReuse, UseExact(20)) }, // Flameburst Tier 3 - { ItemID.DD2LightningAuraT1Popper, autoReuse }, // Lightning Aura Tier 1 - { ItemID.DD2LightningAuraT2Popper, Do(AutoReuse, UseExact(25)) }, // Lightning Aura Tier 2 - { ItemID.DD2LightningAuraT3Popper, Do(AutoReuse, UseExact(20)) }, // Lightning Aura Tier 3 - { ItemID.DeadlySphereStaff, Do(AutoReuse, UseExact(20)) }, - { ItemID.FireWhip, autoReuse }, // Firecracker - { ItemID.FlinxStaff, Do(AutoReuse, UseExact(35)) }, - { ItemID.MaceWhip, autoReuse }, // Morning Star - { ItemID.OpticStaff, Do(AutoReuse, UseExact(25)) }, - { ItemID.PirateStaff, Do(AutoReuse, UseExact(25)) }, + { ItemID.BabyBirdStaff, Do(UseExact(35)) }, // Finch Staff + { ItemID.DD2BallistraTowerT2Popper, Do(UseExact(25)) }, // Ballista Tier 2 + { ItemID.DD2BallistraTowerT3Popper, Do(UseExact(20)) }, // Ballista Tier 3 + { ItemID.DD2ExplosiveTrapT2Popper, Do(UseExact(25)) }, // Explosive Trap Tier 2 + { ItemID.DD2ExplosiveTrapT3Popper, Do(UseExact(20)) }, // Explosive Trap Tier 3 + { ItemID.DD2FlameburstTowerT2Popper, Do(UseExact(25)) }, // Flameburst Tier 2 + { ItemID.DD2FlameburstTowerT3Popper, Do(UseExact(20)) }, // Flameburst Tier 3 + { ItemID.DD2LightningAuraT2Popper, Do(UseExact(25)) }, // Lightning Aura Tier 2 + { ItemID.DD2LightningAuraT3Popper, Do(UseExact(20)) }, // Lightning Aura Tier 3 + { ItemID.DeadlySphereStaff, Do(UseExact(20)) }, + { ItemID.FlinxStaff, Do(UseExact(35)) }, + { ItemID.OpticStaff, Do(UseExact(25)) }, + { ItemID.PirateStaff, Do(UseExact(25)) }, { ItemID.QueenSpiderStaff, Do(UseExact(25)) }, { ItemID.RainbowCrystalStaff, Do(UseExact(15)) }, - { ItemID.RainbowWhip, autoReuse }, // Kaleidoscope - { ItemID.SanguineStaff, Do(AutoReuse, UseExact(25)) }, - { ItemID.ScytheWhip, autoReuse }, // Dark Harvest - { ItemID.SlimeStaff, Do(AutoReuse, UseExact(30)) }, - { ItemID.SpiderStaff, Do(AutoReuse, UseExact(25)) }, + { ItemID.SanguineStaff, Do(UseExact(25)) }, + { ItemID.SlimeStaff, Do(UseExact(30)) }, + { ItemID.SpiderStaff, Do(UseExact(25)) }, { ItemID.StaffoftheFrostHydra, Do(UseExact(20)) }, - { ItemID.StardustCellStaff, Do(AutoReuse, UseExact(20)) }, - { ItemID.SwordWhip, autoReuse }, // Durendal - { ItemID.TempestStaff, Do(AutoReuse, UseExact(20)) }, - { ItemID.ThornWhip, autoReuse }, // Snapthorn - { ItemID.VampireFrogStaff, Do(AutoReuse, UseExact(30)) }, - { ItemID.XenoStaff, Do(AutoReuse, UseExact(20)) }, + { ItemID.StardustCellStaff, Do(UseExact(20)) }, + { ItemID.TempestStaff, Do(UseExact(20)) }, + { ItemID.VampireFrogStaff, Do(UseExact(30)) }, + { ItemID.XenoStaff, Do(UseExact(20)) }, #endregion - #region CATEGORY 7: Other Quality of Life (AutoReuse / UseTurn) - { ItemID.Amarok, autoReuse }, - { ItemID.BatBat, autoReuse }, - { ItemID.BladeofGrass, Do(AutoReuse, UseTurn) }, - { ItemID.BloodButcherer, Do(AutoReuse, UseTurn) }, - { ItemID.BoneSword, Do(AutoReuse, UseTurn) }, - { ItemID.BorealWoodSword, Do(AutoReuse, UseTurn) }, - { ItemID.CactusSword, Do(AutoReuse, UseTurn) }, - { ItemID.CandyCaneSword, Do(AutoReuse, UseTurn) }, - { ItemID.Chik, autoReuse }, - { ItemID.Code1, autoReuse }, - { ItemID.CopperBroadsword, Do(AutoReuse, UseTurn) }, - { ItemID.EbonwoodSword, Do(AutoReuse, UseTurn) }, - { ItemID.FieryGreatsword, Do(AutoReuse, UseTurn) }, // Volcano - { ItemID.FormatC, autoReuse }, - { ItemID.GoldBroadsword, Do(AutoReuse, UseTurn) }, - { ItemID.HelFire, autoReuse }, - { ItemID.IronBroadsword, Do(AutoReuse, UseTurn) }, - { ItemID.JungleYoyo, autoReuse }, // Amazon - { ItemID.LifeCrystal, autoReuse }, - { ItemID.LeadBroadsword, Do(AutoReuse, UseTurn) }, - { ItemID.LifeFruit, autoReuse }, - { ItemID.LightsBane, Do(AutoReuse, UseTurn) }, - { ItemID.ManaCrystal, autoReuse }, - { ItemID.PalmWoodSword, Do(AutoReuse, UseTurn) }, - { ItemID.PaperAirplaneA, autoReuse }, - { ItemID.PaperAirplaneB, autoReuse }, // White Paper Airplane - { ItemID.PlatinumBroadsword, Do(AutoReuse, UseTurn) }, - { ItemID.RichMahoganySword, Do(AutoReuse, UseTurn) }, - { ItemID.ShadewoodSword, Do(AutoReuse, UseTurn) }, - { ItemID.SilverBroadsword, Do(AutoReuse, UseTurn) }, - { ItemID.Starfury, autoReuse }, - { ItemID.TentacleSpike, autoReuse }, - { ItemID.TinBroadsword, Do(AutoReuse, UseTurn) }, - { ItemID.TragicUmbrella, autoReuse }, - { ItemID.TungstenBroadsword, Do(AutoReuse, UseTurn) }, - { ItemID.Umbrella, autoReuse }, - { ItemID.Valor, autoReuse }, - { ItemID.WandofFrosting, autoReuse }, - { ItemID.WandofSparking, autoReuse }, - { ItemID.WeatherPain, autoReuse }, - { ItemID.WoodenSword, Do(AutoReuse, UseTurn) }, - { ItemID.WoodYoyo, autoReuse }, - { ItemID.ZapinatorGray, autoReuse }, - { ItemID.ZapinatorOrange, autoReuse }, + #region CATEGORY 7: UseTurn + { ItemID.BladeofGrass, Do(UseTurn) }, + { ItemID.BloodButcherer, Do(UseTurn) }, + { ItemID.BoneSword, Do(UseTurn) }, + { ItemID.BorealWoodSword, Do(UseTurn) }, + { ItemID.CactusSword, Do(UseTurn) }, + { ItemID.CandyCaneSword, Do(UseTurn) }, + { ItemID.CopperBroadsword, Do(UseTurn) }, + { ItemID.EbonwoodSword, Do(UseTurn) }, + { ItemID.FieryGreatsword, Do(UseTurn) }, // Volcano + { ItemID.GoldBroadsword, Do(UseTurn) }, + { ItemID.IronBroadsword, Do(UseTurn) }, + { ItemID.LeadBroadsword, Do(UseTurn) }, + { ItemID.LightsBane, Do(UseTurn) }, + { ItemID.PalmWoodSword, Do(UseTurn) }, + { ItemID.PlatinumBroadsword, Do(UseTurn) }, + { ItemID.RichMahoganySword, Do(UseTurn) }, + { ItemID.ShadewoodSword, Do(UseTurn) }, + { ItemID.SilverBroadsword, Do(UseTurn) }, + { ItemID.TinBroadsword, Do(UseTurn) }, + { ItemID.TungstenBroadsword, Do(UseTurn) }, + { ItemID.WoodenSword, Do(UseTurn) }, #endregion #region CATEGORY 8: Non-consumable Quality of Life @@ -690,19 +652,6 @@ public void ApplyTweak(Item it) internal static IItemTweak AttackSpeedRatio(float f) => new AttackSpeedRatioRule(f); #endregion - #region Auto Reuse - internal class AutoReuseRule : IItemTweak - { - internal readonly bool flag = true; - - public AutoReuseRule(bool ar) => flag = ar; - public bool AppliesTo(Item it) => IsUsable(it); - public void ApplyTweak(Item it) => it.autoReuse = flag; - } - internal static IItemTweak AutoReuse => new AutoReuseRule(true); - internal static IItemTweak NoAutoReuse => new AutoReuseRule(false); - #endregion - #region Axe Power // Uses the values shown by Terraria, which are multiplied by 5, not the internal values internal class AxePowerRule : IItemTweak 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/Fishing/AstralCatches/AstralCrate.cs b/Items/Fishing/AstralCatches/AstralCrate.cs index 690c4c8e8b..40ed274c6a 100644 --- a/Items/Fishing/AstralCatches/AstralCrate.cs +++ b/Items/Fishing/AstralCatches/AstralCrate.cs @@ -1,16 +1,6 @@ -using CalamityMod.Items.Accessories; -using CalamityMod.Items.Critters; -using CalamityMod.Items.Materials; -using CalamityMod.Items.Placeables.Ores; -using CalamityMod.Items.Potions; -using CalamityMod.Items.Weapons.Magic; -using CalamityMod.Items.Weapons.Melee; -using CalamityMod.Items.Weapons.Ranged; -using CalamityMod.Items.Weapons.Rogue; -using CalamityMod.Items.Weapons.Summon; +using CalamityMod.Items.Materials; using CalamityMod.Tiles.Astral; using Terraria; -using Terraria.GameContent.ItemDropRules; using Terraria.ID; using Terraria.ModLoader; @@ -29,18 +19,11 @@ public override void SetStaticDefaults() public override void SetDefaults() { + Item.DefaultToPlaceableTile(ModContent.TileType()); Item.width = 32; Item.height = 32; - Item.maxStack = 9999; - Item.consumable = true; - Item.rare = ItemRarityID.Green; Item.value = Item.sellPrice(gold: 1); - Item.createTile = ModContent.TileType(); - Item.useTurn = true; - Item.autoReuse = true; - Item.useAnimation = 15; - Item.useTime = 10; - Item.useStyle = ItemUseStyleID.Swing; + Item.rare = ItemRarityID.Green; } public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.ItemGroup itemGroup) @@ -51,48 +34,14 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite public override bool CanRightClick() => true; public override void ModifyItemLoot(ItemLoot itemLoot) { - var postAstrumAureus = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedAstrumAureus); - var postAstrumDeus = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedAstrumDeus); - - // Materials - itemLoot.Add(ModContent.ItemType(), 1, 5, 10); - itemLoot.Add(ItemID.FallenStar, 1, 5, 10); - itemLoot.Add(ItemID.Meteorite, 5, 10, 20); - itemLoot.Add(ItemID.MeteoriteBar, 10, 1, 3); - - postAstrumAureus.Add(ModContent.ItemType(), 5, 2, 5); - postAstrumDeus.Add(ModContent.ItemType(), 5, 10, 20); - postAstrumDeus.Add(ModContent.ItemType(), 10, 1, 3); - postAstrumDeus.Add(ModContent.ItemType(), 4, 5, 10); - - // Weapons (and Starburster Core) - postAstrumAureus.Add(new OneFromOptionsDropRule(10, 1, - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType() - )); - - // Pet - itemLoot.Add(ModContent.ItemType(), 10); - - // Bait - itemLoot.Add(ModContent.ItemType(), 5, 1, 3); - itemLoot.Add(ItemID.EnchantedNightcrawler, 5, 1, 3); - itemLoot.Add(ModContent.ItemType(), 5, 1, 3); - itemLoot.Add(ItemID.Firefly, 3, 1, 3); + // 4-10 Starblight Soot @ 50% + // This is our equivalent to Crystal Shards/Ichor + itemLoot.Add(ModContent.ItemType(), 2, 4, 10); - // Potions - postAstrumAureus.Add(ModContent.ItemType(), 10, 1, 3); - postAstrumAureus.Add(ModContent.ItemType(), 10, 1, 3); - itemLoot.AddCratePotionRules(); + // Astrophage @ 5% + itemLoot.Add(ModContent.ItemType(), 20); - // Money - itemLoot.Add(ItemID.SilverCoin, 1, 10, 90); - itemLoot.Add(ItemID.GoldCoin, 2, 1, 5); + itemLoot.AddBiomeCrateLootRules(); } } } diff --git a/Items/Fishing/AstralCatches/MonolithCrate.cs b/Items/Fishing/AstralCatches/MonolithCrate.cs index 060d03675b..726d74743f 100644 --- a/Items/Fishing/AstralCatches/MonolithCrate.cs +++ b/Items/Fishing/AstralCatches/MonolithCrate.cs @@ -1,5 +1,4 @@ -using CalamityMod.Items.Critters; -using CalamityMod.Tiles.Astral; +using CalamityMod.Tiles.Astral; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -17,18 +16,11 @@ public override void SetStaticDefaults() public override void SetDefaults() { + Item.DefaultToPlaceableTile(ModContent.TileType()); Item.width = 32; Item.height = 32; - Item.maxStack = 9999; - Item.consumable = true; - Item.rare = ItemRarityID.Green; Item.value = Item.sellPrice(gold: 1); - Item.createTile = ModContent.TileType(); - Item.useTurn = true; - Item.autoReuse = true; - Item.useAnimation = 15; - Item.useTime = 10; - Item.useStyle = ItemUseStyleID.Swing; + Item.rare = ItemRarityID.Green; } public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.ItemGroup itemGroup) @@ -39,27 +31,10 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite public override bool CanRightClick() => true; public override void ModifyItemLoot(ItemLoot itemLoot) { - // Materials - itemLoot.Add(ItemID.FallenStar, 1, 5, 10); - itemLoot.Add(ItemID.Meteorite, 5, 10, 20); - itemLoot.Add(ItemID.MeteoriteBar, 10, 1, 3); - - // Pet - itemLoot.Add(ModContent.ItemType(), 10); - - // Bait - itemLoot.Add(ModContent.ItemType(), 5, 1, 3); - itemLoot.Add(ItemID.EnchantedNightcrawler, 5, 1, 3); - itemLoot.Add(ModContent.ItemType(), 5, 1, 3); - - itemLoot.Add(ItemID.Firefly, 3, 1, 3); - - // Potions - itemLoot.AddCratePotionRules(false); + // Astrophage @ 5% + itemLoot.Add(ModContent.ItemType(), 20); - // Money - itemLoot.Add(ItemID.SilverCoin, 1, 10, 90); - itemLoot.Add(ItemID.GoldCoin, 2, 1, 5); + itemLoot.AddBiomeCrateLootRules(false); } } } diff --git a/Items/Fishing/BrimstoneCragCatches/BrimstoneCrate.cs b/Items/Fishing/BrimstoneCragCatches/BrimstoneCrate.cs index 6a0413d264..fb5785cf59 100644 --- a/Items/Fishing/BrimstoneCragCatches/BrimstoneCrate.cs +++ b/Items/Fishing/BrimstoneCragCatches/BrimstoneCrate.cs @@ -1,6 +1,4 @@ -using CalamityMod.Items.Materials; -using CalamityMod.Items.Potions; -using CalamityMod.Tiles.Crags; +using CalamityMod.Tiles.Crags; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -42,28 +40,7 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite public override bool CanRightClick() => true; public override void ModifyItemLoot(ItemLoot itemLoot) { - // Materials - itemLoot.Add(ItemID.Obsidian, 1, 2, 5); - itemLoot.Add(ItemID.Hellstone, 4, 2, 5); - itemLoot.Add(ItemID.HellstoneBar, 10, 1, 3); - itemLoot.Add(ModContent.ItemType(), 1, 1, 4); - itemLoot.AddIf(() => DownedBossSystem.downedBrimstoneElemental, ModContent.ItemType(), 10, 1, 3); - itemLoot.AddIf(() => DownedBossSystem.downedProvidence, ModContent.ItemType(), 2, 1, 3); - - // Weapons (none) - - // Bait - itemLoot.Add(ItemID.MasterBait, 10, 1, 2); - itemLoot.Add(ItemID.JourneymanBait, 5, 1, 3); - itemLoot.Add(ItemID.ApprenticeBait, 3, 2, 3); - - // Potions - itemLoot.Add(ItemID.InfernoPotion, 10, 1, 3); - itemLoot.AddCratePotionRules(); - - // Money - itemLoot.Add(ItemID.SilverCoin, 1, 10, 90); - itemLoot.Add(ItemID.GoldCoin, 2, 1, 5); + itemLoot.AddBiomeCrateLootRules(); } } } diff --git a/Items/Fishing/BrimstoneCragCatches/SlagCrate.cs b/Items/Fishing/BrimstoneCragCatches/SlagCrate.cs index 55ff0e63e7..a6259f890c 100644 --- a/Items/Fishing/BrimstoneCragCatches/SlagCrate.cs +++ b/Items/Fishing/BrimstoneCragCatches/SlagCrate.cs @@ -1,5 +1,4 @@ -using CalamityMod.Items.Materials; -using CalamityMod.Tiles.Crags; +using CalamityMod.Tiles.Crags; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -17,18 +16,11 @@ public override void SetStaticDefaults() public override void SetDefaults() { + Item.DefaultToPlaceableTile(ModContent.TileType()); Item.width = 32; Item.height = 32; - Item.maxStack = 9999; - Item.consumable = true; - Item.rare = ItemRarityID.Green; Item.value = Item.sellPrice(gold: 1); - Item.createTile = ModContent.TileType(); - Item.useTurn = true; - Item.autoReuse = true; - Item.useAnimation = 15; - Item.useTime = 10; - Item.useStyle = ItemUseStyleID.Swing; + Item.rare = ItemRarityID.Green; } public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.ItemGroup itemGroup) @@ -39,26 +31,7 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite public override bool CanRightClick() => true; public override void ModifyItemLoot(ItemLoot itemLoot) { - // Materials - itemLoot.Add(ItemID.Obsidian, 1, 2, 5); - itemLoot.Add(ItemID.Hellstone, 4, 2, 5); - itemLoot.Add(ItemID.HellstoneBar, 10, 1, 3); - itemLoot.Add(ModContent.ItemType(), 1, 1, 4); - - // Weapons (none) - - // Bait - itemLoot.Add(ItemID.MasterBait, 10, 1, 2); - itemLoot.Add(ItemID.JourneymanBait, 5, 1, 3); - itemLoot.Add(ItemID.ApprenticeBait, 3, 2, 3); - - // Potions - itemLoot.Add(ItemID.InfernoPotion, 10, 1, 3); - itemLoot.AddCratePotionRules(false); - - // Money - itemLoot.Add(ItemID.SilverCoin, 1, 10, 90); - itemLoot.Add(ItemID.GoldCoin, 2, 1, 5); + itemLoot.AddBiomeCrateLootRules(false); } } } diff --git a/Items/Fishing/SulphurCatches/HydrothermalCrate.cs b/Items/Fishing/SulphurCatches/HydrothermalCrate.cs index 52dad8a28b..a2abfc6b89 100644 --- a/Items/Fishing/SulphurCatches/HydrothermalCrate.cs +++ b/Items/Fishing/SulphurCatches/HydrothermalCrate.cs @@ -1,9 +1,6 @@ using CalamityMod.Items.Accessories; -using CalamityMod.Items.Materials; using CalamityMod.Items.Pets; -using CalamityMod.Items.Placeables; -using CalamityMod.Items.Placeables.Ores; -using CalamityMod.Items.Potions; +using CalamityMod.Items.Placeables.Furniture; using CalamityMod.Items.Tools.ClimateChange; using CalamityMod.Items.Weapons.Magic; using CalamityMod.Items.Weapons.Melee; @@ -31,18 +28,11 @@ public override void SetStaticDefaults() public override void SetDefaults() { + Item.DefaultToPlaceableTile(ModContent.TileType()); Item.width = 32; Item.height = 32; - Item.maxStack = 9999; - Item.consumable = true; - Item.rare = ItemRarityID.Green; Item.value = Item.sellPrice(gold: 1); - Item.createTile = ModContent.TileType(); - Item.useTurn = true; - Item.autoReuse = true; - Item.useAnimation = 15; - Item.useTime = 10; - Item.useStyle = ItemUseStyleID.Swing; + Item.rare = ItemRarityID.Green; } public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.ItemGroup itemGroup) @@ -53,51 +43,29 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite public override bool CanRightClick() => true; public override void ModifyItemLoot(ItemLoot itemLoot) { - // The contents of this crate depend massively on progression, so it uses a large number of LeadingConditionRules. - var tier1AbyssAvailable = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedSlimeGod || Main.hardMode); - var tier2AbyssAvailable = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedLeviathan); - var scoriaAvailable = itemLoot.DefineConditionalDropSet(() => NPC.downedGolemBoss); - var tier1AcidRain = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedEoCAcidRain); - var tier2AcidRain = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedAquaticScourgeAcidRain); - var tier3AcidRain = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedPolterghast && DownedBossSystem.downedBoomerDuke); - - // Materials - itemLoot.Add(ModContent.ItemType(), 1, 5, 10); - itemLoot.Add(ModContent.ItemType(), 1, 5, 10); - itemLoot.Add(ModContent.ItemType(), 1, 5, 10); - itemLoot.Add(ModContent.ItemType(), 1, 5, 10); + // 20-50 Blocks @ 100%; Individually 33.33% + itemLoot.Add(new OneFromRulesRule(1, new IItemDropRule[3] + { + ItemDropRule.NotScalingWithLuck(ModContent.ItemType(), 1, 20, 50), + ItemDropRule.NotScalingWithLuck(ModContent.ItemType(), 1, 20, 50), + ItemDropRule.NotScalingWithLuck(ModContent.ItemType(), 1, 20, 50) + })); - tier1AcidRain.Add(ModContent.ItemType(), 10, 1, 3); - tier2AcidRain.Add(ModContent.ItemType(), 10, 1, 3); - tier2AbyssAvailable.Add(ModContent.ItemType(), 5, 2, 5); - tier2AbyssAvailable.Add(ModContent.ItemType(), 5, 2, 5); - tier2AbyssAvailable.Add(ModContent.ItemType(), 5, 2, 5); - scoriaAvailable.Add(ModContent.ItemType(), 5, 16, 28); - scoriaAvailable.Add(ModContent.ItemType(), new Fraction(15, 100), 4, 7); - tier3AcidRain.Add(ModContent.ItemType(), 10, 1, 5); + // Rusty Chest Loot @ 100%; Individually 25% + itemLoot.Add(new OneFromOptionsNotScaledWithLuckDropRule(1, 1, + ModContent.ItemType(), + ModContent.ItemType(), + ModContent.ItemType(), + ModContent.ItemType() + )); // Pre-HM Abyss Weapons - tier1AbyssAvailable.Add(new OneFromOptionsDropRule(10, 1, + itemLoot.Add(new OneFromOptionsNotScaledWithLuckDropRule(1, 1, ModContent.ItemType(), ModContent.ItemType(), ModContent.ItemType(), ModContent.ItemType(), - ModContent.ItemType() - )); - - // Post-AS Acid Rain Weapons (and Nuclear Rod) - tier2AcidRain.Add(new OneFromOptionsDropRule(10, 1, - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType() - )); - - // Pre-HM Abyss Equipment (and Torrential Tear) - tier1AbyssAvailable.Add(new OneFromOptionsDropRule(4, 1, + ModContent.ItemType(), ModContent.ItemType(), ModContent.ItemType(), ModContent.ItemType(), @@ -105,18 +73,7 @@ public override void ModifyItemLoot(ItemLoot itemLoot) ModContent.ItemType() )); - // Bait - itemLoot.Add(ItemID.MasterBait, 10, 1, 2); - itemLoot.Add(ItemID.JourneymanBait, 5, 1, 3); - itemLoot.Add(ItemID.ApprenticeBait, 3, 2, 3); - - // Potions - itemLoot.Add(ModContent.ItemType(), 10, 1, 3); - itemLoot.AddCratePotionRules(); - - // Money - itemLoot.Add(ItemID.SilverCoin, 1, 10, 90); - itemLoot.Add(ItemID.GoldCoin, 2, 1, 5); + itemLoot.AddBiomeCrateLootRules(); } } } diff --git a/Items/Fishing/SulphurCatches/SulphurousCrate.cs b/Items/Fishing/SulphurCatches/SulphurousCrate.cs index 98d8b825e3..499fdaa098 100644 --- a/Items/Fishing/SulphurCatches/SulphurousCrate.cs +++ b/Items/Fishing/SulphurCatches/SulphurousCrate.cs @@ -1,19 +1,11 @@ using CalamityMod.Items.Accessories; -using CalamityMod.Items.Materials; -using CalamityMod.Items.Pets; -using CalamityMod.Items.Placeables; -using CalamityMod.Items.Potions; -using CalamityMod.Items.Tools.ClimateChange; -using CalamityMod.Items.Weapons.Magic; -using CalamityMod.Items.Weapons.Melee; -using CalamityMod.Items.Weapons.Ranged; -using CalamityMod.Items.Weapons.Rogue; +using CalamityMod.Items.Placeables.Furniture; using CalamityMod.Items.Weapons.Summon; +using CalamityMod.Tiles.Abyss; using Terraria; using Terraria.GameContent.ItemDropRules; using Terraria.ID; using Terraria.ModLoader; -using CrateTile = CalamityMod.Tiles.Abyss.SulphurousCrateTile; namespace CalamityMod.Items.Fishing.SulphurCatches { @@ -29,18 +21,11 @@ public override void SetStaticDefaults() public override void SetDefaults() { + Item.DefaultToPlaceableTile(ModContent.TileType()); Item.width = 32; Item.height = 32; - Item.maxStack = 9999; - Item.consumable = true; - Item.rare = ItemRarityID.Green; Item.value = Item.sellPrice(gold: 1); - Item.createTile = ModContent.TileType(); - Item.useTurn = true; - Item.autoReuse = true; - Item.useAnimation = 15; - Item.useTime = 10; - Item.useStyle = ItemUseStyleID.Swing; + Item.rare = ItemRarityID.Green; } public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.ItemGroup itemGroup) @@ -51,47 +36,23 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite public override bool CanRightClick() => true; public override void ModifyItemLoot(ItemLoot itemLoot) { - var tier1AbyssAvailable = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedSlimeGod || Main.hardMode); - var tier1AcidRain = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedEoCAcidRain); - - // Materials - itemLoot.Add(ModContent.ItemType(), 1, 5, 10); - itemLoot.Add(ModContent.ItemType(), 1, 5, 10); - itemLoot.Add(ModContent.ItemType(), 1, 5, 10); - itemLoot.Add(ModContent.ItemType(), 1, 5, 10); - - tier1AcidRain.Add(ModContent.ItemType(), 10, 1, 3); - - // Pre-HM Abyss Weapons - tier1AbyssAvailable.Add(new OneFromOptionsDropRule(10, 1, - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType() + // 20-50 Blocks @ 100%; Individually 33.33% + itemLoot.Add(new OneFromRulesRule(1, new IItemDropRule[3] + { + ItemDropRule.NotScalingWithLuck(ModContent.ItemType(), 1, 20, 50), + ItemDropRule.NotScalingWithLuck(ModContent.ItemType(), 1, 20, 50), + ItemDropRule.NotScalingWithLuck(ModContent.ItemType(), 1, 20, 50) + })); + + // Rusty Chest Loot @ 100%; Individually 25% + itemLoot.Add(new OneFromOptionsNotScaledWithLuckDropRule(1, 1, + ModContent.ItemType(), + ModContent.ItemType(), + ModContent.ItemType(), + ModContent.ItemType() )); - // Pre-HM Abyss Equipment (and Torrential Tear) - tier1AbyssAvailable.Add(new OneFromOptionsDropRule(4, 1, - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType() - )); - - // Bait - itemLoot.Add(ItemID.MasterBait, 10, 1, 2); - itemLoot.Add(ItemID.JourneymanBait, 5, 1, 3); - itemLoot.Add(ItemID.ApprenticeBait, 3, 2, 3); - - // Potions - itemLoot.Add(ModContent.ItemType(), 10, 1, 3); - itemLoot.AddCratePotionRules(false); - - // Money - itemLoot.Add(ItemID.SilverCoin, 1, 10, 90); - itemLoot.Add(ItemID.GoldCoin, 2, 1, 5); + itemLoot.AddBiomeCrateLootRules(false); } } } diff --git a/Items/Fishing/SunkenSeaCatches/EutrophicCrate.cs b/Items/Fishing/SunkenSeaCatches/EutrophicCrate.cs index c2c7f48aec..a0752f07ef 100644 --- a/Items/Fishing/SunkenSeaCatches/EutrophicCrate.cs +++ b/Items/Fishing/SunkenSeaCatches/EutrophicCrate.cs @@ -1,10 +1,4 @@ -using CalamityMod.Items.Critters; -using CalamityMod.Items.Materials; -using CalamityMod.Items.Placeables; -using CalamityMod.Items.Weapons.Magic; -using CalamityMod.Items.Weapons.Melee; -using CalamityMod.Items.Weapons.Ranged; -using CalamityMod.Items.Weapons.Summon; +using CalamityMod.Tiles.SunkenSea; using Terraria; using Terraria.GameContent.ItemDropRules; using Terraria.ID; @@ -24,18 +18,11 @@ public override void SetStaticDefaults() public override void SetDefaults() { + Item.DefaultToPlaceableTile(ModContent.TileType()); Item.width = 32; Item.height = 32; - Item.maxStack = 9999; - Item.consumable = true; - Item.rare = ItemRarityID.Green; Item.value = Item.sellPrice(gold: 1); - Item.createTile = ModContent.TileType(); - Item.useTurn = true; - Item.autoReuse = true; - Item.useAnimation = 15; - Item.useTime = 10; - Item.useStyle = ItemUseStyleID.Swing; + Item.rare = ItemRarityID.Green; } public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.ItemGroup itemGroup) @@ -46,26 +33,14 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite public override bool CanRightClick() => true; public override void ModifyItemLoot(ItemLoot itemLoot) { - var postDesertScourge = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedDesertScourge); - - // Materials - itemLoot.Add(ModContent.ItemType(), 1, 10, 30); - itemLoot.Add(ModContent.ItemType(), 1, 10, 30); - postDesertScourge.Add(ModContent.ItemType(), 1, 5, 10); - postDesertScourge.Add(ModContent.ItemType(), 5, 2, 5); - - // Bait - itemLoot.Add(ItemID.MasterBait, 10, 1, 2); - itemLoot.Add(ItemID.JourneymanBait, 5, 1, 3); - itemLoot.Add(ModContent.ItemType(), 5, 1, 3); - itemLoot.Add(ItemID.ApprenticeBait, 3, 2, 3); - - // Potions - itemLoot.AddCratePotionRules(false); - - // Money - itemLoot.Add(ItemID.SilverCoin, 1, 10, 90); - itemLoot.Add(ItemID.GoldCoin, 2, 1, 5); + // 20-50 Blocks @ 100%; Individually 50% + itemLoot.Add(new OneFromRulesRule(1, new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ModContent.ItemType(), 1, 20, 50), + ItemDropRule.NotScalingWithLuck(ModContent.ItemType(), 1, 20, 50) + })); + + itemLoot.AddBiomeCrateLootRules(false); } } } diff --git a/Items/Fishing/SunkenSeaCatches/PrismCrate.cs b/Items/Fishing/SunkenSeaCatches/PrismCrate.cs index ecf064395c..b467105250 100644 --- a/Items/Fishing/SunkenSeaCatches/PrismCrate.cs +++ b/Items/Fishing/SunkenSeaCatches/PrismCrate.cs @@ -6,6 +6,7 @@ using CalamityMod.Items.Weapons.Melee; using CalamityMod.Items.Weapons.Ranged; using CalamityMod.Items.Weapons.Summon; +using CalamityMod.Tiles.SunkenSea; using Terraria; using Terraria.GameContent.ItemDropRules; using Terraria.ID; @@ -26,18 +27,11 @@ public override void SetStaticDefaults() public override void SetDefaults() { + Item.DefaultToPlaceableTile(ModContent.TileType()); Item.width = 32; Item.height = 32; - Item.maxStack = 9999; - Item.consumable = true; - Item.rare = ItemRarityID.Green; Item.value = Item.sellPrice(gold: 1); - Item.createTile = ModContent.TileType(); - Item.useTurn = true; - Item.autoReuse = true; - Item.useAnimation = 15; - Item.useTime = 10; - Item.useStyle = ItemUseStyleID.Swing; + Item.rare = ItemRarityID.Green; } public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.ItemGroup itemGroup) @@ -48,36 +42,14 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite public override bool CanRightClick() => true; public override void ModifyItemLoot(ItemLoot itemLoot) { - var postDesertScourge = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedDesertScourge); - var postHardmodeClam = itemLoot.DefineConditionalDropSet(() => DownedBossSystem.downedCLAMHardMode); - - // Materials - itemLoot.Add(ModContent.ItemType(), 1, 10, 30); - itemLoot.Add(ModContent.ItemType(), 1, 10, 30); - postDesertScourge.Add(ModContent.ItemType(), 1, 5, 10); - postDesertScourge.Add(ModContent.ItemType(), 5, 2, 5); - postHardmodeClam.Add(ModContent.ItemType(), new Fraction(12, 100), 2, 5); - - // Weapons - postHardmodeClam.Add(new OneFromOptionsNotScaledWithLuckDropRule(7, 100, - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType(), - ModContent.ItemType() - )); - - // Bait - itemLoot.Add(ItemID.MasterBait, 10, 1, 2); - itemLoot.Add(ItemID.JourneymanBait, 5, 1, 3); - itemLoot.Add(ModContent.ItemType(), 5, 1, 3); - itemLoot.Add(ItemID.ApprenticeBait, 3, 2, 3); - - // Potions - itemLoot.AddCratePotionRules(); - - // Money - itemLoot.Add(ItemID.SilverCoin, 1, 10, 90); - itemLoot.Add(ItemID.GoldCoin, 2, 1, 5); + // 20-50 Blocks @ 100%; Individually 50% + itemLoot.Add(new OneFromRulesRule(1, new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ModContent.ItemType(), 1, 20, 50), + ItemDropRule.NotScalingWithLuck(ModContent.ItemType(), 1, 20, 50) + })); + + itemLoot.AddBiomeCrateLootRules(); } } } diff --git a/Items/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..8482d2e2a8 100644 --- a/Items/PermanentBoosters/CelestialOnion.cs +++ b/Items/PermanentBoosters/CelestialOnion.cs @@ -40,19 +40,4 @@ public override bool CanUseItem(Player player) return true; } } - - public class CelestialOnionAccessorySlot : ModAccessorySlot - { - // Celestial Onion does not work in Master Mode. - public override bool IsEnabled() - { - // GetModPlayer will throw an index error in this step of the loading process for whatever reason - // We prematurely stop it from getting to that point - if (!Player.active || Main.masterMode) - return false; - - return Player.Calamity().extraAccessoryML; - } - public override bool IsHidden() => IsEmpty && !IsEnabled(); - } } diff --git a/Items/Placeables/CelestialRemains.cs b/Items/Placeables/CelestialRemains.cs index c597021aad..91bbe5daf6 100644 --- a/Items/Placeables/CelestialRemains.cs +++ b/Items/Placeables/CelestialRemains.cs @@ -132,22 +132,22 @@ public override void ExtractinatorUse(int extractinatorBlockType, ref int result } else if (val < 85.03f) { - resultType = CalamityConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.CobaltOre : ItemID.MythrilOre) : ItemID.MythrilOre; + resultType = CalamityServerConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.CobaltOre : ItemID.MythrilOre) : ItemID.MythrilOre; resultStack = Main.rand.Next(1, 17); } else if (val < 87.03f) { - resultType = CalamityConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.PalladiumOre : ItemID.OrichalcumOre) : ItemID.OrichalcumOre; + resultType = CalamityServerConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.PalladiumOre : ItemID.OrichalcumOre) : ItemID.OrichalcumOre; resultStack = Main.rand.Next(1, 17); } else if (val < 88.78f) { - resultType = CalamityConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.CobaltOre : !twoMechsDowned ? ItemID.MythrilOre : ItemID.AdamantiteOre) : ItemID.AdamantiteOre; + resultType = CalamityServerConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.CobaltOre : !twoMechsDowned ? ItemID.MythrilOre : ItemID.AdamantiteOre) : ItemID.AdamantiteOre; resultStack = Main.rand.Next(1, 17); } else if (val < 89.53f) { - resultType = CalamityConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.PalladiumOre : !twoMechsDowned ? ItemID.OrichalcumOre : ItemID.TitaniumOre) : ItemID.TitaniumOre; + resultType = CalamityServerConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.PalladiumOre : !twoMechsDowned ? ItemID.OrichalcumOre : ItemID.TitaniumOre) : ItemID.TitaniumOre; resultStack = Main.rand.Next(1, 17); } else if (DownedBossSystem.downedAstrumDeus) diff --git a/Items/Placeables/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/CraftingStations/DraedonsForge.cs b/Items/Placeables/Furniture/CraftingStations/DraedonsForge.cs index 60d8f1eb10..8647af0c1a 100644 --- a/Items/Placeables/Furniture/CraftingStations/DraedonsForge.cs +++ b/Items/Placeables/Furniture/CraftingStations/DraedonsForge.cs @@ -9,19 +9,6 @@ namespace CalamityMod.Items.Placeables.Furniture.CraftingStations public class DraedonsForge : ModItem, ILocalizedModType { public new string LocalizationCategory => "Items.Placeables"; - public override void SetStaticDefaults() - { - Terraria.On_Recipe.ConsumeForCraft += DraeforgeUnlockDetour; - } - - private static bool DraeforgeUnlockDetour(On_Recipe.orig_ConsumeForCraft orig, Recipe self, Item item, Item requiredItem, ref int stackRequired) - { - if (self.HasTile(ModContent.TileType())) - { - Main.LocalPlayer.Calamity().HasCraftedDraedonsForge = true; - } - return orig(self, item, requiredItem, ref stackRequired); - } public override void SetDefaults() { diff --git a/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs b/Items/Placeables/Furniture/DevPaintings/ThankYouPainting.cs index 63db3bcde1..41b6a1cdda 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", + "Altixal", "apotofkoolaid", "AquaSG", "Atalya", "Ben-TK", + "Big E", + "CDMusic", "Cei", "CongratsIsTrash", "Cooper", "CosmaticMango", "CrabBar", + "Dandy", "Dia", - "enamoured", + "Done", + "dozezoze", + "Eddie Spaghetti", "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", + "Sunny", + "Tobias", + "_tofu", + "Tomat", "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,8 +126,6 @@ public override void ModifyTooltips(List tooltips) "DarkTiny", "Demik", "DM Dokuro", - "Dominic Karma", - "Done", "Doog", "drh", "dwshin", @@ -129,6 +133,7 @@ public override void ModifyTooltips(List tooltips) "Earth", "EchoDuck", "Ein", + "enamoured", "Enreden", "Epsilon", "Fargowilta", @@ -138,7 +143,9 @@ public override void ModifyTooltips(List tooltips) "GramOfSalt", "Graydee", "Grox the Great", + "Heart Plus Up!", "Hectique", + "Hugekraken", "Huggles", "Ian-1KV", "IbanPlay", @@ -151,8 +158,11 @@ public override void ModifyTooltips(List tooltips) "L0st", "Leon", "Leviathan", + "Lilac Olligoci", "Lompl Allimath", + "Lucille Karma", "MarieArk", + "Mihaii", "Minecat", "Mrrp", "Nao", @@ -166,7 +176,6 @@ public override void ModifyTooltips(List tooltips) "Phantasmal Deathray", "Phupperbat", "Pinkie Poss", - "pixlgray", "Poly", "Popo", "President Waluigi", @@ -176,6 +185,7 @@ public override void ModifyTooltips(List tooltips) "Runefield", "Sargassum", "sentri", + "SharZz", "Shucks", "Silver-Lord of Ash", "SixteenInMono", @@ -190,7 +200,6 @@ public override void ModifyTooltips(List tooltips) "ThousandFields", "TikiWiki", "Tinymanx", - "Tomat", "Trivaxy", "Uberransy", "Vaikyia", 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/Placeables/NovaeSlag.cs b/Items/Placeables/NovaeSlag.cs index 78983dd0f0..14b3cdb79f 100644 --- a/Items/Placeables/NovaeSlag.cs +++ b/Items/Placeables/NovaeSlag.cs @@ -120,22 +120,22 @@ public override void ExtractinatorUse(int extractinatorBlockType, ref int result } else if (val < 83.03f) { - resultType = CalamityConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.CobaltOre : ItemID.MythrilOre) : ItemID.MythrilOre; + resultType = CalamityServerConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.CobaltOre : ItemID.MythrilOre) : ItemID.MythrilOre; resultStack = Main.rand.Next(1, 17); } else if (val < 85.03f) { - resultType = CalamityConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.PalladiumOre : ItemID.OrichalcumOre) : ItemID.OrichalcumOre; + resultType = CalamityServerConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.PalladiumOre : ItemID.OrichalcumOre) : ItemID.OrichalcumOre; resultStack = Main.rand.Next(1, 17); } else if (val < 86.78f) { - resultType = CalamityConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.CobaltOre : !twoMechsDowned ? ItemID.MythrilOre : ItemID.AdamantiteOre) : ItemID.AdamantiteOre; + resultType = CalamityServerConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.CobaltOre : !twoMechsDowned ? ItemID.MythrilOre : ItemID.AdamantiteOre) : ItemID.AdamantiteOre; resultStack = Main.rand.Next(1, 17); } else if (val < 88.53f) { - resultType = CalamityConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.PalladiumOre : !twoMechsDowned ? ItemID.OrichalcumOre : ItemID.TitaniumOre) : ItemID.TitaniumOre; + resultType = CalamityServerConfig.Instance.EarlyHardmodeProgressionRework ? (!NPC.downedMechBossAny ? ItemID.PalladiumOre : !twoMechsDowned ? ItemID.OrichalcumOre : ItemID.TitaniumOre) : ItemID.TitaniumOre; resultStack = Main.rand.Next(1, 17); } else if (DownedBossSystem.downedAstrumDeus) diff --git a/Items/Placeables/Ores/AuricOre.cs b/Items/Placeables/Ores/AuricOre.cs index b1e3ec05c6..976cef7ade 100644 --- a/Items/Placeables/Ores/AuricOre.cs +++ b/Items/Placeables/Ores/AuricOre.cs @@ -1,4 +1,5 @@ -using CalamityMod.Rarities; +using CalamityMod.Items.Materials; +using CalamityMod.Rarities; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -29,5 +30,13 @@ public override void SetDefaults() Item.value = Item.sellPrice(gold: 4); Item.rare = ModContent.RarityType(); } + + public override void AddRecipes() + { + CreateRecipe(10). + AddIngredient(). + AddCondition(Condition.NearShimmer). + Register(); + } } } diff --git a/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/SirenproofEarMuffs.cs b/Items/SirenproofEarMuffs.cs index b05a825f31..6763eb7aff 100644 --- a/Items/SirenproofEarMuffs.cs +++ b/Items/SirenproofEarMuffs.cs @@ -1,17 +1,15 @@ using System.Collections.Generic; -using CalamityMod.Items.Materials; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; +using System.IO; using Terraria; using Terraria.ID; using Terraria.ModLoader; +using Terraria.ModLoader.IO; using static CalamityMod.CalamityUtils; namespace CalamityMod.Items { public class SirenproofEarMuffs : ModItem, ILocalizedModType { - public static bool state = false; public new string LocalizationCategory => "Items.Misc"; public override void SetDefaults() { @@ -26,21 +24,40 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite itemGroup = (ContentSamples.CreativeHelper.ItemGroup)CalamityResearchSorting.SpawnPrevention; } + #region Toggle Feature + + public bool Enabled = true; + + public override ModItem Clone(Item item) + { + var clone = (SirenproofEarMuffs)base.Clone(item); + clone.Enabled = Enabled; + return clone; + } + + public override void SaveData(TagCompound tag) => tag.Add("blockerEnabled", Enabled); + + public override void LoadData(TagCompound tag) => Enabled = tag.GetBool("blockerEnabled"); + + public override void NetSend(BinaryWriter writer) => writer.Write(Enabled); + + public override void NetReceive(BinaryReader reader) => Enabled = reader.ReadBoolean(); + public override bool CanRightClick() => true; + public override bool ConsumeItem(Player player) => false; + public override void RightClick(Player player) { - if (player.Calamity().disableAnahitaSpawns == true) - player.Calamity().disableAnahitaSpawns = false; - else - player.Calamity().disableAnahitaSpawns = true; + Enabled = !Enabled; Item.NetStateChanged(); - state = player.Calamity().disableAnahitaSpawns; + } + + #endregion - bool favorited = Item.favorited; - Item.SetDefaults(ModContent.ItemType()); - Item.stack++; - Item.favorited = favorited; + public override void UpdateInventory(Player player) + { + player.Calamity().disableAnahitaSpawns |= Enabled; } /* @@ -85,7 +102,7 @@ public override bool PreDrawInWorld(SpriteBatch spriteBatch, Color lightColor, C public override void ModifyTooltips(List tooltips) { string text; - if (state == true) + if (Enabled) text = GetTextValue("Items.Misc.SpawnBlockersOn"); else text = GetTextValue("Items.Misc.SpawnBlockersOff"); diff --git a/Items/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/AbyssalWarhammer.png b/Items/Tools/AbyssalWarhammer.png index b20edc3726..ec6356d7cf 100644 Binary files a/Items/Tools/AbyssalWarhammer.png and b/Items/Tools/AbyssalWarhammer.png differ 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/VoodooDemonVoodooDoll.cs b/Items/VoodooDemonVoodooDoll.cs index c098d72199..236dd89600 100644 --- a/Items/VoodooDemonVoodooDoll.cs +++ b/Items/VoodooDemonVoodooDoll.cs @@ -1,16 +1,15 @@ -using Terraria; +using System.Collections.Generic; +using System.IO; +using Terraria; using Terraria.ID; using Terraria.ModLoader; -using System.Collections.Generic; -using Microsoft.Xna.Framework.Graphics; -using Microsoft.Xna.Framework; +using Terraria.ModLoader.IO; using static CalamityMod.CalamityUtils; namespace CalamityMod.Items { public class VoodooDemonVoodooDoll : ModItem, ILocalizedModType { - public static bool state = false; public new string LocalizationCategory => "Items.Misc"; public override void SetDefaults() @@ -27,20 +26,40 @@ public override void ModifyResearchSorting(ref ContentSamples.CreativeHelper.Ite itemGroup = (ContentSamples.CreativeHelper.ItemGroup)CalamityResearchSorting.SpawnPrevention; } + #region Toggle Feature + + public bool Enabled = true; + + public override ModItem Clone(Item item) + { + var clone = (VoodooDemonVoodooDoll)base.Clone(item); + clone.Enabled = Enabled; + return clone; + } + + public override void SaveData(TagCompound tag) => tag.Add("blockerEnabled", Enabled); + + public override void LoadData(TagCompound tag) => Enabled = tag.GetBool("blockerEnabled"); + + public override void NetSend(BinaryWriter writer) => writer.Write(Enabled); + + public override void NetReceive(BinaryReader reader) => Enabled = reader.ReadBoolean(); + public override bool CanRightClick() => true; + public override bool ConsumeItem(Player player) => false; + public override void RightClick(Player player) { - if (player.Calamity().disableVoodooSpawns == true) - player.Calamity().disableVoodooSpawns = false; - else - player.Calamity().disableVoodooSpawns = true; + Enabled = !Enabled; Item.NetStateChanged(); - state = player.Calamity().disableVoodooSpawns; - bool favorited = Item.favorited; - Item.SetDefaults(ModContent.ItemType()); - Item.stack++; - Item.favorited = favorited; + } + + #endregion + + public override void UpdateInventory(Player player) + { + player.Calamity().disableVoodooSpawns |= Enabled; } /* @@ -85,7 +104,7 @@ public override bool PreDrawInWorld(SpriteBatch spriteBatch, Color lightColor, C public override void ModifyTooltips(List tooltips) { string text; - if (state == true) + if (Enabled) text = GetTextValue("Items.Misc.SpawnBlockersOn"); else text = GetTextValue("Items.Misc.SpawnBlockersOff"); diff --git a/Items/Weapons/DraedonsArsenal/GaussDagger.cs b/Items/Weapons/DraedonsArsenal/GaussDagger.cs index 98c8eac524..a58d032861 100644 --- a/Items/Weapons/DraedonsArsenal/GaussDagger.cs +++ b/Items/Weapons/DraedonsArsenal/GaussDagger.cs @@ -1,4 +1,6 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using CalamityMod.CustomRecipes; using CalamityMod.Items.Materials; using CalamityMod.Items.Placeables; using CalamityMod.Projectiles.DraedonsArsenal; @@ -58,6 +60,7 @@ public override void AddRecipes() AddIngredient(7). AddIngredient(4). AddIngredient(7). + AddCondition(ArsenalTierGatedRecipe.ConstructRecipeCondition(1, out Func condition), condition). AddTile(TileID.Anvils). Register(); } 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/PhotosynthesisGlow.png b/Items/Weapons/Magic/PhotosynthesisGlow.png index dc3a8eeab5..ca021b33a5 100644 Binary files a/Items/Weapons/Magic/PhotosynthesisGlow.png and b/Items/Weapons/Magic/PhotosynthesisGlow.png 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/Infinity.cs b/Items/Weapons/Ranged/Infinity.cs index 31868841d0..553ab828a0 100644 --- a/Items/Weapons/Ranged/Infinity.cs +++ b/Items/Weapons/Ranged/Infinity.cs @@ -62,8 +62,8 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, { Vector2 helixVel1 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(sine)); Vector2 helixVel2 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(-sine)); - int shot1 = Projectile.NewProjectile(source, position.X, position.Y, helixVel1.X, helixVel1.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, 1f); - int shot2 = Projectile.NewProjectile(source, position.X, position.Y, helixVel2.X, helixVel2.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, 1f); + int shot1 = Projectile.NewProjectile(source, position.X, position.Y, helixVel1.X, helixVel1.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, player.altFunctionUse != 2 ? 1f : 0); + int shot2 = Projectile.NewProjectile(source, position.X, position.Y, helixVel2.X, helixVel2.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, player.altFunctionUse != 2 ? 1f : 0); } else if (player.altFunctionUse != 2) { diff --git a/Items/Weapons/Ranged/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/Ranged/Svantechnical.cs b/Items/Weapons/Ranged/Svantechnical.cs index e304c42a43..28236fc11a 100644 --- a/Items/Weapons/Ranged/Svantechnical.cs +++ b/Items/Weapons/Ranged/Svantechnical.cs @@ -49,7 +49,6 @@ public override bool AltFunctionUse(Player player) { return true; } - public override void HoldItem(Player player) => player.scope = false; public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) { @@ -63,9 +62,9 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 helixVel1 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(sine)); Vector2 helixVel2 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(-sine)); Vector2 helixVel3 = (velocity * Main.rand.NextFloat(0.9f, 1.1f)).RotatedBy(MathHelper.ToRadians(sine2)); - int shot1 = Projectile.NewProjectile(source, position.X, position.Y, helixVel1.X, helixVel1.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, 2f); - int shot2 = Projectile.NewProjectile(source, position.X, position.Y, helixVel2.X, helixVel2.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, 4f); - int shot3 = Projectile.NewProjectile(source, position.X, position.Y, helixVel3.X, helixVel3.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, 3f); + int shot1 = Projectile.NewProjectile(source, position.X, position.Y, helixVel1.X, helixVel1.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, player.altFunctionUse != 2 ? 2f : 0f); + int shot2 = Projectile.NewProjectile(source, position.X, position.Y, helixVel2.X, helixVel2.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, player.altFunctionUse != 2 ? 4f : 0f); + int shot3 = Projectile.NewProjectile(source, position.X, position.Y, helixVel3.X, helixVel3.Y, shotType, damage, knockback, player.whoAmI, 0f, 0, player.altFunctionUse != 2 ? 3f : 0f); } else if (player.altFunctionUse != 2) { diff --git a/Items/Weapons/Rogue/SearedPan.cs b/Items/Weapons/Rogue/SearedPan.cs deleted file mode 100644 index 411e55ba23..0000000000 --- a/Items/Weapons/Rogue/SearedPan.cs +++ /dev/null @@ -1,78 +0,0 @@ -using CalamityMod.Items.Materials; -using CalamityMod.Projectiles.Rogue; -using CalamityMod.Rarities; -using CalamityMod.Tiles.Furniture.CraftingStations; -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.Audio; -using Terraria.DataStructures; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Items.Weapons.Rogue -{ - public class SearedPan : RogueWeapon - { - public static readonly SoundStyle SmashSound = new("CalamityMod/Sounds/Item/SearedPanSmash"); - - // Attacks must be within 40 frames of each other to count as "consecutive" hits - // This is a little less than double the use time - public static int ConsecutiveHitOpening = 40; - public override void SetDefaults() - { - Item.width = 60; - Item.height = 36; - Item.damage = 2222; - Item.DamageType = RogueDamageClass.Instance; - Item.knockBack = 10f; - Item.noMelee = true; - Item.noUseGraphic = true; - Item.useStyle = ItemUseStyleID.Swing; - Item.useTime = Item.useAnimation = 25; - Item.reuseDelay = 1; - Item.useLimitPerAnimation = 1; - Item.UseSound = SoundID.Item1; - Item.autoReuse = true; - Item.value = CalamityGlobalItem.RarityVioletBuyPrice; - Item.rare = ModContent.RarityType(); - Item.shoot = ModContent.ProjectileType(); - Item.shootSpeed = 15f; - Item.Calamity().donorItem = true; - } - - public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) - { - float mode = 1f; - if (player.Calamity().searedPanCounter >= 3) - { - player.Calamity().searedPanCounter = 0; - mode = 2f; - } - if (player.Calamity().StealthStrikeAvailable()) - { - player.Calamity().searedPanCounter = 0; - mode = 3f; - } - int pan = Projectile.NewProjectile(source, position, velocity, type, damage, knockback, player.whoAmI, mode); - if (mode > 1f && pan.WithinBounds(Main.maxProjectiles)) - { - Main.projectile[pan].extraUpdates++; - if (mode == 3f) - Main.projectile[pan].Calamity().stealthStrike = true; - } - return false; - } - - public override void AddRecipes() - { - CreateRecipe(). - AddIngredient(). - AddIngredient(5). - AddIngredient(ItemID.LifeCrystal). - AddIngredient(ItemID.Bone, 92). - // AddIngredient(ItemID.Steak). - AddTile(). - Register(); - } - } -} diff --git a/Items/Weapons/Rogue/SearedPan.png b/Items/Weapons/Rogue/SearedPan.png deleted file mode 100644 index b5bef1d2cc..0000000000 Binary files a/Items/Weapons/Rogue/SearedPan.png and /dev/null 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/Summon/RustyBeaconPrototype.cs b/Items/Weapons/Summon/RustyBeaconPrototype.cs index e17e158a74..0e2de87298 100644 --- a/Items/Weapons/Summon/RustyBeaconPrototype.cs +++ b/Items/Weapons/Summon/RustyBeaconPrototype.cs @@ -34,6 +34,7 @@ public override void SetDefaults() Item.shoot = ModContent.ProjectileType(); Item.shootSpeed = 10f; Item.DamageType = DamageClass.Summon; + Item.sentry = true; } public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) 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.Configs.hjson b/Localization/en-US/Mods.CalamityMod.Configs.hjson index 44503237ef..9914cc0c2b 100644 --- a/Localization/en-US/Mods.CalamityMod.Configs.hjson +++ b/Localization/en-US/Mods.CalamityMod.Configs.hjson @@ -1,13 +1,11 @@ -CalamityConfig: { - DisplayName: Main Config +CalamityClientConfig: { + DisplayName: Client Config Headers: { - ExpertMaster: Expert and Master Mode Changes Gameplay: General Gameplay Changes Graphics: Graphics Changes - Revengeance: Revengeance Mode Changes + MeterPositions: Meter Positions UI: UI Changes - BaseBoosts: Base Stat Boosts MusicEvents: Music Events } @@ -38,15 +36,6 @@ CalamityConfig: { ''' } - BossesStopWeather: { - Label: "[i:CalamityMod/TorrentialTear] Bosses Stop Weather" - Tooltip: - ''' - When enabled, many late game bosses will stop all rain and related weather when spawned. - Enable if you have performance issues during late game boss fights. - ''' - } - BossHealthBarExtraInfo: { Label: "[i:CalamityMod/EncryptedSchematicPlanetoid] Boss Health Bar Extra Info" Tooltip: @@ -56,35 +45,6 @@ CalamityConfig: { ''' } - BossHealthBoost: { - Label: "[i:LifeCrystal] Boss Health Boost Percentage" - Tooltip: - ''' - Globally boosts the health of all bosses by the specified percentage. - This stacks with multiplayer boss health boosts. - Does not affect bosses that are already spawned. - ''' - } - - DefaultDashEnabled: { - Label: "[i:Tabi] Default Dash" - Tooltip: - ''' - Gives the player a very weak dash by default that requires no equipment or items to use. - This dash will be replaced by any other available dash, including those from other mods. - ''' - } - - BossZen: { - Label: "[i:CalamityMod/ZenPotion] Bosses Drastically Reduce Spawn Rates" - Tooltip: - ''' - All living bosses will drastically reduce the spawn rates of regular enemies. - This also prevents Slime Rain from occurring while a boss is alive. - Calamity is balanced around this setting being enabled. - ''' - } - ChargeMeter: { Label: "[i:CalamityMod/DraedonPowerCell] Display Charge Meter" Tooltip: @@ -112,11 +72,6 @@ CalamityConfig: { ''' } - ChilledWaterRework: { - Label: "[i:ArcticDivingGear] Chilled Water Rework" - Tooltip: When enabled, water in the Snow and Ice biomes will rapidly drain the player's breath instead of inflicting Chilled. - } - CooldownDisplay: { Label: "[i:CalamityMod/NebulousCore] Cooldown Rack Display Mode" Tooltip: @@ -136,28 +91,6 @@ CalamityConfig: { Tooltip: Plays Calamity Mod OST - "Scourge of The Universe (Eulogy for The Ego)", after The Devourer of Gods has been defeated. } - EarlyHardmodeProgressionRework: { - Label: "[i:Pwnhammer] Early Hardmode Progression Rework" - Tooltip: - ''' - Demon Altars no longer spawn ores and crimson/corruption blocks when broken. - Wall of Flesh spawns Cobalt and Palladium ore on first kill. - The first mech boss you fight has 20% (10% in Expert and Master) less HP and damage and spawns Mythril and Orichalcum ore on first kill. - The second mech boss you fight has 10% (5% in Expert and Master) less HP and damage and spawns Adamantite and Titanium ore on first kill. - The third mech boss spawns Hallowed Ore on first kill. - ''' - } - - FasterBaseSpeed: { - Label: "[i:HermesBoots] Increase Base Movement Speed" - Tooltip: - ''' - Increases the player's base movement speed substantially by always giving them +50% movement speed. - This setting does nothing if the mod Terraria Overhaul is loaded. - Calamity is balanced around this setting being enabled. - ''' - } - FasterFallHotkey: { Label: "[i:CalamityMod/BallAndChain] Enable Fast Falling" Tooltip: @@ -168,26 +101,8 @@ CalamityConfig: { ''' } - FasterJumpSpeed: { - Label: "[i:FrogLeg] Increase Base Jump Speed" - Tooltip: - ''' - Slightly increases the player's base jump speed. - Calamity is balanced around this setting being enabled. - ''' - } - - FasterTilePlacement: { - Label: "[i:ArchitectGizmoPack] Increase Base Building Speed" - Tooltip: - ''' - Substantially increases how rapidly the player can place tiles and walls. - This config stacks with the Brick Layer, Portable Cement Mixer and other accessories. - ''' - } - FlightBar: { - Label: "[i:CalamityMod/DrewsWings] Display Flight Bar" + Label: "[i:AngelWings] Display Flight Bar" Tooltip: ''' Enables the Flight Bar UI, which shows the player's remaining wing flight time. @@ -214,39 +129,17 @@ CalamityConfig: { ''' } - ForceTownSafety: { - Label: "[i:Sunflower] Force Town Safety" + Interludes: { + Label: "[i:CalamityModMusic/Interlude1MusicBox] Interludes" Tooltip: ''' - Counteracts Expert and Master Mode allowing enemies to spawn near towns by vastly decreasing spawn rates. - This can have unintended side effects such as making critters difficult to find. + Enables the playing of three interlude tracks in-game: + Plays Calamity Mod OST - Interlude 1, "Silence before the storms", after Calamitas Clone has been defeated. + Plays Calamity Mod OST - "Storms before the catastrophes", after the Moon Lord has been defeated. + Plays Calamity Mod OST - "Catastrophes before the calamity", after Yharon has been defeated. ''' } - HigherJumpHeight: { - Label: "[i:ShinyRedBalloon] Increase Base Jump Height" - Tooltip: - ''' - Increases the player's base jump height by 10% so that they can jump 7 tiles. - Calamity is balanced around this setting being enabled. - ''' - } - - Interlude1: { - Label: "[i:CalamityModMusic/Interlude1MusicBox] Interlude 1" - Tooltip: Plays Calamity Mod OST - Interlude 1, "Silence before the storms", after Calamitas Clone has been defeated. - } - - Interlude2: { - Label: "[i:CalamityModMusic/Interlude2MusicBox] Interlude 2" - Tooltip: Plays Calamity Mod OST - Interlude 2, "Storms before the catastrophes", after Moon Lord has been defeated. - } - - Interlude3: { - Label: "[i:CalamityModMusic/Interlude3MusicBox] Interlude 3" - Tooltip: Plays Calamity Mod OST - Interlude 3, "Catastrophes before the calamity", after Yharon has been defeated. - } - MeterPosLock: { Label: "[i:GemLockTopaz] Lock Meter Positions" Tooltip: @@ -265,15 +158,6 @@ CalamityConfig: { ''' } - NerfExpertDebuffs: { - Label: "[i:AnkhCharm] Remove Increased Debuff Duration" - Tooltip: - ''' - Disables Expert Mode doubling (and Master Mode tripling) the duration of debuffs on the player. - Calamity is balanced around this setting being enabled. - ''' - } - NewVanillaTextures: { Label: "[i:Paintbrush] New Vanilla Textures" Tooltip: @@ -312,20 +196,6 @@ CalamityConfig: { ''' } - RemoveLavaDropsFromLavaSlimes: { - Label: "[i:LavaWaders] Remove Lava Drops From Lava Slimes" - Tooltip: When enabled, Lava Slimes will be replaced with a new Lava Slime that no longer drops lava. - } - - RemoveReforgeRNG: { - Label: "[i:TinHammer] Remove Reforge RNG" - Tooltip: - ''' - Removes randomness from the Goblin Tinkerer's reforges for both weapons and accessories. - Disable this if using mods that change reforging on their own to prevent conflicts. - ''' - } - RipperMeterShake: { Label: "[i:CalamityMod/RedLightningContainer] Rage and Adrenaline Meter Shake" Tooltip: @@ -433,12 +303,143 @@ CalamityConfig: { ''' } - PotionSelling: { - Label: "[i:SpelunkerPotion] Town NPC Potion Selling" + VanillaCooldownDisplay: { + Label: "[i:HealingPotion] Display Vanilla Cooldowns" Tooltip: ''' - Allows town NPCs to sell various potions. - Certain potions are sold after specific bosses have been defeated. + Adds the vanilla debuffs Potion Sickness and Chaos State to the Cooldown Rack. + The debuffs will still appear in the buffs array, but this may help make them more visible. + ''' + } + + VCMMStatusMessage: { + Label: "[i:MusicBoxMartians] VCMM Status Message" + Tooltip: Enable or disable the status message promoting the Vanilla Calamity Music Mod that plays on world entry. + } + + WikiStatusMessage: { + Label: "[i:Book] Wiki Status Message" + Tooltip: Enable or disable the status message promoting the Official Calamity Wiki that plays on world entry. + } +} + +CalamityServerConfig: { + DisplayName: Server Config + Denied: You have no permission to change this config + + Headers: { + ExpertMaster: Expert and Master Mode Changes + Gameplay: General Gameplay Changes + BaseBoosts: Base Stat Boosts + } + + BossesStopWeather: { + Label: "[i:CalamityMod/TorrentialTear] Bosses Stop Weather" + Tooltip: + ''' + When enabled, many late game bosses will stop all rain and related weather when spawned. + Enable if you have performance issues during late game boss fights. + ''' + } + + BossHealthBoost: { + Label: "[i:LifeCrystal] Boss Health Boost Percentage" + Tooltip: + ''' + Globally boosts the health of all bosses by the specified percentage. + This stacks with multiplayer boss health boosts. + Does not affect bosses that are already spawned. + ''' + } + + BossZen: { + Label: "[i:CalamityMod/ZenPotion] Bosses Drastically Reduce Spawn Rates" + Tooltip: + ''' + All living bosses will drastically reduce the spawn rates of regular enemies. + This also prevents Slime Rain from occurring while a boss is alive. + Calamity is balanced around this setting being enabled. + ''' + } + + ChilledWaterRework: { + Label: "[i:ArcticDivingGear] Chilled Water Rework" + Tooltip: When enabled, water in the Snow and Ice biomes will rapidly drain the player's breath instead of inflicting Chilled. + } + + DefaultDashEnabled: { + Label: "[i:Tabi] Default Dash" + Tooltip: + ''' + Gives the player a very weak dash by default that requires no equipment or items to use. + This dash will be replaced by any other available dash, including those from other mods. + ''' + } + + EarlyHardmodeProgressionRework: { + Label: "[i:Pwnhammer] Early Hardmode Progression Rework" + Tooltip: + ''' + Demon Altars no longer spawn ores and crimson/corruption blocks when broken. + Wall of Flesh spawns Cobalt and Palladium ore on first kill. + The first mech boss you fight has 20% (10% in Expert and Master) less HP and damage and spawns Mythril and Orichalcum ore on first kill. + The second mech boss you fight has 10% (5% in Expert and Master) less HP and damage and spawns Adamantite and Titanium ore on first kill. + The third mech boss spawns Hallowed Ore on first kill. + ''' + } + + FasterBaseSpeed: { + Label: "[i:HermesBoots] Increase Base Movement Speed" + Tooltip: + ''' + Increases the player's base movement speed substantially by always giving them +50% movement speed. + This setting does nothing if the mod Terraria Overhaul is loaded. + Calamity is balanced around this setting being enabled. + ''' + } + + FasterJumpSpeed: { + Label: "[i:FrogLeg] Increase Base Jump Speed" + Tooltip: + ''' + Slightly increases the player's base jump speed. + Calamity is balanced around this setting being enabled. + ''' + } + + FasterTilePlacement: { + Label: "[i:ArchitectGizmoPack] Increase Base Building Speed" + Tooltip: + ''' + Substantially increases how rapidly the player can place tiles and walls. + This config stacks with the Brick Layer, Portable Cement Mixer and other accessories. + ''' + } + + ForceTownSafety: { + Label: "[i:Sunflower] Force Town Safety" + Tooltip: + ''' + Counteracts Expert and Master Mode allowing enemies to spawn near towns by vastly decreasing spawn rates. + This can have unintended side effects such as making critters difficult to find. + ''' + } + + HigherJumpHeight: { + Label: "[i:ShinyRedBalloon] Increase Base Jump Height" + Tooltip: + ''' + Increases the player's base jump height by 10% so that they can jump 7 tiles. + Calamity is balanced around this setting being enabled. + ''' + } + + NerfExpertDebuffs: { + Label: "[i:AnkhCharm] Remove Increased Debuff Duration" + Tooltip: + ''' + Disables Expert Mode doubling (and Master Mode tripling) the duration of debuffs on the player. + Calamity is balanced around this setting being enabled. ''' } @@ -451,6 +452,29 @@ CalamityConfig: { ''' } + PotionSelling: { + Label: "[i:SpelunkerPotion] Town NPC Potion Selling" + Tooltip: + ''' + Allows town NPCs to sell various potions. + Certain potions are sold after specific bosses have been defeated. + ''' + } + + RemoveLavaDropsFromLavaSlimes: { + Label: "[i:LavaWaders] Remove Lava Drops From Lava Slimes" + Tooltip: When enabled, Lava Slimes will be prevented from dropping lava in Expert Mode. + } + + RemoveReforgeRNG: { + Label: "[i:TinHammer] Remove Reforge RNG" + Tooltip: + ''' + Removes randomness from the Goblin Tinkerer's reforges for both weapons and accessories. + Disable this if using mods that change reforging on their own to prevent conflicts. + ''' + } + TownNPCSpawnRateMultiplier: { Label: "[i:GuideVoodooDoll] Town NPC Spawn Rate Multiplier" Tooltip: @@ -468,18 +492,4 @@ CalamityConfig: { This includes the Old Man. ''' } - - VanillaCooldownDisplay: { - Label: "[i:HealingPotion] Display Vanilla Cooldowns" - Tooltip: - ''' - Adds the vanilla debuffs Potion Sickness and Chaos State to the Cooldown Rack. - The debuffs will still appear in the buffs array, but this may help make them more visible. - ''' - } - - WikiStatusMessage: { - Label: "[i:Book] Wiki Status Message" - Tooltip: Enable or disable the status message promoting the Official Calamity Wiki that plays on world entry. - } } diff --git a/Localization/en-US/Mods.CalamityMod.GameTips.hjson b/Localization/en-US/Mods.CalamityMod.GameTips.hjson index 9d69d69161..3d5faa25c4 100644 --- a/Localization/en-US/Mods.CalamityMod.GameTips.hjson +++ b/Localization/en-US/Mods.CalamityMod.GameTips.hjson @@ -4,7 +4,6 @@ PlanetoidTip: You can find Planetoids high up in Space! AbyssTip: The Abyss can be found deep below the Sulphurous Sea. Be sure to have proper diving gear when exploring it. BanditTip: The Bandit won't steal from the poor. If you want to see them, you will need a lot of money to pique their attention. RefundTip: If you've been reforging a lot with the Goblin Tinkerer, it might pay off to give the Bandit a visit. -DrunkPrincessTip: The Drunk Princess is great to party with. If you carry her favorite vodka, she might move in. SeaKingTip: The Sea King used to like clams. He changed his mind when he got eaten by one. AmidiasBlessingTip: The Sea King can provide a bubble to aid with breathing underwater to any who ask for help. ArchmageTip: The Archmage can be freed if you manage to destroy the cell he was imprisoned in. 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..b132422b93 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 @@ -391,7 +391,7 @@ CoinofDeceit: { DisplayName: Coin of Deceit Tooltip: ''' - Stealth strikes only expend 85% of your max stealth + Stealth strikes only expend 90% of your max stealth 6% increased rogue crit chance ''' } @@ -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..60d4089e0c 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 @@ -425,7 +413,7 @@ PlagueReaperMask: { Enemies receive 10% more damage from ranged projectiles when afflicted by the Plague Getting hit causes plague cinders to rain from above Press {0} to blind yourself for 5 seconds but massively boost your ranged damage - This has a 25 second cooldown. + This has a 25 second cooldown ''' } 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..3520358d3c 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Misc.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Misc.hjson @@ -196,8 +196,8 @@ StarlightFuelCell: { } // Spawn Blockers -SpawnBlockersOn: Currently enabled -SpawnBlockersOff: Currently disabled +SpawnBlockersOn: Spawns are currently disabled +SpawnBlockersOff: Spawns are currently enabled AntiCystOintment: { DisplayName: Anti-Cyst Ointment @@ -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.DraedonsArsenal.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.DraedonsArsenal.hjson index bccef2915e..248ea0cf93 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.DraedonsArsenal.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.DraedonsArsenal.hjson @@ -158,7 +158,8 @@ PulseTurretRemote: { DisplayName: Pulse Turret Remote Tooltip: ''' - Summons a pulse turret which eradicates nearby foes with focused energy blasts + {$CommonItemTooltip.Sentry} + Summons a turret to fire explosive pulse blasts at your enemies Only one pulse turret may exist at a time ''' } diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.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..cba0e65df6 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 @@ -234,7 +224,7 @@ BrokenBiomeBlade: { Hold down while standing still on flat ground to attune the weapon to the powers of the surrounding biome Pressing otherwise switches between the current attunement and an extra stored one Main Attunement : [ATT1] - Secondary Attunement: [ATT2] + Secondary Attunement : [ATT2] ''' DefaultFunction: Does nothing... yet } @@ -845,7 +835,7 @@ OmegaBiomeBlade: { Holding down for 2 seconds attunes the weapon to the powers of the surrounding biome Pressing for a shorter period of time switches your active and passive attunements around Active Attunement : [ATT1] - Passive Attunement: [ATT2] + Passive Attunement : [ATT2] ''' DefaultFunction: ''' @@ -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' ''' @@ -1322,7 +1322,7 @@ TrueBiomeBlade: { Hold down while standing still on flat ground to attune the weapon to the powers of the surrounding biome Pressing otherwise switches between the current attunement and an extra stored one Main Attunement : [ATT1] - Secondary Attunement: [ATT2] + Secondary Attunement : [ATT2] ''' DefaultFunction: ''' diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Ranged.hjson index d15cb408ad..9dd012fb50 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: @@ -655,6 +639,7 @@ Infinity: { ''' Fires a twin stream of energy bolts that split Press to fire a barrage of normal bullets + 80% chance to save ammo 'They say infinity is neverending, yet you hold it in your hands' ''' } @@ -1110,6 +1095,7 @@ Shredder: { ''' Fires a barrage of energy bolts that split and bounce Press to fire a barrage of normal bullets instead + 60% chance to save ammo 'The myth, the legend, the weapon that drops more frames than any other' ''' } @@ -1160,9 +1146,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 +1216,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: @@ -1244,6 +1255,7 @@ Svantechnical: { ''' Fires a trinity of energy bolts that split into beams that track your cursor Press to fire a barrage of normal bullets + 90% chance to save ammo 'The age old balance of trading damage for frames' ''' } diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Rogue.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Rogue.hjson index 69ed27ce98..93277e2d1d 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' ''' } @@ -1003,20 +1003,6 @@ SealedSingularity: { ''' } -SearedPan: { - DisplayName: Seared Pan - Tooltip: - ''' - Fires a frying pan at high velocity - Enemy hits summon fireballs that linger around the target - Landing three consecutive hits will launch a golden pan on the next throw - Golden pans cause all fireballs to aggressively home in on their target on hit - Stealth strikes act similar to golden pans but also explode into golden sparks - Stealth strikes also summon additional fireballs on hit - [c/842593:'dAMaGe iS rAthEr cOnSisTeNT'] - ''' -} - Seraphim: { DisplayName: Seraphim Tooltip: diff --git a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Summon.hjson b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Summon.hjson index 2fa9a00315..5e67eebdd0 100644 --- a/Localization/en-US/Mods.CalamityMod.Items.Weapons.Summon.hjson +++ b/Localization/en-US/Mods.CalamityMod.Items.Weapons.Summon.hjson @@ -24,7 +24,8 @@ AquasScepter: { DisplayName: Aqua's Scepter Tooltip: ''' - Summons a giant storm cloud sentry to rain down on your foes, and strike nearby enemies with overloading tesla energy + {$CommonItemTooltip.Sentry} + Summons a giant storm cloud to rain down on your foes, and strike nearby enemies with overloading tesla energy 'Captain! I think- we've got a risk of rain!' ''' } @@ -44,6 +45,7 @@ AtlasMunitionsBeacon: { DisplayName: Atlas Munitions Beacon Tooltip: ''' + {$CommonItemTooltip.Sentry} [c/F2B629:Brings forth an exo-powered, stationary cannon] [c/F2B629:The cannon will fire at enemies within its range] [c/F27049:If an enemy is in close proximity, it will enter Overdrive] @@ -90,13 +92,17 @@ 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 ''' } CadaverousCarrion: { DisplayName: Cadaverous Carrion - Tooltip: Summons a gross, shark-puking Old Duke head on the ground + Tooltip: + ''' + {$CommonItemTooltip.Sentry} + Summons a gross, shark-puking Old Duke head on the ground + ''' } CalamarisLament: { @@ -115,7 +121,11 @@ CalamarisLament: { CausticCroakerStaff: { DisplayName: Caustic Croaker Staff - Tooltip: Summons a toad that explodes if enemies are nearby + Tooltip: + ''' + {$CommonItemTooltip.Sentry} + Summons a toad that explodes if enemies are nearby + ''' } CausticStaff: { @@ -214,7 +224,8 @@ CryogenicStaff: { DisplayName: Cryogenic Staff Tooltip: ''' - Summons an animated ice construct to protect you + {$CommonItemTooltip.Sentry} + Summons an ice construct to unleash the cold upon your enemies Fire rate and range increase the longer it targets an enemy ''' } @@ -277,7 +288,11 @@ DragonbloodDisgorger: { DreadmineStaff: { DisplayName: Dreadmine Staff - Tooltip: Summons a dreadmine turret to fight for you + Tooltip: + ''' + {$CommonItemTooltip.Sentry} + Summons a turret that swarms your enemies with sea mines + ''' } ElementalAxe: { @@ -420,7 +435,8 @@ GuidelightofOblivion: { DisplayName: Guidelight of Oblivion Tooltip: ''' - Summons a lantern turret to fight for you + {$CommonItemTooltip.Sentry} + Summons a lantern that swarms your enemies with flames 'Shadows dream of endless fire, flames devour and embers swoop' ''' } @@ -437,7 +453,11 @@ HerringStaff: { HivePod: { DisplayName: Hive Pod - Tooltip: Summons an astral hive to protect you + Tooltip: + ''' + {$CommonItemTooltip.Sentry} + Summons an astral hive to spawn hivelings at your enemies + ''' } IgneousExaltation: { @@ -508,7 +528,11 @@ MirrorofKalandra: { OrthoceraShell: { DisplayName: Orthocera Shell - Tooltip: Summons a flying orthocera sentry at the mouse position + Tooltip: + ''' + {$CommonItemTooltip.Sentry} + Summons a flying orthocera to spit acid streams at your enemies + ''' } Perdition: { @@ -532,7 +556,11 @@ PlantationStaff: { PolypLauncher: { DisplayName: Polyp Launcher - Tooltip: Summons a polyp bunch that launches coral chunks at nearby enemies + Tooltip: + ''' + {$CommonItemTooltip.Sentry} + Summons a polyp bunch that launches coral chunks at nearby enemies + ''' } PuffShroom: { @@ -554,14 +582,18 @@ RustyBeaconPrototype: { DisplayName: Rusty Beacon Prototype Tooltip: ''' - Summons a long-abandoned drone to support you - The drone hovers in place and releases toxic waves that irradiate hit enemies + {$CommonItemTooltip.Sentry} + Summons a long-abandoned drone that passively emits irradiated waves ''' } SanctifiedSpark: { DisplayName: Sanctified Spark - Tooltip: Summons a profaned energy turret to fight for you + Tooltip: + ''' + {$CommonItemTooltip.Sentry} + Summons a friendly immolator to fire holy sparks at your enemies + ''' } SandSharknadoStaff: { @@ -617,17 +649,26 @@ SlimePuppetStaff: { SpikecragStaff: { DisplayName: Spikecrag Staff Tooltip: "[GFB]" - TooltipNormal: Summons a spikecrag to protect you + TooltipNormal: + ''' + {$CommonItemTooltip.Sentry} + Summons a bed of stalagmites to spray spikes at your enemies + ''' TooltipGFB: ''' - Summons a spikecrag to protect you" + {$CommonItemTooltip.Sentry} + Summons a bed of stalagmites to spray spikes at your enemies Defeating the Profaned Goddess unlocks its true power ''' } SquirrelSquireStaff: { DisplayName: Squirrel Squire Staff - Tooltip: Summons a squirrel squire to fight for you + Tooltip: + ''' + {$CommonItemTooltip.Sentry} + Summons a squirrel to throw acorns at your enemies + ''' } StaffOfNecrosteocytes: { @@ -818,6 +859,7 @@ HarvestStaff: { DisplayName: Harvest Staff Tooltip: ''' + {$CommonItemTooltip.Sentry} Grows a pumpkin patch that sprouts pumpkins nearby Pumpkins will hop out when approached by nearby creatures or players Once out, they will aggressively tackle enemies, exploding on hit 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..94460c1bf3 100644 --- a/Localization/en-US/Mods.CalamityMod.Misc.hjson +++ b/Localization/en-US/Mods.CalamityMod.Misc.hjson @@ -21,6 +21,7 @@ RecipeGroup: { // Status WikiStatus1: "[i:Book] [c/EE4939:Note: The Fandom wiki is no longer supported by Calamity.] [i:Book]" WikiStatus2: "[i:Book] [c/EE4939:Check out the Official Calamity Mod Wiki at ][c/3989FF:calamitymod.wiki.gg][c/EE4939:!] [i:Book]" +VCMMStatus: "[i:MusicBoxMartians] [c/67F567:Check out the Vanilla Calamity Music Mod at ][c/3898FF:calamitymod.com/downloadvanillamusic][c/67F567:!] [i:MusicBoxMartians]" // 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..8aac0b9493 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 @@ -185,7 +185,6 @@ Rotdog.DisplayName: Rotdog ScornEater.DisplayName: Scorn Eater SeaUrchin.DisplayName: Sea Urchin ShockstormShuttle.DisplayName: Shockstorm Shuttle -SkeletronPrime2.DisplayName: Skeletron Prime Stormlion.DisplayName: Stormlion Sunskater.DisplayName: Sunskater SuperDummyNPC.DisplayName: Super Dummy @@ -274,9 +273,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 +320,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 +338,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 +444,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 +480,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 +502,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 +526,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.Rogue.hjson b/Localization/en-US/Mods.CalamityMod.Projectiles.Rogue.hjson index 3f9813d9d1..ed4a36795c 100644 --- a/Localization/en-US/Mods.CalamityMod.Projectiles.Rogue.hjson +++ b/Localization/en-US/Mods.CalamityMod.Projectiles.Rogue.hjson @@ -193,7 +193,6 @@ NanoblackSplit.DisplayName: Nanoblack Blade NanoblackStealthSplit.DisplayName: Nanoblack Afterimage NastyChollaBol.DisplayName: Nasty Cholla NastyChollaNeedle.DisplayName: Cactus Needle -NiceCock.DisplayName: Kitchen Fire NightsGazeProjectile.DisplayName: Night's Gaze NightsGazeSpark.DisplayName: Night's Gaze Spark NightsGazeStar.DisplayName: Night's Gaze Star @@ -201,7 +200,6 @@ NychthemeronOrb.DisplayName: Nychthemeron Orb NychthemeronProjectile.DisplayName: Nychthemeron OrichalcumSpikedGemstoneProjectile.DisplayName: Orichalcum Gemstone PalladiumJavelinProjectile.DisplayName: Palladium Javelin -PanSpark.DisplayName: Pan Spark PartisanExplosion.DisplayName: Profaned Explosion PenumbraBomb.DisplayName: Penumbra Bomb PenumbraSoul.DisplayName: Penumbra Soul @@ -247,7 +245,6 @@ SeafoamBubble.DisplayName: Seafoam Bubble SealedSingularityBlackhole.DisplayName: Sealed Blackhole SealedSingularityGore.DisplayName: Sealed Singularity Fragment SealedSingularityProj.DisplayName: Sealed Singularity -SearedPanProjectile.DisplayName: Pan SeraphimAngelicLight.DisplayName: Light Orb SeraphimAngelicLight2.DisplayName: Light Orb SeraphimBeamLarge.DisplayName: Holy Beam 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..745765fef4 100644 --- a/Localization/en-US/Mods.CalamityMod.UI.hjson +++ b/Localization/en-US/Mods.CalamityMod.UI.hjson @@ -14,7 +14,7 @@ StealthInfoText: Rogue stealth builds while not attacking and slower while moving Once you have built max stealth, you will be able to perform a Stealth Strike Rogue stealth only reduces when you attack, it does not reduce while moving - The higher your rogue stealth the higher your rogue damage and crit + The higher your rogue stealth the higher your rogue damage Having more stealth regeneration slightly decreases the damage bonus from stealth This is offset by you being able to use stealth strikes far more often ''' @@ -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 @@ -137,7 +138,7 @@ Evoke: Evoke Exit: Exit Communicate: Communicate ConfirmationText: Are you sure? -UpgradesRequired: Encryption unsolveable: Upgrades required. +UpgradesRequired: Encryption unsolvable: Upgrades required. ThanatosIcon: Thanatos, a serpentine terror with impervious armor and innumerable laser turrets. AresIcon: Ares, a heavyweight, diabolical monstrosity with four Exo superweapons. ArtemisApolloIcon: Artemis and Apollo, a pair of extremely persistent automatons with unstable energy reserves. 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/ModCalls.cs b/ModSupport/ModCalls.cs index 09288e3327..3ec60468df 100644 --- a/ModSupport/ModCalls.cs +++ b/ModSupport/ModCalls.cs @@ -2163,7 +2163,7 @@ bool castID(object o, out int id) case "GetBossHealthBoost": case "BossHealthMultiplier": case "GetBossHealthMultiplier": - return CalamityConfig.Instance.BossHealthBoost; + return CalamityServerConfig.Instance.BossHealthBoost; case "HasPermanentPowerup": case "GetPermanentPowerup": diff --git a/ModSupport/WeakReferenceSupport.cs b/ModSupport/WeakReferenceSupport.cs index 16293e26d9..6aba7efb99 100644 --- a/ModSupport/WeakReferenceSupport.cs +++ b/ModSupport/WeakReferenceSupport.cs @@ -206,6 +206,54 @@ public static void Setup() } } + #region BiomeLava + public static void LavaStytleToBiomeLava() + { + CalamityMod calamity = GetInstance(); + Mod biomelava = calamity.biomeLava; + if (biomelava == null) + return; + + foreach (ModLavaStyle item in LavaStylesLoader.Content) + { + int type = item.Slot; + ModLavaStyle lavaStyle = LavaStylesLoader.Get(type); + if (lavaStyle != null) + { + Func GetSplashDust = lavaStyle.GetSplashDust; + Func GetDropletGore = lavaStyle.GetDropletGore; + Func ModifyLightFunc = ModifyLight; + Func IsLavaActive = lavaStyle.IsLavaActive; + Func lavafallGlowmask = lavaStyle.LavafallGlowmask; + Func InflictDebuffFunc = InflictDebuff; + Func yes = InflictsOnFire; + + Vector3 ModifyLight(int x, int y, float r, float g, float b) + { + lavaStyle.ModifyLight(x, y, ref r, ref g, ref b); + return new Vector3(r, g, b); + } + + Action InflictDebuff(Player player, NPC npc, int onfireDuration) + { + if (player != null && npc == null) + { + lavaStyle.InflictDebuff(player, onfireDuration); + } + return null; + } + + bool InflictsOnFire() + { + return true; + } + + biomelava.Call("ModLavaStyle", calamity, lavaStyle.Name, lavaStyle.Texture, lavaStyle.BlockTexture, lavaStyle.SlopeTexture, lavaStyle.WaterfallTexture, GetSplashDust, GetDropletGore, ModifyLightFunc, IsLavaActive, lavafallGlowmask, InflictDebuffFunc, yes); + } + } + } + #endregion + #region WikiThis // This is a separate function because it only runs clientside public static void WikiThisSupport() @@ -235,7 +283,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 @@ -420,9 +467,11 @@ private static void AddCalamityBosses(Mod bossChecklist, Mod calamity) string entryName = "HiveMind"; BossChecklistProgressionValues.TryGetValue(entryName, out float order); int type = NPCType(); + Func IsCorruption = () => !WorldGen.crimson || Main.drunkWorld; List collection = new List() { ItemType(), ItemType(), ItemType(), ItemType(), ItemType(), ItemType() }; AddBoss(bossChecklist, calamity, entryName, order, DownedHiveMind, type, new Dictionary() { + ["availability"] = IsCorruption, ["spawnInfo"] = GetSpawnInfo(entryName), ["despawnMessage"] = GetDespawnMessage(entryName), ["spawnItems"] = ItemType(), @@ -436,9 +485,11 @@ private static void AddCalamityBosses(Mod bossChecklist, Mod calamity) string entryName = "Perforators"; BossChecklistProgressionValues.TryGetValue(entryName, out float order); int type = NPCType(); + Func IsCrimson = () => WorldGen.crimson || Main.drunkWorld; List collection = new List() { ItemType(), ItemType(), ItemType(), ItemType(), ItemType(), ItemType() }; AddBoss(bossChecklist, calamity, entryName, order, DownedPerforators, type, new Dictionary() { + ["availability"] = IsCrimson, ["displayName"] = GetDisplayName(entryName), ["spawnInfo"] = GetSpawnInfo(entryName), ["despawnMessage"] = GetDespawnMessage(entryName), diff --git a/NPCs/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..ffe90598c0 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"); @@ -37,7 +38,7 @@ public override void SetDefaults() if (CalamityWorld.LegendaryMode && CalamityWorld.revenge) NPC.lifeMax *= 2; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.behindTiles = true; NPC.noGravity = true; diff --git a/NPCs/AquaticScourge/AquaticScourgeBodyAlt.cs b/NPCs/AquaticScourge/AquaticScourgeBodyAlt.cs index 6a2871b0a2..920eed7664 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"); @@ -36,7 +37,7 @@ public override void SetDefaults() if (CalamityWorld.LegendaryMode && CalamityWorld.revenge) NPC.lifeMax *= 2; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.behindTiles = true; NPC.noGravity = true; diff --git a/NPCs/AquaticScourge/AquaticScourgeHead.cs b/NPCs/AquaticScourge/AquaticScourgeHead.cs index 01e9e94ab5..eb33d7b299 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() @@ -64,7 +65,7 @@ public override void SetDefaults() if (CalamityWorld.LegendaryMode && CalamityWorld.revenge) NPC.lifeMax *= 2; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.value = Item.buyPrice(0, 40, 0, 0); diff --git a/NPCs/AquaticScourge/AquaticScourgeTail.cs b/NPCs/AquaticScourge/AquaticScourgeTail.cs index 5b7217d8c0..a147d7e144 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"); @@ -36,7 +37,7 @@ public override void SetDefaults() if (CalamityWorld.LegendaryMode && CalamityWorld.revenge) NPC.lifeMax *= 2; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.behindTiles = true; NPC.noGravity = true; diff --git a/NPCs/AstrumAureus/AstrumAureus.cs b/NPCs/AstrumAureus/AstrumAureus.cs index c2222cc170..1e5440cdd1 100644 --- a/NPCs/AstrumAureus/AstrumAureus.cs +++ b/NPCs/AstrumAureus/AstrumAureus.cs @@ -102,7 +102,7 @@ public override void SetDefaults() NPC.value = Item.buyPrice(0, 60, 0, 0); NPC.boss = true; NPC.DeathSound = DeathSound; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.Calamity().VulnerableToHeat = true; NPC.Calamity().VulnerableToSickness = false; @@ -317,7 +317,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d if (NPC.ai[0] == 3f || NPC.ai[0] == 4f) afterimageAmt = 10; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -347,7 +347,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d attackingColor = slimePhase == 0 ? Color.Violet : Color.Yellow; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { @@ -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/AstrumAureus/AureusSpawn.cs b/NPCs/AstrumAureus/AureusSpawn.cs index 379d8a9e6d..e9dec231b7 100644 --- a/NPCs/AstrumAureus/AureusSpawn.cs +++ b/NPCs/AstrumAureus/AureusSpawn.cs @@ -43,7 +43,7 @@ public override void SetDefaults() NPC.Opacity = 0f; NPC.defense = 10; NPC.lifeMax = 5000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.dontTakeDamage = true; @@ -246,7 +246,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color whiteColor = Color.White; int afterimageAmt = 10; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -269,7 +269,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture2D15 = GlowTexture.Value; Color afterimageColorLerp = Color.Lerp(Color.White, Color.Orange, 0.5f) * NPC.Opacity; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/AstrumDeus/AstrumDeusBody.cs b/NPCs/AstrumDeus/AstrumDeusBody.cs index dfc682dcb0..845ba253ca 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"); @@ -52,7 +53,7 @@ public override void SetDefaults() NPC.defense = 35; NPC.DR_NERD(0.25f); NPC.LifeMaxNERB(200000, 240000, 650000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/AstrumDeus/AstrumDeusHead.cs b/NPCs/AstrumDeus/AstrumDeusHead.cs index f814c85120..3082f52d60 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"); @@ -81,7 +82,7 @@ public override void SetDefaults() NPC.defense = 20; NPC.DR_NERD(0.1f); NPC.LifeMaxNERB(200000, 240000, 650000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/AstrumDeus/AstrumDeusTail.cs b/NPCs/AstrumDeus/AstrumDeusTail.cs index 3a3a2f1004..c1554947d1 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"); @@ -42,7 +43,7 @@ public override void SetDefaults() NPC.defense = 50; NPC.DR_NERD(0.4f); NPC.LifeMaxNERB(200000, 240000, 650000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/BrimstoneElemental/Brimling.cs b/NPCs/BrimstoneElemental/Brimling.cs index f4fc581261..d56ca21cb8 100644 --- a/NPCs/BrimstoneElemental/Brimling.cs +++ b/NPCs/BrimstoneElemental/Brimling.cs @@ -45,7 +45,7 @@ public override void SetDefaults() { NPC.lifeMax = 10000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.Calamity().VulnerableToHeat = false; NPC.Calamity().VulnerableToCold = true; diff --git a/NPCs/BrimstoneElemental/BrimstoneElemental.cs b/NPCs/BrimstoneElemental/BrimstoneElemental.cs index 39e33068b0..c7d6d7ed6a 100644 --- a/NPCs/BrimstoneElemental/BrimstoneElemental.cs +++ b/NPCs/BrimstoneElemental/BrimstoneElemental.cs @@ -68,7 +68,7 @@ public override void SetDefaults() NPC.value = Item.buyPrice(0, 40, 0, 0); NPC.LifeMaxNERB(41000, 49200, 780000); NPC.DR_NERD(0.15f); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.aiStyle = -1; diff --git a/NPCs/Bumblebirb/Bumblefuck.cs b/NPCs/Bumblebirb/Bumblefuck.cs index e88ddfb475..12863fa314 100644 --- a/NPCs/Bumblebirb/Bumblefuck.cs +++ b/NPCs/Bumblebirb/Bumblefuck.cs @@ -71,7 +71,7 @@ public override void SetDefaults() NPC.defense = 40; NPC.DR_NERD(0.1f); NPC.LifeMaxNERB(187500, 225000, 300000); // Old HP - 227500, 252500 - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.boss = true; @@ -278,7 +278,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d color = altColor; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += afterimageIncrement) { @@ -331,7 +331,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d } } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 0; j < extraAfterimageAmt; j++) { @@ -373,7 +373,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d glowmaskColor *= glowmaskDampener; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int k = 1; k < afterimageAmt; k += afterimageIncrement) { diff --git a/NPCs/Bumblebirb/Bumblefuck2.cs b/NPCs/Bumblebirb/Bumblefuck2.cs index b79d7fb64a..b4e18592d6 100644 --- a/NPCs/Bumblebirb/Bumblefuck2.cs +++ b/NPCs/Bumblebirb/Bumblefuck2.cs @@ -33,7 +33,7 @@ public override void SetDefaults() NPC.height = 80; NPC.defense = 20; NPC.LifeMaxNERB(9375, 11250, 5000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.15f; NPC.lavaImmune = true; @@ -106,7 +106,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2(TextureAssets.Npc[NPC.type].Value.Width / 2, TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2); int afterimageAmt = NPC.ai[0] == 2.1f ? 7 : 0; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { diff --git a/NPCs/CalClone/CalamitasClone.cs b/NPCs/CalClone/CalamitasClone.cs index c3c1dd0cbc..5853969837 100644 --- a/NPCs/CalClone/CalamitasClone.cs +++ b/NPCs/CalClone/CalamitasClone.cs @@ -70,7 +70,7 @@ public override void SetDefaults() NPC.value = Item.buyPrice(0, 50, 0, 0); NPC.DR_NERD((CalamityWorld.death || BossRushEvent.BossRushActive) ? 0.075f : 0.15f); NPC.LifeMaxNERB(37500, 45000, 520000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -142,7 +142,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d float colorLerpAmt = 0.5f; int afterimageAmt = 7; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -169,7 +169,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d color = Color.CornflowerBlue; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i++) { diff --git a/NPCs/CalClone/Cataclysm.cs b/NPCs/CalClone/Cataclysm.cs index 80b173cc83..257e7143cd 100644 --- a/NPCs/CalClone/Cataclysm.cs +++ b/NPCs/CalClone/Cataclysm.cs @@ -55,7 +55,7 @@ public override void SetDefaults() NPC.defense = (CalamityWorld.death || BossRushEvent.BossRushActive) ? 15 : 10; NPC.DR_NERD((CalamityWorld.death || BossRushEvent.BossRushActive) ? 0.225f : 0.15f); NPC.LifeMaxNERB(11000, 13200, 80000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -117,7 +117,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2((float)(TextureAssets.Npc[NPC.type].Value.Width / 2), (float)(TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2)); int afterimageAmt = 7; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -140,7 +140,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture2D15 = GlowTexture.Value; Color pinkLerp = Color.Lerp(Color.White, Color.Red, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/CalClone/Catastrophe.cs b/NPCs/CalClone/Catastrophe.cs index c06986998d..a189db22f8 100644 --- a/NPCs/CalClone/Catastrophe.cs +++ b/NPCs/CalClone/Catastrophe.cs @@ -55,7 +55,7 @@ public override void SetDefaults() NPC.defense = (CalamityWorld.death || BossRushEvent.BossRushActive) ? 15 : 10; NPC.DR_NERD((CalamityWorld.death || BossRushEvent.BossRushActive) ? 0.225f : 0.15f); NPC.LifeMaxNERB(9200, 11025, 80000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -117,7 +117,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2((float)(TextureAssets.Npc[NPC.type].Value.Width / 2), (float)(TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2)); int afterimageAmt = 7; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -140,7 +140,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture2D15 = GlowTexture.Value; Color pinkLerp = Color.Lerp(Color.White, Color.Red, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/CalClone/SoulSeeker.cs b/NPCs/CalClone/SoulSeeker.cs index adbefe7503..7158e8b378 100644 --- a/NPCs/CalClone/SoulSeeker.cs +++ b/NPCs/CalClone/SoulSeeker.cs @@ -47,7 +47,7 @@ public override void SetDefaults() { NPC.lifeMax = 15000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.HitSound = SoundID.NPCHit4; NPC.DeathSound = SoundID.NPCDeath14; @@ -197,7 +197,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d float colorLerpAmt = 0.5f; int afterImageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int a = 1; a < afterImageAmt; a += 2) { @@ -220,7 +220,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture = GlowTexture.Value; Color glow = Color.Lerp(Color.White, Color.Red, colorLerpAmt); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int a = 1; a < afterImageAmt; a++) { diff --git a/NPCs/CalamityAIs/CalamityBossAIs/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/CeaselessVoidAI.cs b/NPCs/CalamityAIs/CalamityBossAIs/CeaselessVoidAI.cs index e33ab45fd9..4f455fd547 100644 --- a/NPCs/CalamityAIs/CalamityBossAIs/CeaselessVoidAI.cs +++ b/NPCs/CalamityAIs/CalamityBossAIs/CeaselessVoidAI.cs @@ -390,7 +390,7 @@ public static void VanillaCeaselessVoidAI(NPC npc, Mod mod) // Destroy all Dark Energies if their total HP is below 20% int darkEnergyMaxHP = bossRush ? DarkEnergy.MaxBossRushHP : DarkEnergy.MaxHP; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; darkEnergyMaxHP += (int)(darkEnergyMaxHP * HPBoost); int totalDarkEnergiesSpawned = darkEnergyAmt * 3 + 2; int totalDarkEnergyMaxHP = darkEnergyMaxHP * totalDarkEnergiesSpawned; diff --git a/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs b/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs index 7383afb7d4..8f9527ab27 100644 --- a/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs +++ b/NPCs/CalamityAIs/CalamityBossAIs/OldDukeAI.cs @@ -68,9 +68,9 @@ public static void VanillaOldDukeAI(NPC npc, Mod mod) float greenLight = (phase3AI ? 1.2f : phase2AI ? 0.8f : 0.4f) * alphaScale; Lighting.AddLight((int)((npc.position.X + (npc.width / 2)) / 16f), (int)((npc.position.Y + (npc.height / 2)) / 16f), redLight, greenLight, 0f); - if (CalamityConfig.Instance.BossesStopWeather) + if (CalamityServerConfig.Instance.BossesStopWeather) CalamityMod.StopRain(); - else if (!Main.raining) + 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..bb36382de6 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) @@ -1415,10 +1414,9 @@ private void RevDeathStatChanges(NPC npc, Mod mod) npc.scale *= Main.zenithWorld ? 2f : CalamityWorld.death ? 1.4f : 1.2f; } - else if (npc.type == NPCID.SkeletronPrime || npc.type == ModContent.NPCType()) + else if (npc.type == NPCID.SkeletronPrime) { - // HP boosted in Master Mode due to having two heads (piercing can make them die faster than normal here since they share an HP bar) - npc.lifeMax = (int)Math.Round(npc.lifeMax * (Main.masterMode ? 1.7 : 1.2)); + npc.lifeMax = (int)Math.Round(npc.lifeMax * 1.2); npc.npcSlots = 12f; } else if (npc.type <= NPCID.PrimeLaser && npc.type >= NPCID.PrimeCannon) @@ -1521,8 +1519,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. @@ -2234,7 +2232,7 @@ private void OtherStatChanges(NPC npc) if ((npc.boss && npc.type != NPCID.MartianSaucerCore) || CalamityLists.bossHPScaleList.Contains(npc.type)) { - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; npc.lifeMax += (int)Math.Round(npc.lifeMax * HPBoost); } } @@ -2438,7 +2436,7 @@ private void OtherStatChanges(NPC npc) } // Reduce mech boss HP and damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { if (!NPC.downedMechBossAny) { @@ -3097,7 +3095,7 @@ public static void DrawAfterimage(NPC npc, SpriteBatch spriteBatch, Color starti Texture2D npcTexture = texture ?? TextureAssets.Npc[npc.type].Value; Vector2 screenOffset = npc.IsABestiaryIconDummy ? Vector2.Zero : Main.screenPosition; int afterimageCounter = 1; - while (afterimageCounter < NPCID.Sets.TrailCacheLength[npc.type] && CalamityConfig.Instance.Afterimages) + while (afterimageCounter < NPCID.Sets.TrailCacheLength[npc.type] && CalamityClientConfig.Instance.Afterimages) { Color colorToDraw = Color.Lerp(drawColor, endingColor, afterimageCounter / (float)NPCID.Sets.TrailCacheLength[npc.type]); colorToDraw *= afterimageCounter / (float)NPCID.Sets.TrailCacheLength[npc.type]; @@ -3222,17 +3220,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; @@ -3268,10 +3266,6 @@ private float DefaultDRMath(NPC npc, float DR) calcDR *= 0.5f; if (absorberAffliction > 0) calcDR *= 0.8f; - if (npc.betsysCurse) - calcDR *= 0.66f; - if (npc.Calamity().kamiFlu > 0) - calcDR *= KamiFlu.MultiplicativeDamageReduction; if (npc.Calamity().aCrunch > 0) calcDR *= ArmorCrunch.MultiplicativeDamageReductionEnemy; if (npc.Calamity().crumble > 0) @@ -5066,8 +5060,6 @@ public override void PostAI(NPC npc) webbed--; if (slowed > 0) slowed--; - if (kamiFlu > 0) - kamiFlu--; if (vaporfied > 0) vaporfied--; @@ -5079,6 +5071,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 +5120,6 @@ public override void PostAI(NPC npc) sulphurPoison--; if (sagePoisonTime > 0) sagePoisonTime--; - if (kamiFlu > 0) - kamiFlu--; if (relicOfResilienceCooldown > 0) relicOfResilienceCooldown--; if (relicOfResilienceWeakness > 0) @@ -5134,8 +5128,6 @@ public override void PostAI(NPC npc) GaussFluxTimer--; if (ladHearts > 0) ladHearts--; - if (vulnerabilityHex > 0) - vulnerabilityHex--; if (banishingFire > 0) banishingFire--; if (wither > 0) @@ -5210,10 +5202,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)); - } } } @@ -5602,7 +5590,7 @@ public override void ModifyHitByProjectile(NPC npc, Projectile projectile, ref N if (!projectile.npcProj && !projectile.trap) { if (projectile.CountsAsClass() && modPlayer.plagueReaper && pFlames > 0) - modifiers.SourceDamage *= 1.1f; + modifiers.TargetDamageMultiplier *= 1.1f; } // Any weapons that shoot projectiles from anywhere other than the player's center aren't affected by point-blank shot damage boost. @@ -5739,26 +5727,6 @@ private void EditWhipTagDamage(Projectile proj, NPC npc, ref NPC.HitModifiers mo #region Check Dead public override bool CheckDead(NPC npc) { - if (npc.type == NPCID.SkeletronPrime) - { - if ((Main.masterMode || BossRushEvent.BossRushActive) && CalamityWorld.revenge) - { - // Kill the other head if he's still alive when this head dies - for (int i = 0; i < Main.maxNPCs; i++) - { - NPC nPC = Main.npc[i]; - if (nPC.active && nPC.type == ModContent.NPCType() && nPC.life > 0) - { - nPC.life = 0; - nPC.HitEffect(); - nPC.checkDead(); - nPC.active = false; - nPC.netUpdate = true; - } - } - } - } - if (npc.lifeMax > 1000 && npc.type != NPCID.DungeonSpirit && npc.type != NPCType() && npc.type != NPCType() && @@ -6012,17 +5980,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) { @@ -6039,12 +5996,12 @@ public override void EditSpawnRate(Player player, ref int spawnRate, ref int max spawnRate = (int)(spawnRate * 1.4); maxSpawns = (int)(maxSpawns * 0.4f); } - if (player.Calamity().zen || (CalamityConfig.Instance.ForceTownSafety && player.townNPCs > 1f && Main.expertMode)) + if (player.Calamity().zen || (CalamityServerConfig.Instance.ForceTownSafety && player.townNPCs > 1f && Main.expertMode)) { spawnRate = (int)(spawnRate * 2.5); maxSpawns = (int)(maxSpawns * 0.3f); } - if (player.Calamity().isNearbyBoss && CalamityConfig.Instance.BossZen) + if (player.Calamity().isNearbyBoss && CalamityServerConfig.Instance.BossZen) { spawnRate *= 5; maxSpawns = (int)(maxSpawns * 0.001f); @@ -6145,13 +6102,6 @@ public override void EditSpawnPool(IDictionary pool, NPCSpawnInfo sp spawnInfo.Player.Calamity().ZoneSunkenSea || (spawnInfo.Player.Calamity().ZoneAstral && !spawnInfo.Player.PillarZone()); - // Replace vanilla Lava Slimes with Calamity Lava Slimes to avoid annoying lava drops - if (spawnInfo.Player.ZoneUnderworldHeight && !calamityBiomeZone && CalamityConfig.Instance.RemoveLavaDropsFromLavaSlimes && Main.expertMode) - { - pool.Add(NPCType(), SpawnCondition.Underworld.Chance); - pool.Remove(NPCID.LavaSlime); - } - // Spawn Green Jellyfish in prehm and Blue Jellyfish in hardmode if (spawnInfo.Player.ZoneRockLayerHeight && spawnInfo.Water && !calamityBiomeZone) { @@ -6190,8 +6140,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; @@ -6336,11 +6285,11 @@ public override void OnSpawn(NPC npc, IEntitySource source) #region Drawing public override void FindFrame(NPC npc, int frameHeight) { - if (CalamityWorld.revenge || BossRushEvent.BossRushActive) + /*if (CalamityWorld.revenge || BossRushEvent.BossRushActive) { - if (npc.type == NPCID.SkeletronPrime || npc.type == ModContent.NPCType()) + if (npc.type == NPCID.SkeletronPrime) npc.frameCounter = 0D; - } + }*/ } // Debuff visuals. Alphabetical order as per usual, please @@ -6383,6 +6332,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 +6510,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 +6531,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 +6555,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), @@ -6615,7 +6568,7 @@ public override bool PreDraw(NPC npc, SpriteBatch spriteBatch, Vector2 screenPos { if (npc.type != NPCID.BrainofCthulhu && (npc.type != NPCID.DukeFishron || npc.ai[0] <= 9f) && npc.active) { - if (CalamityConfig.Instance.DebuffDisplay && (npc.boss || BossHealthBarManager.MinibossHPBarList.Contains(npc.type) || BossHealthBarManager.OneToMany.ContainsKey(npc.type) || CalamityLists.needsDebuffIconDisplayList.Contains(npc.type))) + if (CalamityClientConfig.Instance.DebuffDisplay && (npc.boss || BossHealthBarManager.MinibossHPBarList.Contains(npc.type) || BossHealthBarManager.OneToMany.ContainsKey(npc.type) || CalamityLists.needsDebuffIconDisplayList.Contains(npc.type))) { List currentDebuffs = new List() { }; @@ -6736,8 +6689,43 @@ public override bool PreDraw(NPC npc, SpriteBatch spriteBatch, Vector2 screenPos if (CalamityWorld.revenge || BossRushEvent.BossRushActive) { - if (npc.type == NPCID.SkeletronPrime || npc.type == ModContent.NPCType() || CalamityLists.DestroyerIDs.Contains(npc.type)) + if (CalamityLists.DestroyerIDs.Contains(npc.type)) return false; + + // Allows correct frames to draw in Rev+ phases + // GFB can rot for all I care + if (npc.type == NPCID.SkeletronPrime && !NPC.IsMechQueenUp) + { + int frameHeight = TextureAssets.Npc[npc.type].Value.Height / Main.npcFrameCount[npc.type]; + if (npc.ai[1] == 0f || npc.ai[1] == 4f) + { + newAI[2] += 1f; + if (newAI[2] >= 12f) + { + newAI[2] = 0f; + newAI[3] += frameHeight; + + if (newAI[3] / frameHeight >= 2f) + newAI[3] = 0f; + } + } + + // Spinning probe spawn or fly over phase + else if (npc.ai[1] == 5f || npc.ai[1] == 6f) + { + newAI[2] = 0f; + newAI[3] = frameHeight; + } + + // Spinning phase + else + { + newAI[2] = 0f; + newAI[3] = frameHeight * 2; + } + + npc.frame.Y = (int)newAI[3]; + } } if (npc.type == NPCID.GolemHeadFree) @@ -7141,7 +7129,7 @@ public override void PostDraw(NPC npc, SpriteBatch spriteBatch, Vector2 screenPo } } - Texture2D glowTexture = CalamityConfig.Instance.NewVanillaTextures ? CalamityMod.DestroyerGlowmasks[0].Value : TextureAssets.Dest[0].Value; + Texture2D glowTexture = CalamityClientConfig.Instance.NewVanillaTextures ? CalamityMod.DestroyerGlowmasks[0].Value : TextureAssets.Dest[0].Value; switch (npc.type) { default: @@ -7149,11 +7137,11 @@ public override void PostDraw(NPC npc, SpriteBatch spriteBatch, Vector2 screenPo break; case NPCID.TheDestroyerBody: - glowTexture = CalamityConfig.Instance.NewVanillaTextures ? CalamityMod.DestroyerGlowmasks[1].Value : TextureAssets.Dest[1].Value; + glowTexture = CalamityClientConfig.Instance.NewVanillaTextures ? CalamityMod.DestroyerGlowmasks[1].Value : TextureAssets.Dest[1].Value; break; case NPCID.TheDestroyerTail: - glowTexture = CalamityConfig.Instance.NewVanillaTextures ? CalamityMod.DestroyerGlowmasks[2].Value : TextureAssets.Dest[2].Value; + glowTexture = CalamityClientConfig.Instance.NewVanillaTextures ? CalamityMod.DestroyerGlowmasks[2].Value : TextureAssets.Dest[2].Value; break; } @@ -7455,7 +7443,7 @@ public override void PostDraw(NPC npc, SpriteBatch spriteBatch, Vector2 screenPo float eyeTelegraphGateValue = WallOfFleshAI.LaserShootGateValue - WallOfFleshAI.LaserShootTelegraphTime; if (npc.localAI[1] > eyeTelegraphGateValue || npc.localAI[2] > 0f || enraged) { - Texture2D glowTexture = CalamityConfig.Instance.NewVanillaTextures ? CalamityMod.WallOfFleshEyeGlowmask.Value : TextureAssets.Npc[npc.type].Value; + Texture2D glowTexture = CalamityClientConfig.Instance.NewVanillaTextures ? CalamityMod.WallOfFleshEyeGlowmask.Value : TextureAssets.Npc[npc.type].Value; Vector2 halfSize = npc.frame.Size() / 2; SpriteEffects spriteEffects = SpriteEffects.None; if (npc.spriteDirection == 1) @@ -7474,83 +7462,6 @@ public override void PostDraw(NPC npc, SpriteBatch spriteBatch, Vector2 screenPo } } - // His afterimages I can't get to work, so fuck it - else if (npc.type == NPCID.SkeletronPrime || npc.type == ModContent.NPCType()) - { - Texture2D npcTexture = (masterMode && revenge && npc.type == NPCID.SkeletronPrime) ? CalamityMod.ChadPrime.Value : TextureAssets.Npc[npc.type].Value; - int frameHeight = npcTexture.Height / Main.npcFrameCount[npc.type]; - - npc.frame.Y = (int)newAI[3]; - - // Mechdusa drawing - if (NPC.IsMechQueenUp) - { - if (npc.ai[1] == 0f || npc.ai[1] == 4f) - { - newAI[2] += 1f; - if (newAI[2] >= 12f) - { - newAI[2] = 0f; - newAI[3] += frameHeight; - if (newAI[3] / frameHeight >= 5) - newAI[3] = frameHeight * 3; - } - } - else - { - newAI[2] = 0f; - newAI[3] = frameHeight * 5; - } - } - - // Floating phase - else if (npc.ai[1] == 0f || npc.ai[1] == 4f) - { - newAI[2] += 1f; - if (newAI[2] >= 12f) - { - newAI[2] = 0f; - newAI[3] += frameHeight; - - if (newAI[3] / frameHeight >= 2f) - newAI[3] = 0f; - } - } - - // Spinning probe spawn or fly over phase - else if (npc.ai[1] == 5f || npc.ai[1] == 6f) - { - newAI[2] = 0f; - newAI[3] = frameHeight; - } - - // Spinning phase - else - { - newAI[2] = 0f; - newAI[3] = frameHeight * 2; - } - - npc.frame.Y = (int)newAI[3]; - - SpriteEffects spriteEffects = SpriteEffects.None; - if (npc.spriteDirection == 1) - spriteEffects = SpriteEffects.FlipHorizontally; - - spriteBatch.Draw(npcTexture, npc.Center - screenPos + new Vector2(0, npc.gfxOffY), npc.frame, npc.GetAlpha(drawColor), npc.rotation, npc.frame.Size() / 2, npc.scale, spriteEffects, 0f); - - Color eyesColor = new Color(200, 200, 200, 0); - if (masterMode && revenge) - { - int alpha = 192; - eyesColor = npc.type == NPCType() ? new Color(150, 100, 255, alpha) : new Color(255, 255, 0, alpha); - Texture2D glowTexture = npc.type == NPCID.SkeletronPrime ? CalamityMod.ChadPrimeEyeGlowmask.Value : SkeletronPrime2.EyeTexture.Value; - spriteBatch.Draw(glowTexture, npc.Center - screenPos + new Vector2(0, npc.gfxOffY), npc.frame, eyesColor, npc.rotation, npc.frame.Size() / 2, npc.scale, spriteEffects, 0f); - } - else - spriteBatch.Draw(TextureAssets.BoneEyes.Value, npc.Center - screenPos + new Vector2(0, npc.gfxOffY), npc.frame, eyesColor, npc.rotation, npc.frame.Size() / 2, npc.scale, spriteEffects, 0f); - } - else if (npc.type == NPCID.Plantera) { // Percent life remaining @@ -7607,7 +7518,7 @@ public override void PostDraw(NPC npc, SpriteBatch spriteBatch, Vector2 screenPo float telegraphScalar = MathHelper.Clamp((Math.Abs(PlanteraAI.StopChargeGateValue) - telegraphTimer) / Math.Abs(PlanteraAI.StopChargeGateValue), 0f, 1f); Color telegraphColor = Color.Lerp(originalColor, newColor, telegraphScalar); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { int afterimageAmount = 10; int afterImageIncrement = 2; diff --git a/NPCs/CalamityGlobalNPCLoot.cs b/NPCs/CalamityGlobalNPCLoot.cs index 6b875b8cad..846f59a6e0 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 @@ -1813,7 +1856,7 @@ public override void OnKill(NPC npc) if (!Main.hardMode) { // Increase altar count to allow natural mech boss spawning. - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework) WorldGen.altarCount++; string key2 = "Mods.CalamityMod.Status.Progression.UglyBossText"; @@ -1834,10 +1877,10 @@ 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) + if (!NPC.downedMechBoss1 && CalamityServerConfig.Instance.EarlyHardmodeProgressionRework) SpawnMechBossHardmodeOres(); break; @@ -1846,25 +1889,25 @@ 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) + if (!NPC.downedMechBoss2 && CalamityServerConfig.Instance.EarlyHardmodeProgressionRework) SpawnMechBossHardmodeOres(); } break; 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) + if (!NPC.downedMechBoss3 && CalamityServerConfig.Instance.EarlyHardmodeProgressionRework) SpawnMechBossHardmodeOres(); 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..653160791d 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,10 +66,10 @@ public static float TaxYieldFactor "Dazren", "Johnny Test", // <@!589966747977777197> (konorango) "Bling Bling Boy", // <@!522970788203069442> (phallguy) + "RICE", // <@!400107830889152524> (rice_xd.) }; private static readonly string[] ArmsDealerNames = { - "Drifter", "Finchi", "Heniek", // <@!363404700445442050> (kazurgundu) "Fire", // <@!354362326947856384> (ultimatefirewaster) @@ -77,7 +77,6 @@ public static float TaxYieldFactor "XiaoEn0426", // <@!440448864772816896> (xiaoen0426) "Jeffred", // <@!295362230038560768> (paladinsamuel) "The Cooler Arthur", // <@!568263512523014154> (gokuartillery) - "Markie", // <@!291141964039061504> (markie_) "Shark", // <@!874464051697172492> (congratsistrash) "Sagi", // <@!508233115781693441> (sagittariod) }; @@ -85,16 +84,19 @@ public static float TaxYieldFactor { "Joeseph Jostar", "Storm Havik", // <@!1013452363178197072> (fishnotduck) + "Magorfis Splunt the Greater Finklejim", // <@!147490809334333440> (eidolbyssus) + "Perrin", // <@!253764551139393537> (easyperrin) }; private static readonly string[] CyborgNames = { "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 = { @@ -103,6 +105,7 @@ public static float TaxYieldFactor "Jasmine", // <@!430532867479699456> (phantasmagoria.) "Cybil", // <@!486507232666845185> (Captain Doofus#????) "Ruth", // <@!1001307586068492388> (briny_coffee) + "Kanna", // <@!730203712898859018> (cosmoredeathwish) }; private static readonly string[] DyeTraderNames = null; private static readonly string[] GoblinTinkererNames = @@ -117,6 +120,9 @@ 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) + "Gobby, Destroyer of Wallets", // <@!429024941296582658> (bwlstorm) }; private static readonly string[] GolferNames = null; private static readonly string[] GuideNames = @@ -136,7 +142,9 @@ 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. + "Baggute", // <@!535140564174110720> (thebaggutegamer) }; private static readonly string[] MechanicNames = { @@ -144,25 +152,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,37 +182,53 @@ 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) + "Yarrim", // <@!290061123137306624> (borb9834) + "Hector Barbossa", // <@!615704209303797790> (thatrockisfullamagic) + "Blunderbeard", // <@!1039460813490102293> (parmiigianoreggiano) }; private static readonly string[] PrincessNames = { - "Catalyst", // <@!156672312425316352> (xaqult) "Nyapano", // <@!120976656826368003> (nyapano) "Jade", // <@!187395834625785869> (verymasterninja) "Nyavi Aceso", // <@!270260920888852480> (navigator.) "everquartz", // <@!451343554451865611> (everquartz) "Gwynevere", // <@!142752927348424704> (nuclearchaosazathoth) + "Hael", // <@!641747280944431156> (kalebtull) + "Yumesaki Mirrin", // <@!100235144744415232> (milinen) + "Vela", // <@!208719047146209281> (nyxxynightstar) }; private static readonly string[] SantaClausNames = { "Jank", // <@!339950757472239616> (jankle_) + "Aoi Kurashiki", // <@!358411687885537291> (nothinpurrsonal) }; private static readonly string[] SkeletonMerchantNames = { - "Sans Undertale", // <@!145379091648872450> (shayy) + "Sans Undertale", // <@!534770496038895616> (done_22_) "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) + "Kreutz", // <@!553445849149997056> (red_r_kreutz) + "Cathlyn", // <@!156672312425316352> (xaqult) }; private static readonly string[] StylistNames = { "Amber", // <@!114677116473180169> (mishirousui) "Faith", // <@!509050283871961123> (toasty1007) "Xsiana", // <@!625780237489143839> (lokistic) + "Lain", // <@!655201622863118337> (literallyadeerfr) + "Hamis", // <@!608455754093035521> (haefer) + "Brio Scarlet", // <@!358576903701004289> (brio_scarlet) }; private static readonly string[] TavernkeepNames = { @@ -212,35 +240,40 @@ 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.) + "Intergaze", // <@!923504188615450654> (gravityglider.) + "Borgus", // <@!539127427482255376> (therealmeepman) + "Postman Hiss", // <@!454638106122125312> (karinthefairy) }; private static readonly string[] TruffleNames = { "Aldrimil", // <@!413719640238194689> (Thorioum#2475) + "Wonton", // <@!1198092982923043040> (imonthatgudkush) + "Mad Lad", // <@!215269032360804352> (crimsoncb) }; private static readonly string[] WitchDoctorNames = { "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) + "Mike Cyclops", // <@!702327497475227741> (seichoseicho) + "Derin", // <@!466703979695308820> (god_15) }; private static readonly string[] ZoologistNames = { @@ -248,7 +281,22 @@ public static float TaxYieldFactor "Lacuna", // <@!790746689211203604> (_lacuna_) "Mae Borowski", //<@!219158690433990656> (justakkolite) "Fera", // <@!195850711567826945> (juneark_) + "Gwenhwyvar", // <@!291342874497515531> (diamondnife) + "Daxie", // <@!465438861103988737> (daxie626) }; + // Town Slimes + private static readonly string[] ClumsySlimeNames = null; + private static readonly string[] CoolSlimeNames = null; + private static readonly string[] DivaSlimeNames = null; + private static readonly string[] ElderSlimeNames = null; + private static readonly string[] MysticSlimeNames = null; + private static readonly string[] NerdySlimeNames = + { + "Big Blungus", // <@!272759434282008577> (schmoov) + "Rimuru Tempest", // <@!806463201398358036> (c0d3_404) + }; + private static readonly string[] SquireSlimeNames = null; + private static readonly string[] SurlySlimeNames = null; // The following sets are for the 1.4 Town Pets: Town Dogs, Cats and Bunnies. // All three pet types come in numerous breeds. Each breed has its own name pool. @@ -263,6 +311,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 = { @@ -302,14 +352,22 @@ public static float TaxYieldFactor private static readonly string[] TownCatBlackNames = { "Bear", // <@!183424826407518208> (lilac_vrt_olligoci) + "Storm", // <@!620383533516718085> (airwaveslr) + "Hognar the Wicked", // <@!766511001356468237> (xzier_tengal) }; private static readonly string[] TownCatOrangeTabbyNames = { "Felix", // <@!183424826407518208> (lilac_vrt_olligoci) "Tardo", // <@!739343546867384391> (midnight295) + "Dali", // <@!460238880436781061> (darthlego) + "Kiba", // <@!852348657072340992> (jollydragonslayer) }; private static readonly string[] TownCatRussianBlueNames = null; - private static readonly string[] TownCatSilverNames = null; + private static readonly string[] TownCatSilverNames = + { + "Archie", // <@!303022375191183360> (jackshiz) + "Hognar the Wicked", // <@!766511001356468237> (xzier_tengal) + }; private static readonly string[] TownCatWhiteNames = null; private const int TownBunnyWhiteVanillaNames = 14; @@ -318,7 +376,11 @@ 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) + "Puffer", // <@!181103507711983616> (piky) + }; private static readonly string[] TownBunnyWhiteNames = null; private static readonly string[] TownBunnyAngoraNames = null; private static readonly string[] TownBunnyDutchNames = null; @@ -556,6 +618,32 @@ public override void ModifyNPCNameList(NPC npc, List nameList) AddNewNames(nameList, ZoologistNames); break; + // Town Slimes + case NPCID.TownSlimePurple: // Clumsy Slime + AddNewNames(nameList, ClumsySlimeNames); + break; + case NPCID.TownSlimeGreen: // Cool Slime + AddNewNames(nameList, CoolSlimeNames); + break; + case NPCID.TownSlimeRainbow: // Diva Slime + AddNewNames(nameList, DivaSlimeNames); + break; + case NPCID.TownSlimeOld: // Elder Slime + AddNewNames(nameList, ElderSlimeNames); + break; + case NPCID.TownSlimeYellow: // Mystic Slime + AddNewNames(nameList, MysticSlimeNames); + break; + case NPCID.TownSlimeBlue: // Nerdy Slime + AddNewNames(nameList, NerdySlimeNames); + break; + case NPCID.TownSlimeCopper: // Squire Slime + AddNewNames(nameList, SquireSlimeNames); + break; + case NPCID.TownSlimeRed: // Surly Slime + AddNewNames(nameList, SurlySlimeNames); + break; + // This function doesn't work with Town Pets currently case NPCID.TownCat: AddNewNames(nameList, TownCatNames); @@ -670,14 +758,13 @@ 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 }; public void TownNPCAlertSystem(NPC npc, Mod mod, SpriteBatch spriteBatch) { - if (CalamityConfig.Instance.ShopNewAlert && npc.townNPC) + if (CalamityClientConfig.Instance.ShopNewAlert && npc.townNPC) { for (int i = 0; i < npcAlertList.Count; i++) { @@ -750,7 +837,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 +890,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 +928,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 +976,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 +983,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 +1011,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 +1023,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 +1051,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 +1161,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 +1202,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 +1217,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 +1265,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 +1280,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 +1323,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/CeaselessVoid/CeaselessVoid.cs b/NPCs/CeaselessVoid/CeaselessVoid.cs index b7e2cb704c..332f6b68c3 100644 --- a/NPCs/CeaselessVoid/CeaselessVoid.cs +++ b/NPCs/CeaselessVoid/CeaselessVoid.cs @@ -67,7 +67,7 @@ public override void SetDefaults() global.DR = 0.5f; NPC.LifeMaxNERB(65000, 78000, 72000); NPC.value = Item.buyPrice(2, 0, 0, 0); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -162,7 +162,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2((float)(TextureAssets.Npc[NPC.type].Value.Width / 2), (float)(TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2)); int afterimageAmt = 7; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -185,7 +185,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture2D15 = GlowTexture.Value; Color cyanLerp = Color.Lerp(Color.White, Color.Cyan, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/CeaselessVoid/DarkEnergy.cs b/NPCs/CeaselessVoid/DarkEnergy.cs index c5fee54bad..cc92e31280 100644 --- a/NPCs/CeaselessVoid/DarkEnergy.cs +++ b/NPCs/CeaselessVoid/DarkEnergy.cs @@ -51,7 +51,7 @@ public override void SetDefaults() NPC.width = NPC.height = HitboxSize; NPC.defense = 50; NPC.lifeMax = BossRushEvent.BossRushActive ? MaxBossRushHP : MaxHP; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.Opacity = 0f; @@ -230,7 +230,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d drawPos -= new Vector2(mainTexture.Width, mainTexture.Height / Main.npcFrameCount[NPC.type]) * NPC.scale / 2f; drawPos += drawOrigin * NPC.scale + new Vector2(0f, NPC.gfxOffY); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < trailCount; i += 2) { @@ -253,7 +253,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Texture2D glowTexture = GlowTexture.Value; Color glowColor = Color.Lerp(Color.White, Color.Fuchsia, 0.5f) * NPC.Opacity; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < trailCount; i++) { diff --git a/NPCs/Crabulon/CrabShroom.cs b/NPCs/Crabulon/CrabShroom.cs index af96c9a5b1..8459e0d094 100644 --- a/NPCs/Crabulon/CrabShroom.cs +++ b/NPCs/Crabulon/CrabShroom.cs @@ -40,7 +40,7 @@ public override void SetDefaults() if (Main.getGoodWorld) NPC.lifeMax *= 2; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); AIType = -1; NPC.knockBackResist = 0.5f; diff --git a/NPCs/Crabulon/Crabulon.cs b/NPCs/Crabulon/Crabulon.cs index 31653519f3..f2c049aecd 100644 --- a/NPCs/Crabulon/Crabulon.cs +++ b/NPCs/Crabulon/Crabulon.cs @@ -74,7 +74,7 @@ public override void SetDefaults() NPC.height = 196; NPC.defense = 8; NPC.LifeMaxNERB(3700, 4400, 680000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/Crags/SoulSlurper.cs b/NPCs/Crags/SoulSlurper.cs index 5ea4ea2956..8f6cd9ff70 100644 --- a/NPCs/Crags/SoulSlurper.cs +++ b/NPCs/Crags/SoulSlurper.cs @@ -254,7 +254,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2((float)(texture.Width / 2), (float)(texture.Height / 2)); int afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -277,7 +277,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture = GlowTexture.Value; Color redGlow = Color.Lerp(Color.White, Color.Red, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/Cryogen/Cryogen.cs b/NPCs/Cryogen/Cryogen.cs index 36f0b6388c..e13b99edae 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; @@ -101,7 +102,7 @@ public override void SetDefaults() NPC.defense = 15; NPC.DR_NERD(0.3f); NPC.LifeMaxNERB(40000, 48000, 300000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -262,9 +263,9 @@ public override void AI() NPC.localAI[1] -= 1f; } - if (CalamityConfig.Instance.BossesStopWeather) + if (CalamityServerConfig.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..0dfc63cd5f 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"); @@ -37,7 +38,7 @@ public override void SetDefaults() { NPC.lifeMax = 10000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.Opacity = 0f; NPC.HitSound = Cryogen.HitSound; diff --git a/NPCs/DesertScourge/DesertNuisanceBody.cs b/NPCs/DesertScourge/DesertNuisanceBody.cs index 3498f8fe14..8fe58967a7 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"); @@ -50,7 +51,7 @@ public override void SetDefaults() if (CalamityWorld.LegendaryMode && CalamityWorld.revenge) NPC.lifeMax = 4800; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DesertScourge/DesertNuisanceBodyYoung.cs b/NPCs/DesertScourge/DesertNuisanceBodyYoung.cs index 5e9f85ba16..b3906e4e5b 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"); @@ -50,7 +51,7 @@ public override void SetDefaults() if (CalamityWorld.LegendaryMode && CalamityWorld.revenge) NPC.lifeMax = 4000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DesertScourge/DesertNuisanceHead.cs b/NPCs/DesertScourge/DesertNuisanceHead.cs index 71e547d8f9..0a7bbce816 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; @@ -65,7 +66,7 @@ public override void SetDefaults() if (CalamityWorld.LegendaryMode && CalamityWorld.revenge) NPC.lifeMax = 4800; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs b/NPCs/DesertScourge/DesertNuisanceHeadYoung.cs index e984be408c..e00b996186 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; @@ -57,7 +58,7 @@ public override void SetDefaults() if (CalamityWorld.LegendaryMode && CalamityWorld.revenge) NPC.lifeMax = 4000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DesertScourge/DesertNuisanceTail.cs b/NPCs/DesertScourge/DesertNuisanceTail.cs index 709710af2f..86cd975e34 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"); @@ -32,7 +33,7 @@ public override void SetDefaults() if (CalamityWorld.LegendaryMode && CalamityWorld.revenge) NPC.lifeMax = 4800; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DesertScourge/DesertNuisanceTailYoung.cs b/NPCs/DesertScourge/DesertNuisanceTailYoung.cs index c2b49d23c3..c0d9871de4 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"); @@ -32,7 +33,7 @@ public override void SetDefaults() if (CalamityWorld.LegendaryMode && CalamityWorld.revenge) NPC.lifeMax = 4000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DesertScourge/DesertScourgeBody.cs b/NPCs/DesertScourge/DesertScourgeBody.cs index 1d30f4e6ce..1ca33e7a01 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"); @@ -51,7 +52,7 @@ public override void SetDefaults() if (Main.getGoodWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DesertScourge/DesertScourgeHead.cs b/NPCs/DesertScourge/DesertScourgeHead.cs index 4cd787ab44..a40033c075 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; @@ -93,7 +94,7 @@ public override void SetDefaults() if (Main.getGoodWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DesertScourge/DesertScourgeTail.cs b/NPCs/DesertScourge/DesertScourgeTail.cs index 749dd0791a..6b423a5b55 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"); @@ -31,7 +32,7 @@ public override void SetDefaults() if (Main.getGoodWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DevourerofGods/CosmicGuardianBody.cs b/NPCs/DevourerofGods/CosmicGuardianBody.cs index 6c0600c59f..488989d80a 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; @@ -39,7 +40,7 @@ public override void SetDefaults() global.DR = 0.5f; global.unbreakableDR = true; NPC.lifeMax = 50000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DevourerofGods/CosmicGuardianHead.cs b/NPCs/DevourerofGods/CosmicGuardianHead.cs index eb7ef94bad..fc0c4c18e2 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; @@ -54,7 +55,7 @@ public override void SetDefaults() NPC.height = 76; NPC.defense = 40; NPC.lifeMax = 50000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DevourerofGods/CosmicGuardianTail.cs b/NPCs/DevourerofGods/CosmicGuardianTail.cs index d44bab21c7..ea936b503e 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; @@ -36,7 +37,7 @@ public override void SetDefaults() NPC.height = 50; NPC.defense = 70; NPC.lifeMax = 50000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DevourerofGods/DevourerofGodsBody.cs b/NPCs/DevourerofGods/DevourerofGodsBody.cs index aff92981bc..5936efcfac 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; @@ -76,7 +77,7 @@ public override void SetDefaults() NPC.chaseable = false; } NPC.LifeMaxNERB(887500, 1065000, 1500000); // Phase 1 is 355000, Phase 2 is 532500 - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/DevourerofGods/DevourerofGodsHead.cs b/NPCs/DevourerofGods/DevourerofGodsHead.cs index 9d5119195f..19d86670bb 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; @@ -202,7 +203,7 @@ public override void SetDefaults() NPC.height = 104; NPC.defense = 50; NPC.LifeMaxNERB(887500, 1065000, 1500000); // Phase 1 is 355000, Phase 2 is 532500 - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.takenDamageMultiplier = 1.1f; NPC.aiStyle = -1; @@ -352,7 +353,7 @@ public override void AI() CalamityGlobalNPC.DoGP2 = -1; // Stop rain - if (CalamityConfig.Instance.BossesStopWeather) + if (CalamityServerConfig.Instance.BossesStopWeather) CalamityMod.StopRain(); // Get a target (time is checked in the second check to ensure a new target isn't being set constantly) @@ -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..e2121c685c 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; @@ -73,7 +74,7 @@ public override void SetDefaults() NPC.height = 66; NPC.defense = 50; NPC.LifeMaxNERB(887500, 1065000, 1500000); // Phase 1 is 355000, Phase 2 is 532500 - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/ExoMechs/Apollo/Apollo.cs b/NPCs/ExoMechs/Apollo/Apollo.cs index 37f8031eee..921ccf2b1e 100644 --- a/NPCs/ExoMechs/Apollo/Apollo.cs +++ b/NPCs/ExoMechs/Apollo/Apollo.cs @@ -154,7 +154,7 @@ public override void SetDefaults() NPC.defense = 100; NPC.DR_NERD(0.25f); NPC.LifeMaxNERB(1250000, 1495000, 650000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -1528,7 +1528,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d // This is created to allow easy duplication of them when drawing the charge. void drawInstance(Vector2 drawOffset, Color baseColor) { - if (CalamityConfig.Instance.Afterimages && !NPC.IsABestiaryIconDummy) + if (CalamityClientConfig.Instance.Afterimages && !NPC.IsABestiaryIconDummy) { for (int i = 1; i < numAfterimages; i += 2) { @@ -1599,7 +1599,7 @@ void drawInstance(Vector2 drawOffset, Color baseColor) } texture = GlowTexture.Value; - if (CalamityConfig.Instance.Afterimages && !NPC.IsABestiaryIconDummy) + if (CalamityClientConfig.Instance.Afterimages && !NPC.IsABestiaryIconDummy) { for (int i = 1; i < numAfterimages; i += 2) { diff --git a/NPCs/ExoMechs/Ares/AresBody.cs b/NPCs/ExoMechs/Ares/AresBody.cs index 631b09ff53..85b2f69e03 100644 --- a/NPCs/ExoMechs/Ares/AresBody.cs +++ b/NPCs/ExoMechs/Ares/AresBody.cs @@ -225,7 +225,7 @@ public override void SetDefaults() NPC.defense = 100; NPC.DR_NERD(0.35f); NPC.LifeMaxNERB(1250000, 1495000, 650000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -1241,7 +1241,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 vector = new Vector2(NPC.width / 2, NPC.height / 2); int numAfterimages = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < numAfterimages; i += 2) { @@ -1261,7 +1261,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture = GlowTexture.Value; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < numAfterimages; i += 2) { @@ -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/Ares/AresGaussNuke.cs b/NPCs/ExoMechs/Ares/AresGaussNuke.cs index dec6dd8459..859810bba4 100644 --- a/NPCs/ExoMechs/Ares/AresGaussNuke.cs +++ b/NPCs/ExoMechs/Ares/AresGaussNuke.cs @@ -93,7 +93,7 @@ public override void SetDefaults() NPC.defense = 100; NPC.DR_NERD(0.35f); NPC.LifeMaxNERB(1250000, 1495000, 650000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -551,7 +551,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color afterimageBaseColor = Main.npc[(int)NPC.ai[2]].localAI[1] == (float)AresBody.Enraged.Yes ? Color.Red : Color.White; int numAfterimages = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < numAfterimages; i += 2) { @@ -592,7 +592,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Texture2D glowTexture = GlowTexture.Value; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < numAfterimages; i += 2) { diff --git a/NPCs/ExoMechs/Ares/AresLaserCannon.cs b/NPCs/ExoMechs/Ares/AresLaserCannon.cs index cbaacc311a..3e3b5baa47 100644 --- a/NPCs/ExoMechs/Ares/AresLaserCannon.cs +++ b/NPCs/ExoMechs/Ares/AresLaserCannon.cs @@ -96,7 +96,7 @@ public override void SetDefaults() NPC.defense = 100; NPC.DR_NERD(0.35f); NPC.LifeMaxNERB(1250000, 1495000, 650000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -599,7 +599,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color afterimageBaseColor = Main.npc[(int)NPC.ai[2]].localAI[1] == (float)AresBody.Enraged.Yes ? Color.Red : Color.White; int numAfterimages = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < numAfterimages; i += 2) { @@ -638,7 +638,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Texture2D glowTexture = GlowTexture.Value; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < numAfterimages; i += 2) { diff --git a/NPCs/ExoMechs/Ares/AresPlasmaFlamethrower.cs b/NPCs/ExoMechs/Ares/AresPlasmaFlamethrower.cs index 9aef9f09fb..d8b6d55613 100644 --- a/NPCs/ExoMechs/Ares/AresPlasmaFlamethrower.cs +++ b/NPCs/ExoMechs/Ares/AresPlasmaFlamethrower.cs @@ -90,7 +90,7 @@ public override void SetDefaults() NPC.defense = 100; NPC.DR_NERD(0.35f); NPC.LifeMaxNERB(1250000, 1495000, 650000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -550,7 +550,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color afterimageBaseColor = Main.npc[(int)NPC.ai[2]].localAI[1] == (float)AresBody.Enraged.Yes ? Color.Red : Color.White; int numAfterimages = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < numAfterimages; i += 2) { @@ -590,7 +590,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Texture2D glowTexture = GlowTexture.Value; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < numAfterimages; i += 2) { diff --git a/NPCs/ExoMechs/Ares/AresTeslaCannon.cs b/NPCs/ExoMechs/Ares/AresTeslaCannon.cs index 09d77162ed..d9bb7d4994 100644 --- a/NPCs/ExoMechs/Ares/AresTeslaCannon.cs +++ b/NPCs/ExoMechs/Ares/AresTeslaCannon.cs @@ -91,7 +91,7 @@ public override void SetDefaults() NPC.defense = 100; NPC.DR_NERD(0.35f); NPC.LifeMaxNERB(1250000, 1495000, 650000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -545,7 +545,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color afterimageBaseColor = Main.npc[(int)NPC.ai[2]].localAI[1] == (float)AresBody.Enraged.Yes ? Color.Red : Color.White; int numAfterimages = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < numAfterimages; i += 2) { @@ -584,7 +584,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Texture2D glowTexture = GlowTexture.Value; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < numAfterimages; i += 2) { diff --git a/NPCs/ExoMechs/Artemis/Artemis.cs b/NPCs/ExoMechs/Artemis/Artemis.cs index f53b9eead4..5fa230c2a8 100644 --- a/NPCs/ExoMechs/Artemis/Artemis.cs +++ b/NPCs/ExoMechs/Artemis/Artemis.cs @@ -187,7 +187,7 @@ public override void SetDefaults() NPC.defense = 100; NPC.DR_NERD(0.25f); NPC.LifeMaxNERB(1250000, 1495000, 650000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -1423,7 +1423,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d // This is created to allow easy duplication of them when drawing the charge. void drawInstance(Vector2 drawOffset, Color baseColor) { - if (CalamityConfig.Instance.Afterimages && !NPC.IsABestiaryIconDummy) + if (CalamityClientConfig.Instance.Afterimages && !NPC.IsABestiaryIconDummy) { for (int i = 1; i < numAfterimages; i += 2) { @@ -1494,7 +1494,7 @@ void drawInstance(Vector2 drawOffset, Color baseColor) } texture = GlowTexture.Value; - if (CalamityConfig.Instance.Afterimages && !NPC.IsABestiaryIconDummy) + if (CalamityClientConfig.Instance.Afterimages && !NPC.IsABestiaryIconDummy) { for (int i = 1; i < numAfterimages; i += 2) { diff --git a/NPCs/ExoMechs/Draedon.cs b/NPCs/ExoMechs/Draedon.cs index 623673c9f1..4149db13cd 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); @@ -801,7 +802,7 @@ public override void HitEffect(NPC.HitInfo hit) if (NPC.life > 0) return; - if (Main.netMode != NetmodeID.Server && !HasBeenKilled) + if (Main.netMode != NetmodeID.Server && !HasBeenKilled && HologramEffectTimer > 0f) { for (int i = 1; i <= 4; i++) { diff --git a/NPCs/ExoMechs/Thanatos/ThanatosBody1.cs b/NPCs/ExoMechs/Thanatos/ThanatosBody1.cs index 4dc825f12a..b9e20ec96c 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; @@ -74,7 +75,7 @@ public override void SetDefaults() NPC.DR_NERD(0.9999f); NPC.Calamity().unbreakableDR = true; NPC.LifeMaxNERB(960000, 1150000, 600000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/ExoMechs/Thanatos/ThanatosBody2.cs b/NPCs/ExoMechs/Thanatos/ThanatosBody2.cs index 76c6275344..3ae03ab9fb 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; @@ -73,7 +74,7 @@ public override void SetDefaults() NPC.DR_NERD(0.9999f); NPC.Calamity().unbreakableDR = true; NPC.LifeMaxNERB(960000, 1150000, 600000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/ExoMechs/Thanatos/ThanatosHead.cs b/NPCs/ExoMechs/Thanatos/ThanatosHead.cs index 3c7d01279b..410decf566 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; @@ -173,7 +174,7 @@ public override void SetDefaults() NPC.DR_NERD(0.9999f); NPC.Calamity().unbreakableDR = true; NPC.LifeMaxNERB(960000, 1150000, 600000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/ExoMechs/Thanatos/ThanatosTail.cs b/NPCs/ExoMechs/Thanatos/ThanatosTail.cs index 23622c7c61..c16d83f33b 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; @@ -73,7 +74,7 @@ public override void SetDefaults() NPC.DR_NERD(0.9999f); NPC.Calamity().unbreakableDR = true; NPC.LifeMaxNERB(960000, 1150000, 600000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/GreatSandShark/GreatSandShark.cs b/NPCs/GreatSandShark/GreatSandShark.cs index 3d1673db94..c0d7469cc5 100644 --- a/NPCs/GreatSandShark/GreatSandShark.cs +++ b/NPCs/GreatSandShark/GreatSandShark.cs @@ -609,7 +609,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d int eightConst = 8; int afterimageInc = 2; int afterimageCounter = 1; - while (((afterimageInc > 0 && afterimageCounter < eightConst) || (afterimageInc < 0 && afterimageCounter > eightConst)) && CalamityConfig.Instance.Afterimages) + while (((afterimageInc > 0 && afterimageCounter < eightConst) || (afterimageInc < 0 && afterimageCounter > eightConst)) && CalamityClientConfig.Instance.Afterimages) { Color alphaAfterimageColor = NPC.GetAlpha(extraAfterimageColor); { diff --git a/NPCs/HiveMind/DankCreeper.cs b/NPCs/HiveMind/DankCreeper.cs index a6e676023c..f8615597f3 100644 --- a/NPCs/HiveMind/DankCreeper.cs +++ b/NPCs/HiveMind/DankCreeper.cs @@ -32,7 +32,7 @@ public override void SetDefaults() if (Main.getGoodWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); if ((CalamityWorld.LegendaryMode && CalamityWorld.revenge)) diff --git a/NPCs/HiveMind/DarkHeart.cs b/NPCs/HiveMind/DarkHeart.cs index 3432898fdc..f5acf1f9bb 100644 --- a/NPCs/HiveMind/DarkHeart.cs +++ b/NPCs/HiveMind/DarkHeart.cs @@ -32,7 +32,7 @@ public override void SetDefaults() if (Main.getGoodWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; diff --git a/NPCs/HiveMind/HiveBlob.cs b/NPCs/HiveMind/HiveBlob.cs index 6e7c638703..69b6b00e6f 100644 --- a/NPCs/HiveMind/HiveBlob.cs +++ b/NPCs/HiveMind/HiveBlob.cs @@ -37,7 +37,7 @@ public override void SetDefaults() if (Main.getGoodWorld) NPC.lifeMax *= 2; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.9f; diff --git a/NPCs/HiveMind/HiveBlob2.cs b/NPCs/HiveMind/HiveBlob2.cs index 9b3e44fd1f..a69f074473 100644 --- a/NPCs/HiveMind/HiveBlob2.cs +++ b/NPCs/HiveMind/HiveBlob2.cs @@ -40,7 +40,7 @@ public override void SetDefaults() if (Main.getGoodWorld) NPC.lifeMax *= 2; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.9f; diff --git a/NPCs/HiveMind/HiveMind.cs b/NPCs/HiveMind/HiveMind.cs index 868e8357c1..859b5daf63 100644 --- a/NPCs/HiveMind/HiveMind.cs +++ b/NPCs/HiveMind/HiveMind.cs @@ -121,7 +121,7 @@ public override void SetDefaults() NPC.height = 122; NPC.defense = 8; NPC.LifeMaxNERB(7700, 9200, 350000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -315,7 +315,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color afterimageBaseColor = Color.White; int numAfterimages = 5; - if (CalamityConfig.Instance.Afterimages && state != 0) + if (CalamityClientConfig.Instance.Afterimages && state != 0) { for (int i = 1; i < numAfterimages; i += 2) { diff --git a/NPCs/Leviathan/Anahita.cs b/NPCs/Leviathan/Anahita.cs index 270966cff3..f7734fff7d 100644 --- a/NPCs/Leviathan/Anahita.cs +++ b/NPCs/Leviathan/Anahita.cs @@ -66,7 +66,7 @@ public override void SetDefaults() NPC.defense = 20; NPC.DR_NERD(0.2f); NPC.LifeMaxNERB(35000, 42000, 260000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.aiStyle = -1; diff --git a/NPCs/Leviathan/AnahitasIceShield.cs b/NPCs/Leviathan/AnahitasIceShield.cs index a32c37cb9b..9ada36e218 100644 --- a/NPCs/Leviathan/AnahitasIceShield.cs +++ b/NPCs/Leviathan/AnahitasIceShield.cs @@ -39,7 +39,7 @@ public override void SetDefaults() NPC.defense = 10; NPC.DR_NERD(0.5f); NPC.lifeMax = BossRushEvent.BossRushActive ? 1000 : 650; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.alpha = 255; NPC.HitSound = SoundID.NPCHit5; diff --git a/NPCs/Leviathan/AquaticAberration.cs b/NPCs/Leviathan/AquaticAberration.cs index e98ae031d8..524778f29c 100644 --- a/NPCs/Leviathan/AquaticAberration.cs +++ b/NPCs/Leviathan/AquaticAberration.cs @@ -43,7 +43,7 @@ public override void SetDefaults() NPC.height = 50; NPC.defense = 14; NPC.lifeMax = BossRushEvent.BossRushActive ? 10000 : 600; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.2f; NPC.noGravity = true; diff --git a/NPCs/Leviathan/Leviathan.cs b/NPCs/Leviathan/Leviathan.cs index ade98ce310..87e60c6fed 100644 --- a/NPCs/Leviathan/Leviathan.cs +++ b/NPCs/Leviathan/Leviathan.cs @@ -66,7 +66,7 @@ public override void SetDefaults() NPC.defense = 40; NPC.DR_NERD(0.35f); NPC.LifeMaxNERB(60000, 72000, 600000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.aiStyle = -1; @@ -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/BloodlettingServant.cs b/NPCs/NormalNPCs/BloodlettingServant.cs index 879a389f03..b31d1d20a2 100644 --- a/NPCs/NormalNPCs/BloodlettingServant.cs +++ b/NPCs/NormalNPCs/BloodlettingServant.cs @@ -45,7 +45,7 @@ public override void SetDefaults() NPC.defense = 5; NPC.lifeMax = 96; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; @@ -259,7 +259,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d float telegraphScalar = MathHelper.Clamp((NPC.ai[0] - ChargeTelegraphGateValue) / ChargeTelegraphGateValue, 0f, 1f); Color telegraphColor = Color.Lerp(originalColor, newColor, telegraphScalar); - if (CalamityConfig.Instance.Afterimages && NPC.ai[1] > 0f) + if (CalamityClientConfig.Instance.Afterimages && NPC.ai[1] > 0f) { int afterimageAmount = 10; int afterImageIncrement = 2; diff --git a/NPCs/NormalNPCs/IceClasper.cs b/NPCs/NormalNPCs/IceClasper.cs index fca3afe2b1..0f98304a97 100644 --- a/NPCs/NormalNPCs/IceClasper.cs +++ b/NPCs/NormalNPCs/IceClasper.cs @@ -342,7 +342,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d (MathHelper.Clamp(AITimer, 0f, TimeBeforeDash) / TimeBeforeDash); float AfterimageFade = MathHelper.Lerp(0f, 1f, interpolant); - if (CurrentState == IceClasperAIState.Dashing && CalamityConfig.Instance.Afterimages) + if (CurrentState == IceClasperAIState.Dashing && CalamityClientConfig.Instance.Afterimages) { for (int i = 0; i < NPC.oldPos.Length; i++) { diff --git a/NPCs/NormalNPCs/KingSlimeJewelEmerald.cs b/NPCs/NormalNPCs/KingSlimeJewelEmerald.cs index 5d5160792f..80fad53f46 100644 --- a/NPCs/NormalNPCs/KingSlimeJewelEmerald.cs +++ b/NPCs/NormalNPCs/KingSlimeJewelEmerald.cs @@ -36,7 +36,7 @@ public override void SetDefaults() NPC.DR_NERD(0.15f); NPC.lifeMax = 240; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.7f; diff --git a/NPCs/NormalNPCs/KingSlimeJewelRuby.cs b/NPCs/NormalNPCs/KingSlimeJewelRuby.cs index 327d1d0054..fe60d9a411 100644 --- a/NPCs/NormalNPCs/KingSlimeJewelRuby.cs +++ b/NPCs/NormalNPCs/KingSlimeJewelRuby.cs @@ -36,7 +36,7 @@ public override void SetDefaults() NPC.DR_NERD(0.1f); NPC.lifeMax = 120; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.8f; diff --git a/NPCs/NormalNPCs/KingSlimeJewelSapphire.cs b/NPCs/NormalNPCs/KingSlimeJewelSapphire.cs index a41db05782..1aa81eac91 100644 --- a/NPCs/NormalNPCs/KingSlimeJewelSapphire.cs +++ b/NPCs/NormalNPCs/KingSlimeJewelSapphire.cs @@ -35,7 +35,7 @@ public override void SetDefaults() NPC.DR_NERD(0.05f); NPC.lifeMax = 120; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.9f; diff --git a/NPCs/NormalNPCs/LavaSlimeNoLavaDrop.cs b/NPCs/NormalNPCs/LavaSlimeNoLavaDrop.cs deleted file mode 100644 index ca5764da80..0000000000 --- a/NPCs/NormalNPCs/LavaSlimeNoLavaDrop.cs +++ /dev/null @@ -1,75 +0,0 @@ -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.NPCs.NormalNPCs -{ - public class LavaSlimeNoLavaDrop : ModNPC - { - public override string Texture => $"Terraria/Images/NPC_{NPCID.LavaSlime}"; - - public override void SetStaticDefaults() - { - Main.npcFrameCount[NPC.type] = 2; - this.HideFromBestiary(); - } - - public override void SetDefaults() - { - NPC.aiStyle = NPCAIStyleID.Slime; - AIType = NPCID.LavaSlime; - AnimationType = NPCID.LavaSlime; - NPC.width = 24; - NPC.height = 18; - NPC.damage = 15; - NPC.defense = 10; - NPC.lifeMax = 50; - NPC.HitSound = SoundID.NPCHit1; - NPC.DeathSound = SoundID.NPCDeath1; - NPC.scale = 1.1f; - NPC.alpha = 50; - NPC.lavaImmune = true; - NPC.value = 120f; - if (Main.remixWorld) - { - NPC.damage = 7; - NPC.defense = 2; - NPC.lifeMax = 25; - NPC.value = 25f; - } - //Banner = NPCID.LavaSlime; - //BannerItem = ItemID.LavaSlimeBanner; - - NPC.Calamity().VulnerableToCold = true; - NPC.Calamity().VulnerableToSickness = false; - NPC.Calamity().VulnerableToHeat = false; - NPC.Calamity().VulnerableToWater = true; - - // Scale stats in Expert and Master - CalamityGlobalNPC.AdjustExpertModeStatScaling(NPC); - CalamityGlobalNPC.AdjustMasterModeStatScaling(NPC); - } - - public override void HitEffect(NPC.HitInfo hit) - { - if (NPC.life > 0) - { - for (int i = 0; (double)i < hit.Damage / (double)NPC.lifeMax * 80D; i++) - { - int dust = Dust.NewDust(NPC.position, NPC.width, NPC.height, 6, hit.HitDirection * 2, -1f, NPC.alpha, default, 1.5f); - if (Main.rand.Next(8) != 0) - Main.dust[dust].noGravity = true; - } - - return; - } - - for (int i = 0; i < 40; i++) - { - int dust = Dust.NewDust(NPC.position, NPC.width, NPC.height, 6, hit.HitDirection * 2, -1f, NPC.alpha, default, 1.5f); - if (Main.rand.Next(8) != 0) - Main.dust[dust].noGravity = true; - } - } - } -} diff --git a/NPCs/NormalNPCs/PlanterasFreeTentacle.cs b/NPCs/NormalNPCs/PlanterasFreeTentacle.cs index f3912e4d09..d86011b3c5 100644 --- a/NPCs/NormalNPCs/PlanterasFreeTentacle.cs +++ b/NPCs/NormalNPCs/PlanterasFreeTentacle.cs @@ -38,7 +38,7 @@ public override void SetDefaults() NPC.defense = 20; NPC.lifeMax = 500; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.4f; diff --git a/NPCs/NormalNPCs/SkeletronPrime2.cs b/NPCs/NormalNPCs/SkeletronPrime2.cs deleted file mode 100644 index d644a5d641..0000000000 --- a/NPCs/NormalNPCs/SkeletronPrime2.cs +++ /dev/null @@ -1,911 +0,0 @@ -using System; -using System.IO; -using CalamityMod.Buffs.DamageOverTime; -using CalamityMod.Buffs.StatDebuffs; -using CalamityMod.DataStructures; -using CalamityMod.Events; -using CalamityMod.World; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using ReLogic.Content; -using Terraria; -using Terraria.Audio; -using Terraria.GameContent.Bestiary; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.NPCs.NormalNPCs -{ - public class SkeletronPrime2 : ModNPC - { - public override string BossHeadTexture => $"Terraria/Images/NPC_Head_Boss_18"; - - public static Asset EyeTexture; - - public const int BombTimeLeft = 600; - - public override void SetStaticDefaults() - { - Main.npcFrameCount[NPC.type] = 6; - NPCID.Sets.NPCBestiaryDrawModifiers bestiaryData = new NPCID.Sets.NPCBestiaryDrawModifiers() { Hide = true }; - NPCID.Sets.NPCBestiaryDrawOffset.Add(Type, bestiaryData); - if (!Main.dedServ) - { - EyeTexture = ModContent.Request("CalamityMod/ExtraTextures/SkeletronPrime2HeadGlow"); - } - } - - public override void SetDefaults() - { - NPC.Calamity().canBreakPlayerDefense = true; - NPC.aiStyle = NPCAIStyleID.SkeletronPrimeHead; - NPC.GetNPCDamage(); - NPC.DR_NERD(0.2f); - - NPC.width = 80; - NPC.height = 102; - if (Main.tenthAnniversaryWorld) - NPC.scale *= 0.5f; - if (Main.getGoodWorld) - NPC.scale *= 1.1f; - - NPC.defense = 24; - - NPC.lifeMax = 28000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; - NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); - - NPC.knockBackResist = 0f; - NPC.noGravity = true; - NPC.noTileCollide = true; - NPC.boss = true; - NPC.value = 200000f; - NPC.HitSound = SoundID.NPCHit4; - NPC.DeathSound = SoundID.NPCDeath14; - NPC.Calamity().VulnerableToElectricity = true; - NPC.Calamity().VulnerableToSickness = false; - AnimationType = NPCID.SkeletronPrime; - Music = MusicID.Boss3; - } - - public override void SendExtraAI(BinaryWriter writer) - { - writer.Write(NPC.localAI[0]); - writer.Write(NPC.localAI[1]); - writer.Write(NPC.localAI[2]); - writer.Write(NPC.localAI[3]); - for (int i = 0; i < 4; i++) - writer.Write(NPC.Calamity().newAI[i]); - } - - public override void ReceiveExtraAI(BinaryReader reader) - { - NPC.localAI[0] = reader.ReadSingle(); - NPC.localAI[1] = reader.ReadSingle(); - NPC.localAI[2] = reader.ReadSingle(); - NPC.localAI[3] = reader.ReadSingle(); - for (int i = 0; i < 4; i++) - NPC.Calamity().newAI[i] = reader.ReadSingle(); - } - - public override void BossHeadRotation(ref float rotation) - { - rotation = (NPC.ai[1] == 1f || NPC.ai[1] == 2f) ? NPC.rotation : 0f; - } - - public override void AI() - { - CalamityGlobalNPC calamityGlobalNPC = NPC.Calamity(); - - bool bossRush = BossRushEvent.BossRushActive; - bool death = CalamityWorld.death || bossRush; - - // Percent life remaining - float lifeRatio = NPC.life / (float)NPC.lifeMax; - - // Spawn arms - if (calamityGlobalNPC.newAI[1] == 0f) - { - calamityGlobalNPC.newAI[1] = 1f; - - if (Main.netMode != NetmodeID.MultiplayerClient) - { - // This head owns the Cannon and the Vice in Master Mode - int arm = NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y, NPCID.PrimeCannon, NPC.whoAmI); - Main.npc[arm].ai[0] = -1f; - Main.npc[arm].ai[1] = NPC.whoAmI; - Main.npc[arm].target = NPC.target; - Main.npc[arm].netUpdate = true; - - arm = NPC.NewNPC(NPC.GetSource_FromAI(), (int)NPC.Center.X, (int)NPC.Center.Y, NPCID.PrimeVice, NPC.whoAmI); - Main.npc[arm].ai[0] = -1f; - Main.npc[arm].ai[1] = NPC.whoAmI; - Main.npc[arm].target = NPC.target; - Main.npc[arm].ai[3] = 150f; - Main.npc[arm].netUpdate = true; - } - - NPC.SyncExtraAI(); - } - - if (!Main.npc[(int)NPC.ai[0]].active || Main.npc[(int)NPC.ai[0]].aiStyle != NPCAIStyleID.SkeletronPrimeHead) - { - NPC.life = 0; - NPC.HitEffect(); - NPC.active = false; - NPC.netUpdate = true; - } - else - { - // Link the HP of both heads - if (NPC.life > Main.npc[(int)NPC.ai[0]].life) - NPC.life = Main.npc[(int)NPC.ai[0]].life; - - // Push away from the lead head if too close, pull closer if too far, if Mechdusa isn't real - if (!NPC.IsMechQueenUp) - { - float pushVelocity = 0.25f; - if (Vector2.Distance(NPC.Center, Main.npc[(int)NPC.ai[0]].Center) < 80f * NPC.scale) - { - if (NPC.position.X < Main.npc[(int)NPC.ai[0]].position.X) - NPC.velocity.X -= pushVelocity; - else - NPC.velocity.X += pushVelocity; - - if (NPC.position.Y < Main.npc[(int)NPC.ai[0]].position.Y) - NPC.velocity.Y -= pushVelocity; - else - NPC.velocity.Y += pushVelocity; - } - else if (Vector2.Distance(NPC.Center, Main.npc[(int)NPC.ai[0]].Center) > 240f * NPC.scale) - { - if (NPC.position.X < Main.npc[(int)NPC.ai[0]].position.X) - NPC.velocity.X += pushVelocity; - else - NPC.velocity.X -= pushVelocity; - - if (NPC.position.Y < Main.npc[(int)NPC.ai[0]].position.Y) - NPC.velocity.Y += pushVelocity; - else - NPC.velocity.Y -= pushVelocity; - } - } - } - - // Check if arms are alive - bool cannonAlive = false; - bool laserAlive = false; - bool viceAlive = false; - bool sawAlive = false; - if (CalamityGlobalNPC.primeCannon != -1) - { - if (Main.npc[CalamityGlobalNPC.primeCannon].active) - cannonAlive = true; - } - if (CalamityGlobalNPC.primeLaser != -1) - { - if (Main.npc[CalamityGlobalNPC.primeLaser].active) - laserAlive = true; - } - if (CalamityGlobalNPC.primeVice != -1) - { - if (Main.npc[CalamityGlobalNPC.primeVice].active) - viceAlive = true; - } - if (CalamityGlobalNPC.primeSaw != -1) - { - if (Main.npc[CalamityGlobalNPC.primeSaw].active) - sawAlive = true; - } - bool allArmsDead = !cannonAlive && !laserAlive && !viceAlive && !sawAlive; - NPC.chaseable = allArmsDead; - - NPC.defense = NPC.defDefense; - - // Phases - bool phase2 = lifeRatio < 0.66f; - bool phase3 = lifeRatio < 0.33f; - bool spawnSpazmatism = lifeRatio < 0.5f && !bossRush && NPC.localAI[2] == 0f; - - // Spawn Spazmatism in Master Mode (just like Oblivion from Avalon) - if (spawnSpazmatism) - { - Player spazmatismSpawnPlayer = Main.player[Player.FindClosest(NPC.position, NPC.width, NPC.height)]; - SoundEngine.PlaySound(SoundID.Roar, spazmatismSpawnPlayer.Center); - if (Main.netMode != NetmodeID.MultiplayerClient) - NPC.SpawnOnPlayer(spazmatismSpawnPlayer.whoAmI, NPCID.Spazmatism); - - NPC.localAI[2] = 1f; - NPC.SyncVanillaLocalAI(); - } - - // Despawn - if (Main.npc[(int)NPC.ai[0]].ai[1] == 3f) - NPC.ai[1] = 3f; - - // Activate daytime enrage - if (Main.IsItDay() && !bossRush && NPC.ai[1] != 3f && NPC.ai[1] != 2f) - { - // Heal - if (Main.netMode != NetmodeID.MultiplayerClient) - { - int healAmt = NPC.life - 300; - if (healAmt < 0) - { - int absHeal = Math.Abs(healAmt); - NPC.life += absHeal; - NPC.HealEffect(absHeal, true); - NPC.netUpdate = true; - } - } - - NPC.ai[1] = 2f; - SoundEngine.PlaySound(SoundID.ForceRoar, NPC.Center); - } - - // Adjust slowing debuff immunity - bool immuneToSlowingDebuffs = NPC.ai[1] == 5f; - NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; - NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; - NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; - NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; - NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; - NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; - NPC.buffImmune[ModContent.BuffType()] = immuneToSlowingDebuffs; - NPC.buffImmune[BuffID.Slow] = immuneToSlowingDebuffs; - NPC.buffImmune[BuffID.Webbed] = immuneToSlowingDebuffs; - - bool normalLaserRotation = NPC.localAI[1] % 2f == 0f; - - // Prevents cheap hits - bool canUseAttackInMaster = NPC.position.Y < Main.player[Main.npc[(int)NPC.ai[0]].target].position.Y - 350f; - - // Float near player - if (NPC.ai[1] == 0f || NPC.ai[1] == 4f) - { - // Avoid unfair bullshit - NPC.damage = 0; - - // Start other phases; if arms are dead, start with spin phase - bool otherHeadChargingOrSpinning = Main.npc[(int)NPC.ai[0]].ai[1] == 5f || Main.npc[(int)NPC.ai[0]].ai[1] == 1f; - - // Start spin phase after 1.875 seconds - NPC.ai[2] += phase3 ? 1.2f : 0.8f; - if (NPC.ai[2] >= (90f - (death ? 15f * (1f - lifeRatio) : 0f)) && (!otherHeadChargingOrSpinning || phase3) && canUseAttackInMaster) - { - bool shouldSpinAround = NPC.ai[1] == 4f && NPC.position.Y < Main.player[Main.npc[(int)NPC.ai[0]].target].position.Y - 400f && - Vector2.Distance(Main.player[Main.npc[(int)NPC.ai[0]].target].Center, NPC.Center) < 600f && Vector2.Distance(Main.player[Main.npc[(int)NPC.ai[0]].target].Center, NPC.Center) > 400f; - - bool shouldCharge = !phase2 && !allArmsDead && !CalamityWorld.LegendaryMode; - if (shouldCharge) - { - NPC.ai[2] = 0f; - NPC.ai[1] = 1f; - NPC.netUpdate = true; - } - else if (shouldSpinAround || NPC.ai[1] != 4f) - { - if (shouldSpinAround) - { - NPC.localAI[3] = 300f; - NPC.SyncVanillaLocalAI(); - } - - NPC.ai[2] = 0f; - NPC.ai[1] = shouldSpinAround ? 5f : 1f; - NPC.netUpdate = true; - } - } - - if (NPC.IsMechQueenUp) - NPC.rotation = NPC.rotation.AngleLerp(NPC.velocity.X / 15f * 0.5f, 0.75f); - else - NPC.rotation = NPC.velocity.X / 15f; - - float acceleration = (bossRush ? 0.2f : 0.125f) + (death ? 0.05f * (1f - lifeRatio) : 0f); - float accelerationMult = 1f; - if (!cannonAlive) - { - acceleration += 0.025f; - accelerationMult += 0.5f; - } - if (!laserAlive) - { - acceleration += 0.025f; - accelerationMult += 0.5f; - } - if (!viceAlive) - acceleration += 0.025f; - if (!sawAlive) - acceleration += 0.025f; - acceleration *= accelerationMult; - - float topVelocity = acceleration * 100f; - float deceleration = 0.7f; - - float headDecelerationUpDist = 0f; - float headDecelerationDownDist = 0f; - float headDecelerationHorizontalDist = 0f; - int headHorizontalDirection = ((!(Main.player[Main.npc[(int)NPC.ai[0]].target].Center.X < NPC.Center.X)) ? 1 : (-1)); - if (NPC.IsMechQueenUp) - { - headDecelerationHorizontalDist = -150f * (float)headHorizontalDirection; - headDecelerationUpDist = 50f; - headDecelerationDownDist = 50f; - } - - if (NPC.position.Y > Main.player[Main.npc[(int)NPC.ai[0]].target].position.Y - (400f + headDecelerationUpDist)) - { - if (NPC.velocity.Y > 0f) - NPC.velocity.Y *= deceleration; - - NPC.velocity.Y -= acceleration; - - if (NPC.velocity.Y > topVelocity) - NPC.velocity.Y = topVelocity; - } - else if (NPC.position.Y < Main.player[Main.npc[(int)NPC.ai[0]].target].position.Y - (450f + headDecelerationDownDist)) - { - if (NPC.velocity.Y < 0f) - NPC.velocity.Y *= deceleration; - - NPC.velocity.Y += acceleration; - - if (NPC.velocity.Y < -topVelocity) - NPC.velocity.Y = -topVelocity; - } - - if (NPC.Center.X > Main.player[Main.npc[(int)NPC.ai[0]].target].Center.X + (400f + headDecelerationHorizontalDist)) - { - if (NPC.velocity.X > 0f) - NPC.velocity.X *= deceleration; - - NPC.velocity.X -= acceleration; - - if (NPC.velocity.X > topVelocity) - NPC.velocity.X = topVelocity; - } - if (NPC.Center.X < Main.player[Main.npc[(int)NPC.ai[0]].target].Center.X - (400f + headDecelerationHorizontalDist)) - { - if (NPC.velocity.X < 0f) - NPC.velocity.X *= deceleration; - - NPC.velocity.X += acceleration; - - if (NPC.velocity.X < -topVelocity) - NPC.velocity.X = -topVelocity; - } - } - - else - { - // Spinning - if (NPC.ai[1] == 1f) - { - NPC.defense *= 2; - NPC.damage = NPC.defDamage * 2; - - calamityGlobalNPC.CurrentlyIncreasingDefenseOrDR = true; - - if (phase2 && Main.netMode != NetmodeID.MultiplayerClient) - { - NPC.localAI[0] += 1f; - if (NPC.localAI[0] >= 60f) - { - NPC.localAI[0] = 0f; - - int totalProjectiles = bossRush ? 20 : death ? 12 : 10; - float radians = MathHelper.TwoPi / totalProjectiles; - int type = ProjectileID.FrostBeam; - int damage = NPC.GetProjectileDamage(type); - - // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) - { - double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; - double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; - if (!NPC.downedMechBossAny) - damage = (int)(damage * firstMechMultiplier); - else if ((!NPC.downedMechBoss1 && !NPC.downedMechBoss2) || (!NPC.downedMechBoss2 && !NPC.downedMechBoss3) || (!NPC.downedMechBoss3 && !NPC.downedMechBoss1)) - damage = (int)(damage * secondMechMultiplier); - } - - float velocity = 4.5f; - double angleA = radians * 0.5; - double angleB = MathHelper.ToRadians(90f) - angleA; - float velocityX = (float)(velocity * Math.Sin(angleA) / Math.Sin(angleB)); - Vector2 spinningPoint = normalLaserRotation ? new Vector2(0f, -velocity) : new Vector2(-velocityX, -velocity); - for (int k = 0; k < totalProjectiles; k++) - { - Vector2 laserFireDirection = spinningPoint.RotatedBy(radians * k); - int proj = Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center + laserFireDirection.SafeNormalize(Vector2.UnitY) * 140f, laserFireDirection, type, damage, 0f, Main.myPlayer, 1f, 0f); - Main.projectile[proj].timeLeft = 600; - } - NPC.localAI[1] += 1f; - } - } - - NPC.ai[2] += 1f; - if (NPC.ai[2] == 2f) - SoundEngine.PlaySound(SoundID.ForceRoar, NPC.Center); - - // Spin for 3 seconds then return to floating phase - float phaseTimer = 240f; - if (phase2 && !phase3) - phaseTimer += 60f; - - if (NPC.ai[2] >= (phaseTimer - (death ? 60f * (1f - lifeRatio) : 0f))) - { - NPC.ai[2] = 0f; - NPC.ai[1] = 4f; - NPC.localAI[0] = 0f; - } - - if (NPC.IsMechQueenUp) - NPC.rotation = NPC.rotation.AngleLerp(NPC.velocity.X / 15f * 0.5f, 0.75f); - else - NPC.rotation += NPC.direction * 0.3f; - - Vector2 headPosition = NPC.Center; - float headTargetX = Main.player[Main.npc[(int)NPC.ai[0]].target].Center.X - headPosition.X; - float headTargetY = Main.player[Main.npc[(int)NPC.ai[0]].target].Center.Y - headPosition.Y; - float headTargetDistance = (float)Math.Sqrt(headTargetX * headTargetX + headTargetY * headTargetY); - - float speed = bossRush ? 12f : 8f; - if (phase2) - speed += 0.5f; - if (phase3) - speed += 0.5f; - - if (headTargetDistance > 150f) - { - float baseDistanceVelocityMult = 1f + MathHelper.Clamp((headTargetDistance - 150f) * 0.0015f, 0.05f, 1.5f); - speed *= baseDistanceVelocityMult; - } - - if (NPC.IsMechQueenUp) - { - float mechdusaSpeedMult = (NPC.npcsFoundForCheckActive[NPCID.TheDestroyerBody] ? 0.6f : 0.75f); - speed *= mechdusaSpeedMult; - } - - headTargetDistance = speed / headTargetDistance; - NPC.velocity.X = headTargetX * headTargetDistance; - NPC.velocity.Y = headTargetY * headTargetDistance; - - if (NPC.IsMechQueenUp) - { - float mechdusaAccelMult = Vector2.Distance(NPC.Center, Main.player[Main.npc[(int)NPC.ai[0]].target].Center); - if (mechdusaAccelMult < 0.1f) - mechdusaAccelMult = 0f; - - if (mechdusaAccelMult < speed) - NPC.velocity = NPC.velocity.SafeNormalize(Vector2.Zero) * mechdusaAccelMult; - } - } - - // Daytime enrage - if (NPC.ai[1] == 2f) - { - NPC.damage = 1000; - calamityGlobalNPC.DR = 0.9999f; - calamityGlobalNPC.unbreakableDR = true; - - calamityGlobalNPC.CurrentlyEnraged = true; - calamityGlobalNPC.CurrentlyIncreasingDefenseOrDR = true; - - if (NPC.IsMechQueenUp) - NPC.rotation = NPC.rotation.AngleLerp(NPC.velocity.X / 15f * 0.5f, 0.75f); - else - NPC.rotation += NPC.direction * 0.3f; - - Vector2 enragedHeadPosition = NPC.Center; - float enragedHeadTargetX = Main.player[Main.npc[(int)NPC.ai[0]].target].Center.X - enragedHeadPosition.X; - float enragedHeadTargetY = Main.player[Main.npc[(int)NPC.ai[0]].target].Center.Y - enragedHeadPosition.Y; - float enragedHeadTargetDist = (float)Math.Sqrt(enragedHeadTargetX * enragedHeadTargetX + enragedHeadTargetY * enragedHeadTargetY); - - float enragedHeadSpeed = 10f; - enragedHeadSpeed += enragedHeadTargetDist / 100f; - if (enragedHeadSpeed < 8f) - enragedHeadSpeed = 8f; - if (enragedHeadSpeed > 32f) - enragedHeadSpeed = 32f; - - enragedHeadTargetDist = enragedHeadSpeed / enragedHeadTargetDist; - NPC.velocity.X = enragedHeadTargetX * enragedHeadTargetDist; - NPC.velocity.Y = enragedHeadTargetY * enragedHeadTargetDist; - - if (Main.netMode != NetmodeID.MultiplayerClient) - { - NPC.localAI[0] += 1f; - if (NPC.localAI[0] >= 60f) - { - NPC.localAI[0] = 0f; - Vector2 headCenter = NPC.Center; - if (Collision.CanHit(headCenter, 1, 1, Main.player[Main.npc[(int)NPC.ai[0]].target].position, Main.player[Main.npc[(int)NPC.ai[0]].target].width, Main.player[Main.npc[(int)NPC.ai[0]].target].height)) - { - enragedHeadSpeed = 7f; - float enragedHeadSkullTargetX = Main.player[Main.npc[(int)NPC.ai[0]].target].Center.X - headCenter.X + Main.rand.Next(-20, 21); - float enragedHeadSkullTargetY = Main.player[Main.npc[(int)NPC.ai[0]].target].Center.Y - headCenter.Y + Main.rand.Next(-20, 21); - float enragedHeadSkullTargetDist = (float)Math.Sqrt(enragedHeadSkullTargetX * enragedHeadSkullTargetX + enragedHeadSkullTargetY * enragedHeadSkullTargetY); - enragedHeadSkullTargetDist = enragedHeadSpeed / enragedHeadSkullTargetDist; - enragedHeadSkullTargetX *= enragedHeadSkullTargetDist; - enragedHeadSkullTargetY *= enragedHeadSkullTargetDist; - - Vector2 value = new Vector2(enragedHeadSkullTargetX * 1f + Main.rand.Next(-50, 51) * 0.01f, enragedHeadSkullTargetY * 1f + Main.rand.Next(-50, 51) * 0.01f).SafeNormalize(Vector2.UnitY); - value *= enragedHeadSpeed; - value += NPC.velocity; - enragedHeadSkullTargetX = value.X; - enragedHeadSkullTargetY = value.Y; - - int type = ProjectileID.Skull; - headCenter += value * 5f; - int enragedSkulls = Projectile.NewProjectile(NPC.GetSource_FromAI(), headCenter.X, headCenter.Y, enragedHeadSkullTargetX, enragedHeadSkullTargetY, type, 250, 0f, Main.myPlayer, -1f, 0f); - Main.projectile[enragedSkulls].timeLeft = 300; - } - } - } - } - - // Despawning - if (NPC.ai[1] == 3f) - { - // Avoid unfair bullshit - NPC.damage = 0; - - if (NPC.IsMechQueenUp) - { - int mechdusaBossDespawning = NPC.FindFirstNPC(NPCID.Retinazer); - if (mechdusaBossDespawning >= 0) - Main.npc[mechdusaBossDespawning].EncourageDespawn(5); - - mechdusaBossDespawning = NPC.FindFirstNPC(NPCID.Spazmatism); - if (mechdusaBossDespawning >= 0) - Main.npc[mechdusaBossDespawning].EncourageDespawn(5); - - if (!NPC.AnyNPCs(NPCID.Retinazer) && !NPC.AnyNPCs(NPCID.Spazmatism)) - { - mechdusaBossDespawning = NPC.FindFirstNPC(NPCID.TheDestroyer); - if (mechdusaBossDespawning >= 0) - Main.npc[mechdusaBossDespawning].Transform(NPCID.TheDestroyerTail); - - NPC.EncourageDespawn(5); - } - - NPC.velocity.Y += 0.1f; - if (NPC.velocity.Y < 0f) - NPC.velocity.Y *= 0.95f; - - NPC.velocity.X *= 0.95f; - if (NPC.velocity.Y > 13f) - NPC.velocity.Y = 13f; - } - else - { - NPC.velocity.Y += 0.1f; - if (NPC.velocity.Y < 0f) - NPC.velocity.Y *= 0.9f; - - NPC.velocity.X *= 0.9f; - - if (NPC.timeLeft > 500) - NPC.timeLeft = 500; - } - } - - // Fly around in a circle - if (NPC.ai[1] == 5f) - { - // Avoid unfair bullshit - NPC.damage = 0; - - NPC.ai[2] += 1f; - - NPC.rotation = NPC.velocity.X / 50f; - - float bombSpawnDivisor = bossRush ? 14f : death ? 22f - (float)Math.Round(5f * (1f - lifeRatio)) : 22f; - float totalBombs = 6f; - int bombSpread = bossRush ? 250 : death ? 125 : 100; - - // Spin for about 3 seconds - float spinVelocity = 24f; - if (NPC.ai[2] == 2f) - { - // Play angry noise - SoundEngine.PlaySound(SoundID.ForceRoar, NPC.Center); - - // Set spin direction - if (Main.player[Main.npc[(int)NPC.ai[0]].target].velocity.X > 0f) - calamityGlobalNPC.newAI[0] = 1f; - else if (Main.player[Main.npc[(int)NPC.ai[0]].target].velocity.X < 0f) - calamityGlobalNPC.newAI[0] = -1f; - else - calamityGlobalNPC.newAI[0] = Main.player[Main.npc[(int)NPC.ai[0]].target].direction; - - // Set spin velocity - NPC.velocity.X = MathHelper.Pi * NPC.localAI[3] / spinVelocity; - NPC.velocity *= -calamityGlobalNPC.newAI[0]; - NPC.SyncExtraAI(); - NPC.netUpdate = true; - } - - // Maintain velocity and spit homing bombs - else if (NPC.ai[2] > 2f) - { - NPC.velocity = NPC.velocity.RotatedBy(MathHelper.Pi / spinVelocity * -calamityGlobalNPC.newAI[0]); - if (NPC.ai[2] == 3f) - NPC.velocity *= 0.6f; - - if (NPC.ai[2] % bombSpawnDivisor == 0f) - { - NPC.localAI[0] += 1f; - - if (Vector2.Distance(Main.player[Main.npc[(int)NPC.ai[0]].target].Center, NPC.Center) > 64f) - { - SoundEngine.PlaySound(SoundID.Item61, NPC.Center); - CreateParticles(NPC, new Vector2(NPC.Center.X + Main.rand.Next(NPC.width / 2), NPC.Center.Y + 4f)); - - if (Main.netMode != NetmodeID.MultiplayerClient) - { - Vector2 headCenter = NPC.Center; - float enragedHeadSpeed = 6f + (death ? 2f * (1f - lifeRatio) : 0f); - float enragedHeadBombTargetX = Main.player[Main.npc[(int)NPC.ai[0]].target].Center.X - headCenter.X + Main.rand.Next(-20, 21); - float enragedHeadBombTargetY = Main.player[Main.npc[(int)NPC.ai[0]].target].Center.Y - headCenter.Y + Main.rand.Next(-20, 21); - float enragedHeadBombTargetDist = (float)Math.Sqrt(enragedHeadBombTargetX * enragedHeadBombTargetX + enragedHeadBombTargetY * enragedHeadBombTargetY); - enragedHeadBombTargetDist = enragedHeadSpeed / enragedHeadBombTargetDist; - enragedHeadBombTargetX *= enragedHeadBombTargetDist; - enragedHeadBombTargetY *= enragedHeadBombTargetDist; - - Vector2 value = new Vector2(enragedHeadBombTargetX + Main.rand.Next(-bombSpread, bombSpread + 1) * 0.01f, enragedHeadBombTargetY + Main.rand.Next(-bombSpread, bombSpread + 1) * 0.01f).SafeNormalize(Vector2.UnitY); - value *= enragedHeadSpeed; - enragedHeadBombTargetX = value.X; - enragedHeadBombTargetY = value.Y; - - int type = ProjectileID.BombSkeletronPrime; - int damage = NPC.GetProjectileDamage(type); - - // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) - { - double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; - double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; - if (!NPC.downedMechBossAny) - damage = (int)(damage * firstMechMultiplier); - else if ((!NPC.downedMechBoss1 && !NPC.downedMechBoss2) || (!NPC.downedMechBoss2 && !NPC.downedMechBoss3) || (!NPC.downedMechBoss3 && !NPC.downedMechBoss1)) - damage = (int)(damage * secondMechMultiplier); - } - - int enragedBombs = Projectile.NewProjectile(NPC.GetSource_FromAI(), headCenter.X, headCenter.Y + 30f, enragedHeadBombTargetX, enragedHeadBombTargetY, type, damage, 0f, Main.myPlayer, -1f); - Main.projectile[enragedBombs].timeLeft = BombTimeLeft; - Main.projectile[enragedBombs].tileCollide = false; - } - } - - // Go to floating phase, or spinning phase if in phase 2 - if (NPC.localAI[0] >= totalBombs) - { - NPC.velocity = NPC.velocity.SafeNormalize(Vector2.UnitY); - - // Fly overhead and spit spreads of bombs into the air if on low health - NPC.ai[1] = phase3 ? 6f : 1f; - NPC.ai[2] = 0f; - NPC.localAI[3] = 0f; - NPC.localAI[0] = 0f; - calamityGlobalNPC.newAI[0] = 0f; - NPC.SyncVanillaLocalAI(); - NPC.SyncExtraAI(); - NPC.netUpdate = true; - } - } - } - } - - // Fly overhead and spit bombs - if (NPC.ai[1] == 6f) - { - // Avoid unfair bullshit - NPC.damage = 0; - - NPC.rotation = NPC.velocity.X / 15f; - - float flightVelocity = bossRush ? 32f : death ? 28f : 24f; - float flightAcceleration = bossRush ? 1.28f : death ? 1.12f : 0.96f; - - Vector2 destination = new Vector2(Main.player[Main.npc[(int)NPC.ai[0]].target].Center.X, Main.player[Main.npc[(int)NPC.ai[0]].target].Center.Y - 500f); - NPC.SimpleFlyMovement((destination - NPC.Center).SafeNormalize(Vector2.UnitY) * flightVelocity, flightAcceleration); - - // Spit bombs and then go to floating phase - NPC.localAI[3] += 1f; - if (Vector2.Distance(NPC.Center, destination) < 160f || NPC.ai[2] > 0f || NPC.localAI[3] > 120f) - { - float bombSpawnDivisor = death ? 50f : 60f; - float totalBombSpreads = 2f; - NPC.ai[2] += 1f; - if (NPC.ai[2] % bombSpawnDivisor == 0f) - { - NPC.localAI[0] += 1f; - - if (Main.netMode != NetmodeID.MultiplayerClient) - { - int totalProjectiles = bossRush ? 24 : 12; - float radians = MathHelper.TwoPi / totalProjectiles; - int type = ProjectileID.BombSkeletronPrime; - int damage = NPC.GetProjectileDamage(type); - - // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) - { - double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; - double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; - if (!NPC.downedMechBossAny) - damage = (int)(damage * firstMechMultiplier); - else if ((!NPC.downedMechBoss1 && !NPC.downedMechBoss2) || (!NPC.downedMechBoss2 && !NPC.downedMechBoss3) || (!NPC.downedMechBoss3 && !NPC.downedMechBoss1)) - damage = (int)(damage * secondMechMultiplier); - } - - float velocity = 12f; - double angleA = radians * 0.5; - double angleB = MathHelper.ToRadians(90f) - angleA; - float velocityX = (float)(velocity * Math.Sin(angleA) / Math.Sin(angleB)); - Vector2 spinningPoint = normalLaserRotation ? new Vector2(0f, -velocity) : new Vector2(-velocityX, -velocity); - Vector2 upwardVelocity = Vector2.UnitY * velocity; - for (int k = 0; k < totalProjectiles; k++) - { - Vector2 bombVelocity = spinningPoint.RotatedBy(radians * k); - int proj = Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center + Vector2.UnitY * 30f + bombVelocity.SafeNormalize(Vector2.UnitY) * 15f, bombVelocity - upwardVelocity, type, damage, 0f, Main.myPlayer, -2f); - Main.projectile[proj].timeLeft = BombTimeLeft; - Main.projectile[proj].tileCollide = false; - } - NPC.localAI[1] += 1f; - } - - SoundEngine.PlaySound(SoundID.Item62, NPC.Center); - CreateParticles(NPC, new Vector2(NPC.Center.X, NPC.Center.Y + 4f), 5); - - if (NPC.localAI[0] >= totalBombSpreads) - { - NPC.ai[1] = 0f; - NPC.ai[2] = 0f; - NPC.localAI[3] = 0f; - calamityGlobalNPC.newAI[0] = 0f; - NPC.localAI[0] = 0f; - NPC.SyncVanillaLocalAI(); - NPC.SyncExtraAI(); - NPC.netUpdate = true; - } - } - } - } - } - } - - private void CreateParticles(NPC npc, Vector2 position, int amountMultiplier = 1) - { - int firstDustCloudParticleAmount = 30 * amountMultiplier; - int secondDustCloudParticleAmount = 20 * amountMultiplier; - int goreAmount = 2 * amountMultiplier; - - for (int dustIndex = 0; dustIndex < firstDustCloudParticleAmount; dustIndex++) - { - int dust = Dust.NewDust(npc.position, npc.width, npc.height, DustID.Smoke, 0f, 0f, 100, default(Color), 1.5f); - Main.dust[dust].velocity *= 1.4f; - } - - for (int dustIndex = 0; dustIndex < secondDustCloudParticleAmount; dustIndex++) - { - int dust = Dust.NewDust(npc.position, npc.width, npc.height, DustID.Torch, 0f, 0f, 100, default(Color), 3.5f); - Main.dust[dust].noGravity = true; - Main.dust[dust].velocity *= 7f; - dust = Dust.NewDust(npc.position, npc.width, npc.height, DustID.Torch, 0f, 0f, 100, default(Color), 1.5f); - Main.dust[dust].velocity *= 3f; - } - - for (int goreIndex = 0; goreIndex < goreAmount; goreIndex++) - { - float goreVelocityMultiplier = 0.4f; - if (goreIndex >= goreAmount / 2) - goreVelocityMultiplier = 0.8f; - - int gore = Gore.NewGore(npc.GetSource_FromAI(), npc.Center, default(Vector2), Main.rand.Next(61, 64)); - Main.gore[gore].velocity *= goreVelocityMultiplier; - Main.gore[gore].velocity.X += 1f; - Main.gore[gore].velocity.Y += 1f; - gore = Gore.NewGore(npc.GetSource_FromAI(), npc.Center, default(Vector2), Main.rand.Next(61, 64)); - Main.gore[gore].velocity *= goreVelocityMultiplier; - Main.gore[gore].velocity.X -= 1f; - Main.gore[gore].velocity.Y += 1f; - gore = Gore.NewGore(npc.GetSource_FromAI(), npc.Center, default(Vector2), Main.rand.Next(61, 64)); - Main.gore[gore].velocity *= goreVelocityMultiplier; - Main.gore[gore].velocity.X += 1f; - Main.gore[gore].velocity.Y -= 1f; - gore = Gore.NewGore(npc.GetSource_FromAI(), npc.Center, default(Vector2), Main.rand.Next(61, 64)); - Main.gore[gore].velocity *= goreVelocityMultiplier; - Main.gore[gore].velocity.X -= 1f; - Main.gore[gore].velocity.Y -= 1f; - } - } - - public override void BossLoot(ref string name, ref int potionType) => potionType = ItemID.GreaterHealingPotion; - - public override void ApplyDifficultyAndPlayerScaling(int numPlayers, float balance, float bossAdjustment) - { - NPC.lifeMax = (int)(NPC.lifeMax * 0.75f * balance * bossAdjustment); - NPC.damage = (int)(NPC.damage * NPC.GetExpertDamageMultiplier()); - } - - public override bool CheckActive() => false; - - public override bool CheckDead() - { - // Kill the lead head if he's still alive when this head dies - for (int i = 0; i < Main.maxNPCs; i++) - { - NPC nPC = Main.npc[i]; - if (nPC.active && nPC.type == NPCID.SkeletronPrime && nPC.life > 0) - { - nPC.life = 0; - nPC.HitEffect(); - nPC.checkDead(); - nPC.active = false; - nPC.netUpdate = true; - } - } - - return true; - } - - public override void HitEffect(NPC.HitInfo hit) - { - if (NPC.life <= 0) - { - if (Main.netMode != NetmodeID.Server) - { - Gore.NewGore(NPC.GetSource_Death(), NPC.position, NPC.velocity, 149); - Gore.NewGore(NPC.GetSource_Death(), NPC.position, NPC.velocity, 150); - - int num802 = Gore.NewGore(NPC.GetSource_Death(), NPC.position, default(Vector2), Main.rand.Next(61, 64)); - Gore gore2 = Main.gore[num802]; - gore2.velocity *= 0.4f; - Main.gore[num802].velocity.X += 1f; - Main.gore[num802].velocity.Y += 1f; - - num802 = Gore.NewGore(NPC.GetSource_Death(), NPC.position, default(Vector2), Main.rand.Next(61, 64)); - gore2 = Main.gore[num802]; - gore2.velocity *= 0.4f; - Main.gore[num802].velocity.X -= 1f; - Main.gore[num802].velocity.Y += 1f; - - num802 = Gore.NewGore(NPC.GetSource_Death(), NPC.position, default(Vector2), Main.rand.Next(61, 64)); - gore2 = Main.gore[num802]; - gore2.velocity *= 0.4f; - Main.gore[num802].velocity.X += 1f; - Main.gore[num802].velocity.Y -= 1f; - - num802 = Gore.NewGore(NPC.GetSource_Death(), NPC.position, default(Vector2), Main.rand.Next(61, 64)); - gore2 = Main.gore[num802]; - gore2.velocity *= 0.4f; - Main.gore[num802].velocity.X -= 1f; - Main.gore[num802].velocity.Y -= 1f; - } - - for (int num798 = 0; num798 < 10; num798++) - { - int num799 = Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Smoke, 0f, 0f, 100, default(Color), 1.5f); - Dust dust = Main.dust[num799]; - dust.velocity *= 1.4f; - } - - for (int num800 = 0; num800 < 5; num800++) - { - int num801 = Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Torch, 0f, 0f, 100, default(Color), 2.5f); - Main.dust[num801].noGravity = true; - Dust dust = Main.dust[num801]; - dust.velocity *= 5f; - num801 = Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Torch, 0f, 0f, 100, default(Color), 1.5f); - dust = Main.dust[num801]; - dust.velocity *= 3f; - } - } - } - } -} diff --git a/NPCs/NormalNPCs/SkeletronPrime2.png b/NPCs/NormalNPCs/SkeletronPrime2.png deleted file mode 100644 index c019c31308..0000000000 Binary files a/NPCs/NormalNPCs/SkeletronPrime2.png and /dev/null differ 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/NormalNPCs/WildBumblefuck.cs b/NPCs/NormalNPCs/WildBumblefuck.cs index 8421f495ff..95f5122d35 100644 --- a/NPCs/NormalNPCs/WildBumblefuck.cs +++ b/NPCs/NormalNPCs/WildBumblefuck.cs @@ -129,7 +129,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2(TextureAssets.Npc[NPC.type].Value.Width / 2, TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2); int afterimageAmt = NPC.ai[0] == 2.1f ? 7 : 0; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { diff --git a/NPCs/OldDuke/OldDuke.cs b/NPCs/OldDuke/OldDuke.cs index fc8ac6e7b3..745133b9e7 100644 --- a/NPCs/OldDuke/OldDuke.cs +++ b/NPCs/OldDuke/OldDuke.cs @@ -73,7 +73,7 @@ public override void SetDefaults() NPC.defense = 90; NPC.DR_NERD(0.5f, null, null, null, true); NPC.LifeMaxNERB(500000, 600000, 400000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.noTileCollide = true; @@ -258,7 +258,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d color = drawColor; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += afterimageIncrement) { @@ -309,7 +309,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d afterimageScale = 20f; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 0; j < secondAfterimageAmt; j++) { @@ -365,7 +365,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d yellowLerpColor *= ai2Opacity; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int k = 1; k < afterimageAmt; k += afterimageIncrement) { diff --git a/NPCs/OldDuke/OldDukeToothBall.cs b/NPCs/OldDuke/OldDukeToothBall.cs index f880849a6e..83b18e5d9b 100644 --- a/NPCs/OldDuke/OldDukeToothBall.cs +++ b/NPCs/OldDuke/OldDukeToothBall.cs @@ -32,7 +32,7 @@ public override void SetDefaults() { NPC.lifeMax = 16000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.2f; NPC.HitSound = SoundID.NPCHit1; diff --git a/NPCs/OldDuke/SulphurousSharkron.cs b/NPCs/OldDuke/SulphurousSharkron.cs index f1480f9f0a..6e8113b600 100644 --- a/NPCs/OldDuke/SulphurousSharkron.cs +++ b/NPCs/OldDuke/SulphurousSharkron.cs @@ -39,7 +39,7 @@ public override void SetDefaults() { NPC.lifeMax = 10000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.HitSound = SoundID.NPCHit1; NPC.DeathSound = SoundID.NPCDeath1; @@ -245,7 +245,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2(TextureAssets.Npc[NPC.type].Value.Width / 2, TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2); int afterimageAmt = 10; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { diff --git a/NPCs/Perforator/PerforatorBodyLarge.cs b/NPCs/Perforator/PerforatorBodyLarge.cs index c25aae7727..6be18b93b6 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); @@ -46,7 +47,7 @@ public override void SetDefaults() if (Main.zenithWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/Perforator/PerforatorBodyMedium.cs b/NPCs/Perforator/PerforatorBodyMedium.cs index ef764fa9f1..ddaee3bf97 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); @@ -44,7 +45,7 @@ public override void SetDefaults() if (Main.zenithWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/Perforator/PerforatorBodySmall.cs b/NPCs/Perforator/PerforatorBodySmall.cs index 08627fc303..22649de4aa 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); @@ -41,7 +42,7 @@ public override void SetDefaults() if (Main.zenithWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/Perforator/PerforatorHeadLarge.cs b/NPCs/Perforator/PerforatorHeadLarge.cs index ae4e888120..c29eb9782f 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); @@ -61,7 +62,7 @@ public override void SetDefaults() if (Main.zenithWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/Perforator/PerforatorHeadMedium.cs b/NPCs/Perforator/PerforatorHeadMedium.cs index acdb3c712b..7b1858cd10 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); @@ -57,7 +58,7 @@ public override void SetDefaults() if (Main.zenithWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/Perforator/PerforatorHeadSmall.cs b/NPCs/Perforator/PerforatorHeadSmall.cs index 40a2a555dc..a0e4994598 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); @@ -60,7 +61,7 @@ public override void SetDefaults() if (Main.zenithWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/Perforator/PerforatorHive.cs b/NPCs/Perforator/PerforatorHive.cs index 92c52757ba..fbeaf2b06f 100644 --- a/NPCs/Perforator/PerforatorHive.cs +++ b/NPCs/Perforator/PerforatorHive.cs @@ -72,7 +72,7 @@ public override void SetDefaults() NPC.height = 100; NPC.defense = 4; NPC.LifeMaxNERB(6000, 7200, 270000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/Perforator/PerforatorTailLarge.cs b/NPCs/Perforator/PerforatorTailLarge.cs index 5095d20a37..656d1ee34e 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); @@ -41,7 +42,7 @@ public override void SetDefaults() if (Main.zenithWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/Perforator/PerforatorTailMedium.cs b/NPCs/Perforator/PerforatorTailMedium.cs index 6880426acc..018a21c9d9 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); @@ -44,7 +45,7 @@ public override void SetDefaults() if (Main.zenithWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/Perforator/PerforatorTailSmall.cs b/NPCs/Perforator/PerforatorTailSmall.cs index 30ad5f8738..264bb06e18 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); @@ -41,7 +42,7 @@ public override void SetDefaults() if (Main.zenithWorld) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/PlagueEnemies/PlagueCharger.cs b/NPCs/PlagueEnemies/PlagueCharger.cs index 1f79c757cc..94015d6530 100644 --- a/NPCs/PlagueEnemies/PlagueCharger.cs +++ b/NPCs/PlagueEnemies/PlagueCharger.cs @@ -77,7 +77,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2((float)(TextureAssets.Npc[NPC.type].Value.Width / 2), (float)(TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2)); int afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -100,7 +100,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture2D15 = GlowTexture.Value; Color redEyeColor = Color.Lerp(Color.White, Color.Red, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/PlagueEnemies/PlagueChargerLarge.cs b/NPCs/PlagueEnemies/PlagueChargerLarge.cs index c6b4e66b75..c0aadd70db 100644 --- a/NPCs/PlagueEnemies/PlagueChargerLarge.cs +++ b/NPCs/PlagueEnemies/PlagueChargerLarge.cs @@ -72,7 +72,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2((float)(TextureAssets.Npc[NPC.type].Value.Width / 2), (float)(TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2)); int afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -95,7 +95,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture2D15 = ModContent.Request("CalamityMod/NPCs/PlagueEnemies/PlagueChargerGlow").Value; Color redEyeColor = Color.Lerp(Color.White, Color.Red, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/PlagueEnemies/PlaguebringerMiniboss.cs b/NPCs/PlagueEnemies/PlaguebringerMiniboss.cs index d8abae06ac..6cae925162 100644 --- a/NPCs/PlagueEnemies/PlaguebringerMiniboss.cs +++ b/NPCs/PlagueEnemies/PlaguebringerMiniboss.cs @@ -337,7 +337,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d if (NPC.ai[0] != 0f) afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { diff --git a/NPCs/PlaguebringerGoliath/PlagueHomingMissile.cs b/NPCs/PlaguebringerGoliath/PlagueHomingMissile.cs index a01811e7b6..8b26d7e1aa 100644 --- a/NPCs/PlaguebringerGoliath/PlagueHomingMissile.cs +++ b/NPCs/PlaguebringerGoliath/PlagueHomingMissile.cs @@ -37,7 +37,7 @@ public override void SetDefaults() NPC.height = 22; NPC.defense = 20; NPC.lifeMax = BossRushEvent.BossRushActive ? 5000 : 500; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -170,7 +170,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2((float)(TextureAssets.Npc[NPC.type].Value.Width / 2), (float)(TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2)); int afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -193,7 +193,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture2D15 = GlowTexture.Value; Color redLerpColor = Color.Lerp(Color.White, Color.Red, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/PlaguebringerGoliath/PlagueMine.cs b/NPCs/PlaguebringerGoliath/PlagueMine.cs index efca4ac339..7df52f7db9 100644 --- a/NPCs/PlaguebringerGoliath/PlagueMine.cs +++ b/NPCs/PlaguebringerGoliath/PlagueMine.cs @@ -35,7 +35,7 @@ public override void SetDefaults() NPC.height = 42; NPC.defense = 20; NPC.lifeMax = BossRushEvent.BossRushActive ? 10000 : 1000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/PlaguebringerGoliath/PlaguebringerGoliath.cs b/NPCs/PlaguebringerGoliath/PlaguebringerGoliath.cs index e1983374f1..c013757851 100644 --- a/NPCs/PlaguebringerGoliath/PlaguebringerGoliath.cs +++ b/NPCs/PlaguebringerGoliath/PlaguebringerGoliath.cs @@ -91,7 +91,7 @@ public override void SetDefaults() NPC.defense = 50; NPC.DR_NERD(0.3f); NPC.LifeMaxNERB(87500, 105000, 370000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.aiStyle = -1; @@ -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; @@ -1265,7 +1264,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d if (NPC.ai[0] != 0f && NPC.ai[0] != 4f) afterimageAmt = 7; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j += 2) { @@ -1287,7 +1286,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color redLerpColor = Color.Lerp(Color.White, Color.Red, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int k = 1; k < afterimageAmt; k++) { diff --git a/NPCs/Polterghast/PhantomFuckYou.cs b/NPCs/Polterghast/PhantomFuckYou.cs index 8856bddc30..e10c08cfad 100644 --- a/NPCs/Polterghast/PhantomFuckYou.cs +++ b/NPCs/Polterghast/PhantomFuckYou.cs @@ -34,7 +34,7 @@ public override void SetDefaults() NPC.noTileCollide = true; NPC.damage = 50; NPC.lifeMax = 20000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.HitSound = SoundID.NPCHit36; NPC.DeathSound = SoundID.NPCDeath39; @@ -153,7 +153,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2(TextureAssets.Npc[NPC.type].Value.Width / 2, TextureAssets.Npc[NPC.type].Value.Height / 2); int afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { diff --git a/NPCs/Polterghast/PolterPhantom.cs b/NPCs/Polterghast/PolterPhantom.cs index 6724039449..386e63a586 100644 --- a/NPCs/Polterghast/PolterPhantom.cs +++ b/NPCs/Polterghast/PolterPhantom.cs @@ -47,7 +47,7 @@ public override void SetDefaults() if (CalamityWorld.LegendaryMode && CalamityWorld.revenge) NPC.lifeMax *= 4; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.aiStyle = -1; @@ -454,7 +454,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color lightRed = new Color(255, 100, 100, 255) * NPC.Opacity; int afterimageAmt = 7; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -489,7 +489,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color blackWhiteLerp = Color.Lerp(Color.White, c, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/Polterghast/Polterghast.cs b/NPCs/Polterghast/Polterghast.cs index 1c8833c123..06987bfa38 100644 --- a/NPCs/Polterghast/Polterghast.cs +++ b/NPCs/Polterghast/Polterghast.cs @@ -116,7 +116,7 @@ public override void SetDefaults() NPC.defense = 90; NPC.DR_NERD(0.2f); NPC.LifeMaxNERB(350000, 420000, 325000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.aiStyle = -1; @@ -306,7 +306,7 @@ public override void AI() } // Stop rain - if (CalamityConfig.Instance.BossesStopWeather) + if (CalamityServerConfig.Instance.BossesStopWeather) CalamityMod.StopRain(); // Set time left @@ -1164,7 +1164,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2(TextureAssets.Npc[NPC.type].Value.Width / 2, TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2); int afterimageAmt = 7; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -1208,7 +1208,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color veinColor = Color.Lerp(Color.White, (NPC.ai[2] >= changeColorGateValue || NPC.Calamity().newAI[0] > changeColorGateValue) ? Color.Red : Color.Black, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/Polterghast/PolterghastHook.cs b/NPCs/Polterghast/PolterghastHook.cs index 50c6039a49..be8e568245 100644 --- a/NPCs/Polterghast/PolterghastHook.cs +++ b/NPCs/Polterghast/PolterghastHook.cs @@ -375,7 +375,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2(TextureAssets.Npc[NPC.type].Value.Width / 2, TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2); int afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -401,7 +401,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d if (Main.npc[CalamityGlobalNPC.ghostBoss].Calamity().newAI[0] > changeColorGateValue) cyanLerp2 = Color.Lerp(cyanLerp2, lightRed, MathHelper.Clamp((Main.npc[CalamityGlobalNPC.ghostBoss].Calamity().newAI[0] - changeColorGateValue) / timeToReachFullColor, 0f, 1f)); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/PrimordialWyrm/PrimordialWyrmBody.cs b/NPCs/PrimordialWyrm/PrimordialWyrmBody.cs index edd0b1f728..8c781cda95 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; @@ -34,7 +35,7 @@ public override void SetDefaults() NPC.height = 88; NPC.defense = 0; NPC.LifeMaxNERB(2500000, 3000000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/PrimordialWyrm/PrimordialWyrmBodyAlt.cs b/NPCs/PrimordialWyrm/PrimordialWyrmBodyAlt.cs index 823636e046..ab0e39e298 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; @@ -33,7 +34,7 @@ public override void SetDefaults() NPC.height = 88; NPC.defense = 0; NPC.LifeMaxNERB(2500000, 3000000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/PrimordialWyrm/PrimordialWyrmHead.cs b/NPCs/PrimordialWyrm/PrimordialWyrmHead.cs index 49391cd55c..e639fd28ab 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 @@ -111,7 +112,7 @@ public override void SetDefaults() NPC.width = 254; NPC.height = 138; NPC.LifeMaxNERB(2500000, 3000000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -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; @@ -1452,6 +1452,13 @@ public override void BossLoot(ref string name, ref int potionType) potionType = ModContent.ItemType(); } + public override void OnKill() + { + // Mark Primordial Wyrm as dead + DownedBossSystem.downedPrimordialWyrm = true; + CalamityNetcode.SyncWorld(); + } + public override void ModifyNPCLoot(NPCLoot npcLoot) { npcLoot.Add(ModContent.ItemType()); diff --git a/NPCs/PrimordialWyrm/PrimordialWyrmTail.cs b/NPCs/PrimordialWyrm/PrimordialWyrmTail.cs index 7b9aae19b0..c9ab0e90ec 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; @@ -32,7 +33,7 @@ public override void SetDefaults() NPC.height = 120; NPC.defense = 0; NPC.LifeMaxNERB(2500000, 3000000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs b/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs index a98ab63273..28605cc0a8 100644 --- a/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs +++ b/NPCs/ProfanedGuardians/ProfanedGuardianCommander.cs @@ -75,7 +75,7 @@ public override void SetDefaults() NPC.defense = 40; NPC.DR_NERD(0.3f); NPC.LifeMaxNERB(100000, 120000, 200000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.noGravity = true; @@ -1015,7 +1015,7 @@ void drawGuardianInstance(Vector2 drawOffset, Color? colorOverride) if (NPC.ai[0] == 2f) afterimageAmt = 10; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -1053,7 +1053,7 @@ void drawGuardianInstance(Vector2 drawOffset, Color? colorOverride) if (colorOverride != null) timeBasedColorLerp = colorOverride.Value; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/ProfanedGuardians/ProfanedGuardianDefender.cs b/NPCs/ProfanedGuardians/ProfanedGuardianDefender.cs index b4033cedc5..465d95f646 100644 --- a/NPCs/ProfanedGuardians/ProfanedGuardianDefender.cs +++ b/NPCs/ProfanedGuardians/ProfanedGuardianDefender.cs @@ -65,7 +65,7 @@ public override void SetDefaults() NPC.defense = 50; NPC.DR_NERD(0.4f); NPC.LifeMaxNERB(40000, 48000, 35000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.noGravity = true; @@ -738,7 +738,7 @@ void drawGuardianInstance(Vector2 drawOffset, Color? colorOverride) if (NPC.ai[0] == 2f) afterimageAmt = 10; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -776,7 +776,7 @@ void drawGuardianInstance(Vector2 drawOffset, Color? colorOverride) if (colorOverride != null) timeBasedGlowColor = colorOverride.Value; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/ProfanedGuardians/ProfanedGuardianHealer.cs b/NPCs/ProfanedGuardians/ProfanedGuardianHealer.cs index 03ed34ed59..53074dc77b 100644 --- a/NPCs/ProfanedGuardians/ProfanedGuardianHealer.cs +++ b/NPCs/ProfanedGuardians/ProfanedGuardianHealer.cs @@ -78,7 +78,7 @@ public override void SetDefaults() NPC.defense = 30; NPC.DR_NERD(0.2f); NPC.LifeMaxNERB(60000, 72000, 50000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.noGravity = true; @@ -443,7 +443,7 @@ void drawGuardianInstance(Vector2 drawOffset, Color? colorOverride) Vector2 halfSizeTexture = new Vector2(TextureAssets.Npc[NPC.type].Value.Width / 2, TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2); int afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -485,7 +485,7 @@ void drawGuardianInstance(Vector2 drawOffset, Color? colorOverride) overrideColor = colorOverride.Value; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/ProfanedGuardians/ProfanedRocks.cs b/NPCs/ProfanedGuardians/ProfanedRocks.cs index 6e8de8df02..1163bdc1c3 100644 --- a/NPCs/ProfanedGuardians/ProfanedRocks.cs +++ b/NPCs/ProfanedGuardians/ProfanedRocks.cs @@ -50,7 +50,7 @@ public override void SetDefaults() NPC.height = 50; NPC.defense = 100; NPC.lifeMax = BossRushEvent.BossRushActive ? MaxBossRushHP : MaxHP; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.Opacity = 0f; diff --git a/NPCs/Providence/ProvSpawnDefense.cs b/NPCs/Providence/ProvSpawnDefense.cs index 0e2e9a8d0d..40a19d10d8 100644 --- a/NPCs/Providence/ProvSpawnDefense.cs +++ b/NPCs/Providence/ProvSpawnDefense.cs @@ -41,7 +41,7 @@ public override void SetDefaults() { NPC.lifeMax = 30000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.noGravity = true; @@ -122,7 +122,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2((float)(TextureAssets.Npc[NPC.type].Value.Width / 2), (float)(TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2)); int afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -145,7 +145,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture2D15 = ProfanedGuardianDefender.Texture_Glow.Value; Color yellowLerp = Color.Lerp(Color.White, Color.Yellow, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/Providence/ProvSpawnHealer.cs b/NPCs/Providence/ProvSpawnHealer.cs index 9d1aa49894..3988b3f8ce 100644 --- a/NPCs/Providence/ProvSpawnHealer.cs +++ b/NPCs/Providence/ProvSpawnHealer.cs @@ -40,7 +40,7 @@ public override void SetDefaults() { NPC.lifeMax = 20000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.noGravity = true; @@ -122,7 +122,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2((float)(TextureAssets.Npc[NPC.type].Value.Width / 2), (float)(TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2)); int afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -146,7 +146,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color yellowLerp = Color.Lerp(Color.White, Color.Yellow, 0.5f); Color violetLerp = Color.Lerp(Color.White, Color.Violet, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/Providence/ProvSpawnOffense.cs b/NPCs/Providence/ProvSpawnOffense.cs index faa67a7dfa..0ecc8a9d0b 100644 --- a/NPCs/Providence/ProvSpawnOffense.cs +++ b/NPCs/Providence/ProvSpawnOffense.cs @@ -41,7 +41,7 @@ public override void SetDefaults() { NPC.lifeMax = 40000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.noGravity = true; @@ -124,7 +124,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d if (NPC.ai[0] == 2f) afterimageAmt = 10; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -147,7 +147,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture2D15 = ProfanedGuardianCommander.Texture_Glow.Value; Color yellowLerpColor = Color.Lerp(Color.White, Color.Yellow, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/Providence/Providence.cs b/NPCs/Providence/Providence.cs index aeb2b7d136..470f8361fa 100644 --- a/NPCs/Providence/Providence.cs +++ b/NPCs/Providence/Providence.cs @@ -229,7 +229,7 @@ public override void SetDefaults() NPC.defense = 50; NPC.DR_NERD(normalDR); NPC.LifeMaxNERB(312500, 375000, 1250000); // Old HP - 440000, 500000 - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.aiStyle = -1; @@ -613,7 +613,7 @@ public override void AI() NPC.chaseable = normalAttackRate; // Prevent lag by stopping rain - if (CalamityConfig.Instance.BossesStopWeather) + if (CalamityServerConfig.Instance.BossesStopWeather) CalamityMod.StopRain(); // Set target biome type @@ -2206,7 +2206,7 @@ void drawProvidenceInstance(Vector2 drawOffset, Color? colorOverride) float Brightness = 0.5f; // Ranges from 0 (full vibrance) to 1 (pure white) int maxAfterimages = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < maxAfterimages; i += 2) { @@ -2270,7 +2270,7 @@ void drawProvidenceInstance(Vector2 drawOffset, Color? colorOverride) BaseCrystalColor = colorOverride.Value; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < maxAfterimages; j++) { diff --git a/NPCs/Ravager/FlamePillar.cs b/NPCs/Ravager/FlamePillar.cs index 933d5a4a8e..ca0b5a9738 100644 --- a/NPCs/Ravager/FlamePillar.cs +++ b/NPCs/Ravager/FlamePillar.cs @@ -36,7 +36,7 @@ public override void SetDefaults() NPC.DR_NERD(0.2f); NPC.chaseable = false; NPC.lifeMax = DownedBossSystem.downedProvidence ? 14000 : 3500; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.alpha = 255; NPC.aiStyle = -1; diff --git a/NPCs/Ravager/RavagerBody.cs b/NPCs/Ravager/RavagerBody.cs index 09b76c70fb..7c2a14c120 100644 --- a/NPCs/Ravager/RavagerBody.cs +++ b/NPCs/Ravager/RavagerBody.cs @@ -90,7 +90,7 @@ public override void SetDefaults() NPC.lifeMax *= 4; NPC.value *= 1.5f; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; AIType = -1; diff --git a/NPCs/Ravager/RavagerClawLeft.cs b/NPCs/Ravager/RavagerClawLeft.cs index 218826ba88..d3d52720cf 100644 --- a/NPCs/Ravager/RavagerClawLeft.cs +++ b/NPCs/Ravager/RavagerClawLeft.cs @@ -48,7 +48,7 @@ public override void SetDefaults() { NPC.lifeMax = 26000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.Calamity().VulnerableToSickness = false; NPC.Calamity().VulnerableToWater = true; diff --git a/NPCs/Ravager/RavagerClawRight.cs b/NPCs/Ravager/RavagerClawRight.cs index 360d61c8a6..20a9ef22a7 100644 --- a/NPCs/Ravager/RavagerClawRight.cs +++ b/NPCs/Ravager/RavagerClawRight.cs @@ -48,7 +48,7 @@ public override void SetDefaults() { NPC.lifeMax = 26000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.Calamity().VulnerableToSickness = false; NPC.Calamity().VulnerableToWater = true; diff --git a/NPCs/Ravager/RavagerHead.cs b/NPCs/Ravager/RavagerHead.cs index b0ff5f487d..27fa02895a 100644 --- a/NPCs/Ravager/RavagerHead.cs +++ b/NPCs/Ravager/RavagerHead.cs @@ -45,7 +45,7 @@ public override void SetDefaults() { NPC.lifeMax = 45000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.Calamity().VulnerableToSickness = false; NPC.Calamity().VulnerableToWater = true; diff --git a/NPCs/Ravager/RavagerHead2.cs b/NPCs/Ravager/RavagerHead2.cs index ccaa1b8db8..2e02f21309 100644 --- a/NPCs/Ravager/RavagerHead2.cs +++ b/NPCs/Ravager/RavagerHead2.cs @@ -44,7 +44,7 @@ public override void SetDefaults() { NPC.lifeMax = 22500; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.Calamity().VulnerableToSickness = false; NPC.Calamity().VulnerableToWater = true; diff --git a/NPCs/Ravager/RavagerLegLeft.cs b/NPCs/Ravager/RavagerLegLeft.cs index 9c1c8355b5..fcccbce5fe 100644 --- a/NPCs/Ravager/RavagerLegLeft.cs +++ b/NPCs/Ravager/RavagerLegLeft.cs @@ -41,7 +41,7 @@ public override void SetDefaults() { NPC.lifeMax = 40000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.Calamity().VulnerableToSickness = false; NPC.Calamity().VulnerableToWater = true; diff --git a/NPCs/Ravager/RavagerLegRight.cs b/NPCs/Ravager/RavagerLegRight.cs index 01ba1268f8..0278f3ad51 100644 --- a/NPCs/Ravager/RavagerLegRight.cs +++ b/NPCs/Ravager/RavagerLegRight.cs @@ -41,7 +41,7 @@ public override void SetDefaults() { NPC.lifeMax = 40000; } - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.Calamity().VulnerableToSickness = false; NPC.Calamity().VulnerableToWater = true; diff --git a/NPCs/Ravager/RockPillar.cs b/NPCs/Ravager/RockPillar.cs index 7af3541cc5..6d14900915 100644 --- a/NPCs/Ravager/RockPillar.cs +++ b/NPCs/Ravager/RockPillar.cs @@ -28,7 +28,7 @@ public override void SetDefaults() NPC.DR_NERD(0.3f); NPC.chaseable = false; NPC.lifeMax = DownedBossSystem.downedProvidence ? 20000 : 5000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.alpha = 255; NPC.aiStyle = -1; diff --git a/NPCs/Signus/CosmicLantern.cs b/NPCs/Signus/CosmicLantern.cs index b3ba7cb89d..c0514c1009 100644 --- a/NPCs/Signus/CosmicLantern.cs +++ b/NPCs/Signus/CosmicLantern.cs @@ -36,7 +36,7 @@ public override void SetDefaults() NPC.height = 25; NPC.defense = 50; NPC.lifeMax = 25; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.alpha = 255; NPC.knockBackResist = 0.85f; @@ -133,7 +133,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2((float)(TextureAssets.Npc[NPC.type].Value.Width / 2), (float)(TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2)); int afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -156,7 +156,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture2D15 = GlowTexture.Value; Color cyanLerp = Color.Lerp(Color.White, Color.Cyan, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/Signus/CosmicMine.cs b/NPCs/Signus/CosmicMine.cs index 7a5e64484a..d4e67c6706 100644 --- a/NPCs/Signus/CosmicMine.cs +++ b/NPCs/Signus/CosmicMine.cs @@ -28,7 +28,7 @@ public override void SetDefaults() NPC.width = 30; NPC.height = 30; NPC.lifeMax = 4800; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -179,7 +179,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2(TextureAssets.Npc[NPC.type].Value.Width / 2, TextureAssets.Npc[NPC.type].Value.Height / 2); int afterimageAmt = 5; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { diff --git a/NPCs/Signus/Signus.cs b/NPCs/Signus/Signus.cs index 997ff5f25a..21b1df60af 100644 --- a/NPCs/Signus/Signus.cs +++ b/NPCs/Signus/Signus.cs @@ -79,7 +79,7 @@ public override void SetDefaults() NPC.defense = 60; NPC.LifeMaxNERB(300000, 360000, 320000); NPC.value = Item.buyPrice(2, 0, 0, 0); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.aiStyle = -1; @@ -851,7 +851,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d transparency = (100 - (stealthTimer - 300)) * 0.01f; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -877,7 +877,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d eyeGlowColor = Color.MediumBlue; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/SlimeGod/CorruptSlimeSpawn.cs b/NPCs/SlimeGod/CorruptSlimeSpawn.cs index b3f43e7cbd..8e84e52535 100644 --- a/NPCs/SlimeGod/CorruptSlimeSpawn.cs +++ b/NPCs/SlimeGod/CorruptSlimeSpawn.cs @@ -31,7 +31,7 @@ public override void SetDefaults() NPC.defense = 6; NPC.lifeMax = BossRushEvent.BossRushActive ? 10000 : (CalamityWorld.LegendaryMode && CalamityWorld.revenge) ? 360 : 180; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.7f; AnimationType = 121; diff --git a/NPCs/SlimeGod/CorruptSlimeSpawn2.cs b/NPCs/SlimeGod/CorruptSlimeSpawn2.cs index 9842a5070c..c13229bb4b 100644 --- a/NPCs/SlimeGod/CorruptSlimeSpawn2.cs +++ b/NPCs/SlimeGod/CorruptSlimeSpawn2.cs @@ -30,7 +30,7 @@ public override void SetDefaults() NPC.defense = 4; NPC.lifeMax = BossRushEvent.BossRushActive ? 5000 : (CalamityWorld.LegendaryMode && CalamityWorld.revenge) ? 180 : 90; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.9f; AnimationType = NPCID.CorruptSlime; diff --git a/NPCs/SlimeGod/CrimsonSlimeSpawn.cs b/NPCs/SlimeGod/CrimsonSlimeSpawn.cs index 14e3462383..7f2a7b3aa3 100644 --- a/NPCs/SlimeGod/CrimsonSlimeSpawn.cs +++ b/NPCs/SlimeGod/CrimsonSlimeSpawn.cs @@ -29,7 +29,7 @@ public override void SetDefaults() NPC.defense = 4; NPC.lifeMax = BossRushEvent.BossRushActive ? 10000 : (CalamityWorld.LegendaryMode && CalamityWorld.revenge) ? 220 : 110; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.8f; AnimationType = NPCID.CorruptSlime; diff --git a/NPCs/SlimeGod/CrimsonSlimeSpawn2.cs b/NPCs/SlimeGod/CrimsonSlimeSpawn2.cs index cec25e0cb4..de73692425 100644 --- a/NPCs/SlimeGod/CrimsonSlimeSpawn2.cs +++ b/NPCs/SlimeGod/CrimsonSlimeSpawn2.cs @@ -34,7 +34,7 @@ public override void SetDefaults() NPC.defense = 6; NPC.lifeMax = BossRushEvent.BossRushActive ? 12000 : (CalamityWorld.LegendaryMode && CalamityWorld.revenge) ? 260 : 130; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0.7f; NPC.Opacity = 0.8f; diff --git a/NPCs/SlimeGod/CrimulanPaladin.cs b/NPCs/SlimeGod/CrimulanPaladin.cs index 8d7147dc4d..52c313c6fb 100644 --- a/NPCs/SlimeGod/CrimulanPaladin.cs +++ b/NPCs/SlimeGod/CrimulanPaladin.cs @@ -32,7 +32,7 @@ public override void SetDefaults() NPC.scale = 1.1f; NPC.defense = 12; NPC.LifeMaxNERB(7500, 9000, 160000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.BossBar = Main.BigBossProgressBar.NeverValid; NPC.knockBackResist = 0f; diff --git a/NPCs/SlimeGod/EbonianPaladin.cs b/NPCs/SlimeGod/EbonianPaladin.cs index fe2ae3f8a7..a3558eacc3 100644 --- a/NPCs/SlimeGod/EbonianPaladin.cs +++ b/NPCs/SlimeGod/EbonianPaladin.cs @@ -32,7 +32,7 @@ public override void SetDefaults() NPC.scale = 1.1f; NPC.defense = 10; NPC.LifeMaxNERB(8000, 9600, 220000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.BossBar = Main.BigBossProgressBar.NeverValid; NPC.aiStyle = -1; diff --git a/NPCs/SlimeGod/SlimeGodCore.cs b/NPCs/SlimeGod/SlimeGodCore.cs index d2f4e0bb7c..69d1294010 100644 --- a/NPCs/SlimeGod/SlimeGodCore.cs +++ b/NPCs/SlimeGod/SlimeGodCore.cs @@ -68,7 +68,7 @@ public override void SetDefaults() NPC.defense = 6; NPC.LifeMaxNERB(420); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPCID.Sets.TrailCacheLength[NPC.type] = 8; NPCID.Sets.TrailingMode[NPC.type] = 1; @@ -595,7 +595,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d spriteBatch.Draw(pog, NPC.Center - screenPos + new Vector2(0, NPC.gfxOffY), NPC.frame, drawColorAlpha, NPC.rotation, NPC.frame.Size() / 2, NPC.scale, spriteEffects, 0); } if (!Main.zenithWorld) - while (((twoConst > 0 && coreID < 8) || (twoConst < 0 && coreID > 8)) && CalamityConfig.Instance.Afterimages) + while (((twoConst > 0 && coreID < 8) || (twoConst < 0 && coreID > 8)) && CalamityClientConfig.Instance.Afterimages) { Color colorLightingAlpha = NPC.GetAlpha(colorLightingArea); { diff --git a/NPCs/SlimeGod/SplitCrimulanPaladin.cs b/NPCs/SlimeGod/SplitCrimulanPaladin.cs index a51706798a..360ed7d596 100644 --- a/NPCs/SlimeGod/SplitCrimulanPaladin.cs +++ b/NPCs/SlimeGod/SplitCrimulanPaladin.cs @@ -36,7 +36,7 @@ public override void SetDefaults() { NPC.Calamity().canBreakPlayerDefense = true; NPC.LifeMaxNERB(1875, 2250, 80000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.BossBar = Main.BigBossProgressBar.NeverValid; NPC.GetNPCDamage(); diff --git a/NPCs/SlimeGod/SplitEbonianPaladin.cs b/NPCs/SlimeGod/SplitEbonianPaladin.cs index fad784a39e..7544e34894 100644 --- a/NPCs/SlimeGod/SplitEbonianPaladin.cs +++ b/NPCs/SlimeGod/SplitEbonianPaladin.cs @@ -36,7 +36,7 @@ public override void SetDefaults() { NPC.Calamity().canBreakPlayerDefense = true; NPC.LifeMaxNERB(2000, 2400, 110000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.BossBar = Main.BigBossProgressBar.NeverValid; NPC.GetNPCDamage(); diff --git a/NPCs/StormWeaver/StormWeaverBody.cs b/NPCs/StormWeaver/StormWeaverBody.cs index d921c85011..eec7a71b80 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; @@ -48,7 +49,7 @@ public override void SetDefaults() NPC.HitSound = SoundID.NPCHit4; NPC.DeathSound = StormWeaverHead.DeathSound; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/StormWeaver/StormWeaverHead.cs b/NPCs/StormWeaver/StormWeaverHead.cs index 75e8814fe4..793fe208c8 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; @@ -103,7 +104,7 @@ public override void SetDefaults() NPC.HitSound = SoundID.NPCHit4; NPC.DeathSound = DeathSound; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -176,7 +177,7 @@ public override void AI() bool revenge = CalamityWorld.revenge || bossRush; bool expertMode = Main.expertMode || bossRush; - if (CalamityConfig.Instance.BossesStopWeather) + if (CalamityServerConfig.Instance.BossesStopWeather) CalamityMod.StopRain(); else if (!Main.raining && !bossRush) CalamityUtils.StartRain(); diff --git a/NPCs/StormWeaver/StormWeaverTail.cs b/NPCs/StormWeaver/StormWeaverTail.cs index 62afff7228..2dc41d2b10 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; @@ -47,7 +48,7 @@ public override void SetDefaults() NPC.HitSound = SoundID.NPCHit53; NPC.DeathSound = StormWeaverHead.DeathSound; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/SupremeCalamitas/BrimstoneHeart.cs b/NPCs/SupremeCalamitas/BrimstoneHeart.cs index fd529f0e33..d006590936 100644 --- a/NPCs/SupremeCalamitas/BrimstoneHeart.cs +++ b/NPCs/SupremeCalamitas/BrimstoneHeart.cs @@ -29,7 +29,7 @@ public override void SetDefaults() NPC.height = 24; NPC.defense = 0; NPC.lifeMax = 15000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -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/SepulcherArm.cs b/NPCs/SupremeCalamitas/SepulcherArm.cs index 0897d65b50..985779582c 100644 --- a/NPCs/SupremeCalamitas/SepulcherArm.cs +++ b/NPCs/SupremeCalamitas/SepulcherArm.cs @@ -86,7 +86,7 @@ public override void SetDefaults() global.DR = 0.999999f; global.unbreakableDR = true; NPC.lifeMax = CalamityWorld.revenge ? 345000 : 300000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = AIType = -1; NPC.knockBackResist = 0f; diff --git a/NPCs/SupremeCalamitas/SepulcherBody.cs b/NPCs/SupremeCalamitas/SepulcherBody.cs index a5be1ff57c..1eed1f576a 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; @@ -39,7 +40,7 @@ public override void SetDefaults() global.DR = 0.999999f; global.unbreakableDR = true; NPC.lifeMax = CalamityWorld.revenge ? 345000 : 300000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/SupremeCalamitas/SepulcherBodyEnergyBall.cs b/NPCs/SupremeCalamitas/SepulcherBodyEnergyBall.cs index be44276128..45b35fad54 100644 --- a/NPCs/SupremeCalamitas/SepulcherBodyEnergyBall.cs +++ b/NPCs/SupremeCalamitas/SepulcherBodyEnergyBall.cs @@ -33,7 +33,7 @@ public override void SetDefaults() NPC.width = 20; NPC.height = 20; NPC.lifeMax = CalamityWorld.revenge ? 345000 : 300000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/SupremeCalamitas/SepulcherHead.cs b/NPCs/SupremeCalamitas/SepulcherHead.cs index 67df4e9c2f..c625e361b4 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"); @@ -52,7 +53,7 @@ public override void SetDefaults() global.DR = 0.999999f; global.unbreakableDR = true; NPC.lifeMax = CalamityWorld.revenge ? 345000 : 300000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/SupremeCalamitas/SepulcherTail.cs b/NPCs/SupremeCalamitas/SepulcherTail.cs index ba744ca331..b5eb8a7c5b 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; @@ -31,7 +32,7 @@ public override void SetDefaults() global.DR = 0.999999f; global.unbreakableDR = true; NPC.lifeMax = CalamityWorld.revenge ? 345000 : 300000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; diff --git a/NPCs/SupremeCalamitas/SoulSeekerSupreme.cs b/NPCs/SupremeCalamitas/SoulSeekerSupreme.cs index 299f2d5144..ed7d0b4a51 100644 --- a/NPCs/SupremeCalamitas/SoulSeekerSupreme.cs +++ b/NPCs/SupremeCalamitas/SoulSeekerSupreme.cs @@ -66,7 +66,7 @@ public override void SetDefaults() NPC.defense = 60; NPC.DR_NERD(NormalDR); NPC.lifeMax = 28000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.DeathSound = SoundID.DD2_SkeletonDeath; NPC.Calamity().VulnerableToHeat = false; @@ -269,7 +269,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 halfSizeTexture = new Vector2((float)(TextureAssets.Npc[NPC.type].Value.Width / 2), (float)(TextureAssets.Npc[NPC.type].Value.Height / Main.npcFrameCount[NPC.type] / 2)); int afterimageAmt = 2; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -292,7 +292,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture2D15 = GlowTexture.Value; Color redLerp = Color.Lerp(Color.White, Color.Red, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int j = 1; j < afterimageAmt; j++) { diff --git a/NPCs/SupremeCalamitas/SupremeCalamitas.cs b/NPCs/SupremeCalamitas/SupremeCalamitas.cs index 42f996b630..e43a79e26b 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); @@ -278,7 +264,7 @@ public override void SetDefaults() NPC.DR_NERD(normalDR); NPC.value = Item.buyPrice(30, 0, 0, 0); NPC.LifeMaxNERB(960000, 1150000, 900000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -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(); @@ -455,7 +441,7 @@ public override void AI() CalamityNetcode.SyncWorld(); } - if (CalamityConfig.Instance.BossesStopWeather) + if (CalamityServerConfig.Instance.BossesStopWeather) CalamityMod.StopRain(); bool bossRush = BossRushEvent.BossRushActive; @@ -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); @@ -2100,6 +2063,7 @@ public override void AI() NPC.dontTakeDamage = true; NPC.chaseable = false; NPC.damage = 0; + attackPause = 5; if (!canDespawn) NPC.velocity *= 0.95f; @@ -2267,11 +2231,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 +2250,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 +2272,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 +2309,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 +2329,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 +2445,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 +2463,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 +2514,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; @@ -2561,7 +2526,8 @@ public override void AI() Vector2 projectileSpawn = NPC.Center + projectileVelocity * 8f; projectileVelocity *= 5f * uDieLul; int projectileType = gigablast; - Projectile.NewProjectile(NPC.GetSource_FromAI(), projectileSpawn, projectileVelocity, projectileType, gigablastDamage, 0f, Main.myPlayer, 0f, 2f); + if (attackPause == 0) + Projectile.NewProjectile(NPC.GetSource_FromAI(), projectileSpawn, projectileVelocity, projectileType, gigablastDamage, 0f, Main.myPlayer, 0f, 2f); } } @@ -2575,8 +2541,8 @@ 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) + // Previously the 40% health threshold transition + if (lifeRatio <= 0.45f && hasSummonedBrothers && (permafrost ? NPC.AnyNPCs(ModContent.NPCType()) : (NPC.AnyNPCs(ModContent.NPCType()) || NPC.AnyNPCs(ModContent.NPCType()))) == false) { NPC.ai[0] = 1f; NPC.ai[1] = 0f; @@ -2621,17 +2587,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 +2606,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 +2632,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 +2795,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 +2813,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 +2836,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 +2979,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 +2997,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 +3055,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 +3140,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 +3178,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 +3246,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 +3308,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 +3414,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 +3474,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 +3523,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 +3556,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 +3580,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 (CalamityClientConfig.Instance.Afterimages && !(permafrost && NPC.ai[1] == 2f)) { for (int i = 1; i < afterimageAmt; i += 2) { @@ -3646,7 +3609,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 +3618,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 +3632,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 +3686,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 +3765,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 +3775,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 +3785,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 +3805,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/SupremeCataclysm.cs b/NPCs/SupremeCalamitas/SupremeCataclysm.cs index 005abccc7d..9fc1836e0d 100644 --- a/NPCs/SupremeCalamitas/SupremeCataclysm.cs +++ b/NPCs/SupremeCalamitas/SupremeCataclysm.cs @@ -84,7 +84,7 @@ public override void SetDefaults() NPC.defense = 80; NPC.DR_NERD(NormalBrothersDR); NPC.lifeMax = 138000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -476,7 +476,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 origin = NPC.frame.Size() * 0.5f; int afterimageCount = 4; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageCount; i += 2) { @@ -493,7 +493,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Color primarycolor = Main.zenithWorld ? Color.Blue : Color.Red; // why? because blue fire is awesome!! Color baseGlowmaskColor = NPC.IsABestiaryIconDummy ? Color.White : Color.Lerp(Color.White, primarycolor, 0.5f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageCount; i++) { diff --git a/NPCs/SupremeCalamitas/SupremeCatastrophe.cs b/NPCs/SupremeCalamitas/SupremeCatastrophe.cs index c8b5db4dd0..c19560cdd2 100644 --- a/NPCs/SupremeCalamitas/SupremeCatastrophe.cs +++ b/NPCs/SupremeCalamitas/SupremeCatastrophe.cs @@ -76,7 +76,7 @@ public override void SetDefaults() NPC.defense = 80; NPC.DR_NERD(SupremeCataclysm.NormalBrothersDR); NPC.lifeMax = 138000; - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.aiStyle = -1; AIType = -1; @@ -512,7 +512,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d Vector2 origin = NPC.frame.Size() * 0.5f; int afterimageCount = 4; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageCount; i += 2) { @@ -528,7 +528,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d texture = GlowTexture.Value; Color baseGlowmaskColor = Color.Lerp(Color.White, Color.Cyan, 0.35f); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageCount; i++) { diff --git a/NPCs/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..7d932e7dfd 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,9 @@ public override bool CanTownNPCSpawn(int numTownNPCs) "Jackson", // <@!525827730646892549> (chowchow360) "Altarca", // <@!1140673052108128337> (altarca_27226_49175) "Jackie", // <@!353241811717718016> (jackalchan) + "Ishmael", // <@!840416568000381046> (vanillaoyster) + "Ariallis", // <@!518231218806980609> (ariallis) + "Shade", // <@!613133259563466755> (shade__storm) // Original names this.GetLocalizedValue("Name.Laura"), @@ -158,11 +162,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 +216,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 +246,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 +306,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/TownNPCs/WITCH.png b/NPCs/TownNPCs/WITCH.png index 7b9a6af20e..9c0c8c8b18 100644 Binary files a/NPCs/TownNPCs/WITCH.png and b/NPCs/TownNPCs/WITCH.png differ diff --git a/NPCs/TownNPCs/WITCH_Head.png b/NPCs/TownNPCs/WITCH_Head.png index 686a9f7aa6..031bd7ac2f 100644 Binary files a/NPCs/TownNPCs/WITCH_Head.png and b/NPCs/TownNPCs/WITCH_Head.png differ diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/DestroyerAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/DestroyerAI.cs index 1308fee41f..c42cb72a79 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/DestroyerAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/DestroyerAI.cs @@ -150,8 +150,6 @@ public static bool BuffedDestroyerAI(NPC npc, Mod mod) } // Check if other segments are still alive, if not, die - // Check for Oblivion too, since having a max power Destroyer during that fight would be turbo cancer - bool oblivionAlive = false; if (npc.type > NPCID.TheDestroyer) { bool shouldDespawn = true; @@ -178,39 +176,13 @@ public static bool BuffedDestroyerAI(NPC npc, Mod mod) npc.active = false; } } - else - { - if (masterMode && !bossRush && npc.localAI[3] != -1f) - { - for (int i = 0; i < Main.maxNPCs; i++) - { - if (Main.npc[i].active && (Main.npc[i].type == ModContent.NPCType() || Main.npc[i].type == NPCID.SkeletronPrime)) - { - oblivionAlive = true; - break; - } - } - } - - // Set variable to force despawn when Prime dies in Master Rev+ - // Set to -1f if Prime isn't alive when summoned - if (npc.localAI[3] == 0f) - { - if (oblivionAlive) - npc.localAI[3] = 1f; - else - npc.localAI[3] = -1f; - - npc.SyncExtraAI(); - } - } // Total segment variable int totalSegments = Main.getGoodWorld ? 100 : 80; // Calculate aggression based on how many broken segments there are float brokenSegmentAggressionMultiplier = 1f; - if (npc.type == NPCID.TheDestroyer && !oblivionAlive) + if (npc.type == NPCID.TheDestroyer) { int numProbeSegments = 0; for (int i = 0; i < Main.maxNPCs; i++) @@ -236,51 +208,39 @@ public static bool BuffedDestroyerAI(NPC npc, Mod mod) // Increase velocity based on distance float velocityMultiplier = increaseSpeedMore ? 2f : increaseSpeed ? 1.5f : 1f; + noFlyZoneBoxHeight -= death ? 400 : (int)(400f * (1f - lifeRatio)); - // If Oblivion is alive, don't fly, don't spit laser spreads, use the default vanilla no fly zone, reduce segment count to 60, use base speed and use base turn speed - if (oblivionAlive) - { - calamityGlobalNPC.newAI[3] = 0f; - totalSegments = Main.getGoodWorld ? 75 : 60; - spitLaserSpreads = false; - noFlyZoneBoxHeight = 2000; - } - else - { - noFlyZoneBoxHeight -= death ? 400 : (int)(400f * (1f - lifeRatio)); + float segmentVelocityBoost = death ? (flyAtTarget ? 4.5f : 6f) * (1f - lifeRatio) : (flyAtTarget ? 3f : 4f) * (1f - lifeRatio); + float speedBoost = death ? (flyAtTarget ? 0.1125f : 0.15f) * (1f - lifeRatio) : (flyAtTarget ? 0.075f : 0.1f) * (1f - lifeRatio); + float turnSpeedBoost = death ? 0.18f * (1f - lifeRatio) : 0.12f * (1f - lifeRatio); - float segmentVelocityBoost = death ? (flyAtTarget ? 4.5f : 6f) * (1f - lifeRatio) : (flyAtTarget ? 3f : 4f) * (1f - lifeRatio); - float speedBoost = death ? (flyAtTarget ? 0.1125f : 0.15f) * (1f - lifeRatio) : (flyAtTarget ? 0.075f : 0.1f) * (1f - lifeRatio); - float turnSpeedBoost = death ? 0.18f * (1f - lifeRatio) : 0.12f * (1f - lifeRatio); + segmentVelocity += segmentVelocityBoost; + speed += speedBoost; + turnSpeed += turnSpeedBoost; - segmentVelocity += segmentVelocityBoost; - speed += speedBoost; - turnSpeed += turnSpeedBoost; + segmentVelocity += 5f * enrageScale; + speed += 0.05f * enrageScale; + turnSpeed += 0.075f * enrageScale; - segmentVelocity += 5f * enrageScale; - speed += 0.05f * enrageScale; - turnSpeed += 0.075f * enrageScale; - - if (flyAtTarget) - { - float speedMultiplier = phase5 ? 1.8f : phase4 ? 1.65f : 1.5f; - speed *= speedMultiplier; - } + if (flyAtTarget) + { + float speedMultiplier = phase5 ? 1.8f : phase4 ? 1.65f : 1.5f; + speed *= speedMultiplier; + } - segmentVelocity *= velocityMultiplier; - speed *= velocityMultiplier; - turnSpeed *= velocityMultiplier; + segmentVelocity *= velocityMultiplier; + speed *= velocityMultiplier; + turnSpeed *= velocityMultiplier; - segmentVelocity *= brokenSegmentAggressionMultiplier; - speed *= brokenSegmentAggressionMultiplier; - turnSpeed *= brokenSegmentAggressionMultiplier; + segmentVelocity *= brokenSegmentAggressionMultiplier; + speed *= brokenSegmentAggressionMultiplier; + turnSpeed *= brokenSegmentAggressionMultiplier; - if (Main.getGoodWorld) - { - segmentVelocity *= 1.2f; - speed *= 1.2f; - turnSpeed *= 1.2f; - } + if (Main.getGoodWorld) + { + segmentVelocity *= 1.2f; + speed *= 1.2f; + turnSpeed *= 1.2f; } bool probeLaunched = npc.ai[2] == 1f; @@ -406,7 +366,7 @@ public static bool BuffedDestroyerAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -598,7 +558,7 @@ public static bool BuffedDestroyerAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(projectileType); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -780,9 +740,7 @@ public static bool BuffedDestroyerAI(NPC npc, Mod mod) } // Despawn - bool oblivionWasAlive = npc.localAI[3] == 1f && !oblivionAlive; - bool oblivionFightDespawn = (oblivionAlive && lifeRatio < 0.75f) || oblivionWasAlive; - if (player.dead || oblivionFightDespawn) + if (player.dead) { shouldFly = false; npc.velocity.Y += 2f; @@ -1045,11 +1003,10 @@ public static bool BuffedDestroyerAI(NPC npc, Mod mod) } // Force the fucker to turn around in ground phase in Master - // Turns slower if Oblivion is alive, for fairness if (npc.type == NPCID.TheDestroyer && masterMode && !flyAtTarget) { if (npc.Distance(player.Center) > 2000f) - npc.velocity += (player.Center - npc.Center).SafeNormalize(Vector2.UnitY) * (oblivionAlive ? speed : turnSpeed); + npc.velocity += (player.Center - npc.Center).SafeNormalize(Vector2.UnitY) * turnSpeed; } if (NPC.IsMechQueenUp && npc.type == NPCID.TheDestroyer) @@ -1301,7 +1258,7 @@ public static bool VanillaDestroyerAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Classic; double secondMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Classic; @@ -1747,7 +1704,6 @@ public static bool BuffedProbeAI(NPC npc, Mod mod) { bool bossRush = BossRushEvent.BossRushActive; bool masterMode = Main.masterMode || bossRush; - bool oblivionAlive = npc.ai[1] == 1f; // Get a target if (npc.target < 0 || npc.target == Main.maxPlayers || Main.player[npc.target].dead || !Main.player[npc.target].active) @@ -1791,12 +1747,6 @@ public static bool BuffedProbeAI(NPC npc, Mod mod) for (int i = 0; i < Main.maxNPCs; i++) { - if (masterMode && !bossRush && npc.ai[1] == 0f) - { - if (Main.npc[i].active && (Main.npc[i].type == ModContent.NPCType() || Main.npc[i].type == NPCID.SkeletronPrime)) - npc.ai[1] = 1f; - } - if (i != npc.whoAmI && Main.npc[i].active && Main.npc[i].type == npc.type) { Vector2 otherProbeDist = Main.npc[i].Center - npc.Center; @@ -1914,7 +1864,7 @@ public static bool BuffedProbeAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -1924,7 +1874,7 @@ public static bool BuffedProbeAI(NPC npc, Mod mod) damage = (int)(damage * secondMechMultiplier); } - int totalProjectiles = oblivionAlive ? 2 : (CalamityWorld.death || bossRush) ? 3 : 1; + int totalProjectiles = (CalamityWorld.death || bossRush) ? 3 : 1; Vector2 npcCenter = new Vector2(probeTargetX, probeTargetY); if (NPC.IsMechQueenUp) { @@ -2173,7 +2123,7 @@ public static bool VanillaProbeAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Classic; double secondMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Classic; diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/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..020264f3cc 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronPrimeAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/SkeletronPrimeAI.cs @@ -35,114 +35,42 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) // Spawn arms if (calamityGlobalNPC.newAI[1] == 0f) { + CalamityUtils.CalamityTargeting(npc, CalamityTargetingParameters.BossDefaults); calamityGlobalNPC.newAI[1] = 1f; if (Main.netMode != NetmodeID.MultiplayerClient) { - // Spawn second head in Master Mode - // The main head owns the Saw and the Laser in Master Mode - if (masterMode) - { - int head = NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType(), npc.whoAmI); - Main.npc[head].ai[0] = npc.whoAmI; - Main.npc[head].target = npc.target; - Main.npc[head].netUpdate = true; - npc.ai[0] = head; - - int arm = NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X, (int)npc.Center.Y, NPCID.PrimeSaw, npc.whoAmI); - Main.npc[arm].ai[0] = 1f; - Main.npc[arm].ai[1] = npc.whoAmI; - Main.npc[arm].target = npc.target; - Main.npc[arm].netUpdate = true; - - arm = NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X, (int)npc.Center.Y, NPCID.PrimeLaser, npc.whoAmI); - Main.npc[arm].ai[0] = 1f; - Main.npc[arm].ai[1] = npc.whoAmI; - Main.npc[arm].target = npc.target; - Main.npc[arm].netUpdate = true; - Main.npc[arm].ai[3] = 150f; - } - else - { - int arm = NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X, (int)npc.Center.Y, NPCID.PrimeCannon, npc.whoAmI); - Main.npc[arm].ai[0] = -1f; - Main.npc[arm].ai[1] = npc.whoAmI; - Main.npc[arm].target = npc.target; - Main.npc[arm].netUpdate = true; - - arm = NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X, (int)npc.Center.Y, NPCID.PrimeSaw, npc.whoAmI); - Main.npc[arm].ai[0] = 1f; - Main.npc[arm].ai[1] = npc.whoAmI; - Main.npc[arm].target = npc.target; - Main.npc[arm].netUpdate = true; - - arm = NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X, (int)npc.Center.Y, NPCID.PrimeVice, npc.whoAmI); - Main.npc[arm].ai[0] = -1f; - Main.npc[arm].ai[1] = npc.whoAmI; - Main.npc[arm].target = npc.target; - Main.npc[arm].ai[3] = 150f; - Main.npc[arm].netUpdate = true; - - arm = NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X, (int)npc.Center.Y, NPCID.PrimeLaser, npc.whoAmI); - Main.npc[arm].ai[0] = 1f; - Main.npc[arm].ai[1] = npc.whoAmI; - Main.npc[arm].target = npc.target; - Main.npc[arm].netUpdate = true; - Main.npc[arm].ai[3] = 150f; - } + int arm = NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X, (int)npc.Center.Y, NPCID.PrimeCannon, npc.whoAmI); + Main.npc[arm].ai[0] = -1f; + Main.npc[arm].ai[1] = npc.whoAmI; + Main.npc[arm].target = npc.target; + Main.npc[arm].netUpdate = true; + + arm = NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X, (int)npc.Center.Y, NPCID.PrimeSaw, npc.whoAmI); + Main.npc[arm].ai[0] = 1f; + Main.npc[arm].ai[1] = npc.whoAmI; + Main.npc[arm].target = npc.target; + Main.npc[arm].netUpdate = true; + + arm = NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X, (int)npc.Center.Y, NPCID.PrimeVice, npc.whoAmI); + Main.npc[arm].ai[0] = -1f; + Main.npc[arm].ai[1] = npc.whoAmI; + Main.npc[arm].target = npc.target; + Main.npc[arm].ai[3] = 150f; + Main.npc[arm].netUpdate = true; + + arm = NPC.NewNPC(npc.GetSource_FromAI(), (int)npc.Center.X, (int)npc.Center.Y, NPCID.PrimeLaser, npc.whoAmI); + Main.npc[arm].ai[0] = 1f; + Main.npc[arm].ai[1] = npc.whoAmI; + Main.npc[arm].target = npc.target; + Main.npc[arm].netUpdate = true; + Main.npc[arm].ai[3] = 150f; } npc.netUpdate = true; npc.SyncExtraAI(); } - if (masterMode) - { - if (!Main.npc[(int)npc.ai[0]].active || Main.npc[(int)npc.ai[0]].aiStyle != NPCAIStyleID.SkeletronPrimeHead) - { - npc.life = 0; - npc.HitEffect(); - npc.active = false; - npc.netUpdate = true; - } - else - { - // Link the HP of both heads - if (npc.life > Main.npc[(int)npc.ai[0]].life) - npc.life = Main.npc[(int)npc.ai[0]].life; - - // Push away from the lead head if too close, pull closer if too far, if Mechdusa isn't real - if (!NPC.IsMechQueenUp) - { - float pushVelocity = 0.25f; - if (Vector2.Distance(npc.Center, Main.npc[(int)npc.ai[0]].Center) < 80f * npc.scale) - { - if (npc.position.X < Main.npc[(int)npc.ai[0]].position.X) - npc.velocity.X -= pushVelocity; - else - npc.velocity.X += pushVelocity; - - if (npc.position.Y < Main.npc[(int)npc.ai[0]].position.Y) - npc.velocity.Y -= pushVelocity; - else - npc.velocity.Y += pushVelocity; - } - else if (Vector2.Distance(npc.Center, Main.npc[(int)npc.ai[0]].Center) > 240f * npc.scale) - { - if (npc.position.X < Main.npc[(int)npc.ai[0]].position.X) - npc.velocity.X += pushVelocity; - else - npc.velocity.X -= pushVelocity; - - if (npc.position.Y < Main.npc[(int)npc.ai[0]].position.Y) - npc.velocity.Y += pushVelocity; - else - npc.velocity.Y -= pushVelocity; - } - } - } - } - // Check if arms are alive bool cannonAlive = false; bool laserAlive = false; @@ -175,33 +103,7 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) // Phases bool phase2 = lifeRatio < 0.66f; - bool spawnDestroyer = lifeRatio < 0.75f && masterMode && !bossRush && npc.localAI[2] == 0f; bool phase3 = lifeRatio < 0.33f; - bool spawnRetinazer = lifeRatio < 0.5f && masterMode && !bossRush && npc.localAI[2] == 1f; - - // Spawn The Destroyer in Master Mode (just like Oblivion from Avalon) - if (spawnDestroyer) - { - Player destroyerSpawnPlayer = Main.player[Player.FindClosest(npc.position, npc.width, npc.height)]; - SoundEngine.PlaySound(SoundID.Roar, destroyerSpawnPlayer.Center); - if (Main.netMode != NetmodeID.MultiplayerClient) - NPC.SpawnOnPlayer(destroyerSpawnPlayer.whoAmI, NPCID.TheDestroyer); - - npc.localAI[2] = 1f; - npc.SyncVanillaLocalAI(); - } - - // Spawn Retinazer in Master Mode (just like Oblivion from Avalon) - if (spawnRetinazer) - { - Player retinazerSpawnPlayer = Main.player[Player.FindClosest(npc.position, npc.width, npc.height)]; - SoundEngine.PlaySound(SoundID.Roar, retinazerSpawnPlayer.Center); - if (Main.netMode != NetmodeID.MultiplayerClient) - NPC.SpawnOnPlayer(retinazerSpawnPlayer.whoAmI, NPCID.Retinazer); - - npc.localAI[2] = 2f; - npc.SyncVanillaLocalAI(); - } // Despawn if (npc.ai[1] != 3f) @@ -241,7 +143,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; @@ -251,9 +152,6 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) bool normalLaserRotation = npc.localAI[1] % 2f == 0f; - // Prevents cheap hits - bool canUseAttackInMaster = npc.position.Y < Main.player[npc.target].position.Y - 350f; - // Float near player if (npc.ai[1] == 0f || npc.ai[1] == 4f) { @@ -261,24 +159,16 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) npc.damage = 0; // Start other phases; if arms are dead, start with spin phase - bool otherHeadChargingOrSpinning = Main.npc[(int)npc.ai[0]].ai[1] == 5f || Main.npc[(int)npc.ai[0]].ai[1] == 1f; - if (phase2 || CalamityWorld.LegendaryMode || allArmsDead || masterMode) + if (phase2 || CalamityWorld.LegendaryMode || allArmsDead) { // Start spin phase after 1.5 seconds npc.ai[2] += phase3 ? 1.5f : 1f; - if (npc.ai[2] >= (90f - (death ? (masterMode ? 15f : 60f) * (1f - lifeRatio) : 0f)) && (!otherHeadChargingOrSpinning || !masterMode || phase3) && (canUseAttackInMaster || !masterMode)) + if (npc.ai[2] >= (90f - (death ? (masterMode ? 15f : 60f) * (1f - lifeRatio) : 0f))) { bool shouldSpinAround = npc.ai[1] == 4f && npc.position.Y < Main.player[npc.target].position.Y - 400f && Vector2.Distance(Main.player[npc.target].Center, npc.Center) < 600f && Vector2.Distance(Main.player[npc.target].Center, npc.Center) > 400f; - bool shouldCharge = masterMode && !phase2 && !allArmsDead && !CalamityWorld.LegendaryMode; - if (shouldCharge) - { - npc.ai[2] = 0f; - npc.ai[1] = 1f; - npc.netUpdate = true; - } - else if (shouldSpinAround || npc.ai[1] != 4f) + if (shouldSpinAround || npc.ai[1] != 4f) { if (shouldSpinAround) { @@ -288,6 +178,7 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) npc.ai[2] = 0f; npc.ai[1] = shouldSpinAround ? 5f : 1f; + CalamityUtils.CalamityTargeting(npc, CalamityTargetingParameters.BossDefaults); npc.netUpdate = true; } } @@ -397,7 +288,7 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -660,7 +551,7 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -670,13 +561,6 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) damage = (int)(damage * secondMechMultiplier); } - if (npc.localAI[0] % 3f == 0f) - { - int probeLimit = death ? (masterMode ? 3 : 4) : 2; - if (NPC.CountNPCS(NPCID.Probe) < probeLimit) - NPC.NewNPC(npc.GetSource_FromAI(), (int)headCenter.X, (int)headCenter.Y + 30, NPCID.Probe); - } - int enragedSkulls = Projectile.NewProjectile(npc.GetSource_FromAI(), headCenter.X, headCenter.Y + 30f, enragedHeadSkullTargetX, enragedHeadSkullTargetY, type, damage, 0f, Main.myPlayer, -3f, 0f); Main.projectile[enragedSkulls].timeLeft = 480; Main.projectile[enragedSkulls].tileCollide = false; @@ -742,7 +626,7 @@ public static bool BuffedSkeletronPrimeAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -950,7 +834,7 @@ public static bool BuffedPrimeLaserAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -1018,7 +902,7 @@ public static bool BuffedPrimeLaserAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -1253,7 +1137,7 @@ public static bool BuffedPrimeCannonAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -1300,7 +1184,7 @@ public static bool BuffedPrimeCannonAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -2498,7 +2382,7 @@ public static bool VanillaPrimeLaserAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Classic; double secondMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Classic; @@ -2598,7 +2482,7 @@ public static bool VanillaPrimeLaserAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Classic; double secondMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Classic; diff --git a/NPCs/VanillaNPCAIOverrides/Bosses/TwinsAI.cs b/NPCs/VanillaNPCAIOverrides/Bosses/TwinsAI.cs index 1647c03d42..f27e82ee0b 100644 --- a/NPCs/VanillaNPCAIOverrides/Bosses/TwinsAI.cs +++ b/NPCs/VanillaNPCAIOverrides/Bosses/TwinsAI.cs @@ -98,34 +98,8 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) } } - // Check for Oblivion in Master Mode - bool oblivionAlive = false; - if (masterMode && !bossRush && npc.localAI[3] != -1f) - { - for (int i = 0; i < Main.maxNPCs; i++) - { - if (Main.npc[i].active && (Main.npc[i].type == ModContent.NPCType() || Main.npc[i].type == NPCID.SkeletronPrime)) - { - oblivionAlive = true; - break; - } - } - } - - // Set variable to force despawn when Prime dies in Master Rev+ - // Set to -1f if Prime isn't alive when summoned - if (npc.localAI[3] == 0f) - { - if (oblivionAlive) - npc.localAI[3] = 1f; - else - npc.localAI[3] = -1f; - - npc.SyncExtraAI(); - } - // Phase HP ratios - float phase2LifeRatio = oblivionAlive ? 0.5f : masterMode ? 0.85f : 0.7f; + float phase2LifeRatio = masterMode ? 0.85f : 0.7f; float finalPhaseLifeRatio = masterMode ? 0.4f : 0.25f; // Movement variables @@ -136,16 +110,6 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) // Phase duration variables float phase1MaxLaserPhaseDurationDecrease = masterMode ? 120f : 300f; - // If Oblivion is alive reduce aggression of all attacks - if (oblivionAlive) - { - phase1MaxSpeedIncrease = masterMode ? 1f : 2f; - phase1MaxAccelerationIncrease = masterMode ? 0.0125f : 0.025f; - phase1MaxChargeSpeedIncrease = masterMode ? 1.5f : 3f; - - phase1MaxLaserPhaseDurationDecrease = masterMode ? 60f : 150f; - } - // Phase checks bool phase2 = lifeRatio < phase2LifeRatio; bool finalPhase = lifeRatio < finalPhaseLifeRatio; @@ -165,9 +129,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) npc.reflectsProjectiles = false; // Despawn - bool oblivionWasAlive = npc.localAI[3] == 1f && !oblivionAlive; - bool oblivionFightDespawn = (oblivionAlive && lifeRatio < 0.75f) || oblivionWasAlive || (oblivionAlive && !spazAlive && lifeRatio < 0.95f); - if (Main.player[npc.target].dead || oblivionFightDespawn) + if (Main.player[npc.target].dead) { npc.velocity.Y -= 0.04f; if (npc.timeLeft > 10) @@ -206,7 +168,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) retinazerFaceDirection = -1; Vector2 retinazerPosition = npc.Center; - float distanceFromTarget = oblivionAlive ? 450f : 300f; + float distanceFromTarget = 300f; float retinazerTargetX = Main.player[npc.target].Center.X + (retinazerFaceDirection * distanceFromTarget) - retinazerPosition.X; float retinazerTargetY = Main.player[npc.target].Center.Y - distanceFromTarget - retinazerPosition.Y; @@ -268,7 +230,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) npc.ai[2] += 1f; float phaseGateValue = (masterMode ? 300f : 450f) - (death ? phase1MaxLaserPhaseDurationDecrease * ((1f - lifeRatio) / (1f - phase2LifeRatio)) : 0f); - float laserGateValue = oblivionAlive ? 60f : 30f; + float laserGateValue = 30f; if (NPC.IsMechQueenUp) { phaseGateValue = 900f; @@ -307,7 +269,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -374,7 +336,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) npc.rotation = (float)Math.Atan2(npc.velocity.Y, npc.velocity.X) - MathHelper.PiOver2; float delayBeforeChargingAgain = (masterMode ? 48f : 56f) - (death ? (masterMode ? 3f : 6f) * ((1f - lifeRatio) / (1f - phase2LifeRatio)) : 0f); - if (npc.ai[2] >= delayBeforeChargingAgain + (oblivionAlive ? 15f : 0f)) + if (npc.ai[2] >= delayBeforeChargingAgain) { npc.ai[3] += 1f; npc.ai[2] = 0f; @@ -439,7 +401,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -449,7 +411,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) damage = (int)(damage * secondMechMultiplier); } - Vector2 projectileVelocity = (Main.player[npc.target].Center - npc.Center).SafeNormalize(Vector2.UnitY) * (oblivionAlive ? 6f : 7f); + Vector2 projectileVelocity = (Main.player[npc.target].Center - npc.Center).SafeNormalize(Vector2.UnitY) * 7f; int numProj = shootLaser ? 6 : 2; int spread = shootLaser ? 20 : 80; float rotation = MathHelper.ToRadians(spread); @@ -538,7 +500,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) Vector2 eyePosition = npc.Center; float retinazerPhase2TargetX = Main.player[npc.target].Center.X - eyePosition.X; - float distanceFromTarget = oblivionAlive ? 480f : 420f; + float distanceFromTarget = 420f; float retinazerPhase2TargetY = Main.player[npc.target].Center.Y - 420f - eyePosition.Y; if (NPC.IsMechQueenUp) @@ -615,7 +577,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) if (Main.netMode != NetmodeID.MultiplayerClient) { npc.localAI[1] += 1f + (death ? (phase2LifeRatio - lifeRatio) / phase2LifeRatio : 0f); - if (npc.localAI[1] >= (spazAlive ? (oblivionAlive ? 76f : 52f) : 26f)) + if (npc.localAI[1] >= (spazAlive ? 52f : 26f)) { bool canHit = Collision.CanHit(npc.position, npc.width, npc.height, Main.player[npc.target].position, Main.player[npc.target].width, Main.player[npc.target].height); if (canHit || !spazAlive || finalPhase) @@ -627,7 +589,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -680,7 +642,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) } Vector2 retinazerPhase2RapidFirePos = npc.Center; - float distanceFromTarget = oblivionAlive ? 480f : 420f; + float distanceFromTarget = 420f; float retinazerPhase2RapidFireTargetX = Main.player[npc.target].Center.X + (retinazerPhase2FaceDirection * distanceFromTarget) - retinazerPhase2RapidFirePos.X; float retinazerPhase2RapidFireTargetY = Main.player[npc.target].Center.Y - retinazerPhase2RapidFirePos.Y; float retinazerPhase2RapidFireTargetDist = (float)Math.Sqrt(retinazerPhase2RapidFireTargetX * retinazerPhase2RapidFireTargetX + retinazerPhase2RapidFireTargetY * retinazerPhase2RapidFireTargetY); @@ -721,7 +683,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) if (Main.netMode != NetmodeID.MultiplayerClient) { npc.localAI[1] += 1f + (death ? (phase2LifeRatio - lifeRatio) / phase2LifeRatio : 0f); - if (npc.localAI[1] > (spazAlive ? (oblivionAlive ? 30f : 20f) : 10f)) + if (npc.localAI[1] > (spazAlive ? 20f : 10f)) { bool canHit = Collision.CanHit(npc.position, npc.width, npc.height, Main.player[npc.target].position, Main.player[npc.target].width, Main.player[npc.target].height); if (canHit || !spazAlive || finalPhase) @@ -731,7 +693,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) int damage = (int)Math.Round(npc.GetProjectileDamage(type) * 0.75); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -847,7 +809,7 @@ public static bool BuffedRetinazerAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -1072,34 +1034,8 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) } } - // Check for Oblivion in Master Mode - bool oblivionAlive = false; - if (masterMode && !bossRush && npc.localAI[3] != -1f) - { - for (int i = 0; i < Main.maxNPCs; i++) - { - if (Main.npc[i].active && (Main.npc[i].type == ModContent.NPCType() || Main.npc[i].type == NPCID.SkeletronPrime)) - { - oblivionAlive = true; - break; - } - } - } - - // Set variable to force despawn when Prime dies in Master Rev+ - // Set to -1f if Prime isn't alive when summoned - if (npc.localAI[3] == 0f) - { - if (oblivionAlive) - npc.localAI[3] = 1f; - else - npc.localAI[3] = -1f; - - npc.SyncExtraAI(); - } - // Phase HP ratios - float phase2LifeRatio = oblivionAlive ? 0.5f : masterMode ? 0.85f : 0.7f; + float phase2LifeRatio = masterMode ? 0.85f : 0.7f; float finalPhaseLifeRatio = masterMode ? 0.4f : 0.25f; // Movement variables @@ -1111,17 +1047,6 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) float phase1MaxCursedFlamePhaseDurationDecrease = masterMode ? 80f : 200f; float phase1MaxChargesDecrease = masterMode ? 2f : 4f; - // If Oblivion is alive reduce aggression of all attacks - if (oblivionAlive) - { - phase1MaxSpeedIncrease = masterMode ? 1.125f : 2.25f; - phase1MaxAccelerationIncrease = masterMode ? 0.0375f : 0.075f; - phase1MaxChargeSpeedIncrease = masterMode ? 1.5f : 3f; - - phase1MaxCursedFlamePhaseDurationDecrease = masterMode ? 40f : 100f; - phase1MaxChargesDecrease = masterMode ? 1f : 2f; - } - // Phase checks bool phase2 = lifeRatio < phase2LifeRatio; bool finalPhase = lifeRatio < finalPhaseLifeRatio; @@ -1141,9 +1066,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) npc.reflectsProjectiles = false; // Despawn - bool oblivionWasAlive = npc.localAI[3] == 1f && !oblivionAlive; - bool oblivionFightDespawn = (oblivionAlive && lifeRatio < 0.75f) || oblivionWasAlive || (oblivionAlive && !retAlive && lifeRatio < 0.95f); - if (Main.player[npc.target].dead || oblivionFightDespawn) + if (Main.player[npc.target].dead) { npc.velocity.Y -= 0.04f; if (npc.timeLeft > 10) @@ -1185,7 +1108,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) spazmatismFireballFaceDirection = -1; Vector2 spazmatismFireballPos = npc.Center; - float distanceFromTarget = oblivionAlive ? 480f : 400f; + float distanceFromTarget = 400f; float spazmatismFireballTargetX = Main.player[npc.target].Center.X + (spazmatismFireballFaceDirection * distanceFromTarget) - spazmatismFireballPos.X; float spazmatismFireballTargetY = Main.player[npc.target].Center.Y - spazmatismFireballPos.Y; if (NPC.IsMechQueenUp) @@ -1264,7 +1187,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) npc.ai[3] += 0.4f; } - if (npc.ai[3] >= (oblivionAlive ? 60f : 30f)) + if (npc.ai[3] >= 30f) { npc.ai[3] = 0f; spazmatismFireballPos = npc.Center; @@ -1278,7 +1201,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -1352,7 +1275,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) // Charge 8 times float chargeTime = masterMode ? 45f : 25f; - if (npc.ai[2] >= chargeTime + (oblivionAlive ? 15f : 0f)) + if (npc.ai[2] >= chargeTime) { // Reset AI array and go to cursed fireball phase npc.ai[3] += 1f; @@ -1422,7 +1345,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -1432,7 +1355,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) damage = (int)(damage * secondMechMultiplier); } - Vector2 projectileVelocity = (Main.player[npc.target].Center - npc.Center).SafeNormalize(Vector2.UnitY) * (oblivionAlive ? 12f : 16f) + Main.rand.NextVector2CircularEdge(3f, 3f); + Vector2 projectileVelocity = (Main.player[npc.target].Center - npc.Center).SafeNormalize(Vector2.UnitY) * 16f + Main.rand.NextVector2CircularEdge(3f, 3f); int proj = Projectile.NewProjectile(npc.GetSource_FromAI(), npc.Center + projectileVelocity.SafeNormalize(Vector2.UnitY) * 50f, projectileVelocity, type, damage, 0f, Main.myPlayer, 0f, 1f); Main.projectile[proj].tileCollide = false; } @@ -1527,7 +1450,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) { // Boost speed if too far from target if (spazmatismFlamethrowerTargetDist > flamethrowerDistance) - spazmatismFlamethrowerMaxSpeed += MathHelper.Lerp(0f, oblivionAlive ? 3f : masterMode ? 8f : 6f, MathHelper.Clamp((spazmatismFlamethrowerTargetDist - flamethrowerDistance) / 1000f, 0f, 1f)); + spazmatismFlamethrowerMaxSpeed += MathHelper.Lerp(0f, masterMode ? 8f : 6f, MathHelper.Clamp((spazmatismFlamethrowerTargetDist - flamethrowerDistance) / 1000f, 0f, 1f)); if (Main.getGoodWorld) { @@ -1605,7 +1528,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -1728,7 +1651,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) npc.rotation = (float)Math.Atan2(npc.velocity.Y, npc.velocity.X) - MathHelper.PiOver2; // Charges 5 times - if (npc.ai[2] >= (chargeTime * 1.6f) + (oblivionAlive ? 15f : 0f)) + if (npc.ai[2] >= (chargeTime * 1.6f)) { npc.ai[3] += 1f; npc.ai[2] = 0f; @@ -1813,7 +1736,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -1964,7 +1887,7 @@ public static bool BuffedSpazmatismAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert; double secondMechMultiplier = CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert; @@ -2210,7 +2133,7 @@ public static bool VanillaRetinazerAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Classic; double secondMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Classic; @@ -2344,7 +2267,7 @@ public static bool VanillaRetinazerAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Classic; double secondMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Classic; @@ -2520,7 +2443,7 @@ public static bool VanillaRetinazerAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Classic; double secondMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Classic; @@ -2611,7 +2534,7 @@ public static bool VanillaRetinazerAI(NPC npc, Mod mod) int damage = (int)Math.Round(npc.GetProjectileDamage(type) * 0.75); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Classic; double secondMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Classic; @@ -2851,7 +2774,7 @@ public static bool VanillaSpazmatismAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Classic; double secondMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Classic; @@ -2984,7 +2907,7 @@ public static bool VanillaSpazmatismAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Classic; double secondMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Classic; @@ -3142,7 +3065,7 @@ public static bool VanillaSpazmatismAI(NPC npc, Mod mod) int damage = npc.GetProjectileDamage(type); // Reduce mech boss projectile damage depending on the new ore progression changes - if (CalamityConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) + if (CalamityServerConfig.Instance.EarlyHardmodeProgressionRework && !BossRushEvent.BossRushActive) { double firstMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkFirstMechStatMultiplier_Classic; double secondMechMultiplier = Main.expertMode ? CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Expert : CalamityGlobalNPC.EarlyHardmodeProgressionReworkSecondMechStatMultiplier_Classic; diff --git a/NPCs/Yharon/Yharon.cs b/NPCs/Yharon/Yharon.cs index 400fdceecb..ec76d46cb0 100644 --- a/NPCs/Yharon/Yharon.cs +++ b/NPCs/Yharon/Yharon.cs @@ -108,7 +108,7 @@ public override void SetDefaults() NPC.height = 200; NPC.defense = 90; NPC.LifeMaxNERB(1300000, 1560000, 740000); - double HPBoost = CalamityConfig.Instance.BossHealthBoost * 0.01; + double HPBoost = CalamityServerConfig.Instance.BossHealthBoost * 0.01; NPC.lifeMax += (int)(NPC.lifeMax * HPBoost); NPC.knockBackResist = 0f; NPC.aiStyle = -1; @@ -196,7 +196,7 @@ public override void AI() float lifeRatio = NPC.life / (float)NPC.lifeMax; // Stop rain - if (CalamityConfig.Instance.BossesStopWeather) + if (CalamityServerConfig.Instance.BossesStopWeather) CalamityMod.StopRain(); // Variables @@ -2767,7 +2767,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d else color = drawColor; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 1; i < afterimageAmt; i += afterimageIncrement) { @@ -2816,7 +2816,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d afterimageScale = 20f; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int k = 0; k < additionalAfterimageAmt; k++) { @@ -2893,7 +2893,7 @@ public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color d blueGlowColor *= teleportGlowColorScaler; } - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int l = 1; l < afterimageAmt; l += afterimageIncrement) { @@ -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..a2d1f017e5 100644 --- a/Particles/GeneralParticleHandler.cs +++ b/Particles/GeneralParticleHandler.cs @@ -86,7 +86,7 @@ public static void SpawnParticle(Particle particle) if (Main.gamePaused || Main.dedServ || particles == null) return; - if (particles.Count >= CalamityConfig.Instance.ParticleLimit && !particle.Important) + if (particles.Count >= CalamityClientConfig.Instance.ParticleLimit && !particle.Important) return; particles.Add(particle); @@ -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; @@ -215,13 +224,19 @@ public static int FreeSpacesAvailable() if (Main.dedServ || particles == null) return 0; - return CalamityConfig.Instance.ParticleLimit - particles.Count(); + return CalamityClientConfig.Instance.ParticleLimit - particles.Count(); } /// /// 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/HolySpear.cs b/Projectiles/Boss/HolySpear.cs index 697dfa6c2a..d1b46f0654 100644 --- a/Projectiles/Boss/HolySpear.cs +++ b/Projectiles/Boss/HolySpear.cs @@ -204,7 +204,7 @@ public override bool PreDraw(ref Color lightColor) if (Projectile.spriteDirection == -1) spriteEffects = SpriteEffects.FlipHorizontally; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 0; i < Projectile.oldPos.Length; i++) { diff --git a/Projectiles/Boss/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/Boss/YharonFireball.cs b/Projectiles/Boss/YharonFireball.cs index aa5a68dc69..553a32d527 100644 --- a/Projectiles/Boss/YharonFireball.cs +++ b/Projectiles/Boss/YharonFireball.cs @@ -72,7 +72,7 @@ public override bool PreDraw(ref Color lightColor) int frameHeight = texture.Height / Main.projFrames[Projectile.type]; int frameY = frameHeight * Projectile.frame; Rectangle rectangle = new Rectangle(0, frameY, texture.Width, frameHeight); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 0; i < Projectile.oldPos.Length; i++) { diff --git a/Projectiles/CalamityGlobalProjectile.cs b/Projectiles/CalamityGlobalProjectile.cs index 27d65eacbf..450012b709 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); @@ -2374,138 +2381,6 @@ public override bool PreAI(Projectile projectile) } } - else if (projectile.type == ProjectileID.BombSkeletronPrime && projectile.ai[0] < 0f && masterMode) - { - int num = (int)(projectile.Center.X / 16f); - int num2 = (int)(projectile.Center.Y / 16f); - if (WorldGen.InWorld(num, num2) && projectile.tileCollide) - { - Tile tile = Main.tile[num, num2]; - if (tile != null && tile.HasTile && (TileID.Sets.Platforms[tile.TileType] || tile.TileType == TileID.PlanterBox)) - { - projectile.Kill(); - return false; - } - } - - bool masterModeSkeletronPrimeHomingBomb = projectile.ai[0] == -1f; - bool masterModeSkeletronPrimeFallingBomb = projectile.ai[0] == -2f; - - int target = 0; - target = Player.FindClosest(projectile.Center, 1, 1); - - if (projectile.Hitbox.Intersects(Main.player[target].Hitbox)) - { - projectile.Kill(); - return false; - } - - if (projectile.timeLeft < SkeletronPrime2.BombTimeLeft / 2 && projectile.timeLeft > 3) - projectile.tileCollide = true; - - if (masterModeSkeletronPrimeHomingBomb) - { - projectile.ai[1] += 1f; - float homingStartTime = 20f; - float homingEndTime = death ? 140f : 110f; - - if (Vector2.Distance(projectile.Center, Main.player[target].Center) < 192f && projectile.ai[1] < homingEndTime) - projectile.ai[1] = homingEndTime; - - if (projectile.ai[1] < homingEndTime && projectile.ai[1] > homingStartTime) - { - float num134 = projectile.velocity.Length(); - Vector2 vector24 = Main.player[target].Center - projectile.Center; - vector24.Normalize(); - vector24 *= num134; - float inertia = death ? 25f : 30f; - projectile.velocity = (projectile.velocity * (inertia - 1f) + vector24) / inertia; - projectile.velocity.Normalize(); - projectile.velocity *= num134; - } - - float maxVelocity = death ? 18f : 15f; - float acceleration = 1.02f; - if (projectile.velocity.Length() < maxVelocity) - projectile.velocity *= acceleration; - } - else - { - if (projectile.velocity.Y > 10f) - projectile.velocity.Y = 10f; - } - - if (projectile.localAI[0] == 0f) - { - projectile.localAI[0] = 1f; - SoundEngine.PlaySound(SoundID.Item10, projectile.Center); - } - - projectile.frameCounter++; - if (projectile.frameCounter > 3) - { - projectile.frame++; - projectile.frameCounter = 0; - } - - if (projectile.frame > 1) - projectile.frame = 0; - - if (projectile.owner == Main.myPlayer && projectile.timeLeft <= 3) - { - projectile.tileCollide = false; - projectile.ai[2] = 0f; - projectile.alpha = 255; - } - else if (Main.rand.NextBool()) - { - int num28 = Dust.NewDust(projectile.position, projectile.width, projectile.height, DustID.Smoke, 0f, 0f, 100); - Main.dust[num28].scale = 0.1f + (float)Main.rand.Next(5) * 0.1f; - Main.dust[num28].fadeIn = 1.5f + (float)Main.rand.Next(5) * 0.1f; - Main.dust[num28].noGravity = true; - Main.dust[num28].position = projectile.Center + new Vector2(0f, -projectile.height / 2).RotatedBy(projectile.rotation) * 1.1f; - int num29 = 6; - Dust dust8 = Dust.NewDustDirect(projectile.position, projectile.width, projectile.height, num29, 0f, 0f, 100); - dust8.scale = 1f + (float)Main.rand.Next(5) * 0.1f; - dust8.noGravity = true; - dust8.position = projectile.Center + new Vector2(0f, -projectile.height / 2 - 6).RotatedBy(projectile.rotation) * 1.1f; - } - - if (masterModeSkeletronPrimeFallingBomb) - { - projectile.ai[2] += 1f; - if (projectile.ai[2] > 60f) - projectile.velocity.Y += 0.2f; - } - - projectile.rotation += projectile.velocity.X * 0.1f; - - return false; - } - - else if (projectile.type == ProjectileID.FrostBeam && projectile.ai[0] == 1f) - { - projectile.rotation = (float)Math.Atan2(projectile.velocity.Y, projectile.velocity.X) + MathHelper.PiOver2; - - Lighting.AddLight(projectile.Center, 0f, (255 - projectile.alpha) * 0.15f / 255f, (255 - projectile.alpha) * 0.6f / 255f); - - if (projectile.alpha > 0) - projectile.alpha -= 125; - if (projectile.alpha < 0) - projectile.alpha = 0; - - if (projectile.localAI[1] == 0f) - { - SoundEngine.PlaySound(SoundID.Item33, projectile.Center); - projectile.localAI[1] = 1f; - } - - if (projectile.velocity.Length() < AcceleratingBossLaserVelocityCap) - projectile.velocity *= 1.0025f; - - return false; - } - else if (projectile.type == ProjectileID.RocketSkeleton && projectile.ai[1] == 1f) { bool primeCannonProjectile = projectile.ai[1] == 2f; @@ -2639,8 +2514,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 +3894,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 +4062,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. @@ -4207,14 +4089,14 @@ public override void ModifyHitNPC(Projectile projectile, NPC target, ref NPC.Hit { float proximityDamageInterpolant = Utils.GetLerpValue(250f, 2400f, target.Distance(player.Center), true); float proximityDamageFactor = MathHelper.SmoothStep(0.7f, 1.45f, proximityDamageInterpolant); - modifiers.SourceDamage *= proximityDamageFactor; + modifiers.TargetDamageMultiplier *= proximityDamageFactor; } if (modPlayer.closeProximityRewardEnchant) { float proximityDamageInterpolant = Utils.GetLerpValue(400f, 175f, target.Distance(player.Center), true); float proximityDamageFactor = MathHelper.SmoothStep(0.75f, 1.75f, proximityDamageInterpolant); - modifiers.SourceDamage *= proximityDamageFactor; + modifiers.TargetDamageMultiplier *= proximityDamageFactor; } // Aerial Bane does 50% damage to "airborne" enemies. This is just simple math to revert that as it is a very unbalanced mechanic. @@ -4639,7 +4521,6 @@ public override bool PreDraw(Projectile projectile, ref Color lightColor) #region Pre Kill public override bool PreKill(Projectile projectile, int timeLeft) { - bool masterRevSkeletronPrimeBomb = projectile.type == ProjectileID.BombSkeletronPrime && projectile.ai[0] < 0f && (Main.masterMode || BossRushEvent.BossRushActive); bool revQueenBeeBeeHive = projectile.type == ProjectileID.BeeHive && (CalamityWorld.revenge || BossRushEvent.BossRushActive) && (projectile.ai[2] == 1f || CalamityWorld.death) && projectile.wet; bool revGolemInferno = projectile.type == ProjectileID.InfernoHostileBolt && projectile.ai[2] > 0f; @@ -4661,96 +4542,7 @@ public override bool PreKill(Projectile projectile, int timeLeft) if (projectile.owner == Main.myPlayer) { - if (masterRevSkeletronPrimeBomb) - { - SoundEngine.PlaySound(SoundID.Item14, projectile.Center); - projectile.position.X += projectile.width / 2; - projectile.position.Y += projectile.height / 2; - projectile.width = projectile.height = 22; - projectile.position.X -= projectile.width / 2; - projectile.position.Y -= projectile.height / 2; - - for (int num951 = 0; num951 < 20; num951++) - { - int num952 = Dust.NewDust(projectile.position, projectile.width, projectile.height, DustID.Smoke, 0f, 0f, 100, default(Color), 1.5f); - Dust dust2 = Main.dust[num952]; - dust2.velocity *= 1.4f; - } - - int num950 = 6; - for (int num953 = 0; num953 < 10; num953++) - { - int num954 = Dust.NewDust(projectile.position, projectile.width, projectile.height, num950, 0f, 0f, 100, default(Color), 2.5f); - Main.dust[num954].noGravity = true; - Dust dust2 = Main.dust[num954]; - dust2.velocity *= 5f; - num954 = Dust.NewDust(projectile.position, projectile.width, projectile.height, num950, 0f, 0f, 100, default(Color), 1.5f); - dust2 = Main.dust[num954]; - dust2.velocity *= 3f; - } - - int num955 = Gore.NewGore(projectile.GetSource_FromAI(), projectile.position, default(Vector2), Main.rand.Next(61, 64)); - Gore gore2 = Main.gore[num955]; - gore2.velocity *= 0.4f; - Main.gore[num955].velocity.X += 1f; - Main.gore[num955].velocity.Y += 1f; - num955 = Gore.NewGore(projectile.GetSource_FromAI(), projectile.position, default(Vector2), Main.rand.Next(61, 64)); - gore2 = Main.gore[num955]; - gore2.velocity *= 0.4f; - Main.gore[num955].velocity.X -= 1f; - Main.gore[num955].velocity.Y += 1f; - num955 = Gore.NewGore(projectile.GetSource_FromAI(), projectile.position, default(Vector2), Main.rand.Next(61, 64)); - gore2 = Main.gore[num955]; - gore2.velocity *= 0.4f; - Main.gore[num955].velocity.X += 1f; - Main.gore[num955].velocity.Y -= 1f; - num955 = Gore.NewGore(projectile.GetSource_FromAI(), projectile.position, default(Vector2), Main.rand.Next(61, 64)); - gore2 = Main.gore[num955]; - gore2.velocity *= 0.4f; - Main.gore[num955].velocity.X -= 1f; - Main.gore[num955].velocity.Y -= 1f; - - Vector2 vector76 = projectile.position; - projectile.position.X += projectile.width / 2; - projectile.position.Y += projectile.height / 2; - projectile.width = projectile.height = 128; - projectile.position.X -= projectile.width / 2; - projectile.position.Y -= projectile.height / 2; - projectile.Damage(); - projectile.position = vector76; - projectile.width = projectile.height = 22; - - if (Main.getGoodWorld && !Main.remixWorld) - { - int num1011 = 4; - Vector2 center3 = projectile.position; - int num1012 = num1011; - int num1013 = num1011; - int num1014 = (int)(center3.X / 16f - (float)num1012); - int num1015 = (int)(center3.X / 16f + (float)num1012); - int num1016 = (int)(center3.Y / 16f - (float)num1013); - int num1017 = (int)(center3.Y / 16f + (float)num1013); - if (num1014 < 0) - num1014 = 0; - - if (num1015 > Main.maxTilesX) - num1015 = Main.maxTilesX; - - if (num1016 < 0) - num1016 = 0; - - if (num1017 > Main.maxTilesY) - num1017 = Main.maxTilesY; - - bool wallSplode2 = projectile.ShouldWallExplode(center3, num1011, num1014, num1015, num1016, num1017); - projectile.ExplodeTiles(center3, num1011, num1014, num1015, num1016, num1017, wallSplode2); - } - - if (Main.netMode != NetmodeID.SinglePlayer) - NetMessage.SendData(MessageID.KillProjectile, -1, -1, null, projectile.identity, projectile.owner); - } - - else if (revQueenBeeBeeHive) + if (revQueenBeeBeeHive) { if (Main.netMode != NetmodeID.MultiplayerClient) { @@ -4815,7 +4607,7 @@ public override bool PreKill(Projectile projectile, int timeLeft) } } - if (masterRevSkeletronPrimeBomb || revQueenBeeBeeHive || revGolemInferno) + if (revQueenBeeBeeHive || revGolemInferno) { projectile.active = false; return false; diff --git a/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/Enemy/IceClasperEnemyProjectile.cs b/Projectiles/Enemy/IceClasperEnemyProjectile.cs index f9c5b9df8e..05065edba3 100644 --- a/Projectiles/Enemy/IceClasperEnemyProjectile.cs +++ b/Projectiles/Enemy/IceClasperEnemyProjectile.cs @@ -51,7 +51,7 @@ public override void OnKill(int timeLeft) public override bool PreDraw(ref Color lightColor) { - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], lightColor); return true; diff --git a/Projectiles/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..a13ab3c529 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; @@ -29,6 +30,10 @@ public override void SetDefaults() public override void AI() { + Player player = Main.player[Projectile.owner]; + if (player is null || player.dead) + Projectile.Kill(); + Projectile.ai[1]++; switch (Projectile.ai[0]) { diff --git a/Projectiles/Magic/ChronomancersScytheHoldout.cs b/Projectiles/Magic/ChronomancersScytheHoldout.cs index d5861097b5..81fda0e112 100644 --- a/Projectiles/Magic/ChronomancersScytheHoldout.cs +++ b/Projectiles/Magic/ChronomancersScytheHoldout.cs @@ -44,6 +44,10 @@ public override void AI() { Owner.ChangeDir((int)Projectile.ai[2]); + Player player = Main.player[Projectile.owner]; + if (player is null || player.dead) + Projectile.Kill(); + Projectile.velocity = Vector2.Zero; Projectile.rotation += (2 * MathHelper.Pi / 60) * Projectile.ai[2]; 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/MeteorStar.cs b/Projectiles/Magic/MeteorStar.cs index c2292cb1bb..ac9a45264c 100644 --- a/Projectiles/Magic/MeteorStar.cs +++ b/Projectiles/Magic/MeteorStar.cs @@ -96,7 +96,7 @@ public override void AI() } // Die immediately if the owner of this projectile is clipping into tiles because of its movement. - if (Collision.SolidCollision(Owner.position, Owner.width, Owner.height) && Projectile.velocity != Vector2.Zero) + if (Collision.SolidCollision(Owner.position + Projectile.velocity, Owner.width, Owner.height) && Projectile.velocity != Vector2.Zero) { Owner.velocity.Y = 0f; Explode(); diff --git a/Projectiles/Magic/NanoPurgeHoldout.cs b/Projectiles/Magic/NanoPurgeHoldout.cs index 4127860c0a..764a582d36 100644 --- a/Projectiles/Magic/NanoPurgeHoldout.cs +++ b/Projectiles/Magic/NanoPurgeHoldout.cs @@ -70,20 +70,23 @@ public override void HoldoutAI() { SoundEngine.PlaySound(SoundID.Item91, Projectile.Center); - int projID = ModContent.ProjectileType(); - float shootSpeed = HeldItem.shootSpeed; - float inaccuracyRatio = 0.045f; - Vector2 shootDirection = Projectile.velocity.SafeNormalize(Vector2.UnitY); - Vector2 perp = shootDirection.RotatedBy(MathHelper.PiOver2); - - // Fire a pair of lasers, one with a negative offset, one with a positive offset. - for (int i = -1; i <= 1; i += 2) + if (Main.myPlayer == Projectile.owner) { - Vector2 spread = Main.rand.NextVector2CircularEdge(shootSpeed, shootSpeed); - Vector2 shootVelocity = shootDirection * shootSpeed + inaccuracyRatio * spread; - Vector2 splitBarrelPos = GunTipPosition + i * LaserOffsetByAnimationFrame[Projectile.frame] * perp; - Projectile.NewProjectile(Projectile.GetSource_FromThis(), splitBarrelPos, shootVelocity, projID, Projectile.damage, Projectile.knockBack, Projectile.owner); - SpawnFiringDust(splitBarrelPos, shootVelocity); + int projID = ModContent.ProjectileType(); + float shootSpeed = HeldItem.shootSpeed; + float inaccuracyRatio = 0.045f; + Vector2 shootDirection = Projectile.velocity.SafeNormalize(Vector2.UnitY); + Vector2 perp = shootDirection.RotatedBy(MathHelper.PiOver2); + + // Fire a pair of lasers, one with a negative offset, one with a positive offset. + for (int i = -1; i <= 1; i += 2) + { + Vector2 spread = Main.rand.NextVector2CircularEdge(shootSpeed, shootSpeed); + Vector2 shootVelocity = shootDirection * shootSpeed + inaccuracyRatio * spread; + Vector2 splitBarrelPos = GunTipPosition + i * LaserOffsetByAnimationFrame[Projectile.frame] * perp; + Projectile.NewProjectile(Projectile.GetSource_FromThis(), splitBarrelPos, shootVelocity, projID, Projectile.damage, Projectile.knockBack, Projectile.owner); + SpawnFiringDust(splitBarrelPos, shootVelocity); + } } } } diff --git a/Projectiles/Magic/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/OmicronHoldout.cs b/Projectiles/Magic/OmicronHoldout.cs index 9d3aef3fb7..afbd989b7c 100644 --- a/Projectiles/Magic/OmicronHoldout.cs +++ b/Projectiles/Magic/OmicronHoldout.cs @@ -107,7 +107,8 @@ public void Shoot(bool yBeam) } Owner.Calamity().GeneralScreenShakePower = 6.5f; - Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), GunTipPosition, firingVelocity3, ModContent.ProjectileType(), Projectile.damage * 32, Projectile.knockBack, Projectile.owner, 0, 0); + if (Main.myPlayer == Projectile.owner) + Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), GunTipPosition, firingVelocity3, ModContent.ProjectileType(), Projectile.damage * 32, Projectile.knockBack, Projectile.owner, 0, 0); for (int i = 0; i < 8; i++) { @@ -120,15 +121,18 @@ public void Shoot(bool yBeam) SoundStyle fire = new("CalamityMod/Sounds/Item/ArcNovaDiffuserBigShot"); SoundEngine.PlaySound(fire with { Volume = 0.2f, Pitch = 0.9f }, Projectile.Center); - for (int i = 0; i < 5; i++) + if (Main.myPlayer == Projectile.owner) { - firingVelocity3 = (shootDirection * 10).RotatedBy((0.035f * (i + 1)) * Utils.GetLerpValue(0, 55, Windup, true)); - Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), GunTipPosition, firingVelocity3 * (1 - i * 0.1f), ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner, 0, 2); - } - for (int i = 0; i < 5; i++) - { - firingVelocity3 = (shootDirection * 10).RotatedBy((-0.035f * (i + 1)) * Utils.GetLerpValue(0, 55, Windup, true)); - Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), GunTipPosition, firingVelocity3 * (1 - i * 0.1f), ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner, 0, 2); + for (int i = 0; i < 5; i++) + { + firingVelocity3 = (shootDirection * 10).RotatedBy((0.035f * (i + 1)) * Utils.GetLerpValue(0, 55, Windup, true)); + Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), GunTipPosition, firingVelocity3 * (1 - i * 0.1f), ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner, 0, 2); + } + for (int i = 0; i < 5; i++) + { + firingVelocity3 = (shootDirection * 10).RotatedBy((-0.035f * (i + 1)) * Utils.GetLerpValue(0, 55, Windup, true)); + Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), GunTipPosition, firingVelocity3 * (1 - i * 0.1f), ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner, 0, 2); + } } Particle pulse3 = new GlowSparkParticle(GunTipPosition, shootDirection * 18, false, 6, 0.057f, EffectsColor, new Vector2(1.7f, 0.8f), true); diff --git a/Projectiles/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/VividExplosion.cs b/Projectiles/Magic/VividExplosion.cs index 141dd92601..2ab46185d6 100644 --- a/Projectiles/Magic/VividExplosion.cs +++ b/Projectiles/Magic/VividExplosion.cs @@ -16,7 +16,7 @@ public override void SetDefaults() Projectile.friendly = true; Projectile.ignoreWater = true; Projectile.tileCollide = false; - Projectile.DamageType = RogueDamageClass.Instance; + Projectile.DamageType = DamageClass.Magic; Projectile.penetrate = -1; Projectile.usesLocalNPCImmunity = true; Projectile.localNPCHitCooldown = 6; 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/ArkOfTheAncients_SwungBlade.cs b/Projectiles/Melee/ArkOfTheAncients_SwungBlade.cs index 9e78cc627b..69c3d25b70 100644 --- a/Projectiles/Melee/ArkOfTheAncients_SwungBlade.cs +++ b/Projectiles/Melee/ArkOfTheAncients_SwungBlade.cs @@ -131,7 +131,7 @@ public override bool PreDraw(ref Color lightColor) Vector2 drawOrigin = new Vector2(Owner.direction < 0 ? sword.Width : 0f, sword.Height); Vector2 drawOffset = Owner.Center + drawAngle.ToRotationVector2() * 10f - Main.screenPosition; - if (CalamityConfig.Instance.Afterimages && Timer > ProjectileID.Sets.TrailCacheLength[Projectile.type]) + if (CalamityClientConfig.Instance.Afterimages && Timer > ProjectileID.Sets.TrailCacheLength[Projectile.type]) { for (int i = 0; i < Projectile.oldRot.Length; ++i) { diff --git a/Projectiles/Melee/ArkOfTheCosmos_SwungBlade.cs b/Projectiles/Melee/ArkOfTheCosmos_SwungBlade.cs index 5b3bb7fb7e..7ef7023edc 100644 --- a/Projectiles/Melee/ArkOfTheCosmos_SwungBlade.cs +++ b/Projectiles/Melee/ArkOfTheCosmos_SwungBlade.cs @@ -489,7 +489,7 @@ public void DrawSingleSwungScissorBlade(Color lightColor) Vector2 drawOrigin = new Vector2(flipped ? sword.Width : 0f, sword.Height); Vector2 drawOffset = Owner.Center + drawAngle.ToRotationVector2() * 10f - Main.screenPosition; - if (CalamityConfig.Instance.Afterimages && SwingTimer > ProjectileID.Sets.TrailCacheLength[Projectile.type] && Combo == 0f) + if (CalamityClientConfig.Instance.Afterimages && SwingTimer > ProjectileID.Sets.TrailCacheLength[Projectile.type] && Combo == 0f) { for (int i = 1; i < Projectile.oldRot.Length; ++i) { @@ -544,7 +544,7 @@ public void DrawSwungScissors(Color lightColor) Vector2 backScissorDrawPosition = Owner.Center + drawAngle.ToRotationVector2() * 10f + (drawAngle.ToRotationVector2() * 56f + (drawAngle - MathHelper.PiOver2).ToRotationVector2() * 11 * Owner.direction) * Projectile.scale - Main.screenPosition; //Lined up with the hole in the front blade - if (CalamityConfig.Instance.Afterimages && SwingTimer > ProjectileID.Sets.TrailCacheLength[Projectile.type]) + if (CalamityClientConfig.Instance.Afterimages && SwingTimer > ProjectileID.Sets.TrailCacheLength[Projectile.type]) { Texture2D afterimage = Request("CalamityMod/Projectiles/Melee/SunderingScissorsGlow").Value; diff --git a/Projectiles/Melee/ArkOfTheElements_SwungBlade.cs b/Projectiles/Melee/ArkOfTheElements_SwungBlade.cs index 6ad36b293e..7afe20cae8 100644 --- a/Projectiles/Melee/ArkOfTheElements_SwungBlade.cs +++ b/Projectiles/Melee/ArkOfTheElements_SwungBlade.cs @@ -308,7 +308,7 @@ public void DrawSingleSwungScissorBlade(Color lightColor) Vector2 drawOrigin = new Vector2(Combo == 1 ? sword.Width / 2f : flipped ? sword.Width : 0f, sword.Height); Vector2 drawOffset = Owner.Center + drawAngle.ToRotationVector2() * 10f - Main.screenPosition; - if (CalamityConfig.Instance.Afterimages && SwingTimer > ProjectileID.Sets.TrailCacheLength[Projectile.type]) + if (CalamityClientConfig.Instance.Afterimages && SwingTimer > ProjectileID.Sets.TrailCacheLength[Projectile.type]) { for (int i = 0; i < Projectile.oldRot.Length; ++i) { @@ -362,7 +362,7 @@ public void DrawSwungScissors(Color lightColor) Vector2 backScissorDrawPosition = Owner.Center + drawAngle.ToRotationVector2() * 10f + functionalDrawAngle.ToRotationVector2() * 70f * Projectile.scale - Main.screenPosition; //Lined up with the hole in the front blade float backScissorRotation = drawRotation + (Combo == 1 ? (!flipped ? MathHelper.PiOver4 * 0.75f : MathHelper.PiOver4 * -0.75f) : 0f); - if (CalamityConfig.Instance.Afterimages && SwingTimer > ProjectileID.Sets.TrailCacheLength[Projectile.type]) + if (CalamityClientConfig.Instance.Afterimages && SwingTimer > ProjectileID.Sets.TrailCacheLength[Projectile.type]) { for (int i = 0; i < Projectile.oldRot.Length; ++i) { diff --git a/Projectiles/Melee/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/DragonRageStaff.cs b/Projectiles/Melee/DragonRageStaff.cs index 79c116440d..aecec54d38 100644 --- a/Projectiles/Melee/DragonRageStaff.cs +++ b/Projectiles/Melee/DragonRageStaff.cs @@ -158,7 +158,7 @@ private void OnHitEffects(Vector2 position) { CalamityPlayer modPlayer = Main.player[Projectile.owner].Calamity(); modPlayer.dragonRageHits++; - if (modPlayer.dragonRageHits > 10 && modPlayer.dragonRageCooldown <= 0) + if (modPlayer.dragonRageHits >= 10 && modPlayer.dragonRageCooldown <= 0) { SpawnFireballs(); modPlayer.dragonRageHits = 0; 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/Galaxia_PhoenixsPride.cs b/Projectiles/Melee/Galaxia_PhoenixsPride.cs index dea78a8c39..3bb96e5877 100644 --- a/Projectiles/Melee/Galaxia_PhoenixsPride.cs +++ b/Projectiles/Melee/Galaxia_PhoenixsPride.cs @@ -286,7 +286,7 @@ public override bool PreDraw(ref Color lightColor) Vector2 drawOffset = Projectile.Center - Main.screenPosition; //Afterimages - if (CalamityConfig.Instance.Afterimages && CurrentState == 0f && Empowerment / maxEmpowerment > 0.4f) + if (CalamityClientConfig.Instance.Afterimages && CurrentState == 0f && Empowerment / maxEmpowerment > 0.4f) { for (int i = 0; i < Projectile.oldRot.Length; ++i) { diff --git a/Projectiles/Melee/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..f8bc673a97 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); @@ -340,7 +340,7 @@ public override bool PreDraw(ref Color lightColor) Vector2 origin = rectangle.Size() / 2f; Color alphaColor = Projectile.GetAlpha(lightColor); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { Vector2 centerOffset = Projectile.Size / 2f; int totalAfterimages = TotalAfterimages; diff --git a/Projectiles/Melee/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/MendedBiomeBlade_HeavensMight.cs b/Projectiles/Melee/MendedBiomeBlade_HeavensMight.cs index 10dbf2ddde..719e2b7024 100644 --- a/Projectiles/Melee/MendedBiomeBlade_HeavensMight.cs +++ b/Projectiles/Melee/MendedBiomeBlade_HeavensMight.cs @@ -215,7 +215,7 @@ public override bool PreDraw(ref Color lightColor) Vector2 drawOffset = Projectile.Center - Main.screenPosition; //Afterimages - if (CalamityConfig.Instance.Afterimages && CurrentState == 0f && Empowerment / maxEmpowerment > 0.4f) + if (CalamityClientConfig.Instance.Afterimages && CurrentState == 0f && Empowerment / maxEmpowerment > 0.4f) { for (int i = 0; i < Projectile.oldRot.Length; ++i) { diff --git a/Projectiles/Melee/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/TrueArkOfTheAncients_SwungBlade.cs b/Projectiles/Melee/TrueArkOfTheAncients_SwungBlade.cs index e3b784cf55..dbf5921c89 100644 --- a/Projectiles/Melee/TrueArkOfTheAncients_SwungBlade.cs +++ b/Projectiles/Melee/TrueArkOfTheAncients_SwungBlade.cs @@ -133,7 +133,7 @@ public override bool PreDraw(ref Color lightColor) Vector2 drawOrigin = new Vector2(Owner.direction < 0 ? sword.Width : 0f, sword.Height); Vector2 drawOffset = Owner.Center + drawAngle.ToRotationVector2() * 10f - Main.screenPosition; - if (CalamityConfig.Instance.Afterimages && Timer > ProjectileID.Sets.TrailCacheLength[Projectile.type]) + if (CalamityClientConfig.Instance.Afterimages && Timer > ProjectileID.Sets.TrailCacheLength[Projectile.type]) { for (int i = 0; i < Projectile.oldRot.Length; ++i) { diff --git a/Projectiles/Melee/TrueBiomeBlade_SwordsmithsPride.cs b/Projectiles/Melee/TrueBiomeBlade_SwordsmithsPride.cs index 8c8351f8f7..6404dc74ae 100644 --- a/Projectiles/Melee/TrueBiomeBlade_SwordsmithsPride.cs +++ b/Projectiles/Melee/TrueBiomeBlade_SwordsmithsPride.cs @@ -310,7 +310,7 @@ public override bool PreDraw(ref Color lightColor) drawOrigin = new Vector2(0f, blade.Height); //Afterimages - if (CalamityConfig.Instance.Afterimages && CurrentState == 0f && Empowerment / maxEmpowerment > 0.4f) + if (CalamityClientConfig.Instance.Afterimages && CurrentState == 0f && Empowerment / maxEmpowerment > 0.4f) { for (int i = 0; i < Projectile.oldRot.Length; ++i) { diff --git a/Projectiles/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..1191eda5d5 --- /dev/null +++ b/Projectiles/Ranged/BuzzkillHoldout.cs @@ -0,0 +1,264 @@ +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); + + int sawLevel = (SawPower >= 1f).ToInt() + (SawPower >= 0.25f).ToInt(); + if (Main.myPlayer == Projectile.owner) + { + float sawDamageMult = MathHelper.Lerp(1f, 5f, SawPower) / 1.5f; // The damage must be divided by 1.5 to offset the holdout having 1.5x base damage. + int sawPierce = (int)MathHelper.Lerp(2f, 6f, SawPower); + + Projectile buzzsaw = Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), GunTipPosition, Projectile.velocity.SafeNormalize(Vector2.UnitY) * Owner.ActiveItem().shootSpeed, ModContent.ProjectileType(), (int)(Projectile.damage * sawDamageMult), (int)(Projectile.knockBack * (sawDamageMult / 2)), Main.myPlayer, sawLevel); + buzzsaw.penetrate = sawPierce; + buzzsaw.rotation = Main.rand.NextFloat(0f, MathHelper.TwoPi); + } + + 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 (!CalamityClientConfig.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..f97bddbd36 --- /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 (!CalamityClientConfig.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/ElementalEruptionHouldout.cs b/Projectiles/Ranged/ElementalEruptionHouldout.cs index bb8f4c68f1..b8fb940c22 100644 --- a/Projectiles/Ranged/ElementalEruptionHouldout.cs +++ b/Projectiles/Ranged/ElementalEruptionHouldout.cs @@ -47,13 +47,14 @@ public override void HoldoutAI() { SoundEngine.PlaySound(SoundID.Item34, Projectile.Center); Owner.PickAmmo(Owner.ActiveItem(), out _, out float shootSpeed, out int damage, out float knockback, out _, Main.rand.NextFloat() < 0.70f); - for (int i = 0; i < 2; i++) + if (Main.myPlayer == Projectile.owner) { - Projectile.NewProjectile(Projectile.GetSource_FromThis(), GunTipPosition, (Projectile.velocity * 10).RotatedByRandom(0.12f), ModContent.ProjectileType(), damage, knockback, Projectile.owner); + for (int i = 0; i < 2; i++) + Projectile.NewProjectile(Projectile.GetSource_FromThis(), GunTipPosition, (Projectile.velocity * 10).RotatedByRandom(0.12f), ModContent.ProjectileType(), damage, knockback, Projectile.owner); } ShotsFired++; ShotCooldown = HeldItem.useTime; - if (FireBlobs == 0) + if (FireBlobs == 0 && Main.myPlayer == Projectile.owner) { Vector2 newVel = (Projectile.velocity * 9); Vector2 newPos = GunTipPosition + Projectile.velocity.SafeNormalize(Vector2.UnitX) * 36f; diff --git a/Projectiles/Ranged/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/FlakKrakenHoldout.cs b/Projectiles/Ranged/FlakKrakenHoldout.cs index 362c7e66a2..89c2ef86cd 100644 --- a/Projectiles/Ranged/FlakKrakenHoldout.cs +++ b/Projectiles/Ranged/FlakKrakenHoldout.cs @@ -72,17 +72,20 @@ public override void HoldoutAI() break; } - // Spawns the projectile. - Projectile.NewProjectileDirect( - Projectile.GetSource_FromThis(), - GunTipPosition, - direction * itemShootSpeed, - ProjectileType(), - itemDamage, - itemKnockback, - Projectile.owner, - rocketTypeShot, - ownerToMouse.Length()); + if (Main.myPlayer == Projectile.owner) + { + // Spawns the projectile. + Projectile.NewProjectileDirect( + Projectile.GetSource_FromThis(), + GunTipPosition, + direction * itemShootSpeed, + ProjectileType(), + itemDamage, + itemKnockback, + Projectile.owner, + rocketTypeShot, + ownerToMouse.Length()); + } // Applies the knockback to the player. Owner.velocity += ownerToMouse.SafeNormalize(Vector2.UnitY) * -OwnerKnockbackStrength; diff --git a/Projectiles/Ranged/FlakToxicannonHoldout.cs b/Projectiles/Ranged/FlakToxicannonHoldout.cs index 1bf6ce82a7..30e1a3e81d 100644 --- a/Projectiles/Ranged/FlakToxicannonHoldout.cs +++ b/Projectiles/Ranged/FlakToxicannonHoldout.cs @@ -69,17 +69,20 @@ public override void HoldoutAI() break; } - // Spawns the projectile. - Projectile.NewProjectileDirect( - Projectile.GetSource_FromThis(), - GunTipPosition, - direction * itemShootSpeed, - ProjectileType(), - itemDamage, - itemKnockback, - Projectile.owner, - rocketTypeShot, - ownerToMouse.Length()); + if (Main.myPlayer == Projectile.owner) + { + // Spawns the projectile. + Projectile.NewProjectileDirect( + Projectile.GetSource_FromThis(), + GunTipPosition, + direction * itemShootSpeed, + ProjectileType(), + itemDamage, + itemKnockback, + Projectile.owner, + rocketTypeShot, + ownerToMouse.Length()); + } // Applies the knockback to the player. Owner.velocity += ownerToMouse.SafeNormalize(Vector2.UnitY) * -OwnerKnockbackStrength; diff --git a/Projectiles/Ranged/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/MagnaCannonHoldout.cs b/Projectiles/Ranged/MagnaCannonHoldout.cs index ef4ea8c38e..cf78fee5f6 100644 --- a/Projectiles/Ranged/MagnaCannonHoldout.cs +++ b/Projectiles/Ranged/MagnaCannonHoldout.cs @@ -56,7 +56,8 @@ public override void HoldoutAI() SoundEngine.PlaySound(MagnaCannon.Fire, Projectile.position); Vector2 shootVelocity = Projectile.velocity.SafeNormalize(Vector2.UnitY) * BulletSpeed; - Projectile.NewProjectile(Projectile.GetSource_FromThis(), GunTipPosition, shootVelocity.RotatedByRandom(MathHelper.ToRadians(9f)), ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack * (FullyCharged ? 3 : 1), Projectile.owner); + if (Main.myPlayer == Projectile.owner) + Projectile.NewProjectile(Projectile.GetSource_FromThis(), GunTipPosition, shootVelocity.RotatedByRandom(MathHelper.ToRadians(9f)), ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack * (FullyCharged ? 3 : 1), Projectile.owner); for (int i = 0; i <= 3; i++) { Dust dust = Dust.NewDustPerfect(GunTipPosition, 187, shootVelocity.RotatedByRandom(MathHelper.ToRadians(15f)) * Main.rand.NextFloat(0.9f, 1.2f), 0, default, Main.rand.NextFloat(1.5f, 2.3f)); diff --git a/Projectiles/Ranged/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/MineralMortarProjectile.cs b/Projectiles/Ranged/MineralMortarProjectile.cs index bbda255676..98a7ae6fec 100644 --- a/Projectiles/Ranged/MineralMortarProjectile.cs +++ b/Projectiles/Ranged/MineralMortarProjectile.cs @@ -179,7 +179,7 @@ public override bool PreDraw(ref Color lightColor) GameShaders.Misc["CalamityMod:TrailStreak"].SetShaderTexture(ModContent.Request("CalamityMod/ExtraTextures/Trails/SwordSlashTexture")); PrimitiveRenderer.RenderTrail(Projectile.oldPos, new(TrailWidthFunction, ColorTrailFunction, (_) => Projectile.Size * 0.5f, shader: GameShaders.Misc["CalamityMod:TrailStreak"]), 50); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 0; i < 3; i++) { diff --git a/Projectiles/Ranged/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/ScorpioHoldout.cs b/Projectiles/Ranged/ScorpioHoldout.cs index 36669dd5f8..10b014a47b 100644 --- a/Projectiles/Ranged/ScorpioHoldout.cs +++ b/Projectiles/Ranged/ScorpioHoldout.cs @@ -142,17 +142,20 @@ public void ShootRocket(Item item, bool isRMB) break; } - // Spawns the projectile. - Projectile.NewProjectileDirect( - Projectile.GetSource_FromThis(), - GunTipPosition, - projectileVelocity.RotatedByRandom(isRMB ? 0f : MathHelper.PiOver4) * projSpeed * (isRMB ? 1f : Main.rand.NextFloat(0.8f, 1f)), - isRMB ? ProjectileType() : ProjectileType(), - damage, - knockback, - Projectile.owner, - rocketType, - projSpeed); + if (Main.myPlayer == Projectile.owner) + { + // Spawns the projectile. + Projectile.NewProjectileDirect( + Projectile.GetSource_FromThis(), + GunTipPosition, + projectileVelocity.RotatedByRandom(isRMB ? 0f : MathHelper.PiOver4) * projSpeed * (isRMB ? 1f : Main.rand.NextFloat(0.8f, 1f)), + isRMB ? ProjectileType() : ProjectileType(), + damage, + knockback, + Projectile.owner, + rocketType, + projSpeed); + } // Inside here go all the things that dedicated servers shouldn't spend resources on. // Like visuals and sounds. diff --git a/Projectiles/Ranged/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..ea4d7a7231 --- /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 (!CalamityClientConfig.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..62806150af --- /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 (!CalamityClientConfig.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..8e7bd1e6a4 --- /dev/null +++ b/Projectiles/Ranged/SuperradiantSlaughtererHoldout.cs @@ -0,0 +1,356 @@ +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 || Owner.dead || !Owner.active) + { + 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) + if (Main.myPlayer == Projectile.owner) + { + float clampedMouseDist = MathHelper.Clamp(Vector2.Distance(GunTipPosition, Owner.Calamity().mouseWorld), 0f, 960f); + float adjustedMouseDist = clampedMouseDist / 21f; + Projectile.NewProjectile(Projectile.GetSource_FromThis(), GunTipPosition, Projectile.velocity.SafeNormalize(Vector2.UnitY) * adjustedMouseDist, ModContent.ProjectileType(), (int)(Projectile.damage * 1.5f), Projectile.knockBack, Projectile.owner); + } + + // Special case: right-clicking while not holding left-click + // This is to keep it friendly to use both fires at the same time, but end the animation early if not + 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. + if (Main.myPlayer == Projectile.owner) + Projectile.NewProjectile(Projectile.GetSource_FromThis(), GunTipPosition, Projectile.velocity.SafeNormalize(Vector2.UnitY) * SuperradiantSlaughterer.ShootSpeed, ModContent.ProjectileType(), (int)(Projectile.damage * sawDamageMult), Projectile.knockBack, Projectile.owner, sawLevel, 0f, sawPierce); + + NoSawOnHoldout = true; + OffsetLengthFromArm -= 4f + 12f * SawPower; + + 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 (!CalamityClientConfig.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/TheHiveHoldout.cs b/Projectiles/Ranged/TheHiveHoldout.cs index a282f52ad9..83af0f3f97 100644 --- a/Projectiles/Ranged/TheHiveHoldout.cs +++ b/Projectiles/Ranged/TheHiveHoldout.cs @@ -140,15 +140,9 @@ public void ShootRocket() SoundStyle fire = new("CalamityMod/Sounds/Custom/PlagueSounds/PBGBarrageLaunch"); SoundEngine.PlaySound(fire with { Volume = 0.5f, Pitch = 0.1f }, Projectile.Center); - Projectile.NewProjectileDirect( - Projectile.GetSource_FromThis(), - GunTipPosition, - shootDirection * projSpeed * 0.3f, - ProjectileType(), - damage * 10, - knockback, - Projectile.owner, - rocketType); + if (Main.myPlayer == Projectile.owner) + Projectile.NewProjectileDirect(Projectile.GetSource_FromThis(), GunTipPosition, shootDirection * projSpeed * 0.3f, ProjectileType(), damage * 10, knockback, Projectile.owner, rocketType); + PostFireCooldown = 75; } else @@ -156,20 +150,23 @@ public void ShootRocket() SoundStyle fire = new("CalamityMod/Sounds/Custom/PlagueSounds/PBGBarrageLaunch"); SoundEngine.PlaySound(fire with { Volume = 0.4f, Pitch = 0.7f }, Projectile.Center); - int numProj = 4; - float rotation = MathHelper.ToRadians(MathHelper.Clamp(35 - VelocityMultiplier * 26, 2, 25)); - for (int i = 0; i < numProj; i++) + if (Main.myPlayer == Projectile.owner) { - Vector2 perturbedSpeed = (shootDirection).RotatedBy(MathHelper.Lerp(-rotation, rotation, i / (float)(numProj - 1))); - Projectile.NewProjectileDirect( - Projectile.GetSource_FromThis(), - GunTipPosition, - perturbedSpeed * projSpeed * VelocityMultiplier, - ProjectileType(), - damage, - knockback, - Projectile.owner, - rocketType); + int numProj = 4; + float rotation = MathHelper.ToRadians(MathHelper.Clamp(35 - VelocityMultiplier * 26, 2, 25)); + for (int i = 0; i < numProj; i++) + { + Vector2 perturbedSpeed = (shootDirection).RotatedBy(MathHelper.Lerp(-rotation, rotation, i / (float)(numProj - 1))); + Projectile.NewProjectileDirect( + Projectile.GetSource_FromThis(), + GunTipPosition, + perturbedSpeed * projSpeed * VelocityMultiplier, + ProjectileType(), + damage, + knockback, + Projectile.owner, + rocketType); + } } PostFireCooldown = 30; } diff --git a/Projectiles/Ranged/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/Ranged/WildfireBloomHoldout.cs b/Projectiles/Ranged/WildfireBloomHoldout.cs index dc4086d841..ffac8c4fd9 100644 --- a/Projectiles/Ranged/WildfireBloomHoldout.cs +++ b/Projectiles/Ranged/WildfireBloomHoldout.cs @@ -41,10 +41,11 @@ public override void HoldoutAI() { SoundEngine.PlaySound(SoundID.Item34, Projectile.Center); Owner.PickAmmo(Owner.ActiveItem(), out _, out float shootSpeed, out int damage, out float knockback, out _, Main.rand.NextBool(2)); - Projectile.NewProjectile(Projectile.GetSource_FromThis(), GunTipPosition, (Projectile.velocity * 9).RotatedByRandom(0.08f), ModContent.ProjectileType(), damage, knockback, Projectile.owner); + if (Main.myPlayer == Projectile.owner) + Projectile.NewProjectile(Projectile.GetSource_FromThis(), GunTipPosition, (Projectile.velocity * 9).RotatedByRandom(0.08f), ModContent.ProjectileType(), damage, knockback, Projectile.owner); ShotsFired++; ShotCooldown = HeldItem.useTime; - if (FireBlobs == 0) + if (FireBlobs == 0 && Main.myPlayer == Projectile.owner) { float randAngle = Main.rand.NextFloat(8f, 15f); Vector2 newVel = (Projectile.velocity * 9).RotatedBy(MathHelper.ToRadians(randAngle)) * 2f; 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/NiceCock.cs b/Projectiles/Rogue/NiceCock.cs deleted file mode 100644 index 11bc1ff1ca..0000000000 --- a/Projectiles/Rogue/NiceCock.cs +++ /dev/null @@ -1,154 +0,0 @@ -using System.IO; -using CalamityMod.CalPlayer; -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.Audio; -using Terraria.ID; -using Terraria.ModLoader; -namespace CalamityMod.Projectiles.Rogue -{ - // The file name is a specific request from the patron - public class NiceCock : ModProjectile, ILocalizedModType - { - public new string LocalizationCategory => "Projectiles.Rogue"; - public bool homing = false; - public int Timer = 0; - private bool initialized = false; - private Color[] colors = new Color[] - { - new Color(255, 0, 0, 50), //Red - new Color(255, 128, 0, 50), //Orange - new Color(255, 255, 0, 50), //Yellow - new Color(128, 255, 0, 50), //Lime - new Color(0, 255, 0, 50), //Green - new Color(0, 255, 128, 50), //Turquoise - new Color(0, 255, 255, 50), //Cyan - new Color(0, 128, 255, 50), //Light Blue - new Color(0, 0, 255, 50), //Blue - new Color(128, 0, 255, 50), //Purple - new Color(255, 0, 255, 50), //Fuschia - new Color(255, 0, 128, 50) //Hot Pink - }; - - public override void SetStaticDefaults() - { - Main.projFrames[Projectile.type] = 5; - } - - public override void SetDefaults() - { - Projectile.width = 44; - Projectile.height = 70; - Projectile.friendly = true; - Projectile.tileCollide = false; - Projectile.DamageType = RogueDamageClass.Instance; - Projectile.timeLeft = 180; - Projectile.alpha = 255; - } - - public override void SendExtraAI(BinaryWriter writer) => writer.Write(homing); - - public override void ReceiveExtraAI(BinaryReader reader) => homing = reader.ReadBoolean(); - - public override bool? CanHitNPC(NPC target) - { - // Do not deal damage before fully opaque - if (Projectile.alpha >= 10) - return false; - int index = (int)Projectile.ai[1]; - if (Main.npc[index] is null || !Main.npc[index].active || Main.npc[index].life < 0) - return false; - // Do not deal damage to any NPC that isn't the specified target - if (index != target.whoAmI) - return false; - return null; - } - - public override void AI() - { - Player player = Main.player[Projectile.owner]; - CalamityPlayer modPlayer = player.Calamity(); - // Fireballs disappear if you can't stealth strike - if (!modPlayer.wearingRogueArmor || modPlayer.rogueStealthMax <= 0) - Projectile.Kill(); - - Projectile.alpha -= 5; - - if (!initialized) - { - // Pick a random frame to start on - Projectile.frame = Main.rand.Next(Main.projFrames[Projectile.type]); - initialized = true; - } - - Projectile.frameCounter++; - if (Projectile.frameCounter > 8) - { - Projectile.frame++; - Projectile.frameCounter = 0; - } - if (Projectile.frame >= Main.projFrames[Projectile.type]) - Projectile.frame = 0; - - int index = (int)Projectile.ai[1]; - - // If the target doesn't exist or is dead, spontaneously combust - if (Main.npc[index] is null || !Main.npc[index].active || Main.npc[index].life < 0) - Projectile.Kill(); - - // Decrement the timer. This should last a second as stealth strikes will initialize this at 61. - if (Timer > 1) - Timer--; - if (Timer == 1) - homing = true; - - NPC target = Main.npc[index]; - - if (homing) - { - // Home in on the target - Vector2 moveDirection = Projectile.SafeDirectionTo(target.Center, Vector2.UnitY); - Projectile.velocity = (Projectile.velocity * 20f + moveDirection * 15f) / 21f; - } - else - { - // Circle around the target counter-clockwise at 4 radians per frame - float height = target.getRect().Height; - float width = target.getRect().Width; - float circleDist = MathHelper.Min((height > width ? height : width) * 3f, (Main.LogicCheckScreenWidth * Main.LogicCheckScreenHeight) / 2); - if (circleDist > Main.LogicCheckScreenWidth / 3) - circleDist = Main.LogicCheckScreenWidth / 3; - Projectile.Center = target.Center + Projectile.ai[0].ToRotationVector2() * circleDist; - Projectile.ai[0] -= MathHelper.ToRadians(4f); - } - } - - public override void OnKill(int timeLeft) - { - SoundEngine.PlaySound(SoundID.Item74, Projectile.Center); - Projectile.ExpandHitboxBy(50); - - // Create into some rainbow-colored dust when dead - for (int d = 0; d < 5; d++) - { - int idx = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.RainbowMk2, 0f, 0f, 150, Main.rand.Next(colors), 2f); - Main.dust[idx].velocity *= 3f; - Main.dust[idx].noGravity = true; - if (Main.rand.NextBool()) - { - Main.dust[idx].scale = 0.5f; - Main.dust[idx].fadeIn = 1f + (float)Main.rand.Next(10) * 0.1f; - } - } - for (int d = 0; d < 8; d++) - { - int idx = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.RainbowMk2, 0f, 0f, 150, Main.rand.Next(colors), 3f); - Main.dust[idx].noGravity = true; - Main.dust[idx].velocity *= 5f; - idx = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.RainbowMk2, 0f, 0f, 150, Main.rand.Next(colors), 2f); - Main.dust[idx].velocity *= 2f; - Main.dust[idx].noGravity = true; - } - } - } -} diff --git a/Projectiles/Rogue/NiceCock.png b/Projectiles/Rogue/NiceCock.png deleted file mode 100644 index 8881462c5c..0000000000 Binary files a/Projectiles/Rogue/NiceCock.png and /dev/null differ 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/PanSpark.cs b/Projectiles/Rogue/PanSpark.cs deleted file mode 100644 index 9fcf5404d8..0000000000 --- a/Projectiles/Rogue/PanSpark.cs +++ /dev/null @@ -1,139 +0,0 @@ -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Projectiles.Rogue -{ - public class PanSpark : ModProjectile, ILocalizedModType - { - public new string LocalizationCategory => "Projectiles.Rogue"; - private bool initialized = false; - - public override void SetStaticDefaults() - { - Main.projFrames[Projectile.type] = 3; - ProjectileID.Sets.TrailCacheLength[Projectile.type] = 2; - ProjectileID.Sets.TrailingMode[Projectile.type] = 0; - } - - public override void SetDefaults() - { - Projectile.width = 14; - Projectile.height = 14; - Projectile.friendly = true; - Projectile.penetrate = -1; - Projectile.timeLeft = 120; - Projectile.usesLocalNPCImmunity = true; - Projectile.localNPCHitCooldown = -1; - Projectile.DamageType = RogueDamageClass.Instance; - Projectile.ignoreWater = true; - } - - public override void AI() - { - //make it face the way it's going - if (Projectile.ai[1] > 0f) - { - Projectile.rotation = -Projectile.velocity.X * 0.05f + MathHelper.PiOver2; - } - else - { - Projectile.rotation = Projectile.velocity.ToRotation(); - } - Projectile.ai[1]--; - - //frames - if (!initialized) - { - initialized = true; - Projectile.frame = Main.rand.Next(Main.projFrames[Projectile.type]); - } - Projectile.frameCounter++; - if (Projectile.frameCounter > 6) - { - Projectile.frame++; - Projectile.frameCounter = 0; - } - if (Projectile.frame >= Main.projFrames[Projectile.type]) - { - Projectile.frame = 0; - } - - //movement - if (Projectile.velocity.X != Projectile.velocity.X) - { - Projectile.velocity.X *= -0.1f; - } - if (Projectile.velocity.X != Projectile.velocity.X) - { - Projectile.velocity.X *= -0.5f; - } - if (Projectile.velocity.Y != Projectile.velocity.Y && Projectile.velocity.Y > 1f) - { - Projectile.velocity.Y *= -0.5f; - } - Projectile.ai[0] += 1f; - if (Projectile.ai[0] > 5f) - { - Projectile.ai[0] = 5f; - if (Projectile.velocity.Y == 0f && Projectile.velocity.X != 0f) - { - Projectile.velocity.X *= 0.97f; - if (Projectile.velocity.X > -0.01f && Projectile.velocity.X < 0.01f) - { - Projectile.velocity.X = 0f; - Projectile.netUpdate = true; - } - } - Projectile.velocity.Y += 0.2f; - } - if (Projectile.velocity.Y < 0.25f && Projectile.velocity.Y > 0.15f) - { - Projectile.velocity.X *= 0.8f; - } - if (Projectile.velocity.Y > 16f) - { - Projectile.velocity.Y = 16f; - } - - //dust - if (Main.rand.NextBool(4)) - { - int fire = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.Torch, 0f, 0f, 100, default, 1f); - Dust dust = Main.dust[fire]; - dust.position.X -= 2f; - dust.position.Y += 2f; - dust.scale += (float)Main.rand.Next(50) * 0.01f; - dust.noGravity = true; - dust.velocity.Y -= 2f; - } - if (Main.rand.NextBool(10)) - { - int fire = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.Torch, 0f, 0f, 100, default, 1f); - Dust dust = Main.dust[fire]; - dust.position.X -= 2f; - dust.position.Y += 2f; - dust.scale += 0.3f + (float)Main.rand.Next(50) * 0.01f; - dust.noGravity = true; - dust.velocity *= 0.1f; - } - } - - public override bool OnTileCollide(Vector2 oldVelocity) - { - Projectile.ai[1] = 10f; - return false; - } - - public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) => target.AddBuff(BuffID.Daybreak, 90); - - public override Color? GetAlpha(Color lightColor) => new Color(255, 230, 130); - - public override bool PreDraw(ref Color lightColor) - { - CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], lightColor, 1); - return false; - } - } -} diff --git a/Projectiles/Rogue/PanSpark.png b/Projectiles/Rogue/PanSpark.png deleted file mode 100644 index c74b2ed1a7..0000000000 Binary files a/Projectiles/Rogue/PanSpark.png and /dev/null differ 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/SearedPanProjectile.cs b/Projectiles/Rogue/SearedPanProjectile.cs deleted file mode 100644 index a7022fce06..0000000000 --- a/Projectiles/Rogue/SearedPanProjectile.cs +++ /dev/null @@ -1,206 +0,0 @@ -using CalamityMod.Buffs.DamageOverTime; -using CalamityMod.CalPlayer; -using CalamityMod.Items.Weapons.Rogue; -using CalamityMod.NPCs.NormalNPCs; -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.Audio; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Projectiles.Rogue -{ - public class SearedPanProjectile : ModProjectile, ILocalizedModType - { - public new string LocalizationCategory => "Projectiles.Rogue"; - internal enum SearedPanTypes - { - VenLocket = 0, - Normal = 1, - Golden = 2, - StealthStrike = 3 - } - - internal SearedPanTypes PanType - { - get => (SearedPanTypes)(int)Projectile.ai[0]; - set => Projectile.ai[0] = (int)value; - } - - public override void SetStaticDefaults() - { - ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; - ProjectileID.Sets.TrailingMode[Projectile.type] = 0; - } - - public override void SetDefaults() - { - Projectile.width = Projectile.height = 20; - Projectile.friendly = true; - Projectile.ignoreWater = true; - Projectile.timeLeft = 420; - Projectile.DamageType = RogueDamageClass.Instance; - Projectile.extraUpdates = 2; - } - - public override void AI() - { - if (Main.rand.NextBool(5)) - { - Dust.NewDust(Projectile.position + Projectile.velocity, Projectile.width, Projectile.height, DustID.Blood, Projectile.velocity.X * 0.5f, Projectile.velocity.Y * 0.5f); - } - Projectile.spriteDirection = Projectile.direction = (Projectile.velocity.X > 0).ToDirectionInt(); - Projectile.rotation = Projectile.velocity.ToRotation() + (Projectile.spriteDirection == 1 ? 0f : MathHelper.Pi); - } - - public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) - { - // Don't increment the Seared Pan counter when hitting dummies - //&& target.type != ModContent.NPCType() this is here just in case its needed again - bool dummy = target.type != NPCID.TargetDummy; - OnHitEffects(target.whoAmI, target.life, dummy); - } - - public override void OnHitPlayer(Player target, Player.HurtInfo info) - { - target.AddBuff(BuffID.Bleeding, 300); - OnHitEffects(-1, target.statLife, true); - } - - private void OnHitEffects(int targetIndex, int health, bool specialEffects) - { - Player player = Main.player[Projectile.owner]; - CalamityPlayer modPlayer = player.Calamity(); - - // Don't spawn fireballs or increment the special effects counter if you can't even stealth strike - bool playerCanStealthStrike = modPlayer.wearingRogueArmor && modPlayer.rogueStealthMax > 0; - if (!playerCanStealthStrike) - return; - - // Increment the seared pan counter. Pans summoned via the Venerated Locket shouldn't increment the counter. - // See CalamityPlayerMiscEffects.cs for code that resets the counter after 40 frames - modPlayer.searedPanTimer = 0; - if (specialEffects && PanType != SearedPanTypes.VenLocket) - modPlayer.searedPanCounter++; - - // Pans summoned via the Venerated Locket have zero special effects - if (PanType == SearedPanTypes.StealthStrike) - { - modPlayer.searedPanCounter = 0; - // Stealth strikes spawn four golden sparks on hit - for (int t = 0; t < 4; t++) - { - Vector2 velocity = CalamityUtils.RandomVelocity(100f, 70f, 100f); - Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, velocity, ModContent.ProjectileType(), (int)(Projectile.damage * 0.2), 0f, Projectile.owner); - } - SoundEngine.PlaySound(SearedPan.SmashSound, Projectile.position); - // Stealth strikes also cause any existing fireballs to home in on their targets - FireballStuff(true); - - if (!specialEffects) - return; - // Stealth strikes then summon five fireballs to circle the hit enemy, they will home in on their own after a second. - for (int t = 0; t < 5; t++) - { - int i = Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, Vector2.Zero, ModContent.ProjectileType(), (int)(Projectile.damage * 0.1), 0f, Projectile.owner, 0f, targetIndex); - Main.projectile[i].ModProjectile().Timer = 61; - } - FireballPositions(targetIndex); - } - else if (PanType == SearedPanTypes.Golden) - { - modPlayer.searedPanCounter = 0; - SoundEngine.PlaySound(SearedPan.SmashSound, Projectile.position); - // Golden pans simply cause all fireballs to home in on their targets - FireballStuff(true); - } - else if (PanType == SearedPanTypes.Normal && targetIndex != -1 && health > 0 && specialEffects) - { - // Summon three fireballs to circle the hit enemy - for (int t = 0; t < 3; t++) - { - Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, Vector2.Zero, ModContent.ProjectileType(), (int)(Projectile.damage * 0.1), 0f, Projectile.owner, 0f, targetIndex); - } - FireballPositions(targetIndex); - } - } - - private void FireballStuff(bool activate) - { - if (Projectile.owner == Main.myPlayer) - { - foreach (Projectile p in Main.ActiveProjectiles) - { - if (p.owner != Projectile.owner) - continue; - if (p.ModProjectile is NiceCock) - { - if (!activate) - p.Kill(); - else - { - p.ModProjectile().homing = true; - p.extraUpdates += 2; - } - } - } - } - } - - private void FireballPositions(int targetIndex) - { - int fireballCount = 0; - // Count how many fireballs exist already around the given target - foreach (Projectile p in Main.ActiveProjectiles) - { - // Keep the loop as short as possible - if (p.owner != Projectile.owner || !p.CountsAsClass() || targetIndex != (int)p.ai[1]) - continue; - if (p.ModProjectile is NiceCock) - { - if (p.ModProjectile().homing) - continue; - fireballCount++; - } - } - // Adjust the angle of the existing fireballs around a target - float angleVariance = MathHelper.TwoPi / fireballCount; - float angle = 0f; - foreach (Projectile p in Main.ActiveProjectiles) - { - if (p.owner != Projectile.owner || !p.CountsAsClass() || targetIndex != (int)p.ai[1]) - continue; - if (p.ModProjectile is NiceCock) - { - if (p.ModProjectile().homing) - continue; - p.ai[0] = angle; - p.netUpdate = true; - angle += angleVariance; - } - } - } - - public override bool OnTileCollide(Vector2 oldVelocity) - { - // Kill all fireballs if you miss a stealth strike or golden pan - if (PanType == SearedPanTypes.Golden || PanType == SearedPanTypes.StealthStrike) - FireballStuff(false); - return true; - } - - public override Color? GetAlpha(Color lightColor) - { - // Stealth strikes and golden pans are golden colored - if (PanType == SearedPanTypes.Golden || PanType == SearedPanTypes.StealthStrike) - return new Color(255, 222, 0); - return null; - } - - public override bool PreDraw(ref Color lightColor) - { - CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], lightColor, 1); - return false; - } - } -} diff --git a/Projectiles/Rogue/SearedPanProjectile.png b/Projectiles/Rogue/SearedPanProjectile.png deleted file mode 100644 index 559b586cb8..0000000000 Binary files a/Projectiles/Rogue/SearedPanProjectile.png and /dev/null differ 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/WrathwingFireball.cs b/Projectiles/Rogue/WrathwingFireball.cs index ea87dc0f35..2d3428e84c 100644 --- a/Projectiles/Rogue/WrathwingFireball.cs +++ b/Projectiles/Rogue/WrathwingFireball.cs @@ -57,7 +57,7 @@ public override bool PreDraw(ref Color lightColor) int frameHeight = texture.Height / Main.projFrames[Projectile.type]; int frameY = frameHeight * Projectile.frame; Rectangle rectangle = new Rectangle(0, frameY, texture.Width, frameHeight); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 0; i < Projectile.oldPos.Length; i++) { diff --git a/Projectiles/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/HarvestStaffSentry.cs b/Projectiles/Summon/HarvestStaffSentry.cs index 58fab16163..f4eeecaec9 100644 --- a/Projectiles/Summon/HarvestStaffSentry.cs +++ b/Projectiles/Summon/HarvestStaffSentry.cs @@ -3,6 +3,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Terraria; +using Terraria.ID; using Terraria.ModLoader; using static CalamityMod.Items.Weapons.Summon.HarvestStaff; @@ -16,7 +17,11 @@ public class HarvestStaffSentry : ModProjectile, ILocalizedModType public static float Gravity = 0.8f; public static float MaxGravity = 20f; - public override void SetStaticDefaults() => Main.projFrames[Type] = 4; + public override void SetStaticDefaults() + { + Main.projFrames[Type] = 4; + ProjectileID.Sets.MinionTargettingFeature[Type] = true; + } public override void SetDefaults() { 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/IceClasperMinion.cs b/Projectiles/Summon/IceClasperMinion.cs index 94aca8ef17..89aded9c6b 100644 --- a/Projectiles/Summon/IceClasperMinion.cs +++ b/Projectiles/Summon/IceClasperMinion.cs @@ -199,7 +199,7 @@ public override bool PreDraw(ref Color lightColor) AfterimageInterpolant = MathHelper.Clamp(AfterimageInterpolant, 0f, 1f); float AfterimageFade = MathHelper.Lerp(0f, 1f, AfterimageInterpolant); - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 0; i < Projectile.oldPos.Length; i++) { diff --git a/Projectiles/Summon/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/MiniGuardianRock.cs b/Projectiles/Summon/MiniGuardianRock.cs index 5f7c775d22..f4030d1c70 100644 --- a/Projectiles/Summon/MiniGuardianRock.cs +++ b/Projectiles/Summon/MiniGuardianRock.cs @@ -122,7 +122,7 @@ public override bool PreDraw(ref Color lightColor) lerpVal = Utils.GetLerpValue(psc ? 87 : 57, psc ? 150 : 120, ownerDist, true); mult = MathHelper.Lerp(0.42f, 1f, lerpVal); } - if (CalamityConfig.Instance.Afterimages && Projectile.ai[0] >= 1f) //handle afterimages manually since the utility broke it and didn't render correctly + if (CalamityClientConfig.Instance.Afterimages && Projectile.ai[0] >= 1f) //handle afterimages manually since the utility broke it and didn't render correctly { for (int i = 0; i < Projectile.oldPos.Length; ++i) { diff --git a/Projectiles/Summon/MirrorofKalandraMinions/HopeShredderArrow.cs b/Projectiles/Summon/MirrorofKalandraMinions/HopeShredderArrow.cs index 5e064d63a7..1d1faac2f7 100644 --- a/Projectiles/Summon/MirrorofKalandraMinions/HopeShredderArrow.cs +++ b/Projectiles/Summon/MirrorofKalandraMinions/HopeShredderArrow.cs @@ -65,7 +65,7 @@ public override bool PreDraw(ref Color lightColor) Rectangle frame = texture.Frame(1, Main.projFrames[Type], 0, Projectile.frame); Vector2 origin = frame.Size() * 0.5f; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 0; i < Projectile.oldPos.Length; i++) { diff --git a/Projectiles/Summon/MirrorofKalandraMinions/Paradoxica.cs b/Projectiles/Summon/MirrorofKalandraMinions/Paradoxica.cs index 2ac39278e4..aae3731d65 100644 --- a/Projectiles/Summon/MirrorofKalandraMinions/Paradoxica.cs +++ b/Projectiles/Summon/MirrorofKalandraMinions/Paradoxica.cs @@ -190,7 +190,7 @@ public override bool PreDraw(ref Color lightColor) Vector2 origin = frame.Size() * 0.5f; float rotation = (Target is not null) ? Projectile.rotation : Projectile.rotation + MathHelper.PiOver4; - if (CalamityConfig.Instance.Afterimages && Target is not null) + if (CalamityClientConfig.Instance.Afterimages && Target is not null) { for (int i = 0; i < Projectile.oldPos.Length; i++) { diff --git a/Projectiles/Summon/MirrorofKalandraMinions/Starforge.cs b/Projectiles/Summon/MirrorofKalandraMinions/Starforge.cs index 2ddb451933..c2fdddd74b 100644 --- a/Projectiles/Summon/MirrorofKalandraMinions/Starforge.cs +++ b/Projectiles/Summon/MirrorofKalandraMinions/Starforge.cs @@ -138,7 +138,7 @@ public override bool PreDraw(ref Color lightColor) DrawSpin -= MathHelper.ToRadians(MirrorofKalandra.Purple_SpinSpeed); float rotation = (Target is not null) ? DrawSpin : Projectile.rotation + MathHelper.Pi - MathHelper.PiOver4; - if (CalamityConfig.Instance.Afterimages && Target is not null) + if (CalamityClientConfig.Instance.Afterimages && Target is not null) { for (int i = 0; i < Projectile.oldPos.Length; i++) { diff --git a/Projectiles/Summon/MirrorofKalandraMinions/WindRipperArrow.cs b/Projectiles/Summon/MirrorofKalandraMinions/WindRipperArrow.cs index e972745785..006b16a2e1 100644 --- a/Projectiles/Summon/MirrorofKalandraMinions/WindRipperArrow.cs +++ b/Projectiles/Summon/MirrorofKalandraMinions/WindRipperArrow.cs @@ -56,7 +56,7 @@ public override bool PreDraw(ref Color lightColor) Rectangle frame = texture.Frame(1, Main.projFrames[Type], 0, Projectile.frame); Vector2 origin = frame.Size() * 0.5f; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 0; i < Projectile.oldPos.Length; i++) { diff --git a/Projectiles/Summon/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/MutatedTruffleMinion.cs b/Projectiles/Summon/MutatedTruffleMinion.cs index 20ca2992a1..498383c09d 100644 --- a/Projectiles/Summon/MutatedTruffleMinion.cs +++ b/Projectiles/Summon/MutatedTruffleMinion.cs @@ -267,7 +267,7 @@ public override bool PreDraw(ref Color lightColor) float drawRotation = Projectile.rotation + (Projectile.spriteDirection == -1 && State != AIState.Idle ? MathHelper.Pi : 0f); SpriteEffects effects = (Projectile.spriteDirection == 1) ? SpriteEffects.None : SpriteEffects.FlipHorizontally; - if (CalamityConfig.Instance.Afterimages && (State == AIState.Dashing || State == AIState.Vortex)) + if (CalamityClientConfig.Instance.Afterimages && (State == AIState.Dashing || State == AIState.Vortex)) { for (int i = 0; i < Projectile.oldPos.Length; i++) { diff --git a/Projectiles/Summon/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..c7ba78c212 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() @@ -91,7 +92,7 @@ public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) public override bool PreDraw(ref Color lightColor) { - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Projectile.type], lightColor, 1); } diff --git a/Projectiles/Summon/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/PlantationStaffSeed.cs b/Projectiles/Summon/PlantationStaffSeed.cs index 86f09239fc..e891f75ec4 100644 --- a/Projectiles/Summon/PlantationStaffSeed.cs +++ b/Projectiles/Summon/PlantationStaffSeed.cs @@ -59,7 +59,7 @@ public override bool PreDraw(ref Color lightColor) Rectangle frame = texture.Frame(1, Main.projFrames[Type], 0, Projectile.frame); Vector2 origin = frame.Size() * 0.5f; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 0; i < Projectile.oldPos.Length; i++) { diff --git a/Projectiles/Summon/PlantationStaffSummon.cs b/Projectiles/Summon/PlantationStaffSummon.cs index 8e0f6380f5..7d8bd78097 100644 --- a/Projectiles/Summon/PlantationStaffSummon.cs +++ b/Projectiles/Summon/PlantationStaffSummon.cs @@ -341,7 +341,7 @@ public override bool PreDraw(ref Color lightColor) Rectangle frame = texture.Frame(1, Main.projFrames[Type], 0, Projectile.frame); Vector2 origin = frame.Size() * 0.5f; - if (State == AIState.Ramming && CalamityConfig.Instance.Afterimages) + if (State == AIState.Ramming && CalamityClientConfig.Instance.Afterimages) CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Type], lightColor); Main.EntitySpriteDraw(texture, drawPosition, frame, Projectile.GetAlpha(lightColor), Projectile.rotation, origin, Projectile.scale, SpriteEffects.None, 0); diff --git a/Projectiles/Summon/PlantationStaffTentacle.cs b/Projectiles/Summon/PlantationStaffTentacle.cs index a713ee71f3..306f069baa 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() @@ -229,7 +230,7 @@ public override bool PreDraw(ref Color lightColor) } } } - else if (CalamityConfig.Instance.Afterimages) + else if (CalamityClientConfig.Instance.Afterimages) CalamityUtils.DrawAfterimagesCentered(Projectile, ProjectileID.Sets.TrailingMode[Type], lightColor); return true; diff --git a/Projectiles/Summon/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..03cb9aa2ed 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() { @@ -1656,7 +1658,7 @@ public override bool PreDraw(ref Color lightColor) drawPos -= new Vector2(texture.Width, texture.Height) * Projectile.scale / 2f; drawPos += drawOrigin * Projectile.scale + new Vector2(0f, Projectile.gfxOffY); Rectangle frame = new Rectangle(0, 0, texture.Width, texture.Height); - if (CalamityConfig.Instance.Afterimages) //handle afterimages manually since the utility broke it and didn't render correctly + if (CalamityClientConfig.Instance.Afterimages) //handle afterimages manually since the utility broke it and didn't render correctly { for (int i = 0; i < Projectile.oldPos.Length; ++i) { @@ -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/Umbrella/MagicHat.cs b/Projectiles/Summon/Umbrella/MagicHat.cs index 663c9df9e3..3da5df70a1 100644 --- a/Projectiles/Summon/Umbrella/MagicHat.cs +++ b/Projectiles/Summon/Umbrella/MagicHat.cs @@ -128,7 +128,7 @@ public override bool PreDraw(ref Color lightColor) // Use a different texture if the player is invisible or has at least 50% stealth Texture2D texture = Terraria.GameContent.TextureAssets.Projectile[Projectile.type].Value; float stealthPercent = player.Calamity().rogueStealthMax != 0 ? (player.Calamity().rogueStealth / player.Calamity().rogueStealthMax) : 0f; //0 to 1 - bool hasStealth = player.Calamity().rogueStealth > 0f && stealthPercent > 0.5f && player.townNPCs < 3f && CalamityConfig.Instance.StealthInvisibility; + bool hasStealth = player.Calamity().rogueStealth > 0f && stealthPercent > 0.5f && player.townNPCs < 3f && CalamityClientConfig.Instance.StealthInvisibility; if (player.ShouldNotDraw || hasStealth) texture = ModContent.Request("CalamityMod/Projectiles/Summon/Umbrella/MagicHatInvis").Value; diff --git a/Projectiles/Summon/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..cbd9dff30f 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() @@ -64,7 +65,7 @@ public override bool PreDraw(ref Color lightColor) if (Projectile.spriteDirection == -1) direction = SpriteEffects.FlipHorizontally; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { for (int i = 0; i < Projectile.oldPos.Length; i++) { diff --git a/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/Scenes/MusicScenes/SkeletronPrimeMasterMusicScene.cs b/Scenes/MusicScenes/SkeletronPrimeMasterMusicScene.cs deleted file mode 100644 index 77398c4c76..0000000000 --- a/Scenes/MusicScenes/SkeletronPrimeMasterMusicScene.cs +++ /dev/null @@ -1,14 +0,0 @@ -using CalamityMod.World; -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Systems -{ - public class SkeletronPrimeMasterMusicScene : ModSceneEffect - { - public override int Music => MusicID.Boss3; // I spent 20 minutes trying to get this music to play while forgetting to actually override this in the first place _ YuH - public override SceneEffectPriority Priority => SceneEffectPriority.BossLow; - public override bool IsSceneEffectActive(Player player) => Main.masterMode && CalamityWorld.revenge && NPC.AnyNPCs(NPCID.SkeletronPrime) && Main.npc[NPC.FindFirstNPC(NPCID.SkeletronPrime)].Distance(player.Center) <= 525f * 16f; - } -} 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/Skies/SulphurSeaSky.cs b/Skies/SulphurSeaSky.cs index bd8c4f1233..6153d869e4 100644 --- a/Skies/SulphurSeaSky.cs +++ b/Skies/SulphurSeaSky.cs @@ -13,11 +13,6 @@ public class SulphurSeaSky : CustomSky private bool skyActive; private float opacity; - private const float ScreenParralaxMultiplier = 0.4f; - - // Vanila scales backgrounds to 250% size. Depending on what you might want to do you can change this if you wanted to make a non scaled bg. - private const float Scale = 2.5f; - public override void Deactivate(params object[] args) { skyActive = Main.LocalPlayer.Calamity().ZoneSulphur; @@ -42,66 +37,6 @@ public override void Draw(SpriteBatch spriteBatch, float minDepth, float maxDept { if (maxDepth >= 4f && minDepth < 4f) spriteBatch.Draw(CalamityMod.SulphurSeaSky, new Rectangle(0, (int)(-Main.screenPosition.Y / 6f) + 1300, Main.screenWidth, Main.screenHeight), Color.Lerp(Main.ColorOfTheSkies, Color.LightSeaGreen, 0.33f) * 0.2f * opacity); - - // Small worlds, default draw height - int sulphurSeaHeight = (World.SulphurousSea.YStart + (int)Main.worldSurface) / 2; - - // Medium worlds - if (Main.maxTilesX >= 6400 && Main.maxTilesX < 8400) - sulphurSeaHeight = (World.SulphurousSea.YStart + (int)Main.worldSurface) / 5; - - // Large worlds (and anything bigger) - if (Main.maxTilesX >= 8400) - sulphurSeaHeight = (World.SulphurousSea.YStart + (int)Main.worldSurface) / 140; - - // Explantion on how to use this BG code for skies. - // This changes the speed of the parralax, the closer the layer to the player the faster it should be. - if (maxDepth >= 1f && minDepth < 1f) - { - Texture2D texture = CalamityMod.SulphurSeaSkyFront; - - // Keep in mind that y paralex should always be half of x's or it will feel odd compared to how terraria does it. - // Keep in mind when you change screen parralax it affects the y offset for the bg in the world. - int x = (int)(Main.screenPosition.X * ScreenParralaxMultiplier); - x %= (int)(texture.Width * Scale); - int y = (int)(Main.screenPosition.Y * 0.5f * ScreenParralaxMultiplier); - - // Y offset to align with whatever position you want it in the world (is affected by screenParralaxMultiplier as stated before). - y -= 1800; - - float screenWidth = Main.screenWidth / 2f; - float screenHeight = Main.screenHeight / 2f; - Vector2 position = texture.Size() / 2f * Scale; - Color color = Color.LightSeaGreen * 0.5f * opacity; - - // This loops the BG horizontally. - for (int k = -1; k <= 1; k++) - { - var pos = new Vector2(screenWidth - x + texture.Width * k * Scale, screenHeight - y); - spriteBatch.Draw(texture, pos - position, null, color, 0f, new Vector2(0f, (float)sulphurSeaHeight), Scale, SpriteEffects.None, 0f); - } - } - - if (maxDepth >= 3f && minDepth < 3f) - { - Texture2D texture = CalamityMod.SulphurSeaSurface; - - int x = (int)(Main.screenPosition.X * ScreenParralaxMultiplier); - x %= (int)(texture.Width * Scale); - int y = (int)(Main.screenPosition.Y * 0.5f * ScreenParralaxMultiplier); - y -= 1800; // 1000 - - float screenWidth = Main.screenWidth / 2f; - float screenHeight = Main.screenHeight / 2f; - Vector2 position = texture.Size() / 2f * Scale; - Color color = Main.ColorOfTheSkies * opacity; - - for (int k = -1; k <= 1; k++) - { - var pos = new Vector2(screenWidth - x + texture.Width * k * Scale, screenHeight - y); - spriteBatch.Draw(texture, pos - position, null, color, 0f, new Vector2(0f, (float)sulphurSeaHeight), Scale, SpriteEffects.None, 0f); - } - } } public override void Update(GameTime gameTime) diff --git a/Sounds/Custom/BEES/Names.txt b/Sounds/Custom/BEES/Names.txt index 440c8bb183..c6fa1f7e74 100644 --- a/Sounds/Custom/BEES/Names.txt +++ b/Sounds/Custom/BEES/Names.txt @@ -6,7 +6,7 @@ Names: 5 - moonburn 6 - Ozzatron 7 - Rebecca -8 - Shayy +8 - Unused 9 - StipulatedVenus 10 - Xyk 11 - Shade \ No newline at end of file diff --git a/Sounds/Custom/BEES/bees8.ogg b/Sounds/Custom/BEES/bees8.ogg deleted file mode 100644 index 677b47fc65..0000000000 Binary files a/Sounds/Custom/BEES/bees8.ogg and /dev/null differ 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/BestiaryRegistrySystem.cs b/Systems/BestiaryRegistrySystem.cs index f14f47f6dc..bd95735428 100644 --- a/Systems/BestiaryRegistrySystem.cs +++ b/Systems/BestiaryRegistrySystem.cs @@ -14,7 +14,6 @@ public override void PostSetupContent() // Manually register variants post-initiailization ContentSamples.NpcBestiaryCreditIdsByNpcNetIds[NPCType()] = ContentSamples.NpcBestiaryCreditIdsByNpcNetIds[NPCType()]; ContentSamples.NpcBestiaryCreditIdsByNpcNetIds[NPCType()] = ContentSamples.NpcBestiaryCreditIdsByNpcNetIds[NPCType()]; - ContentSamples.NpcBestiaryCreditIdsByNpcNetIds[NPCType()] = ContentSamples.NpcBestiaryCreditIdsByNpcNetIds[NPCID.LavaSlime]; } } } diff --git a/Systems/CalamityModWaterStyle.cs b/Systems/CalamityModWaterStyle.cs new file mode 100644 index 0000000000..1f52e12850 --- /dev/null +++ b/Systems/CalamityModWaterStyle.cs @@ -0,0 +1,62 @@ +using Terraria.Graphics; +using Terraria.ModLoader; + +namespace CalamityMod.Systems +{ + public abstract class CalamityModWaterStyle : ModWaterStyle + { + /// + /// Allows water styles to manipulate what color the liquid is drawn to, this can allow waters to be see-throughable to see backgrounds (surface and underground backgrounds not walls) + /// + /// X position of the water + /// Y position of the water + /// The vertexColor of the water color, this is both used to get the current color and to set the color of the water + public virtual void DrawColor(int x, int y, ref VertexColors liquidColor, bool isSlope) + { + } + + /// + /// Allows you to determine how much light this water emits.
+ /// It can also let you light up the block in front of this water.
+ /// See for vanilla tile light values to use as a reference.
+ ///
+ /// The x position in tile coordinates. + /// The y position in tile coordinates. + /// The red component of light, usually a value between 0 and 1 + /// The green component of light, usually a value between 0 and 1 + /// The blue component of light, usually a value between 0 and 1 + public virtual void ModifyLight(int i, int j, ref float r, ref float g, ref float b) + { + } + } + + internal static class CalamityWaterLoader + { + internal static void ModifyLightSetup(int i, int j, int type, ref float r, ref float g, ref float b) + { + if (TryGetCalamityWaterStyle(type, out var styles)) + { + styles.ModifyLight(i, j, ref r, ref g, ref b); + } + } + + internal static void DrawColorSetup(int x, int y, int type, ref VertexColors liquidColor, bool isSlope = false) + { + if (TryGetCalamityWaterStyle(type, out var styles)) + { + styles.DrawColor(x, y, ref liquidColor, isSlope); + } + } + + internal static bool TryGetCalamityWaterStyle(int type, out CalamityModWaterStyle waterStyle) + { + waterStyle = GetCalamityWaterStyle(type); + return waterStyle != null; + } + + internal static CalamityModWaterStyle GetCalamityWaterStyle(int type) + { + return LoaderManager.Get().Get(type) as CalamityModWaterStyle; + } + } +} diff --git a/Systems/LavaRendering.cs b/Systems/LavaRendering.cs new file mode 100644 index 0000000000..3c595acd90 --- /dev/null +++ b/Systems/LavaRendering.cs @@ -0,0 +1,1201 @@ +using System; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.GameContent.Liquid; +using Terraria.Graphics; +using Terraria.ID; +using Terraria.ModLoader; +using static Terraria.GameContent.Liquid.LiquidRenderer; +using static Terraria.WaterfallManager; + +namespace CalamityMod.Systems +{ + public class LavaRendering : ModSystem + { + //Welcome to Calamity's lava rendering. Prepare your eyes + public static LavaRendering instance; + + internal static readonly FieldInfo _drawArea = typeof(LiquidRenderer).GetField("_drawArea", BindingFlags.NonPublic | BindingFlags.Instance); + internal static readonly FieldInfo _drawCache = typeof(LiquidRenderer).GetField("_drawCache", BindingFlags.NonPublic | BindingFlags.Instance); + internal static readonly FieldInfo _animationFrame = typeof(LiquidRenderer).GetField("_animationFrame", BindingFlags.NonPublic | BindingFlags.Instance); + + internal static readonly FieldInfo WaterfallDist = typeof(WaterfallManager).GetField("waterfallDist", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance); + internal static readonly FieldInfo Waterfalls = typeof(WaterfallManager).GetField("waterfalls", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance); + internal static readonly FieldInfo CurrentMax = typeof(WaterfallManager).GetField("currentMax", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance); + internal static readonly FieldInfo SlowFrame = typeof(WaterfallManager).GetField("slowFrame", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance); + + public override void Load() + { + instance = this; + } + + public void DrawLavas(bool isBackground = false) + { + Main.drewLava = false; + if (!isBackground) + { + CalamityMod.LavaStyle = 0; + LavaStylesLoader.IsLavaActive(); + for (int i = 0; i < 1; i++) + { + if (CalamityMod.LavaStyle != i) + { + CalamityMod.lavaAlpha[i] = Math.Max(CalamityMod.lavaAlpha[i] - 0.2f, 0f); + } + else + { + CalamityMod.lavaAlpha[i] = Math.Min(CalamityMod.lavaAlpha[i] + 0.2f, 1f); + } + } + LavaStylesLoader.UpdateLiquidAlphas(); + } + bool flag = false; + for (int j = 0; j < LavaStylesLoader.TotalCount; j++) + { + if (CalamityMod.lavaAlpha[j] > 0f && j != CalamityMod.LavaStyle) + { + DrawLiquid(isBackground, j, isBackground ? 1f : CalamityMod.lavaAlpha[j], drawSinglePassLiquids: false); + flag = true; + } + } + DrawLiquid(isBackground, CalamityMod.LavaStyle, flag ? CalamityMod.lavaAlpha[CalamityMod.LavaStyle] : 1f); + } + + protected internal void DrawLiquid(bool bg = false, int lavaStyle = 0, float Alpha = 1f, bool drawSinglePassLiquids = true) + { + if (!Lighting.NotRetro) + { + oldDrawLava(bg, lavaStyle, Alpha); + return; + } + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + Vector2 drawOffset = (Vector2)(Main.drawToScreen ? Vector2.Zero : new Vector2((float)Main.offScreenRange, (float)Main.offScreenRange)) - Main.screenPosition; + if (bg && !LiquidEdgeRenderer.Active) + { + DrawLiquidBehindTiles(lavaStyle); + } + DrawLava(Main.spriteBatch, drawOffset, lavaStyle, Alpha, bg); + if (!bg) + { + TimeLogger.DrawTime(4, stopwatch.Elapsed.TotalMilliseconds); + } + } + + public unsafe void DrawLava(SpriteBatch spriteBatch, Vector2 drawOffset, int LavaStyle, float globalAlpha, bool isBackgroundDraw) + { + Rectangle drawArea = (Rectangle)_drawArea.GetValue(Instance); + Main.tileBatch.Begin(); + fixed (LiquidDrawCache* ptr3 = &((LiquidDrawCache[])_drawCache.GetValue(Instance))[0]) + { + LiquidDrawCache* ptr2 = ptr3; + int cacheLength = ((LiquidDrawCache[])_drawCache.GetValue(Instance)).Length; + for (int i = drawArea.X; i < drawArea.X + drawArea.Width; i++) + { + for (int j = drawArea.Y; j < drawArea.Y + drawArea.Height; j++) + { + if (ptr2->IsVisible && ptr2->Type == LiquidID.Lava) + { + Rectangle sourceRectangle = ptr2->SourceRectangle; + if (ptr2->IsSurfaceLiquid) + { + sourceRectangle.Y = 1280; + } + else + { + sourceRectangle.Y += ((int)_animationFrame.GetValue(Instance)) * 80; + } + Vector2 liquidOffset = ptr2->LiquidOffset; + float num = ptr2->Opacity * (isBackgroundDraw ? 1f : DEFAULT_OPACITY[ptr2->Type]); + int num2 = LavaStyle; + num *= globalAlpha; + num = Math.Min(1f, num); + Lighting.GetCornerColors(i, j, out var vertices); + ref Color bottomLeftColor = ref vertices.BottomLeftColor; + bottomLeftColor *= num; + ref Color bottomRightColor = ref vertices.BottomRightColor; + bottomRightColor *= num; + ref Color topLeftColor = ref vertices.TopLeftColor; + topLeftColor *= num; + ref Color topRightColor = ref vertices.TopRightColor; + topRightColor *= num; + LavaStylesLoader.DrawColorSetup(i, j, CalamityMod.LavaStyle, ref vertices); + Main.DrawTileInWater(drawOffset, i, j); + Main.tileBatch.Draw(CalamityMod.LavaTextures.liquid[num2].Value, new Vector2((float)(i << 4), (float)(j << 4)) + drawOffset + liquidOffset, sourceRectangle, vertices, Vector2.Zero, 1f, (SpriteEffects)0); + } + ptr2++; + } + } + } + Main.tileBatch.End(); + } + + public void oldDrawLava(bool bg = false, int Style = 0, float Alpha = 1f) + { + float num = 0f; + float num12 = 99999f; + float num23 = 99999f; + int num27 = -1; + int num28 = -1; + Vector2 vector = new((float)Main.offScreenRange, (float)Main.offScreenRange); + if (Main.drawToScreen) + { + vector = Vector2.Zero; + } + _ = new Color[4]; + int num29 = (int)(255f * (1f - Main.gfxQuality) + 40f * Main.gfxQuality); + _ = Main.gfxQuality; + _ = Main.gfxQuality; + int num30 = (int)((Main.screenPosition.X - vector.X) / 16f - 1f); + int num31 = (int)((Main.screenPosition.X + (float)Main.screenWidth + vector.X) / 16f) + 2; + int num32 = (int)((Main.screenPosition.Y - vector.Y) / 16f - 1f); + int num2 = (int)((Main.screenPosition.Y + (float)Main.screenHeight + vector.Y) / 16f) + 5; + if (num30 < 5) + { + num30 = 5; + } + if (num31 > Main.maxTilesX - 5) + { + num31 = Main.maxTilesX - 5; + } + if (num32 < 5) + { + num32 = 5; + } + if (num2 > Main.maxTilesY - 5) + { + num2 = Main.maxTilesY - 5; + } + Vector2 vector2; + Rectangle value; + Color newColor; + for (int i = num32; i < num2 + 4; i++) + { + for (int j = num30 - 2; j < num31 + 2; j++) + { + if (Main.tile[j, i].LiquidAmount <= 0 || (Main.tile[j, i].HasUnactuatedTile && Main.tileSolid[Main.tile[j, i].TileType] && !Main.tileSolidTop[Main.tile[j, i].TileType]) || !(Lighting.Brightness(j, i) > 0f || bg) || Main.tile[j, i].LiquidType != LiquidID.Lava) + { + continue; + } + Color color = Lighting.GetColor(j, i); + float num3 = 256 - Main.tile[j, i].LiquidAmount; + num3 /= 32f; + int num4 = 0; + if (Main.tile[j, i].LiquidType == LiquidID.Lava) + { + /*if (Main.drewLava) //disallows the back liquid to not draw until its alpha hits 1f apparently + { + continue; + }*/ + float num5 = Math.Abs((float)(j * 16 + 8) - (Main.screenPosition.X + (float)(Main.screenWidth / 2))); + float num6 = Math.Abs((float)(i * 16 + 8) - (Main.screenPosition.Y + (float)(Main.screenHeight / 2))); + if (num5 < (float)(Main.screenWidth * 2) && num6 < (float)(Main.screenHeight * 2)) + { + float num7 = (float)Math.Sqrt(num5 * num5 + num6 * num6); + float num8 = 1f - num7 / ((float)Main.screenWidth * 0.75f); + if (num8 > 0f) + { + num += num8; + } + } + if (num5 < num12) + { + num12 = num5; + num27 = j * 16 + 8; + } + if (num6 < num23) + { + num23 = num5; + num28 = i * 16 + 8; + } + } + if (num4 == 0) + { + num4 = Style; + } + if (Main.drewLava) + { + continue; + } + float num9 = 0.5f; + if (bg) + { + num9 = 1f; + } + num9 *= Alpha; + Main.DrawTileInWater(-Main.screenPosition + vector, j, i); //lily pads + vector2 = new((float)(j * 16), (float)(i * 16 + (int)num3 * 2)); + value = new(0, 0, 16, 16 - (int)num3 * 2); + bool flag2 = true; + if (Main.tile[j, i + 1].LiquidAmount < 245 && (!Main.tile[j, i + 1].HasUnactuatedTile || !Main.tileSolid[Main.tile[j, i + 1].TileType] || Main.tileSolidTop[Main.tile[j, i + 1].TileType])) + { + float num10 = 256 - Main.tile[j, i + 1].LiquidAmount; + num10 /= 32f; + num9 = 0.5f * (8f - num3) / 4f; + if ((double)num9 > 0.55) + { + num9 = 0.55f; + } + if ((double)num9 < 0.35) + { + num9 = 0.35f; + } + float num11 = num3 / 2f; + if (Main.tile[j, i + 1].LiquidAmount < 200) + { + if (bg) + { + continue; + } + if (Main.tile[j, i - 1].LiquidAmount > 0 && Main.tile[j, i - 1].LiquidAmount > 0) + { + value = new(0, 4, 16, 16); + num9 = 0.5f; + } + else if (Main.tile[j, i - 1].LiquidAmount > 0) + { + vector2 = new((float)(j * 16), (float)(i * 16 + 4)); + value = new(0, 4, 16, 12); + num9 = 0.5f; + } + else if (Main.tile[j, i + 1].LiquidAmount > 0) + { + vector2 = new((float)(j * 16), (float)(i * 16 + (int)num3 * 2 + (int)num10 * 2)); + value = new(0, 4, 16, 16 - (int)num3 * 2); + } + else + { + vector2 = new((float)(j * 16 + (int)num11), (float)(i * 16 + (int)num11 * 2 + (int)num10 * 2)); + value = new(0, 4, 16 - (int)num11 * 2, 16 - (int)num11 * 2); + } + } + else + { + num9 = 0.5f; + value = new(0, 4, 16, 16 - (int)num3 * 2 + (int)num10 * 2); + } + } + else if (Main.tile[j, i - 1].LiquidAmount > 32) + { + value = new(0, 4, value.Width, value.Height); + } + else if (num3 < 1f && Main.tile[j, i - 1].HasUnactuatedTile && Main.tileSolid[Main.tile[j, i - 1].TileType] && !Main.tileSolidTop[Main.tile[j, i - 1].TileType]) + { + vector2 = new((float)(j * 16), (float)(i * 16)); + value = new(0, 4, 16, 16); + } + else + { + for (int k = i + 1; k < i + 6 && (!Main.tile[j, k].HasUnactuatedTile || !Main.tileSolid[Main.tile[j, k].TileType] || Main.tileSolidTop[Main.tile[j, k].TileType]); k++) + { + if (Main.tile[j, k].LiquidAmount < 200) + { + flag2 = false; + break; + } + } + if (!flag2) + { + num9 = 0.5f; + value = new(0, 4, 16, 16); + } + else if (Main.tile[j, i - 1].LiquidAmount > 0) + { + value = new(0, 2, value.Width, value.Height); + } + } + if ((color.R > 20 || color.B > 20 || color.G > 20) && value.Y < 4) + { + int num13 = color.R; + if (color.G > num13) + { + num13 = color.G; + } + if (color.B > num13) + { + num13 = color.B; + } + num13 /= 30; + if (Main.rand.Next(20000) < num13) + { + newColor = new(255, 255, 255); + int num14 = Dust.NewDust(new Vector2((float)(j * 16), vector2.Y - 2f), 16, 8, DustID.TintableDustLighted, 0f, 0f, 254, newColor, 0.75f); + Dust obj = Main.dust[num14]; + obj.velocity *= 0f; + } + } + if (Main.tile[j, i].LiquidType == LiquidID.Lava) + { + num9 *= 1.8f; + if (num9 > 1f) + { + num9 = 1f; + } + if (Main.instance.IsActive && !Main.gamePaused && Dust.lavaBubbles < 200) + { + if (Main.tile[j, i].LiquidAmount > 200 && Main.rand.NextBool(700)) + { + Dust.NewDust(new Vector2((float)(j * 16), (float)(i * 16)), 16, 16, dustLava()); + } + if (value.Y == 0 && Main.rand.NextBool(350)) + { + int num15 = Dust.NewDust(new Vector2((float)(j * 16), (float)(i * 16) + num3 * 2f - 8f), 16, 8, dustLava(), 0f, 0f, 50, default(Color), 1.5f); + Dust obj2 = Main.dust[num15]; + obj2.velocity *= 0.8f; + Main.dust[num15].velocity.X *= 2f; + Main.dust[num15].velocity.Y -= (float)Main.rand.Next(1, 7) * 0.1f; + if (Main.rand.NextBool(10)) + { + Main.dust[num15].velocity.Y *= Main.rand.Next(2, 5); + } + Main.dust[num15].noGravity = true; + } + } + } + float num16 = (float)(int)color.R * num9; + float num17 = (float)(int)color.G * num9; + float num18 = (float)(int)color.B * num9; + float num19 = (float)(int)color.A * num9; + color = new((int)(byte)num16, (int)(byte)num17, (int)(byte)num18, (int)(byte)num19); + if (Lighting.NotRetro && !bg) + { + Color color2 = color; + if (((double)(int)color2.R > (double)num29 * 0.6 || (double)(int)color2.G > (double)num29 * 0.65 || (double)(int)color2.B > (double)num29 * 0.7)) + { + for (int l = 0; l < 4; l++) + { + int num20 = 0; + int num21 = 0; + int width = 8; + int height = 8; + Color color3 = color2; + Color color4 = Lighting.GetColor(j, i); + if (l == 0) + { + color4 = Lighting.GetColor(j - 1, i - 1); + if (value.Height < 8) + { + height = value.Height; + } + } + if (l == 1) + { + color4 = Lighting.GetColor(j + 1, i - 1); + num20 = 8; + if (value.Height < 8) + { + height = value.Height; + } + } + if (l == 2) + { + color4 = Lighting.GetColor(j - 1, i + 1); + num21 = 8; + height = 8 - (16 - value.Height); + } + if (l == 3) + { + color4 = Lighting.GetColor(j + 1, i + 1); + num20 = 8; + num21 = 8; + height = 8 - (16 - value.Height); + } + num16 = (float)(int)color4.R * num9; + num17 = (float)(int)color4.G * num9; + num18 = (float)(int)color4.B * num9; + num19 = (float)(int)color4.A * num9; + color4 = new((int)(byte)num16, (int)(byte)num17, (int)(byte)num18, (int)(byte)num19); + color3.R = (byte)((color2.R * 3 + color4.R * 2) / 5); + color3.G = (byte)((color2.G * 3 + color4.G * 2) / 5); + color3.B = (byte)((color2.B * 3 + color4.B * 2) / 5); + color3.A = (byte)((color2.A * 3 + color4.A * 2) / 5); + Main.spriteBatch.Draw(CalamityMod.LavaTextures.block[num4].Value, vector2 - Main.screenPosition + new Vector2((float)num20, (float)num21) + vector, (Rectangle?)new Rectangle(value.X + num20, value.Y + num21, width, height), color3, 0f, default(Vector2), 1f, (SpriteEffects)0, 0f); + } + } + else + { + Main.spriteBatch.Draw(CalamityMod.LavaTextures.block[num4].Value, vector2 - Main.screenPosition + vector, (Rectangle?)value, color, 0f, default(Vector2), 1f, (SpriteEffects)0, 0f); + } + } + else + { + if (value.Y < 4) + { + value.X += (int)(Main.wFrame * 18f); + } + Main.spriteBatch.Draw(CalamityMod.LavaTextures.block[num4].Value, vector2 - Main.screenPosition + vector, (Rectangle?)value, color, 0f, default(Vector2), 1f, (SpriteEffects)0, 0f); + } + if (!Main.tile[j, i + 1].IsHalfBlock) + { + continue; + } + color = Lighting.GetColor(j, i + 1); + num16 = (float)(int)color.R * num9; + num17 = (float)(int)color.G * num9; + num18 = (float)(int)color.B * num9; + num19 = (float)(int)color.A * num9; + color = new((int)(byte)num16, (int)(byte)num17, (int)(byte)num18, (int)(byte)num19); + vector2 = new((float)(j * 16), (float)(i * 16 + 16)); + Main.spriteBatch.Draw(CalamityMod.LavaTextures.block[num4].Value, vector2 - Main.screenPosition + vector, (Rectangle?)new Rectangle(0, 4, 16, 8), color, 0f, default(Vector2), 1f, (SpriteEffects)0, 0f); + float num22 = 6f; + float num24 = 0.75f; + num22 = 4f; + num24 = 0.5f; + for (int m = 0; (float)m < num22; m++) + { + int num25 = i + 2 + m; + if (WorldGen.SolidTile(j, num25)) + { + break; + } + float num26 = 1f - (float)m / num22; + num26 *= num24; + vector2 = new((float)(j * 16), (float)(num25 * 16 - 2)); + Main.spriteBatch.Draw(CalamityMod.LavaTextures.block[num4].Value, vector2 - Main.screenPosition + vector, (Rectangle?)new Rectangle(0, 18, 16, 16), color * num26, 0f, default(Vector2), 1f, (SpriteEffects)0, 0f); + } + } + } + if (!Main.drewLava) + { + Main.ambientLavaX = num27; + Main.ambientLavaY = num28; + Main.ambientLavaStrength = num; + } + Main.drewLava = true; + } + + private void DrawLiquidBehindTiles(int lavaStyleOverride = -1) + { + Vector2 unscaledPosition = Main.Camera.UnscaledPosition; + Vector2 vector = new((float)Main.offScreenRange, (float)Main.offScreenRange); + if (Main.drawToScreen) + { + vector = Vector2.Zero; + } + GetScreenDrawArea(unscaledPosition, vector + (Main.Camera.UnscaledPosition - Main.Camera.ScaledPosition), out var firstTileX, out var lastTileX, out var firstTileY, out var lastTileY); + for (int i = firstTileY; i < lastTileY + 4; i++) + { + for (int j = firstTileX - 2; j < lastTileX + 2; j++) + { + Tile tile = Main.tile[j, i]; + if (tile != null) + { + DrawTile_LiquidBehindTile(solidLayer: false, inFrontOfPlayers: false, lavaStyleOverride, unscaledPosition, vector, j, i, tile); + } + } + } + } + + private void GetScreenDrawArea(Vector2 screenPosition, Vector2 offSet, out int firstTileX, out int lastTileX, out int firstTileY, out int lastTileY) + { + firstTileX = (int)((screenPosition.X - offSet.X) / 16f - 1f); + lastTileX = (int)((screenPosition.X + (float)Main.screenWidth + offSet.X) / 16f) + 2; + firstTileY = (int)((screenPosition.Y - offSet.Y) / 16f - 1f); + lastTileY = (int)((screenPosition.Y + (float)Main.screenHeight + offSet.Y) / 16f) + 5; + if (firstTileX < 4) + { + firstTileX = 4; + } + if (lastTileX > Main.maxTilesX - 4) + { + lastTileX = Main.maxTilesX - 4; + } + if (firstTileY < 4) + { + firstTileY = 4; + } + if (lastTileY > Main.maxTilesY - 4) + { + lastTileY = Main.maxTilesY - 4; + } + if (Main.sectionManager.AnyUnfinishedSections) + { + TimeLogger.DetailedDrawReset(); + WorldGen.SectionTileFrameWithCheck(firstTileX, firstTileY, lastTileX, lastTileY); + TimeLogger.DetailedDrawTime(5); + } + if (Main.sectionManager.AnyNeedRefresh) + { + WorldGen.RefreshSections(firstTileX, firstTileY, lastTileX, lastTileY); + } + } + + public void DrawTile_LiquidBehindTile(bool solidLayer, bool inFrontOfPlayers, int waterStyleOverride, Vector2 screenPosition, Vector2 screenOffset, int tileX, int tileY, Tile tileCache) + { + Tile tile = Main.tile[tileX + 1, tileY]; + Tile tile2 = Main.tile[tileX - 1, tileY]; + Tile tile3 = Main.tile[tileX, tileY - 1]; + Tile tile4 = Main.tile[tileX, tileY + 1]; + if ((tileCache.LiquidType != LiquidID.Lava && tile.LiquidType != LiquidID.Lava && tile2.LiquidType != LiquidID.Lava && tile3.LiquidType != LiquidID.Lava && tile4.LiquidType != LiquidID.Lava)) + { + return; + } + //bool[] _tileSolidTop = (bool[])typeof(TileDrawing).GetField("_tileSolidTop", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance).GetValue(null); + if (!tileCache.HasTile || tileCache.IsActuated /*|| _tileSolidTop[tileCache.TileType]*/ || (tileCache.IsHalfBlock && (tile2.LiquidAmount > 160 || tile.LiquidAmount > 160) && Main.instance.waterfallManager.CheckForWaterfall(tileX, tileY)) || (TileID.Sets.BlocksWaterDrawingBehindSelf[tileCache.TileType] && tileCache.Slope == 0)) + { + return; + } + int num = 0; + bool flag = false; + bool flag2 = false; + bool flag3 = false; + bool flag4 = false; + bool flag5 = false; + int num2 = 0; + bool flag6 = true; + int num3 = (int)tileCache.Slope; + int num4 = (int)tileCache.BlockType; + if (tileCache.TileType == 546 && tileCache.LiquidAmount > 0) + { + flag5 = true; + flag4 = true; + flag = true; + flag2 = true; + num = tileCache.LiquidAmount; + } + else + { + if (tileCache.LiquidAmount > 0 && num4 != 0 && (num4 != 1 || tileCache.LiquidAmount > 160)) + { + flag5 = true; + if (tileCache.LiquidAmount > num) + { + num = tileCache.LiquidAmount; + } + } + if (tile2.LiquidAmount > 0 && num3 != 1 && num3 != 3) + { + flag = true; + if (tile2.LiquidAmount > num) + { + num = tile2.LiquidAmount; + } + } + if (tile.LiquidAmount > 0 && num3 != 2 && num3 != 4) + { + flag2 = true; + if (tile.LiquidAmount > num) + { + num = tile.LiquidAmount; + } + } + if (tile3.LiquidAmount > 0 && num3 != 3 && num3 != 4) + { + flag3 = true; + } + if (tile4.LiquidAmount > 0 && num3 != 1 && num3 != 2) + { + if (tile4.LiquidAmount > 240) + { + flag4 = true; + } + } + } + if (!flag3 && !flag4 && !flag && !flag2 && !flag5) + { + return; + } + if (waterStyleOverride != -1) + { + CalamityMod.LavaStyle = waterStyleOverride; + } + if (num2 == 0) + { + num2 = CalamityMod.LavaStyle; + } + Lighting.GetCornerColors(tileX, tileY, out var vertices); + Vector2 vector = new((float)(tileX * 16), (float)(tileY * 16)); + Rectangle liquidSize = new(0, 4, 16, 16); + if (flag4 && (flag || flag2)) + { + flag = true; + flag2 = true; + } + if (tileCache.HasTile && (Main.tileSolidTop[tileCache.TileType] || !Main.tileSolid[tileCache.TileType])) + { + return; + } + if ((!flag3 || !(flag || flag2)) && !(flag4 && flag3)) + { + if (flag3) + { + liquidSize = new(0, 4, 16, 4); + if (tileCache.IsHalfBlock || tileCache.Slope != 0) + { + liquidSize = new(0, 4, 16, 12); + } + } + else if (flag4 && !flag && !flag2) + { + vector = new((float)(tileX * 16), (float)(tileY * 16 + 12)); + liquidSize = new(0, 4, 16, 4); + } + else + { + float num8 = (float)(256 - num) / 32f; + int y = 4; + if (tile3.LiquidAmount == 0 && (num4 != 0 || !WorldGen.SolidTile(tileX, tileY - 1))) + { + y = 0; + } + int num5 = (int)num8 * 2; + if (tileCache.Slope != 0) + { + vector = new((float)(tileX * 16), (float)(tileY * 16 + num5)); + liquidSize = new(0, num5, 16, 16 - num5); + } + else if ((flag && flag2) || tileCache.IsHalfBlock) + { + vector = new((float)(tileX * 16), (float)(tileY * 16 + num5)); + liquidSize = new(0, y, 16, 16 - num5); + } + else if (flag) + { + vector = new((float)(tileX * 16), (float)(tileY * 16 + num5)); + liquidSize = new(0, y, 4, 16 - num5); + } + else + { + vector = new((float)(tileX * 16 + 12), (float)(tileY * 16 + num5)); + liquidSize = new(0, y, 4, 16 - num5); + } + } + } + Vector2 position = vector - screenPosition + screenOffset; + float num6 = 1f; + if ((double)tileY <= Main.worldSurface || num6 > 1f) + { + num6 = 1f; + if (tileCache.WallType == 21) + { + num6 = 0.9f; + } + else if (tileCache.WallType > 0) + { + num6 = 0.6f; + } + } + if (tileCache.IsHalfBlock && tile3.LiquidAmount > 0 && tileCache.WallType > 0) + { + num6 = 0f; + } + if (num3 == 4 && tile2.LiquidAmount == 0 && !WorldGen.SolidTile(tileX - 1, tileY)) + { + num6 = 0f; + } + if (num3 == 3 && tile.LiquidAmount == 0 && !WorldGen.SolidTile(tileX + 1, tileY)) + { + num6 = 0f; + } + ref Color bottomLeftColor = ref vertices.BottomLeftColor; + bottomLeftColor *= num6; + ref Color bottomRightColor = ref vertices.BottomRightColor; + bottomRightColor *= num6; + ref Color topLeftColor = ref vertices.TopLeftColor; + topLeftColor *= num6; + ref Color topRightColor = ref vertices.TopRightColor; + topRightColor *= num6; + bool flag7 = false; + LavaStylesLoader.DrawColorSetup(tileX, tileY, CalamityMod.LavaStyle, ref vertices); + for (int i = 0; i < LavaStylesLoader.TotalCount; i++) + { + if (CalamityMod.lavaAlpha[i] > 0f && i != num2) + { + DrawPartialLiquid(!solidLayer, tileCache, ref position, ref liquidSize, i, ref vertices); + flag7 = true; + break; + } + } + VertexColors colors = vertices; + float num7 = (flag7 ? CalamityMod.lavaAlpha[num2] : 1f); + ref Color bottomLeftColor2 = ref colors.BottomLeftColor; + bottomLeftColor2 *= num7; + ref Color bottomRightColor2 = ref colors.BottomRightColor; + bottomRightColor2 *= num7; + ref Color topLeftColor2 = ref colors.TopLeftColor; + topLeftColor2 *= num7; + ref Color topRightColor2 = ref colors.TopRightColor; + topRightColor2 *= num7; + LavaStylesLoader.DrawColorSetup(tileX, tileY, CalamityMod.LavaStyle, ref colors); + DrawPartialLiquid(!solidLayer, tileCache, ref position, ref liquidSize, num2, ref colors); + } + + private void DrawPartialLiquid(bool behindBlocks, Tile tileCache, ref Vector2 position, ref Rectangle liquidSize, int liquidType, ref VertexColors colors) + { + int num = (int)tileCache.Slope; + bool flag = !TileID.Sets.BlocksWaterDrawingBehindSelf[tileCache.TileType]; + if (!behindBlocks) + { + flag = false; + } + if (flag || num == 0) + { + Main.tileBatch.Draw(CalamityMod.LavaTextures.block[liquidType].Value, position, liquidSize, colors, default(Vector2), 1f, (SpriteEffects)0); + return; + } + liquidSize.X += 18 * (num - 1); + switch (num) + { + case 1: + Main.tileBatch.Draw(CalamityMod.LavaTextures.slope[liquidType].Value, position, liquidSize, colors, Vector2.Zero, 1f, (SpriteEffects)0); + break; + case 2: + Main.tileBatch.Draw(CalamityMod.LavaTextures.slope[liquidType].Value, position, liquidSize, colors, Vector2.Zero, 1f, (SpriteEffects)0); + break; + case 3: + Main.tileBatch.Draw(CalamityMod.LavaTextures.slope[liquidType].Value, position, liquidSize, colors, Vector2.Zero, 1f, (SpriteEffects)0); + break; + case 4: + Main.tileBatch.Draw(CalamityMod.LavaTextures.slope[liquidType].Value, position, liquidSize, colors, Vector2.Zero, 1f, (SpriteEffects)0); + break; + } + } + + public void InitialDrawLavafall(WaterfallManager waterfallManager) + { + for (int i = 0; i < LavaStylesLoader.TotalCount; i++) + { + if (CalamityMod.lavaAlpha[i] > 0f) + { + DrawLavafall(waterfallManager, i, CalamityMod.lavaAlpha[i]); + } + } + } + + internal void DrawLavafall(WaterfallManager waterfallManager, int Style = 0, float Alpha = 1f) + { + int waterfallDist = (int)WaterfallDist.GetValue(waterfallManager); + WaterfallData[] waterfalls = (WaterfallData[])Waterfalls.GetValue(waterfallManager); + int currentMax = (int)CurrentMax.GetValue(waterfallManager); + int slowFrame = (int)SlowFrame.GetValue(waterfallManager); + Main.tileSolid[546] = false; + float num = 0f; + float num12 = 99999f; + float num23 = 99999f; + int num34 = -1; + int num45 = -1; + float num47 = 0f; + int num50 = -1; + int num2 = -1; + for (int i = 0; i < currentMax; i++) + { + if (waterfalls[i].type != 1) + { + continue; + } + int num3 = 0; + int num4 = Style; + int num5 = waterfalls[i].x; + int num6 = waterfalls[i].y; + int num7 = 0; + int num8 = 0; + int num9 = 0; + int num10 = 0; + int num11 = 0; + int num13 = 0; + int num14; + int num15; + if (waterfalls[i].stopAtStep == 0) + { + continue; + } + num14 = 32 * slowFrame; + int num22 = 0; + num15 = waterfallDist; + Color color4 = Color.White; + for (int k = 0; k < num15; k++) + { + if (num22 >= 2) + { + break; + } + typeof(WaterfallManager).GetMethod("AddLight", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static).Invoke(null, new object[] { 1, num5, num6 }); + Tile tile3 = Main.tile[num5, num6]; + if (tile3.HasUnactuatedTile && Main.tileSolid[tile3.TileType] && !Main.tileSolidTop[tile3.TileType] && !TileID.Sets.Platforms[tile3.TileType] && tile3.BlockType == 0) + { + break; + } + Tile tile4 = Main.tile[num5 - 1, num6]; + Tile tile5 = Main.tile[num5, num6 + 1]; + Tile tile6 = Main.tile[num5 + 1, num6]; + if (WorldGen.SolidTile(tile5) && !tile3.IsHalfBlock) + { + num3 = 8; + } + else if (num8 != 0) + { + num3 = 0; + } + int num24 = 0; + int num25 = num10; + int num26 = 0; + int num27 = 0; + bool flag2 = false; + if (tile5.TopSlope && !tile3.IsHalfBlock && tile5.TileType != 19) + { + flag2 = true; + if (tile5.Slope == (SlopeType)1) + { + num24 = 1; + num26 = 1; + num9 = 1; + num10 = num9; + } + else + { + num24 = -1; + num26 = -1; + num9 = -1; + num10 = num9; + } + num27 = 1; + } + else if ((!WorldGen.SolidTile(tile5) && !tile5.BottomSlope && !tile3.IsHalfBlock) || (!tile5.HasTile && !tile3.IsHalfBlock)) + { + num22 = 0; + num27 = 1; + num26 = 0; + } + else if ((WorldGen.SolidTile(tile4) || tile4.TopSlope || tile4.LiquidAmount > 0) && !WorldGen.SolidTile(tile6) && tile6.LiquidAmount == 0) + { + if (num9 == -1) + { + num22++; + } + num26 = 1; + num27 = 0; + num9 = 1; + } + else if ((WorldGen.SolidTile(tile6) || tile6.TopSlope || tile6.LiquidAmount > 0) && !WorldGen.SolidTile(tile4) && tile4.LiquidAmount == 0) + { + if (num9 == 1) + { + num22++; + } + num26 = -1; + num27 = 0; + num9 = -1; + } + else if (((!WorldGen.SolidTile(tile6) && !tile3.TopSlope) || tile6.LiquidAmount == 0) && !WorldGen.SolidTile(tile4) && !tile3.TopSlope && tile4.LiquidAmount == 0) + { + num27 = 0; + num26 = num9; + } + else + { + num22++; + num27 = 0; + num26 = 0; + } + if (num22 >= 2) + { + num9 *= -1; + num26 *= -1; + } + Color color5 = Lighting.GetColor(num5, num6); + if (k > 50) + { + typeof(WaterfallManager).GetMethod("TrySparkling", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static).Invoke(null, new object[] { num5, num6, num9, color5 }); + } + float alpha = GetLavafallAlpha(Alpha, num15, num6, k, tile3); + color5 = (Color)typeof(WaterfallManager).GetMethod("StylizeColor", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static).Invoke(null, new object[] { alpha, num15, 1, num6, k, tile3, color5 }); + float num33 = Math.Abs((float)(num5 * 16 + 8) - (Main.screenPosition.X + (float)(Main.screenWidth / 2))); + float num35 = Math.Abs((float)(num6 * 16 + 8) - (Main.screenPosition.Y + (float)(Main.screenHeight / 2))); + if (num33 < (float)(Main.screenWidth * 2) && num35 < (float)(Main.screenHeight * 2)) + { + float num36 = (float)Math.Sqrt(num33 * num33 + num35 * num35); + float num37 = 1f - num36 / ((float)Main.screenWidth * 0.75f); + if (num37 > 0f) + { + num += num37; + } + } + if (num33 < num12) + { + num12 = num33; + num34 = num5 * 16 + 8; + } + if (num35 < num23) + { + num23 = num33; + num45 = num6 * 16 + 8; + } + int num38 = tile3.LiquidAmount / 16; + if (flag2 && num9 != num25) + { + int num39 = 2; + if (num25 == 1) + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16 - 16), (float)(num6 * 16 + 16 - num39)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38 - num39), color5, (SpriteEffects)1); + } + else + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16 + 16 - num39)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38 - num39), color5, (SpriteEffects)0); + } + } + if (num7 == 0 && num24 != 0 && num8 == 1 && num9 != num10) + { + num24 = 0; + num9 = num10; + color5 = Color.White; + if (num9 == 1) + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16 - 16), (float)(num6 * 16 + 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38), color5, (SpriteEffects)1); + } + else + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16 - 16), (float)(num6 * 16 + 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38), color5, (SpriteEffects)1); + } + } + if (num11 != 0 && num26 == 0 && num27 == 1) + { + if (num9 == 1) + { + if (num13 != num4) + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16 + num3 + 8)) - Main.screenPosition, new Rectangle(num14, 0, 16, 16 - num38 - 8), color4, (SpriteEffects)1); + } + else + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16 + num3 + 8)) - Main.screenPosition, new Rectangle(num14, 0, 16, 16 - num38 - 8), color5, (SpriteEffects)1); + } + } + else + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16 + num3 + 8)) - Main.screenPosition, new Rectangle(num14, 0, 16, 16 - num38 - 8), color5, (SpriteEffects)0); + } + } + if (num3 == 8 && num8 == 1 && num11 == 0) + { + if (num10 == -1) + { + if (num13 != num4) + { + DrawLavafall(num13, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 8), color4, (SpriteEffects)0); + } + else + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 8), color5, (SpriteEffects)0); + } + } + else if (num13 != num4) + { + DrawLavafall(num13, num5, num6, alpha, new Vector2((float)(num5 * 16 - 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 8), color4, (SpriteEffects)1); + } + else + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16 - 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 8), color5, (SpriteEffects)1); + } + } + if (num24 != 0 && num7 == 0) + { + if (num25 == 1) + { + if (num13 != num4) + { + DrawLavafall(num13, num5, num6, alpha, new Vector2((float)(num5 * 16 - 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38), color4, (SpriteEffects)1); + } + else + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16 - 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38), color5, (SpriteEffects)1); + } + } + else if (num13 != num4) + { + DrawLavafall(num13, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38), color4, (SpriteEffects)0); + } + else + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38), color5, (SpriteEffects)0); + } + } + if (num27 == 1 && num24 == 0 && num11 == 0) + { + if (num9 == -1) + { + if (num8 == 0) + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16 + num3)) - Main.screenPosition, new Rectangle(num14, 0, 16, 16 - num38), color5, (SpriteEffects)0); + } + else if (num13 != num4) + { + DrawLavafall(num13, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38), color4, (SpriteEffects)0); + } + else + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38), color5, (SpriteEffects)0); + } + } + else if (num8 == 0) + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16 + num3)) - Main.screenPosition, new Rectangle(num14, 0, 16, 16 - num38), color5, (SpriteEffects)1); + } + else if (num13 != num4) + { + DrawLavafall(num13, num5, num6, alpha, new Vector2((float)(num5 * 16 - 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38), color4, (SpriteEffects)1); + } + else + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16 - 16), (float)(num6 * 16)) - Main.screenPosition, new Rectangle(num14, 24, 32, 16 - num38), color5, (SpriteEffects)1); + } + } + else + { + switch (num26) + { + case 1: + if (Main.tile[num5, num6].LiquidAmount > 0 && !Main.tile[num5, num6].IsHalfBlock) + { + break; + } + if (num24 == 1) + { + for (int m = 0; m < 8; m++) + { + int num43 = m * 2; + int num44 = 14 - m * 2; + int num46 = num43; + num3 = 8; + if (num7 == 0 && m < 2) + { + num46 = 4; + } + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16 + num43), (float)(num6 * 16 + num3 + num46)) - Main.screenPosition, new Rectangle(16 + num14 + num44, 0, 2, 16 - num3), color5, (SpriteEffects)1); + } + } + else + { + int height2 = 16; + if (TileID.Sets.BlocksWaterDrawingBehindSelf[Main.tile[num5, num6].TileType]) + { + height2 = 8; + } + else if (TileID.Sets.BlocksWaterDrawingBehindSelf[Main.tile[num5, num6 + 1].TileType]) + { + height2 = 8; + } + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16 + num3)) - Main.screenPosition, new Rectangle(16 + num14, 0, 16, height2), color5, (SpriteEffects)1); + } + break; + case -1: + if (Main.tile[num5, num6].LiquidAmount > 0 && !Main.tile[num5, num6].IsHalfBlock) + { + break; + } + if (num24 == -1) + { + for (int l = 0; l < 8; l++) + { + int num40 = l * 2; + int num41 = l * 2; + int num42 = 14 - l * 2; + num3 = 8; + if (num7 == 0 && l > 5) + { + num42 = 4; + } + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16 + num40), (float)(num6 * 16 + num3 + num42)) - Main.screenPosition, new Rectangle(16 + num14 + num41, 0, 2, 16 - num3), color5, (SpriteEffects)1); + } + } + else + { + int height = 16; + if (TileID.Sets.BlocksWaterDrawingBehindSelf[Main.tile[num5, num6].TileType]) + { + height = 8; + } + else if (TileID.Sets.BlocksWaterDrawingBehindSelf[Main.tile[num5, num6 + 1].TileType]) + { + height = 8; + } + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16 + num3)) - Main.screenPosition, new Rectangle(16 + num14, 0, 16, height), color5, (SpriteEffects)0); + } + break; + case 0: + if (num27 == 0) + { + if (Main.tile[num5, num6].LiquidAmount <= 0 || Main.tile[num5, num6].IsHalfBlock) + { + DrawLavafall(num4, num5, num6, alpha, new Vector2((float)(num5 * 16), (float)(num6 * 16 + num3)) - Main.screenPosition, new Rectangle(16 + num14, 0, 16, 16), color5, (SpriteEffects)0); + } + k = 1000; + } + break; + } + } + if (tile3.LiquidAmount > 0 && !tile3.IsHalfBlock) + { + k = 1000; + } + num8 = num27; + num10 = num9; + num7 = num26; + num5 += num26; + num6 += num27; + num11 = num24; + color4 = color5; + if (num13 != num4) + { + num13 = num4; + } + if ((tile4.HasTile && (tile4.TileType == 189 || tile4.TileType == 196)) || (tile6.HasTile && (tile6.TileType == 189 || tile6.TileType == 196)) || (tile5.HasTile && (tile5.TileType == 189 || tile5.TileType == 196))) + { + num15 = (int)(40f * ((float)Main.maxTilesX / 4200f) * Main.gfxQuality); + } + } + } + Main.ambientWaterfallX = num34; + Main.ambientWaterfallY = num45; + Main.ambientWaterfallStrength = num; + Main.ambientLavafallX = num50; + Main.ambientLavafallY = num2; + Main.ambientLavafallStrength = num47; + Main.tileSolid[546] = true; + } + + private void DrawLavafall(int waterfallType, int x, int y, float opacity, Vector2 position, Rectangle sourceRect, Color color, SpriteEffects effects) + { + Texture2D value = CalamityMod.LavaTextures.fall[waterfallType].Value; + Main.spriteBatch.Draw(value, position, (Rectangle?)sourceRect, Lighting.GetColor(x, y) * opacity, 0f, default(Vector2), 1f, effects, 0f); + } + + private static float GetLavafallAlpha(float Alpha, int maxSteps, int y, int s, Tile tileCache) + { + float num = (tileCache.WallType != 0 || !((double)y < Main.worldSurface)) ? (1f * Alpha) : Alpha; + if (s > maxSteps - 10) + { + num *= (float)(maxSteps - s) / 10f; + } + return num; + } + + public static int dustLava() + { + if (CalamityMod.LavaStyle >= 1) + { + return LavaStylesLoader.Get(CalamityMod.LavaStyle).GetSplashDust(); + } + else + { + return DustID.Lava; + } + } + + //just better as a method rather than hardcoded type values + public static int goreLava() + { + if (CalamityMod.LavaStyle >= 1) + { + return LavaStylesLoader.Get(CalamityMod.LavaStyle).GetDropletGore(); + } + else + { + return GoreID.LavaDrip; + } + } + } +} diff --git a/Systems/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/ModLavaStyle.cs b/Systems/ModLavaStyle.cs new file mode 100644 index 0000000000..b1d52e2919 --- /dev/null +++ b/Systems/ModLavaStyle.cs @@ -0,0 +1,240 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework.Graphics; +using ReLogic.Content; +using Terraria; +using Terraria.Graphics; +using Terraria.ID; +using Terraria.ModLoader; + +namespace CalamityMod.Systems +{ + public abstract class ModLavaStyle : ModTexturedType + { + /// + /// The ID of the lava style. + /// + public int Slot { get; private set; } = -1; + + public override string Name => base.Name; + + public override string Texture => base.Texture; + + public virtual string BlockTexture => Texture + "_Block"; + + public virtual string SlopeTexture => Texture + "_Slope"; + + public virtual string WaterfallTexture => Texture + "_Waterfall"; + + protected sealed override void Register() + { + Slot = LavaStylesLoader.Register(this); + } + + public sealed override void SetupContent() + { + SetStaticDefaults(); + } + + /// + /// Allows you to determine how much light this lava emits.
+ /// It can also let you light up the block in front of this lava.
+ /// Keep in mind this also effects what color the lavafalls emit
+ /// See for vanilla tile light values to use as a reference.
+ ///
+ /// The x position in tile coordinates. + /// The y position in tile coordinates. + /// The red component of light, usually a value between 0 and 1 + /// The green component of light, usually a value between 0 and 1 + /// The blue component of light, usually a value between 0 and 1 + public virtual void ModifyLight(int i, int j, ref float r, ref float g, ref float b) + { + r = 0.55f; + g = 0.33f; + b = 0.11f; + } + + /// + /// Allows water styles to manipulate what color the liquid is drawn to, this can allow waters to be see-throughable to see backgrounds (surface and underground backgrounds not walls) + /// + /// X position of the water + /// Y position of the water + /// The vertexColor of the water color, this is both used to get the current color and to set the color of the water + public virtual void DrawColor(int x, int y, ref VertexColors liquidColor, bool isSlope) + { + } + + /// + /// The ID of the dust that is created when anything splashes in lava. + /// + public virtual int GetSplashDust() + { + return DustID.Lava; + } + + /// + /// The ID of the gore that represents droplets of lava falling down from a block. Return (or another existing droplet gore). + /// + public virtual int GetDropletGore() + { + return GoreID.LavaDrip; + } + + /// + /// Return true if the player is in the correct zone to activate the lava. + /// + /// + public virtual bool IsLavaActive() + { + return false; + } + + /// + /// Return false if the waterfall made by the lavastyle should have a glowmask + /// + /// + public virtual bool LavafallGlowmask() + { + return true; + } + + /// + /// Allows your lavastyle to inflict debuffs to Players and NPCs when they enter your lava style + /// + /// The Player that is inflicted with the debuff apon entering the lavastyle + /// The duration of the OnFire! debuff. This allows for easy replacement of OnFire + public virtual void InflictDebuff(Player player, int onfireDuration) + { + } + } + + public class LavaStylesLoader : ModSystem + { + private static readonly List _content = []; + + public static IReadOnlyList Content => _content; + + public static int VanillaCount => 1; + + public static int ModCount => _content.Count; + + public static int TotalCount => VanillaCount + ModCount; + + public override void ResizeArrays() + { + int totalCount = TotalCount; + Array.Resize(ref CalamityMod.LavaTextures.liquid, totalCount); + Array.Resize(ref CalamityMod.LavaTextures.block, totalCount); + Array.Resize(ref CalamityMod.LavaTextures.slope, totalCount); + Array.Resize(ref CalamityMod.LavaTextures.fall, totalCount); + Array.Resize(ref CalamityMod.lavaAlpha, totalCount); + } + + public override void PostSetupContent() + { + foreach (ModLavaStyle item in Content) + { + int Slot = item.Slot; + CalamityMod.LavaTextures.liquid[Slot] = ModContent.Request(item.Texture, (AssetRequestMode)2); + CalamityMod.LavaTextures.block[Slot] = ModContent.Request(item.BlockTexture, (AssetRequestMode)2); + CalamityMod.LavaTextures.slope[Slot] = ModContent.Request(item.SlopeTexture, (AssetRequestMode)2); + CalamityMod.LavaTextures.fall[Slot] = ModContent.Request(item.WaterfallTexture, (AssetRequestMode)2); + } + } + + public static ModLavaStyle Get(int type) + { + type -= VanillaCount; + return type >= 0 && type < _content.Count ? _content[type] : null; + } + + internal static int Register(ModLavaStyle instance) + { + int type = TotalCount; + ModTypeLookup.Register(instance); + _content.Add(instance); + return type; + } + + private delegate void ResizeArray_orig(bool unloading); + + public static void UpdateLiquidAlphas() + { + if (CalamityMod.LavaStyle >= VanillaCount) + { + for (int i = 0; i < VanillaCount; i++) + { + CalamityMod.lavaAlpha[i] -= 0.2f; + if (CalamityMod.lavaAlpha[i] < 0f) + { + CalamityMod.lavaAlpha[i] = 0f; + } + } + } + foreach (ModLavaStyle item in Content) + { + int type = item.Slot; + if (CalamityMod.LavaStyle == type) + { + CalamityMod.lavaAlpha[type] += 0.2f; + if (CalamityMod.lavaAlpha[type] > 1f) + { + CalamityMod.lavaAlpha[type] = 1f; + } + } + else + { + CalamityMod.lavaAlpha[type] -= 0.2f; + if (CalamityMod.lavaAlpha[type] < 0f) + { + CalamityMod.lavaAlpha[type] = 0f; + } + } + } + } + + public static void ModifyLightSetup(int i, int j, int style, ref float r, ref float g, ref float b) + { + ModLavaStyle lavaStyle = Get(style); + if (lavaStyle != null) + { + lavaStyle?.ModifyLight(i, j, ref r, ref g, ref b); + } + } + + internal static void DrawColorSetup(int x, int y, int type, ref VertexColors liquidColor, bool isSlope = false) + { + ModLavaStyle styles = Get(type); + if (styles != null) + { + styles?.DrawColor(x, y, ref liquidColor, isSlope); + } + } + + public static void InflictDebuff(Player player, int type, int onfireDuration) + { + ModLavaStyle lavaStyle = Get(type); + if (lavaStyle != null) + { + lavaStyle?.InflictDebuff(player, onfireDuration); + } + } + + public static void IsLavaActive() + { + foreach (ModLavaStyle item in Content) + { + int type = item.Slot; + ModLavaStyle lavaStyle = Get(type); + if (lavaStyle != null) + { + bool? flag = lavaStyle?.IsLavaActive(); + if (flag != null && flag == true) + { + CalamityMod.LavaStyle = lavaStyle.Slot; + } + } + } + } + } +} diff --git a/Systems/MusicEventSystem.cs b/Systems/MusicEventSystem.cs index 803a27df18..6d38337ac7 100644 --- a/Systems/MusicEventSystem.cs +++ b/Systems/MusicEventSystem.cs @@ -52,20 +52,20 @@ static void AddEntry(string eventId, string songName, TimeSpan length, Func DownedBossSystem.downedCalamitasClone, () => CalamityConfig.Instance.Interlude1); + () => DownedBossSystem.downedCalamitasClone, () => CalamityClientConfig.Instance.Interludes); AddEntry("MLDefeated", "Interlude2", TimeSpan.FromSeconds(191.912d), () => NPC.downedMoonlord, - () => CalamityConfig.Instance.Interlude2, outroSilence: TimeSpan.FromSeconds(1f)); + () => CalamityClientConfig.Instance.Interludes, outroSilence: TimeSpan.FromSeconds(1f)); // Alternative Interlude 2 -> AddEntry("MLDefeated", "Interlude2_CutIntro", TimeSpan.FromSeconds(160.989d), // () => NPC.downedMoonlord, () => CalamityConfig.Instance.Interlude2, // outroSilence: TimeSpan.FromSeconds(1f)); AddEntry("YharonDefeated", "Interlude3", TimeSpan.FromSeconds(295.932d), - () => DownedBossSystem.downedYharon, () => CalamityConfig.Instance.Interlude3); + () => DownedBossSystem.downedYharon, () => CalamityClientConfig.Instance.Interludes); AddEntry("DoGDefeated", "DevourerofGodsEulogy", TimeSpan.FromSeconds(203.620d), - () => DownedBossSystem.downedDoG, () => CalamityConfig.Instance.DevourerofGodsEulogy, + () => DownedBossSystem.downedDoG, () => CalamityClientConfig.Instance.DevourerofGodsEulogy, introSilence: TimeSpan.FromSeconds(7.5f)); // Acceptance is NOT toggleable in the config diff --git a/Systems/NerfExpertDebuffsSystem.cs b/Systems/NerfExpertDebuffsSystem.cs index 49a6da275c..67ea9cdaaa 100644 --- a/Systems/NerfExpertDebuffsSystem.cs +++ b/Systems/NerfExpertDebuffsSystem.cs @@ -10,7 +10,7 @@ public class NerfExpertDebuffsSystem : ModSystem public override void PostUpdateTime() { // Reduce the expert+ debuff time multiplier to the normal mode multiplier - if (CalamityConfig.Instance.NerfExpertDebuffs) + if (CalamityServerConfig.Instance.NerfExpertDebuffs) { var copy = Main.RegisteredGameModes[GameModeID.Expert]; copy.DebuffTimeMultiplier = 1f; diff --git a/Systems/TilePingerSystem.cs b/Systems/TilePingerSystem.cs index f28c9cb3b1..b134b0f481 100644 --- a/Systems/TilePingerSystem.cs +++ b/Systems/TilePingerSystem.cs @@ -6,6 +6,7 @@ using Terraria; using Terraria.Audio; using Terraria.DataStructures; +using Terraria.GameContent.Drawing; using Terraria.Graphics.Effects; using Terraria.Graphics.Light; using Terraria.ID; @@ -83,6 +84,8 @@ public override void Load() pingedTiles = new Dictionary>(); pingedNonSolidTiles = new Dictionary>(); tileEffects = new Dictionary(); + + On_TileDrawing.DrawTiles_GetLightOverride += ForceSufficientLight; } public override void Unload() @@ -93,6 +96,42 @@ public override void Unload() tileEffects = null; } + private static Color ForceSufficientLight(On_TileDrawing.orig_DrawTiles_GetLightOverride orig, TileDrawing self, int j, int i, Tile tileCache, ushort typeCache, short tileFrameX, short tileFrameY, Color tileLight) + { + Color returnColor = orig(self, j, i, tileCache, typeCache, tileFrameX, tileFrameY, tileLight); + foreach (IPingedTileEffect effect in tileEffects.Values) + { + // Nothing else uses this so like should be okay + if (effect is WulfrumPingTileEffect w && effect.Active && effect.ShouldRegisterTile(i, j)) + { + float distanceFromCenter = (new Point(i, j).ToWorldCoordinates() - WulfrumPingTileEffect.PingCenter).Length(); + float currentExpansion = MathHelper.Clamp(WulfrumPingTileEffect.PingProgress * WulfrumPingTileEffect.MaxPingLife / (float)WulfrumPingTileEffect.MaxPingTravelTime, 0f, 1f) * WulfrumPingTileEffect.MaxPingRadius; + + if (distanceFromCenter - 8 > currentExpansion) + return returnColor; + + float brightness = 1f; + Tile tile = Framing.GetTileSafely(i, j); + //Counteracts slopes and half tiles being too bright + if (tile.Slope != SlopeType.Solid || tile.IsHalfBlock) + brightness = 0.64f; + + //Fade on the edges + if (distanceFromCenter + 8 > currentExpansion) + brightness *= 1 - (distanceFromCenter - currentExpansion + 8f) / 16f; + + //Fade away with the effect + brightness *= 1 - Math.Max(WulfrumPingTileEffect.PingProgress - 0.9f, 0) / (0.1f); + + if (tileLight.R < 200 * brightness) tileLight.R = (byte)(200 * brightness); + if (tileLight.G < 200 * brightness) tileLight.G = (byte)(200 * brightness); + if (tileLight.B < 200 * brightness) tileLight.B = (byte)(200 * brightness); + returnColor = tileLight; + } + } + return returnColor; + } + public static bool AddPing(string effectName, Vector2 position, Player pinger) { if (!Main.dedServ) @@ -231,11 +270,11 @@ public override void DrawEffects(int i, int j, int type, SpriteBatch spriteBatch public class WulfrumPingTileEffect : IPingedTileEffect, ILoadable { internal static Texture2D emptyFrame; - const int MaxPingLife = 350; - const int MaxPingTravelTime = 60; + public const int MaxPingLife = 350; + public const int MaxPingTravelTime = 60; const float PingWaveThickness = 50f; - const float MaxPingRadius = 1700f; + public const float MaxPingRadius = 1700f; public static Vector2 PingCenter = Vector2.Zero; public static int PingTimer = 0; public static float PingProgress => (MaxPingLife - PingTimer) / (float)MaxPingLife; @@ -316,7 +355,8 @@ public void DrawTile(Point pos) Main.spriteBatch.Draw(emptyFrame, pos.ToWorldCoordinates() - Main.screenPosition, null, Color.White, 0, new Vector2(emptyFrame.Width / 2f, emptyFrame.Height / 2f), 16f, 0, 0); } - public void EditDrawData(int i, int j, ref TileDrawInfo drawData) + // CIT 16JUL2025: Tile lighting override is now applied via an On edit; this code is duplicated there, and thus is no longer needed here. + /*public void EditDrawData(int i, int j, ref TileDrawInfo drawData) { float distanceFromCenter = (new Point(i, j).ToWorldCoordinates() - PingCenter).Length(); float currentExpansion = MathHelper.Clamp(PingProgress * MaxPingLife / (float)MaxPingTravelTime, 0f, 1f) * MaxPingRadius; @@ -340,7 +380,7 @@ public void EditDrawData(int i, int j, ref TileDrawInfo drawData) if (drawData.tileLight.R < 200 * brightness) drawData.tileLight.R = (byte)(200 * brightness); if (drawData.tileLight.G < 200 * brightness) drawData.tileLight.G = (byte)(200 * brightness); if (drawData.tileLight.B < 200 * brightness) drawData.tileLight.B = (byte)(200 * brightness); - } + }*/ public void UpdateEffect() { diff --git a/Systems/WorldMiscUpdateSystem.cs b/Systems/WorldMiscUpdateSystem.cs index 074ff42332..85c1bed3e8 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) @@ -444,9 +444,9 @@ public static void TrySpawnArmoredDigger(Player player, CalamityPlayer modPlayer if (Main.SceneMetrics.WaterCandleCount > 0) spawnRate *= 0.8D; - if (modPlayer.isNearbyBoss && CalamityConfig.Instance.BossZen) + if (modPlayer.isNearbyBoss && CalamityServerConfig.Instance.BossZen) spawnRate *= 50D; - if (modPlayer.zen || (CalamityConfig.Instance.ForceTownSafety && player.townNPCs > 1f && Main.expertMode)) + if (modPlayer.zen || (CalamityServerConfig.Instance.ForceTownSafety && player.townNPCs > 1f && Main.expertMode)) spawnRate *= 2D; if (modPlayer.tranquilityCandle) spawnRate *= 1.67D; diff --git a/Systems/WorldgenManagementSystem.cs b/Systems/WorldgenManagementSystem.cs index 822a6dac34..1c95edcdf9 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; @@ -314,7 +336,7 @@ public override void ModifyHardmodeTasks(List tasks) // Disable gen pass if Early Hardmode Rework is disabled. // Could just not add/remove gen pass, but that could lead to mod conflicts // in case whatever mod targets this specific gen pass. - if (!CalamityConfig.Instance.EarlyHardmodeProgressionRework) + if (!CalamityServerConfig.Instance.EarlyHardmodeProgressionRework) { hardmodeOreT1Pass.Disable(); } @@ -512,10 +534,10 @@ public override void PostWorldGen() } // Save the set of ores that got generated - OreTypes[0] = (ushort)GenVars.copperBar; - OreTypes[1] = (ushort)GenVars.ironBar; - OreTypes[2] = (ushort)GenVars.silverBar; - OreTypes[3] = (ushort)GenVars.goldBar; + OreTypes[0] = (ushort)GenVars.copper; + OreTypes[1] = (ushort)GenVars.iron; + OreTypes[2] = (ushort)GenVars.silver; + OreTypes[3] = (ushort)GenVars.gold; } #endregion } diff --git a/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/Abyss/SteamGeyser.cs b/Tiles/Abyss/SteamGeyser.cs index 7056860026..2ebecf6c03 100644 --- a/Tiles/Abyss/SteamGeyser.cs +++ b/Tiles/Abyss/SteamGeyser.cs @@ -1,4 +1,5 @@ using System; +using CalamityMod.CalPlayer; using CalamityMod.Dusts; using CalamityMod.Projectiles.Environment; using Microsoft.Xna.Framework; @@ -52,7 +53,7 @@ public override void NearbyEffects(int i, int j, bool closer) Tile t = CalamityUtils.ParanoidTileRetrieval(i, j); Vector2 spawnPosition = new(i * 16f + 24f, j * 16f - 4f); - if (!Main.gamePaused && t.TileFrameX % 36 == 0 && t.TileFrameY % 36 == 0 && Collision.CanHitLine(spawnPosition, 1, 1, spawnPosition - Vector2.UnitY * 100f, 1, 1)) + if (!Main.gamePaused && !CalamityPlayer.areThereAnyDamnBosses && t.TileFrameX % 36 == 0 && t.TileFrameY % 36 == 0 && Collision.CanHitLine(spawnPosition, 1, 1, spawnPosition - Vector2.UnitY * 100f, 1, 1)) { float positionInterpolant = (i + j) * 0.041f % 1f; Vector2 smokeVelocity = -Vector2.UnitY.RotatedByRandom(0.11f) * MathHelper.Lerp(4.8f, 8.1f, positionInterpolant); diff --git a/Tiles/CalamityGlobalTile.cs b/Tiles/CalamityGlobalTile.cs index bccfbf26c0..eee4e9752e 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 (CalamityServerConfig.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/LanternCenterTile.cs b/Tiles/Furniture/LanternCenterTile.cs index 5d87d1aad6..6744a2c100 100644 --- a/Tiles/Furniture/LanternCenterTile.cs +++ b/Tiles/Furniture/LanternCenterTile.cs @@ -1,5 +1,6 @@ using CalamityMod.Items.Placeables.Furniture; using Microsoft.Xna.Framework; +using System; using Terraria; using Terraria.Audio; using Terraria.DataStructures; @@ -25,6 +26,8 @@ public override void SetStaticDefaults() TileObjectData.addTile(Type); AddMapEntry(new Color(99, 99, 99), CalamityUtils.GetItemName()); TileID.Sets.HasOutlines[Type] = true; + TileID.Sets.InteractibleByNPCs[Type] = true; + TileID.Sets.DisableSmartInteract[Type] = true; AnimationFrameHeight = 54; } @@ -35,12 +38,21 @@ public override void SetStaticDefaults() public override void AnimateTile(ref int frame, ref int frameCounter) { - frameCounter++; - if (frameCounter >= 6) + if (!LanternNight.LanternsUp) { - frame = (frame + 1) % 6; + frame = 0; frameCounter = 0; } + else + { + frameCounter++; + if (frameCounter >= 6) + { + frame = (frame + 1) % 7; + frameCounter = 0; + } + frame = Math.Clamp(frame, 1, 6); + } } public override void KillMultiTile(int i, int j, int frameX, int frameY) @@ -50,13 +62,11 @@ public override void KillMultiTile(int i, int j, int frameX, int frameY) public override void HitWire(int i, int j) { - CalamityUtils.LightHitWire(Type, i, j, 3, 3); LanternNight.ToggleManualLanterns(); } public override bool RightClick(int i, int j) { - CalamityUtils.LightHitWire(Type, i, j, 3, 3); LanternNight.ToggleManualLanterns(); SoundEngine.PlaySound(SoundID.Mech, new Vector2(i * 16, j * 16)); return true; diff --git a/Tiles/Furniture/LanternCenterTile.png b/Tiles/Furniture/LanternCenterTile.png index 1f8cc97ef3..fffbe3d12e 100644 Binary files a/Tiles/Furniture/LanternCenterTile.png and b/Tiles/Furniture/LanternCenterTile.png differ diff --git a/Tiles/Furniture/LanternCenterTile_Highlight.png b/Tiles/Furniture/LanternCenterTile_Highlight.png index 6e86215b5d..7c9e7546ef 100644 Binary files a/Tiles/Furniture/LanternCenterTile_Highlight.png and b/Tiles/Furniture/LanternCenterTile_Highlight.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/FurniturePlaguedPlate/PlaguedPlateBed.cs b/Tiles/FurniturePlaguedPlate/PlaguedPlateBed.cs index 65721061b7..6e6dc45c34 100644 --- a/Tiles/FurniturePlaguedPlate/PlaguedPlateBed.cs +++ b/Tiles/FurniturePlaguedPlate/PlaguedPlateBed.cs @@ -16,14 +16,16 @@ public override void SetStaticDefaults() Main.tileFrameImportant[Type] = true; Main.tileLavaDeath[Type] = false; TileID.Sets.HasOutlines[Type] = true; + TileID.Sets.InteractibleByNPCs[Type] = true; + TileID.Sets.DisableSmartCursor[Type] = true; + TileID.Sets.IsValidSpawnPoint[Type] = true; TileObjectData.newTile.CopyFrom(TileObjectData.Style3x4); //This bed has different dimensions to conventional beds, using bookcase dimentions instead TileObjectData.newTile.LavaDeath = false; TileObjectData.newTile.CoordinateHeights = new int[] { 16, 16, 16, 16 }; TileObjectData.addTile(Type); + AddToArray(ref TileID.Sets.RoomNeeds.CountsAsChair); AddMapEntry(new Color(191, 142, 111), CreateMapEntryName()); - TileID.Sets.DisableSmartCursor[Type] = true; AdjTiles = new int[] { TileID.Beds }; - AddToArray(ref TileID.Sets.RoomNeeds.CountsAsChair); } public override bool CreateDust(int i, int j, ref int type) @@ -51,12 +53,12 @@ public override bool RightClick(int i, int j) if (player.SpawnX == spawnX && player.SpawnY == spawnY) { player.RemoveSpawn(); - Main.NewText("Spawn point removed!", 255, 240, 20); + Main.NewText(Language.GetTextValue("Game.SpawnPointRemoved"), 255, 240, 20); } else if (Player.CheckSpawn(spawnX, spawnY)) { player.ChangeSpawn(spawnX, spawnY); - Main.NewText("Spawn point set!", 255, 240, 20); + Main.NewText(Language.GetTextValue("Game.SpawnPointSet"), 255, 240, 20); } return true; } diff --git a/Tiles/LivingFire/LivingBrimstoneFireBlockTile.cs b/Tiles/LivingFire/LivingBrimstoneFireBlockTile.cs index d47571bd64..ddaee0e086 100644 --- a/Tiles/LivingFire/LivingBrimstoneFireBlockTile.cs +++ b/Tiles/LivingFire/LivingBrimstoneFireBlockTile.cs @@ -1,83 +1,25 @@ -using System.Collections.Generic; -using CalamityMod.Dusts; -using CalamityMod.Items.Placeables.LivingFire; +using CalamityMod.Dusts; using Microsoft.Xna.Framework; using Terraria; -using Terraria.DataStructures; using Terraria.ID; using Terraria.ModLoader; -using Terraria.ObjectData; + namespace CalamityMod.Tiles.LivingFire { public class LivingBrimstoneFireBlockTile : ModTile { - //Thank you to Seraph for getting living fire blocks to work properly. public override void SetStaticDefaults() { Main.tileLighted[Type] = true; - HitSound = SoundID.Dig; + TileID.Sets.CanPlaceNextToNonSolidTile[Type] = true; + DustType = (int)CalamityDusts.Brimstone; AddMapEntry(new Color(178, 34, 34)); AnimationFrameHeight = 90; - Main.tileSolid[Type] = false; - Main.tileNoAttach[Type] = false; - Main.tileFrameImportant[Type] = false; - TileObjectData.newTile.Width = 1; - TileObjectData.newTile.Height = 1; - TileObjectData.newTile.Origin = new Point16(0, 0); - TileObjectData.newTile.CoordinateHeights = new int[] { 16 }; - TileObjectData.newTile.CoordinateWidth = 16; - TileObjectData.newTile.CoordinatePadding = 2; - TileObjectData.newTile.HookCheckIfCanPlace = new PlacementHook(CanPlaceAlter, -1, 0, true); - TileObjectData.newTile.UsesCustomCanPlace = true; - TileObjectData.newTile.HookPostPlaceMyPlayer = new PlacementHook(AfterPlacement, -1, 0, false); - - TileObjectData.addTile(Type); - } - - public int CanPlaceAlter(int i, int j, int type, int style, int direction, int alternate) => 1; - - public static int AfterPlacement(int i, int j, int type, int style, int direction, int alternate) - { - if (Main.netMode == NetmodeID.MultiplayerClient) - { - NetMessage.SendTileSquare(Main.myPlayer, i, j, 1, 1); - } - return 1; } - public override bool CanPlace(int i, int j) - { - List> around = new List> - { - new List() {i, j-1 }, - new List() {i-1, j }, - new List() {i+1, j }, - new List() {i, j+1 } - }; - //if (Main.tile[i, j]) || tile.type == Type - - //return true; //temporary for testing purposes + public override void SetDrawPositions(int i, int j, ref int width, ref int offsetY, ref int height, ref short tileFrameX, ref short tileFrameY) => offsetY = 2; - if (Main.tile[i, j].WallType != WallID.None) - { - return true; - } - - for (int k = 0; k < around.Count; ++k) - { - Tile tile = Main.tile[around[k][0], around[k][1]]; - if (tile.HasTile && (Main.tileSolid[tile.TileType] || CalamityLists.livingFireBlockList.Contains(tile.TileType))) - { - return true; - } - } - return false; - } - - public override void AnimateTile(ref int frame, ref int frameCounter) - { - frame = Main.tileFrame[TileID.LivingFire]; - } + public override void AnimateTile(ref int frame, ref int frameCounter) => frame = Main.tileFrame[TileID.LivingFire]; public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) { @@ -85,11 +27,5 @@ public override void ModifyLight(int i, int j, ref float r, ref float g, ref flo g = 0f; b = 0f; } - - public override bool CreateDust(int i, int j, ref int type) - { - Dust.NewDust(new Vector2(i, j) * 16f, 16, 16, (int)CalamityDusts.Brimstone, 0f, 0f, 1, default, 1f); - return false; - } } } diff --git a/Tiles/LivingFire/LivingGodSlayerFireBlockTile.cs b/Tiles/LivingFire/LivingGodSlayerFireBlockTile.cs index 688e1eef69..2ad8f0f689 100644 --- a/Tiles/LivingFire/LivingGodSlayerFireBlockTile.cs +++ b/Tiles/LivingFire/LivingGodSlayerFireBlockTile.cs @@ -1,12 +1,9 @@ -using System.Collections.Generic; -using CalamityMod.Dusts; -using CalamityMod.Items.Placeables.LivingFire; +using CalamityMod.Dusts; using Microsoft.Xna.Framework; using Terraria; -using Terraria.DataStructures; using Terraria.ID; using Terraria.ModLoader; -using Terraria.ObjectData; + namespace CalamityMod.Tiles.LivingFire { public class LivingGodSlayerFireBlockTile : ModTile @@ -14,69 +11,15 @@ public class LivingGodSlayerFireBlockTile : ModTile public override void SetStaticDefaults() { Main.tileLighted[Type] = true; - HitSound = SoundID.Dig; + TileID.Sets.CanPlaceNextToNonSolidTile[Type] = true; + DustType = (int)CalamityDusts.PurpleCosmilite; AddMapEntry(new Color(186, 85, 211)); AnimationFrameHeight = 90; - Main.tileSolid[Type] = false; - Main.tileNoAttach[Type] = false; - Main.tileFrameImportant[Type] = false; - TileObjectData.newTile.Width = 1; - TileObjectData.newTile.Height = 1; - TileObjectData.newTile.Origin = new Point16(0, 0); - TileObjectData.newTile.CoordinateHeights = new int[] { 16 }; - TileObjectData.newTile.CoordinateWidth = 16; - TileObjectData.newTile.CoordinatePadding = 2; - TileObjectData.newTile.HookCheckIfCanPlace = new PlacementHook(CanPlaceAlter, -1, 0, true); - TileObjectData.newTile.UsesCustomCanPlace = true; - TileObjectData.newTile.HookPostPlaceMyPlayer = new PlacementHook(AfterPlacement, -1, 0, false); - - TileObjectData.addTile(Type); - } - - public int CanPlaceAlter(int i, int j, int type, int style, int direction, int alternate) => 1; - - public static int AfterPlacement(int i, int j, int type, int style, int direction, int alternate) - { - if (Main.netMode == NetmodeID.MultiplayerClient) - { - NetMessage.SendTileSquare(Main.myPlayer, i, j, 1, 1); - } - return 1; } - public override bool CanPlace(int i, int j) - { - List> around = new List> - { - new List() {i, j-1 }, - new List() {i-1, j }, - new List() {i+1, j }, - new List() {i, j+1 } - }; - //if (Main.tile[i, j]) || tile.type == Type - - //return true; //temporary for testing purposes + public override void SetDrawPositions(int i, int j, ref int width, ref int offsetY, ref int height, ref short tileFrameX, ref short tileFrameY) => offsetY = 2; - if (Main.tile[i, j].WallType != WallID.None) - { - return true; - } - - for (int k = 0; k < around.Count; ++k) - { - Tile tile = Main.tile[around[k][0], around[k][1]]; - if (tile.HasTile && (Main.tileSolid[tile.TileType] || CalamityLists.livingFireBlockList.Contains(tile.TileType))) - { - return true; - } - } - return false; - } - - public override void AnimateTile(ref int frame, ref int frameCounter) - { - frame = Main.tileFrame[TileID.LivingFire]; - } + public override void AnimateTile(ref int frame, ref int frameCounter) => frame = Main.tileFrame[TileID.LivingFire]; public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) { @@ -84,11 +27,5 @@ public override void ModifyLight(int i, int j, ref float r, ref float g, ref flo g = 0f; b = 1f; } - - public override bool CreateDust(int i, int j, ref int type) - { - Dust.NewDust(new Vector2(i, j) * 16f, 16, 16, (int)CalamityDusts.PurpleCosmilite, 0f, 0f, 1, default, 1f); - return false; - } } } diff --git a/Tiles/LivingFire/LivingHolyFireBlockTile.cs b/Tiles/LivingFire/LivingHolyFireBlockTile.cs index 82a99923db..51d1319a34 100644 --- a/Tiles/LivingFire/LivingHolyFireBlockTile.cs +++ b/Tiles/LivingFire/LivingHolyFireBlockTile.cs @@ -1,12 +1,9 @@ -using System.Collections.Generic; -using CalamityMod.Dusts; -using CalamityMod.Items.Placeables.LivingFire; +using CalamityMod.Dusts; using Microsoft.Xna.Framework; using Terraria; -using Terraria.DataStructures; using Terraria.ID; using Terraria.ModLoader; -using Terraria.ObjectData; + namespace CalamityMod.Tiles.LivingFire { public class LivingHolyFireBlockTile : ModTile @@ -14,69 +11,15 @@ public class LivingHolyFireBlockTile : ModTile public override void SetStaticDefaults() { Main.tileLighted[Type] = true; - HitSound = SoundID.Dig; + TileID.Sets.CanPlaceNextToNonSolidTile[Type] = true; + DustType = (int)CalamityDusts.ProfanedFire; AddMapEntry(new Color(255, 215, 0)); AnimationFrameHeight = 90; - Main.tileSolid[Type] = false; - Main.tileNoAttach[Type] = false; - Main.tileFrameImportant[Type] = false; - TileObjectData.newTile.Width = 1; - TileObjectData.newTile.Height = 1; - TileObjectData.newTile.Origin = new Point16(0, 0); - TileObjectData.newTile.CoordinateHeights = new int[] { 16 }; - TileObjectData.newTile.CoordinateWidth = 16; - TileObjectData.newTile.CoordinatePadding = 2; - TileObjectData.newTile.HookCheckIfCanPlace = new PlacementHook(CanPlaceAlter, -1, 0, true); - TileObjectData.newTile.UsesCustomCanPlace = true; - TileObjectData.newTile.HookPostPlaceMyPlayer = new PlacementHook(AfterPlacement, -1, 0, false); - - TileObjectData.addTile(Type); - } - - public int CanPlaceAlter(int i, int j, int type, int style, int direction, int alternate) => 1; - - public static int AfterPlacement(int i, int j, int type, int style, int direction, int alternate) - { - if (Main.netMode == NetmodeID.MultiplayerClient) - { - NetMessage.SendTileSquare(Main.myPlayer, i, j, 1, 1); - } - return 1; } - public override bool CanPlace(int i, int j) - { - List> around = new List> - { - new List() {i, j-1 }, - new List() {i-1, j }, - new List() {i+1, j }, - new List() {i, j+1 } - }; - //if (Main.tile[i, j]) || tile.type == Type - - //return true; //temporary for testing purposes + public override void SetDrawPositions(int i, int j, ref int width, ref int offsetY, ref int height, ref short tileFrameX, ref short tileFrameY) => offsetY = 2; - if (Main.tile[i, j].WallType != WallID.None) - { - return true; - } - - for (int k = 0; k < around.Count; ++k) - { - Tile tile = Main.tile[around[k][0], around[k][1]]; - if (tile.HasTile && (Main.tileSolid[tile.TileType] || CalamityLists.livingFireBlockList.Contains(tile.TileType))) - { - return true; - } - } - return false; - } - - public override void AnimateTile(ref int frame, ref int frameCounter) - { - frame = Main.tileFrame[TileID.LivingFire]; - } + public override void AnimateTile(ref int frame, ref int frameCounter) => frame = Main.tileFrame[TileID.LivingFire]; public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) { @@ -84,11 +27,5 @@ public override void ModifyLight(int i, int j, ref float r, ref float g, ref flo g = 1f; b = 0f; } - - public override bool CreateDust(int i, int j, ref int type) - { - Dust.NewDust(new Vector2(i, j) * 16f, 16, 16, (int)CalamityDusts.ProfanedFire, 0f, 0f, 1, default, 1f); - return false; - } } } 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/CooldownRackUI.cs b/UI/CooldownRackUI.cs index acd23acbd4..8c0469ba29 100644 --- a/UI/CooldownRackUI.cs +++ b/UI/CooldownRackUI.cs @@ -19,7 +19,7 @@ public static bool CompactIcons get { // Option 1: Always use compact icons if configured to do so. - if (CalamityConfig.Instance.CooldownDisplay == 1) + if (CalamityClientConfig.Instance.CooldownDisplay == 1) return true; // Option 2: If there are too many cooldowns, auto switch to compact mode. @@ -43,7 +43,7 @@ public static void Draw(SpriteBatch spriteBatch) // 1 - The game isn't even on the game screen yet. // 2 - The player's inventory is open. // 3 - Cooldown display is completely disabled. - if (Main.gameMenu || Main.playerInventory || CalamityConfig.Instance.CooldownDisplay < 1) + if (Main.gameMenu || Main.playerInventory || CalamityClientConfig.Instance.CooldownDisplay < 1) return; IList cooldownsToDraw = Main.LocalPlayer.GetDisplayedCooldowns(); diff --git a/UI/DraedonsArsenal/ChargeMeterUI.cs b/UI/DraedonsArsenal/ChargeMeterUI.cs index 709f36a8dd..b3c159411e 100644 --- a/UI/DraedonsArsenal/ChargeMeterUI.cs +++ b/UI/DraedonsArsenal/ChargeMeterUI.cs @@ -38,7 +38,7 @@ internal static void Unload() public static void Draw(SpriteBatch spriteBatch, Player player) { // Sanity check the planned position before drawing - Vector2 screenRatioPosition = new Vector2(CalamityConfig.Instance.ChargeMeterPosX, CalamityConfig.Instance.ChargeMeterPosY); + Vector2 screenRatioPosition = new Vector2(CalamityClientConfig.Instance.ChargeMeterPosX, CalamityClientConfig.Instance.ChargeMeterPosY); if (screenRatioPosition.X < 0f || screenRatioPosition.X > 100f) screenRatioPosition.X = DefaultChargePosX; if (screenRatioPosition.Y < 0f || screenRatioPosition.Y > 100f) @@ -54,23 +54,23 @@ public static void Draw(SpriteBatch spriteBatch, Player player) void SavePosition() { bool changed = false; - if (CalamityConfig.Instance.ChargeMeterPosX != screenRatioPosition.X) + if (CalamityClientConfig.Instance.ChargeMeterPosX != screenRatioPosition.X) { - CalamityConfig.Instance.ChargeMeterPosX = screenRatioPosition.X; + CalamityClientConfig.Instance.ChargeMeterPosX = screenRatioPosition.X; changed = true; } - if (CalamityConfig.Instance.ChargeMeterPosY != screenRatioPosition.Y) + if (CalamityClientConfig.Instance.ChargeMeterPosY != screenRatioPosition.Y) { - CalamityConfig.Instance.ChargeMeterPosY = screenRatioPosition.Y; + CalamityClientConfig.Instance.ChargeMeterPosY = screenRatioPosition.Y; changed = true; } if (changed) - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); } // If the Charge Meter is turned off or the player is not holding an item, stop. Item heldItem = player.ActiveItem(); - if (!CalamityConfig.Instance.ChargeMeter || heldItem is null || heldItem.IsAir) + if (!CalamityClientConfig.Instance.ChargeMeter || heldItem is null || heldItem.IsAir) { Reset(); SavePosition(); @@ -96,7 +96,7 @@ void SavePosition() if (chargeBar.Intersects(mouseHitbox)) { - if (!CalamityConfig.Instance.MeterPosLock) + if (!CalamityClientConfig.Instance.MeterPosLock) Main.LocalPlayer.mouseInterface = true; // If the mouse is on top of the meter, show the exact numeric charge. @@ -106,7 +106,7 @@ void SavePosition() Vector2 newScreenRatioPosition = screenRatioPosition; // Handle mouse dragging - if (!CalamityConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) + if (!CalamityClientConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) { // If the drag offset doesn't exist yet, create it. if (!dragOffset.HasValue) @@ -124,15 +124,15 @@ void SavePosition() Vector2 delta = newScreenRatioPosition - screenRatioPosition; if (Math.Abs(delta.X) >= MouseDragEpsilon || Math.Abs(delta.Y) >= MouseDragEpsilon) { - CalamityConfig.Instance.ChargeMeterPosX = newScreenRatioPosition.X; - CalamityConfig.Instance.ChargeMeterPosY = newScreenRatioPosition.Y; + CalamityClientConfig.Instance.ChargeMeterPosX = newScreenRatioPosition.X; + CalamityClientConfig.Instance.ChargeMeterPosY = newScreenRatioPosition.Y; } // When the mouse is released, save the config and destroy the drag offset. if (ms.LeftButton == ButtonState.Released) { dragOffset = null; - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); } } } diff --git a/UI/FlightBar/FlightBar.cs b/UI/FlightBar/FlightBar.cs index b78ed67fcd..8d9d14b533 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; @@ -90,7 +90,7 @@ internal static void Unload() public static void Draw(SpriteBatch spriteBatch, Player player) { // Sanity check the planned position before drawing - Vector2 screenRatioPosition = new Vector2(CalamityConfig.Instance.FlightBarPosX, CalamityConfig.Instance.FlightBarPosY); + Vector2 screenRatioPosition = new Vector2(CalamityClientConfig.Instance.FlightBarPosX, CalamityClientConfig.Instance.FlightBarPosY); if (screenRatioPosition.X < 0f || screenRatioPosition.X > 100f) screenRatioPosition.X = DefaultFlightPosX; if (screenRatioPosition.Y < 0f || screenRatioPosition.Y > 100f) @@ -106,26 +106,26 @@ public static void Draw(SpriteBatch spriteBatch, Player player) CalamityPlayer modPlayer = player.Calamity(); // If not drawing the flight bar, save its latest position to config and leave. - if (CalamityConfig.Instance.FlightBar && (player.wingsLogic > 0 || (player.mount.Active && player.mount._data.flightTimeMax > 0) || player.carpet && !player.canCarpet)) + if (CalamityClientConfig.Instance.FlightBar && ((player.wingsLogic > 0 && player.wingTimeMax > 0) || (player.mount.Active && player.mount._data.flightTimeMax > 0) || player.carpet && !player.canCarpet)) { DrawFlightBar(spriteBatch, modPlayer, screenPos); } else { bool changed = false; - if (CalamityConfig.Instance.FlightBarPosX != screenRatioPosition.X) + if (CalamityClientConfig.Instance.FlightBarPosX != screenRatioPosition.X) { - CalamityConfig.Instance.FlightBarPosX = screenRatioPosition.X; + CalamityClientConfig.Instance.FlightBarPosX = screenRatioPosition.X; changed = true; } - if (CalamityConfig.Instance.FlightBarPosY != screenRatioPosition.Y) + if (CalamityClientConfig.Instance.FlightBarPosY != screenRatioPosition.Y) { - CalamityConfig.Instance.FlightBarPosY = screenRatioPosition.Y; + CalamityClientConfig.Instance.FlightBarPosY = screenRatioPosition.Y; changed = true; } if (changed) - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); return; } @@ -138,7 +138,7 @@ public static void Draw(SpriteBatch spriteBatch, Player player) // Handle mouse dragging if (flightBar.Intersects(mouseHitbox)) { - if (!CalamityConfig.Instance.MeterPosLock) + if (!CalamityClientConfig.Instance.MeterPosLock) Main.LocalPlayer.mouseInterface = true; if (modPlayer.Player.equippedWings != null && modPlayer.Player.wingTimeMax > 0 || (player.mount.Active && modPlayer.Player.mount._data.flightTimeMax > 0) || player.carpet && !player.canCarpet) //equipped wings or riding a flying mount and max wingtime/flighttime above 0 (so not disabled bar) @@ -149,7 +149,7 @@ public static void Draw(SpriteBatch spriteBatch, Player player) Vector2 newScreenRatioPosition = screenRatioPosition; // As long as the mouse button is held down, drag the meter along with an offset. - if (!CalamityConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) + if (!CalamityClientConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) { // If the drag offset doesn't exist yet, create it. if (!dragOffset.HasValue) @@ -167,15 +167,15 @@ public static void Draw(SpriteBatch spriteBatch, Player player) Vector2 delta = newScreenRatioPosition - screenRatioPosition; if (Math.Abs(delta.X) >= MouseDragEpsilon || Math.Abs(delta.Y) >= MouseDragEpsilon) { - CalamityConfig.Instance.FlightBarPosX = newScreenRatioPosition.X; - CalamityConfig.Instance.FlightBarPosY = newScreenRatioPosition.Y; + CalamityClientConfig.Instance.FlightBarPosX = newScreenRatioPosition.X; + CalamityClientConfig.Instance.FlightBarPosY = newScreenRatioPosition.Y; } // When the mouse is released, save the config and destroy the drag offset. if (ms.LeftButton == ButtonState.Released) { dragOffset = null; - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); } } } diff --git a/UI/ModeIndicator/ModeIndicatorUI.cs b/UI/ModeIndicator/ModeIndicatorUI.cs index 6c09b3d4c1..4e18a81e85 100644 --- a/UI/ModeIndicator/ModeIndicatorUI.cs +++ b/UI/ModeIndicator/ModeIndicatorUI.cs @@ -184,8 +184,8 @@ public static void Draw(SpriteBatch spriteBatch) if (!Main.mouseItem.IsAir) textboxStart.X += 34; - if (textboxStart.X + boxSize.X + 4f > (float)Main.screenWidth) - textboxStart.X = Main.screenWidth - boxSize.X - 4f; + if (textboxStart.X + regexedBoxSize.X + 4f > (float)Main.screenWidth) + textboxStart.X = Main.screenWidth - regexedBoxSize.X - 4f; if (textboxStart.Y + regexedBoxSize.Y + 4f > (float)Main.screenHeight) textboxStart.Y = Main.screenHeight - regexedBoxSize.Y - 4f; diff --git a/UI/Rippers/RipperUI.cs b/UI/Rippers/RipperUI.cs index 6c8a3cde57..2f9cce458e 100644 --- a/UI/Rippers/RipperUI.cs +++ b/UI/Rippers/RipperUI.cs @@ -105,14 +105,14 @@ internal static void Reset() public static void Draw(SpriteBatch spriteBatch, Player player) { // Sanity check the planned Rage Meter position - Vector2 rageScreenRatioPos = new Vector2(CalamityConfig.Instance.RageMeterPosX, CalamityConfig.Instance.RageMeterPosY); + Vector2 rageScreenRatioPos = new Vector2(CalamityClientConfig.Instance.RageMeterPosX, CalamityClientConfig.Instance.RageMeterPosY); if (rageScreenRatioPos.X < 0f || rageScreenRatioPos.X > 100f) rageScreenRatioPos.X = DefaultRagePosX; if (rageScreenRatioPos.Y < 0f || rageScreenRatioPos.Y > 100f) rageScreenRatioPos.Y = DefaultRagePosY; // Sanity check the planned Adrenaline Meter position - Vector2 adrenScreenRatioPos = new Vector2(CalamityConfig.Instance.AdrenalineMeterPosX, CalamityConfig.Instance.AdrenalineMeterPosY); + Vector2 adrenScreenRatioPos = new Vector2(CalamityClientConfig.Instance.AdrenalineMeterPosX, CalamityClientConfig.Instance.AdrenalineMeterPosY); if (adrenScreenRatioPos.X < 0f || adrenScreenRatioPos.X > 100f) adrenScreenRatioPos.X = DefaultAdrenPosX; if (adrenScreenRatioPos.Y < 0f || adrenScreenRatioPos.Y > 100f) @@ -135,18 +135,18 @@ public static void Draw(SpriteBatch spriteBatch, Player player) else { bool changed = false; - if (CalamityConfig.Instance.RageMeterPosX != rageScreenRatioPos.X) + if (CalamityClientConfig.Instance.RageMeterPosX != rageScreenRatioPos.X) { - CalamityConfig.Instance.RageMeterPosX = rageScreenRatioPos.X; + CalamityClientConfig.Instance.RageMeterPosX = rageScreenRatioPos.X; changed = true; } - if (CalamityConfig.Instance.RageMeterPosY != rageScreenRatioPos.Y) + if (CalamityClientConfig.Instance.RageMeterPosY != rageScreenRatioPos.Y) { - CalamityConfig.Instance.RageMeterPosY = rageScreenRatioPos.Y; + CalamityClientConfig.Instance.RageMeterPosY = rageScreenRatioPos.Y; changed = true; } if (changed) - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); } if (modPlayer.AdrenalineEnabled) @@ -154,18 +154,18 @@ public static void Draw(SpriteBatch spriteBatch, Player player) else { bool changed = false; - if (CalamityConfig.Instance.AdrenalineMeterPosX != adrenScreenRatioPos.X) + if (CalamityClientConfig.Instance.AdrenalineMeterPosX != adrenScreenRatioPos.X) { - CalamityConfig.Instance.AdrenalineMeterPosX = adrenScreenRatioPos.X; + CalamityClientConfig.Instance.AdrenalineMeterPosX = adrenScreenRatioPos.X; changed = true; } - if (CalamityConfig.Instance.AdrenalineMeterPosY != adrenScreenRatioPos.Y) + if (CalamityClientConfig.Instance.AdrenalineMeterPosY != adrenScreenRatioPos.Y) { - CalamityConfig.Instance.AdrenalineMeterPosY = adrenScreenRatioPos.Y; + CalamityClientConfig.Instance.AdrenalineMeterPosY = adrenScreenRatioPos.Y; changed = true; } if (changed) - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); } #region Mouse Interaction @@ -190,7 +190,7 @@ public static void Draw(SpriteBatch spriteBatch, Player player) if (rageHover && !adrenHover) { // If the meter isn't locked, then the player's mouse counts as being over interface - if (!CalamityConfig.Instance.MeterPosLock) + if (!CalamityClientConfig.Instance.MeterPosLock) Main.LocalPlayer.mouseInterface = true; // Add hover text if the mouse is over Rage bar @@ -199,7 +199,7 @@ public static void Draw(SpriteBatch spriteBatch, Player player) // The bar is draggable if enabled in config. Vector2 newScreenRatioPosition = rageScreenRatioPos; - if (!CalamityConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) + if (!CalamityClientConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) { // If the drag offset doesn't exist yet, create it. if (!rageDragOffset.HasValue) @@ -217,21 +217,21 @@ public static void Draw(SpriteBatch spriteBatch, Player player) Vector2 delta = newScreenRatioPosition - rageScreenRatioPos; if (Math.Abs(delta.X) >= MouseDragEpsilon || Math.Abs(delta.Y) >= MouseDragEpsilon) { - CalamityConfig.Instance.RageMeterPosX = newScreenRatioPosition.X; - CalamityConfig.Instance.RageMeterPosY = newScreenRatioPosition.Y; + CalamityClientConfig.Instance.RageMeterPosX = newScreenRatioPosition.X; + CalamityClientConfig.Instance.RageMeterPosY = newScreenRatioPosition.Y; } // When the mouse is released, save the config and destroy the drag offset. if (ms.LeftButton == ButtonState.Released) { rageDragOffset = null; - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); } } else if (adrenHover) { // If the meter isn't locked, then the player's mouse counts as being over interface - if (!CalamityConfig.Instance.MeterPosLock) + if (!CalamityClientConfig.Instance.MeterPosLock) Main.LocalPlayer.mouseInterface = true; // Add hover text if the mouse is over the bar @@ -241,7 +241,7 @@ public static void Draw(SpriteBatch spriteBatch, Player player) // The bar is draggable if enabled in config. Vector2 newScreenRatioPosition = adrenScreenRatioPos; - if (!CalamityConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) + if (!CalamityClientConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) { // If the drag offset doesn't exist yet, create it. if (!adrenDragOffset.HasValue) @@ -259,15 +259,15 @@ public static void Draw(SpriteBatch spriteBatch, Player player) Vector2 delta = newScreenRatioPosition - adrenScreenRatioPos; if (Math.Abs(delta.X) >= MouseDragEpsilon || Math.Abs(delta.Y) >= MouseDragEpsilon) { - CalamityConfig.Instance.AdrenalineMeterPosX = newScreenRatioPosition.X; - CalamityConfig.Instance.AdrenalineMeterPosY = newScreenRatioPosition.Y; + CalamityClientConfig.Instance.AdrenalineMeterPosX = newScreenRatioPosition.X; + CalamityClientConfig.Instance.AdrenalineMeterPosY = newScreenRatioPosition.Y; } // When the mouse is released, save the config and destroy the drag offset. if (ms.LeftButton == ButtonState.Released) { adrenDragOffset = null; - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); } } #endregion @@ -446,7 +446,7 @@ private static void DrawAdrenalineBar(SpriteBatch spriteBatch, CalamityPlayer mo #endregion private static Vector2 GetShakeOffset() { - float shake = CalamityConfig.Instance.RipperMeterShake; + float shake = CalamityClientConfig.Instance.RipperMeterShake; float shakeX = Main.rand.NextFloat(-shake, shake); float shakeY = Main.rand.NextFloat(-shake, shake); return new Vector2(shakeX, shakeY); diff --git a/UI/SpeedrunTimerUI.cs b/UI/SpeedrunTimerUI.cs index 6f340be742..7835193f47 100644 --- a/UI/SpeedrunTimerUI.cs +++ b/UI/SpeedrunTimerUI.cs @@ -44,11 +44,11 @@ public class SpeedrunTimerUI public static void Draw(Player player) { - if (Main.gameMenu || !CalamityConfig.Instance.SpeedrunTimer) + if (Main.gameMenu || !CalamityClientConfig.Instance.SpeedrunTimer) return; // Sanity check the planned position before drawing - Vector2 screenRatioPosition = new Vector2(CalamityConfig.Instance.SpeedrunTimerPosX, CalamityConfig.Instance.SpeedrunTimerPosY); + Vector2 screenRatioPosition = new Vector2(CalamityClientConfig.Instance.SpeedrunTimerPosX, CalamityClientConfig.Instance.SpeedrunTimerPosY); if (screenRatioPosition.X < 0f || screenRatioPosition.X > 100f) screenRatioPosition.X = DefaultTimerPosX; if (screenRatioPosition.Y < 0f || screenRatioPosition.Y > 100f) diff --git a/UI/StealthUI.cs b/UI/StealthUI.cs index 4562d8a1fe..5abcc3896f 100644 --- a/UI/StealthUI.cs +++ b/UI/StealthUI.cs @@ -41,7 +41,7 @@ internal static void Unload() public static void Draw(SpriteBatch spriteBatch, Player player) { // Sanity check the planned position before drawing - Vector2 screenRatioPosition = new Vector2(CalamityConfig.Instance.StealthMeterPosX, CalamityConfig.Instance.StealthMeterPosY); + Vector2 screenRatioPosition = new Vector2(CalamityClientConfig.Instance.StealthMeterPosX, CalamityClientConfig.Instance.StealthMeterPosY); if (screenRatioPosition.X < 0f || screenRatioPosition.X > 100f) screenRatioPosition.X = DefaultStealthPosX; if (screenRatioPosition.Y < 0f || screenRatioPosition.Y > 100f) @@ -57,26 +57,26 @@ public static void Draw(SpriteBatch spriteBatch, Player player) CalamityPlayer modPlayer = player.Calamity(); // If not drawing the stealth meter, save its latest position to config and leave. - if (modPlayer.stealthUIAlpha > 0f && CalamityConfig.Instance.StealthMeter && modPlayer.rogueStealthMax > 0f && modPlayer.wearingRogueArmor) + if (modPlayer.stealthUIAlpha > 0f && CalamityClientConfig.Instance.StealthMeter && modPlayer.rogueStealthMax > 0f && modPlayer.wearingRogueArmor) { DrawStealthBar(spriteBatch, modPlayer, screenPos); } else { bool changed = false; - if (CalamityConfig.Instance.StealthMeterPosX != screenRatioPosition.X) + if (CalamityClientConfig.Instance.StealthMeterPosX != screenRatioPosition.X) { - CalamityConfig.Instance.StealthMeterPosX = screenRatioPosition.X; + CalamityClientConfig.Instance.StealthMeterPosX = screenRatioPosition.X; changed = true; } - if (CalamityConfig.Instance.StealthMeterPosY != screenRatioPosition.Y) + if (CalamityClientConfig.Instance.StealthMeterPosY != screenRatioPosition.Y) { - CalamityConfig.Instance.StealthMeterPosY = screenRatioPosition.Y; + CalamityClientConfig.Instance.StealthMeterPosY = screenRatioPosition.Y; changed = true; } if (changed) - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); } Rectangle mouseHitbox = new Rectangle((int)Main.MouseScreen.X, (int)Main.MouseScreen.Y, 8, 8); @@ -88,7 +88,7 @@ public static void Draw(SpriteBatch spriteBatch, Player player) // Handle mouse dragging if (stealthBar.Intersects(mouseHitbox)) { - if (!CalamityConfig.Instance.MeterPosLock) + if (!CalamityClientConfig.Instance.MeterPosLock) Main.LocalPlayer.mouseInterface = true; // If the mouse is on top of the meter, show the player's exact numeric stealth. @@ -113,7 +113,7 @@ public static void Draw(SpriteBatch spriteBatch, Player player) Vector2 newScreenRatioPosition = screenRatioPosition; // As long as the mouse button is held down, drag the meter along with an offset. - if (!CalamityConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) + if (!CalamityClientConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) { // If the drag offset doesn't exist yet, create it. if (!dragOffset.HasValue) @@ -131,15 +131,15 @@ public static void Draw(SpriteBatch spriteBatch, Player player) Vector2 delta = newScreenRatioPosition - screenRatioPosition; if (Math.Abs(delta.X) >= MouseDragEpsilon || Math.Abs(delta.Y) >= MouseDragEpsilon) { - CalamityConfig.Instance.StealthMeterPosX = newScreenRatioPosition.X; - CalamityConfig.Instance.StealthMeterPosY = newScreenRatioPosition.Y; + CalamityClientConfig.Instance.StealthMeterPosX = newScreenRatioPosition.X; + CalamityClientConfig.Instance.StealthMeterPosY = newScreenRatioPosition.Y; } // When the mouse is released, save the config and destroy the drag offset. if (ms.LeftButton == ButtonState.Released) { dragOffset = null; - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); } } } diff --git a/UI/SulphurousWaterMeter/SulphurousWaterMeterUI.cs b/UI/SulphurousWaterMeter/SulphurousWaterMeterUI.cs index a1a4899dab..97a3df2f64 100644 --- a/UI/SulphurousWaterMeter/SulphurousWaterMeterUI.cs +++ b/UI/SulphurousWaterMeter/SulphurousWaterMeterUI.cs @@ -37,7 +37,7 @@ public override void Unload() public static void Draw(SpriteBatch spriteBatch, Player player) { // Sanity check the planned position before drawing. This is done relative. - Vector2 screenRatioPosition = new Vector2(CalamityConfig.Instance.SulphuricWaterMeterPosX, CalamityConfig.Instance.SulphuricWaterMeterPosY); + Vector2 screenRatioPosition = new Vector2(CalamityClientConfig.Instance.SulphuricWaterMeterPosX, CalamityClientConfig.Instance.SulphuricWaterMeterPosY); if (screenRatioPosition.X < 0f || screenRatioPosition.X > 100f) screenRatioPosition.X = DefaultPosX; if (screenRatioPosition.Y < 0f || screenRatioPosition.Y > 100f) @@ -58,19 +58,19 @@ public static void Draw(SpriteBatch spriteBatch, Player player) else { bool changed = false; - if (CalamityConfig.Instance.SulphuricWaterMeterPosX != screenRatioPosition.X) + if (CalamityClientConfig.Instance.SulphuricWaterMeterPosX != screenRatioPosition.X) { - CalamityConfig.Instance.SulphuricWaterMeterPosX = screenRatioPosition.X; + CalamityClientConfig.Instance.SulphuricWaterMeterPosX = screenRatioPosition.X; changed = true; } - if (CalamityConfig.Instance.SulphuricWaterMeterPosY != screenRatioPosition.Y) + if (CalamityClientConfig.Instance.SulphuricWaterMeterPosY != screenRatioPosition.Y) { - CalamityConfig.Instance.SulphuricWaterMeterPosY = screenRatioPosition.Y; + CalamityClientConfig.Instance.SulphuricWaterMeterPosY = screenRatioPosition.Y; changed = true; } if (changed) - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); } Rectangle mouseHitbox = new Rectangle((int)Main.MouseScreen.X, (int)Main.MouseScreen.Y, 8, 8); @@ -82,7 +82,7 @@ public static void Draw(SpriteBatch spriteBatch, Player player) // Handle mouse dragging if (waterBarArea.Intersects(mouseHitbox)) { - if (!CalamityConfig.Instance.MeterPosLock) + if (!CalamityClientConfig.Instance.MeterPosLock) Main.LocalPlayer.mouseInterface = true; // If the mouse is on top of the meter, show the player's accumulated sulphuric poisoning. @@ -97,7 +97,7 @@ public static void Draw(SpriteBatch spriteBatch, Player player) Vector2 newScreenRatioPosition = screenRatioPosition; // As long as the mouse button is held down, drag the meter along with an offset. - if (!CalamityConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) + if (!CalamityClientConfig.Instance.MeterPosLock && ms.LeftButton == ButtonState.Pressed) { // If the drag offset doesn't exist yet, create it. if (!dragOffset.HasValue) @@ -115,15 +115,15 @@ public static void Draw(SpriteBatch spriteBatch, Player player) Vector2 delta = newScreenRatioPosition - screenRatioPosition; if (Math.Abs(delta.X) >= MouseDragEpsilon || Math.Abs(delta.Y) >= MouseDragEpsilon) { - CalamityConfig.Instance.SulphuricWaterMeterPosX = newScreenRatioPosition.X; - CalamityConfig.Instance.SulphuricWaterMeterPosY = newScreenRatioPosition.Y; + CalamityClientConfig.Instance.SulphuricWaterMeterPosX = newScreenRatioPosition.X; + CalamityClientConfig.Instance.SulphuricWaterMeterPosY = newScreenRatioPosition.Y; } // When the mouse is released, save the config and destroy the drag offset. if (ms.LeftButton == ButtonState.Released) { dragOffset = null; - CalamityMod.SaveConfig(CalamityConfig.Instance); + CalamityMod.SaveConfig(CalamityClientConfig.Instance); } } else diff --git a/Utilities/CalamityRecipes.cs b/Utilities/CalamityRecipes.cs index bc4aefe0a0..13e8b2696f 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); @@ -1740,19 +1747,6 @@ private static void AddArmorRecipes() r.AddTile(TileID.Loom); r.Register(); r.DisableDecraft(); - - // Pharaoh set - r = Recipe.Create(ItemID.PharaohsMask); - r.AddIngredient(ItemID.AncientCloth, 3); - r.AddTile(TileID.Loom); - r.Register(); - r.DisableDecraft(); - - r = Recipe.Create(ItemID.PharaohsRobe); - r.AddIngredient(ItemID.AncientCloth, 4); - r.AddTile(TileID.Loom); - r.Register(); - r.DisableDecraft(); } #endregion @@ -1997,14 +1991,6 @@ public static void AddShimmerRecipes() int[] convert = ItemID.Sets.ShimmerTransformToItem; InsertShimmerResult(ModContent.ItemType(), ItemID.SummonerEmblem); - - // Pyramid loot edits. There's no good way to have this not be hardcoded. - convert[ItemID.PharaohsMask] = ItemID.PharaohsRobe; - convert[ItemID.PharaohsRobe] = ItemID.PharaohsMask; - - convert[ItemID.AmberHook] = ItemID.SandstorminaBottle; - convert[ItemID.SandstorminaBottle] = ItemID.FlyingCarpet; - convert[ItemID.FlyingCarpet] = ItemID.AmberHook; } #endregion diff --git a/Utilities/DrawingUtils.cs b/Utilities/DrawingUtils.cs index 0b541aa8ec..0ef3726d81 100644 --- a/Utilities/DrawingUtils.cs +++ b/Utilities/DrawingUtils.cs @@ -72,7 +72,7 @@ public static void DrawAfterimagesCentered(Projectile proj, int mode, Color ligh // If no afterimages are drawn due to an invalid mode being specified, ensure the projectile itself is drawn anyway. bool failedToDrawAfterimages = false; - if (CalamityConfig.Instance.Afterimages) + if (CalamityClientConfig.Instance.Afterimages) { Vector2 centerOffset = drawCentered ? proj.Size / 2f : Vector2.Zero; Color alphaColor = proj.GetAlpha(lightColor); @@ -135,7 +135,7 @@ public static void DrawAfterimagesCentered(Projectile proj, int mode, Color ligh } // Draw the projectile itself. Only do this if no afterimages are drawn because afterimage 0 is the projectile itself. - if (!CalamityConfig.Instance.Afterimages || ProjectileID.Sets.TrailCacheLength[proj.type] <= 0 || failedToDrawAfterimages) + if (!CalamityClientConfig.Instance.Afterimages || ProjectileID.Sets.TrailCacheLength[proj.type] <= 0 || failedToDrawAfterimages) { Vector2 startPos = drawCentered ? proj.Center : proj.position; Main.spriteBatch.Draw(texture, startPos - Main.screenPosition + new Vector2(0f, proj.gfxOffY), rectangle, proj.GetAlpha(lightColor), rotation, origin, scale, spriteEffects, 0f); @@ -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/DropHelper.cs b/Utilities/DropHelper.cs index 88a518df31..b971ec69a5 100644 --- a/Utilities/DropHelper.cs +++ b/Utilities/DropHelper.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using CalamityMod.Enums; using CalamityMod.Items.Accessories; using CalamityMod.Items.Potions; using CalamityMod.NPCs.SulphurousSea; @@ -281,52 +282,320 @@ public static void AddRevBagAccessories(this ILoot loot) loot.Add(lcr); } + public static void AddBiomeCrateLootRules(this ILoot loot, bool hardMode = true) + { + if (hardMode) + loot.AddHardmodeOresToCrates(HardmodeCrateType.Biome); + else + { + // Pre-Hardmode Ore/Bar loot pools + // 20-35 Ores @ 14.29%; Individually 1.79% + IItemDropRule[] phmOres = new IItemDropRule[8] + { + ItemDropRule.NotScalingWithLuck(ItemID.CopperOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.TinOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.IronOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.LeadOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.SilverOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.TungstenOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.GoldOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.PlatinumOre, 1, 20, 35) + }; + loot.Add(new OneFromRulesRule(7, phmOres)); + + // 6-16 Bars @ 25%; Individually 4.17% + IItemDropRule[] phmBars = new IItemDropRule[6] + { + ItemDropRule.NotScalingWithLuck(ItemID.IronBar, 1, 6, 16), + ItemDropRule.NotScalingWithLuck(ItemID.LeadBar, 1, 6, 16), + ItemDropRule.NotScalingWithLuck(ItemID.SilverBar, 1, 6, 16), + ItemDropRule.NotScalingWithLuck(ItemID.TungstenBar, 1, 6, 16), + ItemDropRule.NotScalingWithLuck(ItemID.GoldBar, 1, 6, 16), + ItemDropRule.NotScalingWithLuck(ItemID.PlatinumBar, 1, 6, 16) + }; + loot.Add(new OneFromRulesRule(4, phmBars)); + } + + // 2-4 Buff Potions @ 25%; Individually 4.17% + loot.Add(new OneFromRulesRule(4, new IItemDropRule[6] + { + ItemDropRule.NotScalingWithLuck(ItemID.ObsidianSkinPotion, 1, 2, 4), + ItemDropRule.NotScalingWithLuck(ItemID.SpelunkerPotion, 1, 2, 4), + ItemDropRule.NotScalingWithLuck(ItemID.HunterPotion, 1, 2, 4), + ItemDropRule.NotScalingWithLuck(ItemID.GravitationPotion, 1, 2, 4), + ItemDropRule.NotScalingWithLuck(ItemID.MiningPotion, 1, 2, 4), + ItemDropRule.NotScalingWithLuck(ItemID.HeartreachPotion, 1, 2, 4) + })); + + // 5-17 (Regular) Recovery Potions @ 50%; 25% Healing 25% Mana + loot.Add(new OneFromRulesRule(2, new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ItemID.HealingPotion, 1, 5, 17), + ItemDropRule.NotScalingWithLuck(ItemID.ManaPotion, 1, 5, 17) + })); + + // 2-6 Bait @ 50%; 25% Master 25% Apprentice + loot.Add(new OneFromRulesRule(2, new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ItemID.MasterBait, 1, 2, 6), + ItemDropRule.NotScalingWithLuck(ItemID.ApprenticeBait, 1, 2, 6) + })); + + // 5-12 Gold Coin @ 25% + loot.Add(ItemID.GoldCoin, 4, 5, 12); + } + /// - /// Adds all the common potions for fishing crates, alongside scaling mana and regen potions + /// Adds (or re-adds) Hardmode Ores to crates with respect to Hardmode Progression rework
+ /// Drop rules replicate vanilla's rules. ///
/// The ILoot interface for the loot table. - /// Whether or not the crate is considered a hardmode crate. - public static void AddCratePotionRules(this ILoot loot, bool hardMode = true) + /// Type of crate: Mythril, Titanium, Biome + public static void AddHardmodeOresToCrates(this ILoot loot, HardmodeCrateType type) { - loot.Add(ItemID.ObsidianSkinPotion, 10, 1, 3); - loot.Add(ItemID.SwiftnessPotion, 10, 1, 3); - loot.Add(ItemID.IronskinPotion, 10, 1, 3); - loot.Add(ItemID.NightOwlPotion, 10, 1, 3); - loot.Add(ItemID.ShinePotion, 10, 1, 3); - loot.Add(ItemID.MiningPotion, 10, 1, 3); - loot.Add(ItemID.HeartreachPotion, 10, 1, 3); - loot.Add(ItemID.TrapsightPotion, 10, 1, 3); // Dangersense Potion - - // Define all the loot rules for the potion types - var supremePots = new OneFromOptionsNotScaledWithLuckDropRule(1, 1, ModContent.ItemType(), ModContent.ItemType()); - var superPots = new OneFromOptionsNotScaledWithLuckDropRule(1, 1, ItemID.SuperHealingPotion, ItemID.SuperManaPotion); - var greaterPots = new OneFromOptionsNotScaledWithLuckDropRule(1, 1, ItemID.GreaterHealingPotion, ItemID.GreaterManaPotion); - var regularPots = new OneFromOptionsNotScaledWithLuckDropRule(1, 1, ItemID.HealingPotion, ItemID.ManaPotion); - var lesserPots = new OneFromOptionsNotScaledWithLuckDropRule(1, 1, ItemID.LesserHealingPotion, ItemID.LesserManaPotion); - - // Chained LeadingConditionRules achieve the equivalent of "if killed X, else if killed Y, else if killed Z, else..." - var lcrSupremePotion = loot.DefineConditionalDropSet(() => DownedBossSystem.downedDoG); - var lcrSuperPotion = new LeadingConditionRule(If(() => DownedBossSystem.downedProvidence)); - var lcrGreaterPotion = new LeadingConditionRule(If(() => NPC.downedMechBossAny)); - var lcrRegularPotion = new LeadingConditionRule(If(() => NPC.downedBoss3)); - - // Actually chain all the LCRs together - // Greater potions upwards are only chained if the crate is marked as Hardmode - if (hardMode) + var adamantiteLCR = loot.DefineConditionalDropSet(AdamantiteCondition); + var mythrilLCR = new LeadingConditionRule(MythrilCondition); + + if (type == HardmodeCrateType.Biome) { - lcrSupremePotion.Add(supremePots); - lcrSupremePotion.OnFailedConditions(lcrSuperPotion); - lcrSuperPotion.Add(superPots); - lcrSuperPotion.OnFailedConditions(lcrGreaterPotion); - lcrGreaterPotion.Add(greaterPots); - lcrGreaterPotion.OnFailedConditions(lcrRegularPotion); + // Pre-Hardmode loot pools + // 20-35 Ores @ 7.14%; Individually 0.89% + IItemDropRule[] phmOres = new IItemDropRule[8] + { + ItemDropRule.NotScalingWithLuck(ItemID.CopperOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.TinOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.IronOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.LeadOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.SilverOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.TungstenOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.GoldOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.PlatinumOre, 1, 20, 35) + }; + // 6-16 Bars @ 8.33%; Individually 1.39% + IItemDropRule[] phmBars = new IItemDropRule[6] + { + ItemDropRule.NotScalingWithLuck(ItemID.IronBar, 1, 6, 16), + ItemDropRule.NotScalingWithLuck(ItemID.LeadBar, 1, 6, 16), + ItemDropRule.NotScalingWithLuck(ItemID.SilverBar, 1, 6, 16), + ItemDropRule.NotScalingWithLuck(ItemID.TungstenBar, 1, 6, 16), + ItemDropRule.NotScalingWithLuck(ItemID.GoldBar, 1, 6, 16), + ItemDropRule.NotScalingWithLuck(ItemID.PlatinumBar, 1, 6, 16) + }; + + // Tier 3 loot pools + // 20-35 Ores @ 7.14%; Individually 1.19% + IItemDropRule[] hmOresThree = new IItemDropRule[6] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.MythrilOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.OrichalcumOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.AdamantiteOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.TitaniumOre, 1, 20, 35) + }; + // 5-16 Bars @ 16.67%; Individually 2.78% + IItemDropRule[] hmBarsThree = new IItemDropRule[6] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltBar, 1, 5, 16), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumBar, 1, 5, 16), + ItemDropRule.NotScalingWithLuck(ItemID.MythrilBar, 1, 5, 16), + ItemDropRule.NotScalingWithLuck(ItemID.OrichalcumBar, 1, 5, 16), + ItemDropRule.NotScalingWithLuck(ItemID.AdamantiteBar, 1, 5, 16), + ItemDropRule.NotScalingWithLuck(ItemID.TitaniumBar, 1, 5, 16) + }; + var adamantiteDropsOres = new SequentialRulesNotScalingWithLuckRule(7, new OneFromRulesRule(2, hmOresThree), new OneFromRulesRule(1, phmOres)); + var adamantiteDropsBars = new SequentialRulesNotScalingWithLuckRule(4, new OneFromRulesRule(3, 2, hmBarsThree), new OneFromRulesRule(1, phmBars)); + + // Tier 2 loot pools + // 20-35 Ores @ 7.14%; Individually 1.79% + IItemDropRule[] hmOresTwo = new IItemDropRule[4] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.MythrilOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.OrichalcumOre, 1, 20, 35) + }; + // 5-16 Bars @ 16.67%; Individually 4.17% + IItemDropRule[] hmBarsTwo = new IItemDropRule[4] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltBar, 1, 5, 16), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumBar, 1, 5, 16), + ItemDropRule.NotScalingWithLuck(ItemID.MythrilBar, 1, 5, 16), + ItemDropRule.NotScalingWithLuck(ItemID.OrichalcumBar, 1, 5, 16) + }; + var mythrilDropsOres = new SequentialRulesNotScalingWithLuckRule(7, new OneFromRulesRule(2, hmOresTwo), new OneFromRulesRule(1, phmOres)); + var mythrilDropsBars = new SequentialRulesNotScalingWithLuckRule(4, new OneFromRulesRule(3, 2, hmBarsTwo), new OneFromRulesRule(1, phmBars)); + + // Tier 1 loot pools + // 20-35 Ores @ 7.14%; Individually 3.57% + IItemDropRule[] hmOresOne = new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltOre, 1, 20, 35), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumOre, 1, 20, 35) + }; + // 5-16 Bars @ 16.67%; Individually 8.33% + IItemDropRule[] hmBarsOne = new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltBar, 1, 5, 16), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumBar, 1, 5, 16) + }; + var cobaltDropsOres = new SequentialRulesNotScalingWithLuckRule(7, new OneFromRulesRule(2, hmOresOne), new OneFromRulesRule(1, phmOres)); + var cobaltDropsBars = new SequentialRulesNotScalingWithLuckRule(4, new OneFromRulesRule(3, 2, hmBarsOne), new OneFromRulesRule(1, phmBars)); + + adamantiteLCR.Add(adamantiteDropsOres); + adamantiteLCR.Add(adamantiteDropsBars); + adamantiteLCR.OnFailedConditions(mythrilLCR); + mythrilLCR.Add(mythrilDropsOres); + mythrilLCR.Add(mythrilDropsBars); + mythrilLCR.OnFailedConditions(cobaltDropsOres); + mythrilLCR.OnFailedConditions(cobaltDropsBars); } - lcrRegularPotion.Add(regularPots); - lcrRegularPotion.OnFailedConditions(lesserPots); - // Add the chain starting from regular potions if marked as a Pre-Hardmode crate - if (!hardMode) + else if (type == HardmodeCrateType.Mythril) { - loot.Add(lcrRegularPotion); + // Pre-Hardmode loot pools + // 12-21 Ores @ 8.33%; Individually 1.39% + IItemDropRule[] phmOres = new IItemDropRule[6] + { + ItemDropRule.NotScalingWithLuck(ItemID.CopperOre, 1, 12, 21), + ItemDropRule.NotScalingWithLuck(ItemID.TinOre, 1, 12, 21), + ItemDropRule.NotScalingWithLuck(ItemID.IronOre, 1, 12, 21), + ItemDropRule.NotScalingWithLuck(ItemID.LeadOre, 1, 12, 21), + ItemDropRule.NotScalingWithLuck(ItemID.SilverOre, 1, 12, 21), + ItemDropRule.NotScalingWithLuck(ItemID.TungstenOre, 1, 12, 21), + }; + // 4-7 Bars @ 6.94%; Individually 1.16% + IItemDropRule[] phmBars = new IItemDropRule[6] + { + ItemDropRule.NotScalingWithLuck(ItemID.CopperBar, 1, 4, 7), + ItemDropRule.NotScalingWithLuck(ItemID.TinBar, 1, 4, 7), + ItemDropRule.NotScalingWithLuck(ItemID.IronBar, 1, 4, 7), + ItemDropRule.NotScalingWithLuck(ItemID.LeadBar, 1, 4, 7), + ItemDropRule.NotScalingWithLuck(ItemID.SilverBar, 1, 4, 7), + ItemDropRule.NotScalingWithLuck(ItemID.TungstenBar, 1, 4, 7), + }; + + // Tier 2 loot pools + // 12-21 Ores @ 8.33%; Individually 2.08% + IItemDropRule[] hmOresTwo = new IItemDropRule[4] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltOre, 1, 12, 21), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumOre, 1, 12, 21), + ItemDropRule.NotScalingWithLuck(ItemID.MythrilOre, 1, 12, 21), + ItemDropRule.NotScalingWithLuck(ItemID.OrichalcumOre, 1, 12, 21) + }; + // 3-7 Bars @ 13.89%; Individually 3.47% + IItemDropRule[] hmBarsTwo = new IItemDropRule[4] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltBar, 1, 3, 7), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumBar, 1, 3, 7), + ItemDropRule.NotScalingWithLuck(ItemID.MythrilBar, 1, 3, 7), + ItemDropRule.NotScalingWithLuck(ItemID.OrichalcumBar, 1, 3, 7) + }; + var mythrilDropsOres = new SequentialRulesNotScalingWithLuckRule(6, new OneFromRulesRule(2, hmOresTwo), new OneFromRulesRule(1, phmOres)); + var mythrilDropsBars = new SequentialRulesNotScalingWithLuckRule(4, new OneFromRulesRule(3, 2, hmBarsTwo), new OneFromRulesRule(1, phmBars)); + var mythrilDrops = new SequentialRulesNotScalingWithLuckRule(1, mythrilDropsOres, mythrilDropsBars); + + // Tier 1 loot pools + // 12-21 Ores @ 8.33%; Individually 4.17% + IItemDropRule[] hmOresOne = new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltOre, 1, 12, 21), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumOre, 1, 12, 21) + }; + // 3-7 Bars @ 13.89%; Individually 6.94% + IItemDropRule[] hmBarsOne = new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltBar, 1, 3, 7), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumBar, 1, 3, 7) + }; + var cobaltDropsOres = new SequentialRulesNotScalingWithLuckRule(6, new OneFromRulesRule(2, hmOresOne), new OneFromRulesRule(1, phmOres)); + var cobaltDropsBars = new SequentialRulesNotScalingWithLuckRule(4, new OneFromRulesRule(3, 2, hmBarsOne), new OneFromRulesRule(1, phmBars)); + var cobaltDrops = new SequentialRulesNotScalingWithLuckRule(1, cobaltDropsOres, cobaltDropsBars); + + mythrilLCR.Add(mythrilDrops); + mythrilLCR.OnFailedConditions(cobaltDrops); + loot.Add(mythrilLCR); // No Adamantite LCR here so we need to add this in + } + else if (type == HardmodeCrateType.Titanium) + { + // Pre-Hardmode loot pools + // 25-34 Ores @ 10%; Individually 2.5% + IItemDropRule[] phmOres = new IItemDropRule[4] + { + ItemDropRule.NotScalingWithLuck(ItemID.SilverOre, 1, 25, 34), + ItemDropRule.NotScalingWithLuck(ItemID.TungstenOre, 1, 25, 34), + ItemDropRule.NotScalingWithLuck(ItemID.GoldOre, 1, 25, 34), + ItemDropRule.NotScalingWithLuck(ItemID.PlatinumOre, 1, 25, 34) + }; + // 8-11 Bars @ 8.89%; Individually 2.22% + IItemDropRule[] phmBars = new IItemDropRule[4] + { + ItemDropRule.NotScalingWithLuck(ItemID.SilverBar, 1, 8, 11), + ItemDropRule.NotScalingWithLuck(ItemID.TungstenBar, 1, 8, 11), + ItemDropRule.NotScalingWithLuck(ItemID.GoldBar, 1, 8, 11), + ItemDropRule.NotScalingWithLuck(ItemID.PlatinumBar, 1, 8, 11) + }; + + // Tier 3 loot pools + // 25-34 Ores @ 10%; Individually 2.5% + IItemDropRule[] hmOresThree = new IItemDropRule[4] + { + ItemDropRule.NotScalingWithLuck(ItemID.MythrilOre, 1, 25, 34), + ItemDropRule.NotScalingWithLuck(ItemID.OrichalcumOre, 1, 25, 34), + ItemDropRule.NotScalingWithLuck(ItemID.AdamantiteOre, 1, 25, 34), + ItemDropRule.NotScalingWithLuck(ItemID.TitaniumOre, 1, 25, 34) + }; + // 8-11 Bars @ 17.78%; Individually 4.44% + IItemDropRule[] hmBarsThree = new IItemDropRule[4] + { + ItemDropRule.NotScalingWithLuck(ItemID.MythrilBar, 1, 8, 11), + ItemDropRule.NotScalingWithLuck(ItemID.OrichalcumBar, 1, 8, 11), + ItemDropRule.NotScalingWithLuck(ItemID.AdamantiteBar, 1, 8, 11), + ItemDropRule.NotScalingWithLuck(ItemID.TitaniumBar, 1, 8, 11) + }; + var adamantiteDropsOres = new SequentialRulesNotScalingWithLuckRule(5, new OneFromRulesRule(2, hmOresThree), new OneFromRulesRule(1, phmOres)); + var adamantiteDropsBars = new SequentialRulesNotScalingWithLuckRule(3, new OneFromRulesRule(3, 2, hmBarsThree), new OneFromRulesRule(1, phmBars)); + var adamantiteDrops = new SequentialRulesNotScalingWithLuckRule(1, adamantiteDropsOres, adamantiteDropsBars); + + // Tier 2 loot pools + // 25-34 Ores @ 10%; Individually 5% + IItemDropRule[] hmOresTwo = new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ItemID.MythrilOre, 1, 25, 34), + ItemDropRule.NotScalingWithLuck(ItemID.OrichalcumOre, 1, 25, 34) + }; + // 8-11 Bars @ 17.78%; Individually 8.89% + IItemDropRule[] hmBarsTwo = new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ItemID.MythrilBar, 1, 8, 11), + ItemDropRule.NotScalingWithLuck(ItemID.OrichalcumBar, 1, 8, 11) + }; + var mythrilDropsOres = new SequentialRulesNotScalingWithLuckRule(5, new OneFromRulesRule(2, hmOresTwo), new OneFromRulesRule(1, phmOres)); + var mythrilDropsBars = new SequentialRulesNotScalingWithLuckRule(3, new OneFromRulesRule(3, 2, hmBarsTwo), new OneFromRulesRule(1, phmBars)); + var mythrilDrops = new SequentialRulesNotScalingWithLuckRule(1, mythrilDropsOres, mythrilDropsBars); + + // Tier 1 loot pools + // EXCEPTION: Titanium Crates do not drop Cobalt. This is added to make it not entirely useless to get early. + // 25-34 Ores @ 10%; Individually 5% + IItemDropRule[] hmOresOne = new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltOre, 1, 25, 34), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumOre, 1, 25, 34) + }; + // 8-11 Bars @ 17.78%; Individually 8.89% + IItemDropRule[] hmBarsOne = new IItemDropRule[2] + { + ItemDropRule.NotScalingWithLuck(ItemID.CobaltBar, 1, 8, 11), + ItemDropRule.NotScalingWithLuck(ItemID.PalladiumBar, 1, 8, 11) + }; + var cobaltDropsOres = new SequentialRulesNotScalingWithLuckRule(5, new OneFromRulesRule(2, hmOresOne), new OneFromRulesRule(1, phmOres)); + var cobaltDropsBars = new SequentialRulesNotScalingWithLuckRule(3, new OneFromRulesRule(3, 2, hmBarsOne), new OneFromRulesRule(1, phmBars)); + var cobaltDrops = new SequentialRulesNotScalingWithLuckRule(1, cobaltDropsOres, cobaltDropsBars); + + adamantiteLCR.Add(adamantiteDrops); + adamantiteLCR.OnFailedConditions(mythrilLCR); + mythrilLCR.Add(mythrilDrops); + mythrilLCR.OnFailedConditions(cobaltDrops); } } #endregion @@ -484,10 +753,29 @@ public static IItemDropRuleCondition If(Func lambda, Func #endregion #region Drop Rule Conditions + public static IItemDropRuleCondition MythrilCondition = If((info) => + { + // If the Early Hardmode Progression Rework is not enabled, then Mythril/Orichalcum can always drop. + if (!CalamityServerConfig.Instance.EarlyHardmodeProgressionRework) + return true; + + // If the Early Hardmode Progression Rework is enabled, then any Mechanical Boss must be defeated for Mythril/Orichalcum to drop. + return NPC.downedMechBossAny; + }); + public static IItemDropRuleCondition AdamantiteCondition = If((info) => + { + // If the Early Hardmode Progression Rework is not enabled, then Adamantite/Titanium can always drop. + if (!CalamityServerConfig.Instance.EarlyHardmodeProgressionRework) + return true; + + // If the Early Hardmode Progression Rework is enabled, then 2 of the Mechanical Bosses must be defeated for Adamantite/Titanium to drop. + return (NPC.downedMechBoss1 && NPC.downedMechBoss2) || (NPC.downedMechBoss2 && NPC.downedMechBoss3) || (NPC.downedMechBoss1 && NPC.downedMechBoss3); + }); + public static IItemDropRuleCondition HallowedBarsCondition = If((info) => { // If the Early Hardmode Progression Rework is not enabled, then Hallowed Bars can always drop from Mechanical Bosses. - if (!CalamityConfig.Instance.EarlyHardmodeProgressionRework) + if (!CalamityServerConfig.Instance.EarlyHardmodeProgressionRework) return true; // If the Early Hardmode Progression Rework is enabled, then all 3 Mechanical Bosses must be defeated for Hallowed Bars to drop. 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..2fd2cd83bf 100644 --- a/Utilities/MiscUtils.cs +++ b/Utilities/MiscUtils.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using CalamityMod.Items.Tools.ClimateChange; +using CalamityMod.Systems; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Graphics; @@ -195,7 +196,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 +246,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 +290,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..db2b613d5c 100644 --- a/Utilities/PlayerUtils.cs +++ b/Utilities/PlayerUtils.cs @@ -322,16 +322,29 @@ public static bool CheckSolidGround(this Player player, int solidGroundAhead = 0 } return ConditionMet; } + + /// + /// Disables the default wing flap sound from vanilla; this is to stop custom wings playing this sound when they shouldnt + /// This must be called each update (eg, in the wings item UpdateAccessory method) + /// + /// The Player to disable the sound on + public static void DisableWingFlapSound(this Player player) + { + // vanilla plays a flap sound for all wings barring a few hardcoded exceptions + // the flapSound flag is used to see if the sound *has been* played, so we set it to true here to prevent it from playing + player.flapSound = true; + } + #endregion #region Location and Biomes 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 +480,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..2de2365d47 100644 --- a/Utilities/TileUtils.cs +++ b/Utilities/TileUtils.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using CalamityMod.Tiles; using CalamityMod.Tiles.Abyss; using CalamityMod.Tiles.Astral; @@ -103,6 +104,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) @@ -234,7 +238,7 @@ public static bool AnySolidTileInSelection(int x, int y, int width, int height) { for (int j = y; j != y + height; j += Math.Sign(height)) { - if (WorldGen.InWorld(i, j)) + if (!WorldGen.InWorld(i, j)) continue; if (WorldGen.SolidTile(Framing.GetTileSafely(i, j))) @@ -517,6 +521,41 @@ public static void MergeDecorativeTiles(int type) SetMerge(type, TileType()); } + /// + /// The X position of the Tile + /// + /// + /// + public static int X(this Tile tile) + { + TilePos(tile, out int x, out _); + return x; + } + + /// + /// The Y position of the Tile + /// + /// + /// + public static int Y(this Tile tile) + { + TilePos(tile, out _, out int y); + return y; + } + + /// + /// Gets the Position of the tile, the same values that would be inputted in Main.tile to get this Tile + /// + /// + /// The outputted X value, if you want the X by itself use Tile.X + /// The outputted Y value, if you want the Y by itself use Tile.Y + public static void TilePos(this Tile tile, out int x, out int y) + { + uint tileId = Unsafe.BitCast(tile); + x = Math.DivRem((int)tileId, Main.tile.Height, out y); //Thanks to FoxXD_ for the help with this + } + + /// /// Determines if a tile is solid ground based on whether it's active and not actuated or if the tile is solid in any way, including just the top. /// diff --git a/Utilities/WorldgenUtils.cs b/Utilities/WorldgenUtils.cs index 1c18796fbb..b7317bfdfd 100644 --- a/Utilities/WorldgenUtils.cs +++ b/Utilities/WorldgenUtils.cs @@ -155,6 +155,10 @@ public static void AddProtectedStructure(Rectangle area, int padding = 0) // If Fargo's Mutant Mod is loaded, add to their Indestructible Rectangle list, which prevents structures from being trashed by Fargo's terrain tools. Mod fargos = CalamityMod.Instance.fargos; + paddedArea.X *= 16; + paddedArea.Y *= 16; + paddedArea.Width *= 16; + paddedArea.Height *= 16; fargos?.Call("AddIndestructibleRectangle", paddedArea); } } 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/Waters/AstralWater.cs b/Waters/AstralWater.cs index 7064c4fadf..7928f6d6dd 100644 --- a/Waters/AstralWater.cs +++ b/Waters/AstralWater.cs @@ -1,4 +1,7 @@ -using Microsoft.Xna.Framework; +using CalamityMod.Dusts.WaterSplash; +using CalamityMod.Gores.WaterDroplet; +using CalamityMod.Systems; +using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using ReLogic.Content; using Terraria; @@ -6,13 +9,15 @@ namespace CalamityMod.Waters { - public class AstralWater : ModWaterStyle + public class AstralWaterflow : ModWaterfallStyle { } + + public class AstralWater : CalamityModWaterStyle { public override int ChooseWaterfallStyle() => ModContent.Find("CalamityMod/AstralWaterflow").Slot; - public override int GetSplashDust() => 52; //corruption water? - public override int GetDropletGore() => ModContent.Find("CalamityMod/AstralWaterDroplet").Type; + public override int GetSplashDust() => ModContent.DustType(); + public override int GetDropletGore() => ModContent.GoreType(); public override Asset GetRainTexture() => ModContent.Request("CalamityMod/Waters/AstralRain"); public override byte GetRainVariant() => (byte)Main.rand.Next(3); - public override Color BiomeHairColor() => Color.MediumPurple; + public override Color BiomeHairColor() => new Color(93, 78, 107); } } diff --git a/Waters/AstralWaterflow.cs b/Waters/AstralWaterflow.cs deleted file mode 100644 index 76e3fc81d6..0000000000 --- a/Waters/AstralWaterflow.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Terraria.ModLoader; -namespace CalamityMod.Waters -{ - public class AstralWaterflow : ModWaterfallStyle - { - - } -} diff --git a/Waters/CragsLava.cs b/Waters/CragsLava.cs new file mode 100644 index 0000000000..3654038bbd --- /dev/null +++ b/Waters/CragsLava.cs @@ -0,0 +1,38 @@ +using CalamityMod.Buffs.DamageOverTime; +using CalamityMod.CalPlayer; +using CalamityMod.Items.Accessories; +using CalamityMod.Systems; +using Microsoft.Xna.Framework; +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; +using CalamityMod.Dusts.WaterSplash; +using CalamityMod.Gores.WaterDroplet; + +namespace CalamityMod.Waters +{ + public class CragsLava : ModLavaStyle + { + public override string WaterfallTexture => "CalamityMod/Waters/CragsLavaflow"; + + public override int GetSplashDust() => ModContent.DustType(); + + public override int GetDropletGore() => ModContent.GoreType(); + + public override bool IsLavaActive() => Main.LocalPlayer.Calamity().ZoneCalamity || Main.LocalPlayer.Calamity().BrimstoneLavaFountainCounter > 0; + + public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) + { + r = 2.48f / 4; + g = 1.05f / 4; + b = 0.98f / 4; + } + + public override void InflictDebuff(Player player, int onfireDuration) + { + // Extra DoT in the lava of the crags. Negated by Flame-licked Shell. + if (!player.Calamity().flameLickedShell) + player.AddBuff(ModContent.BuffType(), 2, false); + } + } +} diff --git a/Waters/CragsLavaStyle.cs b/Waters/CragsLavaStyle.cs deleted file mode 100644 index 6ffe68bed0..0000000000 --- a/Waters/CragsLavaStyle.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Microsoft.Xna.Framework; -using Terraria; -using Terraria.ModLoader; - -namespace CalamityMod.Waters -{ - public class CragsLavaflow : ModWaterfallStyle { } - - public class CragsLavaStyle : CustomLavaStyle - { - public override string LavaTexturePath => "CalamityMod/Waters/CragsLava"; - - public override string BlockTexturePath => LavaTexturePath + "_Block"; - - public override string SlopeTexturePath => LavaTexturePath + "_Slope"; - - public override bool ChooseLavaStyle() => Main.LocalPlayer.Calamity().ZoneCalamity || Main.LocalPlayer.Calamity().BrimstoneLavaFountainCounter > 0; - - public override int ChooseWaterfallStyle() => ModContent.Find("CalamityMod/CragsLavaflow").Slot; - - public override int GetSplashDust() => 0; - - public override int GetDropletGore() => 0; - - public override void SelectLightColor(ref Color initialLightColor) - { - initialLightColor = Color.Lerp(initialLightColor, Color.White, 0.5f); - initialLightColor.A = 255; - } - } -} diff --git a/Waters/CustomLavaManagement.cs b/Waters/CustomLavaManagement.cs deleted file mode 100644 index e4018ddb5d..0000000000 --- a/Waters/CustomLavaManagement.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using ReLogic.Content; -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; -using Terraria.ModLoader.Core; - -namespace CalamityMod.Waters -{ - // TODO -- This can be made into a ModSystem with simple OnModLoad and Unload hooks. - public static class CustomLavaManagement - { - internal static List CustomLavaStyles; - internal static Texture2D LavaBlockTexture; - internal static Texture2D LavaTexture; - internal static Texture2D LavaSlopeTexture; - - // The IL Edits are loaded separately. - internal static void Load() - { - CustomLavaStyles = new List(); - - Type[] types = AssemblyManager.GetLoadableTypes(CalamityMod.Instance.Code); - foreach (Type type in types) - { - // Ignore abstract types; they cannot have instances. - // Also ignore types which do not derive from CustomLavaStyle. - if (!type.IsSubclassOf(typeof(CustomLavaStyle)) || type.IsAbstract) - continue; - - CustomLavaStyles.Add(Activator.CreateInstance(type) as CustomLavaStyle); - CustomLavaStyles.Last().Load(); - } - - if (Main.netMode != NetmodeID.Server) - { - LavaBlockTexture = ModContent.Request("Terraria/Images/Liquid_1", AssetRequestMode.ImmediateLoad).Value; - LavaTexture = ModContent.Request("Terraria/Images/Misc/water_1", AssetRequestMode.ImmediateLoad).Value; - LavaSlopeTexture = ModContent.Request("Terraria/Images/LiquidSlope_1", AssetRequestMode.ImmediateLoad).Value; - } - } - - internal static void Unload() - { - if (CustomLavaStyles != null) - foreach (CustomLavaStyle lavaStyle in CustomLavaStyles) - lavaStyle?.Unload(); - - CustomLavaStyles = null; - LavaBlockTexture = null; - LavaTexture = null; - } - - internal static int SelectLavafallStyle(int initialLavafallStyle) - { - // Lava waterfall. - if (initialLavafallStyle != 1) - return initialLavafallStyle; - - foreach (CustomLavaStyle lavaStyle in CustomLavaStyles) - { - int waterfallStyle = lavaStyle.ChooseWaterfallStyle(); - if (lavaStyle.ChooseLavaStyle() && waterfallStyle >= 0) - return waterfallStyle; - } - - return initialLavafallStyle; - } - - internal static Color SelectLavafallColor(int initialLavafallStyle, Color initialLavafallColor) - { - // Lava waterfall. - if (initialLavafallStyle != 1) - return initialLavafallColor; - - foreach (CustomLavaStyle lavaStyle in CustomLavaStyles) - { - if (lavaStyle.ChooseLavaStyle()) - { - lavaStyle.SelectLightColor(ref initialLavafallColor); - return initialLavafallColor; - } - } - - return initialLavafallColor; - } - } -} diff --git a/Waters/CustomLavaStyle.cs b/Waters/CustomLavaStyle.cs deleted file mode 100644 index 5059a1134d..0000000000 --- a/Waters/CustomLavaStyle.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using ReLogic.Content; -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; - -namespace CalamityMod.Waters -{ - public abstract class CustomLavaStyle - { - internal Texture2D LavaTexture; - internal Texture2D BlockTexture; - internal Texture2D SlopeTexture; - - internal void Load() - { - // Don't load textures serverside. - if (Main.netMode == NetmodeID.Server) - return; - - LavaTexture = ModContent.Request(LavaTexturePath, AssetRequestMode.ImmediateLoad).Value; - BlockTexture = ModContent.Request(BlockTexturePath, AssetRequestMode.ImmediateLoad).Value; - SlopeTexture = ModContent.Request(SlopeTexturePath, AssetRequestMode.ImmediateLoad).Value; - } - - internal void Unload() - { - LavaTexture = null; - BlockTexture = null; - } - - public abstract string LavaTexturePath { get; } - - public abstract string BlockTexturePath { get; } - - public abstract string SlopeTexturePath { get; } - - public virtual bool ChooseLavaStyle() => false; - - public abstract int ChooseWaterfallStyle(); - - public abstract int GetSplashDust(); - - public abstract int GetDropletGore(); - - public virtual void SelectLightColor(ref Color initialLightColor) - { - } - } -} diff --git a/Waters/IWaterfallWithAlphaChange.cs b/Waters/IWaterfallWithAlphaChange.cs new file mode 100644 index 0000000000..9c2fa326a9 --- /dev/null +++ b/Waters/IWaterfallWithAlphaChange.cs @@ -0,0 +1,7 @@ +namespace CalamityMod.Waters +{ + public interface IWaterfallWithAlphaChange + { + void ModifyAlpha(ref float a); + } +} diff --git a/Waters/LiquidTileType.cs b/Waters/LiquidTileType.cs deleted file mode 100644 index 594a74731d..0000000000 --- a/Waters/LiquidTileType.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace CalamityMod.Waters -{ - public enum LiquidTileType - { - Block, - Waterflow, - Slope - } -} diff --git a/Waters/MiddleAbyssWater.cs b/Waters/MiddleAbyssWater.cs index 1c7f8250f8..bb0d27c08c 100644 --- a/Waters/MiddleAbyssWater.cs +++ b/Waters/MiddleAbyssWater.cs @@ -1,28 +1,26 @@ -using Microsoft.Xna.Framework; +using CalamityMod.Dusts.WaterSplash; +using CalamityMod.Gores.WaterDroplet; +using CalamityMod.Systems; +using Microsoft.Xna.Framework; +using Terraria.Graphics; using Terraria.ModLoader; namespace CalamityMod.Waters { - public class MiddleAbyssWater : ModWaterStyle + public class MiddleAbyssWaterflow : ModWaterfallStyle, IWaterfallWithAlphaChange { - public override int ChooseWaterfallStyle() + public void ModifyAlpha(ref float a) { - return ModContent.Find("CalamityMod/MiddleAbyssWaterflow").Slot; - } - - public override int GetSplashDust() - { - return 33; - } - - public override int GetDropletGore() - { - return 713; + a *= 0.333f; } + } - public override Color BiomeHairColor() - { - return Color.Blue; - } + public class MiddleAbyssWater : CalamityModWaterStyle + { + public override int ChooseWaterfallStyle() => ModContent.Find("CalamityMod/MiddleAbyssWaterflow").Slot; + public override int GetSplashDust() => ModContent.DustType(); + public override int GetDropletGore() => ModContent.GoreType(); + public override Color BiomeHairColor() => new Color(36, 23, 19); + public override void DrawColor(int x, int y, ref VertexColors liquidColor, bool isSlope) => ILEditing.ILChanges.SelectSulphuricWaterColor(x, y, ref liquidColor, isSlope); } } diff --git a/Waters/MiddleAbyssWaterflow.cs b/Waters/MiddleAbyssWaterflow.cs deleted file mode 100644 index 0105e3024f..0000000000 --- a/Waters/MiddleAbyssWaterflow.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Terraria.ModLoader; -namespace CalamityMod.Waters -{ - public class MiddleAbyssWaterflow : ModWaterfallStyle - { - - } -} diff --git a/Waters/PissWater.cs b/Waters/PissWater.cs index 0b315df535..629614b3fe 100644 --- a/Waters/PissWater.cs +++ b/Waters/PissWater.cs @@ -1,28 +1,17 @@ -using Microsoft.Xna.Framework; +using CalamityMod.Systems; +using Microsoft.Xna.Framework; +using Terraria.ID; using Terraria.ModLoader; namespace CalamityMod.Waters { + public class PissWaterflow : ModWaterfallStyle { } + public class PissWater : ModWaterStyle { - public override int ChooseWaterfallStyle() - { - return ModContent.Find("CalamityMod/PissWaterflow").Slot; - } - - public override int GetSplashDust() - { - return 102; - } - - public override int GetDropletGore() - { - return 711; - } - - public override Color BiomeHairColor() - { - return Color.Yellow; - } + public override int ChooseWaterfallStyle() => ModContent.Find("CalamityMod/PissWaterflow").Slot; + public override int GetSplashDust() => DustID.Water_Desert; + public override int GetDropletGore() => GoreID.WaterDripDesert; + public override Color BiomeHairColor() => Color.Yellow; } } diff --git a/Waters/PissWaterflow.cs b/Waters/PissWaterflow.cs deleted file mode 100644 index a5189ea521..0000000000 --- a/Waters/PissWaterflow.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Terraria.ModLoader; -namespace CalamityMod.Waters -{ - public class PissWaterflow : ModWaterfallStyle - { - - } -} diff --git a/Waters/SulphuricDepthsWater.cs b/Waters/SulphuricDepthsWater.cs index 64aa588c33..369dbd4f90 100644 --- a/Waters/SulphuricDepthsWater.cs +++ b/Waters/SulphuricDepthsWater.cs @@ -1,33 +1,40 @@ -using Microsoft.Xna.Framework; +using CalamityMod.Dusts.WaterSplash; +using CalamityMod.Gores.WaterDroplet; +using CalamityMod.Systems; +using CalamityMod.Tiles.Abyss; +using Microsoft.Xna.Framework; +using Terraria.Graphics; using Terraria.ModLoader; namespace CalamityMod.Waters { - public class SulphuricDepthsWater : ModWaterStyle + public class SulphuricDepthsWaterflow : ModWaterfallStyle, IWaterfallWithAlphaChange { - public static int Type; - public override void SetStaticDefaults() + public void ModifyAlpha(ref float a) { - Type = Slot; - } - public override int ChooseWaterfallStyle() - { - return ModContent.Find("CalamityMod/SulphuricDepthsWaterflow").Slot; - } - - public override int GetSplashDust() - { - return 33; - } - - public override int GetDropletGore() - { - return 713; + a *= 0.333f; } + } - public override Color BiomeHairColor() + public class SulphuricDepthsWater : CalamityModWaterStyle + { + public override int ChooseWaterfallStyle() => ModContent.Find("CalamityMod/SulphuricDepthsWaterflow").Slot; + public override int GetSplashDust() => ModContent.DustType(); + public override int GetDropletGore() => ModContent.GoreType(); + public override Color BiomeHairColor() => new Color(35, 117, 89); + public override void DrawColor(int x, int y, ref VertexColors liquidColor, bool isSlope) => ILEditing.ILChanges.SelectSulphuricWaterColor(x, y, ref liquidColor, isSlope); + public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) { - return Color.Teal; + Vector3 outputColor = new Vector3(r, g, b); + if (outputColor == Vector3.One || outputColor == new Vector3(0.25f, 0.25f, 0.25f) || outputColor == new Vector3(0.5f, 0.5f, 0.5f)) + return; + if (CalamityUtils.ParanoidTileRetrieval(i, j).TileType != (ushort)ModContent.TileType()) + { + outputColor = Vector3.Lerp(outputColor, Color.MediumSeaGreen.ToVector3(), 0.18f); + } + r = outputColor.X; + g = outputColor.Y; + b = outputColor.Z; } } } diff --git a/Waters/SulphuricDepthsWaterflow.cs b/Waters/SulphuricDepthsWaterflow.cs deleted file mode 100644 index 5cf86274ff..0000000000 --- a/Waters/SulphuricDepthsWaterflow.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Terraria.ModLoader; -namespace CalamityMod.Waters -{ - public class SulphuricDepthsWaterflow : ModWaterfallStyle - { - - } -} diff --git a/Waters/SulphuricWater.cs b/Waters/SulphuricWater.cs index ef9ce540ea..6c448991b5 100644 --- a/Waters/SulphuricWater.cs +++ b/Waters/SulphuricWater.cs @@ -1,23 +1,109 @@ -using Microsoft.Xna.Framework; +using System; +using CalamityMod.Dusts.WaterSplash; +using CalamityMod.Gores.WaterDroplet; +using CalamityMod.Particles; +using CalamityMod.Systems; +using CalamityMod.Tiles.Abyss; +using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using ReLogic.Content; using Terraria; +using Terraria.Graphics; using Terraria.ModLoader; namespace CalamityMod.Waters { - public class SulphuricWater : ModWaterStyle + public class SulphuricWaterflow : ModWaterfallStyle, IWaterfallWithAlphaChange { - public static int Type; - public override void SetStaticDefaults() + public void ModifyAlpha(ref float a) { - Type = Slot; + a *= 0.333f; } + } + + public class SulphuricWater : CalamityModWaterStyle + { public override int ChooseWaterfallStyle() => ModContent.Find("CalamityMod/SulphuricWaterflow").Slot; - public override int GetSplashDust() => 101; - public override int GetDropletGore() => 708; + public override int GetSplashDust() => ModContent.DustType(); + public override int GetDropletGore() => ModContent.GoreType(); public override Asset GetRainTexture() => ModContent.Request("CalamityMod/Waters/SulphuricRain"); public override byte GetRainVariant() => (byte)Main.rand.Next(3); - public override Color BiomeHairColor() => Color.Turquoise; + public override Color BiomeHairColor() => new Color(43, 168, 110); + public override void DrawColor(int x, int y, ref VertexColors liquidColor, bool isSlope) => ILEditing.ILChanges.SelectSulphuricWaterColor(x, y, ref liquidColor, isSlope); + public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) + { + Vector3 outputColor = new Vector3(r, g, b); + if (outputColor == Vector3.One || outputColor == new Vector3(0.25f, 0.25f, 0.25f) || outputColor == new Vector3(0.5f, 0.5f, 0.5f)) + return; + Tile tile = CalamityUtils.ParanoidTileRetrieval(i, j); + Tile above = CalamityUtils.ParanoidTileRetrieval(i, j - 1); + if (!Main.gamePaused && !above.HasTile && above.LiquidAmount <= 0 && Main.rand.NextBool(9)) + { + MediumMistParticle acidFoam = new(new(i * 16f + Main.rand.NextFloat(16f), j * 16f + 8f), -Vector2.UnitY.RotatedByRandom(0.67f) * Main.rand.NextFloat(1f, 2.4f), Color.LightSeaGreen, Color.White, 0.16f, 128f, 0.02f); + GeneralParticleHandler.SpawnParticle(acidFoam); + } + + if (tile.TileType != (ushort)ModContent.TileType()) + { + if (Main.dayTime && !Main.raining) + { + float brightness = MathHelper.Clamp(0.2f - (j / 680), 0f, 0.2f); + if (j > 580) + brightness *= 1f - (j - 580) / 100f; + + float waveScale1 = Main.GameUpdateCount * 0.014f; + float waveScale2 = Main.GameUpdateCount * 0.1f; + int scalar = i + (-j / 2); + float wave1 = waveScale1 * -50 + scalar * 15; + float wave2 = waveScale2 * -10 + scalar * 14; + float wave3 = waveScale1 * -100 + scalar * 13; + float wave4 = waveScale2 * 10 + scalar * 25; + float wave5 = waveScale1 * -70 + scalar * 5; + float wave1angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave1)); + float wave2angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave2)); + float wave3angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave3)); + float wave4angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave4)); + float wave5angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave5)); + outputColor = Vector3.Lerp(outputColor, Color.LightSeaGreen.ToVector3(), 0.41f + wave1angle + wave2angle + wave3angle + wave4angle + wave5angle); + outputColor *= brightness; + } + + if (!Main.dayTime && !Main.raining) + { + float brightness = MathHelper.Clamp(0.17f - (j / 680), 0f, 0.17f); + if (j > 580) + brightness *= 1f - (j - 580) / 100f; + + float waveScale1 = Main.GameUpdateCount * 0.014f; + float waveScale2 = Main.GameUpdateCount * 0.1f; + int scalar = i + (-j / 2); + float wave1 = waveScale1 * -50 + scalar * 15; + float wave2 = waveScale2 * -10 + scalar * 14; + float wave3 = waveScale1 * -100 + scalar * 13; + float wave4 = waveScale2 * 10 + scalar * 25; + float wave5 = waveScale1 * -70 + scalar * 5; + float wave1angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave1)); + float wave2angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave2)); + float wave3angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave3)); + float wave4angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave4)); + float wave5angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave5)); + outputColor = Vector3.Lerp(outputColor, Color.LightSeaGreen.ToVector3(), 0.41f + wave1angle + wave2angle + wave3angle + wave4angle + wave5angle); + outputColor *= brightness; + } + + if (Main.raining) + { + float brightness = MathHelper.Clamp(1f - (j / 680), 0f, 1f); + if (j > 580) + brightness *= 1f - (j - 580) / 100f; + + outputColor = Vector3.Lerp(outputColor, Color.LightSeaGreen.ToVector3(), 0.41f); + outputColor *= brightness; + } + } + r = outputColor.X; + g = outputColor.Y; + b = outputColor.Z; + } } } diff --git a/Waters/SulphuricWaterflow.cs b/Waters/SulphuricWaterflow.cs deleted file mode 100644 index f9ed907df3..0000000000 --- a/Waters/SulphuricWaterflow.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Terraria.ModLoader; -namespace CalamityMod.Waters -{ - public class SulphuricWaterflow : ModWaterfallStyle - { - - } -} diff --git a/Waters/SunkenSeaWater.cs b/Waters/SunkenSeaWater.cs index 62c32fbd4c..9f6e6b11cd 100644 --- a/Waters/SunkenSeaWater.cs +++ b/Waters/SunkenSeaWater.cs @@ -1,33 +1,63 @@ -using Microsoft.Xna.Framework; +using System; +using CalamityMod.Dusts.WaterSplash; +using CalamityMod.Gores.WaterDroplet; +using CalamityMod.Systems; +using CalamityMod.Tiles.Abyss; +using Microsoft.Xna.Framework; +using Terraria; +using Terraria.Graphics; using Terraria.ModLoader; namespace CalamityMod.Waters { - public class SunkenSeaWater : ModWaterStyle + public class SunkenSeaWaterflow : ModWaterfallStyle, IWaterfallWithAlphaChange { - public static int Type; - public override void SetStaticDefaults() + public void ModifyAlpha(ref float a) { - Type = Slot; - } - public override int ChooseWaterfallStyle() - { - return ModContent.Find("CalamityMod/SunkenSeaWaterflow").Slot; - } - - public override int GetSplashDust() - { - return 33; + a *= 0.333f; } + } - public override int GetDropletGore() + public class SunkenSeaWater : CalamityModWaterStyle + { + public override int ChooseWaterfallStyle() => ModContent.Find("CalamityMod/SunkenSeaWaterflow").Slot; + public override int GetSplashDust() => ModContent.DustType(); + public override int GetDropletGore() => ModContent.GoreType(); + public override Color BiomeHairColor() => new Color(46, 155, 171); + public override void DrawColor(int x, int y, ref VertexColors liquidColor, bool isSlope) => ILEditing.ILChanges.SelectSulphuricWaterColor(x, y, ref liquidColor, isSlope); + public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) { - return 713; - } + Vector3 outputColor = new Vector3(r, g, b); + if (outputColor == Vector3.One || outputColor == new Vector3(0.25f, 0.25f, 0.25f) || outputColor == new Vector3(0.5f, 0.5f, 0.5f)) + return; - public override Color BiomeHairColor() - { - return Color.Blue; + if (CalamityUtils.ParanoidTileRetrieval(i, j).TileType != (ushort)ModContent.TileType()) + { + float brightness = MathHelper.Clamp(0.07f, 0f, 0.07f); + float waveScale1 = Main.GameUpdateCount * 0.028f; + float waveScale2 = Main.GameUpdateCount * 0.1f; + int yScale = -j / 2; + int xScale = i / 15; + float wave1 = Main.GameUpdateCount * 0.024f * -50 + ((-i / 30) + (j / 30)) * 25; + float wave2 = waveScale2 * -10 + ((-xScale) + yScale) * 45; + float wave3 = waveScale1 * -100 + ((i / 7) + (j / 50)) * 25; + float wave4 = Main.GameUpdateCount * 0.15f * 10 + ((i / 3) + yScale) * 45; + float wave5 = waveScale1 * -70 + ((-i / 25) + (-j / 25)) * 20; + float wave6 = waveScale2 * -10 + (xScale + yScale) * 45; + float bigwave = Main.GameUpdateCount * 0.01f * -70 + ((-i / 2) + (-j / 40)) * 5; + float wave1angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave1)); + float wave2angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave2)); + float wave3angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave3)); + float wave4angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave4)); + float wave5angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave5)); + float wave6angle = 0.55f + 0.45f * (float)Math.Sin(MathHelper.ToRadians(wave6)); + float bigwaveangle = 0.55f + 0.80f * (float)Math.Sin(MathHelper.ToRadians(bigwave)); + outputColor = Vector3.Lerp(outputColor, Color.DeepSkyBlue.ToVector3(), 0.07f + wave1angle + wave2angle + wave3angle + wave4angle + wave5angle + wave6angle + bigwaveangle); + outputColor *= brightness; + } + r = outputColor.X; + g = outputColor.Y; + b = outputColor.Z; } } } diff --git a/Waters/SunkenSeaWaterflow.cs b/Waters/SunkenSeaWaterflow.cs deleted file mode 100644 index ae61284b07..0000000000 --- a/Waters/SunkenSeaWaterflow.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Terraria.ModLoader; -namespace CalamityMod.Waters -{ - public class SunkenSeaWaterflow : ModWaterfallStyle - { - - } -} diff --git a/Waters/UpperAbyssWater.cs b/Waters/UpperAbyssWater.cs index 965861fdf7..7cc733466a 100644 --- a/Waters/UpperAbyssWater.cs +++ b/Waters/UpperAbyssWater.cs @@ -1,28 +1,26 @@ -using Microsoft.Xna.Framework; +using CalamityMod.Dusts.WaterSplash; +using CalamityMod.Gores.WaterDroplet; +using CalamityMod.Systems; +using Microsoft.Xna.Framework; +using Terraria.Graphics; using Terraria.ModLoader; namespace CalamityMod.Waters { - public class UpperAbyssWater : ModWaterStyle + public class UpperAbyssWaterflow : ModWaterfallStyle, IWaterfallWithAlphaChange { - public override int ChooseWaterfallStyle() + public void ModifyAlpha(ref float a) { - return ModContent.Find("CalamityMod/UpperAbyssWaterflow").Slot; - } - - public override int GetSplashDust() - { - return 33; - } - - public override int GetDropletGore() - { - return 713; + a *= 0.333f; } + } - public override Color BiomeHairColor() - { - return Color.Blue; - } + public class UpperAbyssWater : CalamityModWaterStyle + { + public override int ChooseWaterfallStyle() => ModContent.Find("CalamityMod/UpperAbyssWaterflow").Slot; + public override int GetSplashDust() => ModContent.DustType(); + public override int GetDropletGore() => ModContent.GoreType(); + public override Color BiomeHairColor() => new Color(9, 69, 82); + public override void DrawColor(int x, int y, ref VertexColors liquidColor, bool isSlope) => ILEditing.ILChanges.SelectSulphuricWaterColor(x, y, ref liquidColor, isSlope); } } diff --git a/Waters/UpperAbyssWaterflow.cs b/Waters/UpperAbyssWaterflow.cs deleted file mode 100644 index e61de17827..0000000000 --- a/Waters/UpperAbyssWaterflow.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Terraria.ModLoader; -namespace CalamityMod.Waters -{ - public class UpperAbyssWaterflow : ModWaterfallStyle - { - - } -} diff --git a/Waters/VoidWater.cs b/Waters/VoidWater.cs index bff3e0bf78..3f2c461d92 100644 --- a/Waters/VoidWater.cs +++ b/Waters/VoidWater.cs @@ -1,28 +1,26 @@ -using Microsoft.Xna.Framework; +using CalamityMod.Dusts.WaterSplash; +using CalamityMod.Gores.WaterDroplet; +using CalamityMod.Systems; +using Microsoft.Xna.Framework; +using Terraria.Graphics; using Terraria.ModLoader; namespace CalamityMod.Waters { - public class VoidWater : ModWaterStyle + public class VoidWaterflow : ModWaterfallStyle, IWaterfallWithAlphaChange { - public override int ChooseWaterfallStyle() + public void ModifyAlpha(ref float a) { - return ModContent.Find("CalamityMod/VoidWaterflow").Slot; - } - - public override int GetSplashDust() - { - return 33; - } - - public override int GetDropletGore() - { - return 713; + a *= 0.333f; } + } - public override Color BiomeHairColor() - { - return Color.Blue; - } + public class VoidWater : CalamityModWaterStyle + { + public override int ChooseWaterfallStyle() => ModContent.Find("CalamityMod/VoidWaterflow").Slot; + public override int GetSplashDust() => ModContent.DustType(); + public override int GetDropletGore() => ModContent.GoreType(); + public override Color BiomeHairColor() => new Color(16, 8, 30); + public override void DrawColor(int x, int y, ref VertexColors liquidColor, bool isSlope) => ILEditing.ILChanges.SelectSulphuricWaterColor(x, y, ref liquidColor, isSlope); } } diff --git a/Waters/VoidWaterflow.cs b/Waters/VoidWaterflow.cs deleted file mode 100644 index bb408bd108..0000000000 --- a/Waters/VoidWaterflow.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Terraria.ModLoader; -namespace CalamityMod.Waters -{ - public class VoidWaterflow : ModWaterfallStyle - { - - } -} 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/Planets/MudPlanet.cs b/World/Planets/MudPlanet.cs index 97113e4681..8b7cfa9dee 100644 --- a/World/Planets/MudPlanet.cs +++ b/World/Planets/MudPlanet.cs @@ -212,8 +212,8 @@ public void PlacePlanet(Point origin, int radius) private int[] BarLoot = new int[] { - GenVars.copperBar == TileID.Copper ? ItemID.CopperBar : ItemID.TinBar, - GenVars.ironBar == TileID.Iron ? ItemID.IronBar : ItemID.LeadBar + GenVars.copper == TileID.Copper ? ItemID.CopperBar : ItemID.TinBar, + GenVars.iron == TileID.Iron ? ItemID.IronBar : ItemID.LeadBar }; private void FillChest(int id) 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..3d4610236c 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.7.2 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