public override void AI() { if (npc.localAI[2] == 0) { npc.TargetClosest(false); Movement(Main.player[npc.target].Center, 0.8f, 32f); if (npc.Distance(Main.player[npc.target].Center) < 1500) { npc.localAI[2] = 1; } else { return; } } EModeGlobalNPC.championBoss = npc.whoAmI; Player player = Main.player[npc.target]; npc.direction = npc.spriteDirection = npc.position.X < player.position.X ? 1 : -1; switch ((int)npc.ai[0]) { case -1: //mourning wood movement { npc.noTileCollide = true; npc.noGravity = true; if (Math.Abs(player.Center.X - npc.Center.X) < npc.width / 2) { npc.velocity.X *= 0.9f; if (Math.Abs(npc.velocity.X) < 0.1f) { npc.velocity.X = 0f; } } else { float accel = 4f; if (npc.direction > 0) { npc.velocity.X = (npc.velocity.X * 20 + accel) / 21; } else { npc.velocity.X = (npc.velocity.X * 20 - accel) / 21; } } bool onPlatforms = false; for (int i = (int)npc.position.X; i <= npc.position.X + npc.width; i += 16) { if (Framing.GetTileSafely(new Vector2(i, npc.position.Y + npc.height + npc.velocity.Y + 1)).type == TileID.Platforms) { onPlatforms = true; break; } } bool onCollision = Collision.SolidCollision(npc.position, npc.width, npc.height); if (npc.position.X < player.position.X && npc.position.X + npc.width > player.position.X + player.width && npc.position.Y + npc.height < player.position.Y + player.height - 16) { npc.velocity.Y += 0.5f; } else if (onCollision || (onPlatforms && player.position.Y + player.height <= npc.position.Y + npc.height)) { if (npc.velocity.Y > 0f) { npc.velocity.Y = 0f; } if (onCollision) { if (npc.velocity.Y > -0.2f) { npc.velocity.Y -= 0.025f; } else { npc.velocity.Y -= 0.2f; } if (npc.velocity.Y < -4f) { npc.velocity.Y = -4f; } } } else { if (npc.velocity.Y < 0f) { npc.velocity.Y = 0f; } if (npc.velocity.Y < 0.1f) { npc.velocity.Y += 0.025f; } else { npc.velocity.Y += 0.5f; } } if (npc.velocity.Y > 10f) { npc.velocity.Y = 10f; } } break; case 0: //jump at player npc.noTileCollide = false; npc.noGravity = false; if (++npc.ai[1] == 60) { npc.TargetClosest(); if (npc.localAI[0] == 0 && npc.life < npc.lifeMax * .66f) //spawn palm tree supports { npc.localAI[0] = 1; if (Main.netMode != NetmodeID.MultiplayerClient) { Projectile.NewProjectile(npc.Center, Vector2.Zero, ModContent.ProjectileType <PalmTreeHostile>(), npc.damage / 4, 0f, Main.myPlayer, npc.whoAmI); } } if (npc.localAI[1] == 0 && npc.life < npc.lifeMax * .33f) //spawn palm tree supports { npc.localAI[1] = 1; if (Main.netMode != NetmodeID.MultiplayerClient) { Projectile.NewProjectile(npc.Center, Vector2.Zero, ModContent.ProjectileType <PalmTreeHostile>(), npc.damage / 4, 0f, Main.myPlayer, npc.whoAmI); } } const float gravity = 0.4f; const float time = 90f; Vector2 distance = player.Center - npc.Center; distance.Y -= npc.height; distance.X = distance.X / time; distance.Y = distance.Y / time - 0.5f * gravity * time; npc.velocity = distance; npc.noTileCollide = true; npc.noGravity = true; npc.netUpdate = true; if (Main.netMode != NetmodeID.MultiplayerClient) //explosive jump { Projectile.NewProjectile(npc.Center, Vector2.Zero, ProjectileID.DD2OgreSmash, npc.damage / 4, 0, Main.myPlayer); } Main.PlaySound(SoundID.Item, (int)npc.position.X, (int)npc.position.Y, 14); for (int k = -2; k <= 2; k++) //explosions { Vector2 dustPos = npc.Center; int width = npc.width / 5; dustPos.X += width * k + Main.rand.NextFloat(-width, width); dustPos.Y += Main.rand.NextFloat(npc.height / 2); for (int i = 0; i < 30; i++) { int dust = Dust.NewDust(dustPos, 32, 32, 31, 0f, 0f, 100, default(Color), 3f); Main.dust[dust].velocity *= 1.4f; } for (int i = 0; i < 20; i++) { int dust = Dust.NewDust(dustPos, 32, 32, 6, 0f, 0f, 100, default(Color), 3.5f); Main.dust[dust].noGravity = true; Main.dust[dust].velocity *= 7f; dust = Dust.NewDust(dustPos, 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; } } } else if (npc.ai[1] > 60) { npc.noTileCollide = true; npc.noGravity = true; npc.velocity.Y += 0.4f; if (npc.ai[1] > 60 + 90) { npc.TargetClosest(); npc.ai[0]++; npc.ai[1] = 0; npc.netUpdate = true; } } else //less than 60 { if (Math.Abs(npc.velocity.X) > Math.Abs(npc.velocity.Y)) { npc.velocity.X = Math.Abs(npc.velocity.Y) * Math.Sign(npc.velocity.X); } if (npc.velocity.Y == 0) { npc.velocity.X *= 0.99f; } if (!player.active || player.dead || Vector2.Distance(npc.Center, player.Center) > 2500f) { npc.TargetClosest(); if (npc.timeLeft > 30) { npc.timeLeft = 30; } npc.noTileCollide = true; npc.noGravity = true; npc.velocity.Y -= 1f; npc.ai[0] = 0; //prevent proceeding to next steps of ai while despawning } else { npc.timeLeft = 600; } goto case -1; } break; case 1: //acorn sprays if (++npc.ai[2] > 35) { npc.ai[2] = 0; const float gravity = 0.2f; float time = 60f; Vector2 distance = player.Center - npc.Center;// + player.velocity * 30f; distance.X = distance.X / time; distance.Y = distance.Y / time - 0.5f * gravity * time; for (int i = 0; i < 20; i++) { Projectile.NewProjectile(npc.Center, distance + Main.rand.NextVector2Square(-0.5f, 0.5f) * 3, ModContent.ProjectileType <Acorn>(), npc.damage / 5, 0f, Main.myPlayer); } } if (++npc.ai[1] > 120) { npc.ai[0]++; npc.ai[1] = 0; npc.ai[2] = 0; npc.netUpdate = true; npc.TargetClosest(); } goto case -1; case 2: goto case 0; case 3: //snowball barrage if (++npc.ai[2] > 5) { npc.ai[2] = 0; if (Main.netMode != NetmodeID.MultiplayerClient && npc.ai[1] > 30 && npc.ai[1] < 120) { Vector2 offset; offset.X = Main.rand.NextFloat(0, npc.width / 2) * npc.direction; offset.Y = 16; Projectile.NewProjectile(npc.Center + offset, Vector2.UnitY * -12f, ModContent.ProjectileType <Snowball>(), npc.damage / 4, 0f, Main.myPlayer); } } if (++npc.ai[1] > 150) { npc.ai[0]++; npc.ai[1] = 0; npc.ai[2] = 0; npc.netUpdate = true; npc.TargetClosest(); } goto case -1; case 4: goto case 0; case 5: //spray squirrels if (++npc.ai[2] > 6) { npc.ai[2] = 0; if (Main.netMode != NetmodeID.MultiplayerClient) { int n = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <LesserSquirrel>()); if (n != Main.maxNPCs) { Main.npc[n].velocity.X = Main.rand.NextFloat(-10, 10); Main.npc[n].velocity.Y = Main.rand.NextFloat(-20, -10); Main.npc[n].netUpdate = true; if (Main.netMode == NetmodeID.Server) { NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n); } } } } if (++npc.ai[1] > 180) { npc.ai[0]++; npc.ai[1] = 0; npc.ai[2] = 0; npc.netUpdate = true; npc.TargetClosest(); } goto case -1; case 6: goto case 0; case 7: goto case 3; case 8: goto case 0; case 9: //grappling hook if (npc.ai[2] == 0) //shoot hook { npc.ai[2] = 1; if (Main.netMode != NetmodeID.MultiplayerClient) { Projectile.NewProjectile(npc.Center, npc.DirectionTo(player.Center) * 16, ModContent.ProjectileType <SquirrelHook>(), 0, 0f, Main.myPlayer, npc.whoAmI); } } if (++npc.ai[1] < 240) //charge power { for (int i = 0; i < 5; i++) { int d = Dust.NewDust(npc.position, npc.width, npc.height, DustID.Shadowflame, 0f, 0f, 0, default(Color), 2f); Main.dust[d].noGravity = true; Main.dust[d].velocity *= 8f; d = Dust.NewDust(npc.Center, 0, 0, DustID.Shadowflame, 0f, 0f, 0, default(Color), 3f); Main.dust[d].noGravity = true; Main.dust[d].velocity *= 16f; } 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) * 500); offset.Y += (float)(Math.Cos(angle) * 500); Dust dust = Main.dust[Dust.NewDust(npc.Center + offset - new Vector2(4, 4), 0, 0, DustID.Shadowflame, 0, 0, 100, Color.White, 2f)]; dust.velocity = npc.velocity; if (Main.rand.Next(3) == 0) { dust.velocity += Vector2.Normalize(offset) * -5f; } dust.noGravity = true; } } else if (npc.ai[1] == 240) //explode { if (Main.netMode != NetmodeID.MultiplayerClient) { Projectile.NewProjectile(npc.Center, Vector2.Zero, ModContent.ProjectileType <ShadowflameBlast>(), npc.damage / 2, 0f, Main.myPlayer); } } else if (npc.ai[1] > 300) { npc.ai[0]++; npc.ai[1] = 0; npc.ai[2] = 0; npc.netUpdate = true; npc.TargetClosest(); } goto case -1; default: npc.ai[0] = 0; goto case 0; } }
public override void AI() { bool flag64 = projectile.type == mod.ProjectileType("DoomiteProbe"); Player player = Main.player[projectile.owner]; AAPlayer modPlayer = player.GetModPlayer <AAPlayer>(); player.AddBuff(mod.BuffType("DoomiteProbe"), 3600); if (flag64) { if (player.dead) { modPlayer.DoomiteProbe = false; } if (modPlayer.DoomiteProbe) { projectile.timeLeft = 2; } } float num633 = 700f; float num634 = 800f; float num635 = 1200f; float num636 = 150f; float num637 = 0.05f; for (int num638 = 0; num638 < 1000; num638++) { bool flag23 = Main.projectile[num638].type == mod.ProjectileType("ProbeMinion"); if (num638 != projectile.whoAmI && Main.projectile[num638].active && Main.projectile[num638].owner == projectile.owner && flag23 && Math.Abs(projectile.position.X - Main.projectile[num638].position.X) + Math.Abs(projectile.position.Y - Main.projectile[num638].position.Y) < projectile.width) { if (projectile.position.X < Main.projectile[num638].position.X) { projectile.velocity.X = projectile.velocity.X - num637; } else { projectile.velocity.X = projectile.velocity.X + num637; } if (projectile.position.Y < Main.projectile[num638].position.Y) { projectile.velocity.Y = projectile.velocity.Y - num637; } else { projectile.velocity.Y = projectile.velocity.Y + num637; } } } bool flag24 = false; if (flag24) { return; } Vector2 vector46 = projectile.position; bool flag25 = false; if (projectile.ai[0] != 1f) { projectile.tileCollide = false; } if (projectile.tileCollide && WorldGen.SolidTile(Framing.GetTileSafely((int)projectile.Center.X / 16, (int)projectile.Center.Y / 16))) { projectile.tileCollide = false; } if (player.HasMinionAttackTargetNPC) { NPC nPC2 = Main.npc[player.MinionAttackTargetNPC]; if (nPC2.CanBeChasedBy(projectile, false)) { float num646 = Vector2.Distance(nPC2.Center, projectile.Center); if (((Vector2.Distance(projectile.Center, vector46) > num646 && num646 < num633) || !flag25) && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, nPC2.position, nPC2.width, nPC2.height)) { num633 = num646; vector46 = nPC2.Center; flag25 = true; } } } else { for (int num645 = 0; num645 < 200; num645++) { NPC nPC2 = Main.npc[num645]; if (nPC2.CanBeChasedBy(projectile, false)) { float num646 = Vector2.Distance(nPC2.Center, projectile.Center); if (((Vector2.Distance(projectile.Center, vector46) > num646 && num646 < num633) || !flag25) && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, nPC2.position, nPC2.width, nPC2.height)) { num633 = num646; vector46 = nPC2.Center; flag25 = true; } } } } float num647 = num634; if (flag25) { num647 = num635; } if (Vector2.Distance(player.Center, projectile.Center) > num647) { projectile.ai[0] = 1f; projectile.tileCollide = false; projectile.netUpdate = true; } if (flag25 && projectile.ai[0] == 0f) { Vector2 vector47 = vector46 - projectile.Center; float num648 = vector47.Length(); vector47.Normalize(); if (num648 > 200f) { float scaleFactor2 = 6f; vector47 *= scaleFactor2; projectile.velocity = (projectile.velocity * 40f + vector47) / 41f; } else { float num649 = 4f; vector47 *= -num649; projectile.velocity = (projectile.velocity * 40f + vector47) / 41f; } } else { bool flag26 = false; if (!flag26) { flag26 = projectile.ai[0] == 1f; } float num650 = 6f; if (flag26) { num650 = 15f; } Vector2 center2 = projectile.Center; Vector2 vector48 = player.Center - center2 + new Vector2(0f, -60f); float num651 = vector48.Length(); if (num651 > 200f && num650 < 8f) { num650 = 8f; } if (num651 < num636 && flag26 && !Collision.SolidCollision(projectile.position, projectile.width, projectile.height)) { projectile.ai[0] = 0f; projectile.netUpdate = true; } if (num651 > 2000f) { projectile.position.X = Main.player[projectile.owner].Center.X - projectile.width / 2; projectile.position.Y = Main.player[projectile.owner].Center.Y - projectile.height / 2; projectile.netUpdate = true; } if (num651 > 70f) { vector48.Normalize(); vector48 *= num650; projectile.velocity = (projectile.velocity * 40f + vector48) / 41f; } else if (projectile.velocity.X == 0f && projectile.velocity.Y == 0f) { projectile.velocity.X = -0.15f; projectile.velocity.Y = -0.05f; } } if (projectile.direction == 1) { projectile.spriteDirection = 1; } else { projectile.spriteDirection = -1; } projectile.frameCounter++; if (projectile.frameCounter >= 5) { projectile.frameCounter = 0; projectile.frame++; } if (projectile.frame > 3) { projectile.frame = 0; } if (projectile.ai[1] > 0f) { projectile.ai[1] += Main.rand.Next(1, 4); } if (projectile.ai[1] > 60f) { projectile.ai[1] = 0f; projectile.netUpdate = true; } if (projectile.ai[0] == 0f) { float scaleFactor3 = 8f; int num658 = 389; if (flag25 && projectile.ai[1] == 0f) { projectile.ai[1] += 1f; if (Main.myPlayer == projectile.owner && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, vector46, 0, 0)) { Vector2 value19 = vector46 - projectile.Center; value19.Normalize(); value19 *= scaleFactor3; int num659 = Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, value19.X, value19.Y, num658, projectile.damage, 0f, Main.myPlayer, 0f, 0f); Main.projectile[num659].penetrate = 1; Main.projectile[num659].timeLeft = 300; projectile.netUpdate = true; } } } }
public override bool SpawnConditions(int i, int j) { var tile = Framing.GetTileSafely(i, j); return(tile.frameX < 16 && tile.frameY == 0); }
public override void AI() { if (npc.localAI[3] == 0) //spawn friends { npc.TargetClosest(false); Movement(Main.player[npc.target].Center, 0.8f, 32f); if (npc.Distance(Main.player[npc.target].Center) < 2000) { npc.localAI[3] = 1; } else { return; } 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); } } } } EModeGlobalNPC.championBoss = npc.whoAmI; Player player = Main.player[npc.target]; Vector2 targetPos; if (npc.HasValidTarget && npc.Distance(player.Center) < 2500 && Framing.GetTileSafely(player.Center).wall != WallID.None) { npc.timeLeft = 600; } switch ((int)npc.ai[0]) { case -4: //final float npc.dontTakeDamage = true; goto case 0; case -3: //final you think you're safe 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) //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); } npc.dontTakeDamage = true; 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 -= 150; 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; } 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) //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] > 60) { 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 { Vector2 target = player.Center; target.X += player.velocity.X * 90; target.Y -= 150; 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.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++) { 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.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.Next(3) == 0) dust.velocity += Vector2.Normalize(offset) * -5f; dust.noGravity = true; } Main.projectile.Where(x => x.active && x.friendly && !x.minion).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 (npc.ai[1] == 0) { Main.PlaySound(SoundID.Roar, npc.Center, 0); } 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] > 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.MasochistMode) //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() { Player player = Main.player[Projectile.owner]; FargoSoulsPlayer modPlayer = player.GetModPlayer <FargoSoulsPlayer>(); if (player.dead || player.ghost) { modPlayer.ChibiDevi = false; } if (modPlayer.ChibiDevi) { Projectile.timeLeft = 2; } DelegateMethods.v3_1 = new Vector3(1f, 0.5f, 0.9f) * 0.75f; Utils.PlotTileLine(Projectile.Center, Projectile.Center + Projectile.velocity * 6f, 20f, DelegateMethods.CastLightOpen); Utils.PlotTileLine(Projectile.Left, Projectile.Right, 20f, DelegateMethods.CastLightOpen); bool asleep = Projectile.ai[0] == 1; if (asleep) { Projectile.tileCollide = true; Projectile.ignoreWater = false; Projectile.frameCounter = 0; Projectile.frame = Projectile.velocity.Y == 0 ? 5 : 4; Projectile.velocity.X *= 0.95f; Projectile.velocity.Y += 0.3f; if (Projectile.owner == Main.myPlayer && Projectile.Distance(Main.MouseWorld) > 180) { Projectile.ai[0] = 0; TryTalkWithCD(TalkType.Wake, ShortCD); } } else { if (Projectile.owner == Main.myPlayer) { Projectile.tileCollide = false; Projectile.ignoreWater = true; Projectile.direction = Projectile.Center.X < Main.MouseWorld.X ? 1 : -1; float distance = 2500; float possibleDist = Main.player[Projectile.owner].Distance(Main.MouseWorld) / 2 + 100; if (distance < possibleDist) { distance = possibleDist; } if (Projectile.Distance(Main.player[Projectile.owner].Center) > distance && Projectile.Distance(Main.MouseWorld) > distance) { Projectile.Center = player.Center; Projectile.velocity = Vector2.Zero; } if (Projectile.Distance(Main.MouseWorld) > 30) { Movement(Main.MouseWorld, 0.15f, 32f); } if (oldMouse == Main.MouseWorld) { Projectile.ai[1]++; if (Projectile.ai[1] > 600) { bool okToRest = !Collision.SolidCollision(Projectile.position, Projectile.width, Projectile.height); if (okToRest) { okToRest = false; Vector2 targetPos = new Vector2(Projectile.Center.X, Projectile.position.Y + Projectile.height); for (int i = 0; i < 10; i++) //collision check below self { targetPos.Y += 16; Tile tile = Framing.GetTileSafely(targetPos); //if solid, ok if (tile.HasUnactuatedTile && Main.tileSolid[tile.TileType]) { okToRest = true; break; } } } if (okToRest) //not in solid tiles, but found tiles within a short distance below { Projectile.ai[0] = 1; Projectile.ai[1] = 0; TryTalkWithCD(TalkType.Sleep, ShortCD); } else //try again in a bit { Projectile.ai[1] = 540; } } } else { Projectile.ai[1] = 0; oldMouse = Main.MouseWorld; } } if (++Projectile.frameCounter > 6) { Projectile.frameCounter = 0; if (++Projectile.frame >= 4) { Projectile.frame = 0; } } } Projectile.spriteDirection = Projectile.direction; bool bossAlive = FargoSoulsUtil.AnyBossAlive(); if (bossAlive) { TryTalkWithCD(TalkType.BossSpawn, ShortCD); if (Main.npc[FargoSoulsGlobalNPC.boss].life < Main.npc[FargoSoulsGlobalNPC.boss].lifeMax / 4) { TryTalkWithCD(TalkType.BossAlmostDead, MediumCD); } } else { //only do idle talk when awake, not a boss fight, and not in danger if (asleep) { TalkCDs[(int)TalkType.Idle] = Math.Max(TalkCDs[(int)TalkType.Idle], 12 * 60); } else if (player.statLife > player.statLifeMax2 / 2) { TryTalkWithCD(TalkType.Idle, MediumCD); } //wont cheer in boss fight unless over 30 seconds const int timeRequirement = 30 * 60; TalkCDs[(int)TalkType.BossAlmostDead] = Math.Max(TalkCDs[(int)TalkType.BossAlmostDead], timeRequirement); TalkCDs[(int)TalkType.KillBoss] = Math.Max(TalkCDs[(int)TalkType.KillBoss], timeRequirement); } if (universalTalkCD > 0) { universalTalkCD--; } if (Projectile.owner == Main.myPlayer) { for (int i = 0; i < TalkCDs.Length; i++) { //dont run these timer during a boss fight if (bossAlive && (i == (int)TalkType.Idle || i == (int)TalkType.BossSpawn)) { continue; } if (TalkCDs[i] > 0) { TalkCDs[i]--; } } } }
public bool PlaceWell(int i, int j) { if (!WorldGen.SolidTile(i, j + 1)) { return(false); } if (Main.tile[i, j].active()) { return(false); } if (j < 150) { return(false); } for (int y = 0; y < wellshape.GetLength(0); y++) { for (int x = 0; x < wellshape.GetLength(1); x++) { int k = i - 3 + x; int l = j - 6 + y; if (WorldGen.InWorld(k, l, 30)) { Tile tile = Framing.GetTileSafely(k, l); switch (wellshape[y, x]) { case 1: tile.type = TileID.RedBrick; tile.active(true); break; case 2: tile.type = TileID.RedBrick; tile.active(true); tile.halfBrick(true); break; case 3: tile.type = TileID.RedBrick; tile.active(true); tile.slope(2); break; case 4: tile.type = TileID.RedBrick; tile.active(true); tile.slope(1); break; case 5: tile.active(false); break; case 6: tile.type = TileID.Rope; tile.active(true); break; } switch (wellshapeWall[y, x]) { case 1: tile.wall = WallID.RedBrick; break; } switch (wellshapeWater[y, x]) { case 1: tile.liquid = 255; break; } } } } return(true); }
/// <summary>Used to make sure associated tiles on the tree die when any given tile is killed. /// Note: This is a very long checklist of every possible way to destroy a tile; in short, custom framing. If you want to change something, you might have to rewrite a good amount of it.</summary> public override void KillTile(int i, int j, ref bool fail, ref bool effectOnly, ref bool noItem) { if (fail) { return; //Do nothing if this doesn't kill the tile } Tile t = Framing.GetTileSafely(i, j); //For quick reference bool FramedTreeTile(int x, int y, params int[] frm) { Tile tile = Framing.GetTileSafely(x, y); return(tile.active() && tile.type == Type && frm.Contains(tile.frameX)); } void CullTree(int x, int startY, bool leftOrigin = false) { Tile tile = Framing.GetTileSafely(x, startY); int y = startY; while (tile.active() && tile.type == Type) { if (y != startY) { WorldGen.KillTile(x, y, false, false, false); WorldGen.KillTile(x + 1, y, false, false, false); WorldGen.KillTile(x, y, false, false, false); //I hate this. works tho } y--; tile = Framing.GetTileSafely(x, y); } WorldGen.KillTile(x + (leftOrigin ? 1 : 0), startY, false, false, false); } //This if-else statement was written many months after this had all been done. It may deprecate any amount of code below. I don't care. if (((FramedTreeTile(i, j, 360, 396) && FramedTreeTile(i + 1, j, 378, 414)) || (FramedTreeTile(i, j, 378, 414) && FramedTreeTile(i - 1, j, 360, 396))) && !CullingTree) { CullingTree = true; if (t.frameX == 360 || t.frameX == 396) { WorldGen.KillTile(i + 1, j, false, false, false); } else if (t.frameX == 378 || t.frameX == 414) { WorldGen.KillTile(i - 1, j, false, false, false); } CullingTree = false; } else if ((FramedTreeTile(i - 1, j, 0, 72, 198) || FramedTreeTile(i + 1, j, 18, 216, 306)) && Framing.GetTileSafely(i, j - 1).type == TileType <BigTree_Purity>()) //Kill any tree tiles above self if both sides are cut { if (t.frameX == 198 || t.frameX == 72) //Kill tile to the left if it's a branch { WorldGen.KillTile(i - 1, j, false, false, false); } if (t.frameX == 0 || t.frameX == 72 || t.frameX == 198) { t.frameX = 432; } if (t.frameX == 216 || t.frameX == 306) { WorldGen.KillTile(i + 1, j, false, false, false); } if (t.frameX == 18 || t.frameX == 216 || t.frameX == 306) { t.frameX = 450; } fail = true; return; //Change the frame to the wedge frame and stop this from dying } else if ((FramedTreeTile(i - 1, j, 432) || FramedTreeTile(i + 1, j, 450)) && Framing.GetTileSafely(i, j - 1).type == TileType <BigTree_Purity>()) { if (!CullingTree) { CullingTree = true; if (t.frameX == 18 || t.frameX == 216 || t.frameX == 306) { CullTree(i - 1, j); } else { CullTree(i, j, true); } CullingTree = false; } } Item.NewItem(new Vector2(i, j) * 16, drop, Main.rand.Next(1, 3)); //Drops extra wood to be proportional to vanilla tree wood loot if (t.frameX == 108 || t.frameX == 270) { Framing.GetTileSafely(i + 1, j).frameX = 162; //Adjust frame for the middle branch } if (t.frameX == 126 || t.frameX == 288) { Framing.GetTileSafely(i - 1, j).frameX = 180; //Same as above, but the right side } if (t.frameX == 90) //[Left] Middle branch killed, kill branch tip and adjust trunk frame { Framing.GetTileSafely(i + 1, j).frameX = 0; WorldGen.KillTile(i - 1, j); } if (t.frameX == 162) { Framing.GetTileSafely(i + 1, j).frameX = 0; //Adjust trunk when cut branch is killed } if (t.frameX == 144) //[Right] Middle branch killed, kill branch tip and adjust trunk frame { Framing.GetTileSafely(i - 1, j).frameX = 18; WorldGen.KillTile(i + 1, j); } if (t.frameX == 180) { Framing.GetTileSafely(i - 1, j).frameX = 18; //Adjust trunk when cut branch is killed } if (t.frameX == 36) { Framing.GetTileSafely(i + 1, j).frameX = 0; //Base left side, adjust trunk frame } if (t.frameX == 54) { Framing.GetTileSafely(i - 1, j).frameX = 18; //Base right side, adjust trunk frame } if (t.frameX == 198 || t.frameX == 396) //If adjacent to a branch, kill the branch { WorldGen.KillTile(i - 1, j, false, false, false); } if (t.frameX == 216 || t.frameX == 414) //If adjacent to a branch, kill the branch { WorldGen.KillTile(i + 1, j, false, false, false); } if (t.frameX == 72 || t.frameX == 324) //Base is killed { t.frameX++; WorldGen.KillTile(i - 1, j, false, false, false); //Kills left base root if (Framing.GetTileSafely(i + 1, j).frameX == 306 || Framing.GetTileSafely(i + 1, j).frameX == 342) { WorldGen.KillTile(i + 1, j, false, false, false); //Kills the rest of the base } } if (t.frameX == 306 || t.frameX == 342) //Base is killed { t.frameX++; WorldGen.KillTile(i + 1, j, false, false, false); //Kills right base root if (Framing.GetTileSafely(i - 1, j).frameX == 72 || Framing.GetTileSafely(i + 1, j).frameX == 324) { WorldGen.KillTile(i - 1, j, false, false, false); //Kills rest of the base } } void CutTrunkFrames(int adj) //Cuts the trunk. Please help me { if (Framing.GetTileSafely(i - adj, j + 1).frameX == 0) { Framing.GetTileSafely(i - adj, j + 1).frameX = 360; //Cut trunk } if (Framing.GetTileSafely(i - adj, j + 1).frameX == 198) { Framing.GetTileSafely(i - adj, j + 1).frameX = 396; //Cut trunk w/ adjacent branch } if (Framing.GetTileSafely(i - adj, j + 1).frameX == 72) { Framing.GetTileSafely(i - adj, j + 1).frameX = 324; } if (Framing.GetTileSafely(i - adj + 1, j + 1).frameX == 18) { Framing.GetTileSafely(i - adj + 1, j + 1).frameX = 378; //Cut trunk (right) } if (Framing.GetTileSafely(i - adj + 1, j + 1).frameX == 216) { Framing.GetTileSafely(i - adj + 1, j + 1).frameX = 414; //Cut trunk w/ adjacent branch (right) } if (Framing.GetTileSafely(i - adj + 1, j + 1).frameX == 306) { Framing.GetTileSafely(i - adj + 1, j + 1).frameX = 342; } } if (t.frameX == 0 || t.frameX == 198 || t.frameX == 360) //Kill adjacent tiles if this is a trunk or the very base of the tree - left { t.frameX++; //This makes sure there's no infinite loop without messing with anything CutTrunkFrames(0); //Cuts the trunk } else if (t.frameX == 18 || t.frameX == 216 || t.frameX == 378) //This is the same as the if above - right { t.frameX++; CutTrunkFrames(1); } if (t.frameX == 360) //Check #29907832: killed adjacent cut trunk { t.frameX++; if (Framing.GetTileSafely(i + 1, j).frameX == 378) { WorldGen.KillTile(i + 1, j); } } else if (t.frameX == 378) { t.frameX++; if (Framing.GetTileSafely(i - 1, j).frameX == 360) { WorldGen.KillTile(i - 1, j); } } if (t.frameX == 234) //Drops loot & gores from the treetop { Vector2 topPos = new Vector2(i - (TreeTopSize.X / 2), j - TreeTopSize.Y) * 16f; Item.NewItem(topPos + new Vector2(Main.rand.Next(TreeTopSize.Width), Main.rand.Next(TreeTopSize.Height)), drop, Main.rand.Next(18, 25)); //Replace Acorn (below) with whatever if you want Item.NewItem(topPos + new Vector2(Main.rand.Next(TreeTopSize.Width), Main.rand.Next(TreeTopSize.Height)), ItemID.Acorn, Main.rand.Next(7, 12)); //And obviously, add whatever extra items too if needed int leaves = Main.rand.Next(20, 28); //Randomized leaf count for (int l = 0; l < leaves; ++l) //Spawns leaf gores - note, these values are adjusted specifically for the size of the top; change TreeTopSize to adjust it easily. { Gore.NewGore(topPos + new Vector2(Main.rand.Next(TreeTopSize.Width), Main.rand.Next(TreeTopSize.Height)), new Vector2(), LeafType, Main.rand.Next(120, 160) * 0.01f); } t.frameX++; if (Framing.GetTileSafely(i + 1, j).frameX == 252) { WorldGen.KillTile(i + 1, j, false, false, false); } CutTrunkFrames(0); //Cuts the trunk } if (t.frameX == 252) //Right side top, kill adjacent { t.frameX++; if (Framing.GetTileSafely(i - 1, j).frameX == 234) { WorldGen.KillTile(i - 1, j, false, false, false); } CutTrunkFrames(1); //Cuts the trunk } if (t.frameX == 270) //Drops loot & gores from branch (left) { Vector2 branchPos = new Vector2(i - BranchSize.X, j - (BranchSize.Y / 2)) * 16; Item.NewItem(branchPos + new Vector2(Main.rand.Next(BranchSize.Width), Main.rand.Next(BranchSize.Height)), ItemID.Acorn, Main.rand.Next(3, 5)); int leaves = Main.rand.Next(12, 22); for (int l = 0; l < leaves; ++l) { Gore.NewGore(branchPos + new Vector2(Main.rand.Next(BranchSize.Width), Main.rand.Next(BranchSize.Height)), new Vector2(), LeafType, Main.rand.Next(90, 130) * 0.01f); } } if (t.frameX == 288) //Drops loot & gores from branch (left) { Vector2 branchPos = new Vector2(i, j - (BranchSize.Y / 2)) * 16; Item.NewItem(branchPos + new Vector2(Main.rand.Next(BranchSize.Width), Main.rand.Next(BranchSize.Height)), ItemID.Acorn, Main.rand.Next(3, 5)); int leaves = Main.rand.Next(12, 22); for (int l = 0; l < leaves; ++l) { Gore.NewGore(branchPos + new Vector2(Main.rand.Next(BranchSize.Width), Main.rand.Next(BranchSize.Height)), new Vector2(), LeafType, Main.rand.Next(90, 130) * 0.01f); } } }
public override void PostUpdate() { if (!Main.hardMode && !madeSunkenTreasure) { wofAlive = true; } if (NPC.AnyNPCs(398)) { moonlordAlive = true; } if (wofAlive && Main.hardMode && !madeSunkenTreasure) { wofAlive = false; wofDead = true; } if (moonlordAlive && !NPC.AnyNPCs(398)) { moonlordDead = true; moonlordAlive = false; } if (NPC.AnyNPCs(245)) { golemAlive = true; } if (golemAlive && !NPC.AnyNPCs(245)) { golemDead = true; golemAlive = false; } if (NPC.AnyNPCs(262)) { planteraAlive = true; } if (planteraAlive && !NPC.AnyNPCs(262)) { planteraDead = true; planteraAlive = false; } if (wofDead) { int ymodifier = 0; bool landed = false; for (ymodifier = 0; ymodifier < Main.maxTilesY - 1; ymodifier++) { if (Main.tile[64, ymodifier + 1].active() && !landed) { WorldGen.PlaceChest(64, ymodifier, Convert.ToUInt16(TileType <SunkenTreasureTile>()), false, 0); landed = true; Main.NewText("A treasure has sunken in the ocean!", 0, 0, 255); for (int chestIndex = 0; chestIndex < 1000; chestIndex++) { Chest chest = Main.chest[chestIndex]; int[] ItemForChest = new int[104] { 74, 78, 82, 17, 79, 83, 91, 92, 108, 107, 264, 327, 355, 517, 554, 696, 697, 698, 709, 712, 715, 744, 741, 743, 855, 864, 955, 1355, 1522, 1523, 1524, 1525, 1526, 1527, 1704, 1705, 1710, 1716, 1720, 1987, 2133, 2137, 2143, 2147, 2155, 2238, 2294, 2308, 2336, 2335, 2334, 2379, 2389, 2405, 2630, 2663, 2843, 2889, 2890, 2891, 2892, 2893, 2894, 2895, 3070, 3071, 3072, 3073, 3074, 3075, 3076, 3096, 3183, 3229, 3230, 3231, 3232, 3233, 3510, 3511, 3512, 3513, 3514, 3515, 3516, 3517, 3518, 3519, 3520, 3521, 3480, 3481, 3482, 3483, 3484, 3485, 3564, 3566, 3643, 3816, 3885, 3887, 3904, 3910 }; int[] OtherForChest = new int[10] { 177, 178, 179, 180, 181, 182, 999, 1348, 3027, 3828 }; int[] SunkenTreasureExclus = new int[] { ItemType <Items.Pickanch>(), ItemType <Items.Riptide>(), ItemType <Items.NautilusSlicer>() }; int Which = Main.rand.Next(7, 8); if (chest != null && Main.tile[chest.x, chest.y].type == TileType <SunkenTreasureTile>()) { for (int inventoryIndex = 0; inventoryIndex < Main.rand.Next(13, 15); inventoryIndex++) { if (chest.item[inventoryIndex].type == 0 && inventoryIndex == 0) { chest.item[inventoryIndex].SetDefaults(19); chest.item[inventoryIndex].stack = Main.rand.Next(10, 35); } if (chest.item[inventoryIndex].type == 0 && inventoryIndex == 1) { chest.item[inventoryIndex].SetDefaults(21); chest.item[inventoryIndex].stack = Main.rand.Next(10, 35); } if (chest.item[inventoryIndex].type == 0 && inventoryIndex == 2) { chest.item[inventoryIndex].SetDefaults(706); chest.item[inventoryIndex].stack = Main.rand.Next(10, 35); } if (chest.item[inventoryIndex].type == 0 && inventoryIndex == 3) { chest.item[inventoryIndex].SetDefaults(72); chest.item[inventoryIndex].stack = Main.rand.Next(10, 99); } if (chest.item[inventoryIndex].type == 0 && inventoryIndex == 4) { chest.item[inventoryIndex].SetDefaults(73); chest.item[inventoryIndex].stack = Main.rand.Next(1, 35); } if (chest.item[inventoryIndex].type == 0 && inventoryIndex < Which) { chest.item[inventoryIndex].SetDefaults(ItemForChest[Main.rand.Next(1, 104)]); } if (chest.item[inventoryIndex].type == 0 && inventoryIndex >= Which && inventoryIndex < 12) { chest.item[inventoryIndex].SetDefaults(OtherForChest[Main.rand.Next(1, 10)]); chest.item[inventoryIndex].stack = Main.rand.Next(1, 20); } if (chest.item[inventoryIndex].type == 0 && inventoryIndex >= 12) { chest.item[inventoryIndex].SetDefaults(SunkenTreasureExclus[Main.rand.Next(1, 3)]); } } } } } } wofDead = false; } if (moonlordDead) { for (int k = 0; k < (int)((Main.maxTilesX * Main.maxTilesY) * 6E-05); k++) { int x = WorldGen.genRand.Next(0, Main.maxTilesX); int y = WorldGen.genRand.Next((int)Main.maxTilesY - 200, Main.maxTilesY); WorldGen.TileRunner(x, y, WorldGen.genRand.Next(5, 15), WorldGen.genRand.Next(2, 6), TileType <Volcanite>()); } for (int k = 0; k < (int)((Main.maxTilesX * Main.maxTilesY) * 6E-04); k++) { int x = WorldGen.genRand.Next(0, Main.maxTilesX); int y = WorldGen.genRand.Next((int)0, 0 + 200); Tile tile = Framing.GetTileSafely(x, y); if (tile.active() && tile.type == TileID.Dirt) { WorldGen.TileRunner(x, y, WorldGen.genRand.Next(5, 15), WorldGen.genRand.Next(2, 6), TileType <Twilite>()); } } Main.NewText("The depths of Hell rise and the sky has truly emerged.", 255, 255, 255); moonlordDead = false; volcaniteGen = false; } if (golemDead) { for (int k = 0; k < (int)((Main.maxTilesX * Main.maxTilesY) * 6E-05); k++) { int x = WorldGen.genRand.Next(0, Main.maxTilesX); int y = WorldGen.genRand.Next((int)WorldGen.worldSurfaceLow + 200, Main.maxTilesY); Tile tile = Framing.GetTileSafely(x, y); if (tile.active() && tile.type == TileID.Crimstone) { WorldGen.TileRunner(x, y, WorldGen.genRand.Next(5, 15), WorldGen.genRand.Next(2, 6), TileType <Scarlet>()); } if (tile.active() && tile.type == TileID.Ebonstone) { WorldGen.TileRunner(x, y, WorldGen.genRand.Next(5, 15), WorldGen.genRand.Next(2, 6), TileType <CursedOre>()); } } Main.NewText("It spreads.", 255, 255, 0); golemDead = false; } if (planteraDead) { for (int k = 0; k < (int)((Main.maxTilesX * Main.maxTilesY) * 6E-05); k++) { int x = WorldGen.genRand.Next(0, Main.maxTilesX); int y = WorldGen.genRand.Next((int)WorldGen.worldSurfaceLow + 200, Main.maxTilesY); Tile tile = Framing.GetTileSafely(x, y); if (tile.active() && tile.type == TileID.Pearlstone) { WorldGen.TileRunner(x, y, WorldGen.genRand.Next(5, 15), WorldGen.genRand.Next(2, 6), TileType <Crystal>()); } } Main.NewText("The crystals are starting their new growth.", 100, 0, 255); planteraDead = false; } if (NPC.downedGolemBoss && Main.rand.Next(40000) == 0) { int ymodifier = 0; int xmodifier = Main.rand.Next(Main.maxTilesX); bool landed = false; for (ymodifier = 0; ymodifier < Main.maxTilesY - 1; ymodifier++) { if (Main.tile[xmodifier, ymodifier + 1].active() && !landed) { WorldGen.PlaceObject(xmodifier, ymodifier, TileType <SpecialCloud>(), false, 0); landed = true; Main.NewText("A cloud has fallen!", 200, 200, 200); } } } }
public override void PostWorldGen() { /*WorldGen.PlaceTile(Main.spawnTileX - 1, Main.spawnTileY, TileID.GrayBrick, false, true); * WorldGen.PlaceTile(Main.spawnTileX, Main.spawnTileY, TileID.GrayBrick, false, true); * WorldGen.PlaceTile(Main.spawnTileX + 1, Main.spawnTileY, TileID.GrayBrick, false, true); * Main.tile[Main.spawnTileX - 1, Main.spawnTileY].slope(0); * Main.tile[Main.spawnTileX, Main.spawnTileY].slope(0); * Main.tile[Main.spawnTileX + 1, Main.spawnTileY].slope(0); * WorldGen.PlaceTile(Main.spawnTileX, Main.spawnTileY - 1, ModLoader.GetMod("Fargowiltas").TileType("RegalStatueSheet"), false, true);*/ int positionX = Main.spawnTileX - 1; //offset by dimensions of statue int positionY = Main.spawnTileY - 4; bool placed = false; List <int> legalBlocks = new List <int> { TileID.Stone, TileID.Grass, TileID.Dirt, TileID.SnowBlock, TileID.IceBlock, TileID.ClayBlock }; for (int offsetX = -50; offsetX <= 50; offsetX++) { for (int offsetY = -30; offsetY <= 10; offsetY++) { int baseCheckX = positionX + offsetX; int baseCheckY = positionY + offsetY; bool canPlaceStatueHere = true; for (int i = 0; i < 3; i++) //check no obstructing blocks { for (int j = 0; j < 4; j++) { Tile tile = Framing.GetTileSafely(baseCheckX + i, baseCheckY + j); if (WorldGen.SolidOrSlopedTile(tile)) { canPlaceStatueHere = false; break; } } } for (int i = 0; i < 3; i++) //check for solid foundation { Tile tile = Framing.GetTileSafely(baseCheckX + i, baseCheckY + 4); if (!WorldGen.SolidTile(tile) || !legalBlocks.Contains(tile.type)) { canPlaceStatueHere = false; break; } } if (canPlaceStatueHere) { for (int i = 0; i < 3; i++) //MAKE SURE nothing in the way { for (int j = 0; j < 4; j++) { WorldGen.KillTile(baseCheckX + i, baseCheckY + j); } } WorldGen.PlaceTile(baseCheckX, baseCheckY + 4, TileID.GrayBrick, false, true); WorldGen.PlaceTile(baseCheckX + 1, baseCheckY + 4, TileID.GrayBrick, false, true); WorldGen.PlaceTile(baseCheckX + 2, baseCheckY + 4, TileID.GrayBrick, false, true); Main.tile[baseCheckX, baseCheckY + 4].slope(0); Main.tile[baseCheckX + 1, baseCheckY + 4].slope(0); Main.tile[baseCheckX + 2, baseCheckY + 4].slope(0); WorldGen.PlaceTile(baseCheckX + 1, baseCheckY + 3, mod.TileType("MutantStatueGift"), false, true); placed = true; break; } } if (placed) { break; } } }
public override void AI() { EModeGlobalNPC.championBoss = npc.whoAmI; if (npc.localAI[3] == 0) //just spawned { if (!npc.HasValidTarget) { npc.TargetClosest(false); } if (npc.ai[1] == 0) { npc.Center = Main.player[npc.target].Center + new Vector2(500 * Math.Sign(npc.Center.X - Main.player[npc.target].Center.X), -250); if (Main.netMode != NetmodeID.MultiplayerClient) { Projectile.NewProjectile(npc.Center + Vector2.UnitY * 1000, Vector2.Zero, ModContent.ProjectileType <EarthChainBlast2>(), 0, 0f, Main.myPlayer, -Vector2.UnitY.ToRotation(), 10); Projectile.NewProjectile(npc.Center - Vector2.UnitY * 1000, Vector2.Zero, ModContent.ProjectileType <EarthChainBlast2>(), 0, 0f, Main.myPlayer, Vector2.UnitY.ToRotation(), 10); } } if (++npc.ai[1] > 6 * 9) //nice { npc.localAI[3] = 1; npc.ai[1] = 0; npc.netUpdate = true; if (!Main.dedServ && Main.LocalPlayer.active) { Main.LocalPlayer.GetModPlayer <FargoPlayer>().Screenshake = 30; } if (Main.netMode != NetmodeID.MultiplayerClient) { const int max = 8; const float baseRotation = MathHelper.TwoPi / max; for (int i = 0; i < max; i++) { float rotation = baseRotation * (i + Main.rand.NextFloat(-0.5f, 0.5f)); Projectile.NewProjectile(npc.Center, Vector2.Zero, ModContent.ProjectileType <EarthChainBlast2>(), 0, 0f, Main.myPlayer, rotation, 3); } int n = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <EarthChampionHand>(), npc.whoAmI, 0, 0, npc.whoAmI, 1); if (n < Main.maxNPCs && 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 <EarthChampionHand>(), npc.whoAmI, 0, 0, npc.whoAmI, -1); if (n < Main.maxNPCs && Main.netMode == NetmodeID.Server) { NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n); } } } return; } Player player = Main.player[npc.target]; Vector2 targetPos; if (npc.HasValidTarget && npc.Distance(player.Center) < 2500 && player.ZoneUnderworldHeight) { npc.timeLeft = 600; } npc.dontTakeDamage = false; npc.alpha = 0; switch ((int)npc.ai[0]) { case -1: npc.localAI[2] = 1; //npc.dontTakeDamage = true; npc.ai[1]++; npc.velocity *= 0.95f; /*if (npc.ai[1] < 120) * { * targetPos = player.Center; * targetPos.Y -= 375; * if (npc.Distance(targetPos) > 50) * Movement(targetPos, 0.6f, 24f, true); * } * else*/ if (npc.ai[1] == 120) //begin healing { Main.PlaySound(SoundID.NPCDeath10, npc.Center); if (Main.netMode != NetmodeID.MultiplayerClient) { //Projectile.NewProjectile(npc.Center, Vector2.Zero, ModContent.ProjectileType<Projectiles.GlowRing>(), 0, 0f, Main.myPlayer, npc.whoAmI, -3); if (!Main.dedServ && Main.LocalPlayer.active) { Main.LocalPlayer.GetModPlayer <FargoPlayer>().Screenshake = 30; } if (Main.netMode != NetmodeID.MultiplayerClient) { const int max = 8; float baseRotation = MathHelper.TwoPi / max * Main.rand.NextFloat(); for (int i = 0; i < max; i++) { float rotation = baseRotation + MathHelper.TwoPi / max * (i + Main.rand.NextFloat(-0.5f, 0.5f)); Projectile.NewProjectile(npc.Center, Vector2.Zero, ModContent.ProjectileType <EarthChainBlast2>(), 0, 0f, Main.myPlayer, rotation, 3); } } } } else if (npc.ai[1] > 120) //healing { npc.velocity *= 0.9f; int heal = (int)(npc.lifeMax / 2 / 120 * Main.rand.NextFloat(1f, 1.5f)); npc.life += heal; if (npc.life > npc.lifeMax) { npc.life = npc.lifeMax; } CombatText.NewText(npc.Hitbox, CombatText.HealLife, heal); for (int i = 0; i < 5; i++) { int d = Dust.NewDust(npc.Center, 0, 0, 174, 0f, 0f, 0, default(Color), 1.5f); Main.dust[d].noGravity = true; Main.dust[d].velocity *= 8f; } if (npc.ai[1] > 240) { npc.ai[0]++; npc.ai[1] = 0; npc.ai[2] = 0; npc.netUpdate = true; } } break; case 0: //float over player if (!player.active || player.dead || Vector2.Distance(npc.Center, player.Center) > 2500f || !player.ZoneUnderworldHeight) //despawn code { npc.TargetClosest(false); if (npc.timeLeft > 30) { npc.timeLeft = 30; } npc.noTileCollide = true; npc.noGravity = true; npc.velocity.Y += 1f; return; } else { targetPos = player.Center; targetPos.Y -= 325; if (npc.Distance(targetPos) > 50) { Movement(targetPos, 0.4f, 16f, true); } } if (npc.localAI[2] == 0 && npc.life < npc.lifeMax / 2) { npc.ai[0] = -1; npc.ai[1] = 0; npc.ai[2] = 0; npc.ai[3] = 0; for (int i = 0; i < Main.maxNPCs; i++) //find hands, update { if (Main.npc[i].active && Main.npc[i].type == ModContent.NPCType <EarthChampionHand>() && Main.npc[i].ai[2] == npc.whoAmI) { Main.npc[i].ai[0] = -1; Main.npc[i].ai[1] = 0; Main.npc[i].localAI[0] = 0; Main.npc[i].localAI[1] = 0; Main.npc[i].netUpdate = true; } } } break; case 1: //fireballs if (!player.active || player.dead || Vector2.Distance(npc.Center, player.Center) > 2500f || !player.ZoneUnderworldHeight) //despawn code { npc.TargetClosest(false); if (npc.timeLeft > 30) { npc.timeLeft = 30; } npc.noTileCollide = true; npc.noGravity = true; npc.velocity.Y += 1f; return; } else { targetPos = player.Center; for (int i = 0; i < 22; i++) //collision check above player's head { targetPos.Y -= 16; Tile tile = Framing.GetTileSafely(targetPos); //if solid, stay below it if (tile.active() && !tile.inActive() && Main.tileSolid[tile.type] && !Main.tileSolidTop[tile.type]) { targetPos.Y += 50 + 16; break; } } if (npc.Distance(targetPos) > 50) { Movement(targetPos, 0.2f, 12f, true); npc.position += (targetPos - npc.Center) / 30; } if (--npc.ai[2] < 0) { npc.ai[2] = 75; Main.PlaySound(4, npc.Center, 13); if (npc.ai[1] > 10 && Main.netMode != NetmodeID.MultiplayerClient) //shoot spread of fireballs, but not the first time { for (int i = -1; i <= 1; i++) { Projectile.NewProjectile(npc.Center + Vector2.UnitY * 60, (npc.localAI[2] == 1 ? 12 : 8) * npc.DirectionTo(player.Center).RotatedBy(MathHelper.ToRadians(8 * i)), ProjectileID.Fireball, npc.damage / 4, 0f, Main.myPlayer); } } } if (++npc.ai[1] > 480) { npc.ai[0]++; npc.ai[1] = 0; npc.netUpdate = true; } } if (npc.localAI[2] == 0 && npc.life < npc.lifeMax / 2) { npc.ai[0] = -1; npc.ai[1] = 0; npc.ai[2] = 0; npc.ai[3] = 0; for (int i = 0; i < Main.maxNPCs; i++) //find hands, update { if (Main.npc[i].active && Main.npc[i].type == ModContent.NPCType <EarthChampionHand>() && Main.npc[i].ai[2] == npc.whoAmI) { Main.npc[i].ai[0] = -1; Main.npc[i].ai[1] = 0; Main.npc[i].localAI[0] = 0; Main.npc[i].localAI[1] = 0; Main.npc[i].netUpdate = true; } } } break; default: npc.ai[0] = 0; goto case 0; } }
public override void AI() { Idle = false; if (FirstFrame) { int tileX = (int)(npc.Center.X * (1f / 16)), tileY = (int)(npc.Center.Y * (1f / 16)); for (int y = 0; y >= -4; y--) { for (int x = -2; x < 3; x++) { int TileX = tileX + x, TileY = tileY + y; if (Main.tile[TileX, TileY].active() && Main.tile[TileX, TileY].type == Terraria.ID.TileID.Trees) { int SizeCount = 0; while (Main.tile[TileX, TileY].active() && Main.tile[TileX, TileY].type == Terraria.ID.TileID.Trees) { TileY--; SizeCount++; } TileY += 3; if (SizeCount >= 9 && Main.tile[TileX, TileY].active() && Main.tile[TileX, TileY].type == Terraria.ID.TileID.Trees) { npc.position.X = TileX * 16 + 8 - npc.width * 0.25f; npc.position.Y = TileY * 16 - npc.height * 0.5f; return; } } } } } if (Sleeping) { npc.velocity = Vector2.Zero; npc.noGravity = true; int TileCenterX = (int)((npc.position.X + npc.width * 0.25f) * (1f / 16)); int TileCenterY = (int)(npc.Center.Y * (1f / 16)); bool SuspendedByTree = false; Tile tile = Framing.GetTileSafely(TileCenterX, TileCenterY); if (tile != null && tile.active()) { SuspendedByTree = true; } if (!SuspendedByTree) { Sleeping = false; SayMessage("*W-what?!*", true); npc.TargetClosest(); } return; } npc.noGravity = false; bool PlayerKnowsGuardian = PlayerMod.PlayerHasGuardian(Main.player[npc.target], GuardianID); if (Step > 0) { if (Step < 5 && Math.Abs(Main.player[npc.target].Center.X - npc.Center.X) >= 1200) { SayMessage("*Hey! I'm talking to you!*"); Step = 1; Timer = 0; Idle = true; PlayerMovedAway = true; } else { if (PlayerMovedAway) { SayMessage("*You returned, now you have to listen to me.*"); Timer = -120; PlayerMovedAway = false; } if (Main.player[npc.target].Center.X < npc.Center.X) { npc.direction = -1; } else { npc.direction = 1; } } } switch (Step) { case 0: if (npc.velocity.Y == 0) { Timer++; if (Timer >= 150) { Timer = 0; Step++; } } break; case 1: if (Timer == 50) { if (PlayerKnowsGuardian) { SayMessage("*Again you destroyed the tree I was sleeping on.*", true); } else { SayMessage("*What is your problem? Didn't see me there?*", true); } } Timer++; if (Timer >= 260) { Timer = 0; Step++; } break; case 2: if (Timer == 0) { if (PlayerKnowsGuardian) { SayMessage("*Do you have anything against me sleeping on trees or something.*", true); } else { SayMessage("*Next time you want to get some lumber, look up-!*", true); } } Timer++; if (Timer >= 210) { Timer = 0; Step++; } break; case 3: if (Timer == 0) { if (PlayerKnowsGuardian) { SayMessage("*Ugh... Whatever...*", true); } else { SayMessage("*Wait a minute, aren't you a Terrarian.*", true); } } Timer++; if (Timer >= 180) { Timer = 0; Step++; } break; case 4: if (Timer == 0) { if (PlayerKnowsGuardian) { SayMessage("*I'm here if you ever need a medic... Now I need to look for a safe place for a nap.*", true); NpcMod.AddGuardianMet(GuardianID, GuardianModID); WorldMod.TurnNpcIntoGuardianTownNpc(npc, GuardianID, GuardianModID); return; } else { SayMessage("*Hm... I wonder if...*", true); } } Timer++; if (Timer >= 180) { Timer = 0; Step++; } break; case 5: if (Timer == 0) { SayMessage("*If you can understand me, could you try speaking to me?*", true); Timer++; } break; default: if (Step >= 6) { bool AnyoneSpeakingToMe = false; for (int i = 0; i < 255; i++) { if (Main.player[i].active && Main.player[i].talkNPC == npc.whoAmI) { AnyoneSpeakingToMe = true; break; } } if (!AnyoneSpeakingToMe) { Step = 5; Timer = 1; SayMessage("*I still would like if we could speak some more, Terrarian.*"); } } break; } base.AI(); }
public bool ExposedToSunlight() { Vampire _Vampire = ModContent.GetInstance <Vampire>(); Tile[] smallWallTiles = new Tile[2]; Point playerTilePointSmall = (Main.LocalPlayer.position / 16).ToPoint(); smallWallTiles[0] = Framing.GetTileSafely(playerTilePointSmall.X, playerTilePointSmall.Y); smallWallTiles[1] = Framing.GetTileSafely(playerTilePointSmall.X + 1, playerTilePointSmall.Y); bool behindSmallWall = false; foreach (var tile in smallWallTiles) { if (tile.wall > 0) { behindSmallWall = true; } else { behindSmallWall = false; break; } } Tile[] wallTiles = new Tile[6]; Point playerTilePoint = (Main.LocalPlayer.position / 16).ToPoint(); wallTiles[0] = Framing.GetTileSafely(playerTilePoint.X, playerTilePoint.Y); wallTiles[1] = Framing.GetTileSafely(playerTilePoint.X, playerTilePoint.Y + 1); wallTiles[2] = Framing.GetTileSafely(playerTilePoint.X, playerTilePoint.Y + 2); wallTiles[3] = Framing.GetTileSafely(playerTilePoint.X + 1, playerTilePoint.Y); wallTiles[4] = Framing.GetTileSafely(playerTilePoint.X + 1, playerTilePoint.Y + 1); wallTiles[5] = Framing.GetTileSafely(playerTilePoint.X + 1, playerTilePoint.Y + 2); bool behindWall = false; foreach (var tile in wallTiles) { if (tile.wall > 0) { behindWall = true; } else { behindWall = false; break; } } Tile[] largeWallTiles = new Tile[36]; Point playerTilePointLarge = (Main.LocalPlayer.position / 16).ToPoint(); largeWallTiles[0] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 15); largeWallTiles[1] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 14); largeWallTiles[2] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 13); largeWallTiles[3] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 12); largeWallTiles[4] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 11); largeWallTiles[5] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 10); largeWallTiles[6] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 9); largeWallTiles[7] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 8); largeWallTiles[8] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 7); largeWallTiles[9] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 6); largeWallTiles[10] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 5); largeWallTiles[11] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 4); largeWallTiles[12] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 3); largeWallTiles[13] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 2); largeWallTiles[14] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 1); largeWallTiles[15] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y); largeWallTiles[16] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y + 1); largeWallTiles[17] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y + 2); largeWallTiles[18] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 15); largeWallTiles[19] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 14); largeWallTiles[20] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 13); largeWallTiles[21] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 12); largeWallTiles[22] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 11); largeWallTiles[23] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 10); largeWallTiles[24] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 9); largeWallTiles[25] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 8); largeWallTiles[26] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 7); largeWallTiles[27] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 6); largeWallTiles[28] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 5); largeWallTiles[29] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 4); largeWallTiles[30] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 3); largeWallTiles[31] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 2); largeWallTiles[32] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 1); largeWallTiles[33] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y); largeWallTiles[34] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y + 1); largeWallTiles[35] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y + 2); bool behindLargeWall = false; foreach (var tile in largeWallTiles) { if (tile.wall > 0) { behindLargeWall = true; } else { behindLargeWall = false; break; } } bool hasCeilingTile = false; Vector2 playerLocation = new Vector2(player.Center.X / 16, player.Center.Y / 16); for (int i = 0; i < 60; i++) { Tile ceilingTile = Main.tile[(int)playerLocation.X, (int)playerLocation.Y]; if (ceilingTile != null && Main.tileSolid[ceilingTile.type] && ceilingTile.nactive()) { hasCeilingTile = true; } if (playerLocation.Y > 0) { playerLocation.Y -= 1; } } bool hasCeilingAbove = false; if (behindLargeWall || hasCeilingTile) { hasCeilingAbove = true; } else { hasCeilingAbove = false; } if (!_Vampire.VampireTransformation) { return((!hasCeilingAbove || !behindWall) && !((double)player.Center.Y > Main.worldSurface * 16.0) && Main.dayTime && !(Collision.DrownCollision(player.position, player.width, player.height, player.gravDir))); } else { return((!hasCeilingAbove || !behindSmallWall) && !((double)player.Center.Y > Main.worldSurface * 16.0) && Main.dayTime && !(Collision.DrownCollision(player.position, player.width, player.height, player.gravDir))); } }
/// <summary>Generates a large island at X/Y.</summary> /// <param name="x">X position.</param> /// <param name="y">Y position.</param> private static void CreateIsland(int x, int y, bool small = false) { int wid = genRand.Next(32, 42); if (small) { wid = genRand.Next(10, 18); } int top = 5; int depth = 2; bool peak = false; int peakEnd = 0; int peakStart = 0; int offset = 0; for (int i = x - (int)(wid / 2f); i < x + (wid / 2f); ++i) { if (i == x - (int)(wid / 2f) + 1) { top++; } else if (i == (x + (int)(wid / 2f)) - 1) { top--; } if (!peak) { if (depth <= 2) { depth += genRand.Next(2); } else { depth += genRand.Next(-1, 2); } if (genRand.Next(3) == 0) { peak = true; peakStart = i; peakEnd = i + genRand.Next(3, 8); if (peakEnd > (x + (wid / 2f)) - 1) { peakEnd = (int)(x + (wid / 2f)) - 1; } } } else { int dist = peakEnd - i; int dif = peakEnd - peakStart; int deep = (7 - dif); if (dist > (int)(dif / 2f)) { depth += genRand.Next(deep, deep + 2); } else { depth -= genRand.Next(deep, deep + 2); } if (x >= peakEnd) { peak = false; } } if (i % 4 == 0) { if (i < x) { top += genRand.Next(2); } else { top -= genRand.Next(2); } } if (i % 8 == 2) { offset += genRand.Next(-1, 2); } if (top < 3) { top = 3; } if (i > x + (wid / 2f) - 4 && depth > 4) { depth--; } if (i > x + (wid / 2f) - 4 && depth > 8) { depth--; } for (int j = y - top + offset; j < y + depth + offset; j++) { int t = j > (y + depth + offset) - 4 ? TileType <VitricSand>() : TileType <VitricSoftSand>(); PlaceTile(i, j, t, false, true); } } //Place crystal if needed if (crystalsPlaced <= (VitricBiome.Width / 240) + 2 && !small) { int tries = 0; while (true) { int cX = x + genRand.Next((int)(wid * -0.60f), (int)(wid * 0.60f)) - 3; int cY = y - 5; while (Main.tile[cX, cY].active()) { cY--; } cY = Math.Max( FindType(cX, cY, -1, ValidGround), FindType(cX + 1, cY, -1, ValidGround) ); if (ValidGround.Any(v => v == Main.tile[cX + 1, cY].type) && ValidGround.Any(v => v == Main.tile[cX + 2, cY].type) && ScanRectangle(cX, cY - 6, 4, 6) < 3) { StructureHelper.StructureHelper.GenerateStructure( "Structures/Vitric/VitricSmallCrystal_" + genRand.Next(2), new Point16(cX, cY - 6), StarlightRiver.Instance ); crystalsPlaced++; break; } else if (tries++ >= 20) { break; } } } else if (small) { // Input variables int spawnAttempts = 30; int cX, cY; // Perform several checks while (spawnAttempts-- > 0) { cX = x + genRand.Next((int)(wid * -0.60f), (int)(wid * 0.60f)) - 3; cY = y - 5; cY = FindType(cX, cY, -1, ValidGround); // If the left side of the crystal isn't valid, // or if the right side is occupied, // skip. if (cY == -1) { continue; } // If there are solid tiles in the way, skip. if (ScanRectangle(cX, cY - 3, 2, 3) > 2) { continue; } // Success! Halve the spawnAttempts count so we don't spam crystals. PlaceTile(cX + 1, cY, Framing.GetTileSafely(cX, cY).type, true, true); Helper.PlaceMultitile(new Point16(cX, cY - 3), TileType <VitricOre>()); spawnAttempts /= 4; } } }
/// <summary>Generates basic biome shape, such as curved walls, noise on floor and ceiling, and spikes on the bottom.</summary> /// <seealso cref="https://github.com/Auburns/FastNoise_CSharp"/> private static void GenerateBase(int minCeilingDepth, int maxCeilingDepth, int minFloorDepth) { genNoise.Seed = _genRandSeed; genNoise.FractalGain = 0.04f; genNoise.Frequency = 0.004f; genNoise.FractalLacunarity = 3.0f; genNoise.FractalOctaves = 2; genNoise.NoiseType = FastNoise.NoiseTypes.SimplexFractal; //Sets noise to proper type float[] heights = new float[VitricBiome.Width]; //2D heightmap to create terrain for (int x = 0; x < heights.Length; x++) { heights[x] = genNoise.GetNoise(x, 0); } float leftCurveConst = 13f; // 15f - ((0.3f + heights[0]) * VitricNoiseHeight); //For curving down into the noise properly, left side float rightCurveConst = 13f; // 15f - ((0.3f + heights[heights.Length - 1]) * VitricNoiseHeight); //Right side //Controls Y location of the top, ceiling, floor and bottom of the biome Dictionary <string, int> layers = new Dictionary <string, int> { { "TOP", 0 }, { "CEILING", 0 }, { "FLOOR", 0 }, { "BOTTOM", 0 } }; for (int x = VitricBiome.X; x < VitricBiome.X + VitricBiome.Width; x++) //Basic biome shape { int xDif = x - VitricBiome.X; int adjXDif = (VitricBiome.Width - xDif); if (xDif < VitricSlopeOffset) //Start curve { layers["CEILING"] = (int)((VitricBiome.Center.Y) - (17f * Math.Log(-8 + xDif))); //17f is the constant that goes to the roof layers["TOP"] = (int)((VitricBiome.Center.Y) - (17f * Math.Log(-8 + (xDif + 12)))) - 12; if (xDif < 10) { layers["CEILING"] = VitricBiome.Y + VitricBiome.Height / 2; } else if (xDif < 17) { layers["CEILING"] += genRand.Next(-1, 2); } if (layers["TOP"] < VitricBiome.Y) { layers["TOP"] = VitricBiome.Y; //Caps off top } layers["FLOOR"] = (int)(VitricBiome.Y + (leftCurveConst * Math.Log(-8 + xDif))) + (VitricBiome.Height / 2); //Curves down towards floor layers["BOTTOM"] = (int)(VitricBiome.Y + (leftCurveConst * Math.Log(-8 + (xDif + 12)))) + (VitricBiome.Height / 2) + 32; if (xDif < 10) { layers["FLOOR"] = VitricBiome.Y + VitricBiome.Height / 2; } else if (xDif < 17) { layers["FLOOR"] += genRand.Next(-1, 2); } if (layers["BOTTOM"] > VitricBiome.Y + VitricBiome.Height) { layers["BOTTOM"] = VitricBiome.Y + VitricBiome.Height; //Caps off bottom } } else if (xDif == VitricSlopeOffset) { layers["CEILING"] = minCeilingDepth; //Flatway start } else if (xDif > VitricSlopeOffset && xDif < VitricBiome.Width - VitricSlopeOffset) //Flatway { if (genRand.Next(2) == 0 && x % 2 == 1) { if (layers["CEILING"] >= minCeilingDepth && layers["CEILING"] <= maxCeilingDepth) { layers["CEILING"] += genRand.Next(-1, 2); } } if (layers["TOP"] >= layers["CEILING"]) { layers["TOP"] = layers["CEILING"]; } if (layers["CEILING"] < minCeilingDepth) { layers["CEILING"] += genRand.Next(2); } if (layers["CEILING"] > maxCeilingDepth || (layers["CEILING"] > VitricBiome.Y + 12 && x > VitricBiome.Center.X - 30 && x < VitricBiome.Center.X + 30)) { layers["CEILING"] -= genRand.Next(2); } if (xDif < (VitricBiome.Width / 2) - 81 && xDif > (VitricBiome.Width / 2) + 84 && layers["CEILING"] > VitricBiome.Y + 7) //Adjust for boss pillars { layers["CEILING"]--; } if (x < VitricBiome.Y - VitricSlopeOffset - 16 && layers["CEILING"] > VitricBiome.Y + 4) { layers["CEILING"]--; } layers["FLOOR"] = (int)Math.Floor(minFloorDepth - ((0.3f + heights[x - VitricBiome.X]) * VitricNoiseHeight)); if (x < VitricBiome.Center.X - 35 && genRand.Next(4) == 0) { layers["TOP"] -= genRand.Next(2); } if (x > VitricBiome.Center.X + 35 && genRand.Next(4) == 0) { layers["TOP"] += genRand.Next(2); } if (layers["TOP"] > VitricBiome.Y) { layers["TOP"] = VitricBiome.Y; } } else //End curve { layers["CEILING"] = (int)(VitricBiome.Center.Y - (17f * Math.Log(-8 + adjXDif))); layers["TOP"] = (int)(VitricBiome.Center.Y - (17f * Math.Log(-8 + (adjXDif + 12)))) - 12; if (layers["TOP"] < VitricBiome.Y) { layers["TOP"] = VitricBiome.Y; //Caps off top } if (xDif > VitricBiome.Width - 10) { layers["CEILING"] = VitricBiome.Center.Y; } else if (xDif > VitricBiome.Width - 17) { layers["CEILING"] += genRand.Next(-1, 2); } layers["FLOOR"] = (int)(VitricBiome.Y + (rightCurveConst * Math.Log(-8 + adjXDif))) + (VitricBiome.Height / 2); layers["BOTTOM"] = (int)(VitricBiome.Y + (rightCurveConst * Math.Log(-8 + (adjXDif + 12)))) + (VitricBiome.Height / 2) + 27; if (xDif < 10) { layers["FLOOR"] = VitricBiome.Center.Y; } else if (xDif < 17) { layers["FLOOR"] += genRand.Next(-1, 2); } if (layers["BOTTOM"] > VitricBiome.Bottom) { layers["BOTTOM"] = VitricBiome.Bottom; //Caps off bottom } } if (layers["CEILING"] > VitricBiome.Y + VitricBiome.Height / 2) { layers["CEILING"] = VitricBiome.Y + VitricBiome.Height / 2; } if (layers["FLOOR"] < VitricBiome.Y + VitricBiome.Height / 2) { layers["FLOOR"] = VitricBiome.Y + VitricBiome.Height / 2; } for (int y = layers["CEILING"]; y < layers["FLOOR"]; ++y) //Dig out cave { Framing.GetTileSafely(x, y).ClearEverything(); } for (int y = layers["TOP"] - 8; y < layers["CEILING"]; ++y) { if (x > VitricBiome.Center.X - 35 && x <= VitricBiome.Center.X + 36) { break; } int xRand = xDif < 20 ? xDif : VitricBiome.Width - xDif; Tile t = Main.tile[x, y]; if ((y < layers["TOP"] && genRand.Next(layers["TOP"] - y) == 0 && t.active() && Main.tileSolid[t.type]) || ((xDif <8 || xDif> VitricBiome.Width - 8) && genRand.Next(xRand) == 0) || y >= layers["TOP"]) { PlaceTile(x, y, TileType <VitricSand>(), false, true); t.slope(0); KillWall(x, y, false); } } for (int y = layers["FLOOR"] - (9 - genRand.Next(2)); y < layers["BOTTOM"] + 8; ++y) { bool validSpike = y < layers["FLOOR"] && y >= (VitricBiome.Y + (VitricBiome.Height / 2f)); int xRand = xDif < 20 ? xDif : VitricBiome.Width - xDif; Tile t = Main.tile[x, y]; if ((y > layers["BOTTOM"] && genRand.Next(y - layers["BOTTOM"]) == 0 && t.active() && Main.tileSolid[t.type]) || ((xDif <8 || xDif> VitricBiome.Width - 8) && genRand.Next(xRand) == 0) || y <= layers["BOTTOM"]) { PlaceTile(x, y, validSpike ? TileType <VitricSpike>() : TileType <VitricSand>(), false, true); t.slope(0); KillWall(x, y, false); } } } }
public override bool NewRightClick(int i, int j) { Player player = Main.LocalPlayer; Tile tile = Main.tile[i, j]; bool anycursedarmor = false; for (int indexX = -70; indexX <= 70; indexX++) { for (int indexY = -90; indexY <= 90; indexY++) { if (Framing.GetTileSafely(indexX + i, indexY + j).type == mod.TileType("CursedArmor")) { WorldGen.KillTile(indexX + i, indexY + j); if (Main.netMode != NetmodeID.SinglePlayer) { NetMessage.SendData(MessageID.TileChange, -1, -1, null, 0, indexX + i, indexY + j); } anycursedarmor = true; } } } if (anycursedarmor) { CombatText.NewText(new Rectangle(i * 16, j * 16, 20, 10), Color.GreenYellow, "Trapped!"); return(true); } else if (NPC.AnyNPCs(ModContent.NPCType <Enchanted_Armor>())) { Main.PlaySound(new LegacySoundStyle(SoundID.NPCKilled, 6).WithPitchVariance(0.2f).WithVolume(0.5f), new Vector2(i * 16, j * 16)); foreach (NPC npc in Main.npc.Where(x => x.active && x.type == ModContent.NPCType <Enchanted_Armor>())) { npc.ai[1] = 30; } return(true); } Main.mouseRightRelease = false; int left = i; int top = j; if (tile.frameX % 36 != 0) { left--; } if (tile.frameY != 0) { top--; } if (player.sign >= 0) { Main.PlaySound(SoundID.MenuClose); player.sign = -1; Main.editSign = false; Main.npcChatText = ""; } if (Main.editChest) { Main.PlaySound(SoundID.MenuTick); Main.editChest = false; Main.npcChatText = ""; } if (player.editedChestName) { NetMessage.SendData(MessageID.SyncPlayerChest, -1, -1, NetworkText.FromLiteral(Main.chest[player.chest].name), player.chest, 1f, 0f, 0f, 0, 0, 0); player.editedChestName = false; } if (Main.netMode == NetmodeID.MultiplayerClient) { if (left == player.chestX && top == player.chestY && player.chest >= 0) { player.chest = -1; Recipe.FindRecipes(); Main.PlaySound(SoundID.MenuClose); } else { NetMessage.SendData(MessageID.RequestChestOpen, -1, -1, null, left, top, 0f, 0f, 0, 0, 0); Main.stackSplit = 600; } } else { int chest = Chest.FindChest(left, top); if (chest >= 0) { Main.stackSplit = 600; if (chest == player.chest) { player.chest = -1; Main.PlaySound(SoundID.MenuClose); } else { player.chest = chest; Main.playerInventory = true; Main.recBigList = false; player.chestX = left; player.chestY = top; Main.PlaySound(player.chest < 0 ? SoundID.MenuOpen : SoundID.MenuTick); } Recipe.FindRecipes(); } } return(true); }
public override void AI() { projectile.frameCounter++; if (projectile.frameCounter >= 8) { projectile.frameCounter = 0; projectile.frame += 1; } if (projectile.frame > 5) { projectile.frame = 0; } Player player = Main.player[projectile.owner]; AAPlayer modPlayer = player.GetModPlayer <AAPlayer>(); if (player.dead) { modPlayer.TerraMinion = false; } if (modPlayer.TerraMinion) { projectile.timeLeft = 2; } dust--; if (dust >= 0) { int num501 = 50; for (int num502 = 0; num502 < num501; num502++) { int num503 = Dust.NewDust(new Vector2(projectile.position.X, projectile.position.Y + 16f), projectile.width, projectile.height - 16, 107, 0f, 0f, 0); Main.dust[num503].noGravity = true; Main.dust[num503].velocity *= 2f; Main.dust[num503].scale *= 1.15f; } } projectile.frameCounter++; if (projectile.frameCounter > 8) { projectile.frame++; projectile.frameCounter = 0; } if (projectile.frame > 4) { projectile.frame = 0; } float num = Main.rand.Next(90, 111) * 0.01f; num *= Main.essScale; Lighting.AddLight(projectile.Center, 1f * num, 0f * num, 0.15f * num); projectile.rotation = projectile.velocity.X * 0.04f; float num633 = 700f; float num634 = 800f; float num635 = 1200f; float num636 = 150f; float num637 = 0.05f; for (int num638 = 0; num638 < 1000; num638++) { bool flag23 = Main.projectile[num638].type == mod.ProjectileType("TerraWizard"); if (num638 != projectile.whoAmI && Main.projectile[num638].active && Main.projectile[num638].owner == projectile.owner && flag23 && Math.Abs(projectile.position.X - Main.projectile[num638].position.X) + Math.Abs(projectile.position.Y - Main.projectile[num638].position.Y) < projectile.width) { if (projectile.position.X < Main.projectile[num638].position.X) { projectile.velocity.X = projectile.velocity.X - num637; } else { projectile.velocity.X = projectile.velocity.X + num637; } if (projectile.position.Y < Main.projectile[num638].position.Y) { projectile.velocity.Y = projectile.velocity.Y - num637; } else { projectile.velocity.Y = projectile.velocity.Y + num637; } } } bool flag24 = false; if (projectile.ai[0] == 2f) { projectile.ai[1] += 1f; projectile.extraUpdates = 1; if (projectile.ai[1] > 40f) { projectile.ai[1] = 1f; projectile.ai[0] = 0f; projectile.extraUpdates = 0; projectile.numUpdates = 0; projectile.netUpdate = true; } else { flag24 = true; } } if (flag24) { return; } Vector2 vector46 = projectile.position; bool flag25 = false; if (projectile.ai[0] != 1f) { projectile.tileCollide = false; } if (projectile.tileCollide && WorldGen.SolidTile(Framing.GetTileSafely((int)projectile.Center.X / 16, (int)projectile.Center.Y / 16))) { projectile.tileCollide = false; } if (player.HasMinionAttackTargetNPC) { NPC nPC2 = Main.npc[player.MinionAttackTargetNPC]; if (nPC2.CanBeChasedBy(projectile, false)) { float num646 = Vector2.Distance(nPC2.Center, projectile.Center); if (((Vector2.Distance(projectile.Center, vector46) > num646 && num646 < num633) || !flag25) && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, nPC2.position, nPC2.width, nPC2.height)) { num633 = num646; vector46 = nPC2.Center; flag25 = true; } } } else { for (int num645 = 0; num645 < 200; num645++) { NPC nPC2 = Main.npc[num645]; if (nPC2.CanBeChasedBy(projectile, false)) { float num646 = Vector2.Distance(nPC2.Center, projectile.Center); if (((Vector2.Distance(projectile.Center, vector46) > num646 && num646 < num633) || !flag25) && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, nPC2.position, nPC2.width, nPC2.height)) { num633 = num646; vector46 = nPC2.Center; flag25 = true; } } } } float num647 = num634; if (flag25) { num647 = num635; } if (flag25) { projectile.spriteDirection = ((vector46 - projectile.Center).X > 0? -1: 1); } else { projectile.spriteDirection = (projectile.velocity.X > 0? -1: 1); } if (Vector2.Distance(player.Center, projectile.Center) > num647) { projectile.ai[0] = 1f; projectile.tileCollide = false; projectile.netUpdate = true; } if (flag25 && projectile.ai[0] == 0f) { Vector2 vector47 = vector46 - projectile.Center; float num648 = vector47.Length(); vector47.Normalize(); if (num648 > 200f) { float scaleFactor2 = 8f; vector47 *= scaleFactor2; projectile.velocity = (projectile.velocity * 40f + vector47) / 41f; } else { float num649 = 4f; vector47 *= -num649; projectile.velocity = (projectile.velocity * 40f + vector47) / 41f; } } else { bool flag26 = false; if (!flag26) { flag26 = projectile.ai[0] == 1f; } float num650 = 5f; //6 if (flag26) { num650 = 12f; //15 } Vector2 center2 = projectile.Center; Vector2 vector48 = player.Center - center2 + new Vector2(0f, -30f); //-60 float num651 = vector48.Length(); if (num651 > 200f && num650 < 6.5f) //200 and 8 { num650 = 6.5f; //8 } if (num651 < num636 && flag26 && !Collision.SolidCollision(projectile.position, projectile.width, projectile.height)) { projectile.ai[0] = 0f; projectile.netUpdate = true; } if (num651 > 2000f) { projectile.position.X = Main.player[projectile.owner].Center.X - (projectile.width / 2); projectile.position.Y = Main.player[projectile.owner].Center.Y - (projectile.height / 2); projectile.netUpdate = true; } if (num651 > 70f) { vector48.Normalize(); vector48 *= num650; projectile.velocity = (projectile.velocity * 40f + vector48) / 41f; } else if (projectile.velocity.X == 0f && projectile.velocity.Y == 0f) { projectile.velocity.X = -0.2f; projectile.velocity.Y = -0.1f; } } if (projectile.ai[1] > 0f) { projectile.ai[1] += Main.rand.Next(1, 4); } if (projectile.ai[1] > 80f) { projectile.ai[1] = 0f; projectile.netUpdate = true; } if (projectile.ai[0] == 0f) { float scaleFactor3 = 8f; int num658 = ModContent.ProjectileType <TerraBlast>(); if (flag25 && projectile.ai[1] == 0f) { projectile.ai[1] += 1f; if (Main.myPlayer == projectile.owner && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, vector46, 0, 0)) { Vector2 value19 = vector46 - projectile.Center; value19.Normalize(); value19 *= scaleFactor3; int num659 = Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, value19.X, value19.Y, num658, projectile.damage, 0f, Main.myPlayer, 0f, 0f); Main.projectile[num659].timeLeft = 300; projectile.netUpdate = true; } } } }
private PlantStage GetStage(int i, int j) { Tile tile = Framing.GetTileSafely(i, j); return((PlantStage)(tile.frameX / FrameWidth)); }
public override void RandomUpdate(int i, int j, int type) { if (type == 367) { if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && TileArray2.Contains(Framing.GetTileSafely(i, j - 2).type)) { if (Main.rand.Next(800) == 0) { WorldGen.PlaceObject(i - 1, j - 1, mod.TileType("Medustalk")); NetMessage.SendObjectPlacment(-1, i - 1, j - 1, mod.TileType("Medustalk"), 0, 0, -1, -1); } } } if (type == 147) { if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && TileArray2.Contains(Framing.GetTileSafely(i, j - 2).type)) { if (Main.rand.Next(1800) == 0) { WorldGen.PlaceObject(i - 1, j - 1, mod.TileType("FrostShine")); NetMessage.SendObjectPlacment(-1, i - 1, j - 1, mod.TileType("FrostShine"), 0, 0, -1, -1); } } } if (type == 2) { if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && (i < (Main.maxTilesX / 5) || i > Main.maxTilesX - (Main.maxTilesX / 5))) { if (Main.rand.Next(400) == 0) { int why = Main.rand.Next(8); WorldGen.PlaceObject(i, j - why, mod.TileType("Bamboo")); NetMessage.SendObjectPlacment(-1, i, j - why, mod.TileType("Bamboo"), 0, 0, -1, -1); } } } if (type == 2) //add water support later { bool place = false; for (int x = i - 5; x < i + 5; x++) { for (int y = j; y < j + 5; y++) { if (Main.tile[x, y].liquid == 255) { place = true; } } } if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && TileArray2.Contains(Framing.GetTileSafely(i, j - 2).type) && place) { if (Main.rand.Next(800) == 1) { WorldGen.PlaceObject(i - 1, j - 1, mod.TileType("CatTail")); NetMessage.SendObjectPlacment(-1, i - 1, j - 1, mod.TileType("CatTail"), 0, 0, -1, -1); } } } if (type == 1) //magma corn { bool place = false; for (int x = i - 7; x < i + 7; x++) { for (int y = j; y < j + 7; y++) { if (Main.tile[x, y].liquid == 255 && Main.tile[x, y].lava()) { place = true; } } } if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && TileArray2.Contains(Framing.GetTileSafely(i, j - 2).type) && place) { if (Main.rand.Next(800) == 1) { WorldGen.PlaceObject(i - 1, j - 1, mod.TileType("MagmaCorn")); NetMessage.SendObjectPlacment(-1, i - 1, j - 1, mod.TileType("MagmaCorn"), 0, 0, -1, -1); } } } if (type == 2) //add water support later { if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && TileArray2.Contains(Framing.GetTileSafely(i, j - 2).type)) { if (Main.rand.Next(1800) == 2) { WorldGen.PlaceObject(i - 1, j - 1, mod.TileType("StrawberryPlant")); NetMessage.SendObjectPlacment(-1, i - 1, j - 1, mod.TileType("StrawberryPlant"), 0, 0, -1, -1); } } } if (type == 368) { if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && TileArray2.Contains(Framing.GetTileSafely(i, j - 2).type)) { if (Main.rand.Next(1400) == 0) { WorldGen.PlaceObject(i - 1, j - 1, mod.TileType("FluxCoral")); NetMessage.SendObjectPlacment(-1, i - 1, j - 1, mod.TileType("FluxCoral"), 0, 0, -1, -1); } } } if (type == 70) { if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && TileArray2.Contains(Framing.GetTileSafely(i, j - 2).type)) { if (Main.rand.Next(1400) == 0) { WorldGen.PlaceObject(i - 1, j - 1, mod.TileType("Gelon")); NetMessage.SendObjectPlacment(-1, i - 1, j - 1, mod.TileType("Gelon"), 0, 0, -1, -1); } } } if (type == 396) { if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && TileArray2.Contains(Framing.GetTileSafely(i, j - 2).type)) { if (Main.rand.Next(1200) == 0) { WorldGen.PlaceObject(i - 1, j - 1, mod.TileType("Jaderose")); NetMessage.SendObjectPlacment(-1, i - 1, j - 1, mod.TileType("Jaderose"), 0, 0, -1, -1); } } /* } * * if (type == 396) * { * if(TileArray2.Contains(Framing.GetTileSafely(i,j-1).type) &&TileArray2.Contains(Framing.GetTileSafely(i,j-2).type)) * { * if(Main.rand.Next(2500)==0) * { * WorldGen.PlaceObject(i-1,j-1,mod.TileType("JungleFungus")); * NetMessage.SendObjectPlacment(-1,i-1,j-1,mod.TileType("JungleFungus"),0,0,-1,-1); * } * * } */ } if (type == 60 && Main.hardMode) { if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && TileArray2.Contains(Framing.GetTileSafely(i, j - 2).type)) { if (Main.rand.Next(2500) == 0) { WorldGen.PlaceObject(i - 1, j - 1, mod.TileType("VenomRadish")); NetMessage.SendObjectPlacment(-1, i - 1, j - 1, mod.TileType("VenomRadish"), 0, 0, -1, -1); } } } if (type == 2) //add water support later { if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && TileArray2.Contains(Framing.GetTileSafely(i, j - 2).type)) { if (Main.rand.Next(1800) == 2) { WorldGen.PlaceObject(i - 1, j - 1, mod.TileType("ForestPlant")); NetMessage.SendObjectPlacment(-1, i - 1, j - 1, mod.TileType("ForestPlant"), 0, 0, -1, -1); } } } if (type == 1) //add water support later { bool place = false; for (int x = i - 5; x < i + 5; x++) { for (int y = j; y < j + 5; y++) { if (Main.tile[x, y].liquid == 255) { place = true; } } } if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && TileArray2.Contains(Framing.GetTileSafely(i, j - 2).type) && place) { if (Main.rand.Next(4000) == 1) { WorldGen.PlaceObject(i - 1, j - 1, mod.TileType("StoneberryPlant")); NetMessage.SendObjectPlacment(-1, i - 1, j - 1, mod.TileType("StoneberryPlant"), 0, 0, -1, -1); } } } }
/// <summary>Just makes it easier to place tiles with good framing.</summary> private static void Place(int x, int y, short frameX, short frameY) { PlaceTile(x, y, TileType <BigTree_Purity>(), true, false, -1, 0); Framing.GetTileSafely(x, y).frameX = frameX; Framing.GetTileSafely(x, y).frameY = frameY; }
public static bool GetSittingTargetInfo(Player player, int x, int y, out int targetDirection, out Vector2 playerSittingPosition, out Vector2 seatDownOffset) { Tile tileSafely = Framing.GetTileSafely(x, y); if (!TileID.Sets.CanBeSatOnForPlayers[tileSafely.type] || !tileSafely.active()) { targetDirection = 1; seatDownOffset = Vector2.Zero; playerSittingPosition = default(Vector2); return(false); } int num = x; int num2 = y; targetDirection = 1; seatDownOffset = Vector2.Zero; int num3 = 6; Vector2 zero = Vector2.Zero; switch (tileSafely.type) { case 15: case 497: seatDownOffset.Y = (tileSafely.type == 15 && tileSafely.frameY / 40 == 27).ToInt() * 4; if (tileSafely.frameY % 40 != 0) { num2--; } targetDirection = -1; if (tileSafely.frameX != 0) { targetDirection = 1; } break; case 102: { int num4 = tileSafely.frameX / 18; if (num4 == 0) { num++; } if (num4 == 2) { num--; } int num5 = tileSafely.frameY / 18; if (num5 == 0) { num2 += 2; } if (num5 == 1) { num2++; } if (num5 == 3) { num2--; } targetDirection = player.direction; num3 = 0; break; } case 487: { int num6 = tileSafely.frameX % 72 / 18; if (num6 == 1) { num--; } if (num6 == 2) { num++; } if (tileSafely.frameY / 18 != 0) { num2--; } targetDirection = (num6 <= 1).ToDirectionInt(); num3 = 0; seatDownOffset.Y -= 1f; break; } case 89: { targetDirection = player.direction; num3 = 0; Vector2 vector = new Vector2(-4f, 2f); Vector2 vector2 = new Vector2(4f, 2f); Vector2 vector3 = new Vector2(0f, 2f); Vector2 zero2 = Vector2.Zero; zero2.X = 1f; zero.X = -1f; switch (tileSafely.frameX / 54) { case 0: vector3.Y = (vector.Y = (vector2.Y = 1f)); break; case 1: vector3.Y = 1f; break; case 2: case 14: case 15: case 17: case 20: case 21: case 22: case 23: case 25: case 26: case 27: case 28: case 35: case 37: case 38: case 39: case 40: case 41: case 42: vector3.Y = (vector.Y = (vector2.Y = 1f)); break; case 3: case 4: case 5: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 16: case 18: case 19: case 36: vector3.Y = (vector.Y = (vector2.Y = 0f)); break; case 6: vector3.Y = (vector.Y = (vector2.Y = -1f)); break; case 24: vector3.Y = 0f; vector.Y = -4f; vector.X = 0f; vector2.X = 0f; vector2.Y = -4f; break; } if (tileSafely.frameY % 40 != 0) { num2--; } if ((tileSafely.frameX % 54 == 0 && targetDirection == -1) || (tileSafely.frameX % 54 == 36 && targetDirection == 1)) { seatDownOffset = vector; } else if ((tileSafely.frameX % 54 == 0 && targetDirection == 1) || (tileSafely.frameX % 54 == 36 && targetDirection == -1)) { seatDownOffset = vector2; } else { seatDownOffset = vector3; } seatDownOffset += zero2; break; } } playerSittingPosition = new Point(num, num2 + 1).ToWorldCoordinates(8f, 16f); playerSittingPosition.X += targetDirection * num3; playerSittingPosition += zero; return(true); }
/// <summary>Spawns a tree at x, y, origin being the left side of the trunk.</summary> /// <param name="r">Pass WorldGen.genRand if you plan to use this during worldgen. Defaults to Main.rand.</param> /// <param name="height">Height of the tree in tiles.</param> /// <param name="requireHeight">If true, this tree will not grow in too small of a space. If false, this will fit the space.</param> /// <param name="minHeight">Stops the spawn if height is too low, or, if requireHeight is false, the adjusted height is too low.</param> public static void Spawn(int x, int y, int height, UnifiedRandom r = null, bool requireHeight = false, int minHeight = 8, bool spawnLeaves = true) { //Feel free to move this method wherever; in my main project I have it under a TileHelper class that also takes a type param for brevity. r = r ?? Main.rand; //Defaults to Main.rand. Again, should be WorldGen.genRand if you want this to work in world generaiton. if (y < minHeight * 2) { return; //There may not be enough space in the world for this, abort now } for (int i = 1; i < height; ++i) //Checks height for obstructions so it doesn't grow into the ceiling { if ((Framing.GetTileSafely(x, y - i).active() && Main.tileSolid[Framing.GetTileSafely(x, y - i).type]) || (Framing.GetTileSafely(x + 1, y - i).active() && Main.tileSolid[Framing.GetTileSafely(x + 1, y - i).type])) { if (!requireHeight) //Adjust height { height = i - 1; } else //Stop spawning if you require a specific height { return; } } } if (height <= minHeight) { return; //Tree is too small, stop the spawn } bool FullTile(int i, int j) => Framing.GetTileSafely(i, j).active() && !Main.tileCut[Framing.GetTileSafely(i, j).type]; //True if a tile is active & not overrideable bool SolidTile(int i, int j) => Framing.GetTileSafely(i, j).active() && Main.tileSolid[Framing.GetTileSafely(i, j).type]; //Self explanatory Place(x, y, (short)(!FullTile(x - 1, y) && SolidTile(x - 1, y + 1) ? 72 : 0), (short)(18 * r.Next(3))); //Middle base Place(x + 1, y, (short)(!FullTile(x + 2, y) && SolidTile(x + 2, y + 1) ? 306 : 18), (short)(18 * r.Next(3))); if (!FullTile(x - 1, y) && SolidTile(x - 1, y + 1)) { Place(x - 1, y, 36, (short)(18 * r.Next(3))); //Left root if space is open & has footing } if (!FullTile(x + 2, y) && SolidTile(x + 2, y + 1)) { Place(x + 2, y, 54, (short)(18 * r.Next(3))); //Right root if space is open & has footing } int[] lastBranch = new int[2]; //Makes sure the gen doesn't spam branches for (int i = 1; i < height; ++i) //Trunk { Place(x, y - i, 0, (short)(18 * r.Next(3))); //Place trunk Place(x + 1, y - i, 18, (short)(18 * r.Next(3))); //Trunk, part 2 if ((lastBranch[0] < 0 || lastBranch[1] < 0) && i > 3 && i < height - 2 && r.Next(2) == 0) //Branch chance and conditions { bool leaf = r.Next(4) > 0; //Leaf chance //There's probably a cleaner way to do this but I didn't think of it. bool left = r.Next(2) == 0; //Direction logic --> if (lastBranch[0] > 0) { left = false; //'Timer' checks } else if (lastBranch[1] > 0) { left = true; } else if (lastBranch[0] < 0 && lastBranch[1] < 0) { left = r.Next(2) == 0; } if (Framing.GetTileSafely(x - 1, y - i).active() || Framing.GetTileSafely(x - 2, y - i).active() && left) //Tile-based placement checks { if ((lastBranch[1] > 0)) { goto skipBranch; //If this branch cannot, in any way, be placed, skip } left = false; //Adjust side } if (Framing.GetTileSafely(x + 2, y - i).active() || Framing.GetTileSafely(x + 3, y - i).active() && !left) //Tile-based placement checks { if ((lastBranch[0] > 0)) { goto skipBranch; //If this branch cannot, in any way, be placed, skip } left = true; //Adjust side } if ((Framing.GetTileSafely(x - 1, y - i).active() || Framing.GetTileSafely(x - 2, y - i).active()) && //If both placements are invalid, skip this entirely (Framing.GetTileSafely(x + 2, y - i).active() || Framing.GetTileSafely(x + 3, y - i).active())) { goto skipBranch; //Eww goto but I didn't wanna reformat this <-- } if (left) //Place left branch; adjust trunk { Framing.GetTileSafely(x, y - i).frameX = 198; Place(x - 1, y - i, 90, (short)(18 * r.Next(3))); Place(x - 2, y - i, (short)(leaf ? 270 : 108), (short)(18 * r.Next(3))); lastBranch[0] = 3 + Main.rand.Next(2); //Make them unable to place within 3-4 tiles of each other. You can change this as you please. } else //Same as lines 68-75, but for right branch { Framing.GetTileSafely(x + 1, y - i).frameX = 216; Place(x + 2, y - i, 144, (short)(18 * r.Next(3))); Place(x + 3, y - i, (short)(leaf ? 288 : 126), (short)(18 * r.Next(3))); lastBranch[1] = 3 + Main.rand.Next(2); } int leaves = r.Next(3, 6); //Random leaf spawns for trunk if (spawnLeaves) //Spawns leaf gores { for (int l = 0; l < leaves; ++l) { Gore.NewGore((new Vector2(x + r.Next(2), y - i) * 16) + new Vector2(r.Next(16), r.Next(16)), new Vector2(), LeafType, r.Next(90, 130) * 0.01f); } } } skipBranch: //Case for skipping branch placement lastBranch[0]--; //Branch countdown lastBranch[1]--; //Branch countdown 2 if (i == height - 1) //Treetop { Framing.GetTileSafely(x, y - i).frameX = 234; //Treetop tiles for drawing the tops Framing.GetTileSafely(x + 1, y - i).frameX = 252; int leaves = r.Next(20, 28); if (spawnLeaves) //Spawns leaf gores { for (int l = 0; l < leaves; ++l) { Gore.NewGore((new Vector2(x - 12, y - i - 20) * 16) + new Vector2(r.Next(360), r.Next(320)), new Vector2(), LeafType, r.Next(120, 160) * 0.01f); } } } } }
public override void AI() { bool flag64 = projectile.type == mod.ProjectileType("SockPuppet"); Player player = Main.player[projectile.owner]; AAPlayer modPlayer = player.GetModPlayer <AAPlayer>(); player.AddBuff(mod.BuffType("SockPuppet"), 3600); if (flag64) { if (player.dead) { modPlayer.Sock = false; } if (modPlayer.Sock) { projectile.timeLeft = 2; } } float num633 = 700f; float num634 = 800f; float num635 = 1200f; float num636 = 150f; float num637 = 0.05f; for (int num638 = 0; num638 < 1000; num638++) { bool flag23 = Main.projectile[num638].type == mod.ProjectileType("SockPuppet"); if (num638 != projectile.whoAmI && Main.projectile[num638].active && Main.projectile[num638].owner == projectile.owner && flag23 && Math.Abs(projectile.position.X - Main.projectile[num638].position.X) + Math.Abs(projectile.position.Y - Main.projectile[num638].position.Y) < projectile.width) { if (projectile.position.X < Main.projectile[num638].position.X) { projectile.velocity.X = projectile.velocity.X - num637; } else { projectile.velocity.X = projectile.velocity.X + num637; } if (projectile.position.Y < Main.projectile[num638].position.Y) { projectile.velocity.Y = projectile.velocity.Y - num637; } else { projectile.velocity.Y = projectile.velocity.Y + num637; } } } bool flag24 = false; if (flag24) { return; } Vector2 vector46 = projectile.position; bool flag25 = false; if (projectile.ai[0] != 1f) { projectile.tileCollide = false; } if (projectile.tileCollide && WorldGen.SolidTile(Framing.GetTileSafely((int)projectile.Center.X / 16, (int)projectile.Center.Y / 16))) { projectile.tileCollide = false; } bool AttackFrame = false; if (player.HasMinionAttackTargetNPC) { NPC npc = Main.npc[player.MinionAttackTargetNPC]; AttackFrame = true; if (Collision.CanHitLine(projectile.position, projectile.width, projectile.height, npc.position, npc.width, npc.height)) { num633 = Vector2.Distance(projectile.Center, vector46); vector46 = npc.Center; flag25 = true; } } else { for (int k = 0; k < 200; k++) { NPC npc = Main.npc[k]; if (npc.CanBeChasedBy(this, false)) { AttackFrame = true; float num646 = Vector2.Distance(npc.Center, projectile.Center); if ((num646 < num633 || !flag25) && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, npc.position, npc.width, npc.height)) { num633 = num646; vector46 = npc.Center; flag25 = true; } } } } float num647 = num634; if (flag25) { num647 = num635; } if (Vector2.Distance(player.Center, projectile.Center) > num647) { projectile.ai[0] = 1f; projectile.tileCollide = false; projectile.netUpdate = true; } if (flag25 && projectile.ai[0] == 0f) { Vector2 vector47 = vector46 - projectile.Center; float num648 = vector47.Length(); vector47.Normalize(); if (num648 > 200f) { float scaleFactor2 = 6f; vector47 *= scaleFactor2; projectile.velocity = (projectile.velocity * 40f + vector47) / 41f; } else { float num649 = 4f; vector47 *= -num649; projectile.velocity = (projectile.velocity * 40f + vector47) / 41f; } } else { bool flag26 = false; if (!flag26) { flag26 = projectile.ai[0] == 1f; } float num650 = 6f; if (flag26) { num650 = 15f; } Vector2 center2 = projectile.Center; Vector2 vector48 = player.Center - center2 + new Vector2(0f, -60f); float num651 = vector48.Length(); if (num651 > 200f && num650 < 8f) { num650 = 8f; } if (num651 < num636 && flag26 && !Collision.SolidCollision(projectile.position, projectile.width, projectile.height)) { projectile.ai[0] = 0f; projectile.netUpdate = true; } if (num651 > 2000f) { projectile.position.X = Main.player[projectile.owner].Center.X - projectile.width / 2; projectile.position.Y = Main.player[projectile.owner].Center.Y - projectile.height / 2; projectile.netUpdate = true; } if (num651 > 70f) { vector48.Normalize(); vector48 *= num650; projectile.velocity = (projectile.velocity * 40f + vector48) / 41f; } else if (projectile.velocity.X == 0f && projectile.velocity.Y == 0f) { projectile.velocity.X = -0.15f; projectile.velocity.Y = -0.05f; } } projectile.rotation = projectile.velocity.X * 0.04f; if (flag25) { projectile.spriteDirection = ((vector46 - projectile.Center).X > 0? -1: 1); } else { projectile.spriteDirection = (projectile.velocity.X > 0? -1: 1); } if (++projectile.frameCounter >= 10) { projectile.frameCounter = 0; if (!AttackFrame) { if (++projectile.frame > 3) { projectile.frame = 0; } } else { if (++projectile.frame < 3 || projectile.frame > 7) { projectile.frame = 3; } } } if (projectile.ai[1] > 0f) { projectile.ai[1] += Main.rand.Next(1, 4); } if (projectile.ai[1] > 90f) { projectile.ai[1] = 0f; projectile.netUpdate = true; } if (projectile.ai[0] == 0f) { float scaleFactor3 = 16f; if (flag25 && projectile.ai[1] == 0f) { projectile.ai[1] += 1f; if (Main.myPlayer == projectile.owner && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, vector46, 0, 0)) { Vector2 value19 = vector46 - projectile.Center; value19.Normalize(); value19 *= scaleFactor3; int proj = Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, value19.X, value19.Y, 449, projectile.damage, projectile.knockBack, Main.myPlayer, 0f, 0f); Main.projectile[proj].hostile = false; Main.projectile[proj].friendly = true; Main.projectile[proj].magic = false; Main.projectile[proj].minion = true; Main.projectile[proj].netUpdate = true; projectile.netUpdate = true; } } } }
public override void RandomUpdate(int i, int j) { if (!Framing.GetTileSafely(i, j - 1).active() && Main.rand.Next(400) == 0) { switch (Main.rand.Next(9)) { case 0: ReachGrassTile.PlaceObject(i, j - 1, mod.TileType("GlowShard1")); NetMessage.SendObjectPlacment(-1, i, j - 1, mod.TileType("GlowShard1"), 0, 0, -1, -1); break; case 1: ReachGrassTile.PlaceObject(i, j - 1, mod.TileType("GlowShard2")); NetMessage.SendObjectPlacment(-1, i, j - 1, mod.TileType("GlowShard2"), 0, 0, -1, -1); break; case 2: ReachGrassTile.PlaceObject(i, j - 1, mod.TileType("GlowShard3")); NetMessage.SendObjectPlacment(-1, i, j - 1, mod.TileType("GlowShard3"), 0, 0, -1, -1); break; case 3: ReachGrassTile.PlaceObject(i, j - 1, mod.TileType("GlowShard4")); NetMessage.SendObjectPlacment(-1, i, j - 1, mod.TileType("GlowShard4"), 0, 0, -1, -1); break; } } if (!Framing.GetTileSafely(i, j + 1).active() && Main.rand.Next(400) == 0) { switch (Main.rand.Next(3)) { case 0: ReachGrassTile.PlaceObject(i, j + 1, mod.TileType("GlowShard1")); NetMessage.SendObjectPlacment(-1, i, j + 1, mod.TileType("GlowShard1"), 0, 0, -1, -1); break; case 1: ReachGrassTile.PlaceObject(i, j + 1, mod.TileType("GlowShard2")); NetMessage.SendObjectPlacment(-1, i, j + 1, mod.TileType("GlowShard2"), 0, 0, -1, -1); break; case 2: ReachGrassTile.PlaceObject(i, j + 1, mod.TileType("GlowShard3")); NetMessage.SendObjectPlacment(-1, i, j + 1, mod.TileType("GlowShard3"), 0, 0, -1, -1); break; case 3: ReachGrassTile.PlaceObject(i, j + 1, mod.TileType("GlowShard4")); NetMessage.SendObjectPlacment(-1, i, j + 1, mod.TileType("GlowShard4"), 0, 0, -1, -1); break; } } if (!Framing.GetTileSafely(i - 1, j).active() && Main.rand.Next(4) == 0) { switch (Main.rand.Next(3)) { case 0: ReachGrassTile.PlaceObject(i - 1, j, mod.TileType("GlowShard1")); NetMessage.SendObjectPlacment(-1, i - 1, j, mod.TileType("GlowShard1"), 0, 0, -1, -1); break; case 1: ReachGrassTile.PlaceObject(i - 1, j, mod.TileType("GlowShard2")); NetMessage.SendObjectPlacment(-1, i - 1, j, mod.TileType("GlowShard2"), 0, 0, -1, -1); break; case 2: ReachGrassTile.PlaceObject(i - 1, j, mod.TileType("GlowShard3")); NetMessage.SendObjectPlacment(-1, i - 1, j, mod.TileType("GlowShard3"), 0, 0, -1, -1); break; case 3: ReachGrassTile.PlaceObject(i - 1, j, mod.TileType("GlowShard4")); NetMessage.SendObjectPlacment(-1, i - 1, j, mod.TileType("GlowShard4"), 0, 0, -1, -1); break; } } if (!Framing.GetTileSafely(i + 1, j).active() && Main.rand.Next(4) == 0) { switch (Main.rand.Next(3)) { case 0: ReachGrassTile.PlaceObject(i + 1, j, mod.TileType("GlowShard1")); NetMessage.SendObjectPlacment(-1, i + 1, j, mod.TileType("GlowShard1"), 0, 0, -1, -1); break; case 1: ReachGrassTile.PlaceObject(i + 1, j, mod.TileType("GlowShard2")); NetMessage.SendObjectPlacment(-1, i + 1, j, mod.TileType("GlowShard2"), 0, 0, -1, -1); break; case 2: ReachGrassTile.PlaceObject(i + 1, j, mod.TileType("GlowShard3")); NetMessage.SendObjectPlacment(-1, i + 1, j, mod.TileType("GlowShard3"), 0, 0, -1, -1); break; case 3: ReachGrassTile.PlaceObject(i + 1, j, mod.TileType("GlowShard4")); NetMessage.SendObjectPlacment(-1, i + 1, j, mod.TileType("GlowShard4"), 0, 0, -1, -1); break; } } }
public override void PostUpdateMiscEffects() { nurseCooldown--; if (!MyWorld.awakenedMode) { sanity = sanityMax; } PlayerUtils playerUtils = player.GetModPlayer <PlayerUtils>(mod); sanityMax = sanityIncreaser; craftWeaponCooldown--; // decreases if (MyWorld.awakenedMode) { // if (sanity > 0) { // low life if (player.statLife < player.statLifeMax2 * 0.25f) { int sanityRegenLoss = (int)Math.Round(MathHelper.Lerp(4, 1, player.statLife / (player.statLifeMax2 * 0.25f))); //ElementsAwoken.DebugModeText(sanityRegenLoss); sanityRegen -= sanityRegenLoss; AddSanityDrain(sanityRegenLoss, "Low Health"); } // in the dark if (playerUtils.playerLight < 0.2) { int sanityRegenLoss = (int)Math.Round(MathHelper.Lerp(3, 1, playerUtils.playerLight / 0.2f)); //ElementsAwoken.DebugModeText(playerUtils.playerLight); sanityRegen -= sanityRegenLoss; AddSanityDrain(sanityRegenLoss, "Darkness"); } // events if (Main.bloodMoon) { sanityRegen--; AddSanityDrain(1, "Blood Moon"); } if (MyWorld.darkMoon) { sanityRegen -= 2; AddSanityDrain(2, "Dark Moon"); } if (MyWorld.voidInvasionUp && Main.time >= 16220 && !Main.dayTime) { sanityRegen -= 3; AddSanityDrain(2, "Dawn of the Void"); } if (player.ZoneUnderworldHeight) { sanityRegen -= 2; AddSanityDrain(2, "In Hell"); } if (player.ZoneSkyHeight) { sanityRegen -= 1; AddSanityDrain(1, "In Space"); } if (miningCounter > 3600 * 10) { if (mineTileCooldown > mineTileCooldownMax - 300) { sanityRegen -= 3;// first 5 seconds after mining a tile reduces sanity AddSanityDrain(3, "Mining For Too Long"); } } if (NPC.AnyNPCs(NPCID.MoonLordCore)) { player.AddBuff(mod.BuffType("EldritchHorror"), 2); } } // increases //if (sanity < sanityMax) { for (int i = 0; i < 22; i++) { if (Main.vanityPet[player.buffType[i]]) { sanityRegen++; AddSanityRegen(1, "Pet"); //if (Main.time % 100 == 0) ElementsAwoken.DebugModeText("has pet"); break; } } #region flowers and campfires nearby int distance = 15 * 16; Point topLeft = ((player.position - new Vector2(distance, distance)) / 16).ToPoint(); Point bottomRight = ((player.BottomRight + new Vector2(distance, distance)) / 16).ToPoint(); Tile closest = null; Vector2 closestPos = new Vector2(); for (int i = topLeft.X; i <= bottomRight.X; i++) { for (int j = topLeft.Y; j <= bottomRight.Y; j++) { Tile t = Framing.GetTileSafely(i, j); if (CheckValidSanityTile(t)) { Vector2 tileCenter = new Vector2(i * 16, j * 16); if (closest != null) { if (Vector2.Distance(tileCenter, player.Center) < Vector2.Distance(closestPos, player.Center)) { closest = t; closestPos = new Vector2(i * 16, j * 16); } } else { closest = t; closestPos = new Vector2(i * 16, j * 16); } } } } if (Vector2.Distance(closestPos, player.Center) < distance && CheckValidSanityTile(closest)) { int amount = (int)Math.Round(MathHelper.Lerp(3, 1, Vector2.Distance(closestPos, player.Center) / distance)); sanityRegen += amount; string type = ""; if (closest.type == TileID.Campfire) { type = "Campfire"; } if (closest.type == TileID.Sunflower) { type = "Sunflower"; } if (closest.type == TileID.PlanterBox) { type = "Planter Box"; } AddSanityRegen(amount, "Nearby " + type); } #endregion int townSanityRegen = 0; int numNPCs = CountNearbyTownNPCs(); if (numNPCs > 5) { townSanityRegen++; } if (numNPCs > 10) { townSanityRegen++; } if (numNPCs > 15) { townSanityRegen++; } if (numNPCs > 20) { townSanityRegen++; } if (numNPCs > 25) { townSanityRegen++; } if (townSanityRegen > 0) { sanityRegen += townSanityRegen; AddSanityRegen(townSanityRegen, "In a Town"); } if (miningCounter < 3600 * 10) { if (mineTileCooldown > mineTileCooldownMax - 300) { sanityRegen += 3; // first 5 seconds after mining a tile gives sanity AddSanityRegen(3, "Mining"); } } } if (sanity < sanityMax * 0.25f && sanity > sanityMax * 0.1f) { player.magicDamage *= 0.9f; player.meleeDamage *= 0.9f; player.minionDamage *= 0.9f; player.rangedDamage *= 0.9f; player.thrownDamage *= 0.9f; } if (sanity < sanityMax * 0.1f) { ElementsAwoken.screenshakeAmount = 2f; if (sanity != 0) { player.magicDamage *= 0.75f; player.meleeDamage *= 0.75f; player.minionDamage *= 0.75f; player.rangedDamage *= 0.75f; player.thrownDamage *= 0.75f; } if (Main.rand.Next(1200) == 0) { int choice = Main.rand.Next(2); if (choice == 0) { player.AddBuff(BuffID.Darkness, 600); } else if (choice == 1) { player.AddBuff(BuffID.Confused, 120); } } } if (sanity == 0) { player.magicDamage *= 0.5f; player.meleeDamage *= 0.5f; player.minionDamage *= 0.5f; player.rangedDamage *= 0.5f; player.thrownDamage *= 0.5f; } // sanity regen logic sanityRegenCount = Math.Abs(sanityRegen); sanityRegenTime -= sanityRegenCount; if (sanityRegenTime <= 0) { sanityRegenTime = 450; sanity += Math.Sign(sanityRegen); } if (sanity > sanityMax) { sanity = sanityMax; } if (sanity < 0) { sanity = 0; } if (mineTileCooldown > 0) { mineTileCooldown--; miningCounter++; } if (mineTileCooldown <= 0) { miningCounter = 0; } InsanityOverlay.Update(); #region glitch anim sanityGlitchCooldown--; if (sanityGlitchCooldown <= 0) { sanityGlitchCooldown = 120; } if (sanityGlitchCooldown <= 12) { sanityGlitch--; if (sanityGlitch <= 0) { sanityGlitchFrame++; sanityGlitch = 3; } } else { sanityGlitchFrame = 0; } if (sanityGlitchFrame > 4) { sanityGlitchFrame = 1; } #endregion #region arrow anim sanityArrow--; if (sanityArrow <= 0) { sanityArrowFrame++; sanityArrow = 5; } if (sanityArrowFrame > 12) { sanityArrowFrame = 0; } #endregion } }
//Explosion #region Explosion /// <summary> /// Takes the projectiles radius attribute in place of passing variables /// Creates a circular explosion in the radius defined /// Efficient but most blocks don't drop due to optimization methods /// </summary> public virtual void Explosion() { // x and y are the tile offset of the current tile relative to the player // i and j are the true tile cords relative to 0,0 in the world Player player = Main.player[projectile.owner]; if (pickPower < -1) { return; } if (player.EE().BombardEmblem) { return; } Vector2 position = new Vector2(projectile.Center.X / 16f, projectile.Center.Y / 16f); // Converts to tile cords for convenience radius = (int)((radius + player.EE().RadiusBonus) * player.EE().RadiusMulti); for (int x = -radius; x <= radius; x++) { //int x = (int)(i + position.X); for (int y = -radius; y <= radius; y++) { //int y = (int)(j + position.Y); int i = (int)(x + position.X); int j = (int)(y + position.Y); if (!WorldGen.InWorld(i, j)) { continue; } if (Math.Sqrt(x * x + y * y) <= radius + 0.5) //Circle { Tile tile = Framing.GetTileSafely(i, j); if (!WorldGen.TileEmpty(i, j) && tile.active()) { if (!CanBreakTile(tile.type, pickPower)) { continue; } //if (!CanBreakTiles) continue; // Using KillTile is laggy, use ClearTile when working with larger tile sets (also stops sound spam) // But it must be done on outside tiles to ensure propper updates so use it only on outermost tiles if (Math.Abs(x) >= radius - 1 || Math.Abs(y) >= radius - 1 || Terraria.ID.TileID.Sets.Ore[tile.type]) { int type = tile.type; WorldGen.KillTile((int)(i), (int)(j), false, false, false); if (Main.netMode == NetmodeID.MultiplayerClient) //update if in mp { WorldGen.SquareTileFrame(i, j, true); //Updates Area NetMessage.SendData(MessageID.TileChange, -1, -1, null, 2, (float)i, (float)j, 0f, 0, 0, 0); } if (player.EE().DropOresTwice&& Main.rand.NextFloat() <= player.EE().dropChanceOre) //chance to drop 2 ores { WorldGen.PlaceTile(i, j, type); WorldGen.KillTile((int)(i), (int)(j), false, false, false); if (Main.netMode == NetmodeID.MultiplayerClient) { WorldGen.SquareTileFrame(i, j, true); //Updates Area NetMessage.SendData(MessageID.TileChange, -1, -1, null, 2, (float)i, (float)j, 0f, 0, 0, 0); } } } else { if (!TileID.Sets.BasicChest[Main.tile[i, j - 1].type] && !TileLoader.IsDresser(Main.tile[i, j - 1].type) && Main.tile[i, j - 1].type != 26) { tile.ClearTile(); tile.active(false); if (Main.netMode == NetmodeID.MultiplayerClient) { WorldGen.SquareTileFrame(i, j, true); //Updates Area NetMessage.SendData(MessageID.TileChange, -1, -1, null, 2, (float)i, (float)j, 0f, 0, 0, 0); } } if (tile.liquid == Tile.Liquid_Water || tile.liquid == Tile.Liquid_Lava || tile.liquid == Tile.Liquid_Honey) { WorldGen.SquareTileFrame(i, j, true); } } } } } } }
public static Point[] FindShortestPath(Point a, Point b, int maxIterations = 3000) { try { if (WorldGen.InWorld(a.X, a.Y, 10)) { if (!(!Framing.GetTileSafely(a).active() || !Main.tileSolid[Framing.GetTileSafely(a).type])) { return new Point[] { a } } } ; List <Point> pointCache = new List <Point>(); Point CurrentTilePos = a; int CMD = 0; Dictionary <Point, FNode> OpenList = new Dictionary <Point, FNode>(); Dictionary <Point, FNode> ClosedList = new Dictionary <Point, FNode>(); ClosedList.Add(CurrentTilePos, new FNode(0, Manhattan(CurrentTilePos, b), CurrentTilePos)); void AddToOpenList(Point from, Point to, float Cost) { OpenList.Add(to, new FNode(ClosedList[from].GCost + Cost, Manhattan(to, b), from)); } int iteration = 0; bool Valid(Point tile) { if (WorldGen.InWorld(tile.X, tile.Y, 10)) { Tile T = Framing.GetTileSafely(tile); return(!ClosedList.ContainsKey(tile) && !T.active() || !Main.tileSolid[T.type] || TileID.Sets.Platforms[T.type]); } return(false); } Point LowestPoint() { Point lowestPoint = new Point(-1, -1); foreach (KeyValuePair <Point, FNode> entry in OpenList) { if (Valid(entry.Key)) { float Score = float.MaxValue; if (OpenList.ContainsKey(lowestPoint)) { Score = OpenList[lowestPoint].FCost; if (entry.Value.FCost == Score && entry.Value.HCost < OpenList[lowestPoint].HCost) { lowestPoint = entry.Key; } } if (entry.Value.FCost < Score) { lowestPoint = entry.Key; } } } return(lowestPoint); } while ((CMD == 0 || CMD > 1) && iteration < maxIterations) { iteration++; CMD = Manhattan(CurrentTilePos, b); //Add to Open List Point Right = new Point(CurrentTilePos.X + 1, CurrentTilePos.Y); Point Left = new Point(CurrentTilePos.X - 1, CurrentTilePos.Y); Point Up = new Point(CurrentTilePos.X, CurrentTilePos.Y - 1); Point Down = new Point(CurrentTilePos.X, CurrentTilePos.Y + 1); Point BR = new Point(CurrentTilePos.X + 1, CurrentTilePos.Y + 1); Point BL = new Point(CurrentTilePos.X - 1, CurrentTilePos.Y + 1); Point TL = new Point(CurrentTilePos.X - 1, CurrentTilePos.Y - 1); Point TR = new Point(CurrentTilePos.X + 1, CurrentTilePos.Y - 1); if (OpenList.ContainsKey(Right)) { OpenList.Remove(Right); } if (OpenList.ContainsKey(Left)) { OpenList.Remove(Left); } if (OpenList.ContainsKey(Up)) { OpenList.Remove(Up); } if (OpenList.ContainsKey(Down)) { OpenList.Remove(Down); } if (OpenList.ContainsKey(BR)) { OpenList.Remove(BR); } if (OpenList.ContainsKey(BL)) { OpenList.Remove(BL); } if (OpenList.ContainsKey(TL)) { OpenList.Remove(TL); } if (OpenList.ContainsKey(TR)) { OpenList.Remove(TR); } if (Valid(Right)) { AddToOpenList(CurrentTilePos, Right, 1f); } if (Valid(Left)) { AddToOpenList(CurrentTilePos, Left, 1f); } if (Valid(Up)) { AddToOpenList(CurrentTilePos, Up, 1f); } if (Valid(Down)) { AddToOpenList(CurrentTilePos, Down, 1f); } if (Valid(BR)) { AddToOpenList(CurrentTilePos, BR, 1f); } if (Valid(BL)) { AddToOpenList(CurrentTilePos, BL, 1f); } if (Valid(TL)) { AddToOpenList(CurrentTilePos, TL, 1f); } if (Valid(TR)) { AddToOpenList(CurrentTilePos, TR, 1f); } CurrentTilePos = LowestPoint(); if (!ClosedList.ContainsKey(CurrentTilePos)) { ClosedList.Add(CurrentTilePos, OpenList[CurrentTilePos]); } if (!OpenList.ContainsKey(CurrentTilePos)) { OpenList.Remove(CurrentTilePos); } pointCache.Add(CurrentTilePos); } Point BackTrack = pointCache[pointCache.Count - 1]; pointCache.Clear(); while (Manhattan(BackTrack, a) >= 2) { BackTrack = ClosedList[BackTrack].parent; pointCache.Add(BackTrack); } return(pointCache.ToArray()); } catch { return(new Point[] { a }); } }
public override bool CanUseItem(Item item, Player player) { FargoPlayer modPlayer = player.GetModPlayer <FargoPlayer>(); if (modPlayer.IronGuard) { //Main.NewText($"iron {modPlayer.ironShieldCD}, {modPlayer.ironShieldTimer}"); modPlayer.IronGuard = false; modPlayer.wasHoldingShield = false; player.shield_parry_cooldown = 0; //prevent that annoying tick sound //check is necessary so if player does a real parry then switches to right click weapon, using it won't reset cooldowns if (modPlayer.ironShieldCD == 40 && modPlayer.ironShieldTimer == 20) { modPlayer.ironShieldCD = 0; modPlayer.ironShieldTimer = 0; } } //dont use hotkeys in stasis if (player.HasBuff(ModContent.BuffType <GoldenStasis>())) { if (item.type == ItemID.RodofDiscord) { player.ClearBuff(ModContent.BuffType <Buffs.Souls.GoldenStasis>()); } else { return(false); } } if (FargoSoulsWorld.EternityMode) { if (item.type == ItemID.RodofDiscord && (modPlayer.LihzahrdCurse || (Framing.GetTileSafely(Main.MouseWorld).wall == WallID.LihzahrdBrickUnsafe && !player.buffImmune[ModContent.BuffType <Buffs.Masomode.LihzahrdCurse>()]))) { return(false); } if (modPlayer.LihzahrdCurse && (item.type == ItemID.WireKite || item.type == ItemID.WireCutter)) { return(false); } } if (item.damage > 0 && (item.melee || item.ranged || item.magic) && item.pick == 0 && item.axe == 0 && item.hammer == 0) { modPlayer.MasomodeWeaponUseTimer = Math.Max(item.useTime + item.reuseDelay, 30); } if (item.magic && player.GetModPlayer <FargoPlayer>().ReverseManaFlow) { int damage = (int)(item.mana / (1f - player.endurance) + player.statDefense); player.Hurt(PlayerDeathReason.ByCustomReason(player.name + " was destroyed by their own magic."), damage, 0); player.immune = false; player.immuneTime = 0; } if (modPlayer.BuilderMode && (item.createTile != -1 || item.createWall != -1) && item.type != ItemID.PlatinumCoin && item.type != ItemID.GoldCoin) { item.useTime = 1; item.useAnimation = 1; } if (item.damage > 0 && player.HasAmmo(item, true) && !(item.mana > 0 && player.statMana < item.mana) && //non weapons and weapons with no ammo begone item.type != ItemID.ExplosiveBunny && item.type != ItemID.Cannonball && item.useTime > 0 && item.createTile == -1 && item.createWall == -1 && item.ammo == AmmoID.None && item.hammer == 0 && item.pick == 0 && item.axe == 0) { modPlayer.TryAdditionalAttacks(item.damage, item.melee, item.ranged, item.magic, item.summon); } //critter attack timer if (modPlayer.WoodEnchant && player.altFunctionUse == ItemAlternativeFunctionID.ActivatedAndUsed && item.makeNPC > 0) { if (modPlayer.CritterAttackTimer == 0) { Vector2 vel = Vector2.Normalize(Main.MouseWorld - player.Center); float damageMultiplier = player.minionDamage; int type = -1; int damage = 0; int attackCooldown = 0; switch (item.type) { //case ItemID.Bunny: // type = ProjectileID.ExplosiveBunny; // damage = 10; // attackCooldown = 10; // break; case ItemID.Bird: type = ModContent.ProjectileType <BirdProj>(); damage = 15; attackCooldown = 15; break; case ItemID.BlueJay: type = ModContent.ProjectileType <BlueJayProj>(); damage = 10; attackCooldown = 10; break; case ItemID.Cardinal: type = ModContent.ProjectileType <CardinalProj>(); damage = 20; attackCooldown = 20; break; } if (type != -1) { Projectile.NewProjectile(player.Center, vel * 2f, type, damage, 2, player.whoAmI); modPlayer.CritterAttackTimer = attackCooldown; } } return(false); } if (item.type == ItemID.RodofDiscord) { if (FargoSoulsWorld.EternityMode && FargoSoulsUtil.AnyBossAlive()) { /*player.AddBuff(ModContent.BuffType<Buffs.Masomode.ChaosLife>(), 30); * modPlayer.MaxLifeReduction += 100;*/ player.chaosState = true; /*player.statLife -= player.statLifeMax2 / 5; * PlayerDeathReason damageSource = PlayerDeathReason.ByOther(13); * if (Main.rand.NextBool()) * damageSource = PlayerDeathReason.ByOther(player.Male ? 14 : 15); * if (player.statLife <= 0 && !player.chaosState) //since chaos state will check and kill anyway, avoid doublekill * player.KillMe(damageSource, 1, 0); * player.lifeRegenCount = 0; * player.lifeRegenTime = 0;*/ } if (player.chaosState) { player.GetModPlayer <FargoPlayer>().WasHurtBySomething = true; //with abom rebirth, die to chaos state } } return(true); }
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.downedBoss[(int)FargoSoulsWorld.Downed.SpiritChampion] && NPC.ai[1] < 120) { NPC.ai[1] = 120; } if (NPC.ai[1] == 180) { SoundEngine.PlaySound(SoundID.Roar, NPC.Center); if (Main.netMode != NetmodeID.MultiplayerClient) { int n = NPC.NewNPC(NPC.GetSource_FromAI(), (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(NPC.GetSource_FromAI(), (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(NPC.GetSource_FromAI(), (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(NPC.GetSource_FromAI(), (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; SoundEngine.PlaySound(SoundID.Item14, NPC.Center); 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(NPC.GetSource_FromThis(), 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).WallType != 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).WallType == 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(NPC.GetSource_FromAI(), (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(NPC.GetSource_FromAI(), (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(NPC.GetSource_FromAI(), (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(NPC.GetSource_FromAI(), (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) { SoundEngine.PlaySound(SoundID.Roar, NPC.Center); 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(NPC.GetSource_FromAI(), (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) { SoundEngine.PlaySound(SoundID.Item2, NPC.Center); for (int i = 0; i < 12; i++) { Projectile.NewProjectile(NPC.GetSource_FromThis(), 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>(), FargoSoulsUtil.ScaledProjectileDamage(NPC.damage), 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(NPC.GetSource_FromThis(), 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; SoundEngine.PlaySound(SoundID.Roar, NPC.Center); } } break; case 0: //float to player if (!player.active || player.dead || Vector2.Distance(NPC.Center, player.Center) > 2500f || (Framing.GetTileSafely(player.Center).WallType == 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 { SoundEngine.PlaySound(SoundID.Item2, NPC.Center); for (int i = 0; i < 12; i++) { Projectile.NewProjectile(NPC.GetSource_FromThis(), 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>(), FargoSoulsUtil.ScaledProjectileDamage(NPC.damage), 0f, Main.myPlayer); } } else //sandnado { doPredictiveSandnado = !doPredictiveSandnado; Vector2 target = player.Center; if (doPredictiveSandnado && NPC.life < NPC.lifeMax * 0.66) { target += player.velocity * 30f; //alternate between predictive and direct aim } target.Y -= 100; Projectile.NewProjectile(NPC.GetSource_FromThis(), 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.GetSource_FromThis(), NPC.Center, speed, ModContent.ProjectileType <SpiritSpirit>(), FargoSoulsUtil.ScaledProjectileDamage(NPC.damage), 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; SoundEngine.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.GetSource_FromThis(), NPC.Center, velocity, ModContent.ProjectileType <SpiritSword>(), FargoSoulsUtil.ScaledProjectileDamage(NPC.damage), 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.GetSource_FromThis(), NPC.Center, vel, ModContent.ProjectileType <SpiritHand>(), FargoSoulsUtil.ScaledProjectileDamage(NPC.damage), 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.IsSummonDamage(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(NPC.GetSource_FromThis(), x.Center, Vector2.Zero, ModContent.ProjectileType <Projectiles.Souls.IronParry>(), 0, 0f, Main.myPlayer); } } }); } if (NPC.ai[1] == 0) { SoundEngine.PlaySound(SoundID.Roar, NPC.Center); if (Main.netMode != NetmodeID.MultiplayerClient) { Projectile.NewProjectile(NPC.GetSource_FromThis(), 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; SoundEngine.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].HasUnactuatedTile) { bool flag2 = true; if (flag2 && Main.tile[index1, index2].LiquidType == LiquidID.Lava && Main.tile[index1, index2].LiquidAmount > 0) { flag2 = false; } if (flag2 && Collision.SolidTiles(index1 - num4, index1 + num4, index2 - num4, index2 + num4)) { flag2 = false; } if (flag2) { Projectile.NewProjectile(NPC.GetSource_FromThis(), index1 * 16 + 8, index2 * 16 + 8, 0, 0f, ProjectileID.DesertDjinnCurse, 0, 1f, Main.myPlayer, NPC.target, 0); 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.GetSource_FromThis(), NPC.Center, vel, ModContent.ProjectileType <SpiritHand>(), FargoSoulsUtil.ScaledProjectileDamage(NPC.damage), 0f, Main.myPlayer, ai0, ai1); } } } if (NPC.ai[1] % 30 == 0 && Main.netMode != NetmodeID.MultiplayerClient && NPC.life < NPC.lifeMax * 0.66) { SoundEngine.PlaySound(SoundID.Item2, NPC.Center); for (int i = 0; i < 3; i++) { Projectile.NewProjectile(NPC.GetSource_FromThis(), 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>(), FargoSoulsUtil.ScaledProjectileDamage(NPC.damage), 0f, Main.myPlayer); Projectile.NewProjectile(NPC.GetSource_FromThis(), 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>(), FargoSoulsUtil.ScaledProjectileDamage(NPC.damage), 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; SoundEngine.PlaySound(SoundID.Roar, NPC.Center); if (Main.netMode != NetmodeID.MultiplayerClient) //spawn super hand { int n2 = NPC.NewNPC(NPC.GetSource_FromAI(), (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 Kill(int timeLeft) { SoundEngine.PlaySound(SoundID.Item14, Projectile.Center); if (Main.netMode == NetmodeID.MultiplayerClient) { return; } int xPos = (int)Projectile.Center.X / 16; int yPos = (int)Projectile.Center.Y / 16; bool WipeColumn(int i) { for (int j = 0; j >= -50; j--) { int tileX = xPos + i; int tileY = yPos + j; if (tileX < 0 || tileX > Main.maxTilesX || tileY <= 0 || tileY > Main.maxTilesY) { if (j == 0) { return(false); } continue; } Tile tile = Framing.GetTileSafely(tileX, tileY); if (tile.type == TileID.LihzahrdAltar) { continue; } if (tile.wall != WallID.LihzahrdBrickUnsafe) { if (j == 0) { return(false); } continue; } //check for chest above this block Tile tileAbove = Framing.GetTileSafely(tileX, tileY - 1); if (TileID.Sets.BasicChest[tileAbove.type]) { TileObjectData data = TileObjectData.GetTileData(tileAbove.type, 0); int x = tileX - (tile.frameX / 18 % data.Width); int y = tileY - 1 - (tile.frameY / 18 % data.Height); //get top left of chest WorldGen.KillTile(x, y); if (Main.netMode == NetmodeID.Server) { NetMessage.SendTileSquare(-1, x, y, 3); } //if couldnt destroy chest, ignore this block if (TileID.Sets.BasicChest[tileAbove.type]) { continue; } } if (TileID.Sets.BasicChest[tile.type]) { TileObjectData data = TileObjectData.GetTileData(tile.type, 0); int x = tileX - tile.frameX / 18 % data.Width; int y = tileY - tile.frameY / 18 % data.Height; //get top left of chest WorldGen.KillTile(x, y); //try to kill chest if (Main.netMode == NetmodeID.Server) { NetMessage.SendTileSquare(-1, x, y, 3); } continue; } if (tile.type == TileID.LihzahrdBrick) { tile.IsActuated = true; //actuate it if (Main.netMode == NetmodeID.Server) { NetMessage.SendTileSquare(-1, tileX, tileY, 1); } continue; } WorldGen.KillTile(tileX, tileY); if (Main.netMode == NetmodeID.Server) { NetMessage.SendTileSquare(-1, tileX, tileY, 1); } } return(true); } int leftMax = 50; int rightMax = 50; int leftTry = 0; for (; leftTry >= -leftMax; leftTry--) //try clearing left side { if (!WipeColumn(leftTry)) //if went OOB or exited temple before reaching normal left limit, give up { rightMax += leftMax - Math.Abs(leftTry); //try to extend right side by this much //Main.NewText($"Extended right max to {rightMax}"); break; } } for (int rightTry = 0; rightTry <= rightMax; rightTry++) //try clearing right side { if (!WipeColumn(rightTry)) //if went OOB or exited temple before reaching normal right limit, give up { leftMax += rightMax - rightTry; //try to extend left side by this much //Main.NewText($"Extended left max to {leftMax}"); for (; leftTry >= -leftMax; leftTry--) //try left one more time with the new extended limit { if (!WipeColumn(leftTry)) { break; } } break; } } }
public override void HoldItem(Player player) { if (Main.mouseRight) { if (charge < 1) { charge += 1f / (item.useTime * 2f); } else { if (!charged) { Main.PlaySound(SoundID.MaxMana); } charged = true; charge = 1; } player.itemAnimation = (int)(charge * player.itemAnimationMax); player.itemRotation = (1.3f - charge * 3.2f) * player.direction; } else if (charge > 0 && charged) { bool inRange = Vector2.DistanceSquared(player.Center, new Vector2(Player.tileTargetX, Player.tileTargetY) * 16) < Math.Pow(Player.tileRangeX * 16, 2); charge -= 0.1f; player.itemAnimation = (int)(charge * player.itemAnimationMax); if (charge > 0.69f && charge < 0.71f && inRange) //trigger VFX early so they line up { Vector2 pos = new Vector2(Player.tileTargetX + 0.5f, Player.tileTargetY + 0.5f) * 16; Projectile.NewProjectile(pos, Vector2.Zero, ProjectileType <AuroraPickVFX>(), 0, 0, player.whoAmI); Main.PlaySound(SoundID.DD2_WitherBeastAuraPulse.SoundId, (int)pos.X, (int)pos.Y, SoundID.DD2_WitherBeastAuraPulse.Style, 1.5f, 2f); } if (charge <= 0) { if (inRange) { for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { int xReal = Player.tileTargetX + x; int yReal = Player.tileTargetY + y; if (Framing.GetTileSafely(xReal, yReal).type != TileID.Trees) { player.PickTile(xReal, yReal, item.pick); } } } } charged = false; player.itemAnimation = 0; } } else { charge = 0; charged = false; } }