diff --git a/Ben10Mod.cs b/Ben10Mod.cs index 08d23b7..57d0db9 100644 --- a/Ben10Mod.cs +++ b/Ben10Mod.cs @@ -1,11 +1,53 @@ +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; +using Terraria.Graphics.Shaders; +using Terraria.ID; using Terraria.ModLoader; -namespace Ben10Mod -{ - public class Ben10Mod : Mod - { - public override void Load() { - base.Load(); - } - } +namespace Ben10Mod { + public class Ben10Mod : Mod { + public override void Load() { + if (Main.netMode != NetmodeID.Server) { + 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); + Filters.Scene["Ben10Mod:Bluescale"] = new Filter(new ScreenShaderData(filterShader, "Bluescale"), EffectPriority.Medium); + } + } + + // 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 new file mode 100644 index 0000000..16244f7 --- /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.PrimaryAbilityEnabled; + } + + // 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/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/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 c853d07..d111ceb 100644 --- a/Common/Systems/GenPasses/OmnitrixCapsulePass.cs +++ b/Common/Systems/GenPasses/OmnitrixCapsulePass.cs @@ -5,138 +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 config) { - progress.Message = "Calling down a strange meteor..."; - - // Your custom tiles - int meteorRockTile = TileID.LunarOre; // "meteor rock" - int meteorOreTile = ModContent.TileType(); // special ore - 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); - - // --- 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 - - // --- 3) Scan around impactX to find the meteorite area --- - int scanRadius = 80; - int minX = impactX - scanRadius; - int maxX = impactX + scanRadius; - - if (minX < 10) minX = 10; - if (maxX > Main.maxTilesX - 10) maxX = Main.maxTilesX - 10; - - bool foundMeteor = false; - int highestMeteorY = Main.maxTilesY; - int lowestMeteorY = 0; - - 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) - continue; - - if (t.TileType == TileID.Meteorite) { - foundMeteor = true; - if (y < highestMeteorY) highestMeteorY = y; - if (y > lowestMeteorY) lowestMeteorY = y; - } - } - } + protected override void ApplyPass(GenerationProgress progress, GameConfiguration configuration) + { + progress.Message = "Calling down strange meteors..."; - if (!foundMeteor) - return; // Somehow no meteorite tiles were created, bail + int meteorOreTile = TileID.Silver; + int meteorRockTile = ModContent.TileType(); + int capsuleTile = ModContent.TileType(); - // --- 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) - continue; + var rand = WorldGen.genRand; - // Random ore pockets inside the meteor - if (WorldGen.genRand.Next(6) == 0) // ~1/6 chance - { - t.TileType = (ushort)meteorOreTile; - } - else { - t.TileType = (ushort)meteorRockTile; - } - } - } + // === 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 - // --- 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; + int placed = 0; + int maxAttempts = numMeteors * 6; // safety net (you'll never hit it) - for (int y = highestMeteorY - 20; y <= lowestMeteorY + 20; y++) { - if (y < 10 || y >= Main.maxTilesY - 10) - continue; + 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); - WorldGen.SquareTileFrame(x, y, resetFrame: true); - } - } + int cavernTop = (int)Main.rockLayer + 60; // well below surface, into caverns + int cavernBottom = Main.maxTilesY - 380; // safe above Underworld - // --- 6) Find a top spot for the 1x1 capsule near impactX --- + if (cavernTop >= cavernBottom) continue; - int bestX = -1; - int bestY = -1; + int centerY = rand.Next(cavernTop, cavernBottom); - int searchHalfWidth = 25; - int topSearchY = highestMeteorY - 5; - if (topSearchY < 10) topSearchY = 10; + // === 2) Build the lumpy meteor blob (slightly bigger & rounder than before) === + int halfWidth = 13; + int halfHeight = 8; + + bool meteorPlaced = false; + + 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; - int bottomSearchY = lowestMeteorY + 10; - if (bottomSearchY > Main.maxTilesY - 10) bottomSearchY = Main.maxTilesY - 10; + float dx = (x - centerX) / (float)halfWidth; + float dy = (y - centerY) / (float)halfHeight; + float distSq = dx * dx + dy * dy; - for (int x = impactX - searchHalfWidth; x <= impactX + searchHalfWidth; x++) { - if (x < minX || x > maxX) - continue; + if (distSq > 1.25f) continue; - // Scan from just above the meteor top downward - for (int y = topSearchY; y <= bottomSearchY; y++) { - Tile t = Main.tile[x, y]; - if (t == null || !t.HasTile) - continue; + // Organic lumpy edges + float noise = (float)(rand.NextDouble() * 0.42 - 0.19); + if (distSq > 1.0f + noise) 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; // capsule goes in this empty tile - break; - } + Tile t = Main.tile[x, y]; + if (t == null) continue; + + t.HasTile = true; + t.TileType = rand.Next(6) == 0 ? (ushort)meteorOreTile : (ushort)meteorRockTile; + + meteorPlaced = true; } } - if (bestX != -1) - break; - } + if (!meteorPlaced) continue; + + // === 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); + } + + // === 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); - if (bestX == -1) - return; // meteor exists, but we couldn't find a clean top spot for the capsule + // 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; - // --- 7) Place the 1x1 PlumberCapsulePod tile directly --- + Tile t = Main.tile[x, y]; + if (t == null || !t.HasTile) continue; + if (t.TileType != meteorRockTile && t.TileType != meteorOreTile) continue; - Tile cap = Main.tile[bestX, bestY]; - cap.HasTile = true; - cap.TileType = (ushort)capsuleTile; + // Found a meteor tile → place capsule directly above it + int capY = y - 1; + if (!WorldGen.InWorld(x, capY)) break; - WorldGen.SquareTileFrame(bestX, bestY, resetFrame: true); + // Carve a clean 1-tile pocket (just in case something is there) + WorldGen.KillTile(x, capY, noItem: true); + + Tile cap = Main.tile[x, capY]; + cap.HasTile = true; + cap.TileType = (ushort)capsuleTile; + + WorldGen.SquareTileFrame(x, capY, true); + WorldGen.SquareTileFrame(x, y, true); + + if (Main.netMode == NetmodeID.Server) + NetMessage.SendTileSquare(-1, x - 1, capY - 1, 3, 3); + + capsulePlaced = true; + break; + } + } - if (Main.netMode == NetmodeID.Server) { - NetMessage.SendTileSquare(-1, bestX, bestY, 1, 1); + if (capsulePlaced) + placed++; } + ModContent.GetInstance().Logger.Info($"OmnitrixCapsulePass: Placed {placed} meteors in cavern layer"); } } } \ No newline at end of file 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/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 18d9f69..0000000 Binary files a/Content/Buffs/Abilities/BuzzShock/BuzzShock_Primary_Buff.png and /dev/null differ 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 18d9f69..0000000 Binary files a/Content/Buffs/Abilities/BuzzShock/BuzzShock_Primary_Cooldown_Buff.png and /dev/null differ 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 18d9f69..0000000 Binary files a/Content/Buffs/Abilities/ChromaStone/ChromaStone_Primary_Buff.png and /dev/null differ 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 18d9f69..0000000 Binary files a/Content/Buffs/Abilities/ChromaStone/ChromaStone_Primary_Cooldown_Buff.png and /dev/null differ 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 18d9f69..0000000 Binary files a/Content/Buffs/Abilities/DiamondHead/DiamondHead_Primary_Buff.png and /dev/null differ 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 18d9f69..0000000 Binary files a/Content/Buffs/Abilities/DiamondHead/DiamondHead_Primary_Cooldown_Buff.png and /dev/null differ 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 18d9f69..0000000 Binary files a/Content/Buffs/Abilities/HeatBlast/HeatBlast_Primary_Buff.png and /dev/null differ 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 18d9f69..0000000 Binary files a/Content/Buffs/Abilities/HeatBlast/HeatBlast_Primary_Cooldown_Buff.png and /dev/null differ 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 0000000..ed8ce59 Binary files /dev/null and b/Content/Buffs/Abilities/PrimaryAbility.png differ diff --git a/Content/Buffs/Abilities/PrimaryAbilityCooldown.cs b/Content/Buffs/Abilities/PrimaryAbilityCooldown.cs new file mode 100644 index 0000000..e4de9f3 --- /dev/null +++ b/Content/Buffs/Abilities/PrimaryAbilityCooldown.cs @@ -0,0 +1,7 @@ +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Buffs.Abilities; + +public class PrimaryAbilityCooldown : ModBuff { + public override bool RightClick(int buffIndex) => 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 0000000..aa90062 Binary files /dev/null and b/Content/Buffs/Abilities/PrimaryAbilityCooldown.png differ diff --git a/Content/Buffs/Abilities/UltimateAbility.cs b/Content/Buffs/Abilities/UltimateAbility.cs new file mode 100644 index 0000000..bc02cab --- /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/Abilities/XLR8/XLR8_Primary_Buff.cs b/Content/Buffs/Abilities/UltimateAbilityCooldown.cs similarity index 50% rename from Content/Buffs/Abilities/XLR8/XLR8_Primary_Buff.cs rename to Content/Buffs/Abilities/UltimateAbilityCooldown.cs index fc3c849..951703a 100644 --- a/Content/Buffs/Abilities/XLR8/XLR8_Primary_Buff.cs +++ b/Content/Buffs/Abilities/UltimateAbilityCooldown.cs @@ -4,18 +4,14 @@ using System.Text; using System.Threading.Tasks; using Terraria; -using Terraria.ID; using Terraria.ModLoader; -namespace Ben10Mod.Content.Buffs.Abilities.XLR8 -{ - public class XLR8_Primary_Buff : ModBuff - { - public override void Update(Player player, ref int buffIndex) - { - OmnitrixPlayer p = player.GetModPlayer(); - p.XLR8PrimaryAbilityEnabled = true; - p.XLR8PrimaryAbilityWasEnabled = true; +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(); } 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 18d9f69..0000000 Binary files a/Content/Buffs/Abilities/XLR8/XLR8_Primary_Buff.png and /dev/null differ 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 18d9f69..0000000 Binary files a/Content/Buffs/Abilities/XLR8/XLR8_Primary_Cooldown_Buff.png and /dev/null differ 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/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 18d9f69..0000000 Binary files a/Content/Buffs/Debuffs/GhostFreakPossesion.png and /dev/null differ 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 0000000..ed8ce59 Binary files /dev/null and b/Content/Buffs/Summons/BuzzShockMinionBuff.png differ 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/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 new file mode 100644 index 0000000..8b88f04 --- /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.Abilities { + 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/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 new file mode 100644 index 0000000..08420ec --- /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.Abilities { + 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 0000000..c18ef46 Binary files /dev/null and b/Content/Buffs/Transformations/OmnitrixUpdating.png differ 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/Interface/AlienSelectionScreen.cs b/Content/Interface/AlienSelectionScreen.cs index 83318dd..a8e7413 100644 --- a/Content/Interface/AlienSelectionScreen.cs +++ b/Content/Interface/AlienSelectionScreen.cs @@ -3,217 +3,353 @@ 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]); + // 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 NextAlienFour(UIMouseEvent evt, UIElement listeningElement) { - TransformationHandler.NextTransformation(Main.LocalPlayer, ref Main.LocalPlayer.GetModPlayer().transformations[3]); - } - 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); + slot.OnMouseOver += (_, _) => UpdateInfoPanel(TransformationEnum.None); + 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(); + Main.LocalPlayer.GetModPlayer().showingUI = false; + }; + 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()); + + var player = Main.LocalPlayer.GetModPlayer(); + + 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]); } - if (AlienFive.IsMouseHovering) { - Main.instance.MouseText(Main.LocalPlayer.GetModPlayer().transformations[4].GetName()); + + 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 0000000..97c97df Binary files /dev/null and b/Content/Interface/OE_Fill.png differ diff --git a/Content/Interface/OE_Panel_Left.png b/Content/Interface/OE_Panel_Left.png new file mode 100644 index 0000000..956bc7c Binary files /dev/null and b/Content/Interface/OE_Panel_Left.png differ diff --git a/Content/Interface/OE_Panel_Middle.png b/Content/Interface/OE_Panel_Middle.png new file mode 100644 index 0000000..9eb5941 Binary files /dev/null and b/Content/Interface/OE_Panel_Middle.png differ diff --git a/Content/Interface/OE_Panel_Right.png b/Content/Interface/OE_Panel_Right.png new file mode 100644 index 0000000..d56cc26 Binary files /dev/null and b/Content/Interface/OE_Panel_Right.png differ 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/AdvancedCircuitMatrix.cs b/Content/Items/Accessories/AdvancedCircuitMatrix.cs new file mode 100644 index 0000000..bf60e80 --- /dev/null +++ b/Content/Items/Accessories/AdvancedCircuitMatrix.cs @@ -0,0 +1,23 @@ +using Ben10Mod.Content.Items.Placeables; +using Terraria; +using Terraria.GameContent.UI.States; +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Items.Accessories; + +public class AdvancedCircuitMatrix : ModItem { + + public override void SetDefaults() { + Item.width = 32; + Item.height = 32; + Item.accessory = true; + Item.value = 100000; + } + + 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/AdvancedCircuitMatrix.png b/Content/Items/Accessories/AdvancedCircuitMatrix.png new file mode 100644 index 0000000..c9f37be Binary files /dev/null and b/Content/Items/Accessories/AdvancedCircuitMatrix.png differ diff --git a/Content/Items/Accessories/HeatBlastExtraJumpAccessory.cs b/Content/Items/Accessories/HeatBlastExtraJumpAccessory.cs new file mode 100644 index 0000000..0e4b4fc --- /dev/null +++ b/Content/Items/Accessories/HeatBlastExtraJumpAccessory.cs @@ -0,0 +1,42 @@ +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) { + + 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 + 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/HeatBlastExtraJumpAccessory.png b/Content/Items/Accessories/HeatBlastExtraJumpAccessory.png new file mode 100644 index 0000000..33d0da0 Binary files /dev/null and b/Content/Items/Accessories/HeatBlastExtraJumpAccessory.png differ 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 0000000..4ba90b4 Binary files /dev/null and b/Content/Items/Accessories/HeroEmblem.png differ diff --git a/Content/Items/Accessories/Omnitrix.cs b/Content/Items/Accessories/Omnitrix.cs index 69c42ec..dfdbb92 100644 --- a/Content/Items/Accessories/Omnitrix.cs +++ b/Content/Items/Accessories/Omnitrix.cs @@ -1,45 +1,170 @@ - using Ben10Mod.Content.Transformations; -using Ben10Mod.Content.Transformations.XLR8; -using Ben10Mod.Keybinds; -using Microsoft.Xna.Framework; -using Steamworks; -using System; +using System.Collections.Generic; +using Ben10Mod.Common.Command; 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 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 { + + 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; - private Player player = null; - public int transformationNum = 0; - public int cooldownTime = 0; + 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 9cbeead..6818894 100644 --- a/Content/Items/Accessories/PrototypeOmnitrix.cs +++ b/Content/Items/Accessories/PrototypeOmnitrix.cs @@ -1,45 +1,20 @@ - 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 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; - 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}"; @@ -48,163 +23,59 @@ 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}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; - this.transformationTime = 300; - } - - 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) { - this.player = player; - player.GetModPlayer().omnitrixEquipped = true; - wasEquipedLastFrame = true; - - 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], 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); - } else { - TransformationHandler.Detransform(player, 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); - - 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) { + 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/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(); - 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/PrototypeOmnitrixUpdating.png b/Content/Items/Accessories/PrototypeOmnitrixUpdating.png new file mode 100644 index 0000000..024f652 Binary files /dev/null and b/Content/Items/Accessories/PrototypeOmnitrixUpdating.png differ diff --git a/Content/Items/Accessories/PrototypeOmnitrixUpdating_HandsOn.png b/Content/Items/Accessories/PrototypeOmnitrixUpdating_HandsOn.png new file mode 100644 index 0000000..b16b212 Binary files /dev/null and b/Content/Items/Accessories/PrototypeOmnitrixUpdating_HandsOn.png differ diff --git a/Content/Items/Accessories/RecalibratedOmnitrix.cs b/Content/Items/Accessories/RecalibratedOmnitrix.cs index 0e9e63c..7b4a7cb 100644 --- a/Content/Items/Accessories/RecalibratedOmnitrix.cs +++ b/Content/Items/Accessories/RecalibratedOmnitrix.cs @@ -1,45 +1,24 @@ - 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 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}"; @@ -67,135 +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; - 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) @@ -213,8 +66,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/Accessories/RecalibratedOmnitrix.png b/Content/Items/Accessories/RecalibratedOmnitrix.png index c11aff5..5ae0503 100644 Binary files a/Content/Items/Accessories/RecalibratedOmnitrix.png and b/Content/Items/Accessories/RecalibratedOmnitrix.png differ diff --git a/Content/Items/Accessories/RecalibratedOmnitrixAlt.png b/Content/Items/Accessories/RecalibratedOmnitrixAlt.png index ea051fd..51c6566 100644 Binary files a/Content/Items/Accessories/RecalibratedOmnitrixAlt.png and b/Content/Items/Accessories/RecalibratedOmnitrixAlt.png differ diff --git a/Content/Items/Accessories/Ultimatrix.cs b/Content/Items/Accessories/Ultimatrix.cs new file mode 100644 index 0000000..30b5a84 --- /dev/null +++ b/Content/Items/Accessories/Ultimatrix.cs @@ -0,0 +1,86 @@ +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 { + 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; + 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 SetStaticDefaults() { + dynamicTexture = ModContent.Request("Ben10Mod/Content/Items/Accessories/Ultimatrix").Value; + } + + 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 0000000..5ae0503 Binary files /dev/null and b/Content/Items/Accessories/Ultimatrix.png differ diff --git a/Content/Items/Accessories/UltimatrixAlt.png b/Content/Items/Accessories/UltimatrixAlt.png new file mode 100644 index 0000000..51c6566 Binary files /dev/null and b/Content/Items/Accessories/UltimatrixAlt.png differ diff --git a/Content/Items/Accessories/UltimatrixAlt_HandsOn.png b/Content/Items/Accessories/UltimatrixAlt_HandsOn.png new file mode 100644 index 0000000..d5bfeb9 Binary files /dev/null and b/Content/Items/Accessories/UltimatrixAlt_HandsOn.png differ diff --git a/Content/Items/Accessories/Ultimatrix_HandsOn.png b/Content/Items/Accessories/Ultimatrix_HandsOn.png new file mode 100644 index 0000000..15e0c70 Binary files /dev/null and b/Content/Items/Accessories/Ultimatrix_HandsOn.png differ 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 0000000..79db883 Binary files /dev/null and b/Content/Items/Accessories/Wings/BigChillWings.png differ diff --git a/Content/Items/Accessories/Wings/BigChillWings_Wings.png b/Content/Items/Accessories/Wings/BigChillWings_Wings.png new file mode 100644 index 0000000..b9bec9d Binary files /dev/null and b/Content/Items/Accessories/Wings/BigChillWings_Wings.png differ 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.png b/Content/Items/Accessories/Wings/HeatBlastWings.png deleted file mode 100644 index 629419e..0000000 Binary files a/Content/Items/Accessories/Wings/HeatBlastWings.png and /dev/null differ diff --git a/Content/Items/Accessories/Wings/HeatBlastWings_Wing.png b/Content/Items/Accessories/Wings/HeatBlastWings_Wing.png deleted file mode 100644 index f8633e1..0000000 Binary files a/Content/Items/Accessories/Wings/HeatBlastWings_Wing.png and /dev/null differ diff --git a/Content/Items/Accessories/Wings/HeatBlastWings_Wings.png b/Content/Items/Accessories/Wings/HeatBlastWings_Wings.png deleted file mode 100644 index fd23110..0000000 Binary files a/Content/Items/Accessories/Wings/HeatBlastWings_Wings.png and /dev/null differ diff --git a/Content/Items/Accessories/Wings/UltimateBigChillWings.cs b/Content/Items/Accessories/Wings/UltimateBigChillWings.cs new file mode 100644 index 0000000..7f0d0ec --- /dev/null +++ b/Content/Items/Accessories/Wings/UltimateBigChillWings.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 UltimateBigChillWings : 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/UltimateBigChillWings.png b/Content/Items/Accessories/Wings/UltimateBigChillWings.png new file mode 100644 index 0000000..79db883 Binary files /dev/null and b/Content/Items/Accessories/Wings/UltimateBigChillWings.png differ diff --git a/Content/Items/Accessories/Wings/UltimateBigChillWings_Wings.png b/Content/Items/Accessories/Wings/UltimateBigChillWings_Wings.png new file mode 100644 index 0000000..0edf432 Binary files /dev/null and b/Content/Items/Accessories/Wings/UltimateBigChillWings_Wings.png differ 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/Consumable/MasterControlKey.cs b/Content/Items/Consumable/MasterControlKey.cs new file mode 100644 index 0000000..ebcebcb --- /dev/null +++ b/Content/Items/Consumable/MasterControlKey.cs @@ -0,0 +1,68 @@ +using Microsoft.Xna.Framework; +using Terraria; +using Terraria.Audio; +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Items.Consumable +{ + public class MasterControlKey : ModItem + { + public override void SetDefaults() + { + Item.width = 30; + Item.height = 10; + Item.useStyle = ItemUseStyleID.HoldUp; + Item.useTime = Item.useAnimation = 45; // Dramatic wind-up for unlock + Item.useTurn = true; + Item.consumable = true; + Item.rare = ItemRarityID.Purple; // Feels like a rare/powerful unlock + } + + public override bool CanUseItem(Player player) + { + // Can only use if Master Control is NOT already unlocked + return !player.GetModPlayer().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)); + + Item.stack--; + + 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 0000000..b5d9143 Binary files /dev/null and b/Content/Items/Consumable/MasterControlKey.png differ 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 0000000..e17f5ec Binary files /dev/null and b/Content/Items/Materials/HeroFragment.png differ 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/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 0000000..68fcac4 Binary files /dev/null and b/Content/Items/Weapons/HeavenlyCrystallineBadge.png differ diff --git a/Content/Items/Weapons/PlumberAgentBadge.cs b/Content/Items/Weapons/PlumberAgentBadge.cs index 0d647c7..cec4abd 100644 --- a/Content/Items/Weapons/PlumberAgentBadge.cs +++ b/Content/Items/Weapons/PlumberAgentBadge.cs @@ -4,22 +4,15 @@ namespace Ben10Mod.Content.Items.Weapons; public class PlumberAgentBadge : PlumbersBadge { - public override int BaseDamage => 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 f1423b5..ddcf526 100644 Binary files a/Content/Items/Weapons/PlumberAgentBadge.png and b/Content/Items/Weapons/PlumberAgentBadge.png differ diff --git a/Content/Items/Weapons/PlumberHelperBadge.cs b/Content/Items/Weapons/PlumberCadetBadge.cs similarity index 56% rename from Content/Items/Weapons/PlumberHelperBadge.cs rename to Content/Items/Weapons/PlumberCadetBadge.cs index 523a028..02252af 100644 --- a/Content/Items/Weapons/PlumberHelperBadge.cs +++ b/Content/Items/Weapons/PlumberCadetBadge.cs @@ -2,21 +2,22 @@ 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() { 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/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 0000000..2ddd655 Binary files /dev/null and b/Content/Items/Weapons/PlumberFieldProctorBadge.png differ diff --git a/Content/Items/Weapons/PlumberMagisterBadge.cs b/Content/Items/Weapons/PlumberMagisterBadge.cs new file mode 100644 index 0000000..326ce08 --- /dev/null +++ b/Content/Items/Weapons/PlumberMagisterBadge.cs @@ -0,0 +1,19 @@ +using Ben10Mod.Content.Items.Materials; +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Items.Weapons; + +public class PlumberMagisterBadge : PlumbersBadge { + public override int BaseDamage => 95; + public override string BadgeRankName => "Magister"; + public override int BadgeRankValue => 8; + + public override void AddRecipes() { + CreateRecipe() + .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 new file mode 100644 index 0000000..bd88ad7 Binary files /dev/null and b/Content/Items/Weapons/PlumberMagisterBadge.png differ diff --git a/Content/Items/Weapons/PlumberMagistrataBadge.cs b/Content/Items/Weapons/PlumberMagistrataBadge.cs new file mode 100644 index 0000000..aa0352d --- /dev/null +++ b/Content/Items/Weapons/PlumberMagistrataBadge.cs @@ -0,0 +1,10 @@ +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Items.Weapons; + +public class PlumberMagistrataBadge : PlumbersBadge { + public override int BaseDamage => 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 0000000..8b0b4c9 Binary files /dev/null and b/Content/Items/Weapons/PlumberMagistrataBadge.png differ diff --git a/Content/Items/Weapons/PlumberProctorBadge.cs b/Content/Items/Weapons/PlumberProctorBadge.cs new file mode 100644 index 0000000..420d480 --- /dev/null +++ b/Content/Items/Weapons/PlumberProctorBadge.cs @@ -0,0 +1,19 @@ +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Items.Weapons; + +public class PlumberProctorBadge : PlumbersBadge { + public override int BaseDamage => 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 0000000..58d4b68 Binary files /dev/null and b/Content/Items/Weapons/PlumberProctorBadge.png differ 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 0000000..5b8d3fc Binary files /dev/null and b/Content/Items/Weapons/PlumberSeniorAgentBadge.png differ diff --git a/Content/Items/Weapons/PlumberSeniorDeputyBadge.cs b/Content/Items/Weapons/PlumberSeniorDeputyBadge.cs new file mode 100644 index 0000000..d669716 --- /dev/null +++ b/Content/Items/Weapons/PlumberSeniorDeputyBadge.cs @@ -0,0 +1,27 @@ +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod.Content.Items.Weapons; + +public class PlumberSeniorDeputyBadge : PlumbersBadge { + public override int BaseDamage => 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 0000000..f1423b5 Binary files /dev/null and b/Content/Items/Weapons/PlumberSeniorDeputyBadge.png differ diff --git a/Content/Items/Weapons/PlumbersBadge.cs b/Content/Items/Weapons/PlumbersBadge.cs index f9d860b..e9741c4 100644 --- a/Content/Items/Weapons/PlumbersBadge.cs +++ b/Content/Items/Weapons/PlumbersBadge.cs @@ -1,5 +1,11 @@ -using Ben10Mod.Content.DamageClasses; +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using Ben10Mod.Content.Buffs.Summons; +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; @@ -7,209 +13,382 @@ using Terraria.ID; using Terraria.ModLoader; using Terraria.Audio; +using Terraria.Localization; -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 string BadgeRankName => "Helper"; - - public override void SetDefaults() - { +namespace Ben10Mod.Content.Items.Weapons { + public abstract class PlumbersBadge : ModItem { + public virtual int BaseDamage => 15; + 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; + + + private int GetUltimateProjectileType(OmnitrixPlayer omp) { + return omp.currTransformation switch { + TransformationEnum.EyeGuy => ModContent.ProjectileType(), + TransformationEnum.GhostFreak => ModContent.ProjectileType(), + TransformationEnum.DiamondHead => ModContent.ProjectileType(), + TransformationEnum.HeatBlast => ModContent.ProjectileType(), + TransformationEnum.BuzzShock => 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 (!state.ultimateStarted) + return; + + if (player.channel) return; + + int ultimateProjType = GetUltimateProjectileType(omp); + if (HasActiveOwnedProjectile(player, ultimateProjType) && + omp.currTransformation == TransformationEnum.EyeGuy) return; + + 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; - Item.useStyle = ItemUseStyleID.Swing; 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.useTime = Item.useAnimation = 25; + Item.useStyle = ItemUseStyleID.Swing; + Item.useTime = Item.useAnimation = 25; Item.shootSpeed = 10f; + + Item.UseSound = null; } - public override bool CanUseItem(Player player) - { - // Only usable when transformed - prevents any use/animation when human - return player.GetModPlayer().isTransformed; + 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 AltFunctionUse(Player player) => true; + public override bool CanUseItem(Player player) { + var omp = player.GetModPlayer(); + return player.GetModPlayer().isTransformed && + !(omp.omnitrixEnergy < OmnitrixEnergyUse && omp.ultimateAttack); + } - public override void HoldItem(Player player) - { + public override void HoldItem(Player player) { var omp = player.GetModPlayer(); + FinalizeUltimateIfEnded(player, omp); + // 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; + Item.UseSound = null; + Item.channel = false; + Item.noMelee = 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 (player.altFunctionUse == 2) { - Item.useStyle = ItemUseStyleID.Swing; - Item.useTime = Item.useAnimation = 50; - 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.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.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; 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 = 25; + OmnitrixEnergyUse = omp.ultimateAttack ? 25 : 0; 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: - Item.useTime = Item.useAnimation = 20; + Item.useTime = Item.useAnimation = 20; Item.shootSpeed = 25f; 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: - Item.useTime = Item.useAnimation = 30; + Item.useTime = Item.useAnimation = 30; Item.shootSpeed = 25f; 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: - 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; + break; + case TransformationEnum.BigChill: + Item.useStyle = ItemUseStyleID.Shoot; + Item.shootSpeed = omp.altAttack ? 3f : 20f; + Item.useTime = Item.useAnimation = omp.altAttack ? 10 : 25; + break; default: Item.useTime = Item.useAnimation = 25; Item.shootSpeed = 10f; Item.useStyle = ItemUseStyleID.Swing; break; } + + Item.useTime = Item.useAnimation = (int)(Item.useTime / AttackSpeedMultiplier); } - public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) - { + public override bool? UseItem(Player player) { var omp = player.GetModPlayer(); + if (omp.omnitrixEnergy >= OmnitrixEnergyUse) { + omp.omnitrixEnergy -= OmnitrixEnergyUse; + } + else { + return false; + } - if (!omp.isTransformed) + 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 || player.altFunctionUse == 2) return false; + + int activeUltimateType = GetUltimateProjectileType(omp); + bool ultimateInProgress = player.channel || + player.GetModPlayer().ultimateStarted; + + if (ultimateInProgress && !omp.ultimateAttack) return false; - int projType = ProjectileID.ImpFireball; // Bright vanilla fallback - you SHOULD see this if alien not matched + if (omp.ultimateAttack && player.HasBuff()) + return false; + + int projType = ProjectileID.ImpFireball; int finalDamage = damage; - switch (omp.currTransformation) - { + switch (omp.currTransformation) { case TransformationEnum.HeatBlast: - if (player.altFunctionUse == 2) { - projType = ModContent.ProjectileType(); - // projType = ProjectileID.Flamelash; - finalDamage = (int)(damage * 2.5f); - } - else { - projType = ProjectileID.Flames; - finalDamage = (int)(damage * 0.2f); + 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 = 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 + 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: - projType = player.altFunctionUse == 2 - ? 0 - : ModContent.ProjectileType(); + projType = omp.altAttack ? ModContent.ProjectileType() : ModContent.ProjectileType(); + if (omp.altAttack) { + finalDamage = (int)(damage * 3f); + player.velocity += velocity * 2f; + } 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 - ? 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); + if (omp.ultimateAttack) finalDamage = (int)(2.5f * finalDamage); + projType = omp.ultimateAttack + ? ModContent.ProjectileType() + : ModContent.ProjectileType(); + break; case TransformationEnum.StinkFly: - projType = player.altFunctionUse == 2 + projType = omp.altAttack ? ModContent.ProjectileType() : ModContent.ProjectileType(); break; case TransformationEnum.GhostFreak: - projType = player.altFunctionUse == 2 - ? ModContent.ProjectileType() - : ModContent.ProjectileType(); + if (omp.ultimateAttack) { + projType = ModContent.ProjectileType(); + } else if (omp.altAttack) { + projType = ModContent.ProjectileType(); + } + else { + projType = ModContent.ProjectileType(); + } + break; case TransformationEnum.WildVine: - projType = player.altFunctionUse == 2 + projType = omp.altAttack ? ModContent.ProjectileType() : ModContent.ProjectileType(); break; + + case TransformationEnum.EyeGuy: + projType = omp.ultimateAttack + ? ModContent.ProjectileType() + : ModContent.ProjectileType(); + finalDamage = omp.ultimateAttack ? (int)(damage * 2f) : damage; + break; + case TransformationEnum.BigChill: + projType = omp.altAttack ? ModContent.ProjectileType() : ModContent.ProjectileType(); + finalDamage = omp.altAttack ? (int)(damage * 0.3f) : damage; + break; } if (projType == 0) return false; - - Projectile.NewProjectile(source, position, velocity, projType, finalDamage, knockback, player.whoAmI); + + if (omp.ultimateAttack && HasActiveOwnedProjectile(player, projType)) + return false; + + 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); + + 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; } } + + + public class BadgeUltimateState : ModPlayer { + public bool ultimateStarted; + + public override void ResetEffects() { } + } } \ No newline at end of file diff --git a/Content/Items/Weapons/ProvisionalAgentBadgeCrimtane.cs b/Content/Items/Weapons/ProvisionalAgentBadgeCrimtane.cs deleted file mode 100644 index 728363c..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.DemoniteBar, 15) - .AddTile(TileID.Anvils) - .Register(); - } -} \ No newline at end of file diff --git a/Content/Projectiles/BigChillFrostBreathProjectile.cs b/Content/Projectiles/BigChillFrostBreathProjectile.cs new file mode 100644 index 0000000..fef4d11 --- /dev/null +++ b/Content/Projectiles/BigChillFrostBreathProjectile.cs @@ -0,0 +1,48 @@ +using Ben10Mod.Content.Buffs.Debuffs; +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 < 12; 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; + } + } + + 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/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 0000000..3c652e9 Binary files /dev/null and b/Content/Projectiles/BigChillProjectile.png differ diff --git a/Content/Projectiles/BuzzShockMinionProjectile.cs b/Content/Projectiles/BuzzShockMinionProjectile.cs index f229dbc..eb2937b 100644 --- a/Content/Projectiles/BuzzShockMinionProjectile.cs +++ b/Content/Projectiles/BuzzShockMinionProjectile.cs @@ -1,6 +1,6 @@ using Microsoft.Xna.Framework; using System; -using Ben10Mod.Enums; +using Ben10Mod.Content.Buffs.Summons; using Terraria; using Terraria.Audio; using Terraria.DataStructures; @@ -10,207 +10,240 @@ 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; } - // --- 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 (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; + } + + 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; + + 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) { + 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; + + Vector2 chargeDestination = target.Center + chargeDirection * ChargeOvershoot; + Vector2 toChargeDestination = chargeDestination - Projectile.Center; + float distanceToDestination = toChargeDestination.Length(); - // --- Face direction --- - if (hasTarget) { - Projectile.direction = (target.Center.X > Projectile.Center.X) ? 1 : -1; - Projectile.spriteDirection = Projectile.direction; + 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/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 0a4693c..0953516 100644 --- a/Content/Projectiles/ChromaStoneProjectile.cs +++ b/Content/Projectiles/ChromaStoneProjectile.cs @@ -15,24 +15,35 @@ 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 = 3; + Projectile.penetrate = -1; Projectile.DamageType = DamageClass.Magic; - + Projectile.timeLeft = 60 * 5; } - public override bool PreDraw(ref Color lightColor) { + 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; + } + } - OmnitrixPlayer omnitrixPlayer = Main.player[Projectile.owner].GetModPlayer(); - lightColor = omnitrixPlayer.GetChromaStoneOverlayColor(); + public override bool PreDraw(ref Color lightColor) { + 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/ChromaStoneProjectile.png b/Content/Projectiles/ChromaStoneProjectile.png index 6fcaaef..57829d9 100644 Binary files a/Content/Projectiles/ChromaStoneProjectile.png and b/Content/Projectiles/ChromaStoneProjectile.png differ diff --git a/Content/Projectiles/DiamondHeadProjectile.cs b/Content/Projectiles/DiamondHeadProjectile.cs index 79a8deb..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; @@ -19,8 +21,18 @@ public override void SetDefaults() { Projectile.hostile = false; Projectile.aiStyle = ProjAIStyleID.Arrow; - + AIType = ProjectileID.Bullet; + Projectile.DamageType = DamageClass.Ranged; + 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/DiamondHeadProjectile.png b/Content/Projectiles/DiamondHeadProjectile.png index 1d4ab98..f5fcdc0 100644 Binary files a/Content/Projectiles/DiamondHeadProjectile.png and b/Content/Projectiles/DiamondHeadProjectile.png differ diff --git a/Content/Projectiles/Explosion.cs b/Content/Projectiles/Explosion.cs index ea989ec..a855bc8 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,10 @@ 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)); + } } } } 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 0000000..8e3bd9c Binary files /dev/null and b/Content/Projectiles/EyeGuyLaserbeam.png differ diff --git a/Content/Projectiles/EyeGuyUltimateBeam.cs b/Content/Projectiles/EyeGuyUltimateBeam.cs new file mode 100644 index 0000000..219f81c --- /dev/null +++ b/Content/Projectiles/EyeGuyUltimateBeam.cs @@ -0,0 +1,295 @@ +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; + 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, + 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 0000000..4f5231e Binary files /dev/null and b/Content/Projectiles/EyeGuyUltimateBeam.png differ diff --git a/Content/Projectiles/GhostFreakPossesionProjectile.cs b/Content/Projectiles/GhostFreakPossesionProjectile.cs index 8dab514..38b953d 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,20 +23,16 @@ 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.possessedTargetIndex = target.whoAmI; omp.possessionTimer = 360; omp.inPossessionMode = true; @@ -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 0000000..6a86939 Binary files /dev/null and b/Content/Projectiles/GhostFreakPossesionProjectile.png differ diff --git a/Content/Projectiles/GhostFreakProjectile.cs b/Content/Projectiles/GhostFreakProjectile.cs index d78e27b..b315558 100644 --- a/Content/Projectiles/GhostFreakProjectile.cs +++ b/Content/Projectiles/GhostFreakProjectile.cs @@ -18,20 +18,21 @@ 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.tileCollide = false; } 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 @@ -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 0000000..4e7a133 Binary files /dev/null and b/Content/Projectiles/GiantDiamondProjectile.png differ diff --git a/Content/Projectiles/HeatBlastBomb.cs b/Content/Projectiles/HeatBlastBomb.cs index 23aa5b4..338a54c 100644 --- a/Content/Projectiles/HeatBlastBomb.cs +++ b/Content/Projectiles/HeatBlastBomb.cs @@ -18,27 +18,29 @@ public override void SetDefaults() { Projectile.height = 4; Projectile.aiStyle = ProjAIStyleID.Arrow; - AIType = ProjectileID.Grenade; + AIType = ProjectileID.Bullet; Projectile.friendly = true; } 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; - } + 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; } 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/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 0000000..ff1cc9d Binary files /dev/null and b/Content/Projectiles/HeatBlastUltimateProjectile.png differ diff --git a/Content/Projectiles/Projectile_464.png b/Content/Projectiles/Projectile_464.png new file mode 100644 index 0000000..ed439df Binary files /dev/null and b/Content/Projectiles/Projectile_464.png differ 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/Projectiles/WildVineProjectile.png b/Content/Projectiles/WildVineProjectile.png index 8d2ac97..dcf8df6 100644 Binary files a/Content/Projectiles/WildVineProjectile.png and b/Content/Projectiles/WildVineProjectile.png differ diff --git a/Content/Projectiles/WildVineProjectile_Chain.png b/Content/Projectiles/WildVineProjectile_Chain.png index 5a995b4..9a54e92 100644 Binary files a/Content/Projectiles/WildVineProjectile_Chain.png and b/Content/Projectiles/WildVineProjectile_Chain.png differ 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/Tiles/PlumberCapsulePod.png b/Content/Tiles/PlumberCapsulePod.png index 74354b4..141afeb 100644 Binary files a/Content/Tiles/PlumberCapsulePod.png and b/Content/Tiles/PlumberCapsulePod.png differ diff --git a/Content/TransformationHandler.cs b/Content/TransformationHandler.cs index 88062f9..6bbdf50 100644 --- a/Content/TransformationHandler.cs +++ b/Content/TransformationHandler.cs @@ -3,12 +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.Transformations; +using Ben10Mod.Content.Buffs.Abilities; using Ben10Mod.Enums; using Terraria; using Terraria.ID; @@ -20,28 +15,40 @@ 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++) { 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); 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) { if (addCooldown) player.AddBuff(ModContent.BuffType(), 60 * seconds); - if (showParticles) { Random random = new Random(); @@ -65,15 +72,42 @@ 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.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 new file mode 100644 index 0000000..7595d53 --- /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); + + 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 + 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, "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.Body.Sets.HidesTopSkin[equipSlotBody] = true; + ArmorIDs.Body.Sets.HidesArms[equipSlotBody] = true; + ArmorIDs.Legs.Sets.HidesBottomSkin[equipSlotLegs] = 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() { + 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 0000000..2394e29 Binary files /dev/null and b/Content/Transformations/BigChill/BigChill.png differ diff --git a/Content/Transformations/BigChill/BigChillUltimate_Body.png b/Content/Transformations/BigChill/BigChillUltimate_Body.png new file mode 100644 index 0000000..bb02160 Binary files /dev/null and b/Content/Transformations/BigChill/BigChillUltimate_Body.png differ diff --git a/Content/Transformations/BigChill/BigChillUltimate_Head.png b/Content/Transformations/BigChill/BigChillUltimate_Head.png new file mode 100644 index 0000000..2d684a6 Binary files /dev/null and b/Content/Transformations/BigChill/BigChillUltimate_Head.png differ diff --git a/Content/Transformations/BigChill/BigChillUltimate_Legs.png b/Content/Transformations/BigChill/BigChillUltimate_Legs.png new file mode 100644 index 0000000..204e2f5 Binary files /dev/null and b/Content/Transformations/BigChill/BigChillUltimate_Legs.png differ diff --git a/Content/Transformations/BigChill/BigChill_Body.png b/Content/Transformations/BigChill/BigChill_Body.png new file mode 100644 index 0000000..355c3b2 Binary files /dev/null and b/Content/Transformations/BigChill/BigChill_Body.png differ diff --git a/Content/Transformations/BigChill/BigChill_Head.png b/Content/Transformations/BigChill/BigChill_Head.png new file mode 100644 index 0000000..7a5297e Binary files /dev/null and b/Content/Transformations/BigChill/BigChill_Head.png differ diff --git a/Content/Transformations/BigChill/BigChill_Legs.png b/Content/Transformations/BigChill/BigChill_Legs.png new file mode 100644 index 0000000..c3db3c4 Binary files /dev/null and b/Content/Transformations/BigChill/BigChill_Legs.png differ 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 0000000..d0b9f35 Binary files /dev/null and b/Content/Transformations/DiamondHead/DiamondHeadAlt_Body.png differ diff --git a/Content/Transformations/DiamondHead/DiamondHeadAlt_Legs.png b/Content/Transformations/DiamondHead/DiamondHeadAlt_Legs.png new file mode 100644 index 0000000..eb6a066 Binary files /dev/null and b/Content/Transformations/DiamondHead/DiamondHeadAlt_Legs.png differ 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 0000000..2394e29 Binary files /dev/null and b/Content/Transformations/EyeGuy/EyeGuy.png differ diff --git a/Content/Transformations/EyeGuy/EyeGuy_Body.png b/Content/Transformations/EyeGuy/EyeGuy_Body.png new file mode 100644 index 0000000..5c66233 Binary files /dev/null and b/Content/Transformations/EyeGuy/EyeGuy_Body.png differ diff --git a/Content/Transformations/EyeGuy/EyeGuy_Head.png b/Content/Transformations/EyeGuy/EyeGuy_Head.png new file mode 100644 index 0000000..f34c3ab Binary files /dev/null and b/Content/Transformations/EyeGuy/EyeGuy_Head.png differ diff --git a/Content/Transformations/EyeGuy/EyeGuy_Legs.png b/Content/Transformations/EyeGuy/EyeGuy_Legs.png new file mode 100644 index 0000000..095b404 Binary files /dev/null and b/Content/Transformations/EyeGuy/EyeGuy_Legs.png differ diff --git a/Content/Transformations/GhostFreak/GhostFreak_Head.png b/Content/Transformations/GhostFreak/GhostFreak_Head.png index 7d416c3..649c591 100644 Binary files a/Content/Transformations/GhostFreak/GhostFreak_Head.png and b/Content/Transformations/GhostFreak/GhostFreak_Head.png differ 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 0000000..35860c8 Binary files /dev/null and b/Content/Transformations/HeatBlast/HeatBlastAlt_Body.png differ diff --git a/Content/Transformations/HeatBlast/HeatBlastAlt_Head.png b/Content/Transformations/HeatBlast/HeatBlastAlt_Head.png new file mode 100644 index 0000000..afc34d7 Binary files /dev/null and b/Content/Transformations/HeatBlast/HeatBlastAlt_Head.png differ diff --git a/Content/Transformations/HeatBlast/HeatBlastAlt_Legs.png b/Content/Transformations/HeatBlast/HeatBlastAlt_Legs.png new file mode 100644 index 0000000..53dd81d Binary files /dev/null and b/Content/Transformations/HeatBlast/HeatBlastAlt_Legs.png differ 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/Effects/Microsoft.Xna.Framework.Content.Pipeline.EffectImporter.dll b/Effects/Microsoft.Xna.Framework.Content.Pipeline.EffectImporter.dll new file mode 100644 index 0000000..61f52fa Binary files /dev/null and b/Effects/Microsoft.Xna.Framework.Content.Pipeline.EffectImporter.dll differ diff --git a/Effects/Microsoft.Xna.Framework.Content.Pipeline.dll b/Effects/Microsoft.Xna.Framework.Content.Pipeline.dll new file mode 100644 index 0000000..a70e412 Binary files /dev/null and b/Effects/Microsoft.Xna.Framework.Content.Pipeline.dll differ diff --git a/Effects/MyDyes.fx b/Effects/MyDyes.fx new file mode 100644 index 0000000..c3aa65a --- /dev/null +++ b/Effects/MyDyes.fx @@ -0,0 +1,35 @@ +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 BasicTint(float4 sampleColor : COLOR0, float2 coords : TEXCOORD0) : COLOR0 +{ + float4 color = tex2D(uImage0, coords); + float luminosity = (color.r + color.g + color.b) / 3; + color.rgb = uColor * luminosity; + return color * sampleColor; +} + +technique Technique1 +{ + pass BasicTint + { + PixelShader = compile ps_2_0 BasicTint(); + } +} \ No newline at end of file diff --git a/Effects/MyDyes.xnb b/Effects/MyDyes.xnb new file mode 100644 index 0000000..d3e6c34 Binary files /dev/null and b/Effects/MyDyes.xnb differ diff --git a/Effects/MyFilters.fx b/Effects/MyFilters.fx new file mode 100644 index 0000000..dea15f3 --- /dev/null +++ b/Effects/MyFilters.fx @@ -0,0 +1,56 @@ +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 Grayscale(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; +} + +float4 FrostyScreen(float4 sampleColor : COLOR0, float2 uv : TEXCOORD0) : COLOR0 +{ + float4 color = tex2D(uImage0, uv); + + float3 blueTint = float3(0.7, 0.85, 1.25); + color.rgb *= blueTint; + + return color * sampleColor; +} + +technique Technique1 +{ + pass Grayscale + { + 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 new file mode 100644 index 0000000..ae4c2b4 Binary files /dev/null and b/Effects/MyFilters.xnb differ diff --git a/Effects/fxcompiler.exe b/Effects/fxcompiler.exe new file mode 100644 index 0000000..cfc1dbb Binary files /dev/null and b/Effects/fxcompiler.exe differ diff --git a/Enums/TranformationEnum.cs b/Enums/TranformationEnum.cs index 7984744..7d32639 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; @@ -9,6 +8,7 @@ using System.Reflection; using System.Text; using System.Threading.Tasks; +using Terraria; using Terraria.ModLoader; namespace Ben10Mod.Enums @@ -25,7 +25,9 @@ public enum TransformationEnum { RipJaws = 8, StinkFly = 9, WildVine = 10, - XLR8 = 11 + XLR8 = 11, + EyeGuy = 12, + BigChill = 13, } static class TransformationMethods { @@ -51,6 +53,10 @@ public static int GetTransformation(this TransformationEnum te) { return ModContent.BuffType(); case TransformationEnum.XLR8: return ModContent.BuffType(); + case TransformationEnum.EyeGuy: + return ModContent.BuffType(); + case TransformationEnum.BigChill: + return ModContent.BuffType(); default: return -1; } } @@ -77,6 +83,10 @@ public static string GetName(this TransformationEnum te) { return "Wildvine"; case TransformationEnum.XLR8: return "XLR8"; + case TransformationEnum.EyeGuy: + return "Eye Guy"; + case TransformationEnum.BigChill: + return "Bigchill"; default: return "None"; } @@ -102,11 +112,309 @@ 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.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"); } } + + 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" } + }; + } + + 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 false; + } + } + + 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 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/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 263f4f3..3a5c240 100644 --- a/Localization/en-US_Mods.Ben10Mod.hjson +++ b/Localization/en-US_Mods.Ben10Mod.hjson @@ -146,29 +146,129 @@ Items: { Tooltip: "" } - PlumberHelperBadge: { + PlumberAgentBadge: { Tooltip: "" - DisplayName: Plumber Helper Badge + DisplayName: Plumbers Agent Badge } - ProvisionalAgentBadgeCrimtane: { - DisplayName: Provisional Agent Badge + PlumberCapsulePodItem: { + DisplayName: Plumber Capsule Pod Item Tooltip: "" } - ProvisionalAgentBadgeDemonite: { - DisplayName: Provisional Agent Badge + AdvancedCircuitMatrix: { + DisplayName: Advanced Circuit Matrix + Tooltip: Doubles Transformation and Cooldown times for the prototype omnitrix + } + + PlumberMagisterBadge: { + DisplayName: Plumbers Magister Badge Tooltip: "" } - PlumberAgentBadge: { + MasterControlKey: { Tooltip: "" - DisplayName: Plumber Agent Badge + DisplayName: Master Control Key } - PlumberCapsulePodItem: { - DisplayName: Plumber Capsule Pod Item + EyeGuy: { + Tooltip: "" + DisplayName: Eye Guy + } + + HeroEmblem: { + Tooltip: "" + DisplayName: Hero Emblem + } + + HeatBlastExtraJumpAccessory: { + DisplayName: Heat Blast Extra Jump Accessory + Tooltip: "" + } + + PlumberCadetBadge: { + DisplayName: Plumbers Cadet Badge + Tooltip: "" + } + + PlumberDeputyBadgeCrimtane: { + DisplayName: Plumbers Deputy Badge Crimtane + Tooltip: "" + } + + PlumberDeputyBadgeDemonite: { + DisplayName: Plumbers Deputy Badge Demonite + Tooltip: "" + } + + SnowFlake: { + DisplayName: Snow Flake + Tooltip: "" + } + + Snowflake: { + DisplayName: Snowflake + Tooltip: "" + } + + PlumberSeniorDeputyBadge: { + Tooltip: "" + DisplayName: Plumber Senior Deputy Badge + } + + HeavenlyCrystallineBadge: { + DisplayName: Heavenly Crystalline Badge + Tooltip: "" + } + + PlumberSeniorAgentBadge: { + DisplayName: Plumber Senior Agent Badge + Tooltip: "" + } + + PlumberProctorBadge: { Tooltip: "" + DisplayName: Plumber Proctor Badge + } + + PlumberMagistrataBadge: { + Tooltip: "" + DisplayName: Plumber Magistrata Badge + } + + PlumberFieldProctorBadge: { + Tooltip: "" + DisplayName: Plumber Field Proctor Badge + } + + HeroFragment: { + Tooltip: "" + DisplayName: Hero Fragment + } + + DiscoDye: { + DisplayName: Disco Dye + Tooltip: "" + } + + BigChill: { + Tooltip: "" + DisplayName: Big Chill + } + + BigChillWings: { + DisplayName: Big Chill Wings + Tooltip: "" + } + + Ultimatrix: { + Tooltip: "" + DisplayName: Ultimatrix + } + + UltimateBigChillWings: { + Tooltip: "" + DisplayName: Ultimate Big Chill Wings } } @@ -193,6 +293,7 @@ Keybinds: { "Quinary Ability.DisplayName": Quinary Ability "Quaternary Ability.DisplayName": Quaternary Ability "Tertiary Ability.DisplayName": Tertiary Ability + "Ultimate Ability.DisplayName": Ultimate Ability } Buffs: { @@ -246,69 +347,59 @@ 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 + TransformationCooldown_Buff: { + Description: Timeout + DisplayName: Cannot transform while timed out } - HeatBlast_Primary_Cooldown_Buff: { - DisplayName: Heatblast Flame Aura Cooldown - Description: Heatblast Flame Aura Cooldown + EnemySlow: { + Description: Mods.Ben10Mod.Buffs.EnemySlow.Description + DisplayName: Enemy Slow } - DiamondHead_Primary_Buff: { - DisplayName: Diamondhead Primary Ability - Description: Immune to damage but unable to move + EyeGuy_Buff: { + Description: Mods.Ben10Mod.Buffs.EyeGuy_Buff.Description + DisplayName: Opticoid } - DiamondHead_Primary_Cooldown_Buff: { - DisplayName: Diamondhead Primary Cooldown - Description: Cooldown for primary ability + UltimateAbility_Cooldown: { + DisplayName: Ultimate Ability Cooldown + Description: Ultimate Ability Cooldown } - ChromaStone_Primary_Buff: { - DisplayName: Chromastone Primary Ability - Description: Absorb and redirect incoming damage + OmnitrixUpdating: { + Description: Omnitrix is undergoing updates + DisplayName: Omnitrix Updating } - ChromaStone_Primary_Cooldown_Buff: { - DisplayName: Chromastone Primary Cooldown - Description: Cooldown for primary ability + PrimaryAbility: { + DisplayName: Primary Ability + Description: Primary Ability Activated } - TransformationCooldown_Buff: { - Description: Timeout - DisplayName: Cannot transform while timed out + PrimaryAbilityCooldown: { + DisplayName: Primary Ability Cooldown + Description: Primary Ability On Cooldown } - BuzzShock_Primary_Buff: { - DisplayName: Buzz Shock_ Primary_ Buff - Description: Mods.Ben10Mod.Buffs.BuzzShock_Primary_Buff.Description + BuzzShockMinionBuff: { + DisplayName: Buzz Shock Minion Buff + Description: Mods.Ben10Mod.Buffs.BuzzShockMinionBuff.Description } - BuzzShock_Primary_Cooldown_Buff: { - DisplayName: Buzz Shock_ Primary_ Cooldown_ Buff - Description: Mods.Ben10Mod.Buffs.BuzzShock_Primary_Cooldown_Buff.Description + UltimateAbilityCooldown: { + Description: Mods.Ben10Mod.Buffs.UltimateAbilityCooldown.Description + DisplayName: Ultimate Ability Cooldown } - EnemySlow: { - Description: Mods.Ben10Mod.Buffs.EnemySlow.Description - DisplayName: Enemy Slow + UltimateAbility: { + Description: Mods.Ben10Mod.Buffs.UltimateAbility.Description + DisplayName: Ultimate Ability } - GhostFreakPossesion: { - DisplayName: Ghost Freak Possesion - Description: Mods.Ben10Mod.Buffs.GhostFreakPossesion.Description + BigChill_Buff: { + Description: Mods.Ben10Mod.Buffs.BigChill_Buff.Description + DisplayName: Big Chill_ Buff } } @@ -332,6 +423,16 @@ 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 + GiantDiamondProjectile.DisplayName: Giant Diamond Projectile + 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 + RipJawsBiteProjectile.DisplayName: Rip Jaws Bite Projectile + GhostFreakShadowProjectile.DisplayName: Ghost Freak Shadow Projectile } Tiles: { diff --git a/NpcEffects.cs b/NpcEffects.cs new file mode 100644 index 0000000..ed4c242 --- /dev/null +++ b/NpcEffects.cs @@ -0,0 +1,57 @@ +using Ben10Mod.Content.Buffs.Abilities; +using Ben10Mod.Content.Buffs.Debuffs; +using Ben10Mod.Enums; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; + +namespace Ben10Mod; + +public class NpcEffects : GlobalNPC { + public override bool InstancePerEntity => true; + + public bool IsPossessed(NPC npc) { + foreach (Player p in Main.ActivePlayers) { + var omp = p.GetModPlayer(); + if (omp.inPossessionMode && omp.possessedTargetIndex == npc.whoAmI) return true; + } + 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) { + var omp = Main.LocalPlayer.GetModPlayer(); + + if (IsPossessed(npc)) { + npc.velocity *= 0.68f; + } + + if (omp.currTransformation == TransformationEnum.BigChill && omp.UltimateAbilityEnabled && npc.active && !npc.friendly) { + npc.AddBuff(ModContent.BuffType(), 120); + } + } + + 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/OmnitrixItem.cs b/OmnitrixItem.cs index d826330..ddd04be 100644 --- a/OmnitrixItem.cs +++ b/OmnitrixItem.cs @@ -11,16 +11,19 @@ namespace Ben10Mod { public class OmnitrixItem : GlobalItem { - public override void ModifyItemLoot(Item item, ItemLoot itemLoot) { - //if (item.type == ItemID.SkeletronBossBag) { - // foreach (var rule in itemLoot.Get()) { - // if (rule is OneFromOptionsNotScaledWithLuckDropRule oneFromOptionsDrop) { - // var original = oneFromOptionsDrop.dropIds.ToList(); - // original.Add(ModContent.ItemType()); - // 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 71a9fd6..dff5a13 100644 --- a/OmnitrixPlayer.cs +++ b/OmnitrixPlayer.cs @@ -1,8 +1,8 @@ -using Ben10Mod.Content.Transformations.XLR8; -using Ben10Mod.Keybinds; +using Ben10Mod.Keybinds; using System; using Microsoft.Xna.Framework; using System.Collections.Generic; +using System.Linq; using Terraria; using Terraria.ID; using Terraria.ModLoader; @@ -11,11 +11,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; @@ -23,39 +19,42 @@ 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 Microsoft.Xna.Framework.Input; +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; +using Terraria.Graphics.Shaders; -namespace Ben10Mod -{ +namespace Ben10Mod { 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 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 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 ultimateForm = false; + + public int cooldownTime = 120; + public int transformationTime = 300; + + 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; @@ -71,84 +70,98 @@ public class OmnitrixPlayer : ModPlayer { public const int DashCooldown = 15; public const int DashDuration = 15; - public bool isPerformingHeatBlastDoubleJump; + public TransformationEnum[] transformations = { + TransformationEnum.HeatBlast, TransformationEnum.None, TransformationEnum.None, + TransformationEnum.None, TransformationEnum.None + }; - 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}; - - // 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 List unlockedTransformation = new List() + { TransformationEnum.HeatBlast }; + + public bool showingUI = false; + + public bool omnitrixUpdating = false; + public bool omnitrixWasUpdating = false; + public float omnitrixEnergy = 0f; + public float omnitrixEnergyMax = 0f; + public float omnitrixEnergyRegen = 0f; + public bool inPossessionMode = false; - public Vector2 prePossessionPosition = Vector2.Zero; // Save player's position before possession - public NPC possessedTarget = null; + public Vector2 prePossessionPosition = Vector2.Zero; + public int possessedTargetIndex = -1; public int possessionTimer = 0; - private const int PossessionDuration = 360; // 6 seconds + private const int PossessionDuration = 360; - public Color GetChromaStoneOverlayColor() - { - return Color.Lerp(colours[thisColour], colours[nextColour], colourAmount); - } + public bool snowflake = false; + public bool advancedCircuitMatrix = false; + public bool advancedCircuitMatrixEquippedWhileTransformed = false; public override void SaveData(TagCompound tag) { - 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; + tag["omnitrixEnergy"] = omnitrixEnergy; + + tag["roster"] = transformations.Select(t => (int)t).ToArray(); + + tag["unlockedRoster"] = unlockedTransformation + .Where(t => t != TransformationEnum.None) + .Select(t => (int)t) + .ToArray(); } public override void LoadData(TagCompound tag) { - 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; + omnitrixEnergy = tag.TryGet("omnitrixEnergy", out omnitrixEnergy) ? omnitrixEnergy : 0f; + + 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]); - } - } + + 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); + + if (!unlockedTransformation.Contains(TransformationEnum.HeatBlast)) + unlockedTransformation.Insert(0, TransformationEnum.HeatBlast); } public override void ResetEffects() { + advancedCircuitMatrix = false; + snowflake = false; + + cooldownTime = 120; + transformationTime = 300; + omnitrixEnergyMax = 0; + 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; + UltimateAbilityEnabled = false; // Handle dashing if (Player.controlDown && Player.releaseDown && Player.doubleTapCardinalTimer[DashDown] < 15) { @@ -171,48 +184,70 @@ 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 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 { + if (omnitrixSlot.FunctionalItem.type == ModContent.ItemType()) + TransformationHandler.Detransform(Player, ModContent.GetInstance().TimeoutDuration); + if (omnitrixSlot.FunctionalItem.type == ModContent.ItemType()) + TransformationHandler.Detransform(Player, 0, addCooldown: false); } } - wasTransformed = false; + + wasTransformed = isTransformed; } - + + 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; } - + 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; } - 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; } } @@ -221,7 +256,7 @@ public override void PostUpdateBuffs() { // Heatblast Transformation if (currTransformation == TransformationEnum.HeatBlast) { - Player.fireWalk = true; + Player.fireWalk = true; Player.lavaImmune = true; } @@ -229,37 +264,45 @@ public override void PostUpdateBuffs() { if (currTransformation == TransformationEnum.DiamondHead) { - Player.statDefense += 25; - Player.GetDamage(DamageClass.Melee) *= 1.25f; - Player.GetDamage() *= 1.25f; + Player.statDefense += 20; + Player.wingTimeMax = 0; + Player.wingTime = 0; - if (DiamondHeadPrimaryAbilityEnabled) { - Player.moveSpeed = 0; - Player.lifeRegen += 10; - Player.immune = true; - Player.immuneAlpha = 0; - Player.releaseJump = false; + if (PrimaryAbilityEnabled) { + Player.moveSpeed /= 10; + Player.lifeRegen += 15; + Player.statDefense *= 1.5f; + Player.releaseJump = false; + Player.gravity *= 2f; } } // Ripjaws Transformation if (currTransformation == TransformationEnum.RipJaws) { - if (Player.wet) { - Player.merman = true; - Player.breathCD = 0; - Player.breath = Player.breathMax; + 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; + Player.accFlipper = true; + } // Chromastone Transformation - if (currTransformation == TransformationEnum.ChromaStone) { - } + if (currTransformation == TransformationEnum.ChromaStone) { } // Buzzshock Transformation @@ -268,20 +311,16 @@ 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.noFallDmg = true; - Player.jumpSpeed *= 1.75f; + Player.GetAttackSpeed(DamageClass.Melee) += 0.25f; + Player.GetCritChance(DamageClass.Generic) = 50; + Player.noFallDmg = true; + Player.jumpSpeed *= 1.9f; } // Stinkfly Transformation - if (currTransformation == TransformationEnum.StinkFly) { - } - + if (currTransformation == TransformationEnum.StinkFly) { } + // Ghostfreak Transformation if (currTransformation == TransformationEnum.GhostFreak) { @@ -290,47 +329,41 @@ public override void PostUpdateBuffs() { // Wildvine Transformation - if (currTransformation == TransformationEnum.WildVine) { - } + if (currTransformation == TransformationEnum.WildVine) { } } - + public override void PostUpdate() { - + var abilitySlot = ModContent.GetInstance(); if (!isTransformed) { abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } - // Handles the detransformation effect + omnitrixEnergy += (omnitrixEnergyRegen / 120); - 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 (omnitrixEnergy > omnitrixEnergyMax) omnitrixEnergy = omnitrixEnergyMax; + + if (KeybindSystem.OpenTransformationScreen.JustPressed && omnitrixEquipped) { + if (!showingUI) { + ModContent.GetInstance().ShowMyUI(); + showingUI = true; + } + else { + ModContent.GetInstance().HideMyUI(); + showingUI = false; } - wasTransformed = false; } - - // XLR8 Transformation - if (currTransformation == TransformationEnum.XLR8) { + if (Main.mouseRight && Main.mouseRightRelease && Player.HeldItem.ModItem is PlumbersBadge) { + altAttack = !altAttack; + } - 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); - } + // XLR8 Transformation + + if (currTransformation == TransformationEnum.XLR8) { abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } @@ -338,46 +371,44 @@ 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())) { - Player.AddBuff(ModContent.BuffType(), 60 * 60); - } - } - if (HeatBlastPrimaryAbilityEnabled) { - Vector2[] points = GenerateCirclePoints(250, 10 * (16)); + + 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.OnFire)) { - npc.AddBuff(BuffID.OnFire, 10 * 60); + if (!npc.HasBuff(BuffID.Frostburn2) && snowflake) { + npc.AddBuff(BuffID.Frostburn2, 10 * 60); + } + 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()); - } - - if (HeatBlastPrimaryAbilityEnabled != HeatBlastPrimaryAbilityWasEnabled) { - HeatBlastPrimaryAbilityWasEnabled = false; - Player.AddBuff(ModContent.BuffType(), 10 * 60); + 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())) { - Player.AddBuff(ModContent.BuffType(), 5 * 60); - } + 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()); @@ -386,62 +417,49 @@ public override void PostUpdate() { // Ripjaws Transformation if (currTransformation == TransformationEnum.RipJaws) { - abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } // 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); - } - } - - if (ChromaStonePrimaryAbilityEnabled) - { - Lighting.AddLight(Player.Center, GetChromaStoneOverlayColor().ToVector3()); + 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 && !Player.HasBuff(BuffID.ChaosState)) { + if (PrimaryAbilityEnabled) { if (Main.myPlayer == Player.whoAmI) { 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; } - - Player.AddBuff(BuffID.ChaosState, 60 * 6); } } abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } - if (BuzzShockPrimaryAbilityEnabled != BuzzShockPrimaryAbilityWasEnabled) { - BuzzShockPrimaryAbilityWasEnabled = false; - Player.AddBuff(ModContent.BuffType(), 10 * 60); - } - // Fourarms Transformation if (currTransformation == TransformationEnum.FourArms) { @@ -453,34 +471,10 @@ 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) { // 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; - } - abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } @@ -490,23 +484,30 @@ public override void PostUpdate() { abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); } - if (inPossessionMode) - { - if (possessedTarget == null || !possessedTarget.active || currTransformation != TransformationEnum.GhostFreak ) - { - EndPossession(); // Safety: end if target dies/missing + // Bigchill Transformation + + if (currTransformation == TransformationEnum.BigChill) { + abilitySlot.FunctionalItem = new Item(ModContent.ItemType()); + } + + if (inPossessionMode) { + if (possessedTargetIndex < 0 || possessedTargetIndex >= Main.maxNPCs) { + EndPossession(); return; } - - // Sync player to possessed NPC's center (camera follows player naturally) + + 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; - // Optional: Sync some velocity for "riding" feel (but keep player locked) - Player.velocity = possessedTarget.velocity * 0.8f; // Slight lag for smoothness + Player.velocity = npc.velocity * 0.8f; - // Lock controls to prevent input interference Player.controlJump = false; Player.controlDown = false; Player.controlLeft = false; @@ -517,28 +518,115 @@ public override void PostUpdate() { Player.controlHook = false; possessionTimer--; - if (possessionTimer <= 0) { - possessedTarget.SimpleStrikeNPC(Player.HeldItem.damage, Player.direction, false, 0, DamageClass.Magic); + npc.SimpleStrikeNPC(Player.HeldItem.damage * 2, Player.direction, false, 0, + DamageClass.Magic); EndPossession(); } } + + if (isTransformed) { + 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 (isTransformed) { + if (KeybindSystem.PrimaryAbility.JustPressed && currTransformation.HasPrimaryAbility()) { + ActivatePrimaryAbility(); + } + } + + 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; + 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; + } + + 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) { - return !(currTransformation == TransformationEnum.GhostFreak && KeybindSystem.PrimaryAbility.Current); + if (Player.whoAmI != Main.myPlayer) return false; + return !((currTransformation == TransformationEnum.GhostFreak || currTransformation == TransformationEnum.BigChill) && PrimaryAbilityEnabled); } public override bool CanBeHitByNPC(NPC npc, ref int cooldownSlot) { - return !(currTransformation == TransformationEnum.GhostFreak && KeybindSystem.PrimaryAbility.Current); + if (Player.whoAmI != Main.myPlayer) return false; + return !((currTransformation == TransformationEnum.GhostFreak || currTransformation == TransformationEnum.BigChill) && PrimaryAbilityEnabled); } public override bool CanBeHitByProjectile(Projectile proj) { - return !(currTransformation == TransformationEnum.GhostFreak && KeybindSystem.PrimaryAbility.Current); + if (Player.whoAmI != Main.myPlayer) return false; + return !((currTransformation == TransformationEnum.GhostFreak || currTransformation == TransformationEnum.BigChill) && PrimaryAbilityEnabled); } public override void OnHurt(Player.HurtInfo info) { - if (ChromaStonePrimaryAbilityEnabled) { + if (PrimaryAbilityEnabled && currTransformation == TransformationEnum.ChromaStone) { ChromaStoneAbsorbtion += Math.Max(info.Damage / 5, 0); } @@ -546,17 +634,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.OnFire) && currTransformation == TransformationEnum.HeatBlast) { - Main.npc[victim.whoAmI].AddBuff(BuffID.OnFire, 3 * 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); + } } } 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); @@ -569,31 +662,36 @@ 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; 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; break; case TransformationEnum.GhostFreak when inPossessionMode: - Player.invis = true; + 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: break; - case TransformationEnum.ChromaStone when ChromaStonePrimaryAbilityEnabled: - Color overlayColor = GetChromaStoneOverlayColor(); - drawInfo.colorArmorHead = overlayColor; - drawInfo.colorArmorBody = overlayColor; - drawInfo.colorArmorLegs = overlayColor; + case TransformationEnum.ChromaStone when PrimaryAbilityEnabled: + Color overlayColor = Main.DiscoColor; + // drawInfo.colorArmorHead = overlayColor; + // drawInfo.colorArmorBody = overlayColor; + // drawInfo.colorArmorLegs = overlayColor; break; case TransformationEnum.DiamondHead: case TransformationEnum.FourArms: @@ -601,16 +699,17 @@ public override void ModifyDrawInfo(ref PlayerDrawSet drawInfo) { case TransformationEnum.StinkFly: case TransformationEnum.WildVine: case TransformationEnum.XLR8: + case TransformationEnum.EyeGuy: case TransformationEnum.None: break; - default: - throw new ArgumentOutOfRangeException(); } } // 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(); @@ -618,7 +717,11 @@ 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 { @@ -638,12 +741,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; } } @@ -657,7 +760,11 @@ 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 { @@ -677,6 +784,7 @@ public override void FrameEffects() { } } } + if (!customSlot.HideVisuals) { if (isTransformed) { Player.wings = -1; @@ -684,19 +792,31 @@ public override void FrameEffects() { Player.handoff = -1; Player.handon = -1; Player.back = -1; + Player.waist = -1; + Player.shield = -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 (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) { var costume = ModContent.GetInstance(); Player.head = EquipLoader.GetEquipSlot(Mod, costume.Name, EquipType.Head); @@ -704,12 +824,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; @@ -720,57 +842,116 @@ 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(); - 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(); 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 (XLR8PrimaryAbilityEnabled) { + 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); 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); + } + + if (currTransformation == TransformationEnum.BigChill) { + var costume = ModContent.GetInstance(); + 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); + } } } public override void PreUpdateMovement() { DashMovement(); + + 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; + if (Player.controlUp) input.Y -= 1f; + if (Player.controlDown) input.Y += 1f; + + const float speed = 14.5f; + const float damp = 0.82f; + + if (input != Vector2.Zero) { + input.Normalize(); + Vector2 move = input * speed; + + if (input.Y < 0) move.Y -= 3f; + + Player.position += move; + } + else { + Player.velocity *= damp; + Player.position += Player.velocity; + } + + Player.velocity = Vector2.Zero; + } } private void DashMovement() { @@ -782,56 +963,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() { @@ -840,73 +1014,114 @@ public override void OnEnterWorld() { currTransformation = TransformationEnum.None; } } - - private void EndPossession() - { - if (!inPossessionMode) return; - inPossessionMode = false; - possessedTarget = null; + private void EndPossession() { + if (!inPossessionMode) return; - // Snap player back to pre-possession position + inPossessionMode = false; + possessedTargetIndex = -1; + 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 && !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) { + 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 (colourAmount >= 1.0f) { - thisColour++; - nextColour++; - colourAmount = 0.0f; + 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 (thisColour >= colours.Length) { - thisColour = 0; + if (UltimateAbilityEnabled && Main.netMode != NetmodeID.Server && + currTransformation == TransformationEnum.BigChill) { + if (!Filters.Scene["Ben10Mod:Bluescale"].IsActive()) { + Filters.Scene.Activate("Ben10Mod:Bluescale"); + } } - if (nextColour >= colours.Length) { - nextColour = 0; + else if (Filters.Scene["Ben10Mod:Bluescale"].IsActive()) { + Filters.Scene.Deactivate("Ben10Mod:Bluescale"); } - colourAmount += 0.1f; + 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); + } + } + 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) { + 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); + packet.Write((int)transformation); + packet.Send(toClient: Player.whoAmI); + } + } } } -} +} \ No newline at end of file diff --git a/OmnitrixProjectile.cs b/OmnitrixProjectile.cs new file mode 100644 index 0000000..9b9ba33 --- /dev/null +++ b/OmnitrixProjectile.cs @@ -0,0 +1,65 @@ +using Ben10Mod.Content.Items.Weapons; +using Ben10Mod.Content.Projectiles; +using Ben10Mod.Enums; +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; + 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; + initialVelocity = projectile.velocity; + } + } + + 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 AI(Projectile projectile) { + framesAlive++; + if (projectile.owner == Main.LocalPlayer.whoAmI) { + var omp = Main.LocalPlayer.GetModPlayer(); + if (omp.UltimateAbilityEnabled && omp.currTransformation == TransformationEnum.XLR8) { + projectile.velocity = initialVelocity * (1 - framesAlive / 60f); + if (framesAlive >= 60) projectile.velocity = initialVelocity.SafeNormalize(Vector2.Zero); + projectileSlowed = true; + } + else if (projectileSlowed) projectile.velocity = initialVelocity * 2f; + } + } + + 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 new file mode 100644 index 0000000..01c3cf7 --- /dev/null +++ b/ShopNPC.cs @@ -0,0 +1,73 @@ +using System.Linq; +using Ben10Mod.Content.Items.Accessories; +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; +using Terraria.Localization; +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()); + } + } + + public override void ModifyNPCLoot(NPC npc, NPCLoot npcLoot) { + if (npc.type == NPCID.Plantera) { + npcLoot.Add(ItemDropRule.ByCondition(new Conditions.IsExpert(), + ModContent.ItemType(), + 10 + )); + } + + 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 + && 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() + )); + } + + if (npc.type == NPCID.QueenSlimeBoss) { + npcLoot.Add(ItemDropRule.BossBagByCondition(new NotNormalMode(), ModContent.ItemType())); + npcLoot.Add(ItemDropRule.ByCondition(new IsNormalMode(), ModContent.ItemType(), 10, 0)); + } + } +} + +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 diff --git a/OmnitrixNPC.cs b/bossTrackerNPC.cs similarity index 51% rename from OmnitrixNPC.cs rename to bossTrackerNPC.cs index 4bdb75a..1de7909 100644 --- a/OmnitrixNPC.cs +++ b/bossTrackerNPC.cs @@ -1,5 +1,6 @@ using System.Runtime.CompilerServices; using Ben10Mod.Content; +using Ben10Mod.Content.Buffs.Abilities; using Ben10Mod.Enums; using Microsoft.Xna.Framework; using Terraria; @@ -7,8 +8,7 @@ using Terraria.ModLoader; namespace Ben10Mod { - public class OmnitrixNPC : 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 OmnitrixNPC : 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,23 +55,54 @@ 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; 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; + + 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]; // 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 @@ -84,75 +111,92 @@ public override void OnKill(NPC npc) switch (npc.type) { case NPCID.KingSlime: { - Main.player[credited].GetModPlayer() - .addTransformation(TransformationEnum.DiamondHead); + player.GetModPlayer() + .AddTransformation(TransformationEnum.DiamondHead); break; } case NPCID.EyeofCthulhu: { - Main.player[credited].GetModPlayer() - .addTransformation(TransformationEnum.XLR8); + player.GetModPlayer() + .AddTransformation(TransformationEnum.XLR8); break; } case NPCID.BrainofCthulhu: { - Main.player[credited].GetModPlayer() - .addTransformation(TransformationEnum.FourArms); + player.GetModPlayer() + .AddTransformation(TransformationEnum.FourArms); break; } case NPCID.EaterofWorldsHead: case NPCID.EaterofWorldsTail: case NPCID.EaterofWorldsBody: { - Main.player[credited].GetModPlayer() - .addTransformation(TransformationEnum.FourArms); + player.GetModPlayer() + .AddTransformation(TransformationEnum.FourArms); break; } case NPCID.QueenBee: { - Main.player[credited].GetModPlayer() - .addTransformation(TransformationEnum.StinkFly); + player.GetModPlayer() + .AddTransformation(TransformationEnum.StinkFly); break; } case NPCID.SkeletronHead: { - Main.player[credited].GetModPlayer() - .addTransformation(TransformationEnum.BuzzShock); + player.GetModPlayer() + .AddTransformation(TransformationEnum.BuzzShock); break; } case NPCID.Deerclops: { - Main.player[credited].GetModPlayer() - .addTransformation(TransformationEnum.WildVine); + player.GetModPlayer() + .AddTransformation(TransformationEnum.WildVine); break; } case NPCID.WallofFlesh: { - Main.player[credited].GetModPlayer() - .addTransformation(TransformationEnum.ChromaStone); + if (player.GetModPlayer().prototypeOmnitrix) { + TransformationHandler.Detransform(player, 120); + player.AddBuff(ModContent.BuffType(), 120 * 60); + } break; } + case NPCID.QueenSlimeBoss: { + player.GetModPlayer() + .AddTransformation(TransformationEnum.ChromaStone); + break; + } + case NPCID.Retinazer: + case NPCID.Spazmatism: + player.GetModPlayer().AddTransformation(TransformationEnum.EyeGuy); + break; + case NPCID.IceQueen: + player.GetModPlayer().AddTransformation(TransformationEnum.BigChill); + 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) diff --git a/build.txt b/build.txt index 775986b..c768228 100644 --- a/build.txt +++ b/build.txt @@ -1,3 +1,8 @@ displayName = Terraria 10 (Ben 10 mod) author = DestroyerMob -version = 0.061 \ No newline at end of file +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 +includeSource = false +includePDB = true \ No newline at end of file diff --git a/icon_workshop.png b/icon_workshop.png index 321ecb3..6f9aacf 100644 Binary files a/icon_workshop.png and b/icon_workshop.png differ