public override bool Shoot(Item item, Player player, ref Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack) { if (item.type == ItemID.Torch) { Vector2 vec = ModHelper.GetFromToVector(position, Main.MouseWorld); position -= vec * 48; } return(base.Shoot(item, player, ref position, ref speedX, ref speedY, ref type, ref damage, ref knockBack)); }
public override void Update(GameTime gameTime, Player attackPlayer, NPC attackNPC) { //if (LifeSpan > 4.96 && LifeSpan <= 5.1f) // Velocity += -ModHelper.GetFromToVector(CardGameUI.ToUIPos(Center), TargetPosition) * 0.4f; //else if (LifeSpan <= 5.1f) Velocity += ModHelper.GetFromToVector(CardGameUI.ToUIPos(Center), TargetPosition) * 0.9f; _rotation = MathHelper.ToRadians(45f) + ModHelper.GetFromToRadians(CardGameUI.ToUIPos(Center), TargetPosition); if (Vector2.Distance(CardGameUI.ToUIPos(Center), TargetPosition) < 20f) { IsRemoved = true; CardFightableNPC fightNPC = (CardFightableNPC)attackNPC.modNPC; fightNPC.CardGameHealth -= 120 / 5; // 总伤害120,,因为一射5个 } base.Update(gameTime, attackPlayer, attackNPC); }
public override void CustomBehavior() { if (Main.netMode != NetmodeID.MultiplayerClient) { if (attackCounter > 0) { attackCounter--; } Player target = Main.player[npc.target]; if (attackCounter <= 0 && Vector2.Distance(npc.Center, target.Center) < 1024 && Collision.CanHit(npc.Center, 1, 1, target.Center, 1, 1)) { Vector2 direction = ModHelper.GetFromToVector(target.Center, npc.Center); direction = direction.RotatedByRandom(MathHelper.ToRadians(10)); int projectile = Projectile.NewProjectile(npc.Center, direction * 4f, ProjectileID.CursedFlameHostile, 15, 0, Main.myPlayer); Main.projectile[projectile].timeLeft = 600; attackCounter = Main.rand.Next(200, 801); npc.netUpdate = true; } } }
public override void AI() { if (!Main.npc[(int)npc.ai[1]].active) { npc.life = 0; npc.HitEffect(0, 10.0); npc.active = false; } if (Main.netMode != NetmodeID.MultiplayerClient) { npc.localAI[0] += Main.rand.Next(4); if (npc.localAI[0] >= Main.rand.Next(1, 500000)) { npc.localAI[0] = 0f; npc.TargetClosest(true); if (Collision.CanHit(npc.position, npc.width, npc.height, Main.player[npc.target].position, Main.player[npc.target].width, Main.player[npc.target].height)) { Vector2 vec = ModHelper.GetFromToVector(npc.Center, Main.player[npc.target].Center) * 4f; Projectile.NewProjectile(npc.Center.X, npc.Center.Y, vec.X, vec.Y, ProjectileType <污染之虫射弹>(), 18, 0f, Main.myPlayer, 0f, 0f); npc.netUpdate = true; } } } }
private void MovementAI(Player player, int damagedNearlySum, bool UpgradeOutBeach) { switch ((NPCState)State) { case NPCState.Start: { oldLife = npc.life; npc.TargetClosest(true); npc.alpha = 0; SwitchState((int)NPCState.Move); break; } case NPCState.Break: { if ((float)npc.life / (float)npc.lifeMax <= 0.46f) { SwitchState((int)NPCState.Break_State2); Timer = 0; npc.ai[2] = npc.ai[3] = 0; IsState2 = true; return; } Timer++; if (Timer <= 15) { npc.alpha -= 255 / 15 + 1; } npc.dontTakeDamage = true; if (Timer > (int)(80f - (1f - (float)npc.life / (float)npc.lifeMax) * 40f)) { npc.TargetClosest(); switch (Main.rand.Next(3)) { case 0: SwitchState((int)NPCState.Move); break; case 1: SwitchState((int)NPCState.Dash); break; default: SwitchState((int)NPCState.Rotat); break; } if (damagedNearlySum >= 680 && FindWater(60, 60) && Main.rand.NextBool(2)) { SwitchState((int)NPCState.FindingWaters); } if ((NPCState)State == NPCState.Dash) // 冲刺Biss { switch (Main.rand.Next(2)) { case 0: SwitchState((int)NPCState.Move); break; default: SwitchState((int)NPCState.Rotat); break; } } Timer = 0; } break; } case NPCState.Move: { Timer++; if (Timer == 1) { npc.Center = player.Center + new Vector2(Main.rand.Next(24, 33) * 16 * (Main.rand.NextBool(2) ? 1f : -1f) , Main.rand.Next(14, 21) * 16 * (Main.rand.NextBool(2) ? 1f : -1f)); npc.netUpdate = true; } if (Timer <= 15) { npc.alpha += 255 / 15 + 1; } npc.velocity = (player.Center - npc.Center).ToRotation().ToRotationVector2() * (7.2f - (float)water / (float)waterMax * 2f); int MigrantCount = 0; foreach (NPC npc in Main.npc) { if (npc.type == NPCType <Migrant>()) { MigrantCount++; } } if (Timer % 85 == 0 && MigrantCount <= 20 && Main.netMode != NetmodeID.MultiplayerClient) { NPC migrant = Main.npc[NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, NPCType <Migrant>())]; migrant.scale = 1f + (float)water / (float)waterMax * 0.4f; water -= 32; if (Main.netMode == NetmodeID.Server) { NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, migrant.whoAmI, -1f, 0f, 0f, 0, 0, 0); } } if (Timer % (int)(72f - (1f - (float)npc.life / (float)npc.lifeMax) * 50f) == 0) { float shouldHeight = -12.4f; if (player.Center.Y < npc.Center.Y) { shouldHeight -= (npc.Center.Y - player.Center.Y) * 0.0625f; } if (shouldHeight < -20f) { shouldHeight = -20f; } Shooting(2, npc.Center, player.Center + player.velocity * 85f, 0.0f, Main.rand.NextFloat(9.6f, 14.9f) * 3f, shouldHeight); water -= 8; } if (Timer >= 185) { Timer = 0; SwitchState((int)NPCState.Break); } break; } case NPCState.Dash: { Timer++; if (Timer == 1) { npc.Center = player.Center + new Vector2(30 * 16 * (Main.rand.NextBool(2) ? 1f : -1f) , 20 * 16 * (Main.rand.NextBool(2) ? 1f : -1f)); npc.netUpdate = true; } if (Timer <= 15) { npc.alpha += 255 / 15 + 1; } if (Timer == 25) { npc.direction = npc.Center.X > player.Center.X ? -1 : 1; npc.spriteDirection = npc.direction; npc.velocity.X = npc.direction * 24; Main.PlaySound(SoundID.ForceRoar, (int)npc.position.X, (int)npc.position.Y, -1, 1f, 0f); } if ((Timer - 25) % 5 == 0) { Shooting(0, npc.Center, player.Center, 0f, 20f); water -= 2; } if (Timer == 40 && Main.netMode != NetmodeID.MultiplayerClient) { NPC migrant = Main.npc[NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, NPCType <Migrant>())]; migrant.scale = 1f + (float)water / (float)waterMax * 0.4f; water -= 32; if (Main.netMode == NetmodeID.Server) { NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, migrant.whoAmI, -1f, 0f, 0f, 0, 0, 0); } } if (Timer >= 65) { Timer = 0; npc.velocity.X = 0f; SwitchState((int)NPCState.Break); } break; } case NPCState.Rotat: { npc.velocity = Vector2.Zero; Timer++; if (Timer == 1) { npc.Center = player.Center + new Vector2(0f, 26 * 16 * (Main.rand.NextBool(2) ? 1f : -1f)); npc.netUpdate = true; int insideTiles = 0; for (int i = 0; i < npc.width / 16; i++) { for (int j = 0; j < npc.height / 16; j++) { Tile tile = Main.tile[i + (int)npc.position.X / 16, j + (int)npc.position.Y / 16]; if (Main.tileSolid[tile.type] && tile.active() && tile != null) { insideTiles++; } } } if (insideTiles >= 12) { npc.Center = new Vector2(npc.Center.X, npc.Center.Y + -(npc.Center.Y - player.Center.Y)); } } if (Timer <= 15) { npc.alpha += 255 / 15 + 1; } npc.ai[3] += 0.006f; if (npc.ai[3] >= 0.3f) { if (npc.ai[3] >= 0.55f) { npc.ai[3] = 0.55f; } npc.frameCounter += npc.ai[3]; // 发射 if (Timer % 2 == 0 && Main.rand.Next(1, 4) <= 2 && Main.netMode != NetmodeID.MultiplayerClient) { if (Main.rand.NextBool(6)) { water -= 6; Shooting(1, npc.Center, npc.Center + new Vector2(0f, -10f), Main.rand.NextFloat(0.0f, MathHelper.TwoPi), Main.rand.Next(9, 20)); } water -= 1; Shooting(0, npc.Center, player.Center, Main.rand.NextFloat(0.0f, MathHelper.TwoPi), Main.rand.Next(10, 16)); } } if (Timer >= 245) { Timer = 0; npc.ai[3] = 0f; SwitchState((int)NPCState.Break); } break; } case NPCState.FindingWaters: { Timer++; npc.velocity = Vector2.Zero; if (Timer == 1) { npc.Center = waterPos + new Vector2(50f, 50f); npc.netUpdate = true; if (water >= waterMax) { water = (int)(waterMax * 0.7f); } } if (Timer <= 15) { npc.alpha += 255 / 15 + 1; } if (Timer >= 150 || water >= waterMax || npc.life >= npc.lifeMax) { Timer = 0; SwitchState((int)NPCState.Break); } break; } case NPCState.Break_State2: { Timer++; if (Timer > 10 && Main.netMode != NetmodeID.MultiplayerClient) { switch (Main.rand.Next(2)) { case 0: SwitchState((int)NPCState.Move_State2); break; default: SwitchState((int)NPCState.Round_State2); break; } npc.netUpdate = true; Timer = 0; npc.ai[2] = npc.ai[3] = 0; IsState2 = true; } break; } case NPCState.Move_State2: { npc.velocity = ModHelper.GetFromToVector(npc.Center, player.Center) * 8.2f; Timer++; if ((Timer - 30) % 50 == 0 && Timer > 60 && Main.netMode != NetmodeID.MultiplayerClient) { int proj = Projectile.NewProjectile(npc.Center, Vector2.Zero, ProjectileType <ShootingLine>(), 0, 0f, 255, 0f, npc.whoAmI); Main.projectile[proj].ai[1] = npc.whoAmI; if (Main.dedServ) { NetMessage.SendData(MessageID.SyncProjectile, -1, -1, null, proj); } } if (Timer == 250) { if (Main.rand.NextBool(3)) { SwitchState((int)NPCState.Magic_State2); } else { SwitchState((int)NPCState.Round_State2); } npc.ai[2] = npc.ai[3] = Timer = 0; return; } break; } case NPCState.Magic_State2: { // 距离小于50,且没有成功过就进入 Vector2 targetPos = player.Center + new Vector2(0f, 320f); if (Vector2.Distance(npc.Center, targetPos) > 50f && npc.ai[2] != 1) { npc.velocity = ModHelper.GetFromToVector(npc.Center, targetPos) * 36f; return; } else if (npc.ai[2] != 1) { npc.ai[2] = 1; Timer = 20; } if (npc.ai[2] == 1) { Timer++; } if (Timer >= 20) { npc.velocity = Vector2.Zero; npc.Center = targetPos; npc.netUpdate = true; } if (Timer <= 25) { //npc.alpha -= 255 / 15 + 1; //npc.alpha = Math.Max(0, npc.alpha); } if (Timer % 40 == 0 && Timer >= 70 && Main.netMode != NetmodeID.MultiplayerClient) { int offset = Timer % 80 == 40 ? 80 : 0; for (float pos = -1600f; pos <= 1600f; pos += 320f) { int proj = Projectile.NewProjectile(player.Center - new Vector2(pos + offset, 1000f), Vector2.Zero, ProjectileType <ContimatedShark>(), 60, 3f, 255, 0f, 0f); if (Main.dedServ) { NetMessage.SendData(MessageID.SyncProjectile, -1, -1, null, proj); } } } if (Timer >= 200f) { //npc.alpha += 255 / 15 + 1; //npc.alpha = Math.Min(255, npc.alpha); } if (Timer >= 215f) { SwitchState((int)(NPCState.Move_State2)); npc.ai[2] = npc.ai[3] = Timer = 0; return; } break; } case NPCState.Round_State2: { // 规定ai2只有0,1,2两种状态 // ai3为记录中的本回合的总时长 // Timer为进入转圈状态的总时长 npc.ai[3]++; // 距离小于36,且没有成功过就进入 Vector2 targetPos = player.Center + new Vector2(0f, -500f); if (Vector2.Distance(npc.Center, targetPos) > 36f && npc.ai[2] < 1) { npc.velocity = ModHelper.GetFromToVector(npc.Center, targetPos) * 30f; return; } else if (npc.ai[2] < 1) { recordedStartRoundPos = npc.Center; npc.ai[2] = 1; } if (npc.ai[2] >= 1) { Timer++; npc.velocity = Vector2.Zero; // 缓冲时间 if (Timer >= 30 && npc.ai[2] != 2f) { npc.ai[2] = 2f; Timer = 0; } if (npc.ai[2] != 2f) { return; } float speedMultipiler = 3.4f; float radians = MathHelper.ToRadians(Timer * speedMultipiler); npc.velocity = new Vector2(16f * speedMultipiler) * radians.ToRotationVector2(); //Main.NewText($"Timer:{Timer}, Radians:{radians}, Velocity:{npc.velocity}."); // 射击(向与NPC移动方向垂直的圈内向量射击)(其实我也不知道我这注释写的什么) Vector2 shootTarget = npc.Center + npc.velocity; // 旋转90°,也就是垂直,是向圆心射击 Shooting(3, npc.Center, shootTarget, 90f, 24f); if (Main.expertMode && Timer % 5 == 0 && Main.netMode != NetmodeID.MultiplayerClient) { Shooting(3, npc.Center, shootTarget, 90f, 10f); } // for模拟一圈,用于显示粒子特效。因为属于特效所以服务器就别掺和了 if (!Main.dedServ) { Vector2 _position = recordedStartRoundPos; for (int _Timer = 0; _Timer <= 360; _Timer += UpgradeOutBeach ? 2 : 1) { float _radians = MathHelper.ToRadians(_Timer); Vector2 _velocity = new Vector2(16f) * _radians.ToRotationVector2(); _position += _velocity; // 生成粒子 Dust d = Dust.NewDustDirect(_position, 4, 4, MyDustId.LightBlueParticle); d.noGravity = true; } } // 转了2.75圈 if (Timer >= 2.75 * (360 / speedMultipiler)) { switch (Main.rand.Next(2)) { case 0: SwitchState((int)NPCState.Move_State2); break; case 1: SwitchState((int)NPCState.Magic_State2); break; } npc.ai[2] = npc.ai[3] = Timer = 0; return; } } else { if (npc.ai[3] >= 240) { switch (Main.rand.Next(2)) { case 0: SwitchState((int)NPCState.Move_State2); break; case 1: SwitchState((int)NPCState.Magic_State2); break; } npc.ai[2] = npc.ai[3] = Timer = 0; return; } } break; } case NPCState.PlayerDead: { npc.TargetClosest(true); Timer++; if (!player.dead && player.active && player.ZoneBeach) { SwitchState((int)NPCState.Break); Timer = 0; } else if (Timer >= 180) { npc.TargetClosest(true); if (player.dead || !player.active || !player.ZoneBeach) { if (Timer <= 195) { npc.alpha -= 255 / 15 + 1; } else { npc.active = false; } } else { SwitchState((int)NPCState.Break); Timer = 0; } } break; } } }