From 005491b26710f8b6768528c1d99992a42adce463 Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Sun, 15 Feb 2026 09:08:58 +1100 Subject: [PATCH 01/25] Added the visual effect to diamondheads ability --- Ben10Mod.cs | 2 +- .../CustomVisuals/DiamondHeadShimmerLayer.cs | 85 ++++ .../Systems/GenPasses/OmnitrixCapsulePass.cs | 181 ++++--- Common/Systems/WorldSystem.cs | 2 +- .../Accessories/AdvancedCircuitMatrix.cs | 22 + .../Accessories/AdvancedCircuitMatrix.png | Bin 0 -> 432 bytes Content/Items/Accessories/Omnitrix.cs | 1 - .../Items/Accessories/PrototypeOmnitrix.cs | 31 +- .../Items/Accessories/RecalibratedOmnitrix.cs | 444 +++++++++--------- Content/Items/Weapons/PlumberHelperBadge.cs | 4 +- Content/Items/Weapons/PlumberMagisterBadge.cs | 18 + .../Items/Weapons/PlumberMagisterBadge.png | Bin 0 -> 581 bytes Content/Items/Weapons/PlumbersBadge.cs | 19 +- .../Weapons/ProvisionalAgentBadgeCrimtane.cs | 2 +- Content/Projectiles/DiamondHeadProjectile.cs | 7 +- Content/Projectiles/DiamondHeadProjectile.png | Bin 150 -> 156 bytes Content/Tiles/PlumberCapsulePod.png | Bin 462 -> 439 bytes Localization/en-US_Mods.Ben10Mod.hjson | 10 + OmnitrixPlayer.cs | 135 +++--- ShopNPC.cs | 20 + OmnitrixNPC.cs => bossTrackerNPC.cs | 20 +- 21 files changed, 620 insertions(+), 383 deletions(-) create mode 100644 Common/CustomVisuals/DiamondHeadShimmerLayer.cs create mode 100644 Content/Items/Accessories/AdvancedCircuitMatrix.cs create mode 100644 Content/Items/Accessories/AdvancedCircuitMatrix.png create mode 100644 Content/Items/Weapons/PlumberMagisterBadge.cs create mode 100644 Content/Items/Weapons/PlumberMagisterBadge.png create mode 100644 ShopNPC.cs rename OmnitrixNPC.cs => bossTrackerNPC.cs (89%) diff --git a/Ben10Mod.cs b/Ben10Mod.cs index 08d23b7..b110fe6 100644 --- a/Ben10Mod.cs +++ b/Ben10Mod.cs @@ -1,3 +1,4 @@ +using Terraria.DataStructures; using Terraria.ModLoader; namespace Ben10Mod @@ -5,7 +6,6 @@ namespace Ben10Mod public class Ben10Mod : Mod { public override void Load() { - base.Load(); } } } \ No newline at end of file diff --git a/Common/CustomVisuals/DiamondHeadShimmerLayer.cs b/Common/CustomVisuals/DiamondHeadShimmerLayer.cs new file mode 100644 index 0000000..c5fdbbe --- /dev/null +++ b/Common/CustomVisuals/DiamondHeadShimmerLayer.cs @@ -0,0 +1,85 @@ +using System; +using Ben10Mod.Enums; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.DataStructures; +using Terraria.GameContent; +using Terraria.ModLoader; + +namespace Ben10Mod.Common.CustomVisuals; + +public class DiamondHeadShimmerLayer : PlayerDrawLayer { + + public override bool GetDefaultVisibility(PlayerDrawSet drawInfo) { + Player player = drawInfo.drawPlayer; + var omp = player.GetModPlayer(); + + return omp.currTransformation == TransformationEnum.DiamondHead && omp.DiamondHeadPrimaryAbilityEnabled; + } + + // Position after armor/body + public override Position GetDefaultPosition() + { + // Draw after armor layer so we overlay everything the player is wearing + return new AfterParent(PlayerDrawLayers.ArmOverItem); + } + + protected override void Draw(ref PlayerDrawSet drawInfo) + { + Player player = drawInfo.drawPlayer; + + // If our player is dead or invisible, skip + if (player.dead || player.invis) + return; + + // How many existing draw entries there are; we only clone the originals + int originalCount = drawInfo.DrawDataCache.Count; + if (originalCount == 0) + return; + + // Pulsing alpha between 0.3 and 0.5 + float pulse = (float)((System.Math.Sin(Main.GameUpdateCount / 15f) + 1f) * 0.5f); // 0..1 + float alpha = MathHelper.Lerp(0.3f, 0.5f, pulse); + + // Rainbow shimmer color + Color baseColor = Color.White; + Color rainbow = Main.DiscoColor; // built-in cycling rainbow + Color shimmerColor = Color.Lerp(baseColor, rainbow, 0.75f) * alpha; + + // Slight random offset (1–2 px in a random direction each frame) + Vector2 jitter = new Vector2( + Main.rand.NextFloat(-2f, 2f), + Main.rand.NextFloat(-2f, 2f) + ); + + // Clone each original DrawData and add a tinted copy with small offset + for (int i = 0; i < originalCount; i++) + { + var data = drawInfo.DrawDataCache[i]; + + // Optional: skip shadows, or stuff not attached to the player + // (Here we just clone everything; you can add filters if needed) + + var copy = data; + copy.position += jitter; + + // Multiply color by our shimmer; we also respect original alpha + // by combining them. + Color originalColor = data.color; + // Combine original color and shimmer; you can simplify this if you want + Color combined = new Color( + (byte)(originalColor.R * alpha + shimmerColor.R * (1f - alpha)), + (byte)(originalColor.G * alpha + shimmerColor.G * (1f - alpha)), + (byte)(originalColor.B * alpha + shimmerColor.B * (1f - alpha)), + (byte)(originalColor.A * alpha) + ); + + copy.color = combined; + + // Add the draw to the cache so tML draws it after the original + drawInfo.DrawDataCache.Add(copy); + } + + } +} \ No newline at end of file diff --git a/Common/Systems/GenPasses/OmnitrixCapsulePass.cs b/Common/Systems/GenPasses/OmnitrixCapsulePass.cs index c853d07..136792e 100644 --- a/Common/Systems/GenPasses/OmnitrixCapsulePass.cs +++ b/Common/Systems/GenPasses/OmnitrixCapsulePass.cs @@ -10,101 +10,152 @@ public class OmnitrixCapsulePass : GenPass { public OmnitrixCapsulePass(string name, float loadWeight) : base(name, loadWeight) { } - protected override void ApplyPass(GenerationProgress progress, GameConfiguration config) { + protected override void ApplyPass(GenerationProgress progress, GameConfiguration configuration) { progress.Message = "Calling down a strange meteor..."; - // Your custom tiles - int meteorRockTile = TileID.LunarOre; // "meteor rock" - int meteorOreTile = ModContent.TileType(); // special ore + // --- 0) Your tiles --- + int meteorOreTile = TileID.Silver; + int meteorRockTile = ModContent.TileType(); int capsuleTile = ModContent.TileType(); // 1x1 capsule - // --- 1) Choose an impact X away from the very edges --- - int impactX = WorldGen.genRand.Next(250, Main.maxTilesX - 250); + var rand = WorldGen.genRand; - // --- 2) Call vanilla meteor generator once --- - // y argument is mostly ignored; vanilla picks its own vertical area. - bool spawned = WorldGen.meteor(impactX, 0); - if (!spawned) - return; // If vanilla couldn't place a meteor, we can't do anything + // --- 1) Pick a surface position --- - // --- 3) Scan around impactX to find the meteorite area --- - int scanRadius = 80; - int minX = impactX - scanRadius; - int maxX = impactX + scanRadius; + // Avoid very close to edges to prevent clipping into oceans. + int centerX = rand.Next(300, Main.maxTilesX - 300); - if (minX < 10) minX = 10; - if (maxX > Main.maxTilesX - 10) maxX = Main.maxTilesX - 10; - - bool foundMeteor = false; - int highestMeteorY = Main.maxTilesY; - int lowestMeteorY = 0; + // Find the "surface" at this X: first solid tile going down. + int surfaceY = -1; + for (int y = 0; y < Main.maxTilesY - 300; y++) { + if (WorldGen.SolidTile(centerX, y)) { + surfaceY = y; + break; + } + } - for (int x = minX; x <= maxX; x++) { - for (int y = 0; y < Main.maxTilesY - 200; y++) { - Tile t = Main.tile[x, y]; - if (t == null || !t.HasTile) + // If we couldn't find solid ground for some reason, bail. + if (surfaceY < 0) + return; + + // --- 2) Define meteor shape parameters --- + + // Overall horizontal and vertical extents of the meteor blob + int halfWidth = 12; + int halfHeight = 5; + + // The center of the meteor mass is a bit below the surface + int meteorCenterY = surfaceY + 10; + + // Crater radius around the surface + int craterRadius = 26; + + // Clamp Y so we don't go out of world bounds + if (meteorCenterY > Main.maxTilesY - 60) + meteorCenterY = Main.maxTilesY - 60; + + // --- 3) Carve a crater on the surface (kill tiles in a circle) --- + + // int craterMinX = centerX - craterRadius - 5; + // int craterMaxX = centerX + craterRadius + 5; + // int craterMinY = surfaceY - 10; + // int craterMaxY = surfaceY + 10; + // + // for (int x = craterMinX; x <= craterMaxX; x++) { + // for (int y = craterMinY; y <= craterMaxY; y++) { + // if (!WorldGen.InWorld(x, y, 20)) + // continue; + // + // float dx = x - centerX; + // float dy = y - surfaceY; + // float dist = (float)System.Math.Sqrt(dx * dx + dy * dy); + // + // // Slightly flattened crater + // float craterShape = craterRadius * (1f + 0.15f * (float)System.Math.Sin(dx / 4f)); + // if (dist <= craterShape) { + // WorldGen.KillTile(x, y, noItem: true); + // } + // } + // } + + // --- 4) Build a lumpy meteor blob under the crater --- + + int meteorMinX = centerX - halfWidth; + int meteorMaxX = centerX + halfWidth; + int meteorMinY = meteorCenterY - halfHeight; + int meteorMaxY = meteorCenterY + halfHeight; + + if (meteorMinY < 10) meteorMinY = 10; + if (meteorMaxY > Main.maxTilesY - 30) meteorMaxY = Main.maxTilesY - 30; + + for (int x = meteorMinX; x <= meteorMaxX; x++) { + for (int y = meteorMinY; y <= meteorMaxY; y++) { + if (!WorldGen.InWorld(x, y, 20)) continue; - if (t.TileType == TileID.Meteorite) { - foundMeteor = true; - if (y < highestMeteorY) highestMeteorY = y; - if (y > lowestMeteorY) lowestMeteorY = y; - } - } - } + float dx = (x - centerX) / (float)halfWidth; + float dy = (y - meteorCenterY) / (float)halfHeight; + float distSq = dx * dx + dy * dy; - if (!foundMeteor) - return; // Somehow no meteorite tiles were created, bail + if (distSq > 1.2f) + continue; // outside the main ellipse + + // Add some noise so the outline isn't perfectly smooth + float noise = (float)(rand.NextDouble() * 0.35 - 0.15); // [-0.15, +0.20] + if (distSq > 1f + noise) + continue; - // --- 4) Convert Meteorite into your meteor rock / ore --- - for (int x = minX; x <= maxX; x++) { - for (int y = 0; y < Main.maxTilesY - 200; y++) { Tile t = Main.tile[x, y]; - if (t == null || !t.HasTile || t.TileType != TileID.Meteorite) + if (t == null) continue; - // Random ore pockets inside the meteor - if (WorldGen.genRand.Next(6) == 0) // ~1/6 chance - { + t.HasTile = true; + + // About 1/6 chance to be the special codon ore + if (rand.Next(6) == 0) t.TileType = (ushort)meteorOreTile; - } - else { + else t.TileType = (ushort)meteorRockTile; - } } } - // --- 5) Fix framing for that region so it looks nice --- - for (int x = minX - 2; x <= maxX + 2; x++) { - if (x < 10 || x >= Main.maxTilesX - 10) - continue; + // --- 5) Fix framing in the area so it looks correct --- - for (int y = highestMeteorY - 20; y <= lowestMeteorY + 20; y++) { - if (y < 10 || y >= Main.maxTilesY - 10) + int frameMinX = meteorMinX - 2; + int frameMaxX = meteorMaxX + 2; + int frameMinY = meteorMinY - 2; + int frameMaxY = meteorMaxY + 2; + + for (int x = frameMinX; x <= frameMaxX; x++) { + for (int y = frameMinY; y <= frameMaxY; y++) { + if (!WorldGen.InWorld(x, y, 20)) continue; WorldGen.SquareTileFrame(x, y, resetFrame: true); } } - // --- 6) Find a top spot for the 1x1 capsule near impactX --- + // --- 6) Find a top spot on the meteor for the capsule --- int bestX = -1; int bestY = -1; - int searchHalfWidth = 25; - int topSearchY = highestMeteorY - 5; - if (topSearchY < 10) topSearchY = 10; + int searchHalfWidth = 20; + int searchTopY = surfaceY - 10; + int searchBottomY = meteorMinY + (meteorMaxY - meteorMinY) / 2; - int bottomSearchY = lowestMeteorY + 10; - if (bottomSearchY > Main.maxTilesY - 10) bottomSearchY = Main.maxTilesY - 10; + if (searchTopY < 10) searchTopY = 10; + if (searchBottomY > Main.maxTilesY - 30) searchBottomY = Main.maxTilesY - 30; - for (int x = impactX - searchHalfWidth; x <= impactX + searchHalfWidth; x++) { - if (x < minX || x > maxX) + for (int x = centerX - searchHalfWidth; x <= centerX + searchHalfWidth; x++) { + if (x < meteorMinX || x > meteorMaxX) continue; - // Scan from just above the meteor top downward - for (int y = topSearchY; y <= bottomSearchY; y++) { + // scan downward from just above the crater + for (int y = searchTopY; y <= searchBottomY; y++) { + if (!WorldGen.InWorld(x, y, 20)) + continue; + Tile t = Main.tile[x, y]; if (t == null || !t.HasTile) continue; @@ -113,7 +164,7 @@ protected override void ApplyPass(GenerationProgress progress, GameConfiguration Tile above = Main.tile[x, y - 1]; if (above != null && !above.HasTile) { bestX = x; - bestY = y - 1; // capsule goes in this empty tile + bestY = y - 1; break; } } @@ -123,10 +174,12 @@ protected override void ApplyPass(GenerationProgress progress, GameConfiguration break; } - if (bestX == -1) - return; // meteor exists, but we couldn't find a clean top spot for the capsule + if (bestX == -1) { + // Couldn't find a clean top; meteor still exists, just no capsule. + return; + } - // --- 7) Place the 1x1 PlumberCapsulePod tile directly --- + // --- 7) Place the 1x1 PlumberCapsulePod tile --- Tile cap = Main.tile[bestX, bestY]; cap.HasTile = true; diff --git a/Common/Systems/WorldSystem.cs b/Common/Systems/WorldSystem.cs index ac83567..0684d29 100644 --- a/Common/Systems/WorldSystem.cs +++ b/Common/Systems/WorldSystem.cs @@ -26,7 +26,7 @@ public override void ModifyWorldGenTasks(List tasks, ref double totalWe if (microBiomesIndex == -1) microBiomesIndex = tasks.Count - 1; - tasks.Insert(microBiomesIndex + 1, new OmnitrixCapsulePass("Omnitrix Capsule Pass", 0.5f)); + tasks.Insert(microBiomesIndex + 1, new OmnitrixCapsulePass("Omnitrix Capsule Pass", 200f)); } } } \ No newline at end of file diff --git a/Content/Items/Accessories/AdvancedCircuitMatrix.cs b/Content/Items/Accessories/AdvancedCircuitMatrix.cs new file mode 100644 index 0000000..a3e4a0e --- /dev/null +++ b/Content/Items/Accessories/AdvancedCircuitMatrix.cs @@ -0,0 +1,22 @@ +using Ben10Mod.Content.Items.Placeables; +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Items.Accessories; + +public class AdvancedCircuitMatrix : ModItem { + + public override void SetDefaults() { + Item.width = 64; + Item.height = 64; + Item.accessory = true; + Item.value = 100000; + } + + public override void UpdateAccessory(Player player, bool hideVisual) { + var omp = player.GetModPlayer(); + omp.advancedCircuitMatrix = true; + omp.wasAdvancedCircuitMatrix = true; + } +} \ No newline at end of file diff --git a/Content/Items/Accessories/AdvancedCircuitMatrix.png b/Content/Items/Accessories/AdvancedCircuitMatrix.png new file mode 100644 index 0000000000000000000000000000000000000000..7a935fa1db31b292f0cb44e110fb6a844df01024 GIT binary patch literal 432 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%zvpiiKLn`LH zo$V`h&_SS8U26)j`NN#Dbq{6wlGEQZh;VC$Y!p;m`BQsth0p%{si#uns^-bfGzp&Z zZs+#}nZYHRW-o%?$S-7k!Ej;6v*7#1628f2UKua=V(Ozl`MujEOGFP|KbVAcPQby@zN~5C4AxRtG_vS{dRD_ zW$(JY_ZQCskl7a)N*FRS7_1mfE|xazU9)BWdcAMa_0e5G{at>ugAV?#pM9+2s(<65 z>5Qee4~q77GEg ze?yr4>NVplV~4$rYuGzNj2pf(Ow3~2ASaL$>hSW%`h<7;g-wo~u5wsnTMc%I34<(y zlvD#B1FyEz%jwTLtC;sxw;8SDC_F!bx4ie^qaVChciVrrRJZ@<1gSd9>>2c6Qr{C> RS6~z{c)I$ztaD0e0szL!xiSC% literal 0 HcmV?d00001 diff --git a/Content/Items/Accessories/Omnitrix.cs b/Content/Items/Accessories/Omnitrix.cs index 69c42ec..d59f09c 100644 --- a/Content/Items/Accessories/Omnitrix.cs +++ b/Content/Items/Accessories/Omnitrix.cs @@ -32,7 +32,6 @@ public class Omnitrix : ModItem { private Player player = null; public int transformationNum = 0; - public int cooldownTime = 0; public override string Texture => $"Terraria/Images/Item_{ItemID.None}"; diff --git a/Content/Items/Accessories/PrototypeOmnitrix.cs b/Content/Items/Accessories/PrototypeOmnitrix.cs index 9cbeead..b187c85 100644 --- a/Content/Items/Accessories/PrototypeOmnitrix.cs +++ b/Content/Items/Accessories/PrototypeOmnitrix.cs @@ -32,8 +32,6 @@ public class PrototypeOmnitrix : Omnitrix { private Player player = null; public int transformationNum = 0; - public int cooldownTime = 120; - public int transformationTime = 300; public TransformationEnum[] transformations = new TransformationEnum[5]; bool wasEquipedLastFrame = false; @@ -82,7 +80,6 @@ public override void SetDefaults() { Item.height = 28; Item.rare = ItemRarityID.Master; Item.accessory = true; - this.transformationTime = 300; } public override void ModifyTooltips(List tooltips) @@ -92,7 +89,8 @@ public override void ModifyTooltips(List tooltips) public override void UpdateAccessory(Player player, bool hideVisual) { this.player = player; - player.GetModPlayer().omnitrixEquipped = true; + var omp = player.GetModPlayer(); + omp.omnitrixEquipped = true; wasEquipedLastFrame = true; transformations = player.GetModPlayer().transformations; @@ -109,14 +107,14 @@ public override void UpdateAccessory(Player player, bool hideVisual) { } if (KeybindSystem.TransformationKeybind.JustPressed && !player.GetModPlayer().isTransformed && !player.GetModPlayer().onCooldown) { - TransformationHandler.Transform(player, transformations[transformationNum], transformationTime); + TransformationHandler.Transform(player, transformations[transformationNum], omp.transformationTime); } else if (KeybindSystem.TransformationKeybind.JustPressed && player.GetModPlayer().isTransformed && !player.GetModPlayer().onCooldown && player.GetModPlayer().masterControl) { if (player.GetModPlayer().currTransformation != transformations[transformationNum]) { TransformationHandler.Detransform(player, 0, false, false, false); - TransformationHandler.Transform(player, transformations[transformationNum], transformationTime); + TransformationHandler.Transform(player, transformations[transformationNum], omp.transformationTime); } else { - TransformationHandler.Detransform(player, cooldownTime, true, false); + TransformationHandler.Detransform(player, omp.cooldownTime, true, false); } } else if (KeybindSystem.AlienOneKeybind.JustPressed) { @@ -162,6 +160,7 @@ public override void UpdateAccessory(Player player, bool hideVisual) { public override void UpdateInventory(Player player) { base.UpdateInventory(player); + var omp = player.GetModPlayer(); if (wasEquipedLastFrame) { @@ -169,9 +168,7 @@ public override void UpdateInventory(Player player) ModContent.GetInstance().HideMyUI(); showingUI = false; if (player.GetModPlayer().isTransformed) { - TransformationHandler.Detransform(player, cooldownTime, true, true); - } else { - TransformationHandler.Detransform(player, cooldownTime, false, false); + TransformationHandler.Detransform(player, omp.cooldownTime, true, true); } } } @@ -195,16 +192,10 @@ public override bool PreDrawInInventory(SpriteBatch spriteBatch, Vector2 positio public override void AddRecipes() { base.AddRecipes(); - Recipe recipe = CreateRecipe() - .AddIngredient(ModContent.ItemType(), 20) - .AddIngredient(ItemID.Lens, 3) - .AddIngredient(ItemID.Emerald) - .AddTile(TileID.Anvils).Register(); - - Recipe recipeAlt = CreateRecipe() - .AddIngredient(ModContent.ItemType(), 20) - .AddIngredient(ItemID.Lens, 3) - .AddIngredient(ItemID.Emerald) + CreateRecipe() + .AddIngredient(ModContent.ItemType(), 25) + .AddIngredient(ItemID.Lens, 6) + .AddIngredient(ItemID.Emerald, 3) .AddTile(TileID.Anvils).Register(); } diff --git a/Content/Items/Accessories/RecalibratedOmnitrix.cs b/Content/Items/Accessories/RecalibratedOmnitrix.cs index 0e9e63c..a4778b9 100644 --- a/Content/Items/Accessories/RecalibratedOmnitrix.cs +++ b/Content/Items/Accessories/RecalibratedOmnitrix.cs @@ -1,222 +1,222 @@ - using Ben10Mod.Content.Transformations; -using Ben10Mod.Content.Transformations.XLR8; -using Ben10Mod.Keybinds; -using Microsoft.Xna.Framework; -using Steamworks; -using System; -using Terraria; -using Terraria.DataStructures; -using Terraria.GameContent.UI.Elements; -using Terraria.ID; -using Terraria.ModLoader; -using Terraria.ModLoader.IO; -using Ben10Mod.Enums; -using System.Collections.Generic; -using System.Threading.Tasks.Dataflow; -using System.Security.Cryptography.X509Certificates; -using Ben10Mod.Content.Interface; -using Ben10Mod.Content.Buffs.Abilities.ChromaStone; -using Ben10Mod.Content.Buffs.Abilities.DiamondHead; -using Ben10Mod.Content.Buffs.Abilities.HeatBlast; -using Ben10Mod.Content.Buffs.Abilities.XLR8; -using Ben10Mod.Content.Buffs.Transformations; -using Ben10Mod.Content.Items.Placeables; -using Ben10Mod.Content.DamageClasses; -using Terraria.ModLoader.Default; -using Microsoft.Xna.Framework.Graphics; -using Terraria.Audio; - -namespace Ben10Mod.Content.Items.Accessories -{ - public class RecalibratedOmnitrix : Omnitrix { - - private Player player = null; - public int transformationNum = 0; - public int transformationEnergy = 0; - private int maxEnergy = 0; - public TransformationEnum[] transformations = new TransformationEnum[5]; - - bool wasEquipedLastFrame = false; - bool showingUI = false; - - Texture2D dynamicTexture; - - public override string Texture => $"Ben10Mod/Content/Items/Accessories/{this.Name}"; - - public override void Load() { - if (Main.netMode == NetmodeID.Server) - return; - - EquipLoader.AddEquipTexture(Mod, $"{Texture}_{EquipType.HandsOn}", EquipType.HandsOn, name: "RecalibratedOmnitrix"); - EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.HandsOn}", EquipType.HandsOn, name: "RecalibratedOmnitrixAlt"); - } - - public override ModItem Clone(Item item) { - RecalibratedOmnitrix clone = (RecalibratedOmnitrix)base.Clone(item); - clone.transformationNum = transformationNum; - clone.transformations = (TransformationEnum[])transformations?.Clone(); - return clone; - } - - public override void SaveData(TagCompound tag) { - tag["selectedAlien"] = transformationNum; - } - - public override void LoadData(TagCompound tag) - { - tag.TryGet("selectedAlien", out transformationNum); - } - - public override void OnCreated(ItemCreationContext context) - { - transformationNum = 0; - } - - public override void SetStaticDefaults() { - dynamicTexture = ModContent.Request("Ben10Mod/Content/Items/Accessories/RecalibratedOmnitrix").Value; - } - - public override void SetDefaults() { - Item.maxStack = 1; - Item.width = 22; - Item.height = 28; - Item.rare = ItemRarityID.Master; - Item.accessory = true; - this.transformationEnergy = 300 * 60; - this.maxEnergy = 300 * 60; - } - - public override void ModifyTooltips(List tooltips) - { - tooltips.Add(new TooltipLine(Mod, "TransformationEnergy", "Energy: " + (int)(transformationEnergy / 60))); - tooltips.Add(new TooltipLine(Mod, "AlienSelection", "Alien " + (transformationNum + 1) + ": " + transformations[transformationNum].ToString())); - } - - public override void UpdateAccessory(Player player, bool hideVisual) { - this.player = player; - player.GetModPlayer().omnitrixEquipped = true; - wasEquipedLastFrame = true; - - transformations = player.GetModPlayer().transformations; - if (player.GetModPlayer().isTransformed && transformationEnergy > 0) { - transformationEnergy -= 1; - } - else if (transformationEnergy < maxEnergy) { - transformationEnergy += 3; - transformationEnergy = Math.Min(transformationEnergy, maxEnergy); - } - if (KeybindSystem.OpenTransformationScreen.JustPressed) { - if (!showingUI) { - player.GetModPlayer().transformations = transformations; - ModContent.GetInstance().ShowMyUI(); - showingUI = true; - } - else { - ModContent.GetInstance().HideMyUI(); - showingUI = false; - } - } - if (transformationEnergy <= 0) { - TransformationHandler.Detransform(player, 60); - } - - if (KeybindSystem.TransformationKeybind.JustPressed && !player.GetModPlayer().isTransformed && !player.GetModPlayer().onCooldown) { - TransformationHandler.Transform(player, transformations[transformationNum], transformationEnergy); - } - else if (KeybindSystem.TransformationKeybind.JustPressed && player.GetModPlayer().isTransformed && !player.GetModPlayer().onCooldown) { - if (player.GetModPlayer().currTransformation != transformations[transformationNum]) { - TransformationHandler.Detransform(player, 0, false, false, false); - if (transformationEnergy > 0) { - transformationEnergy -= 30; - transformationEnergy = Math.Max(transformationEnergy, 0); - } - TransformationHandler.Transform(player, transformations[transformationNum], transformationEnergy); - } else { - TransformationHandler.Detransform(player, 0, true, false); - } - } - else if (KeybindSystem.AlienOneKeybind.JustPressed) { - transformationNum = 0; - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienTwoKeybind.JustPressed) { - transformationNum = 1; - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienThreeKeybind.JustPressed) { - transformationNum = 2; - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienFourKeybind.JustPressed) { - transformationNum = 3; - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienFiveKeybind.JustPressed) { - transformationNum = 4; - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienNextKeybind.JustPressed) { - transformationNum++; - if (transformationNum > transformations.Length - 1) { - transformationNum = 0; - } - SoundEngine.PlaySound(SoundID.MenuTick, player.position); - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienPrevKeybind.JustPressed) { - transformationNum--; - if (transformationNum < 0) { - transformationNum = transformations.Length - 1; - } - SoundEngine.PlaySound(SoundID.MenuTick, player.position); - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - - base.UpdateAccessory(player, hideVisual); - } - - public override void UpdateInventory(Player player) - { - base.UpdateInventory(player); - - if (wasEquipedLastFrame) - { - wasEquipedLastFrame = false; - ModContent.GetInstance().HideMyUI(); - showingUI = false; - if (player.GetModPlayer().isTransformed) { - TransformationHandler.Detransform(player, cooldownTime, true, true); - } else { - TransformationHandler.Detransform(player, cooldownTime, false, false); - } - } - } - - public override bool CanEquipAccessory(Player player, int slot, bool modded) { - return modded; - } - - public override bool PreDrawInInventory(SpriteBatch spriteBatch, Vector2 position, Rectangle frame, Color drawColor, Color itemColor, Vector2 origin, float scale) { - - if (player == null) - return true; - - dynamicTexture = player.GetModPlayer().onCooldown ? ModContent.Request("Ben10Mod/Content/Items/Accessories/RecalibratedOmnitrixAlt").Value : ModContent.Request("Ben10Mod/Content/Items/Accessories/RecalibratedOmnitrix").Value; - - spriteBatch.Draw(dynamicTexture, position, null, drawColor, 0f, origin, scale, SpriteEffects.None, 0f); - - return false; - } - - public override void AddRecipes() { - base.AddRecipes(); - - Recipe recipeAlt = CreateRecipe() - .AddIngredient(ModContent.ItemType()) - .AddIngredient(ItemID.SoulofNight, 5) - .AddIngredient(ItemID.SoulofLight, 5) - .AddTile(TileID.MythrilAnvil).Register(); - - } - } -} \ No newline at end of file +// using Ben10Mod.Content.Transformations; +// using Ben10Mod.Content.Transformations.XLR8; +// using Ben10Mod.Keybinds; +// using Microsoft.Xna.Framework; +// using Steamworks; +// using System; +// using Terraria; +// using Terraria.DataStructures; +// using Terraria.GameContent.UI.Elements; +// using Terraria.ID; +// using Terraria.ModLoader; +// using Terraria.ModLoader.IO; +// using Ben10Mod.Enums; +// using System.Collections.Generic; +// using System.Threading.Tasks.Dataflow; +// using System.Security.Cryptography.X509Certificates; +// using Ben10Mod.Content.Interface; +// using Ben10Mod.Content.Buffs.Abilities.ChromaStone; +// using Ben10Mod.Content.Buffs.Abilities.DiamondHead; +// using Ben10Mod.Content.Buffs.Abilities.HeatBlast; +// using Ben10Mod.Content.Buffs.Abilities.XLR8; +// using Ben10Mod.Content.Buffs.Transformations; +// using Ben10Mod.Content.Items.Placeables; +// using Ben10Mod.Content.DamageClasses; +// using Terraria.ModLoader.Default; +// using Microsoft.Xna.Framework.Graphics; +// using Terraria.Audio; +// +// namespace Ben10Mod.Content.Items.Accessories +// { +// public class RecalibratedOmnitrix : Omnitrix { +// +// private Player player = null; +// public int transformationNum = 0; +// public int transformationEnergy = 0; +// private int maxEnergy = 0; +// public TransformationEnum[] transformations = new TransformationEnum[5]; +// +// bool wasEquipedLastFrame = false; +// bool showingUI = false; +// +// Texture2D dynamicTexture; +// +// public override string Texture => $"Ben10Mod/Content/Items/Accessories/{this.Name}"; +// +// public override void Load() { +// if (Main.netMode == NetmodeID.Server) +// return; +// +// EquipLoader.AddEquipTexture(Mod, $"{Texture}_{EquipType.HandsOn}", EquipType.HandsOn, name: "RecalibratedOmnitrix"); +// EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.HandsOn}", EquipType.HandsOn, name: "RecalibratedOmnitrixAlt"); +// } +// +// public override ModItem Clone(Item item) { +// RecalibratedOmnitrix clone = (RecalibratedOmnitrix)base.Clone(item); +// clone.transformationNum = transformationNum; +// clone.transformations = (TransformationEnum[])transformations?.Clone(); +// return clone; +// } +// +// public override void SaveData(TagCompound tag) { +// tag["selectedAlien"] = transformationNum; +// } +// +// public override void LoadData(TagCompound tag) +// { +// tag.TryGet("selectedAlien", out transformationNum); +// } +// +// public override void OnCreated(ItemCreationContext context) +// { +// transformationNum = 0; +// } +// +// public override void SetStaticDefaults() { +// dynamicTexture = ModContent.Request("Ben10Mod/Content/Items/Accessories/RecalibratedOmnitrix").Value; +// } +// +// public override void SetDefaults() { +// Item.maxStack = 1; +// Item.width = 22; +// Item.height = 28; +// Item.rare = ItemRarityID.Master; +// Item.accessory = true; +// this.transformationEnergy = 300 * 60; +// this.maxEnergy = 300 * 60; +// } +// +// public override void ModifyTooltips(List tooltips) +// { +// tooltips.Add(new TooltipLine(Mod, "TransformationEnergy", "Energy: " + (int)(transformationEnergy / 60))); +// tooltips.Add(new TooltipLine(Mod, "AlienSelection", "Alien " + (transformationNum + 1) + ": " + transformations[transformationNum].ToString())); +// } +// +// public override void UpdateAccessory(Player player, bool hideVisual) { +// this.player = player; +// player.GetModPlayer().omnitrixEquipped = true; +// wasEquipedLastFrame = true; +// +// transformations = player.GetModPlayer().transformations; +// if (player.GetModPlayer().isTransformed && transformationEnergy > 0) { +// transformationEnergy -= 1; +// } +// else if (transformationEnergy < maxEnergy) { +// transformationEnergy += 3; +// transformationEnergy = Math.Min(transformationEnergy, maxEnergy); +// } +// if (KeybindSystem.OpenTransformationScreen.JustPressed) { +// if (!showingUI) { +// player.GetModPlayer().transformations = transformations; +// ModContent.GetInstance().ShowMyUI(); +// showingUI = true; +// } +// else { +// ModContent.GetInstance().HideMyUI(); +// showingUI = false; +// } +// } +// if (transformationEnergy <= 0) { +// TransformationHandler.Detransform(player, 60); +// } +// +// if (KeybindSystem.TransformationKeybind.JustPressed && !player.GetModPlayer().isTransformed && !player.GetModPlayer().onCooldown) { +// TransformationHandler.Transform(player, transformations[transformationNum], transformationEnergy); +// } +// else if (KeybindSystem.TransformationKeybind.JustPressed && player.GetModPlayer().isTransformed && !player.GetModPlayer().onCooldown) { +// if (player.GetModPlayer().currTransformation != transformations[transformationNum]) { +// TransformationHandler.Detransform(player, 0, false, false, false); +// if (transformationEnergy > 0) { +// transformationEnergy -= 30; +// transformationEnergy = Math.Max(transformationEnergy, 0); +// } +// TransformationHandler.Transform(player, transformations[transformationNum], transformationEnergy); +// } else { +// TransformationHandler.Detransform(player, 0, true, false); +// } +// } +// else if (KeybindSystem.AlienOneKeybind.JustPressed) { +// transformationNum = 0; +// Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); +// } +// else if (KeybindSystem.AlienTwoKeybind.JustPressed) { +// transformationNum = 1; +// Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); +// } +// else if (KeybindSystem.AlienThreeKeybind.JustPressed) { +// transformationNum = 2; +// Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); +// } +// else if (KeybindSystem.AlienFourKeybind.JustPressed) { +// transformationNum = 3; +// Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); +// } +// else if (KeybindSystem.AlienFiveKeybind.JustPressed) { +// transformationNum = 4; +// Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); +// } +// else if (KeybindSystem.AlienNextKeybind.JustPressed) { +// transformationNum++; +// if (transformationNum > transformations.Length - 1) { +// transformationNum = 0; +// } +// SoundEngine.PlaySound(SoundID.MenuTick, player.position); +// Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); +// } +// else if (KeybindSystem.AlienPrevKeybind.JustPressed) { +// transformationNum--; +// if (transformationNum < 0) { +// transformationNum = transformations.Length - 1; +// } +// SoundEngine.PlaySound(SoundID.MenuTick, player.position); +// Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); +// } +// +// base.UpdateAccessory(player, hideVisual); +// } +// +// public override void UpdateInventory(Player player) +// { +// base.UpdateInventory(player); +// +// if (wasEquipedLastFrame) +// { +// wasEquipedLastFrame = false; +// ModContent.GetInstance().HideMyUI(); +// showingUI = false; +// if (player.GetModPlayer().isTransformed) { +// TransformationHandler.Detransform(player, cooldownTime, true, true); +// } else { +// TransformationHandler.Detransform(player, cooldownTime, false, false); +// } +// } +// } +// +// public override bool CanEquipAccessory(Player player, int slot, bool modded) { +// return modded; +// } +// +// public override bool PreDrawInInventory(SpriteBatch spriteBatch, Vector2 position, Rectangle frame, Color drawColor, Color itemColor, Vector2 origin, float scale) { +// +// if (player == null) +// return true; +// +// dynamicTexture = player.GetModPlayer().onCooldown ? ModContent.Request("Ben10Mod/Content/Items/Accessories/RecalibratedOmnitrixAlt").Value : ModContent.Request("Ben10Mod/Content/Items/Accessories/RecalibratedOmnitrix").Value; +// +// spriteBatch.Draw(dynamicTexture, position, null, drawColor, 0f, origin, scale, SpriteEffects.None, 0f); +// +// return false; +// } +// +// public override void AddRecipes() { +// base.AddRecipes(); +// +// Recipe recipeAlt = CreateRecipe() +// .AddIngredient(ModContent.ItemType()) +// .AddIngredient(ItemID.SoulofNight, 5) +// .AddIngredient(ItemID.SoulofLight, 5) +// .AddTile(TileID.MythrilAnvil).Register(); +// +// } +// } +// } \ No newline at end of file diff --git a/Content/Items/Weapons/PlumberHelperBadge.cs b/Content/Items/Weapons/PlumberHelperBadge.cs index 523a028..388c27e 100644 --- a/Content/Items/Weapons/PlumberHelperBadge.cs +++ b/Content/Items/Weapons/PlumberHelperBadge.cs @@ -10,13 +10,13 @@ public override void AddRecipes() { CreateRecipe() .AddIngredient(ItemID.IronBar, 15) - .AddIngredient(ItemID.Lens, 5) + .AddIngredient(ItemID.Glass, 5) .AddTile(TileID.Anvils) .Register(); CreateRecipe() .AddIngredient(ItemID.LeadBar, 15) - .AddIngredient(ItemID.Lens, 5) + .AddIngredient(ItemID.Glass, 5) .AddTile(TileID.Anvils) .Register(); } diff --git a/Content/Items/Weapons/PlumberMagisterBadge.cs b/Content/Items/Weapons/PlumberMagisterBadge.cs new file mode 100644 index 0000000..f928b16 --- /dev/null +++ b/Content/Items/Weapons/PlumberMagisterBadge.cs @@ -0,0 +1,18 @@ +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Items.Weapons; + +public class PlumberMagisterBadge : PlumbersBadge { + public override int BaseDamage => 55; + public override string BadgeRankName => "Magister"; + + public override void AddRecipes() + { + CreateRecipe() + .AddIngredient(ModContent.ItemType()) + .AddIngredient(ItemID.HellstoneBar, 25) + .AddTile(TileID.Anvils) + .Register(); + } +} \ No newline at end of file diff --git a/Content/Items/Weapons/PlumberMagisterBadge.png b/Content/Items/Weapons/PlumberMagisterBadge.png new file mode 100644 index 0000000000000000000000000000000000000000..ddcf52683469a47d58e6037d2da734a84b25468f GIT binary patch literal 581 zcmV-L0=oT)P)00001b5ch_0Itp) z=>Px$|4BqaR9J=Wm@!BKVHC&zN+g6dq)U_0(vm})fe}dr4MMFhw+Rhx4&o9m5*QIQ z1Ww-4TGS9o5K&-TgERyUIfRQgnP7u9yzd=%pLgdSIDAI`MfiN*_db62f4p}Wz?c+^ zMF)24i_Mm8{QVCCZs!HZbg!{%%I^jzGH>TrGB@8P06@L|Vp)GYy6}`oSz@lw88(Du zGD~|=UkN{Yw0|K)`x=dw?H!aQ=IAjd7G(!n}LDvc!g-?eI<)~ZBmGZOKavE8O~I$;1nZO-uA04A@gON_m>mM2p2_zGYl zM&c?=9+L@ulM*ua337Zc^r|IJSz`Ye^DCn&*;9oC^|UJ1ErA8ldND_yxbx|?<#ZYV za9XJV0A_MK003Qhi>p2*Jg+RVfa64}Nxf3H@0DE#a!iQDq)M}0z|<@GJQjBXb%{Cs zA(NCRPbOMK#x()YVJvw+67;i8mNR(); // Safety defaults - Item.useTime = Item.useAnimation = 25; - Item.shootSpeed = 10f; + Item.useTime = Item.useAnimation = 25; + Item.shootSpeed = 10f; + Item.useStyle = ItemUseStyleID.Swing; + Item.ArmorPenetration = 0; if (!omp.isTransformed) return; @@ -64,7 +66,6 @@ public override void HoldItem(Player player) case TransformationEnum.HeatBlast: if (player.altFunctionUse == 2) { - Item.useStyle = ItemUseStyleID.Swing; Item.useTime = Item.useAnimation = 50; Item.shootSpeed = 10f; } @@ -84,8 +85,10 @@ public override void HoldItem(Player player) break; case TransformationEnum.DiamondHead: - Item.useTime = Item.useAnimation = 30; - Item.shootSpeed = 35f; + Item.useStyle = ItemUseStyleID.Shoot; + Item.useTime = Item.useAnimation = 8; + Item.shootSpeed = 35f; + Item.ArmorPenetration = 10; break; case TransformationEnum.RipJaws: @@ -164,6 +167,8 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, projType = player.altFunctionUse == 2 ? 0 : ModContent.ProjectileType(); + finalDamage = (int)(damage * 0.5f); + velocity.Y += Main.rand.NextFloat(-0.35f, 0.35f); break; case TransformationEnum.RipJaws: diff --git a/Content/Items/Weapons/ProvisionalAgentBadgeCrimtane.cs b/Content/Items/Weapons/ProvisionalAgentBadgeCrimtane.cs index 728363c..b4d1072 100644 --- a/Content/Items/Weapons/ProvisionalAgentBadgeCrimtane.cs +++ b/Content/Items/Weapons/ProvisionalAgentBadgeCrimtane.cs @@ -11,7 +11,7 @@ public override void AddRecipes() { CreateRecipe() .AddIngredient(ModContent.ItemType()) - .AddIngredient(ItemID.DemoniteBar, 15) + .AddIngredient(ItemID.CrimtaneBar, 15) .AddTile(TileID.Anvils) .Register(); } diff --git a/Content/Projectiles/DiamondHeadProjectile.cs b/Content/Projectiles/DiamondHeadProjectile.cs index 79a8deb..ef8a548 100644 --- a/Content/Projectiles/DiamondHeadProjectile.cs +++ b/Content/Projectiles/DiamondHeadProjectile.cs @@ -19,8 +19,13 @@ public override void SetDefaults() { Projectile.hostile = false; Projectile.aiStyle = ProjAIStyleID.Arrow; - + AIType = ProjectileID.Bullet; + Projectile.DamageType = DamageClass.Ranged; } + + public override void AI() { + Projectile.spriteDirection = Projectile.direction; + } } } diff --git a/Content/Projectiles/DiamondHeadProjectile.png b/Content/Projectiles/DiamondHeadProjectile.png index 1d4ab98895fb9bcb10de149bc9672ce800d239b6..f5fcdc0a7ff65b0eaa8db944c3409c8925b39eaa 100644 GIT binary patch delta 114 zcmbQnIEQh9VRo3Oi(`ny)Z_#QrXsOh|DWn?`ER^{dzOFCul>KiU;Gaeo0-rwY2q&) zwr^nttv)wcBqbyyW=Iq;JW`3-!n-n6q>W`)aAqRA*?|)bye=sR-PP9_F)^G75Nm15 R56NHv0#8>zmvv4FO#mlZE%X2Y delta 108 zcmV-y0F(cm0hR%fF=bFmL_t&-m1AUJU|^85(EiVW1RkBZ%E%~Zq5Xf~@!iPc3{IA= z3``6-01E>H1H<`0_c0`J>cDT*o~!4nU=)5kE*v~YOFM8%FfuS;4|V{WX%qzx7zytH O0000&VIXUNWug0Bve0~Ylch7aS zq&fW_@b&E-|8Qb99g{Cu0AUi59tW4~8mY8#^QTIqjhQhRL4T-{Jg8tJo4e;omXXax z>}dkr>J0#-xsE0+_{RW%YP}g51XwTUtU;1RG7!Em=RX2J zCV9JANiv}Xpw$~Nf>0MjqVffce8FP7SrP1aHyJ#2`%wh|9i{p8`H>i&P!a#G1NeuN zY!u73w4;Kzn|~F>vK`4L*zeFi*U?50RvK*pF6Tg65rIMfTLM#QgM7haHXUPTu0bO90A-P?^(OxDO4jN2@eij+FWB$oN=pTv>u5=-$4dnh uzXg#8K*_E}fQ!jc&Zzyw6XhT0{0lYQu?E0ARyqIx00{s|MNUMnLSTYPxweb| delta 423 zcmV;Y0a*UG1I`1GF@K0jL_t(IjkS}(ZrVT)hQC>xn1n#EpjE|7R7K*%%j7YTI3w{6 zz3>7(_X)TZiK^-g^wdk7tZfVm*xv0Wc8sx-Q%729G&}!4|IE(9|Frwr!rspo_N^Rg z0u}yrGTsB7^=1peYB|5impXVl8UF%4H&t72wihH)1Hao=oqt4Cz{h%WZgRqSN0#S^ zNYU0=o2ruU6_VoQKoCYmyFJEQ;$%;tLr&@Gf<#rN3lKbMvOGhHpp@{SBaX)tj-yBp z&qTZZnM$`Dh6s;ggg6dao)PF>84r^K`UN=jy97FAIvHzb3#(`_9lut2dJM{At*zeu zIh%pC7Gn$my?>kQvU*iv9BO(u*SLg R4G91M002ovPDHLkV1kEI&}{$! diff --git a/Localization/en-US_Mods.Ben10Mod.hjson b/Localization/en-US_Mods.Ben10Mod.hjson index 263f4f3..5a5a0c0 100644 --- a/Localization/en-US_Mods.Ben10Mod.hjson +++ b/Localization/en-US_Mods.Ben10Mod.hjson @@ -170,6 +170,16 @@ Items: { DisplayName: Plumber Capsule Pod Item Tooltip: "" } + + AdvancedCircuitMatrix: { + DisplayName: Advanced Circuit Matrix + Tooltip: "" + } + + PlumberMagisterBadge: { + DisplayName: Plumber Magister Badge + Tooltip: "" + } } Keybinds: { diff --git a/OmnitrixPlayer.cs b/OmnitrixPlayer.cs index 71a9fd6..6953b3d 100644 --- a/OmnitrixPlayer.cs +++ b/OmnitrixPlayer.cs @@ -46,6 +46,12 @@ public class OmnitrixPlayer : ModPlayer { public bool wasTransformed = false; public bool onCooldown = false; + public bool advancedCircuitMatrix = false; + public bool wasAdvancedCircuitMatrix = false; + + public int cooldownTime = 120; + public int transformationTime = 300; + public bool XLR8PrimaryAbilityEnabled = false; public bool XLR8PrimaryAbilityWasEnabled = false; public bool HeatBlastPrimaryAbilityEnabled = false; @@ -138,6 +144,11 @@ public override void LoadData(TagCompound tag) { public override void ResetEffects() { + advancedCircuitMatrix = false; + + cooldownTime = 120; + transformationTime = 300; + // Transformations isTransformed = false; onCooldown = false; @@ -175,20 +186,29 @@ public override void PostUpdateBuffs() { var abilitySlot = ModContent.GetInstance(); // Handles the detransformation effect + + if (wasAdvancedCircuitMatrix != advancedCircuitMatrix) { + if (wasTransformed != isTransformed) { + wasAdvancedCircuitMatrix = advancedCircuitMatrix; + } + } if (wasTransformed != isTransformed) { var customSlot = ModContent.GetInstance(); if (customSlot != null) { - if (customSlot.FunctionalItem.ModItem is PrototypeOmnitrix prototypeOmnitrix) { - if (masterControl) { - TransformationHandler.Detransform(Player, 0, true, false); - } else { - TransformationHandler.Detransform(Player, prototypeOmnitrix.cooldownTime); - } + if (masterControl) { + TransformationHandler.Detransform(Player, 0, true, false); + } else { + TransformationHandler.Detransform(Player, cooldownTime); } } wasTransformed = false; } + + if (wasAdvancedCircuitMatrix) { + transformationTime *= 2; + cooldownTime *= 2; + } // XLR8 Transformation @@ -201,7 +221,7 @@ public override void PostUpdateBuffs() { Player.moveSpeed *= 2.5f * multiplier; Player.accRunSpeed *= 2.0f * multiplier; - Player.GetAttackSpeed(DamageClass.Generic) += (multiplier / 5); + Player.GetAttackSpeed(DamageClass.Generic) += (multiplier / 2); if (Math.Abs(Player.velocity.X) > 2) { Player.jumpSpeed *= 1.5f * multiplier; Player.waterWalk = true; @@ -230,15 +250,13 @@ public override void PostUpdateBuffs() { if (currTransformation == TransformationEnum.DiamondHead) { Player.statDefense += 25; - Player.GetDamage(DamageClass.Melee) *= 1.25f; - Player.GetDamage() *= 1.25f; if (DiamondHeadPrimaryAbilityEnabled) { - Player.moveSpeed = 0; - Player.lifeRegen += 10; - Player.immune = true; - Player.immuneAlpha = 0; - Player.releaseJump = false; + Player.moveSpeed /= 10; + Player.lifeRegen += 15; + Player.statDefense *= 2; + Player.releaseJump = false; + Player.gravity *= 2f; } } @@ -268,13 +286,11 @@ public override void PostUpdateBuffs() { // Fourarms Transformation if (currTransformation == TransformationEnum.FourArms) { - - Player.GetDamage(DamageClass.Melee) *= 1.25f; - Player.GetDamage() *= 1.25f; + Player.GetAttackSpeed(DamageClass.Melee) += 0.25f; - Player.GetCritChance(DamageClass.Generic) = 100; + Player.GetCritChance(DamageClass.Generic) = 50; Player.noFallDmg = true; - Player.jumpSpeed *= 1.75f; + Player.jumpSpeed *= 1.9f; } // Stinkfly Transformation @@ -301,22 +317,6 @@ public override void PostUpdate() { if (!isTransformed) { abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } - - // Handles the detransformation effect - - if (wasTransformed != isTransformed) { - var customSlot = ModContent.GetInstance(); - if (customSlot != null) { - if (customSlot.FunctionalItem.ModItem is PrototypeOmnitrix prototypeOmnitrix) { - if (masterControl) { - TransformationHandler.Detransform(Player, 0, true, false); - } else { - TransformationHandler.Detransform(Player, prototypeOmnitrix.cooldownTime); - } - } - } - wasTransformed = false; - } // XLR8 Transformation @@ -346,15 +346,15 @@ public override void PostUpdate() { } } if (HeatBlastPrimaryAbilityEnabled) { - Vector2[] points = GenerateCirclePoints(250, 10 * (16)); + Vector2[] points = GenerateCirclePoints(250, 7 * (16)); for (int i = 0; i < points.Length; i++) { dustNum = Dust.NewDust(points[i] + Player.Center, 1, 1, DustID.Torch, rand.Next(-1, 2), rand.Next(-1, 2)); Main.dust[dustNum].noGravity = true; } foreach (NPC npc in Main.npc) { if (Player.Distance(npc.Center) <= 10 * (16) && !npc.friendly) { - if (!npc.HasBuff(BuffID.OnFire)) { - npc.AddBuff(BuffID.OnFire, 10 * 60); + if (!npc.HasBuff(BuffID.OnFire3)) { + npc.AddBuff(BuffID.OnFire3, 10 * 60); } } } @@ -376,13 +376,23 @@ public override void PostUpdate() { if (currTransformation == TransformationEnum.DiamondHead) { if (KeybindSystem.PrimaryAbility.JustPressed) { if (!Player.HasBuff(ModContent.BuffType()) && !Player.HasBuff(ModContent.BuffType())) { - Player.AddBuff(ModContent.BuffType(), 5 * 60); + Player.AddBuff(ModContent.BuffType(), 60 * 60); + Player.velocity = Vector2.Zero; } } abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } + if (DiamondHeadPrimaryAbilityEnabled != DiamondHeadPrimaryAbilityWasEnabled) { + DiamondHeadPrimaryAbilityWasEnabled = false; + // Player.AddBuff(ModContent.BuffType(), 25 * 60); + } + + if (DiamondHeadPrimaryAbilityEnabled) { + Lighting.AddLight(Player.Center, new Vector3(0.4f, 0.3f, 0.8f)); + } + // Ripjaws Transformation if (currTransformation == TransformationEnum.RipJaws) { @@ -416,7 +426,7 @@ public override void PostUpdate() { // Buzzshock Transformation if (currTransformation == TransformationEnum.BuzzShock) { - if (KeybindSystem.PrimaryAbility.JustPressed && !Player.HasBuff(BuffID.ChaosState)) { + if (KeybindSystem.PrimaryAbility.JustPressed) { if (Main.myPlayer == Player.whoAmI) { SoundEngine.PlaySound(SoundID.Item8, Player.position); Random random = new Random(); @@ -596,6 +606,7 @@ public override void ModifyDrawInfo(ref PlayerDrawSet drawInfo) { drawInfo.colorArmorLegs = overlayColor; break; case TransformationEnum.DiamondHead: + break; case TransformationEnum.FourArms: case TransformationEnum.RipJaws: case TransformationEnum.StinkFly: @@ -626,17 +637,17 @@ public override void DrawEffects(PlayerDrawSet drawInfo, ref float r, ref float } } } - else if (customSlot.FunctionalItem.type == ModContent.ItemType()) { - var costume = ModContent.GetInstance(); - if (!customSlot.HideVisuals && !isTransformed) { - if (onCooldown) { - Player.handon = EquipLoader.GetEquipSlot(Mod, "RecalibratedOmnitrixAlt", EquipType.HandsOn); - } - else { - Player.handon = EquipLoader.GetEquipSlot(Mod, "RecalibratedOmnitrix", EquipType.HandsOn); - } - } - } + // else if (customSlot.FunctionalItem.type == ModContent.ItemType()) { + // var costume = ModContent.GetInstance(); + // if (!customSlot.HideVisuals && !isTransformed) { + // if (onCooldown) { + // Player.handon = EquipLoader.GetEquipSlot(Mod, "RecalibratedOmnitrixAlt", EquipType.HandsOn); + // } + // else { + // Player.handon = EquipLoader.GetEquipSlot(Mod, "RecalibratedOmnitrix", EquipType.HandsOn); + // } + // } + // } } if (!customSlot.HideVisuals) { @@ -665,17 +676,17 @@ public override void FrameEffects() { } } } - else if (customSlot.FunctionalItem.type == ModContent.ItemType()) { - var costume = ModContent.GetInstance(); - if (!customSlot.HideVisuals && !isTransformed) { - if (onCooldown) { - Player.handon = EquipLoader.GetEquipSlot(Mod, "RecalibratedOmnitrixAlt", EquipType.HandsOn); - } - else { - Player.handon = EquipLoader.GetEquipSlot(Mod, "RecalibratedOmnitrix", EquipType.HandsOn); - } - } - } + // else if (customSlot.FunctionalItem.type == ModContent.ItemType()) { + // var costume = ModContent.GetInstance(); + // if (!customSlot.HideVisuals && !isTransformed) { + // if (onCooldown) { + // Player.handon = EquipLoader.GetEquipSlot(Mod, "RecalibratedOmnitrixAlt", EquipType.HandsOn); + // } + // else { + // Player.handon = EquipLoader.GetEquipSlot(Mod, "RecalibratedOmnitrix", EquipType.HandsOn); + // } + // } + // } } if (!customSlot.HideVisuals) { if (isTransformed) { diff --git a/ShopNPC.cs b/ShopNPC.cs new file mode 100644 index 0000000..a4ea5d5 --- /dev/null +++ b/ShopNPC.cs @@ -0,0 +1,20 @@ +using Ben10Mod.Content.Items.Accessories; +using Ben10Mod.Content.Items.Vanity; +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod; + +public class ShopNPC : GlobalNPC { + public override void ModifyShop(NPCShop shop) { + if (shop.NpcType == NPCID.Mechanic) { + shop.Add(ModContent.ItemType()); + } + + if (shop.NpcType == NPCID.Clothier) { + shop.Add(ModContent.ItemType()); + shop.Add(ModContent.ItemType()); + } + } +} \ No newline at end of file diff --git a/OmnitrixNPC.cs b/bossTrackerNPC.cs similarity index 89% rename from OmnitrixNPC.cs rename to bossTrackerNPC.cs index 4bdb75a..555a1dd 100644 --- a/OmnitrixNPC.cs +++ b/bossTrackerNPC.cs @@ -7,7 +7,7 @@ using Terraria.ModLoader; namespace Ben10Mod { - public class OmnitrixNPC : GlobalNPC + public class bossTrackerNPC : GlobalNPC { public override bool InstancePerEntity => true; @@ -67,6 +67,24 @@ public override void OnKill(NPC npc) int credited = GetTopDamager(npc); if (credited == -1) return; + int eaterCount = 0; + + if (npc.type == NPCID.EaterofWorldsBody || npc.type == NPCID.EaterofWorldsHead || + npc.type == NPCID.EaterofWorldsTail) { + for (int i = 0; i < Main.npc.Length; i++) { + if (Main.npc[i].type == NPCID.EaterofWorldsBody || Main.npc[i].type == NPCID.EaterofWorldsHead || + Main.npc[i].type == NPCID.EaterofWorldsTail) { + if (Main.npc[i].active) { + eaterCount++; + } + } + } + } + + if (eaterCount > 1) { + return; + } + string msg = $"{Main.player[credited].name} dealt the most damage!"; // Show message in both SP and MP From 49c109d23406127f9897665608b8756c1e7dd2ed Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Tue, 17 Feb 2026 08:43:31 +1100 Subject: [PATCH 02/25] Balance changes, working on adding shader to heatblast --- Assets/Effects/HeatDistort.fx | 27 ++ .../Systems/GenPasses/OmnitrixCapsulePass.cs | 296 ++++++------ Common/Systems/HeatBlastShaderSystem.cs | 28 ++ .../Accessories/AdvancedCircuitMatrix.cs | 5 +- .../Accessories/AdvancedCircuitMatrix.png | Bin 432 -> 341 bytes .../Items/Accessories/PrototypeOmnitrix.cs | 10 +- .../Items/Accessories/RecalibratedOmnitrix.cs | 447 +++++++++--------- .../Accessories/RecalibratedOmnitrix.png | Bin 776 -> 376 bytes .../Accessories/RecalibratedOmnitrixAlt.png | Bin 772 -> 369 bytes Content/Items/Consumable/MasterControlKey.cs | 66 +++ Content/Items/Consumable/MasterControlKey.png | Bin 0 -> 148 bytes Content/Items/Weapons/PlumberMagisterBadge.cs | 2 +- Content/Items/Weapons/PlumbersBadge.cs | 63 +-- Content/Projectiles/DiamondHeadProjectile.cs | 1 + Content/TransformationHandler.cs | 10 +- Localization/en-US_Mods.Ben10Mod.hjson | 5 + OmnitrixPlayer.cs | 91 ++-- ShopNPC.cs | 10 + build.txt | 2 +- 19 files changed, 611 insertions(+), 452 deletions(-) create mode 100644 Assets/Effects/HeatDistort.fx create mode 100644 Common/Systems/HeatBlastShaderSystem.cs create mode 100644 Content/Items/Consumable/MasterControlKey.cs create mode 100644 Content/Items/Consumable/MasterControlKey.png diff --git a/Assets/Effects/HeatDistort.fx b/Assets/Effects/HeatDistort.fx new file mode 100644 index 0000000..785070f --- /dev/null +++ b/Assets/Effects/HeatDistort.fx @@ -0,0 +1,27 @@ +sampler2D ScreenTexture : register(s0); + +float4 uColor; +float uOpacity; +float uTime; +float2 uTargetPosition; // screen-space-ish, provided by tML shader pipeline +float uIntensity; + +float4 HeatDistortPass(float2 uv : TEXCOORD0) : COLOR0 +{ + // Simple animated wave distortion + float wave = sin((uv.y * 120.0) + (uTime * 3.2)) * 0.0018; + float wave2 = cos((uv.x * 95.0) + (uTime * 2.6)) * 0.0012; + + float2 distortedUV = uv + float2(wave, wave2) * uIntensity; + float4 col = tex2D(ScreenTexture, distortedUV); + + return col; +} + +technique HeatDistortPass +{ + pass P0 + { + PixelShader = compile ps_2_0 HeatDistortPass(); + } +} diff --git a/Common/Systems/GenPasses/OmnitrixCapsulePass.cs b/Common/Systems/GenPasses/OmnitrixCapsulePass.cs index 136792e..6bdb656 100644 --- a/Common/Systems/GenPasses/OmnitrixCapsulePass.cs +++ b/Common/Systems/GenPasses/OmnitrixCapsulePass.cs @@ -14,182 +14,180 @@ protected override void ApplyPass(GenerationProgress progress, GameConfiguration progress.Message = "Calling down a strange meteor..."; // --- 0) Your tiles --- - int meteorOreTile = TileID.Silver; - int meteorRockTile = ModContent.TileType(); - int capsuleTile = ModContent.TileType(); // 1x1 capsule - + int meteorOreTile = TileID.Silver; + int meteorRockTile = ModContent.TileType(); + int capsuleTile = ModContent.TileType(); // 1x1 capsule + var rand = WorldGen.genRand; - // --- 1) Pick a surface position --- + // --- 1) Pick a surface position --- - // Avoid very close to edges to prevent clipping into oceans. - int centerX = rand.Next(300, Main.maxTilesX - 300); + // Avoid very close to edges to prevent clipping into oceans. + int centerX = rand.Next(300, Main.maxTilesX - 300); - // Find the "surface" at this X: first solid tile going down. - int surfaceY = -1; - for (int y = 0; y < Main.maxTilesY - 300; y++) { - if (WorldGen.SolidTile(centerX, y)) { - surfaceY = y; - break; + // Find the "surface" at this X: first solid tile going down. + int surfaceY = -1; + for (int y = 0; y < Main.maxTilesY - 300; y++) { + if (WorldGen.SolidTile(centerX, y)) { + surfaceY = y; + if (Main.rand.Next(101) == 1) { + break; + } + } } - } - - // If we couldn't find solid ground for some reason, bail. - if (surfaceY < 0) - return; - - // --- 2) Define meteor shape parameters --- - - // Overall horizontal and vertical extents of the meteor blob - int halfWidth = 12; - int halfHeight = 5; - - // The center of the meteor mass is a bit below the surface - int meteorCenterY = surfaceY + 10; - - // Crater radius around the surface - int craterRadius = 26; - - // Clamp Y so we don't go out of world bounds - if (meteorCenterY > Main.maxTilesY - 60) - meteorCenterY = Main.maxTilesY - 60; - - // --- 3) Carve a crater on the surface (kill tiles in a circle) --- - - // int craterMinX = centerX - craterRadius - 5; - // int craterMaxX = centerX + craterRadius + 5; - // int craterMinY = surfaceY - 10; - // int craterMaxY = surfaceY + 10; - // - // for (int x = craterMinX; x <= craterMaxX; x++) { - // for (int y = craterMinY; y <= craterMaxY; y++) { - // if (!WorldGen.InWorld(x, y, 20)) - // continue; - // - // float dx = x - centerX; - // float dy = y - surfaceY; - // float dist = (float)System.Math.Sqrt(dx * dx + dy * dy); - // - // // Slightly flattened crater - // float craterShape = craterRadius * (1f + 0.15f * (float)System.Math.Sin(dx / 4f)); - // if (dist <= craterShape) { - // WorldGen.KillTile(x, y, noItem: true); - // } - // } - // } - - // --- 4) Build a lumpy meteor blob under the crater --- - - int meteorMinX = centerX - halfWidth; - int meteorMaxX = centerX + halfWidth; - int meteorMinY = meteorCenterY - halfHeight; - int meteorMaxY = meteorCenterY + halfHeight; - - if (meteorMinY < 10) meteorMinY = 10; - if (meteorMaxY > Main.maxTilesY - 30) meteorMaxY = Main.maxTilesY - 30; - - for (int x = meteorMinX; x <= meteorMaxX; x++) { - for (int y = meteorMinY; y <= meteorMaxY; y++) { - if (!WorldGen.InWorld(x, y, 20)) - continue; - - float dx = (x - centerX) / (float)halfWidth; - float dy = (y - meteorCenterY) / (float)halfHeight; - float distSq = dx * dx + dy * dy; - - if (distSq > 1.2f) - continue; // outside the main ellipse - - // Add some noise so the outline isn't perfectly smooth - float noise = (float)(rand.NextDouble() * 0.35 - 0.15); // [-0.15, +0.20] - if (distSq > 1f + noise) - continue; - - Tile t = Main.tile[x, y]; - if (t == null) - continue; - - t.HasTile = true; - // About 1/6 chance to be the special codon ore - if (rand.Next(6) == 0) - t.TileType = (ushort)meteorOreTile; - else - t.TileType = (ushort)meteorRockTile; + // --- 2) Define meteor shape parameters --- + + // Overall horizontal and vertical extents of the meteor blob + int halfWidth = 12; + int halfHeight = 5; + + // The center of the meteor mass is a bit below the surface + int meteorCenterY = surfaceY + 10; + + // Crater radius around the surface + int craterRadius = 26; + + // Clamp Y so we don't go out of world bounds + if (meteorCenterY > Main.maxTilesY - 60) + meteorCenterY = Main.maxTilesY - 60; + + // --- 3) Carve a crater on the surface (kill tiles in a circle) --- + + // int craterMinX = centerX - craterRadius - 5; + // int craterMaxX = centerX + craterRadius + 5; + // int craterMinY = surfaceY - 10; + // int craterMaxY = surfaceY + 10; + // + // for (int x = craterMinX; x <= craterMaxX; x++) { + // for (int y = craterMinY; y <= craterMaxY; y++) { + // if (!WorldGen.InWorld(x, y, 20)) + // continue; + // + // float dx = x - centerX; + // float dy = y - surfaceY; + // float dist = (float)System.Math.Sqrt(dx * dx + dy * dy); + // + // // Slightly flattened crater + // float craterShape = craterRadius * (1f + 0.15f * (float)System.Math.Sin(dx / 4f)); + // if (dist <= craterShape) { + // WorldGen.KillTile(x, y, noItem: true); + // } + // } + // } + + // --- 4) Build a lumpy meteor blob under the crater --- + + int meteorMinX = centerX - halfWidth; + int meteorMaxX = centerX + halfWidth; + int meteorMinY = meteorCenterY - halfHeight; + int meteorMaxY = meteorCenterY + halfHeight; + + if (meteorMinY < 10) meteorMinY = 10; + if (meteorMaxY > Main.maxTilesY - 30) meteorMaxY = Main.maxTilesY - 30; + + for (int x = meteorMinX; x <= meteorMaxX; x++) { + for (int y = meteorMinY; y <= meteorMaxY; y++) { + if (!WorldGen.InWorld(x, y, 20)) + continue; + + float dx = (x - centerX) / (float)halfWidth; + float dy = (y - meteorCenterY) / (float)halfHeight; + float distSq = dx * dx + dy * dy; + + if (distSq > 1.2f) + continue; // outside the main ellipse + + // Add some noise so the outline isn't perfectly smooth + float noise = (float)(rand.NextDouble() * 0.35 - 0.15); // [-0.15, +0.20] + if (distSq > 1f + noise) + continue; + + Tile t = Main.tile[x, y]; + if (t == null) + continue; + + t.HasTile = true; + + // About 1/6 chance to be the special codon ore + if (rand.Next(6) == 0) + t.TileType = (ushort)meteorOreTile; + else + t.TileType = (ushort)meteorRockTile; + } } - } - // --- 5) Fix framing in the area so it looks correct --- + // --- 5) Fix framing in the area so it looks correct --- - int frameMinX = meteorMinX - 2; - int frameMaxX = meteorMaxX + 2; - int frameMinY = meteorMinY - 2; - int frameMaxY = meteorMaxY + 2; + int frameMinX = meteorMinX - 2; + int frameMaxX = meteorMaxX + 2; + int frameMinY = meteorMinY - 2; + int frameMaxY = meteorMaxY + 2; - for (int x = frameMinX; x <= frameMaxX; x++) { - for (int y = frameMinY; y <= frameMaxY; y++) { - if (!WorldGen.InWorld(x, y, 20)) - continue; + for (int x = frameMinX; x <= frameMaxX; x++) { + for (int y = frameMinY; y <= frameMaxY; y++) { + if (!WorldGen.InWorld(x, y, 20)) + continue; - WorldGen.SquareTileFrame(x, y, resetFrame: true); + WorldGen.SquareTileFrame(x, y, resetFrame: true); + } } - } - // --- 6) Find a top spot on the meteor for the capsule --- + // --- 6) Find a top spot on the meteor for the capsule --- - int bestX = -1; - int bestY = -1; + int bestX = -1; + int bestY = -1; - int searchHalfWidth = 20; - int searchTopY = surfaceY - 10; - int searchBottomY = meteorMinY + (meteorMaxY - meteorMinY) / 2; + int searchHalfWidth = 20; + int searchTopY = surfaceY - 10; + int searchBottomY = meteorMinY + (meteorMaxY - meteorMinY) / 2; - if (searchTopY < 10) searchTopY = 10; - if (searchBottomY > Main.maxTilesY - 30) searchBottomY = Main.maxTilesY - 30; - - for (int x = centerX - searchHalfWidth; x <= centerX + searchHalfWidth; x++) { - if (x < meteorMinX || x > meteorMaxX) - continue; - - // scan downward from just above the crater - for (int y = searchTopY; y <= searchBottomY; y++) { - if (!WorldGen.InWorld(x, y, 20)) - continue; + if (searchTopY < 10) searchTopY = 10; + if (searchBottomY > Main.maxTilesY - 30) searchBottomY = Main.maxTilesY - 30; - Tile t = Main.tile[x, y]; - if (t == null || !t.HasTile) + for (int x = centerX - searchHalfWidth; x <= centerX + searchHalfWidth; x++) { + if (x < meteorMinX || x > meteorMaxX) continue; - if (t.TileType == meteorRockTile || t.TileType == meteorOreTile) { - Tile above = Main.tile[x, y - 1]; - if (above != null && !above.HasTile) { - bestX = x; - bestY = y - 1; - break; + // scan downward from just above the crater + for (int y = searchTopY; y <= searchBottomY; y++) { + if (!WorldGen.InWorld(x, y, 20)) + continue; + + Tile t = Main.tile[x, y]; + if (t == null || !t.HasTile) + continue; + + if (t.TileType == meteorRockTile || t.TileType == meteorOreTile) { + Tile above = Main.tile[x, y - 1]; + if (above != null && !above.HasTile) { + bestX = x; + bestY = y - 1; + break; + } } } - } - if (bestX != -1) - break; - } + if (bestX != -1) + break; + } - if (bestX == -1) { - // Couldn't find a clean top; meteor still exists, just no capsule. - return; - } + if (bestX == -1) { + // Couldn't find a clean top; meteor still exists, just no capsule. + return; + } - // --- 7) Place the 1x1 PlumberCapsulePod tile --- + // --- 7) Place the 1x1 PlumberCapsulePod tile --- - Tile cap = Main.tile[bestX, bestY]; - cap.HasTile = true; - cap.TileType = (ushort)capsuleTile; + Tile cap = Main.tile[bestX, bestY]; + cap.HasTile = true; + cap.TileType = (ushort)capsuleTile; - WorldGen.SquareTileFrame(bestX, bestY, resetFrame: true); + WorldGen.SquareTileFrame(bestX, bestY, resetFrame: true); - if (Main.netMode == NetmodeID.Server) { - NetMessage.SendTileSquare(-1, bestX, bestY, 1, 1); - } + if (Main.netMode == NetmodeID.Server) { + NetMessage.SendTileSquare(-1, bestX, bestY, 1, 1); + } } } } \ No newline at end of file diff --git a/Common/Systems/HeatBlastShaderSystem.cs b/Common/Systems/HeatBlastShaderSystem.cs new file mode 100644 index 0000000..2a75ee8 --- /dev/null +++ b/Common/Systems/HeatBlastShaderSystem.cs @@ -0,0 +1,28 @@ +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.Graphics.Effects; +using Terraria.Graphics.Shaders; +using Terraria.ModLoader; + +namespace Ben10Mod.Common.Systems; + +public class HeatBlastShaderSystem : ModSystem { + public override void Load() { + if (Main.dedServ) + return; + + Ref effect = new Ref(ModContent.Request("Ben10Mod/Assets/Effects/HeatDistort", + ReLogic.Content.AssetRequestMode.ImmediateLoad).Value); + + Filters.Scene["Ben10Mod:HeatDistort"] = new Filter( + new ScreenShaderData(effect, "HeatDistortPass"), + EffectPriority.VeryHigh); + } + + public override void Unload() { + if (!Main.dedServ) { + Filters.Scene.Deactivate("Ben10Mod:HeatDistort"); + Filters.Scene["Ben10Mod:HeatDistort"] = null; + } + } +} \ No newline at end of file diff --git a/Content/Items/Accessories/AdvancedCircuitMatrix.cs b/Content/Items/Accessories/AdvancedCircuitMatrix.cs index a3e4a0e..c2eaff7 100644 --- a/Content/Items/Accessories/AdvancedCircuitMatrix.cs +++ b/Content/Items/Accessories/AdvancedCircuitMatrix.cs @@ -8,8 +8,8 @@ namespace Ben10Mod.Content.Items.Accessories; public class AdvancedCircuitMatrix : ModItem { public override void SetDefaults() { - Item.width = 64; - Item.height = 64; + Item.width = 32; + Item.height = 32; Item.accessory = true; Item.value = 100000; } @@ -17,6 +17,5 @@ public override void SetDefaults() { public override void UpdateAccessory(Player player, bool hideVisual) { var omp = player.GetModPlayer(); omp.advancedCircuitMatrix = true; - omp.wasAdvancedCircuitMatrix = true; } } \ No newline at end of file diff --git a/Content/Items/Accessories/AdvancedCircuitMatrix.png b/Content/Items/Accessories/AdvancedCircuitMatrix.png index 7a935fa1db31b292f0cb44e110fb6a844df01024..c9f37be105b82169e491c012811fb9922a33a4b5 100644 GIT binary patch literal 341 zcmV-b0jmCqP)Px$4@pEpR9J=WS6dRoAPhvuE5QBF2ZyL%IC0rLiqbk`_opU8NW*TRDg8Tc;`esO z+V_JO9q>R$$$9C5wY4{!R-n|z-0rw;OTQOu;6TawHK~?71hIVGFKvXVfXx96qSPEBGiSLBhbn>$)e3wIUR6vPV&9LR4e0NZ49k!W^rXcICr?MM5>v-< zS4dO|tSOlZM3T~~gq6bW3nkzYrw8_$OeEIto`zQIWmhlFo^HifU`8sI6yBD?39ze` nw3!0fNoe^yPUpb&Wpv>QiSgLv(ALXb00000NkvXXu0mjfx;T?O literal 432 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%zvpiiKLn`LH zo$V`h&_SS8U26)j`NN#Dbq{6wlGEQZh;VC$Y!p;m`BQsth0p%{si#uns^-bfGzp&Z zZs+#}nZYHRW-o%?$S-7k!Ej;6v*7#1628f2UKua=V(Ozl`MujEOGFP|KbVAcPQby@zN~5C4AxRtG_vS{dRD_ zW$(JY_ZQCskl7a)N*FRS7_1mfE|xazU9)BWdcAMa_0e5G{at>ugAV?#pM9+2s(<65 z>5Qee4~q77GEg ze?yr4>NVplV~4$rYuGzNj2pf(Ow3~2ASaL$>hSW%`h<7;g-wo~u5wsnTMc%I34<(y zlvD#B1FyEz%jwTLtC;sxw;8SDC_F!bx4ie^qaVChciVrrRJZ@<1gSd9>>2c6Qr{C> RS6~z{c)I$ztaD0e0szL!xiSC% diff --git a/Content/Items/Accessories/PrototypeOmnitrix.cs b/Content/Items/Accessories/PrototypeOmnitrix.cs index b187c85..a8bdd3e 100644 --- a/Content/Items/Accessories/PrototypeOmnitrix.cs +++ b/Content/Items/Accessories/PrototypeOmnitrix.cs @@ -82,8 +82,7 @@ public override void SetDefaults() { Item.accessory = true; } - public override void ModifyTooltips(List tooltips) - { + public override void ModifyTooltips(List tooltips) { tooltips.Add(new TooltipLine(Mod, "AlienSelection", "Alien " + (transformationNum + 1) + ": " + transformations[transformationNum].ToString())); } @@ -107,12 +106,15 @@ public override void UpdateAccessory(Player player, bool hideVisual) { } if (KeybindSystem.TransformationKeybind.JustPressed && !player.GetModPlayer().isTransformed && !player.GetModPlayer().onCooldown) { - TransformationHandler.Transform(player, transformations[transformationNum], omp.transformationTime); + omp.advancedCircuitMatrixEquippedWhileTransformed = omp.advancedCircuitMatrix; + TransformationHandler.Transform(player, transformations[transformationNum], + omp.advancedCircuitMatrixEquippedWhileTransformed ? omp.transformationTime * 2 : omp.transformationTime); } else if (KeybindSystem.TransformationKeybind.JustPressed && player.GetModPlayer().isTransformed && !player.GetModPlayer().onCooldown && player.GetModPlayer().masterControl) { if (player.GetModPlayer().currTransformation != transformations[transformationNum]) { TransformationHandler.Detransform(player, 0, false, false, false); - TransformationHandler.Transform(player, transformations[transformationNum], omp.transformationTime); + TransformationHandler.Transform(player, transformations[transformationNum], + omp.advancedCircuitMatrixEquippedWhileTransformed ? omp.transformationTime * 2 : omp.transformationTime); } else { TransformationHandler.Detransform(player, omp.cooldownTime, true, false); } diff --git a/Content/Items/Accessories/RecalibratedOmnitrix.cs b/Content/Items/Accessories/RecalibratedOmnitrix.cs index a4778b9..b3bb396 100644 --- a/Content/Items/Accessories/RecalibratedOmnitrix.cs +++ b/Content/Items/Accessories/RecalibratedOmnitrix.cs @@ -1,222 +1,225 @@ -// using Ben10Mod.Content.Transformations; -// using Ben10Mod.Content.Transformations.XLR8; -// using Ben10Mod.Keybinds; -// using Microsoft.Xna.Framework; -// using Steamworks; -// using System; -// using Terraria; -// using Terraria.DataStructures; -// using Terraria.GameContent.UI.Elements; -// using Terraria.ID; -// using Terraria.ModLoader; -// using Terraria.ModLoader.IO; -// using Ben10Mod.Enums; -// using System.Collections.Generic; -// using System.Threading.Tasks.Dataflow; -// using System.Security.Cryptography.X509Certificates; -// using Ben10Mod.Content.Interface; -// using Ben10Mod.Content.Buffs.Abilities.ChromaStone; -// using Ben10Mod.Content.Buffs.Abilities.DiamondHead; -// using Ben10Mod.Content.Buffs.Abilities.HeatBlast; -// using Ben10Mod.Content.Buffs.Abilities.XLR8; -// using Ben10Mod.Content.Buffs.Transformations; -// using Ben10Mod.Content.Items.Placeables; -// using Ben10Mod.Content.DamageClasses; -// using Terraria.ModLoader.Default; -// using Microsoft.Xna.Framework.Graphics; -// using Terraria.Audio; -// -// namespace Ben10Mod.Content.Items.Accessories -// { -// public class RecalibratedOmnitrix : Omnitrix { -// -// private Player player = null; -// public int transformationNum = 0; -// public int transformationEnergy = 0; -// private int maxEnergy = 0; -// public TransformationEnum[] transformations = new TransformationEnum[5]; -// -// bool wasEquipedLastFrame = false; -// bool showingUI = false; -// -// Texture2D dynamicTexture; -// -// public override string Texture => $"Ben10Mod/Content/Items/Accessories/{this.Name}"; -// -// public override void Load() { -// if (Main.netMode == NetmodeID.Server) -// return; -// -// EquipLoader.AddEquipTexture(Mod, $"{Texture}_{EquipType.HandsOn}", EquipType.HandsOn, name: "RecalibratedOmnitrix"); -// EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.HandsOn}", EquipType.HandsOn, name: "RecalibratedOmnitrixAlt"); -// } -// -// public override ModItem Clone(Item item) { -// RecalibratedOmnitrix clone = (RecalibratedOmnitrix)base.Clone(item); -// clone.transformationNum = transformationNum; -// clone.transformations = (TransformationEnum[])transformations?.Clone(); -// return clone; -// } -// -// public override void SaveData(TagCompound tag) { -// tag["selectedAlien"] = transformationNum; -// } -// -// public override void LoadData(TagCompound tag) -// { -// tag.TryGet("selectedAlien", out transformationNum); -// } -// -// public override void OnCreated(ItemCreationContext context) -// { -// transformationNum = 0; -// } -// -// public override void SetStaticDefaults() { -// dynamicTexture = ModContent.Request("Ben10Mod/Content/Items/Accessories/RecalibratedOmnitrix").Value; -// } -// -// public override void SetDefaults() { -// Item.maxStack = 1; -// Item.width = 22; -// Item.height = 28; -// Item.rare = ItemRarityID.Master; -// Item.accessory = true; -// this.transformationEnergy = 300 * 60; -// this.maxEnergy = 300 * 60; -// } -// -// public override void ModifyTooltips(List tooltips) -// { -// tooltips.Add(new TooltipLine(Mod, "TransformationEnergy", "Energy: " + (int)(transformationEnergy / 60))); -// tooltips.Add(new TooltipLine(Mod, "AlienSelection", "Alien " + (transformationNum + 1) + ": " + transformations[transformationNum].ToString())); -// } -// -// public override void UpdateAccessory(Player player, bool hideVisual) { -// this.player = player; -// player.GetModPlayer().omnitrixEquipped = true; -// wasEquipedLastFrame = true; -// -// transformations = player.GetModPlayer().transformations; -// if (player.GetModPlayer().isTransformed && transformationEnergy > 0) { -// transformationEnergy -= 1; -// } -// else if (transformationEnergy < maxEnergy) { -// transformationEnergy += 3; -// transformationEnergy = Math.Min(transformationEnergy, maxEnergy); -// } -// if (KeybindSystem.OpenTransformationScreen.JustPressed) { -// if (!showingUI) { -// player.GetModPlayer().transformations = transformations; -// ModContent.GetInstance().ShowMyUI(); -// showingUI = true; -// } -// else { -// ModContent.GetInstance().HideMyUI(); -// showingUI = false; -// } -// } -// if (transformationEnergy <= 0) { -// TransformationHandler.Detransform(player, 60); -// } -// -// if (KeybindSystem.TransformationKeybind.JustPressed && !player.GetModPlayer().isTransformed && !player.GetModPlayer().onCooldown) { -// TransformationHandler.Transform(player, transformations[transformationNum], transformationEnergy); -// } -// else if (KeybindSystem.TransformationKeybind.JustPressed && player.GetModPlayer().isTransformed && !player.GetModPlayer().onCooldown) { -// if (player.GetModPlayer().currTransformation != transformations[transformationNum]) { -// TransformationHandler.Detransform(player, 0, false, false, false); -// if (transformationEnergy > 0) { -// transformationEnergy -= 30; -// transformationEnergy = Math.Max(transformationEnergy, 0); -// } -// TransformationHandler.Transform(player, transformations[transformationNum], transformationEnergy); -// } else { -// TransformationHandler.Detransform(player, 0, true, false); -// } -// } -// else if (KeybindSystem.AlienOneKeybind.JustPressed) { -// transformationNum = 0; -// Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); -// } -// else if (KeybindSystem.AlienTwoKeybind.JustPressed) { -// transformationNum = 1; -// Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); -// } -// else if (KeybindSystem.AlienThreeKeybind.JustPressed) { -// transformationNum = 2; -// Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); -// } -// else if (KeybindSystem.AlienFourKeybind.JustPressed) { -// transformationNum = 3; -// Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); -// } -// else if (KeybindSystem.AlienFiveKeybind.JustPressed) { -// transformationNum = 4; -// Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); -// } -// else if (KeybindSystem.AlienNextKeybind.JustPressed) { -// transformationNum++; -// if (transformationNum > transformations.Length - 1) { -// transformationNum = 0; -// } -// SoundEngine.PlaySound(SoundID.MenuTick, player.position); -// Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); -// } -// else if (KeybindSystem.AlienPrevKeybind.JustPressed) { -// transformationNum--; -// if (transformationNum < 0) { -// transformationNum = transformations.Length - 1; -// } -// SoundEngine.PlaySound(SoundID.MenuTick, player.position); -// Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); -// } -// -// base.UpdateAccessory(player, hideVisual); -// } -// -// public override void UpdateInventory(Player player) -// { -// base.UpdateInventory(player); -// -// if (wasEquipedLastFrame) -// { -// wasEquipedLastFrame = false; -// ModContent.GetInstance().HideMyUI(); -// showingUI = false; -// if (player.GetModPlayer().isTransformed) { -// TransformationHandler.Detransform(player, cooldownTime, true, true); -// } else { -// TransformationHandler.Detransform(player, cooldownTime, false, false); -// } -// } -// } -// -// public override bool CanEquipAccessory(Player player, int slot, bool modded) { -// return modded; -// } -// -// public override bool PreDrawInInventory(SpriteBatch spriteBatch, Vector2 position, Rectangle frame, Color drawColor, Color itemColor, Vector2 origin, float scale) { -// -// if (player == null) -// return true; -// -// dynamicTexture = player.GetModPlayer().onCooldown ? ModContent.Request("Ben10Mod/Content/Items/Accessories/RecalibratedOmnitrixAlt").Value : ModContent.Request("Ben10Mod/Content/Items/Accessories/RecalibratedOmnitrix").Value; -// -// spriteBatch.Draw(dynamicTexture, position, null, drawColor, 0f, origin, scale, SpriteEffects.None, 0f); -// -// return false; -// } -// -// public override void AddRecipes() { -// base.AddRecipes(); -// -// Recipe recipeAlt = CreateRecipe() -// .AddIngredient(ModContent.ItemType()) -// .AddIngredient(ItemID.SoulofNight, 5) -// .AddIngredient(ItemID.SoulofLight, 5) -// .AddTile(TileID.MythrilAnvil).Register(); -// -// } -// } -// } \ No newline at end of file + using Ben10Mod.Content.Transformations; +using Ben10Mod.Content.Transformations.XLR8; +using Ben10Mod.Keybinds; +using Microsoft.Xna.Framework; +using Steamworks; +using System; +using Terraria; +using Terraria.DataStructures; +using Terraria.GameContent.UI.Elements; +using Terraria.ID; +using Terraria.ModLoader; +using Terraria.ModLoader.IO; +using Ben10Mod.Enums; +using System.Collections.Generic; +using System.Threading.Tasks.Dataflow; +using System.Security.Cryptography.X509Certificates; +using Ben10Mod.Content.Interface; +using Ben10Mod.Content.Buffs.Abilities.ChromaStone; +using Ben10Mod.Content.Buffs.Abilities.DiamondHead; +using Ben10Mod.Content.Buffs.Abilities.HeatBlast; +using Ben10Mod.Content.Buffs.Abilities.XLR8; +using Ben10Mod.Content.Buffs.Transformations; +using Ben10Mod.Content.Items.Placeables; +using Ben10Mod.Content.DamageClasses; +using Terraria.ModLoader.Default; +using Microsoft.Xna.Framework.Graphics; +using Terraria.Audio; + +namespace Ben10Mod.Content.Items.Accessories +{ + public class RecalibratedOmnitrix : Omnitrix { + + private Player player = null; + public int transformationNum = 0; + public int transformationEnergy = 0; + private int maxEnergy = 0; + public TransformationEnum[] transformations = new TransformationEnum[5]; + + bool wasEquipedLastFrame = false; + bool showingUI = false; + + Texture2D dynamicTexture; + + public override string Texture => $"Ben10Mod/Content/Items/Accessories/{this.Name}"; + + public override void Load() { + if (Main.netMode == NetmodeID.Server) + return; + + EquipLoader.AddEquipTexture(Mod, $"{Texture}_{EquipType.HandsOn}", EquipType.HandsOn, name: "RecalibratedOmnitrix"); + EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.HandsOn}", EquipType.HandsOn, name: "RecalibratedOmnitrixAlt"); + } + + public override ModItem Clone(Item item) { + RecalibratedOmnitrix clone = (RecalibratedOmnitrix)base.Clone(item); + clone.transformationNum = transformationNum; + clone.transformations = (TransformationEnum[])transformations?.Clone(); + return clone; + } + + public override void SaveData(TagCompound tag) { + tag["selectedAlien"] = transformationNum; + } + + public override void LoadData(TagCompound tag) + { + tag.TryGet("selectedAlien", out transformationNum); + } + + public override void OnCreated(ItemCreationContext context) + { + transformationNum = 0; + } + + public override void SetStaticDefaults() { + dynamicTexture = ModContent.Request("Ben10Mod/Content/Items/Accessories/RecalibratedOmnitrix").Value; + } + + public override void SetDefaults() { + Item.maxStack = 1; + Item.width = 22; + Item.height = 28; + Item.rare = ItemRarityID.Master; + Item.accessory = true; + this.transformationEnergy = 300 * 60; + this.maxEnergy = 300 * 60; + } + + public override void ModifyTooltips(List tooltips) + { + tooltips.Add(new TooltipLine(Mod, "TransformationEnergy", "Energy: " + (int)(transformationEnergy / 60))); + tooltips.Add(new TooltipLine(Mod, "AlienSelection", "Alien " + (transformationNum + 1) + ": " + transformations[transformationNum].ToString())); + } + + public override void UpdateAccessory(Player player, bool hideVisual) { + this.player = player; + player.GetModPlayer().omnitrixEquipped = true; + wasEquipedLastFrame = true; + + transformations = player.GetModPlayer().transformations; + if (player.GetModPlayer().isTransformed && transformationEnergy > 0) { + transformationEnergy -= 1; + } + else if (transformationEnergy < maxEnergy) { + transformationEnergy += 3; + transformationEnergy = Math.Min(transformationEnergy, maxEnergy); + } + if (KeybindSystem.OpenTransformationScreen.JustPressed) { + if (!showingUI) { + player.GetModPlayer().transformations = transformations; + ModContent.GetInstance().ShowMyUI(); + showingUI = true; + } + else { + ModContent.GetInstance().HideMyUI(); + showingUI = false; + } + } + if (transformationEnergy <= 0) { + TransformationHandler.Detransform(player, 60); + } + + if (KeybindSystem.TransformationKeybind.JustPressed && !player.GetModPlayer().isTransformed && !player.GetModPlayer().onCooldown) { + TransformationHandler.Transform(player, transformations[transformationNum], transformationEnergy); + } + else if (KeybindSystem.TransformationKeybind.JustPressed && player.GetModPlayer().isTransformed && !player.GetModPlayer().onCooldown) { + if (player.GetModPlayer().currTransformation != transformations[transformationNum]) { + TransformationHandler.Detransform(player, 0, false, false, false); + if (transformationEnergy > 0) { + transformationEnergy -= 30; + transformationEnergy = Math.Max(transformationEnergy, 0); + } + TransformationHandler.Transform(player, transformations[transformationNum], transformationEnergy); + } else { + TransformationHandler.Detransform(player, 0, true, false); + } + } + else if (KeybindSystem.AlienOneKeybind.JustPressed) { + transformationNum = 0; + Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); + } + else if (KeybindSystem.AlienTwoKeybind.JustPressed) { + transformationNum = 1; + Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); + } + else if (KeybindSystem.AlienThreeKeybind.JustPressed) { + transformationNum = 2; + Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); + } + else if (KeybindSystem.AlienFourKeybind.JustPressed) { + transformationNum = 3; + Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); + } + else if (KeybindSystem.AlienFiveKeybind.JustPressed) { + transformationNum = 4; + Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); + } + else if (KeybindSystem.AlienNextKeybind.JustPressed) { + transformationNum++; + if (transformationNum > transformations.Length - 1) { + transformationNum = 0; + } + SoundEngine.PlaySound(SoundID.MenuTick, player.position); + Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); + } + else if (KeybindSystem.AlienPrevKeybind.JustPressed) { + transformationNum--; + if (transformationNum < 0) { + transformationNum = transformations.Length - 1; + } + SoundEngine.PlaySound(SoundID.MenuTick, player.position); + Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); + } + + base.UpdateAccessory(player, hideVisual); + } + + public override void UpdateInventory(Player player) + { + + var omp = player.GetModPlayer(); + + base.UpdateInventory(player); + + if (wasEquipedLastFrame) + { + wasEquipedLastFrame = false; + ModContent.GetInstance().HideMyUI(); + showingUI = false; + if (player.GetModPlayer().isTransformed) { + TransformationHandler.Detransform(player, omp.cooldownTime, true, true); + } else { + TransformationHandler.Detransform(player, omp.cooldownTime, false, false); + } + } + } + + public override bool CanEquipAccessory(Player player, int slot, bool modded) { + return modded; + } + + public override bool PreDrawInInventory(SpriteBatch spriteBatch, Vector2 position, Rectangle frame, Color drawColor, Color itemColor, Vector2 origin, float scale) { + + if (player == null) + return true; + + dynamicTexture = player.GetModPlayer().onCooldown ? ModContent.Request("Ben10Mod/Content/Items/Accessories/RecalibratedOmnitrixAlt").Value : ModContent.Request("Ben10Mod/Content/Items/Accessories/RecalibratedOmnitrix").Value; + + spriteBatch.Draw(dynamicTexture, position, null, drawColor, 0f, origin, scale, SpriteEffects.None, 0f); + + return false; + } + + public override void AddRecipes() { + base.AddRecipes(); + + Recipe recipeAlt = CreateRecipe() + .AddIngredient(ModContent.ItemType()) + .AddIngredient(ItemID.SoulofNight, 5) + .AddIngredient(ItemID.SoulofLight, 5) + .AddTile(TileID.MythrilAnvil).Register(); + + } + } +} \ No newline at end of file diff --git a/Content/Items/Accessories/RecalibratedOmnitrix.png b/Content/Items/Accessories/RecalibratedOmnitrix.png index c11aff596ba67c2875dc0fa3e9284233967bcb75..5ae0503fead37a0bd797b4b70117bcb848fdaf01 100644 GIT binary patch delta 337 zcmV-X0j~at2KWMyFn<9uNkl;BGCdUck$TwXs$$xj>{rMBfWHLQPL~0SK zyNb8hRiLgJ#!eV5_|?k(ba(%D$sp!A$r=m(3fI)_u>{SVKYtWfJJekI#{SA3gKMfN zik;&`^th_30JwfpK`&&CCTncyntH$az8vsXp8zg5wi#pU{^CTjpr&z}K!y!&VsXS=l9=^7g?>>IHLf8^MO z$+2}*9Ft>)WJ-%CGPl>WgDTvPqoD?{;}w@gL%vA@0X9Y j$yhT!k~NmeWK!c3R~B0&sax)600000NkvXXu0mjffHR^Q delta 740 zcmV{C0mk$BTu`i1si0jd zm4Lh5PEc&ISePmpjYfs*KA#WmcDoI1Hk*QCu~-c4>2wP8+!$h9=61UkRyZ6E(Wckv zMS4S)P41_+vVYmE@B{*ZfH2fjG1n2x<#Gb^(P(7qwL+mF#APxWv@0*~0$-HB0O?f* zce`CvZ*e^127`g$>#P^tFU+op<@?)?yyqkm`R^KCpHbG(oq&2r_iUJFh?eMEl~-5?C&mf#Gl% z_;K+H_%Qk$xL&V;tyT;8{#yh{@A>_Hv~^uS%ww)4#$CxrY2_Ka9+T$_27^%QXpgy$ z7!5$>QotUf? zmu*##rPFCa8RowF<#$|v^Xxv5o?>vn-^X9M*1xuT?CivN9B_qpYkv7Hi6=UDA1!e9 zn*VIXoW56b7qXgg&3omw6Qie`e!F0m@wom0Q(axw9|={3VSfCr)oQ?#f4ew2F*(=S z{ai$)Bay3mYq`9t*Z8*Mbl#)CkDZFxZ#Iv&A;dYpcmMzZ4rN$LW=%~1DgXcg2mk;8 W00000(o>TF0000#}Q3_0(g8g&1h4fH@5&>FXjMzZ3_UVO?{r{M!)A- zT~4}07(J^XB8Y|Hfmp1aE1U!otRfbYLhvsL z!Q!y8j7=&_D=QoSf`>&A6axpsVc~&m=N2NKX(Bcv34{xImv`(8F1N1H+t@s3=bPC# zZ{N)K?Ycgh{8Ux_ZS2xC&1Dw5&vmQwn%>On1pAPBjkP-OUw>kXqCg?H+l_l=vsqv? z8U@yBHK3+x`*K0Ns;aw;pDNCfTicnoxX7-C%Jdc77_*zfnzrq}32 zdP9~??x(lX>3_8F1bjZ9Fw|5r#}Uh9G6M6#V6f9`xm-?&OQlk1SD&AOR}T+BdX>TL zc6+C{IG%C6UQhIxh(54cL#R6^aUXG&&`FtMNW#w!u<~U-Cq6psk{`7?Q=lL91EEa*mVDQhb zt5$*G>ucb0xdb*E4dAa(2uSaFy(tkUGAq`&SZltmt&v@I4{dZ#j%9T9%nd69t6$_$KDdtKlE{{JrSDu`htQ41R zR*xlG097sTF0000().masterControl; + } + + public override bool? UseItem(Player player) + { + var omp = player.GetModPlayer(); + + omp.masterControl = true; + + // Dramatic effects + SoundEngine.PlaySound(SoundID.Unlock, player.Center); + SoundEngine.PlaySound(SoundID.MaxMana with { Pitch = 0.4f }, player.Center); // Omnitrix-like chime + + // Big energy burst + for (int i = 0; i < 50; i++) + { + Dust d = Dust.NewDustPerfect(player.Center + Main.rand.NextVector2Circular(20f, 20f), + DustID.Firework_Green, Main.rand.NextVector2Circular(6f, 6f), Scale: Main.rand.NextFloat(1.5f, 2.5f)); + d.noGravity = true; + } + + // Rainbow pulse for flair + for (int i = 0; i < 30; i++) + { + Dust d = Dust.NewDustPerfect(player.Center, DustID.RainbowMk2, + Main.rand.NextVector2Circular(8f, 8f), Scale: 2f); + d.noGravity = true; + } + + // Announcement + Main.NewText("Master Control unlocked!", new Color(0, 255, 0)); + + return true; // Item was used successfully + } + + // Optional: Extra safety - don't consume if already unlocked (CanUseItem already blocks use) + public override bool ConsumeItem(Player player) + { + return !player.GetModPlayer().masterControl; + } + } +} \ No newline at end of file diff --git a/Content/Items/Consumable/MasterControlKey.png b/Content/Items/Consumable/MasterControlKey.png new file mode 100644 index 0000000000000000000000000000000000000000..f45bb4f1d15205ba7d932bc3609685581aeadc84 GIT binary patch literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^azM<*!3HE3m%q~oQjEnx?oJHr&dIz4a{N49978O6 zlT#8Bew;U8XvkF1NlgHPM#GX9Pu^?y2vj|&}hekagm22WQ%mvv4FO#lXJFjxQp literal 0 HcmV?d00001 diff --git a/Content/Items/Weapons/PlumberMagisterBadge.cs b/Content/Items/Weapons/PlumberMagisterBadge.cs index f928b16..d8107c5 100644 --- a/Content/Items/Weapons/PlumberMagisterBadge.cs +++ b/Content/Items/Weapons/PlumberMagisterBadge.cs @@ -5,7 +5,7 @@ namespace Ben10Mod.Content.Items.Weapons; public class PlumberMagisterBadge : PlumbersBadge { public override int BaseDamage => 55; - public override string BadgeRankName => "Magister"; + public override string BadgeRankName => "Magister"; public override void AddRecipes() { diff --git a/Content/Items/Weapons/PlumbersBadge.cs b/Content/Items/Weapons/PlumbersBadge.cs index d770260..5113e8c 100644 --- a/Content/Items/Weapons/PlumbersBadge.cs +++ b/Content/Items/Weapons/PlumbersBadge.cs @@ -1,4 +1,5 @@ -using Ben10Mod.Content.DamageClasses; +using System.Collections.Generic; +using Ben10Mod.Content.DamageClasses; using Ben10Mod.Content.Projectiles; using Ben10Mod.Enums; using Microsoft.Xna.Framework; @@ -7,6 +8,7 @@ using Terraria.ID; using Terraria.ModLoader; using Terraria.Audio; +using Terraria.Localization; namespace Ben10Mod.Content.Items.Weapons { @@ -14,9 +16,10 @@ public abstract class PlumbersBadge : ModItem { // Override these in subclasses for tier-specific values - public virtual int BaseDamage => 15; - public virtual float DamageMultiplier => 1f; // For universal scaling if needed - public virtual string BadgeRankName => "Helper"; + public virtual int BaseDamage => 15; + public virtual float DamageMultiplier => 1f; // For universal scaling if needed + public virtual float AttackSpeedMultiplier => 1f; + public virtual string BadgeRankName => "Helper"; public override void SetDefaults() { @@ -39,6 +42,11 @@ public override void SetDefaults() Item.shootSpeed = 10f; } + public override void ModifyTooltips(List tooltips) + { + tooltips.Add(new TooltipLine(Mod, "badgeHelperLine", "Right click while holding to alternate between primary and secondary attacks")); + } + public override bool CanUseItem(Player player) { // Only usable when transformed - prevents any use/animation when human @@ -65,7 +73,7 @@ public override void HoldItem(Player player) { case TransformationEnum.HeatBlast: - if (player.altFunctionUse == 2) { + if (omp.altAttack) { Item.useTime = Item.useAnimation = 50; Item.shootSpeed = 10f; } @@ -88,7 +96,7 @@ public override void HoldItem(Player player) Item.useStyle = ItemUseStyleID.Shoot; Item.useTime = Item.useAnimation = 8; Item.shootSpeed = 35f; - Item.ArmorPenetration = 10; + Item.ArmorPenetration = 25; break; case TransformationEnum.RipJaws: @@ -126,14 +134,20 @@ public override void HoldItem(Player player) Item.useStyle = ItemUseStyleID.Swing; break; } + + Item.useTime = Item.useAnimation = (int)(Item.useTime / AttackSpeedMultiplier); + } + + public override bool? UseItem(Player player) { + if (player.altFunctionUse == 2) player.GetModPlayer().altAttack = !player.GetModPlayer().altAttack; + return base.UseItem(player); } public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) { var omp = player.GetModPlayer(); - if (!omp.isTransformed) - return false; + if (!omp.isTransformed || player.altFunctionUse == 2) return false; int projType = ProjectileID.ImpFireball; // Bright vanilla fallback - you SHOULD see this if alien not matched int finalDamage = damage; @@ -141,70 +155,63 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, switch (omp.currTransformation) { case TransformationEnum.HeatBlast: - if (player.altFunctionUse == 2) { + if (omp.altAttack) { projType = ModContent.ProjectileType(); // projType = ProjectileID.Flamelash; finalDamage = (int)(damage * 2.5f); } else { projType = ProjectileID.Flames; - finalDamage = (int)(damage * 0.2f); + finalDamage = (int)(damage * 0.5f); } break; case TransformationEnum.XLR8: - projType = player.altFunctionUse == 2 - ? 0 - : ModContent.ProjectileType(); + projType = ModContent.ProjectileType(); + finalDamage = (int)(damage * 0.25f); break; case TransformationEnum.FourArms: - projType = player.altFunctionUse == 2 + projType = omp.altAttack ? ModContent.ProjectileType() : ModContent.ProjectileType(); break; case TransformationEnum.DiamondHead: - projType = player.altFunctionUse == 2 - ? 0 - : ModContent.ProjectileType(); + projType = ModContent.ProjectileType(); finalDamage = (int)(damage * 0.5f); velocity.Y += Main.rand.NextFloat(-0.35f, 0.35f); break; case TransformationEnum.RipJaws: - projType = player.altFunctionUse == 2 - ? 0 - : ModContent.ProjectileType(); + projType = ModContent.ProjectileType(); break; case TransformationEnum.ChromaStone: - projType = player.altFunctionUse == 2 - ? 0 - : ModContent.ProjectileType(); + projType = ModContent.ProjectileType(); finalDamage += omp.ChromaStoneAbsorbtion; break; case TransformationEnum.BuzzShock: - projType = player.altFunctionUse == 2 + projType = omp.altAttack ? ModContent.ProjectileType() : ModContent.ProjectileType(); SoundEngine.PlaySound(SoundID.DD2_LightningAuraZap, player.position); break; case TransformationEnum.StinkFly: - projType = player.altFunctionUse == 2 + projType = omp.altAttack ? ModContent.ProjectileType() : ModContent.ProjectileType(); break; case TransformationEnum.GhostFreak: - projType = player.altFunctionUse == 2 + projType = omp.altAttack ? ModContent.ProjectileType() : ModContent.ProjectileType(); break; case TransformationEnum.WildVine: - projType = player.altFunctionUse == 2 + projType = omp.altAttack ? ModContent.ProjectileType() : ModContent.ProjectileType(); break; @@ -212,7 +219,7 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, if (projType == 0) return false; - Projectile.NewProjectile(source, position, velocity, projType, finalDamage, knockback, player.whoAmI); + Projectile.NewProjectile(source, position, velocity, projType, (int)(finalDamage * DamageMultiplier), knockback, player.whoAmI); return false; } diff --git a/Content/Projectiles/DiamondHeadProjectile.cs b/Content/Projectiles/DiamondHeadProjectile.cs index ef8a548..6e140f9 100644 --- a/Content/Projectiles/DiamondHeadProjectile.cs +++ b/Content/Projectiles/DiamondHeadProjectile.cs @@ -22,6 +22,7 @@ public override void SetDefaults() { AIType = ProjectileID.Bullet; Projectile.DamageType = DamageClass.Ranged; + Projectile.penetrate = 2; } public override void AI() { diff --git a/Content/TransformationHandler.cs b/Content/TransformationHandler.cs index 88062f9..7e3b2b3 100644 --- a/Content/TransformationHandler.cs +++ b/Content/TransformationHandler.cs @@ -29,11 +29,19 @@ public static void Transform(Player player, TransformationEnum transformation, i int dustNum = Dust.NewDust(player.position - new Vector2(1, 1), player.width + 1, player.height + 1, DustID.GreenTorch, random.Next(-4, 5), random.Next(-4, 5), 1, Color.White, 4); Main.dust[dustNum].noGravity = true; } + + CombatText.NewText( + new Rectangle((int)player.position.X, (int)player.position.Y, player.width, player.height), + new Color(0, 255, 0), + transformation.GetName() + "!", + dramatic: true, + dot: false + ); } if (playSound) { SoundEngine.PlaySound(new SoundStyle("Ben10Mod/Content/Sounds/OmnitrixTransformation"), player.position); } - Main.NewText(transformation.GetName() + "!", Color.Green); + // Main.NewText(transformation.GetName() + "!", Color.Green); player.AddBuff(transformation.GetTransformation(), 60 * seconds); // player.GetModPlayer().currTransformation = transformation; } diff --git a/Localization/en-US_Mods.Ben10Mod.hjson b/Localization/en-US_Mods.Ben10Mod.hjson index 5a5a0c0..eb42c52 100644 --- a/Localization/en-US_Mods.Ben10Mod.hjson +++ b/Localization/en-US_Mods.Ben10Mod.hjson @@ -180,6 +180,11 @@ Items: { DisplayName: Plumber Magister Badge Tooltip: "" } + + MasterControlKey: { + Tooltip: "" + DisplayName: Master Control Key + } } Keybinds: { diff --git a/OmnitrixPlayer.cs b/OmnitrixPlayer.cs index 6953b3d..a715f2d 100644 --- a/OmnitrixPlayer.cs +++ b/OmnitrixPlayer.cs @@ -34,6 +34,7 @@ using Ben10Mod.Content.Buffs.Transformations; using Ben10Mod.Content.Items.Accessories.Wings; using Microsoft.Xna.Framework.Input; +using Terraria.Graphics.Effects; namespace Ben10Mod { @@ -41,13 +42,14 @@ public class OmnitrixPlayer : ModPlayer { public bool masterControl = false; - public bool omnitrixEquipped = false; - public bool isTransformed = false; - public bool wasTransformed = false; - public bool onCooldown = false; - - public bool advancedCircuitMatrix = false; - public bool wasAdvancedCircuitMatrix = false; + public bool omnitrixEquipped = false; + public bool isTransformed = false; + public bool wasTransformed = false; + public bool onCooldown = false; + public bool altAttack = false; + + public bool advancedCircuitMatrix = false; + public bool advancedCircuitMatrixEquippedWhileTransformed = false; public int cooldownTime = 120; public int transformationTime = 300; @@ -186,12 +188,6 @@ public override void PostUpdateBuffs() { var abilitySlot = ModContent.GetInstance(); // Handles the detransformation effect - - if (wasAdvancedCircuitMatrix != advancedCircuitMatrix) { - if (wasTransformed != isTransformed) { - wasAdvancedCircuitMatrix = advancedCircuitMatrix; - } - } if (wasTransformed != isTransformed) { var customSlot = ModContent.GetInstance(); @@ -199,16 +195,13 @@ public override void PostUpdateBuffs() { if (masterControl) { TransformationHandler.Detransform(Player, 0, true, false); } else { - TransformationHandler.Detransform(Player, cooldownTime); + TransformationHandler.Detransform(Player, advancedCircuitMatrixEquippedWhileTransformed ? cooldownTime * 2 : cooldownTime); } + + advancedCircuitMatrixEquippedWhileTransformed = false; } wasTransformed = false; } - - if (wasAdvancedCircuitMatrix) { - transformationTime *= 2; - cooldownTime *= 2; - } // XLR8 Transformation @@ -364,6 +357,18 @@ public override void PostUpdate() { Player.lavaImmune = true; abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); + + if (!Filters.Scene["Ben10Mod:HeatDistort"].IsActive()) + Filters.Scene.Activate("Ben10Mod:HeatDistort", Player.Center); + + Filters.Scene["Ben10Mod:HeatDistort"] + .GetShader() + .UseTargetPosition(Player.Center) + .UseColor(1f, 0.45f, 0.1f) + .UseIntensity(0.35f); + } else { + if (Filters.Scene["Ben10Mod:HeatDistort"].IsActive()) + Filters.Scene["Ben10Mod:HeatDistort"].Deactivate(); } if (HeatBlastPrimaryAbilityEnabled != HeatBlastPrimaryAbilityWasEnabled) { @@ -556,8 +561,8 @@ public override void OnHurt(Player.HurtInfo info) { } public override void OnHitAnything(float x, float y, Entity victim) { - if (!Main.npc[victim.whoAmI].HasBuff(BuffID.OnFire) && currTransformation == TransformationEnum.HeatBlast) { - Main.npc[victim.whoAmI].AddBuff(BuffID.OnFire, 3 * 60); + if (!Main.npc[victim.whoAmI].HasBuff(BuffID.OnFire3) && currTransformation == TransformationEnum.HeatBlast) { + Main.npc[victim.whoAmI].AddBuff(BuffID.OnFire3, 3 * 60); } } @@ -637,17 +642,17 @@ public override void DrawEffects(PlayerDrawSet drawInfo, ref float r, ref float } } } - // else if (customSlot.FunctionalItem.type == ModContent.ItemType()) { - // var costume = ModContent.GetInstance(); - // if (!customSlot.HideVisuals && !isTransformed) { - // if (onCooldown) { - // Player.handon = EquipLoader.GetEquipSlot(Mod, "RecalibratedOmnitrixAlt", EquipType.HandsOn); - // } - // else { - // Player.handon = EquipLoader.GetEquipSlot(Mod, "RecalibratedOmnitrix", EquipType.HandsOn); - // } - // } - // } + else if (customSlot.FunctionalItem.type == ModContent.ItemType()) { + var costume = ModContent.GetInstance(); + if (!customSlot.HideVisuals && !isTransformed) { + if (onCooldown) { + Player.handon = EquipLoader.GetEquipSlot(Mod, "RecalibratedOmnitrixAlt", EquipType.HandsOn); + } + else { + Player.handon = EquipLoader.GetEquipSlot(Mod, "RecalibratedOmnitrix", EquipType.HandsOn); + } + } + } } if (!customSlot.HideVisuals) { @@ -676,17 +681,17 @@ public override void FrameEffects() { } } } - // else if (customSlot.FunctionalItem.type == ModContent.ItemType()) { - // var costume = ModContent.GetInstance(); - // if (!customSlot.HideVisuals && !isTransformed) { - // if (onCooldown) { - // Player.handon = EquipLoader.GetEquipSlot(Mod, "RecalibratedOmnitrixAlt", EquipType.HandsOn); - // } - // else { - // Player.handon = EquipLoader.GetEquipSlot(Mod, "RecalibratedOmnitrix", EquipType.HandsOn); - // } - // } - // } + else if (customSlot.FunctionalItem.type == ModContent.ItemType()) { + var costume = ModContent.GetInstance(); + if (!customSlot.HideVisuals && !isTransformed) { + if (onCooldown) { + Player.handon = EquipLoader.GetEquipSlot(Mod, "RecalibratedOmnitrixAlt", EquipType.HandsOn); + } + else { + Player.handon = EquipLoader.GetEquipSlot(Mod, "RecalibratedOmnitrix", EquipType.HandsOn); + } + } + } } if (!customSlot.HideVisuals) { if (isTransformed) { diff --git a/ShopNPC.cs b/ShopNPC.cs index a4ea5d5..7975f7f 100644 --- a/ShopNPC.cs +++ b/ShopNPC.cs @@ -1,6 +1,8 @@ using Ben10Mod.Content.Items.Accessories; +using Ben10Mod.Content.Items.Consumable; using Ben10Mod.Content.Items.Vanity; using Terraria; +using Terraria.GameContent.ItemDropRules; using Terraria.ID; using Terraria.ModLoader; @@ -17,4 +19,12 @@ public override void ModifyShop(NPCShop shop) { shop.Add(ModContent.ItemType()); } } + + public override void ModifyNPCLoot(NPC npc, NPCLoot npcLoot) { + if (npc.type == NPCID.Plantera) { + if (Main.expertMode) { + npcLoot.Add(ItemDropRule.BossBag(ModContent.ItemType())); + } + } + } } \ No newline at end of file diff --git a/build.txt b/build.txt index 775986b..90b957e 100644 --- a/build.txt +++ b/build.txt @@ -1,3 +1,3 @@ displayName = Terraria 10 (Ben 10 mod) author = DestroyerMob -version = 0.061 \ No newline at end of file +version = 0.066 \ No newline at end of file From 5a50819c674ba540ce413a0913c837606ec7e30d Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Tue, 17 Feb 2026 09:35:48 +1100 Subject: [PATCH 03/25] Shader finished --- Assets/Effects/HeatDistort.fx | 27 --------- Ben10Mod.cs | 6 +- Common/CustomVisuals/HeatShimmerLayer.cs | 70 ++++++++++++++++++++++++ Common/Systems/HeatBlastShaderSystem.cs | 28 ---------- OmnitrixPlayer.cs | 21 ++----- 5 files changed, 78 insertions(+), 74 deletions(-) delete mode 100644 Assets/Effects/HeatDistort.fx create mode 100644 Common/CustomVisuals/HeatShimmerLayer.cs delete mode 100644 Common/Systems/HeatBlastShaderSystem.cs diff --git a/Assets/Effects/HeatDistort.fx b/Assets/Effects/HeatDistort.fx deleted file mode 100644 index 785070f..0000000 --- a/Assets/Effects/HeatDistort.fx +++ /dev/null @@ -1,27 +0,0 @@ -sampler2D ScreenTexture : register(s0); - -float4 uColor; -float uOpacity; -float uTime; -float2 uTargetPosition; // screen-space-ish, provided by tML shader pipeline -float uIntensity; - -float4 HeatDistortPass(float2 uv : TEXCOORD0) : COLOR0 -{ - // Simple animated wave distortion - float wave = sin((uv.y * 120.0) + (uTime * 3.2)) * 0.0018; - float wave2 = cos((uv.x * 95.0) + (uTime * 2.6)) * 0.0012; - - float2 distortedUV = uv + float2(wave, wave2) * uIntensity; - float4 col = tex2D(ScreenTexture, distortedUV); - - return col; -} - -technique HeatDistortPass -{ - pass P0 - { - PixelShader = compile ps_2_0 HeatDistortPass(); - } -} diff --git a/Ben10Mod.cs b/Ben10Mod.cs index b110fe6..4ef5f89 100644 --- a/Ben10Mod.cs +++ b/Ben10Mod.cs @@ -1,11 +1,11 @@ -using Terraria.DataStructures; using Terraria.ModLoader; namespace Ben10Mod { public class Ben10Mod : Mod { - public override void Load() { - } + public override void Load() + { + } } } \ No newline at end of file diff --git a/Common/CustomVisuals/HeatShimmerLayer.cs b/Common/CustomVisuals/HeatShimmerLayer.cs new file mode 100644 index 0000000..6a6ec17 --- /dev/null +++ b/Common/CustomVisuals/HeatShimmerLayer.cs @@ -0,0 +1,70 @@ +using System; +using Ben10Mod.Enums; +using Microsoft.Build.Tasks; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.DataStructures; +using Terraria.GameContent; +using Terraria.ModLoader; + +namespace Ben10Mod.Common.CustomVisuals; + +public class HeatShimmerLayer : PlayerDrawLayer { + + public override bool GetDefaultVisibility(PlayerDrawSet drawInfo) { + Player player = drawInfo.drawPlayer; + var omp = player.GetModPlayer(); + + return omp.currTransformation == TransformationEnum.HeatBlast; + } + + // Position after armor/body + public override Position GetDefaultPosition() + { + // Draw after armor layer so we overlay everything the player is wearing + return new AfterParent(PlayerDrawLayers.ArmOverItem); + } + + protected override void Draw(ref PlayerDrawSet drawInfo) { + Player player = drawInfo.drawPlayer; + int originalCount = drawInfo.DrawDataCache.Count; + if (originalCount <= 0) + return; + + float t = (float)Main.GameUpdateCount; + + // Keep it subtle + float baseAlpha = 0.10f; // lower = subtler + float wobble = 2.5f; // pixel offset magnitude + + // Warm colors cycling + Color c1 = new Color(255, 140, 40, 0); + Color c2 = new Color(255, 90, 20, 0); + + // Multiple tiny offset passes for refractive feel + Vector2[] offsets = new Vector2[] + { + new Vector2((float)System.Math.Sin(t * 0.18f), (float)System.Math.Cos(t * 0.15f)) * wobble, + new Vector2((float)System.Math.Cos(t * 0.21f), (float)System.Math.Sin(t * 0.19f)) * (wobble * 0.8f), + new Vector2((float)System.Math.Sin(t * 0.25f + 1.3f), (float)System.Math.Cos(t * 0.22f + 0.7f)) * (wobble * 0.6f), + }; + + for (int i = 0; i < originalCount; i++) + { + var src = drawInfo.DrawDataCache[i]; + + for (int p = 0; p < offsets.Length; p++) + { + var copy = src; + copy.position += offsets[p]; + + Color tint = Color.Lerp(c1, c2, (float)p / (offsets.Length - 1)); + copy.color = tint * baseAlpha; + copy.scale *= new Vector2(1.2f, 1.2f); + + drawInfo.DrawDataCache.Add(copy); + } + } + } +} \ No newline at end of file diff --git a/Common/Systems/HeatBlastShaderSystem.cs b/Common/Systems/HeatBlastShaderSystem.cs deleted file mode 100644 index 2a75ee8..0000000 --- a/Common/Systems/HeatBlastShaderSystem.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Microsoft.Xna.Framework.Graphics; -using Terraria; -using Terraria.Graphics.Effects; -using Terraria.Graphics.Shaders; -using Terraria.ModLoader; - -namespace Ben10Mod.Common.Systems; - -public class HeatBlastShaderSystem : ModSystem { - public override void Load() { - if (Main.dedServ) - return; - - Ref effect = new Ref(ModContent.Request("Ben10Mod/Assets/Effects/HeatDistort", - ReLogic.Content.AssetRequestMode.ImmediateLoad).Value); - - Filters.Scene["Ben10Mod:HeatDistort"] = new Filter( - new ScreenShaderData(effect, "HeatDistortPass"), - EffectPriority.VeryHigh); - } - - public override void Unload() { - if (!Main.dedServ) { - Filters.Scene.Deactivate("Ben10Mod:HeatDistort"); - Filters.Scene["Ben10Mod:HeatDistort"] = null; - } - } -} \ No newline at end of file diff --git a/OmnitrixPlayer.cs b/OmnitrixPlayer.cs index a715f2d..aa38080 100644 --- a/OmnitrixPlayer.cs +++ b/OmnitrixPlayer.cs @@ -3,6 +3,7 @@ using System; using Microsoft.Xna.Framework; using System.Collections.Generic; +using System.CommandLine.Help; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -344,6 +345,7 @@ public override void PostUpdate() { dustNum = Dust.NewDust(points[i] + Player.Center, 1, 1, DustID.Torch, rand.Next(-1, 2), rand.Next(-1, 2)); Main.dust[dustNum].noGravity = true; } + foreach (NPC npc in Main.npc) { if (Player.Distance(npc.Center) <= 10 * (16) && !npc.friendly) { if (!npc.HasBuff(BuffID.OnFire3)) { @@ -356,20 +358,7 @@ public override void PostUpdate() { Player.fireWalk = true; Player.lavaImmune = true; - abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); - - if (!Filters.Scene["Ben10Mod:HeatDistort"].IsActive()) - Filters.Scene.Activate("Ben10Mod:HeatDistort", Player.Center); - - Filters.Scene["Ben10Mod:HeatDistort"] - .GetShader() - .UseTargetPosition(Player.Center) - .UseColor(1f, 0.45f, 0.1f) - .UseIntensity(0.35f); - } else { - if (Filters.Scene["Ben10Mod:HeatDistort"].IsActive()) - Filters.Scene["Ben10Mod:HeatDistort"].Deactivate(); - } + abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } if (HeatBlastPrimaryAbilityEnabled != HeatBlastPrimaryAbilityWasEnabled) { HeatBlastPrimaryAbilityWasEnabled = false; @@ -416,7 +405,7 @@ public override void PostUpdate() { if (ChromaStonePrimaryAbilityEnabled) { - Lighting.AddLight(Player.Center, GetChromaStoneOverlayColor().ToVector3()); + Lighting.AddLight(Player.Center, Main.DiscoColor.ToVector3()); } abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); @@ -605,7 +594,7 @@ public override void ModifyDrawInfo(ref PlayerDrawSet drawInfo) { case TransformationEnum.BuzzShock: break; case TransformationEnum.ChromaStone when ChromaStonePrimaryAbilityEnabled: - Color overlayColor = GetChromaStoneOverlayColor(); + Color overlayColor = Main.DiscoColor; drawInfo.colorArmorHead = overlayColor; drawInfo.colorArmorBody = overlayColor; drawInfo.colorArmorLegs = overlayColor; From a5856846955ecca63ade78c780d26ee34726da49 Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Sat, 21 Feb 2026 01:09:46 +1100 Subject: [PATCH 04/25] Fixed meteorite generation --- .../GenPasses/CongealedCodonOreGenPass.cs | 4 +- .../Systems/GenPasses/OmnitrixCapsulePass.cs | 235 +++++++----------- .../Items/Accessories/RecalibratedOmnitrix.cs | 15 +- Content/Items/Consumable/MasterControlKey.cs | 2 + Content/Projectiles/ChromaStoneProjectile.cs | 2 +- OmnitrixPlayer.cs | 37 ++- 6 files changed, 130 insertions(+), 165 deletions(-) diff --git a/Common/Systems/GenPasses/CongealedCodonOreGenPass.cs b/Common/Systems/GenPasses/CongealedCodonOreGenPass.cs index 3905948..3d02fc1 100644 --- a/Common/Systems/GenPasses/CongealedCodonOreGenPass.cs +++ b/Common/Systems/GenPasses/CongealedCodonOreGenPass.cs @@ -18,7 +18,7 @@ public CongealedCodonOreGenPass(string name, float weight) : base(name, weight) protected override void ApplyPass(GenerationProgress progress, GameConfiguration configuration) { progress.Message = "Spawning Congealed Codon Ore"; - int maxToSpawn = WorldGen.genRand.Next(325, 350); + int maxToSpawn = WorldGen.genRand.Next(275, 325); int numSpawned = 0; int attempts = 0; @@ -28,7 +28,7 @@ protected override void ApplyPass(GenerationProgress progress, GameConfiguration Tile tile = Framing.GetTileSafely(x, y); if (tile.TileType == TileID.Stone) { - WorldGen.TileRunner(x, y, WorldGen.genRand.Next(10, 15), WorldGen.genRand.Next(1, 4), ModContent.TileType()); + WorldGen.TileRunner(x, y, WorldGen.genRand.Next(8, 13), WorldGen.genRand.Next(1, 4), ModContent.TileType()); numSpawned++; } diff --git a/Common/Systems/GenPasses/OmnitrixCapsulePass.cs b/Common/Systems/GenPasses/OmnitrixCapsulePass.cs index 6bdb656..d111ceb 100644 --- a/Common/Systems/GenPasses/OmnitrixCapsulePass.cs +++ b/Common/Systems/GenPasses/OmnitrixCapsulePass.cs @@ -5,189 +5,128 @@ using Ben10Mod.Content.Tiles; using Terraria.ID; -namespace Ben10Mod.Common.Systems.GenPasses { - public class OmnitrixCapsulePass : GenPass { +namespace Ben10Mod.Common.Systems.GenPasses +{ + public class OmnitrixCapsulePass : GenPass + { public OmnitrixCapsulePass(string name, float loadWeight) : base(name, loadWeight) { } - protected override void ApplyPass(GenerationProgress progress, GameConfiguration configuration) { - progress.Message = "Calling down a strange meteor..."; + protected override void ApplyPass(GenerationProgress progress, GameConfiguration configuration) + { + progress.Message = "Calling down strange meteors..."; - // --- 0) Your tiles --- int meteorOreTile = TileID.Silver; int meteorRockTile = ModContent.TileType(); - int capsuleTile = ModContent.TileType(); // 1x1 capsule - - var rand = WorldGen.genRand; + int capsuleTile = ModContent.TileType(); - // --- 1) Pick a surface position --- + var rand = WorldGen.genRand; - // Avoid very close to edges to prevent clipping into oceans. + // === WORLD-SIZE BASED COUNT (exactly what you asked for) === + int numMeteors; + if (Main.maxTilesX < 5000) // Small world (4200 tiles) + numMeteors = rand.Next(1, 3); // 1-2 + else if (Main.maxTilesX < 7000) // Medium world (6400 tiles) + numMeteors = rand.Next(3, 5); // 3-4 + else // Large world (8400 tiles) + numMeteors = rand.Next(5, 7); // 5-6 + + int placed = 0; + int maxAttempts = numMeteors * 6; // safety net (you'll never hit it) + + for (int attempt = 0; attempt < maxAttempts && placed < numMeteors; attempt++) + { + // === 1) Pick random spot DEEP in the Cavern layer === int centerX = rand.Next(300, Main.maxTilesX - 300); - // Find the "surface" at this X: first solid tile going down. - int surfaceY = -1; - for (int y = 0; y < Main.maxTilesY - 300; y++) { - if (WorldGen.SolidTile(centerX, y)) { - surfaceY = y; - if (Main.rand.Next(101) == 1) { - break; - } - } - } + int cavernTop = (int)Main.rockLayer + 60; // well below surface, into caverns + int cavernBottom = Main.maxTilesY - 380; // safe above Underworld - // --- 2) Define meteor shape parameters --- - - // Overall horizontal and vertical extents of the meteor blob - int halfWidth = 12; - int halfHeight = 5; - - // The center of the meteor mass is a bit below the surface - int meteorCenterY = surfaceY + 10; - - // Crater radius around the surface - int craterRadius = 26; - - // Clamp Y so we don't go out of world bounds - if (meteorCenterY > Main.maxTilesY - 60) - meteorCenterY = Main.maxTilesY - 60; - - // --- 3) Carve a crater on the surface (kill tiles in a circle) --- - - // int craterMinX = centerX - craterRadius - 5; - // int craterMaxX = centerX + craterRadius + 5; - // int craterMinY = surfaceY - 10; - // int craterMaxY = surfaceY + 10; - // - // for (int x = craterMinX; x <= craterMaxX; x++) { - // for (int y = craterMinY; y <= craterMaxY; y++) { - // if (!WorldGen.InWorld(x, y, 20)) - // continue; - // - // float dx = x - centerX; - // float dy = y - surfaceY; - // float dist = (float)System.Math.Sqrt(dx * dx + dy * dy); - // - // // Slightly flattened crater - // float craterShape = craterRadius * (1f + 0.15f * (float)System.Math.Sin(dx / 4f)); - // if (dist <= craterShape) { - // WorldGen.KillTile(x, y, noItem: true); - // } - // } - // } - - // --- 4) Build a lumpy meteor blob under the crater --- - - int meteorMinX = centerX - halfWidth; - int meteorMaxX = centerX + halfWidth; - int meteorMinY = meteorCenterY - halfHeight; - int meteorMaxY = meteorCenterY + halfHeight; - - if (meteorMinY < 10) meteorMinY = 10; - if (meteorMaxY > Main.maxTilesY - 30) meteorMaxY = Main.maxTilesY - 30; - - for (int x = meteorMinX; x <= meteorMaxX; x++) { - for (int y = meteorMinY; y <= meteorMaxY; y++) { - if (!WorldGen.InWorld(x, y, 20)) - continue; - - float dx = (x - centerX) / (float)halfWidth; - float dy = (y - meteorCenterY) / (float)halfHeight; - float distSq = dx * dx + dy * dy; + if (cavernTop >= cavernBottom) continue; - if (distSq > 1.2f) - continue; // outside the main ellipse + int centerY = rand.Next(cavernTop, cavernBottom); - // Add some noise so the outline isn't perfectly smooth - float noise = (float)(rand.NextDouble() * 0.35 - 0.15); // [-0.15, +0.20] - if (distSq > 1f + noise) - continue; + // === 2) Build the lumpy meteor blob (slightly bigger & rounder than before) === + int halfWidth = 13; + int halfHeight = 8; - Tile t = Main.tile[x, y]; - if (t == null) - continue; + bool meteorPlaced = false; - t.HasTile = true; + for (int x = centerX - halfWidth; x <= centerX + halfWidth; x++) + { + for (int y = centerY - halfHeight; y <= centerY + halfHeight; y++) + { + if (!WorldGen.InWorld(x, y, 20)) continue; - // About 1/6 chance to be the special codon ore - if (rand.Next(6) == 0) - t.TileType = (ushort)meteorOreTile; - else - t.TileType = (ushort)meteorRockTile; - } - } + float dx = (x - centerX) / (float)halfWidth; + float dy = (y - centerY) / (float)halfHeight; + float distSq = dx * dx + dy * dy; - // --- 5) Fix framing in the area so it looks correct --- + if (distSq > 1.25f) continue; - int frameMinX = meteorMinX - 2; - int frameMaxX = meteorMaxX + 2; - int frameMinY = meteorMinY - 2; - int frameMaxY = meteorMaxY + 2; + // Organic lumpy edges + float noise = (float)(rand.NextDouble() * 0.42 - 0.19); + if (distSq > 1.0f + noise) continue; - for (int x = frameMinX; x <= frameMaxX; x++) { - for (int y = frameMinY; y <= frameMaxY; y++) { - if (!WorldGen.InWorld(x, y, 20)) - continue; + Tile t = Main.tile[x, y]; + if (t == null) continue; - WorldGen.SquareTileFrame(x, y, resetFrame: true); + t.HasTile = true; + t.TileType = rand.Next(6) == 0 ? (ushort)meteorOreTile : (ushort)meteorRockTile; + + meteorPlaced = true; } } - // --- 6) Find a top spot on the meteor for the capsule --- - - int bestX = -1; - int bestY = -1; - - int searchHalfWidth = 20; - int searchTopY = surfaceY - 10; - int searchBottomY = meteorMinY + (meteorMaxY - meteorMinY) / 2; + if (!meteorPlaced) continue; - if (searchTopY < 10) searchTopY = 10; - if (searchBottomY > Main.maxTilesY - 30) searchBottomY = Main.maxTilesY - 30; + // === 3) Fix framing === + for (int x = centerX - halfWidth - 4; x <= centerX + halfWidth + 4; x++) + for (int y = centerY - halfHeight - 4; y <= centerY + halfHeight + 4; y++) { + if (WorldGen.InWorld(x, y, 15)) + WorldGen.SquareTileFrame(x, y, true); + } - for (int x = centerX - searchHalfWidth; x <= centerX + searchHalfWidth; x++) { - if (x < meteorMinX || x > meteorMaxX) - continue; + // === 4) GUARANTEED capsule placement (no more missing capsules!) === + // Try up to 40 columns on the meteor until we find a valid top spot + bool capsulePlaced = false; + for (int tries = 0; tries < 40 && !capsulePlaced; tries++) { + int x = centerX + rand.Next(-halfWidth + 3, halfWidth - 2); - // scan downward from just above the crater - for (int y = searchTopY; y <= searchBottomY; y++) { - if (!WorldGen.InWorld(x, y, 20)) - continue; + // Scan this column from the top of the meteor downward + for (int y = centerY - halfHeight - 12; y <= centerY + halfHeight; y++) { + if (!WorldGen.InWorld(x, y)) continue; Tile t = Main.tile[x, y]; - if (t == null || !t.HasTile) - continue; - - if (t.TileType == meteorRockTile || t.TileType == meteorOreTile) { - Tile above = Main.tile[x, y - 1]; - if (above != null && !above.HasTile) { - bestX = x; - bestY = y - 1; - break; - } - } - } + if (t == null || !t.HasTile) continue; + if (t.TileType != meteorRockTile && t.TileType != meteorOreTile) continue; - if (bestX != -1) - break; - } + // Found a meteor tile → place capsule directly above it + int capY = y - 1; + if (!WorldGen.InWorld(x, capY)) break; - if (bestX == -1) { - // Couldn't find a clean top; meteor still exists, just no capsule. - return; - } + // Carve a clean 1-tile pocket (just in case something is there) + WorldGen.KillTile(x, capY, noItem: true); - // --- 7) Place the 1x1 PlumberCapsulePod tile --- + Tile cap = Main.tile[x, capY]; + cap.HasTile = true; + cap.TileType = (ushort)capsuleTile; - Tile cap = Main.tile[bestX, bestY]; - cap.HasTile = true; - cap.TileType = (ushort)capsuleTile; + WorldGen.SquareTileFrame(x, capY, true); + WorldGen.SquareTileFrame(x, y, true); - WorldGen.SquareTileFrame(bestX, bestY, resetFrame: true); + if (Main.netMode == NetmodeID.Server) + NetMessage.SendTileSquare(-1, x - 1, capY - 1, 3, 3); - if (Main.netMode == NetmodeID.Server) { - NetMessage.SendTileSquare(-1, bestX, bestY, 1, 1); + capsulePlaced = true; + break; + } } + + if (capsulePlaced) + placed++; + } + ModContent.GetInstance().Logger.Info($"OmnitrixCapsulePass: Placed {placed} meteors in cavern layer"); } } } \ No newline at end of file diff --git a/Content/Items/Accessories/RecalibratedOmnitrix.cs b/Content/Items/Accessories/RecalibratedOmnitrix.cs index b3bb396..38b1177 100644 --- a/Content/Items/Accessories/RecalibratedOmnitrix.cs +++ b/Content/Items/Accessories/RecalibratedOmnitrix.cs @@ -100,8 +100,7 @@ public override void UpdateAccessory(Player player, bool hideVisual) { transformations = player.GetModPlayer().transformations; if (player.GetModPlayer().isTransformed && transformationEnergy > 0) { transformationEnergy -= 1; - } - else if (transformationEnergy < maxEnergy) { + } else if (transformationEnergy < maxEnergy) { transformationEnergy += 3; transformationEnergy = Math.Min(transformationEnergy, maxEnergy); } @@ -121,16 +120,14 @@ public override void UpdateAccessory(Player player, bool hideVisual) { } if (KeybindSystem.TransformationKeybind.JustPressed && !player.GetModPlayer().isTransformed && !player.GetModPlayer().onCooldown) { - TransformationHandler.Transform(player, transformations[transformationNum], transformationEnergy); + TransformationHandler.Transform(player, transformations[transformationNum], transformationEnergy / 60); } else if (KeybindSystem.TransformationKeybind.JustPressed && player.GetModPlayer().isTransformed && !player.GetModPlayer().onCooldown) { if (player.GetModPlayer().currTransformation != transformations[transformationNum]) { - TransformationHandler.Detransform(player, 0, false, false, false); - if (transformationEnergy > 0) { - transformationEnergy -= 30; - transformationEnergy = Math.Max(transformationEnergy, 0); - } - TransformationHandler.Transform(player, transformations[transformationNum], transformationEnergy); + transformationEnergy -= 50; + TransformationHandler.Detransform(player, 60, false, transformationEnergy <= 0, false); + transformationEnergy = Math.Max(transformationEnergy, 0); + TransformationHandler.Transform(player, transformations[transformationNum], transformationEnergy / 60); } else { TransformationHandler.Detransform(player, 0, true, false); } diff --git a/Content/Items/Consumable/MasterControlKey.cs b/Content/Items/Consumable/MasterControlKey.cs index 41e45f1..ebcebcb 100644 --- a/Content/Items/Consumable/MasterControlKey.cs +++ b/Content/Items/Consumable/MasterControlKey.cs @@ -54,6 +54,8 @@ public override bool CanUseItem(Player player) // Announcement Main.NewText("Master Control unlocked!", new Color(0, 255, 0)); + Item.stack--; + return true; // Item was used successfully } diff --git a/Content/Projectiles/ChromaStoneProjectile.cs b/Content/Projectiles/ChromaStoneProjectile.cs index 0a4693c..e4caec4 100644 --- a/Content/Projectiles/ChromaStoneProjectile.cs +++ b/Content/Projectiles/ChromaStoneProjectile.cs @@ -32,7 +32,7 @@ public override bool PreDraw(ref Color lightColor) { OmnitrixPlayer omnitrixPlayer = Main.player[Projectile.owner].GetModPlayer(); - lightColor = omnitrixPlayer.GetChromaStoneOverlayColor(); + lightColor = Main.DiscoColor; Lighting.AddLight(Projectile.position + Projectile.velocity * 0.5f, lightColor.ToVector3() * 0.5f); return base.PreDraw(ref lightColor); } diff --git a/OmnitrixPlayer.cs b/OmnitrixPlayer.cs index aa38080..97f4dd5 100644 --- a/OmnitrixPlayer.cs +++ b/OmnitrixPlayer.cs @@ -105,6 +105,7 @@ public Color GetChromaStoneOverlayColor() } public override void SaveData(TagCompound tag) { + if (Player.whoAmI != Main.myPlayer) return; tag["masterControl"] = masterControl; int[] temp = new int[transformations.Length]; for (int i = 0; i < temp.Length; i++) { @@ -120,6 +121,7 @@ public override void SaveData(TagCompound tag) { } public override void LoadData(TagCompound tag) { + if (Player.whoAmI != Main.myPlayer) return; int[] temp = null; if (tag.TryGet("roster", out temp)) { if (temp != null) { @@ -146,7 +148,7 @@ public override void LoadData(TagCompound tag) { public override void ResetEffects() { - + if (Player.whoAmI != Main.myPlayer) return; advancedCircuitMatrix = false; cooldownTime = 120; @@ -185,8 +187,9 @@ public override void ResetEffects() { // Handles players abilities public override void PostUpdateBuffs() { - + if (Player.whoAmI != Main.myPlayer) return; var abilitySlot = ModContent.GetInstance(); + var omnitrixSlot = ModContent.GetInstance(); // Handles the detransformation effect @@ -196,7 +199,8 @@ public override void PostUpdateBuffs() { if (masterControl) { TransformationHandler.Detransform(Player, 0, true, false); } else { - TransformationHandler.Detransform(Player, advancedCircuitMatrixEquippedWhileTransformed ? cooldownTime * 2 : cooldownTime); + if (omnitrixSlot.FunctionalItem.type == ModContent.ItemType()) + TransformationHandler.Detransform(Player, advancedCircuitMatrixEquippedWhileTransformed ? cooldownTime * 2 : cooldownTime); } advancedCircuitMatrixEquippedWhileTransformed = false; @@ -243,12 +247,14 @@ public override void PostUpdateBuffs() { if (currTransformation == TransformationEnum.DiamondHead) { - Player.statDefense += 25; + Player.statDefense += 20; + Player.wingTimeMax = 0; + Player.wingTime = 0; if (DiamondHeadPrimaryAbilityEnabled) { Player.moveSpeed /= 10; Player.lifeRegen += 15; - Player.statDefense *= 2; + Player.statDefense *= 1.5f; Player.releaseJump = false; Player.gravity *= 2f; } @@ -305,6 +311,7 @@ public override void PostUpdateBuffs() { } public override void PostUpdate() { + if (Player.whoAmI != Main.myPlayer) return; var abilitySlot = ModContent.GetInstance(); @@ -375,6 +382,10 @@ public override void PostUpdate() { } } + if (DiamondHeadPrimaryAbilityEnabled) { + Player.velocity = new Vector2(float.Clamp(Player.velocity.X, -0.5f, 0.5f), Math.Max(0, Player.velocity.Y)); + } + abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } @@ -530,18 +541,22 @@ public override void PostUpdate() { } public override bool CanUseItem(Item item) { + if (Player.whoAmI != Main.myPlayer) return false; return !(currTransformation == TransformationEnum.GhostFreak && KeybindSystem.PrimaryAbility.Current); } public override bool CanBeHitByNPC(NPC npc, ref int cooldownSlot) { + if (Player.whoAmI != Main.myPlayer) return false; return !(currTransformation == TransformationEnum.GhostFreak && KeybindSystem.PrimaryAbility.Current); } public override bool CanBeHitByProjectile(Projectile proj) { + if (Player.whoAmI != Main.myPlayer) return false; return !(currTransformation == TransformationEnum.GhostFreak && KeybindSystem.PrimaryAbility.Current); } public override void OnHurt(Player.HurtInfo info) { + if (Player.whoAmI != Main.myPlayer) return; if (ChromaStonePrimaryAbilityEnabled) { ChromaStoneAbsorbtion += Math.Max(info.Damage / 5, 0); } @@ -550,6 +565,7 @@ public override void OnHurt(Player.HurtInfo info) { } public override void OnHitAnything(float x, float y, Entity victim) { + if (Player.whoAmI != Main.myPlayer) return; if (!Main.npc[victim.whoAmI].HasBuff(BuffID.OnFire3) && currTransformation == TransformationEnum.HeatBlast) { Main.npc[victim.whoAmI].AddBuff(BuffID.OnFire3, 3 * 60); } @@ -573,6 +589,7 @@ public static Vector2[] GenerateCirclePoints(int numberOfPoints, float radius) { } public override void ModifyDrawInfo(ref PlayerDrawSet drawInfo) { + if (Player.whoAmI != Main.myPlayer) return; if (isTransformed) { } switch (currTransformation) { @@ -616,6 +633,8 @@ public override void ModifyDrawInfo(ref PlayerDrawSet drawInfo) { // Set the visuals for the aliens public override void DrawEffects(PlayerDrawSet drawInfo, ref float r, ref float g, ref float b, ref float a, ref bool fullBright) { + + if (Player.whoAmI != Main.myPlayer) return; var customSlot = ModContent.GetInstance(); @@ -656,6 +675,9 @@ public override void DrawEffects(PlayerDrawSet drawInfo, ref float r, ref float } public override void FrameEffects() { + + if (Player.whoAmI != Main.myPlayer) return; + var customSlot = ModContent.GetInstance(); if (omnitrixEquipped) { @@ -775,6 +797,7 @@ public override void FrameEffects() { } public override void PreUpdateMovement() { + if (Player.whoAmI != Main.myPlayer) return; DashMovement(); } @@ -840,6 +863,7 @@ private bool CanUseDash() { } public override void OnEnterWorld() { + if (Player.whoAmI != Main.myPlayer) return; ModContent.GetInstance().HideMyUI(); if (!isTransformed) { currTransformation = TransformationEnum.None; @@ -876,6 +900,7 @@ private void EndPossession() // This is where we unlock transformations public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { + if (Player.whoAmI != Main.myPlayer) return; base.OnHitNPC(target, hit, damageDone); if (target.life <= 0) { if (Main.bloodMoon) @@ -890,6 +915,7 @@ public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { } public override void PreUpdate() { + if (Player.whoAmI != Main.myPlayer) return; if (colourAmount >= 1.0f) { thisColour++; @@ -908,6 +934,7 @@ public override void PreUpdate() { } public void addTransformation(TransformationEnum transformation) { + if (Player.whoAmI != Main.myPlayer) return; if (!TransformationHandler.HasTransformation(Player, transformation)) { unlockedTransformation.Add(transformation); Main.NewText(Player.name + " has unlocked " + transformation.GetName(), Color.Green); From 25f3dc90a991f6675d07362d22037dd22d4d2ec0 Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Tue, 24 Feb 2026 15:45:02 +1100 Subject: [PATCH 05/25] Added eyeguy, revamped UI, added stat bar, implemented a working recalibrated omnitrix, and added an ultimate move system --- .../Debuffs/TransformationCooldown_Buff.cs | 19 + Content/Buffs/Transformations/EyeGuy_Buff.cs | 24 + Content/Interface/AlienSelectionScreen.cs | 460 +++++++++++------- Content/Interface/OE_Fill.png | Bin 0 -> 127 bytes Content/Interface/OE_Panel_Left.png | Bin 0 -> 189 bytes Content/Interface/OE_Panel_Middle.png | Bin 0 -> 147 bytes Content/Interface/OE_Panel_Right.png | Bin 0 -> 213 bytes Content/Items/Accessories/HeroEmblem.cs | 30 ++ Content/Items/Accessories/HeroEmblem.png | Bin 0 -> 493 bytes .../Items/Accessories/PrototypeOmnitrix.cs | 2 + .../Items/Accessories/RecalibratedOmnitrix.cs | 57 ++- Content/Items/Armour/PlumbersGlassHelmet.cs | 11 +- Content/Items/Armour/PlumbersHelmet.cs | 10 +- Content/Items/Armour/PlumbersPants.cs | 2 +- Content/Items/Armour/PlumbersShirt.cs | 2 +- Content/Items/Weapons/PlumbersBadge.cs | 128 ++++- Content/Projectiles/EyeGuyLaserbeam.cs | 58 +++ Content/Projectiles/EyeGuyLaserbeam.png | Bin 0 -> 96 bytes Content/Projectiles/EyeGuyUltimateBeam.cs | 289 +++++++++++ Content/Projectiles/EyeGuyUltimateBeam.png | Bin 0 -> 418 bytes Content/TransformationHandler.cs | 11 +- Content/Transformations/EyeGuy/EyeGuy.cs | 78 +++ Content/Transformations/EyeGuy/EyeGuy.png | Bin 0 -> 745 bytes .../Transformations/EyeGuy/EyeGuy_Body.png | Bin 0 -> 4194 bytes .../Transformations/EyeGuy/EyeGuy_Head.png | Bin 0 -> 3944 bytes .../Transformations/EyeGuy/EyeGuy_Legs.png | Bin 0 -> 4217 bytes Enums/TranformationEnum.cs | 50 +- Keybinds/KeybindSystem.cs | 4 +- Localization/en-US_Mods.Ben10Mod.hjson | 23 + OmnitrixPlayer.cs | 122 +++-- ShopNPC.cs | 24 +- build.txt | 2 +- 32 files changed, 1150 insertions(+), 256 deletions(-) create mode 100644 Content/Buffs/Debuffs/TransformationCooldown_Buff.cs create mode 100644 Content/Buffs/Transformations/EyeGuy_Buff.cs create mode 100644 Content/Interface/OE_Fill.png create mode 100644 Content/Interface/OE_Panel_Left.png create mode 100644 Content/Interface/OE_Panel_Middle.png create mode 100644 Content/Interface/OE_Panel_Right.png create mode 100644 Content/Items/Accessories/HeroEmblem.cs create mode 100644 Content/Items/Accessories/HeroEmblem.png create mode 100644 Content/Projectiles/EyeGuyLaserbeam.cs create mode 100644 Content/Projectiles/EyeGuyLaserbeam.png create mode 100644 Content/Projectiles/EyeGuyUltimateBeam.cs create mode 100644 Content/Projectiles/EyeGuyUltimateBeam.png create mode 100644 Content/Transformations/EyeGuy/EyeGuy.cs create mode 100644 Content/Transformations/EyeGuy/EyeGuy.png create mode 100644 Content/Transformations/EyeGuy/EyeGuy_Body.png create mode 100644 Content/Transformations/EyeGuy/EyeGuy_Head.png create mode 100644 Content/Transformations/EyeGuy/EyeGuy_Legs.png diff --git a/Content/Buffs/Debuffs/TransformationCooldown_Buff.cs b/Content/Buffs/Debuffs/TransformationCooldown_Buff.cs new file mode 100644 index 0000000..3ca3999 --- /dev/null +++ b/Content/Buffs/Debuffs/TransformationCooldown_Buff.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Terraria; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Buffs.Transformations { + public class UltimateAbility_Cooldown : ModBuff { + public override string Texture => "Ben10Mod/Content/Buffs/Transformations/TransformationCooldown"; + private OmnitrixPlayer p; + public override void Update(Player player, ref int buffIndex) { + p = player.GetModPlayer(); + } + + public override bool RightClick(int buffIndex) => false; + } +} diff --git a/Content/Buffs/Transformations/EyeGuy_Buff.cs b/Content/Buffs/Transformations/EyeGuy_Buff.cs new file mode 100644 index 0000000..c179e01 --- /dev/null +++ b/Content/Buffs/Transformations/EyeGuy_Buff.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Ben10Mod.Enums; +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Buffs.Transformations { + public class EyeGuy_Buff : ModBuff { + public override string Texture => "Ben10Mod/Content/Buffs/Transformations/EmptyTransformation"; + private OmnitrixPlayer p; + public override void Update(Player player, ref int buffIndex) { + p = player.GetModPlayer(); + + p.currTransformation = TransformationEnum.EyeGuy; + p.isTransformed = true; + p.wasTransformed = true; + } + public override bool RightClick(int buffIndex) => false; + } +} diff --git a/Content/Interface/AlienSelectionScreen.cs b/Content/Interface/AlienSelectionScreen.cs index 83318dd..b8bbc54 100644 --- a/Content/Interface/AlienSelectionScreen.cs +++ b/Content/Interface/AlienSelectionScreen.cs @@ -3,217 +3,347 @@ using Microsoft.Xna.Framework.Graphics; using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Terraria; using Terraria.GameContent.UI.Elements; -using Terraria.GameInput; using Terraria.ModLoader; -using Terraria.ModLoader.UI; +using Terraria.ModLoader.UI.Elements; using Terraria.UI; -namespace Ben10Mod.Content.Interface { - public class UISystem : ModSystem { +namespace Ben10Mod.Content.Interface +{ + public class UISystem : ModSystem + { internal UserInterface MyInterface; internal AlienSelectionScreen AS; - private GameTime _lastUpdateUiGameTime; - public override void Load() { - base.Load(); - if (!Main.dedServ) { + public override void Load() + { + if (!Main.dedServ) + { MyInterface = new UserInterface(); AS = new AlienSelectionScreen(); AS.Activate(); } } - public override void Unload() { - base.Unload(); - AS = null; - } + public override void Unload() => AS = null; - public override void UpdateUI(GameTime gameTime) { + public override void UpdateUI(GameTime gameTime) + { _lastUpdateUiGameTime = gameTime; - if (MyInterface?.CurrentState != null) { + if (MyInterface?.CurrentState != null) MyInterface.Update(gameTime); - } } - - public override void ModifyInterfaceLayers(List layers) { + public override void ModifyInterfaceLayers(List layers) + { int mouseTextIndex = layers.FindIndex(layer => layer.Name.Equals("Vanilla: Mouse Text")); if (mouseTextIndex != -1) { + // Your existing Alien Roster layer layers.Insert(mouseTextIndex, new LegacyGameInterfaceLayer( - "MyMod: MyInterface", + "Ben10Mod: AlienSelection", delegate { - if (_lastUpdateUiGameTime != null && MyInterface?.CurrentState != null) { + if (_lastUpdateUiGameTime != null && MyInterface?.CurrentState != null) MyInterface.Draw(Main.spriteBatch, _lastUpdateUiGameTime); - } + return true; + }, + InterfaceScaleType.UI)); + + // NEW: Omnitrix Energy Bar (always visible when transformed) + layers.Insert(mouseTextIndex, new LegacyGameInterfaceLayer( + "Ben10Mod: OmnitrixEnergyBar", + delegate { + DrawOmnitrixEnergyBar(); return true; }, InterfaceScaleType.UI)); } } - internal void ShowMyUI() { - MyInterface?.SetState(AS); - } + private void DrawOmnitrixEnergyBar() { + Player player = Main.LocalPlayer; + var omp = player.GetModPlayer(); - internal void HideMyUI() { - MyInterface?.SetState(null); - } + if (!omp.omnitrixEquipped) return; - } + float fillPercent = MathHelper.Clamp(omp.omnitrixEnergy / (float)omp.omnitrixEnergyMax, 0f, 1f); - public class AlienSelectionScreen : UIState { - - UIPanel panel; - - UIImage AlienOne; - UIImage AlienTwo; - UIImage AlienThree; - UIImage AlienFour; - UIImage AlienFive; - UIImage AlienSix; - UIImage AlienSeven; - UIImage AlienEight; - UIImage AlienNine; - UIImage AlienTen; - - public override void OnInitialize() { - panel = new UIPanel(); - panel.Width.Set(512, 0); - panel.Height.Set(256, 0); - panel.HAlign = panel.VAlign = 0.5f; - Append(panel); - - UIText text = new UIText("Alien Selection Screen"); - text.HAlign = 0.5f; - text.Top.Set(10f, 0f); - panel.Append(text); - - int drawHeight = 60; - int drawWidth = 50; - int padding = 20; // space between icons - - AlienOne = new(TransformationEnum.None.GetTransformationIcon()); - AlienTwo = new(TransformationEnum.None.GetTransformationIcon()); - AlienThree = new(TransformationEnum.None.GetTransformationIcon()); - AlienFour = new(TransformationEnum.None.GetTransformationIcon()); - AlienFive = new(TransformationEnum.None.GetTransformationIcon()); - - // Hook up events - AlienOne.OnLeftClick += NextAlienOne; - AlienOne.OnRightClick += PrevAlienOne; - AlienTwo.OnLeftClick += NextAlienTwo; - AlienTwo.OnRightClick += PrevAlienTwo; - AlienThree.OnLeftClick += NextAlienThree; - AlienThree.OnRightClick+= PrevAlienThree; - AlienFour.OnLeftClick += NextAlienFour; - AlienFour.OnRightClick += PrevAlienFour; - AlienFive.OnLeftClick += NextAlienFive; - AlienFive.OnRightClick += PrevAlienFive; - - var aliens = new[] { AlienOne, AlienTwo, AlienThree, AlienFour, AlienFive }; - int count = aliens.Length; - - // spacing between icons (center-to-center) - float spacing = drawWidth + padding; - // middle index (2 for 5 items, 1.5 for 4 items, etc.) - float centerIndex = (count - 1) / 2f; - - for (int i = 0; i < count; i++) { - var alien = aliens[i]; - - alien.Width.Set(drawWidth, 0f); - alien.Height.Set(drawHeight, 0f); - - // vertically: some fixed offset below the title - alien.Top.Set(80f, 0f); - - // horizontally: center aligned, then shifted left/right - alien.HAlign = 0.5f; - float offsetFromCenter = (i - centerIndex) * spacing; - alien.Left.Set(offsetFromCenter, 0f); - - panel.Append(alien); - } - } + Texture2D panelLeft = ModContent.Request("Ben10Mod/Content/Interface/OE_Panel_Left").Value; + Texture2D panelMid = ModContent.Request("Ben10Mod/Content/Interface/OE_Panel_Middle").Value; + Texture2D panelRight = ModContent.Request("Ben10Mod/Content/Interface/OE_Panel_Right").Value; + Texture2D fillTex = ModContent.Request("Ben10Mod/Content/Interface/OE_Fill").Value; + // Width: left + (mid repeated N times) + right + int midCount = 20; + int barWidth = panelLeft.Width + panelMid.Width * midCount + panelRight.Width; + + int uiMargin = 20; // distance from screen edge (matches vanilla feel) + int gap = 26; // space between your bar and the HP bar + int hpBarWidth = 252; // horizontal bars HP width (works with your screenshot) + int y = 30; // top padding (match vanilla horizontal bars baseline) - protected override void DrawSelf(SpriteBatch spriteBatch) { - base.DrawSelf(spriteBatch); - // If this code is in the panel or container element, check it directly - if (ContainsPoint(Main.MouseScreen)) { - Main.LocalPlayer.mouseInterface = true; - } - // Otherwise, we can check a child element instead - if (panel.ContainsPoint(Main.MouseScreen)) { - Main.LocalPlayer.mouseInterface = true; + // left edge of the vanilla HP bar area + int hpLeftX = Main.screenWidth - uiMargin - hpBarWidth; + + // your bar goes immediately to the left of that + int x = hpLeftX - gap - barWidth; + + // Height: unify by using the tallest piece, then center the others vertically + int barHeight = Math.Max(panelLeft.Height, Math.Max(panelMid.Height, panelRight.Height)); + + int yLeft = y + (barHeight - panelLeft.Height) / 2; + int yMid = y + (barHeight - panelMid.Height) / 2; + int yRight = y + (barHeight - panelRight.Height) / 2; + + // Draw left + Main.spriteBatch.Draw(panelLeft, new Vector2(x, yLeft), Color.White); + + // Draw tiled middle + int midStartX = x + panelLeft.Width; + int midEndX = x + barWidth - panelRight.Width; + + for (int drawX = midStartX; drawX < midEndX; drawX += panelMid.Width) { + int w = Math.Min(panelMid.Width, midEndX - drawX); + Rectangle src = new Rectangle(0, 0, w, panelMid.Height); + Main.spriteBatch.Draw(panelMid, new Vector2(drawX, yMid), src, Color.White); } - if (IsMouseHovering) { - PlayerInput.LockVanillaMouseScroll("MyMod/ScrollListA"); // The passed in string can be anything. + // Draw right (now vertically aligned) + Main.spriteBatch.Draw(panelRight, new Vector2(x + barWidth - panelRight.Width, yRight), Color.White); + + // ===== Fill inset tuned for your art ===== + int padLeft = 6; + int padRight = 6; + int padTop = 6; + int padBottom = 6; + + int innerX = x + padLeft; + int innerY = y + padTop; + int innerWidth = barWidth - padLeft - padRight; + int innerHeight = barHeight - padTop - padBottom; // 12 + + if (innerWidth < 1 || innerHeight < 1) + return; + + int fillWidth = (int)(innerWidth * fillPercent); + if (fillPercent > 0f && fillWidth < 1) fillWidth = 1; + + if (fillWidth > 0) + { + Rectangle fillRect = new Rectangle(innerX, innerY, fillWidth, innerHeight); + Main.spriteBatch.Draw(fillTex, fillRect, Color.White); } - } - private void NextAlienOne(UIMouseEvent evt, UIElement listeningElement) { - TransformationHandler.NextTransformation(Main.LocalPlayer, ref Main.LocalPlayer.GetModPlayer().transformations[0]); - } - private void NextAlienTwo(UIMouseEvent evt, UIElement listeningElement) { - TransformationHandler.NextTransformation(Main.LocalPlayer, ref Main.LocalPlayer.GetModPlayer().transformations[1]); - } - private void NextAlienThree(UIMouseEvent evt, UIElement listeningElement) { - TransformationHandler.NextTransformation(Main.LocalPlayer, ref Main.LocalPlayer.GetModPlayer().transformations[2]); - } - private void NextAlienFour(UIMouseEvent evt, UIElement listeningElement) { - TransformationHandler.NextTransformation(Main.LocalPlayer, ref Main.LocalPlayer.GetModPlayer().transformations[3]); + // Energy text above the bar + string text = $"{(int)omp.omnitrixEnergy}/{(int)omp.omnitrixEnergyMax}"; + Utils.DrawBorderString( + Main.spriteBatch, + text, + new Vector2(x + barWidth * 0.5f, y - 12), + Color.White, + 0.9f, + 0.5f, + 0.5f + ); } - private void NextAlienFive(UIMouseEvent evt, UIElement listeningElement) { - TransformationHandler.NextTransformation(Main.LocalPlayer, ref Main.LocalPlayer.GetModPlayer().transformations[4]); - } - private void PrevAlienOne(UIMouseEvent evt, UIElement listeningElement) { - TransformationHandler.PrevTransformation(Main.LocalPlayer, ref Main.LocalPlayer.GetModPlayer().transformations[0]); - } - private void PrevAlienTwo(UIMouseEvent evt, UIElement listeningElement) { - TransformationHandler.PrevTransformation(Main.LocalPlayer, ref Main.LocalPlayer.GetModPlayer().transformations[1]); - } - private void PrevAlienThree(UIMouseEvent evt, UIElement listeningElement) { - TransformationHandler.PrevTransformation(Main.LocalPlayer, ref Main.LocalPlayer.GetModPlayer().transformations[2]); - } - private void PrevAlienFour(UIMouseEvent evt, UIElement listeningElement) { - TransformationHandler.PrevTransformation(Main.LocalPlayer, ref Main.LocalPlayer.GetModPlayer().transformations[3]); + + internal void ShowMyUI() => MyInterface?.SetState(AS); + internal void HideMyUI() => MyInterface?.SetState(null); + } + + public class AlienSelectionScreen : UIState + { + private UIPanel mainPanel; + private readonly List rosterSlots = new(); + private UIGrid unlockedGrid; + private UIPanel infoPanel; + private UIImage previewImage; + private UIText nameText; + private UIText descriptionText; + private UIList abilityList; + + private TransformationEnum currentlySelected = TransformationEnum.None; + + public override void OnInitialize() + { + mainPanel = new UIPanel(); + mainPanel.Width.Set(1220f, 0f); + mainPanel.Height.Set(680f, 0f); + mainPanel.HAlign = mainPanel.VAlign = 0.5f; + Append(mainPanel); + + var title = new UIText("Omnitrix - Alien Roster", 1.45f); + title.HAlign = 0.5f; + title.Top.Set(18f, 0f); + mainPanel.Append(title); + + var rosterHeader = new UIText("Active Roster", 1.25f); + rosterHeader.Left.Set(65f, 0f); + rosterHeader.Top.Set(68f, 0f); + mainPanel.Append(rosterHeader); + + int slotSize = 92; + int rosterStartX = 65; + int rosterY = 105; + + for (int i = 0; i < 5; i++) + { + var slot = new UIImage(TransformationEnum.None.GetTransformationIcon()); + slot.Width.Set(slotSize, 0f); + slot.Height.Set(slotSize, 0f); + slot.Left.Set(rosterStartX + i * (slotSize + 26f), 0f); + slot.Top.Set(rosterY, 0f); + + int index = i; + slot.OnLeftClick += (_, _) => AssignToSlot(index); + slot.OnRightClick += (_, _) => ClearSlot(index); + + mainPanel.Append(slot); + rosterSlots.Add(slot); + } + + var divider = new UIPanel(); + divider.Width.Set(610f, 0f); + divider.Height.Set(4f, 0f); + divider.Left.Set(65f, 0f); + divider.Top.Set(rosterY + slotSize + 22f, 0f); + divider.BackgroundColor = new Color(80, 120, 255, 180); + mainPanel.Append(divider); + + var unlockedHeader = new UIText("Unlocked Aliens", 1.25f); + unlockedHeader.Left.Set(65f, 0f); + unlockedHeader.Top.Set(rosterY + slotSize + 52f, 0f); + mainPanel.Append(unlockedHeader); + + unlockedGrid = new UIGrid(); + unlockedGrid.Width.Set(610f, 0f); + unlockedGrid.Height.Set(315f, 0f); // ← SHORTENED so it ends before Close button + unlockedGrid.Left.Set(65f, 0f); + unlockedGrid.Top.Set(rosterY + slotSize + 85f, 0f); + unlockedGrid.ListPadding = 10f; + mainPanel.Append(unlockedGrid); + + var gridScrollbar = new UIScrollbar(); + gridScrollbar.Height.Set(315f, 0f); // ← matches new grid height + gridScrollbar.Left.Set(685f, 0f); + gridScrollbar.Top.Set(rosterY + slotSize + 85f, 0f); + mainPanel.Append(gridScrollbar); + unlockedGrid.SetScrollbar(gridScrollbar); + + infoPanel = new UIPanel(); + infoPanel.Width.Set(460f, 0f); + infoPanel.Height.Set(545f, 0f); + infoPanel.Left.Set(740f, 0f); + infoPanel.Top.Set(92f, 0f); + mainPanel.Append(infoPanel); + + previewImage = new UIImage(TransformationEnum.None.GetTransformationIcon()); + previewImage.Width.Set(158f, 0f); + previewImage.Height.Set(158f, 0f); + previewImage.HAlign = 0.5f; + previewImage.Top.Set(28f, 0f); + infoPanel.Append(previewImage); + + nameText = new UIText("Select an alien", 1.3f); + nameText.HAlign = 0.5f; + nameText.Top.Set(205f, 0f); + infoPanel.Append(nameText); + + descriptionText = new UIText("Click any unlocked alien", 0.95f); + descriptionText.HAlign = 0.5f; + descriptionText.Top.Set(240f, 0f); + descriptionText.Width.Set(400f, 0f); + descriptionText.IsWrapped = true; + infoPanel.Append(descriptionText); + + var abilitiesHeader = new UIText("Abilities:", 1.15f); + abilitiesHeader.Left.Set(32f, 0f); + abilitiesHeader.Top.Set(295f, 0f); + infoPanel.Append(abilitiesHeader); + + abilityList = new UIList(); + abilityList.Width.Set(400f, 0f); + abilityList.Height.Set(190f, 0f); + abilityList.Left.Set(32f, 0f); + abilityList.Top.Set(325f, 0f); + infoPanel.Append(abilityList); + + var closeBtn = new UITextPanel("Close Roster"); + closeBtn.HAlign = 0.5f; + closeBtn.Top.Set(-58f, 1f); + closeBtn.OnLeftClick += (_, _) => ModContent.GetInstance().HideMyUI(); + mainPanel.Append(closeBtn); } - private void PrevAlienFive(UIMouseEvent evt, UIElement listeningElement) { - TransformationHandler.PrevTransformation(Main.LocalPlayer, ref Main.LocalPlayer.GetModPlayer().transformations[4]); + + private void AssignToSlot(int slotIndex) + { + if (currentlySelected == TransformationEnum.None) return; + + var player = Main.LocalPlayer.GetModPlayer(); + if (player.unlockedTransformation.Contains(currentlySelected)) + player.transformations[slotIndex] = currentlySelected; } + private void ClearSlot(int slotIndex) + { + var player = Main.LocalPlayer.GetModPlayer(); + player.transformations[slotIndex] = TransformationEnum.None; + } - public override void Update(GameTime gameTime) { + public override void Update(GameTime gameTime) + { base.Update(gameTime); - AlienOne.SetImage(Main.LocalPlayer.GetModPlayer().transformations[0].GetTransformationIcon()); - AlienTwo.SetImage(Main.LocalPlayer.GetModPlayer().transformations[1].GetTransformationIcon()); - AlienThree.SetImage(Main.LocalPlayer.GetModPlayer().transformations[2].GetTransformationIcon()); - AlienFour.SetImage(Main.LocalPlayer.GetModPlayer().transformations[3].GetTransformationIcon()); - AlienFive.SetImage(Main.LocalPlayer.GetModPlayer().transformations[4].GetTransformationIcon()); - - if (AlienOne.IsMouseHovering) { - Main.instance.MouseText(Main.LocalPlayer.GetModPlayer().transformations[0].GetName()); - } - if (AlienTwo.IsMouseHovering) { - Main.instance.MouseText(Main.LocalPlayer.GetModPlayer().transformations[1].GetName()); - } - if (AlienThree.IsMouseHovering) { - Main.instance.MouseText(Main.LocalPlayer.GetModPlayer().transformations[2].GetName()); - } - if (AlienFour.IsMouseHovering) { - Main.instance.MouseText(Main.LocalPlayer.GetModPlayer().transformations[3].GetName()); - } - if (AlienFive.IsMouseHovering) { - Main.instance.MouseText(Main.LocalPlayer.GetModPlayer().transformations[4].GetName()); + + var player = Main.LocalPlayer.GetModPlayer(); + + for (int i = 0; i < rosterSlots.Count; i++) + rosterSlots[i].SetImage(player.transformations[i].GetTransformationIcon()); + + unlockedGrid.Clear(); + foreach (var trans in player.unlockedTransformation) + { + if (trans == TransformationEnum.None) continue; + + var btn = new UIImage(trans.GetTransformationIcon()); + btn.Width.Set(80f, 0f); + btn.Height.Set(80f, 0f); + + btn.OnLeftClick += (_, _) => + { + currentlySelected = trans; + UpdateInfoPanel(trans); + }; + + btn.OnMouseOver += (_, _) => UpdateInfoPanel(trans); + + unlockedGrid.Add(btn); } + + unlockedGrid.Recalculate(); + unlockedGrid.RecalculateChildren(); + + if (mainPanel.ContainsPoint(Main.MouseScreen)) + Main.LocalPlayer.mouseInterface = true; + } + + private void UpdateInfoPanel(TransformationEnum trans) + { + previewImage.SetImage(trans.GetTransformationIcon()); + nameText.SetText(trans.GetName()); + descriptionText.SetText(trans.GetDescription()); + + abilityList.Clear(); + var abilities = trans.GetAbilities(); + foreach (var ability in abilities) + abilityList.Add(new UIText("• " + ability, 0.95f)); + } + + protected override void DrawSelf(SpriteBatch spriteBatch) + { + base.DrawSelf(spriteBatch); + if (ContainsPoint(Main.MouseScreen)) + Main.LocalPlayer.mouseInterface = true; } } -} +} \ No newline at end of file diff --git a/Content/Interface/OE_Fill.png b/Content/Interface/OE_Fill.png new file mode 100644 index 0000000000000000000000000000000000000000..97c97dfa4d5506c3d91b069c1dc67e5b5f23858d GIT binary patch literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&k#^NA%Cx&(BWL^R}mYyz-AsQ2t z-~6-xY0oV9;LrD39uV+3qT$A-6TWY)il6FYjY_kgECsd=HPJWl#q~^aX~eqK`=HoIn#!@PWFY?_WY>scy{hx2RdiRcU<}S2Qdw6z9HGy!-4aWfXmqI!l z=iLFT+F+2Jpzwgd;>Dqwnvd6My;OXk;vd$@?2>^B3 BQk?(* literal 0 HcmV?d00001 diff --git a/Content/Items/Accessories/HeroEmblem.cs b/Content/Items/Accessories/HeroEmblem.cs new file mode 100644 index 0000000..e2f8a68 --- /dev/null +++ b/Content/Items/Accessories/HeroEmblem.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using Ben10Mod.Content.DamageClasses; +using Ben10Mod.Content.Items.Placeables; +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Items.Accessories; + +public class HeroEmblem : ModItem { + + public override void SetDefaults() { + Item.width = 32; + Item.height = 32; + Item.accessory = true; + Item.value = 100000; + Item.rare = ItemRarityID.Orange; + } + + public override void ModifyTooltips(List tooltips) { + TooltipLine damageLine = new TooltipLine(Mod, "HeroDamageBonus", "+15% increased hero damage"); + + tooltips.Add(damageLine); + } + + public override void UpdateAccessory(Player player, bool hideVisual) { + var omp = player.GetModPlayer(); + player.GetDamage() += 0.15f; + } +} \ No newline at end of file diff --git a/Content/Items/Accessories/HeroEmblem.png b/Content/Items/Accessories/HeroEmblem.png new file mode 100644 index 0000000000000000000000000000000000000000..4ba90b46e0cf8ae365357b3ffdadabed7144fbeb GIT binary patch literal 493 zcmVPx$r%6OXR7i=FH` z>RMV01q+;czHp z;;+29S&IIrLZ3>L)@rrDymq_oiz}6iFAgJ*4{|2q7=ZqB2Y{sE#`cL#8Vm*iG#U*6y7dhJatGJo@z^9e1MCsYsteQl_8|aI{Tl!t zFP7bj{<|BWyW#Fx$Cp2uOni0n`8;@bkNsXP=dj*yx>pOimL`=q*=#leD3{9sv|6p0 z_G(#ua>_`&u(lVNuSq38O!hq%X|H7!npVH(dhmEE*NeBJ_z~+TmwhM->+K@_rsDU_ j6{cDLokZGGEo;O-^3}G-#7n>900000NkvXXu0mjfXO!JS literal 0 HcmV?d00001 diff --git a/Content/Items/Accessories/PrototypeOmnitrix.cs b/Content/Items/Accessories/PrototypeOmnitrix.cs index a8bdd3e..82e0877 100644 --- a/Content/Items/Accessories/PrototypeOmnitrix.cs +++ b/Content/Items/Accessories/PrototypeOmnitrix.cs @@ -92,6 +92,8 @@ public override void UpdateAccessory(Player player, bool hideVisual) { omp.omnitrixEquipped = true; wasEquipedLastFrame = true; + omp.omnitrixEnergyMax += 300; + transformations = player.GetModPlayer().transformations; if (KeybindSystem.OpenTransformationScreen.JustPressed) { if (!showingUI) { diff --git a/Content/Items/Accessories/RecalibratedOmnitrix.cs b/Content/Items/Accessories/RecalibratedOmnitrix.cs index 38b1177..c647ace 100644 --- a/Content/Items/Accessories/RecalibratedOmnitrix.cs +++ b/Content/Items/Accessories/RecalibratedOmnitrix.cs @@ -32,8 +32,6 @@ public class RecalibratedOmnitrix : Omnitrix { private Player player = null; public int transformationNum = 0; - public int transformationEnergy = 0; - private int maxEnergy = 0; public TransformationEnum[] transformations = new TransformationEnum[5]; bool wasEquipedLastFrame = false; @@ -82,28 +80,37 @@ public override void SetDefaults() { Item.height = 28; Item.rare = ItemRarityID.Master; Item.accessory = true; - this.transformationEnergy = 300 * 60; - this.maxEnergy = 300 * 60; } - public override void ModifyTooltips(List tooltips) - { - tooltips.Add(new TooltipLine(Mod, "TransformationEnergy", "Energy: " + (int)(transformationEnergy / 60))); - tooltips.Add(new TooltipLine(Mod, "AlienSelection", "Alien " + (transformationNum + 1) + ": " + transformations[transformationNum].ToString())); + public override void ModifyTooltips(List tooltips) { + tooltips.Add(new TooltipLine(Mod, "AlienSelection", + "Alien " + (transformationNum + 1) + ": " + transformations[transformationNum].ToString())); } public override void UpdateAccessory(Player player, bool hideVisual) { this.player = player; - player.GetModPlayer().omnitrixEquipped = true; - wasEquipedLastFrame = true; + var omp = player.GetModPlayer(); + omp.omnitrixEnergyMax += 500; + omp.omnitrixEquipped = true; + wasEquipedLastFrame = true; + + if (omp.isTransformed) + omp.omnitrixEnergyRegen -= 1; - transformations = player.GetModPlayer().transformations; - if (player.GetModPlayer().isTransformed && transformationEnergy > 0) { - transformationEnergy -= 1; - } else if (transformationEnergy < maxEnergy) { - transformationEnergy += 3; - transformationEnergy = Math.Min(transformationEnergy, maxEnergy); + if (omp.omnitrixEnergy <= 0 && omp.isTransformed) { + TransformationHandler.Detransform(player, 120); + } + + if (omp.omnitrixEnergy > 0 && omp.isTransformed) { + TransformationHandler.Transform(player, omp.currTransformation, 2, false,false); } + if (omp.isTransformed) + omp.omnitrixEnergyRegen -= 1; + else + omp.omnitrixEnergyRegen += 3; + + + transformations = player.GetModPlayer().transformations; if (KeybindSystem.OpenTransformationScreen.JustPressed) { if (!showingUI) { player.GetModPlayer().transformations = transformations; @@ -115,19 +122,21 @@ public override void UpdateAccessory(Player player, bool hideVisual) { showingUI = false; } } - if (transformationEnergy <= 0) { - TransformationHandler.Detransform(player, 60); - } if (KeybindSystem.TransformationKeybind.JustPressed && !player.GetModPlayer().isTransformed && !player.GetModPlayer().onCooldown) { - TransformationHandler.Transform(player, transformations[transformationNum], transformationEnergy / 60); + TransformationHandler.Transform(player, transformations[transformationNum], 2); } else if (KeybindSystem.TransformationKeybind.JustPressed && player.GetModPlayer().isTransformed && !player.GetModPlayer().onCooldown) { if (player.GetModPlayer().currTransformation != transformations[transformationNum]) { - transformationEnergy -= 50; - TransformationHandler.Detransform(player, 60, false, transformationEnergy <= 0, false); - transformationEnergy = Math.Max(transformationEnergy, 0); - TransformationHandler.Transform(player, transformations[transformationNum], transformationEnergy / 60); + omp.omnitrixEnergy -= 50; + omp.omnitrixEnergy = Math.Max(omp.omnitrixEnergy, 0); + if (omp.omnitrixEnergy > 0) { + TransformationHandler.Detransform(player, 0, false, false); + TransformationHandler.Transform(player, transformations[transformationNum], 2); + } + else { + TransformationHandler.Detransform(player, 60); + } } else { TransformationHandler.Detransform(player, 0, true, false); } diff --git a/Content/Items/Armour/PlumbersGlassHelmet.cs b/Content/Items/Armour/PlumbersGlassHelmet.cs index e84e5f4..dfe24b6 100644 --- a/Content/Items/Armour/PlumbersGlassHelmet.cs +++ b/Content/Items/Armour/PlumbersGlassHelmet.cs @@ -21,7 +21,7 @@ public override void SetDefaults() { Item.width = 18; Item.height = 14; - Item.defense = 3; + Item.defense = 1; Item.value = 010000; } @@ -35,9 +35,14 @@ public override bool IsArmorSet(Item head, Item body, Item legs) { public override void UpdateArmorSet(Player player) { - player.setBonus = "+5 Hero damage"; + player.setBonus = "+12% movement speed while transformed"; - player.GetDamage(ModContent.GetInstance()).Flat += 5; + var omp = player.GetModPlayer(); + + if (omp.isTransformed) { + player.moveSpeed *= 1.12f; + player.accRunSpeed *= 1.12f; + } } public override void AddRecipes() diff --git a/Content/Items/Armour/PlumbersHelmet.cs b/Content/Items/Armour/PlumbersHelmet.cs index 8fef6ba..ce69bb0 100644 --- a/Content/Items/Armour/PlumbersHelmet.cs +++ b/Content/Items/Armour/PlumbersHelmet.cs @@ -23,7 +23,7 @@ public override void SetDefaults() { Item.value = 010000; - Item.defense = 5; + Item.defense = 2; } public override bool IsArmorSet(Item head, Item body, Item legs) { @@ -35,9 +35,13 @@ public override bool IsArmorSet(Item head, Item body, Item legs) { public override void UpdateArmorSet(Player player) { - player.setBonus = "+10 defence"; + player.setBonus = "+8 defence while transformed"; + + var omp = player.GetModPlayer(); - player.statDefense += 10; + if (omp.isTransformed) { + player.statDefense += 8; + } } public override void AddRecipes() diff --git a/Content/Items/Armour/PlumbersPants.cs b/Content/Items/Armour/PlumbersPants.cs index cff4071..cda993f 100644 --- a/Content/Items/Armour/PlumbersPants.cs +++ b/Content/Items/Armour/PlumbersPants.cs @@ -22,7 +22,7 @@ public override void SetDefaults() { Item.value = 010000; - Item.defense = 4; + Item.defense = 2; } diff --git a/Content/Items/Armour/PlumbersShirt.cs b/Content/Items/Armour/PlumbersShirt.cs index 4df14fc..3e998e5 100644 --- a/Content/Items/Armour/PlumbersShirt.cs +++ b/Content/Items/Armour/PlumbersShirt.cs @@ -22,7 +22,7 @@ public override void SetDefaults() { Item.value = 010000; - Item.defense = 6; + Item.defense = 3; } public override void AddRecipes() diff --git a/Content/Items/Weapons/PlumbersBadge.cs b/Content/Items/Weapons/PlumbersBadge.cs index 5113e8c..bab4445 100644 --- a/Content/Items/Weapons/PlumbersBadge.cs +++ b/Content/Items/Weapons/PlumbersBadge.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using Ben10Mod.Content.Buffs.Transformations; using Ben10Mod.Content.DamageClasses; using Ben10Mod.Content.Projectiles; using Ben10Mod.Enums; @@ -20,8 +21,61 @@ public abstract class PlumbersBadge : ModItem public virtual float DamageMultiplier => 1f; // For universal scaling if needed public virtual float AttackSpeedMultiplier => 1f; public virtual string BadgeRankName => "Helper"; - - public override void SetDefaults() + public int OmnitrixEnergyUse = 0; + + + private int GetUltimateProjectileType(OmnitrixPlayer omp) + { + // Add more mappings here as you implement other ultimate attacks. + return omp.currTransformation switch + { + TransformationEnum.EyeGuy => ModContent.ProjectileType(), + _ => 0 + }; + } + + private static bool HasActiveOwnedProjectile(Player player, int projType) + { + if (projType <= 0) return false; + + int owner = player.whoAmI; + for (int i = 0; i < Main.maxProjectiles; i++) + { + Projectile p = Main.projectile[i]; + if (p.active && p.owner == owner && p.type == projType) + return true; + } + return false; + } + + private void FinalizeUltimateIfEnded(Player player, OmnitrixPlayer omp) + { + if (!omp.ultimateAttack) return; + + var state = player.GetModPlayer(); + + // If the ultimate hasn't actually started yet (no ultimate projectile spawned), + // don't auto-cancel it. This prevents "arming" the ultimate from immediately ending it. + if (!state.ultimateStarted) + return; + + // If player is still holding the channel, ultimate is still in progress. + if (player.channel) return; + + // If the ultimate projectile is still alive, ultimate is still in progress. + int ultimateProjType = GetUltimateProjectileType(omp); + if (HasActiveOwnedProjectile(player, ultimateProjType)) return; + + // If we're here, the player has released channel and the ultimate projectile is gone. + if (!player.HasBuff()) + player.AddBuff(ModContent.BuffType(), 60 * 60); + + omp.ultimateAttack = false; + state.ultimateStarted = false; + } + + +public override void SetDefaults() { Item.width = 32; Item.height = 32; @@ -40,6 +94,8 @@ public override void SetDefaults() Item.useStyle = ItemUseStyleID.Swing; Item.useTime = Item.useAnimation = 25; Item.shootSpeed = 10f; + + Item.UseSound = null; } public override void ModifyTooltips(List tooltips) @@ -49,8 +105,8 @@ public override void ModifyTooltips(List tooltips) public override bool CanUseItem(Player player) { - // Only usable when transformed - prevents any use/animation when human - return player.GetModPlayer().isTransformed; + var omp = player.GetModPlayer(); + return player.GetModPlayer().isTransformed && !(omp.omnitrixEnergy < OmnitrixEnergyUse && omp.ultimateAttack); } public override bool AltFunctionUse(Player player) => true; @@ -59,11 +115,16 @@ public override void HoldItem(Player player) { var omp = player.GetModPlayer(); + FinalizeUltimateIfEnded(player, omp); + // Safety defaults Item.useTime = Item.useAnimation = 25; Item.shootSpeed = 10f; Item.useStyle = ItemUseStyleID.Swing; Item.ArmorPenetration = 0; + Item.UseSound = null; + OmnitrixEnergyUse = 0; + if (!omp.isTransformed) return; @@ -78,8 +139,8 @@ public override void HoldItem(Player player) Item.shootSpeed = 10f; } else { - Item.useStyle = ItemUseStyleID.Shoot; - Item.useTime = Item.useAnimation = 6; // Fast enough for fireballs, bombs will feel strong but same rate + Item.useStyle = ItemUseStyleID.Shoot; + Item.useTime = Item.useAnimation = 6; Item.shootSpeed = 3f; } break; @@ -128,6 +189,14 @@ public override void HoldItem(Player player) Item.useTime = Item.useAnimation = 32; Item.shootSpeed = 10f; break; + case TransformationEnum.EyeGuy: + Item.useStyle = ItemUseStyleID.Shoot; + Item.useTime = Item.useAnimation = 12; + Item.shootSpeed = omp.ultimateAttack ? 0f : 35f; + Item.UseSound = omp.ultimateAttack ? null : SoundID.Item12; + Item.channel = omp.ultimateAttack; + OmnitrixEnergyUse = omp.ultimateAttack ? 10 : 0; + break; default: Item.useTime = Item.useAnimation = 25; Item.shootSpeed = 10f; @@ -140,6 +209,13 @@ public override void HoldItem(Player player) public override bool? UseItem(Player player) { if (player.altFunctionUse == 2) player.GetModPlayer().altAttack = !player.GetModPlayer().altAttack; + var omp = player.GetModPlayer(); + if (omp.omnitrixEnergy >= OmnitrixEnergyUse) { + omp.omnitrixEnergy -= OmnitrixEnergyUse; + } + else { + return false; + } return base.UseItem(player); } @@ -149,6 +225,21 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, if (!omp.isTransformed || player.altFunctionUse == 2) return false; + // Block non-ultimate attacks while an ultimate is in progress (channeling or projectile alive). + int activeUltimateType = GetUltimateProjectileType(omp); + bool ultimateProjectileAlive = HasActiveOwnedProjectile(player, activeUltimateType); + bool ultimateInProgress = player.channel || ultimateProjectileAlive || player.GetModPlayer().ultimateStarted; + + // If ultimate is in progress, only allow firing the ultimate projectile itself (and only once). + if (ultimateInProgress && !omp.ultimateAttack) + return false; + + // Don't allow starting an ultimate while on cooldown. + + if (omp.ultimateAttack && player.HasBuff()) + return false; + + int projType = ProjectileID.ImpFireball; // Bright vanilla fallback - you SHOULD see this if alien not matched int finalDamage = damage; @@ -162,7 +253,7 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, } else { projType = ProjectileID.Flames; - finalDamage = (int)(damage * 0.5f); + finalDamage = (int)(damage * 0.3f); } break; @@ -215,13 +306,34 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, ? ModContent.ProjectileType() : ModContent.ProjectileType(); break; + case TransformationEnum.EyeGuy: + projType = omp.ultimateAttack ? ModContent.ProjectileType() : ModContent.ProjectileType(); + finalDamage = omp.ultimateAttack ? (int)(damage * 1.2f) : damage; + break; } if (projType == 0) return false; - + + // While channeling an ultimate, keep exactly one ultimate projectile alive. + if (omp.ultimateAttack && HasActiveOwnedProjectile(player, projType)) + return false; + + // Mark ultimate as started the moment we actually fire its projectile. + if (omp.ultimateAttack && projType == activeUltimateType) + player.GetModPlayer().ultimateStarted = true; + Projectile.NewProjectile(source, position, velocity, projType, (int)(finalDamage * DamageMultiplier), knockback, player.whoAmI); return false; } } + + + public class BadgeUltimateState : ModPlayer { + public bool ultimateStarted; + + public override void ResetEffects() { + // no per-tick reset; state persists until ultimate finishes + } + } } \ No newline at end of file diff --git a/Content/Projectiles/EyeGuyLaserbeam.cs b/Content/Projectiles/EyeGuyLaserbeam.cs new file mode 100644 index 0000000..8a6ac3c --- /dev/null +++ b/Content/Projectiles/EyeGuyLaserbeam.cs @@ -0,0 +1,58 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Projectiles +{ + public class EyeGuyLaserbeam : ModProjectile + { + public override void SetDefaults() + { + Projectile.width = 16; // Square hitbox = no more culling + Projectile.height = 16; + Projectile.friendly = true; + Projectile.penetrate = -1; // Goes through enemies + Projectile.tileCollide = true; + Projectile.ignoreWater = true; + Projectile.extraUpdates = 2; // Much smoother laser feel + Projectile.timeLeft = 240; + Projectile.alpha = 40; + } + + public override void AI() + { + // Always face movement direction (this is the correct way) + Projectile.rotation = Projectile.velocity.ToRotation(); + + // Eye Guy green glow + Lighting.AddLight(Projectile.Center, 0f, 0.95f, 0.25f); + + // Optional green dust trail + if (Main.rand.NextBool(2)) + { + Dust d = Dust.NewDustPerfect(Projectile.Center, DustID.GreenFairy, Projectile.velocity * 0.2f, 100, default, 1.4f); + d.noGravity = true; + } + } + + public override bool PreDraw(ref Color lightColor) + { + Texture2D texture = ModContent.Request(Texture).Value; + + Main.EntitySpriteDraw( + texture, + Projectile.Center - Main.screenPosition, // position + null, // source rectangle + lightColor * Projectile.Opacity, // color + Projectile.rotation + MathHelper.PiOver2, // ← THIS IS THE FIX (90° offset) + new Vector2(texture.Width / 2f, texture.Height / 2f), // centered origin + Projectile.scale, + SpriteEffects.None, + 0); + + return false; // skip default drawing + } + } +} \ No newline at end of file diff --git a/Content/Projectiles/EyeGuyLaserbeam.png b/Content/Projectiles/EyeGuyLaserbeam.png new file mode 100644 index 0000000000000000000000000000000000000000..8e3bd9c3d061fd3e4099930d23df0347ccad3ac7 GIT binary patch literal 96 zcmeAS@N?(olHy`uVBq!ia0vp^Oh9bI!3HFKj%EJ@QjEnx?oJHr&dIz4a-=+6978lF rCj0!B|2@AE2s#bP0l+XkK`ehf! literal 0 HcmV?d00001 diff --git a/Content/Projectiles/EyeGuyUltimateBeam.cs b/Content/Projectiles/EyeGuyUltimateBeam.cs new file mode 100644 index 0000000..81b91d9 --- /dev/null +++ b/Content/Projectiles/EyeGuyUltimateBeam.cs @@ -0,0 +1,289 @@ +using Microsoft.Build.Evaluation; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using ReLogic.Utilities; +using Terraria; +using Terraria.Audio; +using Terraria.GameContent; +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Projectiles +{ + public class EyeGuyUltimateBeam : ModProjectile + { + private const float MaxLength = 2600f; + private const float BeamThickness = 28f; + private const float StartOffset = 52f; + + private SlotId _loopSlot; + private bool _loopStarted; + + // Beam lengths for this tick: + // localAI[0] = collision length (reaches the first hit) + // localAI[1] = draw length (slightly shorter so the end-cap doesn't clip) + private float BeamHitLength { + get => Projectile.localAI[0]; + set => Projectile.localAI[0] = value; + } + + private float BeamDrawLength { + get => Projectile.localAI[1]; + set => Projectile.localAI[1] = value; + } + + public override string Texture => "Terraria/Images/Projectile_" + ProjectileID.LastPrismLaser; + + public override void SetStaticDefaults() { + Main.projFrames[Type] = 3; // start, middle, end + } + + public override void SetDefaults() { + Projectile.width = 34; + Projectile.height = 34; + Projectile.friendly = true; + Projectile.penetrate = -1; + Projectile.tileCollide = false; // we handle tiles via LaserScan + Projectile.ignoreWater = true; + + Projectile.hide = false; // must be false for PreDraw to run + Projectile.alpha = 255; // hide the projectile sprite itself + Projectile.timeLeft = 2; + + Projectile.DamageType = DamageClass.Magic; // change if needed + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 10; + } + + public override void AI() { + Player owner = Main.player[Projectile.owner]; + var omp = owner.GetModPlayer(); + + if (!owner.active || owner.dead) { + Projectile.Kill(); + return; + } + + if (!owner.channel || owner.noItems || owner.CCed) { + Projectile.Kill(); + return; + } + + if (omp.omnitrixEnergy < 10) { + Projectile.Kill(); + return; + } + + Projectile.timeLeft = 2; + + Vector2 dir = Main.MouseWorld - owner.Center; + if (dir.LengthSquared() < 0.0001f) + dir = new Vector2(owner.direction, 0f); + + dir.Normalize(); + + Projectile.velocity = dir; + Projectile.rotation = dir.ToRotation(); + Projectile.Center = owner.Center + dir * StartOffset; + + // Compute current beam length (tiles + first enemy hit). + Vector2 start = owner.Center + dir * StartOffset; + BeamHitLength = GetBeamLength(start, dir); + // Pull back slightly so the end cap doesn't clip inside tiles/NPCs. + BeamDrawLength = MathHelper.Clamp(BeamHitLength - 6f, 16f, BeamHitLength); + + if (Projectile.owner == Main.myPlayer) { + if (!_loopStarted) { + SoundStyle loopStyle = SoundID.Item15; + loopStyle.IsLooped = true; + loopStyle.MaxInstances = 1; + loopStyle.SoundLimitBehavior = SoundLimitBehavior.IgnoreNew; + + _loopSlot = SoundEngine.PlaySound(loopStyle, Projectile.Center); + _loopStarted = true; + } + + if (SoundEngine.TryGetActiveSound(_loopSlot, out ActiveSound active)) + active.Position = Projectile.Center; + } + + Lighting.AddLight(Projectile.Center, 0.2f, 1.6f, 0.6f); + } + + private float GetBeamLength(Vector2 start, Vector2 dir) { + // Stop at tiles, like Last Prism. + float[] samples = new float[3]; + Collision.LaserScan(start, dir, BeamThickness, MaxLength, samples); + + float tileLength = 0f; + for (int i = 0; i < samples.Length; i++) + tileLength += samples[i]; + tileLength /= samples.Length; + + // Safety clamp + if (tileLength < 16f) tileLength = 16f; + if (tileLength > MaxLength) tileLength = MaxLength; + + // Now also stop at the first enemy we intersect (without killing the projectile). + float best = tileLength; + + for (int n = 0; n < Main.maxNPCs; n++) { + NPC npc = Main.npc[n]; + if (!npc.active || npc.friendly || npc.dontTakeDamage || npc.lifeMax <= 5) + continue; + + float collisionPoint = 0f; + bool hit = Collision.CheckAABBvLineCollision( + npc.Hitbox.TopLeft(), + npc.Hitbox.Size(), + start, + start + dir * tileLength, + BeamThickness, + ref collisionPoint + ); + + if (hit && collisionPoint > 0f && collisionPoint < best) + best = collisionPoint; + } + + return best; + } + + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) { + Player owner = Main.player[Projectile.owner]; + + Vector2 dir = Projectile.velocity; + if (dir.LengthSquared() < 0.0001f) + return false; + + Vector2 start = owner.Center + dir * StartOffset; + float length = BeamHitLength; + Vector2 end = start + dir * length; + + float _ = 0f; + return Collision.CheckAABBvLineCollision( + targetHitbox.TopLeft(), + targetHitbox.Size(), + start, + end, + BeamThickness, + ref _ + ); + } + + public override void OnKill(int timeLeft) { + if (Projectile.owner == Main.myPlayer && + SoundEngine.TryGetActiveSound(_loopSlot, out ActiveSound active)) { + active.Stop(); + } + } + + public override bool PreDraw(ref Color lightColor) { + Player owner = Main.player[Projectile.owner]; + + Vector2 dir = Projectile.velocity; + if (dir.LengthSquared() < 0.0001f) + return false; + + dir.Normalize(); + + Vector2 start = owner.Center + dir * StartOffset; + float length = BeamDrawLength; + + Texture2D tex = TextureAssets.Projectile[Type].Value; + + int frameHeight = tex.Height / 3; + int frameWidth = tex.Width; + + Rectangle startFrame = new Rectangle(0, 0 * frameHeight, frameWidth, frameHeight); + Rectangle midFrame = new Rectangle(0, 1 * frameHeight, frameWidth, frameHeight); + Rectangle endFrame = new Rectangle(0, 2 * frameHeight, frameWidth, frameHeight); + + // Last Prism laser is authored "up" in texture space and faces opposite our direction. + float rot = dir.ToRotation() + MathHelper.PiOver2 + MathHelper.Pi; + + Vector2 origin = new Vector2(frameWidth * 0.5f, frameHeight * 0.5f); + + float t = Main.GlobalTimeWrappedHourly; + float pulse = 0.88f + 0.12f * (float)System.Math.Sin(t * 10f); + float shimmer = 0.82f + 0.18f * (float)System.Math.Sin(t * 6.5f); + + float intensity = 1.25f; + Color baseColor = new Color(60, 255, 140) * (shimmer * intensity); + + Main.spriteBatch.End(); + Main.spriteBatch.Begin( + SpriteSortMode.Deferred, + BlendState.Additive, + Main.DefaultSamplerState, + DepthStencilState.None, + RasterizerState.CullNone, + null, + Main.GameViewMatrix.TransformationMatrix + ); + + // Start cap + Main.EntitySpriteDraw( + tex, + start - Main.screenPosition, + startFrame, + baseColor, + rot, + origin, + new Vector2(1.55f * pulse, 1f), + SpriteEffects.None, + 0 + ); + + // Middle segments: no fade-in (prevents gap), only fade near the end + float step = frameHeight * 0.60f; + float i = step * 0.50f; + + while (i < length - step * 0.50f) { + float along = i / length; + + float fadeOut = 1f; + if (along > 0.90f) + fadeOut = MathHelper.SmoothStep(1f, 0f, (along - 0.90f) / 0.10f); + + Vector2 pos = start + dir * i; + + Main.EntitySpriteDraw(tex, pos - Main.screenPosition, midFrame, baseColor * (0.18f * fadeOut), rot, + origin, new Vector2(2.55f * pulse, 1f), SpriteEffects.None, 0); + Main.EntitySpriteDraw(tex, pos - Main.screenPosition, midFrame, baseColor * (0.32f * fadeOut), rot, + origin, new Vector2(1.85f * pulse, 1f), SpriteEffects.None, 0); + Main.EntitySpriteDraw(tex, pos - Main.screenPosition, midFrame, Color.White * (0.58f * fadeOut), rot, + origin, new Vector2(1.25f * pulse, 1f), SpriteEffects.None, 0); + + i += step; + } + + // End cap + Vector2 endPos = start + dir * length; + Main.EntitySpriteDraw( + tex, + endPos - Main.screenPosition, + endFrame, + baseColor * 1.15f, + rot, + origin, + new Vector2(1.55f * pulse, 1f), + SpriteEffects.None, + 0 + ); + + Main.spriteBatch.End(); + Main.spriteBatch.Begin( + SpriteSortMode.Deferred, + BlendState.AlphaBlend, + Main.DefaultSamplerState, + DepthStencilState.None, + RasterizerState.CullNone, + null, + Main.GameViewMatrix.TransformationMatrix + ); + + return false; + } + } +} diff --git a/Content/Projectiles/EyeGuyUltimateBeam.png b/Content/Projectiles/EyeGuyUltimateBeam.png new file mode 100644 index 0000000000000000000000000000000000000000..4f5231edbc6a9beb05971d753b8e31940a32b7e2 GIT binary patch literal 418 zcmV;T0bTxyP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0XIoRK~!i%?UykQ z!ypVrbN|z2%$yTs%+?CTV{na365^JWFa5z7`>6&hWvbOY&#&NRS)z$kx}9zZ(QsYY z=xy7giJJj$2bBQ(zDG9$x`8-!36Lhw{#0JC+d*<C4~-I{RRM4}>VF1sw(;cMylHL4pro0x37p^W-)hHgf zMj9lzKhX2e$O4fcpsWG99n{}DqLBs(?g!Mb_-s#MR;$tF{_dc>kVI@4W(1Mois>rN*kJ{H)3wAHA-~mu>b%7 M07*qoM6N<$f^cZ5Bme*a literal 0 HcmV?d00001 diff --git a/Content/TransformationHandler.cs b/Content/TransformationHandler.cs index 7e3b2b3..05be508 100644 --- a/Content/TransformationHandler.cs +++ b/Content/TransformationHandler.cs @@ -73,12 +73,13 @@ public static void Detransform(Player player, int seconds, bool showParticles = player.ClearBuff(ModContent.BuffType()); player.ClearBuff(ModContent.BuffType()); player.ClearBuff(ModContent.BuffType()); + player.ClearBuff(ModContent.BuffType()); - player.ClearBuff(ModContent.BuffType()); - player.ClearBuff(ModContent.BuffType()); - player.ClearBuff(ModContent.BuffType()); - player.ClearBuff(ModContent.BuffType()); - player.ClearBuff(ModContent.BuffType()); + // player.ClearBuff(ModContent.BuffType()); + // player.ClearBuff(ModContent.BuffType()); + // player.ClearBuff(ModContent.BuffType()); + // player.ClearBuff(ModContent.BuffType()); + // player.ClearBuff(ModContent.BuffType()); player.GetModPlayer().currTransformation = TransformationEnum.None; diff --git a/Content/Transformations/EyeGuy/EyeGuy.cs b/Content/Transformations/EyeGuy/EyeGuy.cs new file mode 100644 index 0000000..a69e445 --- /dev/null +++ b/Content/Transformations/EyeGuy/EyeGuy.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Terraria.ID; +using Terraria; +using Terraria.ModLoader; +using Ben10Mod.Enums; + +namespace Ben10Mod.Content.Transformations.EyeGuy +{ + public class EyeGuy : ModItem { + public override void Load() { + // The code below runs only if we're not loading on a server + if (Main.netMode == NetmodeID.Server) + return; + + // Add equip textures + EquipLoader.AddEquipTexture(Mod, $"{Texture}_{EquipType.Head}", EquipType.Head, this, equipTexture: new XLR8Head()); + EquipLoader.AddEquipTexture(Mod, $"{Texture}_{EquipType.Body}", EquipType.Body, this); + EquipLoader.AddEquipTexture(Mod, $"{Texture}_{EquipType.Legs}", EquipType.Legs, this); + + //Add a separate set of equip textures by providing a custom name reference instead of an item reference + //EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.Head}", EquipType.Head, name: "BlockyAlt", equipTexture: new BlockyHead()); + //EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.Body}", EquipType.Body, name: "BlockyAlt"); + //EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.Legs}", EquipType.Legs, name: "BlockyAlt"); + } + + // Called in SetStaticDefaults + private void SetupDrawing() { + // Since the equipment textures weren't loaded on the server, we can't have this code running server-side + if (Main.netMode == NetmodeID.Server) + return; + + int equipSlotHead = EquipLoader.GetEquipSlot(Mod, Name, EquipType.Head); + int equipSlotBody = EquipLoader.GetEquipSlot(Mod, Name, EquipType.Body); + int equipSlotLegs = EquipLoader.GetEquipSlot(Mod, Name, EquipType.Legs); + + //int equipSlotHeadAlt = EquipLoader.GetEquipSlot(Mod, "BlockyAlt", EquipType.Head); + //int equipSlotBodyAlt = EquipLoader.GetEquipSlot(Mod, "BlockyAlt", EquipType.Body); + //int equipSlotLegsAlt = EquipLoader.GetEquipSlot(Mod, "BlockyAlt", EquipType.Legs); + + ArmorIDs.Head.Sets.DrawHead[equipSlotHead] = false; + //ArmorIDs.Head.Sets.DrawHead[equipSlotHeadAlt] = false; + ArmorIDs.Body.Sets.HidesTopSkin[equipSlotBody] = true; + ArmorIDs.Body.Sets.HidesArms[equipSlotBody] = true; + //ArmorIDs.Body.Sets.HidesTopSkin[equipSlotBodyAlt] = true; + //ArmorIDs.Body.Sets.HidesArms[equipSlotBodyAlt] = true; + ArmorIDs.Legs.Sets.HidesBottomSkin[equipSlotLegs] = true; + //ArmorIDs.Legs.Sets.HidesBottomSkin[equipSlotLegsAlt] = true; + } + + public override void SetStaticDefaults() { + SetupDrawing(); + } + + public override void SetDefaults() { + Item.width = 40; + Item.height = 80; + Item.useAnimation = 30; + Item.useTime = 30; + Item.useStyle = ItemUseStyleID.HiddenAnimation; + Item.consumable = true; + } + + public override bool CanUseItem(Player player) => !TransformationHandler.HasTransformation(player, TransformationEnum.EyeGuy); + + public override bool? UseItem(Player player) { + player.GetModPlayer().unlockedTransformation.Add(TransformationEnum.EyeGuy); + return true; + } + } + + public class XLR8Head : EquipTexture { + public override bool IsVanitySet(int head, int body, int legs) => true; + } +} diff --git a/Content/Transformations/EyeGuy/EyeGuy.png b/Content/Transformations/EyeGuy/EyeGuy.png new file mode 100644 index 0000000000000000000000000000000000000000..2394e29ec5129e51083c1f704c9669c6db9269f9 GIT binary patch literal 745 zcmVPx%qe(Fbsu!t}{ml$hq?dPU%r}EKe zYL^p`^S*1fp(r6PwV$%(C?Y?FxYVyyfJ$BqnHt2U{#<}1bX=aVNnEnyeFCE`accdY zgE+N^?}1@O8P#jNnxXRM%!ymrzCX@NoPxi|aD0hdj9s&khyz^Cp*-H_Bre&Ph$FWU z+H>(z`4{j{{)AyTg*hgOnm_tBnzptH#%`s0qNgkR4>p_LXHDTuvP)ZyiK^~7`Joak}ND;Rr zsEU@#8Um(x98tW^PZ3aqI6#KH7CO?vRsj~`)|}>*e2iUVNl9>c1bB#RW4Tfv){L%1 zkir`(mT?~^V@4V#1pwI7A>L525(jXuHq@|p4ot}sYk0i;Jn49!HzUNrecnkCL+0DS z5ZdG=a?S>ZnB_Lmbd`yQ=DLSPSiDW)xI6c>u(RLe?|hJXW;(KS06e2 b#P>E|0p$^yRj}8i00000NkvXXu0mjfrl(t1 literal 0 HcmV?d00001 diff --git a/Content/Transformations/EyeGuy/EyeGuy_Body.png b/Content/Transformations/EyeGuy/EyeGuy_Body.png new file mode 100644 index 0000000000000000000000000000000000000000..5c66233e5f351fca11279b217282ac0630348c1c GIT binary patch literal 4194 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 gtUdPsSvB@XMIOKY`GUD<-qo;#PAdxCa?_dLB z1c^@`2pS+DC4iA4JZbma9(KS{6%d|Dif;x!SOKbCX+9XB9*P;Wlu`i$Cib7zrQjlf z4-cT}hhP%}psdlSEWTonN4@rbrH3n$yP75A1~E6oHuNxNkT5YZKG=!u9I4D-s$Yd~ zhvXyLW-fV~hf`6}zdV2&S$$N3y}$pf*DQ6)%RAr-9eZZ?`dWY?Y1HhC`gZU;0f$+! z#X4$ZC7|sId?;0M?&FJ|(E<*I5qwWa?#tu>9@O4E%Wt8kQlX9`l7Bu1g$_B(Ot~oR z-(lU=m<*V#+Nu_Lv*W=(YLfjn!>98D_XNY~pi_`M%;nW5o?!>{5h^;DF|?d5DrG5Z ze(NG3Oebv;Z=4(W z7B~h|^*hF?T-qFW?=-z?{>Ty-9Ech-98(|TaAjW-s09t(ZH)o9-Ju##=fbbxWyeJ% zl2TunO$M*tVyJKLLmmC5N8p6Vqpc(b9NFw+HKd{iOiYg|9z#klNNWo83bcUY;?<lLLqnvR{+v(&S~TOXDtNS!geArpB|LOx&SSdBC`-QTRtbjYmZ5vY-S zID5gIPnM_i>y%)SRx=ib)jO46SZ-%2zmzFwe#l$4B-hSH$EMjN!mPxOw_JH3urjG7 z*4bL$@P(;(A)%y#r0DDF%wlCdY6>%j8MRtPnw9liea>GGZ%HAfUoe83piiKSiMEXn z+z3HArE`@Cf4i32byr+9vU;IJ&n+T72uD+!uIhS+=!6`DxQgU=sbkHtpCC~X&&vI0 zVPspfC7HMKN#%WnMAZSZqZU6w=j@MBt^h=AYKGhv14L=OFp2aC!4B11i!m5_!DF^fu#x3>J#~ohu->~^G zk5mceXw9Yc9w846@-x?ZxqrE@Kvh*M+q1r_uzivs^*YTn8~L1E-xD}s`c97Mn|vmZ zB<|U$_C}i=-g+%@^?7oIS;{ZY8J9BNlpZRLDZOp^tK~9|)T8%S^ubviMe}%e@Z0{L zFq~V{38lkIc1jSXTIZrH>n!Q+^I4Ssm44UKkhgvq#STQ z&(*uuUyMJM@T~8>5Y_=VXR^KTL$!RxCLCY2EBKI{+>P=fr!vs*IXA4 zKeBT8i#pwWO?P2qY;@3Np7L40_xiN*bpC2PYC8&pYC(}vvkV7@!HUL;#cI_Wcq44x zZ2^4@kPr~A*C|x7J)S1vD5S019WmJFw0QDyVP_$xFtJ^D_*K-0^iGb=5!>5k8B zA84YXulwh$_gfyN9y}d4_aBc>ymc-Cj;X)xC`dZ+OOmUA6Zorc7pzide(7+N4o&9@ zsfz?6X^}pu8K{-0?KJ$&iV#y5UnUEd|vsf zlCr|hmoYCt(x9Oendmh?PukD5f@Sw8Ib1o!oEy+cqyeJRxurZL(4sS|v}U2k*v0LN zOZ}o9&S*G)F>{f&xHH{8tprO6MUJczq@NU(^|dy7lzr*lfV~L=g`S^SY;L`o+M7?+ zU;cvmGCnfs9Ue3Ii;qA+>n)&MP_KQ(e@}E!Lm}7YNPR}SLeL@OamagqA@D_l@u5ygy`!rh1TEncDYY6d#Z!WPesR2G?H?JL^ z?Ilt~=qq&0Qq`DBWZ_QXyw6$zcr$O)hL5p7#2^I~9+n1YtlwX78|N3%D}qD7gW%c- zt;PS77WpfdBvi literal 0 HcmV?d00001 diff --git a/Content/Transformations/EyeGuy/EyeGuy_Legs.png b/Content/Transformations/EyeGuy/EyeGuy_Legs.png new file mode 100644 index 0000000000000000000000000000000000000000..095b404c88aea16746c1c8582b10ddc6a4bf885c GIT binary patch literal 4217 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 HI7R*oH(ud| literal 0 HcmV?d00001 diff --git a/Enums/TranformationEnum.cs b/Enums/TranformationEnum.cs index 7984744..1466bb0 100644 --- a/Enums/TranformationEnum.cs +++ b/Enums/TranformationEnum.cs @@ -25,7 +25,8 @@ public enum TransformationEnum { RipJaws = 8, StinkFly = 9, WildVine = 10, - XLR8 = 11 + XLR8 = 11, + EyeGuy = 12, } static class TransformationMethods { @@ -51,6 +52,8 @@ public static int GetTransformation(this TransformationEnum te) { return ModContent.BuffType(); case TransformationEnum.XLR8: return ModContent.BuffType(); + case TransformationEnum.EyeGuy: + return ModContent.BuffType(); default: return -1; } } @@ -77,6 +80,8 @@ public static string GetName(this TransformationEnum te) { return "Wildvine"; case TransformationEnum.XLR8: return "XLR8"; + case TransformationEnum.EyeGuy: + return "Eye Guy"; default: return "None"; } @@ -102,11 +107,54 @@ public static ReLogic.Content.Asset GetTransformationIcon(this Transf return ModContent.Request("Ben10Mod/Content/Interface/EmptyAlien"); case TransformationEnum.WildVine: return ModContent.Request("Ben10Mod/Content/Interface/EmptyAlien"); + case TransformationEnum.EyeGuy: + return ModContent.Request("Ben10Mod/Content/Interface/EmptyAlien"); case TransformationEnum.XLR8: return ModContent.Request("Ben10Mod/Content/Interface/XLR8Select"); default: return ModContent.Request("Ben10Mod/Content/Interface/EmptyAlien"); } } + + public static string GetDescription(this TransformationEnum trans) + { + return trans switch + { + TransformationEnum.None => "No alien selected. Choose one from the Omnitrix!", + + TransformationEnum.HeatBlast => "A fiery Pyronite from the blazing star Pyros. A living inferno of plasma wrapped in molten rock.", + + TransformationEnum.DiamondHead => "A crystalline Petrosapien from the shattered planet Petropia. Body forged from unbreakable diamond-like crystal.", + + TransformationEnum.XLR8 => "A lightning-fast Kineceleran from the planet Kinet. Built like a velociraptor and engineered for pure speed.", + + TransformationEnum.ChromaStone => "A radiant Crystalsapien from Petropia. Living energy crystal that absorbs and unleashes raw power.", + + TransformationEnum.FourArms => "A mighty Tetramand from the harsh desert world Khoros. Four powerful arms of raw, unstoppable strength.", + + TransformationEnum.BuzzShock => "A hyper-charged Nosedeenian from the Nosideen Quasar. Electric plasma being that crackles with limitless energy.", + + TransformationEnum.RipJaws => "A ferocious Piscciss Volann from the ocean planet Piscciss. Aquatic predator with razor-sharp jaws and gills.", + + TransformationEnum.GhostFreak => "A terrifying Ectonurite from the nightmare dimension Anur Phaetos. Intangible phantom that haunts the darkness.", + + TransformationEnum.WildVine => "A versatile Florauna from the lush planet Flors Verdance. Living plant with stretching vines and natural camouflage.", + + TransformationEnum.StinkFly => "A winged Lepidopterran from the insect world Lepidopterra. Acid-spitting flyer with a signature pungent aroma.", + + _ => "A mysterious alien from the Omnitrix database." + }; + } + + public static List GetAbilities(this TransformationEnum trans) + { + return trans switch + { + TransformationEnum.None => new List { "None" }, + TransformationEnum.HeatBlast => new List { "Flamethrower blast", "Flight via Propulsion", "Heat Immunity", "Explosive Fireballs" }, + // ← Add real abilities for every alien (this is where the fun Ben 10 flavor goes!) + _ => new List { "Unknown abilities" } + }; + } } } diff --git a/Keybinds/KeybindSystem.cs b/Keybinds/KeybindSystem.cs index 2e32bde..ea1a398 100644 --- a/Keybinds/KeybindSystem.cs +++ b/Keybinds/KeybindSystem.cs @@ -11,7 +11,7 @@ public class KeybindSystem : ModSystem { public static ModKeybind SecondaryAbility { get; private set; } public static ModKeybind TertiaryAbility { get; private set; } public static ModKeybind QuaternaryAbility { get; private set; } - public static ModKeybind QuinaryAbility { get; private set; } + public static ModKeybind UltimateAbility { get; private set; } public static ModKeybind TransformationKeybind { get; private set; } public static ModKeybind OpenTransformationScreen { get; private set; } public static ModKeybind AlienOneKeybind { get; private set; } @@ -27,7 +27,7 @@ public override void Load() { SecondaryAbility = KeybindLoader.RegisterKeybind(Mod, "Secondary Ability", "G"); TertiaryAbility = KeybindLoader.RegisterKeybind(Mod, "Tertiary Ability", "H"); QuaternaryAbility = KeybindLoader.RegisterKeybind(Mod, "Quaternary Ability", "J"); - QuinaryAbility = KeybindLoader.RegisterKeybind(Mod, "Quinary Ability", "K"); + UltimateAbility = KeybindLoader.RegisterKeybind(Mod, "Ultimate Ability", "U"); TransformationKeybind = KeybindLoader.RegisterKeybind(Mod, "Transform", "P"); OpenTransformationScreen = KeybindLoader.RegisterKeybind(Mod, "Open Menu", "L"); AlienOneKeybind = KeybindLoader.RegisterKeybind(Mod, "Alien One", "NumPad1"); diff --git a/Localization/en-US_Mods.Ben10Mod.hjson b/Localization/en-US_Mods.Ben10Mod.hjson index eb42c52..c110fe5 100644 --- a/Localization/en-US_Mods.Ben10Mod.hjson +++ b/Localization/en-US_Mods.Ben10Mod.hjson @@ -185,6 +185,16 @@ Items: { Tooltip: "" DisplayName: Master Control Key } + + EyeGuy: { + Tooltip: "" + DisplayName: Eye Guy + } + + HeroEmblem: { + Tooltip: "" + DisplayName: Hero Emblem + } } Keybinds: { @@ -208,6 +218,7 @@ Keybinds: { "Quinary Ability.DisplayName": Quinary Ability "Quaternary Ability.DisplayName": Quaternary Ability "Tertiary Ability.DisplayName": Tertiary Ability + "Ultimate Ability.DisplayName": Ultimate Ability } Buffs: { @@ -325,6 +336,16 @@ Buffs: { DisplayName: Ghost Freak Possesion Description: Mods.Ben10Mod.Buffs.GhostFreakPossesion.Description } + + EyeGuy_Buff: { + Description: Mods.Ben10Mod.Buffs.EyeGuy_Buff.Description + DisplayName: Eye Guy_ Buff + } + + UltimateAbility_Cooldown: { + DisplayName: Ultimate Ability_ Cooldown + Description: Mods.Ben10Mod.Buffs.UltimateAbility_Cooldown.Description + } } Projectiles: { @@ -347,6 +368,8 @@ Projectiles: { StinkFlySlowProjectile.DisplayName: Stink Fly Slow Projectile StinkFlyPoisonProjectile.DisplayName: Stink Fly Poison Projectile GhostFreakPossesionProjectile.DisplayName: Ghost Freak Possesion Projectile + EyeGuyLaserbeam.DisplayName: Eye Guy Laserbeam + EyeGuyUltimateBeam.DisplayName: Eye Guy Ultimate Beam } Tiles: { diff --git a/OmnitrixPlayer.cs b/OmnitrixPlayer.cs index 97f4dd5..f3eee82 100644 --- a/OmnitrixPlayer.cs +++ b/OmnitrixPlayer.cs @@ -4,6 +4,7 @@ using Microsoft.Xna.Framework; using System.Collections.Generic; using System.CommandLine.Help; +using System.Linq; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -34,6 +35,7 @@ using Ben10Mod.Content.Buffs.Abilities.BuzzShock; using Ben10Mod.Content.Buffs.Transformations; using Ben10Mod.Content.Items.Accessories.Wings; +using Ben10Mod.Content.Transformations.EyeGuy; using Microsoft.Xna.Framework.Input; using Terraria.Graphics.Effects; @@ -48,6 +50,7 @@ public class OmnitrixPlayer : ModPlayer { public bool wasTransformed = false; public bool onCooldown = false; public bool altAttack = false; + public bool ultimateAttack = false; public bool advancedCircuitMatrix = false; public bool advancedCircuitMatrixEquippedWhileTransformed = false; @@ -84,8 +87,11 @@ public class OmnitrixPlayer : ModPlayer { public TransformationEnum[] transformations = { TransformationEnum.HeatBlast, TransformationEnum.HeatBlast, TransformationEnum.HeatBlast, TransformationEnum.HeatBlast, TransformationEnum.HeatBlast }; public TransformationEnum currTransformation = TransformationEnum.None; - - public List unlockedTransformation = new List() {TransformationEnum.HeatBlast}; + public List unlockedTransformation = new List() { TransformationEnum.HeatBlast }; + + public float omnitrixEnergy = 0f; + public float omnitrixEnergyMax = 0f; + public float omnitrixEnergyRegen = 0f; // Rainbow effect public Color[] colours = { Color.White, Color.LightPink, Color.Pink, Color.OrangeRed, Color.LightBlue, Color.Cyan, Color.LightGreen, Color.YellowGreen, Color.LightYellow, Color.Yellow }; @@ -103,47 +109,58 @@ public Color GetChromaStoneOverlayColor() { return Color.Lerp(colours[thisColour], colours[nextColour], colourAmount); } - - public override void SaveData(TagCompound tag) { + + public override void SaveData(TagCompound tag) + { if (Player.whoAmI != Main.myPlayer) return; - tag["masterControl"] = masterControl; - int[] temp = new int[transformations.Length]; - for (int i = 0; i < temp.Length; i++) { - temp[i] = (int)transformations[i]; - } - tag["roster"] = temp; - int[] tempList = new int[unlockedTransformation.Count]; - for (int i = 0; i < tempList.Length; i++) { - tempList[i] = (int)unlockedTransformation[i]; - } - tag["unlockedRoster"] = tempList; + + tag["masterControl"] = masterControl; tag["currTransformation"] = (int)currTransformation; + + // Roster (5 slots) + tag["roster"] = transformations.Select(t => (int)t).ToArray(); + + // Unlocked aliens + tag["unlockedRoster"] = unlockedTransformation + .Where(t => t != TransformationEnum.None) + .Select(t => (int)t) + .ToArray(); } - public override void LoadData(TagCompound tag) { + public override void LoadData(TagCompound tag) + { if (Player.whoAmI != Main.myPlayer) return; - int[] temp = null; - if (tag.TryGet("roster", out temp)) { - if (temp != null) { - for (int i = 0; i < temp.Length; i++) { - transformations[i] = (TransformationEnum)temp[i]; - } + + tag.TryGet("masterControl", out masterControl); + + int currInt = -1; + tag.TryGet("currTransformation", out currInt); + currTransformation = (TransformationEnum)currInt; + + // Load roster + if (tag.TryGet("roster", out int[] rosterArray) && rosterArray != null) + { + for (int i = 0; i < Math.Min(rosterArray.Length, transformations.Length); i++) + { + transformations[i] = (TransformationEnum)rosterArray[i]; } } - int[] tempList = null; - if (tag.TryGet("unlockedRoster", out tempList)) { - if (tempList != null) { - for (int i = 0; i < tempList.Length; i++) { - if (!TransformationHandler.HasTransformation(Player, (TransformationEnum)tempList[i])) { - unlockedTransformation.Add((TransformationEnum)tempList[i]); - } - } + + // Load unlocked (clears old duplicates automatically) + unlockedTransformation.Clear(); + if (tag.TryGet("unlockedRoster", out int[] unlockedArray) && unlockedArray != null) + { + foreach (int id in unlockedArray) + { + var trans = (TransformationEnum)id; + if (trans != TransformationEnum.None && !unlockedTransformation.Contains(trans)) + unlockedTransformation.Add(trans); } } - int tempInt = -1; - tag.TryGet("currTransformation", out tempInt); - currTransformation = (TransformationEnum)tempInt; - tag.TryGet("masterControl", out masterControl); + + // Safety: always have HeatBlast + if (!unlockedTransformation.Contains(TransformationEnum.HeatBlast)) + unlockedTransformation.Insert(0, TransformationEnum.HeatBlast); } @@ -151,8 +168,10 @@ public override void ResetEffects() { if (Player.whoAmI != Main.myPlayer) return; advancedCircuitMatrix = false; - cooldownTime = 120; - transformationTime = 300; + cooldownTime = 120; + transformationTime = 300; + omnitrixEnergyMax = 0; + omnitrixEnergyRegen = 0; // Transformations isTransformed = false; @@ -318,6 +337,23 @@ public override void PostUpdate() { if (!isTransformed) { abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } + + omnitrixEnergy += (omnitrixEnergyRegen / 120); + + if (omnitrixEnergy > omnitrixEnergyMax) omnitrixEnergy = omnitrixEnergyMax; + + if (isTransformed) { + if (KeybindSystem.UltimateAbility.JustPressed) + if (!Player.HasBuff()) { + for (int i = 0; i < 50; i++) + { + Dust d = Dust.NewDustPerfect(Player.Center + Main.rand.NextVector2Circular(20f, 20f), + ultimateAttack ? DustID.Firework_Yellow : DustID.Firework_Blue, Main.rand.NextVector2Circular(6f, 6f), Scale: Main.rand.NextFloat(1.5f, 2.5f)); + d.noGravity = true; + } + ultimateAttack = !ultimateAttack; + } + } // XLR8 Transformation @@ -617,16 +653,14 @@ public override void ModifyDrawInfo(ref PlayerDrawSet drawInfo) { drawInfo.colorArmorLegs = overlayColor; break; case TransformationEnum.DiamondHead: - break; case TransformationEnum.FourArms: case TransformationEnum.RipJaws: case TransformationEnum.StinkFly: case TransformationEnum.WildVine: case TransformationEnum.XLR8: + case TransformationEnum.EyeGuy: case TransformationEnum.None: break; - default: - throw new ArgumentOutOfRangeException(); } } @@ -793,6 +827,13 @@ public override void FrameEffects() { Player.back = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Back); Player.armorEffectDrawShadow = true; } + + if (currTransformation == TransformationEnum.EyeGuy) { + var costume = ModContent.GetInstance(); + Player.head = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Head); + Player.body = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Body); + Player.legs = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Legs); + } } } @@ -912,6 +953,9 @@ public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { addTransformation(TransformationEnum.RipJaws); } } + + if (isTransformed && !ultimateAttack && omnitrixEnergyRegen == 0) + omnitrixEnergy += Math.Max(hit.Damage / 25, 1); } public override void PreUpdate() { diff --git a/ShopNPC.cs b/ShopNPC.cs index 7975f7f..7b8c7b2 100644 --- a/ShopNPC.cs +++ b/ShopNPC.cs @@ -1,3 +1,4 @@ +using System.Linq; using Ben10Mod.Content.Items.Accessories; using Ben10Mod.Content.Items.Consumable; using Ben10Mod.Content.Items.Vanity; @@ -22,9 +23,26 @@ public override void ModifyShop(NPCShop shop) { public override void ModifyNPCLoot(NPC npc, NPCLoot npcLoot) { if (npc.type == NPCID.Plantera) { - if (Main.expertMode) { - npcLoot.Add(ItemDropRule.BossBag(ModContent.ItemType())); - } + npcLoot.Add(ItemDropRule.ByCondition(new Conditions.IsExpert(), + ModContent.ItemType(), + 10 + )); + } + + if (npc.type == NPCID.WallofFlesh) { + // Remove the original vanilla emblem rule + npcLoot.RemoveWhere(rule => rule is OneFromOptionsNotScaledWithLuckDropRule optionsRule + && optionsRule.dropIds != null + && optionsRule.dropIds.Contains(ItemID.WarriorEmblem)); + + // New pool: 4 vanilla emblems + your HeroEmblem (equal chance) + npcLoot.Add(ItemDropRule.OneFromOptionsNotScalingWithLuck(1, + ItemID.WarriorEmblem, + ItemID.RangerEmblem, + ItemID.SorcererEmblem, + ItemID.SummonerEmblem, + ModContent.ItemType() + )); } } } \ No newline at end of file diff --git a/build.txt b/build.txt index 90b957e..65a1ff7 100644 --- a/build.txt +++ b/build.txt @@ -1,3 +1,3 @@ displayName = Terraria 10 (Ben 10 mod) author = DestroyerMob -version = 0.066 \ No newline at end of file +version = 0.069 \ No newline at end of file From 508cb3857fa07e6270ff39e7457c306d2b29d812 Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Fri, 27 Feb 2026 07:21:54 +1100 Subject: [PATCH 06/25] Fixed ghostfreak's phasing ability. Changed the ability system to use a single buff, ability use is kept track using an enum variable instead of multiple booleans and buffs. --- Ben10Mod.cs | 28 ++ .../CustomVisuals/DiamondHeadShimmerLayer.cs | 2 +- .../BuzzShock/BuzzShock_Primary_Buff.cs | 23 -- .../BuzzShock/BuzzShock_Primary_Buff.png | Bin 3071 -> 0 bytes .../BuzzShock_Primary_Cooldown_Buff.cs | 25 -- .../BuzzShock_Primary_Cooldown_Buff.png | Bin 3071 -> 0 bytes .../ChromaStone/ChromaStone_Primary_Buff.cs | 23 -- .../ChromaStone/ChromaStone_Primary_Buff.png | Bin 3071 -> 0 bytes .../ChromaStone_Primary_Cooldown_Buff.cs | 18 -- .../ChromaStone_Primary_Cooldown_Buff.png | Bin 3071 -> 0 bytes .../DiamondHead/DiamondHead_Primary_Buff.cs | 23 -- .../DiamondHead/DiamondHead_Primary_Buff.png | Bin 3071 -> 0 bytes .../DiamondHead_Primary_Cooldown_Buff.cs | 18 -- .../DiamondHead_Primary_Cooldown_Buff.png | Bin 3071 -> 0 bytes .../HeatBlast/HeatBlast_Primary_Buff.cs | 23 -- .../HeatBlast/HeatBlast_Primary_Buff.png | Bin 3071 -> 0 bytes .../HeatBlast_Primary_Cooldown_Buff.cs | 18 -- .../HeatBlast_Primary_Cooldown_Buff.png | Bin 3071 -> 0 bytes Content/Buffs/Abilities/PrimaryAbility.cs | 15 + Content/Buffs/Abilities/PrimaryAbility.png | Bin 0 -> 3008 bytes .../Buffs/Abilities/PrimaryAbilityCooldown.cs | 7 + .../Abilities/PrimaryAbilityCooldown.png | Bin 0 -> 3004 bytes .../Buffs/Abilities/XLR8/XLR8_Primary_Buff.cs | 23 -- .../Abilities/XLR8/XLR8_Primary_Buff.png | Bin 3071 -> 0 bytes .../XLR8/XLR8_Primary_Cooldown_Buff.cs | 25 -- .../XLR8/XLR8_Primary_Cooldown_Buff.png | Bin 3071 -> 0 bytes .../Buffs/Transformations/OmnitrixUpdating.cs | 23 ++ .../Transformations/OmnitrixUpdating.png | Bin 0 -> 2767 bytes Content/Interface/OmnitrixSlot.cs | 2 +- Content/Items/Accessories/Omnitrix.cs | 23 -- .../Items/Accessories/PrototypeOmnitrix.cs | 23 +- .../Accessories/PrototypeOmnitrixUpdating.png | Bin 0 -> 797 bytes .../PrototypeOmnitrixUpdating_HandsOn.png | Bin 0 -> 1237 bytes .../Items/Accessories/RecalibratedOmnitrix.cs | 23 +- Content/Items/Consumable/MasterControlKey.png | Bin 148 -> 224 bytes Content/TransformationHandler.cs | 12 +- Localization/en-US_Mods.Ben10Mod.hjson | 15 + OmnitrixPlayer.cs | 295 ++++++++++-------- bossTrackerNPC.cs | 77 ++--- 39 files changed, 307 insertions(+), 457 deletions(-) delete mode 100644 Content/Buffs/Abilities/BuzzShock/BuzzShock_Primary_Buff.cs delete mode 100644 Content/Buffs/Abilities/BuzzShock/BuzzShock_Primary_Buff.png delete mode 100644 Content/Buffs/Abilities/BuzzShock/BuzzShock_Primary_Cooldown_Buff.cs delete mode 100644 Content/Buffs/Abilities/BuzzShock/BuzzShock_Primary_Cooldown_Buff.png delete mode 100644 Content/Buffs/Abilities/ChromaStone/ChromaStone_Primary_Buff.cs delete mode 100644 Content/Buffs/Abilities/ChromaStone/ChromaStone_Primary_Buff.png delete mode 100644 Content/Buffs/Abilities/ChromaStone/ChromaStone_Primary_Cooldown_Buff.cs delete mode 100644 Content/Buffs/Abilities/ChromaStone/ChromaStone_Primary_Cooldown_Buff.png delete mode 100644 Content/Buffs/Abilities/DiamondHead/DiamondHead_Primary_Buff.cs delete mode 100644 Content/Buffs/Abilities/DiamondHead/DiamondHead_Primary_Buff.png delete mode 100644 Content/Buffs/Abilities/DiamondHead/DiamondHead_Primary_Cooldown_Buff.cs delete mode 100644 Content/Buffs/Abilities/DiamondHead/DiamondHead_Primary_Cooldown_Buff.png delete mode 100644 Content/Buffs/Abilities/HeatBlast/HeatBlast_Primary_Buff.cs delete mode 100644 Content/Buffs/Abilities/HeatBlast/HeatBlast_Primary_Buff.png delete mode 100644 Content/Buffs/Abilities/HeatBlast/HeatBlast_Primary_Cooldown_Buff.cs delete mode 100644 Content/Buffs/Abilities/HeatBlast/HeatBlast_Primary_Cooldown_Buff.png create mode 100644 Content/Buffs/Abilities/PrimaryAbility.cs create mode 100644 Content/Buffs/Abilities/PrimaryAbility.png create mode 100644 Content/Buffs/Abilities/PrimaryAbilityCooldown.cs create mode 100644 Content/Buffs/Abilities/PrimaryAbilityCooldown.png delete mode 100644 Content/Buffs/Abilities/XLR8/XLR8_Primary_Buff.cs delete mode 100644 Content/Buffs/Abilities/XLR8/XLR8_Primary_Buff.png delete mode 100644 Content/Buffs/Abilities/XLR8/XLR8_Primary_Cooldown_Buff.cs delete mode 100644 Content/Buffs/Abilities/XLR8/XLR8_Primary_Cooldown_Buff.png create mode 100644 Content/Buffs/Transformations/OmnitrixUpdating.cs create mode 100644 Content/Buffs/Transformations/OmnitrixUpdating.png create mode 100644 Content/Items/Accessories/PrototypeOmnitrixUpdating.png create mode 100644 Content/Items/Accessories/PrototypeOmnitrixUpdating_HandsOn.png diff --git a/Ben10Mod.cs b/Ben10Mod.cs index 4ef5f89..7f29ca5 100644 --- a/Ben10Mod.cs +++ b/Ben10Mod.cs @@ -1,3 +1,6 @@ +using System.IO; +using Ben10Mod.Enums; +using Terraria; using Terraria.ModLoader; namespace Ben10Mod @@ -7,5 +10,30 @@ public class Ben10Mod : Mod public override void Load() { } + + // Add this enum anywhere in the class (or in a separate file) + public enum MessageType : byte + { + UnlockTransformation + } + + public override void HandlePacket(BinaryReader reader, int whoAmI) + { + MessageType msgType = (MessageType)reader.ReadByte(); + + switch (msgType) + { + case MessageType.UnlockTransformation: + int playerIndex = reader.ReadByte(); + TransformationEnum transformation = (TransformationEnum)reader.ReadInt32(); + + if (playerIndex >= 0 && playerIndex < Main.maxPlayers) + { + var modPlayer = Main.player[playerIndex].GetModPlayer(); + modPlayer.addTransformation(transformation); // client will apply it locally + } + break; + } + } } } \ No newline at end of file diff --git a/Common/CustomVisuals/DiamondHeadShimmerLayer.cs b/Common/CustomVisuals/DiamondHeadShimmerLayer.cs index c5fdbbe..16244f7 100644 --- a/Common/CustomVisuals/DiamondHeadShimmerLayer.cs +++ b/Common/CustomVisuals/DiamondHeadShimmerLayer.cs @@ -15,7 +15,7 @@ public override bool GetDefaultVisibility(PlayerDrawSet drawInfo) { Player player = drawInfo.drawPlayer; var omp = player.GetModPlayer(); - return omp.currTransformation == TransformationEnum.DiamondHead && omp.DiamondHeadPrimaryAbilityEnabled; + return omp.currTransformation == TransformationEnum.DiamondHead && omp.PrimaryAbilityEnabled; } // Position after armor/body diff --git a/Content/Buffs/Abilities/BuzzShock/BuzzShock_Primary_Buff.cs b/Content/Buffs/Abilities/BuzzShock/BuzzShock_Primary_Buff.cs deleted file mode 100644 index ded10af..0000000 --- a/Content/Buffs/Abilities/BuzzShock/BuzzShock_Primary_Buff.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; - -namespace Ben10Mod.Content.Buffs.Abilities.BuzzShock -{ - public class BuzzShock_Primary_Buff : ModBuff - { - public override void Update(Player player, ref int buffIndex) - { - OmnitrixPlayer p = player.GetModPlayer(); - p.BuzzShockPrimaryAbilityEnabled = true; - p.BuzzShockPrimaryAbilityWasEnabled = true; - } - - public override bool RightClick(int buffIndex) => false; - } -} diff --git a/Content/Buffs/Abilities/BuzzShock/BuzzShock_Primary_Buff.png b/Content/Buffs/Abilities/BuzzShock/BuzzShock_Primary_Buff.png deleted file mode 100644 index 18d9f697f32a7d6bea17b7333a0351cf9e3a641a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3071 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 N002ovPDHLkV1kN{to8r^ diff --git a/Content/Buffs/Abilities/BuzzShock/BuzzShock_Primary_Cooldown_Buff.cs b/Content/Buffs/Abilities/BuzzShock/BuzzShock_Primary_Cooldown_Buff.cs deleted file mode 100644 index b1d2b62..0000000 --- a/Content/Buffs/Abilities/BuzzShock/BuzzShock_Primary_Cooldown_Buff.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Terraria; -using Terraria.Audio; -using Terraria.ID; -using Terraria.ModLoader; - -namespace Ben10Mod.Content.Buffs.Abilities.BuzzShock -{ - public class BuzzShock_Primary_Cooldown_Buff : ModBuff - { - public override bool RightClick(int buffIndex) { - return false; - } - - public override void Update(Player player, ref int buffIndex) { - if (player.buffTime[player.FindBuffIndex(ModContent.BuffType())] == 1) { - SoundEngine.PlaySound(SoundID.MenuTick, player.position); - } - } - } -} diff --git a/Content/Buffs/Abilities/BuzzShock/BuzzShock_Primary_Cooldown_Buff.png b/Content/Buffs/Abilities/BuzzShock/BuzzShock_Primary_Cooldown_Buff.png deleted file mode 100644 index 18d9f697f32a7d6bea17b7333a0351cf9e3a641a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3071 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 N002ovPDHLkV1kN{to8r^ diff --git a/Content/Buffs/Abilities/ChromaStone/ChromaStone_Primary_Buff.cs b/Content/Buffs/Abilities/ChromaStone/ChromaStone_Primary_Buff.cs deleted file mode 100644 index acd5613..0000000 --- a/Content/Buffs/Abilities/ChromaStone/ChromaStone_Primary_Buff.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; - -namespace Ben10Mod.Content.Buffs.Abilities.ChromaStone -{ - public class ChromaStone_Primary_Buff : ModBuff - { - public override void Update(Player player, ref int buffIndex) - { - OmnitrixPlayer p = player.GetModPlayer(); - p.ChromaStonePrimaryAbilityEnabled = true; - p.ChromaStonePrimaryAbilityWasEnabled = true; - } - - public override bool RightClick(int buffIndex) => false; - } -} diff --git a/Content/Buffs/Abilities/ChromaStone/ChromaStone_Primary_Buff.png b/Content/Buffs/Abilities/ChromaStone/ChromaStone_Primary_Buff.png deleted file mode 100644 index 18d9f697f32a7d6bea17b7333a0351cf9e3a641a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3071 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 N002ovPDHLkV1kN{to8r^ diff --git a/Content/Buffs/Abilities/ChromaStone/ChromaStone_Primary_Cooldown_Buff.cs b/Content/Buffs/Abilities/ChromaStone/ChromaStone_Primary_Cooldown_Buff.cs deleted file mode 100644 index 30e521f..0000000 --- a/Content/Buffs/Abilities/ChromaStone/ChromaStone_Primary_Cooldown_Buff.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; - -namespace Ben10Mod.Content.Buffs.Abilities.ChromaStone -{ - public class ChromaStone_Primary_Cooldown_Buff : ModBuff - { - public override bool RightClick(int buffIndex) { - return false; - } - } -} diff --git a/Content/Buffs/Abilities/ChromaStone/ChromaStone_Primary_Cooldown_Buff.png b/Content/Buffs/Abilities/ChromaStone/ChromaStone_Primary_Cooldown_Buff.png deleted file mode 100644 index 18d9f697f32a7d6bea17b7333a0351cf9e3a641a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3071 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 N002ovPDHLkV1kN{to8r^ diff --git a/Content/Buffs/Abilities/DiamondHead/DiamondHead_Primary_Buff.cs b/Content/Buffs/Abilities/DiamondHead/DiamondHead_Primary_Buff.cs deleted file mode 100644 index d7e4527..0000000 --- a/Content/Buffs/Abilities/DiamondHead/DiamondHead_Primary_Buff.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; - -namespace Ben10Mod.Content.Buffs.Abilities.DiamondHead -{ - public class DiamondHead_Primary_Buff : ModBuff - { - public override void Update(Player player, ref int buffIndex) - { - OmnitrixPlayer p = player.GetModPlayer(); - p.DiamondHeadPrimaryAbilityEnabled = true; - p.DiamondHeadPrimaryAbilityWasEnabled = true; - } - - public override bool RightClick(int buffIndex) => false; - } -} diff --git a/Content/Buffs/Abilities/DiamondHead/DiamondHead_Primary_Buff.png b/Content/Buffs/Abilities/DiamondHead/DiamondHead_Primary_Buff.png deleted file mode 100644 index 18d9f697f32a7d6bea17b7333a0351cf9e3a641a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3071 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 N002ovPDHLkV1kN{to8r^ diff --git a/Content/Buffs/Abilities/DiamondHead/DiamondHead_Primary_Cooldown_Buff.cs b/Content/Buffs/Abilities/DiamondHead/DiamondHead_Primary_Cooldown_Buff.cs deleted file mode 100644 index 80bb8d7..0000000 --- a/Content/Buffs/Abilities/DiamondHead/DiamondHead_Primary_Cooldown_Buff.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; - -namespace Ben10Mod.Content.Buffs.Abilities.DiamondHead -{ - public class DiamondHead_Primary_Cooldown_Buff : ModBuff - { - public override bool RightClick(int buffIndex) { - return false; - } - } -} diff --git a/Content/Buffs/Abilities/DiamondHead/DiamondHead_Primary_Cooldown_Buff.png b/Content/Buffs/Abilities/DiamondHead/DiamondHead_Primary_Cooldown_Buff.png deleted file mode 100644 index 18d9f697f32a7d6bea17b7333a0351cf9e3a641a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3071 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 N002ovPDHLkV1kN{to8r^ diff --git a/Content/Buffs/Abilities/HeatBlast/HeatBlast_Primary_Buff.cs b/Content/Buffs/Abilities/HeatBlast/HeatBlast_Primary_Buff.cs deleted file mode 100644 index c7c3f3c..0000000 --- a/Content/Buffs/Abilities/HeatBlast/HeatBlast_Primary_Buff.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; - -namespace Ben10Mod.Content.Buffs.Abilities.HeatBlast -{ - public class HeatBlast_Primary_Buff : ModBuff - { - public override void Update(Player player, ref int buffIndex) - { - OmnitrixPlayer p = player.GetModPlayer(); - p.HeatBlastPrimaryAbilityEnabled = true; - p.HeatBlastPrimaryAbilityWasEnabled = true; - } - - public override bool RightClick(int buffIndex) => false; - } -} diff --git a/Content/Buffs/Abilities/HeatBlast/HeatBlast_Primary_Buff.png b/Content/Buffs/Abilities/HeatBlast/HeatBlast_Primary_Buff.png deleted file mode 100644 index 18d9f697f32a7d6bea17b7333a0351cf9e3a641a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3071 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 N002ovPDHLkV1kN{to8r^ diff --git a/Content/Buffs/Abilities/HeatBlast/HeatBlast_Primary_Cooldown_Buff.cs b/Content/Buffs/Abilities/HeatBlast/HeatBlast_Primary_Cooldown_Buff.cs deleted file mode 100644 index 06b528d..0000000 --- a/Content/Buffs/Abilities/HeatBlast/HeatBlast_Primary_Cooldown_Buff.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Terraria; -using Terraria.ID; -using Terraria.ModLoader; - -namespace Ben10Mod.Content.Buffs.Abilities.HeatBlast -{ - public class HeatBlast_Primary_Cooldown_Buff : ModBuff - { - public override bool RightClick(int buffIndex) { - return false; - } - } -} diff --git a/Content/Buffs/Abilities/HeatBlast/HeatBlast_Primary_Cooldown_Buff.png b/Content/Buffs/Abilities/HeatBlast/HeatBlast_Primary_Cooldown_Buff.png deleted file mode 100644 index 18d9f697f32a7d6bea17b7333a0351cf9e3a641a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3071 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 N002ovPDHLkV1kN{to8r^ diff --git a/Content/Buffs/Abilities/PrimaryAbility.cs b/Content/Buffs/Abilities/PrimaryAbility.cs new file mode 100644 index 0000000..bddd471 --- /dev/null +++ b/Content/Buffs/Abilities/PrimaryAbility.cs @@ -0,0 +1,15 @@ +using Terraria; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Buffs.Abilities; + +public class PrimaryAbility : ModBuff { + public override void Update(Player player, ref int buffIndex) { + var omp = player.GetModPlayer(); + + omp.PrimaryAbilityEnabled = true; + omp.PrimaryAbilityWasEnabled = true; + } + + public override bool RightClick(int buffIndex) => false; +} \ No newline at end of file diff --git a/Content/Buffs/Abilities/PrimaryAbility.png b/Content/Buffs/Abilities/PrimaryAbility.png new file mode 100644 index 0000000000000000000000000000000000000000..ed8ce597139e4430d5d17430cacdb4a83480beeb GIT binary patch literal 3008 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 false; +} \ No newline at end of file diff --git a/Content/Buffs/Abilities/PrimaryAbilityCooldown.png b/Content/Buffs/Abilities/PrimaryAbilityCooldown.png new file mode 100644 index 0000000000000000000000000000000000000000..aa90062558320908fc7433e3c4dbd0e2b5adb191 GIT binary patch literal 3004 zcmV;t3q$mYP)U1G7g|CDq=eq2N(mrRLKToIO;kb> zAe0b8La`S_1xFMW5v<6lfCG*WMaGIK76wHH>;p20sN>)$qGEX~vexLDH}Ac9vwz&R z*S_c6d(S@S0?-12MdB<}1t3!_lScS^vt#4p*~BhDfeZw&1K{zqB_WZ1Q2+pezFc;8 zgugd@0Rr&4SFr-zunGucv*G`PDqkX%0U%)jFkK+b<^v!F0FaR@lPL620AMDiD>#Z% zaA|B@JOHYp;3<=Q+UJ-_?y2B{OtAm}RlHdu$P_4eI{>W9kqZR?STFz-=7@y30N70c zFv^f;iU6=Tirh>gFBZk8lp zDoRO}vCa7AY&#bh4m&`Yn<13RtipKwbe>ee=4NF|c;bA3$(lbyP2nv&(3k6E=i=mK zWp8cwl~Mn7^KU}Y+e!8^{BzF`R_7P(ui~<*061d+*rqR9(hh*;H2@lSzGy~!0h9{> zny!9T4@)sGsWO?w)y5__H`iJuYkm{b3K=N0`i$XUNzJ-}qS> zS#l{mTf*ZD*;aoZ;(wg@*YB7XAxsuZg<`&t9W4^(io_{wZkAXel8Lg!Y?1gsHSr&& z{RxwE4FHVlkHB1D4Jucefc@GDI0hB4gx!j+|IxQ#ax^G@UX0%GlVk}G_ zv%)wS7YoJWv1Ck&EyIeiGOP-#$6B!t>;~44J;UDO2sj3gjkChJ;R0}TaD3cC+%nt- zTm|kBt_jzUyMY_Pjp9Dy>3D6tCEgVuh>yjm;B)bX_%i$fd?Wrmz6U>qe@!3|SOimo zGa-NwM@SAyG+s zBzuw{DV`)Its<3?YDuR^*Ga>q39<^=nCwapB@4*; z8f7J=oKjCYPq{~VNu^Q^s4moSs))LRT24Jey+|FPzNM+rENEO>0!>caNIOV7L%U6T zNvG3I=$`a=x{SV&UPC`ee?Whu#89$U3RDs(Emx{kYErtc^jw*&Y^?01JYRW{a+&fm z<*UliRLCkODqIzw$}*KomE$UXDr2e)RXf#C)lAh5sNV|Fn|)z#D;)T7n&)GO6bs`s-nmI*76 zmBA`u9cA^h-c8Y&;x$D$W&M=;Dc7frYfRPf)DUVEX*6i`XuQ*8Yx-)YYi`zT*1WHU z)3VSC*UHt}t#w}O*;M9Kx2gQ8MN^MXy`zn4TWCjUFV^0#-KjmMqpRbuBhlHRb57@( zE=$)_H%)h|?kU|7J%-*)J(1p4z0-P6*y?OAb_Tng-Oe7>*VYfvm+SA-@6w+zFg2KC zu*#sp;JzWnkYku^xYe-DaMVc8D8y)qQJv8pW3n;FIMsN&afk7^iK$79$y$?UlgFkS zrh%r5OzTYVnbFNW%odtencXxem~+h2&3Bn!vp_8zEmAEiEv{OkmQI!;%Uzb;)9}+= zrirIjP3yCwS$SFISk+k#ShK8ytyft$TR*okvWd6ZY|~-$(bmy6!?xP?uAQ3QEW1^9 zt#-fLTiEmMEA4Mir%(5rzI=Mi^cN164nl|B4!0Z`jvo$8%NoQ<3l zop(C-ahRMi&IZm!7rcwN%W{_!E^l3(TxG6DU4L`4a!Yrsb$dL+bcS$7^^8Gx19zVL zKKK5a?3sx(_s;D1(D&eZRCzq~H1rgB9`GFYGWSaJI_&k_+typ^-RM2eb>%MQp7Fta z{C$dix_s4q=lE9mKJYW}OYy7o8})beU+jM-03Q$(usNVFP$!TdSQ9up%X!w)S?xiz zpva(#pohU0!P4N?5Hw^~$d-_MvyEqqXE%pJXkh4;(EDMgVGF~43@3z#g;$0@im;1V z644RKh+Gg^8~HlQJE|n=?i{l@@;PnM%FzkYHPPcSJ~5>+{joN&OJlFZX~l`+TH=ZE z(eVf3$L9LZ-8Oe9!7-sQp?99?yu5jr=4;K*n16DC@&ew1V~P00n8ez|_qlsl zFllGfD4)yU&VMTK6l@iY2;GIH!r^517nTd(?4azWHe-wG7~e8i`B&G;`S`vth}sliKV1a(!bDk;kJdN(je)9Y$SVLc8iQD zlgK*dX7V-ift;B+l{s&6qjQhtspg6EI`b{^*XIu}@>}%nV%%c>;LcaT5$^q1^k-VYT#qCYAd)*G&QZ2$Pgh~LPyCv%?+J(WD2cvkqU>aRPWn?3*G zH_zWXM`K5aUPxbj`hCMo&6fvXIlO8c3mbdzI`j3!c+nfpH;3MG-gdl;c{ehul#2)eDkX24 zYsCowR>u_PX*!0>-Q9_^Uc+iXJHAuHLKRsY@?A>z z@vcDT1C{9(xM4nN8^&s}GFQ09kJm<#WU~hVq@yMff&x`n2bm0-pV>Iyrg!_pQ$W3) zcr{GwDqJ_&*x$V?ko^UERvNM1RX`&wLErMOK;{Evtd(); - p.XLR8PrimaryAbilityEnabled = true; - p.XLR8PrimaryAbilityWasEnabled = true; - } - - public override bool RightClick(int buffIndex) => false; - } -} diff --git a/Content/Buffs/Abilities/XLR8/XLR8_Primary_Buff.png b/Content/Buffs/Abilities/XLR8/XLR8_Primary_Buff.png deleted file mode 100644 index 18d9f697f32a7d6bea17b7333a0351cf9e3a641a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3071 zcmVKLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0003hNklq^VKn##y)i;guhJA%LFR;l<>C(h5pO zMnp_f?Xh5&jA3j?sUHF(kh%*W_1CDq4-LJGYc8SoGobpX!VkW@fy zE*W&SAq#qo23D_A8X~xSjNWn@e02e=C4*ikpqK5W0$eSm!P_2yl~}my2vS=_s~!&0 zasX#-h#qHzTE*x-C!~My*M_jxD-58wWJv89g~_W7&f1W1#P^N?0|04naOK!pCD{M~ N002ovPDHLkV1kN{to8r^ diff --git a/Content/Buffs/Abilities/XLR8/XLR8_Primary_Cooldown_Buff.cs b/Content/Buffs/Abilities/XLR8/XLR8_Primary_Cooldown_Buff.cs deleted file mode 100644 index d71c572..0000000 --- a/Content/Buffs/Abilities/XLR8/XLR8_Primary_Cooldown_Buff.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Terraria; -using Terraria.Audio; -using Terraria.ID; -using Terraria.ModLoader; - -namespace Ben10Mod.Content.Buffs.Abilities.XLR8 -{ - public class XLR8_Primary_Cooldown_Buff : ModBuff - { - public override bool RightClick(int buffIndex) { - return false; - } - - public override void Update(Player player, ref int buffIndex) { - if (player.buffTime[player.FindBuffIndex(ModContent.BuffType())] == 1) { - SoundEngine.PlaySound(SoundID.MenuTick, player.position); - } - } - } -} diff --git a/Content/Buffs/Abilities/XLR8/XLR8_Primary_Cooldown_Buff.png b/Content/Buffs/Abilities/XLR8/XLR8_Primary_Cooldown_Buff.png deleted file mode 100644 index 18d9f697f32a7d6bea17b7333a0351cf9e3a641a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3071 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 N002ovPDHLkV1kN{to8r^ diff --git a/Content/Buffs/Transformations/OmnitrixUpdating.cs b/Content/Buffs/Transformations/OmnitrixUpdating.cs new file mode 100644 index 0000000..167d0a7 --- /dev/null +++ b/Content/Buffs/Transformations/OmnitrixUpdating.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Ben10Mod.Enums; +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Buffs.Transformations { + public class OmnitrixUpdating : ModBuff { + public override string Texture => "Ben10Mod/Content/Buffs/Transformations/OmnitrixUpdating"; + private OmnitrixPlayer p; + public override void Update(Player player, ref int buffIndex) { + p = player.GetModPlayer(); + + p.omnitrixUpdating = true; + p.omnitrixWasUpdating = true; + } + public override bool RightClick(int buffIndex) => false; + } +} diff --git a/Content/Buffs/Transformations/OmnitrixUpdating.png b/Content/Buffs/Transformations/OmnitrixUpdating.png new file mode 100644 index 0000000000000000000000000000000000000000..c18ef466c7cf65a9e9b36a7a7da35bc4a087bf92 GIT binary patch literal 2767 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 V1G0pq<0b$A002ovPDHLkV1kB&R;B;| literal 0 HcmV?d00001 diff --git a/Content/Interface/OmnitrixSlot.cs b/Content/Interface/OmnitrixSlot.cs index 8524ca2..d2e774c 100644 --- a/Content/Interface/OmnitrixSlot.cs +++ b/Content/Interface/OmnitrixSlot.cs @@ -36,7 +36,7 @@ public override void OnMouseHover(AccessorySlotType context) { } public override bool IsHidden() { - return Player.GetModPlayer().isTransformed; + return Player.GetModPlayer().isTransformed || Player.GetModPlayer().omnitrixUpdating; } } } diff --git a/Content/Items/Accessories/Omnitrix.cs b/Content/Items/Accessories/Omnitrix.cs index d59f09c..9558806 100644 --- a/Content/Items/Accessories/Omnitrix.cs +++ b/Content/Items/Accessories/Omnitrix.cs @@ -1,30 +1,7 @@ - using Ben10Mod.Content.Transformations; -using Ben10Mod.Content.Transformations.XLR8; -using Ben10Mod.Keybinds; -using Microsoft.Xna.Framework; -using Steamworks; -using System; using Terraria; -using Terraria.DataStructures; -using Terraria.GameContent.UI.Elements; using Terraria.ID; using Terraria.ModLoader; -using Terraria.ModLoader.IO; -using Ben10Mod.Enums; -using System.Collections.Generic; -using System.Threading.Tasks.Dataflow; -using System.Security.Cryptography.X509Certificates; -using Ben10Mod.Content.Interface; -using Ben10Mod.Content.Buffs.Abilities.ChromaStone; -using Ben10Mod.Content.Buffs.Abilities.DiamondHead; -using Ben10Mod.Content.Buffs.Abilities.HeatBlast; -using Ben10Mod.Content.Buffs.Abilities.XLR8; -using Ben10Mod.Content.Buffs.Transformations; -using Ben10Mod.Content.Items.Placeables; using Ben10Mod.Content.DamageClasses; -using Terraria.ModLoader.Default; -using Microsoft.Xna.Framework.Graphics; -using Terraria.Audio; namespace Ben10Mod.Content.Items.Accessories { diff --git a/Content/Items/Accessories/PrototypeOmnitrix.cs b/Content/Items/Accessories/PrototypeOmnitrix.cs index 82e0877..ba73432 100644 --- a/Content/Items/Accessories/PrototypeOmnitrix.cs +++ b/Content/Items/Accessories/PrototypeOmnitrix.cs @@ -1,28 +1,14 @@ - using Ben10Mod.Content.Transformations; -using Ben10Mod.Content.Transformations.XLR8; using Ben10Mod.Keybinds; using Microsoft.Xna.Framework; -using Steamworks; -using System; using Terraria; using Terraria.DataStructures; -using Terraria.GameContent.UI.Elements; using Terraria.ID; using Terraria.ModLoader; using Terraria.ModLoader.IO; using Ben10Mod.Enums; using System.Collections.Generic; -using System.Threading.Tasks.Dataflow; -using System.Security.Cryptography.X509Certificates; using Ben10Mod.Content.Interface; -using Ben10Mod.Content.Buffs.Abilities.ChromaStone; -using Ben10Mod.Content.Buffs.Abilities.DiamondHead; -using Ben10Mod.Content.Buffs.Abilities.HeatBlast; -using Ben10Mod.Content.Buffs.Abilities.XLR8; -using Ben10Mod.Content.Buffs.Transformations; using Ben10Mod.Content.Items.Placeables; -using Ben10Mod.Content.DamageClasses; -using Terraria.ModLoader.Default; using Microsoft.Xna.Framework.Graphics; using Terraria.Audio; @@ -47,6 +33,7 @@ public override void Load() { EquipLoader.AddEquipTexture(Mod, $"{Texture}_{EquipType.HandsOn}", EquipType.HandsOn, this); EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.HandsOn}", EquipType.HandsOn, name: "PrototypeOmnitrixAlt"); + EquipLoader.AddEquipTexture(Mod, $"{Texture}Updating_{EquipType.HandsOn}", EquipType.HandsOn, name: "PrototypeOmnitrixUpdating"); } public override ModItem Clone(Item item) { @@ -87,10 +74,12 @@ public override void ModifyTooltips(List tooltips) { } public override void UpdateAccessory(Player player, bool hideVisual) { + if (player.whoAmI != Main.myPlayer) return; this.player = player; var omp = player.GetModPlayer(); - omp.omnitrixEquipped = true; - wasEquipedLastFrame = true; + omp.omnitrixEquipped = true; + omp.prototypeOmnitrix = true; + wasEquipedLastFrame = true; omp.omnitrixEnergyMax += 300; @@ -186,7 +175,7 @@ public override bool PreDrawInInventory(SpriteBatch spriteBatch, Vector2 positio if (player == null) return true; - dynamicTexture = player.GetModPlayer().onCooldown ? ModContent.Request("Ben10Mod/Content/Items/Accessories/PrototypeOmnitrixAlt").Value : ModContent.Request("Ben10Mod/Content/Items/Accessories/PrototypeOmnitrix").Value; + dynamicTexture = player.GetModPlayer().omnitrixUpdating ? ModContent.Request("Ben10Mod/Content/Items/Accessories/PrototypeOmnitrixUpdating").Value : player.GetModPlayer().onCooldown ? ModContent.Request("Ben10Mod/Content/Items/Accessories/PrototypeOmnitrixAlt").Value : ModContent.Request("Ben10Mod/Content/Items/Accessories/PrototypeOmnitrix").Value; spriteBatch.Draw(dynamicTexture, position, null, drawColor, 0f, origin, scale, SpriteEffects.None, 0f); diff --git a/Content/Items/Accessories/PrototypeOmnitrixUpdating.png b/Content/Items/Accessories/PrototypeOmnitrixUpdating.png new file mode 100644 index 0000000000000000000000000000000000000000..024f652ddb39abc9c77228b94f2e88b80289eadb GIT binary patch literal 797 zcmV+&1LFLNP)Px%*GWV{R9J=8m@#WwQ5c4wlq?~*1Z$fiI4FS<9mLvzr9*IVwST}-2xJKP18x66 z=-^VvkRRYGB)B=$io=a`(Lq9LE5W5hMmt%*wDiDUG(02&Ufy4c+YpfbJtj) zR4O$!udlAI))uw>8!a36*}oX#?Q~Vh|X`oap z1;EM42>`ubPmiVmcXxLH3bJL1v5W^f_1j9?ry^%~N0qAr(*8Ot148GUE@M0_$dvpMK=kV~*y07>e&sF$| zxigp7s?{n0M@L6s5EF@fJ`X_e#}@#eufMnYOY)ZD-QL~;u)Dh(_+p_YHqW|RorOXH zfNr-71{q175aD{g9vE08Z*FeDSiR~ek7hC%04^^tVHNUN&^|RKAYZwj5~(r20t3f* zVYP3yS`d)m+U<7WyM&h5gFNPHGMRwkJ&_U#&+|R^@|C{|e}4C`(`lP*sZ@eT$hitF zv4tK>Bofxm!S7jK8v9);l?njc+uHzq`urMz569mC7>z~%)M_=qU(7GVR5f z0^cRH#1?vNYikP(kCpO%MpxPzkH=u-pSSNm0&sqQ40g2uKra4f7B6DOH;7pZEwQEZ zn8<0S^ZXN=J_rE!Ues#zJkRPcty~^kdau;4_Bj0-GqxmB+ABre?Z0w+<+@8s5+R+I zRFCcN?_2HU#rE(k7^_#Fk}fVTz^KO>jfVBy7=J}-e&r=88jXTMs@ZHpKs`0Dvt}9H z^Xxn&^6Ia6s`=e^V`NVvtIwv!OF0Sw@*1c5 zZOfMJ&;2uRRq>3JX6sE$%Kv_u0yG#WNH)=yW%$=od0o}>^V94}OLC*1n=LL6wPIjc zUaKX`P!~L1<@)EktA7EgBvs^p#od{I`~I4IDgJx?Z{~-$ zx9vSA{r>&?;pauq9WR^2PTFF>@4I!}zsT4LuOG`wnK&#x<5)jsaj4K?tGh>&CaT=b z+g@92DE@Q1RaAW3b*r}vE&21~?Cih)Zci7Izn2gzZ|~a7w&KbX_vQU1cLKis-e);C zLiM5fkKLu7pFVt;uqQIr$mDep@5hG^7kb|hnS9vXqkVl%hTiq#=RqDdeR=Vv6W_d` z>3M!rKJJQow7)Il*LVBMI6l3Kx?Ohn7CJJAoYG)@a-=HddmC5A1)MQKK;poYvtH~o z8uUD8E%ThTCTz9J$-8&wCiCxky{d$P!S8p7)q(izd!?R5w(rfuSKn4SnYUeAid%vo z6j{$4?e86wDY?DvaNTjaxOM%)G4jAb+S?N(eBH!%y2{)B_ka7AM~XgoS-bO`r1!n7 zB01Z|k?Vh_n{*#l^4xScZ}LC+^r^=`2AO0uctsvHjE$Y7GySy6$bD`J zc%|ue%jA>Mq352RzP{(|=G$*4|NGnEeQd=%Hr@bD-l|8yFx|;h+|b|O%Di_4M6LI^ z#Jrukx0^#{^24mJemcKc1DvkDxX7+QeJ{tXRrqVx+0t_npTg#RUZAX~m1K#XRp(eIHS@$dQ>qxZ#uje|}8~L&Bw9#=q~*o)j~ckKsV3o92U0&tk!e z9-N|e#JW{ZmhJYPv?bU2W%U%Ge^z?-`#DJZUM}(66r(p;<@aB^m(rggBp&^C)AMn&J09 hUd^Bq2tQ~L{2`vU&}hw0_D$X(m7cDCF6*2UngGJ=<+T6+ literal 0 HcmV?d00001 diff --git a/Content/Items/Accessories/RecalibratedOmnitrix.cs b/Content/Items/Accessories/RecalibratedOmnitrix.cs index c647ace..bda2236 100644 --- a/Content/Items/Accessories/RecalibratedOmnitrix.cs +++ b/Content/Items/Accessories/RecalibratedOmnitrix.cs @@ -1,28 +1,14 @@ - using Ben10Mod.Content.Transformations; -using Ben10Mod.Content.Transformations.XLR8; using Ben10Mod.Keybinds; using Microsoft.Xna.Framework; -using Steamworks; using System; using Terraria; using Terraria.DataStructures; -using Terraria.GameContent.UI.Elements; using Terraria.ID; using Terraria.ModLoader; using Terraria.ModLoader.IO; using Ben10Mod.Enums; using System.Collections.Generic; -using System.Threading.Tasks.Dataflow; -using System.Security.Cryptography.X509Certificates; using Ben10Mod.Content.Interface; -using Ben10Mod.Content.Buffs.Abilities.ChromaStone; -using Ben10Mod.Content.Buffs.Abilities.DiamondHead; -using Ben10Mod.Content.Buffs.Abilities.HeatBlast; -using Ben10Mod.Content.Buffs.Abilities.XLR8; -using Ben10Mod.Content.Buffs.Transformations; -using Ben10Mod.Content.Items.Placeables; -using Ben10Mod.Content.DamageClasses; -using Terraria.ModLoader.Default; using Microsoft.Xna.Framework.Graphics; using Terraria.Audio; @@ -88,6 +74,9 @@ public override void ModifyTooltips(List tooltips) { } public override void UpdateAccessory(Player player, bool hideVisual) { + + if (player.whoAmI != Main.myPlayer) return; + this.player = player; var omp = player.GetModPlayer(); omp.omnitrixEnergyMax += 500; @@ -196,7 +185,7 @@ public override void UpdateInventory(Player player) if (player.GetModPlayer().isTransformed) { TransformationHandler.Detransform(player, omp.cooldownTime, true, true); } else { - TransformationHandler.Detransform(player, omp.cooldownTime, false, false); + TransformationHandler.Detransform(player, omp.cooldownTime, false, false, false); } } } @@ -222,8 +211,8 @@ public override void AddRecipes() { Recipe recipeAlt = CreateRecipe() .AddIngredient(ModContent.ItemType()) - .AddIngredient(ItemID.SoulofNight, 5) - .AddIngredient(ItemID.SoulofLight, 5) + .AddIngredient(ItemID.SoulofNight, 8) + .AddIngredient(ItemID.SoulofLight, 8) .AddTile(TileID.MythrilAnvil).Register(); } diff --git a/Content/Items/Consumable/MasterControlKey.png b/Content/Items/Consumable/MasterControlKey.png index f45bb4f1d15205ba7d932bc3609685581aeadc84..b5d9143cd9f2258aedafb81780dd5e9877dc772e 100644 GIT binary patch literal 224 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRq!3HGvW!zy0QjEnx?oJHr&dIz4a%OqDIEGmC zCZ`-=%<+5m-~E}q;r0aOSj=W%u;IbvBjGy)SWa+q#=ko9iZw^7K+>sDf`Q@T X5#Qf>rI*!!u4M3Z^>bP0l+XkK)-zHs literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^azM<*!3HE3m%q~oQjEnx?oJHr&dIz4a{N49978O6 zlT#8Bew;U8XvkF1NlgHPM#GX9Pu^?y2vj|&}hekagm22WQ%mvv4FO#lXJFjxQp diff --git a/Content/TransformationHandler.cs b/Content/TransformationHandler.cs index 05be508..876ebe8 100644 --- a/Content/TransformationHandler.cs +++ b/Content/TransformationHandler.cs @@ -3,11 +3,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using Ben10Mod.Content.Buffs.Abilities.ChromaStone; -using Ben10Mod.Content.Buffs.Abilities.DiamondHead; -using Ben10Mod.Content.Buffs.Abilities.HeatBlast; -using Ben10Mod.Content.Buffs.Abilities.XLR8; -using Ben10Mod.Content.Buffs.Abilities.BuzzShock; +using Ben10Mod.Content.Buffs.Abilities; using Ben10Mod.Content.Buffs.Transformations; using Ben10Mod.Enums; using Terraria; @@ -75,11 +71,7 @@ public static void Detransform(Player player, int seconds, bool showParticles = player.ClearBuff(ModContent.BuffType()); player.ClearBuff(ModContent.BuffType()); - // player.ClearBuff(ModContent.BuffType()); - // player.ClearBuff(ModContent.BuffType()); - // player.ClearBuff(ModContent.BuffType()); - // player.ClearBuff(ModContent.BuffType()); - // player.ClearBuff(ModContent.BuffType()); + player.ClearBuff(ModContent.BuffType()); player.GetModPlayer().currTransformation = TransformationEnum.None; diff --git a/Localization/en-US_Mods.Ben10Mod.hjson b/Localization/en-US_Mods.Ben10Mod.hjson index c110fe5..141caa9 100644 --- a/Localization/en-US_Mods.Ben10Mod.hjson +++ b/Localization/en-US_Mods.Ben10Mod.hjson @@ -346,6 +346,21 @@ Buffs: { DisplayName: Ultimate Ability_ Cooldown Description: Mods.Ben10Mod.Buffs.UltimateAbility_Cooldown.Description } + + OmnitrixUpdating: { + Description: Mods.Ben10Mod.Buffs.OmnitrixUpdating.Description + DisplayName: Omnitrix Updating + } + + PrimaryAbility: { + DisplayName: Primary Ability + Description: Mods.Ben10Mod.Buffs.PrimaryAbility.Description + } + + PrimaryAbilityCooldown: { + DisplayName: Primary Ability Cooldown + Description: Mods.Ben10Mod.Buffs.PrimaryAbilityCooldown.Description + } } Projectiles: { diff --git a/OmnitrixPlayer.cs b/OmnitrixPlayer.cs index f3eee82..a10b2c5 100644 --- a/OmnitrixPlayer.cs +++ b/OmnitrixPlayer.cs @@ -1,5 +1,4 @@ -using Ben10Mod.Content.Transformations.XLR8; -using Ben10Mod.Keybinds; +using Ben10Mod.Keybinds; using System; using Microsoft.Xna.Framework; using System.Collections.Generic; @@ -13,11 +12,7 @@ using Ben10Mod.Content.Items.Accessories; using Terraria.DataStructures; using Ben10Mod.Content.Transformations.DiamondHead; -using Terraria.GameInput; -using Ben10Mod.Content.Buffs.Abilities.XLR8; -using Ben10Mod.Content.Buffs.Abilities.HeatBlast; -using Ben10Mod.Content.Projectiles; -using Ben10Mod.Content.Buffs.Abilities.DiamondHead; +using Ben10Mod.Content.Transformations.XLR8; using Ben10Mod.Content.Transformations.BuzzShock; using Ben10Mod.Content.Transformations.ChromaStone; using Ben10Mod.Content.Transformations.FourArms; @@ -25,19 +20,15 @@ using Ben10Mod.Content.Transformations.RipJaws; using Ben10Mod.Content.Transformations.StinkFly; using Ben10Mod.Content.Transformations.WildVine; -using Ben10Mod.Content.Buffs.Abilities.ChromaStone; using Ben10Mod.Enums; using Ben10Mod.Content.Interface; using Ben10Mod.Content; +using Ben10Mod.Content.Buffs.Abilities; using Ben10Mod.Content.DamageClasses; -using Ben10Mod.Content.Items.Weapons; using Terraria.Audio; -using Ben10Mod.Content.Buffs.Abilities.BuzzShock; using Ben10Mod.Content.Buffs.Transformations; using Ben10Mod.Content.Items.Accessories.Wings; using Ben10Mod.Content.Transformations.EyeGuy; -using Microsoft.Xna.Framework.Input; -using Terraria.Graphics.Effects; namespace Ben10Mod { @@ -45,29 +36,23 @@ public class OmnitrixPlayer : ModPlayer { public bool masterControl = false; - public bool omnitrixEquipped = false; - public bool isTransformed = false; - public bool wasTransformed = false; - public bool onCooldown = false; - public bool altAttack = false; - public bool ultimateAttack = false; + public bool omnitrixEquipped = false; + public bool prototypeOmnitrix = false; + public bool isTransformed = false; + public bool wasTransformed = false; + public bool onCooldown = false; + public bool altAttack = false; + public bool ultimateAttack = false; public bool advancedCircuitMatrix = false; public bool advancedCircuitMatrixEquippedWhileTransformed = false; public int cooldownTime = 120; public int transformationTime = 300; - - public bool XLR8PrimaryAbilityEnabled = false; - public bool XLR8PrimaryAbilityWasEnabled = false; - public bool HeatBlastPrimaryAbilityEnabled = false; - public bool HeatBlastPrimaryAbilityWasEnabled = false; - public bool DiamondHeadPrimaryAbilityEnabled = false; - public bool DiamondHeadPrimaryAbilityWasEnabled = false; - public bool ChromaStonePrimaryAbilityEnabled = false; - public bool ChromaStonePrimaryAbilityWasEnabled = false; - public bool BuzzShockPrimaryAbilityEnabled = false; - public bool BuzzShockPrimaryAbilityWasEnabled = false; + + public bool PrimaryAbilityEnabled = false; + public bool PrimaryAbilityWasEnabled = false; + public TransformationEnum tranUsedAbility = TransformationEnum.None; public int ChromaStoneAbsorbtion = 0; @@ -88,7 +73,9 @@ public class OmnitrixPlayer : ModPlayer { public TransformationEnum[] transformations = { TransformationEnum.HeatBlast, TransformationEnum.HeatBlast, TransformationEnum.HeatBlast, TransformationEnum.HeatBlast, TransformationEnum.HeatBlast }; public TransformationEnum currTransformation = TransformationEnum.None; public List unlockedTransformation = new List() { TransformationEnum.HeatBlast }; - + + public bool omnitrixUpdating = false; + public bool omnitrixWasUpdating = false; public float omnitrixEnergy = 0f; public float omnitrixEnergyMax = 0f; public float omnitrixEnergyRegen = 0f; @@ -112,7 +99,6 @@ public Color GetChromaStoneOverlayColor() public override void SaveData(TagCompound tag) { - if (Player.whoAmI != Main.myPlayer) return; tag["masterControl"] = masterControl; tag["currTransformation"] = (int)currTransformation; @@ -129,7 +115,6 @@ public override void SaveData(TagCompound tag) public override void LoadData(TagCompound tag) { - if (Player.whoAmI != Main.myPlayer) return; tag.TryGet("masterControl", out masterControl); @@ -165,7 +150,6 @@ public override void LoadData(TagCompound tag) public override void ResetEffects() { - if (Player.whoAmI != Main.myPlayer) return; advancedCircuitMatrix = false; cooldownTime = 120; @@ -174,16 +158,16 @@ public override void ResetEffects() { omnitrixEnergyRegen = 0; // Transformations - isTransformed = false; - onCooldown = false; - omnitrixEquipped = false; + isTransformed = false; + onCooldown = false; + omnitrixEquipped = false; + prototypeOmnitrix = false; + + // Updating + omnitrixUpdating = false; // Abilities - XLR8PrimaryAbilityEnabled = false; - HeatBlastPrimaryAbilityEnabled = false; - DiamondHeadPrimaryAbilityEnabled = false; - ChromaStonePrimaryAbilityEnabled = false; - BuzzShockPrimaryAbilityEnabled = false; + PrimaryAbilityEnabled = false; // Handle dashing if (Player.controlDown && Player.releaseDown && Player.doubleTapCardinalTimer[DashDown] < 15) { @@ -206,7 +190,6 @@ public override void ResetEffects() { // Handles players abilities public override void PostUpdateBuffs() { - if (Player.whoAmI != Main.myPlayer) return; var abilitySlot = ModContent.GetInstance(); var omnitrixSlot = ModContent.GetInstance(); @@ -226,13 +209,25 @@ public override void PostUpdateBuffs() { } wasTransformed = false; } + + if (omnitrixUpdating != omnitrixWasUpdating) { + if (omnitrixSlot.FunctionalItem.type == ModContent.ItemType()) { + Random random = new Random(); + for (int i = 0; i < 25; i++) { + int dustNum = Dust.NewDust(Player.position - new Vector2(1, 1), Player.width + 1, Player.height + 1, DustID.BlueTorch, random.Next(-4, 5), random.Next(-4, 5), 1, Color.White, 4); + Main.dust[dustNum].noGravity = true; + } + omnitrixSlot.FunctionalItem = new Item(ModContent.ItemType()); + } + omnitrixWasUpdating = omnitrixUpdating; + } // XLR8 Transformation if (currTransformation == TransformationEnum.XLR8) { float multiplier = 1; - if (XLR8PrimaryAbilityEnabled) { + if (PrimaryAbilityEnabled) { multiplier = 2; } @@ -270,7 +265,7 @@ public override void PostUpdateBuffs() { Player.wingTimeMax = 0; Player.wingTime = 0; - if (DiamondHeadPrimaryAbilityEnabled) { + if (PrimaryAbilityEnabled) { Player.moveSpeed /= 10; Player.lifeRegen += 15; Player.statDefense *= 1.5f; @@ -330,7 +325,6 @@ public override void PostUpdateBuffs() { } public override void PostUpdate() { - if (Player.whoAmI != Main.myPlayer) return; var abilitySlot = ModContent.GetInstance(); @@ -359,13 +353,9 @@ public override void PostUpdate() { if (currTransformation == TransformationEnum.XLR8) { - if (KeybindSystem.PrimaryAbility.JustPressed && !Player.HasBuff(ModContent.BuffType()) && !Player.HasBuff(ModContent.BuffType())) { - Player.AddBuff(ModContent.BuffType(), 10 * 60); - } - - if (XLR8PrimaryAbilityEnabled != XLR8PrimaryAbilityWasEnabled) { - XLR8PrimaryAbilityWasEnabled = false; - Player.AddBuff(ModContent.BuffType(), 10 * 60); + if (KeybindSystem.PrimaryAbility.JustPressed && !Player.HasBuff(ModContent.BuffType()) && !Player.HasBuff(ModContent.BuffType())) { + Player.AddBuff(ModContent.BuffType(), 10 * 60); + tranUsedAbility = currTransformation; } abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); @@ -378,11 +368,12 @@ public override void PostUpdate() { int dustNum = Dust.NewDust(Player.position, Player.width, Player.height, DustID.Flare, 0, rand.Next(-1, 2), rand.Next(-1, 2), Color.White, rand.Next(3)); Main.dust[dustNum].noGravity = true; if (KeybindSystem.PrimaryAbility.JustPressed) { - if (!Player.HasBuff(ModContent.BuffType()) && !Player.HasBuff(ModContent.BuffType())) { - Player.AddBuff(ModContent.BuffType(), 60 * 60); + if (!Player.HasBuff(ModContent.BuffType()) && !Player.HasBuff(ModContent.BuffType())) { + Player.AddBuff(ModContent.BuffType(), 60 * 60); + tranUsedAbility = currTransformation; } } - if (HeatBlastPrimaryAbilityEnabled) { + if (PrimaryAbilityEnabled) { Vector2[] points = GenerateCirclePoints(250, 7 * (16)); for (int i = 0; i < points.Length; i++) { dustNum = Dust.NewDust(points[i] + Player.Center, 1, 1, DustID.Torch, rand.Next(-1, 2), rand.Next(-1, 2)); @@ -403,41 +394,28 @@ public override void PostUpdate() { abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } - if (HeatBlastPrimaryAbilityEnabled != HeatBlastPrimaryAbilityWasEnabled) { - HeatBlastPrimaryAbilityWasEnabled = false; - Player.AddBuff(ModContent.BuffType(), 10 * 60); - } - // Diamondhead Transformation if (currTransformation == TransformationEnum.DiamondHead) { if (KeybindSystem.PrimaryAbility.JustPressed) { - if (!Player.HasBuff(ModContent.BuffType()) && !Player.HasBuff(ModContent.BuffType())) { - Player.AddBuff(ModContent.BuffType(), 60 * 60); + if (!Player.HasBuff(ModContent.BuffType()) && !Player.HasBuff(ModContent.BuffType())) { + Player.AddBuff(ModContent.BuffType(), 60 * 60); + tranUsedAbility = currTransformation; Player.velocity = Vector2.Zero; } } - if (DiamondHeadPrimaryAbilityEnabled) { + if (PrimaryAbilityEnabled) { Player.velocity = new Vector2(float.Clamp(Player.velocity.X, -0.5f, 0.5f), Math.Max(0, Player.velocity.Y)); + Lighting.AddLight(Player.Center, new Vector3(0.4f, 0.3f, 0.8f)); } abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } - if (DiamondHeadPrimaryAbilityEnabled != DiamondHeadPrimaryAbilityWasEnabled) { - DiamondHeadPrimaryAbilityWasEnabled = false; - // Player.AddBuff(ModContent.BuffType(), 25 * 60); - } - - if (DiamondHeadPrimaryAbilityEnabled) { - Lighting.AddLight(Player.Center, new Vector3(0.4f, 0.3f, 0.8f)); - } - // Ripjaws Transformation if (currTransformation == TransformationEnum.RipJaws) { - abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } @@ -445,29 +423,29 @@ public override void PostUpdate() { if (currTransformation == TransformationEnum.ChromaStone) { if (KeybindSystem.PrimaryAbility.JustPressed) { - if (!Player.HasBuff(ModContent.BuffType()) && !Player.HasBuff(ModContent.BuffType())) { - Player.AddBuff(ModContent.BuffType(), 30 * 60); + if (!Player.HasBuff(ModContent.BuffType()) && !Player.HasBuff(ModContent.BuffType())) { + Player.AddBuff(ModContent.BuffType(), 30 * 60); + tranUsedAbility = currTransformation; } } - if (ChromaStonePrimaryAbilityEnabled) + if (PrimaryAbilityEnabled) { Lighting.AddLight(Player.Center, Main.DiscoColor.ToVector3()); } abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); - } else { } - if (ChromaStonePrimaryAbilityEnabled == false) { - ChromaStoneAbsorbtion = 0; + if (!PrimaryAbilityEnabled) { + } // Buzzshock Transformation if (currTransformation == TransformationEnum.BuzzShock) { - if (KeybindSystem.PrimaryAbility.JustPressed) { + if (KeybindSystem.PrimaryAbility.JustPressed && !Player.HasBuff()) { if (Main.myPlayer == Player.whoAmI) { SoundEngine.PlaySound(SoundID.Item8, Player.position); Random random = new Random(); @@ -481,17 +459,12 @@ public override void PostUpdate() { Main.dust[dustNum].noGravity = true; } - Player.AddBuff(BuffID.ChaosState, 60 * 6); + Player.AddBuff(ModContent.BuffType(), 60 * 6); } } abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } - - if (BuzzShockPrimaryAbilityEnabled != BuzzShockPrimaryAbilityWasEnabled) { - BuzzShockPrimaryAbilityWasEnabled = false; - Player.AddBuff(ModContent.BuffType(), 10 * 60); - } // Fourarms Transformation @@ -509,29 +482,12 @@ public override void PostUpdate() { if (currTransformation == TransformationEnum.GhostFreak) { Random random = new Random(); - - if (KeybindSystem.PrimaryAbility.Current) { // Phasing Logic - - Vector2 move = Vector2.Zero; - if (Player.controlLeft) move.X -= 1f; - if (Player.controlRight) move.X += 1f; - if (Player.controlUp) move.Y -= 1f; - if (Player.controlDown) move.Y += 1f; - - if (move == Vector2.Zero) - return; - - float phaseSpeed = 6f; - move = Vector2.Normalize(move); - Player.velocity = Vector2.Zero; - Player.gravity = 0f; - Player.fallStart = (int)(Player.position.Y / 16f); - Player.velocity.Y = move.Y; - - Player.position += move * phaseSpeed; + if (KeybindSystem.PrimaryAbility.Current && !Player.HasBuff() && !Player.HasBuff()) { + Player.AddBuff(ModContent.BuffType(), 15 * 60); + tranUsedAbility = currTransformation; } - + abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } @@ -570,30 +526,58 @@ public override void PostUpdate() { possessionTimer--; if (possessionTimer <= 0) { - possessedTarget.SimpleStrikeNPC(Player.HeldItem.damage, Player.direction, false, 0, DamageClass.Magic); + possessedTarget.SimpleStrikeNPC(Player.HeldItem.damage * 2, Player.direction, false, 0, DamageClass.Magic); EndPossession(); } } + + if (PrimaryAbilityEnabled != PrimaryAbilityWasEnabled) { + PrimaryAbilityWasEnabled = PrimaryAbilityEnabled; + switch (tranUsedAbility) { + case TransformationEnum.HeatBlast: { + Player.AddBuff(ModContent.BuffType(), 30 * 60); + break; + } + case TransformationEnum.XLR8: { + Player.AddBuff(ModContent.BuffType(), 30 * 60); + break; + } + case TransformationEnum.DiamondHead: { + Player.AddBuff(ModContent.BuffType(), 30 * 60); + break; + } + case TransformationEnum.ChromaStone: { + Player.AddBuff(ModContent.BuffType(), 60 * 60); + break; + } + case TransformationEnum.GhostFreak: { + Player.AddBuff(ModContent.BuffType(), 30 * 60); + break; + } + } + + ChromaStoneAbsorbtion = 0; + PrimaryAbilityWasEnabled = PrimaryAbilityEnabled; + } } public override bool CanUseItem(Item item) { if (Player.whoAmI != Main.myPlayer) return false; - return !(currTransformation == TransformationEnum.GhostFreak && KeybindSystem.PrimaryAbility.Current); + return !(currTransformation == TransformationEnum.GhostFreak && PrimaryAbilityEnabled); } public override bool CanBeHitByNPC(NPC npc, ref int cooldownSlot) { if (Player.whoAmI != Main.myPlayer) return false; - return !(currTransformation == TransformationEnum.GhostFreak && KeybindSystem.PrimaryAbility.Current); + return !(currTransformation == TransformationEnum.GhostFreak && PrimaryAbilityEnabled); } public override bool CanBeHitByProjectile(Projectile proj) { if (Player.whoAmI != Main.myPlayer) return false; - return !(currTransformation == TransformationEnum.GhostFreak && KeybindSystem.PrimaryAbility.Current); + return !(currTransformation == TransformationEnum.GhostFreak && PrimaryAbilityEnabled); } public override void OnHurt(Player.HurtInfo info) { - if (Player.whoAmI != Main.myPlayer) return; - if (ChromaStonePrimaryAbilityEnabled) { + if (PrimaryAbilityEnabled && currTransformation == TransformationEnum.ChromaStone) { ChromaStoneAbsorbtion += Math.Max(info.Damage / 5, 0); } @@ -601,7 +585,6 @@ public override void OnHurt(Player.HurtInfo info) { } public override void OnHitAnything(float x, float y, Entity victim) { - if (Player.whoAmI != Main.myPlayer) return; if (!Main.npc[victim.whoAmI].HasBuff(BuffID.OnFire3) && currTransformation == TransformationEnum.HeatBlast) { Main.npc[victim.whoAmI].AddBuff(BuffID.OnFire3, 3 * 60); } @@ -625,7 +608,6 @@ public static Vector2[] GenerateCirclePoints(int numberOfPoints, float radius) { } public override void ModifyDrawInfo(ref PlayerDrawSet drawInfo) { - if (Player.whoAmI != Main.myPlayer) return; if (isTransformed) { } switch (currTransformation) { @@ -634,7 +616,7 @@ public override void ModifyDrawInfo(ref PlayerDrawSet drawInfo) { drawInfo.colorArmorBody = Color.White; drawInfo.colorArmorLegs = Color.White; break; - case TransformationEnum.GhostFreak when KeybindSystem.PrimaryAbility.Current: + case TransformationEnum.GhostFreak when PrimaryAbilityEnabled: drawInfo.colorArmorHead.A /= 2; drawInfo.colorArmorBody.A /= 2; drawInfo.colorArmorLegs.A /= 2; @@ -646,7 +628,7 @@ public override void ModifyDrawInfo(ref PlayerDrawSet drawInfo) { break; case TransformationEnum.BuzzShock: break; - case TransformationEnum.ChromaStone when ChromaStonePrimaryAbilityEnabled: + case TransformationEnum.ChromaStone when PrimaryAbilityEnabled: Color overlayColor = Main.DiscoColor; drawInfo.colorArmorHead = overlayColor; drawInfo.colorArmorBody = overlayColor; @@ -668,7 +650,6 @@ public override void ModifyDrawInfo(ref PlayerDrawSet drawInfo) { public override void DrawEffects(PlayerDrawSet drawInfo, ref float r, ref float g, ref float b, ref float a, ref bool fullBright) { - if (Player.whoAmI != Main.myPlayer) return; var customSlot = ModContent.GetInstance(); @@ -676,10 +657,12 @@ public override void DrawEffects(PlayerDrawSet drawInfo, ref float r, ref float if (customSlot.FunctionalItem.type == ModContent.ItemType()) { var costume = ModContent.GetInstance(); if (!customSlot.HideVisuals && !isTransformed) { - if (onCooldown) { + if (omnitrixUpdating) { + Player.handon = + EquipLoader.GetEquipSlot(Mod, "PrototypeOmnitrixUpdating", EquipType.HandsOn); + } else if (onCooldown) { Player.handon = EquipLoader.GetEquipSlot(Mod, "PrototypeOmnitrixAlt", EquipType.HandsOn); - } - else { + } else { Player.handon = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.HandsOn); } } @@ -709,8 +692,7 @@ public override void DrawEffects(PlayerDrawSet drawInfo, ref float r, ref float } public override void FrameEffects() { - - if (Player.whoAmI != Main.myPlayer) return; + var customSlot = ModContent.GetInstance(); @@ -718,10 +700,12 @@ public override void FrameEffects() { if (customSlot.FunctionalItem.type == ModContent.ItemType()) { var costume = ModContent.GetInstance(); if (!customSlot.HideVisuals && !isTransformed) { - if (onCooldown) { + if (omnitrixUpdating) { + Player.handon = + EquipLoader.GetEquipSlot(Mod, "PrototypeOmnitrixUpdating", EquipType.HandsOn); + } else if (onCooldown) { Player.handon = EquipLoader.GetEquipSlot(Mod, "PrototypeOmnitrixAlt", EquipType.HandsOn); - } - else { + } else { Player.handon = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.HandsOn); } } @@ -817,7 +801,7 @@ public override void FrameEffects() { } if (currTransformation == TransformationEnum.XLR8) { var costume = ModContent.GetInstance(); - if (XLR8PrimaryAbilityEnabled) { + if (PrimaryAbilityEnabled) { Player.head = EquipLoader.GetEquipSlot(Mod, "XLR8_alt", EquipType.Head); } else { Player.head = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Head); @@ -838,8 +822,36 @@ public override void FrameEffects() { } public override void PreUpdateMovement() { - if (Player.whoAmI != Main.myPlayer) return; DashMovement(); + if (PrimaryAbilityEnabled && currTransformation == TransformationEnum.GhostFreak) { // Phasing Logic + Vector2 input = Vector2.Zero; + if (Player.controlLeft) input.X -= 1f; + if (Player.controlRight) input.X += 1f; + if (Player.controlUp) input.Y -= 1f; + if (Player.controlDown) input.Y += 1f; + + const float speed = 14.5f; // Ghostfreak feels fast & floaty — tweak as you like + const float damp = 0.82f; // smooth deceleration when letting go + + if (input != Vector2.Zero) + { + input.Normalize(); + Vector2 move = input * speed; + + // Extra upward nudge so you can lift off the ground cleanly + if (input.Y < 0) move.Y -= 3f; + + Player.position += move; + } + else + { + Player.velocity *= damp; + Player.position += Player.velocity; // gentle drift + } + + // Kill vanilla movement/collision/gravity for this frame + Player.velocity = Vector2.Zero; + } } private void DashMovement() { @@ -904,7 +916,6 @@ private bool CanUseDash() { } public override void OnEnterWorld() { - if (Player.whoAmI != Main.myPlayer) return; ModContent.GetInstance().HideMyUI(); if (!isTransformed) { currTransformation = TransformationEnum.None; @@ -941,7 +952,6 @@ private void EndPossession() // This is where we unlock transformations public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { - if (Player.whoAmI != Main.myPlayer) return; base.OnHitNPC(target, hit, damageDone); if (target.life <= 0) { if (Main.bloodMoon) @@ -954,12 +964,12 @@ public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { } } + if (isTransformed && !ultimateAttack && omnitrixEnergyRegen == 0) omnitrixEnergy += Math.Max(hit.Damage / 25, 1); } public override void PreUpdate() { - if (Player.whoAmI != Main.myPlayer) return; if (colourAmount >= 1.0f) { thisColour++; @@ -975,13 +985,32 @@ public override void PreUpdate() { } colourAmount += 0.1f; + + if (PrimaryAbilityEnabled && currTransformation == TransformationEnum.GhostFreak) { + // Core noclip setup (DragonLens-style) + Player.gravity = 0f; // disable gravity multiplier + Player.noKnockback = true; + Player.noFallDmg = true; + + // Prevent ground-snap / fall damage logic + Player.fallStart = (int)(Player.position.Y / 16f); + } } - public void addTransformation(TransformationEnum transformation) { - if (Player.whoAmI != Main.myPlayer) return; + public void addTransformation(TransformationEnum transformation) { if (!TransformationHandler.HasTransformation(Player, transformation)) { unlockedTransformation.Add(transformation); Main.NewText(Player.name + " has unlocked " + transformation.GetName(), Color.Green); + + if (Main.netMode == NetmodeID.Server) + { + ModPacket packet = Mod.GetPacket(); + packet.Write((byte)Ben10Mod.MessageType.UnlockTransformation); + packet.Write((byte)Player.whoAmI); // the player who earned it + packet.Write((int)transformation); + packet.Send(toClient: Player.whoAmI); // send ONLY to the player who deserves it + } + } } } diff --git a/bossTrackerNPC.cs b/bossTrackerNPC.cs index 555a1dd..4a8ec99 100644 --- a/bossTrackerNPC.cs +++ b/bossTrackerNPC.cs @@ -1,5 +1,6 @@ using System.Runtime.CompilerServices; using Ben10Mod.Content; +using Ben10Mod.Content.Buffs.Transformations; using Ben10Mod.Enums; using Microsoft.Xna.Framework; using Terraria; @@ -7,8 +8,7 @@ using Terraria.ModLoader; namespace Ben10Mod { - public class bossTrackerNPC : GlobalNPC - { + public class bossTrackerNPC : GlobalNPC { public override bool InstancePerEntity => true; // total damage dealt to THIS npc instance by each player @@ -17,14 +17,12 @@ public class bossTrackerNPC : GlobalNPC // optional: track who last damaged it as a tie-breaker private int _lastDamager = -1; - private static bool CountsAsBoss(NPC npc) - { + private static bool CountsAsBoss(NPC npc) { // npc.boss is true for most bosses, but this catches extra boss-like NPCs too return npc.boss || NPCID.Sets.ShouldBeCountedAsBoss[npc.type]; } - private void RecordDamage(int playerIndex, int damage) - { + private void RecordDamage(int playerIndex, int damage) { if (damage <= 0) return; if (playerIndex < 0 || playerIndex >= Main.maxPlayers) return; @@ -32,13 +30,12 @@ private void RecordDamage(int playerIndex, int damage) if (!p.active) return; _damageByPlayer[playerIndex] += damage; - _lastDamager = playerIndex; + _lastDamager = playerIndex; } - - public override void OnHitByItem(NPC npc, Player player, Item item, NPC.HitInfo hit, int damageDone) - { + + public override void OnHitByItem(NPC npc, Player player, Item item, NPC.HitInfo hit, int damageDone) { if (Main.netMode == NetmodeID.MultiplayerClient) return; if (!CountsAsBoss(npc)) return; @@ -46,8 +43,7 @@ public override void OnHitByItem(NPC npc, Player player, Item item, NPC.HitInfo RecordDamage(player.whoAmI, damageDone); } - public override void OnHitByProjectile(NPC npc, Projectile projectile, NPC.HitInfo hit, int damageDone) - { + public override void OnHitByProjectile(NPC npc, Projectile projectile, NPC.HitInfo hit, int damageDone) { if (Main.netMode == NetmodeID.MultiplayerClient) return; if (!CountsAsBoss(npc)) return; if (damageDone <= 0) return; @@ -59,8 +55,7 @@ public override void OnHitByProjectile(NPC npc, Projectile projectile, NPC.HitIn } } - public override void OnKill(NPC npc) - { + public override void OnKill(NPC npc) { if (Main.netMode == NetmodeID.MultiplayerClient) return; if (!CountsAsBoss(npc)) return; @@ -68,7 +63,7 @@ public override void OnKill(NPC npc) if (credited == -1) return; int eaterCount = 0; - + if (npc.type == NPCID.EaterofWorldsBody || npc.type == NPCID.EaterofWorldsHead || npc.type == NPCID.EaterofWorldsTail) { for (int i = 0; i < Main.npc.Length; i++) { @@ -86,14 +81,14 @@ public override void OnKill(NPC npc) } string msg = $"{Main.player[credited].name} dealt the most damage!"; + + var player = Main.player[credited]; // Show message in both SP and MP - if (Main.netMode == NetmodeID.SinglePlayer) - { + if (Main.netMode == NetmodeID.SinglePlayer) { Main.NewText(msg, Color.Cyan); } - else if (Main.netMode == NetmodeID.Server) - { + else if (Main.netMode == NetmodeID.Server) { Terraria.Chat.ChatHelper.BroadcastChatMessage( Terraria.Localization.NetworkText.FromLiteral(msg), Color.Cyan @@ -102,75 +97,85 @@ public override void OnKill(NPC npc) switch (npc.type) { case NPCID.KingSlime: { - Main.player[credited].GetModPlayer() + player.GetModPlayer() .addTransformation(TransformationEnum.DiamondHead); break; } case NPCID.EyeofCthulhu: { - Main.player[credited].GetModPlayer() + player.GetModPlayer() .addTransformation(TransformationEnum.XLR8); break; } case NPCID.BrainofCthulhu: { - Main.player[credited].GetModPlayer() + player.GetModPlayer() .addTransformation(TransformationEnum.FourArms); break; } case NPCID.EaterofWorldsHead: case NPCID.EaterofWorldsTail: case NPCID.EaterofWorldsBody: { - Main.player[credited].GetModPlayer() + player.GetModPlayer() .addTransformation(TransformationEnum.FourArms); break; } case NPCID.QueenBee: { - Main.player[credited].GetModPlayer() + player.GetModPlayer() .addTransformation(TransformationEnum.StinkFly); break; } case NPCID.SkeletronHead: { - Main.player[credited].GetModPlayer() + player.GetModPlayer() .addTransformation(TransformationEnum.BuzzShock); break; } case NPCID.Deerclops: { - Main.player[credited].GetModPlayer() + player.GetModPlayer() .addTransformation(TransformationEnum.WildVine); break; } case NPCID.WallofFlesh: { - Main.player[credited].GetModPlayer() + if (player.GetModPlayer().prototypeOmnitrix) { + TransformationHandler.Detransform(player, 120); + player.AddBuff(ModContent.BuffType(), 120 * 60); + } + break; + } + case NPCID.QueenSlimeBoss: { + player.GetModPlayer() .addTransformation(TransformationEnum.ChromaStone); break; } default: break; } + + // === SYNC THE UNLOCK TO THE CLIENT === + if (Main.netMode == NetmodeID.Server && credited >= 0 && credited < Main.maxPlayers) + { + NetMessage.SendData(MessageID.SyncPlayer, credited, -1, null, credited); + } // TODO: store the kill credit here // Main.player[credited].GetModPlayer().RegisterBossKill(npc.type); } - private int GetTopDamager(NPC npc) - { + private int GetTopDamager(NPC npc) { int bestPlayer = -1; int bestDamage = 0; - for (int i = 0; i < Main.maxPlayers; i++) - { + for (int i = 0; i < Main.maxPlayers; i++) { if (!Main.player[i].active) continue; int dmg = _damageByPlayer[i]; - if (dmg > bestDamage) - { + if (dmg > bestDamage) { bestDamage = dmg; bestPlayer = i; } } // If nobody recorded (weird edge case), fallback: - if (bestPlayer == -1) - { - if (npc.lastInteraction >= 0 && npc.lastInteraction < Main.maxPlayers && Main.player[npc.lastInteraction].active) + if (bestPlayer == -1) { + if (npc.lastInteraction >= 0 && npc.lastInteraction < Main.maxPlayers && + Main.player[npc.lastInteraction].active) return npc.lastInteraction; if (_lastDamager >= 0 && _lastDamager < Main.maxPlayers && Main.player[_lastDamager].active) From abad08a0d445e8ef4de68a3f8d03db3dfe0ffebb Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Fri, 27 Feb 2026 12:08:29 +1100 Subject: [PATCH 07/25] Improved Ghostfreak possession --- Content/Buffs/Debuffs/GhostFreakPossesion.cs | 12 ------ Content/Buffs/Debuffs/GhostFreakPossesion.png | Bin 3071 -> 0 bytes .../Accessories/AdvancedCircuitMatrix.cs | 4 +- Content/Items/Weapons/PlumbersBadge.cs | 13 +++--- Content/Projectiles/EyeGuyUltimateBeam.cs | 8 +++- .../GhostFreakPossesionProjectile.cs | 35 +++++++-------- .../GhostFreakPossesionProjectile.png | Bin 0 -> 491 bytes Content/Projectiles/GhostFreakProjectile.cs | 2 +- Content/Projectiles/HeatBlastBomb.cs | 2 +- .../GhostFreak/GhostFreak_Head.png | Bin 5325 -> 951 bytes NpcEffects.cs | 40 ++++++++++++++++++ OmnitrixPlayer.cs | 11 +++++ bossTrackerNPC.cs | 20 ++++++++- 13 files changed, 105 insertions(+), 42 deletions(-) delete mode 100644 Content/Buffs/Debuffs/GhostFreakPossesion.cs delete mode 100644 Content/Buffs/Debuffs/GhostFreakPossesion.png create mode 100644 Content/Projectiles/GhostFreakPossesionProjectile.png create mode 100644 NpcEffects.cs diff --git a/Content/Buffs/Debuffs/GhostFreakPossesion.cs b/Content/Buffs/Debuffs/GhostFreakPossesion.cs deleted file mode 100644 index 4af0729..0000000 --- a/Content/Buffs/Debuffs/GhostFreakPossesion.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Terraria; -using Terraria.ModLoader; - -namespace Ben10Mod.Content.Buffs.Debuffs; - -public class GhostFreakPossesion : ModBuff { - public override bool RightClick(int buffIndex) => false; - - public override void Update(NPC npc, ref int buffIndex) { - npc.lifeRegen -= 12; - } -} \ No newline at end of file diff --git a/Content/Buffs/Debuffs/GhostFreakPossesion.png b/Content/Buffs/Debuffs/GhostFreakPossesion.png deleted file mode 100644 index 18d9f697f32a7d6bea17b7333a0351cf9e3a641a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3071 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 N002ovPDHLkV1kN{to8r^ diff --git a/Content/Items/Accessories/AdvancedCircuitMatrix.cs b/Content/Items/Accessories/AdvancedCircuitMatrix.cs index c2eaff7..18b0735 100644 --- a/Content/Items/Accessories/AdvancedCircuitMatrix.cs +++ b/Content/Items/Accessories/AdvancedCircuitMatrix.cs @@ -1,5 +1,6 @@ using Ben10Mod.Content.Items.Placeables; using Terraria; +using Terraria.GameContent.UI.States; using Terraria.ID; using Terraria.ModLoader; @@ -16,6 +17,7 @@ public override void SetDefaults() { public override void UpdateAccessory(Player player, bool hideVisual) { var omp = player.GetModPlayer(); - omp.advancedCircuitMatrix = true; + omp.advancedCircuitMatrix = true; + omp.omnitrixEnergyRegen += 50; } } \ No newline at end of file diff --git a/Content/Items/Weapons/PlumbersBadge.cs b/Content/Items/Weapons/PlumbersBadge.cs index bab4445..c06ca72 100644 --- a/Content/Items/Weapons/PlumbersBadge.cs +++ b/Content/Items/Weapons/PlumbersBadge.cs @@ -27,9 +27,9 @@ public abstract class PlumbersBadge : ModItem private int GetUltimateProjectileType(OmnitrixPlayer omp) { // Add more mappings here as you implement other ultimate attacks. - return omp.currTransformation switch - { + return omp.currTransformation switch { TransformationEnum.EyeGuy => ModContent.ProjectileType(), + TransformationEnum.GhostFreak => ModContent.ProjectileType(), _ => 0 }; } @@ -181,8 +181,9 @@ public override void HoldItem(Player player) break; case TransformationEnum.GhostFreak: - Item.useTime = Item.useAnimation = 14; - Item.shootSpeed = 12f; + Item.useTime = Item.useAnimation = 14; + Item.shootSpeed = 12f; + OmnitrixEnergyUse = omp.ultimateAttack ? 50 : 0; break; case TransformationEnum.WildVine: @@ -296,7 +297,7 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, break; case TransformationEnum.GhostFreak: - projType = omp.altAttack + projType = omp.ultimateAttack ? ModContent.ProjectileType() : ModContent.ProjectileType(); break; @@ -308,7 +309,7 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, break; case TransformationEnum.EyeGuy: projType = omp.ultimateAttack ? ModContent.ProjectileType() : ModContent.ProjectileType(); - finalDamage = omp.ultimateAttack ? (int)(damage * 1.2f) : damage; + finalDamage = omp.ultimateAttack ? (int)(damage * 2f) : damage; break; } diff --git a/Content/Projectiles/EyeGuyUltimateBeam.cs b/Content/Projectiles/EyeGuyUltimateBeam.cs index 81b91d9..219f81c 100644 --- a/Content/Projectiles/EyeGuyUltimateBeam.cs +++ b/Content/Projectiles/EyeGuyUltimateBeam.cs @@ -17,7 +17,7 @@ public class EyeGuyUltimateBeam : ModProjectile private const float StartOffset = 52f; private SlotId _loopSlot; - private bool _loopStarted; + private bool _loopStarted; // Beam lengths for this tick: // localAI[0] = collision length (reaches the first hit) @@ -161,6 +161,7 @@ ref collisionPoint Vector2 end = start + dir * length; float _ = 0f; + return Collision.CheckAABBvLineCollision( targetHitbox.TopLeft(), targetHitbox.Size(), @@ -260,6 +261,11 @@ public override bool PreDraw(ref Color lightColor) { // End cap Vector2 endPos = start + dir * length; + for (int j = 0; j < 5; j++) { + int dustNum = Dust.NewDust(endPos, endFrame.Width, endFrame.Height, DustID.GreenTorch, 0, 0, 0, Color.White, 3f); + Main.dust[dustNum].noGravity = true; + } + Main.EntitySpriteDraw( tex, endPos - Main.screenPosition, diff --git a/Content/Projectiles/GhostFreakPossesionProjectile.cs b/Content/Projectiles/GhostFreakPossesionProjectile.cs index 8dab514..b649d46 100644 --- a/Content/Projectiles/GhostFreakPossesionProjectile.cs +++ b/Content/Projectiles/GhostFreakPossesionProjectile.cs @@ -9,12 +9,9 @@ namespace Ben10Mod.Content.Projectiles; public class GhostFreakPossesionProjectile : ModProjectile { - - public override string Texture => $"Terraria/Images/Projectile_{ProjectileID.None}"; - public override void SetDefaults() { - Projectile.width = 4; - Projectile.height = 4; + Projectile.width = 26; + Projectile.height = 44; Projectile.aiStyle = ProjAIStyleID.Arrow; AIType = ProjectileID.Bullet; @@ -26,18 +23,14 @@ public override void SetDefaults() { } - public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) - { - target.AddBuff(ModContent.BuffType(), 360); + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { - if (Main.myPlayer == Projectile.owner) - { + if (Main.myPlayer == Projectile.owner) { Player player = Main.player[Projectile.owner]; var omp = player.GetModPlayer(); // Or CameraPlayer if separate // Only start possession if not already in mode (prevent stacking) - if (!omp.inPossessionMode) - { + if (!omp.inPossessionMode) { omp.prePossessionPosition = player.position; // Save current pos omp.possessedTarget = target; omp.possessionTimer = 360; @@ -48,19 +41,23 @@ public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) // Initial effects SoundEngine.PlaySound(SoundID.MaxMana with { Pitch = 0.5f, Volume = 0.8f }, player.Center); - for (int i = 0; i < 40; i++) - { - Dust d = Dust.NewDustPerfect(target.Center, DustID.PurpleTorch, Main.rand.NextVector2Circular(8f, 8f), Scale: 2f); + for (int i = 0; i < 40; i++) { + Dust d = Dust.NewDustPerfect(target.Center, DustID.PurpleTorch, + Main.rand.NextVector2Circular(8f, 8f), Scale: 2f); d.noGravity = true; } } } } - - public override void EmitEnchantmentVisualsAt(Vector2 boxPosition, int boxWidth, int boxHeight) { - Random random = new Random(); + + public override bool PreDraw(ref Color lightColor) { + lightColor.A /= 2; + return base.PreDraw(ref lightColor); + } + + public override void AI() { for (int i = 0; i < 5; i++) { - int dustNum = Dust.NewDust(boxPosition, boxWidth, boxHeight, DustID.WhiteTorch, 0, 0, 1, Color.White, 1); + int dustNum = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.WhiteTorch, 0, 0, 1, i % 2 == 0 ? Color.White : Color.Black, 3); Main.dust[dustNum].noGravity = true; } } diff --git a/Content/Projectiles/GhostFreakPossesionProjectile.png b/Content/Projectiles/GhostFreakPossesionProjectile.png new file mode 100644 index 0000000000000000000000000000000000000000..6a869396dfc4e3cd341f678085032b7227c531ac GIT binary patch literal 491 zcmVPx$rAb6VR9J=0m%U2FKoo_~iVw2EMX-_uYpcMrK8B@WB|>29B>}M#wn*UFSe ztur@>N|fx40RZ*;2VkiinG@e#8owX$TUXWC7$*ruV)m!?`pNpd`29$#&+AO;r+vsgx*HcDYVlK;{gv6DqN1_?s8SOlrISt ho{0MCN_`cK=o2+;wdOe1O|Sp}002ovPDHLkV1l();aLCx literal 0 HcmV?d00001 diff --git a/Content/Projectiles/GhostFreakProjectile.cs b/Content/Projectiles/GhostFreakProjectile.cs index d78e27b..26ca6e4 100644 --- a/Content/Projectiles/GhostFreakProjectile.cs +++ b/Content/Projectiles/GhostFreakProjectile.cs @@ -31,7 +31,7 @@ public override void SetDefaults() { public override void AI() { // Rotate velocity a tiny random amount each tick -> tentacle-like curve - float maxCurve = 0.30f; // radians; tweak for more/less wiggle + float maxCurve = 0.15f; // radians; tweak for more/less wiggle Projectile.velocity = Projectile.velocity.RotatedByRandom(maxCurve); // Slow down over time so it doesn’t go forever diff --git a/Content/Projectiles/HeatBlastBomb.cs b/Content/Projectiles/HeatBlastBomb.cs index 23aa5b4..ca02f36 100644 --- a/Content/Projectiles/HeatBlastBomb.cs +++ b/Content/Projectiles/HeatBlastBomb.cs @@ -18,7 +18,7 @@ public override void SetDefaults() { Projectile.height = 4; Projectile.aiStyle = ProjAIStyleID.Arrow; - AIType = ProjectileID.Grenade; + AIType = ProjectileID.Bullet; Projectile.friendly = true; } diff --git a/Content/Transformations/GhostFreak/GhostFreak_Head.png b/Content/Transformations/GhostFreak/GhostFreak_Head.png index 7d416c309fa811b34ee41347f84686e296b0b022..649c5913fdaa4a1c14372664256789c081693dd1 100644 GIT binary patch literal 951 zcmeAS@N?(olHy`uVBq!ia0vp^8Vn392^?%d*6dv(^+1ZTILO_JVcj{ImkbQdg`O^s zAr*7p-rAcblE~0@(f?!G8kK}xQI0CfX-!ijmh!P2@!IgkD9Cqe6h~N`pUxrnLdA)1 znDf$#{I=U0@7{CfpU8O$h5(z@>K1jyHMRF2pME+i?s28%kNS#@?;DGEPM*9yxyP`t zFYfN0|L-b#43ACUy#Djb>&iMi@3Jo6d1p(EPV$|oPltc^e_ptE+MRz*dehnG=Ktn? zr}ypWm&+2{>pY)*fAaI^&$#FJ-!&DljNN@Yw7>4)pZbEG5%2!mTb#ZBtbO0JZ{l;_ zMHStDy3BpQ0x&=r7-YKgmR&jF44d!3E@lQR$VT`X-5-!J z2wrNlYKr^RPb-4tLQgIBstnQW*LoTV7Nm|1gq(O_;R?8)&^*cxb^*n)@BztBXdV@$ dh7AWE{$XThYW(~8t#~fTJWp3Ymvv4FO#sy+v7`V1 literal 5325 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 true; + + public bool IsPossessed(NPC npc) { + foreach (Player p in Main.ActivePlayers) { + var omp = p.GetModPlayer(); + if (omp.inPossessionMode && omp.possessedTarget.whoAmI == npc.whoAmI) return true; + } + return false; + } + + public override void AI(NPC npc) { + if (IsPossessed(npc)) { + npc.velocity *= 0.68f; + } + } + + public override void DrawEffects(NPC npc, ref Color drawColor) { + if (IsPossessed(npc)) { + drawColor = new Color(170, 100, 255, 190); + } + } + + public override void PostDraw(NPC npc, SpriteBatch spriteBatch, Vector2 screenPos, Color drawColor) { + if (IsPossessed(npc)) { + if (Main.rand.NextBool(3)) { + Dust.NewDustPerfect(npc.Center + Main.rand.NextVector2Circular(npc.width * 0.6f, npc.height * 0.6f), + DustID.Ghost, new Vector2(0, -1.2f), 100, new Color(160, 210, 255), 1.5f).noGravity = true; + } + } + } +} \ No newline at end of file diff --git a/OmnitrixPlayer.cs b/OmnitrixPlayer.cs index a10b2c5..b1d4635 100644 --- a/OmnitrixPlayer.cs +++ b/OmnitrixPlayer.cs @@ -203,6 +203,8 @@ public override void PostUpdateBuffs() { } else { if (omnitrixSlot.FunctionalItem.type == ModContent.ItemType()) TransformationHandler.Detransform(Player, advancedCircuitMatrixEquippedWhileTransformed ? cooldownTime * 2 : cooldownTime); + if (omnitrixSlot.FunctionalItem.type == ModContent.ItemType()) + TransformationHandler.Detransform(Player, 0, addCooldown: false); } advancedCircuitMatrixEquippedWhileTransformed = false; @@ -986,6 +988,15 @@ public override void PreUpdate() { colourAmount += 0.1f; + if (inPossessionMode) { + if (Main.GameUpdateCount % 60 == 0) { + int dotDamage = 35; + possessedTarget.life -= dotDamage; + if (possessedTarget.life < 1) possessedTarget.life = 1; + CombatText.NewText(possessedTarget.Hitbox, new Color(180, 80, 255), dotDamage, dramatic: true); + } + } + if (PrimaryAbilityEnabled && currTransformation == TransformationEnum.GhostFreak) { // Core noclip setup (DragonLens-style) Player.gravity = 0f; // disable gravity multiplier diff --git a/bossTrackerNPC.cs b/bossTrackerNPC.cs index 4a8ec99..0cb2eed 100644 --- a/bossTrackerNPC.cs +++ b/bossTrackerNPC.cs @@ -76,10 +76,24 @@ public override void OnKill(NPC npc) { } } - if (eaterCount > 1) { + if (eaterCount > 1) return; + + int twinsCount = 0; + + if (npc.type == NPCID.Retinazer || npc.type == NPCID.Spazmatism) { + for (int i = 0; i < Main.npc.Length; i++) { + if (Main.npc[i].type == NPCID.Retinazer || Main.npc[i].type == NPCID.Spazmatism) { + if (Main.npc[i].active) { + twinsCount++; + } + } + } } + if (twinsCount > 1) + return; + string msg = $"{Main.player[credited].name} dealt the most damage!"; var player = Main.player[credited]; @@ -145,6 +159,10 @@ public override void OnKill(NPC npc) { .addTransformation(TransformationEnum.ChromaStone); break; } + case NPCID.Retinazer: + case NPCID.Spazmatism: + player.GetModPlayer().addTransformation(TransformationEnum.EyeGuy); + break; default: break; } From 98830f922d8b0fdc0ff6d48a370e75ceaa451d7d Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Fri, 27 Feb 2026 16:04:25 +1100 Subject: [PATCH 08/25] Boom --- Content/Items/Weapons/PlumbersBadge.cs | 12 +++- Content/Projectiles/DiamondHeadProjectile.cs | 6 ++ Content/Projectiles/Explosion.cs | 9 ++- Content/Projectiles/GhostFreakProjectile.cs | 21 +++--- Content/Projectiles/GiantDiamondProjectile.cs | 50 +++++++++++++ .../Projectiles/GiantDiamondProjectile.png | Bin 0 -> 1086 bytes Content/Projectiles/HeatBlastBomb.cs | 12 ++-- .../DiamondHead/DiamondHead.cs | 4 +- .../DiamondHead/DiamondHeadAlt_Body.png | Bin 0 -> 3043 bytes .../DiamondHead/DiamondHeadAlt_Legs.png | Bin 0 -> 4710 bytes Localization/en-US_Mods.Ben10Mod.hjson | 68 ++---------------- OmnitrixPlayer.cs | 2 + 12 files changed, 100 insertions(+), 84 deletions(-) create mode 100644 Content/Projectiles/GiantDiamondProjectile.cs create mode 100644 Content/Projectiles/GiantDiamondProjectile.png create mode 100644 Content/Transformations/DiamondHead/DiamondHeadAlt_Body.png create mode 100644 Content/Transformations/DiamondHead/DiamondHeadAlt_Legs.png diff --git a/Content/Items/Weapons/PlumbersBadge.cs b/Content/Items/Weapons/PlumbersBadge.cs index c06ca72..52e8162 100644 --- a/Content/Items/Weapons/PlumbersBadge.cs +++ b/Content/Items/Weapons/PlumbersBadge.cs @@ -30,6 +30,7 @@ private int GetUltimateProjectileType(OmnitrixPlayer omp) return omp.currTransformation switch { TransformationEnum.EyeGuy => ModContent.ProjectileType(), TransformationEnum.GhostFreak => ModContent.ProjectileType(), + TransformationEnum.DiamondHead => ModContent.ProjectileType(), _ => 0 }; } @@ -123,6 +124,7 @@ public override void HoldItem(Player player) Item.useStyle = ItemUseStyleID.Swing; Item.ArmorPenetration = 0; Item.UseSound = null; + Item.channel = false; OmnitrixEnergyUse = 0; @@ -158,6 +160,7 @@ public override void HoldItem(Player player) Item.useTime = Item.useAnimation = 8; Item.shootSpeed = 35f; Item.ArmorPenetration = 25; + OmnitrixEnergyUse = omp.ultimateAttack ? 25 : 0; break; case TransformationEnum.RipJaws: @@ -269,9 +272,12 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, break; case TransformationEnum.DiamondHead: - projType = ModContent.ProjectileType(); - finalDamage = (int)(damage * 0.5f); - velocity.Y += Main.rand.NextFloat(-0.35f, 0.35f); + projType = omp.ultimateAttack ? ModContent.ProjectileType() : ModContent.ProjectileType(); + finalDamage = omp.ultimateAttack ? damage * 5 : (int)(damage * 0.5f); + if (omp.ultimateAttack) { + velocity = Vector2.Zero; + position = Main.MouseWorld; + } break; case TransformationEnum.RipJaws: diff --git a/Content/Projectiles/DiamondHeadProjectile.cs b/Content/Projectiles/DiamondHeadProjectile.cs index 6e140f9..f712ff1 100644 --- a/Content/Projectiles/DiamondHeadProjectile.cs +++ b/Content/Projectiles/DiamondHeadProjectile.cs @@ -5,6 +5,8 @@ using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading.Tasks; +using Terraria; +using Terraria.DataStructures; using Terraria.ID; using Terraria.ModLoader; @@ -25,6 +27,10 @@ public override void SetDefaults() { Projectile.penetrate = 2; } + public override void OnSpawn(IEntitySource source) { + Projectile.velocity = Projectile.velocity.RotatedByRandom(0.05f); + } + public override void AI() { Projectile.spriteDirection = Projectile.direction; } diff --git a/Content/Projectiles/Explosion.cs b/Content/Projectiles/Explosion.cs index ea989ec..1aab9d8 100644 --- a/Content/Projectiles/Explosion.cs +++ b/Content/Projectiles/Explosion.cs @@ -31,8 +31,8 @@ public override void ModifyDamageHitbox(ref Rectangle hitbox) { int explosionRadius = (int)Projectile.ai[0]; // explosion size hitbox = new Rectangle( - (int)(Projectile.Center.X - explosionRadius / 2), - (int)(Projectile.Center.Y - explosionRadius / 2), + (int)(Projectile.Center.X - explosionRadius), + (int)(Projectile.Center.Y - explosionRadius), explosionRadius, explosionRadius ); @@ -42,9 +42,12 @@ public override void OnSpawn(Terraria.DataStructures.IEntitySource source) { // Optional visuals SoundEngine.PlaySound(SoundID.Item14, Projectile.position); - for (int i = 0; i < 30; i++) + for (int i = 0; i < 30; i++) { Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.Smoke, Main.rand.NextFloat(-6, 6), Main.rand.NextFloat(-6, 6)); + int dustNum = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.Torch, + Main.rand.NextFloat(-25, 25), Main.rand.NextFloat(0, 25), Scale: 3); + } } } } diff --git a/Content/Projectiles/GhostFreakProjectile.cs b/Content/Projectiles/GhostFreakProjectile.cs index 26ca6e4..2b201e7 100644 --- a/Content/Projectiles/GhostFreakProjectile.cs +++ b/Content/Projectiles/GhostFreakProjectile.cs @@ -18,14 +18,15 @@ public class GhostFreakProjectile : ModProjectile { public override void SetDefaults() { - Projectile.width = (int)(Projectile.width * 0.6f); - Projectile.height = (int)(Projectile.height * 0.6f); - Projectile.scale = 0.6f; - Projectile.friendly = true; - Projectile.hostile = false; - Projectile.penetrate = -1; - Projectile.timeLeft = 35; - Projectile.DamageType = DamageClass.Magic; + Projectile.width = (int)(Projectile.width * 0.6f); + Projectile.height = (int)(Projectile.height * 0.6f); + Projectile.scale = 0.6f; + Projectile.friendly = true; + Projectile.hostile = false; + Projectile.penetrate = -1; + Projectile.timeLeft = 35; + Projectile.DamageType = DamageClass.Magic; + Projectile.usesLocalNPCImmunity = true; } @@ -41,6 +42,10 @@ public override void AI() { Projectile.rotation = Projectile.velocity.ToRotation() + MathHelper.PiOver2; } + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { + if (Main.rand.NextBool(5)) target.AddBuff(BuffID.Confused, 60 * 5); + } + public override void EmitEnchantmentVisualsAt(Vector2 boxPosition, int boxWidth, int boxHeight) { oddEven++; Random random = new Random(); diff --git a/Content/Projectiles/GiantDiamondProjectile.cs b/Content/Projectiles/GiantDiamondProjectile.cs new file mode 100644 index 0000000..bd41422 --- /dev/null +++ b/Content/Projectiles/GiantDiamondProjectile.cs @@ -0,0 +1,50 @@ +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Threading.Tasks; +using Terraria; +using Terraria.DataStructures; +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Projectiles { + public class GiantDiamondProjectile : ModProjectile { + private int timeAlive = 0; + + public override void SetDefaults() { + Projectile.width = 64; + Projectile.height = 128; + + Projectile.friendly = true; + Projectile.hostile = false; + + Projectile.DamageType = DamageClass.Ranged; + Projectile.penetrate = -1; + Projectile.tileCollide = true; + Projectile.ignoreWater = true; + } + + public override void OnSpawn(IEntitySource source) { + if (Projectile.ai[0] == 0) { + Projectile.NewProjectile(source, Projectile.position + new Vector2(Projectile.width + Main.rand.Next(15, 25), 0), Projectile.velocity, this.Type, Projectile.damage, 0, Projectile.owner, 1); + Projectile.NewProjectile(source, Projectile.position - new Vector2(Projectile.width - Main.rand.Next(15, 25), 0), Projectile.velocity, this.Type, Projectile.damage, 0, Projectile.owner, 1); + } + } + + public override void AI() { + timeAlive++; + Projectile.velocity.Y = (float)Math.Pow(timeAlive / 10f, 2); + } + + public override void OnKill(int timeLeft) { + for (int i = 0; i < 10; i++) { + int dustNum = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.GemDiamond, + 1, 1, 0, Color.White, 2); + Main.dust[dustNum].noGravity = true; + } + } + } +} diff --git a/Content/Projectiles/GiantDiamondProjectile.png b/Content/Projectiles/GiantDiamondProjectile.png new file mode 100644 index 0000000000000000000000000000000000000000..4e7a1331d28891ab25d5937f838877b06e1337b3 GIT binary patch literal 1086 zcmV-E1i|}>P)Px&_(?=TRCt{2ok?yRF%U(og=~UknG0BkcDesW?44lc0$FC*g;_||>Vaf)sDaZ5 z1lY0!cK!d@O;T2K0xg-FS^YkpCym26X*61rKB=^7ZU)|8_RlF$pi02y_5SEf=4Rl{ zn9HB_1Ky0;ofibu{W(Ck&prCS3;XK_0DS);dPNunh_!T(K1!N`L4Zgrf$5_pDd?U6 zeghooUqAnzfByCF=jv~lR{(f_+0Pdkq(Z>5c+}PeDe)Q*+4q-{qClJgTly#s3iu4j zNFOCZfhYmK^ik3j@EAalK8l+HF#kNUrA*wna<82LGJ&QA-NuZa^p+0~A(ssoJC?fFXSpCk6QiXrxcrHVpxc z>7%$P$TL7QeWGK?CqN*56bA)kQ8f9TmSHbv`Y0;}8QowIkn}F4^ih-)3<9Fxp`1R7 zih@Bv)T;|gA4NgIARzdajLThAN}(W&08RW+xyxo@29z-AiB;e+hZ9iH$#1KiNz$in$t%e)No8d1?i(wC~zClLi#9AEq($jN*@(Vf!%I7DujZk0X?LTTGYBGprQ0p zM-7=>zFWP>2G`^nuI(jSo_Y+N7NfEhwPu28cg(`ao)cBn5^Rvy0rDEV&JOJ;&`KZFw%&fIg#Rzl`(nh{eZCC+2U53e?s#qty#N3J07*qoM6N<$ Ef_}Bk#{d8T literal 0 HcmV?d00001 diff --git a/Content/Projectiles/HeatBlastBomb.cs b/Content/Projectiles/HeatBlastBomb.cs index ca02f36..b3be1cd 100644 --- a/Content/Projectiles/HeatBlastBomb.cs +++ b/Content/Projectiles/HeatBlastBomb.cs @@ -23,22 +23,20 @@ public override void SetDefaults() { } public override void EmitEnchantmentVisualsAt(Vector2 boxPosition, int boxWidth, int boxHeight) { - Random random = new Random(); - for (int i = 0; i < 6; i++) { - int dustNum = Dust.NewDust(boxPosition, 1, 1, DustID.Torch, 0, 0, 1, Color.White, 2); - Main.dust[dustNum].noGravity = true; - } + Random random = new Random(); + int dustNum = Dust.NewDust(boxPosition, 1, 1, DustID.Torch, 0, 0, 1, Color.White, 5); + Main.dust[dustNum].noGravity = true; } public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { base.OnHitNPC(target, hit, damageDone); - Projectile.NewProjectile(Projectile.GetSource_Death(), Projectile.Center, Vector2.Zero, ModContent.ProjectileType(), Projectile.damage, 0, -1, 100); + Projectile.NewProjectile(Projectile.GetSource_Death(), Projectile.Center, Vector2.Zero, ModContent.ProjectileType(), Projectile.damage, 0, -1, 50); } public override bool OnTileCollide(Vector2 oldVelocity) { - Projectile.NewProjectile(Projectile.GetSource_Death(), Projectile.Center, Vector2.Zero, ModContent.ProjectileType(), Projectile.damage, 0, -1, 100); + Projectile.NewProjectile(Projectile.GetSource_Death(), Projectile.Center, Vector2.Zero, ModContent.ProjectileType(), Projectile.damage, 0, -1, 50); return base.OnTileCollide(oldVelocity); } } diff --git a/Content/Transformations/DiamondHead/DiamondHead.cs b/Content/Transformations/DiamondHead/DiamondHead.cs index f7722da..9683490 100644 --- a/Content/Transformations/DiamondHead/DiamondHead.cs +++ b/Content/Transformations/DiamondHead/DiamondHead.cs @@ -25,8 +25,8 @@ public override void Load() { //Add a separate set of equip textures by providing a custom name reference instead of an item reference //EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.Head}", EquipType.Head, name: "BlockyAlt", equipTexture: new BlockyHead()); - //EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.Body}", EquipType.Body, name: "BlockyAlt"); - //EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.Legs}", EquipType.Legs, name: "BlockyAlt"); + EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.Body}", EquipType.Body, this, "DiamondHeadAlt"); + EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.Legs}", EquipType.Legs, this, "DiamondHeadAlt"); } // Called in SetStaticDefaults diff --git a/Content/Transformations/DiamondHead/DiamondHeadAlt_Body.png b/Content/Transformations/DiamondHead/DiamondHeadAlt_Body.png new file mode 100644 index 0000000000000000000000000000000000000000..d0b9f3563bb526a7dc6b556873e4a59fb600a481 GIT binary patch literal 3043 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 ZQfe@y&8Nng*%fM8gU5Y5h{w(q`~&TD`b7W$ literal 0 HcmV?d00001 diff --git a/Content/Transformations/DiamondHead/DiamondHeadAlt_Legs.png b/Content/Transformations/DiamondHead/DiamondHeadAlt_Legs.png new file mode 100644 index 0000000000000000000000000000000000000000..eb6a06684fe95cf508fb220f0626e080bd7afcb8 GIT binary patch literal 4710 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 LVUyzh0Eqt!x9;Bu literal 0 HcmV?d00001 diff --git a/Localization/en-US_Mods.Ben10Mod.hjson b/Localization/en-US_Mods.Ben10Mod.hjson index 141caa9..5d9bcca 100644 --- a/Localization/en-US_Mods.Ben10Mod.hjson +++ b/Localization/en-US_Mods.Ben10Mod.hjson @@ -272,94 +272,39 @@ Buffs: { Description: Florauna } - XLR8_Primary_Buff: { - DisplayName: XLR8 Speed Boost - Description: XLR8 Speed Boost - } - - XLR8_Primary_Cooldown_Buff: { - DisplayName: XLR8 Speed Boost Cooldown - Description: XLR8 Speed Boost Cooldown - } - - HeatBlast_Primary_Buff: { - DisplayName: Heatblast Flame Aura - Description: Heatblast Flame Aura - } - - HeatBlast_Primary_Cooldown_Buff: { - DisplayName: Heatblast Flame Aura Cooldown - Description: Heatblast Flame Aura Cooldown - } - - DiamondHead_Primary_Buff: { - DisplayName: Diamondhead Primary Ability - Description: Immune to damage but unable to move - } - - DiamondHead_Primary_Cooldown_Buff: { - DisplayName: Diamondhead Primary Cooldown - Description: Cooldown for primary ability - } - - ChromaStone_Primary_Buff: { - DisplayName: Chromastone Primary Ability - Description: Absorb and redirect incoming damage - } - - ChromaStone_Primary_Cooldown_Buff: { - DisplayName: Chromastone Primary Cooldown - Description: Cooldown for primary ability - } - TransformationCooldown_Buff: { Description: Timeout DisplayName: Cannot transform while timed out } - BuzzShock_Primary_Buff: { - DisplayName: Buzz Shock_ Primary_ Buff - Description: Mods.Ben10Mod.Buffs.BuzzShock_Primary_Buff.Description - } - - BuzzShock_Primary_Cooldown_Buff: { - DisplayName: Buzz Shock_ Primary_ Cooldown_ Buff - Description: Mods.Ben10Mod.Buffs.BuzzShock_Primary_Cooldown_Buff.Description - } - EnemySlow: { Description: Mods.Ben10Mod.Buffs.EnemySlow.Description DisplayName: Enemy Slow } - GhostFreakPossesion: { - DisplayName: Ghost Freak Possesion - Description: Mods.Ben10Mod.Buffs.GhostFreakPossesion.Description - } - EyeGuy_Buff: { Description: Mods.Ben10Mod.Buffs.EyeGuy_Buff.Description - DisplayName: Eye Guy_ Buff + DisplayName: Opticoid } UltimateAbility_Cooldown: { - DisplayName: Ultimate Ability_ Cooldown - Description: Mods.Ben10Mod.Buffs.UltimateAbility_Cooldown.Description + DisplayName: Ultimate Ability Cooldown + Description: Ultimate Ability Cooldown } OmnitrixUpdating: { - Description: Mods.Ben10Mod.Buffs.OmnitrixUpdating.Description + Description: Omnitrix is undergoing updates DisplayName: Omnitrix Updating } PrimaryAbility: { DisplayName: Primary Ability - Description: Mods.Ben10Mod.Buffs.PrimaryAbility.Description + Description: Primary Ability Activated } PrimaryAbilityCooldown: { DisplayName: Primary Ability Cooldown - Description: Mods.Ben10Mod.Buffs.PrimaryAbilityCooldown.Description + Description: Primary Ability On Cooldown } } @@ -385,6 +330,7 @@ Projectiles: { GhostFreakPossesionProjectile.DisplayName: Ghost Freak Possesion Projectile EyeGuyLaserbeam.DisplayName: Eye Guy Laserbeam EyeGuyUltimateBeam.DisplayName: Eye Guy Ultimate Beam + GiantDiamondProjectile.DisplayName: Giant Diamond Projectile } Tiles: { diff --git a/OmnitrixPlayer.cs b/OmnitrixPlayer.cs index b1d4635..55b168f 100644 --- a/OmnitrixPlayer.cs +++ b/OmnitrixPlayer.cs @@ -102,6 +102,7 @@ public override void SaveData(TagCompound tag) tag["masterControl"] = masterControl; tag["currTransformation"] = (int)currTransformation; + tag["omnitrixEnergy"] = omnitrixEnergy; // Roster (5 slots) tag["roster"] = transformations.Select(t => (int)t).ToArray(); @@ -121,6 +122,7 @@ public override void LoadData(TagCompound tag) int currInt = -1; tag.TryGet("currTransformation", out currInt); currTransformation = (TransformationEnum)currInt; + omnitrixEnergy = tag.TryGet("omnitrixEnergy", out omnitrixEnergy) ? omnitrixEnergy : 0f; // Load roster if (tag.TryGet("roster", out int[] rosterArray) && rosterArray != null) From 89a899d0652552142a9cb16aa68892807b80d54c Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Sat, 28 Feb 2026 07:59:25 +1100 Subject: [PATCH 09/25] Replaced heatblast wings with an extra jump accessory --- .../Accessories/AdvancedCircuitMatrix.cs | 1 - .../HeatBlastExtraJumpAccessory.cs | 36 ++++++++++++ .../HeatBlastExtraJumpAccessory.png | Bin 0 -> 377 bytes .../Items/Accessories/Wings/HeatBlastWings.cs | 52 ------------------ .../Accessories/Wings/HeatBlastWings_Wing.png | Bin 822 -> 0 bytes .../Wings/HeatBlastWings_Wings.png | Bin 205 -> 0 bytes Content/Projectiles/GhostFreakProjectile.cs | 18 +++--- Content/Projectiles/WildVineProjectile.png | Bin 124 -> 751 bytes .../Projectiles/WildVineProjectile_Chain.png | Bin 127 -> 367 bytes Localization/en-US_Mods.Ben10Mod.hjson | 7 ++- OmnitrixPlayer.cs | 12 ++-- 11 files changed, 57 insertions(+), 69 deletions(-) create mode 100644 Content/Items/Accessories/HeatBlastExtraJumpAccessory.cs create mode 100644 Content/Items/Accessories/HeatBlastExtraJumpAccessory.png delete mode 100644 Content/Items/Accessories/Wings/HeatBlastWings.cs delete mode 100644 Content/Items/Accessories/Wings/HeatBlastWings_Wing.png delete mode 100644 Content/Items/Accessories/Wings/HeatBlastWings_Wings.png diff --git a/Content/Items/Accessories/AdvancedCircuitMatrix.cs b/Content/Items/Accessories/AdvancedCircuitMatrix.cs index 18b0735..dfb3785 100644 --- a/Content/Items/Accessories/AdvancedCircuitMatrix.cs +++ b/Content/Items/Accessories/AdvancedCircuitMatrix.cs @@ -18,6 +18,5 @@ public override void SetDefaults() { public override void UpdateAccessory(Player player, bool hideVisual) { var omp = player.GetModPlayer(); omp.advancedCircuitMatrix = true; - omp.omnitrixEnergyRegen += 50; } } \ No newline at end of file diff --git a/Content/Items/Accessories/HeatBlastExtraJumpAccessory.cs b/Content/Items/Accessories/HeatBlastExtraJumpAccessory.cs new file mode 100644 index 0000000..40f2457 --- /dev/null +++ b/Content/Items/Accessories/HeatBlastExtraJumpAccessory.cs @@ -0,0 +1,36 @@ +using Microsoft.Xna.Framework; +using Terraria; +using Terraria.Enums; +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Items.Accessories; + +public class HeatBlastExtraJumpAccessory : ModItem { + public override void SetDefaults() { + Item.DefaultToAccessory(20, 26); + Item.SetShopValues(ItemRarityColor.Green2, 005000); + } + + public override void UpdateAccessory(Player player, bool hideVisual) { + player.GetJumpState().Enable(); + } +} + +public class HeatBlastExtraJump : ExtraJump { + public override Position GetDefaultPosition() => new After(BlizzardInABottle); + public override float GetDurationMultiplier(Player player) => 2.25f; + + public override void UpdateHorizontalSpeeds(Player player) { + player.runAcceleration *= 1.75f; + player.maxRunSpeed *= 2f; + } + + public override void ShowVisuals(Player player) { + for (int i = 0; i < 6; i++) { + int dustNum = Dust.NewDust(new Vector2(player.position.X, player.position.Y + player.height), player.width, + 0, DustID.Torch, 1F, 1F, Scale: 2f); + Main.dust[dustNum].noGravity = true; + } + } +} \ No newline at end of file diff --git a/Content/Items/Accessories/HeatBlastExtraJumpAccessory.png b/Content/Items/Accessories/HeatBlastExtraJumpAccessory.png new file mode 100644 index 0000000000000000000000000000000000000000..33d0da0025110ba61302f84f89d375e26b9658b4 GIT binary patch literal 377 zcmV-<0fzpGP)Px$Gf6~2R7i>KRXc71F%W$qPOzro0A7WZh$86%U8FRTa*Q+_CwIspLP<#%Iak1Y zgh0Uzyd8T#6i_kJYG-ZF^YeS7^#CTu4=;N=))u?pp84!|FP0zf5;J+RsS*O+#@ zTv6^XV3;ub7G@DZiF57%1e{sRm}Q!p!XO|3ePD7EDPYJH6a?f&j)FFC1>{AlT@(=A zq)4h-02w5jan>=zE)VF)5M{)sJj+-}DuKqfDTR?T|pYu!fkkvs1c8}|Qrzf*7k Xw7XV;t5+JK00000NkvXXu0mjfImMWm literal 0 HcmV?d00001 diff --git a/Content/Items/Accessories/Wings/HeatBlastWings.cs b/Content/Items/Accessories/Wings/HeatBlastWings.cs deleted file mode 100644 index ef9f00c..0000000 --- a/Content/Items/Accessories/Wings/HeatBlastWings.cs +++ /dev/null @@ -1,52 +0,0 @@ -using Microsoft.Xna.Framework; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Terraria; -using Terraria.DataStructures; -using Terraria.ID; -using Terraria.ModLoader; - -namespace Ben10Mod.Content.Items.Accessories.Wings { - [AutoloadEquip(EquipType.Wings)] - public class HeatBlastWings : ModItem { - - public override void SetStaticDefaults() { - ArmorIDs.Wing.Sets.Stats[Item.wingSlot] = new WingStats(1, 1, 1); - } - - public override void SetDefaults() { - Item.width = 24; - Item.height = 26; - Item.value = 0; - Item.rare = ItemRarityID.Green; - Item.accessory = true; - } - - public override void VerticalWingSpeeds(Player player, ref float ascentWhenFalling, ref float ascentWhenRising, - ref float maxCanAscendMultiplier, ref float maxAscentMultiplier, ref float constantAscend) { - ascentWhenFalling = 0.1f; // Falling glide speed - ascentWhenRising = 1f; // Rising speed - maxCanAscendMultiplier = 1f; - maxAscentMultiplier = 1f; - constantAscend = 1f; - } - - public override bool WingUpdate(Player player, bool inUse) - { - if (player.controlJump) - { - Random rand = new Random(); - int dustNum = Dust.NewDust(new Vector2(player.position.X, player.height + player.position.Y), player.width, 0, DustID.SomethingRed, 0, 0, 0, Color.White); - Main.dust[dustNum].noGravity = true; - dustNum = Dust.NewDust(new Vector2(player.position.X, player.height + player.position.Y), player.width, 0, DustID.FlameBurst, 0, 0, 0, Color.White); - Main.dust[dustNum].noGravity = true; - dustNum = Dust.NewDust(new Vector2(player.position.X, player.height + player.position.Y), player.width, 0, DustID.SolarFlare, 0, 0, 0, Color.White); - Main.dust[dustNum].noGravity = true; - } - return base.WingUpdate(player, inUse); - } - } -} diff --git a/Content/Items/Accessories/Wings/HeatBlastWings_Wing.png b/Content/Items/Accessories/Wings/HeatBlastWings_Wing.png deleted file mode 100644 index f8633e131f26b532b14ecc332465ae4433b938a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 822 zcmeAS@N?(olHy`uVBq!ia0vp^VGIn60UT^VmTE<39FSrx4sv&5Sa(k5B?AM~2TvEr zkcv5P?*?`WI|{Hp=zAkrBX+P`r;73YgWcwz_~tnrsn+Q@|41-Kev*)ES((-3m!7MB z|Bh?pZS;Mx+-PM<`BWyLnZ$tt-}dbN4N?8`%c~)P-cW`E5F4b}6@au6J5xdHtTc|3!Q3Z04@@7S`F= zyTtcRj?(lwS-F*ezx_Y1d@y*q%lz31ow-k*3GKG(44!yK_41Q_RrP!R{ixaFH#ue| zP-;nJQuhAS`m22JEqyjgTIpb7QMh4kz0hrseNxubA7nmy<}+DhS?8MCe?CR3+a}%> zuKu?C-z}-?%%*JLN!2_4t8UcIopz)9z5RLLv|OdbOHampdi(fe)vB#Rw@=(nyI=Bb zi(gX4+!LxFcggRYrnK>GPF?th=(VBA$4j>6$DOTaeV6=uNw~lluA&S5yuUVDK3TnS z>z`*=m(TXj(S6OuHq~sS_nNz}LbiAE)=!q+x;4;gxyrVQg<&P@|CGdgCrNt-C%^rS z8sHCnzFjg)($7`S6xuy)X6IbV=PkU(!oM%%_Lja2TYgFH+Re7+T|19h*-uNiTx@Nz z*t)&O^qNe|#+frSuKDPtspTEDSzkM2<_=L~;qQrQkHW6p0P=xi05I z|5?TO-nCE7*W2BVNy?54H(0TyGdAgM*z#SzIR?fXjUTUhVP?FMKQn7hEhv2vx&z&x*-9X;mEakt tG3V_;Lq;I)(1Nf2xt#tBfK0lA3aKOa85r3QY?=kK*3;F`Wt~$(6996U7|H+u diff --git a/Content/Projectiles/GhostFreakProjectile.cs b/Content/Projectiles/GhostFreakProjectile.cs index 2b201e7..b315558 100644 --- a/Content/Projectiles/GhostFreakProjectile.cs +++ b/Content/Projectiles/GhostFreakProjectile.cs @@ -18,15 +18,15 @@ public class GhostFreakProjectile : ModProjectile { public override void SetDefaults() { - Projectile.width = (int)(Projectile.width * 0.6f); - Projectile.height = (int)(Projectile.height * 0.6f); - Projectile.scale = 0.6f; - Projectile.friendly = true; - Projectile.hostile = false; - Projectile.penetrate = -1; - Projectile.timeLeft = 35; - Projectile.DamageType = DamageClass.Magic; - Projectile.usesLocalNPCImmunity = true; + Projectile.width = (int)(Projectile.width * 0.6f); + Projectile.height = (int)(Projectile.height * 0.6f); + Projectile.scale = 0.6f; + Projectile.friendly = true; + Projectile.hostile = false; + Projectile.penetrate = -1; + Projectile.timeLeft = 35; + Projectile.DamageType = DamageClass.Magic; + Projectile.tileCollide = false; } diff --git a/Content/Projectiles/WildVineProjectile.png b/Content/Projectiles/WildVineProjectile.png index 8d2ac97dc1485c2d6cd0f755db97ed44568adbce..dcf8df642880a67d8704032ed269e5faf372e12e 100644 GIT binary patch delta 714 zcmV;*0yX`7?*))Be*&pVL_t(IjeV5OauY`sg}>X~(=(c3JhCKYsf0x=yCArV1h9D= z_IU#KtW#u{P1dkWWkDq`kt+5OQYKK9$hMGd{TW8qbY~$MpfO&mAxh5Yuz=u)6u1jrhSe>l}F-%!+61A2cI)Y^(q z6VJ+ez^_k-=YVn=VhnV)BYN*<*jUqf5VE^7WBp->jUbZq;;RN9)s`vRLl7;DN6MJd%B=bk7Q zo;@C*0J6HGwHe|8JY*F`;XG-@;2n&61=p&=QpIrNf3`sjl$#1XsL!etfQazVA31ms zfl=R~1eWRwG-xA~8v)}3$EfcZ?l}&-4uE)hK{5c{H*TB11Ici0$) zdyahUu!&|mbhN**1SO%A3LoAV3q?CGa|t3r85r(6T6YWrjQbAnpj=m^6-9H?vQ$$f z%Zl#ne;G2LEdEJkVMH-7+;yaNjW0ZtL4o)1^OJ)w&OYS?m>f8=hDHGAVAOMD z4a3o)qq?dY_X|AG+%U9moe9Oop>2O_Xl_`HM1?5U?7f|Fea#ZaU?a_o?+-5z?M1-# wZAPx$DM>^@R5*>jl)Xv=K@>*M1W5!*AQllJ5fZjgNFxej7ws&CbPFjIAH!rFqwTRGqTUsgs&}`YbCngbbdSZXX$qVtWKNtcKYD+F%v9eZh z;)+K#15jQM0QlLh_$5xQC^4_M4h+ORPxkZdaK|B)nq^Pi*eDoc6Zju_a^ghUb%l5v z>WV`q6BlS3*K8G|7ZXF4yW$UVQbKlpYPZ?r#U}s@jj;{5N-vW);$NA|UY$L-MjikF N002ovPDHLkV1nQokAeUI literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rf|#^NA%Cx&(BWL^R}mYyz-Ar`&K zDGp4}f?*mXjdy^CFnGH9xvX unlockedTransformation = new List() { TransformationEnum.HeatBlast }; @@ -257,8 +255,8 @@ public override void PostUpdateBuffs() { // Heatblast Transformation if (currTransformation == TransformationEnum.HeatBlast) { - Player.fireWalk = true; - Player.lavaImmune = true; + Player.fireWalk = true; + Player.lavaImmune = true; } // Diamondhead Transformation @@ -396,7 +394,8 @@ public override void PostUpdate() { Player.fireWalk = true; Player.lavaImmune = true; - abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } + abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); + } // Diamondhead Transformation @@ -827,6 +826,7 @@ public override void FrameEffects() { public override void PreUpdateMovement() { DashMovement(); + if (PrimaryAbilityEnabled && currTransformation == TransformationEnum.GhostFreak) { // Phasing Logic Vector2 input = Vector2.Zero; if (Player.controlLeft) input.X -= 1f; From 4ae3f7e8e6e299b2bb7fa8c6f022eb208642cdd0 Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Mon, 2 Mar 2026 20:32:10 +1100 Subject: [PATCH 10/25] Added ultimate abilities to some other aliens --- Content/Interface/AlienSelectionScreen.cs | 12 +- .../Accessories/AdvancedCircuitMatrix.cs | 1 + .../HeatBlastExtraJumpAccessory.cs | 10 +- .../Items/Accessories/PrototypeOmnitrix.cs | 12 -- .../Items/Accessories/RecalibratedOmnitrix.cs | 13 -- Content/Items/Materials/HeroFragment.cs | 26 +++ Content/Items/Materials/HeroFragment.png | Bin 0 -> 295 bytes .../Items/Weapons/HeavenlyCrystallineBadge.cs | 10 + .../Weapons/HeavenlyCrystallineBadge.png | Bin 0 -> 667 bytes Content/Items/Weapons/PlumberAgentBadge.cs | 17 +- Content/Items/Weapons/PlumberAgentBadge.png | Bin 646 -> 581 bytes ...berHelperBadge.cs => PlumberCadetBadge.cs} | 7 +- ...rHelperBadge.png => PlumberCadetBadge.png} | Bin .../Weapons/PlumberDeputyBadgeCrimtane.cs | 19 ++ ...ane.png => PlumberDeputyBadgeCrimtane.png} | Bin ...onite.cs => PlumberDeputyBadgeDemonite.cs} | 9 +- ...ite.png => PlumberDeputyBadgeDemonite.png} | Bin .../Items/Weapons/PlumberFieldProctorBadge.cs | 18 ++ .../Weapons/PlumberFieldProctorBadge.png | Bin 0 -> 646 bytes Content/Items/Weapons/PlumberMagisterBadge.cs | 15 +- .../Items/Weapons/PlumberMagisterBadge.png | Bin 581 -> 644 bytes .../Items/Weapons/PlumberMagistrataBadge.cs | 10 + .../Items/Weapons/PlumberMagistrataBadge.png | Bin 0 -> 680 bytes Content/Items/Weapons/PlumberProctorBadge.cs | 19 ++ Content/Items/Weapons/PlumberProctorBadge.png | Bin 0 -> 635 bytes .../Items/Weapons/PlumberSeniorAgentBadge.cs | 19 ++ .../Items/Weapons/PlumberSeniorAgentBadge.png | Bin 0 -> 643 bytes .../Items/Weapons/PlumberSeniorDeputyBadge.cs | 27 +++ .../Weapons/PlumberSeniorDeputyBadge.png | Bin 0 -> 646 bytes Content/Items/Weapons/PlumbersBadge.cs | 172 +++++++++--------- .../Weapons/ProvisionalAgentBadgeCrimtane.cs | 18 -- Content/Projectiles/ChromaStoneProjectile.cs | 7 +- Content/Projectiles/Explosion.cs | 2 - Content/Projectiles/HeatBlastBomb.cs | 8 +- .../HeatBlastUltimateProjectile.cs | 103 +++++++++++ .../HeatBlastUltimateProjectile.png | Bin 0 -> 6717 bytes Content/Tiles/PlumberCapsulePod.cs | 2 +- .../Transformations/HeatBlast/HeatBlast.cs | 3 + .../HeatBlast/HeatBlastAlt_Body.png | Bin 0 -> 3458 bytes .../HeatBlast/HeatBlastAlt_Head.png | Bin 0 -> 1326 bytes .../HeatBlast/HeatBlastAlt_Legs.png | Bin 0 -> 1927 bytes Localization/en-US_Mods.Ben10Mod.hjson | 81 +++++++-- OmnitrixItem.cs | 23 ++- OmnitrixPlayer.cs | 59 ++++-- OmnitrixProjectile.cs | 47 +++++ ShopNPC.cs | 19 ++ 46 files changed, 579 insertions(+), 209 deletions(-) create mode 100644 Content/Items/Materials/HeroFragment.cs create mode 100644 Content/Items/Materials/HeroFragment.png create mode 100644 Content/Items/Weapons/HeavenlyCrystallineBadge.cs create mode 100644 Content/Items/Weapons/HeavenlyCrystallineBadge.png rename Content/Items/Weapons/{PlumberHelperBadge.cs => PlumberCadetBadge.cs} (69%) rename Content/Items/Weapons/{PlumberHelperBadge.png => PlumberCadetBadge.png} (100%) create mode 100644 Content/Items/Weapons/PlumberDeputyBadgeCrimtane.cs rename Content/Items/Weapons/{ProvisionalAgentBadgeCrimtane.png => PlumberDeputyBadgeCrimtane.png} (100%) rename Content/Items/Weapons/{ProvisionalAgentBadgeDemonite.cs => PlumberDeputyBadgeDemonite.cs} (51%) rename Content/Items/Weapons/{ProvisionalAgentBadgeDemonite.png => PlumberDeputyBadgeDemonite.png} (100%) create mode 100644 Content/Items/Weapons/PlumberFieldProctorBadge.cs create mode 100644 Content/Items/Weapons/PlumberFieldProctorBadge.png create mode 100644 Content/Items/Weapons/PlumberMagistrataBadge.cs create mode 100644 Content/Items/Weapons/PlumberMagistrataBadge.png create mode 100644 Content/Items/Weapons/PlumberProctorBadge.cs create mode 100644 Content/Items/Weapons/PlumberProctorBadge.png create mode 100644 Content/Items/Weapons/PlumberSeniorAgentBadge.cs create mode 100644 Content/Items/Weapons/PlumberSeniorAgentBadge.png create mode 100644 Content/Items/Weapons/PlumberSeniorDeputyBadge.cs create mode 100644 Content/Items/Weapons/PlumberSeniorDeputyBadge.png delete mode 100644 Content/Items/Weapons/ProvisionalAgentBadgeCrimtane.cs create mode 100644 Content/Projectiles/HeatBlastUltimateProjectile.cs create mode 100644 Content/Projectiles/HeatBlastUltimateProjectile.png create mode 100644 Content/Transformations/HeatBlast/HeatBlastAlt_Body.png create mode 100644 Content/Transformations/HeatBlast/HeatBlastAlt_Head.png create mode 100644 Content/Transformations/HeatBlast/HeatBlastAlt_Legs.png create mode 100644 OmnitrixProjectile.cs diff --git a/Content/Interface/AlienSelectionScreen.cs b/Content/Interface/AlienSelectionScreen.cs index b8bbc54..a8e7413 100644 --- a/Content/Interface/AlienSelectionScreen.cs +++ b/Content/Interface/AlienSelectionScreen.cs @@ -194,7 +194,7 @@ public override void OnInitialize() slot.Height.Set(slotSize, 0f); slot.Left.Set(rosterStartX + i * (slotSize + 26f), 0f); slot.Top.Set(rosterY, 0f); - + slot.OnMouseOver += (_, _) => UpdateInfoPanel(TransformationEnum.None); int index = i; slot.OnLeftClick += (_, _) => AssignToSlot(index); slot.OnRightClick += (_, _) => ClearSlot(index); @@ -272,7 +272,10 @@ public override void OnInitialize() var closeBtn = new UITextPanel("Close Roster"); closeBtn.HAlign = 0.5f; closeBtn.Top.Set(-58f, 1f); - closeBtn.OnLeftClick += (_, _) => ModContent.GetInstance().HideMyUI(); + closeBtn.OnLeftClick += (_, _) => { + ModContent.GetInstance().HideMyUI(); + Main.LocalPlayer.GetModPlayer().showingUI = false; + }; mainPanel.Append(closeBtn); } @@ -297,8 +300,11 @@ public override void Update(GameTime gameTime) var player = Main.LocalPlayer.GetModPlayer(); - for (int i = 0; i < rosterSlots.Count; i++) + for (int i = 0; i < rosterSlots.Count; i++) { rosterSlots[i].SetImage(player.transformations[i].GetTransformationIcon()); + var i1 = i; + rosterSlots[i].OnMouseOver += (_, _) => UpdateInfoPanel(player.transformations[i1]); + } unlockedGrid.Clear(); foreach (var trans in player.unlockedTransformation) diff --git a/Content/Items/Accessories/AdvancedCircuitMatrix.cs b/Content/Items/Accessories/AdvancedCircuitMatrix.cs index dfb3785..2293be9 100644 --- a/Content/Items/Accessories/AdvancedCircuitMatrix.cs +++ b/Content/Items/Accessories/AdvancedCircuitMatrix.cs @@ -18,5 +18,6 @@ public override void SetDefaults() { public override void UpdateAccessory(Player player, bool hideVisual) { var omp = player.GetModPlayer(); omp.advancedCircuitMatrix = true; + omp.omnitrixEnergyRegen += 150; } } \ No newline at end of file diff --git a/Content/Items/Accessories/HeatBlastExtraJumpAccessory.cs b/Content/Items/Accessories/HeatBlastExtraJumpAccessory.cs index 40f2457..0e4b4fc 100644 --- a/Content/Items/Accessories/HeatBlastExtraJumpAccessory.cs +++ b/Content/Items/Accessories/HeatBlastExtraJumpAccessory.cs @@ -27,10 +27,16 @@ public override void UpdateHorizontalSpeeds(Player player) { } public override void ShowVisuals(Player player) { + + int offsetY = player.height - 6; + var omp = player.GetModPlayer(); + for (int i = 0; i < 6; i++) { - int dustNum = Dust.NewDust(new Vector2(player.position.X, player.position.Y + player.height), player.width, - 0, DustID.Torch, 1F, 1F, Scale: 2f); + int dustNum = Dust.NewDust(new Vector2(player.position.X, player.position.Y + offsetY), player.width, + 0, omp.snowflake ? DustID.IceTorch : DustID.Torch, 1F, 1F, Scale: 2f); Main.dust[dustNum].noGravity = true; } + if (!player.controlUseItem && Main.GameUpdateCount % 4 == 0) + player.direction = -player.direction; } } \ No newline at end of file diff --git a/Content/Items/Accessories/PrototypeOmnitrix.cs b/Content/Items/Accessories/PrototypeOmnitrix.cs index ba73432..7d21e5f 100644 --- a/Content/Items/Accessories/PrototypeOmnitrix.cs +++ b/Content/Items/Accessories/PrototypeOmnitrix.cs @@ -84,17 +84,6 @@ public override void UpdateAccessory(Player player, bool hideVisual) { omp.omnitrixEnergyMax += 300; transformations = player.GetModPlayer().transformations; - if (KeybindSystem.OpenTransformationScreen.JustPressed) { - if (!showingUI) { - player.GetModPlayer().transformations = transformations; - ModContent.GetInstance().ShowMyUI(); - showingUI = true; - } - else { - ModContent.GetInstance().HideMyUI(); - showingUI = false; - } - } if (KeybindSystem.TransformationKeybind.JustPressed && !player.GetModPlayer().isTransformed && !player.GetModPlayer().onCooldown) { omp.advancedCircuitMatrixEquippedWhileTransformed = omp.advancedCircuitMatrix; @@ -159,7 +148,6 @@ public override void UpdateInventory(Player player) { wasEquipedLastFrame = false; ModContent.GetInstance().HideMyUI(); - showingUI = false; if (player.GetModPlayer().isTransformed) { TransformationHandler.Detransform(player, omp.cooldownTime, true, true); } diff --git a/Content/Items/Accessories/RecalibratedOmnitrix.cs b/Content/Items/Accessories/RecalibratedOmnitrix.cs index bda2236..2998f62 100644 --- a/Content/Items/Accessories/RecalibratedOmnitrix.cs +++ b/Content/Items/Accessories/RecalibratedOmnitrix.cs @@ -21,7 +21,6 @@ public class RecalibratedOmnitrix : Omnitrix { public TransformationEnum[] transformations = new TransformationEnum[5]; bool wasEquipedLastFrame = false; - bool showingUI = false; Texture2D dynamicTexture; @@ -100,17 +99,6 @@ public override void UpdateAccessory(Player player, bool hideVisual) { transformations = player.GetModPlayer().transformations; - if (KeybindSystem.OpenTransformationScreen.JustPressed) { - if (!showingUI) { - player.GetModPlayer().transformations = transformations; - ModContent.GetInstance().ShowMyUI(); - showingUI = true; - } - else { - ModContent.GetInstance().HideMyUI(); - showingUI = false; - } - } if (KeybindSystem.TransformationKeybind.JustPressed && !player.GetModPlayer().isTransformed && !player.GetModPlayer().onCooldown) { TransformationHandler.Transform(player, transformations[transformationNum], 2); @@ -181,7 +169,6 @@ public override void UpdateInventory(Player player) { wasEquipedLastFrame = false; ModContent.GetInstance().HideMyUI(); - showingUI = false; if (player.GetModPlayer().isTransformed) { TransformationHandler.Detransform(player, omp.cooldownTime, true, true); } else { diff --git a/Content/Items/Materials/HeroFragment.cs b/Content/Items/Materials/HeroFragment.cs new file mode 100644 index 0000000..e5e37dc --- /dev/null +++ b/Content/Items/Materials/HeroFragment.cs @@ -0,0 +1,26 @@ +using Microsoft.Xna.Framework; +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Items.Materials; + +public class HeroFragment : ModItem { + public override void SetStaticDefaults() { + ItemID.Sets.ItemNoGravity[Type] = true; + ItemID.Sets.ItemIconPulse[Type] = true; + Item.ResearchUnlockCount = 25; + } + + public override void SetDefaults() { + Item.width = 24; + Item.height = 24; + Item.maxStack = Item.CommonMaxStack; + Item.value = Item.buyPrice(gold: 1); + Item.rare = ItemRarityID.Blue; + } + + public override void PostUpdate() { + Lighting.AddLight(Item.Center, Color.LimeGreen.ToVector3() * 0.6f * Main.essScale); + } +} \ No newline at end of file diff --git a/Content/Items/Materials/HeroFragment.png b/Content/Items/Materials/HeroFragment.png new file mode 100644 index 0000000000000000000000000000000000000000..e17f5ecd330cbb0179b58383a9538c09ed02ec95 GIT binary patch literal 295 zcmV+?0oeYDP)Px#;Ymb6R7i>4R51>MKoFcI6eb>YM|UrP*!ci|;|ok|Y<&^651=#f1rpCnI1?+@ z4{&=4N{nnf*_qv)o1?Ndj2SDMlYAKhF#s!1u*xKSz)S3p0Tezkjka1*egViM!q#!K z>xSy?;~+`>YR?)#4ZydB1yF3VqgP-VCX3be4n*UZWM-s^nl7+EoRFwBn8(9TMCjdf zx&VM6L8yN3!KWt*=Ai3cO*9@fX0~af#2f@S2)&X}Eg)!RYqSr143$=t3sx~4H@a+% tSAfda+@uM<@m+@qBp9Lo|2KJdfj8JdOPBH?^SuB7002ovPDHLkV1k2KbUXk6 literal 0 HcmV?d00001 diff --git a/Content/Items/Weapons/HeavenlyCrystallineBadge.cs b/Content/Items/Weapons/HeavenlyCrystallineBadge.cs new file mode 100644 index 0000000..cb01442 --- /dev/null +++ b/Content/Items/Weapons/HeavenlyCrystallineBadge.cs @@ -0,0 +1,10 @@ +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Items.Weapons; + +public class HeavenlyCrystallineBadge : PlumbersBadge { + public override int BaseDamage => 44; + public override string BadgeRankName => "HeavenlyCrystalline"; + public override int BadgeRankValue => 4; +} \ No newline at end of file diff --git a/Content/Items/Weapons/HeavenlyCrystallineBadge.png b/Content/Items/Weapons/HeavenlyCrystallineBadge.png new file mode 100644 index 0000000000000000000000000000000000000000..68fcac431f3d01f356ec1e13ea9cb33537573315 GIT binary patch literal 667 zcmV;M0%ZM(P)00001b5ch_0Itp) z=>Px%RY^oaR9J=Wmpy0{K@`V-7p{mz5lkZ%Nn__17YjXO4k2k$TsXKif)+NC!Vi=a zqA^7fweUbqt`M;ZSXgM9T)@Uy#KaIV94d;1B1v(iiH%+%gq+38J9o$3WG7rP2mYI7 zXWz`5{mp-QZ)4O+*;Gq4Xndt~HZXqf=cCwW>owJBUv*d9c0w4L7so#N?qBa{2Vj1! zg4*mRl?aOVWH&Ia~E$dHz={*L+1fF z{44>$htuLI_12ZxW$=*dX>GMi_-b_(0?17tk$mbkXNkp4Qpq0KdBq6SuP`^cJyNRL zybW^6K3O+g?()SsOYHx~Y*nk3pT8{vFx0sRfFkX_z-;*j0QtVVGB9}^EWCCwod)2+ z__%K!U01t~Q^O-woF=w6@f3jH$hCh#9%Sz20RD12AvG;m+^CgXkW)e`C6$eh0r0&n zwNgo$a+X+V2Wxh&`esuVA@?Qq93u2%+J~vMtH{jAiJZB14uC>)3OqHl@raoUBd7$T zO8dOx1#$1v6S+2CcVR0fs9xFM(gwiS$})Joqh!*BCGdDjWs*`kOU(LDTvhuYOyzyv zQ-Uh>P@!4w!w8vjme{sE7N)V`HXp&LgiJY0>< 40; - public override string BadgeRankName => "Agent"; + public override int BaseDamage => 35; + public override string BadgeRankName => "Agent"; + public override int BadgeRankValue => 4; public override void AddRecipes() { CreateRecipe() - .AddIngredient(ModContent.ItemType()) - .AddIngredient(ItemID.MeteoriteBar, 15) - .AddIngredient(ItemID.TissueSample, 5) - .AddTile(TileID.Anvils) - .Register(); - - CreateRecipe() - .AddIngredient(ModContent.ItemType()) - .AddIngredient(ItemID.MeteoriteBar, 15) - .AddIngredient(ItemID.ShadowScale, 5) + .AddIngredient(ModContent.ItemType()) + .AddIngredient(ItemID.HellstoneBar, 25) .AddTile(TileID.Anvils) .Register(); } diff --git a/Content/Items/Weapons/PlumberAgentBadge.png b/Content/Items/Weapons/PlumberAgentBadge.png index f1423b509abe82ba220a27af8ae7afeb06eab150..ddcf52683469a47d58e6037d2da734a84b25468f 100644 GIT binary patch delta 544 zcmV+*0^j|H1;qrAFnh z2@P!y;u0+q7!foCPTta5)DTDzQD9qxGz1Mfgo`$rV1qWi?;Uracjp~Ad`AC8_&?*=C_Z-3`jGB@8P06@L|Vp)GY zy6}`oSz@lw88(DuGD~|=UkN{Yw0|K)`x=dw?H!aQ=IAjd7G( z!n}LDvc!g-? zeIJ#mXyS^46+EYBLh?m$BWZb2?!FKyA+O+yEx8 zsY{H#wU#GR@%Rd0Ax7dVOdgX7eUlP0_6c%)F7&D;PFZ6A7xOElD%n$o1ogBk)-8br z(0VaPp1AYrwdHgg0B~BV003rkI{*M(c#Eq(B|NVzv44Q$M5;->Qn&AwT?cYZh{dEz zvt7W{EBQPYcLH^ZIsGA%lqXLnT13V*0ncG9c|Q{LvrU#WdgkO2lQoK?M}d8~NWO#u|F>bf`AgsBadmze`LO i&vz`Zgc)QhOY9fRMYrox3Y>=k0000`lGj33MFh7MY_PU2r#yircHn=;fsje&``d9}32%2RVoS?s09eoF9QP1dVy+$&QYN9) z#{~ec$A6RuMdF9xj6uOCx2<{O4VPiN#+SMv5;Fw`k_Z}lNwX!!G2d-)#OG_2#JJL zr1Klt`Y|CTlA9p7#M~xKlJaF0DRpAM+EeG{)bda&J@rAN$^ z8$lu9Ra(;L<$kNGk2YO}QtB=|6Eh_Q#Vh04EdUacMzDED$b@SzfXz!Hla%QA5fho- vbE`Iy8zEE2mzb&h_nvD6y%I7NSYrPG*sHcP!Da!900000NkvXXu0mjf(aRxm diff --git a/Content/Items/Weapons/PlumberHelperBadge.cs b/Content/Items/Weapons/PlumberCadetBadge.cs similarity index 69% rename from Content/Items/Weapons/PlumberHelperBadge.cs rename to Content/Items/Weapons/PlumberCadetBadge.cs index 388c27e..02252af 100644 --- a/Content/Items/Weapons/PlumberHelperBadge.cs +++ b/Content/Items/Weapons/PlumberCadetBadge.cs @@ -2,9 +2,10 @@ namespace Ben10Mod.Content.Items.Weapons; -public class PlumberHelperBadge : PlumbersBadge { - public override int BaseDamage => 15; - public override string BadgeRankName => "Helper"; +public class PlumberCadetBadge : PlumbersBadge { + public override int BaseDamage => 10; + public override string BadgeRankName => "Cadet"; + public override int BadgeRankValue => 1; public override void AddRecipes() { diff --git a/Content/Items/Weapons/PlumberHelperBadge.png b/Content/Items/Weapons/PlumberCadetBadge.png similarity index 100% rename from Content/Items/Weapons/PlumberHelperBadge.png rename to Content/Items/Weapons/PlumberCadetBadge.png diff --git a/Content/Items/Weapons/PlumberDeputyBadgeCrimtane.cs b/Content/Items/Weapons/PlumberDeputyBadgeCrimtane.cs new file mode 100644 index 0000000..e617678 --- /dev/null +++ b/Content/Items/Weapons/PlumberDeputyBadgeCrimtane.cs @@ -0,0 +1,19 @@ +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Items.Weapons; + +public class PlumberDeputyBadgeCrimtane : PlumbersBadge { + public override int BaseDamage => 17; + public override string BadgeRankName => "Deputy"; + public override int BadgeRankValue => 2; + + public override void AddRecipes() + { + CreateRecipe() + .AddIngredient(ModContent.ItemType()) + .AddIngredient(ItemID.CrimtaneBar, 15) + .AddTile(TileID.Anvils) + .Register(); + } +} \ No newline at end of file diff --git a/Content/Items/Weapons/ProvisionalAgentBadgeCrimtane.png b/Content/Items/Weapons/PlumberDeputyBadgeCrimtane.png similarity index 100% rename from Content/Items/Weapons/ProvisionalAgentBadgeCrimtane.png rename to Content/Items/Weapons/PlumberDeputyBadgeCrimtane.png diff --git a/Content/Items/Weapons/ProvisionalAgentBadgeDemonite.cs b/Content/Items/Weapons/PlumberDeputyBadgeDemonite.cs similarity index 51% rename from Content/Items/Weapons/ProvisionalAgentBadgeDemonite.cs rename to Content/Items/Weapons/PlumberDeputyBadgeDemonite.cs index eed5a3f..5080535 100644 --- a/Content/Items/Weapons/ProvisionalAgentBadgeDemonite.cs +++ b/Content/Items/Weapons/PlumberDeputyBadgeDemonite.cs @@ -4,14 +4,15 @@ namespace Ben10Mod.Content.Items.Weapons; -public class ProvisionalAgentBadgeDemonite : PlumbersBadge { - public override int BaseDamage => 25; - public override string BadgeRankName => "Helper"; +public class PlumberDeputyBadgeDemonite : PlumbersBadge { + public override int BaseDamage => 17; + public override string BadgeRankName => "Deputy"; + public override int BadgeRankValue => 2; public override void AddRecipes() { CreateRecipe() - .AddIngredient(ModContent.ItemType()) + .AddIngredient(ModContent.ItemType()) .AddIngredient(ItemID.DemoniteBar, 15) .AddTile(TileID.Anvils) .Register(); diff --git a/Content/Items/Weapons/ProvisionalAgentBadgeDemonite.png b/Content/Items/Weapons/PlumberDeputyBadgeDemonite.png similarity index 100% rename from Content/Items/Weapons/ProvisionalAgentBadgeDemonite.png rename to Content/Items/Weapons/PlumberDeputyBadgeDemonite.png diff --git a/Content/Items/Weapons/PlumberFieldProctorBadge.cs b/Content/Items/Weapons/PlumberFieldProctorBadge.cs new file mode 100644 index 0000000..f4e8b05 --- /dev/null +++ b/Content/Items/Weapons/PlumberFieldProctorBadge.cs @@ -0,0 +1,18 @@ +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Items.Weapons; + +public class PlumberFieldProctorBadge : PlumbersBadge { + public override int BaseDamage => 80; + public override string BadgeRankName => "FieldProctor"; + public override int BadgeRankValue => 7; + + public override void AddRecipes() { + CreateRecipe() + .AddIngredient(ModContent.ItemType()) + .AddIngredient(ItemID.ShroomiteBar, 25) + .AddTile(TileID.MythrilAnvil) + .Register(); + } +} \ No newline at end of file diff --git a/Content/Items/Weapons/PlumberFieldProctorBadge.png b/Content/Items/Weapons/PlumberFieldProctorBadge.png new file mode 100644 index 0000000000000000000000000000000000000000..2ddd655cf50cc72255ec6d0d453bd20f8341b12f GIT binary patch literal 646 zcmV;10(t$3P)00001b5ch_0Itp) z=>Px%KuJVFR9J=WmqAEWK^Vt>yLgC@I%tOo)5IWRw+#%s6hx%qVWXf!1#RJ>4v7a3 zUc6=p4ol*rt08^|JDH2c_gXo(Gzma!Yok_Q zo%;|ejan^{oKVai}{| zpyjVM0M^!3|KSJC02B({2`BbHQuhXq1F-*qdZ*u?+F}L#vFkGgJod0O3Knwi6T35b z-vjt|v`=dwqpfY;n5Cf+)kIRe1K!Y^w>S%sbR+a%>{v!73H#vfNa zEOM6E&cxzsb5)khYJY0Ha@X4M?YlGTCby`r^9Lb@*E0D$0As}>05gXdwQ*(DudP=+ zTqc$ZJCR%k{u39;|KPKUtmeHe`u-;#s`}+HLZ+N0wr!7vsbx=D gBN&yCDQAgo0HU 55; - public override string BadgeRankName => "Magister"; + public override int BaseDamage => 95; + public override string BadgeRankName => "Magister"; + public override int BadgeRankValue => 8; - public override void AddRecipes() - { + public override void AddRecipes() { CreateRecipe() - .AddIngredient(ModContent.ItemType()) - .AddIngredient(ItemID.HellstoneBar, 25) - .AddTile(TileID.Anvils) + .AddIngredient(ModContent.ItemType()) + .AddIngredient(ModContent.ItemType(), 25) + .AddTile(TileID.LunarCraftingStation) .Register(); } } \ No newline at end of file diff --git a/Content/Items/Weapons/PlumberMagisterBadge.png b/Content/Items/Weapons/PlumberMagisterBadge.png index ddcf52683469a47d58e6037d2da734a84b25468f..bd88ad7fcc977870e8e65339c0866b95ef577608 100644 GIT binary patch delta 607 zcmV-l0-*iH1cU{UFniLy#a% z4l3yI2F0a@jDnt;gJ45jG&nTW;$(tDle7rIqotuBvG7qO@z98_pvh}E{p+6Vy?U>` z;aupyT<&@2p6|Th{eR#2ZiWi!(%|88*m&XPcIf=A4`lXQuYamS`>MDOC4C@@%;V|% z*8P=%aR83iWv%faB`;PSXNm3ko(UloBr`OcPZY4H`y2qX^KSrHda@n5hx8E>sUV@t z*CqjYI$sBXw{av^pil2=0BGs>3P68%34ry2mo8$vvT{FCV|QBt@HV~!kjuYM6mWv` z0JOD#0pKm!GJhfDoF(>Wm(`~!0~B6OSrbI6t=&}co1@L(BUPJA7I1yWTqk-BIeD(@ zWHBAYc6m&MW*5#_94*8F!Z0|BWS8Mjorl9tU7?@eTlM<$q@Y^mMI2NFBSiYU)^AuXS=A zfafpf0C>>U0>H!Rk0#FVtXExgmsnIsIyhqY>bHkY*6OTOmPU~iAxWfec&2Wt9}_9b zePU5R1WD?jP2O7u;Oxas@Odsu>cb?F(i`bGWzOc}&qv@pGt);bs3?LW5LfE+l=WLX z-yluhMObWNL5ZNe;uTG{WgAV`An%AweWnk5UXp^OBxi{w{t}n|eh*T7N(-MGt?Z3UC@5!%{Q{)!yIj)+NL~N{002ovPDHLkV1kRHDZ&5% delta 544 zcmV+*0^j|F1;qrAFnh z2@P!y;u0+q7!foCPTta5)DTDzQD9qxGz1Mfgo`$rV1qWi?;Uracjp~Ad`AC8_&?*=C_Z-3`jGB@8P06@L|Vp)GY zy6}`oSz@lw88(DuGD~|=UkN{Yw0|K)`x=dw?H!aQ=IAjd7G( z!n}LDvc!g-? zeIJ#mXyS^46+EYBLh?m$BWZb2?!FKyA+O+yEx8 zsY{H#wU#GR@%Rd0Ax7dVOdgX7eUlP0_6c%)F7&D;PFZ6A7xOElD%n$o1ogBk)-8br z(0VaPp1AYrwdHgg0B~BV003rkI{*M(c#Eq(B|NVzv44Q$M5;->Qn&AwT?cYZh{dEz zvt7W{EBQPYcLH^ZIsGA%lqXLnT13V*0ncG9c|Q{LvrU#WdgkO2lQoK?M}d8~NWO#u|F>bf`AgsBadmze`LO i&vz`Zgc)QhOY9fRMYrox3Y>=k0000 110; + public override string BadgeRankName => "Magistrata"; + public override int BadgeRankValue => 9; +} \ No newline at end of file diff --git a/Content/Items/Weapons/PlumberMagistrataBadge.png b/Content/Items/Weapons/PlumberMagistrataBadge.png new file mode 100644 index 0000000000000000000000000000000000000000..8b0b4c9d9f8dbfcc65c4a4cf91b4896ea238be08 GIT binary patch literal 680 zcmV;Z0$2TsP)00001b5ch_0Itp) z=>Px%NJ&INR9Hvtm|aAJQ5eU!k=R9x@k(SQ5v8sox~q%WDl4VBOn0%mNkmIi-SnX* zlJ#|wmPo~>F6wSXyGklDF_DZe*2U@(i_OBC@Mi?)I zC*$=_8#!@Po6|+}&%z;!k&AFvJ861MI$;pR6B-{Krkz&RH&JwVICT+wh&|H0+q-*; zvFl5U(P-2dG3kV93F_=0q@7k*RZ?6U=+;FHlU%-e#$)eqiLB%@FiIy(Q54GD`$y_+ z!4IA)E>WnOPL@v9`iUjp;LFb-Ma6H^p5Px;qXZ&j3+F&^Xdm{G6Qwzt!I%R4(1d2gZWKwe9G zOgdqr!mq2RmvKdKbCtKZKnRO~RO!qjb)g;uDa=a~lU5j?U(n_SV`rzwYThvy z6;Z_7DOv}07{);gC(=+?Lqmb>U5a=!g%zx{!gvBAp&%e4#`mKl#;y0xE-<7pU$f@d zI@-Jo6A^@0QmGV8v0AMZ;T@29dVXQNg!TA3%rLQn5hglf(QVTr#BW@;$MmKZX@v2D z`-eQtzdj-lY2D%<6ZTF O0000 65; + public override string BadgeRankName => "Proctor"; + public override int BadgeRankValue => 6; + + public override void AddRecipes() + { + CreateRecipe() + .AddIngredient(ModContent.ItemType()) + .AddIngredient(ItemID.ChlorophyteBar, 25) + .AddTile(TileID.MythrilAnvil) + .Register(); + } +} \ No newline at end of file diff --git a/Content/Items/Weapons/PlumberProctorBadge.png b/Content/Items/Weapons/PlumberProctorBadge.png new file mode 100644 index 0000000000000000000000000000000000000000..58d4b68deaedb73946e662cce99962a4103720bb GIT binary patch literal 635 zcmV->0)+jEP)00001b5ch_0Itp) z=>Px%HAzH4R9J=Wmc46JQ5eR5u|lPa846j0B3=9dk(5H?QtDu!xK_a-2o=PD|3SF3 zix4RY7Au9i6-20m(!~_PiwG8%4uxzIEZD)s3MLLGPsq8R+ujQqj>Ts?=bo?oJJ0)` zH^Y#0;?h{x)qncyDd+fRvza+)y<&oU?63PhjMRgt=K!dWya3?Slsiwwsj@i-10L&>3q$KH-V*D3 zESJl50UmBNtpOsnwf_Zx`iSv_NEJJsR2$Z&UjeYRX`)k}3q#v${u7g;Q3vZVkbi1Z z=8r{cc6>bDj=Q^NogO)PuCQL{GT=3TiOE~}d>(*oHtQUyC@gkNrcX_(r~bSiIjy_3 zZ@(bk68nF!wCYD?yWIxh{%ey@c52hsz-PCN2g)DJi|}^R^e6S&g*g*_kCvAK_|aQO z>niHE*Cx97Oe_;ukzQG_qvY4~GvIhDPfog{RD>jvy8Pa*$3#lfOW-fDxDQd1`m@D~ z$v+>z*8wQ6wp`QuQXM9Vlx}2U{u=;0wJHEX5cr+>53Tv7ID#UORI2ktND?XO-zOH8 z2+Aw>u3iIR@!cD6c;{>-u-a0TlyvlnNm1{`MVk~yD5|4NEUId?Y7tCIC@OD>{Q(&a VyFFzs%x3@q002ovPDHLkV1je^Aj|*& literal 0 HcmV?d00001 diff --git a/Content/Items/Weapons/PlumberSeniorAgentBadge.cs b/Content/Items/Weapons/PlumberSeniorAgentBadge.cs new file mode 100644 index 0000000..119287e --- /dev/null +++ b/Content/Items/Weapons/PlumberSeniorAgentBadge.cs @@ -0,0 +1,19 @@ +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Items.Weapons; + +public class PlumberSeniorAgentBadge : PlumbersBadge { + public override int BaseDamage => 50; + public override string BadgeRankName => "SeniorAgent"; + public override int BadgeRankValue => 5; + + public override void AddRecipes() + { + CreateRecipe() + .AddIngredient(ModContent.ItemType()) + .AddIngredient(ItemID.HallowedBar, 25) + .AddTile(TileID.MythrilAnvil) + .Register(); + } +} \ No newline at end of file diff --git a/Content/Items/Weapons/PlumberSeniorAgentBadge.png b/Content/Items/Weapons/PlumberSeniorAgentBadge.png new file mode 100644 index 0000000000000000000000000000000000000000..5b8d3fc9378d08e36e40b44b15d261485c329095 GIT binary patch literal 643 zcmV-}0(||6P)00001b5ch_0Itp) z=>Px%JxN4CR9J=WmOp3|K@^9-c(Jkx1TGLrbs_%2P7A@X#CV7xDFX3`*N7IPlFA~L zM3879A}NG4l8Y80#GsWZa$d2hm11KdhbIQ%kb^)Pn_%uNX5O+h*}dD9E5_ijo7uPT z&3^lv$Lpa>@oW)sU zfyc7hY+F+GS`H#ejW(O93VOryDz7Fdo`Xdr&V6DcA@uN8pI)nd=|A4ENh;r;tdj@Y z+|+qYa=pJYEka&%mza2K{FwTZdSfRtP`owTybXUtN-KCzlasvl+LDe?jm=qN{|}Z{ z!L9uK<1hf%FPzXj&yB!)H;MqvuBmCFTu}Wksn?E9OaQR3ybQpY&Ler{))!|sS~yMY zP@n2oY;QwozIylS2mmsF4(8rNXiA_1IUytxQg^@2sd&#MWy@J&u@kI4xyqNFDpUZ- z{QM3H=COdVmP{2x0|Nk@JbMs;%BTGRtgkP+-T6Dt{GvF5LLjMRdMTV%xBlw=0)$A3 z{(WM$grIn(^z 25; + public override string BadgeRankName => "SeniorDeputy"; + public override int BadgeRankValue => 3; + + public override void AddRecipes() + { + CreateRecipe() + .AddIngredient(ModContent.ItemType()) + .AddIngredient(ItemID.MeteoriteBar, 15) + .AddIngredient(ItemID.TissueSample, 5) + .AddTile(TileID.Anvils) + .Register(); + + CreateRecipe() + .AddIngredient(ModContent.ItemType()) + .AddIngredient(ItemID.MeteoriteBar, 15) + .AddIngredient(ItemID.ShadowScale, 5) + .AddTile(TileID.Anvils) + .Register(); + } +} \ No newline at end of file diff --git a/Content/Items/Weapons/PlumberSeniorDeputyBadge.png b/Content/Items/Weapons/PlumberSeniorDeputyBadge.png new file mode 100644 index 0000000000000000000000000000000000000000..f1423b509abe82ba220a27af8ae7afeb06eab150 GIT binary patch literal 646 zcmV;10(t$3P)00001b5ch_0Itp) z=>Px%KuJVFR9J=WmQ6@hQ5462BRbPUF&!B}GD}(reYg_Tl%X=Ag#}5{&Xt=Yirlzy z5ciTIxCunTg%mBuWe`z{2or5YaM2eTLPJIaE}Vg!7WbXu-P?Qmp3LHn_}{&I&%5Wo z-}|3?PlzJvawMF08t*?9c8nj(?1m0nudF!RD!$77zTigY?6rjUoE)45py9Dj>_PU2 zr#yircHn=;fsje&``d9}32%2RVoS?s09eoF9QP1dVy+$&QYN9)#{~ec$A80Ya)iqrOx;C8WCc_kAT?DN`(joOo{WdWg=jDE@s*g5Z zg;MG+JQFh|1jQ@k*)0GPkw&n2N63V0FM!QUB9oNp_z@GC-gB!qksBdX$CsF?`}dw} g1icb66 15; - public virtual float DamageMultiplier => 1f; // For universal scaling if needed - public virtual float AttackSpeedMultiplier => 1f; + public virtual int BaseDamage => 15; + public virtual float DamageMultiplier => 1f; // For universal scaling if needed + public virtual float AttackSpeedMultiplier => 1f; + public virtual float AdditionalProjectileChance => 0; + public virtual string BadgeRankName => "Helper"; + public virtual int BadgeRankValue => 0; public int OmnitrixEnergyUse = 0; - private int GetUltimateProjectileType(OmnitrixPlayer omp) - { + private int GetUltimateProjectileType(OmnitrixPlayer omp) { // Add more mappings here as you implement other ultimate attacks. return omp.currTransformation switch { TransformationEnum.EyeGuy => ModContent.ProjectileType(), TransformationEnum.GhostFreak => ModContent.ProjectileType(), TransformationEnum.DiamondHead => ModContent.ProjectileType(), + TransformationEnum.HeatBlast => ModContent.ProjectileType(), _ => 0 }; } - private static bool HasActiveOwnedProjectile(Player player, int projType) - { + private static bool HasActiveOwnedProjectile(Player player, int projType) { if (projType <= 0) return false; int owner = player.whoAmI; - for (int i = 0; i < Main.maxProjectiles; i++) - { + for (int i = 0; i < Main.maxProjectiles; i++) { Projectile p = Main.projectile[i]; if (p.active && p.owner == owner && p.type == projType) return true; } + return false; } - private void FinalizeUltimateIfEnded(Player player, OmnitrixPlayer omp) - { + private void FinalizeUltimateIfEnded(Player player, OmnitrixPlayer omp) { if (!omp.ultimateAttack) return; var state = player.GetModPlayer(); @@ -65,31 +66,30 @@ private void FinalizeUltimateIfEnded(Player player, OmnitrixPlayer omp) // If the ultimate projectile is still alive, ultimate is still in progress. int ultimateProjType = GetUltimateProjectileType(omp); - if (HasActiveOwnedProjectile(player, ultimateProjType)) return; + if (HasActiveOwnedProjectile(player, ultimateProjType) && omp.currTransformation == TransformationEnum.EyeGuy) return; // If we're here, the player has released channel and the ultimate projectile is gone. if (!player.HasBuff()) player.AddBuff(ModContent.BuffType(), 60 * 60); - omp.ultimateAttack = false; + omp.ultimateAttack = false; state.ultimateStarted = false; } -public override void SetDefaults() - { + public override void SetDefaults() { Item.width = 32; Item.height = 32; Item.noUseGraphic = true; Item.useTurn = false; Item.autoReuse = true; Item.noMelee = true; - + Item.shoot = 1; Item.DamageType = ModContent.GetInstance(); - Item.damage = BaseDamage; - Item.knockBack = 4f; + Item.damage = BaseDamage; + Item.knockBack = 4f; // Base defaults - overridden per alien in HoldItem Item.useStyle = ItemUseStyleID.Swing; @@ -99,21 +99,20 @@ public override void SetDefaults() Item.UseSound = null; } - public override void ModifyTooltips(List tooltips) - { - tooltips.Add(new TooltipLine(Mod, "badgeHelperLine", "Right click while holding to alternate between primary and secondary attacks")); + public override void ModifyTooltips(List tooltips) { + tooltips.Add(new TooltipLine(Mod, "badgeHelperLine", + "Right click while holding to alternate between primary and secondary attacks")); } - public override bool CanUseItem(Player player) - { + public override bool CanUseItem(Player player) { var omp = player.GetModPlayer(); - return player.GetModPlayer().isTransformed && !(omp.omnitrixEnergy < OmnitrixEnergyUse && omp.ultimateAttack); + return player.GetModPlayer().isTransformed && + !(omp.omnitrixEnergy < OmnitrixEnergyUse && omp.ultimateAttack); } public override bool AltFunctionUse(Player player) => true; - public override void HoldItem(Player player) - { + public override void HoldItem(Player player) { var omp = player.GetModPlayer(); FinalizeUltimateIfEnded(player, omp); @@ -126,32 +125,27 @@ public override void HoldItem(Player player) Item.UseSound = null; Item.channel = false; OmnitrixEnergyUse = 0; - + if (!omp.isTransformed) return; // Fixed per-alien useTime/shootSpeed (balanced to feel good - no alt-dependent for now to avoid timing issues) - switch (omp.currTransformation) - { + switch (omp.currTransformation) { case TransformationEnum.HeatBlast: - - if (omp.altAttack) { - Item.useTime = Item.useAnimation = 50; - Item.shootSpeed = 10f; - } - else { - Item.useStyle = ItemUseStyleID.Shoot; - Item.useTime = Item.useAnimation = 6; - Item.shootSpeed = 3f; - } + Item.useTime = Item.useAnimation = omp.altAttack ? 50 : 6; + Item.shootSpeed = omp.ultimateAttack ? 0 : omp.altAttack ? 10f : 3f; + Item.useStyle = omp.ultimateAttack ? ItemUseStyleID.HoldUp : + omp.altAttack ? ItemUseStyleID.Swing : ItemUseStyleID.Shoot; + OmnitrixEnergyUse = omp.ultimateAttack ? 10 : 0; + Item.channel = omp.ultimateAttack; break; case TransformationEnum.XLR8: Item.useTime = Item.useAnimation = 10; // Fast punches Item.shootSpeed = 25f; break; case TransformationEnum.FourArms: - Item.useTime = Item.useAnimation = 18; // Fast punches + Item.useTime = Item.useAnimation = 18; // Fast punches Item.shootSpeed = 25f; break; @@ -164,22 +158,22 @@ public override void HoldItem(Player player) break; case TransformationEnum.RipJaws: - Item.useTime = Item.useAnimation = 28; + Item.useTime = Item.useAnimation = 28; Item.shootSpeed = 6f; break; case TransformationEnum.ChromaStone: - Item.useTime = Item.useAnimation = 20; + Item.useTime = Item.useAnimation = 20; Item.shootSpeed = 25f; break; case TransformationEnum.BuzzShock: - Item.useTime = Item.useAnimation = 20; + Item.useTime = Item.useAnimation = 20; Item.shootSpeed = 25f; break; case TransformationEnum.StinkFly: - Item.useTime = Item.useAnimation = 30; + Item.useTime = Item.useAnimation = 30; Item.shootSpeed = 25f; break; @@ -190,16 +184,16 @@ public override void HoldItem(Player player) break; case TransformationEnum.WildVine: - Item.useTime = Item.useAnimation = 32; + Item.useTime = Item.useAnimation = 32; Item.shootSpeed = 10f; break; case TransformationEnum.EyeGuy: - Item.useStyle = ItemUseStyleID.Shoot; - Item.useTime = Item.useAnimation = 12; - Item.shootSpeed = omp.ultimateAttack ? 0f : 35f; - Item.UseSound = omp.ultimateAttack ? null : SoundID.Item12; - Item.channel = omp.ultimateAttack; - OmnitrixEnergyUse = omp.ultimateAttack ? 10 : 0; + Item.useStyle = ItemUseStyleID.Shoot; + Item.useTime = Item.useAnimation = 12; + Item.shootSpeed = omp.ultimateAttack ? 0f : 35f; + Item.UseSound = omp.ultimateAttack ? null : SoundID.Item12; + Item.channel = omp.ultimateAttack; + OmnitrixEnergyUse = omp.ultimateAttack ? 10 : 0; break; default: Item.useTime = Item.useAnimation = 25; @@ -212,7 +206,8 @@ public override void HoldItem(Player player) } public override bool? UseItem(Player player) { - if (player.altFunctionUse == 2) player.GetModPlayer().altAttack = !player.GetModPlayer().altAttack; + if (player.altFunctionUse == 2) + player.GetModPlayer().altAttack = !player.GetModPlayer().altAttack; var omp = player.GetModPlayer(); if (omp.omnitrixEnergy >= OmnitrixEnergyUse) { omp.omnitrixEnergy -= OmnitrixEnergyUse; @@ -220,19 +215,20 @@ public override void HoldItem(Player player) else { return false; } + return base.UseItem(player); } - public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) - { + public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, + Vector2 velocity, int type, int damage, float knockback) { var omp = player.GetModPlayer(); if (!omp.isTransformed || player.altFunctionUse == 2) return false; // Block non-ultimate attacks while an ultimate is in progress (channeling or projectile alive). - int activeUltimateType = GetUltimateProjectileType(omp); - bool ultimateProjectileAlive = HasActiveOwnedProjectile(player, activeUltimateType); - bool ultimateInProgress = player.channel || ultimateProjectileAlive || player.GetModPlayer().ultimateStarted; + int activeUltimateType = GetUltimateProjectileType(omp); + bool ultimateInProgress = player.channel || + player.GetModPlayer().ultimateStarted; // If ultimate is in progress, only allow firing the ultimate projectile itself (and only once). if (ultimateInProgress && !omp.ultimateAttack) @@ -244,25 +240,21 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, return false; - int projType = ProjectileID.ImpFireball; // Bright vanilla fallback - you SHOULD see this if alien not matched + int projType = + ProjectileID.ImpFireball; // Bright vanilla fallback - you SHOULD see this if alien not matched int finalDamage = damage; - switch (omp.currTransformation) - { + switch (omp.currTransformation) { case TransformationEnum.HeatBlast: - if (omp.altAttack) { - projType = ModContent.ProjectileType(); - // projType = ProjectileID.Flamelash; - finalDamage = (int)(damage * 2.5f); - } - else { - projType = ProjectileID.Flames; - finalDamage = (int)(damage * 0.3f); + projType = omp.ultimateAttack ? ModContent.ProjectileType() : + omp.altAttack ? ModContent.ProjectileType() : ProjectileID.Flames; + finalDamage = omp.ultimateAttack ? (int)(damage * 3f) : omp.altAttack ? (int)(damage * 1.5f) : (int)(damage * 0.3f); + if (omp.ultimateAttack) { + velocity = Vector2.Zero; } break; - case TransformationEnum.XLR8: - projType = ModContent.ProjectileType(); + projType = ModContent.ProjectileType(); finalDamage = (int)(damage * 0.25f); break; case TransformationEnum.FourArms: @@ -272,12 +264,15 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, break; case TransformationEnum.DiamondHead: - projType = omp.ultimateAttack ? ModContent.ProjectileType() : ModContent.ProjectileType(); + projType = omp.ultimateAttack + ? ModContent.ProjectileType() + : ModContent.ProjectileType(); finalDamage = omp.ultimateAttack ? damage * 5 : (int)(damage * 0.5f); if (omp.ultimateAttack) { velocity = Vector2.Zero; position = Main.MouseWorld; } + break; case TransformationEnum.RipJaws: @@ -285,7 +280,7 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, break; case TransformationEnum.ChromaStone: - projType = ModContent.ProjectileType(); + projType = ModContent.ProjectileType(); finalDamage += omp.ChromaStoneAbsorbtion; break; @@ -305,7 +300,7 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, case TransformationEnum.GhostFreak: projType = omp.ultimateAttack ? ModContent.ProjectileType() - : ModContent.ProjectileType(); + : omp.altAttack ? ProjectileID.CursedFlameFriendly : ModContent.ProjectileType(); break; case TransformationEnum.WildVine: @@ -314,7 +309,9 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, : ModContent.ProjectileType(); break; case TransformationEnum.EyeGuy: - projType = omp.ultimateAttack ? ModContent.ProjectileType() : ModContent.ProjectileType(); + projType = omp.ultimateAttack + ? ModContent.ProjectileType() + : ModContent.ProjectileType(); finalDamage = omp.ultimateAttack ? (int)(damage * 2f) : damage; break; } @@ -329,7 +326,20 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, if (omp.ultimateAttack && projType == activeUltimateType) player.GetModPlayer().ultimateStarted = true; - Projectile.NewProjectile(source, position, velocity, projType, (int)(finalDamage * DamageMultiplier), knockback, player.whoAmI); + Projectile.NewProjectile(source, position, velocity, projType, (int)(finalDamage * DamageMultiplier), + knockback, player.whoAmI); + + if (!omp.ultimateAttack) { + for (int i = (int)Math.Floor(AdditionalProjectileChance); i >= 1; i--) { + Projectile.NewProjectile(source, position, velocity.RotatedByRandom(0.25f), projType, (int)(finalDamage * DamageMultiplier), + knockback, player.whoAmI); + } + + if (Main.rand.Next(100) <= 100 * (int)(AdditionalProjectileChance - Math.Floor(AdditionalProjectileChance))) { + Projectile.NewProjectile(source, position, velocity.RotatedByRandom(0.25f), projType, (int)(finalDamage * DamageMultiplier), + knockback, player.whoAmI); + } + } return false; } diff --git a/Content/Items/Weapons/ProvisionalAgentBadgeCrimtane.cs b/Content/Items/Weapons/ProvisionalAgentBadgeCrimtane.cs deleted file mode 100644 index b4d1072..0000000 --- a/Content/Items/Weapons/ProvisionalAgentBadgeCrimtane.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Terraria.ID; -using Terraria.ModLoader; - -namespace Ben10Mod.Content.Items.Weapons; - -public class ProvisionalAgentBadgeCrimtane : PlumbersBadge { - public override int BaseDamage => 25; - public override string BadgeRankName => "Helper"; - - public override void AddRecipes() - { - CreateRecipe() - .AddIngredient(ModContent.ItemType()) - .AddIngredient(ItemID.CrimtaneBar, 15) - .AddTile(TileID.Anvils) - .Register(); - } -} \ No newline at end of file diff --git a/Content/Projectiles/ChromaStoneProjectile.cs b/Content/Projectiles/ChromaStoneProjectile.cs index e4caec4..8c6c849 100644 --- a/Content/Projectiles/ChromaStoneProjectile.cs +++ b/Content/Projectiles/ChromaStoneProjectile.cs @@ -21,17 +21,14 @@ public override void SetDefaults() { AIType = ProjectileID.Bullet; Projectile.friendly = true; - Projectile.tileCollide = false; - Projectile.penetrate = 3; + Projectile.tileCollide = true; + Projectile.penetrate = -1; Projectile.DamageType = DamageClass.Magic; } public override bool PreDraw(ref Color lightColor) { - - - OmnitrixPlayer omnitrixPlayer = Main.player[Projectile.owner].GetModPlayer(); lightColor = Main.DiscoColor; Lighting.AddLight(Projectile.position + Projectile.velocity * 0.5f, lightColor.ToVector3() * 0.5f); return base.PreDraw(ref lightColor); diff --git a/Content/Projectiles/Explosion.cs b/Content/Projectiles/Explosion.cs index 1aab9d8..a855bc8 100644 --- a/Content/Projectiles/Explosion.cs +++ b/Content/Projectiles/Explosion.cs @@ -45,8 +45,6 @@ public override void OnSpawn(Terraria.DataStructures.IEntitySource source) for (int i = 0; i < 30; i++) { Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.Smoke, Main.rand.NextFloat(-6, 6), Main.rand.NextFloat(-6, 6)); - int dustNum = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.Torch, - Main.rand.NextFloat(-25, 25), Main.rand.NextFloat(0, 25), Scale: 3); } } } diff --git a/Content/Projectiles/HeatBlastBomb.cs b/Content/Projectiles/HeatBlastBomb.cs index b3be1cd..338a54c 100644 --- a/Content/Projectiles/HeatBlastBomb.cs +++ b/Content/Projectiles/HeatBlastBomb.cs @@ -23,8 +23,12 @@ public override void SetDefaults() { } public override void EmitEnchantmentVisualsAt(Vector2 boxPosition, int boxWidth, int boxHeight) { - Random random = new Random(); - int dustNum = Dust.NewDust(boxPosition, 1, 1, DustID.Torch, 0, 0, 1, Color.White, 5); + Player player = null; + bool gotPlayer = Projectile.TryGetOwner(out player); + var omp = gotPlayer ? player.GetModPlayer() : null; + int dust = gotPlayer ? omp.snowflake ? DustID.IceTorch : DustID.Torch : DustID.Torch; + Random random = new Random(); + int dustNum = Dust.NewDust(boxPosition, 1, 1, dust, 0, 0, 1, Color.White, 5); Main.dust[dustNum].noGravity = true; } diff --git a/Content/Projectiles/HeatBlastUltimateProjectile.cs b/Content/Projectiles/HeatBlastUltimateProjectile.cs new file mode 100644 index 0000000..6f76680 --- /dev/null +++ b/Content/Projectiles/HeatBlastUltimateProjectile.cs @@ -0,0 +1,103 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; +using Terraria.GameContent; + +namespace Ben10Mod.Content.Projectiles +{ + public class HeatBlastUltimateProjectile : ModProjectile + { + private bool launched = false; + + public override void SetDefaults() + { + Projectile.width = 128; + Projectile.height = 128; + Projectile.scale = 0.3f; + Projectile.penetrate = -1; + Projectile.tileCollide = false; + Projectile.ignoreWater = true; + Projectile.friendly = true; + Projectile.timeLeft = 600; + } + + public override void AI() + { + Player owner = Main.player[Projectile.owner]; + + if (!launched) + { + if (owner.channel && owner.active && !owner.dead) + { + Projectile.Center = owner.Center + new Vector2(0f, -78f); + Projectile.rotation = 0f; + + // Grow while holding + if (Projectile.scale < 2.2f) + { + Projectile.scale += 0.038f; + Projectile.scale = Math.Min(2.2f, Projectile.scale); + } + else + { + owner.channel = false; + } + + // Grow hitbox with scale + Projectile.width = (int)(128 * Projectile.scale); + Projectile.height = (int)(128 * Projectile.scale); + + SpawnChargingDust(); + return; + } else { + launched = true; + + Vector2 launchDir = (Main.MouseWorld - Projectile.Center).SafeNormalize(Vector2.Zero); + Projectile.velocity = launchDir * 5f; + } + } + SpawnFlyingDust(); + } + + private void SpawnChargingDust() { + float radius = 58f * Projectile.scale; + Lighting.AddLight(Projectile.Center, Color.Red.ToVector3()); + for (int i = 0; i < 35; i++) { + if (Main.rand.NextBool(2)) { + Vector2 pos = Projectile.Center + Main.rand.NextVector2Circular(radius, radius); + Dust d = Dust.NewDustPerfect(pos, DustID.InfernoFork, + Main.rand.NextVector2Circular(1f, 2.5f), 90, + new Color(255, 90, 0), Main.rand.NextFloat(2.1f, 3.4f)); + d.noGravity = true; + } + } + } + + private void SpawnFlyingDust() { + float radius = 58f * Projectile.scale; + Lighting.AddLight(Projectile.Center, Color.Red.ToVector3()); + for (int i = 0; i < 28; i++) { + if (Main.rand.NextBool(2)) { + Vector2 pos = Projectile.Center + Main.rand.NextVector2Circular(radius * 0.8f, radius * 0.8f); + Dust d = Dust.NewDustPerfect(pos, DustID.InfernoFork, + Projectile.velocity * -0.15f, 100, + new Color(255, 110, 0), 2.4f); + d.noGravity = true; + } + } + } + + public override bool PreDraw(ref Color lightColor) { + Texture2D tex = TextureAssets.Projectile[Projectile.type].Value; + Vector2 origin = tex.Size() / 2f; + + Main.EntitySpriteDraw(tex, Projectile.Center - Main.screenPosition, null, lightColor, + Projectile.rotation, origin, Projectile.scale, SpriteEffects.None, 0); + + return false; // skip default draw + } + } +} \ No newline at end of file diff --git a/Content/Projectiles/HeatBlastUltimateProjectile.png b/Content/Projectiles/HeatBlastUltimateProjectile.png new file mode 100644 index 0000000000000000000000000000000000000000..ff1cc9ddf576479da8dc27cc475e2e060bbcfa94 GIT binary patch literal 6717 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 T9JWIO00000NkvXXu0mjfi>d1d literal 0 HcmV?d00001 diff --git a/Content/Tiles/PlumberCapsulePod.cs b/Content/Tiles/PlumberCapsulePod.cs index 0b65a6a..d7825b3 100644 --- a/Content/Tiles/PlumberCapsulePod.cs +++ b/Content/Tiles/PlumberCapsulePod.cs @@ -66,6 +66,6 @@ public override void MouseOver(int i, int j) Player player = Main.LocalPlayer; player.noThrow = 2; player.cursorItemIconEnabled = true; - player.cursorItemIconID = ModContent.ItemType(); + player.cursorItemIconID = ModContent.ItemType(); } } \ No newline at end of file diff --git a/Content/Transformations/HeatBlast/HeatBlast.cs b/Content/Transformations/HeatBlast/HeatBlast.cs index 8ebc1f9..a4c05bf 100644 --- a/Content/Transformations/HeatBlast/HeatBlast.cs +++ b/Content/Transformations/HeatBlast/HeatBlast.cs @@ -21,6 +21,9 @@ public override void Load() { EquipLoader.AddEquipTexture(Mod, $"{Texture}_{EquipType.Head}", EquipType.Head, this, equipTexture: new XLR8Head()); EquipLoader.AddEquipTexture(Mod, $"{Texture}_{EquipType.Body}", EquipType.Body, this); EquipLoader.AddEquipTexture(Mod, $"{Texture}_{EquipType.Legs}", EquipType.Legs, this); + EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.Head}", EquipType.Head, name: "HeatBlastAlt", equipTexture: new XLR8Head()); + EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.Body}", EquipType.Body, name: "HeatBlastAlt"); + EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.Legs}", EquipType.Legs, name: "HeatBlastAlt"); //Add a separate set of equip textures by providing a custom name reference instead of an item reference //EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.Head}", EquipType.Head, name: "BlockyAlt", equipTexture: new BlockyHead()); diff --git a/Content/Transformations/HeatBlast/HeatBlastAlt_Body.png b/Content/Transformations/HeatBlast/HeatBlastAlt_Body.png new file mode 100644 index 0000000000000000000000000000000000000000..35860c80b73827a1915e5e15b5c9115778e02bd2 GIT binary patch literal 3458 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 literal 0 HcmV?d00001 diff --git a/Content/Transformations/HeatBlast/HeatBlastAlt_Head.png b/Content/Transformations/HeatBlast/HeatBlastAlt_Head.png new file mode 100644 index 0000000000000000000000000000000000000000..afc34d79eaf69c3506f4aa5a63b14c31481695f9 GIT binary patch literal 1326 zcmeAS@N?(olHy`uVBq!ia0vp^8Vn392^?%d*6dv(^+1ZTILO_JVcj{Imq3{po-U3d z6?5L++SnD7D$(%J-f@vx^od(bJp@^_qc?JeO{-?y$+UV(Tw6y4Ygp38rBB0>5*0N# zgpMf94Kq6^64_nsS1?WI-M{y%4*#$@n`r#g@6hr3w6X`X&9;SqzWn*~ z^S%FJ+1*_$rDN~h%U^$g*Tm}gf7#+!n%^+{{^#ST&+4ybhfP7%y!J(`}S{cwbyp#%KEz(wr$Lv zJp1kBr~iM8#6NpCH~jdI({0-}mwkD7JGsX&?)RJHhQ}o4-`jn!mOsCF`+NQCm){zf z|84p4>hsggzYiW3J?rc1FMk$i^Ys4SKYu@7s(-)h|H1m(Tg`Xa*4|b>7-9bN(aN~{ z-|c=?mgiOf-Sw@m`RDBGA656W=cRub=POo8NOF(VQ}k^6oK8q3{tvl zrVrH}%I@$raHU-u5V42KYhQI=`fEjq{M1*AgK9%o^?QNjv_OI&>lyC)ESo)Z>Fk-Z zSI(}%2q2h?L79Z1#CT?2+O)j1vHR1P)qBkV=JMxzJOKBTp^9>G<@bS7nH1 zzt+>hr8cXkxKI7GA_yc076d7EFrWM~Ee(j+OO3U$#}d$dMvzh(xU_+J0VrrT15xv; ze#{Vp1slkEn#Ab@P|#e|d3y29f=?NkAp{FHko~kseIM@s6z=)p&~QYybO*=|Pgg&e IbxsLQ05pP{L;wH) literal 0 HcmV?d00001 diff --git a/Content/Transformations/HeatBlast/HeatBlastAlt_Legs.png b/Content/Transformations/HeatBlast/HeatBlastAlt_Legs.png new file mode 100644 index 0000000000000000000000000000000000000000..53dd81d41cefe727eb61dca8c164dbf537e32d3c GIT binary patch literal 1927 zcmY*Z4OG%u7RMQPO{daHr?Sbcra;p*6OH^xPGvgcSBjPCh*Tq57>K<1bUDmmG>p{PiH03wc~C<0<2A}G55#%<2=o!>d{opbMd_uk*TzkBCQ zc+eKBT~;6vXiMn6?78B=-n*`fhgtjx<5HT5nsuF+GxM@iDTCld+ zSk5dmnH}bSi6mDvw=X3DJ_1r(>j24*JkTDVYP}pmm6}_xk_q>t5M4wMJ<8M3I<-xF zV{C%C2KX+lXngAxNuP40LlNK2vtN?*ZgXC>bJK^#eOY8aX@wwc&t6=_YH#ddu82ED zpB%)s0v;d@p%KeOk2v>tull0&b=++lO*y(PK(mY1Q&jQ6wByDNX;FSe@r} z@pSwMD(froHtt(|n;WUz<=^ewt|%ZQVxH?5_EIjE81|6FkKPm1QhX=a&jtK>F{yNT zPH-vAfAy5@=x)~mVJ&J0A@gQK-u2O+_DnV5;cJM9^WU86PDTBK%6Ysq_`(k*fO(32 zWb`fbru<*ng!@t5_yNjXMYamNb>hgiJSu6Y1`P)=C(@Q79moJW) zCPnojJjk0pU;o~k_+K(lwPG|0wNCHK`=UiOOB5c06qzjZ3TD4W#KAwt34$R*U`Q-p zm$pE!UYt>22BtD=vR?r?j%TK|W?4IWs(Tr>btlWZ?DFQypD)|G#@(X6A%;~bFLQkk z1RQ)mD}5uOp>GEhGN6fv8*5AybW9WNsVec;p$MDxT7IL{Q7z%C9o9&Mv+0iug3J+e$=UN~e``sL?cOir_Vv5K1(5tMf{$wV)>`?F(KTI#sL zL9Z{}RN-30#mSQR-IHEyj!tY~ABDvgw9?L%3Gi!~yj_0kBn>Vy$0!~K^mku6dD^?# zcuh6!NnV^BEK;WuJ?{xa|6kC^-6k4dC$~^HGxW_DW&{}ngYx16U(%CS-qW@_ z9sdxo^V35ckGrHS{CNERT%n}0l4i;83pnV3r%|*_=z>LSGQGB_!qoHnfl48acKlMD ziaBa)zFyK%I*V#aHih={a{m+H{g#o9Nv^e#`E~&A{U~sX$sAHEH5w^GM#t>z&h_u4i!xelH&ccOB6*h1qH3!&)36cu#V@N z+c-?Tt_zq)-|5nz%!cJR%yZ@4o@Y%B%eG2!0=V-LE+N>3!jpEq<bI+uX}F<0*DkYpk#Mm<%YHMUw3beU~G75PAvUW)Mjs3|m5IRYq(h+i5% ztuRgoriUC4XXPXFE_IbJM5e{`<^wFmWDVoI;zR3N5@aZFI1Ay}yhg4wgg#4oF=xjS z4Kj)usO()); - // oneFromOptionsDrop.dropIds = original.ToArray(); - // } - // } - //} + public override void SetDefaults(Item entity) { + if (entity.type == ItemID.FrostCore) { + entity.accessory = true; + } + } + + public override void UpdateAccessory(Item item, Player player, bool hideVisual) { + + var omp = player.GetModPlayer(); + + if (item.type == ItemID.FrostCore) { + omp.snowflake = true; + } } } } diff --git a/OmnitrixPlayer.cs b/OmnitrixPlayer.cs index acaaa2a..27af28b 100644 --- a/OmnitrixPlayer.cs +++ b/OmnitrixPlayer.cs @@ -3,6 +3,7 @@ using Microsoft.Xna.Framework; using System.Collections.Generic; using System.CommandLine.Help; +using System.Data.SqlTypes; using System.Linq; using Terraria; using Terraria.ID; @@ -44,9 +45,6 @@ public class OmnitrixPlayer : ModPlayer { public bool onCooldown = false; public bool altAttack = false; public bool ultimateAttack = false; - - public bool advancedCircuitMatrix = false; - public bool advancedCircuitMatrixEquippedWhileTransformed = false; public int cooldownTime = 120; public int transformationTime = 300; @@ -71,6 +69,7 @@ public class OmnitrixPlayer : ModPlayer { public TransformationEnum[] transformations = { TransformationEnum.HeatBlast, TransformationEnum.HeatBlast, TransformationEnum.HeatBlast, TransformationEnum.HeatBlast, TransformationEnum.HeatBlast }; public TransformationEnum currTransformation = TransformationEnum.None; public List unlockedTransformation = new List() { TransformationEnum.HeatBlast }; + public bool showingUI = false; public bool omnitrixUpdating = false; public bool omnitrixWasUpdating = false; @@ -89,6 +88,11 @@ public class OmnitrixPlayer : ModPlayer { public NPC possessedTarget = null; public int possessionTimer = 0; private const int PossessionDuration = 360; // 6 seconds + + // Accessory Values + public bool snowflake = false; + public bool advancedCircuitMatrix = false; + public bool advancedCircuitMatrixEquippedWhileTransformed = false; public Color GetChromaStoneOverlayColor() { @@ -151,6 +155,7 @@ public override void LoadData(TagCompound tag) public override void ResetEffects() { advancedCircuitMatrix = false; + snowflake = false; cooldownTime = 120; transformationTime = 300; @@ -302,11 +307,10 @@ public override void PostUpdateBuffs() { // Fourarms Transformation if (currTransformation == TransformationEnum.FourArms) { - - Player.GetAttackSpeed(DamageClass.Melee) += 0.25f; - Player.GetCritChance(DamageClass.Generic) = 50; - Player.noFallDmg = true; - Player.jumpSpeed *= 1.9f; + Player.GetAttackSpeed(DamageClass.Melee) += 0.25f; + Player.GetCritChance(DamageClass.Generic) = 50; + Player.noFallDmg = true; + Player.jumpSpeed *= 1.9f; } // Stinkfly Transformation @@ -337,6 +341,17 @@ public override void PostUpdate() { omnitrixEnergy += (omnitrixEnergyRegen / 120); if (omnitrixEnergy > omnitrixEnergyMax) omnitrixEnergy = omnitrixEnergyMax; + + if (KeybindSystem.OpenTransformationScreen.JustPressed && omnitrixEquipped) { + if (!showingUI) { + ModContent.GetInstance().ShowMyUI(); + showingUI = true; + } + else { + ModContent.GetInstance().HideMyUI(); + showingUI = false; + } + } if (isTransformed) { if (KeybindSystem.UltimateAbility.JustPressed) @@ -367,7 +382,7 @@ public override void PostUpdate() { if (currTransformation == TransformationEnum.HeatBlast) { Random rand = new Random(); - int dustNum = Dust.NewDust(Player.position, Player.width, Player.height, DustID.Flare, 0, rand.Next(-1, 2), rand.Next(-1, 2), Color.White, rand.Next(3)); + int dustNum = Dust.NewDust(Player.position, Player.width, Player.height, snowflake ? DustID.IceTorch : DustID.Flare, 0, rand.Next(-1, 2), rand.Next(-1, 2), Color.White, rand.Next(3)); Main.dust[dustNum].noGravity = true; if (KeybindSystem.PrimaryAbility.JustPressed) { if (!Player.HasBuff(ModContent.BuffType()) && !Player.HasBuff(ModContent.BuffType())) { @@ -378,13 +393,15 @@ public override void PostUpdate() { if (PrimaryAbilityEnabled) { Vector2[] points = GenerateCirclePoints(250, 7 * (16)); for (int i = 0; i < points.Length; i++) { - dustNum = Dust.NewDust(points[i] + Player.Center, 1, 1, DustID.Torch, rand.Next(-1, 2), rand.Next(-1, 2)); + dustNum = Dust.NewDust(points[i] + Player.Center, 1, 1, snowflake ? DustID.IceTorch : DustID.Torch, rand.Next(-1, 2), rand.Next(-1, 2)); Main.dust[dustNum].noGravity = true; } foreach (NPC npc in Main.npc) { if (Player.Distance(npc.Center) <= 10 * (16) && !npc.friendly) { - if (!npc.HasBuff(BuffID.OnFire3)) { + if (!npc.HasBuff(BuffID.Frostburn2) && snowflake) { + npc.AddBuff(BuffID.Frostburn2, 10 * 60); + } else if (!npc.HasBuff(BuffID.OnFire3)) { npc.AddBuff(BuffID.OnFire3, 10 * 60); } } @@ -588,8 +605,10 @@ public override void OnHurt(Player.HurtInfo info) { } public override void OnHitAnything(float x, float y, Entity victim) { - if (!Main.npc[victim.whoAmI].HasBuff(BuffID.OnFire3) && currTransformation == TransformationEnum.HeatBlast) { - Main.npc[victim.whoAmI].AddBuff(BuffID.OnFire3, 3 * 60); + if (!Main.npc[victim.whoAmI].HasBuff(BuffID.Frostburn2) && snowflake && currTransformation == TransformationEnum.HeatBlast) { + Main.npc[victim.whoAmI].AddBuff(BuffID.Frostburn2, 10 * 60); + } else if (!Main.npc[victim.whoAmI].HasBuff(BuffID.OnFire3) && !snowflake && currTransformation == TransformationEnum.HeatBlast) { + Main.npc[victim.whoAmI].AddBuff(BuffID.OnFire3, 10 * 60); } } @@ -696,7 +715,6 @@ public override void DrawEffects(PlayerDrawSet drawInfo, ref float r, ref float public override void FrameEffects() { - var customSlot = ModContent.GetInstance(); if (omnitrixEquipped) { @@ -774,9 +792,16 @@ public override void FrameEffects() { } if (currTransformation == TransformationEnum.HeatBlast) { var costume = ModContent.GetInstance(); - Player.head = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Head); - Player.body = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Body); - Player.legs = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Legs); + if (snowflake) { + Player.head = EquipLoader.GetEquipSlot(Mod, costume.Name + "Alt", EquipType.Head); + Player.body = EquipLoader.GetEquipSlot(Mod, costume.Name + "Alt", EquipType.Body); + Player.legs = EquipLoader.GetEquipSlot(Mod, costume.Name + "Alt", EquipType.Legs); + } + else { + Player.head = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Head); + Player.body = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Body); + Player.legs = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Legs); + } } if (currTransformation == TransformationEnum.RipJaws) { var costume = ModContent.GetInstance(); diff --git a/OmnitrixProjectile.cs b/OmnitrixProjectile.cs new file mode 100644 index 0000000..5b9e2c1 --- /dev/null +++ b/OmnitrixProjectile.cs @@ -0,0 +1,47 @@ +using Ben10Mod.Content.Items.Weapons; +using Ben10Mod.Content.Projectiles; +using Microsoft.Xna.Framework; +using Terraria; +using Terraria.DataStructures; +using Terraria.ID; +using Terraria.ModLoader; +using Terraria.WorldBuilding; + +namespace Ben10Mod; + +public class OmnitrixProjectile : GlobalProjectile { + public override bool InstancePerEntity => true; + + public int itemUsed = 0; + + public override void OnSpawn(Projectile projectile, IEntitySource source) { + if (source is IEntitySource_WithStatsFromItem itemSource) { + itemUsed = itemSource.Item.type; + } + } + + public override void ModifyHitNPC(Projectile projectile, NPC target, ref NPC.HitModifiers modifiers) { + // if (itemUsed == ModContent.ItemType()) + // if (target.life / (float)target.lifeMax >= 0.9f) { + // modifiers.FinalDamage *= 1.5f; + // } + } + + public override void OnHitNPC(Projectile projectile, NPC target, NPC.HitInfo hit, int damageDone) { + // if (itemUsed == ModContent.ItemType()) + // target.AddBuff(BuffID.OnFire, 120); + if (itemUsed == ModContent.ItemType()) { + if (!Main.rand.NextBool(3)) return; + for (int i = 0; i < 3; i++) { + Vector2 spawnPos = target.Center + new Vector2(Main.rand.NextFloat(-200f, 201f), -620f); + Vector2 vel = (target.Center - spawnPos).SafeNormalize(Vector2.Zero) * 17.5f; + int projNum = Projectile.NewProjectile(projectile.GetSource_FromThis(), + spawnPos, + vel, ProjectileID.QueenSlimeGelAttack, + damageDone / 3, 0); + Main.projectile[projNum].hostile = false; + Main.projectile[projNum].friendly = true; + } + } + } +} \ No newline at end of file diff --git a/ShopNPC.cs b/ShopNPC.cs index 7b8c7b2..b2ef4fe 100644 --- a/ShopNPC.cs +++ b/ShopNPC.cs @@ -1,10 +1,12 @@ using System.Linq; using Ben10Mod.Content.Items.Accessories; using Ben10Mod.Content.Items.Consumable; +using Ben10Mod.Content.Items.Materials; using Ben10Mod.Content.Items.Vanity; using Terraria; using Terraria.GameContent.ItemDropRules; using Terraria.ID; +using Terraria.Localization; using Terraria.ModLoader; namespace Ben10Mod; @@ -29,6 +31,11 @@ public override void ModifyNPCLoot(NPC npc, NPCLoot npcLoot) { )); } + if (npc.type == NPCID.LunarTowerSolar || npc.type == NPCID.LunarTowerNebula || npc.type == NPCID.LunarTowerStardust || npc.type == NPCID.LunarTowerVortex) { + npcLoot.Add(ItemDropRule.ByCondition(new Conditions.NotExpert(), ModContent.ItemType(), 1, 4, 15)); + npcLoot.Add(ItemDropRule.ByCondition(new NotNormalMode(), ModContent.ItemType(), 1, 6, 25)); + } + if (npc.type == NPCID.WallofFlesh) { // Remove the original vanilla emblem rule npcLoot.RemoveWhere(rule => rule is OneFromOptionsNotScaledWithLuckDropRule optionsRule @@ -45,4 +52,16 @@ public override void ModifyNPCLoot(NPC npc, NPCLoot npcLoot) { )); } } +} + +public class NotNormalMode : IItemDropRuleCondition, IProvideItemConditionDescription { + public bool CanDrop(DropAttemptInfo info) => Main.expertMode || Main.masterMode; + public bool CanShowItemDropInUI() => Main.expertMode || Main.masterMode; + public string GetConditionDescription() => "Only drops in Expert or Master mode"; +} + +public class IsNormalMode : IItemDropRuleCondition, IProvideItemConditionDescription { + public bool CanDrop(DropAttemptInfo info) => !Main.expertMode && !Main.masterMode; + public bool CanShowItemDropInUI() => !Main.expertMode && !Main.masterMode; + public string GetConditionDescription() => "Only drops in Normal difficulty"; } \ No newline at end of file From 9da44fedf6fa598aa887bb601b59143555e5d348 Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Tue, 3 Mar 2026 07:34:44 +1100 Subject: [PATCH 11/25] Fixed buzzshock minion --- Content/Buffs/Summons/BuzzShockMinionBuff.cs | 25 ++ Content/Buffs/Summons/BuzzShockMinionBuff.png | Bin 0 -> 3008 bytes Content/Items/Weapons/PlumbersBadge.cs | 66 ++-- .../Projectiles/BuzzShockMinionProjectile.cs | 326 ++++++++++-------- Localization/en-US_Mods.Ben10Mod.hjson | 5 + 5 files changed, 246 insertions(+), 176 deletions(-) create mode 100644 Content/Buffs/Summons/BuzzShockMinionBuff.cs create mode 100644 Content/Buffs/Summons/BuzzShockMinionBuff.png diff --git a/Content/Buffs/Summons/BuzzShockMinionBuff.cs b/Content/Buffs/Summons/BuzzShockMinionBuff.cs new file mode 100644 index 0000000..e3751e1 --- /dev/null +++ b/Content/Buffs/Summons/BuzzShockMinionBuff.cs @@ -0,0 +1,25 @@ +using Ben10Mod.Content.Projectiles; +using Terraria; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Buffs.Summons; + +public class BuzzShockMinionBuff : ModBuff { + public override void SetStaticDefaults() { + Main.buffNoSave[Type] = true; + Main.buffNoTimeDisplay[Type] = true; + } + + public override void Update(Player player, ref int buffIndex) + { + if (player.ownedProjectileCounts[ModContent.ProjectileType()] > 0) + { + player.buffTime[buffIndex] = 18000; + } + else + { + player.DelBuff(buffIndex); + buffIndex--; + } + } +} \ No newline at end of file diff --git a/Content/Buffs/Summons/BuzzShockMinionBuff.png b/Content/Buffs/Summons/BuzzShockMinionBuff.png new file mode 100644 index 0000000000000000000000000000000000000000..ed8ce597139e4430d5d17430cacdb4a83480beeb GIT binary patch literal 3008 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 1f; // For universal scaling if needed public virtual float AttackSpeedMultiplier => 1f; public virtual float AdditionalProjectileChance => 0; - - public virtual string BadgeRankName => "Helper"; - public virtual int BadgeRankValue => 0; + + public virtual string BadgeRankName => "Helper"; + public virtual int BadgeRankValue => 0; public int OmnitrixEnergyUse = 0; @@ -66,7 +67,8 @@ private void FinalizeUltimateIfEnded(Player player, OmnitrixPlayer omp) { // If the ultimate projectile is still alive, ultimate is still in progress. int ultimateProjType = GetUltimateProjectileType(omp); - if (HasActiveOwnedProjectile(player, ultimateProjType) && omp.currTransformation == TransformationEnum.EyeGuy) return; + if (HasActiveOwnedProjectile(player, ultimateProjType) && + omp.currTransformation == TransformationEnum.EyeGuy) return; // If we're here, the player has released channel and the ultimate projectile is gone. if (!player.HasBuff()) @@ -76,7 +78,6 @@ private void FinalizeUltimateIfEnded(Player player, OmnitrixPlayer omp) { state.ultimateStarted = false; } - public override void SetDefaults() { Item.width = 32; Item.height = 32; @@ -91,7 +92,6 @@ public override void SetDefaults() { Item.damage = BaseDamage; Item.knockBack = 4f; - // Base defaults - overridden per alien in HoldItem Item.useStyle = ItemUseStyleID.Swing; Item.useTime = Item.useAnimation = 25; Item.shootSpeed = 10f; @@ -225,38 +225,36 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, if (!omp.isTransformed || player.altFunctionUse == 2) return false; - // Block non-ultimate attacks while an ultimate is in progress (channeling or projectile alive). - int activeUltimateType = GetUltimateProjectileType(omp); + int activeUltimateType = GetUltimateProjectileType(omp); bool ultimateInProgress = player.channel || player.GetModPlayer().ultimateStarted; - // If ultimate is in progress, only allow firing the ultimate projectile itself (and only once). if (ultimateInProgress && !omp.ultimateAttack) return false; - // Don't allow starting an ultimate while on cooldown. - if (omp.ultimateAttack && player.HasBuff()) return false; - - int projType = - ProjectileID.ImpFireball; // Bright vanilla fallback - you SHOULD see this if alien not matched + int projType = ProjectileID.ImpFireball; int finalDamage = damage; switch (omp.currTransformation) { case TransformationEnum.HeatBlast: projType = omp.ultimateAttack ? ModContent.ProjectileType() : omp.altAttack ? ModContent.ProjectileType() : ProjectileID.Flames; - finalDamage = omp.ultimateAttack ? (int)(damage * 3f) : omp.altAttack ? (int)(damage * 1.5f) : (int)(damage * 0.3f); + finalDamage = omp.ultimateAttack ? (int)(damage * 3f) : + omp.altAttack ? (int)(damage * 1.5f) : (int)(damage * 0.3f); if (omp.ultimateAttack) { - velocity = Vector2.Zero; + velocity = Vector2.Zero; } + break; + case TransformationEnum.XLR8: projType = ModContent.ProjectileType(); finalDamage = (int)(damage * 0.25f); break; + case TransformationEnum.FourArms: projType = omp.altAttack ? ModContent.ProjectileType() @@ -285,10 +283,24 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, break; case TransformationEnum.BuzzShock: - projType = omp.altAttack - ? ModContent.ProjectileType() - : ModContent.ProjectileType(); + + if (omp.altAttack) { + SoundEngine.PlaySound(SoundID.AbigailSummon, player.position); + int buffType = ModContent.BuffType(); + int minionType = ModContent.ProjectileType(); + player.AddBuff(buffType, 2); + player.SpawnMinionOnCursor( + source, + player.whoAmI, + minionType, + (int)(finalDamage * DamageMultiplier), + knockback + ); + + return false; + } SoundEngine.PlaySound(SoundID.DD2_LightningAuraZap, player.position); + projType = ModContent.ProjectileType(); break; case TransformationEnum.StinkFly: @@ -300,7 +312,9 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, case TransformationEnum.GhostFreak: projType = omp.ultimateAttack ? ModContent.ProjectileType() - : omp.altAttack ? ProjectileID.CursedFlameFriendly : ModContent.ProjectileType(); + : omp.altAttack + ? ProjectileID.CursedFlameFriendly + : ModContent.ProjectileType(); break; case TransformationEnum.WildVine: @@ -308,6 +322,7 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, ? ModContent.ProjectileType() : ModContent.ProjectileType(); break; + case TransformationEnum.EyeGuy: projType = omp.ultimateAttack ? ModContent.ProjectileType() @@ -318,11 +333,9 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, if (projType == 0) return false; - // While channeling an ultimate, keep exactly one ultimate projectile alive. if (omp.ultimateAttack && HasActiveOwnedProjectile(player, projType)) return false; - // Mark ultimate as started the moment we actually fire its projectile. if (omp.ultimateAttack && projType == activeUltimateType) player.GetModPlayer().ultimateStarted = true; @@ -331,12 +344,15 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, if (!omp.ultimateAttack) { for (int i = (int)Math.Floor(AdditionalProjectileChance); i >= 1; i--) { - Projectile.NewProjectile(source, position, velocity.RotatedByRandom(0.25f), projType, (int)(finalDamage * DamageMultiplier), + Projectile.NewProjectile(source, position, velocity.RotatedByRandom(0.25f), projType, + (int)(finalDamage * DamageMultiplier), knockback, player.whoAmI); } - if (Main.rand.Next(100) <= 100 * (int)(AdditionalProjectileChance - Math.Floor(AdditionalProjectileChance))) { - Projectile.NewProjectile(source, position, velocity.RotatedByRandom(0.25f), projType, (int)(finalDamage * DamageMultiplier), + if (Main.rand.Next(100) <= + 100 * (int)(AdditionalProjectileChance - Math.Floor(AdditionalProjectileChance))) { + Projectile.NewProjectile(source, position, velocity.RotatedByRandom(0.25f), projType, + (int)(finalDamage * DamageMultiplier), knockback, player.whoAmI); } } diff --git a/Content/Projectiles/BuzzShockMinionProjectile.cs b/Content/Projectiles/BuzzShockMinionProjectile.cs index f229dbc..f9f0841 100644 --- a/Content/Projectiles/BuzzShockMinionProjectile.cs +++ b/Content/Projectiles/BuzzShockMinionProjectile.cs @@ -1,8 +1,7 @@ using Microsoft.Xna.Framework; using System; -using Ben10Mod.Enums; +using Ben10Mod.Content.Buffs.Summons; using Terraria; -using Terraria.Audio; using Terraria.DataStructures; using Terraria.ID; using Terraria.ModLoader; @@ -10,207 +9,232 @@ namespace Ben10Mod.Content.Projectiles { public class BuzzShockMinionProjectile : ModProjectile { - // Follow tuning - private const float FollowLerp = 0.12f; - private const float MaxFollowSpeed = 12f; + private const float IdleInertia = 40f; + private const float IdleSpeed = 10f; - // Combat tuning - private const float DetectRange = 700f; - private const float AttackRange = 520f; - private const int AttackCooldownTicks = 60; // base cooldown (~1s) - private const float ThrowSpeed = 13f; + private const float ChargeSpeed = 22f; + private const float ChargeInertia = 8f; + private const float ChargeOvershoot = 110f; + private const float MaxTargetRange = 700f; + private const float LostTargetRange = 950f; + + private const float RecoverSpeed = 12f; + private const float RecoverInertia = 18f; + private const int RecoverTime = 20; + + private ref float State => ref Projectile.ai[0]; + private ref float Timer => ref Projectile.ai[1]; + + private const int State_Idle = 0; + private const int State_Charge = 1; + private const int State_Recover = 2; public override void SetStaticDefaults() { ProjectileID.Sets.MinionTargettingFeature[Type] = true; - ProjectileID.Sets.MinionSacrificable[Type] = true; - Main.projFrames[Projectile.type] = 1; + ProjectileID.Sets.MinionSacrificable[Type] = true; + Main.projFrames[Projectile.type] = 1; } public override void SetDefaults() { - Projectile.width = 40; + Projectile.width = 40; Projectile.height = 52; - - Projectile.minion = true; - Projectile.minionSlots = 0.5f; - Projectile.friendly = false; - Projectile.DamageType = DamageClass.Summon; - + Projectile.friendly = true; + Projectile.minion = true; + Projectile.DamageType = DamageClass.Summon; + Projectile.minionSlots = 1f; + Projectile.penetrate = -1; Projectile.tileCollide = false; Projectile.ignoreWater = true; - - Projectile.penetrate = -1; + Projectile.timeLeft = 18000; Projectile.netImportant = true; - } - - public override void OnSpawn(IEntitySource source) { - // Personal offset so each minion stays out of sync forever (deterministic, MP-safe) - // 0..19 ticks extra delay depending on whoAmI - Projectile.localAI[0] = Projectile.whoAmI % 20; - // Start cooldown already offset (prevents first volley syncing) - Projectile.ai[0] = Projectile.localAI[0]; + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 30; } + public override bool MinionContactDamage() => true; + public override void AI() { Player player = Main.player[Projectile.owner]; if (!player.active || player.dead) { - Projectile.Kill(); + player.ClearBuff(ModContent.BuffType()); + return; + } + + if (player.HasBuff(ModContent.BuffType())) { + Projectile.timeLeft = 2; + } + + Vector2 idlePosition = GetIdlePosition(player); + NPC target = FindTarget(player, MaxTargetRange); + + if (State == State_Recover) { + DoRecoverMovement(idlePosition); + + Projectile.rotation = Projectile.velocity.X * 0.05f; + Projectile.spriteDirection = Projectile.velocity.X >= 0f ? 1 : -1; return; } - // --- Idle follow position behind player (slot-aware, stable with 0.5 minionSlots) --- - float slotPos = Projectile.minionPos; // computed by Terraria using minionSlots - float spacingPerSlot = 44f; // spacing per 1.0 summon slot - - Vector2 behind = new Vector2( - -player.direction * (56f + slotPos * spacingPerSlot), - -24f - ); - - // stable stagger + gentle bob so they don't overlap perfectly - behind.Y += ((Projectile.whoAmI & 1) == 0) ? 0f : 10f; - behind.Y += (float)Math.Sin((Main.GameUpdateCount + (ulong)Projectile.whoAmI) * 0.08f) * 3f; - - Vector2 idlePos = player.Center + behind; - - float distToIdle = Vector2.Distance(Projectile.Center, idlePos); - if (distToIdle > 1000f) { - SoundEngine.PlaySound(SoundID.Item8, Projectile.Center); - Random random = new Random(); - for (int i = 0; i < 50; i++) { - int dustNum = Dust.NewDust(Projectile.position - new Vector2(1, 1), Projectile.width + 1, Projectile.height + 1, DustID.UltraBrightTorch, random.Next(-4, 5), random.Next(-4, 5), 1, Color.White, 2); - Main.dust[dustNum].noGravity = true; + if (target == null) { + State = State_Idle; + DoIdleMovement(idlePosition); + } + else { + if (State != State_Charge) { + State = State_Charge; + Timer = target.whoAmI; + Projectile.netUpdate = true; } - Projectile.Center = idlePos; - Projectile.velocity = Vector2.Zero; + + DoChargeMovement(target, idlePosition); + } + + Projectile.rotation = Projectile.velocity.X * 0.05f; + Projectile.spriteDirection = Projectile.velocity.X >= 0f ? 1 : -1; + } + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { + State = State_Recover; + Timer = RecoverTime; + + Vector2 away = Projectile.Center - target.Center; + if (away == Vector2.Zero) + away = new Vector2(Projectile.spriteDirection == 0 ? 1f : Projectile.spriteDirection, 0f); + + away.Normalize(); + Projectile.velocity = away * 14f; + Projectile.netUpdate = true; + } + + private Vector2 GetIdlePosition(Player player) { + int index = 0; + + for (int i = 0; i < Main.maxProjectiles; i++) { + Projectile other = Main.projectile[i]; + if (!other.active || other.owner != Projectile.owner || other.type != Projectile.type || other.whoAmI == Projectile.whoAmI) + continue; + + if (other.whoAmI < Projectile.whoAmI) + index++; + } + + float side = index % 2 == 0 ? 1f : -1f; + float row = index / 2; + + return player.Center + new Vector2(56f * side, -60f - row * 36f); + } + + private void DoIdleMovement(Vector2 idlePosition) { + Vector2 toIdle = idlePosition - Projectile.Center; + float distance = toIdle.Length(); + + if (distance > 2000f) { + Projectile.Center = idlePosition; + Projectile.velocity *= 0.1f; Projectile.netUpdate = true; - for (int i = 0; i < 50; i++) { - int dustNum = Dust.NewDust(Projectile.position - new Vector2(1, 1), Projectile.width + 1, Projectile.height + 1, DustID.UltraBrightTorch, random.Next(-4, 5), random.Next(-4, 5), 1, Color.White, 2); - Main.dust[dustNum].noGravity = true; - } } - // --- Targeting --- - int targetIndex = FindTarget(player, out float targetDist); - bool hasTarget = targetIndex != -1; - NPC target = hasTarget ? Main.npc[targetIndex] : null; + if (distance > 16f) { + toIdle.Normalize(); + toIdle *= IdleSpeed; + Projectile.velocity = (Projectile.velocity * (IdleInertia - 1f) + toIdle) / IdleInertia; + } + else if (Projectile.velocity.Length() > 1f) { + Projectile.velocity *= 0.96f; + } + } - // --- Movement --- - // IMPORTANT CHANGE: don't move all minions to the same "attackOffset". - // Keep their pack spacing and only raise them a bit while in combat. - Vector2 desiredPos = idlePos; + private void DoChargeMovement(NPC target, Vector2 idlePosition) { + if (!target.active || target.friendly || target.dontTakeDamage) { + State = State_Idle; + Projectile.netUpdate = true; + return; + } - if (hasTarget && targetDist < AttackRange) { - desiredPos += new Vector2(0f, -14f); // small combat lift, keeps spacing + float distanceToTarget = Vector2.Distance(Projectile.Center, target.Center); + if (distanceToTarget > LostTargetRange) { + State = State_Idle; + Projectile.netUpdate = true; + return; } - MoveToward(desiredPos); + Vector2 chargeDirection = Projectile.Center.DirectionTo(target.Center); + if (chargeDirection == Vector2.Zero) + chargeDirection = Vector2.UnitX * Projectile.spriteDirection; - // --- Face direction --- - if (hasTarget) { - Projectile.direction = (target.Center.X > Projectile.Center.X) ? 1 : -1; - Projectile.spriteDirection = Projectile.direction; + Vector2 chargeDestination = target.Center + chargeDirection * ChargeOvershoot; + Vector2 toChargeDestination = chargeDestination - Projectile.Center; + float distanceToDestination = toChargeDestination.Length(); + + if (distanceToDestination > 8f) { + toChargeDestination.Normalize(); + toChargeDestination *= ChargeSpeed; + Projectile.velocity = (Projectile.velocity * (ChargeInertia - 1f) + toChargeDestination) / ChargeInertia; } else { - Projectile.direction = player.direction; - Projectile.spriteDirection = Projectile.direction; - } - - // --- Attack --- - if (Projectile.ai[0] > 0) - Projectile.ai[0]--; - - if (hasTarget && targetDist < AttackRange) { - if (Main.myPlayer == Projectile.owner && Projectile.ai[0] <= 0) { - if (Collision.CanHitLine(Projectile.Center, 1, 1, target.Center, 1, 1)) { - Vector2 from = Projectile.Center + new Vector2(Projectile.direction * 10f, -6f); - Vector2 to = target.Center; - - Vector2 vel = to - from; - if (vel.LengthSquared() < 0.001f) - vel = Vector2.UnitX * Projectile.direction; - - vel.Normalize(); - vel *= ThrowSpeed; - - int projType = ModContent.ProjectileType(); - - Projectile.NewProjectile( - Projectile.GetSource_FromThis(), - from, - vel, - projType, - Projectile.damage, - Projectile.knockBack, - Projectile.owner - ); - - // IMPORTANT CHANGE: per-minion offset so they don't shoot in sync - Projectile.ai[0] = AttackCooldownTicks + (int)Projectile.localAI[0]; - Projectile.netUpdate = true; - } - else { - // If we can't see the target, don't "spam attempt" every tick. - Projectile.ai[0] = 10 + (int)Projectile.localAI[0]; - } + State = State_Recover; + Timer = 10f; + + Vector2 toIdle = idlePosition - Projectile.Center; + if (toIdle != Vector2.Zero) { + toIdle.Normalize(); + Projectile.velocity = toIdle * 10f; } + + Projectile.netUpdate = true; } } - private void MoveToward(Vector2 destination) { - Vector2 toDest = destination - Projectile.Center; - float dist = toDest.Length(); + private void DoRecoverMovement(Vector2 idlePosition) { + Timer--; - if (dist < 6f) { - Projectile.velocity *= 0.9f; - return; - } + Vector2 toIdle = idlePosition - Projectile.Center; + float distance = toIdle.Length(); - Vector2 desiredVel = toDest * FollowLerp; - if (desiredVel.Length() > MaxFollowSpeed) - desiredVel = Vector2.Normalize(desiredVel) * MaxFollowSpeed; + if (distance > 16f) { + toIdle.Normalize(); + toIdle *= RecoverSpeed; + Projectile.velocity = (Projectile.velocity * (RecoverInertia - 1f) + toIdle) / RecoverInertia; + } + else if (Projectile.velocity.Length() > 1f) { + Projectile.velocity *= 0.94f; + } - Projectile.velocity = Vector2.Lerp(Projectile.velocity, desiredVel, 0.25f); + if (Timer <= 0f) { + State = State_Idle; + Projectile.netUpdate = true; + } } - private int FindTarget(Player player, out float bestDist) { - bestDist = DetectRange; + private NPC FindTarget(Player player, float maxDetectDistance) { + NPC selectedTarget = null; + float sqrMaxDetectDistance = maxDetectDistance * maxDetectDistance; if (player.HasMinionAttackTargetNPC) { - NPC forced = Main.npc[player.MinionAttackTargetNPC]; - if (forced.CanBeChasedBy(this)) { - float d = Vector2.Distance(Projectile.Center, forced.Center); - if (d < DetectRange) { - bestDist = d; - return forced.whoAmI; + NPC npc = Main.npc[player.MinionAttackTargetNPC]; + if (npc.CanBeChasedBy(this)) { + float sqrDistanceToTarget = Vector2.DistanceSquared(npc.Center, Projectile.Center); + if (sqrDistanceToTarget < sqrMaxDetectDistance) { + return npc; } } } - int best = -1; - for (int i = 0; i < Main.maxNPCs; i++) { - NPC npc = Main.npc[i]; + for (int k = 0; k < Main.maxNPCs; k++) { + NPC npc = Main.npc[k]; if (!npc.CanBeChasedBy(this)) continue; - float d = Vector2.Distance(Projectile.Center, npc.Center); - if (d < bestDist) { - bestDist = d; - best = i; + float sqrDistanceToTarget = Vector2.DistanceSquared(npc.Center, Projectile.Center); + if (sqrDistanceToTarget < sqrMaxDetectDistance) { + sqrMaxDetectDistance = sqrDistanceToTarget; + selectedTarget = npc; } } - return best; - } - - public override void PostAI() { - Player player = Main.player[Projectile.owner]; - - if (!player.active || player.dead || - player.GetModPlayer().currTransformation != TransformationEnum.BuzzShock) { - Projectile.Kill(); - } + return selectedTarget; } } -} +} \ No newline at end of file diff --git a/Localization/en-US_Mods.Ben10Mod.hjson b/Localization/en-US_Mods.Ben10Mod.hjson index b056ecf..7bb3203 100644 --- a/Localization/en-US_Mods.Ben10Mod.hjson +++ b/Localization/en-US_Mods.Ben10Mod.hjson @@ -356,6 +356,11 @@ Buffs: { DisplayName: Primary Ability Cooldown Description: Primary Ability On Cooldown } + + BuzzShockMinionBuff: { + DisplayName: Buzz Shock Minion Buff + Description: Mods.Ben10Mod.Buffs.BuzzShockMinionBuff.Description + } } Projectiles: { From d391554900c303f596668fd8a3984bed8fe7f8e7 Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Tue, 3 Mar 2026 20:01:30 +1100 Subject: [PATCH 12/25] Working on ultimate abilities and refining already existing abilites --- Content/Items/Weapons/PlumbersBadge.cs | 23 ++++-- .../Projectiles/BuzzShockMinionProjectile.cs | 9 +++ .../BuzzShockUltimateProjectile.cs | 74 +++++++++++++++++++ Content/Projectiles/ChromaStoneProjectile.cs | 3 +- Localization/en-US_Mods.Ben10Mod.hjson | 1 + ShopNPC.cs | 6 ++ 6 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 Content/Projectiles/BuzzShockUltimateProjectile.cs diff --git a/Content/Items/Weapons/PlumbersBadge.cs b/Content/Items/Weapons/PlumbersBadge.cs index 5147937..9d2f883 100644 --- a/Content/Items/Weapons/PlumbersBadge.cs +++ b/Content/Items/Weapons/PlumbersBadge.cs @@ -25,7 +25,7 @@ public abstract class PlumbersBadge : ModItem { public virtual string BadgeRankName => "Helper"; public virtual int BadgeRankValue => 0; - public int OmnitrixEnergyUse = 0; + public int OmnitrixEnergyUse = 0; private int GetUltimateProjectileType(OmnitrixPlayer omp) { @@ -35,6 +35,7 @@ private int GetUltimateProjectileType(OmnitrixPlayer omp) { TransformationEnum.GhostFreak => ModContent.ProjectileType(), TransformationEnum.DiamondHead => ModContent.ProjectileType(), TransformationEnum.HeatBlast => ModContent.ProjectileType(), + TransformationEnum.BuzzShock => ModContent.ProjectileType(), _ => 0 }; } @@ -168,8 +169,9 @@ public override void HoldItem(Player player) { break; case TransformationEnum.BuzzShock: - Item.useTime = Item.useAnimation = 20; - Item.shootSpeed = 25f; + Item.useTime = Item.useAnimation = 20; + Item.shootSpeed = 25f; + OmnitrixEnergyUse = omp.ultimateAttack ? 25 : 0; break; case TransformationEnum.StinkFly: @@ -278,7 +280,7 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, break; case TransformationEnum.ChromaStone: - projType = ModContent.ProjectileType(); + projType = ModContent.ProjectileType(); finalDamage += omp.ChromaStoneAbsorbtion; break; @@ -300,7 +302,9 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, return false; } SoundEngine.PlaySound(SoundID.DD2_LightningAuraZap, player.position); - projType = ModContent.ProjectileType(); + if (omp.ultimateAttack) finalDamage = (int)(2.5f * finalDamage); + projType = omp.ultimateAttack ? ModContent.ProjectileType() : ModContent.ProjectileType(); + break; case TransformationEnum.StinkFly: @@ -339,6 +343,15 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, if (omp.ultimateAttack && projType == activeUltimateType) player.GetModPlayer().ultimateStarted = true; + if (omp.currTransformation == TransformationEnum.BuzzShock && omp.ultimateAttack) { + for (int i = 0; i < 5; i++) { + Projectile.NewProjectile(source, position, velocity.RotatedBy(i * 2.5), projType, (int)(finalDamage * DamageMultiplier), + knockback, player.whoAmI); + } + + return false; + } + Projectile.NewProjectile(source, position, velocity, projType, (int)(finalDamage * DamageMultiplier), knockback, player.whoAmI); diff --git a/Content/Projectiles/BuzzShockMinionProjectile.cs b/Content/Projectiles/BuzzShockMinionProjectile.cs index f9f0841..eb2937b 100644 --- a/Content/Projectiles/BuzzShockMinionProjectile.cs +++ b/Content/Projectiles/BuzzShockMinionProjectile.cs @@ -2,6 +2,7 @@ using System; using Ben10Mod.Content.Buffs.Summons; using Terraria; +using Terraria.Audio; using Terraria.DataStructures; using Terraria.ID; using Terraria.ModLoader; @@ -106,6 +107,14 @@ public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { away.Normalize(); Projectile.velocity = away * 14f; Projectile.netUpdate = true; + + for (int i = 0; i < 25; i++) { + int dustNum = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, + DustID.UltraBrightTorch, Scale: Main.rand.Next(1, 4)); + Main.dust[dustNum].noGravity = true; + } + + SoundEngine.PlaySound(SoundID.Thunder, Projectile.position); } private Vector2 GetIdlePosition(Player player) { diff --git a/Content/Projectiles/BuzzShockUltimateProjectile.cs b/Content/Projectiles/BuzzShockUltimateProjectile.cs new file mode 100644 index 0000000..5ed53f1 --- /dev/null +++ b/Content/Projectiles/BuzzShockUltimateProjectile.cs @@ -0,0 +1,74 @@ +using Microsoft.Xna.Framework; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Terraria; +using Terraria.DataStructures; +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Projectiles { + public class BuzzShockUltimateProjectile : ModProjectile { + + public override string Texture => $"Terraria/Images/Projectile_{ProjectileID.None}"; + + private int target = -1; + + public override void SetDefaults() { + Projectile.width = 16; + Projectile.height = 16; + Projectile.aiStyle = ProjAIStyleID.Arrow; + + AIType = ProjectileID.Bullet; + Projectile.friendly = true; + Projectile.penetrate = 10; + + Projectile.DamageType = DamageClass.Ranged; + + } + + public override void EmitEnchantmentVisualsAt(Vector2 boxPosition, int boxWidth, int boxHeight) { + int dustNum = Dust.NewDust(boxPosition, boxWidth, boxHeight, DustID.UltraBrightTorch, Scale: 3); + Main.dust[dustNum].noGravity = true; + } + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { + FindTarget(); + for (int i = 0; i < 5; i++) { + int dustNum = Dust.NewDust(target.position, target.width, target.height, DustID.UltraBrightTorch); + Main.dust[dustNum].noGravity = true; + } + } + + public override void AI() { + if (target == -1 || !Main.npc[target].active || !Main.npc[target].CanBeChasedBy(this)) { + target = -1; + FindTarget(); + } + + if (target != -1) { + NPC npc = Main.npc[target]; + Vector2 desiredVelocity = Projectile.DirectionTo(npc.Center) * 24f; + Projectile.velocity = Vector2.Lerp(Projectile.velocity, desiredVelocity, 0.2f); + } + } + + private void FindTarget() { + float smallestDistance = 250f; + target = -1; + + foreach (NPC npc in Main.npc) { + if (npc.CanBeChasedBy(this)) { + float distance = Vector2.Distance(Projectile.Center, npc.Center); + if (distance < smallestDistance) { + smallestDistance = distance; + target = npc.whoAmI; + } + } + } + } + } +} diff --git a/Content/Projectiles/ChromaStoneProjectile.cs b/Content/Projectiles/ChromaStoneProjectile.cs index 8c6c849..11763a3 100644 --- a/Content/Projectiles/ChromaStoneProjectile.cs +++ b/Content/Projectiles/ChromaStoneProjectile.cs @@ -21,10 +21,11 @@ public override void SetDefaults() { AIType = ProjectileID.Bullet; Projectile.friendly = true; - Projectile.tileCollide = true; + Projectile.tileCollide = false; Projectile.penetrate = -1; Projectile.DamageType = DamageClass.Magic; + Projectile.timeLeft = 60 * 5; } diff --git a/Localization/en-US_Mods.Ben10Mod.hjson b/Localization/en-US_Mods.Ben10Mod.hjson index 7bb3203..88fa28d 100644 --- a/Localization/en-US_Mods.Ben10Mod.hjson +++ b/Localization/en-US_Mods.Ben10Mod.hjson @@ -388,6 +388,7 @@ Projectiles: { GiantDiamondProjectile.DisplayName: Giant Diamond Projectile HeatBlastUltimateProjectile.DisplayName: Heat Blast Ultimate Projectile IcyFlames.DisplayName: Icy Flames + BuzzShockUltimateProjectile.DisplayName: Buzz Shock Ultimate Projectile } Tiles: { diff --git a/ShopNPC.cs b/ShopNPC.cs index b2ef4fe..01c3cf7 100644 --- a/ShopNPC.cs +++ b/ShopNPC.cs @@ -3,6 +3,7 @@ using Ben10Mod.Content.Items.Consumable; using Ben10Mod.Content.Items.Materials; using Ben10Mod.Content.Items.Vanity; +using Ben10Mod.Content.Items.Weapons; using Terraria; using Terraria.GameContent.ItemDropRules; using Terraria.ID; @@ -51,6 +52,11 @@ public override void ModifyNPCLoot(NPC npc, NPCLoot npcLoot) { ModContent.ItemType() )); } + + if (npc.type == NPCID.QueenSlimeBoss) { + npcLoot.Add(ItemDropRule.BossBagByCondition(new NotNormalMode(), ModContent.ItemType())); + npcLoot.Add(ItemDropRule.ByCondition(new IsNormalMode(), ModContent.ItemType(), 10, 0)); + } } } From 97bf87ae3bc9d1d3963d92603f229f7d894f467c Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Tue, 3 Mar 2026 21:21:35 +1100 Subject: [PATCH 13/25] Working on XLR8's timestop ability --- Content/Buffs/Abilities/UltimateAbility.cs | 18 +++++++ .../UltimateAbilityCooldown.cs} | 8 +-- .../Buffs/Transformations/BuzzShock_Buff.cs | 2 +- .../Buffs/Transformations/ChromaStone_Buff.cs | 2 +- .../Buffs/Transformations/DiamondHead_Buff.cs | 2 +- Content/Buffs/Transformations/EyeGuy_Buff.cs | 2 +- .../Buffs/Transformations/FourArms_Buff.cs | 2 +- .../Buffs/Transformations/GhostFreak_Buff.cs | 2 +- .../Buffs/Transformations/HeatBlast_Buff.cs | 2 +- .../Buffs/Transformations/OmnitrixUpdating.cs | 2 +- Content/Buffs/Transformations/RipJaws_Buff.cs | 2 +- .../Buffs/Transformations/StinkFly_Buff.cs | 2 +- .../TransformationCooldown_Buff.cs | 2 +- .../Buffs/Transformations/WildVine_Buff.cs | 2 +- Content/Buffs/Transformations/XLR8_Buff.cs | 2 +- Content/Items/Weapons/PlumbersBadge.cs | 8 +-- Content/TransformationHandler.cs | 1 - Enums/TranformationEnum.cs | 1 - Localization/en-US_Mods.Ben10Mod.hjson | 10 ++++ NpcEffects.cs | 10 ++++ OmnitrixPlayer.cs | 52 +++++++++++++------ OmnitrixProjectile.cs | 2 +- bossTrackerNPC.cs | 2 +- 23 files changed, 97 insertions(+), 41 deletions(-) create mode 100644 Content/Buffs/Abilities/UltimateAbility.cs rename Content/Buffs/{Debuffs/TransformationCooldown_Buff.cs => Abilities/UltimateAbilityCooldown.cs} (67%) diff --git a/Content/Buffs/Abilities/UltimateAbility.cs b/Content/Buffs/Abilities/UltimateAbility.cs new file mode 100644 index 0000000..82feab1 --- /dev/null +++ b/Content/Buffs/Abilities/UltimateAbility.cs @@ -0,0 +1,18 @@ +using Terraria; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Buffs.Abilities; + +public class UltimateAbility : ModBuff { + + public override string Texture => "Ben10Mod/Content/Buffs/Abilities/PrimaryAbility"; + + public override void Update(Player player, ref int buffIndex) { + var omp = player.GetModPlayer(); + + omp.ultimateAbilityEnabled = true; + omp.ultimateAbilityWasEnabled = true; + } + + public override bool RightClick(int buffIndex) => false; +} \ No newline at end of file diff --git a/Content/Buffs/Debuffs/TransformationCooldown_Buff.cs b/Content/Buffs/Abilities/UltimateAbilityCooldown.cs similarity index 67% rename from Content/Buffs/Debuffs/TransformationCooldown_Buff.cs rename to Content/Buffs/Abilities/UltimateAbilityCooldown.cs index 3ca3999..a526f90 100644 --- a/Content/Buffs/Debuffs/TransformationCooldown_Buff.cs +++ b/Content/Buffs/Abilities/UltimateAbilityCooldown.cs @@ -6,12 +6,14 @@ using Terraria; using Terraria.ModLoader; -namespace Ben10Mod.Content.Buffs.Transformations { - public class UltimateAbility_Cooldown : ModBuff { - public override string Texture => "Ben10Mod/Content/Buffs/Transformations/TransformationCooldown"; +namespace Ben10Mod.Content.Buffs.Abilities { + public class UltimateAbilityCooldown : ModBuff { + public override string Texture => "Ben10Mod/Content/Buffs/Abilities/PrimaryAbilityCooldown"; private OmnitrixPlayer p; public override void Update(Player player, ref int buffIndex) { p = player.GetModPlayer(); + p.ultimateAbilityEnabled = true; + p.ultimateAbilityWasEnabled = true; } public override bool RightClick(int buffIndex) => false; diff --git a/Content/Buffs/Transformations/BuzzShock_Buff.cs b/Content/Buffs/Transformations/BuzzShock_Buff.cs index 33fdb85..e97c8fd 100644 --- a/Content/Buffs/Transformations/BuzzShock_Buff.cs +++ b/Content/Buffs/Transformations/BuzzShock_Buff.cs @@ -8,7 +8,7 @@ using Terraria.ID; using Terraria.ModLoader; -namespace Ben10Mod.Content.Buffs.Transformations { +namespace Ben10Mod.Content.Buffs.Abilities { public class BuzzShock_Buff : ModBuff { public override string Texture => "Ben10Mod/Content/Buffs/Transformations/EmptyTransformation"; private OmnitrixPlayer p; diff --git a/Content/Buffs/Transformations/ChromaStone_Buff.cs b/Content/Buffs/Transformations/ChromaStone_Buff.cs index 3fe1211..ed65943 100644 --- a/Content/Buffs/Transformations/ChromaStone_Buff.cs +++ b/Content/Buffs/Transformations/ChromaStone_Buff.cs @@ -8,7 +8,7 @@ using Terraria.ID; using Terraria.ModLoader; -namespace Ben10Mod.Content.Buffs.Transformations { +namespace Ben10Mod.Content.Buffs.Abilities { public class ChromaStone_Buff : ModBuff { public override string Texture => "Ben10Mod/Content/Buffs/Transformations/EmptyTransformation"; private OmnitrixPlayer p; diff --git a/Content/Buffs/Transformations/DiamondHead_Buff.cs b/Content/Buffs/Transformations/DiamondHead_Buff.cs index cfcdda1..b5a3c41 100644 --- a/Content/Buffs/Transformations/DiamondHead_Buff.cs +++ b/Content/Buffs/Transformations/DiamondHead_Buff.cs @@ -8,7 +8,7 @@ using Terraria.ID; using Terraria.ModLoader; -namespace Ben10Mod.Content.Buffs.Transformations { +namespace Ben10Mod.Content.Buffs.Abilities { public class DiamondHead_Buff : ModBuff { public override string Texture => "Ben10Mod/Content/Buffs/Transformations/EmptyTransformation"; private OmnitrixPlayer p; diff --git a/Content/Buffs/Transformations/EyeGuy_Buff.cs b/Content/Buffs/Transformations/EyeGuy_Buff.cs index c179e01..8b88f04 100644 --- a/Content/Buffs/Transformations/EyeGuy_Buff.cs +++ b/Content/Buffs/Transformations/EyeGuy_Buff.cs @@ -8,7 +8,7 @@ using Terraria.ID; using Terraria.ModLoader; -namespace Ben10Mod.Content.Buffs.Transformations { +namespace Ben10Mod.Content.Buffs.Abilities { public class EyeGuy_Buff : ModBuff { public override string Texture => "Ben10Mod/Content/Buffs/Transformations/EmptyTransformation"; private OmnitrixPlayer p; diff --git a/Content/Buffs/Transformations/FourArms_Buff.cs b/Content/Buffs/Transformations/FourArms_Buff.cs index 9e869c2..38a370e 100644 --- a/Content/Buffs/Transformations/FourArms_Buff.cs +++ b/Content/Buffs/Transformations/FourArms_Buff.cs @@ -8,7 +8,7 @@ using Terraria.ID; using Terraria.ModLoader; -namespace Ben10Mod.Content.Buffs.Transformations { +namespace Ben10Mod.Content.Buffs.Abilities { public class FourArms_Buff : ModBuff { public override string Texture => "Ben10Mod/Content/Buffs/Transformations/EmptyTransformation"; private OmnitrixPlayer p; diff --git a/Content/Buffs/Transformations/GhostFreak_Buff.cs b/Content/Buffs/Transformations/GhostFreak_Buff.cs index 1fbe5d2..493a93e 100644 --- a/Content/Buffs/Transformations/GhostFreak_Buff.cs +++ b/Content/Buffs/Transformations/GhostFreak_Buff.cs @@ -8,7 +8,7 @@ using Terraria.ID; using Terraria.ModLoader; -namespace Ben10Mod.Content.Buffs.Transformations { +namespace Ben10Mod.Content.Buffs.Abilities { public class GhostFreak_Buff : ModBuff { public override string Texture => "Ben10Mod/Content/Buffs/Transformations/EmptyTransformation"; private OmnitrixPlayer p; diff --git a/Content/Buffs/Transformations/HeatBlast_Buff.cs b/Content/Buffs/Transformations/HeatBlast_Buff.cs index ffb2242..f3097c9 100644 --- a/Content/Buffs/Transformations/HeatBlast_Buff.cs +++ b/Content/Buffs/Transformations/HeatBlast_Buff.cs @@ -8,7 +8,7 @@ using Terraria.ID; using Terraria.ModLoader; -namespace Ben10Mod.Content.Buffs.Transformations { +namespace Ben10Mod.Content.Buffs.Abilities { public class HeatBlast_Buff : ModBuff { public override string Texture => "Ben10Mod/Content/Buffs/Transformations/EmptyTransformation"; private OmnitrixPlayer p; diff --git a/Content/Buffs/Transformations/OmnitrixUpdating.cs b/Content/Buffs/Transformations/OmnitrixUpdating.cs index 167d0a7..08420ec 100644 --- a/Content/Buffs/Transformations/OmnitrixUpdating.cs +++ b/Content/Buffs/Transformations/OmnitrixUpdating.cs @@ -8,7 +8,7 @@ using Terraria.ID; using Terraria.ModLoader; -namespace Ben10Mod.Content.Buffs.Transformations { +namespace Ben10Mod.Content.Buffs.Abilities { public class OmnitrixUpdating : ModBuff { public override string Texture => "Ben10Mod/Content/Buffs/Transformations/OmnitrixUpdating"; private OmnitrixPlayer p; diff --git a/Content/Buffs/Transformations/RipJaws_Buff.cs b/Content/Buffs/Transformations/RipJaws_Buff.cs index ecc813a..98403f2 100644 --- a/Content/Buffs/Transformations/RipJaws_Buff.cs +++ b/Content/Buffs/Transformations/RipJaws_Buff.cs @@ -8,7 +8,7 @@ using Terraria.ID; using Terraria.ModLoader; -namespace Ben10Mod.Content.Buffs.Transformations { +namespace Ben10Mod.Content.Buffs.Abilities { public class RipJaws_Buff : ModBuff { public override string Texture => "Ben10Mod/Content/Buffs/Transformations/EmptyTransformation"; private OmnitrixPlayer p; diff --git a/Content/Buffs/Transformations/StinkFly_Buff.cs b/Content/Buffs/Transformations/StinkFly_Buff.cs index e55059a..a5d0ae6 100644 --- a/Content/Buffs/Transformations/StinkFly_Buff.cs +++ b/Content/Buffs/Transformations/StinkFly_Buff.cs @@ -8,7 +8,7 @@ using Terraria.ID; using Terraria.ModLoader; -namespace Ben10Mod.Content.Buffs.Transformations { +namespace Ben10Mod.Content.Buffs.Abilities { public class StinkFly_Buff : ModBuff { public override string Texture => "Ben10Mod/Content/Buffs/Transformations/EmptyTransformation"; private OmnitrixPlayer p; diff --git a/Content/Buffs/Transformations/TransformationCooldown_Buff.cs b/Content/Buffs/Transformations/TransformationCooldown_Buff.cs index 38827e8..7f1a86a 100644 --- a/Content/Buffs/Transformations/TransformationCooldown_Buff.cs +++ b/Content/Buffs/Transformations/TransformationCooldown_Buff.cs @@ -6,7 +6,7 @@ using Terraria; using Terraria.ModLoader; -namespace Ben10Mod.Content.Buffs.Transformations { +namespace Ben10Mod.Content.Buffs.Abilities { public class TransformationCooldown_Buff : ModBuff { public override string Texture => "Ben10Mod/Content/Buffs/Transformations/TransformationCooldown"; private OmnitrixPlayer p; diff --git a/Content/Buffs/Transformations/WildVine_Buff.cs b/Content/Buffs/Transformations/WildVine_Buff.cs index 8764fb9..1b5cf27 100644 --- a/Content/Buffs/Transformations/WildVine_Buff.cs +++ b/Content/Buffs/Transformations/WildVine_Buff.cs @@ -8,7 +8,7 @@ using Terraria.ID; using Terraria.ModLoader; -namespace Ben10Mod.Content.Buffs.Transformations { +namespace Ben10Mod.Content.Buffs.Abilities { public class WildVine_Buff : ModBuff { public override string Texture => "Ben10Mod/Content/Buffs/Transformations/EmptyTransformation"; private OmnitrixPlayer p; diff --git a/Content/Buffs/Transformations/XLR8_Buff.cs b/Content/Buffs/Transformations/XLR8_Buff.cs index 3548749..2e7e220 100644 --- a/Content/Buffs/Transformations/XLR8_Buff.cs +++ b/Content/Buffs/Transformations/XLR8_Buff.cs @@ -8,7 +8,7 @@ using Terraria.ID; using Terraria.ModLoader; -namespace Ben10Mod.Content.Buffs.Transformations { +namespace Ben10Mod.Content.Buffs.Abilities { public class XLR8_Buff : ModBuff { public override string Texture => "Ben10Mod/Content/Buffs/Transformations/EmptyTransformation"; diff --git a/Content/Items/Weapons/PlumbersBadge.cs b/Content/Items/Weapons/PlumbersBadge.cs index 9d2f883..1b13803 100644 --- a/Content/Items/Weapons/PlumbersBadge.cs +++ b/Content/Items/Weapons/PlumbersBadge.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; using Ben10Mod.Content.Buffs.Summons; -using Ben10Mod.Content.Buffs.Transformations; +using Ben10Mod.Content.Buffs.Abilities; using Ben10Mod.Content.DamageClasses; using Ben10Mod.Content.Projectiles; using Ben10Mod.Enums; @@ -72,8 +72,8 @@ private void FinalizeUltimateIfEnded(Player player, OmnitrixPlayer omp) { omp.currTransformation == TransformationEnum.EyeGuy) return; // If we're here, the player has released channel and the ultimate projectile is gone. - if (!player.HasBuff()) - player.AddBuff(ModContent.BuffType(), 60 * 60); + if (!player.HasBuff()) + player.AddBuff(ModContent.BuffType(), 60 * 60); omp.ultimateAttack = false; state.ultimateStarted = false; @@ -234,7 +234,7 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, if (ultimateInProgress && !omp.ultimateAttack) return false; - if (omp.ultimateAttack && player.HasBuff()) + if (omp.ultimateAttack && player.HasBuff()) return false; int projType = ProjectileID.ImpFireball; diff --git a/Content/TransformationHandler.cs b/Content/TransformationHandler.cs index 876ebe8..8228d36 100644 --- a/Content/TransformationHandler.cs +++ b/Content/TransformationHandler.cs @@ -4,7 +4,6 @@ using System.Text; using System.Threading.Tasks; using Ben10Mod.Content.Buffs.Abilities; -using Ben10Mod.Content.Buffs.Transformations; using Ben10Mod.Enums; using Terraria; using Terraria.ID; diff --git a/Enums/TranformationEnum.cs b/Enums/TranformationEnum.cs index 1466bb0..f489178 100644 --- a/Enums/TranformationEnum.cs +++ b/Enums/TranformationEnum.cs @@ -1,5 +1,4 @@ using Ben10Mod.Content.Buffs.Abilities; -using Ben10Mod.Content.Buffs.Transformations; using Microsoft.Xna.Framework.Graphics; using System; using System.Collections.Generic; diff --git a/Localization/en-US_Mods.Ben10Mod.hjson b/Localization/en-US_Mods.Ben10Mod.hjson index 88fa28d..de0516c 100644 --- a/Localization/en-US_Mods.Ben10Mod.hjson +++ b/Localization/en-US_Mods.Ben10Mod.hjson @@ -361,6 +361,16 @@ Buffs: { DisplayName: Buzz Shock Minion Buff Description: Mods.Ben10Mod.Buffs.BuzzShockMinionBuff.Description } + + UltimateAbilityCooldown: { + Description: Mods.Ben10Mod.Buffs.UltimateAbilityCooldown.Description + DisplayName: Ultimate Ability Cooldown + } + + UltimateAbility: { + Description: Mods.Ben10Mod.Buffs.UltimateAbility.Description + DisplayName: Ultimate Ability + } } Projectiles: { diff --git a/NpcEffects.cs b/NpcEffects.cs index dd1df61..8c409f4 100644 --- a/NpcEffects.cs +++ b/NpcEffects.cs @@ -1,3 +1,5 @@ +using Ben10Mod.Content.Buffs.Abilities; +using Ben10Mod.Enums; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Terraria; @@ -17,6 +19,14 @@ public bool IsPossessed(NPC npc) { return false; } + public override bool PreAI(NPC npc) { + var omp = Main.LocalPlayer.GetModPlayer(); + if (omp.ultimateAbilityEnabled && omp.currTransformation == TransformationEnum.XLR8) { + npc.velocity = Vector2.Zero; + } + return base.PreAI(npc); + } + public override void AI(NPC npc) { if (IsPossessed(npc)) { npc.velocity *= 0.68f; diff --git a/OmnitrixPlayer.cs b/OmnitrixPlayer.cs index 27af28b..4fb24a9 100644 --- a/OmnitrixPlayer.cs +++ b/OmnitrixPlayer.cs @@ -27,7 +27,6 @@ using Ben10Mod.Content.Buffs.Abilities; using Ben10Mod.Content.DamageClasses; using Terraria.Audio; -using Ben10Mod.Content.Buffs.Transformations; using Ben10Mod.Content.Items.Accessories.Wings; using Ben10Mod.Content.Transformations.EyeGuy; using Terraria.WorldBuilding; @@ -49,9 +48,11 @@ public class OmnitrixPlayer : ModPlayer { public int cooldownTime = 120; public int transformationTime = 300; - public bool PrimaryAbilityEnabled = false; - public bool PrimaryAbilityWasEnabled = false; - public TransformationEnum tranUsedAbility = TransformationEnum.None; + public bool PrimaryAbilityEnabled = false; + public bool PrimaryAbilityWasEnabled = false; + public bool ultimateAbilityEnabled = false; + public bool ultimateAbilityWasEnabled = false; + public TransformationEnum tranUsedAbility = TransformationEnum.None; public int ChromaStoneAbsorbtion = 0; @@ -172,7 +173,8 @@ public override void ResetEffects() { omnitrixUpdating = false; // Abilities - PrimaryAbilityEnabled = false; + PrimaryAbilityEnabled = false; + ultimateAbilityEnabled = false; // Handle dashing if (Player.controlDown && Player.releaseDown && Player.doubleTapCardinalTimer[DashDown] < 15) { @@ -353,18 +355,7 @@ public override void PostUpdate() { } } - if (isTransformed) { - if (KeybindSystem.UltimateAbility.JustPressed) - if (!Player.HasBuff()) { - for (int i = 0; i < 50; i++) - { - Dust d = Dust.NewDustPerfect(Player.Center + Main.rand.NextVector2Circular(20f, 20f), - ultimateAttack ? DustID.Firework_Yellow : DustID.Firework_Blue, Main.rand.NextVector2Circular(6f, 6f), Scale: Main.rand.NextFloat(1.5f, 2.5f)); - d.noGravity = true; - } - ultimateAttack = !ultimateAttack; - } - } + // XLR8 Transformation @@ -374,6 +365,10 @@ public override void PostUpdate() { Player.AddBuff(ModContent.BuffType(), 10 * 60); tranUsedAbility = currTransformation; } + if (KeybindSystem.UltimateAbility.JustPressed && !Player.HasBuff(ModContent.BuffType()) && !Player.HasBuff(ModContent.BuffType())) { + Player.AddBuff(ModContent.BuffType(), 10 * 60); + tranUsedAbility = currTransformation; + } abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } @@ -551,6 +546,19 @@ public override void PostUpdate() { } } + if (isTransformed) { + if (KeybindSystem.UltimateAbility.JustPressed) + if (!Player.HasBuff() && !Player.HasBuff()) { + for (int i = 0; i < 50; i++) + { + Dust d = Dust.NewDustPerfect(Player.Center + Main.rand.NextVector2Circular(20f, 20f), + ultimateAttack ? DustID.Firework_Yellow : DustID.Firework_Blue, Main.rand.NextVector2Circular(6f, 6f), Scale: Main.rand.NextFloat(1.5f, 2.5f)); + d.noGravity = true; + } + ultimateAttack = !ultimateAttack; + } + } + if (PrimaryAbilityEnabled != PrimaryAbilityWasEnabled) { PrimaryAbilityWasEnabled = PrimaryAbilityEnabled; switch (tranUsedAbility) { @@ -579,6 +587,16 @@ public override void PostUpdate() { ChromaStoneAbsorbtion = 0; PrimaryAbilityWasEnabled = PrimaryAbilityEnabled; } + + if (ultimateAbilityEnabled != ultimateAbilityWasEnabled) { + ultimateAbilityWasEnabled = ultimateAbilityEnabled; + switch (tranUsedAbility) { + case TransformationEnum.XLR8: { + Player.AddBuff(ModContent.BuffType(), 30 * 60); + break; + } + } + } } public override bool CanUseItem(Item item) { diff --git a/OmnitrixProjectile.cs b/OmnitrixProjectile.cs index 5b9e2c1..676a5dc 100644 --- a/OmnitrixProjectile.cs +++ b/OmnitrixProjectile.cs @@ -12,7 +12,7 @@ namespace Ben10Mod; public class OmnitrixProjectile : GlobalProjectile { public override bool InstancePerEntity => true; - public int itemUsed = 0; + public int itemUsed = 0; public override void OnSpawn(Projectile projectile, IEntitySource source) { if (source is IEntitySource_WithStatsFromItem itemSource) { diff --git a/bossTrackerNPC.cs b/bossTrackerNPC.cs index 0cb2eed..cc9ec63 100644 --- a/bossTrackerNPC.cs +++ b/bossTrackerNPC.cs @@ -1,6 +1,6 @@ using System.Runtime.CompilerServices; using Ben10Mod.Content; -using Ben10Mod.Content.Buffs.Transformations; +using Ben10Mod.Content.Buffs.Abilities; using Ben10Mod.Enums; using Microsoft.Xna.Framework; using Terraria; From adc7bfafa9cd6f2ac8994dabf795a5461359ea61 Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Thu, 5 Mar 2026 20:34:12 +1100 Subject: [PATCH 14/25] Got a basic shader working --- Ben10Mod.cs | 39 ++++++++++++++++++++++----------------- Effects/BasicTint.fx | 31 +++++++++++++++++++++++++++++++ Effects/BasicTint.xnb | Bin 0 -> 1804 bytes OmnitrixPlayer.cs | 10 +++++----- OmnitrixProjectile.cs | 14 +++++++++++++- build.txt | 7 ++++++- 6 files changed, 77 insertions(+), 24 deletions(-) create mode 100644 Effects/BasicTint.fx create mode 100644 Effects/BasicTint.xnb diff --git a/Ben10Mod.cs b/Ben10Mod.cs index 7f29ca5..4532a42 100644 --- a/Ben10Mod.cs +++ b/Ben10Mod.cs @@ -1,39 +1,44 @@ using System.IO; +using Ben10Mod.Content.Items.Accessories; using Ben10Mod.Enums; +using Microsoft.Xna.Framework.Graphics; +using ReLogic.Content; using Terraria; +using Terraria.Graphics.Shaders; +using Terraria.ID; using Terraria.ModLoader; -namespace Ben10Mod -{ - public class Ben10Mod : Mod - { - public override void Load() - { +namespace Ben10Mod { + public class Ben10Mod : Mod { + public override void Load() { + if (Main.netMode != NetmodeID.Server) { + // Asset dyeShader = this.Assets.Request("Effects/BasicTint"); + // + // GameShaders.Armor.BindShader(ModContent.ItemType(), + // new ArmorShaderData(dyeShader, "ArmorBasic")).UseColor(1f, 0, 0); + } } - + // Add this enum anywhere in the class (or in a separate file) - public enum MessageType : byte - { + public enum MessageType : byte { UnlockTransformation } - public override void HandlePacket(BinaryReader reader, int whoAmI) - { + public override void HandlePacket(BinaryReader reader, int whoAmI) { MessageType msgType = (MessageType)reader.ReadByte(); - switch (msgType) - { + switch (msgType) { case MessageType.UnlockTransformation: int playerIndex = reader.ReadByte(); TransformationEnum transformation = (TransformationEnum)reader.ReadInt32(); - if (playerIndex >= 0 && playerIndex < Main.maxPlayers) - { + if (playerIndex >= 0 && playerIndex < Main.maxPlayers) { var modPlayer = Main.player[playerIndex].GetModPlayer(); - modPlayer.addTransformation(transformation); // client will apply it locally + modPlayer.addTransformation(transformation); // client will apply it locally } + break; } } - } + } } \ No newline at end of file diff --git a/Effects/BasicTint.fx b/Effects/BasicTint.fx new file mode 100644 index 0000000..e3283c4 --- /dev/null +++ b/Effects/BasicTint.fx @@ -0,0 +1,31 @@ +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; +float2 uTargetPosition; +float4 uLegacyArmorSourceRect; +float2 uLegacyArmorSheetSize; + +float4 ArmorBasic(float2 texCoord : TEXCOORD0, float4 color : COLOR0) : COLOR0 +{ + float4 tex = tex2D(uImage0, texCoord); + return tex * float4(uColor.rgb, 1) * color; +} + +technique Technique1 +{ + pass ArmorBasic + { + PixelShader = compile ps_2_0 ArmorBasic(); + } +} \ No newline at end of file diff --git a/Effects/BasicTint.xnb b/Effects/BasicTint.xnb new file mode 100644 index 0000000000000000000000000000000000000000..9bb86b871f1841b833f2b83cdab8b5e3c9889b7d GIT binary patch literal 1804 zcma)7zi-n(6h4=hrZgxZAz+Av2Zka=RvHqNO0Co;<(CLhB@uL}RJqP2w(9u8#itU) z(4iX)MKCZhbYQ5&(t&}Y1OEYx9XfXGz{u3_p6zo^RfGDX=li~Q-}AkDcXF1Wl{Ut- z*b z*0@N>ugO3AR{|P7w2A)7j|(Bb1j8tJI;8P40Z2SXWFinb2X=hqlN1*&%xDiKsF^R1ez4UAUdFtN z)3W_qP$b5r?yZu0y2fB%!TqW^Z{Uu}oV|1B4DQ^~e{zDmQ#W~w`f)SlTDK8IHmv_Q zU|v*c%d~n6yv=yH%it*Dnj6Y{PVe*j>3o|~AGZu~>^+_puB{rLMX*@O>^c@9$m`Uy zJ?E96(}Y|Fj=7kJ>*074T-p?XSxI25fZGb+1pGze`+yG=ehfGvF9zT=;G)7SfNh1p z2K-6k-vR$t_%Yywaz<&uMTIW|_7(mf@UFst0zOpuU%=Otp3ehbQTT3zv4qbG{uu3X z3u2o}JPMOOn8X=O9_jZ_`dL!0FO8|Ehvn2lS(5I?*^hcFiMX%ZTx1yI>yW_Y3W{liD zW2TTZa>aa}+zQLvgo^eCIJF(&ZIVdsl!9_opgGzjiKCsdfR7_bk9aVTd>d*SfxKWI GyY>&!iQ{Jg literal 0 HcmV?d00001 diff --git a/OmnitrixPlayer.cs b/OmnitrixPlayer.cs index 4fb24a9..de12ecc 100644 --- a/OmnitrixPlayer.cs +++ b/OmnitrixPlayer.cs @@ -545,20 +545,20 @@ public override void PostUpdate() { EndPossession(); } } - + if (isTransformed) { if (KeybindSystem.UltimateAbility.JustPressed) if (!Player.HasBuff() && !Player.HasBuff()) { - for (int i = 0; i < 50; i++) - { + for (int i = 0; i < 50; i++) { Dust d = Dust.NewDustPerfect(Player.Center + Main.rand.NextVector2Circular(20f, 20f), - ultimateAttack ? DustID.Firework_Yellow : DustID.Firework_Blue, Main.rand.NextVector2Circular(6f, 6f), Scale: Main.rand.NextFloat(1.5f, 2.5f)); + ultimateAttack ? DustID.Firework_Yellow : DustID.Firework_Blue, + Main.rand.NextVector2Circular(6f, 6f), Scale: Main.rand.NextFloat(1.5f, 2.5f)); d.noGravity = true; } ultimateAttack = !ultimateAttack; } } - + if (PrimaryAbilityEnabled != PrimaryAbilityWasEnabled) { PrimaryAbilityWasEnabled = PrimaryAbilityEnabled; switch (tranUsedAbility) { diff --git a/OmnitrixProjectile.cs b/OmnitrixProjectile.cs index 676a5dc..18d8e34 100644 --- a/OmnitrixProjectile.cs +++ b/OmnitrixProjectile.cs @@ -1,5 +1,6 @@ using Ben10Mod.Content.Items.Weapons; using Ben10Mod.Content.Projectiles; +using Ben10Mod.Enums; using Microsoft.Xna.Framework; using Terraria; using Terraria.DataStructures; @@ -12,7 +13,8 @@ namespace Ben10Mod; public class OmnitrixProjectile : GlobalProjectile { public override bool InstancePerEntity => true; - public int itemUsed = 0; + public int itemUsed = 0; + private int framesAlive = 0; public override void OnSpawn(Projectile projectile, IEntitySource source) { if (source is IEntitySource_WithStatsFromItem itemSource) { @@ -27,6 +29,16 @@ public override void ModifyHitNPC(Projectile projectile, NPC target, ref NPC.Hit // } } + public override void AI(Projectile projectile) { + framesAlive++; + if (projectile.owner == Main.LocalPlayer.whoAmI) { + var omp = Main.LocalPlayer.GetModPlayer(); + if (framesAlive >= 60 && omp.ultimateAbilityEnabled && omp.currTransformation == TransformationEnum.XLR8) { + projectile.velocity.Normalize(); + } + } + } + public override void OnHitNPC(Projectile projectile, NPC target, NPC.HitInfo hit, int damageDone) { // if (itemUsed == ModContent.ItemType()) // target.AddBuff(BuffID.OnFire, 120); diff --git a/build.txt b/build.txt index 65a1ff7..3d69f52 100644 --- a/build.txt +++ b/build.txt @@ -1,3 +1,8 @@ displayName = Terraria 10 (Ben 10 mod) author = DestroyerMob -version = 0.069 \ No newline at end of file +version = 0.069 +buildIgnore = .vs\*, Properties\*, *.csproj, *.user, obj\*, bin\*, *.config, .git\*, .github\*, LICENSE, README.md, .editorconfig, .gitignore, .gitattributes, Effects\Compiler\* +hideCode = false +hideResources = true +includeSource = false +includePDB = true \ No newline at end of file From 642b40f70bd1439441b4bbf2cbc54e21063adc37 Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Thu, 5 Mar 2026 20:35:38 +1100 Subject: [PATCH 15/25] Added the compiler for shaders --- Effects/Grayscale.fx | 22 ++++++++++++++++++ Effects/Grayscale.xnb | Bin 0 -> 788 bytes ...mework.Content.Pipeline.EffectImporter.dll | Bin 0 -> 9728 bytes ...crosoft.Xna.Framework.Content.Pipeline.dll | Bin 0 -> 536064 bytes Effects/fxcompiler.exe | Bin 0 -> 11264 bytes 5 files changed, 22 insertions(+) create mode 100644 Effects/Grayscale.fx create mode 100644 Effects/Grayscale.xnb create mode 100644 Effects/Microsoft.Xna.Framework.Content.Pipeline.EffectImporter.dll create mode 100644 Effects/Microsoft.Xna.Framework.Content.Pipeline.dll create mode 100644 Effects/fxcompiler.exe diff --git a/Effects/Grayscale.fx b/Effects/Grayscale.fx new file mode 100644 index 0000000..7695708 --- /dev/null +++ b/Effects/Grayscale.fx @@ -0,0 +1,22 @@ +sampler uImage0 : register(s0); + +float strength = 1.0f; + +float4 MainPS(float2 uv : TEXCOORD0) : COLOR0 +{ + float4 color = tex2D(uImage0, uv); + + float gray = dot(color.rgb, float3(0.299, 0.587, 0.114)); + float3 grayscale = float3(gray, gray, gray); + + color.rgb = lerp(color.rgb, grayscale, strength); + return color; +} + +technique Technique1 +{ + pass Grayscale + { + PixelShader = compile ps_2_0 MainPS(); + } +} \ No newline at end of file diff --git a/Effects/Grayscale.xnb b/Effects/Grayscale.xnb new file mode 100644 index 0000000000000000000000000000000000000000..eaf8532367a53e6f24fd3e43cc3ff2016ac5f6b9 GIT binary patch literal 788 zcmZ`%&2G~`5T12g;Zh_cgsL8p*kh3*D=|rx9zsPzp@@J=8=)MKitBC~tB#$n*J^w7 z4Q>>1;%0Hpr4PV6aN-Se;l>lx%sA^R9GKPk`{rjov$NZO(>_~b_ZI-z7xvosWE4jO zW%onZelFdSIE&H}?;U?NFgj@)BW1w3FOI~oa?R)BPC8F{Rv2#?heVqa0rLZ$!C3)R8{ zUc{ao2;?iMJ>d;Q|1=Rb0Bp7RFV!PX``1uQSx54$G!RqGsor>wf7SdwVt>xBDdZ?6 z@6u)?&#&_ubb3$QG>6X=L?88_=fXcBr`lzYyU0JFQeEnoVdNZ<-=|%>O7pao?<^&nqPuxW$mJU3;ok8FsB*b`vL=#?3BSYyNB0c bz%8^PV~}e<7)FtkV-6nNv{D1}X{vt#G;@$3 literal 0 HcmV?d00001 diff --git a/Effects/Microsoft.Xna.Framework.Content.Pipeline.EffectImporter.dll b/Effects/Microsoft.Xna.Framework.Content.Pipeline.EffectImporter.dll new file mode 100644 index 0000000000000000000000000000000000000000..61f52fa6c5e8564b88b0b7d9b4005d55d1bb9372 GIT binary patch literal 9728 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 literal 0 HcmV?d00001 diff --git a/Effects/Microsoft.Xna.Framework.Content.Pipeline.dll b/Effects/Microsoft.Xna.Framework.Content.Pipeline.dll new file mode 100644 index 0000000000000000000000000000000000000000..a70e4120a2a0f6a98b212cf83f826fea41f8821a GIT binary patch literal 536064 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

MZ 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�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 literal 0 HcmV?d00001 diff --git a/Effects/fxcompiler.exe b/Effects/fxcompiler.exe new file mode 100644 index 0000000000000000000000000000000000000000..cfc1dbbf0ea7d581542d93a17b36d5dd76b97627 GIT binary patch literal 11264 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 AHUIzs literal 0 HcmV?d00001 From 5784064871c8562ade6d6500d46568270e68d754 Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Thu, 5 Mar 2026 23:08:00 +1100 Subject: [PATCH 16/25] Fixed up xlr8 ability and added the screen shader --- Ben10Mod.cs | 7 +- Content/Buffs/Abilities/UltimateAbility.cs | 2 +- .../Abilities/UltimateAbilityCooldown.cs | 2 - Content/Items/Weapons/PlumbersBadge.cs | 37 +- Content/Projectiles/ChromaStoneProjectile.cs | 19 +- Content/Projectiles/ChromaStoneProjectile.png | Bin 300 -> 236 bytes Content/TransformationHandler.cs | 3 +- Effects/BasicTint.xnb | Bin 1804 -> 1804 bytes Effects/{Grayscale.fx => MyFilters.fx} | 0 Effects/{Grayscale.xnb => MyFilters.xnb} | Bin 788 -> 788 bytes NpcEffects.cs | 2 +- OmnitrixPlayer.cs | 474 +++++++++--------- OmnitrixProjectile.cs | 16 +- bossTrackerNPC.cs | 18 +- 14 files changed, 298 insertions(+), 282 deletions(-) rename Effects/{Grayscale.fx => MyFilters.fx} (100%) rename Effects/{Grayscale.xnb => MyFilters.xnb} (94%) diff --git a/Ben10Mod.cs b/Ben10Mod.cs index 4532a42..d470e19 100644 --- a/Ben10Mod.cs +++ b/Ben10Mod.cs @@ -4,6 +4,7 @@ using Microsoft.Xna.Framework.Graphics; using ReLogic.Content; using Terraria; +using Terraria.Graphics.Effects; using Terraria.Graphics.Shaders; using Terraria.ID; using Terraria.ModLoader; @@ -16,6 +17,10 @@ public override void Load() { // // GameShaders.Armor.BindShader(ModContent.ItemType(), // new ArmorShaderData(dyeShader, "ArmorBasic")).UseColor(1f, 0, 0); + + Asset filterShader = this.Assets.Request("Effects/MyFilters"); + + Filters.Scene["Ben10Mod:Grayscale"] = new Filter(new ScreenShaderData(filterShader, "Grayscale"), EffectPriority.Medium); } } @@ -34,7 +39,7 @@ public override void HandlePacket(BinaryReader reader, int whoAmI) { if (playerIndex >= 0 && playerIndex < Main.maxPlayers) { var modPlayer = Main.player[playerIndex].GetModPlayer(); - modPlayer.addTransformation(transformation); // client will apply it locally + modPlayer.AddTransformation(transformation); // client will apply it locally } break; diff --git a/Content/Buffs/Abilities/UltimateAbility.cs b/Content/Buffs/Abilities/UltimateAbility.cs index 82feab1..e8f8167 100644 --- a/Content/Buffs/Abilities/UltimateAbility.cs +++ b/Content/Buffs/Abilities/UltimateAbility.cs @@ -10,7 +10,7 @@ public class UltimateAbility : ModBuff { public override void Update(Player player, ref int buffIndex) { var omp = player.GetModPlayer(); - omp.ultimateAbilityEnabled = true; + omp.UltimateAbilityEnabled = true; omp.ultimateAbilityWasEnabled = true; } diff --git a/Content/Buffs/Abilities/UltimateAbilityCooldown.cs b/Content/Buffs/Abilities/UltimateAbilityCooldown.cs index a526f90..951703a 100644 --- a/Content/Buffs/Abilities/UltimateAbilityCooldown.cs +++ b/Content/Buffs/Abilities/UltimateAbilityCooldown.cs @@ -12,8 +12,6 @@ public class UltimateAbilityCooldown : ModBuff { private OmnitrixPlayer p; public override void Update(Player player, ref int buffIndex) { p = player.GetModPlayer(); - p.ultimateAbilityEnabled = true; - p.ultimateAbilityWasEnabled = true; } public override bool RightClick(int buffIndex) => false; diff --git a/Content/Items/Weapons/PlumbersBadge.cs b/Content/Items/Weapons/PlumbersBadge.cs index 1b13803..559d085 100644 --- a/Content/Items/Weapons/PlumbersBadge.cs +++ b/Content/Items/Weapons/PlumbersBadge.cs @@ -16,20 +16,17 @@ namespace Ben10Mod.Content.Items.Weapons { public abstract class PlumbersBadge : ModItem { - - // Override these in subclasses for tier-specific values public virtual int BaseDamage => 15; - public virtual float DamageMultiplier => 1f; // For universal scaling if needed + public virtual float DamageMultiplier => 1f; public virtual float AttackSpeedMultiplier => 1f; public virtual float AdditionalProjectileChance => 0; public virtual string BadgeRankName => "Helper"; public virtual int BadgeRankValue => 0; - public int OmnitrixEnergyUse = 0; + public int OmnitrixEnergyUse = 0; private int GetUltimateProjectileType(OmnitrixPlayer omp) { - // Add more mappings here as you implement other ultimate attacks. return omp.currTransformation switch { TransformationEnum.EyeGuy => ModContent.ProjectileType(), TransformationEnum.GhostFreak => ModContent.ProjectileType(), @@ -58,20 +55,15 @@ private void FinalizeUltimateIfEnded(Player player, OmnitrixPlayer omp) { var state = player.GetModPlayer(); - // If the ultimate hasn't actually started yet (no ultimate projectile spawned), - // don't auto-cancel it. This prevents "arming" the ultimate from immediately ending it. if (!state.ultimateStarted) return; - // If player is still holding the channel, ultimate is still in progress. if (player.channel) return; - // If the ultimate projectile is still alive, ultimate is still in progress. int ultimateProjType = GetUltimateProjectileType(omp); if (HasActiveOwnedProjectile(player, ultimateProjType) && omp.currTransformation == TransformationEnum.EyeGuy) return; - // If we're here, the player has released channel and the ultimate projectile is gone. if (!player.HasBuff()) player.AddBuff(ModContent.BuffType(), 60 * 60); @@ -131,7 +123,6 @@ public override void HoldItem(Player player) { if (!omp.isTransformed) return; - // Fixed per-alien useTime/shootSpeed (balanced to feel good - no alt-dependent for now to avoid timing issues) switch (omp.currTransformation) { case TransformationEnum.HeatBlast: Item.useTime = Item.useAnimation = omp.altAttack ? 50 : 6; @@ -142,11 +133,11 @@ public override void HoldItem(Player player) { Item.channel = omp.ultimateAttack; break; case TransformationEnum.XLR8: - Item.useTime = Item.useAnimation = 10; // Fast punches + Item.useTime = Item.useAnimation = 10; Item.shootSpeed = 25f; break; case TransformationEnum.FourArms: - Item.useTime = Item.useAnimation = 18; // Fast punches + Item.useTime = Item.useAnimation = 18; Item.shootSpeed = 25f; break; @@ -280,12 +271,12 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, break; case TransformationEnum.ChromaStone: - projType = ModContent.ProjectileType(); + projType = ModContent.ProjectileType(); finalDamage += omp.ChromaStoneAbsorbtion; break; case TransformationEnum.BuzzShock: - + if (omp.altAttack) { SoundEngine.PlaySound(SoundID.AbigailSummon, player.position); int buffType = ModContent.BuffType(); @@ -301,9 +292,12 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, return false; } + SoundEngine.PlaySound(SoundID.DD2_LightningAuraZap, player.position); if (omp.ultimateAttack) finalDamage = (int)(2.5f * finalDamage); - projType = omp.ultimateAttack ? ModContent.ProjectileType() : ModContent.ProjectileType(); + projType = omp.ultimateAttack + ? ModContent.ProjectileType() + : ModContent.ProjectileType(); break; @@ -345,13 +339,14 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, if (omp.currTransformation == TransformationEnum.BuzzShock && omp.ultimateAttack) { for (int i = 0; i < 5; i++) { - Projectile.NewProjectile(source, position, velocity.RotatedBy(i * 2.5), projType, (int)(finalDamage * DamageMultiplier), + Projectile.NewProjectile(source, position, velocity.RotatedBy(i * 2.5), projType, + (int)(finalDamage * DamageMultiplier), knockback, player.whoAmI); } - + return false; } - + Projectile.NewProjectile(source, position, velocity, projType, (int)(finalDamage * DamageMultiplier), knockback, player.whoAmI); @@ -378,8 +373,6 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, public class BadgeUltimateState : ModPlayer { public bool ultimateStarted; - public override void ResetEffects() { - // no per-tick reset; state persists until ultimate finishes - } + public override void ResetEffects() { } } } \ No newline at end of file diff --git a/Content/Projectiles/ChromaStoneProjectile.cs b/Content/Projectiles/ChromaStoneProjectile.cs index 11763a3..0953516 100644 --- a/Content/Projectiles/ChromaStoneProjectile.cs +++ b/Content/Projectiles/ChromaStoneProjectile.cs @@ -15,18 +15,31 @@ public class ChromaStoneProjectile : ModProjectile { public override void SetDefaults() { - Projectile.width = 32; - Projectile.height = 64; + Projectile.width = 16; + Projectile.height = 16; Projectile.aiStyle = ProjAIStyleID.Arrow; AIType = ProjectileID.Bullet; Projectile.friendly = true; - Projectile.tileCollide = false; Projectile.penetrate = -1; Projectile.DamageType = DamageClass.Magic; Projectile.timeLeft = 60 * 5; + } + + public override void AI() { + for (int i = 0; i < 3; i++) { + int dustNum = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.WhiteTorch, + newColor: Main.DiscoColor, Scale: 2); + Main.dust[dustNum].noGravity = true; + } + } + public override void OnKill(int timeLeft) { + for (int i = 0; i < 25; i++) { + int dustNum = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.WhiteTorch, Main.rand.NextFloat(-10f, 10f), Main.rand.NextFloat(-25f, 25f), 0, Main.DiscoColor, 3f); + Main.dust[dustNum].noGravity = true; + } } public override bool PreDraw(ref Color lightColor) { diff --git a/Content/Projectiles/ChromaStoneProjectile.png b/Content/Projectiles/ChromaStoneProjectile.png index 6fcaaef8167871a90f8ce90b35a4f9f264ff5fea..57829d94481a078b7fe3fca4b1cfc2a4ccba21e4 100644 GIT binary patch delta 221 zcmV<303!da0_*{h7k?lK1^@s68;SVL00001b5ch_0Itp)=>Px#rb$FWR7i>KRmly2 zFbs3pfN7Y6Njpau;oB!q^GQlL1+)?pB2pAUsqGZC7OaA#e+^oD`ye8V{$>quH!_@K z4gflRZnY+@(bSldVg;F9Gmsoejt4ntPgY#M2RpO3=Sz_MURKok3nZ_yZ&Va3cppF> z%x{qZ#P>(|0X_rJ>&Z$N`Yk?n8Zmpq?K@FK>O0e(D|u#kc2xC7Z2b{VP1L&Z#VQIW XKDuMMQ&)Ut00000NkvXXu0mjfQovXB delta 286 zcmV+(0pb4a0jvU$7k@wq1^@s66MgrV00001b5ch_0Itp)=>Px#=1D|BR9J=Wmr)MG zAP9zGH`r-<4o|vs^fVrUJxn&BG}A#7v&f6B(VvgMHW369L?mAyZ7e*2h-&@K3XF!5 z6WKZQ*2Z0uNQyiHlbti)+gJsOq6iaM0WZ6J-r(a;B7yn#Hh;T2$9qye;QGDnl0x|q zCvfWT4kF6)pr?Kg*cUjNGKG=+huI)@< kI40^`9STWuT^INM1QUcsIe;mP!2kdN07*qoM6N<$f~6LAtpET3 diff --git a/Content/TransformationHandler.cs b/Content/TransformationHandler.cs index 8228d36..9a6707d 100644 --- a/Content/TransformationHandler.cs +++ b/Content/TransformationHandler.cs @@ -36,9 +36,7 @@ public static void Transform(Player player, TransformationEnum transformation, i if (playSound) { SoundEngine.PlaySound(new SoundStyle("Ben10Mod/Content/Sounds/OmnitrixTransformation"), player.position); } - // Main.NewText(transformation.GetName() + "!", Color.Green); player.AddBuff(transformation.GetTransformation(), 60 * seconds); - // player.GetModPlayer().currTransformation = transformation; } public static void Detransform(Player player, int seconds, bool showParticles = true, bool addCooldown = true, bool playSound = true) { @@ -71,6 +69,7 @@ public static void Detransform(Player player, int seconds, bool showParticles = player.ClearBuff(ModContent.BuffType()); player.ClearBuff(ModContent.BuffType()); + player.ClearBuff(ModContent.BuffType()); player.GetModPlayer().currTransformation = TransformationEnum.None; diff --git a/Effects/BasicTint.xnb b/Effects/BasicTint.xnb index 9bb86b871f1841b833f2b83cdab8b5e3c9889b7d..140377a5d0b584b82a94d764321fe768ca6da0a3 100644 GIT binary patch delta 15 WcmeC->*3pA$HK&+z1e}~3=;q%S_B~g delta 15 WcmeC->*3pA$HK(Gu-Sp-3=;q$AOr3I diff --git a/Effects/Grayscale.fx b/Effects/MyFilters.fx similarity index 100% rename from Effects/Grayscale.fx rename to Effects/MyFilters.fx diff --git a/Effects/Grayscale.xnb b/Effects/MyFilters.xnb similarity index 94% rename from Effects/Grayscale.xnb rename to Effects/MyFilters.xnb index eaf8532367a53e6f24fd3e43cc3ff2016ac5f6b9..456e737ee3a589f3ccf35bc3538d3a6713372c0f 100644 GIT binary patch delta 16 XcmbQjHid12C?hii1H)zs#y^YzAvXiZ delta 16 XcmbQjHid12C?j)mX31s=#y^YzDrN;2 diff --git a/NpcEffects.cs b/NpcEffects.cs index 8c409f4..d03a718 100644 --- a/NpcEffects.cs +++ b/NpcEffects.cs @@ -21,7 +21,7 @@ public bool IsPossessed(NPC npc) { public override bool PreAI(NPC npc) { var omp = Main.LocalPlayer.GetModPlayer(); - if (omp.ultimateAbilityEnabled && omp.currTransformation == TransformationEnum.XLR8) { + if (omp.UltimateAbilityEnabled && omp.currTransformation == TransformationEnum.XLR8) { npc.velocity = Vector2.Zero; } return base.PreAI(npc); diff --git a/OmnitrixPlayer.cs b/OmnitrixPlayer.cs index de12ecc..b9139ea 100644 --- a/OmnitrixPlayer.cs +++ b/OmnitrixPlayer.cs @@ -29,14 +29,14 @@ using Terraria.Audio; using Ben10Mod.Content.Items.Accessories.Wings; using Ben10Mod.Content.Transformations.EyeGuy; +using Terraria.Graphics.Effects; using Terraria.WorldBuilding; -namespace Ben10Mod -{ +namespace Ben10Mod { public class OmnitrixPlayer : ModPlayer { public bool masterControl = false; - + public bool omnitrixEquipped = false; public bool prototypeOmnitrix = false; public bool isTransformed = false; @@ -44,13 +44,13 @@ public class OmnitrixPlayer : ModPlayer { public bool onCooldown = false; public bool altAttack = false; public bool ultimateAttack = false; - + public int cooldownTime = 120; public int transformationTime = 300; - + public bool PrimaryAbilityEnabled = false; public bool PrimaryAbilityWasEnabled = false; - public bool ultimateAbilityEnabled = false; + public bool UltimateAbilityEnabled = false; public bool ultimateAbilityWasEnabled = false; public TransformationEnum tranUsedAbility = TransformationEnum.None; @@ -67,9 +67,17 @@ public class OmnitrixPlayer : ModPlayer { public int DashTimer = 0; public const int DashCooldown = 15; public const int DashDuration = 15; - public TransformationEnum[] transformations = { TransformationEnum.HeatBlast, TransformationEnum.HeatBlast, TransformationEnum.HeatBlast, TransformationEnum.HeatBlast, TransformationEnum.HeatBlast }; + + public TransformationEnum[] transformations = { + TransformationEnum.HeatBlast, TransformationEnum.HeatBlast, TransformationEnum.HeatBlast, + TransformationEnum.HeatBlast, TransformationEnum.HeatBlast + }; + public TransformationEnum currTransformation = TransformationEnum.None; - public List unlockedTransformation = new List() { TransformationEnum.HeatBlast }; + + public List unlockedTransformation = new List() + { TransformationEnum.HeatBlast }; + public bool showingUI = false; public bool omnitrixUpdating = false; @@ -77,78 +85,55 @@ public class OmnitrixPlayer : ModPlayer { public float omnitrixEnergy = 0f; public float omnitrixEnergyMax = 0f; public float omnitrixEnergyRegen = 0f; - - // Rainbow effect - public Color[] colours = { Color.White, Color.LightPink, Color.Pink, Color.OrangeRed, Color.LightBlue, Color.Cyan, Color.LightGreen, Color.YellowGreen, Color.LightYellow, Color.Yellow }; - public float colourAmount = 0.00f; - public int thisColour = 0; - public int nextColour = 1; - + public bool inPossessionMode = false; - public Vector2 prePossessionPosition = Vector2.Zero; // Save player's position before possession + public Vector2 prePossessionPosition = Vector2.Zero; public NPC possessedTarget = null; public int possessionTimer = 0; - private const int PossessionDuration = 360; // 6 seconds - - // Accessory Values + private const int PossessionDuration = 360; + public bool snowflake = false; public bool advancedCircuitMatrix = false; public bool advancedCircuitMatrixEquippedWhileTransformed = false; - public Color GetChromaStoneOverlayColor() - { - return Color.Lerp(colours[thisColour], colours[nextColour], colourAmount); - } - - public override void SaveData(TagCompound tag) - { + public override void SaveData(TagCompound tag) { tag["masterControl"] = masterControl; tag["currTransformation"] = (int)currTransformation; - tag["omnitrixEnergy"] = omnitrixEnergy; + tag["omnitrixEnergy"] = omnitrixEnergy; - // Roster (5 slots) tag["roster"] = transformations.Select(t => (int)t).ToArray(); - // Unlocked aliens tag["unlockedRoster"] = unlockedTransformation .Where(t => t != TransformationEnum.None) .Select(t => (int)t) .ToArray(); } - public override void LoadData(TagCompound tag) - { + public override void LoadData(TagCompound tag) { tag.TryGet("masterControl", out masterControl); int currInt = -1; tag.TryGet("currTransformation", out currInt); currTransformation = (TransformationEnum)currInt; - omnitrixEnergy = tag.TryGet("omnitrixEnergy", out omnitrixEnergy) ? omnitrixEnergy : 0f; + omnitrixEnergy = tag.TryGet("omnitrixEnergy", out omnitrixEnergy) ? omnitrixEnergy : 0f; - // Load roster - if (tag.TryGet("roster", out int[] rosterArray) && rosterArray != null) - { - for (int i = 0; i < Math.Min(rosterArray.Length, transformations.Length); i++) - { + if (tag.TryGet("roster", out int[] rosterArray) && rosterArray != null) { + for (int i = 0; i < Math.Min(rosterArray.Length, transformations.Length); i++) { transformations[i] = (TransformationEnum)rosterArray[i]; } } - // Load unlocked (clears old duplicates automatically) unlockedTransformation.Clear(); - if (tag.TryGet("unlockedRoster", out int[] unlockedArray) && unlockedArray != null) - { - foreach (int id in unlockedArray) - { + if (tag.TryGet("unlockedRoster", out int[] unlockedArray) && unlockedArray != null) { + foreach (int id in unlockedArray) { var trans = (TransformationEnum)id; if (trans != TransformationEnum.None && !unlockedTransformation.Contains(trans)) unlockedTransformation.Add(trans); } } - // Safety: always have HeatBlast if (!unlockedTransformation.Contains(TransformationEnum.HeatBlast)) unlockedTransformation.Insert(0, TransformationEnum.HeatBlast); } @@ -157,7 +142,7 @@ public override void LoadData(TagCompound tag) public override void ResetEffects() { advancedCircuitMatrix = false; snowflake = false; - + cooldownTime = 120; transformationTime = 300; omnitrixEnergyMax = 0; @@ -168,13 +153,13 @@ public override void ResetEffects() { onCooldown = false; omnitrixEquipped = false; prototypeOmnitrix = false; - + // Updating omnitrixUpdating = false; // Abilities PrimaryAbilityEnabled = false; - ultimateAbilityEnabled = false; + UltimateAbilityEnabled = false; // Handle dashing if (Player.controlDown && Player.releaseDown && Player.doubleTapCardinalTimer[DashDown] < 15) { @@ -197,7 +182,7 @@ public override void ResetEffects() { // Handles players abilities public override void PostUpdateBuffs() { - var abilitySlot = ModContent.GetInstance(); + var abilitySlot = ModContent.GetInstance(); var omnitrixSlot = ModContent.GetInstance(); // Handles the detransformation effect @@ -207,15 +192,18 @@ public override void PostUpdateBuffs() { if (customSlot != null) { if (masterControl) { TransformationHandler.Detransform(Player, 0, true, false); - } else { + } + else { if (omnitrixSlot.FunctionalItem.type == ModContent.ItemType()) - TransformationHandler.Detransform(Player, advancedCircuitMatrixEquippedWhileTransformed ? cooldownTime * 2 : cooldownTime); + TransformationHandler.Detransform(Player, + advancedCircuitMatrixEquippedWhileTransformed ? cooldownTime * 2 : cooldownTime); if (omnitrixSlot.FunctionalItem.type == ModContent.ItemType()) TransformationHandler.Detransform(Player, 0, addCooldown: false); } advancedCircuitMatrixEquippedWhileTransformed = false; } + wasTransformed = false; } @@ -223,14 +211,18 @@ public override void PostUpdateBuffs() { if (omnitrixSlot.FunctionalItem.type == ModContent.ItemType()) { Random random = new Random(); for (int i = 0; i < 25; i++) { - int dustNum = Dust.NewDust(Player.position - new Vector2(1, 1), Player.width + 1, Player.height + 1, DustID.BlueTorch, random.Next(-4, 5), random.Next(-4, 5), 1, Color.White, 4); + int dustNum = Dust.NewDust(Player.position - new Vector2(1, 1), Player.width + 1, + Player.height + 1, DustID.BlueTorch, random.Next(-4, 5), random.Next(-4, 5), 1, Color.White, + 4); Main.dust[dustNum].noGravity = true; } + omnitrixSlot.FunctionalItem = new Item(ModContent.ItemType()); } + omnitrixWasUpdating = omnitrixUpdating; } - + // XLR8 Transformation if (currTransformation == TransformationEnum.XLR8) { @@ -239,7 +231,7 @@ public override void PostUpdateBuffs() { if (PrimaryAbilityEnabled) { multiplier = 2; } - + Player.moveSpeed *= 2.5f * multiplier; Player.accRunSpeed *= 2.0f * multiplier; Player.GetAttackSpeed(DamageClass.Generic) += (multiplier / 2); @@ -248,12 +240,15 @@ public override void PostUpdateBuffs() { Player.waterWalk = true; } - if (Player.velocity.X == 0 && (Player.holdDownCardinalTimer[2] > 0 || Player.holdDownCardinalTimer[3] > 0)) { + if (Player.velocity.X == 0 && + (Player.holdDownCardinalTimer[2] > 0 || Player.holdDownCardinalTimer[3] > 0)) { if (Player.holdDownCardinalTimer[0] > 0) { Player.maxFallSpeed *= 2.0f; - } else if (Player.holdDownCardinalTimer[1] > 0) { + } + else if (Player.holdDownCardinalTimer[1] > 0) { Player.velocity.Y = -Player.maxFallSpeed * multiplier; - } else { + } + else { Player.maxFallSpeed = 0; } } @@ -262,8 +257,8 @@ public override void PostUpdateBuffs() { // Heatblast Transformation if (currTransformation == TransformationEnum.HeatBlast) { - Player.fireWalk = true; - Player.lavaImmune = true; + Player.fireWalk = true; + Player.lavaImmune = true; } // Diamondhead Transformation @@ -287,20 +282,19 @@ public override void PostUpdateBuffs() { if (currTransformation == TransformationEnum.RipJaws) { if (Player.wet) { - Player.merman = true; - Player.breathCD = 0; - Player.breath = Player.breathMax; + Player.merman = true; + Player.breathCD = 0; + Player.breath = Player.breathMax; Player.GetDamage() *= 2.0f; } Player.accFlipper = true; - + } // Chromastone Transformation - if (currTransformation == TransformationEnum.ChromaStone) { - } + if (currTransformation == TransformationEnum.ChromaStone) { } // Buzzshock Transformation @@ -317,9 +311,8 @@ public override void PostUpdateBuffs() { // Stinkfly Transformation - if (currTransformation == TransformationEnum.StinkFly) { - } - + if (currTransformation == TransformationEnum.StinkFly) { } + // Ghostfreak Transformation if (currTransformation == TransformationEnum.GhostFreak) { @@ -328,12 +321,11 @@ public override void PostUpdateBuffs() { // Wildvine Transformation - if (currTransformation == TransformationEnum.WildVine) { - } + if (currTransformation == TransformationEnum.WildVine) { } } - + public override void PostUpdate() { - + var abilitySlot = ModContent.GetInstance(); if (!isTransformed) { @@ -341,9 +333,9 @@ public override void PostUpdate() { } omnitrixEnergy += (omnitrixEnergyRegen / 120); - + if (omnitrixEnergy > omnitrixEnergyMax) omnitrixEnergy = omnitrixEnergyMax; - + if (KeybindSystem.OpenTransformationScreen.JustPressed && omnitrixEquipped) { if (!showingUI) { ModContent.GetInstance().ShowMyUI(); @@ -356,20 +348,30 @@ public override void PostUpdate() { } - + // XLR8 Transformation if (currTransformation == TransformationEnum.XLR8) { - if (KeybindSystem.PrimaryAbility.JustPressed && !Player.HasBuff(ModContent.BuffType()) && !Player.HasBuff(ModContent.BuffType())) { + if (KeybindSystem.PrimaryAbility.JustPressed && + !Player.HasBuff(ModContent.BuffType()) && + !Player.HasBuff(ModContent.BuffType())) { Player.AddBuff(ModContent.BuffType(), 10 * 60); tranUsedAbility = currTransformation; } - if (KeybindSystem.UltimateAbility.JustPressed && !Player.HasBuff(ModContent.BuffType()) && !Player.HasBuff(ModContent.BuffType())) { + + if (KeybindSystem.UltimateAbility.JustPressed && + !Player.HasBuff(ModContent.BuffType()) && + !Player.HasBuff(ModContent.BuffType())) { Player.AddBuff(ModContent.BuffType(), 10 * 60); tranUsedAbility = currTransformation; } + if (UltimateAbilityEnabled && Main.netMode != NetmodeID.Server) { + Filters.Scene.Activate("Ben10Mod:Grayscale"); + Filters.Scene["Ben10Mod:Grayscale"].GetShader().Shader.Parameters["strength"]?.SetValue(1f); + } + abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } @@ -377,43 +379,50 @@ public override void PostUpdate() { if (currTransformation == TransformationEnum.HeatBlast) { Random rand = new Random(); - int dustNum = Dust.NewDust(Player.position, Player.width, Player.height, snowflake ? DustID.IceTorch : DustID.Flare, 0, rand.Next(-1, 2), rand.Next(-1, 2), Color.White, rand.Next(3)); + int dustNum = Dust.NewDust(Player.position, Player.width, Player.height, + snowflake ? DustID.IceTorch : DustID.Flare, 0, rand.Next(-1, 2), rand.Next(-1, 2), Color.White, + rand.Next(3)); Main.dust[dustNum].noGravity = true; if (KeybindSystem.PrimaryAbility.JustPressed) { - if (!Player.HasBuff(ModContent.BuffType()) && !Player.HasBuff(ModContent.BuffType())) { + if (!Player.HasBuff(ModContent.BuffType()) && + !Player.HasBuff(ModContent.BuffType())) { Player.AddBuff(ModContent.BuffType(), 60 * 60); tranUsedAbility = currTransformation; } } + if (PrimaryAbilityEnabled) { Vector2[] points = GenerateCirclePoints(250, 7 * (16)); for (int i = 0; i < points.Length; i++) { - dustNum = Dust.NewDust(points[i] + Player.Center, 1, 1, snowflake ? DustID.IceTorch : DustID.Torch, rand.Next(-1, 2), rand.Next(-1, 2)); + dustNum = Dust.NewDust(points[i] + Player.Center, 1, 1, + snowflake ? DustID.IceTorch : DustID.Torch, rand.Next(-1, 2), rand.Next(-1, 2)); Main.dust[dustNum].noGravity = true; } - + foreach (NPC npc in Main.npc) { if (Player.Distance(npc.Center) <= 10 * (16) && !npc.friendly) { if (!npc.HasBuff(BuffID.Frostburn2) && snowflake) { npc.AddBuff(BuffID.Frostburn2, 10 * 60); - } else if (!npc.HasBuff(BuffID.OnFire3)) { + } + else if (!npc.HasBuff(BuffID.OnFire3)) { npc.AddBuff(BuffID.OnFire3, 10 * 60); } } } } - Player.fireWalk = true; + Player.fireWalk = true; Player.lavaImmune = true; - abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); + abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } // Diamondhead Transformation if (currTransformation == TransformationEnum.DiamondHead) { if (KeybindSystem.PrimaryAbility.JustPressed) { - if (!Player.HasBuff(ModContent.BuffType()) && !Player.HasBuff(ModContent.BuffType())) { + if (!Player.HasBuff(ModContent.BuffType()) && + !Player.HasBuff(ModContent.BuffType())) { Player.AddBuff(ModContent.BuffType(), 60 * 60); tranUsedAbility = currTransformation; Player.velocity = Vector2.Zero; @@ -421,7 +430,8 @@ public override void PostUpdate() { } if (PrimaryAbilityEnabled) { - Player.velocity = new Vector2(float.Clamp(Player.velocity.X, -0.5f, 0.5f), Math.Max(0, Player.velocity.Y)); + Player.velocity = new Vector2(float.Clamp(Player.velocity.X, -0.5f, 0.5f), + Math.Max(0, Player.velocity.Y)); Lighting.AddLight(Player.Center, new Vector3(0.4f, 0.3f, 0.8f)); } @@ -438,14 +448,14 @@ public override void PostUpdate() { if (currTransformation == TransformationEnum.ChromaStone) { if (KeybindSystem.PrimaryAbility.JustPressed) { - if (!Player.HasBuff(ModContent.BuffType()) && !Player.HasBuff(ModContent.BuffType())) { + if (!Player.HasBuff(ModContent.BuffType()) && + !Player.HasBuff(ModContent.BuffType())) { Player.AddBuff(ModContent.BuffType(), 30 * 60); tranUsedAbility = currTransformation; } } - if (PrimaryAbilityEnabled) - { + if (PrimaryAbilityEnabled) { Lighting.AddLight(Player.Center, Main.DiscoColor.ToVector3()); } @@ -453,9 +463,7 @@ public override void PostUpdate() { } - if (!PrimaryAbilityEnabled) { - - } + if (!PrimaryAbilityEnabled) { } // Buzzshock Transformation @@ -465,12 +473,17 @@ public override void PostUpdate() { SoundEngine.PlaySound(SoundID.Item8, Player.position); Random random = new Random(); for (int i = 0; i < 50; i++) { - int dustNum = Dust.NewDust(Player.position - new Vector2(1, 1), Player.width + 1, Player.height + 1, DustID.UltraBrightTorch, random.Next(-4, 5), random.Next(-4, 5), 1, Color.White, 2); + int dustNum = Dust.NewDust(Player.position - new Vector2(1, 1), Player.width + 1, + Player.height + 1, DustID.UltraBrightTorch, random.Next(-4, 5), random.Next(-4, 5), 1, + Color.White, 2); Main.dust[dustNum].noGravity = true; } + Player.Teleport(Main.MouseWorld, TeleportationStyleID.DebugTeleport); for (int i = 0; i < 50; i++) { - int dustNum = Dust.NewDust(Player.position - new Vector2(1, 1), Player.width + 1, Player.height + 1, DustID.UltraBrightTorch, random.Next(-4, 5), random.Next(-4, 5), 1, Color.White, 2); + int dustNum = Dust.NewDust(Player.position - new Vector2(1, 1), Player.width + 1, + Player.height + 1, DustID.UltraBrightTorch, random.Next(-4, 5), random.Next(-4, 5), 1, + Color.White, 2); Main.dust[dustNum].noGravity = true; } @@ -480,7 +493,7 @@ public override void PostUpdate() { abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } - + // Fourarms Transformation if (currTransformation == TransformationEnum.FourArms) { @@ -492,13 +505,14 @@ public override void PostUpdate() { if (currTransformation == TransformationEnum.StinkFly) { abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } - + // Ghostfreak Transformation if (currTransformation == TransformationEnum.GhostFreak) { Random random = new Random(); - if (KeybindSystem.PrimaryAbility.Current && !Player.HasBuff() && !Player.HasBuff()) { + if (KeybindSystem.PrimaryAbility.Current && !Player.HasBuff() && + !Player.HasBuff()) { Player.AddBuff(ModContent.BuffType(), 15 * 60); tranUsedAbility = currTransformation; } @@ -511,24 +525,20 @@ public override void PostUpdate() { if (currTransformation == TransformationEnum.WildVine) { abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } - - if (inPossessionMode) - { - if (possessedTarget == null || !possessedTarget.active || currTransformation != TransformationEnum.GhostFreak ) - { - EndPossession(); // Safety: end if target dies/missing + + if (inPossessionMode) { + if (possessedTarget == null || !possessedTarget.active || + currTransformation != TransformationEnum.GhostFreak) { + EndPossession(); return; } - // Sync player to possessed NPC's center (camera follows player naturally) Player.immuneNoBlink = true; Player.immuneTime = 999; Player.Center = possessedTarget.Center; - // Optional: Sync some velocity for "riding" feel (but keep player locked) - Player.velocity = possessedTarget.velocity * 0.8f; // Slight lag for smoothness + Player.velocity = possessedTarget.velocity * 0.8f; - // Lock controls to prevent input interference Player.controlJump = false; Player.controlDown = false; Player.controlLeft = false; @@ -541,7 +551,8 @@ public override void PostUpdate() { possessionTimer--; if (possessionTimer <= 0) { - possessedTarget.SimpleStrikeNPC(Player.HeldItem.damage * 2, Player.direction, false, 0, DamageClass.Magic); + possessedTarget.SimpleStrikeNPC(Player.HeldItem.damage * 2, Player.direction, false, 0, + DamageClass.Magic); EndPossession(); } } @@ -555,6 +566,7 @@ public override void PostUpdate() { Main.rand.NextVector2Circular(6f, 6f), Scale: Main.rand.NextFloat(1.5f, 2.5f)); d.noGravity = true; } + ultimateAttack = !ultimateAttack; } } @@ -583,13 +595,13 @@ public override void PostUpdate() { break; } } - - ChromaStoneAbsorbtion = 0; + + ChromaStoneAbsorbtion = 0; PrimaryAbilityWasEnabled = PrimaryAbilityEnabled; } - if (ultimateAbilityEnabled != ultimateAbilityWasEnabled) { - ultimateAbilityWasEnabled = ultimateAbilityEnabled; + if (UltimateAbilityEnabled != ultimateAbilityWasEnabled) { + ultimateAbilityWasEnabled = UltimateAbilityEnabled; switch (tranUsedAbility) { case TransformationEnum.XLR8: { Player.AddBuff(ModContent.BuffType(), 30 * 60); @@ -597,6 +609,11 @@ public override void PostUpdate() { } } } + + if (!isTransformed) { + Filters.Scene["Ben10Mod:Grayscale"].GetShader().Shader.Parameters["strength"]?.SetValue(0f); + Filters.Scene.Deactivate("Ben10Mod:Grayscale"); + } } public override bool CanUseItem(Item item) { @@ -623,19 +640,22 @@ public override void OnHurt(Player.HurtInfo info) { } public override void OnHitAnything(float x, float y, Entity victim) { - if (!Main.npc[victim.whoAmI].HasBuff(BuffID.Frostburn2) && snowflake && currTransformation == TransformationEnum.HeatBlast) { + if (!Main.npc[victim.whoAmI].HasBuff(BuffID.Frostburn2) && snowflake && + currTransformation == TransformationEnum.HeatBlast) { Main.npc[victim.whoAmI].AddBuff(BuffID.Frostburn2, 10 * 60); - } else if (!Main.npc[victim.whoAmI].HasBuff(BuffID.OnFire3) && !snowflake && currTransformation == TransformationEnum.HeatBlast) { + } + else if (!Main.npc[victim.whoAmI].HasBuff(BuffID.OnFire3) && !snowflake && + currTransformation == TransformationEnum.HeatBlast) { Main.npc[victim.whoAmI].AddBuff(BuffID.OnFire3, 10 * 60); } } public static Vector2[] GenerateCirclePoints(int numberOfPoints, float radius) { - Vector2[] circlePoints = new Vector2[numberOfPoints]; - float angleIncrement = 360f / numberOfPoints; + Vector2[] circlePoints = new Vector2[numberOfPoints]; + float angleIncrement = 360f / numberOfPoints; for (int i = 0; i < numberOfPoints; i++) { - float angle = i * angleIncrement; + float angle = i * angleIncrement; float radians = MathF.PI / 180 * angle; float x = radius * MathF.Cos(radians); @@ -648,8 +668,8 @@ public static Vector2[] GenerateCirclePoints(int numberOfPoints, float radius) { } public override void ModifyDrawInfo(ref PlayerDrawSet drawInfo) { - if (isTransformed) { - } + if (isTransformed) { } + switch (currTransformation) { case TransformationEnum.HeatBlast: drawInfo.colorArmorHead = Color.White; @@ -662,7 +682,7 @@ public override void ModifyDrawInfo(ref PlayerDrawSet drawInfo) { drawInfo.colorArmorLegs.A /= 2; break; case TransformationEnum.GhostFreak when inPossessionMode: - Player.invis = true; + Player.invis = true; break; case TransformationEnum.Arctiguana: break; @@ -688,8 +708,9 @@ public override void ModifyDrawInfo(ref PlayerDrawSet drawInfo) { // Set the visuals for the aliens - public override void DrawEffects(PlayerDrawSet drawInfo, ref float r, ref float g, ref float b, ref float a, ref bool fullBright) { - + public override void DrawEffects(PlayerDrawSet drawInfo, ref float r, ref float g, ref float b, ref float a, + ref bool fullBright) { + var customSlot = ModContent.GetInstance(); @@ -700,9 +721,11 @@ public override void DrawEffects(PlayerDrawSet drawInfo, ref float r, ref float if (omnitrixUpdating) { Player.handon = EquipLoader.GetEquipSlot(Mod, "PrototypeOmnitrixUpdating", EquipType.HandsOn); - } else if (onCooldown) { + } + else if (onCooldown) { Player.handon = EquipLoader.GetEquipSlot(Mod, "PrototypeOmnitrixAlt", EquipType.HandsOn); - } else { + } + else { Player.handon = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.HandsOn); } } @@ -719,12 +742,12 @@ public override void DrawEffects(PlayerDrawSet drawInfo, ref float r, ref float } } } - + if (!customSlot.HideVisuals) { if (currTransformation == TransformationEnum.HeatBlast) { - r = 255; - g = 255; - b = 255; + r = 255; + g = 255; + b = 255; fullBright = true; } } @@ -732,7 +755,7 @@ public override void DrawEffects(PlayerDrawSet drawInfo, ref float r, ref float } public override void FrameEffects() { - + var customSlot = ModContent.GetInstance(); if (omnitrixEquipped) { @@ -742,9 +765,11 @@ public override void FrameEffects() { if (omnitrixUpdating) { Player.handon = EquipLoader.GetEquipSlot(Mod, "PrototypeOmnitrixUpdating", EquipType.HandsOn); - } else if (onCooldown) { + } + else if (onCooldown) { Player.handon = EquipLoader.GetEquipSlot(Mod, "PrototypeOmnitrixAlt", EquipType.HandsOn); - } else { + } + else { Player.handon = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.HandsOn); } } @@ -761,6 +786,7 @@ public override void FrameEffects() { } } } + if (!customSlot.HideVisuals) { if (isTransformed) { Player.wings = -1; @@ -769,18 +795,21 @@ public override void FrameEffects() { Player.handon = -1; Player.back = -1; } + if (currTransformation == TransformationEnum.BuzzShock) { var costume = ModContent.GetInstance(); Player.head = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Head); Player.body = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Body); Player.legs = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Legs); } + if (currTransformation == TransformationEnum.ChromaStone) { var costume = ModContent.GetInstance(); Player.head = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Head); Player.body = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Body); Player.legs = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Legs); } + if (currTransformation == TransformationEnum.DiamondHead) { var costume = ModContent.GetInstance(); Player.head = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Head); @@ -788,12 +817,14 @@ public override void FrameEffects() { Player.legs = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Legs); Player.back = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Back); } + if (currTransformation == TransformationEnum.FourArms) { var costume = ModContent.GetInstance(); Player.head = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Head); Player.body = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Body); Player.legs = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Legs); } + if (currTransformation == TransformationEnum.GhostFreak) { if (inPossessionMode) { Player.head = -1; @@ -804,10 +835,11 @@ public override void FrameEffects() { var costume = ModContent.GetInstance(); Player.head = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Head); Player.body = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Body); - Player.legs = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Legs); + Player.legs = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Legs); } } + if (currTransformation == TransformationEnum.HeatBlast) { var costume = ModContent.GetInstance(); if (snowflake) { @@ -821,37 +853,45 @@ public override void FrameEffects() { Player.legs = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Legs); } } + if (currTransformation == TransformationEnum.RipJaws) { var costume = ModContent.GetInstance(); Player.head = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Head); Player.body = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Body); if (Player.wet) { Player.legs = EquipLoader.GetEquipSlot(Mod, "RipJaws_alt", EquipType.Legs); - } else { - Player.legs = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Legs); + } + else { + Player.legs = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Legs); Player.waist = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Waist); } } + if (currTransformation == TransformationEnum.StinkFly) { var costume = ModContent.GetInstance(); - Player.head = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Head); - Player.body = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Body); - Player.legs = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Legs); - Player.wings = EquipLoader.GetEquipSlot(Mod, ModContent.GetInstance().Name, EquipType.Wings); + Player.head = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Head); + Player.body = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Body); + Player.legs = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Legs); + Player.wings = EquipLoader.GetEquipSlot(Mod, ModContent.GetInstance().Name, + EquipType.Wings); } + if (currTransformation == TransformationEnum.WildVine) { var costume = ModContent.GetInstance(); Player.head = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Head); Player.body = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Body); Player.legs = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Legs); } + if (currTransformation == TransformationEnum.XLR8) { var costume = ModContent.GetInstance(); if (PrimaryAbilityEnabled) { Player.head = EquipLoader.GetEquipSlot(Mod, "XLR8_alt", EquipType.Head); - } else { + } + else { Player.head = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Head); } + Player.body = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Body); Player.legs = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Legs); Player.back = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Back); @@ -869,34 +909,30 @@ public override void FrameEffects() { public override void PreUpdateMovement() { DashMovement(); - + if (PrimaryAbilityEnabled && currTransformation == TransformationEnum.GhostFreak) { // Phasing Logic Vector2 input = Vector2.Zero; - if (Player.controlLeft) input.X -= 1f; + if (Player.controlLeft) input.X -= 1f; if (Player.controlRight) input.X += 1f; - if (Player.controlUp) input.Y -= 1f; - if (Player.controlDown) input.Y += 1f; + if (Player.controlUp) input.Y -= 1f; + if (Player.controlDown) input.Y += 1f; - const float speed = 14.5f; // Ghostfreak feels fast & floaty — tweak as you like - const float damp = 0.82f; // smooth deceleration when letting go + const float speed = 14.5f; + const float damp = 0.82f; - if (input != Vector2.Zero) - { + if (input != Vector2.Zero) { input.Normalize(); Vector2 move = input * speed; - - // Extra upward nudge so you can lift off the ground cleanly + if (input.Y < 0) move.Y -= 3f; Player.position += move; } - else - { + else { Player.velocity *= damp; - Player.position += Player.velocity; // gentle drift + Player.position += Player.velocity; } - - // Kill vanilla movement/collision/gravity for this frame + Player.velocity = Vector2.Zero; } } @@ -910,56 +946,49 @@ private void DashMovement() { // Only apply the dash velocity if our current speed in the wanted direction is less than DashVelocity case DashUp when Player.velocity.Y > -DashVelocity: return; + // float dashDirection = DashDir == DashDown ? 1 : -1.3f; + // newVelocity.Y = dashDirection * DashVelocity; + // break; case DashDown when Player.velocity.Y < DashVelocity: { - return; - // Y-velocity is set here - // If the direction requested was DashUp, then we adjust the velocity to make the dash appear "faster" due to gravity being immediately in effect - // This adjustment is roughly 1.3x the intended dash velocity - float dashDirection = DashDir == DashDown ? 1 : -1.3f; - newVelocity.Y = dashDirection * DashVelocity; - break; - } + return; + // float dashDirection = DashDir == DashDown ? 1 : -1.3f; + // newVelocity.Y = dashDirection * DashVelocity; + // break; + } case DashLeft when Player.velocity.X > -DashVelocity: case DashRight when Player.velocity.X < DashVelocity: { - // X-velocity is set here - float dashDirection = DashDir == DashRight ? 1 : -1; - newVelocity.X = dashDirection * DashVelocity; - break; - } + float dashDirection = DashDir == DashRight ? 1 : -1; + newVelocity.X = dashDirection * DashVelocity; + break; + } default: - return; // not moving fast enough, so don't start our dash + return; } - - // start our dash - DashDelay = DashCooldown; - DashTimer = DashDuration; + + DashDelay = DashCooldown; + DashTimer = DashDuration; Player.velocity = newVelocity; - // Here you'd be able to set an effect that happens when the dash first activates - // Some examples include: the larger smoke effect from the Master Ninja Gear and Tabi } } if (DashDelay > 0) DashDelay--; - if (DashTimer > 0) { // dash is active - // This is where we set the afterimage effect. You can replace these two lines with whatever you want to happen during the dash - // Some examples include: spawning dust where the player is, adding buffs, making the player immune, etc. - // Here we take advantage of "player.eocDash" and "player.armorEffectDrawShadowEOCShield" to get the Shield of Cthulhu's afterimage effect - Player.eocDash = DashTimer; + if (DashTimer > 0) { + Player.eocDash = DashTimer; Player.armorEffectDrawShadowEOCShield = true; Player.GiveImmuneTimeForCollisionAttack(40); - - // count down frames remaining + DashTimer--; } } private bool CanUseDash() { - return Player.dashType == 0 // player doesn't have Tabi or EoCShield equipped (give priority to those dashes) - && !Player.setSolar // player isn't wearing solar armor - && !Player.mount.Active; // player isn't mounted, since dashes on a mount look weird + return + Player.dashType == 0 + && !Player.setSolar + && !Player.mount.Active; } public override void OnEnterWorld() { @@ -968,71 +997,47 @@ public override void OnEnterWorld() { currTransformation = TransformationEnum.None; } } - - private void EndPossession() - { + + private void EndPossession() { if (!inPossessionMode) return; inPossessionMode = false; possessedTarget = null; - - // Snap player back to pre-possession position + Player.position = prePossessionPosition; - - // Re-enable visuals and remove immunity + Player.invis = false; Player.immune = false; - - // Optional: Short invincibility after return + Player.immune = true; Player.immuneTime = 60; - - // Visual/sound cue for return + SoundEngine.PlaySound(SoundID.MaxMana with { Pitch = -0.3f, Volume = 0.8f }, Player.Center); - for (int i = 0; i < 30; i++) - { - Dust d = Dust.NewDustPerfect(Player.Center, DustID.PurpleTorch, Main.rand.NextVector2Circular(6f, 6f), Scale: 1.8f); + for (int i = 0; i < 30; i++) { + Dust d = Dust.NewDustPerfect(Player.Center, DustID.PurpleTorch, Main.rand.NextVector2Circular(6f, 6f), + Scale: 1.8f); d.noGravity = true; } } - - - // This is where we unlock transformations + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { base.OnHitNPC(target, hit, damageDone); if (target.life <= 0) { - if (Main.bloodMoon) - { - addTransformation(TransformationEnum.GhostFreak); + if (Main.bloodMoon) { + AddTransformation(TransformationEnum.GhostFreak); } - if (NPC.downedGoblins) - { - addTransformation(TransformationEnum.RipJaws); + + if (NPC.downedGoblins) { + AddTransformation(TransformationEnum.RipJaws); } } - - + + if (isTransformed && !ultimateAttack && omnitrixEnergyRegen == 0) omnitrixEnergy += Math.Max(hit.Damage / 25, 1); } public override void PreUpdate() { - - if (colourAmount >= 1.0f) { - thisColour++; - nextColour++; - colourAmount = 0.0f; - } - - if (thisColour >= colours.Length) { - thisColour = 0; - } - if (nextColour >= colours.Length) { - nextColour = 0; - } - - colourAmount += 0.1f; - if (inPossessionMode) { if (Main.GameUpdateCount % 60 == 0) { int dotDamage = 35; @@ -1043,31 +1048,28 @@ public override void PreUpdate() { } if (PrimaryAbilityEnabled && currTransformation == TransformationEnum.GhostFreak) { - // Core noclip setup (DragonLens-style) - Player.gravity = 0f; // disable gravity multiplier - Player.noKnockback = true; - Player.noFallDmg = true; + Player.gravity = 0f; + Player.noKnockback = true; + Player.noFallDmg = true; - // Prevent ground-snap / fall damage logic Player.fallStart = (int)(Player.position.Y / 16f); } } - public void addTransformation(TransformationEnum transformation) { + public void AddTransformation(TransformationEnum transformation) { if (!TransformationHandler.HasTransformation(Player, transformation)) { unlockedTransformation.Add(transformation); Main.NewText(Player.name + " has unlocked " + transformation.GetName(), Color.Green); - - if (Main.netMode == NetmodeID.Server) - { + + if (Main.netMode == NetmodeID.Server) { ModPacket packet = Mod.GetPacket(); packet.Write((byte)Ben10Mod.MessageType.UnlockTransformation); - packet.Write((byte)Player.whoAmI); // the player who earned it + packet.Write((byte)Player.whoAmI); packet.Write((int)transformation); - packet.Send(toClient: Player.whoAmI); // send ONLY to the player who deserves it + packet.Send(toClient: Player.whoAmI); } - + } } } -} +} \ No newline at end of file diff --git a/OmnitrixProjectile.cs b/OmnitrixProjectile.cs index 18d8e34..7502649 100644 --- a/OmnitrixProjectile.cs +++ b/OmnitrixProjectile.cs @@ -13,12 +13,15 @@ namespace Ben10Mod; public class OmnitrixProjectile : GlobalProjectile { public override bool InstancePerEntity => true; - public int itemUsed = 0; - private int framesAlive = 0; + public int itemUsed = 0; + private int framesAlive = 0; + public bool projectileSlowed = false; + public Vector2 initialVelocity = Vector2.Zero; public override void OnSpawn(Projectile projectile, IEntitySource source) { if (source is IEntitySource_WithStatsFromItem itemSource) { - itemUsed = itemSource.Item.type; + itemUsed = itemSource.Item.type; + initialVelocity = projectile.velocity; } } @@ -33,9 +36,12 @@ public override void AI(Projectile projectile) { framesAlive++; if (projectile.owner == Main.LocalPlayer.whoAmI) { var omp = Main.LocalPlayer.GetModPlayer(); - if (framesAlive >= 60 && omp.ultimateAbilityEnabled && omp.currTransformation == TransformationEnum.XLR8) { - projectile.velocity.Normalize(); + if (omp.UltimateAbilityEnabled && omp.currTransformation == TransformationEnum.XLR8) { + projectile.velocity = initialVelocity * (1 - framesAlive / 60f); + if (framesAlive >= 60) projectile.velocity = Vector2.Zero; + projectileSlowed = true; } + else if (projectileSlowed) projectile.velocity = initialVelocity * 2f; } } diff --git a/bossTrackerNPC.cs b/bossTrackerNPC.cs index cc9ec63..9c412a5 100644 --- a/bossTrackerNPC.cs +++ b/bossTrackerNPC.cs @@ -112,39 +112,39 @@ public override void OnKill(NPC npc) { switch (npc.type) { case NPCID.KingSlime: { player.GetModPlayer() - .addTransformation(TransformationEnum.DiamondHead); + .AddTransformation(TransformationEnum.DiamondHead); break; } case NPCID.EyeofCthulhu: { player.GetModPlayer() - .addTransformation(TransformationEnum.XLR8); + .AddTransformation(TransformationEnum.XLR8); break; } case NPCID.BrainofCthulhu: { player.GetModPlayer() - .addTransformation(TransformationEnum.FourArms); + .AddTransformation(TransformationEnum.FourArms); break; } case NPCID.EaterofWorldsHead: case NPCID.EaterofWorldsTail: case NPCID.EaterofWorldsBody: { player.GetModPlayer() - .addTransformation(TransformationEnum.FourArms); + .AddTransformation(TransformationEnum.FourArms); break; } case NPCID.QueenBee: { player.GetModPlayer() - .addTransformation(TransformationEnum.StinkFly); + .AddTransformation(TransformationEnum.StinkFly); break; } case NPCID.SkeletronHead: { player.GetModPlayer() - .addTransformation(TransformationEnum.BuzzShock); + .AddTransformation(TransformationEnum.BuzzShock); break; } case NPCID.Deerclops: { player.GetModPlayer() - .addTransformation(TransformationEnum.WildVine); + .AddTransformation(TransformationEnum.WildVine); break; } case NPCID.WallofFlesh: { @@ -156,12 +156,12 @@ public override void OnKill(NPC npc) { } case NPCID.QueenSlimeBoss: { player.GetModPlayer() - .addTransformation(TransformationEnum.ChromaStone); + .AddTransformation(TransformationEnum.ChromaStone); break; } case NPCID.Retinazer: case NPCID.Spazmatism: - player.GetModPlayer().addTransformation(TransformationEnum.EyeGuy); + player.GetModPlayer().AddTransformation(TransformationEnum.EyeGuy); break; default: break; } From 541591d6a28d5a1eda5637c560eb079110db9152 Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Fri, 6 Mar 2026 08:28:35 +1100 Subject: [PATCH 17/25] More shader work --- Ben10Mod.cs | 13 ++++++++----- Content/Items/Vanity/ShaderDyes/DiscoDye.cs | 17 +++++++++++++++++ Effects/{BasicTint.fx => MyDyes.fx} | 16 ++++++++++------ Effects/{BasicTint.xnb => MyDyes.xnb} | Bin 1804 -> 1876 bytes Localization/en-US_Mods.Ben10Mod.hjson | 5 +++++ OmnitrixPlayer.cs | 17 ++++++++++++++--- 6 files changed, 54 insertions(+), 14 deletions(-) create mode 100644 Content/Items/Vanity/ShaderDyes/DiscoDye.cs rename Effects/{BasicTint.fx => MyDyes.fx} (51%) rename Effects/{BasicTint.xnb => MyDyes.xnb} (51%) diff --git a/Ben10Mod.cs b/Ben10Mod.cs index d470e19..de30a37 100644 --- a/Ben10Mod.cs +++ b/Ben10Mod.cs @@ -1,7 +1,9 @@ using System.IO; using Ben10Mod.Content.Items.Accessories; +using Ben10Mod.Content.Items.Vanity.ShaderDyes; using Ben10Mod.Enums; using Microsoft.Xna.Framework.Graphics; +using Mono.Cecil; using ReLogic.Content; using Terraria; using Terraria.Graphics.Effects; @@ -13,12 +15,13 @@ namespace Ben10Mod { public class Ben10Mod : Mod { public override void Load() { if (Main.netMode != NetmodeID.Server) { - // Asset dyeShader = this.Assets.Request("Effects/BasicTint"); - // - // GameShaders.Armor.BindShader(ModContent.ItemType(), - // new ArmorShaderData(dyeShader, "ArmorBasic")).UseColor(1f, 0, 0); - + Asset dyeShader = this.Assets.Request("Effects/MyDyes"); Asset filterShader = this.Assets.Request("Effects/MyFilters"); + + + GameShaders.Armor.BindShader(ModContent.ItemType(), + new ArmorShaderData(dyeShader, "BasicTint")); + Filters.Scene["Ben10Mod:Grayscale"] = new Filter(new ScreenShaderData(filterShader, "Grayscale"), EffectPriority.Medium); } diff --git a/Content/Items/Vanity/ShaderDyes/DiscoDye.cs b/Content/Items/Vanity/ShaderDyes/DiscoDye.cs new file mode 100644 index 0000000..1b00da1 --- /dev/null +++ b/Content/Items/Vanity/ShaderDyes/DiscoDye.cs @@ -0,0 +1,17 @@ +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Items.Vanity.ShaderDyes; + +public class DiscoDye : ModItem { + public override string Texture => "Terraria/Images/Item_" + ItemID.None; + + public override void SetDefaults() { + Item.width = 20; + Item.height = 20; + Item.maxStack = 1; + Item.value = Item.sellPrice(gold: 1); + Item.rare = ItemRarityID.Blue; + } +} \ No newline at end of file diff --git a/Effects/BasicTint.fx b/Effects/MyDyes.fx similarity index 51% rename from Effects/BasicTint.fx rename to Effects/MyDyes.fx index e3283c4..c3aa65a 100644 --- a/Effects/BasicTint.fx +++ b/Effects/MyDyes.fx @@ -1,4 +1,4 @@ -sampler uImage0 : register(s0); +sampler uImage0 : register(s0); sampler uImage1 : register(s1); float3 uColor; float3 uSecondaryColor; @@ -16,16 +16,20 @@ float2 uTargetPosition; float4 uLegacyArmorSourceRect; float2 uLegacyArmorSheetSize; -float4 ArmorBasic(float2 texCoord : TEXCOORD0, float4 color : COLOR0) : COLOR0 + + +float4 BasicTint(float4 sampleColor : COLOR0, float2 coords : TEXCOORD0) : COLOR0 { - float4 tex = tex2D(uImage0, texCoord); - return tex * float4(uColor.rgb, 1) * color; + float4 color = tex2D(uImage0, coords); + float luminosity = (color.r + color.g + color.b) / 3; + color.rgb = uColor * luminosity; + return color * sampleColor; } technique Technique1 { - pass ArmorBasic + pass BasicTint { - PixelShader = compile ps_2_0 ArmorBasic(); + PixelShader = compile ps_2_0 BasicTint(); } } \ No newline at end of file diff --git a/Effects/BasicTint.xnb b/Effects/MyDyes.xnb similarity index 51% rename from Effects/BasicTint.xnb rename to Effects/MyDyes.xnb index 140377a5d0b584b82a94d764321fe768ca6da0a3..d3e6c34257deae12432454bb2809fdbcb51610fd 100644 GIT binary patch delta 164 zcmeC-yTZpF;pbG&$`~?{eJFJBU5`Ih!f~=LjFU delta 92 zcmcb@*Tcsi;pbG&%E&X3eJ*3l#-*E?`M4Pv7#xdo^NXAki!+lqr?HeVGU`me%X(Tu lo`Hc0DA~Zkz`Oy$=ASV62Ad2wD^QeyfgLFMWU@ZHDgae|6+Hj| diff --git a/Localization/en-US_Mods.Ben10Mod.hjson b/Localization/en-US_Mods.Ben10Mod.hjson index de0516c..ee1c902 100644 --- a/Localization/en-US_Mods.Ben10Mod.hjson +++ b/Localization/en-US_Mods.Ben10Mod.hjson @@ -245,6 +245,11 @@ Items: { Tooltip: "" DisplayName: Hero Fragment } + + DiscoDye: { + DisplayName: Disco Dye + Tooltip: "" + } } Keybinds: { diff --git a/OmnitrixPlayer.cs b/OmnitrixPlayer.cs index b9139ea..582f1be 100644 --- a/OmnitrixPlayer.cs +++ b/OmnitrixPlayer.cs @@ -28,8 +28,10 @@ using Ben10Mod.Content.DamageClasses; using Terraria.Audio; using Ben10Mod.Content.Items.Accessories.Wings; +using Ben10Mod.Content.Items.Vanity.ShaderDyes; using Ben10Mod.Content.Transformations.EyeGuy; using Terraria.Graphics.Effects; +using Terraria.Graphics.Shaders; using Terraria.WorldBuilding; namespace Ben10Mod { @@ -690,9 +692,9 @@ public override void ModifyDrawInfo(ref PlayerDrawSet drawInfo) { break; case TransformationEnum.ChromaStone when PrimaryAbilityEnabled: Color overlayColor = Main.DiscoColor; - drawInfo.colorArmorHead = overlayColor; - drawInfo.colorArmorBody = overlayColor; - drawInfo.colorArmorLegs = overlayColor; + // drawInfo.colorArmorHead = overlayColor; + // drawInfo.colorArmorBody = overlayColor; + // drawInfo.colorArmorLegs = overlayColor; break; case TransformationEnum.DiamondHead: case TransformationEnum.FourArms: @@ -794,6 +796,8 @@ public override void FrameEffects() { Player.handoff = -1; Player.handon = -1; Player.back = -1; + Player.waist = -1; + Player.shield = -1; } if (currTransformation == TransformationEnum.BuzzShock) { @@ -808,6 +812,13 @@ public override void FrameEffects() { Player.head = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Head); Player.body = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Body); Player.legs = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Legs); + if (PrimaryAbilityEnabled) { + int shaderID = GameShaders.Armor.GetShaderIdFromItemId(ModContent.ItemType()); + GameShaders.Armor.GetShaderFromItemId(ModContent.ItemType())?.UseColor(Main.DiscoR / 255f, Main.DiscoG / 255f, Main.DiscoB / 255f); + Player.cHead = shaderID; + Player.cBody = shaderID; + Player.cLegs = shaderID; + } } if (currTransformation == TransformationEnum.DiamondHead) { From eb0c9a735c828f5abda38f3da9b89edc00e15396 Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Fri, 6 Mar 2026 14:25:10 +1100 Subject: [PATCH 18/25] Started work on Bigchill --- .../Buffs/Transformations/BigChill_Buff.cs | 24 ++++++ Content/Items/Weapons/PlumbersBadge.cs | 3 + Content/TransformationHandler.cs | 1 + Content/Transformations/BigChill/BigChill.cs | 78 ++++++++++++++++++ Content/Transformations/BigChill/BigChill.png | Bin 0 -> 745 bytes .../BigChill/BigChill_Body.png | Bin 0 -> 4105 bytes .../BigChill/BigChill_Head.png | Bin 0 -> 3909 bytes .../BigChill/BigChill_Legs.png | Bin 0 -> 4257 bytes Enums/TranformationEnum.cs | 7 ++ Localization/en-US_Mods.Ben10Mod.hjson | 10 +++ OmnitrixPlayer.cs | 39 +++++++-- OmnitrixProjectile.cs | 2 +- 12 files changed, 158 insertions(+), 6 deletions(-) create mode 100644 Content/Buffs/Transformations/BigChill_Buff.cs create mode 100644 Content/Transformations/BigChill/BigChill.cs create mode 100644 Content/Transformations/BigChill/BigChill.png create mode 100644 Content/Transformations/BigChill/BigChill_Body.png create mode 100644 Content/Transformations/BigChill/BigChill_Head.png create mode 100644 Content/Transformations/BigChill/BigChill_Legs.png diff --git a/Content/Buffs/Transformations/BigChill_Buff.cs b/Content/Buffs/Transformations/BigChill_Buff.cs new file mode 100644 index 0000000..8eea774 --- /dev/null +++ b/Content/Buffs/Transformations/BigChill_Buff.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Ben10Mod.Enums; +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Buffs.Abilities { + public class BigChill_Buff : ModBuff { + public override string Texture => "Ben10Mod/Content/Buffs/Transformations/EmptyTransformation"; + private OmnitrixPlayer p; + public override void Update(Player player, ref int buffIndex) { + p = player.GetModPlayer(); + + p.currTransformation = TransformationEnum.BigChill; + p.isTransformed = true; + p.wasTransformed = true; + } + public override bool RightClick(int buffIndex) => false; + } +} diff --git a/Content/Items/Weapons/PlumbersBadge.cs b/Content/Items/Weapons/PlumbersBadge.cs index 559d085..21d96c8 100644 --- a/Content/Items/Weapons/PlumbersBadge.cs +++ b/Content/Items/Weapons/PlumbersBadge.cs @@ -327,6 +327,9 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, : ModContent.ProjectileType(); finalDamage = omp.ultimateAttack ? (int)(damage * 2f) : damage; break; + case TransformationEnum.BigChill: + projType = ProjectileID.FrostBlastFriendly; + break; } if (projType == 0) return false; diff --git a/Content/TransformationHandler.cs b/Content/TransformationHandler.cs index 9a6707d..44a91ea 100644 --- a/Content/TransformationHandler.cs +++ b/Content/TransformationHandler.cs @@ -67,6 +67,7 @@ public static void Detransform(Player player, int seconds, bool showParticles = player.ClearBuff(ModContent.BuffType()); player.ClearBuff(ModContent.BuffType()); player.ClearBuff(ModContent.BuffType()); + player.ClearBuff(ModContent.BuffType()); player.ClearBuff(ModContent.BuffType()); player.ClearBuff(ModContent.BuffType()); diff --git a/Content/Transformations/BigChill/BigChill.cs b/Content/Transformations/BigChill/BigChill.cs new file mode 100644 index 0000000..4f2ff18 --- /dev/null +++ b/Content/Transformations/BigChill/BigChill.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Terraria.ID; +using Terraria; +using Terraria.ModLoader; +using Ben10Mod.Enums; + +namespace Ben10Mod.Content.Transformations.BigChill +{ + public class BigChill : ModItem { + public override void Load() { + // The code below runs only if we're not loading on a server + if (Main.netMode == NetmodeID.Server) + return; + + // Add equip textures + EquipLoader.AddEquipTexture(Mod, $"{Texture}_{EquipType.Head}", EquipType.Head, this, equipTexture: new XLR8Head()); + EquipLoader.AddEquipTexture(Mod, $"{Texture}_{EquipType.Body}", EquipType.Body, this); + EquipLoader.AddEquipTexture(Mod, $"{Texture}_{EquipType.Legs}", EquipType.Legs, this); + + //Add a separate set of equip textures by providing a custom name reference instead of an item reference + //EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.Head}", EquipType.Head, name: "BlockyAlt", equipTexture: new BlockyHead()); + //EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.Body}", EquipType.Body, name: "BlockyAlt"); + //EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.Legs}", EquipType.Legs, name: "BlockyAlt"); + } + + // Called in SetStaticDefaults + private void SetupDrawing() { + // Since the equipment textures weren't loaded on the server, we can't have this code running server-side + if (Main.netMode == NetmodeID.Server) + return; + + int equipSlotHead = EquipLoader.GetEquipSlot(Mod, Name, EquipType.Head); + int equipSlotBody = EquipLoader.GetEquipSlot(Mod, Name, EquipType.Body); + int equipSlotLegs = EquipLoader.GetEquipSlot(Mod, Name, EquipType.Legs); + + //int equipSlotHeadAlt = EquipLoader.GetEquipSlot(Mod, "BlockyAlt", EquipType.Head); + //int equipSlotBodyAlt = EquipLoader.GetEquipSlot(Mod, "BlockyAlt", EquipType.Body); + //int equipSlotLegsAlt = EquipLoader.GetEquipSlot(Mod, "BlockyAlt", EquipType.Legs); + + ArmorIDs.Head.Sets.DrawHead[equipSlotHead] = false; + //ArmorIDs.Head.Sets.DrawHead[equipSlotHeadAlt] = false; + ArmorIDs.Body.Sets.HidesTopSkin[equipSlotBody] = true; + ArmorIDs.Body.Sets.HidesArms[equipSlotBody] = true; + //ArmorIDs.Body.Sets.HidesTopSkin[equipSlotBodyAlt] = true; + //ArmorIDs.Body.Sets.HidesArms[equipSlotBodyAlt] = true; + ArmorIDs.Legs.Sets.HidesBottomSkin[equipSlotLegs] = true; + //ArmorIDs.Legs.Sets.HidesBottomSkin[equipSlotLegsAlt] = true; + } + + public override void SetStaticDefaults() { + SetupDrawing(); + } + + public override void SetDefaults() { + Item.width = 40; + Item.height = 80; + Item.useAnimation = 30; + Item.useTime = 30; + Item.useStyle = ItemUseStyleID.HiddenAnimation; + Item.consumable = true; + } + + public override bool CanUseItem(Player player) => !TransformationHandler.HasTransformation(player, TransformationEnum.BigChill); + + public override bool? UseItem(Player player) { + player.GetModPlayer().unlockedTransformation.Add(TransformationEnum.BigChill); + return true; + } + } + + public class XLR8Head : EquipTexture { + public override bool IsVanitySet(int head, int body, int legs) => true; + } +} diff --git a/Content/Transformations/BigChill/BigChill.png b/Content/Transformations/BigChill/BigChill.png new file mode 100644 index 0000000000000000000000000000000000000000..2394e29ec5129e51083c1f704c9669c6db9269f9 GIT binary patch literal 745 zcmVPx%qe(Fbsu!t}{ml$hq?dPU%r}EKe zYL^p`^S*1fp(r6PwV$%(C?Y?FxYVyyfJ$BqnHt2U{#<}1bX=aVNnEnyeFCE`accdY zgE+N^?}1@O8P#jNnxXRM%!ymrzCX@NoPxi|aD0hdj9s&khyz^Cp*-H_Bre&Ph$FWU z+H>(z`4{j{{)AyTg*hgOnm_tBnzptH#%`s0qNgkR4>p_LXHDTuvP)ZyiK^~7`Joak}ND;Rr zsEU@#8Um(x98tW^PZ3aqI6#KH7CO?vRsj~`)|}>*e2iUVNl9>c1bB#RW4Tfv){L%1 zkir`(mT?~^V@4V#1pwI7A>L525(jXuHq@|p4ot}sYk0i;Jn49!HzUNrecnkCL+0DS z5ZdG=a?S>ZnB_Lmbd`yQ=DLSPSiDW)xI6c>u(RLe?|hJXW;(KS06e2 b#P>E|0p$^yRj}8i00000NkvXXu0mjfrl(t1 literal 0 HcmV?d00001 diff --git a/Content/Transformations/BigChill/BigChill_Body.png b/Content/Transformations/BigChill/BigChill_Body.png new file mode 100644 index 0000000000000000000000000000000000000000..355c3b2dae6e6fd33c1f548e8d9573f665b46a02 GIT binary patch literal 4105 zcma)92Q*x3yWUYIh76(}M3jgy(MyyuWR&P7BFZ58FwTZ+eV(dYDSuuCj7t2FOl?7dOO3P81Q{5O?{(qCRD2u03J4) zaCb5A`M`jZo&+j#z*q!eSd0v>2S&94k?wf=XrMwWdP0j!m<>>Uuq?)y~ir|?)nHPn+Udk+?!Va&|bu)Aq*xRU-V`RsG-i81)J z_@|wQ&ul>OU+D@;+CKzg{i#1~muBZ}?Oa{bX0Aw3hH zah)kXDq-wAv7#AQP5YW?-!)1(ePF_3;?55<{X9oCW*BsRHYnp@gpkI>rNyN2+`2iQ zU65`ux}D$oaf&hL>!_-B=Y#_V$t{lj6L6vj1c+IU`($Pbff}KMPrietL5vmQlhI{o zxLQkh3BG5KVx~6dCxSrRgo2!#(Kk(#wq@eju6|kU$&*R+k9Gz7WCx3hAm}|?X}^A= zTx(^S_(UII#T2f{(B2v_qXe}LWpK9wmxL?wz0j_JKrLwulpsTG_faqC-I#P6qwI^jW57th)4={E6()D>((*G+gxb&8PS<&+3z$%x5Ssv*k#EqJfk$37gs^>zot2+m@o{OqImO5k8TX}N z#$)UGf!Oh-fE%ZB&6gFzgS0tmjmaK_igN|is;b=(;C1F)qctt4$!}wB)oKb*^zYbKO_>R zzDd>fYo5+svOYN=Sxy;~{a#;-e(7!uJ(I#6(_jh4svc8;TdPEU_qQkqjoWbZOZziMQBz ziK^o9L+nGjc;e7)yl&BcwMYv1c6@Rx)Qa71w`xiohn|&Gk+wTYI^-WIh;h=wZw}Eq zGB`+}c2JFjwoZqR`A(0AorfFCpAS~`Q;u}wzn4CJ^mEK$(V({QxKQOmoK912tfMJP z6(u}8RX$k=&(AHME5Csod+VXIgci~qc_5|jUA)0Rc@_R*N(-JaW!N<6r#rgpEbIkp z$e8TAjvpDOIkz=okT8%XA|jb)Q_-E>I@8ScCEg~@xei~^>o%nJjjtUQbw3lwZc`=N zDUJ7OcoMNy7geYp^A|Gl&&1Ar*8GtCms&ry2xwfd+*hXbhv-R(TWKC&2YbEI7S(qJ zuL$lfkbqaL%-!upK_3SWHr%)?KOj6fg zV|m5(%87manu4?pOg(co^Ik@527RWt?EaIq43R!ip9*v1%i13IRC*y-^Gq|lGF9^+ zk7{>K@8YNaa&4Y3-0tnhAiPPvF-P+Ir|30wl=yz%+J683jIV*O+>XQ!gU|KNYkOk* z8bsN(-HGvG)78mkc;C|np#{uVYrt_}bO1I0AFy;_cp$$izNxuYOk~^j-mzE<;srQp z87gG5h4pU5a~RW0%l7yV516bYK4f=gM`uU0GPMrO4AV;38g`|``&Y->zqFT%P()cS zr}Q6LnmG?qM$ z%6q3b(9-|($H(Wn1Dq=%&OH8)yk5reCw9p${JAZ;9g=~TNtSVS&-I8~C|ryp$`S>) zN0w-Ww@r7}ttYHcXFuLN)HD=gFDSd^lFU#>@-V04ks(GXqXyN{Ft&8Enz~l!Lz&ab&Ms^?NPv#PT<0s|sEN@VR#J=}*)9gygFI_8DF|}|ptytGb zD~(~+lh(J_PZnAi1Yt2=&fmA1xodI?1{$iY3ikSTVV&M!FZ1d3`i5t5eVAD|VJ~`b z>ibeld13dvB4-7wpuSU8JPyx3?cQ7}ll?UN;8R4{Y}iQzH+9X3^vKYV<4DTT+o#*u zgf?(QdEgS!T(jxnNi)b$Y3r&qx5D=PQ9Hpu4#e&P>yR-#3)`ZBv9ZLeXsbPVHi+_Y z^a#>4)7;-O=^RH+BH4mIoNmp4Pw10x;dN6oax$ROyDK|6gEsa&_Lxj<8QAE@?DdWM zQ4gu{w(*9(%b6`ct%T3@)a9=RnJ0xYb@P5J2X=i6i??-*(q-9UY(ehFg_S*p#VbWb ze2SCM2(rQ6GYh-%`>@r1B{_DS}tJu!>zF!NBC`rwMEd`y6kcf7*EPU@P)6b++Xjslczn61p$`Rt%Q za=NSLmPghVc(PokkKsY_YB?5!*K`>LSXmt&WZ(T8u55oH*OmM$e*h# zBMf{p)+bxjbD^{#z4dZt-?M^sc5iX?U)oN}o}&=zm;k`3~u( z%y-54iPOJg?%uE{r2;I+ynm9Qepb@G3p%9fE2CY;kU?mZ$a?!h&5AQ19#n9)#J{2h zF`ZFk9H|)!qRz)qv)GFu_SiLn)!0ekZin%^ym)`2rK2d zN2rJ5EIowvd)0XOL$4?qBxGL-g?&yioC zzla8DXtgP+w8q6`Ld#S=K{^*?4*V;sKraXEOI2O30u0%t?hM zg)UkLpYP2}RjZj_EnLJnHr@EWW>oxSwR^hpAh#1GrR%b|8d-0USzj)GSbORyJ(;a7 zdzYO~qW|lArmVg3L4)El0_0>K4I0~;;qr6=Q~bvH<{9`6teDvyT=cy1trC^ESApalF*=%DW03`0|MLP>9p%;J~Xi1|R5J9$In z5xh=j^+vCM3r`}|q=8{s(BXsiDGAH2WARYkh3|Nl`vfx4{<>^NVnI8~e{-8J9mUWc ze?C`eN_K8R{_-xQT{+QZXs+t_jt;rN*k1W5kFOT0d&gMwd5db;g(kX%UY*7;)0f$u zF25jy{2%Bg#IgcIlJwCUkG>LDs_uQf^Me-xBI28Iu3SMtKal8p7-G5<66 z5c{3-s5MA1nq-M$?Av1*nj$d_i6L7dWSb(p3}Y)y3J)VATZHUeB}SPU)MSJ_xJmKKlk^X`${l3Gvs7H z$_@YkC*0_q#oj6n0L)Hotb0!n8~HH+zz*}&*Ecu!@Coqo_wex*gX`;y`TF@>^F+A; zfKfuWr8_cpNKkitvrx!RkNI)z*kfamn1!A|GQxYN%{2`E#bm(#y~~%;+;p%gkulyVEmF@0p?vXmUsv zF-y7B^Ng@Mmrt}Ig2I`o!_3tOCsyjD#8V13g-Cf3r|6Xl=-ls=k}NktFOWWX0o zCZZ8F0AST@E78R-9RdZ)dr~-902?KMe>y(40r+4FD0L^hV}WW7>?lH95eyhwepV5O z2>|XKfSM5`5RV>qs+mobfk3JGyR&tyClPkU4T zDr7q#2iZ1#&CNK3hK_ub3DY5mwwL%8Df_cmnD7lNuTnJIP6V z*~2>rcU32RCd$5*3v}){bB`EiyiIlQ`oKQUuobrTlY!d5`ouA0jX6%kWHBg98G_;n zLF3z3TarcOd8e@i8Ptt*8?oOKY6++m226cLv}gyE>dy%z&Ly=uIB`NQ;Ujm3L7J=r z)v;7;;!5J!^5iInmA+J*FNKw|PorxkfseeN?kUtt4a53?Lh>S2l+N-6 zwDY`eW1nvq9&O`8I}66@@e|t76Z#O>XnsFuP=C2~5aaW}|-SV}cfV^V-%oWwx?&-}ulKHF` zaKtY1#+g#m)f-hAWp!X#tPVoQwAt*KM2q-E_$|q>-$Z3{Bu`dI;8MKc#YPl($74_} z`%uQbF_#oa*Vjp2KlKJ28mDtEC+~>`LS`{d+W4rORAH9I1+5DWhN1963(hABgTAHl zjnQ^yx_U2-MDkh+ONeqF4t7kYW+O&WBdC6pX&AhC!1Qy@T1aDJOUe~}m?7p2rhs5x zYt4@2m6pF$iuAH*tXy-zm!rz(3w0brQ~dCB<*BmncgQZtNr;0$PPYoq821Sh4sj_x zYy~BmlMp1%(r2X)kfLQrNQgl+iP?+A>l>-Bgi}T7j(AMZgsQb_sql=jK7wf=O}Go; zBBYagp-28^Gk66Pilv5WaM_{^^@#4BF@$c)nDxtnTNgge zp%jByo3f~V$4L}2_g<`*2A2ABm6X&oT&lbC+9z7XUnjd{pk9!wdwmCu-boWY5-w&F zMObw=qw8B%>PG$JN9q0|l zJJy|%KPGP>50S65%TG5;m*}~iP90bta41SBwle)vmv0+tJ7q(%<+Q0QkEyt1t6>kT zSFTN{A3_Z{uM)|`Upt-;Z&YSyQstVgf+~VqN9;eWF32wUm=#~xeAt4%)w3qVmCmIX zN9C$NCVXG~zPHH8F_@+n6rMeoeLm}67GHL-_U6ruETulyJ_DiVyY)SO5BL;(E@wNq zRT^H#_}BTF1eXPd>2w6#@jbtucsBT8aL%{Wo8R&C_ypC>zWL4fn-ihPP@OfkHU5y} z%f~iUHjP)c=hsI^$o6y8&$@kqQwmc#EA8m*a4fnJO+wEwtQn`5RhLax%2vVa!E285 zn3I4g4}Y~*o}&4wWKkPFP3@jga=-1u*{6A3dDy(TcER@k2{MnGt94g;a#-Cx_q*;I zae5w3pVQxeb1rh`=!iIcDmL!+r8_We^<5iY;*mG;4m`HtuiD+vQpvf+V|7||t?R^Y zB8aF?{G@zZxlnnh=GPh%mnwqi>jat|En$VYa){PBz12tkHCVb``H|A2;GEg!=FkVz z-o5WKFn&>Vrm<+31O_34FihBNHoqd^BPXNe>E17$+cVyWfh_Z*1QOY(w+ml=blsfn zpX`)bl(DxsZ=q|^W09NiBA=aj_i5x)UC&Rmk7f@Iz}yI~YOcSj@Tn%M zUX`a)X1EpU_G=4QN3VXTJ(t=tu~rbanR^y6uHtIjU;BLOP7g;qcg3>fO%EwIx2^76 z>!C`><#n&Xw{v8s>}Ua&81HS$pa4X`nByC{v4UF1Rd4pR(tBrZ9ZJT?@$z3*crLFX z8_^oo`jM^?G@gc8^>m^CUddbh8}%XEL&C#b8eyo@$Wpt;Cjq`DUFk&?^A!g6j@Rw0 z7cB7lLpcj+3-pDZsrD&(Xkrj*c%?<+S$=VUQ>}CHM&CNLGZ++fd3>RvDI%#aho-x< zf!!Dzo@uQr>3&>_f;nUQz8jK=B$08ymI|%Bz&u7bBYOTL=L{kDrpZrEx3QJ-YxeonZ%X&9vg&PVMzGq-+WEnBw z;qT>-F>x^2T(RvOv7_37F;Bm*On`RyaHmKY(zEijAe!s5Yxx5%?vm~~*``|156|-! z78^eJYm9V^H1!?IZVhQ)dey*Hb$>vJs+jX)^42WFt#4{t*6dQIwg?oA@!Kw`=_x6j zEnOw0dn-`vn%o0&8y9cx%yZ^~g>JBpHTSDF6*mQ&EmgF{wtTmbwomeLAC0(qYNn4s z71&(f#4eVNDu(6lw^JeaY%O}>ys-}|p@ zho3u(49Qv;ZpY4@;Wr?rX)f=!l5MlJkHD`NfGX8}Zl!K|C=A*P0+FgWVwHwFv&*Y+Kio~s(Ecd<;;J!eNfbWqlnjLs29m3+k`iEn#wGhzXtic zxArur3QKAqmM~ifsp8u9B^s_lehB=FTL0`M)U$NI1Qj7wy)RLT-xv6c4*$^qmCXGT zZW@-L@_h;KqJ4q?!7=G(7PjGgo|YvUJGrf21eH6e;z)*nZw{!uSMF6i^s_yXAYFjN97+a09b*m3mIm{{WsHC#3)Y literal 0 HcmV?d00001 diff --git a/Content/Transformations/BigChill/BigChill_Legs.png b/Content/Transformations/BigChill/BigChill_Legs.png new file mode 100644 index 0000000000000000000000000000000000000000..c3db3c400590039255c9c6f9da8106fa6d3039b4 GIT binary patch literal 4257 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 literal 0 HcmV?d00001 diff --git a/Enums/TranformationEnum.cs b/Enums/TranformationEnum.cs index f489178..f7270d2 100644 --- a/Enums/TranformationEnum.cs +++ b/Enums/TranformationEnum.cs @@ -26,6 +26,7 @@ public enum TransformationEnum { WildVine = 10, XLR8 = 11, EyeGuy = 12, + BigChill = 13, } static class TransformationMethods { @@ -53,6 +54,8 @@ public static int GetTransformation(this TransformationEnum te) { return ModContent.BuffType(); case TransformationEnum.EyeGuy: return ModContent.BuffType(); + case TransformationEnum.BigChill: + return ModContent.BuffType(); default: return -1; } } @@ -81,6 +84,8 @@ public static string GetName(this TransformationEnum te) { return "XLR8"; case TransformationEnum.EyeGuy: return "Eye Guy"; + case TransformationEnum.BigChill: + return "Bigchill"; default: return "None"; } @@ -108,6 +113,8 @@ public static ReLogic.Content.Asset GetTransformationIcon(this Transf return ModContent.Request("Ben10Mod/Content/Interface/EmptyAlien"); case TransformationEnum.EyeGuy: return ModContent.Request("Ben10Mod/Content/Interface/EmptyAlien"); + case TransformationEnum.BigChill: + return ModContent.Request("Ben10Mod/Content/Interface/EmptyAlien"); case TransformationEnum.XLR8: return ModContent.Request("Ben10Mod/Content/Interface/XLR8Select"); default: return ModContent.Request("Ben10Mod/Content/Interface/EmptyAlien"); diff --git a/Localization/en-US_Mods.Ben10Mod.hjson b/Localization/en-US_Mods.Ben10Mod.hjson index ee1c902..0b7357f 100644 --- a/Localization/en-US_Mods.Ben10Mod.hjson +++ b/Localization/en-US_Mods.Ben10Mod.hjson @@ -250,6 +250,11 @@ Items: { DisplayName: Disco Dye Tooltip: "" } + + BigChill: { + Tooltip: "" + DisplayName: Big Chill + } } Keybinds: { @@ -376,6 +381,11 @@ Buffs: { Description: Mods.Ben10Mod.Buffs.UltimateAbility.Description DisplayName: Ultimate Ability } + + BigChill_Buff: { + Description: Mods.Ben10Mod.Buffs.BigChill_Buff.Description + DisplayName: Big Chill_ Buff + } } Projectiles: { diff --git a/OmnitrixPlayer.cs b/OmnitrixPlayer.cs index 582f1be..977f132 100644 --- a/OmnitrixPlayer.cs +++ b/OmnitrixPlayer.cs @@ -29,6 +29,7 @@ using Terraria.Audio; using Ben10Mod.Content.Items.Accessories.Wings; using Ben10Mod.Content.Items.Vanity.ShaderDyes; +using Ben10Mod.Content.Transformations.BigChill; using Ben10Mod.Content.Transformations.EyeGuy; using Terraria.Graphics.Effects; using Terraria.Graphics.Shaders; @@ -527,6 +528,17 @@ public override void PostUpdate() { if (currTransformation == TransformationEnum.WildVine) { abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } + + // Bigchill Transformation + + if (currTransformation == TransformationEnum.BigChill) + { + if (KeybindSystem.PrimaryAbility.Current && !Player.HasBuff() && + !Player.HasBuff()) { + Player.AddBuff(ModContent.BuffType(), 15 * 60); + tranUsedAbility = currTransformation; + } + } if (inPossessionMode) { if (possessedTarget == null || !possessedTarget.active || @@ -596,6 +608,11 @@ public override void PostUpdate() { Player.AddBuff(ModContent.BuffType(), 30 * 60); break; } + case TransformationEnum.BigChill: + { + Player.AddBuff(ModContent.BuffType(), 30 * 60); + break; + } } ChromaStoneAbsorbtion = 0; @@ -612,7 +629,7 @@ public override void PostUpdate() { } } - if (!isTransformed) { + if (!isTransformed || !UltimateAbilityEnabled) { Filters.Scene["Ben10Mod:Grayscale"].GetShader().Shader.Parameters["strength"]?.SetValue(0f); Filters.Scene.Deactivate("Ben10Mod:Grayscale"); } @@ -620,17 +637,17 @@ public override void PostUpdate() { public override bool CanUseItem(Item item) { if (Player.whoAmI != Main.myPlayer) return false; - return !(currTransformation == TransformationEnum.GhostFreak && PrimaryAbilityEnabled); + return !((currTransformation == TransformationEnum.GhostFreak || currTransformation == TransformationEnum.BigChill) && PrimaryAbilityEnabled); } public override bool CanBeHitByNPC(NPC npc, ref int cooldownSlot) { if (Player.whoAmI != Main.myPlayer) return false; - return !(currTransformation == TransformationEnum.GhostFreak && PrimaryAbilityEnabled); + return !((currTransformation == TransformationEnum.GhostFreak || currTransformation == TransformationEnum.BigChill) && PrimaryAbilityEnabled); } public override bool CanBeHitByProjectile(Projectile proj) { if (Player.whoAmI != Main.myPlayer) return false; - return !(currTransformation == TransformationEnum.GhostFreak && PrimaryAbilityEnabled); + return !((currTransformation == TransformationEnum.GhostFreak || currTransformation == TransformationEnum.BigChill) && PrimaryAbilityEnabled); } public override void OnHurt(Player.HurtInfo info) { @@ -686,6 +703,11 @@ public override void ModifyDrawInfo(ref PlayerDrawSet drawInfo) { case TransformationEnum.GhostFreak when inPossessionMode: Player.invis = true; break; + case TransformationEnum.BigChill when PrimaryAbilityEnabled: + drawInfo.colorArmorHead.A /= 2; + drawInfo.colorArmorBody.A /= 2; + drawInfo.colorArmorLegs.A /= 2; + break; case TransformationEnum.Arctiguana: break; case TransformationEnum.BuzzShock: @@ -915,13 +937,20 @@ public override void FrameEffects() { Player.body = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Body); Player.legs = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Legs); } + + if (currTransformation == TransformationEnum.BigChill) { + var costume = ModContent.GetInstance(); + Player.head = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Head); + Player.body = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Body); + Player.legs = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Legs); + } } } public override void PreUpdateMovement() { DashMovement(); - if (PrimaryAbilityEnabled && currTransformation == TransformationEnum.GhostFreak) { // Phasing Logic + if (PrimaryAbilityEnabled && (currTransformation == TransformationEnum.GhostFreak || currTransformation == TransformationEnum.BigChill)) { // Phasing Logic Vector2 input = Vector2.Zero; if (Player.controlLeft) input.X -= 1f; if (Player.controlRight) input.X += 1f; diff --git a/OmnitrixProjectile.cs b/OmnitrixProjectile.cs index 7502649..9b9ba33 100644 --- a/OmnitrixProjectile.cs +++ b/OmnitrixProjectile.cs @@ -38,7 +38,7 @@ public override void AI(Projectile projectile) { var omp = Main.LocalPlayer.GetModPlayer(); if (omp.UltimateAbilityEnabled && omp.currTransformation == TransformationEnum.XLR8) { projectile.velocity = initialVelocity * (1 - framesAlive / 60f); - if (framesAlive >= 60) projectile.velocity = Vector2.Zero; + if (framesAlive >= 60) projectile.velocity = initialVelocity.SafeNormalize(Vector2.Zero); projectileSlowed = true; } else if (projectileSlowed) projectile.velocity = initialVelocity * 2f; From ea76ff03f4e0c1d66deefd28f0db866a149c80a8 Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Fri, 6 Mar 2026 18:43:26 +1100 Subject: [PATCH 19/25] Adding more stuff to bigchill --- Content/Items/Weapons/PlumbersBadge.cs | 8 +- .../BigChillFrostBreathProjectile.cs | 42 ++++++++ Content/Projectiles/BigChillProjectile.cs | 100 ++++++++++++++++++ Content/Projectiles/BigChillProjectile.png | Bin 0 -> 620 bytes Content/Projectiles/Projectile_464.png | Bin 0 -> 2025 bytes Localization/en-US_Mods.Ben10Mod.hjson | 2 + 6 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 Content/Projectiles/BigChillFrostBreathProjectile.cs create mode 100644 Content/Projectiles/BigChillProjectile.cs create mode 100644 Content/Projectiles/BigChillProjectile.png create mode 100644 Content/Projectiles/Projectile_464.png diff --git a/Content/Items/Weapons/PlumbersBadge.cs b/Content/Items/Weapons/PlumbersBadge.cs index 21d96c8..9511707 100644 --- a/Content/Items/Weapons/PlumbersBadge.cs +++ b/Content/Items/Weapons/PlumbersBadge.cs @@ -5,6 +5,7 @@ using Ben10Mod.Content.Buffs.Abilities; using Ben10Mod.Content.DamageClasses; using Ben10Mod.Content.Projectiles; +using Ben10Mod.Content.Transformations.BigChill; using Ben10Mod.Enums; using Microsoft.Xna.Framework; using Terraria; @@ -188,6 +189,11 @@ public override void HoldItem(Player player) { Item.channel = omp.ultimateAttack; OmnitrixEnergyUse = omp.ultimateAttack ? 10 : 0; break; + case TransformationEnum.BigChill: + Item.useStyle = ItemUseStyleID.Shoot; + Item.shootSpeed = omp.altAttack ? 3f : 20f; + Item.useTime = Item.useAnimation = omp.altAttack ? 6 : 25; + break; default: Item.useTime = Item.useAnimation = 25; Item.shootSpeed = 10f; @@ -328,7 +334,7 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, finalDamage = omp.ultimateAttack ? (int)(damage * 2f) : damage; break; case TransformationEnum.BigChill: - projType = ProjectileID.FrostBlastFriendly; + projType = omp.altAttack ? ModContent.ProjectileType() : ModContent.ProjectileType(); break; } diff --git a/Content/Projectiles/BigChillFrostBreathProjectile.cs b/Content/Projectiles/BigChillFrostBreathProjectile.cs new file mode 100644 index 0000000..9749e26 --- /dev/null +++ b/Content/Projectiles/BigChillFrostBreathProjectile.cs @@ -0,0 +1,42 @@ +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; +using Microsoft.Xna.Framework; + +namespace Ben10Mod.Content.Projectiles; + +public class BigChillFrostBreathProjectile : ModProjectile { + public override string Texture => "Terraria/Images/Projectile_" + ProjectileID.None; + private int _timeAlive = 1; + + public override void SetDefaults() { + Projectile.width = 64; + Projectile.height = 64; + Projectile.friendly = true; + Projectile.tileCollide = false; + Projectile.penetrate = -1; + Projectile.timeLeft = 40; + } + + public override void AI() { + if (Main.GameUpdateCount % 10 == 0) { + _timeAlive++; + } + + Projectile.scale = 1f - 1f / _timeAlive; + + Vector2 center = Projectile.Center; + float scaledW = Projectile.width * Projectile.scale; + float scaledH = Projectile.height * Projectile.scale; + + for (int i = 0; i < 25; i++) { + Vector2 spawnPos = center + new Vector2( + Main.rand.NextFloat(-scaledW / 2f, scaledW / 2f), + Main.rand.NextFloat(-scaledH / 2f, scaledH / 2f) + ); + + int dustNum = Dust.NewDust(spawnPos, 1, 1, DustID.Frost); + Main.dust[dustNum].noGravity = true; + } + } +} \ No newline at end of file diff --git a/Content/Projectiles/BigChillProjectile.cs b/Content/Projectiles/BigChillProjectile.cs new file mode 100644 index 0000000..fb2e808 --- /dev/null +++ b/Content/Projectiles/BigChillProjectile.cs @@ -0,0 +1,100 @@ +using Microsoft.Xna.Framework; +using Terraria; +using Terraria.ModLoader; +using Game = Terraria.Server.Game; + +namespace Ben10Mod.Content.Projectiles; + +public class BigChillProjectile : ModProjectile { + private const float MaxSearchDistance = 250f; + private const float LostTargetRange = 400f; + private const float ChargeSpeed = 22f; + private const float ChargeInertia = 8f; + private const float ChargeOvershoot = 110f; + + public override void SetStaticDefaults() { + Main.projFrames[Type] = 3; + } + + public override void SetDefaults() { + Projectile.width = 52; + Projectile.height = 52; + Projectile.penetrate = 15; + Projectile.tileCollide = false; + Projectile.friendly = true; + } + + public override void AI() { + Player player = Main.player[Projectile.owner]; + + NPC target = FindTarget(player, MaxSearchDistance); + if (target != null) + DoChargeMovement(target); + Projectile.rotation += 0.15f; + if (Main.GameUpdateCount % 20 == 0) { + if (Projectile.frame == 2) { + Projectile.frame = 0; + } + else { + Projectile.frame++; + } + } + } + + private NPC FindTarget(Player player, float maxDetectDistance) { + NPC selectedTarget = null; + float sqrMaxDetectDistance = maxDetectDistance * maxDetectDistance; + + if (player.HasMinionAttackTargetNPC) { + NPC npc = Main.npc[player.MinionAttackTargetNPC]; + if (npc.CanBeChasedBy(this)) { + float sqrDistanceToTarget = Vector2.DistanceSquared(npc.Center, Projectile.Center); + if (sqrDistanceToTarget < sqrMaxDetectDistance) { + return npc; + } + } + } + + for (int k = 0; k < Main.maxNPCs; k++) { + NPC npc = Main.npc[k]; + if (!npc.CanBeChasedBy(this)) + continue; + + float sqrDistanceToTarget = Vector2.DistanceSquared(npc.Center, Projectile.Center); + if (sqrDistanceToTarget < sqrMaxDetectDistance) { + sqrMaxDetectDistance = sqrDistanceToTarget; + selectedTarget = npc; + } + } + + return selectedTarget; + } + + private void DoChargeMovement(NPC target) { + if (!target.active || target.friendly || target.dontTakeDamage) + return; + + float distanceToTarget = Vector2.Distance(Projectile.Center, target.Center); + if (distanceToTarget > LostTargetRange) { + Projectile.Kill(); + return; + } + + Vector2 chargeDirection = Projectile.Center.DirectionTo(target.Center); + if (chargeDirection == Vector2.Zero) + chargeDirection = Vector2.UnitX * Projectile.spriteDirection; + + Vector2 chargeDestination = target.Center + chargeDirection * ChargeOvershoot; + Vector2 toChargeDestination = chargeDestination - Projectile.Center; + float distanceToDestination = toChargeDestination.Length(); + + if (distanceToDestination > 8f) { + toChargeDestination.Normalize(); + toChargeDestination *= ChargeSpeed; + Projectile.velocity = (Projectile.velocity * (ChargeInertia - 1f) + toChargeDestination) / ChargeInertia; + } + else { + Projectile.Kill(); + } + } +} \ No newline at end of file diff --git a/Content/Projectiles/BigChillProjectile.png b/Content/Projectiles/BigChillProjectile.png new file mode 100644 index 0000000000000000000000000000000000000000..3c652e931a379df1f36d2050c2345ef0f2a94c72 GIT binary patch literal 620 zcmeAS@N?(olHy`uVBq!ia0vp^CO|xggAGU;n0I6VDaPU;cPEB*=VV?oFfgfkx;TbZ z%y~P<(2vhEbj5Lk6-UtXHKpy_ z-kp(8d&Dw&Ro|m2Wo!Rt8(?Y>x?z7)TV%Fx-d11|c(?R;%)7QLG@Q`I$*{lEz3k#mt zilqWe`06Zyq~F%-$4@i<_Sstce;U}8S4|K6K6gE?e-cRJ@wLwLwjV#;`65QoYMyFr zi@=h;*Opr?FU*{6`91pl%ICMg{V9v%Th=Ymbmirffam3QQQ~vvY>*3n|6W}Ad7U%J zW3tzrfp*V*wV6N8&!zVEo70j&ODpoNf6eXtwQZ#{8_-eyj6K-AV>La&A0w@FL<(Z z+}uqMrvHAwMEJ@czR3LZKYuLBh?f6$I{Ibw0zQzvU*|P#pEvXTui|B2BR@jCTg`QG tGtb4%qJfuOIUHYor~w8O&@BfN>lp7(Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D2YyLJK~#8N?bpqX zBvlXu;I#!KZ~}9104uoT11DSn5AXm9i6a*TdZYL4reZs(-rB0_o|%_Y9A5rJW<*Oh znh$R^zWL$Te+TAs#o4h8zbF{}^B;e{U>SdMEWpbm3vci`y^_eb=oeNPvJ5xfjPIS5PP41uGJFpoF)3WKgRzVpZwV`j~C>VZ*Sl^ zif?x~fIvocU`RE)8kmBTKl|mY*#q*)w>R({#rM_Wko>d|&Y)__KsCJ@S;Y-xzc>D_ zZhoG*8FgpHUcS@9Azm_`i|*iM z_|CX@kv^Z6G(=t>s1s<80p|39x_0sQm4*Jt?FLiIGl;h;{Kw|dUuC0yNH_RE_Cd41K~3iZp47WL@=TdYo48UgAA zdaLIg-gjrXgS->7{bPR`LKR$ixjMj&5+HhT1>@Wv|ygnc(`!WxNs(Y)O2X)B3 z^4X71pZe1nE*#)Mhl4}a^~)2O`Hm+IP*0=0^?^Fb=X{;1b$3qr*M|cfT1^^ou)6+E zhF?`8N#)MWz< z$V24`N-zx1mVuy;!0gYx+2^gVLw8rs>w{_2aghrwuBO})o*)EI3QIoFM|k$<-t6<% z*P**B=k>v~X@4Z4h1Gd*th_19*}zfj^;+&)#YGGQ8e8fG7D9_!H{*?45Rh3WcLVpo3C~ zx_*bMcS5qBeO=z3E|1?`)%<#Qhr06?|FnA zt9J(I*O&RNx_90K`2%DU8Y{fGCps=8tGEkRSIIx;h4N%9EZ+#%&@q6p9 zI|p)pFQy&mhlLK`5|D-fL)7u)TOY`G{NDQO&ViiYi)qLCaclX&EPt%05x@v_24r5p zdiHmpEN^{yJ3jsM{O1b?CT4jVepNV}5CS0$O+(VaoXdCigM9KQa(>EqJ>l?W_(kFH zTjB;7kVX*hhk!ae!0}tR={0qaO1XNQ82=vyMMyun? zemo$bhJpN>Gv0v?CkzPl*0&7b84e@}2+I7H(aEQ8%P73blXbj!lF!_f_k7_%LQ+uX z31@^np5)WVkTgggZ}MavFP`KxH|0G~q@Yd!fduQ9Pl4X*c+BM+FLZp6Jl);;C(Yv{ z1$2iqjv@NxQ<%3p9&`DwW)F0HkUZVp`X|lf!$DhzGlJ00Xd$15d*eyI&hQNNdojlz z9}Z&3GW?`)2*I7vX;2k0FzG%Eb@TWDAA|MXYxt`Rf(T!RpBw~rMt`Zn8T#>5vj@^> z$i0*9^#?)A@QZ?=EzI`afhP?IM*9Jd+WT}t*cN8{?!a@)?16V<_*KC`#^$F>{>^?$ zu8w8+#lb*^G8`Dbj6Nuq;SUOirs3<4y&zc?7`6T)zxnq~OGu?)XB7|LLVFQZS2 zW%z@F!T#}ChMyeE@QZ`N{&+6KPmX2ygJKzdaXh!-A3ppC4h;;%Q?}OK00000NkvXX Hu0mjf<6Hqe literal 0 HcmV?d00001 diff --git a/Localization/en-US_Mods.Ben10Mod.hjson b/Localization/en-US_Mods.Ben10Mod.hjson index 0b7357f..36a11bc 100644 --- a/Localization/en-US_Mods.Ben10Mod.hjson +++ b/Localization/en-US_Mods.Ben10Mod.hjson @@ -414,6 +414,8 @@ Projectiles: { HeatBlastUltimateProjectile.DisplayName: Heat Blast Ultimate Projectile IcyFlames.DisplayName: Icy Flames BuzzShockUltimateProjectile.DisplayName: Buzz Shock Ultimate Projectile + BigChillProjectile.DisplayName: Big Chill Projectile + BigChillFrostBreathProjectile.DisplayName: Big Chill Frost Breath Projectile } Tiles: { From e8c3acaacca672cd626a5c5e37d8366f49fa03fa Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Sat, 7 Mar 2026 01:18:33 +1100 Subject: [PATCH 20/25] Pushing next update --- Content/Items/Accessories/AdvancedCircuitMatrix.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Content/Items/Accessories/AdvancedCircuitMatrix.cs b/Content/Items/Accessories/AdvancedCircuitMatrix.cs index 2293be9..dfb3785 100644 --- a/Content/Items/Accessories/AdvancedCircuitMatrix.cs +++ b/Content/Items/Accessories/AdvancedCircuitMatrix.cs @@ -18,6 +18,5 @@ public override void SetDefaults() { public override void UpdateAccessory(Player player, bool hideVisual) { var omp = player.GetModPlayer(); omp.advancedCircuitMatrix = true; - omp.omnitrixEnergyRegen += 150; } } \ No newline at end of file From 93170426ef1d55e6b25799a45eec9ae1a1265147 Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Sat, 7 Mar 2026 01:19:45 +1100 Subject: [PATCH 21/25] Added version number --- build.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.txt b/build.txt index 3d69f52..8aac54c 100644 --- a/build.txt +++ b/build.txt @@ -1,6 +1,6 @@ displayName = Terraria 10 (Ben 10 mod) author = DestroyerMob -version = 0.069 +version = 0.070 buildIgnore = .vs\*, Properties\*, *.csproj, *.user, obj\*, bin\*, *.config, .git\*, .github\*, LICENSE, README.md, .editorconfig, .gitignore, .gitattributes, Effects\Compiler\* hideCode = false hideResources = true From 603834c037d0d63ca3ecf6b72b0e50a30ca1dd6f Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Sat, 7 Mar 2026 16:43:46 +1100 Subject: [PATCH 22/25] Trying to get big chill shader working and adding more util stuff --- Ben10Mod.cs | 1 + Content/Items/Weapons/PlumbersBadge.cs | 3 +- .../BigChillFrostBreathProjectile.cs | 6 +- Effects/MyFilters.fx | 37 +++++++++++- Effects/MyFilters.xnb | Bin 788 -> 2540 bytes Enums/TranformationEnum.cs | 35 +++++++++++- NpcEffects.cs | 6 ++ OmnitrixPlayer.cs | 53 +++++++++++++----- 8 files changed, 120 insertions(+), 21 deletions(-) diff --git a/Ben10Mod.cs b/Ben10Mod.cs index de30a37..57d0db9 100644 --- a/Ben10Mod.cs +++ b/Ben10Mod.cs @@ -24,6 +24,7 @@ public override void Load() { Filters.Scene["Ben10Mod:Grayscale"] = new Filter(new ScreenShaderData(filterShader, "Grayscale"), EffectPriority.Medium); + Filters.Scene["Ben10Mod:Bluescale"] = new Filter(new ScreenShaderData(filterShader, "Bluescale"), EffectPriority.Medium); } } diff --git a/Content/Items/Weapons/PlumbersBadge.cs b/Content/Items/Weapons/PlumbersBadge.cs index 9511707..3ce339f 100644 --- a/Content/Items/Weapons/PlumbersBadge.cs +++ b/Content/Items/Weapons/PlumbersBadge.cs @@ -192,7 +192,7 @@ public override void HoldItem(Player player) { case TransformationEnum.BigChill: Item.useStyle = ItemUseStyleID.Shoot; Item.shootSpeed = omp.altAttack ? 3f : 20f; - Item.useTime = Item.useAnimation = omp.altAttack ? 6 : 25; + Item.useTime = Item.useAnimation = omp.altAttack ? 10 : 25; break; default: Item.useTime = Item.useAnimation = 25; @@ -335,6 +335,7 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, break; case TransformationEnum.BigChill: projType = omp.altAttack ? ModContent.ProjectileType() : ModContent.ProjectileType(); + finalDamage = omp.altAttack ? (int)(damage * 0.3f) : damage; break; } diff --git a/Content/Projectiles/BigChillFrostBreathProjectile.cs b/Content/Projectiles/BigChillFrostBreathProjectile.cs index 9749e26..0db680f 100644 --- a/Content/Projectiles/BigChillFrostBreathProjectile.cs +++ b/Content/Projectiles/BigChillFrostBreathProjectile.cs @@ -29,7 +29,7 @@ public override void AI() { float scaledW = Projectile.width * Projectile.scale; float scaledH = Projectile.height * Projectile.scale; - for (int i = 0; i < 25; i++) { + for (int i = 0; i < 12; i++) { Vector2 spawnPos = center + new Vector2( Main.rand.NextFloat(-scaledW / 2f, scaledW / 2f), Main.rand.NextFloat(-scaledH / 2f, scaledH / 2f) @@ -39,4 +39,8 @@ public override void AI() { Main.dust[dustNum].noGravity = true; } } + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { + target.AddBuff(BuffID.Frostburn2, 120); + } } \ No newline at end of file diff --git a/Effects/MyFilters.fx b/Effects/MyFilters.fx index 7695708..0998636 100644 --- a/Effects/MyFilters.fx +++ b/Effects/MyFilters.fx @@ -1,8 +1,28 @@ -sampler uImage0 : register(s0); +sampler uImage0 : register(s0); // The contents of the screen. +sampler uImage1 : register(s1); // Up to three extra textures you can use for various purposes (for instance as an overlay). +sampler uImage2 : register(s2); +sampler uImage3 : register(s3); +float3 uColor; +float3 uSecondaryColor; +float2 uScreenResolution; +float2 uScreenPosition; // The position of the camera. +float2 uTargetPosition; // The "target" of the shader, what this actually means tends to vary per shader. +float2 uDirection; +float uOpacity; +float uTime; +float uIntensity; +float uProgress; +float2 uImageSize1; +float2 uImageSize2; +float2 uImageSize3; +float2 uImageOffset; +float uSaturation; +float4 uSourceRect; // Doesn't seem to be used, but included for parity. +float2 uZoom; float strength = 1.0f; -float4 MainPS(float2 uv : TEXCOORD0) : COLOR0 +float4 Grayscale(float2 uv : TEXCOORD0) : COLOR0 { float4 color = tex2D(uImage0, uv); @@ -13,10 +33,21 @@ float4 MainPS(float2 uv : TEXCOORD0) : COLOR0 return color; } +float4 FrostyScreen(float4 sampleColor: COLOR0, float2 uv : TEXCOORD0) : COLOR0 +{ + float4 color = tex2D(uImage0, uv); + float luminosity = (color.r + color.g + color.b) / 3; + return color * sampleColor; +} + technique Technique1 { pass Grayscale { - PixelShader = compile ps_2_0 MainPS(); + PixelShader = compile ps_2_0 Grayscale(); + } + pass Bluescale + { + PixelShader = compile ps_2_0 FrostyScreen(); } } \ No newline at end of file diff --git a/Effects/MyFilters.xnb b/Effects/MyFilters.xnb index 456e737ee3a589f3ccf35bc3538d3a6713372c0f..93e00ec2007d74eae625b5115de12228462a5adf 100644 GIT binary patch literal 2540 zcmcIlzi$*r6n<+T;fNC%A!Mb9l#P_akxr-caYjbM*zuVFiW57&16c?OFMD&o6??mv z{UL0sEh2>?QVzvUq!gzpmEHIcaFHTK3M5jHp5hv$6fRRlEZ^H-9s_G=nA6;R-^};s zy?HaUv-Zuxy%Wm6r-+n?%GZYO*sk67%4?QZ{?gI9;-2l?E!SJ8zzhHcH($`$^V)Vgnaz9VKW;d_o|medvhj%ny$iLIu6S6H(% zwW{8pxg(}pV!ARteU7*&i-_*=*unls5k2~+oC=>03US~2Xc&HcR6<2?|5{hu5EV)_ z^SPR-Ow-EMR5Q(kT+KNe#h8M+FKN;~sf$j6_;uT~9m;GDB*E)!PP0uz=(g3;oUPb6 z)lIU~q>P}ID4hZK8@eNewJKcO^gV148TV7$mLz`JHuf3WuGp>-S*CWszR9ksIUB-z z#qP;5c4HjtqT%4oagb4Ncv%GwEGcZBPJv@W{&G*#4R4EwIW{h}9Q}J3^P5Ij5Cy4r zJx3eGa*eM67LM6deLqLf=gePm>wlr=j7-Ye&w?-;$p1tDFO#k4tQ8 z`;IPFvH#h+3dvn(&CBbG_VcD~ccuNTNczLrf;m1buIC7A!|MeRA;(q}TC0>9tl^rH!9{85TH-Wb$z6bnB;zP#LxjPG7k@!6DEs6Jlf0XzDcwgdA zfDa^IL=rxe&cQ|CHHmw`eTn}L{D;J!0{<`Z(@1EElbV!%g4yL-f_X_lC*zCgn@0^^ zGiIW%lk}${vu%iynA1{}pD=tLeoFP`7YqF6Ec4(<81hi^2B}wpE2tc*f`rbX<&wTf z1)Ovx`o;Y{_jdJmg|fF*om~A~y}Hy`QX3t9cGbGw?HMM(g>vD0Cig{@Tbsd%OOq%yiU@qC6-`(BiQ91Wm&RndD|KG(PDcGYQCVsi}+vSP5 ue>R`ZvZuG*mm&g=_l5H}9N;a-Q+P7K6a(HD&L!s+i3JWL%sC!Oa{K~wRz+d} delta 179 zcmaDOJcW%T!q2Ikl~IIwBF7x593}>a^V}cy2rwW3Bj^8r6Bs5Q)8b-=3VJY1e#D~8 z0^~7HHe{7%aW6`&oE*R^5eL-GzzD=3g&;Oai3AYCfCiA^0^ GetAbilities(this TransformationEnum trans) _ => new List { "Unknown abilities" } }; } - + + public static bool HasUltimateAttack(this TransformationEnum te) { + switch (te) { + case TransformationEnum.BuzzShock: + return true; + case TransformationEnum.ChromaStone: + return true; + case TransformationEnum.DiamondHead: + return true; + case TransformationEnum.FourArms: + return true; + case TransformationEnum.GhostFreak: + return true; + case TransformationEnum.HeatBlast: + return true; + case TransformationEnum.RipJaws: + return true; + case TransformationEnum.StinkFly: + return true; + case TransformationEnum.WildVine: + return true; + case TransformationEnum.XLR8: + return false; + case TransformationEnum.EyeGuy: + return true; + case TransformationEnum.BigChill: + return false; + default: return true; + } + } + + public static bool HasUltimateAbility(this TransformationEnum te) { + return !HasUltimateAttack(te); + } } } diff --git a/NpcEffects.cs b/NpcEffects.cs index d03a718..4fa09c4 100644 --- a/NpcEffects.cs +++ b/NpcEffects.cs @@ -28,9 +28,15 @@ public override bool PreAI(NPC npc) { } public override void AI(NPC npc) { + var omp = Main.LocalPlayer.GetModPlayer(); + if (IsPossessed(npc)) { npc.velocity *= 0.68f; } + + if (omp.currTransformation == TransformationEnum.BigChill && omp.UltimateAbilityEnabled) { + npc.AddBuff(BuffID.Frozen, 120); + } } public override void DrawEffects(NPC npc, ref Color drawColor) { diff --git a/OmnitrixPlayer.cs b/OmnitrixPlayer.cs index 977f132..f22ab4b 100644 --- a/OmnitrixPlayer.cs +++ b/OmnitrixPlayer.cs @@ -365,14 +365,10 @@ public override void PostUpdate() { if (KeybindSystem.UltimateAbility.JustPressed && !Player.HasBuff(ModContent.BuffType()) && - !Player.HasBuff(ModContent.BuffType())) { - Player.AddBuff(ModContent.BuffType(), 10 * 60); - tranUsedAbility = currTransformation; - } - - if (UltimateAbilityEnabled && Main.netMode != NetmodeID.Server) { - Filters.Scene.Activate("Ben10Mod:Grayscale"); - Filters.Scene["Ben10Mod:Grayscale"].GetShader().Shader.Parameters["strength"]?.SetValue(1f); + !Player.HasBuff(ModContent.BuffType()) && omnitrixEnergy >= 50) { + Player.AddBuff(ModContent.BuffType(), 4 * 60); + tranUsedAbility = currTransformation; + omnitrixEnergy -= 50; } abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); @@ -538,6 +534,13 @@ public override void PostUpdate() { Player.AddBuff(ModContent.BuffType(), 15 * 60); tranUsedAbility = currTransformation; } + + if (KeybindSystem.UltimateAbility.JustPressed && + !Player.HasBuff(ModContent.BuffType()) && + !Player.HasBuff(ModContent.BuffType())) { + Player.AddBuff(ModContent.BuffType(), 10 * 60); + tranUsedAbility = currTransformation; + } } if (inPossessionMode) { @@ -626,13 +629,12 @@ public override void PostUpdate() { Player.AddBuff(ModContent.BuffType(), 30 * 60); break; } + case TransformationEnum.BigChill: { + Player.AddBuff(ModContent.BuffType(), 30 * 60); + break; + } } } - - if (!isTransformed || !UltimateAbilityEnabled) { - Filters.Scene["Ben10Mod:Grayscale"].GetShader().Shader.Parameters["strength"]?.SetValue(0f); - Filters.Scene.Deactivate("Ben10Mod:Grayscale"); - } } public override bool CanUseItem(Item item) { @@ -779,7 +781,6 @@ public override void DrawEffects(PlayerDrawSet drawInfo, ref float r, ref float } public override void FrameEffects() { - var customSlot = ModContent.GetInstance(); if (omnitrixEquipped) { @@ -1087,13 +1088,35 @@ public override void PreUpdate() { } } - if (PrimaryAbilityEnabled && currTransformation == TransformationEnum.GhostFreak) { + if (PrimaryAbilityEnabled && currTransformation is TransformationEnum.GhostFreak or TransformationEnum.BigChill) { Player.gravity = 0f; Player.noKnockback = true; Player.noFallDmg = true; Player.fallStart = (int)(Player.position.Y / 16f); } + + if (UltimateAbilityEnabled && Main.netMode != NetmodeID.Server && currTransformation == TransformationEnum.BigChill) { + if (!Filters.Scene["Ben10Mod:Bluescale"].IsActive()) { + Filters.Scene.Activate("Ben10Mod:Bluescale"); + Filters.Scene["Ben10Mod:Bluescale"].GetShader().Shader.Parameters["strength"]?.SetValue(1f); + } + } + else if (Filters.Scene["Ben10Mod:Bluescale"].IsActive()) { + Filters.Scene["Ben10Mod:Bluescale"].GetShader().Shader.Parameters["strength"]?.SetValue(0f); + Filters.Scene.Deactivate("Ben10Mod:Bluescale"); + } + + if (UltimateAbilityEnabled && Main.netMode != NetmodeID.Server && currTransformation == TransformationEnum.XLR8) { + if (!Filters.Scene["Ben10Mod:Bluescale"].IsActive()) { + Filters.Scene.Activate("Ben10Mod:Grayscale"); + Filters.Scene["Ben10Mod:Grayscale"].GetShader().Shader.Parameters["strength"]?.SetValue(1f); + } + } + else if (Filters.Scene["Ben10Mod:Grayscale"].IsActive()) { + Filters.Scene["Ben10Mod:Grayscale"].GetShader().Shader.Parameters["strength"]?.SetValue(0f); + Filters.Scene.Deactivate("Ben10Mod:Grayscale"); + } } public void AddTransformation(TransformationEnum transformation) { From a7e8784f1dea5fb8705ea1c0070ea81d888789b2 Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Mon, 9 Mar 2026 17:34:33 +1100 Subject: [PATCH 23/25] Added the ultimatrix and the evolution function --- Content/Buffs/Debuffs/EnemySlow.cs | 4 +- .../Accessories/AdvancedCircuitMatrix.cs | 1 + Content/Items/Accessories/Ultimatrix.cs | 213 ++++++++++++++++++ Content/Items/Accessories/Ultimatrix.png | Bin 0 -> 376 bytes Content/Items/Accessories/UltimatrixAlt.png | Bin 0 -> 369 bytes .../Accessories/UltimatrixAlt_HandsOn.png | Bin 0 -> 1712 bytes .../Items/Accessories/Ultimatrix_HandsOn.png | Bin 0 -> 1713 bytes .../Items/Accessories/Wings/BigChillWings.cs | 36 +++ .../Items/Accessories/Wings/BigChillWings.png | Bin 0 -> 362 bytes .../Accessories/Wings/BigChillWings_Wings.png | Bin 0 -> 3251 bytes .../Accessories/Wings/HeatBlastWings.png | Bin 356 -> 0 bytes .../Wings/UltimateBigChillWings.cs | 36 +++ .../Wings/UltimateBigChillWings.png | Bin 0 -> 362 bytes .../Wings/UltimateBigChillWings_Wings.png | Bin 0 -> 3163 bytes Content/Items/Weapons/PlumbersBadge.cs | 24 +- .../BigChillFrostBreathProjectile.cs | 2 + .../GhostFreakPossesionProjectile.cs | 2 +- Content/Projectiles/RipJawsBiteProjectile.cs | 41 ++++ Content/TransformationHandler.cs | 28 +++ Content/Transformations/BigChill/BigChill.cs | 24 +- .../BigChill/BigChillUltimate_Body.png | Bin 0 -> 3965 bytes .../BigChill/BigChillUltimate_Head.png | Bin 0 -> 3904 bytes .../BigChill/BigChillUltimate_Legs.png | Bin 0 -> 4255 bytes Effects/MyFilters.fx | 7 +- Effects/MyFilters.xnb | Bin 2540 -> 2496 bytes Enums/TranformationEnum.cs | 30 +++ Localization/en-US_Mods.Ben10Mod.hjson | 17 ++ NpcEffects.cs | 7 +- OmnitrixPlayer.cs | 110 +++++---- bossTrackerNPC.cs | 3 + build.txt | 2 +- 31 files changed, 521 insertions(+), 66 deletions(-) create mode 100644 Content/Items/Accessories/Ultimatrix.cs create mode 100644 Content/Items/Accessories/Ultimatrix.png create mode 100644 Content/Items/Accessories/UltimatrixAlt.png create mode 100644 Content/Items/Accessories/UltimatrixAlt_HandsOn.png create mode 100644 Content/Items/Accessories/Ultimatrix_HandsOn.png create mode 100644 Content/Items/Accessories/Wings/BigChillWings.cs create mode 100644 Content/Items/Accessories/Wings/BigChillWings.png create mode 100644 Content/Items/Accessories/Wings/BigChillWings_Wings.png delete mode 100644 Content/Items/Accessories/Wings/HeatBlastWings.png create mode 100644 Content/Items/Accessories/Wings/UltimateBigChillWings.cs create mode 100644 Content/Items/Accessories/Wings/UltimateBigChillWings.png create mode 100644 Content/Items/Accessories/Wings/UltimateBigChillWings_Wings.png create mode 100644 Content/Projectiles/RipJawsBiteProjectile.cs create mode 100644 Content/Transformations/BigChill/BigChillUltimate_Body.png create mode 100644 Content/Transformations/BigChill/BigChillUltimate_Head.png create mode 100644 Content/Transformations/BigChill/BigChillUltimate_Legs.png diff --git a/Content/Buffs/Debuffs/EnemySlow.cs b/Content/Buffs/Debuffs/EnemySlow.cs index 393bdb1..a46b236 100644 --- a/Content/Buffs/Debuffs/EnemySlow.cs +++ b/Content/Buffs/Debuffs/EnemySlow.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using Microsoft.Xna.Framework; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -12,7 +13,8 @@ namespace Ben10Mod.Content.Buffs.Debuffs public class EnemySlow : ModBuff { public override void Update(NPC npc, ref int buffIndex) { - npc.velocity *= 0.75f; + npc.velocity *= 0.25f; + npc.color = new Color(0.7f, 0.85f, 1.25f); } public override bool RightClick(int buffIndex) => false; diff --git a/Content/Items/Accessories/AdvancedCircuitMatrix.cs b/Content/Items/Accessories/AdvancedCircuitMatrix.cs index dfb3785..bf60e80 100644 --- a/Content/Items/Accessories/AdvancedCircuitMatrix.cs +++ b/Content/Items/Accessories/AdvancedCircuitMatrix.cs @@ -18,5 +18,6 @@ public override void SetDefaults() { public override void UpdateAccessory(Player player, bool hideVisual) { var omp = player.GetModPlayer(); omp.advancedCircuitMatrix = true; + // omp.omnitrixEnergyRegen += 500; } } \ No newline at end of file diff --git a/Content/Items/Accessories/Ultimatrix.cs b/Content/Items/Accessories/Ultimatrix.cs new file mode 100644 index 0000000..d32a0e7 --- /dev/null +++ b/Content/Items/Accessories/Ultimatrix.cs @@ -0,0 +1,213 @@ +using Ben10Mod.Keybinds; +using Microsoft.Xna.Framework; +using System; +using Terraria; +using Terraria.DataStructures; +using Terraria.ID; +using Terraria.ModLoader; +using Terraria.ModLoader.IO; +using Ben10Mod.Enums; +using System.Collections.Generic; +using Ben10Mod.Content.Interface; +using Microsoft.Xna.Framework.Graphics; +using Terraria.Audio; + +namespace Ben10Mod.Content.Items.Accessories +{ + public class Ultimatrix : Omnitrix { + + private Player player = null; + public int transformationNum = 0; + public TransformationEnum[] transformations = new TransformationEnum[5]; + + bool wasEquipedLastFrame = false; + + Texture2D dynamicTexture; + + public override string Texture => $"Ben10Mod/Content/Items/Accessories/{this.Name}"; + + public override void Load() { + if (Main.netMode == NetmodeID.Server) + return; + + EquipLoader.AddEquipTexture(Mod, $"{Texture}_{EquipType.HandsOn}", EquipType.HandsOn, name: "Ultimatrix"); + EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.HandsOn}", EquipType.HandsOn, name: "UltimatrixAlt"); + } + + public override ModItem Clone(Item item) { + Ultimatrix clone = (Ultimatrix)base.Clone(item); + clone.transformationNum = transformationNum; + clone.transformations = (TransformationEnum[])transformations?.Clone(); + return clone; + } + + public override void SaveData(TagCompound tag) { + tag["selectedAlien"] = transformationNum; + } + + public override void LoadData(TagCompound tag) + { + tag.TryGet("selectedAlien", out transformationNum); + } + + public override void OnCreated(ItemCreationContext context) + { + transformationNum = 0; + } + + public override void SetStaticDefaults() { + dynamicTexture = ModContent.Request("Ben10Mod/Content/Items/Accessories/Ultimatrix").Value; + } + + public override void SetDefaults() { + Item.maxStack = 1; + Item.width = 22; + Item.height = 28; + Item.rare = ItemRarityID.Master; + Item.accessory = true; + } + + public override void ModifyTooltips(List tooltips) { + tooltips.Add(new TooltipLine(Mod, "AlienSelection", + "Alien " + (transformationNum + 1) + ": " + transformations[transformationNum].ToString())); + } + + public override void UpdateAccessory(Player player, bool hideVisual) { + + if (player.whoAmI != Main.myPlayer) return; + + this.player = player; + var omp = player.GetModPlayer(); + omp.omnitrixEnergyMax += 700; + omp.omnitrixEquipped = true; + wasEquipedLastFrame = true; + + if (omp.isTransformed) + omp.omnitrixEnergyRegen -= 1; + + if (omp.omnitrixEnergy <= 0 && omp.isTransformed) { + TransformationHandler.Detransform(player, 120); + } + + if (omp.omnitrixEnergy > 0 && omp.isTransformed) { + TransformationHandler.Transform(player, omp.currTransformation, 2, false,false); + } + if (omp.isTransformed) + omp.omnitrixEnergyRegen -= 1; + else + omp.omnitrixEnergyRegen += 3; + + + transformations = omp.transformations; + + if (KeybindSystem.TransformationKeybind.JustPressed && !omp.isTransformed && !omp.onCooldown) { + TransformationHandler.Transform(player, transformations[transformationNum], 2); + } + else if (KeybindSystem.TransformationKeybind.JustPressed && omp.isTransformed && !omp.onCooldown) { + if (omp.currTransformation != transformations[transformationNum]) { + omp.omnitrixEnergy -= 50; + omp.omnitrixEnergy = Math.Max(omp.omnitrixEnergy, 0); + if (omp.omnitrixEnergy > 0) { + TransformationHandler.Detransform(player, 0, false, false); + TransformationHandler.Transform(player, transformations[transformationNum], 2); + } + else { + TransformationHandler.Detransform(player, 60); + } + } else if (omp.currTransformation.HasUltimateForm() && !omp.ultimateForm) { + omp.omnitrixEnergy -= 150; + omp.omnitrixEnergy = Math.Max(omp.omnitrixEnergy, 0); + if (omp.omnitrixEnergy > 0) { + TransformationHandler.GoUltimate(player, omp.currTransformation); + } + } else { + TransformationHandler.Detransform(player, 0, true, false); + } + } + else if (KeybindSystem.AlienOneKeybind.JustPressed) { + transformationNum = 0; + Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); + } + else if (KeybindSystem.AlienTwoKeybind.JustPressed) { + transformationNum = 1; + Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); + } + else if (KeybindSystem.AlienThreeKeybind.JustPressed) { + transformationNum = 2; + Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); + } + else if (KeybindSystem.AlienFourKeybind.JustPressed) { + transformationNum = 3; + Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); + } + else if (KeybindSystem.AlienFiveKeybind.JustPressed) { + transformationNum = 4; + Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); + } + else if (KeybindSystem.AlienNextKeybind.JustPressed) { + transformationNum++; + if (transformationNum > transformations.Length - 1) { + transformationNum = 0; + } + SoundEngine.PlaySound(SoundID.MenuTick, player.position); + Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); + } + else if (KeybindSystem.AlienPrevKeybind.JustPressed) { + transformationNum--; + if (transformationNum < 0) { + transformationNum = transformations.Length - 1; + } + SoundEngine.PlaySound(SoundID.MenuTick, player.position); + Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); + } + + base.UpdateAccessory(player, hideVisual); + } + + public override void UpdateInventory(Player player) + { + + var omp = player.GetModPlayer(); + + base.UpdateInventory(player); + + if (wasEquipedLastFrame) + { + wasEquipedLastFrame = false; + ModContent.GetInstance().HideMyUI(); + if (player.GetModPlayer().isTransformed) { + TransformationHandler.Detransform(player, omp.cooldownTime, true, true); + } else { + TransformationHandler.Detransform(player, omp.cooldownTime, false, false, false); + } + } + } + + public override bool CanEquipAccessory(Player player, int slot, bool modded) { + return modded; + } + + public override bool PreDrawInInventory(SpriteBatch spriteBatch, Vector2 position, Rectangle frame, Color drawColor, Color itemColor, Vector2 origin, float scale) { + + if (player == null) + return true; + + dynamicTexture = player.GetModPlayer().onCooldown ? ModContent.Request("Ben10Mod/Content/Items/Accessories/UltimatrixAlt").Value : ModContent.Request("Ben10Mod/Content/Items/Accessories/Ultimatrix").Value; + + spriteBatch.Draw(dynamicTexture, position, null, drawColor, 0f, origin, scale, SpriteEffects.None, 0f); + + return false; + } + + public override void AddRecipes() { + base.AddRecipes(); + + // Recipe recipeAlt = CreateRecipe() + // .AddIngredient(ModContent.ItemType()) + // .AddIngredient(ItemID.SoulofNight, 8) + // .AddIngredient(ItemID.SoulofLight, 8) + // .AddTile(TileID.MythrilAnvil).Register(); + + } + } +} \ No newline at end of file diff --git a/Content/Items/Accessories/Ultimatrix.png b/Content/Items/Accessories/Ultimatrix.png new file mode 100644 index 0000000000000000000000000000000000000000..5ae0503fead37a0bd797b4b70117bcb848fdaf01 GIT binary patch literal 376 zcmV-;0f+vHP)Px$GD$>1R9J=Wma$3$F&KcqN(bo!xVpPYhl2PLE*(0`jaBFa1Sh!%5S)J;9lCV! z5u_j@UEH1S4W!_34l#0xjV8wl;m9{#F3Ep)-~IU$$Ye4-MMP>5sk@4|*Hxgd8OBZ+ zE%?>S{&aW$cF7>-ImsFe{tDOB?Xd*Sn?Dp*JJekI#{SA3gKMfNik;&`^th_30Jwfp zK`&&CCTncyntH$az8vsXp8zg5wi#pU{^CTjpr&z}K!y!&VsXS=l9=^7g?>>IHLf8^MO$+2}*9Ft>)WR3k> z9dlP>Z|YdN{=p4gQ~lX1L-C!rOhxzQQg6;<(I;5%myfl{STjD7HI~U_QsWa> W7F#5#TkdB70000Px$D@jB_R9J=WmOX02Fc?5zN`{gHl&*m;ol5Q!asWe@QpjG>Dfj?|W(s@<2%d9| z(5XwIqq}w~+1$Zau|(8J#sOjUCd>M>o#}Q3_0(g8g&1h4fH@5&>FXjMzZ3_UVO?{r{M!)A-T~2B0&WPfYK3obYp^gJ?4T)Hs^h$+@xI{2PWrHLQ6k9LMc#`50Kh_DhD8B@3j>`GE_6qqfywp`^yQKgMcx72R;<)p|p4e8+Q1|(S-@42h&E~?yQ;a-`+Uox-l$i3+7zz!h}m~ zmm@=qKDx1V*>38@O6L0H2jqQchLK=i*@bn<*GLZ?8o5r8j~4sa(Z>ifyGWu{4(n7q z`Gx<8j+F$#N-_lNIjQ|f;3Wep(Zv$)X-&U8V+L@>I4}m9pG^gztF7r(0fUaHbQh=r~l$^-{;HRMEJdFj|y;J(m`-_*laV zB;fJYIXh{lDYkdeWI8J$+6fF`9d>q~Jx@cAJ|eRldFsoX4z>f)Y+O)&VL;-3YCCXk zfp>Y~c1+>NjO-{^EM*t!#|Nm{IqrTw|MTK?k1ud>9&eLSF?3}C6XS`BbjyltX;Ud+ zb?R9X#GW*8w>C>Mnlm21{6yzko9l+9JmpJ#m57B5O~!MunRkU%%VaCZzrSUxw=j-| zVmfNd5tX0*uwrE72OHn!j8=A*aZ7h7DMr!9Rz$w6-~_8K3rMR$)Ov+ZM|hJNN>I1G z*ZLfRV3Ak2Ryr2^;A(NWp`oj%*mSzoWZna-d!9FfQWRAbT{YX7tw6SHmh;{H5<-!B z4Vy~CJW~oVW!n9JeN!t;+13*y*(_#zwNA4714+$>0Mz^C<}3Ha(J%_JDZQ;arD1xm z=X_VnEiqn)C+eO?o%*fsxStcjZqB&0j>HQwFLm5364f3^9jl&-H85qII*ky5OOjX@ zi4V)22X@j!>Ux&r89yh4Vkpr2i}l?oy?W5@0i5n-%3H~+LU#Jk=Zj_bTWx(*SU8UO zLJ{coA0Aoa0l|4UOtu>0KWXI1KhG)zIj7Bm(8es|28bQf5KD+-eY3ao?)+W8-?H2H zOvRJx_36pq3RwGzZ|n`)P+4@1P+C9DEkRLvkC?yPkGBM^U7Q8PRmr=!++UvWMVpwj zN8WGwPSjlLBh@>2uv*>8T~Bm;oewtDZxelH5D(CPpKnm!FPfZPIEjqFpweqe0oYw2 zdxDw1xMkm(zdcT^*?h=;52ep)P1Kkg6@2H<<-bQZeuCb#B!(9iT@~!y3GIvsyS*ch F|0i>B^8)|? literal 0 HcmV?d00001 diff --git a/Content/Items/Accessories/Ultimatrix_HandsOn.png b/Content/Items/Accessories/Ultimatrix_HandsOn.png new file mode 100644 index 0000000000000000000000000000000000000000..15e0c705ab5626cb043ae7ade67e345023b77277 GIT binary patch literal 1713 zcmeAS@N?(olHy`uVBq!ia0y~yV9WrrA8@b%Nxi~9SAY~_age(c!@6@aFBurvvOQfK zLn`LHy}dCnx>TC&gZg}}D^n)6cuf_!X?2)4rCY#bC)2UA$7(w|@^pYq{=lhAU)@mj z+1V)8xv)rG#L4i+zwzo!DU3Kuvak;`j);P+L10T6#Y{d%8Mu(w*u8bx)(YIn{al+3PHR6}}K;`?`N2JHvyl?QL=l|CUBhvZ>iJ zU8S<@yX&MBtDEz5_pSFdj*>EQ(Bz#JIq8i|oQkKN?GFRbqF-n87iY~&-~HTk(#yxU znf;mm%koMsn8LPq;k0P})0=N^zWcNK>*vXzkBZ)Q?)mDUqk0m^iJTpUmbeE8`8dfxKCUkx?DZm4y>cW=^+eD^!` zd*`cIR#xq?F}^Bt&tE(J_i5dk(`?_S7T^2%=(@_u@cD05J@@_p_I#_!@ABH(CmEY( zZ(-vN@M_+tczXBO{qrsLW?g>yP+|JL7_6}kHU_oMRX zzaKr%ckchIPygp!KfW8}ncOcw&-v~Gd1m^rpyE&U`yJQaxGeYUd;QbTMVY*p3coxsM9-Byf8ToE z|D1Su4!@z8ff7^&D3+obNxe7C^8P+|;-Z*Km)e`nF&sOP)RMLf%$S!{JP?%wRkn~!#Ed3)v4$>adAFrDnkgDf4=1(Abt^Dir{Ute-ep}9! z&fR#%dYa{A6?>V#7GF4;F9F>gy1%;bW`~ps(9?`7RDc4UK*ulv^G*YshU(zpmS(?T zZ0I%H{p{n~t$u-C&1@RLG@1P!T!Mhh2g}>G{*z$Y%O?Mt`|P_*OhI94vZ3s|+#SzJ zHoJc-c^cK$SbG*(Rc_jmRNb-hRR%Ckn`9)sT{ijc+N0N}>h{e&+&%Suz7;sn^73RZ z)$~_CH&6fa;0Oc4QE^wQiXma~*>#mQ*=vKRfTA|@!hu_Rku$>i$tvID->ZB2&67Jn z`|HIt^Gt|m*WBI9UOq|X{JVV~lYHdw`%RkTH&18X4Y{N>R^S9D6|wteN_FFVdQ&MBb@07abC$p8QV literal 0 HcmV?d00001 diff --git a/Content/Items/Accessories/Wings/BigChillWings.cs b/Content/Items/Accessories/Wings/BigChillWings.cs new file mode 100644 index 0000000..a0e0546 --- /dev/null +++ b/Content/Items/Accessories/Wings/BigChillWings.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Terraria; +using Terraria.DataStructures; +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Items.Accessories.Wings { + [AutoloadEquip(EquipType.Wings)] + public class BigChillWings : ModItem { + + public override void SetStaticDefaults() { + ArmorIDs.Wing.Sets.Stats[Item.wingSlot] = new WingStats(100, 9f, 2.5f); + } + + public override void SetDefaults() { + Item.width = 24; + Item.height = 26; + Item.value = 0; + Item.rare = ItemRarityID.Green; + Item.accessory = true; + } + + public override void VerticalWingSpeeds(Player player, ref float ascentWhenFalling, ref float ascentWhenRising, + ref float maxCanAscendMultiplier, ref float maxAscentMultiplier, ref float constantAscend) { + ascentWhenFalling = 0.85f; // Falling glide speed + ascentWhenRising = 0.15f; // Rising speed + maxCanAscendMultiplier = 1f; + maxAscentMultiplier = 3f; + constantAscend = 0.135f; + } + } +} diff --git a/Content/Items/Accessories/Wings/BigChillWings.png b/Content/Items/Accessories/Wings/BigChillWings.png new file mode 100644 index 0000000000000000000000000000000000000000..79db8834e031b0813b108a9fd59c5ac673c1436d GIT binary patch literal 362 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 CKUw<# literal 0 HcmV?d00001 diff --git a/Content/Items/Accessories/Wings/HeatBlastWings.png b/Content/Items/Accessories/Wings/HeatBlastWings.png deleted file mode 100644 index 629419ed395aa0cb4f73e06aa589604303a80850..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 356 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 literal 0 HcmV?d00001 diff --git a/Content/Items/Weapons/PlumbersBadge.cs b/Content/Items/Weapons/PlumbersBadge.cs index 3ce339f..fa876c2 100644 --- a/Content/Items/Weapons/PlumbersBadge.cs +++ b/Content/Items/Weapons/PlumbersBadge.cs @@ -118,6 +118,7 @@ public override void HoldItem(Player player) { Item.ArmorPenetration = 0; Item.UseSound = null; Item.channel = false; + Item.noMelee = false; OmnitrixEnergyUse = 0; @@ -151,8 +152,9 @@ public override void HoldItem(Player player) { break; case TransformationEnum.RipJaws: - Item.useTime = Item.useAnimation = 28; + Item.useTime = Item.useAnimation = omp.altAttack ? 75 : 28; Item.shootSpeed = 6f; + Item.useStyle = omp.altAttack ? ItemUseStyleID.HiddenAnimation : ItemUseStyleID.Swing; break; case TransformationEnum.ChromaStone: @@ -273,7 +275,11 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, break; case TransformationEnum.RipJaws: - projType = ModContent.ProjectileType(); + projType = omp.altAttack ? ModContent.ProjectileType() : ModContent.ProjectileType(); + if (omp.altAttack) { + finalDamage = (int)(damage * 3f); + player.velocity += velocity * 2f; + } break; case TransformationEnum.ChromaStone: @@ -314,11 +320,15 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, break; case TransformationEnum.GhostFreak: - projType = omp.ultimateAttack - ? ModContent.ProjectileType() - : omp.altAttack - ? ProjectileID.CursedFlameFriendly - : ModContent.ProjectileType(); + if (omp.ultimateAttack) { + projType = ModContent.ProjectileType(); + } else if (omp.altAttack) { + projType = ModContent.ProjectileType(); + } + else { + projType = ModContent.ProjectileType(); + } + break; case TransformationEnum.WildVine: diff --git a/Content/Projectiles/BigChillFrostBreathProjectile.cs b/Content/Projectiles/BigChillFrostBreathProjectile.cs index 0db680f..fef4d11 100644 --- a/Content/Projectiles/BigChillFrostBreathProjectile.cs +++ b/Content/Projectiles/BigChillFrostBreathProjectile.cs @@ -1,3 +1,4 @@ +using Ben10Mod.Content.Buffs.Debuffs; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -42,5 +43,6 @@ public override void AI() { public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { target.AddBuff(BuffID.Frostburn2, 120); + target.AddBuff(ModContent.BuffType(), 120); } } \ No newline at end of file diff --git a/Content/Projectiles/GhostFreakPossesionProjectile.cs b/Content/Projectiles/GhostFreakPossesionProjectile.cs index b649d46..38b953d 100644 --- a/Content/Projectiles/GhostFreakPossesionProjectile.cs +++ b/Content/Projectiles/GhostFreakPossesionProjectile.cs @@ -32,7 +32,7 @@ public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { // Only start possession if not already in mode (prevent stacking) if (!omp.inPossessionMode) { omp.prePossessionPosition = player.position; // Save current pos - omp.possessedTarget = target; + omp.possessedTargetIndex = target.whoAmI; omp.possessionTimer = 360; omp.inPossessionMode = true; diff --git a/Content/Projectiles/RipJawsBiteProjectile.cs b/Content/Projectiles/RipJawsBiteProjectile.cs new file mode 100644 index 0000000..785cfce --- /dev/null +++ b/Content/Projectiles/RipJawsBiteProjectile.cs @@ -0,0 +1,41 @@ +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Threading.Tasks; +using Terraria; +using Terraria.DataStructures; +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Projectiles { + public class RipJawsBiteProjectile : ModProjectile { + public override string Texture => "Terraria/Images/Projectile_" + ProjectileID.None; + + public override void SetDefaults() { + Projectile.height = 25; + Projectile.width = 50; + Projectile.aiStyle = ProjAIStyleID.Arrow; + Projectile.friendly = true; + Projectile.hostile = false; + Projectile.timeLeft = 25; + Projectile.tileCollide = false; + AIType = ProjectileID.Bullet; + Projectile.DamageType = DamageClass.MeleeNoSpeed; + Projectile.penetrate = -1; + } + + public override void AI() { + var player = Main.player[Projectile.owner]; + Projectile.position = player.Center + (new Vector2(15f, 0) * player.direction); + } + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { + target.AddBuff(BuffID.Bleeding, 240); + int dustNum = Dust.NewDust(target.Center, target.height, target.width, DustID.GemDiamond, Scale: 10); + Main.dust[dustNum].noGravity = true; + } + } +} diff --git a/Content/TransformationHandler.cs b/Content/TransformationHandler.cs index 44a91ea..2b60a30 100644 --- a/Content/TransformationHandler.cs +++ b/Content/TransformationHandler.cs @@ -73,8 +73,36 @@ public static void Detransform(Player player, int seconds, bool showParticles = player.ClearBuff(ModContent.BuffType()); player.GetModPlayer().currTransformation = TransformationEnum.None; + player.GetModPlayer().ultimateForm = false; } + + public static void GoUltimate(Player player, TransformationEnum transformation, bool showParticles = true, bool playSound = true) { + if (transformation.GetTransformation() == -1) + return; + if (!transformation.HasUltimateForm() && !player.GetModPlayer().ultimateForm) + return; + if (showParticles) { + Random random = new Random(); + for (int i = 0; i < 25; i++) { + int dustNum = Dust.NewDust(player.position - new Vector2(1, 1), player.width + 1, player.height + 1, DustID.GreenTorch, random.Next(-4, 5), random.Next(-4, 5), 1, Color.White, 4); + Main.dust[dustNum].noGravity = true; + } + + CombatText.NewText( + new Rectangle((int)player.position.X, (int)player.position.Y, player.width, player.height), + new Color(0, 255, 0), + "Ultimate " + transformation.GetName() + "!", + dramatic: true, + dot: false + ); + } + if (playSound) { + SoundEngine.PlaySound(new SoundStyle("Ben10Mod/Content/Sounds/OmnitrixTransformation"), player.position); + } + + player.GetModPlayer().ultimateForm = true; + } public static void NextTransformation(Player player, ref TransformationEnum transformation) { diff --git a/Content/Transformations/BigChill/BigChill.cs b/Content/Transformations/BigChill/BigChill.cs index 4f2ff18..7595d53 100644 --- a/Content/Transformations/BigChill/BigChill.cs +++ b/Content/Transformations/BigChill/BigChill.cs @@ -20,11 +20,10 @@ public override void Load() { EquipLoader.AddEquipTexture(Mod, $"{Texture}_{EquipType.Head}", EquipType.Head, this, equipTexture: new XLR8Head()); EquipLoader.AddEquipTexture(Mod, $"{Texture}_{EquipType.Body}", EquipType.Body, this); EquipLoader.AddEquipTexture(Mod, $"{Texture}_{EquipType.Legs}", EquipType.Legs, this); - - //Add a separate set of equip textures by providing a custom name reference instead of an item reference - //EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.Head}", EquipType.Head, name: "BlockyAlt", equipTexture: new BlockyHead()); - //EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.Body}", EquipType.Body, name: "BlockyAlt"); - //EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.Legs}", EquipType.Legs, name: "BlockyAlt"); + + EquipLoader.AddEquipTexture(Mod, $"{Texture}Ultimate_{EquipType.Head}", EquipType.Head, name: "UltimateBigChill", equipTexture: new XLR8Head()); + EquipLoader.AddEquipTexture(Mod, $"{Texture}Ultimate_{EquipType.Body}", EquipType.Body, name: "UltimateBigChill"); + EquipLoader.AddEquipTexture(Mod, $"{Texture}Ultimate_{EquipType.Legs}", EquipType.Legs, name: "UltimateBigChill"); } // Called in SetStaticDefaults @@ -37,18 +36,19 @@ private void SetupDrawing() { int equipSlotBody = EquipLoader.GetEquipSlot(Mod, Name, EquipType.Body); int equipSlotLegs = EquipLoader.GetEquipSlot(Mod, Name, EquipType.Legs); - //int equipSlotHeadAlt = EquipLoader.GetEquipSlot(Mod, "BlockyAlt", EquipType.Head); - //int equipSlotBodyAlt = EquipLoader.GetEquipSlot(Mod, "BlockyAlt", EquipType.Body); - //int equipSlotLegsAlt = EquipLoader.GetEquipSlot(Mod, "BlockyAlt", EquipType.Legs); + int equipSlotHeadAlt = EquipLoader.GetEquipSlot(Mod, "UltimateBigChill", EquipType.Head); + int equipSlotBodyAlt = EquipLoader.GetEquipSlot(Mod, "UltimateBigChill", EquipType.Body); + int equipSlotLegsAlt = EquipLoader.GetEquipSlot(Mod, "UltimateBigChill", EquipType.Legs); ArmorIDs.Head.Sets.DrawHead[equipSlotHead] = false; - //ArmorIDs.Head.Sets.DrawHead[equipSlotHeadAlt] = false; ArmorIDs.Body.Sets.HidesTopSkin[equipSlotBody] = true; ArmorIDs.Body.Sets.HidesArms[equipSlotBody] = true; - //ArmorIDs.Body.Sets.HidesTopSkin[equipSlotBodyAlt] = true; - //ArmorIDs.Body.Sets.HidesArms[equipSlotBodyAlt] = true; ArmorIDs.Legs.Sets.HidesBottomSkin[equipSlotLegs] = true; - //ArmorIDs.Legs.Sets.HidesBottomSkin[equipSlotLegsAlt] = true; + + ArmorIDs.Head.Sets.DrawHead[equipSlotHeadAlt] = false; + ArmorIDs.Body.Sets.HidesTopSkin[equipSlotBodyAlt] = true; + ArmorIDs.Body.Sets.HidesArms[equipSlotBodyAlt] = true; + ArmorIDs.Legs.Sets.HidesBottomSkin[equipSlotLegsAlt] = true; } public override void SetStaticDefaults() { diff --git a/Content/Transformations/BigChill/BigChillUltimate_Body.png b/Content/Transformations/BigChill/BigChillUltimate_Body.png new file mode 100644 index 0000000000000000000000000000000000000000..bb021606be78f03c07971c860cec17b8f9dfbdec GIT binary patch literal 3965 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 ReXuy!XsPSpsaAau@h?7&HcS8j literal 0 HcmV?d00001 diff --git a/Content/Transformations/BigChill/BigChillUltimate_Head.png b/Content/Transformations/BigChill/BigChillUltimate_Head.png new file mode 100644 index 0000000000000000000000000000000000000000..2d684a61dc9dedd97bc9fab848bd666583e7e326 GIT binary patch literal 3904 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 NH!-xlQlsw@{Vy3f1Oos7 literal 0 HcmV?d00001 diff --git a/Effects/MyFilters.fx b/Effects/MyFilters.fx index 0998636..dea15f3 100644 --- a/Effects/MyFilters.fx +++ b/Effects/MyFilters.fx @@ -33,10 +33,13 @@ float4 Grayscale(float2 uv : TEXCOORD0) : COLOR0 return color; } -float4 FrostyScreen(float4 sampleColor: COLOR0, float2 uv : TEXCOORD0) : COLOR0 +float4 FrostyScreen(float4 sampleColor : COLOR0, float2 uv : TEXCOORD0) : COLOR0 { float4 color = tex2D(uImage0, uv); - float luminosity = (color.r + color.g + color.b) / 3; + + float3 blueTint = float3(0.7, 0.85, 1.25); + color.rgb *= blueTint; + return color * sampleColor; } diff --git a/Effects/MyFilters.xnb b/Effects/MyFilters.xnb index 93e00ec2007d74eae625b5115de12228462a5adf..ae4c2b41baee7d712653e6be9141255dcdbb0152 100644 GIT binary patch delta 130 zcmaDOd_b5z!q2IkmGQtt_PLA_8lfq`+dA*=Le6;=@@ zMuo|i?9+LSjg9SR&5X2XU|3*3`3}200|PSyL>wds Sg{6?5P!q2IkmGR9)_PLBM8xfq`+dA*=Le6;=_Z z$psu-lbzW6co=|S^{Q2NAbRp0c8f$N1_owE295>>hEO18Xn^n;f$UWcj12!9Sb_2k w3@ku414wKFkOnCMvKbbD*o+L^K=u=`I3oiKkR7@JqK6+O-oUuolcSsw0BEoxn*aa+ diff --git a/Enums/TranformationEnum.cs b/Enums/TranformationEnum.cs index 3057383..d86da8a 100644 --- a/Enums/TranformationEnum.cs +++ b/Enums/TranformationEnum.cs @@ -195,5 +195,35 @@ public static bool HasUltimateAttack(this TransformationEnum te) { public static bool HasUltimateAbility(this TransformationEnum te) { return !HasUltimateAttack(te); } + + public static bool HasUltimateForm(this TransformationEnum te) { + switch (te) { + case TransformationEnum.BuzzShock: + return false; + case TransformationEnum.ChromaStone: + return false; + case TransformationEnum.DiamondHead: + return false; + case TransformationEnum.FourArms: + return false; + case TransformationEnum.GhostFreak: + return false; + case TransformationEnum.HeatBlast: + return false; + case TransformationEnum.RipJaws: + return false; + case TransformationEnum.StinkFly: + return false; + case TransformationEnum.WildVine: + return false; + case TransformationEnum.XLR8: + return false; + case TransformationEnum.EyeGuy: + return false; + case TransformationEnum.BigChill: + return true; + default: return true; + } + } } } diff --git a/Localization/en-US_Mods.Ben10Mod.hjson b/Localization/en-US_Mods.Ben10Mod.hjson index 36a11bc..3a5c240 100644 --- a/Localization/en-US_Mods.Ben10Mod.hjson +++ b/Localization/en-US_Mods.Ben10Mod.hjson @@ -255,6 +255,21 @@ Items: { Tooltip: "" DisplayName: Big Chill } + + BigChillWings: { + DisplayName: Big Chill Wings + Tooltip: "" + } + + Ultimatrix: { + Tooltip: "" + DisplayName: Ultimatrix + } + + UltimateBigChillWings: { + Tooltip: "" + DisplayName: Ultimate Big Chill Wings + } } Keybinds: { @@ -416,6 +431,8 @@ Projectiles: { BuzzShockUltimateProjectile.DisplayName: Buzz Shock Ultimate Projectile BigChillProjectile.DisplayName: Big Chill Projectile BigChillFrostBreathProjectile.DisplayName: Big Chill Frost Breath Projectile + RipJawsBiteProjectile.DisplayName: Rip Jaws Bite Projectile + GhostFreakShadowProjectile.DisplayName: Ghost Freak Shadow Projectile } Tiles: { diff --git a/NpcEffects.cs b/NpcEffects.cs index 4fa09c4..ed4c242 100644 --- a/NpcEffects.cs +++ b/NpcEffects.cs @@ -1,4 +1,5 @@ using Ben10Mod.Content.Buffs.Abilities; +using Ben10Mod.Content.Buffs.Debuffs; using Ben10Mod.Enums; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; @@ -14,7 +15,7 @@ public class NpcEffects : GlobalNPC { public bool IsPossessed(NPC npc) { foreach (Player p in Main.ActivePlayers) { var omp = p.GetModPlayer(); - if (omp.inPossessionMode && omp.possessedTarget.whoAmI == npc.whoAmI) return true; + if (omp.inPossessionMode && omp.possessedTargetIndex == npc.whoAmI) return true; } return false; } @@ -34,8 +35,8 @@ public override void AI(NPC npc) { npc.velocity *= 0.68f; } - if (omp.currTransformation == TransformationEnum.BigChill && omp.UltimateAbilityEnabled) { - npc.AddBuff(BuffID.Frozen, 120); + if (omp.currTransformation == TransformationEnum.BigChill && omp.UltimateAbilityEnabled && npc.active && !npc.friendly) { + npc.AddBuff(ModContent.BuffType(), 120); } } diff --git a/OmnitrixPlayer.cs b/OmnitrixPlayer.cs index f22ab4b..efb91dc 100644 --- a/OmnitrixPlayer.cs +++ b/OmnitrixPlayer.cs @@ -47,6 +47,7 @@ public class OmnitrixPlayer : ModPlayer { public bool onCooldown = false; public bool altAttack = false; public bool ultimateAttack = false; + public bool ultimateForm = false; public int cooldownTime = 120; public int transformationTime = 300; @@ -91,7 +92,7 @@ public class OmnitrixPlayer : ModPlayer { public bool inPossessionMode = false; public Vector2 prePossessionPosition = Vector2.Zero; - public NPC possessedTarget = null; + public int possessedTargetIndex = -1; public int possessionTimer = 0; private const int PossessionDuration = 360; @@ -207,7 +208,7 @@ public override void PostUpdateBuffs() { advancedCircuitMatrixEquippedWhileTransformed = false; } - wasTransformed = false; + wasTransformed = isTransformed; } if (omnitrixUpdating != omnitrixWasUpdating) { @@ -284,13 +285,22 @@ public override void PostUpdateBuffs() { // Ripjaws Transformation if (currTransformation == TransformationEnum.RipJaws) { - if (Player.wet) { + if (Player.wet || Main.raining) { Player.merman = true; Player.breathCD = 0; Player.breath = Player.breathMax; Player.GetDamage() *= 2.0f; + Lighting.AddLight(Player.Center, new Vector3(1, 1, 1)); + Player.maxFallSpeed *= 2; + Player.moveSpeed *= 4; } - + else { + Player.breath -= 4; + if (Player.breath <= 1) { + Player.lifeRegen -= 60; + } + } + Player.accFlipper = true; } @@ -541,20 +551,27 @@ public override void PostUpdate() { Player.AddBuff(ModContent.BuffType(), 10 * 60); tranUsedAbility = currTransformation; } + + abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } if (inPossessionMode) { - if (possessedTarget == null || !possessedTarget.active || - currTransformation != TransformationEnum.GhostFreak) { + if (possessedTargetIndex < 0 || possessedTargetIndex >= Main.maxNPCs) { EndPossession(); return; } - + + NPC npc = Main.npc[possessedTargetIndex]; + if (npc == null || !npc.active || npc.whoAmI != possessedTargetIndex) { + EndPossession(); + return; + } + Player.immuneNoBlink = true; Player.immuneTime = 999; - Player.Center = possessedTarget.Center; + Player.Center = npc.Center; - Player.velocity = possessedTarget.velocity * 0.8f; + Player.velocity = npc.velocity * 0.8f; Player.controlJump = false; Player.controlDown = false; @@ -566,16 +583,15 @@ public override void PostUpdate() { Player.controlHook = false; possessionTimer--; - if (possessionTimer <= 0) { - possessedTarget.SimpleStrikeNPC(Player.HeldItem.damage * 2, Player.direction, false, 0, + npc.SimpleStrikeNPC(Player.HeldItem.damage * 2, Player.direction, false, 0, DamageClass.Magic); EndPossession(); } } if (isTransformed) { - if (KeybindSystem.UltimateAbility.JustPressed) + if (KeybindSystem.UltimateAbility.JustPressed && currTransformation.HasUltimateAttack()) if (!Player.HasBuff() && !Player.HasBuff()) { for (int i = 0; i < 50; i++) { Dust d = Dust.NewDustPerfect(Player.Center + Main.rand.NextVector2Circular(20f, 20f), @@ -661,13 +677,13 @@ public override void OnHurt(Player.HurtInfo info) { } public override void OnHitAnything(float x, float y, Entity victim) { - if (!Main.npc[victim.whoAmI].HasBuff(BuffID.Frostburn2) && snowflake && - currTransformation == TransformationEnum.HeatBlast) { - Main.npc[victim.whoAmI].AddBuff(BuffID.Frostburn2, 10 * 60); - } - else if (!Main.npc[victim.whoAmI].HasBuff(BuffID.OnFire3) && !snowflake && - currTransformation == TransformationEnum.HeatBlast) { - Main.npc[victim.whoAmI].AddBuff(BuffID.OnFire3, 10 * 60); + if (victim is NPC npc && currTransformation == TransformationEnum.HeatBlast) { + if (!npc.HasBuff(BuffID.Frostburn2) && snowflake) { + npc.AddBuff(BuffID.Frostburn2, 10 * 60); + } + else if (!npc.HasBuff(BuffID.OnFire3) && !snowflake) { + npc.AddBuff(BuffID.OnFire3, 10 * 60); + } } } @@ -941,9 +957,12 @@ public override void FrameEffects() { if (currTransformation == TransformationEnum.BigChill) { var costume = ModContent.GetInstance(); - Player.head = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Head); - Player.body = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Body); - Player.legs = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Legs); + Player.head = ultimateForm ? EquipLoader.GetEquipSlot(Mod, "Ultimate" + costume.Name, EquipType.Head) : EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Head); + Player.body = ultimateForm ? EquipLoader.GetEquipSlot(Mod, "Ultimate" + costume.Name, EquipType.Body) : EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Body); + Player.legs = ultimateForm ? EquipLoader.GetEquipSlot(Mod, "Ultimate" + costume.Name, EquipType.Legs) : EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Legs); + Player.wings = ultimateForm ? EquipLoader.GetEquipSlot(Mod, "Ultimate" + ModContent.GetInstance().Name, + EquipType.Wings) : EquipLoader.GetEquipSlot(Mod, ModContent.GetInstance().Name, + EquipType.Wings); } } } @@ -1042,8 +1061,8 @@ public override void OnEnterWorld() { private void EndPossession() { if (!inPossessionMode) return; - inPossessionMode = false; - possessedTarget = null; + inPossessionMode = false; + possessedTargetIndex = -1; Player.position = prePossessionPosition; @@ -1074,41 +1093,54 @@ public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { } - if (isTransformed && !ultimateAttack && omnitrixEnergyRegen == 0) + if (isTransformed && !ultimateAttack && omnitrixEnergyRegen == 0 && !UltimateAbilityEnabled && !ultimateAttack) omnitrixEnergy += Math.Max(hit.Damage / 25, 1); } public override void PreUpdate() { if (inPossessionMode) { + if (possessedTargetIndex < 0 || possessedTargetIndex >= Main.maxNPCs) { + EndPossession(); + return; + } + + NPC npc = Main.npc[possessedTargetIndex]; + if (npc == null || !npc.active || npc.whoAmI != possessedTargetIndex || npc.life <= 0) { + EndPossession(); + return; + } + if (Main.GameUpdateCount % 60 == 0) { - int dotDamage = 35; - possessedTarget.life -= dotDamage; - if (possessedTarget.life < 1) possessedTarget.life = 1; - CombatText.NewText(possessedTarget.Hitbox, new Color(180, 80, 255), dotDamage, dramatic: true); + if (npc.active && npc.whoAmI == possessedTargetIndex && npc.life > 0) { + int dotDamage = 35; + npc.life -= dotDamage; + if (npc.life < 1) npc.life = 1; + CombatText.NewText(npc.Hitbox, new Color(180, 80, 255), dotDamage, dramatic: true); + } } } - if (PrimaryAbilityEnabled && currTransformation is TransformationEnum.GhostFreak or TransformationEnum.BigChill) { + if (PrimaryAbilityEnabled && + currTransformation is TransformationEnum.GhostFreak or TransformationEnum.BigChill) { Player.gravity = 0f; Player.noKnockback = true; Player.noFallDmg = true; - - Player.fallStart = (int)(Player.position.Y / 16f); + Player.fallStart = (int)(Player.position.Y / 16f); } - - if (UltimateAbilityEnabled && Main.netMode != NetmodeID.Server && currTransformation == TransformationEnum.BigChill) { + + if (UltimateAbilityEnabled && Main.netMode != NetmodeID.Server && + currTransformation == TransformationEnum.BigChill) { if (!Filters.Scene["Ben10Mod:Bluescale"].IsActive()) { Filters.Scene.Activate("Ben10Mod:Bluescale"); - Filters.Scene["Ben10Mod:Bluescale"].GetShader().Shader.Parameters["strength"]?.SetValue(1f); } } else if (Filters.Scene["Ben10Mod:Bluescale"].IsActive()) { - Filters.Scene["Ben10Mod:Bluescale"].GetShader().Shader.Parameters["strength"]?.SetValue(0f); Filters.Scene.Deactivate("Ben10Mod:Bluescale"); } - - if (UltimateAbilityEnabled && Main.netMode != NetmodeID.Server && currTransformation == TransformationEnum.XLR8) { - if (!Filters.Scene["Ben10Mod:Bluescale"].IsActive()) { + + if (UltimateAbilityEnabled && Main.netMode != NetmodeID.Server && + currTransformation == TransformationEnum.XLR8) { + if (!Filters.Scene["Ben10Mod:Grayscale"].IsActive()) { Filters.Scene.Activate("Ben10Mod:Grayscale"); Filters.Scene["Ben10Mod:Grayscale"].GetShader().Shader.Parameters["strength"]?.SetValue(1f); } diff --git a/bossTrackerNPC.cs b/bossTrackerNPC.cs index 9c412a5..1de7909 100644 --- a/bossTrackerNPC.cs +++ b/bossTrackerNPC.cs @@ -163,6 +163,9 @@ public override void OnKill(NPC npc) { case NPCID.Spazmatism: player.GetModPlayer().AddTransformation(TransformationEnum.EyeGuy); break; + case NPCID.IceQueen: + player.GetModPlayer().AddTransformation(TransformationEnum.BigChill); + break; default: break; } diff --git a/build.txt b/build.txt index 8aac54c..c768228 100644 --- a/build.txt +++ b/build.txt @@ -1,6 +1,6 @@ displayName = Terraria 10 (Ben 10 mod) author = DestroyerMob -version = 0.070 +version = 0.071 buildIgnore = .vs\*, Properties\*, *.csproj, *.user, obj\*, bin\*, *.config, .git\*, .github\*, LICENSE, README.md, .editorconfig, .gitignore, .gitattributes, Effects\Compiler\* hideCode = false hideResources = true From a86a33105cccdbb644ce0572787ce7bb4646f727 Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Mon, 9 Mar 2026 20:33:07 +1100 Subject: [PATCH 24/25] Reconfigured to make things easier --- Content/Items/Weapons/PlumbersBadge.cs | 4 - Enums/TranformationEnum.cs | 195 ++++++++++++++++++++++++- OmnitrixPlayer.cs | 189 ++++++++++-------------- icon_workshop.png | Bin 2992 -> 2991 bytes 4 files changed, 269 insertions(+), 119 deletions(-) diff --git a/Content/Items/Weapons/PlumbersBadge.cs b/Content/Items/Weapons/PlumbersBadge.cs index fa876c2..e9741c4 100644 --- a/Content/Items/Weapons/PlumbersBadge.cs +++ b/Content/Items/Weapons/PlumbersBadge.cs @@ -104,8 +104,6 @@ public override bool CanUseItem(Player player) { !(omp.omnitrixEnergy < OmnitrixEnergyUse && omp.ultimateAttack); } - public override bool AltFunctionUse(Player player) => true; - public override void HoldItem(Player player) { var omp = player.GetModPlayer(); @@ -207,8 +205,6 @@ public override void HoldItem(Player player) { } public override bool? UseItem(Player player) { - if (player.altFunctionUse == 2) - player.GetModPlayer().altAttack = !player.GetModPlayer().altAttack; var omp = player.GetModPlayer(); if (omp.omnitrixEnergy >= OmnitrixEnergyUse) { omp.omnitrixEnergy -= OmnitrixEnergyUse; diff --git a/Enums/TranformationEnum.cs b/Enums/TranformationEnum.cs index d86da8a..7d32639 100644 --- a/Enums/TranformationEnum.cs +++ b/Enums/TranformationEnum.cs @@ -8,6 +8,7 @@ using System.Reflection; using System.Text; using System.Threading.Tasks; +using Terraria; using Terraria.ModLoader; namespace Ben10Mod.Enums @@ -188,7 +189,7 @@ public static bool HasUltimateAttack(this TransformationEnum te) { return true; case TransformationEnum.BigChill: return false; - default: return true; + default: return false; } } @@ -222,7 +223,197 @@ public static bool HasUltimateForm(this TransformationEnum te) { return false; case TransformationEnum.BigChill: return true; - default: return true; + default: return false; + } + } + + public static int GetUltimateAbilityCost(this TransformationEnum te, OmnitrixPlayer omp) { // Determines the cost for both the ultimate ability and the ultimate attack, will be used to check if the player can use ultimate abilities + switch (te) { + case TransformationEnum.BuzzShock: + return 50; + case TransformationEnum.ChromaStone: + return 50; + case TransformationEnum.DiamondHead: + return 50; + case TransformationEnum.FourArms: + return 50; + case TransformationEnum.GhostFreak: + return 50; + case TransformationEnum.HeatBlast: + return 50; + case TransformationEnum.RipJaws: + return 50; + case TransformationEnum.StinkFly: + return 50; + case TransformationEnum.WildVine: + return 50; + case TransformationEnum.XLR8: + return 50; + case TransformationEnum.EyeGuy: + return 50; + case TransformationEnum.BigChill when omp.ultimateForm: + return 150; + case TransformationEnum.BigChill: + return 50; + default: return 50; + } + } + + public static int GetUltimateAbilityDuration(this TransformationEnum te, OmnitrixPlayer omp) { // Determines the cost for both the ultimate ability and the ultimate attack, will be used to check if the player can use ultimate abilities + switch (te) { + case TransformationEnum.BuzzShock: + return 30 * 60; + case TransformationEnum.ChromaStone: + return 30 * 60; + case TransformationEnum.DiamondHead: + return 30 * 60; + case TransformationEnum.FourArms: + return 30 * 60; + case TransformationEnum.GhostFreak: + return 30 * 60; + case TransformationEnum.HeatBlast: + return 30 * 60; + case TransformationEnum.RipJaws: + return 30 * 60; + case TransformationEnum.StinkFly: + return 30 * 60; + case TransformationEnum.WildVine: + return 30 * 60; + case TransformationEnum.XLR8: + return 30 * 60; + case TransformationEnum.EyeGuy: + return 30 * 60; + case TransformationEnum.BigChill when omp.ultimateForm: + return 60 * 60; + case TransformationEnum.BigChill: + return 30 * 60; + default: return 30 * 60; + } + } + + public static int GetUltimateCooldownDuration(this TransformationEnum te, OmnitrixPlayer omp) { + switch (te) { + case TransformationEnum.BuzzShock: + return 60 * 60; + case TransformationEnum.ChromaStone: + return 60 * 60; + case TransformationEnum.DiamondHead: + return 60 * 60; + case TransformationEnum.FourArms: + return 60 * 60; + case TransformationEnum.GhostFreak: + return 60 * 60; + case TransformationEnum.HeatBlast: + return 60 * 60; + case TransformationEnum.RipJaws: + return 60 * 60; + case TransformationEnum.StinkFly: + return 60 * 60; + case TransformationEnum.WildVine: + return 60 * 60; + case TransformationEnum.XLR8: + return 60 * 60; + case TransformationEnum.EyeGuy: + return 60 * 60; + case TransformationEnum.BigChill when omp.ultimateForm: + return 120 * 60; + case TransformationEnum.BigChill: + return 60 * 60; + default: return 60 * 60; + } + } + + public static bool HasPrimaryAbility(this TransformationEnum te) { + switch (te) { + case TransformationEnum.BuzzShock: + return true; + case TransformationEnum.ChromaStone: + return true; + case TransformationEnum.DiamondHead: + return true; + case TransformationEnum.FourArms: + return false; + case TransformationEnum.GhostFreak: + return false; + case TransformationEnum.HeatBlast: + return true; + case TransformationEnum.RipJaws: + return false; + case TransformationEnum.StinkFly: + return false; + case TransformationEnum.WildVine: + return false; + case TransformationEnum.XLR8: + return true; + case TransformationEnum.EyeGuy: + return false; + case TransformationEnum.BigChill: + return true; + default: return false; + } + } + + public static int GetPrimaryAbilityDuration(this TransformationEnum te, OmnitrixPlayer omp) { + switch (te) { + case TransformationEnum.BuzzShock: + return 1; + case TransformationEnum.ChromaStone: + return 30 * 60; + case TransformationEnum.DiamondHead: + return 30 * 60; + case TransformationEnum.FourArms: + return 30 * 60; + case TransformationEnum.GhostFreak: + return 30 * 60; + case TransformationEnum.HeatBlast: + return 30 * 60; + case TransformationEnum.RipJaws: + return 30 * 60; + case TransformationEnum.StinkFly: + return 30 * 60; + case TransformationEnum.WildVine: + return 30 * 60; + case TransformationEnum.XLR8: + return 30 * 60; + case TransformationEnum.EyeGuy: + return 30 * 60; + case TransformationEnum.BigChill when omp.ultimateForm: + return 60 * 60; + case TransformationEnum.BigChill: + return 30 * 60; + default: return 30 * 60; + } + } + + public static int GetPrimaryCooldownDuration(this TransformationEnum te, OmnitrixPlayer omp) { + switch (te) { + case TransformationEnum.BuzzShock: + return 60 * 60; + case TransformationEnum.ChromaStone: + return 60 * 60; + case TransformationEnum.DiamondHead: + return 60 * 60; + case TransformationEnum.FourArms: + return 60 * 60; + case TransformationEnum.GhostFreak: + return 60 * 60; + case TransformationEnum.HeatBlast: + return 60 * 60; + case TransformationEnum.RipJaws: + return 60 * 60; + case TransformationEnum.StinkFly: + return 60 * 60; + case TransformationEnum.WildVine: + return 60 * 60; + case TransformationEnum.XLR8: + return 60 * 60; + case TransformationEnum.EyeGuy: + return 60 * 60; + case TransformationEnum.BigChill when omp.ultimateForm: + return 120 * 60; + case TransformationEnum.BigChill: + return 60 * 60; + default: return 60 * 60; } } } diff --git a/OmnitrixPlayer.cs b/OmnitrixPlayer.cs index efb91dc..0ecb28d 100644 --- a/OmnitrixPlayer.cs +++ b/OmnitrixPlayer.cs @@ -29,6 +29,7 @@ using Terraria.Audio; using Ben10Mod.Content.Items.Accessories.Wings; using Ben10Mod.Content.Items.Vanity.ShaderDyes; +using Ben10Mod.Content.Items.Weapons; using Ben10Mod.Content.Transformations.BigChill; using Ben10Mod.Content.Transformations.EyeGuy; using Terraria.Graphics.Effects; @@ -360,27 +361,15 @@ public override void PostUpdate() { } } + if (Main.mouseRight && Main.mouseRightRelease && Player.HeldItem.ModItem is PlumbersBadge) { + altAttack = !altAttack; + } + // XLR8 Transformation if (currTransformation == TransformationEnum.XLR8) { - - if (KeybindSystem.PrimaryAbility.JustPressed && - !Player.HasBuff(ModContent.BuffType()) && - !Player.HasBuff(ModContent.BuffType())) { - Player.AddBuff(ModContent.BuffType(), 10 * 60); - tranUsedAbility = currTransformation; - } - - if (KeybindSystem.UltimateAbility.JustPressed && - !Player.HasBuff(ModContent.BuffType()) && - !Player.HasBuff(ModContent.BuffType()) && omnitrixEnergy >= 50) { - Player.AddBuff(ModContent.BuffType(), 4 * 60); - tranUsedAbility = currTransformation; - omnitrixEnergy -= 50; - } - abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } @@ -392,13 +381,6 @@ public override void PostUpdate() { snowflake ? DustID.IceTorch : DustID.Flare, 0, rand.Next(-1, 2), rand.Next(-1, 2), Color.White, rand.Next(3)); Main.dust[dustNum].noGravity = true; - if (KeybindSystem.PrimaryAbility.JustPressed) { - if (!Player.HasBuff(ModContent.BuffType()) && - !Player.HasBuff(ModContent.BuffType())) { - Player.AddBuff(ModContent.BuffType(), 60 * 60); - tranUsedAbility = currTransformation; - } - } if (PrimaryAbilityEnabled) { Vector2[] points = GenerateCirclePoints(250, 7 * (16)); @@ -429,15 +411,6 @@ public override void PostUpdate() { // Diamondhead Transformation if (currTransformation == TransformationEnum.DiamondHead) { - if (KeybindSystem.PrimaryAbility.JustPressed) { - if (!Player.HasBuff(ModContent.BuffType()) && - !Player.HasBuff(ModContent.BuffType())) { - Player.AddBuff(ModContent.BuffType(), 60 * 60); - tranUsedAbility = currTransformation; - Player.velocity = Vector2.Zero; - } - } - if (PrimaryAbilityEnabled) { Player.velocity = new Vector2(float.Clamp(Player.velocity.X, -0.5f, 0.5f), Math.Max(0, Player.velocity.Y)); @@ -456,14 +429,6 @@ public override void PostUpdate() { // Chromastone Transformation if (currTransformation == TransformationEnum.ChromaStone) { - if (KeybindSystem.PrimaryAbility.JustPressed) { - if (!Player.HasBuff(ModContent.BuffType()) && - !Player.HasBuff(ModContent.BuffType())) { - Player.AddBuff(ModContent.BuffType(), 30 * 60); - tranUsedAbility = currTransformation; - } - } - if (PrimaryAbilityEnabled) { Lighting.AddLight(Player.Center, Main.DiscoColor.ToVector3()); } @@ -477,7 +442,7 @@ public override void PostUpdate() { // Buzzshock Transformation if (currTransformation == TransformationEnum.BuzzShock) { - if (KeybindSystem.PrimaryAbility.JustPressed && !Player.HasBuff()) { + if (PrimaryAbilityEnabled) { if (Main.myPlayer == Player.whoAmI) { SoundEngine.PlaySound(SoundID.Item8, Player.position); Random random = new Random(); @@ -495,8 +460,6 @@ public override void PostUpdate() { Color.White, 2); Main.dust[dustNum].noGravity = true; } - - Player.AddBuff(ModContent.BuffType(), 60 * 6); } } @@ -518,14 +481,6 @@ public override void PostUpdate() { // Ghostfreak Transformation if (currTransformation == TransformationEnum.GhostFreak) { - Random random = new Random(); - - if (KeybindSystem.PrimaryAbility.Current && !Player.HasBuff() && - !Player.HasBuff()) { - Player.AddBuff(ModContent.BuffType(), 15 * 60); - tranUsedAbility = currTransformation; - } - abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } @@ -537,21 +492,7 @@ public override void PostUpdate() { // Bigchill Transformation - if (currTransformation == TransformationEnum.BigChill) - { - if (KeybindSystem.PrimaryAbility.Current && !Player.HasBuff() && - !Player.HasBuff()) { - Player.AddBuff(ModContent.BuffType(), 15 * 60); - tranUsedAbility = currTransformation; - } - - if (KeybindSystem.UltimateAbility.JustPressed && - !Player.HasBuff(ModContent.BuffType()) && - !Player.HasBuff(ModContent.BuffType())) { - Player.AddBuff(ModContent.BuffType(), 10 * 60); - tranUsedAbility = currTransformation; - } - + if (currTransformation == TransformationEnum.BigChill) { abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } @@ -591,66 +532,88 @@ public override void PostUpdate() { } if (isTransformed) { - if (KeybindSystem.UltimateAbility.JustPressed && currTransformation.HasUltimateAttack()) - if (!Player.HasBuff() && !Player.HasBuff()) { - for (int i = 0; i < 50; i++) { - Dust d = Dust.NewDustPerfect(Player.Center + Main.rand.NextVector2Circular(20f, 20f), - ultimateAttack ? DustID.Firework_Yellow : DustID.Firework_Blue, - Main.rand.NextVector2Circular(6f, 6f), Scale: Main.rand.NextFloat(1.5f, 2.5f)); - d.noGravity = true; - } - - ultimateAttack = !ultimateAttack; + if (omnitrixEnergy < currTransformation.GetUltimateAbilityCost(this) && ultimateAttack) { + for (int i = 0; i < 50; i++) { + Dust d = Dust.NewDustPerfect(Player.Center + Main.rand.NextVector2Circular(20f, 20f), + DustID.Firework_Yellow, + Main.rand.NextVector2Circular(6f, 6f), Scale: Main.rand.NextFloat(1.5f, 2.5f)); + d.noGravity = true; } + + ultimateAttack = !ultimateAttack; + } } - - if (PrimaryAbilityEnabled != PrimaryAbilityWasEnabled) { - PrimaryAbilityWasEnabled = PrimaryAbilityEnabled; - switch (tranUsedAbility) { - case TransformationEnum.HeatBlast: { - Player.AddBuff(ModContent.BuffType(), 30 * 60); - break; - } - case TransformationEnum.XLR8: { - Player.AddBuff(ModContent.BuffType(), 30 * 60); - break; - } - case TransformationEnum.DiamondHead: { - Player.AddBuff(ModContent.BuffType(), 30 * 60); - break; - } - case TransformationEnum.ChromaStone: { - Player.AddBuff(ModContent.BuffType(), 60 * 60); - break; - } - case TransformationEnum.GhostFreak: { - Player.AddBuff(ModContent.BuffType(), 30 * 60); - break; - } - case TransformationEnum.BigChill: - { - Player.AddBuff(ModContent.BuffType(), 30 * 60); - break; - } + + if (isTransformed) { + if (KeybindSystem.PrimaryAbility.JustPressed && currTransformation.HasPrimaryAbility()) { + ActivatePrimaryAbility(); } + } - ChromaStoneAbsorbtion = 0; + if (isTransformed) { + if (KeybindSystem.UltimateAbility.JustPressed && (currTransformation.HasUltimateAbility() || currTransformation.HasUltimateAttack())) { + ActivateUltimateAbility(); + } + } + + if (PrimaryAbilityEnabled != PrimaryAbilityWasEnabled) { + Player.AddBuff(ModContent.BuffType(), tranUsedAbility.GetPrimaryCooldownDuration(this)); PrimaryAbilityWasEnabled = PrimaryAbilityEnabled; + ChromaStoneAbsorbtion = 0; } if (UltimateAbilityEnabled != ultimateAbilityWasEnabled) { ultimateAbilityWasEnabled = UltimateAbilityEnabled; - switch (tranUsedAbility) { - case TransformationEnum.XLR8: { - Player.AddBuff(ModContent.BuffType(), 30 * 60); - break; + Player.AddBuff(ModContent.BuffType(), tranUsedAbility.GetUltimateCooldownDuration(this)); + } + } + + public bool ActivateUltimateAbility() { + + if (currTransformation.HasUltimateAbility() && !Player.HasBuff() && !Player.HasBuff()) { + if (omnitrixEnergy >= currTransformation.GetUltimateAbilityCost(this)) { + Player.AddBuff(ModContent.BuffType(), currTransformation.GetUltimateAbilityDuration(this)); + tranUsedAbility = currTransformation; + omnitrixEnergy -= currTransformation.GetUltimateAbilityCost(this); + return true; + } + } + else { + if (omnitrixEnergy >= currTransformation.GetUltimateAbilityCost(this) && !ultimateAttack && !Player.HasBuff()) { + for (int i = 0; i < 50; i++) { + Dust d = Dust.NewDustPerfect(Player.Center + Main.rand.NextVector2Circular(20f, 20f), + DustID.Firework_Blue, + Main.rand.NextVector2Circular(6f, 6f), Scale: Main.rand.NextFloat(1.5f, 2.5f)); + d.noGravity = true; } - case TransformationEnum.BigChill: { - Player.AddBuff(ModContent.BuffType(), 30 * 60); - break; + + ultimateAttack = true; + return true; + } + if (ultimateAttack) { + for (int i = 0; i < 50; i++) { + Dust d = Dust.NewDustPerfect(Player.Center + Main.rand.NextVector2Circular(20f, 20f), + DustID.Firework_Yellow, + Main.rand.NextVector2Circular(6f, 6f), Scale: Main.rand.NextFloat(1.5f, 2.5f)); + d.noGravity = true; } + + ultimateAttack = false; + return true; } } + + return false; + } + + public bool ActivatePrimaryAbility() { + if (!Player.HasBuff() && !Player.HasBuff()) { + Player.AddBuff(ModContent.BuffType(), currTransformation.GetPrimaryAbilityDuration(this)); + tranUsedAbility = currTransformation; + return true; + } + + return false; } public override bool CanUseItem(Item item) { diff --git a/icon_workshop.png b/icon_workshop.png index 321ecb3441234c2aa92ae0107826ad1fd010dd54..6f9aacf70ac11cce763b2b3db4630e1b5578b45e 100644 GIT binary patch literal 2991 zcmb7G4NMbv6u*K)NVry3SD?^V(BR0N zH4-5kjA}aF4B=Z_Xz9mn91>wgKBUr?LilL47SvK|zjtO5mEgi%a=GO0fA78D`@P?L zul$Q7ysuZF7XSdh3H##@0sw0CegT>=qOigX=hzXC*cc6gnif0hm zArJ^mV_+g95ExZ13jo~Qd;k>6|0<+i8%FeDlvIVKuEa`?)R)!ba5#|8Y<-w$wbMmGbmn7L zSUAYVC0Aw%)hn?$J~5i*EY=mG-?la%LhNZ&aPR_WGD0sK#06R1QYb&fFs!F^mK#4i zi%>7Zxyt)oMtfUZ0NvSD5wb@vM7hTkbV2lK-hqJIB7D5dTN(e#klqv#QnF!ZOiTk?TB=g1e6W(6X01-&8iCBv z;kvImHy^|eSERRN^jv72NNC$Czf8PQvcZtp^%c6!(l$3{GH=^ zj>G*jYh+v1jm{(BSX>YElWj;+fSI*}uDNHKq_L-n0u^OYl{|GmmmuU4#8jhAVuvA{ zKM@?q@}XM;2@7Csf6)*=hK2M+pFb^d^z2X*pta4cJES5ix2zgRPRu?{+2mH%+#Sjm%)N8XCeZ-|I>?QiQK)zj&UWlcG)MB= zlaKr|bL-|ni9?ndGUmw5)5!Hyg=&#Lwm``9ZB9`-^0BgBc)ZTiWO0c&L)s>U1n>xj z`_X8$X|*Dwv$GS1*n^~Sb>;x|u-XiLt-LMVVP!tGg1mMSSUG2e$cR8N+3gT#*lTKI z4EV7n8E(IAi}JVNO3q@-SQPsdb6Ra+gcGlWj6 z&8apIRoD=u4sM?wip$ra4Qyu-ga;!Lp-+#yKH|muu7g12$fl4eG@|>in6g!Fh*nW% z9e*RE+PA2?GK`wF&dx-nJa8xBFKL5`bGOdFE>tJWs$MG=8fXM?Yy)Dq0GK5r z`e9vGlm4n!y>xl|P~s?jWddjU>8Nk&4^=Rk2*`oAgcM4Kn>0U zGa-TFOD760GOOKQtg{$saFf^ZLV$Y_CY~`{vJY8>1*!WwUhZ1VTSt7cIKg0))zYpR zAl#4^A0-mu<&W5St`>AyqG8(uqLWKk?#W_0ovsIKYHC#0XL`N9x?H{tDAG<$OuXQ+ zQ&Uql){aGH_~-+TVi$Y~^n5P+!Uem31W>H3|6KHPy-i;v#Znh48K3slr(;bbynzD= Mdz0cDcBhs83+&UeI{*Lx delta 1417 zcmYjRX;2eq7~Uul?10c>iCV*g2h<~69*kTODNsj|ahOs&u>w;Ih$f+mQ7D@zwK7g? zz^=s(X^Kj9rea8HY*x#J#9GO4CQy*TO2W}(12Kw*gpzB!IFj-G`F-#4JkNWGDH2Lu z9I5nj{Q7uFcFV(0Cpsy0?ZIVo_YeCfJ2S$w>n`q&FG#zKuFnX)vbLw;;-HKsYI+h^l`4t;7 z+cfjP;c{iw_nzd>8Z4ZoaxP1L#{SG_n8*kp@C$=ueFHWc5iNm~JLIZ|J(3j*$-Dl1io5t+{OH z>)()-x@wsvK$*IFl%r!IAt@dB{e`G^iFe)c9l6P5pu5w=nf=gP-dA>w6g~zkNi=Gu z{BX|8HIfjON@ZIo2~S8!NXM?)J!>GSzC93*BdvwU{K#9CGoiDkf2>aARaESBY$*Ej zC@R`(9ZI0z0mrYoW+!<;!ba3gcerx#s)HkD={-w{w-!iHU6jXkReS6t${Ic0gi3+d zyQ8cqw+oJ2wmJ9$a&0`~66+YsH@41jCnMk>GA#%iyQRBL9ql!6W#1O=d-{9_X-o>-0Z4ZMVVkv`but)?q}w-s`p1sbz$Bm`#mWDY)k| z1Ze2oKqk_r@D$x3&lkwv6;6#b3^ED1-Ntx6mq8Mj5m9MJB?@LaHz$!gEx({q-HDdfQXk{aSvz zj^6YFfpDA(LH8Ts%S<NjnfG+Q-x#u%a?5dfPqGlM`9Vzu91S`_=sIg%d?9(Zws6 z*irX5NN)iP`;5rr6idC$w8L4P?z=od?`f;KWQKUl@Bm|Cuaoy-d8CN}&2)lmHc6)~BM3WC7{JGQI z;r2!c2e8wYKI`n4@w0HbtSLzF8iFJ|m+gy2>u7I;pam8k(IZzdd-7BEth*gvPL777 zmR0!c^qf`^I8GxZiCYeUMe@TzLY{4U@U4XoCZ-&kB2~m7O?o!mJXD z#q3*E;ea+PDk@5aKrV;F@x)402njpK;C*2>5!RyTrzR%8VrYOFoW-0T92^wYj1s#R a5{mogWEIS?Ycf>;VS6(6f7G(Op!$D3UEqEI From a0de89385989c9aa6762425170ef52601ea1c0a9 Mon Sep 17 00:00:00 2001 From: DestroyerMob Date: Tue, 10 Mar 2026 20:22:42 +1100 Subject: [PATCH 25/25] Starting to refactor to a more modular code base to make it easier to add more aliens --- Content/Buffs/Abilities/UltimateAbility.cs | 2 +- Content/Items/Accessories/Omnitrix.cs | 163 +++++++++++++++++- .../Items/Accessories/PrototypeOmnitrix.cs | 143 +++------------ .../Items/Accessories/RecalibratedOmnitrix.cs | 140 +-------------- Content/Items/Accessories/Ultimatrix.cs | 141 +-------------- Content/TransformationHandler.cs | 10 +- .../Transformations/TransformationPlayer.cs | 20 +++ OmnitrixPlayer.cs | 18 +- 8 files changed, 223 insertions(+), 414 deletions(-) create mode 100644 Content/Transformations/TransformationPlayer.cs diff --git a/Content/Buffs/Abilities/UltimateAbility.cs b/Content/Buffs/Abilities/UltimateAbility.cs index e8f8167..bc02cab 100644 --- a/Content/Buffs/Abilities/UltimateAbility.cs +++ b/Content/Buffs/Abilities/UltimateAbility.cs @@ -11,7 +11,7 @@ public override void Update(Player player, ref int buffIndex) { var omp = player.GetModPlayer(); omp.UltimateAbilityEnabled = true; - omp.ultimateAbilityWasEnabled = true; + omp.UltimateAbilityWasEnabled = true; } public override bool RightClick(int buffIndex) => false; diff --git a/Content/Items/Accessories/Omnitrix.cs b/Content/Items/Accessories/Omnitrix.cs index 9558806..dfdbb92 100644 --- a/Content/Items/Accessories/Omnitrix.cs +++ b/Content/Items/Accessories/Omnitrix.cs @@ -1,21 +1,170 @@ +using System.Collections.Generic; +using Ben10Mod.Common.Command; using Terraria; using Terraria.ID; using Terraria.ModLoader; using Ben10Mod.Content.DamageClasses; +using Ben10Mod.Content.Interface; +using Ben10Mod.Enums; +using Ben10Mod.Keybinds; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Terraria.Audio; -namespace Ben10Mod.Content.Items.Accessories -{ - public class Omnitrix : ModItem { +namespace Ben10Mod.Content.Items.Accessories { + public abstract class Omnitrix : ModItem { - private Player player = null; - public int transformationNum = 0; + public virtual int MaxOmnitrixEnergy => 0; + public virtual int OmnitrixEnergyRegen => 0; + public virtual int OmnitrixEnergyDrain => 0; + public virtual bool UseEnergyForTransformation => false; + public virtual int TranformationSwapCost => 50; + public virtual int TimeoutDuration => 120; + public virtual int TransformationDuration => 300; + public virtual bool EvolutionFeature => false; + public virtual int EvolutionCost => 150; + + public int transformationNum = 0; + public TransformationEnum[] transformations = new TransformationEnum[5]; + + public bool wasEquipedLastFrame = false; + public bool showingUI = false; + + public Player player = null; + + public Texture2D dynamicTexture; public override string Texture => $"Terraria/Images/Item_{ItemID.None}"; public override void SetDefaults() { - Item.maxStack = 1; - Item.rare = ItemRarityID.Master; + Item.maxStack = 1; + Item.width = 22; + Item.height = 28; + Item.rare = ItemRarityID.Master; Item.DamageType = ModContent.GetInstance(); + Item.accessory = true; + } + + public override void ModifyTooltips(List tooltips) { + tooltips.Add(new TooltipLine(Mod, "AlienSelection", + "Alien " + (transformationNum + 1) + ": " + transformations[transformationNum].ToString())); + } + + public override void UpdateAccessory(Player player, bool hideVisual) { + if (player.whoAmI != Main.myPlayer) return; + this.player = player; + var omp = player.GetModPlayer(); + omp.omnitrixEquipped = true; + wasEquipedLastFrame = true; + + omp.omnitrixEnergyMax += MaxOmnitrixEnergy; + + omp.omnitrixEnergyRegen = omp.isTransformed ? omp.omnitrixEnergyRegen - OmnitrixEnergyDrain : omp.omnitrixEnergyRegen + OmnitrixEnergyRegen; + + transformations = omp.transformations; + + HandleAlienSelection(omp); + + HandleTransformationKey(omp); + + if (!omp.isTransformed || !UseEnergyForTransformation) return; + if (omp.omnitrixEnergy > 0) + TransformationHandler.Transform(player, omp.currTransformation, 2, false, false, EvolutionFeature); + else + TransformationHandler.Detransform(player, TimeoutDuration); + } + + public override void UpdateInventory(Player player) { + base.UpdateInventory(player); + var omp = player.GetModPlayer(); + + if (wasEquipedLastFrame) { + wasEquipedLastFrame = false; + ModContent.GetInstance().HideMyUI(); + if (player.GetModPlayer().isTransformed) { + TransformationHandler.Detransform(player, TimeoutDuration, true, true); + } + } + } + + private void HandleAlienSelection(OmnitrixPlayer omp) { + bool selectionChanged = false; + + if (KeybindSystem.AlienOneKeybind.JustPressed) { + transformationNum = 0; + selectionChanged = true; + } + else if (KeybindSystem.AlienTwoKeybind.JustPressed) { + transformationNum = 1; + selectionChanged = true; + } + else if (KeybindSystem.AlienThreeKeybind.JustPressed) { + transformationNum = 2; + selectionChanged = true; + } + else if (KeybindSystem.AlienFourKeybind.JustPressed) { + transformationNum = 3; + selectionChanged = true; + } + else if (KeybindSystem.AlienFiveKeybind.JustPressed) { + transformationNum = 4; + selectionChanged = true; + } + else if (KeybindSystem.AlienNextKeybind.JustPressed) { + transformationNum = (transformationNum + 1) % transformations.Length; + selectionChanged = true; + SoundEngine.PlaySound(SoundID.MenuTick, player.position); + } + else if (KeybindSystem.AlienPrevKeybind.JustPressed) { + transformationNum = (transformationNum - 1 + transformations.Length) % transformations.Length; + selectionChanged = true; + SoundEngine.PlaySound(SoundID.MenuTick, player.position); + } + + if (selectionChanged) + Main.NewText($"Transformation {transformationNum + 1}: {transformations[transformationNum].GetName()}!", + Color.Green); + } + + private void HandleTransformationKey(OmnitrixPlayer omp) { + if (!KeybindSystem.TransformationKeybind.JustPressed || omp.onCooldown) + return; + + TransformationEnum desiredAlien = transformations[transformationNum]; + + if (!omp.isTransformed) { + // Normal transformation + if (UseEnergyForTransformation) + TransformationHandler.Transform(player, desiredAlien, 2); + else + TransformationHandler.Transform(player, desiredAlien, TransformationDuration); + } + else { + // Already transformed + if (omp.currTransformation != desiredAlien) { + // Swap to a different alien while transformed + if (UseEnergyForTransformation && omp.omnitrixEnergy >= TranformationSwapCost) { + omp.omnitrixEnergy -= TranformationSwapCost; + TransformationHandler.Detransform(player, 0, addCooldown: false); + TransformationHandler.Transform(player, desiredAlien, 2); + } + } + else { + // Same alien → Ultimate or Detransform + if (EvolutionFeature && desiredAlien.HasUltimateForm() && omp.omnitrixEnergy >= EvolutionCost) { + if (!omp.ultimateForm) { + omp.omnitrixEnergy -= EvolutionCost; + TransformationHandler.GoUltimate(player, desiredAlien); + } + else { + TransformationHandler.Detransform(player, 0, addCooldown: false); + } + } + else if (UseEnergyForTransformation || omp.masterControl) { + TransformationHandler.Detransform(player, 0, addCooldown: false); + } + } + } } } } \ No newline at end of file diff --git a/Content/Items/Accessories/PrototypeOmnitrix.cs b/Content/Items/Accessories/PrototypeOmnitrix.cs index 7d21e5f..6818894 100644 --- a/Content/Items/Accessories/PrototypeOmnitrix.cs +++ b/Content/Items/Accessories/PrototypeOmnitrix.cs @@ -12,18 +12,9 @@ using Microsoft.Xna.Framework.Graphics; using Terraria.Audio; -namespace Ben10Mod.Content.Items.Accessories -{ - public class PrototypeOmnitrix : Omnitrix - { - private Player player = null; - public int transformationNum = 0; - public TransformationEnum[] transformations = new TransformationEnum[5]; - - bool wasEquipedLastFrame = false; - bool showingUI = false; - - Texture2D dynamicTexture; +namespace Ben10Mod.Content.Items.Accessories { + public class PrototypeOmnitrix : Omnitrix { + public override int MaxOmnitrixEnergy => 300; public override string Texture => $"Ben10Mod/Content/Items/Accessories/{this.Name}"; @@ -32,148 +23,56 @@ public override void Load() { return; EquipLoader.AddEquipTexture(Mod, $"{Texture}_{EquipType.HandsOn}", EquipType.HandsOn, this); - EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.HandsOn}", EquipType.HandsOn, name: "PrototypeOmnitrixAlt"); - EquipLoader.AddEquipTexture(Mod, $"{Texture}Updating_{EquipType.HandsOn}", EquipType.HandsOn, name: "PrototypeOmnitrixUpdating"); + EquipLoader.AddEquipTexture(Mod, $"{Texture}Alt_{EquipType.HandsOn}", EquipType.HandsOn, + name: "PrototypeOmnitrixAlt"); + EquipLoader.AddEquipTexture(Mod, $"{Texture}Updating_{EquipType.HandsOn}", EquipType.HandsOn, + name: "PrototypeOmnitrixUpdating"); } - public override ModItem Clone(Item item) { PrototypeOmnitrix clone = (PrototypeOmnitrix)base.Clone(item); clone.transformationNum = transformationNum; - clone.transformations = (TransformationEnum[])transformations?.Clone(); + clone.transformations = (TransformationEnum[])transformations?.Clone(); return clone; } - public override void SaveData(TagCompound tag) { tag["selectedAlien"] = transformationNum; } - - public override void LoadData(TagCompound tag) - { + public override void LoadData(TagCompound tag) { tag.TryGet("selectedAlien", out transformationNum); } - - public override void OnCreated(ItemCreationContext context) - { + public override void OnCreated(ItemCreationContext context) { transformationNum = 0; } - public override void SetStaticDefaults() { - dynamicTexture = ModContent.Request("Ben10Mod/Content/Items/Accessories/PrototypeOmnitrix").Value; - } - - public override void SetDefaults() { - Item.maxStack = 1; - Item.width = 22; - Item.height = 28; - Item.rare = ItemRarityID.Master; - Item.accessory = true; - } - - public override void ModifyTooltips(List tooltips) { - tooltips.Add(new TooltipLine(Mod, "AlienSelection", "Alien " + (transformationNum + 1) + ": " + transformations[transformationNum].ToString())); + dynamicTexture = ModContent.Request("Ben10Mod/Content/Items/Accessories/PrototypeOmnitrix") + .Value; } public override void UpdateAccessory(Player player, bool hideVisual) { - if (player.whoAmI != Main.myPlayer) return; - this.player = player; - var omp = player.GetModPlayer(); - omp.omnitrixEquipped = true; - omp.prototypeOmnitrix = true; - wasEquipedLastFrame = true; - - omp.omnitrixEnergyMax += 300; - - transformations = player.GetModPlayer().transformations; - - if (KeybindSystem.TransformationKeybind.JustPressed && !player.GetModPlayer().isTransformed && !player.GetModPlayer().onCooldown) { - omp.advancedCircuitMatrixEquippedWhileTransformed = omp.advancedCircuitMatrix; - TransformationHandler.Transform(player, transformations[transformationNum], - omp.advancedCircuitMatrixEquippedWhileTransformed ? omp.transformationTime * 2 : omp.transformationTime); - } - else if (KeybindSystem.TransformationKeybind.JustPressed && player.GetModPlayer().isTransformed && !player.GetModPlayer().onCooldown && player.GetModPlayer().masterControl) { - if (player.GetModPlayer().currTransformation != transformations[transformationNum]) { - TransformationHandler.Detransform(player, 0, false, false, false); - TransformationHandler.Transform(player, transformations[transformationNum], - omp.advancedCircuitMatrixEquippedWhileTransformed ? omp.transformationTime * 2 : omp.transformationTime); - } else { - TransformationHandler.Detransform(player, omp.cooldownTime, true, false); - } - } - else if (KeybindSystem.AlienOneKeybind.JustPressed) { - transformationNum = 0; - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienTwoKeybind.JustPressed) { - transformationNum = 1; - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienThreeKeybind.JustPressed) { - transformationNum = 2; - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienFourKeybind.JustPressed) { - transformationNum = 3; - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienFiveKeybind.JustPressed) { - transformationNum = 4; - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienNextKeybind.JustPressed) { - transformationNum++; - if (transformationNum > transformations.Length - 1) { - transformationNum = 0; - } - SoundEngine.PlaySound(SoundID.MenuTick, player.position); - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienPrevKeybind.JustPressed) { - transformationNum--; - if (transformationNum < 0) { - transformationNum = transformations.Length - 1; - } - SoundEngine.PlaySound(SoundID.MenuTick, player.position); - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - base.UpdateAccessory(player, hideVisual); } - public override void UpdateInventory(Player player) - { - base.UpdateInventory(player); - var omp = player.GetModPlayer(); - - if (wasEquipedLastFrame) - { - wasEquipedLastFrame = false; - ModContent.GetInstance().HideMyUI(); - if (player.GetModPlayer().isTransformed) { - TransformationHandler.Detransform(player, omp.cooldownTime, true, true); - } - } - } - - public override bool CanEquipAccessory(Player player, int slot, bool modded) { - return modded; - } - - public override bool PreDrawInInventory(SpriteBatch spriteBatch, Vector2 position, Rectangle frame, Color drawColor, Color itemColor, Vector2 origin, float scale) { + public override bool PreDrawInInventory(SpriteBatch spriteBatch, Vector2 position, Rectangle frame, + Color drawColor, Color itemColor, Vector2 origin, float scale) { if (player == null) return true; - dynamicTexture = player.GetModPlayer().omnitrixUpdating ? ModContent.Request("Ben10Mod/Content/Items/Accessories/PrototypeOmnitrixUpdating").Value : player.GetModPlayer().onCooldown ? ModContent.Request("Ben10Mod/Content/Items/Accessories/PrototypeOmnitrixAlt").Value : ModContent.Request("Ben10Mod/Content/Items/Accessories/PrototypeOmnitrix").Value; + dynamicTexture = player.GetModPlayer().omnitrixUpdating + ? + ModContent.Request("Ben10Mod/Content/Items/Accessories/PrototypeOmnitrixUpdating").Value + : player.GetModPlayer().onCooldown + ? ModContent.Request("Ben10Mod/Content/Items/Accessories/PrototypeOmnitrixAlt").Value + : ModContent.Request("Ben10Mod/Content/Items/Accessories/PrototypeOmnitrix").Value; spriteBatch.Draw(dynamicTexture, position, null, drawColor, 0f, origin, scale, SpriteEffects.None, 0f); return false; } - public override void AddRecipes() { base.AddRecipes(); - CreateRecipe() + CreateRecipe() .AddIngredient(ModContent.ItemType(), 25) .AddIngredient(ItemID.Lens, 6) .AddIngredient(ItemID.Emerald, 3) diff --git a/Content/Items/Accessories/RecalibratedOmnitrix.cs b/Content/Items/Accessories/RecalibratedOmnitrix.cs index 2998f62..7b4a7cb 100644 --- a/Content/Items/Accessories/RecalibratedOmnitrix.cs +++ b/Content/Items/Accessories/RecalibratedOmnitrix.cs @@ -15,14 +15,10 @@ namespace Ben10Mod.Content.Items.Accessories { public class RecalibratedOmnitrix : Omnitrix { - - private Player player = null; - public int transformationNum = 0; - public TransformationEnum[] transformations = new TransformationEnum[5]; - - bool wasEquipedLastFrame = false; - - Texture2D dynamicTexture; + public override int MaxOmnitrixEnergy => 500; + public override int OmnitrixEnergyDrain => 1; + public override int OmnitrixEnergyRegen => 3; + public override bool UseEnergyForTransformation => true; public override string Texture => $"Ben10Mod/Content/Items/Accessories/{this.Name}"; @@ -50,137 +46,9 @@ public override void LoadData(TagCompound tag) tag.TryGet("selectedAlien", out transformationNum); } - public override void OnCreated(ItemCreationContext context) - { - transformationNum = 0; - } - public override void SetStaticDefaults() { dynamicTexture = ModContent.Request("Ben10Mod/Content/Items/Accessories/RecalibratedOmnitrix").Value; } - - public override void SetDefaults() { - Item.maxStack = 1; - Item.width = 22; - Item.height = 28; - Item.rare = ItemRarityID.Master; - Item.accessory = true; - } - - public override void ModifyTooltips(List tooltips) { - tooltips.Add(new TooltipLine(Mod, "AlienSelection", - "Alien " + (transformationNum + 1) + ": " + transformations[transformationNum].ToString())); - } - - public override void UpdateAccessory(Player player, bool hideVisual) { - - if (player.whoAmI != Main.myPlayer) return; - - this.player = player; - var omp = player.GetModPlayer(); - omp.omnitrixEnergyMax += 500; - omp.omnitrixEquipped = true; - wasEquipedLastFrame = true; - - if (omp.isTransformed) - omp.omnitrixEnergyRegen -= 1; - - if (omp.omnitrixEnergy <= 0 && omp.isTransformed) { - TransformationHandler.Detransform(player, 120); - } - - if (omp.omnitrixEnergy > 0 && omp.isTransformed) { - TransformationHandler.Transform(player, omp.currTransformation, 2, false,false); - } - if (omp.isTransformed) - omp.omnitrixEnergyRegen -= 1; - else - omp.omnitrixEnergyRegen += 3; - - - transformations = player.GetModPlayer().transformations; - - if (KeybindSystem.TransformationKeybind.JustPressed && !player.GetModPlayer().isTransformed && !player.GetModPlayer().onCooldown) { - TransformationHandler.Transform(player, transformations[transformationNum], 2); - } - else if (KeybindSystem.TransformationKeybind.JustPressed && player.GetModPlayer().isTransformed && !player.GetModPlayer().onCooldown) { - if (player.GetModPlayer().currTransformation != transformations[transformationNum]) { - omp.omnitrixEnergy -= 50; - omp.omnitrixEnergy = Math.Max(omp.omnitrixEnergy, 0); - if (omp.omnitrixEnergy > 0) { - TransformationHandler.Detransform(player, 0, false, false); - TransformationHandler.Transform(player, transformations[transformationNum], 2); - } - else { - TransformationHandler.Detransform(player, 60); - } - } else { - TransformationHandler.Detransform(player, 0, true, false); - } - } - else if (KeybindSystem.AlienOneKeybind.JustPressed) { - transformationNum = 0; - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienTwoKeybind.JustPressed) { - transformationNum = 1; - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienThreeKeybind.JustPressed) { - transformationNum = 2; - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienFourKeybind.JustPressed) { - transformationNum = 3; - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienFiveKeybind.JustPressed) { - transformationNum = 4; - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienNextKeybind.JustPressed) { - transformationNum++; - if (transformationNum > transformations.Length - 1) { - transformationNum = 0; - } - SoundEngine.PlaySound(SoundID.MenuTick, player.position); - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienPrevKeybind.JustPressed) { - transformationNum--; - if (transformationNum < 0) { - transformationNum = transformations.Length - 1; - } - SoundEngine.PlaySound(SoundID.MenuTick, player.position); - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - - base.UpdateAccessory(player, hideVisual); - } - - public override void UpdateInventory(Player player) - { - - var omp = player.GetModPlayer(); - - base.UpdateInventory(player); - - if (wasEquipedLastFrame) - { - wasEquipedLastFrame = false; - ModContent.GetInstance().HideMyUI(); - if (player.GetModPlayer().isTransformed) { - TransformationHandler.Detransform(player, omp.cooldownTime, true, true); - } else { - TransformationHandler.Detransform(player, omp.cooldownTime, false, false, false); - } - } - } - - public override bool CanEquipAccessory(Player player, int slot, bool modded) { - return modded; - } - public override bool PreDrawInInventory(SpriteBatch spriteBatch, Vector2 position, Rectangle frame, Color drawColor, Color itemColor, Vector2 origin, float scale) { if (player == null) diff --git a/Content/Items/Accessories/Ultimatrix.cs b/Content/Items/Accessories/Ultimatrix.cs index d32a0e7..30b5a84 100644 --- a/Content/Items/Accessories/Ultimatrix.cs +++ b/Content/Items/Accessories/Ultimatrix.cs @@ -15,6 +15,12 @@ namespace Ben10Mod.Content.Items.Accessories { public class Ultimatrix : Omnitrix { + public override int MaxOmnitrixEnergy => 750; + public override bool UseEnergyForTransformation => true; + public override int OmnitrixEnergyRegen => 4; + public override int OmnitrixEnergyDrain => 2; + public override int TranformationSwapCost => 75; + public override bool EvolutionFeature => true; private Player player = null; public int transformationNum = 0; @@ -50,143 +56,10 @@ public override void LoadData(TagCompound tag) tag.TryGet("selectedAlien", out transformationNum); } - public override void OnCreated(ItemCreationContext context) - { - transformationNum = 0; - } - public override void SetStaticDefaults() { dynamicTexture = ModContent.Request("Ben10Mod/Content/Items/Accessories/Ultimatrix").Value; } - - public override void SetDefaults() { - Item.maxStack = 1; - Item.width = 22; - Item.height = 28; - Item.rare = ItemRarityID.Master; - Item.accessory = true; - } - - public override void ModifyTooltips(List tooltips) { - tooltips.Add(new TooltipLine(Mod, "AlienSelection", - "Alien " + (transformationNum + 1) + ": " + transformations[transformationNum].ToString())); - } - - public override void UpdateAccessory(Player player, bool hideVisual) { - - if (player.whoAmI != Main.myPlayer) return; - - this.player = player; - var omp = player.GetModPlayer(); - omp.omnitrixEnergyMax += 700; - omp.omnitrixEquipped = true; - wasEquipedLastFrame = true; - - if (omp.isTransformed) - omp.omnitrixEnergyRegen -= 1; - - if (omp.omnitrixEnergy <= 0 && omp.isTransformed) { - TransformationHandler.Detransform(player, 120); - } - - if (omp.omnitrixEnergy > 0 && omp.isTransformed) { - TransformationHandler.Transform(player, omp.currTransformation, 2, false,false); - } - if (omp.isTransformed) - omp.omnitrixEnergyRegen -= 1; - else - omp.omnitrixEnergyRegen += 3; - - - transformations = omp.transformations; - - if (KeybindSystem.TransformationKeybind.JustPressed && !omp.isTransformed && !omp.onCooldown) { - TransformationHandler.Transform(player, transformations[transformationNum], 2); - } - else if (KeybindSystem.TransformationKeybind.JustPressed && omp.isTransformed && !omp.onCooldown) { - if (omp.currTransformation != transformations[transformationNum]) { - omp.omnitrixEnergy -= 50; - omp.omnitrixEnergy = Math.Max(omp.omnitrixEnergy, 0); - if (omp.omnitrixEnergy > 0) { - TransformationHandler.Detransform(player, 0, false, false); - TransformationHandler.Transform(player, transformations[transformationNum], 2); - } - else { - TransformationHandler.Detransform(player, 60); - } - } else if (omp.currTransformation.HasUltimateForm() && !omp.ultimateForm) { - omp.omnitrixEnergy -= 150; - omp.omnitrixEnergy = Math.Max(omp.omnitrixEnergy, 0); - if (omp.omnitrixEnergy > 0) { - TransformationHandler.GoUltimate(player, omp.currTransformation); - } - } else { - TransformationHandler.Detransform(player, 0, true, false); - } - } - else if (KeybindSystem.AlienOneKeybind.JustPressed) { - transformationNum = 0; - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienTwoKeybind.JustPressed) { - transformationNum = 1; - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienThreeKeybind.JustPressed) { - transformationNum = 2; - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienFourKeybind.JustPressed) { - transformationNum = 3; - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienFiveKeybind.JustPressed) { - transformationNum = 4; - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienNextKeybind.JustPressed) { - transformationNum++; - if (transformationNum > transformations.Length - 1) { - transformationNum = 0; - } - SoundEngine.PlaySound(SoundID.MenuTick, player.position); - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - else if (KeybindSystem.AlienPrevKeybind.JustPressed) { - transformationNum--; - if (transformationNum < 0) { - transformationNum = transformations.Length - 1; - } - SoundEngine.PlaySound(SoundID.MenuTick, player.position); - Main.NewText("Transformation " + (transformationNum + 1) + ": " + transformations[transformationNum].GetName() + "!", Color.Green); - } - - base.UpdateAccessory(player, hideVisual); - } - - public override void UpdateInventory(Player player) - { - - var omp = player.GetModPlayer(); - - base.UpdateInventory(player); - - if (wasEquipedLastFrame) - { - wasEquipedLastFrame = false; - ModContent.GetInstance().HideMyUI(); - if (player.GetModPlayer().isTransformed) { - TransformationHandler.Detransform(player, omp.cooldownTime, true, true); - } else { - TransformationHandler.Detransform(player, omp.cooldownTime, false, false, false); - } - } - } - - public override bool CanEquipAccessory(Player player, int slot, bool modded) { - return modded; - } - + public override bool PreDrawInInventory(SpriteBatch spriteBatch, Vector2 position, Rectangle frame, Color drawColor, Color itemColor, Vector2 origin, float scale) { if (player == null) diff --git a/Content/TransformationHandler.cs b/Content/TransformationHandler.cs index 2b60a30..6bbdf50 100644 --- a/Content/TransformationHandler.cs +++ b/Content/TransformationHandler.cs @@ -15,9 +15,16 @@ namespace Ben10Mod.Content { public static class TransformationHandler { - public static void Transform(Player player, TransformationEnum transformation, int seconds, bool showParticles = true, bool playSound = true) { + public static void Transform(Player player, TransformationEnum transformation, int seconds, bool showParticles = true, bool playSound = true, bool stayUltimate = false) { if (transformation.GetTransformation() == -1) return; + + var omp = player.GetModPlayer(); + omp.currTransformation = transformation; + omp.isTransformed = true; + if (!stayUltimate) + omp.ultimateForm = false; + if (showParticles) { Random random = new Random(); for (int i = 0; i < 25; i++) { @@ -42,7 +49,6 @@ public static void Transform(Player player, TransformationEnum transformation, i public static void Detransform(Player player, int seconds, bool showParticles = true, bool addCooldown = true, bool playSound = true) { if (addCooldown) player.AddBuff(ModContent.BuffType(), 60 * seconds); - if (showParticles) { Random random = new Random(); diff --git a/Content/Transformations/TransformationPlayer.cs b/Content/Transformations/TransformationPlayer.cs new file mode 100644 index 0000000..31d0d78 --- /dev/null +++ b/Content/Transformations/TransformationPlayer.cs @@ -0,0 +1,20 @@ +using Ben10Mod.Enums; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Transformations; + +public abstract class TransformationPlayer : ModPlayer { + public virtual int PrimaryAttack => -1; + public virtual int SecondaryAttack => -1; + public virtual int UltimateAttack => -1; + public virtual float PrimaryAttackModifier => 1f; + public virtual float SecondaryAttackModifier => 1f; + public virtual float UltimateAttackModifier => 1f; + public virtual int TransformationBuffId => -1; + public new virtual string Name => "None"; + public virtual string IconPath => "Ben10Mod/Content/Interface/EmptyAlien"; + public virtual string Description => "A mysterious alien from the Omnitrix database."; + + + +} \ No newline at end of file diff --git a/OmnitrixPlayer.cs b/OmnitrixPlayer.cs index 0ecb28d..dff5a13 100644 --- a/OmnitrixPlayer.cs +++ b/OmnitrixPlayer.cs @@ -2,8 +2,6 @@ using System; using Microsoft.Xna.Framework; using System.Collections.Generic; -using System.CommandLine.Help; -using System.Data.SqlTypes; using System.Linq; using Terraria; using Terraria.ID; @@ -34,7 +32,6 @@ using Ben10Mod.Content.Transformations.EyeGuy; using Terraria.Graphics.Effects; using Terraria.Graphics.Shaders; -using Terraria.WorldBuilding; namespace Ben10Mod { public class OmnitrixPlayer : ModPlayer { @@ -56,7 +53,7 @@ public class OmnitrixPlayer : ModPlayer { public bool PrimaryAbilityEnabled = false; public bool PrimaryAbilityWasEnabled = false; public bool UltimateAbilityEnabled = false; - public bool ultimateAbilityWasEnabled = false; + public bool UltimateAbilityWasEnabled = false; public TransformationEnum tranUsedAbility = TransformationEnum.None; public int ChromaStoneAbsorbtion = 0; @@ -74,8 +71,8 @@ public class OmnitrixPlayer : ModPlayer { public const int DashDuration = 15; public TransformationEnum[] transformations = { - TransformationEnum.HeatBlast, TransformationEnum.HeatBlast, TransformationEnum.HeatBlast, - TransformationEnum.HeatBlast, TransformationEnum.HeatBlast + TransformationEnum.HeatBlast, TransformationEnum.None, TransformationEnum.None, + TransformationEnum.None, TransformationEnum.None }; public TransformationEnum currTransformation = TransformationEnum.None; @@ -200,13 +197,10 @@ public override void PostUpdateBuffs() { } else { if (omnitrixSlot.FunctionalItem.type == ModContent.ItemType()) - TransformationHandler.Detransform(Player, - advancedCircuitMatrixEquippedWhileTransformed ? cooldownTime * 2 : cooldownTime); + TransformationHandler.Detransform(Player, ModContent.GetInstance().TimeoutDuration); if (omnitrixSlot.FunctionalItem.type == ModContent.ItemType()) TransformationHandler.Detransform(Player, 0, addCooldown: false); } - - advancedCircuitMatrixEquippedWhileTransformed = false; } wasTransformed = isTransformed; @@ -562,8 +556,8 @@ public override void PostUpdate() { ChromaStoneAbsorbtion = 0; } - if (UltimateAbilityEnabled != ultimateAbilityWasEnabled) { - ultimateAbilityWasEnabled = UltimateAbilityEnabled; + if (UltimateAbilityEnabled != UltimateAbilityWasEnabled) { + UltimateAbilityWasEnabled = UltimateAbilityEnabled; Player.AddBuff(ModContent.BuffType(), tranUsedAbility.GetUltimateCooldownDuration(this)); } }