예제 #1
0
        public override bool?CanBeHitByProjectile(NPC npc, Projectile projectile)
        {
            if (!Main.player[projectile.owner].buffImmune[ModContent.BuffType <NullificationCurse>()] && !FargoSoulsWorld.SwarmActive)
            {
                switch (GetVulnerabilityState(npc))
                {
                case 0: if (!projectile.melee)
                    {
                        return(false);
                    }
                    break;

                case 1: if (!projectile.ranged)
                    {
                        return(false);
                    }
                    break;

                case 2: if (!projectile.magic)
                    {
                        return(false);
                    }
                    break;

                case 3: if (!FargoSoulsUtil.IsMinionDamage(projectile))
                    {
                        return(false);
                    }
                    break;

                default: break;
                }
            }

            return(base.CanBeHitByProjectile(npc, projectile));
        }
예제 #2
0
        public override void AI()
        {
            EModeGlobalNPC.championBoss = npc.whoAmI;

            if (npc.localAI[3] == 0) //spawn friends
            {
                npc.TargetClosest(false);

                if (npc.ai[2] == 1)
                {
                    npc.velocity      = Vector2.Zero;
                    npc.noTileCollide = true;
                    npc.noGravity     = true;
                    npc.alpha         = 0;

                    if (FargoSoulsWorld.downedChampions[6] && npc.ai[1] < 120)
                    {
                        npc.ai[1] = 120;
                    }

                    if (npc.ai[1] == 180)
                    {
                        Main.PlaySound(SoundID.Roar, npc.Center, 0);

                        if (Main.netMode != NetmodeID.MultiplayerClient)
                        {
                            int n = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <SpiritChampionHand>(), npc.whoAmI, 0f, npc.whoAmI, -1f, -1f, npc.target);
                            if (n != Main.maxNPCs)
                            {
                                Main.npc[n].velocity.X = Main.rand.NextFloat(-24f, 24f);
                                Main.npc[n].velocity.Y = Main.rand.NextFloat(-24f, 24f);
                                if (Main.netMode == NetmodeID.Server)
                                {
                                    NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n);
                                }
                            }
                            n = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <SpiritChampionHand>(), npc.whoAmI, 0f, npc.whoAmI, -1f, 1f, npc.target);
                            if (n != Main.maxNPCs)
                            {
                                Main.npc[n].velocity.X = Main.rand.NextFloat(-24f, 24f);
                                Main.npc[n].velocity.Y = Main.rand.NextFloat(-24f, 24f);
                                if (Main.netMode == NetmodeID.Server)
                                {
                                    NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n);
                                }
                            }
                            n = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <SpiritChampionHand>(), npc.whoAmI, 0f, npc.whoAmI, 1f, -1f, npc.target);
                            if (n != Main.maxNPCs)
                            {
                                Main.npc[n].velocity.X = Main.rand.NextFloat(-24f, 24f);
                                Main.npc[n].velocity.Y = Main.rand.NextFloat(-24f, 24f);
                                if (Main.netMode == NetmodeID.Server)
                                {
                                    NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n);
                                }
                            }
                            n = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <SpiritChampionHand>(), npc.whoAmI, 0f, npc.whoAmI, 1f, 1f, npc.target);
                            if (n != Main.maxNPCs)
                            {
                                Main.npc[n].velocity.X = Main.rand.NextFloat(-24f, 24f);
                                Main.npc[n].velocity.Y = Main.rand.NextFloat(-24f, 24f);
                                if (Main.netMode == NetmodeID.Server)
                                {
                                    NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n);
                                }
                            }
                        }
                    }

                    if (++npc.ai[1] > 300)
                    {
                        npc.ai[1]      = 0;
                        npc.ai[2]      = 0;
                        npc.ai[3]      = 0;
                        npc.localAI[3] = 1;
                        npc.netUpdate  = true;
                    }
                    return;
                }

                if (npc.ai[3] == 0 && npc.HasValidTarget)
                {
                    npc.ai[3]     = 1;
                    npc.Center    = Main.player[npc.target].Center - Vector2.UnitY * 500;
                    npc.ai[2]     = Main.player[npc.target].Center.Y - npc.height / 2; //fall this distance, accounting for my height
                    npc.netUpdate = true;
                }

                npc.alpha -= 10;
                if (npc.alpha < 0)
                {
                    npc.alpha     = 0;
                    npc.noGravity = false;
                }

                if (npc.Center.Y > npc.ai[2])
                {
                    npc.noTileCollide = false;
                }

                if (++npc.ai[1] > 300 || (npc.velocity.Y == 0 && npc.ai[1] > 30))
                {
                    npc.ai[1] = 0;
                    npc.ai[2] = 1;

                    Main.PlaySound(SoundID.Item, npc.Center, 14);

                    for (int k = -2; k <= 2; k++) //explosions
                    {
                        Vector2 dustPos = npc.Center;
                        int     width   = npc.width / 5;
                        dustPos.X += width * k;
                        dustPos.Y += npc.height / 2;

                        for (int i = 0; i < 20; i++)
                        {
                            int dust = Dust.NewDust(dustPos - new Vector2(16, 16), 32, 32, 31, 0f, 0f, 100, default(Color), 2f);
                            //Main.dust[dust].velocity *= 1.4f;
                        }

                        /*for (int i = 0; i < 20; i++)
                         * {
                         *  int dust = Dust.NewDust(dustPos - new Vector2(16, 16), 32, 32, 6, 0f, 0f, 100, default(Color), 3.5f);
                         *  Main.dust[dust].noGravity = true;
                         *  Main.dust[dust].velocity *= 7f;
                         *  dust = Dust.NewDust(dustPos - new Vector2(16, 16), 32, 32, 6, 0f, 0f, 100, default(Color), 1.5f);
                         *  Main.dust[dust].velocity *= 3f;
                         * }*/

                        float scaleFactor9 = 0.5f;
                        for (int j = 0; j < 4; j++)
                        {
                            int gore = Gore.NewGore(dustPos, default(Vector2), Main.rand.Next(61, 64));
                            Main.gore[gore].velocity *= scaleFactor9;
                            //Main.gore[gore].velocity.X += 1f;
                            //Main.gore[gore].velocity.Y += 1f;
                        }
                    }
                }

                return;
            }

            Player  player = Main.player[npc.target];
            Vector2 targetPos;

            if (npc.HasValidTarget && npc.Distance(player.Center) < 2500 && (Framing.GetTileSafely(player.Center).wall != WallID.None || player.ZoneUndergroundDesert))
            {
                npc.timeLeft = 600;
            }

            npc.dontTakeDamage = false;

            switch ((int)npc.ai[0])
            {
            case -4:     //final float
                npc.dontTakeDamage = true;
                goto case 0;

            case -3:     //final you think you're safe
                npc.dontTakeDamage = true;

                if (npc.localAI[2] == 0)
                {
                    npc.localAI[2] = 1;
                }

                if (!player.active || player.dead || Vector2.Distance(npc.Center, player.Center) > 2500f ||
                    (Framing.GetTileSafely(player.Center).wall == WallID.None && !player.ZoneUndergroundDesert))        //despawn code
                {
                    npc.TargetClosest(false);
                    if (npc.timeLeft > 30)
                    {
                        npc.timeLeft = 30;
                    }

                    npc.noTileCollide = true;
                    npc.noGravity     = true;
                    npc.velocity.Y   += 1f;

                    return;
                }

                targetPos = new Vector2(npc.localAI[0], npc.localAI[1]);
                if (npc.Distance(targetPos) > 25)
                {
                    Movement(targetPos, 0.8f, 24f);
                }

                if (npc.ai[1] == 0)     //respawn dead hands
                {
                    bool[] foundHand = new bool[4];

                    for (int i = 0; i < Main.maxNPCs; i++)
                    {
                        if (Main.npc[i].active && Main.npc[i].type == ModContent.NPCType <SpiritChampionHand>() && Main.npc[i].ai[1] == npc.whoAmI)
                        {
                            if (!foundHand[0])
                            {
                                foundHand[0] = Main.npc[i].ai[2] == -1f && Main.npc[i].ai[3] == -1f;
                            }
                            if (!foundHand[1])
                            {
                                foundHand[1] = Main.npc[i].ai[2] == -1f && Main.npc[i].ai[3] == 1f;
                            }
                            if (!foundHand[2])
                            {
                                foundHand[2] = Main.npc[i].ai[2] == 1f && Main.npc[i].ai[3] == -1f;
                            }
                            if (!foundHand[3])
                            {
                                foundHand[3] = Main.npc[i].ai[2] == 1f && Main.npc[i].ai[3] == 1f;
                            }
                        }
                    }

                    if (Main.netMode != NetmodeID.MultiplayerClient)     //if hands somehow disappear
                    {
                        if (!foundHand[0])
                        {
                            int n = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <SpiritChampionHand>(), npc.whoAmI, 0f, npc.whoAmI, -1f, -1f, npc.target);
                            if (n != Main.maxNPCs)
                            {
                                Main.npc[n].velocity.X = Main.rand.NextFloat(-24f, 24f);
                                Main.npc[n].velocity.Y = Main.rand.NextFloat(-24f, 24f);
                                if (Main.netMode == NetmodeID.Server)
                                {
                                    NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n);
                                }
                            }
                        }
                        if (!foundHand[1])
                        {
                            int n = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <SpiritChampionHand>(), npc.whoAmI, 0f, npc.whoAmI, -1f, 1f, npc.target);
                            if (n != Main.maxNPCs)
                            {
                                Main.npc[n].velocity.X = Main.rand.NextFloat(-24f, 24f);
                                Main.npc[n].velocity.Y = Main.rand.NextFloat(-24f, 24f);
                                if (Main.netMode == NetmodeID.Server)
                                {
                                    NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n);
                                }
                            }
                        }
                        if (!foundHand[2])
                        {
                            int n = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <SpiritChampionHand>(), npc.whoAmI, 0f, npc.whoAmI, 1f, -1f, npc.target);
                            if (n != Main.maxNPCs)
                            {
                                Main.npc[n].velocity.X = Main.rand.NextFloat(-24f, 24f);
                                Main.npc[n].velocity.Y = Main.rand.NextFloat(-24f, 24f);
                                if (Main.netMode == NetmodeID.Server)
                                {
                                    NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n);
                                }
                            }
                        }
                        if (!foundHand[3])
                        {
                            int n = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <SpiritChampionHand>(), npc.whoAmI, 0f, npc.whoAmI, 1f, 1f, npc.target);
                            if (n != Main.maxNPCs)
                            {
                                Main.npc[n].velocity.X = Main.rand.NextFloat(-24f, 24f);
                                Main.npc[n].velocity.Y = Main.rand.NextFloat(-24f, 24f);
                                if (Main.netMode == NetmodeID.Server)
                                {
                                    NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n);
                                }
                            }
                        }
                    }
                }
                else if (npc.ai[1] == 120)
                {
                    Main.PlaySound(SoundID.Roar, npc.Center, 0);

                    for (int i = 0; i < Main.maxNPCs; i++)     //update ai
                    {
                        if (Main.npc[i].active && Main.npc[i].type == ModContent.NPCType <SpiritChampionHand>() && Main.npc[i].ai[1] == npc.whoAmI)
                        {
                            Main.npc[i].ai[0]     = 1f;
                            Main.npc[i].netUpdate = true;
                        }
                    }

                    if (Main.netMode != NetmodeID.MultiplayerClient)     //spawn super hand
                    {
                        int n2 = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <SpiritChampionHand>(), npc.whoAmI, 3f, npc.whoAmI, 1f, 1f, npc.target);
                        if (n2 != Main.maxNPCs)
                        {
                            Main.npc[n2].velocity.X = Main.rand.NextFloat(-24f, 24f);
                            Main.npc[n2].velocity.Y = Main.rand.NextFloat(-24f, 24f);
                            if (Main.netMode == NetmodeID.Server)
                            {
                                NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n2);
                            }
                        }
                    }
                }

                if (++npc.ai[2] > 85)     //bone spray
                {
                    npc.ai[2] = 0;

                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        Main.PlaySound(SoundID.Item2, npc.Center);

                        for (int i = 0; i < 12; i++)
                        {
                            Projectile.NewProjectile(npc.position.X + Main.rand.Next(npc.width), npc.position.Y + Main.rand.Next(npc.height),
                                                     Main.rand.NextFloat(-8f, 8f), Main.rand.NextFloat(-8f, 8f), ModContent.ProjectileType <SpiritCrossBone>(), npc.damage / 4, 0f, Main.myPlayer);
                        }
                    }
                }

                if (++npc.ai[3] > 110)
                {
                    npc.ai[3] = 0;
                    if (Main.netMode != NetmodeID.MultiplayerClient)     //sandnado
                    {
                        Vector2 target = player.Center;
                        target.Y -= 100;
                        Projectile.NewProjectile(target, Vector2.Zero, ProjectileID.SandnadoHostileMark, 0, 0f, Main.myPlayer);

                        int     length = (int)npc.Distance(target) / 10;
                        Vector2 offset = npc.DirectionTo(target) * 10f;
                        for (int i = 0; i < length; i++)     //dust warning line for sandnado
                        {
                            int d = Dust.NewDust(npc.Center + offset * i, 0, 0, 269, 0f, 0f, 0, new Color());
                            Main.dust[d].noLight = true;
                            Main.dust[d].scale   = 1.25f;
                        }
                    }
                }

                if (++npc.ai[1] > 600)
                {
                    npc.dontTakeDamage = false;
                    npc.netUpdate      = true;
                    npc.ai[0]          = 0;
                    npc.ai[1]          = 0;
                    npc.ai[2]          = 0;
                    npc.ai[3]          = 0;
                    npc.localAI[3]     = 2; //can die now
                }
                break;

            case -1:
                targetPos = new Vector2(npc.localAI[0], npc.localAI[1]);
                if (npc.Distance(targetPos) > 25)
                {
                    Movement(targetPos, 0.8f, 24f);
                }

                if (++npc.ai[1] > 360)
                {
                    npc.TargetClosest();
                    npc.ai[0]     = 4;
                    npc.ai[1]     = 0;
                    npc.ai[2]     = 0;
                    npc.ai[3]     = 0;
                    npc.netUpdate = true;

                    if (npc.Hitbox.Intersects(player.Hitbox))
                    {
                        player.velocity.X = player.Center.X < npc.Center.X ? -15f : 15f;
                        player.velocity.Y = -10f;
                        Main.PlaySound(SoundID.Roar, npc.Center, 0);
                    }
                }
                break;

            case 0:                                                                                              //float to player
                if (!player.active || player.dead || Vector2.Distance(npc.Center, player.Center) > 2500f ||
                    (Framing.GetTileSafely(player.Center).wall == WallID.None && !player.ZoneUndergroundDesert)) //despawn code
                {
                    npc.TargetClosest(false);
                    if (npc.timeLeft > 30)
                    {
                        npc.timeLeft = 30;
                    }

                    npc.noTileCollide = true;
                    npc.noGravity     = true;
                    npc.velocity.Y   += 1f;

                    return;
                }

                if (npc.ai[1] == 0)
                {
                    targetPos    = player.Center;
                    npc.velocity = (targetPos - npc.Center) / 75;

                    npc.localAI[0] = targetPos.X;
                    npc.localAI[1] = targetPos.Y;
                }

                if (++npc.ai[1] > 75)
                {
                    npc.TargetClosest();
                    npc.ai[0]++;
                    npc.ai[1]     = 0;
                    npc.ai[2]     = 0;
                    npc.ai[3]     = 0;
                    npc.netUpdate = true;
                }
                break;

            case 1:     //cross bone/sandnado
                if (npc.localAI[2] == 0)
                {
                    npc.localAI[2] = 1;
                }

                targetPos = new Vector2(npc.localAI[0], npc.localAI[1]);
                if (npc.Distance(targetPos) > 25)
                {
                    Movement(targetPos, 0.8f, 24f);
                }

                if (++npc.ai[2] > 45)
                {
                    npc.ai[2] = 0;

                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        if (npc.ai[1] < 180)     //cross bones
                        {
                            Main.PlaySound(SoundID.Item2, npc.Center);

                            for (int i = 0; i < 12; i++)
                            {
                                Projectile.NewProjectile(npc.position.X + Main.rand.Next(npc.width), npc.position.Y + Main.rand.Next(npc.height),
                                                         Main.rand.NextFloat(-8f, 8f), Main.rand.NextFloat(-8f, 8f), ModContent.ProjectileType <SpiritCrossBone>(), npc.damage / 4, 0f, Main.myPlayer);
                            }
                        }
                        else     //sandnado
                        {
                            npc.GetGlobalNPC <EModeGlobalNPC>().masoBool[0] = !npc.GetGlobalNPC <EModeGlobalNPC>().masoBool[0];

                            Vector2 target = player.Center;
                            if (npc.GetGlobalNPC <EModeGlobalNPC>().masoBool[0] && npc.life < npc.lifeMax * 0.66)
                            {
                                target += player.velocity * 30f;     //alternate between predictive and direct aim
                            }
                            target.Y -= 100;
                            Projectile.NewProjectile(target, Vector2.Zero, ProjectileID.SandnadoHostileMark, 0, 0f, Main.myPlayer);

                            int     length = (int)npc.Distance(target) / 10;
                            Vector2 offset = npc.DirectionTo(target) * 10f;
                            for (int i = 0; i < length; i++)     //dust warning line for sandnado
                            {
                                int d = Dust.NewDust(npc.Center + offset * i, 0, 0, 269, 0f, 0f, 0, new Color());
                                Main.dust[d].noLight = true;
                                Main.dust[d].scale   = 1.25f;
                            }
                        }
                    }
                }

                if (++npc.ai[1] > 400)
                {
                    npc.TargetClosest();
                    npc.ai[0]++;
                    npc.ai[1]     = 0;
                    npc.ai[2]     = 0;
                    npc.ai[3]     = 0;
                    npc.netUpdate = true;
                }
                break;

            case 2:
                goto case 0;

            case 3:     //grab
                targetPos = new Vector2(npc.localAI[0], npc.localAI[1]);
                if (npc.Distance(targetPos) > 25)
                {
                    Movement(targetPos, 0.8f, 24f);
                }

                if (++npc.ai[2] == 30)
                {
                    for (int i = 0; i < Main.maxNPCs; i++)
                    {
                        if (Main.npc[i].active && Main.npc[i].type == ModContent.NPCType <SpiritChampionHand>() && Main.npc[i].ai[1] == npc.whoAmI)
                        {
                            Main.npc[i].ai[0]     = 1f;
                            Main.npc[i].netUpdate = true;
                        }
                    }
                }

                if (npc.life < npc.lifeMax * 0.66)
                {
                    if (++npc.ai[3] > 55)     //homing spectre bolts
                    {
                        npc.ai[3] = 0;
                        if (Main.netMode != NetmodeID.MultiplayerClient)
                        {
                            const int max = 5;
                            for (int i = 0; i < max; i++)
                            {
                                Vector2 speed = Main.rand.NextFloat(1, 2) * Vector2.UnitX.RotatedByRandom(Math.PI * 2);
                                float   ai1   = 60 + Main.rand.Next(30);
                                Projectile.NewProjectile(npc.Center, speed, ModContent.ProjectileType <SpiritSpirit>(),
                                                         npc.damage / 4, 0f, Main.myPlayer, npc.whoAmI, ai1);
                            }
                        }
                    }
                }

                if (++npc.ai[1] > 360)
                {
                    npc.TargetClosest();
                    npc.ai[0]++;
                    npc.ai[1]     = 0;
                    npc.ai[2]     = 0;
                    npc.ai[3]     = 0;
                    npc.netUpdate = true;
                }
                break;

            case 4:
                goto case 0;

            case 5:     //swords
                targetPos = new Vector2(npc.localAI[0], npc.localAI[1]);
                if (npc.Distance(targetPos) > 25)
                {
                    Movement(targetPos, 0.8f, 24f);
                }

                if (++npc.ai[2] > 80)
                {
                    npc.ai[2] = 0;

                    Main.PlaySound(SoundID.Item92, npc.Center);

                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        for (int i = 0; i < 15; i++)     //sword burst
                        {
                            float   speed    = Main.rand.NextFloat(4f, 8f);
                            Vector2 velocity = speed * Vector2.UnitX.RotatedBy(Main.rand.NextDouble() * 2 * Math.PI);
                            float   ai1      = speed / Main.rand.NextFloat(60f, 120f);
                            Projectile.NewProjectile(npc.Center, velocity, ModContent.ProjectileType <SpiritSword>(), npc.damage / 4, 0f, Main.myPlayer, 0f, ai1);
                        }

                        if (npc.life < npc.lifeMax * 0.66)
                        {
                            const int max = 12;     //hand ring
                            for (int i = 0; i < max; i++)
                            {
                                Vector2 vel = npc.DirectionTo(player.Center).RotatedBy(Math.PI * 2 / max * i);
                                float   ai0 = 1.04f;
                                Projectile.NewProjectile(npc.Center, vel, ModContent.ProjectileType <SpiritHand>(), npc.damage / 4, 0f, Main.myPlayer, ai0);
                            }
                        }
                    }
                }

                if (++npc.ai[1] > 300)
                {
                    npc.TargetClosest();
                    npc.ai[0]++;
                    npc.ai[1]     = 0;
                    npc.ai[2]     = 0;
                    npc.ai[3]     = 0;
                    npc.netUpdate = true;
                }
                break;

            case 6:
                goto case 0;

            case 7:     //skip this number, staying on even number allows hands to remain drawn close
                npc.ai[0]++;
                break;

            case 8:     //shadow hands, reflect, mummy spirits
            {
                targetPos = new Vector2(npc.localAI[0], npc.localAI[1]);
                if (npc.Distance(targetPos) > 25)
                {
                    Movement(targetPos, 0.8f, 24f);
                }

                const float distance = 150;

                for (int i = 0; i < 20; i++)
                {
                    Vector2 offset = new Vector2();
                    double  angle  = Main.rand.NextDouble() * 2d * Math.PI;
                    offset.X += (float)(Math.Sin(angle) * distance);
                    offset.Y += (float)(Math.Cos(angle) * distance);
                    Dust dust = Main.dust[Dust.NewDust(
                                              npc.Center + offset - new Vector2(4, 4), 0, 0,
                                              87, 0, 0, 100, Color.White, 1f
                                              )];
                    dust.velocity = npc.velocity;
                    //if (Main.rand.NextBool(3)) dust.velocity += Vector2.Normalize(offset) * -5f;
                    dust.noGravity = true;
                }

                if (npc.ai[1] > 60)
                {
                    Main.projectile.Where(x => x.active && x.friendly && !FargoSoulsUtil.IsMinionDamage(x, false)).ToList().ForEach(x =>         //reflect projectiles
                        {
                            if (Vector2.Distance(x.Center, npc.Center) <= distance)
                            {
                                for (int i = 0; i < 5; i++)
                                {
                                    int dustId = Dust.NewDust(x.position, x.width, x.height, 87,
                                                              x.velocity.X * 0.2f, x.velocity.Y * 0.2f, 100, default(Color), 1.5f);
                                    Main.dust[dustId].noGravity = true;
                                }

                                // Set ownership
                                x.hostile  = true;
                                x.friendly = false;
                                x.owner    = Main.myPlayer;
                                x.damage  /= 4;

                                // Turn around
                                x.velocity *= -1f;

                                // Flip sprite
                                if (x.Center.X > npc.Center.X * 0.5f)
                                {
                                    x.direction       = 1;
                                    x.spriteDirection = 1;
                                }
                                else
                                {
                                    x.direction       = -1;
                                    x.spriteDirection = -1;
                                }

                                //x.netUpdate = true;

                                if (x.owner == Main.myPlayer)
                                {
                                    Projectile.NewProjectile(x.Center, Vector2.Zero, ModContent.ProjectileType <Projectiles.Souls.IronParry>(), 0, 0f, Main.myPlayer);
                                }
                            }
                        });
                }

                if (npc.ai[1] == 0)
                {
                    Main.PlaySound(SoundID.Roar, npc.Center, 0);
                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        Projectile.NewProjectile(npc.Center, Vector2.Zero, ModContent.ProjectileType <Projectiles.GlowRing>(), 0, 0f, Main.myPlayer, npc.whoAmI, -6);
                    }
                }

                if (++npc.ai[3] > 10)         //spirits
                {
                    npc.ai[3] = 0;

                    Main.PlaySound(SoundID.Item8, npc.Center);

                    if (Main.netMode != NetmodeID.MultiplayerClient)         //vanilla code from desert spirits idfk
                    {
                        Point   tileCoordinates1 = npc.Center.ToTileCoordinates();
                        Point   tileCoordinates2 = Main.player[npc.target].Center.ToTileCoordinates();
                        Vector2 vector2          = Main.player[npc.target].Center - npc.Center;
                        int     num1             = 6;
                        int     num2             = 6;
                        int     num3             = 0;
                        int     num4             = 2;
                        int     num5             = 0;
                        bool    flag1            = false;
                        if (vector2.Length() > 2000)
                        {
                            flag1 = true;
                        }
                        while (!flag1 && num5 < 50)
                        {
                            ++num5;
                            int index1 = Main.rand.Next(tileCoordinates2.X - num1, tileCoordinates2.X + num1 + 1);
                            int index2 = Main.rand.Next(tileCoordinates2.Y - num1, tileCoordinates2.Y + num1 + 1);
                            if ((index2 < tileCoordinates2.Y - num3 || index2 > tileCoordinates2.Y + num3 || (index1 < tileCoordinates2.X - num3 || index1 > tileCoordinates2.X + num3)) && (index2 < tileCoordinates1.Y - num2 || index2 > tileCoordinates1.Y + num2 || (index1 < tileCoordinates1.X - num2 || index1 > tileCoordinates1.X + num2)) && !Main.tile[index1, index2].nactive())
                            {
                                bool flag2 = true;
                                if (flag2 && Main.tile[index1, index2].lava())
                                {
                                    flag2 = false;
                                }
                                if (flag2 && Collision.SolidTiles(index1 - num4, index1 + num4, index2 - num4, index2 + num4))
                                {
                                    flag2 = false;
                                }
                                if (flag2)
                                {
                                    Projectile.NewProjectile(index1 * 16 + 8, index2 * 16 + 8, 0, 0f,
                                                             ProjectileID.DesertDjinnCurse, 0, 1f, Main.myPlayer, npc.target, 0f);
                                    break;
                                }
                            }
                        }
                    }
                }

                if (++npc.ai[2] > 70)         //hands
                {
                    npc.ai[2] = 0;

                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        for (int i = 0; i < 4; i++)
                        {
                            Vector2 vel = npc.DirectionTo(player.Center).RotatedBy(Math.PI / 6 * (Main.rand.NextDouble() - 0.5));
                            float   ai0 = Main.rand.NextFloat(1.04f, 1.06f);
                            float   ai1 = Main.rand.NextFloat(0.025f);
                            Projectile.NewProjectile(npc.Center, vel, ModContent.ProjectileType <SpiritHand>(), npc.damage / 4, 0f, Main.myPlayer, ai0, ai1);
                        }
                    }
                }

                if (npc.ai[1] % 30 == 0 && Main.netMode != NetmodeID.MultiplayerClient && npc.life < npc.lifeMax * 0.66)
                {
                    Main.PlaySound(SoundID.Item2, npc.Center);
                    for (int i = 0; i < 3; i++)
                    {
                        Projectile.NewProjectile(npc.position.X + Main.rand.Next(npc.width), npc.position.Y + Main.rand.Next(npc.height),
                                                 Main.rand.NextFloat(-1f, 1f), Main.rand.NextFloat(-8f, 0f), ModContent.ProjectileType <SpiritCrossBone>(), npc.damage / 4, 0f, Main.myPlayer);
                        Projectile.NewProjectile(npc.position.X + Main.rand.Next(npc.width), npc.position.Y + Main.rand.Next(npc.height),
                                                 Main.rand.NextFloat(-1f, 1f), Main.rand.NextFloat(8f, 0f), ModContent.ProjectileType <SpiritCrossBoneReverse>(), npc.damage / 4, 0f, Main.myPlayer);
                    }
                }

                if (++npc.ai[1] > 360)
                {
                    npc.TargetClosest();
                    npc.ai[0]++;
                    npc.ai[1]     = 0;
                    npc.ai[2]     = 0;
                    npc.ai[3]     = 0;
                    npc.netUpdate = true;
                }
            }
            break;

            case 9:     //skip this number, get back to usual behaviour
                npc.ai[0]++;
                break;

            /*case 10:
             *  goto case 0;*/

            default:
                npc.ai[0] = 0;
                goto case 0;
            }

            if (npc.localAI[2] != 0 && FargoSoulsWorld.EternityMode) //aura
            {
                const float auraDistance = 1200;
                float       range        = npc.Distance(player.Center);
                if (range > auraDistance && range < 3000)
                {
                    if (++npc.localAI[2] > 60)
                    {
                        npc.localAI[2] = 1;
                        npc.netUpdate  = true;

                        Main.PlaySound(SoundID.Roar, npc.Center, 0);

                        if (Main.netMode != NetmodeID.MultiplayerClient) //spawn super hand
                        {
                            int n2 = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <SpiritChampionHand>(), npc.whoAmI, 4f, npc.whoAmI, 1f, 1f, npc.target);
                            if (n2 != Main.maxNPCs)
                            {
                                Main.npc[n2].velocity.X = Main.rand.NextFloat(-24f, 24f);
                                Main.npc[n2].velocity.Y = Main.rand.NextFloat(-24f, 24f);
                                if (Main.netMode == NetmodeID.Server)
                                {
                                    NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n2);
                                }
                            }
                        }
                    }
                }

                for (int i = 0; i < 20; i++) //dust
                {
                    int d = Dust.NewDust(npc.Center + auraDistance * Vector2.UnitX.RotatedBy(Math.PI * 2 * Main.rand.NextDouble()), 0, 0, 87);
                    Main.dust[d].velocity  = npc.velocity;
                    Main.dust[d].noGravity = true;
                    Main.dust[d].scale++;
                }
            }
        }
예제 #3
0
        public override void AI()
        {
            if (projectile.localAI[1] == 0)
            {
                projectile.localAI[1] = Main.rand.NextBool() ? -1 : 1;
                projectile.timeLeft   = (int)projectile.ai[1];
            }

            NPC mutant = Main.npc[(int)projectile.ai[0]];

            if (mutant.active && mutant.type == mod.NPCType("MutantBoss"))
            {
                projectile.Center = mutant.Center;
                direction         = mutant.direction;

                if (mutant.ai[0] == 4 || mutant.ai[0] == 13 || mutant.ai[0] == 21)
                {
                    projectile.rotation += (float)Math.PI / 6.85f * projectile.localAI[1];

                    if (++projectile.localAI[0] > 8)
                    {
                        projectile.localAI[0] = 0;
                        if (Main.netMode != NetmodeID.MultiplayerClient)
                        {
                            Vector2 speed = Vector2.UnitY.RotatedByRandom(Math.PI / 2) * Main.rand.NextFloat(6f, 9f);
                            if (mutant.Center.Y < Main.player[mutant.target].Center.Y)
                            {
                                speed *= -1f;
                            }
                            float ai1 = projectile.timeLeft + Main.rand.Next(projectile.timeLeft / 2);
                            Projectile.NewProjectile(projectile.position + Main.rand.NextVector2Square(0f, projectile.width),
                                                     speed, ModContent.ProjectileType <MutantEyeHoming>(), projectile.damage, 0f, projectile.owner, mutant.target, ai1);
                        }
                    }

                    if (projectile.timeLeft % 20 == 0)
                    {
                        Main.PlaySound(SoundID.Item1, projectile.Center);
                    }

                    if (mutant.ai[0] == 13)
                    {
                        predictive = true;
                    }

                    projectile.alpha = 0;

                    if (FargoSoulsWorld.MasochistModeReal)
                    {
                        Main.projectile.Where(x => x.active && x.friendly && !FargoSoulsUtil.IsMinionDamage(x, false)).ToList().ForEach(x => //reflect projectiles
                        {
                            if (Vector2.Distance(x.Center, mutant.Center) <= projectile.width / 2)
                            {
                                for (int i = 0; i < 5; i++)
                                {
                                    int dustId = Dust.NewDust(x.position, x.width, x.height, 87,
                                                              x.velocity.X * 0.2f, x.velocity.Y * 0.2f, 100, default(Color), 1.5f);
                                    Main.dust[dustId].noGravity = true;
                                }

                                // Set ownership
                                x.hostile  = true;
                                x.friendly = false;
                                x.owner    = Main.myPlayer;
                                x.damage  /= 4;

                                // Turn around
                                x.velocity *= -1f;

                                // Flip sprite
                                if (x.Center.X > mutant.Center.X)
                                {
                                    x.direction       = 1;
                                    x.spriteDirection = 1;
                                }
                                else
                                {
                                    x.direction       = -1;
                                    x.spriteDirection = -1;
                                }

                                //x.netUpdate = true;

                                if (x.owner == Main.myPlayer)
                                {
                                    Projectile.NewProjectile(x.Center, Vector2.Zero, ModContent.ProjectileType <Souls.IronParry>(), 0, 0f, Main.myPlayer);
                                }
                            }
                        });
                    }
                }
                else
                {
                    projectile.alpha = 255;
                }
            }
            else
            {
                projectile.Kill();
                return;
            }
        }
        public override void AI()
        {
            Player      player    = Main.player[projectile.owner];
            FargoPlayer modPlayer = player.GetModPlayer <FargoPlayer>();

            projectile.netUpdate = true;

            if (player.whoAmI == Main.myPlayer && (player.dead || !(modPlayer.ShadowEnchant || modPlayer.TerrariaSoul) || !player.GetToggleValue("Shadow")))
            {
                modPlayer.ShadowEnchant = false;
                projectile.Kill();
                return;
            }

            // CD
            if (projectile.ai[0] > 0)
            {
                projectile.ai[0]--;

                //dusts indicate its back
                if (projectile.ai[0] == 0)
                {
                    const int num226 = 18;
                    for (int num227 = 0; num227 < num226; num227++)
                    {
                        Vector2 vector6 = Vector2.UnitX.RotatedBy(projectile.rotation) * 6f;
                        vector6 = vector6.RotatedBy(((num227 - (num226 / 2 - 1)) * 6.28318548f / num226), default(Vector2)) + projectile.Center;
                        Vector2 vector7 = vector6 - projectile.Center;
                        int     num228  = Dust.NewDust(vector6 + vector7, 0, 0, DustID.Shadowflame, 0f, 0f, 0, default(Color), 2f);
                        Main.dust[num228].noGravity = true;
                        Main.dust[num228].velocity  = vector7;
                    }
                }
            }

            float num395 = Main.mouseTextColor / 200f - 0.35f;

            num395          *= 0.2f;
            projectile.scale = num395 + 0.95f;

            if (projectile.owner == Main.myPlayer)
            {
                //rotation mumbo jumbo
                float distanceFromPlayer = 250;

                Lighting.AddLight(projectile.Center, 0.1f, 0.4f, 0.2f);

                projectile.position    = player.Center + new Vector2(distanceFromPlayer, 0f).RotatedBy(projectile.ai[1]);
                projectile.position.X -= projectile.width / 2;
                projectile.position.Y -= projectile.height / 2;
                float rotation = (float)Math.PI / 120;
                projectile.ai[1] -= rotation;
                if (projectile.ai[1] > (float)Math.PI)
                {
                    projectile.ai[1]    -= 2f * (float)Math.PI;
                    projectile.netUpdate = true;
                }
                projectile.rotation = projectile.ai[1] + (float)Math.PI / 2f;


                //wait for CD
                if (projectile.ai[0] != 0f)
                {
                    return;
                }

                //detect being hit
                foreach (Projectile proj in Main.projectile.Where(proj => proj.active && proj.friendly && !proj.hostile && proj.owner == projectile.owner && proj.damage > 0 &&
                                                                  !FargoSoulsUtil.IsMinionDamage(proj, false) && proj.type != ModContent.ProjectileType <ShadowBall>() && proj.Colliding(proj.Hitbox, projectile.Hitbox)))
                {
                    int numBalls = 5;
                    int dmg      = 25;

                    if (modPlayer.AncientShadowEnchant)
                    {
                        numBalls = 10;
                        dmg      = 50;
                    }

                    FargoSoulsUtil.XWay(numBalls, projectile.Center, ModContent.ProjectileType <ShadowBall>(), 6, modPlayer.HighestDamageTypeScaling(dmg), 0);

                    if (FargoSoulsUtil.CanDeleteProjectile(proj))
                    {
                        proj.Kill();
                    }

                    projectile.ai[0] = 300;

                    break;
                }
            }
        }
예제 #5
0
        public override void OnHitByProjectile(NPC npc, Projectile projectile, int damage, float knockback, bool crit)
        {
            base.OnHitByProjectile(npc, projectile, damage, knockback, crit);

            IncrementDamageCounters(projectile.melee, projectile.ranged, projectile.magic, FargoSoulsUtil.IsMinionDamage(projectile), damage);
        }