public override bool?CanBeHitByProjectile(NPC npc, Projectile projectile) { if (!Main.player[projectile.owner].buffImmune[ModContent.BuffType <NullificationCurse>()] && !FargoSoulsWorld.SwarmActive) { switch (GetVulnerabilityState(npc)) { case 0: if (!projectile.melee) { return(false); } break; case 1: if (!projectile.ranged) { return(false); } break; case 2: if (!projectile.magic) { return(false); } break; case 3: if (!FargoSoulsUtil.IsMinionDamage(projectile)) { return(false); } break; default: break; } } return(base.CanBeHitByProjectile(npc, projectile)); }
public override void AI() { EModeGlobalNPC.championBoss = npc.whoAmI; if (npc.localAI[3] == 0) //spawn friends { npc.TargetClosest(false); if (npc.ai[2] == 1) { npc.velocity = Vector2.Zero; npc.noTileCollide = true; npc.noGravity = true; npc.alpha = 0; if (FargoSoulsWorld.downedChampions[6] && npc.ai[1] < 120) { npc.ai[1] = 120; } if (npc.ai[1] == 180) { Main.PlaySound(SoundID.Roar, npc.Center, 0); if (Main.netMode != NetmodeID.MultiplayerClient) { int n = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <SpiritChampionHand>(), npc.whoAmI, 0f, npc.whoAmI, -1f, -1f, npc.target); if (n != Main.maxNPCs) { Main.npc[n].velocity.X = Main.rand.NextFloat(-24f, 24f); Main.npc[n].velocity.Y = Main.rand.NextFloat(-24f, 24f); if (Main.netMode == NetmodeID.Server) { NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n); } } n = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <SpiritChampionHand>(), npc.whoAmI, 0f, npc.whoAmI, -1f, 1f, npc.target); if (n != Main.maxNPCs) { Main.npc[n].velocity.X = Main.rand.NextFloat(-24f, 24f); Main.npc[n].velocity.Y = Main.rand.NextFloat(-24f, 24f); if (Main.netMode == NetmodeID.Server) { NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n); } } n = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <SpiritChampionHand>(), npc.whoAmI, 0f, npc.whoAmI, 1f, -1f, npc.target); if (n != Main.maxNPCs) { Main.npc[n].velocity.X = Main.rand.NextFloat(-24f, 24f); Main.npc[n].velocity.Y = Main.rand.NextFloat(-24f, 24f); if (Main.netMode == NetmodeID.Server) { NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n); } } n = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <SpiritChampionHand>(), npc.whoAmI, 0f, npc.whoAmI, 1f, 1f, npc.target); if (n != Main.maxNPCs) { Main.npc[n].velocity.X = Main.rand.NextFloat(-24f, 24f); Main.npc[n].velocity.Y = Main.rand.NextFloat(-24f, 24f); if (Main.netMode == NetmodeID.Server) { NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n); } } } } if (++npc.ai[1] > 300) { npc.ai[1] = 0; npc.ai[2] = 0; npc.ai[3] = 0; npc.localAI[3] = 1; npc.netUpdate = true; } return; } if (npc.ai[3] == 0 && npc.HasValidTarget) { npc.ai[3] = 1; npc.Center = Main.player[npc.target].Center - Vector2.UnitY * 500; npc.ai[2] = Main.player[npc.target].Center.Y - npc.height / 2; //fall this distance, accounting for my height npc.netUpdate = true; } npc.alpha -= 10; if (npc.alpha < 0) { npc.alpha = 0; npc.noGravity = false; } if (npc.Center.Y > npc.ai[2]) { npc.noTileCollide = false; } if (++npc.ai[1] > 300 || (npc.velocity.Y == 0 && npc.ai[1] > 30)) { npc.ai[1] = 0; npc.ai[2] = 1; Main.PlaySound(SoundID.Item, npc.Center, 14); for (int k = -2; k <= 2; k++) //explosions { Vector2 dustPos = npc.Center; int width = npc.width / 5; dustPos.X += width * k; dustPos.Y += npc.height / 2; for (int i = 0; i < 20; i++) { int dust = Dust.NewDust(dustPos - new Vector2(16, 16), 32, 32, 31, 0f, 0f, 100, default(Color), 2f); //Main.dust[dust].velocity *= 1.4f; } /*for (int i = 0; i < 20; i++) * { * int dust = Dust.NewDust(dustPos - new Vector2(16, 16), 32, 32, 6, 0f, 0f, 100, default(Color), 3.5f); * Main.dust[dust].noGravity = true; * Main.dust[dust].velocity *= 7f; * dust = Dust.NewDust(dustPos - new Vector2(16, 16), 32, 32, 6, 0f, 0f, 100, default(Color), 1.5f); * Main.dust[dust].velocity *= 3f; * }*/ float scaleFactor9 = 0.5f; for (int j = 0; j < 4; j++) { int gore = Gore.NewGore(dustPos, default(Vector2), Main.rand.Next(61, 64)); Main.gore[gore].velocity *= scaleFactor9; //Main.gore[gore].velocity.X += 1f; //Main.gore[gore].velocity.Y += 1f; } } } return; } Player player = Main.player[npc.target]; Vector2 targetPos; if (npc.HasValidTarget && npc.Distance(player.Center) < 2500 && (Framing.GetTileSafely(player.Center).wall != WallID.None || player.ZoneUndergroundDesert)) { npc.timeLeft = 600; } npc.dontTakeDamage = false; switch ((int)npc.ai[0]) { case -4: //final float npc.dontTakeDamage = true; goto case 0; case -3: //final you think you're safe npc.dontTakeDamage = true; if (npc.localAI[2] == 0) { npc.localAI[2] = 1; } if (!player.active || player.dead || Vector2.Distance(npc.Center, player.Center) > 2500f || (Framing.GetTileSafely(player.Center).wall == WallID.None && !player.ZoneUndergroundDesert)) //despawn code { npc.TargetClosest(false); if (npc.timeLeft > 30) { npc.timeLeft = 30; } npc.noTileCollide = true; npc.noGravity = true; npc.velocity.Y += 1f; return; } targetPos = new Vector2(npc.localAI[0], npc.localAI[1]); if (npc.Distance(targetPos) > 25) { Movement(targetPos, 0.8f, 24f); } if (npc.ai[1] == 0) //respawn dead hands { bool[] foundHand = new bool[4]; for (int i = 0; i < Main.maxNPCs; i++) { if (Main.npc[i].active && Main.npc[i].type == ModContent.NPCType <SpiritChampionHand>() && Main.npc[i].ai[1] == npc.whoAmI) { if (!foundHand[0]) { foundHand[0] = Main.npc[i].ai[2] == -1f && Main.npc[i].ai[3] == -1f; } if (!foundHand[1]) { foundHand[1] = Main.npc[i].ai[2] == -1f && Main.npc[i].ai[3] == 1f; } if (!foundHand[2]) { foundHand[2] = Main.npc[i].ai[2] == 1f && Main.npc[i].ai[3] == -1f; } if (!foundHand[3]) { foundHand[3] = Main.npc[i].ai[2] == 1f && Main.npc[i].ai[3] == 1f; } } } if (Main.netMode != NetmodeID.MultiplayerClient) //if hands somehow disappear { if (!foundHand[0]) { int n = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <SpiritChampionHand>(), npc.whoAmI, 0f, npc.whoAmI, -1f, -1f, npc.target); if (n != Main.maxNPCs) { Main.npc[n].velocity.X = Main.rand.NextFloat(-24f, 24f); Main.npc[n].velocity.Y = Main.rand.NextFloat(-24f, 24f); if (Main.netMode == NetmodeID.Server) { NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n); } } } if (!foundHand[1]) { int n = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <SpiritChampionHand>(), npc.whoAmI, 0f, npc.whoAmI, -1f, 1f, npc.target); if (n != Main.maxNPCs) { Main.npc[n].velocity.X = Main.rand.NextFloat(-24f, 24f); Main.npc[n].velocity.Y = Main.rand.NextFloat(-24f, 24f); if (Main.netMode == NetmodeID.Server) { NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n); } } } if (!foundHand[2]) { int n = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <SpiritChampionHand>(), npc.whoAmI, 0f, npc.whoAmI, 1f, -1f, npc.target); if (n != Main.maxNPCs) { Main.npc[n].velocity.X = Main.rand.NextFloat(-24f, 24f); Main.npc[n].velocity.Y = Main.rand.NextFloat(-24f, 24f); if (Main.netMode == NetmodeID.Server) { NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n); } } } if (!foundHand[3]) { int n = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <SpiritChampionHand>(), npc.whoAmI, 0f, npc.whoAmI, 1f, 1f, npc.target); if (n != Main.maxNPCs) { Main.npc[n].velocity.X = Main.rand.NextFloat(-24f, 24f); Main.npc[n].velocity.Y = Main.rand.NextFloat(-24f, 24f); if (Main.netMode == NetmodeID.Server) { NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n); } } } } } else if (npc.ai[1] == 120) { Main.PlaySound(SoundID.Roar, npc.Center, 0); for (int i = 0; i < Main.maxNPCs; i++) //update ai { if (Main.npc[i].active && Main.npc[i].type == ModContent.NPCType <SpiritChampionHand>() && Main.npc[i].ai[1] == npc.whoAmI) { Main.npc[i].ai[0] = 1f; Main.npc[i].netUpdate = true; } } if (Main.netMode != NetmodeID.MultiplayerClient) //spawn super hand { int n2 = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <SpiritChampionHand>(), npc.whoAmI, 3f, npc.whoAmI, 1f, 1f, npc.target); if (n2 != Main.maxNPCs) { Main.npc[n2].velocity.X = Main.rand.NextFloat(-24f, 24f); Main.npc[n2].velocity.Y = Main.rand.NextFloat(-24f, 24f); if (Main.netMode == NetmodeID.Server) { NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n2); } } } } if (++npc.ai[2] > 85) //bone spray { npc.ai[2] = 0; if (Main.netMode != NetmodeID.MultiplayerClient) { Main.PlaySound(SoundID.Item2, npc.Center); for (int i = 0; i < 12; i++) { Projectile.NewProjectile(npc.position.X + Main.rand.Next(npc.width), npc.position.Y + Main.rand.Next(npc.height), Main.rand.NextFloat(-8f, 8f), Main.rand.NextFloat(-8f, 8f), ModContent.ProjectileType <SpiritCrossBone>(), npc.damage / 4, 0f, Main.myPlayer); } } } if (++npc.ai[3] > 110) { npc.ai[3] = 0; if (Main.netMode != NetmodeID.MultiplayerClient) //sandnado { Vector2 target = player.Center; target.Y -= 100; Projectile.NewProjectile(target, Vector2.Zero, ProjectileID.SandnadoHostileMark, 0, 0f, Main.myPlayer); int length = (int)npc.Distance(target) / 10; Vector2 offset = npc.DirectionTo(target) * 10f; for (int i = 0; i < length; i++) //dust warning line for sandnado { int d = Dust.NewDust(npc.Center + offset * i, 0, 0, 269, 0f, 0f, 0, new Color()); Main.dust[d].noLight = true; Main.dust[d].scale = 1.25f; } } } if (++npc.ai[1] > 600) { npc.dontTakeDamage = false; npc.netUpdate = true; npc.ai[0] = 0; npc.ai[1] = 0; npc.ai[2] = 0; npc.ai[3] = 0; npc.localAI[3] = 2; //can die now } break; case -1: targetPos = new Vector2(npc.localAI[0], npc.localAI[1]); if (npc.Distance(targetPos) > 25) { Movement(targetPos, 0.8f, 24f); } if (++npc.ai[1] > 360) { npc.TargetClosest(); npc.ai[0] = 4; npc.ai[1] = 0; npc.ai[2] = 0; npc.ai[3] = 0; npc.netUpdate = true; if (npc.Hitbox.Intersects(player.Hitbox)) { player.velocity.X = player.Center.X < npc.Center.X ? -15f : 15f; player.velocity.Y = -10f; Main.PlaySound(SoundID.Roar, npc.Center, 0); } } break; case 0: //float to player if (!player.active || player.dead || Vector2.Distance(npc.Center, player.Center) > 2500f || (Framing.GetTileSafely(player.Center).wall == WallID.None && !player.ZoneUndergroundDesert)) //despawn code { npc.TargetClosest(false); if (npc.timeLeft > 30) { npc.timeLeft = 30; } npc.noTileCollide = true; npc.noGravity = true; npc.velocity.Y += 1f; return; } if (npc.ai[1] == 0) { targetPos = player.Center; npc.velocity = (targetPos - npc.Center) / 75; npc.localAI[0] = targetPos.X; npc.localAI[1] = targetPos.Y; } if (++npc.ai[1] > 75) { npc.TargetClosest(); npc.ai[0]++; npc.ai[1] = 0; npc.ai[2] = 0; npc.ai[3] = 0; npc.netUpdate = true; } break; case 1: //cross bone/sandnado if (npc.localAI[2] == 0) { npc.localAI[2] = 1; } targetPos = new Vector2(npc.localAI[0], npc.localAI[1]); if (npc.Distance(targetPos) > 25) { Movement(targetPos, 0.8f, 24f); } if (++npc.ai[2] > 45) { npc.ai[2] = 0; if (Main.netMode != NetmodeID.MultiplayerClient) { if (npc.ai[1] < 180) //cross bones { Main.PlaySound(SoundID.Item2, npc.Center); for (int i = 0; i < 12; i++) { Projectile.NewProjectile(npc.position.X + Main.rand.Next(npc.width), npc.position.Y + Main.rand.Next(npc.height), Main.rand.NextFloat(-8f, 8f), Main.rand.NextFloat(-8f, 8f), ModContent.ProjectileType <SpiritCrossBone>(), npc.damage / 4, 0f, Main.myPlayer); } } else //sandnado { npc.GetGlobalNPC <EModeGlobalNPC>().masoBool[0] = !npc.GetGlobalNPC <EModeGlobalNPC>().masoBool[0]; Vector2 target = player.Center; if (npc.GetGlobalNPC <EModeGlobalNPC>().masoBool[0] && npc.life < npc.lifeMax * 0.66) { target += player.velocity * 30f; //alternate between predictive and direct aim } target.Y -= 100; Projectile.NewProjectile(target, Vector2.Zero, ProjectileID.SandnadoHostileMark, 0, 0f, Main.myPlayer); int length = (int)npc.Distance(target) / 10; Vector2 offset = npc.DirectionTo(target) * 10f; for (int i = 0; i < length; i++) //dust warning line for sandnado { int d = Dust.NewDust(npc.Center + offset * i, 0, 0, 269, 0f, 0f, 0, new Color()); Main.dust[d].noLight = true; Main.dust[d].scale = 1.25f; } } } } if (++npc.ai[1] > 400) { npc.TargetClosest(); npc.ai[0]++; npc.ai[1] = 0; npc.ai[2] = 0; npc.ai[3] = 0; npc.netUpdate = true; } break; case 2: goto case 0; case 3: //grab targetPos = new Vector2(npc.localAI[0], npc.localAI[1]); if (npc.Distance(targetPos) > 25) { Movement(targetPos, 0.8f, 24f); } if (++npc.ai[2] == 30) { for (int i = 0; i < Main.maxNPCs; i++) { if (Main.npc[i].active && Main.npc[i].type == ModContent.NPCType <SpiritChampionHand>() && Main.npc[i].ai[1] == npc.whoAmI) { Main.npc[i].ai[0] = 1f; Main.npc[i].netUpdate = true; } } } if (npc.life < npc.lifeMax * 0.66) { if (++npc.ai[3] > 55) //homing spectre bolts { npc.ai[3] = 0; if (Main.netMode != NetmodeID.MultiplayerClient) { const int max = 5; for (int i = 0; i < max; i++) { Vector2 speed = Main.rand.NextFloat(1, 2) * Vector2.UnitX.RotatedByRandom(Math.PI * 2); float ai1 = 60 + Main.rand.Next(30); Projectile.NewProjectile(npc.Center, speed, ModContent.ProjectileType <SpiritSpirit>(), npc.damage / 4, 0f, Main.myPlayer, npc.whoAmI, ai1); } } } } if (++npc.ai[1] > 360) { npc.TargetClosest(); npc.ai[0]++; npc.ai[1] = 0; npc.ai[2] = 0; npc.ai[3] = 0; npc.netUpdate = true; } break; case 4: goto case 0; case 5: //swords targetPos = new Vector2(npc.localAI[0], npc.localAI[1]); if (npc.Distance(targetPos) > 25) { Movement(targetPos, 0.8f, 24f); } if (++npc.ai[2] > 80) { npc.ai[2] = 0; Main.PlaySound(SoundID.Item92, npc.Center); if (Main.netMode != NetmodeID.MultiplayerClient) { for (int i = 0; i < 15; i++) //sword burst { float speed = Main.rand.NextFloat(4f, 8f); Vector2 velocity = speed * Vector2.UnitX.RotatedBy(Main.rand.NextDouble() * 2 * Math.PI); float ai1 = speed / Main.rand.NextFloat(60f, 120f); Projectile.NewProjectile(npc.Center, velocity, ModContent.ProjectileType <SpiritSword>(), npc.damage / 4, 0f, Main.myPlayer, 0f, ai1); } if (npc.life < npc.lifeMax * 0.66) { const int max = 12; //hand ring for (int i = 0; i < max; i++) { Vector2 vel = npc.DirectionTo(player.Center).RotatedBy(Math.PI * 2 / max * i); float ai0 = 1.04f; Projectile.NewProjectile(npc.Center, vel, ModContent.ProjectileType <SpiritHand>(), npc.damage / 4, 0f, Main.myPlayer, ai0); } } } } if (++npc.ai[1] > 300) { npc.TargetClosest(); npc.ai[0]++; npc.ai[1] = 0; npc.ai[2] = 0; npc.ai[3] = 0; npc.netUpdate = true; } break; case 6: goto case 0; case 7: //skip this number, staying on even number allows hands to remain drawn close npc.ai[0]++; break; case 8: //shadow hands, reflect, mummy spirits { targetPos = new Vector2(npc.localAI[0], npc.localAI[1]); if (npc.Distance(targetPos) > 25) { Movement(targetPos, 0.8f, 24f); } const float distance = 150; for (int i = 0; i < 20; i++) { Vector2 offset = new Vector2(); double angle = Main.rand.NextDouble() * 2d * Math.PI; offset.X += (float)(Math.Sin(angle) * distance); offset.Y += (float)(Math.Cos(angle) * distance); Dust dust = Main.dust[Dust.NewDust( npc.Center + offset - new Vector2(4, 4), 0, 0, 87, 0, 0, 100, Color.White, 1f )]; dust.velocity = npc.velocity; //if (Main.rand.NextBool(3)) dust.velocity += Vector2.Normalize(offset) * -5f; dust.noGravity = true; } if (npc.ai[1] > 60) { Main.projectile.Where(x => x.active && x.friendly && !FargoSoulsUtil.IsMinionDamage(x, false)).ToList().ForEach(x => //reflect projectiles { if (Vector2.Distance(x.Center, npc.Center) <= distance) { for (int i = 0; i < 5; i++) { int dustId = Dust.NewDust(x.position, x.width, x.height, 87, x.velocity.X * 0.2f, x.velocity.Y * 0.2f, 100, default(Color), 1.5f); Main.dust[dustId].noGravity = true; } // Set ownership x.hostile = true; x.friendly = false; x.owner = Main.myPlayer; x.damage /= 4; // Turn around x.velocity *= -1f; // Flip sprite if (x.Center.X > npc.Center.X * 0.5f) { x.direction = 1; x.spriteDirection = 1; } else { x.direction = -1; x.spriteDirection = -1; } //x.netUpdate = true; if (x.owner == Main.myPlayer) { Projectile.NewProjectile(x.Center, Vector2.Zero, ModContent.ProjectileType <Projectiles.Souls.IronParry>(), 0, 0f, Main.myPlayer); } } }); } if (npc.ai[1] == 0) { Main.PlaySound(SoundID.Roar, npc.Center, 0); if (Main.netMode != NetmodeID.MultiplayerClient) { Projectile.NewProjectile(npc.Center, Vector2.Zero, ModContent.ProjectileType <Projectiles.GlowRing>(), 0, 0f, Main.myPlayer, npc.whoAmI, -6); } } if (++npc.ai[3] > 10) //spirits { npc.ai[3] = 0; Main.PlaySound(SoundID.Item8, npc.Center); if (Main.netMode != NetmodeID.MultiplayerClient) //vanilla code from desert spirits idfk { Point tileCoordinates1 = npc.Center.ToTileCoordinates(); Point tileCoordinates2 = Main.player[npc.target].Center.ToTileCoordinates(); Vector2 vector2 = Main.player[npc.target].Center - npc.Center; int num1 = 6; int num2 = 6; int num3 = 0; int num4 = 2; int num5 = 0; bool flag1 = false; if (vector2.Length() > 2000) { flag1 = true; } while (!flag1 && num5 < 50) { ++num5; int index1 = Main.rand.Next(tileCoordinates2.X - num1, tileCoordinates2.X + num1 + 1); int index2 = Main.rand.Next(tileCoordinates2.Y - num1, tileCoordinates2.Y + num1 + 1); if ((index2 < tileCoordinates2.Y - num3 || index2 > tileCoordinates2.Y + num3 || (index1 < tileCoordinates2.X - num3 || index1 > tileCoordinates2.X + num3)) && (index2 < tileCoordinates1.Y - num2 || index2 > tileCoordinates1.Y + num2 || (index1 < tileCoordinates1.X - num2 || index1 > tileCoordinates1.X + num2)) && !Main.tile[index1, index2].nactive()) { bool flag2 = true; if (flag2 && Main.tile[index1, index2].lava()) { flag2 = false; } if (flag2 && Collision.SolidTiles(index1 - num4, index1 + num4, index2 - num4, index2 + num4)) { flag2 = false; } if (flag2) { Projectile.NewProjectile(index1 * 16 + 8, index2 * 16 + 8, 0, 0f, ProjectileID.DesertDjinnCurse, 0, 1f, Main.myPlayer, npc.target, 0f); break; } } } } } if (++npc.ai[2] > 70) //hands { npc.ai[2] = 0; if (Main.netMode != NetmodeID.MultiplayerClient) { for (int i = 0; i < 4; i++) { Vector2 vel = npc.DirectionTo(player.Center).RotatedBy(Math.PI / 6 * (Main.rand.NextDouble() - 0.5)); float ai0 = Main.rand.NextFloat(1.04f, 1.06f); float ai1 = Main.rand.NextFloat(0.025f); Projectile.NewProjectile(npc.Center, vel, ModContent.ProjectileType <SpiritHand>(), npc.damage / 4, 0f, Main.myPlayer, ai0, ai1); } } } if (npc.ai[1] % 30 == 0 && Main.netMode != NetmodeID.MultiplayerClient && npc.life < npc.lifeMax * 0.66) { Main.PlaySound(SoundID.Item2, npc.Center); for (int i = 0; i < 3; i++) { Projectile.NewProjectile(npc.position.X + Main.rand.Next(npc.width), npc.position.Y + Main.rand.Next(npc.height), Main.rand.NextFloat(-1f, 1f), Main.rand.NextFloat(-8f, 0f), ModContent.ProjectileType <SpiritCrossBone>(), npc.damage / 4, 0f, Main.myPlayer); Projectile.NewProjectile(npc.position.X + Main.rand.Next(npc.width), npc.position.Y + Main.rand.Next(npc.height), Main.rand.NextFloat(-1f, 1f), Main.rand.NextFloat(8f, 0f), ModContent.ProjectileType <SpiritCrossBoneReverse>(), npc.damage / 4, 0f, Main.myPlayer); } } if (++npc.ai[1] > 360) { npc.TargetClosest(); npc.ai[0]++; npc.ai[1] = 0; npc.ai[2] = 0; npc.ai[3] = 0; npc.netUpdate = true; } } break; case 9: //skip this number, get back to usual behaviour npc.ai[0]++; break; /*case 10: * goto case 0;*/ default: npc.ai[0] = 0; goto case 0; } if (npc.localAI[2] != 0 && FargoSoulsWorld.EternityMode) //aura { const float auraDistance = 1200; float range = npc.Distance(player.Center); if (range > auraDistance && range < 3000) { if (++npc.localAI[2] > 60) { npc.localAI[2] = 1; npc.netUpdate = true; Main.PlaySound(SoundID.Roar, npc.Center, 0); if (Main.netMode != NetmodeID.MultiplayerClient) //spawn super hand { int n2 = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <SpiritChampionHand>(), npc.whoAmI, 4f, npc.whoAmI, 1f, 1f, npc.target); if (n2 != Main.maxNPCs) { Main.npc[n2].velocity.X = Main.rand.NextFloat(-24f, 24f); Main.npc[n2].velocity.Y = Main.rand.NextFloat(-24f, 24f); if (Main.netMode == NetmodeID.Server) { NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n2); } } } } } for (int i = 0; i < 20; i++) //dust { int d = Dust.NewDust(npc.Center + auraDistance * Vector2.UnitX.RotatedBy(Math.PI * 2 * Main.rand.NextDouble()), 0, 0, 87); Main.dust[d].velocity = npc.velocity; Main.dust[d].noGravity = true; Main.dust[d].scale++; } } }
public override void AI() { if (projectile.localAI[1] == 0) { projectile.localAI[1] = Main.rand.NextBool() ? -1 : 1; projectile.timeLeft = (int)projectile.ai[1]; } NPC mutant = Main.npc[(int)projectile.ai[0]]; if (mutant.active && mutant.type == mod.NPCType("MutantBoss")) { projectile.Center = mutant.Center; direction = mutant.direction; if (mutant.ai[0] == 4 || mutant.ai[0] == 13 || mutant.ai[0] == 21) { projectile.rotation += (float)Math.PI / 6.85f * projectile.localAI[1]; if (++projectile.localAI[0] > 8) { projectile.localAI[0] = 0; if (Main.netMode != NetmodeID.MultiplayerClient) { Vector2 speed = Vector2.UnitY.RotatedByRandom(Math.PI / 2) * Main.rand.NextFloat(6f, 9f); if (mutant.Center.Y < Main.player[mutant.target].Center.Y) { speed *= -1f; } float ai1 = projectile.timeLeft + Main.rand.Next(projectile.timeLeft / 2); Projectile.NewProjectile(projectile.position + Main.rand.NextVector2Square(0f, projectile.width), speed, ModContent.ProjectileType <MutantEyeHoming>(), projectile.damage, 0f, projectile.owner, mutant.target, ai1); } } if (projectile.timeLeft % 20 == 0) { Main.PlaySound(SoundID.Item1, projectile.Center); } if (mutant.ai[0] == 13) { predictive = true; } projectile.alpha = 0; if (FargoSoulsWorld.MasochistModeReal) { Main.projectile.Where(x => x.active && x.friendly && !FargoSoulsUtil.IsMinionDamage(x, false)).ToList().ForEach(x => //reflect projectiles { if (Vector2.Distance(x.Center, mutant.Center) <= projectile.width / 2) { for (int i = 0; i < 5; i++) { int dustId = Dust.NewDust(x.position, x.width, x.height, 87, x.velocity.X * 0.2f, x.velocity.Y * 0.2f, 100, default(Color), 1.5f); Main.dust[dustId].noGravity = true; } // Set ownership x.hostile = true; x.friendly = false; x.owner = Main.myPlayer; x.damage /= 4; // Turn around x.velocity *= -1f; // Flip sprite if (x.Center.X > mutant.Center.X) { x.direction = 1; x.spriteDirection = 1; } else { x.direction = -1; x.spriteDirection = -1; } //x.netUpdate = true; if (x.owner == Main.myPlayer) { Projectile.NewProjectile(x.Center, Vector2.Zero, ModContent.ProjectileType <Souls.IronParry>(), 0, 0f, Main.myPlayer); } } }); } } else { projectile.alpha = 255; } } else { projectile.Kill(); return; } }
public override void AI() { Player player = Main.player[projectile.owner]; FargoPlayer modPlayer = player.GetModPlayer <FargoPlayer>(); projectile.netUpdate = true; if (player.whoAmI == Main.myPlayer && (player.dead || !(modPlayer.ShadowEnchant || modPlayer.TerrariaSoul) || !player.GetToggleValue("Shadow"))) { modPlayer.ShadowEnchant = false; projectile.Kill(); return; } // CD if (projectile.ai[0] > 0) { projectile.ai[0]--; //dusts indicate its back if (projectile.ai[0] == 0) { const int num226 = 18; for (int num227 = 0; num227 < num226; num227++) { Vector2 vector6 = Vector2.UnitX.RotatedBy(projectile.rotation) * 6f; vector6 = vector6.RotatedBy(((num227 - (num226 / 2 - 1)) * 6.28318548f / num226), default(Vector2)) + projectile.Center; Vector2 vector7 = vector6 - projectile.Center; int num228 = Dust.NewDust(vector6 + vector7, 0, 0, DustID.Shadowflame, 0f, 0f, 0, default(Color), 2f); Main.dust[num228].noGravity = true; Main.dust[num228].velocity = vector7; } } } float num395 = Main.mouseTextColor / 200f - 0.35f; num395 *= 0.2f; projectile.scale = num395 + 0.95f; if (projectile.owner == Main.myPlayer) { //rotation mumbo jumbo float distanceFromPlayer = 250; Lighting.AddLight(projectile.Center, 0.1f, 0.4f, 0.2f); projectile.position = player.Center + new Vector2(distanceFromPlayer, 0f).RotatedBy(projectile.ai[1]); projectile.position.X -= projectile.width / 2; projectile.position.Y -= projectile.height / 2; float rotation = (float)Math.PI / 120; projectile.ai[1] -= rotation; if (projectile.ai[1] > (float)Math.PI) { projectile.ai[1] -= 2f * (float)Math.PI; projectile.netUpdate = true; } projectile.rotation = projectile.ai[1] + (float)Math.PI / 2f; //wait for CD if (projectile.ai[0] != 0f) { return; } //detect being hit foreach (Projectile proj in Main.projectile.Where(proj => proj.active && proj.friendly && !proj.hostile && proj.owner == projectile.owner && proj.damage > 0 && !FargoSoulsUtil.IsMinionDamage(proj, false) && proj.type != ModContent.ProjectileType <ShadowBall>() && proj.Colliding(proj.Hitbox, projectile.Hitbox))) { int numBalls = 5; int dmg = 25; if (modPlayer.AncientShadowEnchant) { numBalls = 10; dmg = 50; } FargoSoulsUtil.XWay(numBalls, projectile.Center, ModContent.ProjectileType <ShadowBall>(), 6, modPlayer.HighestDamageTypeScaling(dmg), 0); if (FargoSoulsUtil.CanDeleteProjectile(proj)) { proj.Kill(); } projectile.ai[0] = 300; break; } } }
public override void OnHitByProjectile(NPC npc, Projectile projectile, int damage, float knockback, bool crit) { base.OnHitByProjectile(npc, projectile, damage, knockback, crit); IncrementDamageCounters(projectile.melee, projectile.ranged, projectile.magic, FargoSoulsUtil.IsMinionDamage(projectile), damage); }