From 5556791d509fdb55147bb47e534c2055e08a2db9 Mon Sep 17 00:00:00 2001 From: Alex <87573461+MatteSevai@users.noreply.github.com> Date: Fri, 23 May 2025 18:01:20 -0700 Subject: [PATCH 01/11] AdventureItem.cs: Spectre Pickaxe can break Temple brick --- AdventureItem.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/AdventureItem.cs b/AdventureItem.cs index b5c4454a..c525f4ec 100644 --- a/AdventureItem.cs +++ b/AdventureItem.cs @@ -16,6 +16,17 @@ public class AdventureItem : GlobalItem ItemID.Sets.Factory.CreateBoolSet(ItemID.MagicMirror, ItemID.CellPhone, ItemID.IceMirror, ItemID.Shellphone, ItemID.ShellphoneSpawn); + public class PickaxeAdjustments : GlobalItem + { + public override void SetDefaults(Item item) + { + if (item.type == ItemID.SpectrePickaxe || item.type == ItemID.ShroomiteDiggingClaw) + { + item.pick = 210; + } + } + } + public override void SetDefaults(Item item) { var adventureConfig = ModContent.GetInstance(); From 1117279f72b337a91d08c1b2bb549675a42e9ca2 Mon Sep 17 00:00:00 2001 From: Alex <87573461+MatteSevai@users.noreply.github.com> Date: Fri, 23 May 2025 18:02:46 -0700 Subject: [PATCH 02/11] AdventurePlayer.cs: Added Shiny stone switch penalty --- AdventurePlayer.cs | 57 ++++++++++++++++++++++++++++++ Assets/Buff/ShinyStoneHotswap.png | Bin 0 -> 1253 bytes 2 files changed, 57 insertions(+) create mode 100644 Assets/Buff/ShinyStoneHotswap.png diff --git a/AdventurePlayer.cs b/AdventurePlayer.cs index 084d6b08..913eaf9f 100644 --- a/AdventurePlayer.cs +++ b/AdventurePlayer.cs @@ -510,6 +510,52 @@ public override bool PreKill(double damage, int hitDirection, bool pvp, ref bool return true; } + private bool hadShinyStoneLastFrame; + + public override void PostUpdateEquips() + { + // Check if Shiny Stone is equipped + bool hasShinyStone = IsShinyStoneEquipped(); + + // Apply debuff when first equipped or after respawn + if (hasShinyStone && !hadShinyStoneLastFrame) + { + Player.AddBuff(ModContent.BuffType(), 3600); // 60 seconds + } + + // Disable Shiny Stone effects while debuffed + if (Player.HasBuff(ModContent.BuffType())) + { + Player.shinyStone = false; + } + + hadShinyStoneLastFrame = hasShinyStone; + + // Check if wearing full Tiki Armor + + } + public override void OnRespawn() + { + // Re-apply debuff if equipped during respawn + if (IsShinyStoneEquipped()) + { + Player.AddBuff(ModContent.BuffType(), 900); + } + } + + private bool IsShinyStoneEquipped() + { + for (int i = 3; i < 10; i++) // Check all accessory slots + { + if (Player.armor[i].type == ItemID.ShinyStone && + (i < 7 || !Player.hideVisibleAccessory[i - 3])) + { + return true; + } + } + return false; + } + public override void Kill(double damage, int hitDirection, bool pvp, PlayerDeathReason damageSource) { // Only play kill markers on clients that we hurt that aren't ourselves @@ -851,4 +897,15 @@ public override string ToString() { return $"{Player.whoAmI}/{Player.name}/{DiscordUser?.Id}"; } +} +public class ShinyStoneHotswap : ModBuff +{ + public override string Texture => $"PvPAdventure/Assets/Buff/ShinyStoneHotswap"; + + public override void SetStaticDefaults() + { + Main.debuff[Type] = true; + Main.buffNoSave[Type] = true; + Main.buffNoTimeDisplay[Type] = false; // Show timer + } } \ No newline at end of file diff --git a/Assets/Buff/ShinyStoneHotswap.png b/Assets/Buff/ShinyStoneHotswap.png new file mode 100644 index 0000000000000000000000000000000000000000..e18d0f432eb900f533369f1c190e7a5f9748976e GIT binary patch literal 1253 zcmV#dBtE(XoR>JmOeS?cH=`Hg4jzO=bJh z?B_rn006p@gYpG5?SKwYXJURPXxb)@&#m4FfrZGs-|$D28#KBW1${n7XN$SKGy(ZQ z)jr9MqB1(uG7}#cgzxi8ZQVAlSOMdVz(5g*83v0fg*7Okg1s!t$>>~+$Xl#!kmm)& z+;%L>ZQSRv1c*SBz!E0$IxZcCRMO~@i!dzO3&`S^!g$`5jmBObzDX(<FAM11Qy*{H^kx^&K`uZr;>zrYAA%|0-b$ym=VO%1_k z7l}ksbp6=SIkOMsAX4TOewogFITDMCJ<h#G7WD19z z!ZHfDQA~$|ZnV?s%dd;jp)MnEwGjAue#ujrPQ9saQ1*WNWCU^$DI*F`e44hNtG8F% z>KA@2l=TAmof9LFDI8J?<54y}(vL^QIa*tN?u6ss;{}^d*oDsNa9f@A{N_W(M&aC? zDj0z!&qQis0)aXw(qR`mmzvmeHgK{JWiFmeD#CQ#pF9|Mj%tTj413T zO}kTh(VEg;75R!Gl#29>4^LredK%mUYThZpVt_#W*KBmrqvvh(8Ieg*p>v|_RoC>q zk58mIh^%o6BQ@&C3p*G%yf|l_6sed($4p;7GNC>rkSQE;3ez(_Ox5UlpqovYM3!pO zJtMlHytnl6HzWKzkyS?E(CuBevXsaDlFSwW;N+<~m zm$T!h58j4=@sC$irCCdxGx|40s=y zU17W@8E>n#-RP|;g*W|#RmR?p=k4>X`A(_Ufe{$255)hSfQ3(ER#pB30%Ga Date: Fri, 23 May 2025 18:04:16 -0700 Subject: [PATCH 03/11] AdventurePlayer.cs: Tiki armor KB immunity buff --- AdventurePlayer.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/AdventurePlayer.cs b/AdventurePlayer.cs index 913eaf9f..7c8343f8 100644 --- a/AdventurePlayer.cs +++ b/AdventurePlayer.cs @@ -532,6 +532,12 @@ public override void PostUpdateEquips() hadShinyStoneLastFrame = hasShinyStone; // Check if wearing full Tiki Armor + if (Player.armor[0].type == ItemID.TikiMask && + Player.armor[1].type == ItemID.TikiShirt && + Player.armor[2].type == ItemID.TikiPants) + { + Player.noKnockback = true; + } } public override void OnRespawn() From 037d8e7fcfb65b892417087b3589507f2ab1c86f Mon Sep 17 00:00:00 2001 From: EJCrispy Date: Fri, 23 May 2025 20:03:43 -0700 Subject: [PATCH 04/11] Replaced garmon's SHITTY ASS code with my COOL SHIT that makes it so that you can craft 3 of any item in a pool into any other item from that pool at shimmer. Also has some qol that can be worked on later. --- System/RecipeManager.cs | 393 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 361 insertions(+), 32 deletions(-) diff --git a/System/RecipeManager.cs b/System/RecipeManager.cs index 7f13e24a..8c8f7b40 100644 --- a/System/RecipeManager.cs +++ b/System/RecipeManager.cs @@ -1,49 +1,378 @@ using System.Collections.Generic; +using System.Linq; using Terraria; using Terraria.ID; +using Terraria.Localization; using Terraria.ModLoader; namespace PvPAdventure.System { - [Autoload] - public class RecipeManager : ModSystem - { - private readonly List> _lootTables = - [ - [ItemID.FlyingKnife, ItemID.DaedalusStormbow, ItemID.CrystalVileShard, ItemID.IlluminantHook], - [ItemID.ChainGuillotines, ItemID.DartRifle, ItemID.ClingerStaff, ItemID.PutridScent, ItemID.WormHook], - [ItemID.FetidBaghnakhs, ItemID.DartPistol, ItemID.SoulDrain, ItemID.FleshKnuckles, ItemID.TendonHook], - [ItemID.TitanGlove, ItemID.MagicDagger, ItemID.StarCloak, ItemID.CrossNecklace, ItemID.PhilosophersStone, ItemID.DualHook], - [ItemID.RazorbladeTyphoon, ItemID.Flairon, ItemID.BubbleGun, ItemID.Tsunami, ItemID.TempestStaff], - [ItemID.BreakerBlade, ItemID.ClockworkAssaultRifle, ItemID.LaserRifle, ItemID.FireWhip], - [ - ItemID.GolemFist, ItemID.PossessedHatchet, ItemID.Stynger, ItemID.StaffofEarth, ItemID.HeatRay, - ItemID.SunStone, ItemID.EyeoftheGolem - ], - [ItemID.Flairon, ItemID.Tsunami, ItemID.RazorbladeTyphoon, ItemID.BubbleGun, ItemID.TempestStaff] - ]; + public class AnyGolem1 : ModSystem + { + public static RecipeGroup AnyGolemPrimary; + public static int[] PrimaryItems => new int[] { + ItemID.GolemMasterTrophy, + ItemID.Stynger, + ItemID.PossessedHatchet, + ItemID.HeatRay, + ItemID.GolemFist, + ItemID.StaffofEarth + }; - public override void AddRecipes() + public override void AddRecipeGroups() + { + // Main group with trophy as first item (for icon) + AnyGolemPrimary = new RecipeGroup(() => Language.GetTextValue("Any Golem Primary"), PrimaryItems); + RecipeGroup.RegisterGroup("PvPAdventure:AnyGolemPrimary", AnyGolemPrimary); + + // Create exclude subgroups while maintaining trophy as first item + foreach (int itemID in PrimaryItems.Where(id => id != ItemID.GolemMasterTrophy)) + { + var validItems = PrimaryItems + .Where(id => id != itemID && id != ItemID.GolemMasterTrophy) + .Prepend(ItemID.GolemMasterTrophy) // Keep trophy first for icon + .ToArray(); + + RecipeGroup group = new RecipeGroup( + () => Language.GetTextValue("Any Golem Primary"), + validItems + ); + RecipeGroup.RegisterGroup($"PvPAdventure:AnyGolemPrimaryExclude{itemID}", group); + } + } + } + + public class AnyGolem2 : ModSystem + { + public static RecipeGroup AnyGolemSecondary; + public static int[] SecondaryItems => new int[] { + ItemID.GolemBossBag, + ItemID.SunStone, + ItemID.ShinyStone, + ItemID.EyeoftheGolem, + ItemID.Picksaw + }; + + public override void AddRecipeGroups() + { + // Main group with boss bag as first item (for icon) + AnyGolemSecondary = new RecipeGroup(() => Language.GetTextValue("Any Golem Secondary"), SecondaryItems); + RecipeGroup.RegisterGroup("PvPAdventure:AnyGolemSecondary", AnyGolemSecondary); + + // Create exclude subgroups while maintaining boss bag as first item + foreach (int itemID in SecondaryItems.Where(id => id != ItemID.GolemBossBag)) + { + var validItems = SecondaryItems + .Where(id => id != itemID && id != ItemID.GolemBossBag) + .Prepend(ItemID.GolemBossBag) // Keep boss bag first for icon + .ToArray(); + + RecipeGroup group = new RecipeGroup( + () => Language.GetTextValue("Any Golem Secondary"), + validItems + ); + RecipeGroup.RegisterGroup($"PvPAdventure:AnyGolemSecondaryExclude{itemID}", group); + } + } + } + + public class AnyQueenSlime1 : ModSystem + { + public static RecipeGroup AnyQueenSlimePrimary; + public static int[] PrimaryItems => new int[] { + ItemID.QueenSlimeMasterTrophy, + ItemID.Smolstar, + ItemID.QueenSlimeHook, + ItemID.QueenSlimeMountSaddle, + }; + + public override void AddRecipeGroups() + { + // Main group with trophy as first item (for icon) + AnyQueenSlimePrimary = new RecipeGroup(() => Language.GetTextValue("Any Queen Slime Primary"), PrimaryItems); + RecipeGroup.RegisterGroup("PvPAdventure:AnyQueenSlimePrimary", AnyQueenSlimePrimary); + + // Create exclude subgroups while maintaining icon as first item + foreach (int itemID in PrimaryItems.Where(id => id != ItemID.QueenSlimeMasterTrophy)) + { + var validItems = PrimaryItems + .Where(id => id != itemID && id != ItemID.QueenSlimeMasterTrophy) + .Prepend(ItemID.QueenSlimeMasterTrophy) // Keep item first for icon + .ToArray(); + + RecipeGroup group = new RecipeGroup( + () => Language.GetTextValue("Any Queen Slime Primary"), + validItems + ); + RecipeGroup.RegisterGroup($"PvPAdventure:AnyQueenSlimePrimaryExclude{itemID}", group); + } + } + } + + public class AnyPlantera1 : ModSystem + { + public static RecipeGroup AnyPlanteraPrimary; + public static int[] PrimaryItems => new int[] { + ItemID.PlanteraMasterTrophy, + ItemID.GrenadeLauncher, + ItemID.LeafBlower, + ItemID.WaspGun, + ItemID.NettleBurst, + ItemID.FlowerPow, + ItemID.VenusMagnum, + ItemID.Seedler, + }; + + public override void AddRecipeGroups() + { + // Main group with trophy as first item (for icon) + AnyPlanteraPrimary = new RecipeGroup(() => Language.GetTextValue("Any Plantera Drop"), PrimaryItems); + RecipeGroup.RegisterGroup("PvPAdventure:AnyPlanteraPrimary", AnyPlanteraPrimary); + + // Create exclude subgroups while maintaining icon as first item + foreach (int itemID in PrimaryItems.Where(id => id != ItemID.PlanteraMasterTrophy)) + { + var validItems = PrimaryItems + .Where(id => id != itemID && id != ItemID.PlanteraMasterTrophy) + .Prepend(ItemID.PlanteraMasterTrophy) // Keep item first for icon + .ToArray(); + + RecipeGroup group = new RecipeGroup( + () => Language.GetTextValue("Any Plantera Drop"), + validItems + ); + RecipeGroup.RegisterGroup($"PvPAdventure:AnyPlanteraPrimaryExclude{itemID}", group); + } + } + } + + public class AnyDuke1 : ModSystem + { + public static RecipeGroup AnyDukePrimary; + public static int[] PrimaryItems => new int[] { + ItemID.DukeFishronMasterTrophy, + ItemID.RazorbladeTyphoon, + ItemID.BubbleGun, + ItemID.Flairon, + ItemID.Tsunami, + ItemID.TempestStaff, + }; + + public override void AddRecipeGroups() + { + // Main group with trophy as first item (for icon) + AnyDukePrimary = new RecipeGroup(() => Language.GetTextValue("Any Duke Primary"), PrimaryItems); + RecipeGroup.RegisterGroup("PvPAdventure:AnyDukePrimary", AnyDukePrimary); + + // Create exclude subgroups while maintaining icon as first item + foreach (int itemID in PrimaryItems.Where(id => id != ItemID.DukeFishronMasterTrophy)) + { + var validItems = PrimaryItems + .Where(id => id != itemID && id != ItemID.DukeFishronMasterTrophy) + .Prepend(ItemID.DukeFishronMasterTrophy) // Keep item first for icon + .ToArray(); + + RecipeGroup group = new RecipeGroup( + () => Language.GetTextValue("Any Duke Primary"), + validItems + ); + RecipeGroup.RegisterGroup($"PvPAdventure:AnyDukePrimaryExclude{itemID}", group); + } + } + } + + public class AnyEmpress1 : ModSystem + { + public static RecipeGroup AnyEmpressPrimary; + public static int[] PrimaryItems => new int[] { + ItemID.FairyQueenMasterTrophy, + ItemID.FairyQueenMagicItem, + ItemID.FairyQueenRangedItem, + ItemID.PiercingStarlight, + ItemID.RainbowWhip, + ItemID.EmpressBlade, + }; + + public override void AddRecipeGroups() { - foreach (var lootTable in _lootTables) - CreateDuplicateDropRecipe(lootTable, 3); + // Main group with trophy as first item (for icon) + AnyEmpressPrimary = new RecipeGroup(() => Language.GetTextValue("Any Empress Primary"), PrimaryItems); + RecipeGroup.RegisterGroup("PvPAdventure:AnyEmpressPrimary", AnyEmpressPrimary); + + // Create exclude subgroups while maintaining icon as first item + foreach (int itemID in PrimaryItems.Where(id => id != ItemID.FairyQueenMasterTrophy)) + { + var validItems = PrimaryItems + .Where(id => id != itemID && id != ItemID.FairyQueenMasterTrophy) + .Prepend(ItemID.FairyQueenMasterTrophy) // Keep item first for icon + .ToArray(); + + RecipeGroup group = new RecipeGroup( + () => Language.GetTextValue("Any Empress Primary"), + validItems + ); + RecipeGroup.RegisterGroup($"PvPAdventure:AnyEmpressPrimaryExclude{itemID}", group); + } + } + } + + public class AnyWall1 : ModSystem + { + public static RecipeGroup AnyWallPrimary; + public static int[] PrimaryItems => new int[] { + ItemID.WallofFleshMasterTrophy, + ItemID.FireWhip, + ItemID.ClockworkAssaultRifle, + ItemID.BreakerBlade, + ItemID.LaserRifle, + }; + + public override void AddRecipeGroups() + { + // Main group with trophy as first item (for icon) + AnyWallPrimary = new RecipeGroup(() => Language.GetTextValue("Any Wall of Flesh Primary"), PrimaryItems); + RecipeGroup.RegisterGroup("PvPAdventure:AnyWallPrimary", AnyWallPrimary); + + // Create exclude subgroups while maintaining icon as first item + foreach (int itemID in PrimaryItems.Where(id => id != ItemID.WallofFleshMasterTrophy)) + { + var validItems = PrimaryItems + .Where(id => id != itemID && id != ItemID.WallofFleshMasterTrophy) + .Prepend(ItemID.WallofFleshMasterTrophy) // Keep item first for icon + .ToArray(); + + RecipeGroup group = new RecipeGroup( + () => Language.GetTextValue("Any Wall of Flesh Primary"), + validItems + ); + RecipeGroup.RegisterGroup($"PvPAdventure:AnyWallPrimaryExclude{itemID}", group); + } + } + } + + public class AnySaucer1 : ModSystem + { + public static RecipeGroup AnySaucerPrimary; + public static int[] PrimaryItems => new int[] { + ItemID.UFOMasterTrophy, + ItemID.XenoStaff, + ItemID.LaserMachinegun, + ItemID.InfluxWaver, + ItemID.ElectrosphereLauncher, + ItemID.Xenopopper, + }; + + public override void AddRecipeGroups() + { + // Main group with trophy as first item (for icon) + AnySaucerPrimary = new RecipeGroup(() => Language.GetTextValue("Any Saucer Primary"), PrimaryItems); + RecipeGroup.RegisterGroup("PvPAdventure:AnySaucerPrimary", AnySaucerPrimary); + + // Create exclude subgroups while maintaining icon as first item + foreach (int itemID in PrimaryItems.Where(id => id != ItemID.UFOMasterTrophy)) + { + var validItems = PrimaryItems + .Where(id => id != itemID && id != ItemID.UFOMasterTrophy) + .Prepend(ItemID.UFOMasterTrophy) // Keep item first for icon + .ToArray(); + + RecipeGroup group = new RecipeGroup( + () => Language.GetTextValue("Any Saucer Primary"), + validItems + ); + RecipeGroup.RegisterGroup($"PvPAdventure:AnySaucerPrimaryExclude{itemID}", group); + } } + } - private static void CreateDuplicateDropRecipe(List lootTable, int amountOfMaterial) + public class RecipeSystem : ModSystem + { + public override void AddRecipes() { - for (int i = 0; i < lootTable.Count; i++) + var shimmerCondition = new Condition( + Language.GetText("Mods.PvPAdventure.Conditions.NearShimmer"), + () => Main.LocalPlayer.adjShimmer + ); + + // Primary recipes (trophy remains icon) + foreach (int itemID in AnyGolem1.PrimaryItems.Where(id => id != ItemID.GolemMasterTrophy)) { - for (int j = 0; j < lootTable.Count; j++) - { - if (j == i) - continue; + Recipe.Create(itemID) + .AddRecipeGroup($"PvPAdventure:AnyGolemPrimaryExclude{itemID}", 3) + .AddCondition(shimmerCondition) + .DisableDecraft() + .Register(); + } - Recipe.Create(lootTable[i]) - .AddIngredient(lootTable[j], amountOfMaterial) - .DisableDecraft() - .Register(); - } + // Secondary recipes (boss bag remains icon) + foreach (int itemID in AnyGolem2.SecondaryItems.Where(id => id != ItemID.GolemBossBag)) + { + Recipe.Create(itemID) + .AddRecipeGroup($"PvPAdventure:AnyGolemSecondaryExclude{itemID}", 3) + .AddCondition(shimmerCondition) + .DisableDecraft() + .Register(); + } + + // Primary QS recipes (Relic remains icon) + foreach (int itemID in AnyQueenSlime1.PrimaryItems.Where(id => id != ItemID.QueenSlimeMasterTrophy)) + { + Recipe.Create(itemID) + .AddRecipeGroup($"PvPAdventure:AnyQueenSlimePrimaryExclude{itemID}", 3) + .AddCondition(shimmerCondition) + .DisableDecraft() + .Register(); + } + + // Primary Plantera recipes (Relic remains icon) + foreach (int itemID in AnyPlantera1.PrimaryItems.Where(id => id != ItemID.PlanteraMasterTrophy)) + { + Recipe.Create(itemID) + .AddRecipeGroup($"PvPAdventure:AnyPlanteraPrimaryExclude{itemID}", 4) + .AddCondition(shimmerCondition) + .DisableDecraft() + .Register(); + } + + // Primary Duke recipes (Relic remains icon) + foreach (int itemID in AnyDuke1.PrimaryItems.Where(id => id != ItemID.DukeFishronMasterTrophy)) + { + Recipe.Create(itemID) + .AddRecipeGroup($"PvPAdventure:AnyDukePrimaryExclude{itemID}", 3) + .AddCondition(shimmerCondition) + .DisableDecraft() + .Register(); + } + + // Primary Empress recipes (Relic remains icon) + foreach (int itemID in AnyEmpress1.PrimaryItems.Where(id => id != ItemID.FairyQueenMasterTrophy)) + { + Recipe.Create(itemID) + .AddRecipeGroup($"PvPAdventure:AnyEmpressPrimaryExclude{itemID}", 2) + .AddCondition(shimmerCondition) + .DisableDecraft() + .Register(); + } + + // Primary Wall recipes (Relic remains icon) + foreach (int itemID in AnyWall1.PrimaryItems.Where(id => id != ItemID.WallofFleshMasterTrophy)) + { + Recipe.Create(itemID) + .AddRecipeGroup($"PvPAdventure:AnyWallPrimaryExclude{itemID}", 2) + .AddCondition(shimmerCondition) + .DisableDecraft() + .Register(); + } + + // Primary UFO recipes (Relic remains icon) + foreach (int itemID in AnySaucer1.PrimaryItems.Where(id => id != ItemID.UFOMasterTrophy)) + { + Recipe.Create(itemID) + .AddRecipeGroup($"PvPAdventure:AnySaucerPrimaryExclude{itemID}", 3) + .AddCondition(shimmerCondition) + .DisableDecraft() + .Register(); } } } -} +} \ No newline at end of file From a75f749a5c64465ba3b70d9e645d214645dfe045 Mon Sep 17 00:00:00 2001 From: Alex <87573461+MatteSevai@users.noreply.github.com> Date: Fri, 23 May 2025 20:10:17 -0700 Subject: [PATCH 05/11] added psudo terra blade --- System/RecipeManager.cs | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/System/RecipeManager.cs b/System/RecipeManager.cs index 2db8ccb4..6899c4a2 100644 --- a/System/RecipeManager.cs +++ b/System/RecipeManager.cs @@ -1,13 +1,16 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Terraria; using Terraria.ID; using Terraria.ModLoader; +using System.Linq; namespace PvPAdventure.System; [Autoload(Side = ModSide.Both)] public class RecipeManager : ModSystem { + public override void AddRecipes() { CreateDuplicateDropRecipe([ @@ -79,6 +82,37 @@ public override void AddRecipes() .AddIngredient(ItemID.StoneBlock, 50) .AddTile(TileID.HeavyWorkBench) .Register(); + + + + + int[] itemsToRemove = new int[] + { + ItemID.TrueNightsEdge, + ItemID.MoonlordArrow + }; + + for (int i = 0; i < Main.recipe.Length; i++) + { + Recipe recipe = Main.recipe[i]; + if (recipe.createItem.type != ItemID.None && itemsToRemove.Contains(recipe.createItem.type)) + { + recipe.DisableRecipe(); + } + } + + //temp sudo terrablade + Recipe.Create(ItemID.TrueNightsEdge) + .AddIngredient(ItemID.SoulofFright, 20) + .AddIngredient(ItemID.SoulofMight, 20) + .AddIngredient(ItemID.SoulofSight, 20) + .AddIngredient(ItemID.NightsEdge) + .AddIngredient(ItemID.TrueExcalibur) + .AddIngredient(ItemID.BrokenHeroSword) + .AddTile(TileID.MythrilAnvil) + .Register(); + + } private static void CreateDuplicateDropRecipe(List lootTable, int amountOfMaterial) From 7b930993022b8eb759f0358096674cbf73c1e105 Mon Sep 17 00:00:00 2001 From: Alex <87573461+MatteSevai@users.noreply.github.com> Date: Fri, 23 May 2025 20:12:47 -0700 Subject: [PATCH 06/11] updated shiny stone localization --- Localization/en-US.hjson | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Localization/en-US.hjson b/Localization/en-US.hjson index 230c7dd0..06092d72 100644 --- a/Localization/en-US.hjson +++ b/Localization/en-US.hjson @@ -665,5 +665,12 @@ Mods: { True: "[c/FF0000:The game has been paused.]" False: "[c/00FF00:The game has been resumed.]" } + + Buffs: { + ShinyStoneHotswap: { + DisplayName: Shiny Stone Hotswap + Description: Shiny Stone is charging up! + } + } } } From e4a2d4a0bd16594dfa8bc86b5bbb4186457e5b2e Mon Sep 17 00:00:00 2001 From: Alex <87573461+MatteSevai@users.noreply.github.com> Date: Fri, 23 May 2025 20:26:27 -0700 Subject: [PATCH 07/11] AdventureItem.cs: No Underground QS --- AdventureItem.cs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/AdventureItem.cs b/AdventureItem.cs index c525f4ec..f22320ed 100644 --- a/AdventureItem.cs +++ b/AdventureItem.cs @@ -26,6 +26,30 @@ public override void SetDefaults(Item item) } } } + public class GelatinCrystalRestriction : GlobalItem + { + public override bool CanUseItem(Item item, Player player) + { + if (item.type == ItemID.QueenSlimeCrystal) + { + bool isUnderground = player.position.Y > Main.worldSurface * 16; + bool inUndergroundHallow = isUnderground && player.ZoneHallow; + + if (inUndergroundHallow) + { + Main.NewText("Queen Slime refuses to emerge in the corrupted crystals here!", 255, 50, 50); + return false; + } + + // Still block summon in other underground areas but without message + if (isUnderground) + { + return false; + } + } + return base.CanUseItem(item, player); + } + } public override void SetDefaults(Item item) { From 8db35bd208dc97f9239a857760dd7a006313f3fe Mon Sep 17 00:00:00 2001 From: EJCrispy Date: Mon, 26 May 2025 15:18:39 -0700 Subject: [PATCH 08/11] Makes first wof drop 2 emblems --- AdventureDropDatabase.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/AdventureDropDatabase.cs b/AdventureDropDatabase.cs index 92594f5d..aab3eb9c 100644 --- a/AdventureDropDatabase.cs +++ b/AdventureDropDatabase.cs @@ -23,7 +23,12 @@ private static void ModifyDropRate(IItemDropRule rule, int type, int numerator, foreach (var ruleChainAttempt in rule.ChainedRules) ModifyDropRate(ruleChainAttempt.RuleToChain, type, numerator, denominator); } - + public class NotInHardmodeCondition : IItemDropRuleCondition + { + public bool CanDrop(DropAttemptInfo info) => !Main.hardMode; + public bool CanShowItemDropInUI() => true; + public string GetConditionDescription() => "Drops in pre-Hardmode"; + } public static void ModifyNPCLoot(NPC npc, NPCLoot npcLoot) { var drops = npcLoot.Get(); @@ -218,6 +223,16 @@ public static void ModifyNPCLoot(NPC npc, NPCLoot npcLoot) case NPCID.SkeletronHead: npcLoot.Add(ItemDropRule.Common(ItemID.GoldenKey)); break; + + case NPCID.WallofFlesh: + npcLoot.Add(new LeadingConditionRule(new NotInHardmodeCondition())) + .OnSuccess(ItemDropRule.OneFromOptions(1, + ItemID.SummonerEmblem, + ItemID.RangerEmblem, + ItemID.WarriorEmblem, + ItemID.SorcererEmblem + )); + break; } } } \ No newline at end of file From 6ebc67e429320fc219f40f62b452a6539902583a Mon Sep 17 00:00:00 2001 From: EJCrispy Date: Mon, 26 May 2025 15:36:52 -0700 Subject: [PATCH 09/11] Updating this to account for Biome mimics --- System/RecipeManager.cs | 89 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/System/RecipeManager.cs b/System/RecipeManager.cs index 8c8f7b40..1832c29d 100644 --- a/System/RecipeManager.cs +++ b/System/RecipeManager.cs @@ -285,6 +285,75 @@ public override void AddRecipeGroups() } } + public class AnyCorruptionMimic1 : ModSystem + { + public static RecipeGroup AnyCorruptionMimicPrimary; + public static int[] PrimaryItems => new int[] { + ItemID.Fake_CorruptionChest, + ItemID.PutridScent, + ItemID.DartRifle, + ItemID.ClingerStaff, + ItemID.ChainGuillotines, + ItemID.WormHook, + }; + + public override void AddRecipeGroups() + { + // Main group with trophy as first item (for icon) + AnyCorruptionMimicPrimary = new RecipeGroup(() => Language.GetTextValue("Any Corrupt Mimic Primary"), PrimaryItems); + RecipeGroup.RegisterGroup("PvPAdventure:AnyCorruptionMimicPrimary", AnyCorruptionMimicPrimary); + + // Create exclude subgroups while maintaining icon as first item + foreach (int itemID in PrimaryItems.Where(id => id != ItemID.Fake_CorruptionChest)) + { + var validItems = PrimaryItems + .Where(id => id != itemID && id != ItemID.Fake_CorruptionChest) + .Prepend(ItemID.Fake_CorruptionChest) // Keep item first for icon + .ToArray(); + + RecipeGroup group = new RecipeGroup( + () => Language.GetTextValue("Any Corrupt Mimic Primary"), + validItems + ); + RecipeGroup.RegisterGroup($"PvPAdventure:AnyCorruptionMimicPrimaryExclude{itemID}", group); + } + } + } + + public class AnyHallowedMimic1 : ModSystem + { + public static RecipeGroup AnyHallowedMimicPrimary; + public static int[] PrimaryItems => new int[] { + ItemID.Fake_HallowedChest, + ItemID.DaedalusStormbow, + ItemID.CrystalVileShard, + ItemID.FlyingKnife, + ItemID.IlluminantHook, + }; + + public override void AddRecipeGroups() + { + // Main group with trophy as first item (for icon) + AnyHallowedMimicPrimary = new RecipeGroup(() => Language.GetTextValue("Any Hallowed Mimic Primary"), PrimaryItems); + RecipeGroup.RegisterGroup("PvPAdventure:AnyHallowedMimicPrimary", AnyHallowedMimicPrimary); + + // Create exclude subgroups while maintaining icon as first item + foreach (int itemID in PrimaryItems.Where(id => id != ItemID.Fake_HallowedChest)) + { + var validItems = PrimaryItems + .Where(id => id != itemID && id != ItemID.Fake_HallowedChest) + .Prepend(ItemID.Fake_HallowedChest) // Keep item first for icon + .ToArray(); + + RecipeGroup group = new RecipeGroup( + () => Language.GetTextValue("Any Hallowed Mimic Primary"), + validItems + ); + RecipeGroup.RegisterGroup($"PvPAdventure:AnyHallowedMimicPrimaryExclude{itemID}", group); + } + } + } + public class RecipeSystem : ModSystem { public override void AddRecipes() @@ -373,6 +442,26 @@ public override void AddRecipes() .DisableDecraft() .Register(); } + + // Primary Corro mimic recipes (Relic remains icon) + foreach (int itemID in AnyCorruptionMimic1.PrimaryItems.Where(id => id != ItemID.Fake_CorruptionChest)) + { + Recipe.Create(itemID) + .AddRecipeGroup($"PvPAdventure:AnyCorruptionMimicPrimaryExclude{itemID}", 3) + .AddCondition(shimmerCondition) + .DisableDecraft() + .Register(); + } + + // Primary Hallow mimic recipes (Relic remains icon) + foreach (int itemID in AnyHallowedMimic1.PrimaryItems.Where(id => id != ItemID.Fake_HallowedChest)) + { + Recipe.Create(itemID) + .AddRecipeGroup($"PvPAdventure:AnyHallowedMimicPrimaryExclude{itemID}", 2) + .AddCondition(shimmerCondition) + .DisableDecraft() + .Register(); + } } } } \ No newline at end of file From e1a7ed586a267b5965d16450753ee115730ea313 Mon Sep 17 00:00:00 2001 From: EJCrispy Date: Mon, 26 May 2025 16:41:33 -0700 Subject: [PATCH 10/11] Makes all summons* dissapear when not in invetory to prevent sharing --- AdventureProjectile.cs | 293 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 293 insertions(+) diff --git a/AdventureProjectile.cs b/AdventureProjectile.cs index 28058db8..64aaf890 100644 --- a/AdventureProjectile.cs +++ b/AdventureProjectile.cs @@ -83,4 +83,297 @@ public override void PostAI(Projectile projectile) // Ignore net spam restraints. projectile.netSpam = 0; } + + public class SpiderStaffGlobalProjectile : GlobalProjectile + { + public override bool AppliesToEntity(Projectile entity, bool lateInstantiation) + { + return entity.type == ProjectileID.VenomSpider || + entity.type == ProjectileID.JumperSpider || // Note: Fix typo here + entity.type == ProjectileID.DangerousSpider; + } + + public override void PostAI(Projectile projectile) + { + Player owner = Main.player[projectile.owner]; + + // Check inventory (including equipped items) AND mouse slot + bool hasStaff = owner.HasItem(ItemID.SpiderStaff); + bool mouseHasStaff = owner.inventory[58].type == ItemID.SpiderStaff && owner.inventory[58].stack > 0; + + if (!hasStaff && !mouseHasStaff) + { + projectile.Kill(); + } + } + } + + public class ClingerStaffGlobalProjectile : GlobalProjectile + { + public override bool AppliesToEntity(Projectile entity, bool lateInstantiation) + { + return entity.type == ProjectileID.ClingerStaff; + } + + public override void PostAI(Projectile projectile) + { + Player owner = Main.player[projectile.owner]; + + // Check inventory (including equipped items) AND mouse slot + bool hasStaff = owner.HasItem(ItemID.ClingerStaff); + bool mouseHasStaff = owner.inventory[58].type == ItemID.ClingerStaff && owner.inventory[58].stack > 0; + + if (!hasStaff && !mouseHasStaff) + { + projectile.Kill(); + } + } + } + + public class QueenSpiderStaffGlobalProjectile : GlobalProjectile + { + public override bool AppliesToEntity(Projectile entity, bool lateInstantiation) + { + return entity.type == ProjectileID.SpiderHiver; + } + + public override void PostAI(Projectile projectile) + { + Player owner = Main.player[projectile.owner]; + + // Check inventory (including equipped items) AND mouse slot + bool hasStaff = owner.HasItem(ItemID.QueenSpiderStaff); + bool mouseHasStaff = owner.inventory[58].type == ItemID.QueenSpiderStaff && owner.inventory[58].stack > 0; + + if (!hasStaff && !mouseHasStaff) + { + projectile.Kill(); + } + } + } + + public class NimbusRodGlobalProjectile : GlobalProjectile + { + public override bool AppliesToEntity(Projectile entity, bool lateInstantiation) + { + return entity.type == ProjectileID.RainNimbus; + } + + public override void PostAI(Projectile projectile) + { + Player owner = Main.player[projectile.owner]; + + // Check inventory (including equipped items) AND mouse slot + bool hasStaff = owner.HasItem(ItemID.NimbusRod); + bool mouseHasStaff = owner.inventory[58].type == ItemID.NimbusRod && owner.inventory[58].stack > 0; + + if (!hasStaff && !mouseHasStaff) + { + projectile.Kill(); + } + } + } + + public class XenoStaffGlobalProjectile : GlobalProjectile + { + public override bool AppliesToEntity(Projectile entity, bool lateInstantiation) + { + return entity.type == ProjectileID.UFOMinion; + } + + public override void PostAI(Projectile projectile) + { + Player owner = Main.player[projectile.owner]; + + // Check inventory (including equipped items) AND mouse slot + bool hasStaff = owner.HasItem(ItemID.XenoStaff); + bool mouseHasStaff = owner.inventory[58].type == ItemID.XenoStaff && owner.inventory[58].stack > 0; + + if (!hasStaff && !mouseHasStaff) + { + projectile.Kill(); + } + } + } + + public class BladeStaffGlobalProjectile : GlobalProjectile + { + public override bool AppliesToEntity(Projectile entity, bool lateInstantiation) + { + return entity.type == ProjectileID.Smolstar; + } + + public override void PostAI(Projectile projectile) + { + Player owner = Main.player[projectile.owner]; + + // Check inventory (including equipped items) AND mouse slot + bool hasStaff = owner.HasItem(ItemID.Smolstar); + bool mouseHasStaff = owner.inventory[58].type == ItemID.Smolstar && owner.inventory[58].stack > 0; + + if (!hasStaff && !mouseHasStaff) + { + projectile.Kill(); + } + } + } + + public class HornetStaffGlobalProjectile : GlobalProjectile + { + public override bool AppliesToEntity(Projectile entity, bool lateInstantiation) + { + return entity.type == ProjectileID.Hornet; + } + + public override void PostAI(Projectile projectile) + { + Player owner = Main.player[projectile.owner]; + + // Check inventory (including equipped items) AND mouse slot + bool hasStaff = owner.HasItem(ItemID.HornetStaff); + bool mouseHasStaff = owner.inventory[58].type == ItemID.HornetStaff && owner.inventory[58].stack > 0; + + if (!hasStaff && !mouseHasStaff) + { + projectile.Kill(); + } + } + } + + public class ImpStaffGlobalProjectile : GlobalProjectile + { + public override bool AppliesToEntity(Projectile entity, bool lateInstantiation) + { + return entity.type == ProjectileID.FlyingImp; + } + + public override void PostAI(Projectile projectile) + { + Player owner = Main.player[projectile.owner]; + + // Check inventory (including equipped items) AND mouse slot + bool hasStaff = owner.HasItem(ItemID.ImpStaff); + bool mouseHasStaff = owner.inventory[58].type == ItemID.ImpStaff && owner.inventory[58].stack > 0; + + if (!hasStaff && !mouseHasStaff) + { + projectile.Kill(); + } + } + } + + public class PygmyStaffGlobalProjectile : GlobalProjectile + { + public override bool AppliesToEntity(Projectile entity, bool lateInstantiation) + { + return entity.type == ProjectileID.Pygmy || + entity.type == ProjectileID.Pygmy2 || + entity.type == ProjectileID.Pygmy3 || + entity.type == ProjectileID.Pygmy4; + } + + public override void PostAI(Projectile projectile) + { + Player owner = Main.player[projectile.owner]; + + // Check inventory (including equipped items) AND mouse slot + bool hasStaff = owner.HasItem(ItemID.PygmyStaff); + bool mouseHasStaff = owner.inventory[58].type == ItemID.PygmyStaff && owner.inventory[58].stack > 0; + + if (!hasStaff && !mouseHasStaff) + { + projectile.Kill(); + } + } + } + + public class DeadlySphereGlobalProjectile : GlobalProjectile + { + public override bool AppliesToEntity(Projectile entity, bool lateInstantiation) + { + return entity.type == ProjectileID.DeadlySphere; + } + + public override void PostAI(Projectile projectile) + { + Player owner = Main.player[projectile.owner]; + + // Check inventory (including equipped items) AND mouse slot + bool hasStaff = owner.HasItem(ItemID.DeadlySphereStaff); + bool mouseHasStaff = owner.inventory[58].type == ItemID.DeadlySphereStaff && owner.inventory[58].stack > 0; + + if (!hasStaff && !mouseHasStaff) + { + projectile.Kill(); + } + } + } + + public class PirateStaffGlobalProjectile : GlobalProjectile + { + public override bool AppliesToEntity(Projectile entity, bool lateInstantiation) + { + return entity.type == ProjectileID.OneEyedPirate || + entity.type == ProjectileID.SoulscourgePirate || + entity.type == ProjectileID.PirateCaptain; + } + + public override void PostAI(Projectile projectile) + { + Player owner = Main.player[projectile.owner]; + + // Check inventory (including equipped items) AND mouse slot + bool hasStaff = owner.HasItem(ItemID.PirateStaff); + bool mouseHasStaff = owner.inventory[58].type == ItemID.PirateStaff && owner.inventory[58].stack > 0; + + if (!hasStaff && !mouseHasStaff) + { + projectile.Kill(); + } + } + } + + public class TempestStaffGlobalProjectile : GlobalProjectile + { + public override bool AppliesToEntity(Projectile entity, bool lateInstantiation) + { + return entity.type == ProjectileID.Tempest; + } + + public override void PostAI(Projectile projectile) + { + Player owner = Main.player[projectile.owner]; + + // Check inventory (including equipped items) AND mouse slot + bool hasStaff = owner.HasItem(ItemID.TempestStaff); + bool mouseHasStaff = owner.inventory[58].type == ItemID.TempestStaff && owner.inventory[58].stack > 0; + + if (!hasStaff && !mouseHasStaff) + { + projectile.Kill(); + } + } + } + + public class TerraprismaGlobalProjectile : GlobalProjectile + { + public override bool AppliesToEntity(Projectile entity, bool lateInstantiation) + { + return entity.type == ProjectileID.EmpressBlade; + } + + public override void PostAI(Projectile projectile) + { + Player owner = Main.player[projectile.owner]; + + // Check inventory (including equipped items) AND mouse slot + bool hasStaff = owner.HasItem(ItemID.EmpressBlade); + bool mouseHasStaff = owner.inventory[58].type == ItemID.EmpressBlade && owner.inventory[58].stack > 0; + + if (!hasStaff && !mouseHasStaff) + { + projectile.Kill(); + } + } + } } \ No newline at end of file From 93cd6a64ca7f08b5189f18bccba158dbe838ed19 Mon Sep 17 00:00:00 2001 From: EJCrispy Date: Wed, 28 May 2025 16:50:11 -0700 Subject: [PATCH 11/11] Makes the spac and claff projectiles disappear on dead --- AdventureProjectile.cs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/AdventureProjectile.cs b/AdventureProjectile.cs index 64aaf890..a8985aad 100644 --- a/AdventureProjectile.cs +++ b/AdventureProjectile.cs @@ -376,4 +376,32 @@ public override void PostAI(Projectile projectile) } } } + + public class DeadProjectileList : GlobalProjectile + { + public override bool AppliesToEntity(Projectile entity, bool lateInstantiation) + { + return entity.type == ProjectileID.ClingerStaff || + entity.type == ProjectileID.SporeTrap || + entity.type == ProjectileID.SporeTrap2 || + entity.type == ProjectileID.SporeGas || + entity.type == ProjectileID.SporeGas2 || + entity.type == ProjectileID.SporeGas3; + } + + public override void PostAI(Projectile projectile) + { + // Ensure owner index is valid + if (projectile.owner < 0 || projectile.owner >= Main.maxPlayers) + return; + + Player owner = Main.player[projectile.owner]; + + // Kill projectile if owner is dead or inactive + if (owner.dead || !owner.active) + { + projectile.Kill(); + } + } + } } \ No newline at end of file