From faedafac3d7a21984551f6d2c0c80cdf4eb3934a Mon Sep 17 00:00:00 2001 From: YouHaveTrouble Date: Sat, 3 Dec 2022 14:53:59 +0100 Subject: [PATCH 1/4] toclafane --- Buffs/ToclafaneMinionBuff.cs | 24 +++ Buffs/ToclafaneMinionBuff.png | Bin 0 -> 483 bytes Items/ToclafaneStaff.cs | 44 +++++ Items/ToclafaneStaff.png | Bin 0 -> 338 bytes Projectiles/Weapons/ToclafaneMinion.cs | 220 ++++++++++++++++++++++++ Projectiles/Weapons/ToclafaneMinion.png | Bin 0 -> 483 bytes 6 files changed, 288 insertions(+) create mode 100644 Buffs/ToclafaneMinionBuff.cs create mode 100644 Buffs/ToclafaneMinionBuff.png create mode 100644 Items/ToclafaneStaff.cs create mode 100644 Items/ToclafaneStaff.png create mode 100644 Projectiles/Weapons/ToclafaneMinion.cs create mode 100644 Projectiles/Weapons/ToclafaneMinion.png diff --git a/Buffs/ToclafaneMinionBuff.cs b/Buffs/ToclafaneMinionBuff.cs new file mode 100644 index 0000000..2433d33 --- /dev/null +++ b/Buffs/ToclafaneMinionBuff.cs @@ -0,0 +1,24 @@ +using Terraria; +using Terraria.ModLoader; +using YHTMod.Projectiles.Weapons; + +namespace YHTMod.Buffs; + +public class ToclafaneMinionBuff : ModBuff { + + public override void SetStaticDefaults() { + DisplayName.SetDefault("Summon Toclafane"); + Description.SetDefault("It came from a parallel world to fight for its Master."); + 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/Buffs/ToclafaneMinionBuff.png b/Buffs/ToclafaneMinionBuff.png new file mode 100644 index 0000000000000000000000000000000000000000..0f32619c286a07aa809bcdf681c895a50b9cd2b9 GIT binary patch literal 483 zcmV<90UZ8`P)Px$ok>JNR9J=WRy%IPFbt)Ojy^;>3UJO6FAfZ7$YlbgL$9HwS<~ z!P2BYc837%1A;_9z88K(0sM7TYYy$3W&!~Cyx-wvx0~k&?~Cm{m25tC-Gtk^)GHgQs841^GX&jA305a#_k9!YutjY*^w(pru;q5`Oa5CRxul0rCQAxjG2L?MJ( z2nPy7k<$4h0o3*MI|p23%nLVyivoD5(abJIDi=fnTKRF2F~Ko=Ndfd=iLo_M@9Nn7kH2|0=;H}z7&@u6)O zHmtSP4*?qLx-NQPaE#*^<;Z$MNuiJujj!iCNRlri=iG$u0sz$;RMh+Rn*BD6Rskc2 z!Taje_ly1j@E!A0-^1X2CFN5wG$U{4vud2KZ4$ADe65H@2)Ns~z*_q|;n<3Y5b=+P Z#TT8J61Y|&t#<$b002ovPDHLkV1mX9(z*Zu literal 0 HcmV?d00001 diff --git a/Items/ToclafaneStaff.cs b/Items/ToclafaneStaff.cs new file mode 100644 index 0000000..963dbc0 --- /dev/null +++ b/Items/ToclafaneStaff.cs @@ -0,0 +1,44 @@ +using Microsoft.Xna.Framework; +using Terraria; +using Terraria.DataStructures; +using Terraria.ID; +using Terraria.ModLoader; +using YHTMod.Buffs; +using YHTMod.Projectiles.Weapons; + +namespace YHTMod.Items; + +public class ToclafaneStaff : ModItem { + + public override void SetStaticDefaults() { + DisplayName.SetDefault("Toclafane Staff"); + Tooltip.SetDefault("Summons a toclafane to remove population for you"); + ItemID.Sets.GamepadWholeScreenUseRange[Item.type] = true; // This lets the player target anywhere on the whole screen while using a controller. + ItemID.Sets.LockOnIgnoresCollision[Item.type] = true; + } + + public override void SetDefaults() { + Item.damage = 30; + Item.knockBack = 3f; + Item.mana = 10; + Item.width = 32; + Item.height = 32; + Item.useTime = 36; + Item.useAnimation = 36; + Item.useStyle = ItemUseStyleID.Swing; + Item.value = Item.buyPrice(0, 30, 0, 0); + Item.rare = ItemRarityID.Cyan; + Item.UseSound = SoundID.Item44; + Item.noMelee = true; + Item.DamageType = DamageClass.Summon; + Item.buffType = ModContent.BuffType(); + Item.shoot = ModContent.ProjectileType(); + } + + public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) { + player.AddBuff(Item.buffType, 2); + position = Main.MouseWorld; + return base.Shoot(player, source, position, velocity, type, damage, knockback); + } + +} \ No newline at end of file diff --git a/Items/ToclafaneStaff.png b/Items/ToclafaneStaff.png new file mode 100644 index 0000000000000000000000000000000000000000..989695b60c940a7dedd6d0b6d510f57e2f10596b GIT binary patch literal 338 zcmV-Y0j>UtP)Px$3`s;mR9J<@);|h@U>t|>=WTcF2A-hR!85cp2+P&V)|T-NVrCh_=u0N`|b01yP8 z5?`Q=14P?B07(+d22^-a0aAFc07?9BfHeLyzy#hIU<&^lU=sfbFpa+j*ud)m kTR4ESi9_S3)CLal0(FO?10x9^asU7T07*qoM6N<$f?_3&tN;K2 literal 0 HcmV?d00001 diff --git a/Projectiles/Weapons/ToclafaneMinion.cs b/Projectiles/Weapons/ToclafaneMinion.cs new file mode 100644 index 0000000..9488b7f --- /dev/null +++ b/Projectiles/Weapons/ToclafaneMinion.cs @@ -0,0 +1,220 @@ +using System; +using Microsoft.Xna.Framework; +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; +using YHTMod.Buffs; + +namespace YHTMod.Projectiles.Weapons; + +public class ToclafaneMinion : ModProjectile { + + private int shootCooldown = 0; + + public override void SetStaticDefaults() { + DisplayName.SetDefault("Toclafane Minion"); + // Sets the amount of frames this minion has on its spritesheet + Main.projFrames[Projectile.type] = 1; + // This is necessary for right-click targeting + ProjectileID.Sets.MinionTargettingFeature[Projectile.type] = true; + + Main.projPet[Projectile.type] = true; + ProjectileID.Sets.MinionSacrificable[Projectile.type] = true; + } + + public sealed override void SetDefaults() { + Projectile.width = 32; + Projectile.height = 32; + + Projectile.tileCollide = false; + + Projectile.friendly = true; + Projectile.minion = true; + Projectile.minionSlots = 1f; + Projectile.penetrate = -1; + } + + public override bool? CanCutTiles() { + return false; + } + + public override bool MinionContactDamage() { + return true; + } + + public override void AI() { + Player player = Main.player[Projectile.owner]; + + #region Active check + + if (player.dead || !player.active) { + player.ClearBuff(ModContent.BuffType()); + } + + if (player.HasBuff(ModContent.BuffType())) { + Projectile.timeLeft = 2; + } + + #endregion + + #region General behavior + + if (shootCooldown > 0) { + shootCooldown = shootCooldown - 1; + } + + Vector2 idlePosition = player.Center; + idlePosition.Y -= 48f; + + float minionPositionOffsetX = (10 + Projectile.minionPos * 40) * -player.direction; + idlePosition.X += minionPositionOffsetX; + + // All of this code below this line is adapted from Spazmamini code (ID 388, aiStyle 66) + + // Teleport to player if distance is too big + Vector2 vectorToIdlePosition = idlePosition - Projectile.Center; + float distanceToIdlePosition = vectorToIdlePosition.Length(); + if (Main.myPlayer == player.whoAmI && distanceToIdlePosition > 2000f) { + // Whenever you deal with non-regular events that change the behavior or position drastically, make sure to only run the code on the owner of the projectile, + // and then set netUpdate to true + Projectile.position = idlePosition; + Projectile.velocity *= 0.1f; + Projectile.netUpdate = true; + } + + // If your minion is flying, you want to do this independently of any conditions + float overlapVelocity = 0.04f; + for (int i = 0; i < Main.maxProjectiles; i++) { + // Fix overlap with other minions + Projectile other = Main.projectile[i]; + if (i != Projectile.whoAmI && other.active && other.owner == Projectile.owner && + Math.Abs(Projectile.position.X - other.position.X) + + Math.Abs(Projectile.position.Y - other.position.Y) < Projectile.width) { + if (Projectile.position.X < other.position.X) Projectile.velocity.X -= overlapVelocity; + else Projectile.velocity.X += overlapVelocity; + + if (Projectile.position.Y < other.position.Y) Projectile.velocity.Y -= overlapVelocity; + else Projectile.velocity.Y += overlapVelocity; + } + } + + #endregion + + #region Find target + + // Starting search distance + float distanceFromTarget = 700f; + Vector2 targetCenter = Projectile.position; + bool foundTarget = false; + + // This code is required if your minion weapon has the targeting feature + if (player.HasMinionAttackTargetNPC) { + NPC npc = Main.npc[player.MinionAttackTargetNPC]; + float between = Vector2.Distance(npc.Center, Projectile.Center); + // Reasonable distance away so it doesn't target across multiple screens + if (between < 2000f) { + distanceFromTarget = between; + targetCenter = npc.Center; + foundTarget = true; + } + } + + if (!foundTarget) { + for (int i = 0; i < Main.maxNPCs; i++) { + NPC npc = Main.npc[i]; + if (npc.CanBeChasedBy()) { + float between = Vector2.Distance(npc.Center, Projectile.Center); + bool closest = Vector2.Distance(Projectile.Center, targetCenter) > between; + bool inRange = between < distanceFromTarget; + bool lineOfSight = Collision.CanHitLine(Projectile.position, Projectile.width, + Projectile.height, npc.position, npc.width, npc.height); + // Additional check for this specific minion behavior, otherwise it will stop attacking once it dashed through an enemy while flying though tiles afterwards + // The number depends on various parameters seen in the movement code below. Test different ones out until it works alright + bool closeThroughWall = between < 100f; + if (((closest && inRange) || !foundTarget) && (lineOfSight || closeThroughWall)) { + distanceFromTarget = between; + targetCenter = npc.Center; + foundTarget = true; + } + } + } + } + + Projectile.friendly = foundTarget; + + #endregion + + #region Movement + + // Default movement parameters (here for attacking) + float speed = 8f; + float inertia = 20f; + + if (foundTarget) { + Vector2 direction = targetCenter - Projectile.Center; + direction.Normalize(); + if (distanceFromTarget > 40f) { + // The immediate range around the target (so it doesn't latch onto it when close) + direction *= speed; + Projectile.velocity = (Projectile.velocity * (inertia - 1) + direction) / inertia; + } + + if (distanceFromTarget > 80f && shootCooldown == 0) { + shootCooldown = 60; // 1 second between shots + Projectile laser = Projectile.NewProjectileDirect(player.GetSource_FromThis(), Projectile.position, direction, ProjectileID.DeathLaser, 30, Projectile.knockBack, Projectile.owner); + laser.friendly = true; + laser.penetrate = 5; + } + } + else { + // Minion doesn't have a target: return to player and idle + if (distanceToIdlePosition > 600f) { + // Speed up the minion if it's away from the player + speed = 12f; + inertia = 60f; + } + else { + // Slow down the minion if closer to the player + speed = 4f; + inertia = 80f; + } + + if (distanceToIdlePosition > 20f) { + // The immediate range around the player (when it passively floats about) + + // This is a simple movement formula using the two parameters and its desired direction to create a "homing" movement + vectorToIdlePosition.Normalize(); + vectorToIdlePosition *= speed; + Projectile.velocity = (Projectile.velocity * (inertia - 1) + vectorToIdlePosition) / inertia; + } + else if (Projectile.velocity == Vector2.Zero) { + // If there is a case where it's not moving at all, give it a little "poke" + Projectile.velocity.X = -0.15f; + Projectile.velocity.Y = -0.05f; + } + } + + #endregion + + #region Animation and visuals + + // So it will lean slightly towards the direction it's moving + Projectile.rotation = Projectile.velocity.X * 0.05f; + + // This is a simple "loop through all frames from top to bottom" animation + int frameSpeed = 5; + Projectile.frameCounter++; + if (Projectile.frameCounter >= frameSpeed) { + Projectile.frameCounter = 0; + Projectile.frame++; + if (Projectile.frame >= Main.projFrames[Projectile.type]) { + Projectile.frame = 0; + } + } + + // Some visuals here + Lighting.AddLight(Projectile.Center, Color.White.ToVector3() * 0.78f); + + #endregion + } +} \ No newline at end of file diff --git a/Projectiles/Weapons/ToclafaneMinion.png b/Projectiles/Weapons/ToclafaneMinion.png new file mode 100644 index 0000000000000000000000000000000000000000..0f32619c286a07aa809bcdf681c895a50b9cd2b9 GIT binary patch literal 483 zcmV<90UZ8`P)Px$ok>JNR9J=WRy%IPFbt)Ojy^;>3UJO6FAfZ7$YlbgL$9HwS<~ z!P2BYc837%1A;_9z88K(0sM7TYYy$3W&!~Cyx-wvx0~k&?~Cm{m25tC-Gtk^)GHgQs841^GX&jA305a#_k9!YutjY*^w(pru;q5`Oa5CRxul0rCQAxjG2L?MJ( z2nPy7k<$4h0o3*MI|p23%nLVyivoD5(abJIDi=fnTKRF2F~Ko=Ndfd=iLo_M@9Nn7kH2|0=;H}z7&@u6)O zHmtSP4*?qLx-NQPaE#*^<;Z$MNuiJujj!iCNRlri=iG$u0sz$;RMh+Rn*BD6Rskc2 z!Taje_ly1j@E!A0-^1X2CFN5wG$U{4vud2KZ4$ADe65H@2)Ns~z*_q|;n<3Y5b=+P Z#TT8J61Y|&t#<$b002ovPDHLkV1mX9(z*Zu literal 0 HcmV?d00001 From e2f9131c0114fd883d7be3f604355d813def81b9 Mon Sep 17 00:00:00 2001 From: YouHaveTrouble Date: Sat, 3 Dec 2022 21:55:34 +0100 Subject: [PATCH 2/4] you are my vodoo child --- Items/ToclafaneStaff.cs | 40 ++++++++++- Projectiles/Weapons/ToclafaneMinion.cs | 87 ++++++++++++++++++++---- Projectiles/Weapons/ToclafaneMinion.png | Bin 483 -> 5667 bytes 3 files changed, 112 insertions(+), 15 deletions(-) diff --git a/Items/ToclafaneStaff.cs b/Items/ToclafaneStaff.cs index 963dbc0..82a8427 100644 --- a/Items/ToclafaneStaff.cs +++ b/Items/ToclafaneStaff.cs @@ -40,5 +40,43 @@ public class ToclafaneStaff : ModItem { position = Main.MouseWorld; return base.Shoot(player, source, position, velocity, type, damage, knockback); } - + + public override void AddRecipes() { + CreateRecipe() + .AddIngredient(ItemID.GuideVoodooDoll, 1) + .AddIngredient(ItemID.HallowedBar, 15) + .AddIngredient(ItemID.CopperWatch) + .AddTile(TileID.MythrilAnvil) + .Register(); + CreateRecipe() + .AddIngredient(ItemID.GuideVoodooDoll, 1) + .AddIngredient(ItemID.HallowedBar, 15) + .AddIngredient(ItemID.TinWatch) + .AddTile(TileID.MythrilAnvil) + .Register(); + CreateRecipe() + .AddIngredient(ItemID.GuideVoodooDoll, 1) + .AddIngredient(ItemID.HallowedBar, 15) + .AddIngredient(ItemID.SilverWatch) + .AddTile(TileID.MythrilAnvil) + .Register(); + CreateRecipe() + .AddIngredient(ItemID.GuideVoodooDoll, 1) + .AddIngredient(ItemID.HallowedBar, 15) + .AddIngredient(ItemID.TungstenWatch) + .AddTile(TileID.MythrilAnvil) + .Register(); + CreateRecipe() + .AddIngredient(ItemID.GuideVoodooDoll, 1) + .AddIngredient(ItemID.HallowedBar, 15) + .AddTile(TileID.MythrilAnvil) + .AddIngredient(ItemID.GoldWatch) + .Register(); + CreateRecipe() + .AddIngredient(ItemID.GuideVoodooDoll, 1) + .AddIngredient(ItemID.HallowedBar, 15) + .AddIngredient(ItemID.PlatinumWatch) + .AddTile(TileID.MythrilAnvil) + .Register(); + } } \ No newline at end of file diff --git a/Projectiles/Weapons/ToclafaneMinion.cs b/Projectiles/Weapons/ToclafaneMinion.cs index 9488b7f..f3532f4 100644 --- a/Projectiles/Weapons/ToclafaneMinion.cs +++ b/Projectiles/Weapons/ToclafaneMinion.cs @@ -10,11 +10,12 @@ namespace YHTMod.Projectiles.Weapons; public class ToclafaneMinion : ModProjectile { private int shootCooldown = 0; + private AttackMode attackMode = AttackMode.RANGED; public override void SetStaticDefaults() { DisplayName.SetDefault("Toclafane Minion"); // Sets the amount of frames this minion has on its spritesheet - Main.projFrames[Projectile.type] = 1; + Main.projFrames[Projectile.type] = 8; // This is necessary for right-click targeting ProjectileID.Sets.MinionTargettingFeature[Projectile.type] = true; @@ -25,6 +26,7 @@ public class ToclafaneMinion : ModProjectile { public sealed override void SetDefaults() { Projectile.width = 32; Projectile.height = 32; + Projectile.scale = 0.65f; Projectile.tileCollide = false; @@ -63,6 +65,8 @@ public class ToclafaneMinion : ModProjectile { shootCooldown = shootCooldown - 1; } + attackMode = AttackMode.RANGED; + Vector2 idlePosition = player.Center; idlePosition.Y -= 48f; @@ -92,7 +96,6 @@ public class ToclafaneMinion : ModProjectile { Math.Abs(Projectile.position.Y - other.position.Y) < Projectile.width) { if (Projectile.position.X < other.position.X) Projectile.velocity.X -= overlapVelocity; else Projectile.velocity.X += overlapVelocity; - if (Projectile.position.Y < other.position.Y) Projectile.velocity.Y -= overlapVelocity; else Projectile.velocity.Y += overlapVelocity; } @@ -159,11 +162,15 @@ public class ToclafaneMinion : ModProjectile { Projectile.velocity = (Projectile.velocity * (inertia - 1) + direction) / inertia; } - if (distanceFromTarget > 80f && shootCooldown == 0) { + if (distanceFromTarget <= 120f) { + attackMode = AttackMode.MELEE; + } + if (distanceFromTarget > 120f && shootCooldown == 0) { shootCooldown = 60; // 1 second between shots - Projectile laser = Projectile.NewProjectileDirect(player.GetSource_FromThis(), Projectile.position, direction, ProjectileID.DeathLaser, 30, Projectile.knockBack, Projectile.owner); + Projectile laser = Projectile.NewProjectileDirect(player.GetSource_FromThis(), Projectile.Center, direction, ProjectileID.DeathLaser, 30, Projectile.knockBack, Projectile.owner); laser.friendly = true; laser.penetrate = 5; + attackMode = AttackMode.RANGED; } } else { @@ -186,8 +193,7 @@ public class ToclafaneMinion : ModProjectile { vectorToIdlePosition.Normalize(); vectorToIdlePosition *= speed; Projectile.velocity = (Projectile.velocity * (inertia - 1) + vectorToIdlePosition) / inertia; - } - else if (Projectile.velocity == Vector2.Zero) { + } else if (Projectile.velocity == Vector2.Zero) { // If there is a case where it's not moving at all, give it a little "poke" Projectile.velocity.X = -0.15f; Projectile.velocity.Y = -0.05f; @@ -200,21 +206,74 @@ public class ToclafaneMinion : ModProjectile { // So it will lean slightly towards the direction it's moving Projectile.rotation = Projectile.velocity.X * 0.05f; - - // This is a simple "loop through all frames from top to bottom" animation - int frameSpeed = 5; + + int frameSpeed = 8; Projectile.frameCounter++; if (Projectile.frameCounter >= frameSpeed) { Projectile.frameCounter = 0; - Projectile.frame++; - if (Projectile.frame >= Main.projFrames[Projectile.type]) { - Projectile.frame = 0; + if (attackMode == AttackMode.MELEE) { + switch (Projectile.frame) { + case 0: + Projectile.frame++; + break; + case 1: + Projectile.frame++; + break; + case 2: + Projectile.frame++; + break; + case 3: + Projectile.frame = 0; + break; + case 4: + Projectile.frame = 1; + break; + case 5: + Projectile.frame = 2; + break; + case 6: + Projectile.frame = 3; + break; + case 7: + Projectile.frame = 4; + break; + } + } + if (attackMode == AttackMode.RANGED) { + switch (Projectile.frame) { + case 0: + Projectile.frame = 5; + break; + case 1: + Projectile.frame = 6; + break; + case 2: + Projectile.frame = 7; + break; + case 3: + Projectile.frame = 4; + break; + case 4: + Projectile.frame++; + break; + case 5: + Projectile.frame++; + break; + case 6: + Projectile.frame++; + break; + case 7: + Projectile.frame = 4; + break; + } } } - - // Some visuals here Lighting.AddLight(Projectile.Center, Color.White.ToVector3() * 0.78f); #endregion } + + enum AttackMode { + MELEE, RANGED + } } \ No newline at end of file diff --git a/Projectiles/Weapons/ToclafaneMinion.png b/Projectiles/Weapons/ToclafaneMinion.png index 0f32619c286a07aa809bcdf681c895a50b9cd2b9..70541be1d62bcee46c4da8023d75ba83052b1327 100644 GIT binary patch literal 5667 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 literal 483 zcmV<90UZ8`P)Px$ok>JNR9J=WRy%IPFbt)Ojy^;>3UJO6FAfZ7$YlbgL$9HwS<~ z!P2BYc837%1A;_9z88K(0sM7TYYy$3W&!~Cyx-wvx0~k&?~Cm{m25tC-Gtk^)GHgQs841^GX&jA305a#_k9!YutjY*^w(pru;q5`Oa5CRxul0rCQAxjG2L?MJ( z2nPy7k<$4h0o3*MI|p23%nLVyivoD5(abJIDi=fnTKRF2F~Ko=Ndfd=iLo_M@9Nn7kH2|0=;H}z7&@u6)O zHmtSP4*?qLx-NQPaE#*^<;Z$MNuiJujj!iCNRlri=iG$u0sz$;RMh+Rn*BD6Rskc2 z!Taje_ly1j@E!A0-^1X2CFN5wG$U{4vud2KZ4$ADe65H@2)Ns~z*_q|;n<3Y5b=+P Z#TT8J61Y|&t#<$b002ovPDHLkV1mX9(z*Zu From 50c07dd04cdbdbb73170baa3da3d35d9f23ee1b7 Mon Sep 17 00:00:00 2001 From: YouHaveTrouble Date: Sun, 4 Dec 2022 12:31:41 +0100 Subject: [PATCH 3/4] toclafane minion buff icon --- Buffs/ToclafaneMinionBuff.png | Bin 483 -> 3266 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Buffs/ToclafaneMinionBuff.png b/Buffs/ToclafaneMinionBuff.png index 0f32619c286a07aa809bcdf681c895a50b9cd2b9..3677becad61d5f9fc73a57a12771e267009ef1a5 100644 GIT binary patch delta 3263 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 delta 458 zcmV;*0X6=@8RG+xBYyw^b5ch_0Itp)=>Px$ok>JNR9J=WRy%IPFbt)Ojy^;>3UJO6 zFAfZ7$YlbgL$9HwS<~!P2BYc837%1A;_9z88K(0sM7TYYy$3W&!~C zyx-wvx0~k&?~Cm{m25tC-Gtk^)GHgQs841^GX&wl{`gb?QaIUY%R0F6nc z6w+FbH=+Wlfe->1W0FERVj)Wk;6x#WSqKLTLy^+?A_3I(^g9P!WXuaiRiF{jIsDg} zr?Ld>n`V*-v@vx#KZhaF5;ExlBw7;+JddAZ0hBCNf?DFG1d9TAsnN_XMJg9W0b2QS zkukwBdr1NGV1J3RHBj&B*!_>cc{k+yD73zitb$nlI5~h^o-stb6>mg5(cmy37^g&f)zK5jSlQo`|}Z5KAIwbc&+8tS?(dSGyj;~3@0dO}H|kP?lr z=R8P~FCypMgzf?W)f-gQ`}LarHjGvQBZtBJ>eTm({zCxp9rIJ)!{B`- Date: Sun, 4 Dec 2022 12:33:16 +0100 Subject: [PATCH 4/4] newline at end of file --- Buffs/ToclafaneMinionBuff.cs | 2 +- Items/ToclafaneStaff.cs | 2 +- Projectiles/Weapons/ToclafaneMinion.cs | 18 ++++++++++++------ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Buffs/ToclafaneMinionBuff.cs b/Buffs/ToclafaneMinionBuff.cs index 2433d33..08703ee 100644 --- a/Buffs/ToclafaneMinionBuff.cs +++ b/Buffs/ToclafaneMinionBuff.cs @@ -21,4 +21,4 @@ public class ToclafaneMinionBuff : ModBuff { buffIndex--; } } -} \ No newline at end of file +} diff --git a/Items/ToclafaneStaff.cs b/Items/ToclafaneStaff.cs index 82a8427..bae006e 100644 --- a/Items/ToclafaneStaff.cs +++ b/Items/ToclafaneStaff.cs @@ -79,4 +79,4 @@ public class ToclafaneStaff : ModItem { .AddTile(TileID.MythrilAnvil) .Register(); } -} \ No newline at end of file +} diff --git a/Projectiles/Weapons/ToclafaneMinion.cs b/Projectiles/Weapons/ToclafaneMinion.cs index f3532f4..fece0a3 100644 --- a/Projectiles/Weapons/ToclafaneMinion.cs +++ b/Projectiles/Weapons/ToclafaneMinion.cs @@ -11,7 +11,7 @@ public class ToclafaneMinion : ModProjectile { private int shootCooldown = 0; private AttackMode attackMode = AttackMode.RANGED; - + public override void SetStaticDefaults() { DisplayName.SetDefault("Toclafane Minion"); // Sets the amount of frames this minion has on its spritesheet @@ -165,9 +165,11 @@ public class ToclafaneMinion : ModProjectile { if (distanceFromTarget <= 120f) { attackMode = AttackMode.MELEE; } + if (distanceFromTarget > 120f && shootCooldown == 0) { shootCooldown = 60; // 1 second between shots - Projectile laser = Projectile.NewProjectileDirect(player.GetSource_FromThis(), Projectile.Center, direction, ProjectileID.DeathLaser, 30, Projectile.knockBack, Projectile.owner); + Projectile laser = Projectile.NewProjectileDirect(player.GetSource_FromThis(), Projectile.Center, + direction, ProjectileID.DeathLaser, 30, Projectile.knockBack, Projectile.owner); laser.friendly = true; laser.penetrate = 5; attackMode = AttackMode.RANGED; @@ -193,7 +195,8 @@ public class ToclafaneMinion : ModProjectile { vectorToIdlePosition.Normalize(); vectorToIdlePosition *= speed; Projectile.velocity = (Projectile.velocity * (inertia - 1) + vectorToIdlePosition) / inertia; - } else if (Projectile.velocity == Vector2.Zero) { + } + else if (Projectile.velocity == Vector2.Zero) { // If there is a case where it's not moving at all, give it a little "poke" Projectile.velocity.X = -0.15f; Projectile.velocity.Y = -0.05f; @@ -206,7 +209,7 @@ public class ToclafaneMinion : ModProjectile { // So it will lean slightly towards the direction it's moving Projectile.rotation = Projectile.velocity.X * 0.05f; - + int frameSpeed = 8; Projectile.frameCounter++; if (Projectile.frameCounter >= frameSpeed) { @@ -239,6 +242,7 @@ public class ToclafaneMinion : ModProjectile { break; } } + if (attackMode == AttackMode.RANGED) { switch (Projectile.frame) { case 0: @@ -268,12 +272,14 @@ public class ToclafaneMinion : ModProjectile { } } } + Lighting.AddLight(Projectile.Center, Color.White.ToVector3() * 0.78f); #endregion } enum AttackMode { - MELEE, RANGED + MELEE, + RANGED } -} \ No newline at end of file +}