public int movementVariance = 60; //how far from the center point to move. public override void AI() { //npc.defDamage = isAwakened ? 200 : 180; NPC npcBody = Main.npc[(int)npc.ai[0]]; if (npcBody.active && npcBody.type == mod.NPCType("YamataA")) { Body = (YamataA)npcBody.modNPC; } else { if (Main.netMode != NetmodeID.MultiplayerClient) //force a kill to prevent 'ghost hands' { npc.life = 0; npc.checkDead(); npc.netUpdate = true; killedbyplayer = false; } return; } npc.alpha = Body.npc.alpha; npc.TargetClosest(true); Player targetPlayer = Main.player[npc.target]; if (targetPlayer == null || !targetPlayer.active || targetPlayer.dead) { targetPlayer = null; //deliberately set to null } Vector2 nextTarget = Body.npc.Center + new Vector2(npc.ai[1], npc.ai[2]); switch ((int)internalAI[0]) { case 0: //charge up //insert charging dust here if (internalAI[1] == 180 - 60) { if (Main.netMode != NetmodeID.MultiplayerClient) { float ai0 = (float)Math.PI * 2 / 300 * (npc.ai[3] == 2 ? 1 : -1) * Math.Sign(npc.ai[1]); Projectile.NewProjectile(npc.Center, Vector2.UnitY, mod.ProjectileType("YamataWaveDeathraySmall"), npc.damage / 4, 0f, Main.myPlayer, ai0, npc.whoAmI); } } if (++internalAI[1] > 180) { internalAI[0]++; internalAI[1] = 0; npc.netUpdate = true; } break; case 1: //idle while firing laser if (++internalAI[3] > 20) { internalAI[3] = 0; if (npc.ai[3] == 3 && Main.netMode != NetmodeID.MultiplayerClient) { if (Math.Sign(npc.Center.X - targetPlayer.Center.X) != Math.Sign(npc.ai[1])) //outermost heads enrage at player if they walk away from underneath { Projectile.NewProjectile(npc.Center, npc.DirectionTo(targetPlayer.Center) * 7f, mod.ProjectileType("YamataAVenom2"), npc.damage / 5, 0f, Main.myPlayer); Projectile.NewProjectile(npc.Center, npc.DirectionTo(targetPlayer.Center) * 7f, mod.ProjectileType("YamataABomb"), npc.damage / 5, 0f, Main.myPlayer); } else { Projectile.NewProjectile(npc.Center, Vector2.UnitY * 10, mod.ProjectileType("AbyssalThunder"), npc.damage / 5, 0f, Main.myPlayer); } } } if (++internalAI[1] > 300) { internalAI[0]++; internalAI[1] = 0; internalAI[3] = 0; npc.netUpdate = true; } break; case 2: //shoot shit internalAI[2] += npc.ai[3]; if (internalAI[2] > 180) { internalAI[2] = 0; if (Main.netMode != NetmodeID.MultiplayerClient) { Projectile.NewProjectile(npc.Center, npc.DirectionTo(targetPlayer.Center) * 5f, mod.ProjectileType("YamataAVenom2"), npc.damage / 5, 0f, Main.myPlayer); } } if (++internalAI[1] > 240) { internalAI[0]++; internalAI[1] = 0; internalAI[2] = 0; npc.netUpdate = true; } break; case 3: //breathe lingering flame internalAI[2] += npc.ai[3]; if (++internalAI[2] > 120) { internalAI[2] = 0; if (Main.netMode != NetmodeID.MultiplayerClient) { Projectile.NewProjectile(npc.Center, npc.DirectionTo(targetPlayer.Center) * 20f, mod.ProjectileType("YamataABreath"), npc.damage / 5, 0f, Main.myPlayer); } } if (++internalAI[1] > 180) { internalAI[0]++; internalAI[1] = 0; internalAI[2] = 0; npc.netUpdate = true; } break; case 4: //shoot direct aim deathrays if (internalAI[1] == npc.ai[3] * 60 - 30) { if (Main.netMode != NetmodeID.MultiplayerClient) { Projectile.NewProjectile(npc.Center, npc.DirectionTo(targetPlayer.Center), mod.ProjectileType("YamataDeathraySmall"), npc.damage / 4, 0f, Main.myPlayer, 0f, npc.whoAmI); } } if (++internalAI[1] > 360) { internalAI[0]++; internalAI[1] = 0; npc.netUpdate = true; } break; case 5: //shoot the shit again goto case 2; case 6: //drop meteor that creates ripples across ground internalAI[2] += npc.ai[3]; if (internalAI[2] > 360) { internalAI[2] = 0; if (Main.netMode != NetmodeID.MultiplayerClient) { Projectile.NewProjectile(npc.Center, Vector2.UnitY * 5, mod.ProjectileType("YamataAShockBomb"), npc.damage / 5, 0f, Main.myPlayer, npc.target); } } if (++internalAI[1] > 420) { internalAI[0]++; internalAI[1] = 0; internalAI[2] = 0; npc.netUpdate = true; } break; case 7: //pause, let previous waves disperse if (++internalAI[1] > 120) { internalAI[0]++; internalAI[1] = 0; npc.netUpdate = true; } break; case 8: //breathe the lingering shit goto case 3; case 9: //weaker meteor rain internalAI[2] += npc.ai[3]; if (internalAI[2] > 120) { internalAI[2] = 0; if (Main.netMode != NetmodeID.MultiplayerClient) { Projectile.NewProjectile(npc.Center, Vector2.UnitY * 10, mod.ProjectileType("AbyssalThunder"), npc.damage / 5, 0f, Main.myPlayer); } } if (++internalAI[3] > 20) //outermost heads enrage at player if they walk away from underneath { internalAI[3] = 0; if (npc.ai[3] == 3 && Math.Sign(npc.Center.X - targetPlayer.Center.X) != Math.Sign(npc.ai[1]) && Main.netMode != NetmodeID.MultiplayerClient) { Projectile.NewProjectile(npc.Center, npc.DirectionTo(targetPlayer.Center) * 5f, mod.ProjectileType("YamataAVenom2"), npc.damage / 5, 0f, Main.myPlayer); } } if (++internalAI[1] > 360) { internalAI[0]++; internalAI[1] = 0; internalAI[2] = 0; internalAI[3] = 0; npc.netUpdate = true; } break; case 10: //shoot the shit again goto case 2; default: internalAI[0] = 0; npc.netUpdate = true; goto case 0; } float dist = Vector2.Distance(nextTarget, npc.Center); /*if (YamataHead.EATTHELITTLEMAGGOT && playerDistance < 300f) * { * BaseAI.AIFlier(npc, ref customAI, true, .5f, .8f, 5, 5, false, 300); * } * else*/ if (dist < 100) { npc.velocity *= 0.9f; if (Math.Abs(npc.velocity.X) < 0.05f) { npc.velocity.X = 0f; } if (Math.Abs(npc.velocity.Y) < 0.05f) { npc.velocity.Y = 0f; } } else if (dist < 500) { npc.velocity = Vector2.Normalize(nextTarget - npc.Center); npc.velocity *= 10f; } else { npc.velocity = Vector2.Normalize(nextTarget - npc.Center); npc.velocity *= 30f; } //npc.position += Body.npc.position - Body.npc.oldPosition; npc.spriteDirection = -1; if (Body.TeleportMe1) { Body.TeleportMe1 = false; npc.Center = Body.npc.Center; return; } if (Body.TeleportMe2) { Body.TeleportMe2 = false; npc.Center = Body.npc.Center; return; } if (Body.TeleportMe3) { Body.TeleportMe3 = false; npc.Center = Body.npc.Center; return; } if (Body.TeleportMe4) { Body.TeleportMe4 = false; npc.Center = Body.npc.Center; return; } if (Body.TeleportMe5) { Body.TeleportMe5 = false; npc.Center = Body.npc.Center; return; } if (Body.TeleportMe6) { Body.TeleportMe6 = false; npc.Center = Body.npc.Center; return; } }
public override void AI() { if (Body == null) { NPC npcBody = Main.npc[(int)npc.ai[0]]; if (npcBody.type == mod.NPCType("YamataA")) { Body = (YamataA)npcBody.modNPC; } } if (Body == null) { return; } npc.alpha = Body.npc.alpha; if (!Body.npc.active) { if (Main.netMode != NetmodeID.MultiplayerClient) //force a kill to prevent 'ghost hands' { npc.life = 0; npc.checkDead(); npc.netUpdate = true; } return; } //npc.realLife = Body.npc.whoAmI; npc.timeLeft = 100; npc.TargetClosest(true); Player player = Main.player[npc.target]; if (Yamata.TeleportMeBitch) { YamataA.TeleportMeBitch = false; npc.Center = Body.npc.Center; return; } Laugh(); int roarSound = ModLoader.GetMod("AAMod").GetSoundSlot(SoundType.Item, "Sounds/Sounds/YamataRoar"); if (!player.active || player.dead || !Body.npc.active) { npc.TargetClosest(false); player = Main.player[npc.target]; if (!player.active || player.dead || !Body.npc.active) { if (npc.timeLeft > 10) { npc.timeLeft = 10; } return; } } npc.rotation = 0; Vector2 nextTarget = new Vector2(Body.npc.Center.X + npc.ai[1], Body.npc.Center.Y + npc.ai[2]); float dist = Vector2.Distance(nextTarget, npc.Center); if (dist < 100) { npc.velocity *= 0.9f; if (Math.Abs(npc.velocity.X) < 0.05f) { npc.velocity.X = 0f; } if (Math.Abs(npc.velocity.Y) < 0.05f) { npc.velocity.Y = 0f; } } else if (dist < 500) { npc.velocity = Vector2.Normalize(nextTarget - npc.Center); npc.velocity *= 10f; } else { npc.velocity = Vector2.Normalize(nextTarget - npc.Center); npc.velocity *= 30f; } //npc.position += Body.position - Body.oldPosition; switch ((int)internalAI[0]) { case 0: //while other heads are charging if (internalAI[3] == 0) { internalAI[3] = 1; if (Main.netMode != NetmodeID.MultiplayerClient) { Projectile.NewProjectile(npc.Center, Vector2.Zero, mod.ProjectileType("YamataHarukaProj"), npc.damage / 4, 0f, Main.myPlayer, npc.target); } } if (++internalAI[2] > 60) { internalAI[2] = 0; if (Main.netMode != NetmodeID.MultiplayerClient) { Projectile.NewProjectile(npc.Center, Vector2.UnitY * 5, mod.ProjectileType("YamataAShockBomb"), npc.damage / 6, 0f, Main.myPlayer, npc.target); } } if (++internalAI[1] > 180) { if (laughTimer <= 0) { laughTimer = 120; } internalAI[0]++; internalAI[1] = 0; internalAI[2] = 0; internalAI[3] = 0; npc.netUpdate = true; } break; case 1: //while other heads are shooting waveray if (++internalAI[1] > 300) { internalAI[0]++; internalAI[1] = 0; npc.netUpdate = true; } break; case 2: //shoot shit if (++internalAI[2] > 20) { internalAI[2] = 0; if (Main.netMode != NetmodeID.MultiplayerClient) { Projectile.NewProjectile(npc.Center, npc.DirectionTo(Main.player[npc.target].Center) * 5f, mod.ProjectileType("YamataAVenom2"), npc.damage / 6, 0f, Main.myPlayer); } } if (++internalAI[1] > 240) { internalAI[0]++; internalAI[1] = 0; internalAI[2] = 0; npc.netUpdate = true; } break; case 3: //breathe lingering flame if (++internalAI[2] > 60) { internalAI[2] = 0; if (Main.netMode != NetmodeID.MultiplayerClient) { Projectile.NewProjectile(npc.Center, npc.DirectionTo(Main.player[npc.target].Center) * 7f, mod.ProjectileType("YamataABomb"), npc.damage / 6, 0f, Main.myPlayer); } } if (++internalAI[1] > 180) { if (laughTimer <= 0) { laughTimer = 120; } internalAI[0]++; internalAI[1] = 0; internalAI[2] = 0; npc.netUpdate = true; } break; case 4: //shoot direct aim deathrays if (internalAI[1] == npc.ai[3] * 60 - 30) { if (Main.netMode != NetmodeID.MultiplayerClient) { Projectile.NewProjectile(npc.Center, npc.DirectionTo(Main.player[npc.target].Center), mod.ProjectileType("YamataDeathraySmall"), npc.damage / 4, 0f, Main.myPlayer, 0f, npc.whoAmI); } } if (++internalAI[1] > 360) { internalAI[0]++; internalAI[1] = 0; npc.netUpdate = true; } break; case 5: //shoot the shit again goto case 2; case 6: //drop meteor that creates ripples across ground if (++internalAI[2] > 90) { internalAI[2] = 0; if (Main.netMode != NetmodeID.MultiplayerClient) { for (int i = -1; i <= 1; i++) { Projectile.NewProjectile(npc.Center, npc.DirectionTo(Main.player[npc.target].Center).RotatedBy(MathHelper.ToRadians(i * 5)) * 5f, mod.ProjectileType("YamataAVenom2"), npc.damage / 6, 0f, Main.myPlayer); } } } if (++internalAI[1] > 420) { if (laughTimer <= 0) { laughTimer = 120; } internalAI[0]++; internalAI[1] = 0; internalAI[2] = 0; npc.netUpdate = true; } break; case 7: //pause, let previous waves disperse if (++internalAI[1] > 120) { internalAI[0]++; internalAI[1] = 0; npc.netUpdate = true; } break; case 8: //breathe the lingering shit goto case 3; case 9: //some mix of 2 attacks he already does, something homing + something directly aimed if (--internalAI[2] < 0) { internalAI[2] = 120; if (Main.netMode != NetmodeID.MultiplayerClient) { Projectile.NewProjectile(npc.Center, npc.DirectionTo(Main.player[npc.target].Center) * 7f, mod.ProjectileType("YamataABomb"), npc.damage / 6, 0f, Main.myPlayer); } } if (++internalAI[1] > 360) { internalAI[0]++; internalAI[1] = 0; internalAI[2] = 0; npc.netUpdate = true; } break; case 10: //shoot the shit again goto case 2; default: internalAI[0] = 0; npc.netUpdate = true; goto case 0; } if (YamataA.TeleportMeBitch) { YamataA.TeleportMeBitch = false; npc.Center = Body.npc.Center; return; } }