Esempio n. 1
0
        public override bool?CanBeHitByProjectile(NPC npc, Projectile projectile)
        {
            if (npc.ai[3] == -1f && FargoSoulsUtil.IsSummonDamage(projectile, includeWhips: false))
            {
                return(false);
            }

            return(base.CanBeHitByProjectile(npc, projectile));
        }
Esempio n. 2
0
        public override void OnHitByProjectile(NPC npc, Projectile projectile, int damage, float knockback, bool crit)
        {
            base.OnHitByProjectile(npc, projectile, damage, knockback, crit);

            if (projectile.DamageType == DamageClass.Melee || projectile.DamageType == DamageClass.Throwing)
            {
                MeleeDamageCounter += damage;
            }
            if (projectile.DamageType == DamageClass.Ranged)
            {
                RangedDamageCounter += damage;
            }
            if (projectile.DamageType == DamageClass.Magic)
            {
                MagicDamageCounter += damage;
            }
            if (FargoSoulsUtil.IsSummonDamage(projectile))
            {
                MinionDamageCounter += damage;
            }
        }
Esempio n. 3
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.DamageType != DamageClass.Melee)
                    {
                        return(false);
                    }
                    break;

                case 1: if (projectile.DamageType != DamageClass.Ranged)
                    {
                        return(false);
                    }
                    break;

                case 2: if (projectile.DamageType != DamageClass.Magic)
                    {
                        return(false);
                    }
                    break;

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

                default: break;
                }
            }

            return(base.CanBeHitByProjectile(npc, projectile));
        }
        public override void AI()
        {
            const int   time      = 1800;
            const int   maxScale  = 3;
            const float suckRange = 150;

            void Suck()
            {
                foreach (Projectile p in Main.projectile.Where(p => p.active && p.friendly && p.Distance(Projectile.Center) < suckRange && !FargoSoulsUtil.IsSummonDamage(p) && FargoSoulsUtil.CanDeleteProjectile(p) && p.type != ModContent.ProjectileType <Minions.LunarCultistLightningArc>()))
                {
                    //suck in nearby friendly projs
                    p.velocity  = p.DirectionTo(Projectile.Center) * p.velocity.Length();
                    p.velocity *= 1.015f;

                    //kill ones that actually fall in and retaliate
                    if (Main.netMode != NetmodeID.MultiplayerClient && Projectile.Colliding(Projectile.Hitbox, p.Hitbox))
                    {
                        Player player = Main.player[p.owner];
                        if (player.active && !player.dead && !player.ghost && suck <= 0)
                        {
                            suck = 6;

                            Vector2 dir    = Projectile.DirectionTo(player.Center).RotatedByRandom(MathHelper.ToRadians(10));
                            float   ai1New = (Main.rand.NextBool()) ? 1 : -1; //randomize starting direction
                            Vector2 vel    = Vector2.Normalize(dir) * 6f;
                            Projectile.NewProjectile(Terraria.Entity.InheritSource(Projectile), Projectile.Center, vel * 6, ModContent.ProjectileType <Champions.CosmosLightning>(),
                                                     Projectile.damage, 0, Main.myPlayer, dir.ToRotation(), ai1New);
                        }
                        p.Kill();
                    }
                }
            };

            if (suck > 0)
            {
                suck--;
            }

            NPC npc = FargoSoulsUtil.NPCExists(Projectile.ai[1], NPCID.MoonLordCore);

            if (npc != null)
            {
                Projectile.localAI[0]++;

                const int orbitTime = 180;

                Vector2 offset;
                offset.X = 300f * (float)Math.Sin(Math.PI * 2 / (orbitTime * 2) * Projectile.localAI[0]);
                offset.Y = 150f * (float)Math.Sin(Math.PI * 2 / orbitTime * Projectile.localAI[0]);

                Projectile.Center = npc.Center + offset;

                //if (Projectile.localAI[1] < 120)
                //{
                //    float num1 = 0.5f;
                //    for (int i = 0; i < 5; ++i)
                //    {
                //        if (Main.rand.NextFloat() >= num1)
                //        {
                //            float f = Main.rand.NextFloat() * 6.283185f;
                //            float num2 = Main.rand.NextFloat();
                //            Dust dust = Dust.NewDustPerfect(Projectile.Center + f.ToRotationVector2() * (110 + 600 * num2), 229, (f - 3.141593f).ToRotationVector2() * (14 + 8 * num2), 0, default, 1f);
                //            dust.scale = 0.9f;
                //            dust.fadeIn = 1.15f + num2 * 0.3f;
                //            //dust.color = new Color(1f, 1f, 1f, num1) * (1f - num1);
                //            dust.noGravity = true;
                //            //dust.noLight = true;
                //        }
                //    }
                //}

                if (npc.GetEModeNPCMod <MoonLordCore>().VulnerabilityState != 1 && Projectile.timeLeft > 60)
                {
                    Projectile.timeLeft = 60;
                }
            }
            else
            {
                Projectile.Kill();
                return;
            }

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

            Projectile.localAI[1]++;
            if (Projectile.localAI[1] <= 50)
            {
                if (Main.rand.NextBool(4))
                {
                    Vector2 spinningpoint = Vector2.UnitY.RotatedByRandom(6.28318548202515);
                    Dust    dust          = Main.dust[Dust.NewDust(Projectile.Center - spinningpoint * 30f, 0, 0, 229, 0.0f, 0.0f, 0, new Color(), 1f)];
                    dust.noGravity = true;
                    dust.position  = Projectile.Center - spinningpoint * Main.rand.Next(10, 21);
                    dust.velocity  = spinningpoint.RotatedBy(1.57079637050629, new Vector2()) * 4f;
                    dust.scale     = 0.5f + Main.rand.NextFloat();
                    dust.fadeIn    = 0.5f;
                }
                if (Main.rand.NextBool(4))
                {
                    Vector2 spinningpoint = Vector2.UnitY.RotatedByRandom(6.28318548202515);
                    Dust    dust          = Main.dust[Dust.NewDust(Projectile.Center - spinningpoint * 30f, 0, 0, 240, 0.0f, 0.0f, 0, new Color(), 1f)];
                    dust.noGravity = true;
                    dust.position  = Projectile.Center - spinningpoint * 30f;
                    dust.velocity  = spinningpoint.RotatedBy(-1.57079637050629, new Vector2()) * 2f;
                    dust.scale     = 0.5f + Main.rand.NextFloat();
                    dust.fadeIn    = 0.5f;
                }
            }
            else if (Projectile.localAI[1] <= 90)
            {
                Projectile.scale    = (Projectile.localAI[1] - 50) / 40 * maxScale;
                Projectile.alpha    = 255 - (int)(255 * Projectile.scale / maxScale);
                Projectile.rotation = Projectile.rotation - 0.1570796f;
                if (Main.rand.NextBool())
                {
                    Vector2 spinningpoint = Vector2.UnitY.RotatedByRandom(6.28318548202515) * Projectile.scale;
                    Dust    dust          = Main.dust[Dust.NewDust(Projectile.Center - spinningpoint * 30f, 0, 0, 229, 0.0f, 0.0f, 0, new Color(), 1f)];
                    dust.noGravity  = true;
                    dust.position   = Projectile.Center - spinningpoint * Main.rand.Next(10, 21);
                    dust.velocity   = spinningpoint.RotatedBy(1.57079637050629, new Vector2()) * 6f;
                    dust.scale      = 0.5f + Main.rand.NextFloat();
                    dust.fadeIn     = 0.5f;
                    dust.customData = Projectile.Center;
                }
                if (Main.rand.NextBool())
                {
                    Vector2 spinningpoint = Vector2.UnitY.RotatedByRandom(6.28318548202515) * Projectile.scale;
                    Dust    dust          = Main.dust[Dust.NewDust(Projectile.Center - spinningpoint * 30f, 0, 0, 240, 0.0f, 0.0f, 0, new Color(), 1f)];
                    dust.noGravity  = true;
                    dust.position   = Projectile.Center - spinningpoint * 30f;
                    dust.velocity   = spinningpoint.RotatedBy(-1.57079637050629, new Vector2()) * 3f;
                    dust.scale      = 0.5f + Main.rand.NextFloat();
                    dust.fadeIn     = 0.5f;
                    dust.customData = Projectile.Center;
                }

                Suck();
            }
            else if (Projectile.localAI[1] <= 90 + time)
            {
                Projectile.velocity *= 0.9f;

                Projectile.scale    = maxScale;
                Projectile.alpha    = 0;
                Projectile.rotation = Projectile.rotation - (float)Math.PI / 60f;
                if (Main.rand.NextBool())
                {
                    Vector2 spinningpoint = Vector2.UnitY.RotatedByRandom(6.28318548202515) * Projectile.scale;
                    Dust    dust          = Main.dust[Dust.NewDust(Projectile.Center - spinningpoint * 30f, 0, 0, 229, 0.0f, 0.0f, 0, new Color(), 1f)];
                    dust.noGravity  = true;
                    dust.position   = Projectile.Center - spinningpoint * Main.rand.Next(10, 21);
                    dust.velocity   = spinningpoint.RotatedBy(1.57079637050629, new Vector2()) * 6f;
                    dust.scale      = 0.5f + Main.rand.NextFloat();
                    dust.fadeIn     = 0.5f;
                    dust.customData = Projectile.Center;
                }
                else
                {
                    Vector2 spinningpoint = Vector2.UnitY.RotatedByRandom(6.28318548202515) * Projectile.scale;
                    Dust    dust          = Main.dust[Dust.NewDust(Projectile.Center - spinningpoint * 30f, 0, 0, 240, 0.0f, 0.0f, 0, new Color(), 1f)];
                    dust.noGravity  = true;
                    dust.position   = Projectile.Center - spinningpoint * 30f;
                    dust.velocity   = spinningpoint.RotatedBy(-1.57079637050629, new Vector2()) * 3f;
                    dust.scale      = 0.5f + Main.rand.NextFloat();
                    dust.fadeIn     = 0.5f;
                    dust.customData = Projectile.Center;
                }

                Suck();
            }
            else
            {
                Projectile.scale    = (float)(1.0 - (Projectile.localAI[1] - time) / 60.0) * maxScale;
                Projectile.alpha    = 255 - (int)(255 * Projectile.scale / maxScale);
                Projectile.rotation = Projectile.rotation - (float)Math.PI / 30f;
                if (Projectile.alpha >= 255)
                {
                    Projectile.Kill();
                }
                for (int index = 0; index < 2; ++index)
                {
                    switch (Main.rand.Next(3))
                    {
                    case 0:
                        Vector2 spinningpoint1 = Vector2.UnitY.RotatedByRandom(6.28318548202515) * Projectile.scale;
                        Dust    dust1          = Main.dust[Dust.NewDust(Projectile.Center - spinningpoint1 * 30f, 0, 0, 229, 0.0f, 0.0f, 0, new Color(), 1f)];
                        dust1.noGravity  = true;
                        dust1.position   = Projectile.Center - spinningpoint1 * Main.rand.Next(10, 21);
                        dust1.velocity   = spinningpoint1.RotatedBy(1.57079637050629, new Vector2()) * 6f;
                        dust1.scale      = 0.5f + Main.rand.NextFloat();
                        dust1.fadeIn     = 0.5f;
                        dust1.customData = Projectile.Center;
                        break;

                    case 1:
                        Vector2 spinningpoint2 = Vector2.UnitY.RotatedByRandom(6.28318548202515) * Projectile.scale;
                        Dust    dust2          = Main.dust[Dust.NewDust(Projectile.Center - spinningpoint2 * 30f, 0, 0, 240, 0.0f, 0.0f, 0, new Color(), 1f)];
                        dust2.noGravity  = true;
                        dust2.position   = Projectile.Center - spinningpoint2 * 30f;
                        dust2.velocity   = spinningpoint2.RotatedBy(-1.57079637050629, new Vector2()) * 3f;
                        dust2.scale      = 0.5f + Main.rand.NextFloat();
                        dust2.fadeIn     = 0.5f;
                        dust2.customData = Projectile.Center;
                        break;
                    }
                }
            }

            Dust dust3 = Main.dust[Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, 229, 0f, 0f, 0, new Color(), 1f)];

            dust3.velocity *= 5f;
            dust3.fadeIn    = 1f;
            dust3.scale     = 1f + Main.rand.NextFloat() + Main.rand.Next(4) * 0.3f;
            dust3.noGravity = true;
        }
Esempio n. 5
0
        public override void AI()
        {
            Player           player    = Main.player[Projectile.owner];
            FargoSoulsPlayer modPlayer = player.GetModPlayer <FargoSoulsPlayer>();

            Projectile.netUpdate = true;

            if (player.whoAmI == Main.myPlayer && (player.dead || !(modPlayer.ShadowEnchantActive || modPlayer.TerrariaSoul) || !player.GetToggleValue("Shadow")))
            {
                modPlayer.ShadowEnchantActive = 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.IsSummonDamage(proj, false) && proj.type != ModContent.ProjectileType <ShadowBall>() && proj.Colliding(proj.Hitbox, Projectile.Hitbox)))
                {
                    int numBalls = 5;
                    int dmg      = 25;

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

                    int          damage = FargoSoulsUtil.HighestDamageTypeScaling(player, dmg);
                    Projectile[] balls  = FargoSoulsUtil.XWay(numBalls, Projectile.GetSource_FromThis(), Projectile.Center, ModContent.ProjectileType <ShadowBall>(), 6, damage, 0);

                    foreach (Projectile ball in balls)
                    {
                        ball.originalDamage = damage;
                    }


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

                    Projectile.ai[0] = 300;

                    break;
                }
            }
        }
Esempio n. 6
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.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++;
                }
            }
        }
Esempio n. 7
0
        public override void AI()
        {
            Player           player    = Main.player[Projectile.owner];
            FargoSoulsPlayer modPlayer = player.GetModPlayer <FargoSoulsPlayer>();

            //destroy duplicates if they somehow spawn
            if (player.ownedProjectileCounts[Projectile.type] > 1 ||
                (Projectile.owner == Main.myPlayer && (!player.GetToggleValue("Rain") || !modPlayer.RainEnchantActive)))
            {
                Projectile.Kill();
            }
            else
            {
                Projectile.timeLeft = 2;
            }

            //follow player
            float dist = Vector2.Distance(Projectile.Center, player.Center);

            if (dist > 200)
            {
                Vector2 velocity = Vector2.Normalize(player.Center - Projectile.Center) * player.velocity.Length();
                Projectile.position += velocity;
            }
            else
            {
                Projectile.velocity.Y = 0;
            }

            //always max size
            if (modPlayer.NatureForce)
            {
                Projectile.scale = 3f;
                shrinkTimer      = 1;
            }

            //absorb Projectiles
            if (Projectile.owner == Main.myPlayer)
            {
                for (int i = 0; i < Main.maxProjectiles; i++)
                {
                    Projectile proj = Main.projectile[i];

                    if (proj.active && proj.friendly && !proj.hostile && proj.owner == player.whoAmI && proj.damage > 0 && FargoSoulsUtil.CanDeleteProjectile(proj) && !FargoSoulsUtil.IsSummonDamage(proj, false) && proj.Hitbox.Intersects(Projectile.Hitbox) &&
                        proj.type != Projectile.type && proj.type != ProjectileID.RainFriendly && proj.type != ModContent.ProjectileType <LightningArc>() && proj.whoAmI != Main.player[proj.owner].heldProj &&
                        Array.IndexOf(FargoSoulsGlobalProjectile.noSplit, Projectile.type) <= -1 && proj.type != ModContent.ProjectileType <Chlorofuck>())
                    {
                        if (Projectile.scale < 3f)
                        {
                            Projectile.scale *= 1.1f;
                        }
                        else
                        {
                            Vector2 rotationVector2 = (proj.Center + proj.velocity * 25) - Projectile.Center;
                            rotationVector2.Normalize();

                            Vector2 vector2_3 = rotationVector2 * 10f;
                            float   ai_1      = Main.rand.Next(80);
                            int     p         = Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.position.X + Main.rand.NextFloat(Projectile.width), Projectile.position.Y + Main.rand.NextFloat(Projectile.height), vector2_3.X, vector2_3.Y,
                                                                         ModContent.ProjectileType <LightningArc>(), proj.maxPenetrate == 1 ? proj.damage * 2 : (int)(proj.damage * 1.2), Projectile.knockBack, Projectile.owner,
                                                                         rotationVector2.ToRotation(), ai_1);
                            if (p != Main.maxProjectiles)
                            {
                                Main.projectile[p].DamageType = DamageClass.Magic;
                                Main.projectile[p].usesIDStaticNPCImmunity = false;
                                Main.projectile[p].idStaticNPCHitCooldown  = 0;
                                Main.projectile[p].GetGlobalProjectile <FargoSoulsGlobalProjectile>().noInteractionWithNPCImmunityFrames = false;
                                if (proj.maxPenetrate == 1)
                                {
                                    Main.projectile[p].penetrate = Main.projectile[p].maxPenetrate = 3;
                                }
                            }
                        }

                        proj.active = false;
                        shrinkTimer = 120;

                        break;
                    }
                }
            }

            //shrink over time if no Projectiles absorbed
            if (shrinkTimer > 0 && Projectile.scale > 1f)
            {
                shrinkTimer--;

                if (shrinkTimer == 0)
                {
                    Projectile.scale *= 0.9f;
                    shrinkTimer       = 10;
                }
            }

            //cancel normal rain
            Projectile.ai[0] = 0;

            Projectile.localAI[1]++;

            //bigger = more rain
            if (Projectile.scale > 3f)
            {
                Projectile.localAI[1] += 4;
            }
            else if (Projectile.scale > 2f)
            {
                Projectile.localAI[1] += 3;
            }
            else if (Projectile.scale > 1.5f)
            {
                Projectile.localAI[1] += 2;
            }
            else
            {
                Projectile.localAI[1]++;
            }

            //do the rain
            if (Projectile.localAI[1] >= 8)
            {
                Projectile.localAI[1] = 0;
                if (Projectile.owner == Main.myPlayer)
                {
                    int num414 = (int)(Projectile.Center.X + (float)Main.rand.Next((int)(-20 * Projectile.scale), (int)(20 * Projectile.scale)));
                    int num415 = (int)(Projectile.position.Y + (float)Projectile.height + 4f);
                    int p      = Projectile.NewProjectile(Projectile.GetSource_FromThis(), (float)num414, (float)num415, 0f, 5f, ProjectileID.RainFriendly, Projectile.damage / 4, 0f, Projectile.owner, 0f, 0);
                    if (p != Main.maxProjectiles)
                    {
                        Main.projectile[p].penetrate = 1;
                        Main.projectile[p].timeLeft  = 45 * Main.projectile[p].MaxUpdates;
                    }
                }
            }
        }