using System; using Decimation.Content.Projectiles; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Terraria; namespace Decimation.Lib.Projectile { public abstract class WormProjectile : DecimationProjectile { protected int BodyType; protected bool Directional = false; protected bool Flies = false; /* ai[0] = follower * ai[1] = following * ai[2] = distanceFromTail * ai[3] = head */ protected bool Head; protected int HeadType; protected int MaxLength; protected int MinLength; protected float Speed; protected bool Tail; protected int TailType; protected float TurnSpeed; protected int Target; protected int RealLife; protected float DistanceFromTail; protected float WormHead; public override void AI() { if (projectile.localAI[1] == 0f) { projectile.localAI[1] = 1f; InitWorm(); } if (WormHead > 0f) RealLife = (int) WormHead; if (!Head && projectile.timeLeft < 300) projectile.timeLeft = 300; if (Target < 0 || Target == 255 || !Main.npc[Target].active) TargetClosest(); if (Main.player[projectile.owner].dead && projectile.timeLeft > 300) projectile.timeLeft = 300; Entity target; if (Target < 0) { target = Main.player[projectile.owner]; } else { target = Main.npc[Target]; } if (Main.netMode != 1) { if (!Tail && projectile.ai[0] == 0f) { if (Head) { WormHead = projectile.whoAmI; RealLife = projectile.whoAmI; DistanceFromTail = Main.rand.Next(MinLength, MaxLength + 1); projectile.ai[0] = Terraria.Projectile.NewProjectile( (int) (projectile.position.X + projectile.width / 2f), (int) (projectile.position.Y + projectile.height), 0f, 0f, BodyType, 0, 0f, projectile.owner ); } else if (DistanceFromTail > 0f) { projectile.ai[0] = Terraria.Projectile.NewProjectile( (int) (projectile.position.X + projectile.width / 2f), (int) (projectile.position.Y + projectile.height), 0f, 0f, projectile.type, 0, 0f, projectile.owner ); } else { projectile.ai[0] = Terraria.Projectile.NewProjectile( (int) (projectile.position.X + projectile.width / 2f), (int) (projectile.position.Y + projectile.height), 0f, 0f, TailType, 0, 0f, projectile.whoAmI ); } ((WormProjectile) Main.projectile[(int) projectile.ai[0]].modProjectile).WormHead = WormHead; ((WormProjectile) Main.projectile[(int) projectile.ai[0]].modProjectile).RealLife = RealLife; Main.projectile[(int) projectile.ai[0]].ai[1] = projectile.whoAmI; ((WormProjectile) Main.projectile[(int) projectile.ai[0]].modProjectile).DistanceFromTail = DistanceFromTail - 1f; projectile.netUpdate = true; } } var num180 = (int) (projectile.position.X / 16f) - 1; var num181 = (int) ((projectile.position.X + projectile.width) / 16f) + 2; var num182 = (int) (projectile.position.Y / 16f) - 1; var num183 = (int) ((projectile.position.Y + projectile.height) / 16f) + 2; if (num180 < 0) num180 = 0; if (num181 > Main.maxTilesX) num181 = Main.maxTilesX; if (num182 < 0) num182 = 0; if (num183 > Main.maxTilesY) num183 = Main.maxTilesY; var flag18 = Flies; if (!flag18) for (var num184 = num180; num184 < num181; num184++) for (var num185 = num182; num185 < num183; num185++) if (Main.tile[num184, num185] != null && (Main.tile[num184, num185].nactive() && (Main.tileSolid[Main.tile[num184, num185].type] || Main.tileSolidTop[Main.tile[num184, num185].type] && Main.tile[num184, num185].frameY == 0) || Main.tile[num184, num185].liquid > 64)) { Vector2 vector17; vector17.X = num184 * 16; vector17.Y = num185 * 16; if (projectile.position.X + projectile.width > vector17.X && projectile.position.X < vector17.X + 16f && projectile.position.Y + projectile.height > vector17.Y && projectile.position.Y < vector17.Y + 16f) { flag18 = true; } } if (!flag18 && Head) { var rectangle = new Rectangle((int) projectile.position.X, (int) projectile.position.Y, projectile.width, projectile.height); var num186 = 1000; var flag19 = true; for (var num187 = 0; num187 < 255; num187++) if (Main.player[num187].active) { var rectangle2 = new Rectangle((int) Main.player[num187].position.X - num186, (int) Main.player[num187].position.Y - num186, num186 * 2, num186 * 2); if (rectangle.Intersects(rectangle2)) { flag19 = false; break; } } if (flag19) flag18 = true; } if (Directional) { if (projectile.velocity.X < 0f) projectile.spriteDirection = 1; else if (projectile.velocity.X > 0f) projectile.spriteDirection = -1; } var num188 = Speed; var num189 = TurnSpeed; var vector18 = new Vector2(projectile.position.X + projectile.width * 0.5f, projectile.position.Y + projectile.height * 0.5f); var num191 = target.position.X + target.width / 2f; var num192 = target.position.Y + target.height / 2f; num191 = (int) (num191 / 16f) * 16; num192 = (int) (num192 / 16f) * 16; vector18.X = (int) (vector18.X / 16f) * 16; vector18.Y = (int) (vector18.Y / 16f) * 16; num191 -= vector18.X; num192 -= vector18.Y; var num193 = (float) Math.Sqrt(num191 * num191 + num192 * num192); if (projectile.ai[1] > 0f && projectile.ai[1] < Main.projectile.Length) { try { vector18 = new Vector2(projectile.position.X + projectile.width * 0.5f, projectile.position.Y + projectile.height * 0.5f); num191 = Main.projectile[(int) projectile.ai[1]].position.X + Main.projectile[(int) projectile.ai[1]].width / 2 - vector18.X; num192 = Main.projectile[(int) projectile.ai[1]].position.Y + Main.projectile[(int) projectile.ai[1]].height / 2 - vector18.Y; } catch { } projectile.rotation = (float) Math.Atan2(num192, num191) + 1.57f; num193 = (float) Math.Sqrt(num191 * num191 + num192 * num192); int num194 = projectile.width; num193 = (num193 - num194) / num193; num191 *= num193; num192 *= num193; projectile.velocity = Vector2.Zero; projectile.position.X = projectile.position.X + num191; projectile.position.Y = projectile.position.Y + num192; if (Directional) { if (num191 < 0f) projectile.spriteDirection = 1; if (num191 > 0f) projectile.spriteDirection = -1; } } else { if (!flag18) { TargetClosest(); projectile.velocity.Y = projectile.velocity.Y + 0.11f; if (projectile.velocity.Y > num188) projectile.velocity.Y = num188; if (Math.Abs(projectile.velocity.X) + Math.Abs(projectile.velocity.Y) < num188 * 0.4) { if (projectile.velocity.X < 0f) projectile.velocity.X = projectile.velocity.X - num189 * 1.1f; else projectile.velocity.X = projectile.velocity.X + num189 * 1.1f; } else if (projectile.velocity.Y == num188) { if (projectile.velocity.X < num191) projectile.velocity.X = projectile.velocity.X + num189; else if (projectile.velocity.X > num191) projectile.velocity.X = projectile.velocity.X - num189; } else if (projectile.velocity.Y > 4f) { if (projectile.velocity.X < 0f) projectile.velocity.X = projectile.velocity.X + num189 * 0.9f; else projectile.velocity.X = projectile.velocity.X - num189 * 0.9f; } } else { // if (!Flies && projectile.BehindTiles() && projectile.soundDelay == 0) // if (Main.netMode != NetmodeID.MultiplayerClient) // { // projectile.soundDelay = 120; // Main.PlaySound(undergroundSound, projectile.position); // if (Main.netMode == NetmodeID.Server) SendSoundPacket(); // } num193 = (float) Math.Sqrt(num191 * num191 + num192 * num192); var num196 = Math.Abs(num191); var num197 = Math.Abs(num192); var num198 = num188 / num193; num191 *= num198; num192 *= num198; if (ShouldRun()) { if (Main.netMode != 1 && projectile.position.Y / 16f > (Main.rockLayer + Main.maxTilesY) / 2.0) { projectile.active = false; var num200 = (int) projectile.ai[0]; while (num200 > 0 && num200 < 200 && Main.projectile[num200].active && Main.projectile[num200].aiStyle == projectile.aiStyle) { var num201 = (int) Main.projectile[num200].ai[0]; Main.projectile[num200].active = false; // projectile.life = 0; if (Main.netMode == 2) NetMessage.SendData(23, -1, -1, null, num200); num200 = num201; } if (Main.netMode == 2) NetMessage.SendData(23, -1, -1, null, projectile.whoAmI); } num191 = 0f; num192 = num188; } var flag21 = false; if (projectile.type == 87) { if ((projectile.velocity.X > 0f && num191 < 0f || projectile.velocity.X < 0f && num191 > 0f || projectile.velocity.Y > 0f && num192 < 0f || projectile.velocity.Y < 0f && num192 > 0f) && Math.Abs(projectile.velocity.X) + Math.Abs(projectile.velocity.Y) > num189 / 2f && num193 < 300f) { flag21 = true; if (Math.Abs(projectile.velocity.X) + Math.Abs(projectile.velocity.Y) < num188) projectile.velocity *= 1.1f; } if (projectile.position.Y > Main.npc[Target].position.Y || Main.npc[Target].position.Y / 16f > Main.worldSurface || !Main.npc[Target].active) { flag21 = true; if (Math.Abs(projectile.velocity.X) < num188 / 2f) { if (projectile.velocity.X == 0f) projectile.velocity.X = projectile.velocity.X - projectile.direction; projectile.velocity.X = projectile.velocity.X * 1.1f; } else { if (projectile.velocity.Y > -num188) projectile.velocity.Y = projectile.velocity.Y - num189; } } } if (!flag21) { if (projectile.velocity.X > 0f && num191 > 0f || projectile.velocity.X < 0f && num191 < 0f || projectile.velocity.Y > 0f && num192 > 0f || projectile.velocity.Y < 0f && num192 < 0f) { if (projectile.velocity.X < num191) { projectile.velocity.X = projectile.velocity.X + num189; } else { if (projectile.velocity.X > num191) projectile.velocity.X = projectile.velocity.X - num189; } if (projectile.velocity.Y < num192) { projectile.velocity.Y = projectile.velocity.Y + num189; } else { if (projectile.velocity.Y > num192) projectile.velocity.Y = projectile.velocity.Y - num189; } if (Math.Abs(num192) < num188 * 0.2 && (projectile.velocity.X > 0f && num191 < 0f || projectile.velocity.X < 0f && num191 > 0f)) { if (projectile.velocity.Y > 0f) projectile.velocity.Y = projectile.velocity.Y + num189 * 2f; else projectile.velocity.Y = projectile.velocity.Y - num189 * 2f; } if (Math.Abs(num191) < num188 * 0.2 && (projectile.velocity.Y > 0f && num192 < 0f || projectile.velocity.Y < 0f && num192 > 0f)) { if (projectile.velocity.X > 0f) projectile.velocity.X = projectile.velocity.X + num189 * 2f; else projectile.velocity.X = projectile.velocity.X - num189 * 2f; } } else { if (num196 > num197) { if (projectile.velocity.X < num191) projectile.velocity.X = projectile.velocity.X + num189 * 1.1f; else if (projectile.velocity.X > num191) projectile.velocity.X = projectile.velocity.X - num189 * 1.1f; if (Math.Abs(projectile.velocity.X) + Math.Abs(projectile.velocity.Y) < num188 * 0.5) { if (projectile.velocity.Y > 0f) projectile.velocity.Y = projectile.velocity.Y + num189; else projectile.velocity.Y = projectile.velocity.Y - num189; } } else { if (projectile.velocity.Y < num192) projectile.velocity.Y = projectile.velocity.Y + num189 * 1.1f; else if (projectile.velocity.Y > num192) projectile.velocity.Y = projectile.velocity.Y - num189 * 1.1f; if (Math.Abs(projectile.velocity.X) + Math.Abs(projectile.velocity.Y) < num188 * 0.5) { if (projectile.velocity.X > 0f) projectile.velocity.X = projectile.velocity.X + num189; else projectile.velocity.X = projectile.velocity.X - num189; } } } } } projectile.rotation = (float) Math.Atan2(projectile.velocity.Y, projectile.velocity.X) + 1.57f; if (Head) { if (flag18) { if (projectile.localAI[0] != 1f) projectile.netUpdate = true; projectile.localAI[0] = 1f; } else { if (projectile.localAI[0] != 0f) projectile.netUpdate = true; projectile.localAI[0] = 0f; } if ((projectile.velocity.X > 0f && projectile.oldVelocity.X < 0f || projectile.velocity.X < 0f && projectile.oldVelocity.X > 0f || projectile.velocity.Y > 0f && projectile.oldVelocity.Y < 0f || projectile.velocity.Y < 0f && projectile.oldVelocity.Y > 0f) /* && !projectile.justHit*/) { projectile.netUpdate = true; return; } } } CustomBehavior(); } public virtual void InitWorm() { } protected virtual void TargetClosest() { if (!Head) return; Target = -1; Player player13 = Main.player[projectile.owner]; float num1105 = 700f; float num1106 = 1000f; NPC ownerMinionAttackTargetNPC5 = projectile.OwnerMinionAttackTargetNPC; if (ownerMinionAttackTargetNPC5 != null && ownerMinionAttackTargetNPC5.CanBeChasedBy(this)) { float distance = projectile.Distance(ownerMinionAttackTargetNPC5.Center); if (distance < num1105 * 2f) { Target = ownerMinionAttackTargetNPC5.whoAmI; } } if (Target < 0) { for (int num1112 = 0; num1112 < 200; num1112++) { NPC nPC15 = Main.npc[num1112]; if (!nPC15.CanBeChasedBy(this) || !(player13.Distance(nPC15.Center) < num1106)) { continue; } float num1113 = projectile.Distance(nPC15.Center); if (num1113 < num1105) { Target = num1112; } } } } public virtual bool ShouldRun() { return false; } public virtual void CustomBehavior() { } protected void Draw(string texturePath, SpriteBatch spriteBatch, Color drawColor) { var frameSize = new Vector2(projectile.width, projectile.height); var texture = mod.GetTexture(texturePath); spriteBatch.Draw ( texture, new Vector2( projectile.position.X - Main.screenPosition.X + frameSize.X / 2, projectile.position.Y - Main.screenPosition.Y + frameSize.Y / 2 ), null, drawColor, projectile.rotation, frameSize * 0.5f, projectile.scale, SpriteEffects.None, 0f ); } } }