Ejemplo n.º 1
0
 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));
 }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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;
                }
            }
        }
Ejemplo n.º 4
0
 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;
             }
         }
     }
 }
Ejemplo n.º 5
0
        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;
            }
            }
        }