Exemplo n.º 1
0
 public override void OnFirstTick(NPC npc)
 {
     for (int i = 0; i < 9; i++)
     {
         FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center, NPCID.Zombie, velocity: Main.rand.NextVector2Circular(8, 8));
     }
 }
        public override void HitEffect(int hitDirection, double damage)
        {
            if (NPC.life <= 0)
            {
                for (int i = 3; i <= 10; i++)
                {
                    Vector2 pos = NPC.position + new Vector2(Main.rand.NextFloat(NPC.width), Main.rand.NextFloat(NPC.height));
                    if (!Main.dedServ)
                    {
                        Gore.NewGore(NPC.GetSource_FromThis(), pos, NPC.velocity, ModContent.Find <ModGore>(Mod.Name, $"TimberGore{i}").Type, NPC.scale);
                    }
                }

                if (spawnPhase2)
                {
                    FargoSoulsUtil.NewNPCEasy(NPC.GetSource_FromAI(), NPC.Center, ModContent.NPCType <TimberChampionHead>(), NPC.whoAmI, target: NPC.target);
                }

                FargoSoulsUtil.GrossVanillaDodgeDust(NPC);

                for (int i = 0; i < 6; i++)
                {
                    ExplodeDust(NPC.position + new Vector2(Main.rand.Next(NPC.width), Main.rand.Next(NPC.height)));
                }
            }
        }
Exemplo n.º 3
0
        public override void OnFirstTick(NPC npc)
        {
            base.OnFirstTick(npc);

            FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center + 100 * Vector2.UnitX, NPCID.MothronSpawn);
            FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center - 100 * Vector2.UnitX, NPCID.MothronSpawn);
        }
Exemplo n.º 4
0
        public override void Kill(int timeLeft)
        {
            if (FargoSoulsWorld.EternityMode)
            {
                FargoSoulsUtil.NewNPCEasy(Terraria.Entity.InheritSource(Projectile), Projectile.Top - 20 * Vector2.UnitY, ModContent.NPCType <LesserSquirrel>(), velocity: new Vector2(Main.rand.NextFloat(-10, 10), Main.rand.NextFloat(-20, -10)));
            }

            if (Main.netMode != NetmodeID.MultiplayerClient)
            {
                Player player = FargoSoulsUtil.PlayerExists(Projectile.ai[0]);
                if (player != null)
                {
                    for (int i = 0; i < 10; i++)
                    {
                        Vector2 spawnPos = Projectile.position;
                        spawnPos.X += Projectile.width / 2f + Main.rand.NextFloat(-40, 40);
                        spawnPos.Y += 40 + Main.rand.NextFloat(-40, 40);

                        const float gravity  = 0.2f;
                        float       time     = 30f;
                        Vector2     distance = player.Center - spawnPos;
                        distance.X = Main.rand.NextFloat(-1.5f, 1.5f);
                        distance.Y = distance.Y / time - 0.5f * gravity * time;
                        float minimumY = Main.rand.NextFloat(-12f, -9f);
                        if (distance.Y > minimumY)
                        {
                            distance.Y = minimumY;
                        }
                        distance += Main.rand.NextVector2Square(-0.5f, 0.5f);

                        Projectile.NewProjectile(Terraria.Entity.InheritSource(Projectile), spawnPos, distance, ModContent.ProjectileType <TimberAcorn>(), Projectile.damage, Projectile.knockBack, Projectile.owner);
                    }
                }
            }
        }
Exemplo n.º 5
0
        public override void OnKill(NPC npc)
        {
            base.OnKill(npc);

            if (Main.netMode != NetmodeID.MultiplayerClient)
            {
                if (Main.rand.NextBool(5))
                {
                    FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center, NPCID.CursedSkull);
                }

                for (int i = 0; i < 15; i++)
                {
                    Vector2 speed = new Vector2(Main.rand.Next(-50, 51), Main.rand.Next(-100, 1));
                    speed.Normalize();
                    speed   *= Main.rand.NextFloat(3f, 6f);
                    speed.Y -= Math.Abs(speed.X) * 0.2f;
                    speed.Y -= 3f;
                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, speed, ProjectileID.SkeletonBone, FargoSoulsUtil.ScaledProjectileDamage(npc.damage), 0f, Main.myPlayer);
                    }
                }
            }
        }
Exemplo n.º 6
0
        public override bool PreAI(NPC npc)
        {
            bool result = base.PreAI(npc);

            if (FargoSoulsWorld.SwarmActive)
            {
                return(result);
            }

            NPC head = FargoSoulsUtil.NPCExists(npc.ai[1], NPCID.SkeletronHead);

            if (head != null && (head.ai[1] == 1f || head.ai[1] == 2f)) //spinning or DG mode
            {
                if (AttackTimer > 0 && head.life >= head.lifeMax * .75) //for a short period
                {
                    if (--AttackTimer < 65)
                    {
                        Vector2 centerPoint = head.Center - 10 * 16 * Vector2.UnitY;
                        if (!npc.HasValidTarget || npc.Distance(centerPoint) > 15 * 16)
                        {
                            AttackTimer++;                                                             //pause here, dont begin guardians attack until in range
                        }
                        else if (AttackTimer % 10 == 0 && Main.netMode != NetmodeID.MultiplayerClient) //periodic below 50%
                        {
                            Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, npc.DirectionTo(Main.player[npc.target].Center), ModContent.ProjectileType <SkeletronGuardian2>(), FargoSoulsUtil.ScaledProjectileDamage(npc.damage), 0f, Main.myPlayer);
                        }
                    }
                }
            }
            else
            {
                if (AttackTimer != 65 + 150)
                {
                    AttackTimer = 65 + 150;

                    if (Main.netMode != NetmodeID.MultiplayerClient && npc.HasPlayerTarget) //throw undead miner
                    {
                        float       gravity  = 0.4f;                                        //shoot down
                        const float time     = 60f;
                        Vector2     distance = Main.player[npc.target].Top - npc.Center + Main.rand.NextVector2Circular(80, 80);
                        distance.X = distance.X / time;
                        distance.Y = distance.Y / time - 0.5f * gravity * time;

                        FargoSoulsUtil.NewNPCEasy(
                            npc.GetSource_FromAI(),
                            npc.Center,
                            Main.rand.Next(new int[] {
                            NPCID.BoneThrowingSkeleton,
                            NPCID.BoneThrowingSkeleton2,
                            NPCID.BoneThrowingSkeleton3,
                            NPCID.BoneThrowingSkeleton4
                        }),
                            velocity: distance);
                    }
                }
            }

            return(result);
        }
        public override void OnKill()
        {
            NPC.SetEventFlagCleared(ref FargoSoulsWorld.downedBoss[(int)FargoSoulsWorld.Downed.TrojanSquirrel], -1);

            if (ModContent.TryFind("Fargowiltas", "Squirrel", out ModNPC squrrl) && !NPC.AnyNPCs(squrrl.Type))
            {
                FargoSoulsUtil.NewNPCEasy(NPC.GetSource_FromThis(), NPC.Center, squrrl.Type);
            }
        }
Exemplo n.º 8
0
        public override void OnFirstTick(NPC npc)
        {
            base.OnFirstTick(npc);

            for (int i = 0; i < 6; i++)
            {
                FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromThis(), npc.Center, NPCID.DarkCaster, velocity: Main.rand.NextVector2Circular(8, 8));
            }
        }
Exemplo n.º 9
0
        public override void OnKill(NPC npc)
        {
            base.OnKill(npc);

            if (Main.rand.NextBool())
            {
                FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center, NPCID.Ghost);
            }
        }
Exemplo n.º 10
0
        public void BeCompanionCube()
        {
            Player player = Main.player[Projectile.owner];
            Color  color;

            color = Lighting.GetColor((int)Projectile.Center.X / 16, (int)Projectile.Center.Y / 16);
            Vector3 vector3_1 = color.ToVector3();

            color = Lighting.GetColor((int)player.Center.X / 16, (int)player.Center.Y / 16);
            Vector3 vector3_2 = color.ToVector3();

            if (vector3_1.Length() < 0.15f && vector3_2.Length() < 0.15)
            {
                notlocalai1 += 1;
            }
            else if (notlocalai1 > 0)
            {
                notlocalai1 -= 1;
            }

            notlocalai1 = MathHelper.Clamp(notlocalai1, -3600f, 600);

            if (notlocalai1 > Main.rand.Next(300, 600) && !player.immune)
            {
                notlocalai1 = Main.rand.Next(30) * -10 - 300;

                switch (Main.rand.Next(3))
                {
                case 0:     //stab
                    if (Projectile.owner == Main.myPlayer)
                    {
                        SoundEngine.PlaySound(SoundID.Item1, Projectile.Center);
                        player.Hurt(Terraria.DataStructures.PlayerDeathReason.ByOther(6), 777, 0, false, false, false, -1);
                        player.immune     = false;
                        player.immuneTime = 0;
                    }
                    break;

                case 1:     //spawn mutant
                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        FargoSoulsUtil.NewNPCEasy(Projectile.GetSource_FromThis(), Projectile.Center, ModContent.NPCType <NPCs.MutantBoss.MutantBoss>());
                        FargoSoulsUtil.PrintLocalization($"Mods.{Mod.Name}.Message.{Name}MutantBoss", 175, 75, 255);
                    }
                    break;

                default:
                    if (Projectile.owner == Main.myPlayer)
                    {
                        CombatText.NewText(Projectile.Hitbox, Color.LimeGreen, Language.GetTextValue($"Mods.{Mod.Name}.Message.{Name}NotSafe"));
                    }
                    break;
                }
            }
        }
Exemplo n.º 11
0
        public override void AI(NPC npc)
        {
            base.AI(npc);

            if (++AttackTimer > 420)
            {
                AttackTimer = 0;

                FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center, NPCID.ChaosBall);
            }
        }
Exemplo n.º 12
0
 private void ManualSpawn(NPC npc, int type)
 {
     if (Main.netMode != NetmodeID.MultiplayerClient)
     {
         int n = FargoSoulsUtil.NewNPCEasy(Terraria.Entity.InheritSource(Projectile), npc.Center, type);
         if (n != Main.maxNPCs)
         {
             FargoSoulsUtil.PrintText(Main.npc[n].FullName + " has awoken!", 175, 75, 255);
         }
     }
 }
Exemplo n.º 13
0
        public override void OnKill(NPC npc)
        {
            base.OnKill(npc);

            if (Main.rand.NextBool(5))
            {
                for (int i = 0; i < 4; i++)
                {
                    FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center, NPCID.WallCreeper, velocity: new Vector2(Main.rand.NextFloat(-5f, 5f), -Main.rand.NextFloat(10f)));
                }
            }
        }
Exemplo n.º 14
0
        public override void OnKill(NPC npc)
        {
            base.OnKill(npc);

            if (npc.type == NPCID.BlueSlime)
            {
                void SplitIntoSlimes(int type, int amount)
                {
                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        for (int i = 0; i < amount; i++)
                        {
                            if (Main.rand.Next(3) != 0)
                            {
                                continue;
                            }

                            int n = FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center, type,
                                                              velocity: new Vector2(npc.velocity.X * 2, npc.velocity.Y));

                            if (n != Main.maxNPCs)
                            {
                                Main.npc[n].velocity.X += Main.rand.Next(-20, 20) * 0.1f + i * npc.direction * 0.3f;
                                Main.npc[n].velocity.Y -= Main.rand.Next(0, 10) * 0.1f + i;
                            }
                        }
                    }
                }

                switch (npc.netID)
                {
                case NPCID.YellowSlime:
                    SplitIntoSlimes(NPCID.PurpleSlime, 2);
                    break;

                case NPCID.PurpleSlime:
                    SplitIntoSlimes(NPCID.RedSlime, 2);
                    break;

                case NPCID.RedSlime:
                    SplitIntoSlimes(NPCID.GreenSlime, 2);
                    break;

                case NPCID.Pinky:
                    SplitIntoSlimes(NPCID.YellowSlime, 2);
                    SplitIntoSlimes(NPCID.MotherSlime, 1);
                    break;

                default:
                    break;
                }
            }
        }
Exemplo n.º 15
0
        public override void OnKill(NPC npc)
        {
            base.OnKill(npc);

            if (NPC.downedPlantBoss && Main.netMode != NetmodeID.MultiplayerClient)
            {
                int n = FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center, NPCID.Paladin, velocity: new Vector2(Main.rand.NextFloat(-10, 10), Main.rand.NextFloat(-10, 0)));
                if (n != Main.maxNPCs)
                {
                    Main.npc[n].GetEModeNPCMod <Paladin>().IsSmallPaladin = true;
                }
            }
        }
Exemplo n.º 16
0
        public override void OnKill(NPC npc)
        {
            base.OnKill(npc);

            if (Main.rand.NextBool(3) && Main.netMode != NetmodeID.MultiplayerClient)
            {
                for (int i = 0; i < 4; i++)
                {
                    FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center, NPCID.DemonEye,
                                              velocity: new Vector2(Main.rand.NextFloat(-3, 3), Main.rand.NextFloat(-3, 3)));
                }
            }
        }
Exemplo n.º 17
0
        public override void OnFirstTick(NPC npc)
        {
            base.OnFirstTick(npc);

            if (npc.type == NPCID.CultistDragonHead)
            {
                if (FargoSoulsWorld.MasochistModeReal && FargoSoulsUtil.BossIsAlive(ref EModeGlobalNPC.cultBoss, NPCID.CultistBoss))
                {
                    npc.Center = Main.npc[EModeGlobalNPC.cultBoss].Center;
                }

                if (NPC.CountNPCS(NPCID.AncientCultistSquidhead) < 4 && Main.netMode != NetmodeID.MultiplayerClient)
                {
                    FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center, NPCID.AncientCultistSquidhead);
                }
            }
        }
Exemplo n.º 18
0
        public override void AI(NPC npc)
        {
            base.AI(npc);

            Counter++;

            if (IsFakeBat)
            {
                if (Main.netMode == NetmodeID.Server && Counter <= 65 && Counter % 15 == 5) //mp sync
                {
                    npc.netUpdate = true;
                    NetSync(npc);
                }

                if (npc.alpha > 200)
                {
                    npc.alpha = 200;
                }

                if (npc.lifeMax > 100)
                {
                    npc.lifeMax = 100;
                }

                if (npc.life > npc.lifeMax)
                {
                    npc.life = npc.lifeMax;
                }
            }
            else if (Counter > 600)
            {
                Counter = 0;

                if (npc.HasPlayerTarget && npc.Distance(Main.player[npc.target].Center) < 1000 &&
                    Main.netMode != NetmodeID.MultiplayerClient && NPC.CountNPCS(NPCID.IlluminantBat) < 10)
                {
                    int bat = FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center, npc.type,
                                                        velocity: new Vector2(Main.rand.NextFloat(-5, 5), Main.rand.NextFloat(-5, 5)));
                    if (bat != Main.maxNPCs)
                    {
                        Main.npc[bat].GetEModeNPCMod <IlluminantBat>().IsFakeBat = true;
                    }
                }
            }
        }
Exemplo n.º 19
0
        public override void HitEffect(NPC npc, int hitDirection, double damage)
        {
            base.HitEffect(npc, hitDirection, damage);

            if (!FargoSoulsWorld.SwarmActive)
            {
                NPC cultist = FargoSoulsUtil.NPCExists(npc.ai[3], NPCID.CultistBoss);

                //yes, this spawns two clones without the check
                if (cultist != null && NPC.CountNPCS(npc.type) < (FargoSoulsWorld.MasochistModeReal ? Math.Min(TotalCultistCount + 1, 12) : TotalCultistCount))
                {
                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        FargoSoulsUtil.NewNPCEasy(cultist.GetSource_FromAI(), npc.Center, NPCID.CultistBossClone, 0, npc.ai[0], npc.ai[1], npc.ai[2], npc.ai[3], npc.target);
                    }
                }
            }
        }
Exemplo n.º 20
0
        public override void AI(NPC npc)
        {
            base.AI(npc);

            if (++Counter >= 300 && Counter % 20 == 0)
            {
                int t = npc.HasPlayerTarget ? npc.target : npc.FindClosestPlayer();
                if (t != -1 && npc.Distance(Main.player[t].Center) < 800 && Main.netMode != NetmodeID.MultiplayerClient)
                {
                    FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center, NPCID.BurningSphere);
                }
            }

            if (Counter > 420)
            {
                Counter = 0;
            }
        }
Exemplo n.º 21
0
        public override void OnKill(NPC npc)
        {
            base.OnKill(npc);

            switch (npc.type)
            {
            case NPCID.SmallSlimedZombie:
            case NPCID.SlimedZombie:
            case NPCID.BigSlimedZombie:
            case NPCID.ArmedZombieSlimed:
                if (Main.rand.NextBool() && Main.netMode != NetmodeID.MultiplayerClient)
                {
                    FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center, NPCID.BlueSlime);
                }
                break;

            default:
                break;
            }
        }
Exemplo n.º 22
0
        public override void OnKill(NPC npc)
        {
            base.OnKill(npc);

            if (Main.netMode != NetmodeID.MultiplayerClient && Main.hardMode && Main.rand.NextBool())
            {
                if (NPC.CountNPCS(NPCID.FungiSpore) < 24)
                {
                    for (int i = 0; i < 8; i++)
                    {
                        FargoSoulsUtil.NewNPCEasy(npc.GetSource_Death(), npc.Center, NPCID.FungiSpore,
                                                  velocity: 0.5f * new Vector2(Main.rand.NextFloat(-5, 5), Main.rand.NextFloat(-5, 5)));
                    }
                }
                else if (npc.type != NPCID.SporeBat)
                {
                    FargoSoulsUtil.NewNPCEasy(npc.GetSource_Death(), npc.Center, NPCID.SporeBat,
                                              velocity: 0.5f * new Vector2(Main.rand.NextFloat(-5, 5), Main.rand.NextFloat(-5, 5)));
                }
            }
        }
Exemplo n.º 23
0
        public override bool PreAI(NPC npc)
        {
            bool result = base.PreAI(npc);

            EModeGlobalNPC.skeleBoss = npc.whoAmI;

            if (FargoSoulsWorld.SwarmActive)
            {
                return(result);
            }

            if (!SpawnedArms && npc.life < npc.lifeMax * .25)
            {
                SpawnedArms = true;

                FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center, NPCID.SkeletronHand, npc.whoAmI, 1f, npc.whoAmI, 0f, 0f, npc.target);
                FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center, NPCID.SkeletronHand, npc.whoAmI, -1f, npc.whoAmI, 0f, 0f, npc.target);

                string text = Language.GetTextValue($"Mods.{mod.Name}.Message.SkeletronRegrow");
                FargoSoulsUtil.PrintLocalization($"{npc.FullName} {text}", new Color(175, 75, 255));
            }

            if (npc.ai[1] == 0f)
            {
                if (npc.ai[2] == 800 - 90) //telegraph spin
                {
                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, Vector2.Zero, ModContent.ProjectileType <TargetingReticle>(), 0, 0f, Main.myPlayer, npc.whoAmI, npc.type);
                    }
                }
                if (npc.ai[2] < 800 - 5)
                {
                    ReticleTarget = npc.target;
                }
            }

            if (npc.ai[1] == 1f || npc.ai[1] == 2f) //spinning or DG mode
            {
                //force targeted player back to the one i telegraphed with reticle (otherwise, may target another player when spin starts)
                if (ReticleTarget > -1 && ReticleTarget < Main.maxPlayers)
                {
                    npc.target    = ReticleTarget;
                    ReticleTarget = -1;

                    npc.netUpdate = true;
                    NetSync(npc);

                    if (!npc.HasValidTarget)
                    {
                        npc.TargetClosest(false);
                    }

                    if (npc.ai[1] == 1) //do cross guardian attack
                    {
                        if (!FargoSoulsWorld.MasochistModeReal)
                        {
                            for (int i = 0; i < Main.maxProjectiles; i++) //also clear leftover babies
                            {
                                if (Main.projectile[i].active && Main.projectile[i].hostile && Main.projectile[i].type == ModContent.ProjectileType <SkeletronGuardian2>())
                                {
                                    Main.projectile[i].Kill();
                                }
                            }
                        }

                        if ((npc.life >= npc.lifeMax * .75 || FargoSoulsWorld.MasochistModeReal) && Main.netMode != NetmodeID.MultiplayerClient)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                for (int j = -2; j <= 2; j++)
                                {
                                    Vector2 spawnPos = new Vector2(1200, 80 * j);
                                    Vector2 vel      = -8 * Vector2.UnitX;
                                    spawnPos = Main.player[npc.target].Center + spawnPos.RotatedBy(Math.PI / 2 * (i + 0.5));
                                    vel      = vel.RotatedBy(Math.PI / 2 * (i + 0.5));
                                    int p = Projectile.NewProjectile(npc.GetSource_FromThis(), spawnPos, vel, ModContent.ProjectileType <Projectiles.Champions.ShadowGuardian>(),
                                                                     FargoSoulsUtil.ScaledProjectileDamage(npc.damage), 0f, Main.myPlayer);
                                    if (p != Main.maxProjectiles)
                                    {
                                        Main.projectile[p].timeLeft = 1200 / 8 + 1;
                                    }
                                }
                            }
                        }
                    }
                }

                float ratio    = (float)npc.life / npc.lifeMax;
                float cooldown = 20f;
                if (!FargoSoulsWorld.MasochistModeReal)
                {
                    cooldown += 100f * ratio;
                }
                if (++npc.localAI[2] >= cooldown) //spray bones
                {
                    npc.localAI[2] = 0f;
                    if (cooldown > 0 && npc.HasPlayerTarget && Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        Vector2 speed = Vector2.Normalize(Main.player[npc.target].Center - npc.Center) * 6f;
                        for (int i = 0; i < 8; i++)
                        {
                            Vector2 vel = speed.RotatedBy(Math.PI * 2 / 8 * i);
                            vel   += npc.velocity * (1f - ratio);
                            vel.Y -= Math.Abs(vel.X) * 0.2f;
                            Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, vel, ModContent.ProjectileType <SkeletronBone>(), npc.defDamage / 9 * 2, 0f, Main.myPlayer);
                        }
                    }
                }

                if (BabyGuardianTimer > 180)
                {
                    BabyGuardianTimer = 180;
                }

                if (npc.life < npc.lifeMax * .75 && npc.ai[1] == 1f && --BabyGuardianTimer < 0)
                {
                    BabyGuardianTimer = 180;

                    SoundEngine.PlaySound(SoundID.ForceRoarPitched, npc.Center);

                    if (Main.netMode != NetmodeID.MultiplayerClient) //spray of baby guardian missiles
                    {
                        const int max      = 30;
                        float     modifier = 1f - (float)npc.life / npc.lifeMax;
                        modifier *= 4f / 3f;                                    //scaling maxes at 25% life
                        if (modifier > 1f || FargoSoulsWorld.MasochistModeReal) //cap it, or force it to cap in emode
                        {
                            modifier = 1f;
                        }
                        int actualNumberToSpawn = (int)(max * modifier);
                        for (int i = 0; i < actualNumberToSpawn; i++)
                        {
                            float   speed    = Main.rand.NextFloat(3f, 9f);
                            Vector2 velocity = speed * npc.DirectionFrom(Main.player[npc.target].Center).RotatedBy(Math.PI * (Main.rand.NextDouble() - 0.5));
                            float   ai1      = speed / (60f + Main.rand.NextFloat(actualNumberToSpawn * 2));
                            Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, velocity, ModContent.ProjectileType <SkeletronGuardian>(), FargoSoulsUtil.ScaledProjectileDamage(npc.damage, 0.8f), 0f, Main.myPlayer, 0f, ai1);
                        }
                    }
                }
            }
            else
            {
                if (npc.ai[2] == 0)
                {
                    //compensate for not changing targets when beginning spin
                    npc.TargetClosest(false);

                    //prevent skeletron from firing his stupid tick 1 no telegraph skull right after finishing spin
                    if (!FargoSoulsWorld.MasochistModeReal)
                    {
                        npc.ai[2] = 1;
                    }
                }

                if (npc.life < npc.lifeMax * .75)               //phase 2
                {
                    if (npc.ai[2] <= 60 && npc.ai[2] % 10 == 0) //vomit skeletons
                    {
                        int[] skeletons =
                        {
                            NPCID.BoneThrowingSkeleton,
                            NPCID.BoneThrowingSkeleton2,
                            NPCID.BoneThrowingSkeleton3,
                            NPCID.BoneThrowingSkeleton4
                        };

                        if (Main.npc.Count(n => n.active && skeletons.Contains(n.type)) < 12)
                        {
                            float       gravity  = 0.4f; //shoot down
                            const float time     = 60f;
                            Vector2     distance = Main.player[npc.target].Top - npc.Center + Main.rand.NextVector2Circular(80, 80);
                            distance.X = distance.X / time;
                            distance.Y = distance.Y / time - 0.5f * gravity * time;

                            FargoSoulsUtil.NewNPCEasy(
                                npc.GetSource_FromAI(),
                                npc.Center,
                                Main.rand.Next(skeletons),
                                velocity: distance);

                            SoundEngine.PlaySound(SoundID.NPCDeath13, npc.Center);
                        }
                    }

                    if (--BabyGuardianTimer < 0)
                    {
                        BabyGuardianTimer = FargoSoulsWorld.MasochistModeReal ? 180 : 240;

                        SoundEngine.PlaySound(SoundID.ForceRoarPitched, npc.Center);

                        for (int j = -1; j <= 1; j++) //to both sides
                        {
                            if (j == 0)
                            {
                                continue;
                            }

                            const int gap      = 40;
                            const int max      = 14;
                            float     modifier = 1f - (float)npc.life / npc.lifeMax;
                            modifier *= 4f / 3f;                                    //scaling maxes at 25% life
                            if (modifier > 1f || FargoSoulsWorld.MasochistModeReal) //cap it, or force it to cap in emode
                            {
                                modifier = 1f;
                            }
                            int     actualNumberToSpawn = (int)(max * modifier);
                            Vector2 baseVel             = npc.DirectionTo(Main.player[npc.target].Center).RotatedBy(MathHelper.ToRadians(gap) * j);
                            for (int k = 0; k < actualNumberToSpawn; k++) //a fan of skulls
                            {
                                if (Main.netMode != NetmodeID.MultiplayerClient)
                                {
                                    float velModifier = 1f + 9f * k / max;
                                    Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, velModifier * baseVel.RotatedBy(MathHelper.ToRadians(10) * j * k),
                                                             ModContent.ProjectileType <SkeletronGuardian2>(), FargoSoulsUtil.ScaledProjectileDamage(npc.damage, 0.8f), 0f, Main.myPlayer);
                                }
                            }
                        }

                        if (Main.netMode != NetmodeID.MultiplayerClient) //one more shot straight behind skeletron
                        {
                            float velModifier = 10f;
                            Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, velModifier * npc.DirectionFrom(Main.player[npc.target].Center),
                                                     ModContent.ProjectileType <SkeletronGuardian2>(), FargoSoulsUtil.ScaledProjectileDamage(npc.damage, 0.8f), 0f, Main.myPlayer);
                        }
                    }
                }
            }

            if (npc.ai[1] == 2f)
            {
                npc.defense = 9999;
                npc.damage  = npc.defDamage * 15;

                if (!Main.dayTime && !FargoSoulsWorld.MasochistModeReal)
                {
                    if (++DGSpeedRampup < 120)
                    {
                        npc.position -= npc.velocity * (120 - DGSpeedRampup) / 120;
                    }
                }
            }

            EModeUtils.DropSummon(npc, "SuspiciousSkull", NPC.downedBoss3, ref DroppedSummon);

            return(result);
        }
Exemplo n.º 24
0
        public override bool PreAI(NPC npc)
        {
            bool result = base.PreAI(npc);

            EModeGlobalNPC.moonBoss = npc.whoAmI;

            if (FargoSoulsWorld.SwarmActive)
            {
                return(result);
            }

            if (!SpawnedRituals)
            {
                SpawnedRituals     = true;
                VulnerabilityState = 0;
                if (Main.netMode != NetmodeID.MultiplayerClient)
                {
                    Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, Vector2.Zero, ModContent.ProjectileType <LunarRitual>(), 25, 0f, Main.myPlayer, 0f, npc.whoAmI);
                    Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, Vector2.Zero, ModContent.ProjectileType <FragmentRitual>(), 0, 0f, Main.myPlayer, 0f, npc.whoAmI);
                }
            }

            if (Main.LocalPlayer.active && !Main.LocalPlayer.dead && !Main.LocalPlayer.ghost && VulnerabilityState >= 0 && VulnerabilityState <= 3)
            {
                Main.LocalPlayer.AddBuff(ModContent.BuffType <NullificationCurse>(), 2);
            }

            npc.position -= npc.velocity * 2f / 3f; //SLOW DOWN

            if (npc.dontTakeDamage)
            {
                if (AttackTimer == 370 && Main.netMode != NetmodeID.MultiplayerClient)
                {
                    for (int i = 0; i < 3; i++)
                    {
                        NPC bodyPart = Main.npc[(int)npc.localAI[i]];
                        if (bodyPart.active)
                        {
                            Projectile.NewProjectile(npc.GetSource_FromThis(), bodyPart.Center, Vector2.Zero, ModContent.ProjectileType <GlowRing>(), 0, 0f, Main.myPlayer, bodyPart.whoAmI, bodyPart.type);
                        }
                    }
                }

                if (AttackTimer > 400)
                {
                    AttackTimer   = 0;
                    npc.netUpdate = true;
                    NetSync(npc);

                    switch (VulnerabilityState)
                    {
                    case 0:     //melee
                        for (int i = 0; i < 3; i++)
                        {
                            NPC bodyPart = Main.npc[(int)npc.localAI[i]];

                            if (bodyPart.active)
                            {
                                int damage = 30;
                                for (int j = -2; j <= 2; j++)
                                {
                                    if (Main.netMode != NetmodeID.MultiplayerClient)
                                    {
                                        Projectile.NewProjectile(npc.GetSource_FromThis(), bodyPart.Center,
                                                                 6f * bodyPart.DirectionFrom(Main.player[npc.target].Center).RotatedBy(Math.PI / 2 / 4 * j),
                                                                 ModContent.ProjectileType <MoonLordFireball>(), damage, 0f, Main.myPlayer, 20, 20 + 60);
                                    }
                                }
                            }
                        }
                        break;

                    case 1:     //ranged
                        for (int j = 0; j < 6; j++)
                        {
                            Vector2 spawn = Main.player[npc.target].Center + 500 * npc.DirectionFrom(Main.player[npc.target].Center).RotatedBy(MathHelper.TwoPi / 6 * (j + 0.5f));
                            if (Main.netMode != NetmodeID.MultiplayerClient)
                            {
                                Projectile.NewProjectile(npc.GetSource_FromThis(), spawn, Vector2.Zero, ModContent.ProjectileType <LightningVortexHostile>(), 30, 0f, Main.myPlayer, 1, Main.player[npc.target].DirectionFrom(spawn).ToRotation());
                            }
                        }
                        break;

                    case 2:     //magic
                        for (int i = 0; i < 3; i++)
                        {
                            NPC bodyPart = Main.npc[(int)npc.localAI[i]];

                            if (bodyPart.active &&
                                ((i == 2 && bodyPart.type == NPCID.MoonLordHead) ||
                                 bodyPart.type == NPCID.MoonLordHand))
                            {
                                int       damage = 35;
                                const int max    = 6;
                                for (int j = 0; j < max; j++)
                                {
                                    if (Main.netMode != NetmodeID.MultiplayerClient)
                                    {
                                        int p = Projectile.NewProjectile(npc.GetSource_FromThis(), bodyPart.Center,
                                                                         2.5f * bodyPart.DirectionFrom(Main.player[npc.target].Center).RotatedBy(Math.PI * 2 / max * (j + 0.5)),
                                                                         ModContent.ProjectileType <MoonLordNebulaBlaze>(), damage, 0f, Main.myPlayer);
                                        if (p != Main.maxProjectiles)
                                        {
                                            Main.projectile[p].timeLeft = 1200;
                                        }
                                    }
                                }
                            }
                        }
                        break;

                    case 3:     //summoner
                        for (int i = 0; i < 3; i++)
                        {
                            NPC bodyPart = Main.npc[(int)npc.localAI[i]];

                            if (bodyPart.active &&
                                ((i == 2 && bodyPart.type == NPCID.MoonLordHead) ||
                                 bodyPart.type == NPCID.MoonLordHand))
                            {
                                Vector2 speed = Main.player[npc.target].Center - bodyPart.Center;
                                speed.Normalize();
                                speed *= 5f;
                                for (int j = -1; j <= 1; j++)
                                {
                                    Vector2 vel = speed.RotatedBy(MathHelper.ToRadians(15) * j);
                                    FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), bodyPart.Center, NPCID.AncientLight, 0, 0f, (Main.rand.NextFloat() - 0.5f) * 0.3f * 6.28318548202515f / 60f, vel.X, vel.Y, velocity: vel);
                                }
                            }
                        }
                        break;

                    default:     //phantasmal eye rings
                        if (Main.netMode != NetmodeID.MultiplayerClient)
                        {
                            const int   max              = 4;
                            const int   speed            = 8;
                            const float rotationModifier = 0.5f;
                            int         damage           = 40;
                            float       rotation         = 2f * (float)Math.PI / max;
                            Vector2     vel              = Vector2.UnitY * speed;
                            int         type             = ModContent.ProjectileType <Projectiles.MutantBoss.MutantSphereRing>();
                            for (int i = 0; i < max; i++)
                            {
                                vel = vel.RotatedBy(rotation);
                                if (Main.netMode != NetmodeID.MultiplayerClient)
                                {
                                    int p = Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, vel, type, damage, 0f, Main.myPlayer, rotationModifier, speed);
                                    if (p != Main.maxProjectiles)
                                    {
                                        Main.projectile[p].timeLeft = 1800 - VulnerabilityTimer;
                                    }
                                    p = Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, vel, type, damage, 0f, Main.myPlayer, -rotationModifier, speed);
                                    if (p != Main.maxProjectiles)
                                    {
                                        Main.projectile[p].timeLeft = 1800 - VulnerabilityTimer;
                                    }
                                }
                            }
                            SoundEngine.PlaySound(SoundID.Item84, npc.Center);
                        }
                        break;
                    }
                }
            }
            else //only when vulnerable
            {
                if (!EnteredPhase2)
                {
                    EnteredPhase2 = true;
                    AttackTimer   = 0;
                    SoundEngine.PlaySound(SoundID.Roar, Main.LocalPlayer.Center);
                    npc.netUpdate = true;
                    NetSync(npc);
                }

                Player player = Main.player[npc.target];
                switch (VulnerabilityState)
                {
                case 0:     //melee
                {
                    if (AttackTimer > 30)
                    {
                        AttackTimer -= 300;
                        AttackMemory = AttackMemory == 0 ? 1 : 0;

                        float handToAttackWith = npc.localAI[AttackMemory];
                        if (Main.netMode != NetmodeID.MultiplayerClient)
                        {
                            Projectile.NewProjectile(npc.GetSource_FromThis(), Main.npc[(int)handToAttackWith].Center, Vector2.Zero, ModContent.ProjectileType <MoonLordSun>(), 60, 0f, Main.myPlayer, npc.whoAmI, handToAttackWith);
                        }
                    }
                }
                break;

                case 1:                    //vortex
                {
                    if (AttackMemory == 0) //spawn the vortex
                    {
                        AttackMemory = 1;
                        for (int i = -1; i <= 1; i += 2)
                        {
                            if (Main.netMode != NetmodeID.MultiplayerClient)
                            {
                                Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, Vector2.Zero, ModContent.ProjectileType <MoonLordVortex>(), 40, 0f, Main.myPlayer, i, npc.whoAmI);
                            }
                        }
                    }
                }
                break;

                case 2:     //nebula
                {
                    if (AttackTimer > 30)
                    {
                        AttackTimer -= 360;

                        for (int i = 0; i < 3; i++)
                        {
                            NPC bodyPart = Main.npc[(int)npc.localAI[i]];
                            int damage   = 35;
                            for (int j = -2; j <= 2; j++)
                            {
                                if (Main.netMode != NetmodeID.MultiplayerClient)
                                {
                                    Projectile.NewProjectile(npc.GetSource_FromThis(), bodyPart.Center,
                                                             2.5f * bodyPart.DirectionFrom(Main.player[npc.target].Center).RotatedBy(Math.PI / 2 / 2 * (j + Main.rand.NextFloat(-0.25f, 0.25f))),
                                                             ModContent.ProjectileType <MoonLordNebulaBlaze2>(), damage, 0f, Main.myPlayer, npc.whoAmI);
                                }
                            }
                        }
                    }
                }
                break;

                case 3:     //stardust
                {
                    if (AttackTimer > 360)
                    {
                        AttackTimer -= 360;
                        AttackMemory = 0;
                    }

                    float baseRotation = MathHelper.ToRadians(50);
                    if (++AttackMemory == 10)
                    {
                        if (Main.netMode != NetmodeID.MultiplayerClient)
                        {
                            Projectile.NewProjectile(npc.GetSource_FromThis(), Main.npc[(int)npc.localAI[0]].Center, Main.npc[(int)npc.localAI[0]].DirectionTo(player.Center), ModContent.ProjectileType <PhantasmalDeathrayMLSmall>(),
                                                     60, 0f, Main.myPlayer, baseRotation * Main.rand.NextFloat(0.9f, 1.1f), npc.localAI[0]);
                        }
                    }
                    else if (AttackMemory == 20)
                    {
                        if (Main.netMode != NetmodeID.MultiplayerClient)
                        {
                            Projectile.NewProjectile(npc.GetSource_FromThis(), Main.npc[(int)npc.localAI[1]].Center, Main.npc[(int)npc.localAI[2]].DirectionTo(player.Center), ModContent.ProjectileType <PhantasmalDeathrayMLSmall>(),
                                                     60, 0f, Main.myPlayer, -baseRotation * Main.rand.NextFloat(0.9f, 1.1f), npc.localAI[1]);
                        }
                    }
                    else if (AttackMemory == 30)
                    {
                        if (Main.netMode != NetmodeID.MultiplayerClient)
                        {
                            Projectile.NewProjectile(npc.GetSource_FromThis(), Main.npc[(int)npc.localAI[2]].Center, Main.npc[(int)npc.localAI[1]].DirectionTo(player.Center), ModContent.ProjectileType <PhantasmalDeathrayMLSmall>(),
                                                     60, 0f, Main.myPlayer, baseRotation * Main.rand.NextFloat(0.9f, 1.1f), npc.localAI[2]);
                        }
                    }
                    else if (AttackMemory == 40)
                    {
                        if (Main.netMode != NetmodeID.MultiplayerClient)
                        {
                            Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, npc.DirectionTo(player.Center), ModContent.ProjectileType <PhantasmalDeathrayMLSmall>(),
                                                     60, 0f, Main.myPlayer, -baseRotation * Main.rand.NextFloat(0.9f, 1.1f), npc.whoAmI);
                        }
                    }
                }
                break;

                default:                   //any
                {
                    if (AttackMemory == 0) //spawn the moons
                    {
                        AttackMemory = 1;

                        foreach (Projectile p in Main.projectile.Where(p => p.active && p.hostile))
                        {
                            if (p.type == ModContent.ProjectileType <LunarRitual>() && p.ai[1] == npc.whoAmI)        //find my arena
                            {
                                if (Main.netMode != NetmodeID.MultiplayerClient)
                                {
                                    for (int i = 0; i < 4; i++)
                                    {
                                        Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, p.DirectionTo(Main.player[npc.target].Center).RotatedBy(MathHelper.TwoPi / 4 * i), ModContent.ProjectileType <MoonLordMoon>(),
                                                                 60, 0f, Main.myPlayer, p.identity, 1450);
                                    }
                                    for (int i = 0; i < 4; i++)
                                    {
                                        Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, p.DirectionTo(Main.player[npc.target].Center).RotatedBy(MathHelper.TwoPi / 4 * (i + 0.5f)), ModContent.ProjectileType <MoonLordMoon>(),
                                                                 60, 0f, Main.myPlayer, p.identity, -950);
                                    }
                                }
                                break;
                            }
                        }
                    }
                }
                break;
                }
            }

            if (npc.ai[0] == 2f) //moon lord is dead
            {
                VulnerabilityState = 4;
                VulnerabilityTimer = 0;
                AttackTimer        = 0;
            }
            else //moon lord isn't dead
            {
                int increment = (int)Math.Max(1, (1f - (float)npc.life / npc.lifeMax) * 4);
                if (FargoSoulsWorld.MasochistModeReal)
                {
                    increment++;
                }

                VulnerabilityTimer += increment;
                AttackTimer        += increment;

                if (VulnerabilityTimer > 1800) //next vuln phase
                {
                    VulnerabilityState = ++VulnerabilityState % 5;

                    VulnerabilityTimer = 0;
                    AttackTimer        = 0;
                    AttackMemory       = 0;

                    npc.netUpdate = true;
                    NetSync(npc);

                    if (FargoSoulsWorld.MasochistModeReal)
                    {
                        switch (VulnerabilityState)
                        {
                        case 0:     //melee
                            for (int i = 0; i < 3; i++)
                            {
                                NPC bodyPart = Main.npc[(int)npc.localAI[i]];

                                if (bodyPart.active && bodyPart.type == NPCID.MoonLordHead)
                                {
                                    for (int j = -3; j <= 3; j++)
                                    {
                                        FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(),
                                                                  bodyPart.Center, NPCID.SolarGoop, target: npc.target,
                                                                  velocity: -10f * Vector2.UnitY.RotatedBy(MathHelper.ToRadians(20 * j)));
                                    }
                                }
                            }
                            break;

                        case 1:     //ranged
                            if (Main.netMode != NetmodeID.MultiplayerClient)
                            {
                                Projectile.NewProjectile(
                                    npc.GetSource_FromThis(),
                                    npc.Center, Vector2.Zero,
                                    ModContent.ProjectileType <MoonLordVortexOld>(),
                                    40, 0f, Main.myPlayer, 0, npc.whoAmI);
                            }
                            break;

                        case 2:     //magic
                            if (Main.netMode != NetmodeID.MultiplayerClient)
                            {
                                for (int i = -1; i <= 1; i++)
                                {
                                    int p = Projectile.NewProjectile(
                                        npc.GetSource_FromThis(),
                                        npc.Center, Vector2.Zero,
                                        ModContent.ProjectileType <GlowLine>(),
                                        0, 0f, Main.myPlayer, 17f, npc.whoAmI);
                                    if (p != Main.maxProjectiles)
                                    {
                                        Main.projectile[p].localAI[0] = 950f * i;
                                        if (Main.netMode == NetmodeID.Server)
                                        {
                                            NetMessage.SendData(MessageID.SyncProjectile, number: p);
                                        }
                                    }
                                }
                            }
                            break;

                        case 3:     //summon
                            for (int i = 0; i < 3; i++)
                            {
                                NPC bodyPart = Main.npc[(int)npc.localAI[i]];

                                if (bodyPart.active)
                                {
                                    for (int j = -2; j <= 2; j++)
                                    {
                                        Vector2 vel = 9f * bodyPart.DirectionTo(Main.player[npc.target].Center).RotatedBy(MathHelper.Pi / 5 * j);
                                        FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(),
                                                                  bodyPart.Center, NPCID.AncientLight, 0,
                                                                  0f,
                                                                  (Main.rand.NextFloat() - 0.5f) * 0.3f * 6.28318548202515f / 60f,
                                                                  vel.X,
                                                                  vel.Y,
                                                                  npc.target,
                                                                  vel);
                                    }
                                }
                            }
                            break;

                        default:
                            if (Main.netMode != NetmodeID.MultiplayerClient)
                            {
                                const int   max              = 8;
                                const int   speed            = 8;
                                const float rotationModifier = 0.5f;
                                int         damage           = 40;
                                float       rotation         = 2f * (float)Math.PI / max;
                                Vector2     vel              = Vector2.UnitY * speed;
                                int         type             = ModContent.ProjectileType <Projectiles.MutantBoss.MutantSphereRing>();
                                for (int i = 0; i < max; i++)
                                {
                                    vel = vel.RotatedBy(rotation);
                                    Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, vel, type, damage, 0f, Main.myPlayer, rotationModifier, speed);
                                    Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, vel, type, damage, 0f, Main.myPlayer, -rotationModifier, speed);
                                }
                                SoundEngine.PlaySound(SoundID.Item84, npc.Center);
                            }
                            break;
                        }
                    }
                }
            }

            //because 1.4 is f*****g stupid and time freeze prevents custom skies from working I HATE 1.4
            if (Main.GameModeInfo.IsJourneyMode && CreativePowerManager.Instance.GetPower <CreativePowers.FreezeTime>().Enabled)
            {
                CreativePowerManager.Instance.GetPower <CreativePowers.FreezeTime>().SetPowerInfo(false);
            }

            if (!Main.dedServ && VulnerabilityTimer % 30 == 0 && NPC.FindFirstNPC(npc.type) == npc.whoAmI)
            {
                if (!SkyManager.Instance["FargowiltasSouls:MoonLordSky"].IsActive())
                {
                    SkyManager.Instance.Activate("FargowiltasSouls:MoonLordSky");
                }

                void HandleScene(string name)
                {
                    if (!Filters.Scene[$"FargowiltasSouls:{name}"].IsActive())
                    {
                        Filters.Scene.Activate($"FargowiltasSouls:{name}");
                    }
                }

                switch (VulnerabilityState)
                {
                case 0: HandleScene("Solar"); break;

                case 1: HandleScene("Vortex"); break;

                case 2: HandleScene("Nebula"); break;

                case 3:
                    HandleScene("Stardust");
                    if (VulnerabilityTimer < 120)     //so that player isn't punished for using weapons during prior phase
                    {
                        Main.LocalPlayer.GetModPlayer <EModePlayer>().MasomodeMinionNerfTimer = 0;
                    }
                    break;

                default: break;
                }
            }

            EModeUtils.DropSummon(npc, "CelestialSigil2", NPC.downedMoonlord, ref DroppedSummon, NPC.downedAncientCultist);

            return(result);
        }
Exemplo n.º 25
0
        public override bool PreAI(NPC npc)
        {
            EModeGlobalNPC.betsyBoss = npc.whoAmI;

            if (FargoSoulsWorld.SwarmActive)
            {
                return(true);
            }

            if (FargoSoulsWorld.MasochistModeReal)
            {
                for (int i = 0; i < 3; i++)
                {
                    Rectangle rectangle = new Rectangle((int)Main.screenPosition.X + Main.screenWidth / 3, (int)Main.screenPosition.Y + Main.screenHeight / 3, Main.screenWidth / 3, Main.screenHeight / 3);
                    CombatText.NewText(rectangle, new Color(100 + Main.rand.Next(150), 100 + Main.rand.Next(150), 100 + Main.rand.Next(150)), Main.rand.Next(new List <string> {
                        "CRINGE",
                        "NOT POGGERS",
                        "MONKAS",
                        "SHOW WINGS",
                        "AERIAL BANE POG",
                        "REAL BOSS WHEN?",
                        "#NOTMYMASOMODE",
                        "OOA BAD ANYWAY",
                        "COPE MALD SEETHE",
                        "GET REAL",
                        "GET FAKE",
                        "POGGERS",
                        "ResidentSleeper",
                        "If you can read this say 22",
                        "GuraSit",
                        "play calamity",
                        "play thorium",
                        "hardcore 1hp challenge when?",
                        "now do it with a copper shortsword",
                        "Zenith Yoyo?",
                        "guys how do i beat moon lord",
                        "GUYS I GOT TERRAPRISMA",
                        "how do i install this update",
                        "Hi YouTube!",
                        "<Message was deleted by staff>",
                        $"<User {Main.rand.Next(10)}{Main.rand.Next(10)}{Main.rand.Next(10)}{Main.rand.Next(10)}{Main.rand.Next(10)} was banned>",
                        $"<User {Main.rand.Next(10)}{Main.rand.Next(10)}{Main.rand.Next(10)}{Main.rand.Next(10)}{Main.rand.Next(10)} was muted>",
                    }), Main.rand.NextBool(), Main.rand.NextBool());
                }

                if (Main.rand.NextBool(30) && npc.HasPlayerTarget)
                {
                    switch (Main.rand.Next(12))
                    {
                    case 0:
                        if (!Main.dedServ)
                        {
                            SoundEngine.PlaySound(new SoundStyle("FargowiltasSouls/Sounds/Thunder"), Main.player[npc.target].Center);
                        }
                        break;

                    case 1:
                        SoundEngine.PlaySound(SoundID.ScaryScream, Main.player[npc.target].Center);     //arte scream
                        break;

                    case 2:
                        SoundEngine.PlaySound(SoundID.Roar, Main.player[npc.target].Center);
                        break;

                    case 3:
                        SoundEngine.PlaySound(SoundID.ForceRoarPitched, Main.player[npc.target].Center);     //eoc roar
                        break;

                    case 4:
                        if (!Main.dedServ)
                        {
                            SoundEngine.PlaySound(new SoundStyle("FargowiltasSouls/Sounds/Monster94"), Main.player[npc.target].Center);
                        }
                        break;

                    case 5:
                        if (!Main.dedServ)
                        {
                            SoundEngine.PlaySound(new SoundStyle("FargowiltasSouls/Sounds/Monster5")
                            {
                                Volume = 1.5f
                            }, Main.player[npc.target].Center);
                        }
                        break;

                    case 6:
                        if (!Main.dedServ)
                        {
                            SoundEngine.PlaySound(new SoundStyle("FargowiltasSouls/Sounds/Thunder")
                            {
                                Volume = 1.5f, Pitch = 1.5f
                            }, Main.player[npc.target].Center);
                        }
                        break;

                    case 7:
                        if (!Main.dedServ)
                        {
                            SoundEngine.PlaySound(new SoundStyle("FargowiltasSouls/Sounds/Zombie_104"), Main.player[npc.target].Center);
                        }
                        break;

                    case 8:
                        if (!Main.dedServ)
                        {
                            SoundEngine.PlaySound(new SoundStyle("FargowiltasSouls/Sounds/Monster70"), Main.player[npc.target].Center);
                        }
                        break;

                    case 9:
                        if (!Main.dedServ)
                        {
                            SoundEngine.PlaySound(new SoundStyle("FargowiltasSouls/Sounds/Railgun"), Main.player[npc.target].Center);
                        }
                        break;

                    case 10:
                        if (!Main.dedServ)
                        {
                            SoundEngine.PlaySound(new SoundStyle("FargowiltasSouls/Sounds/Navi"), Main.player[npc.target].Center);
                        }
                        break;

                    case 11:
                        if (!Main.dedServ)
                        {
                            SoundEngine.PlaySound(new SoundStyle("FargowiltasSouls/Sounds/ZaWarudo")
                            {
                                Volume = 1.5f
                            }, Main.player[npc.target].Center);
                        }
                        break;

                    default:
                        SoundEngine.PlaySound(SoundID.NPCDeath10, Main.player[npc.target].Center);
                        break;
                    }
                }
            }

            if (!InPhase2 && npc.life < npc.lifeMax / 2)
            {
                InPhase2 = true;
                SoundEngine.PlaySound(SoundID.Roar, npc.Center);
            }

            if (npc.ai[0] == 6f) //when approaching for roar
            {
                if (npc.ai[1] == 0f)
                {
                    npc.position += npc.velocity;
                }
                else if (npc.ai[1] == 1f)
                {
                    DoFuryRingAttack = true;
                }
            }

            if (DoFuryRingAttack)
            {
                npc.velocity = Vector2.Zero;

                if (FuryRingTimer == 0)
                {
                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, Vector2.Zero, ModContent.ProjectileType <GlowRingHollow>(), FargoSoulsUtil.ScaledProjectileDamage(npc.damage, 4f / 3), 0f, Main.myPlayer, 4);
                    }

                    if (FargoSoulsWorld.MasochistModeReal)
                    {
                        if (NPC.CountNPCS(NPCID.DD2DarkMageT3) < 3)
                        {
                            FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center, NPCID.DD2DarkMageT3, target: npc.target);
                        }
                    }
                }

                FuryRingTimer++;
                if (FuryRingTimer % 2 == 0)
                {
                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        float rotation = FuryRingShotRotationCounter;
                        if (FargoSoulsWorld.MasochistModeReal && FuryRingTimer >= 30 && FuryRingTimer <= 60)
                        {
                            rotation += 1; //staggers each wave instead of lining them up behind each other
                        }
                        Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, -Vector2.UnitY.RotatedBy(2 * Math.PI / 30 * rotation), ModContent.ProjectileType <BetsyFury>(), FargoSoulsUtil.ScaledProjectileDamage(npc.damage, 4f / 3), 0f, Main.myPlayer, npc.target);
                        Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, -Vector2.UnitY.RotatedBy(2 * Math.PI / 30 * -rotation), ModContent.ProjectileType <BetsyFury>(), FargoSoulsUtil.ScaledProjectileDamage(npc.damage, 4f / 3), 0f, Main.myPlayer, npc.target);
                    }
                    FuryRingShotRotationCounter++;
                }
                if (FuryRingTimer > (InPhase2 ? 90 : 30) + 2)
                {
                    DoFuryRingAttack            = false;
                    InFuryRingAttackCooldown    = true;
                    FuryRingTimer               = 0;
                    FuryRingShotRotationCounter = 0;
                }

                EModeGlobalNPC.Aura(npc, 1200, BuffID.WitheredWeapon, true, 226);
                EModeGlobalNPC.Aura(npc, 1200, BuffID.WitheredArmor, true, 226);
            }

            if (InFuryRingAttackCooldown)
            {
                EModeGlobalNPC.Aura(npc, 1200, BuffID.WitheredWeapon, true, 226);
                EModeGlobalNPC.Aura(npc, 1200, BuffID.WitheredArmor, true, 226);

                if (++FuryRingShotRotationCounter > 90)
                {
                    InFuryRingAttackCooldown    = false;
                    FuryRingTimer               = 0;
                    FuryRingShotRotationCounter = 0;
                }
                npc.position -= npc.velocity * 0.5f;
                if (FuryRingTimer % 2 == 0)
                {
                    return(false);
                }
            }

            if (!DD2Event.Ongoing && npc.HasPlayerTarget && (!Main.player[npc.target].active || Main.player[npc.target].dead || npc.Distance(Main.player[npc.target].Center) > 3000))
            {
                int p = Player.FindClosest(npc.Center, 0, 0); //extra despawn code for when summoned outside event
                if (p < 0 || !Main.player[p].active || Main.player[p].dead || npc.Distance(Main.player[p].Center) > 3000)
                {
                    npc.active = false;
                }
            }

            EModeUtils.DropSummon(npc, "BetsyEgg", FargoSoulsWorld.downedBetsy, ref DroppedSummon, NPC.downedGolemBoss);

            return(true);
        }
Exemplo n.º 26
0
        public override void AI()
        {
            if (!spawned)
            {
                spawned = true;

                NPC.TargetClosest(false);

                if (Main.netMode != NetmodeID.MultiplayerClient)
                {
                    head = FargoSoulsUtil.NPCExists(FargoSoulsUtil.NewNPCEasy(NPC.GetSource_FromThis(), NPC.Center, ModContent.NPCType <TrojanSquirrelHead>(), NPC.whoAmI, target: NPC.target));
                    arms = FargoSoulsUtil.NPCExists(FargoSoulsUtil.NewNPCEasy(NPC.GetSource_FromThis(), NPC.Center, ModContent.NPCType <TrojanSquirrelArms>(), NPC.whoAmI, target: NPC.target));
                }

                //drop summon
                if (FargoSoulsWorld.EternityMode && !FargoSoulsWorld.downedBoss[(int)FargoSoulsWorld.Downed.TrojanSquirrel] && Main.netMode != NetmodeID.MultiplayerClient)
                {
                    Item.NewItem(NPC.GetSource_Loot(), Main.player[NPC.target].Hitbox, ModContent.ItemType <SquirrelCoatofArms>());
                }

                //start by jumping
                NPC.ai[0] = 1f;
                NPC.ai[3] = 1f;

                for (int i = 0; i < 80; i++)
                {
                    int d = Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Smoke, NPC.velocity.X, NPC.velocity.Y, 50, default(Color), 4f);
                    Main.dust[d].velocity.Y -= 1.5f;
                    Main.dust[d].velocity   *= 1.5f;
                    Main.dust[d].noGravity   = true;
                }

                FargoSoulsUtil.GrossVanillaDodgeDust(NPC);

                SoundEngine.PlaySound(SoundID.Roar, Main.player[NPC.target].Center);
            }

            Player player = Main.player[NPC.target];

            NPC.direction = NPC.spriteDirection = NPC.Center.X < player.Center.X ? 1 : -1;

            bool despawn = false;

            switch ((int)NPC.ai[0])
            {
            case 0:     //mourning wood movement
            {
                Vector2 target = player.Bottom - Vector2.UnitY;
                if (NPC.localAI[0] > 0)         //doing running attack
                {
                    NPC.localAI[0] -= 1f;

                    float distance     = NPC.Center.X - target.X;
                    bool  passedTarget = Math.Sign(distance) == NPC.localAI[1];
                    if (passedTarget && Math.Abs(distance) > 160)
                    {
                        NPC.localAI[0] = 0f;
                    }

                    target = new Vector2(NPC.Center.X + 256f * NPC.localAI[1], target.Y);

                    if (NPC.localAI[0] == 0f)
                    {
                        NPC.TargetClosest(false);
                    }

                    if (FargoSoulsWorld.EternityMode && head == null && NPC.localAI[0] % 3 == 0 && Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        int p = Projectile.NewProjectile(NPC.GetSource_FromThis(), NPC.Top.X, NPC.Top.Y, Main.rand.NextFloat(-5, 5), Main.rand.NextFloat(-5),
                                                         Main.rand.Next(326, 329), FargoSoulsUtil.ScaledProjectileDamage(NPC.damage), 0f, Main.myPlayer);
                        if (p != Main.maxProjectiles)
                        {
                            Main.projectile[p].timeLeft = 90;
                        }
                    }
                }
                else if (!NPC.HasValidTarget || NPC.Distance(player.Center) > (FargoSoulsWorld.EternityMode ? 1600 : 2400))
                {
                    target = NPC.Center + new Vector2(256f * Math.Sign(NPC.Center.X - player.Center.X), -128);

                    NPC.TargetClosest(false);

                    despawn = true;
                }

                if (Math.Abs(NPC.velocity.Y) < 0.05f && NPC.localAI[3] >= 2)
                {
                    if (NPC.localAI[3] == 2)
                    {
                        NPC.localAI[3] = 0f;
                    }
                    else
                    {
                        NPC.localAI[3] -= 1;
                        NPC.ai[0]       = 1f;
                        NPC.ai[3]       = 1f;
                    }

                    SoundEngine.PlaySound(SoundID.Item14, NPC.Center);

                    ExplodeAttack();
                }

                bool goFast = despawn || NPC.localAI[0] > 0;
                Movement(target, goFast);

                if (arms != null && (NPC.localAI[3] == -1 || NPC.localAI[3] == 1))         //from arms
                {
                    NPC.direction = NPC.spriteDirection = (int)NPC.localAI[3];
                }

                bool canDoAttacks = FargoSoulsWorld.EternityMode && !goFast;
                if (canDoAttacks)         //decide next action
                {
                    float increment = 1f;
                    if (head == null)
                    {
                        increment += 0.5f;
                    }
                    if (arms == null)
                    {
                        increment += 0.5f;
                    }
                    if (FargoSoulsWorld.MasochistModeReal)
                    {
                        increment += 1f;
                    }
                    if (NPC.dontTakeDamage)
                    {
                        increment /= 2;
                    }

                    if (target.Y > NPC.Top.Y)
                    {
                        NPC.ai[1] += increment;
                    }
                    else
                    {
                        NPC.ai[2] += increment;
                    }

                    if (Math.Abs(NPC.velocity.Y) < 0.05f)
                    {
                        //its structured like this to ensure body picks the right attack for the situation after being delayed by head/arms
                        bool canProceed = !(head != null && head.ai[0] != 0) && !(arms != null && arms.ai[0] != 0);

                        int threshold = 300;
                        if (NPC.ai[1] > threshold)
                        {
                            if (canProceed)
                            {
                                NPC.ai[0] = 1f;
                                NPC.ai[1] = 0f;
                                //NPC.ai[2] = 0f;
                                NPC.ai[3]      = 0f;
                                NPC.localAI[0] = 0f;
                                NPC.netUpdate  = true;
                            }
                            else
                            {
                                NPC.ai[1] -= 10f;
                            }
                        }

                        if (NPC.ai[2] > threshold)
                        {
                            if (canProceed)
                            {
                                NPC.ai[0] = 1f;
                                //NPC.ai[1] = 0f;
                                NPC.ai[2]      = 0f;
                                NPC.ai[3]      = 1f;
                                NPC.localAI[0] = 0f;
                                NPC.netUpdate  = true;
                            }
                            else
                            {
                                NPC.ai[2] -= 10f;
                            }
                        }
                    }
                }
            }
            break;

            case 1:     //telegraph something
            {
                NPC.velocity.X *= 0.9f;

                TileCollision(player.Bottom.Y - 1 > NPC.Bottom.Y, Math.Abs(player.Center.X - NPC.Center.X) < NPC.width / 2 && NPC.Bottom.Y < player.Bottom.Y - 1);

                int threshold = 120;
                if (FargoSoulsWorld.EternityMode)
                {
                    if (head == null)
                    {
                        threshold -= 20;
                    }
                    if (arms == null)
                    {
                        threshold -= 20;
                    }
                    if (head == null && arms == null)
                    {
                        threshold -= 30;
                    }
                    if (NPC.localAI[3] >= 2)
                    {
                        threshold -= 20;
                    }
                }
                if (FargoSoulsWorld.MasochistModeReal)
                {
                    threshold -= 20;
                }

                if (++NPC.localAI[0] > threshold)
                {
                    NPC.localAI[0] = 0f;
                    NPC.netUpdate  = true;

                    if (NPC.ai[3] == 0f)
                    {
                        NPC.ai[0] = 0f;

                        NPC.localAI[0] = 300f;
                        NPC.localAI[1] = Math.Sign(player.Center.X - NPC.Center.X);
                        NPC.localAI[2] = player.Center.X;
                    }
                    else
                    {
                        NPC.ai[0] = 2f;
                    }
                }
            }
            break;

            case 2:     //jump
            {
                const float gravity = 0.4f;
                float       time    = FargoSoulsWorld.EternityMode && arms == null ? 60f : 90f;

                if (NPC.localAI[0]++ == 0)
                {
                    Vector2 distance = player.Top - NPC.Bottom;

                    if (FargoSoulsWorld.EternityMode && arms == null)
                    {
                        distance.X += NPC.width * Math.Sign(player.Center.X - NPC.Center.X);

                        if (NPC.localAI[3] < 2)
                        {
                            NPC.localAI[3] = 2;         //flag to stomp again on landing
                            if (head == null)
                            {
                                NPC.localAI[3] += 2;         //flag to do more stomps
                            }
                        }

                        ExplodeAttack();
                    }

                    distance.X   = distance.X / time;
                    distance.Y   = distance.Y / time - 0.5f * gravity * time;
                    NPC.velocity = distance;

                    NPC.netUpdate = true;

                    SoundEngine.PlaySound(SoundID.Item14, NPC.Center);
                }
                else
                {
                    NPC.velocity.Y += gravity;
                }

                if (NPC.localAI[0] > time)
                {
                    NPC.TargetClosest(false);

                    NPC.velocity.X = Utils.Clamp(NPC.velocity.X, -20, 20);
                    NPC.velocity.Y = Utils.Clamp(NPC.velocity.Y, -10, 10);

                    NPC.ai[0]      = 0f;
                    NPC.localAI[0] = 0f;
                    NPC.netUpdate  = true;
                }
            }
            break;

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

            if (despawn)
            {
                if (NPC.timeLeft > 60)
                {
                    NPC.timeLeft = 60;
                }
            }
            else
            {
                if (NPC.timeLeft < 600)
                {
                    NPC.timeLeft = 600;
                }
            }

            if (head == null)
            {
                Vector2 pos = NPC.Top;
                pos.X += 2f * 16f * NPC.direction;
                pos.Y -= 8f;

                int width  = 4 * 16;
                int height = 2 * 16;

                pos.X -= width / 2f;
                pos.Y -= height / 2f;

                for (int i = 0; i < 3; i++)
                {
                    int d = Dust.NewDust(pos, width, height, DustID.Smoke, NPC.velocity.X, NPC.velocity.Y, 50, default(Color), 2.5f);
                    Main.dust[d].velocity.Y -= 1.5f;
                    Main.dust[d].velocity   *= 1.5f;
                    Main.dust[d].noGravity   = true;
                }

                if (Main.rand.NextBool(3))
                {
                    int d = Dust.NewDust(pos, width, height, DustID.Torch, NPC.velocity.X * 0.4f, NPC.velocity.Y * 0.4f, 100, default(Color), 2.5f);
                    Main.dust[d].noGravity   = true;
                    Main.dust[d].velocity.Y -= 3f;
                    Main.dust[d].velocity   *= 1.5f;
                }
            }
            else
            {
                lifeMaxHead = head.lifeMax;
                head        = FargoSoulsUtil.NPCExists(head.whoAmI, ModContent.NPCType <TrojanSquirrelHead>());
            }

            if (arms == null)
            {
                Vector2 pos = NPC.Center;
                pos.X -= 16f * NPC.direction;
                pos.Y -= 3f * 16f;

                int width  = 2 * 16;
                int height = 2 * 16;

                pos.X -= width / 2f;
                pos.Y -= height / 2f;

                for (int i = 0; i < 2; i++)
                {
                    int d = Dust.NewDust(pos, width, height, DustID.Smoke, NPC.velocity.X, NPC.velocity.Y, 50, default(Color), 1.5f);
                    Main.dust[d].noGravity = true;
                }

                if (Main.rand.NextBool())
                {
                    int d2 = Dust.NewDust(pos, width, height, DustID.Torch, NPC.velocity.X * 0.4f, NPC.velocity.Y * 0.4f, 100, default(Color), 3f);
                    Main.dust[d2].noGravity = true;
                }
            }
            else
            {
                lifeMaxArms = arms.lifeMax;
                arms        = FargoSoulsUtil.NPCExists(arms.whoAmI, ModContent.NPCType <TrojanSquirrelArms>());
            }

            if (NPC.life < NPC.lifeMax / 2 && Main.rand.NextBool(3))
            {
                int d = Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Smoke, NPC.velocity.X, NPC.velocity.Y, 50, default(Color), 4f);
                Main.dust[d].velocity.Y -= 1.5f;
                Main.dust[d].velocity   *= 1.5f;
                Main.dust[d].noGravity   = true;
            }

            if (FargoSoulsWorld.EternityMode)
            {
                bool wasImmune = NPC.dontTakeDamage;
                NPC.dontTakeDamage = NPC.life < NPC.lifeMax / 2 && (head != null || arms != null);

                if (wasImmune != NPC.dontTakeDamage)
                {
                    for (int i = 0; i < 6; i++)
                    {
                        ExplodeDust(NPC.position + new Vector2(Main.rand.Next(NPC.width), Main.rand.Next(NPC.height)));
                    }
                }
            }
            else
            {
                NPC.dontTakeDamage = false;
            }
        }
Exemplo n.º 27
0
        public override bool PreAI(NPC npc)
        {
            EModeGlobalNPC.queenSlimeBoss = npc.whoAmI;

            if (FargoSoulsWorld.SwarmActive)
            {
                return(true);
            }

            void TrySpawnMinions(ref bool check, double threshold)
            {
                if (!check && npc.life < npc.lifeMax * threshold)
                {
                    check = true;

                    FargoSoulsUtil.PrintLocalization($"Mods.{mod.Name}.Message.GelatinSubjects", new Color(175, 75, 255));

                    for (int i = 0; i < 6; i++)
                    {
                        FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center, ModContent.NPCType <GelatinSubject>(), npc.whoAmI, target: npc.target,
                                                  velocity: Main.rand.NextFloat(8f) * npc.DirectionFrom(Main.player[npc.target].Center).RotatedByRandom(MathHelper.PiOver2));
                    }

                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, Vector2.Zero, ModContent.ProjectileType <GlowRing>(), 0, 0f, Main.myPlayer, npc.whoAmI, npc.type);
                    }
                }
            }

            TrySpawnMinions(ref SpawnedMinions1, 0.75);
            TrySpawnMinions(ref SpawnedMinions2, 0.25);

            GelatinSubjectDR = NPC.AnyNPCs(ModContent.NPCType <GelatinSubject>());
            npc.HitSound     = GelatinSubjectDR ? SoundID.Item27 : SoundID.NPCHit1;

            //ai0
            //0 = default
            //3 = chase?
            //4 = stomp
            //5 = shooty gels

            if (npc.ai[0] == 5) //when shooting, p1 and p2
            {
                if (NPC.AnyNPCs(ModContent.NPCType <GelatinSubject>()))
                {
                    npc.ai[1] -= 0.5f;
                }

                if (npc.ai[1] == 45 && --SpikeCounter < 0) //every few shots
                {
                    SpikeCounter = 4;
                    NetSync(npc);

                    SoundEngine.PlaySound(SoundID.Roar, npc.Center);

                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        Vector2 focus = Main.player[npc.target].Center;
                        for (int i = 0; i < 50; i++)
                        {
                            Tile tile = Framing.GetTileSafely(focus);
                            if (tile.HasUnactuatedTile && (Main.tileSolid[tile.TileType] || Main.tileSolidTop[tile.TileType]))
                            {
                                break;
                            }
                            focus.Y += 16f;
                        }
                        focus.Y -= Player.defaultHeight / 2f;

                        for (int i = -5; i <= 5; i++)
                        {
                            Vector2 targetPos = focus;
                            targetPos.X += 330 * i;

                            float   minionTravelTime = StompTravelTime + Main.rand.Next(30);
                            float   minionGravity    = 0.4f;
                            Vector2 vel = targetPos - npc.Center;
                            vel.X = vel.X / minionTravelTime;
                            vel.Y = vel.Y / minionTravelTime - 0.5f * minionGravity * minionTravelTime;

                            FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center, ModContent.NPCType <GelatinSlime>(), npc.whoAmI, minionTravelTime, minionGravity, vel.X, vel.Y, target: npc.target);
                        }
                    }
                }
            }

            if (npc.life > npc.lifeMax / 2) //phase 1
            {
                if (StompTimer > 0 || (npc.ai[0] == 0 && npc.velocity.Y == 0))
                {
                    if (StompTimer < 0)
                    {
                        StompTimer++;
                    }
                    else
                    {
                        npc.ai[0] = 4; //activates trail visual
                    }
                    if (!Stompy(npc))
                    {
                        return(false);
                    }
                }
            }
            else //phase 2
            {
                npc.defense = npc.defDefense / 2;

                if (RainTimer < 0)
                {
                    RainTimer++;
                }

                if (RainTimer <= 0 && StompTimer < 0) //dont run timer during rain attack
                {
                    StompTimer++;
                }

                if (npc.ai[0] == 0) //basic flying ai
                {
                    if (RainTimer == 0)
                    {
                        if (npc.velocity.Y < 0)
                        {
                            npc.position.Y += npc.velocity.Y;
                        }

                        npc.ai[1] -= 1; //dont progress to next ai

                        if (npc.HasValidTarget && Math.Abs(npc.Center.Y - (Main.player[npc.target].Center.Y - 250)) < 32)
                        {
                            RainTimer = 1; //begin attack
                            NetSync(npc);

                            npc.netUpdate = true;

                            SoundEngine.PlaySound(SoundID.Roar, npc.Center);

                            if (Main.netMode != NetmodeID.MultiplayerClient)
                            {
                                Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, Vector2.Zero, ModContent.ProjectileType <GlowRing>(), 0, 0f, Main.myPlayer, npc.whoAmI, -16);
                            }
                        }
                    }
                    else if (RainTimer > 0) //actually doing rain
                    {
                        npc.velocity.X *= 0.9f;

                        npc.ai[1] -= 1f; //dont progress ai

                        RainTimer++;

                        const int delay = 45;
                        const int timeBeforeStreamsMove = 45;
                        const int maxAttackTime         = 480;
                        int       attackTimer           = RainTimer - delay - timeBeforeStreamsMove;
                        if (attackTimer < 0)
                        {
                            attackTimer = 0;
                        }

                        if (RainTimer == delay)
                        {
                            RainDirection = Math.Sign(Main.player[npc.target].Center.X - npc.Center.X);
                        }

                        if (RainTimer > delay && RainTimer < delay + maxAttackTime && RainTimer % 5 == 0)
                        {
                            const float maxWavy    = 200;
                            Vector2     focusPoint = new Vector2(npc.Center.X, Math.Min(npc.Center.Y, Main.player[npc.target].Center.Y));
                            focusPoint.X += maxWavy * RainDirection * (float)Math.Sin(Math.PI * 2f / maxAttackTime * attackTimer * 1.5f);
                            focusPoint.Y -= 500;

                            for (int i = -4; i <= 4; i++)
                            {
                                Vector2 spawnPos = focusPoint + Main.rand.NextVector2Circular(32, 32);
                                spawnPos.X += 330 * i;
                                if (Main.netMode != NetmodeID.MultiplayerClient)
                                {
                                    Projectile.NewProjectile(npc.GetSource_FromThis(), spawnPos, 8f * Vector2.UnitY,
                                                             ProjectileID.QueenSlimeMinionBlueSpike, FargoSoulsUtil.ScaledProjectileDamage(npc.damage), 0f, Main.myPlayer);
                                }
                            }
                        }

                        bool endAttack = RainTimer > delay + maxAttackTime + 90;
                        if (npc.Distance(Main.player[npc.target].Center) > 1200)
                        {
                            endAttack = true;

                            StompTimer   = 0;
                            StompCounter = -3; //enraged super stomps
                        }

                        if (!npc.HasValidTarget)
                        {
                            npc.TargetClosest(false);
                            if (!npc.HasValidTarget)
                            {
                                endAttack = true;
                            }
                        }

                        if (endAttack)
                        {
                            RainTimer     = -1000;
                            npc.netUpdate = true;
                            NetSync(npc);

                            if (StompTimer == 0) //transition directly to stompy if ready
                            {
                                npc.ai[0] = 4f;
                                npc.ai[1] = 0f;
                            }
                        }
                    }
                    else
                    {
                        npc.ai[1] += 1; //proceed to next ais faster
                    }
                }
                else if (npc.ai[0] == 4) //stompy
                {
                    if (!Stompy(npc))
                    {
                        return(false);
                    }
                }
                else if (npc.ai[0] == 5) //when shooting
                {
                    //be careful to stay above player
                    if (npc.HasValidTarget && npc.Bottom.Y > Main.player[npc.target].Top.Y - 80 && npc.velocity.Y > -8f)
                    {
                        npc.velocity.Y -= 0.8f;
                    }
                }
            }

            //FargoSoulsUtil.PrintAI(npc);

            EModeUtils.DropSummon(npc, "JellyCrystal", NPC.downedQueenSlime, ref DroppedSummon, Main.hardMode);

            return(true);
        }
Exemplo n.º 28
0
        public override bool PreAI(NPC npc)
        {
            EModeGlobalNPC.retiBoss = npc.whoAmI;

            if (FargoSoulsWorld.SwarmActive)
            {
                return(true);
            }

            NPC spazmatism = FargoSoulsUtil.NPCExists(EModeGlobalNPC.spazBoss, NPCID.Spazmatism);

            if (FargoSoulsWorld.MasochistModeReal && spazmatism == null && npc.HasValidTarget && ++RespawnTimer > 600)
            {
                RespawnTimer = 0;
                if (Main.netMode != NetmodeID.MultiplayerClient)
                {
                    int n = FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromThis(), npc.Center + new Vector2(Main.rand.NextFloat(-1000, 1000), Main.rand.NextFloat(-800, -600)), NPCID.Spazmatism, target: npc.target);
                    if (n != Main.maxNPCs)
                    {
                        Main.npc[n].life = Main.npc[n].lifeMax / 4;
                        if (Main.netMode == NetmodeID.Server)
                        {
                            NetMessage.SendData(MessageID.SyncNPC, number: n);
                        }
                        string text = Language.GetTextValue($"Mods.{mod.Name}.Message.TwinsRevive");
                        FargoSoulsUtil.PrintText($"{Main.npc[n].FullName} {text}", new Color(175, 75, 255));
                    }
                }
            }

            if (!ForcedPhase2OnSpawn) //start phase 2
            {
                ForcedPhase2OnSpawn = true;
                npc.ai[0]           = 1f;
                npc.ai[1]           = 0.0f;
                npc.ai[2]           = 0.0f;
                npc.ai[3]           = 0.0f;
                npc.netUpdate       = true;
            }

            if (npc.life <= npc.lifeMax / 2 || npc.dontTakeDamage)
            {
                npc.dontTakeDamage = npc.life == 1 || !npc.HasValidTarget;
                if (npc.life != 1 && npc.HasValidTarget)
                {
                    npc.dontTakeDamage = false;
                }
                //become vulnerable again when both twins at low life
                if (npc.dontTakeDamage && npc.HasValidTarget && (spazmatism == null || spazmatism.life == 1))
                {
                    npc.dontTakeDamage = false;
                }
            }

            if (Main.dayTime)
            {
                if (npc.velocity.Y > 0)
                {
                    npc.velocity.Y = 0;
                }

                npc.velocity.Y    -= 0.5f;
                npc.dontTakeDamage = true;

                if (spazmatism != null)
                {
                    if (npc.timeLeft < 60)
                    {
                        npc.timeLeft = 60;
                    }

                    if (spazmatism.timeLeft < 60)
                    {
                        spazmatism.timeLeft = 60;
                    }

                    npc.TargetClosest(false);
                    spazmatism.TargetClosest(false);
                    if (npc.Distance(Main.player[npc.target].Center) > 2000 && spazmatism.Distance(Main.player[spazmatism.target].Center) > 2000)
                    {
                        if (Main.netMode != NetmodeID.MultiplayerClient)
                        {
                            npc.active = false;
                            if (Main.netMode == NetmodeID.Server)
                            {
                                NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, npc.whoAmI);
                            }
                            spazmatism.active = false;
                            if (Main.netMode == NetmodeID.Server)
                            {
                                NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, EModeGlobalNPC.spazBoss);
                            }
                        }
                    }
                }

                return(true);
            }

            if (npc.ai[0] < 4f) //going to phase 3
            {
                if (npc.life <= npc.lifeMax / 2)
                {
                    //npc.ai[0] = 4f;
                    npc.ai[0]     = 604f; //initiate spin immediately
                    npc.netUpdate = true;
                    SoundEngine.PlaySound(SoundID.Roar, npc.Center);

                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, Vector2.Zero, ModContent.ProjectileType <GlowRingHollow>(), 0, 0f, Main.myPlayer, 11, npc.whoAmI);
                    }
                }
            }
            else //in phase 3
            {
                if (FargoSoulsWorld.MasochistModeReal && npc.life == 1 && --DarkStarTimer < 0) //when brought to 1hp, begin shooting dark stars
                {
                    DarkStarTimer = 240;
                    if (Main.netMode != NetmodeID.MultiplayerClient && npc.HasPlayerTarget)
                    {
                        Vector2 distance = Main.player[npc.target].Center - npc.Center;
                        distance.Normalize();
                        distance *= 10f;
                        for (int i = 0; i < 12; i++)
                        {
                            Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, distance.RotatedBy(2 * Math.PI / 12 * i),
                                                     ModContent.ProjectileType <DarkStar>(), FargoSoulsUtil.ScaledProjectileDamage(npc.damage, 0.8f), 0f, Main.myPlayer);
                        }
                    }
                }

                //dust code
                if (Main.rand.Next(4) < 3)
                {
                    int dust = Dust.NewDust(npc.position - new Vector2(2f, 2f), npc.width + 4, npc.height + 4, 90, npc.velocity.X * 0.4f, npc.velocity.Y * 0.4f, 100, default(Color), 3.5f);
                    Main.dust[dust].noGravity   = true;
                    Main.dust[dust].velocity   *= 1.8f;
                    Main.dust[dust].velocity.Y -= 0.5f;
                    if (Main.rand.NextBool(4))
                    {
                        Main.dust[dust].noGravity = false;
                        Main.dust[dust].scale    *= 0.5f;
                    }
                }

                if (npc.localAI[1] >= (npc.ai[1] == 0 ? 175 : 55)) //hijacking vanilla laser code
                {
                    npc.localAI[1] = 0;
                    Vector2 vel = npc.DirectionTo(Main.player[npc.target].Center);
                    Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center + (npc.width - 24) * vel, vel, ModContent.ProjectileType <DarkStarTwins>(), FargoSoulsUtil.ScaledProjectileDamage(npc.damage), 0f, Main.myPlayer, npc.target);
                }

                if (DeathrayState == 0 || DeathrayState == 3) //not doing deathray, grow arena
                {
                    AuraRadiusCounter--;
                    if (AuraRadiusCounter < 0)
                    {
                        AuraRadiusCounter = 0;
                    }
                }
                else //doing deathray, shrink arena
                {
                    AuraRadiusCounter++;
                    if (AuraRadiusCounter > 180)
                    {
                        AuraRadiusCounter = 180;
                    }
                }

                float auraDistance = 2000 - 1200 * AuraRadiusCounter / 180f;
                if (FargoSoulsWorld.MasochistModeReal)
                {
                    auraDistance *= 0.75f;
                }
                if (auraDistance < 2000)
                {
                    EModeGlobalNPC.Aura(npc, auraDistance, true, DustID.Torch, default, ModContent.BuffType <Oiled>(), BuffID.OnFire, BuffID.Burning);
Exemplo n.º 29
0
        public override bool PreAI(NPC npc)
        {
            EModeGlobalNPC.brainBoss = npc.whoAmI;

            if (FargoSoulsWorld.SwarmActive)
            {
                return(base.PreAI(npc));
            }

            if (!npc.HasValidTarget || npc.Distance(Main.player[npc.target].Center) > 3000)
            {
                npc.velocity.Y += 0.75f;
                if (npc.timeLeft > 120)
                {
                    npc.timeLeft = 120;
                }
            }

            if (npc.alpha > 0 && (npc.ai[0] == 2 || npc.ai[0] == -3) && npc.HasValidTarget) //stay at a minimum distance
            {
                const float safeRange = 360;

                /*Vector2 stayAwayFromHere = Main.player[npc.target].Center + Main.player[npc.target].velocity * 30f;
                 * if (npc.Distance(stayAwayFromHere) < safeRange)
                 *  npc.Center = stayAwayFromHere + npc.DirectionFrom(stayAwayFromHere) * safeRange;*/
                Vector2 stayAwayFromHere = Main.player[npc.target].Center;
                if (npc.Distance(stayAwayFromHere) < safeRange)
                {
                    npc.Center = stayAwayFromHere + npc.DirectionFrom(stayAwayFromHere) * safeRange;
                }
            }

            if (EnteredPhase2)
            {
                if (npc.buffType[0] != 0) //constant debuff cleanse
                {
                    npc.buffImmune[npc.buffType[0]] = true;
                    npc.DelBuff(0);
                }

                void TelegraphConfusion(Vector2 spawn)
                {
                    Projectile.NewProjectile(npc.GetSource_FromThis(), spawn, Vector2.Zero, ModContent.ProjectileType <GlowRingHollow>(), 0, 0f, Main.myPlayer, 8, 180);
                    Projectile.NewProjectile(npc.GetSource_FromThis(), spawn, Vector2.Zero, ModContent.ProjectileType <GlowRingHollow>(), 0, 0f, Main.myPlayer, 8, 200);
                    Projectile.NewProjectile(npc.GetSource_FromThis(), spawn, Vector2.Zero, ModContent.ProjectileType <GlowRingHollow>(), 0, 0f, Main.myPlayer, 8, 220);
                };

                void LaserSpread(Vector2 spawn)
                {
                    if (npc.HasValidTarget && Main.netMode != NetmodeID.MultiplayerClient) //laser spreads from each illusion
                    {
                        int max         = FargoSoulsWorld.MasochistModeReal ? 7 : 3;
                        int degree      = FargoSoulsWorld.MasochistModeReal ? 2 : 3;
                        int laserDamage = FargoSoulsUtil.ScaledProjectileDamage(npc.damage, 4f / 3);

                        Projectile.NewProjectile(npc.GetSource_FromThis(), spawn, new Vector2(0, -4), ModContent.ProjectileType <BrainofConfusion>(), 0, 0, Main.myPlayer);
                        for (int i = -max; i <= max; i++)
                        {
                            Projectile.NewProjectile(npc.GetSource_FromThis(), spawn, 0.2f * Main.player[npc.target].DirectionFrom(spawn).RotatedBy(MathHelper.ToRadians(degree) * i), ModContent.ProjectileType <DestroyerLaser>(), laserDamage, 0f, Main.myPlayer);
                        }
                    }
                };

                int confusionThreshold = FargoSoulsWorld.MasochistModeReal ? 240 : 300;

                if (--ConfusionTimer < 0)
                {
                    ConfusionTimer = confusionThreshold;

                    if (Main.player[npc.target].HasBuff(BuffID.Confused))
                    {
                        SoundEngine.PlaySound(SoundID.ForceRoarPitched, npc.Center);
                        TelegraphConfusion(npc.Center);

                        IllusionTimer = 120 + 90;

                        if (Main.netMode != NetmodeID.MultiplayerClient)
                        {
                            int type  = ModContent.ProjectileType <BrainIllusionProj>(); //make illusions attack
                            int alpha = (int)(255f * npc.life / npc.lifeMax);

                            void SpawnClone(Vector2 center)
                            {
                                int n = NPC.NewNPC(npc.GetSource_FromAI(), (int)center.X, (int)center.Y, ModContent.NPCType <BrainIllusionAttack>(), npc.whoAmI, npc.whoAmI, alpha);

                                if (n != Main.maxNPCs)
                                {
                                    NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n);
                                }
                            }

                            foreach (Projectile p in Main.projectile.Where(p => p.active && p.type == type && p.ai[0] == npc.whoAmI && p.ai[1] == 0f))
                            {
                                if (p.Distance(Main.player[npc.target].Center) < 1000)
                                {
                                    //p.ai[1] = 1f;
                                    //p.netUpdate = true;

                                    SpawnClone(p.Center);
                                }
                                p.Kill();
                            }

                            Vector2 offset   = npc.Center - Main.player[npc.target].Center;
                            Vector2 spawnPos = Main.player[npc.target].Center;

                            SpawnClone(new Vector2(spawnPos.X + offset.X, spawnPos.Y + offset.Y));
                            SpawnClone(new Vector2(spawnPos.X + offset.X, spawnPos.Y - offset.Y));
                            SpawnClone(new Vector2(spawnPos.X - offset.X, spawnPos.Y + offset.Y));
                            SpawnClone(new Vector2(spawnPos.X - offset.X, spawnPos.Y - offset.Y));
                        }
                    }
                    else
                    {
                        SoundEngine.PlaySound(SoundID.Roar, npc.Center);

                        Vector2 offset   = npc.Center - Main.player[npc.target].Center;
                        Vector2 spawnPos = Main.player[npc.target].Center;

                        TelegraphConfusion(new Vector2(spawnPos.X + offset.X, spawnPos.Y + offset.Y));
                        TelegraphConfusion(new Vector2(spawnPos.X + offset.X, spawnPos.Y - offset.Y));
                        TelegraphConfusion(new Vector2(spawnPos.X - offset.X, spawnPos.Y + offset.Y));
                        TelegraphConfusion(new Vector2(spawnPos.X - offset.X, spawnPos.Y - offset.Y));
                    }

                    npc.netUpdate = true;
                    NetSync(npc);
                }
                else if (ConfusionTimer == confusionThreshold - 60)
                {
                    //npc.netUpdate = true; //disabled because might be causing mp issues???
                    //NetSync(npc);

                    if (!Main.player[npc.target].HasBuff(BuffID.Confused))
                    {
                        Vector2 offset   = npc.Center - Main.player[npc.target].Center;
                        Vector2 spawnPos = Main.player[npc.target].Center;

                        LaserSpread(new Vector2(spawnPos.X + offset.X, spawnPos.Y + offset.Y));
                        LaserSpread(new Vector2(spawnPos.X + offset.X, spawnPos.Y - offset.Y));
                        LaserSpread(new Vector2(spawnPos.X - offset.X, spawnPos.Y + offset.Y));
                        LaserSpread(new Vector2(spawnPos.X - offset.X, spawnPos.Y - offset.Y));
                    }

                    if (npc.Distance(Main.LocalPlayer.Center) < 3000 && !Main.LocalPlayer.HasBuff(BuffID.Confused)) //inflict confusion
                    {
                        FargoSoulsUtil.AddDebuffFixedDuration(Main.LocalPlayer, BuffID.Confused, confusionThreshold + 5);
                    }
                }

                if (--IllusionTimer < 0) //spawn illusions
                {
                    IllusionTimer = Main.rand.Next(5, 11);
                    if (npc.life > npc.lifeMax / 2)
                    {
                        IllusionTimer += 5;
                    }
                    if (npc.life < npc.lifeMax / 10)
                    {
                        IllusionTimer -= 2;
                    }
                    if (FargoSoulsWorld.MasochistModeReal)
                    {
                        IllusionTimer -= 2;
                    }

                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        Vector2 spawn = Main.player[npc.target].Center + Main.rand.NextVector2CircularEdge(1200f, 1200f);
                        Vector2 speed = Main.player[npc.target].Center + Main.player[npc.target].velocity * 45f + Main.rand.NextVector2Circular(-600f, 600f) - spawn;
                        speed = Vector2.Normalize(speed) * Main.rand.NextFloat(12f, 48f);
                        Projectile.NewProjectile(npc.GetSource_FromThis(), spawn, speed, ModContent.ProjectileType <BrainIllusionProj>(), FargoSoulsUtil.ScaledProjectileDamage(npc.damage, 4f / 3), 0f, Main.myPlayer, npc.whoAmI);
                    }
                }

                if (IllusionTimer > 60)
                {
                    if (npc.ai[0] == -1f && npc.localAI[1] < 80) //force a tp
                    {
                        npc.localAI[1] = 80f;
                    }
                    if (npc.ai[0] == -3f && npc.ai[3] > 200) //stay invis
                    {
                        npc.dontTakeDamage = true;
                        npc.ai[0]          = -3f;
                        npc.ai[3]          = 255;
                        npc.alpha          = 255;
                        return(false);
                    }
                }
            }
            else if (!npc.dontTakeDamage)
            {
                EnteredPhase2 = true;

                if (Main.netMode != NetmodeID.MultiplayerClient) //spawn illusions
                {
                    bool recolor = SoulConfig.Instance.BossRecolors && FargoSoulsWorld.EternityMode;
                    int  type    = recolor ? ModContent.NPCType <BrainIllusion2>() : ModContent.NPCType <BrainIllusion>();

                    FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center, type, npc.whoAmI, npc.whoAmI, -1, 1);
                    FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center, type, npc.whoAmI, npc.whoAmI, 1, -1);
                    FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center, type, npc.whoAmI, npc.whoAmI, 1, 1);

                    FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), npc.Center, ModContent.NPCType <BrainClone>(), npc.whoAmI);

                    for (int i = 0; i < Main.maxProjectiles; i++) //clear old golden showers
                    {
                        if (Main.projectile[i].active && Main.projectile[i].type == ModContent.ProjectileType <GoldenShowerHoming>())
                        {
                            Main.projectile[i].Kill();
                        }
                    }
                }
            }

            EModeUtils.DropSummon(npc, "GoreySpine", NPC.downedBoss2, ref DroppedSummon);

            npc.defense    = 0;
            npc.defDefense = 0;

            return(base.PreAI(npc));
        }
Exemplo n.º 30
0
        public override bool PreAI(NPC npc)
        {
            bool result = base.PreAI(npc);

            EModeGlobalNPC.cultBoss = npc.whoAmI;

            if (FargoSoulsWorld.SwarmActive)
            {
                return(result);
            }

            if (npc.ai[3] == -1f)
            {
                //if (Fargowiltas.Instance.MasomodeEXLoaded && npc.ai[1] >= 120f && npc.ai[1] < 419f) //skip summoning ritual LMAO
                //{
                //    npc.ai[1] = 419f;
                //    npc.netUpdate = true;
                //}

                if (npc.ai[0] == 5)
                {
                    if (npc.ai[1] == 1f)
                    {
                        RitualRotation = Main.rand.Next(360);
                        npc.netUpdate  = true;
                        NetSync(npc);
                    }

                    if (npc.ai[1] > 30f && npc.ai[1] < 330f)
                    {
                        RitualRotation += 2f - Math.Min(1f, 2f * npc.life / npc.lifeMax); //always at least 1, begins scaling below 50% life
                        npc.Center      = Main.player[npc.target].Center + 180f * Vector2.UnitX.RotatedBy(MathHelper.ToRadians(RitualRotation));
                    }

                    /*if (npc.ai[1] > 275f && npc.ai[1] < 330f) //dust that reveals the real cultist at last second
                     * {
                     *  float modifier = 0;
                     *  int repeats = (int)npc.ai[1] - 275;
                     *  for (int i = 0; i < repeats; i++)
                     *      modifier = MathHelper.Lerp(modifier, 1f, 0.08f);
                     *  float distance = npc.height * 2 * modifier;
                     *  float rotation = MathHelper.TwoPi * modifier;
                     *  for (int i = 0; i < 4; i++)
                     *  {
                     *      int d = Dust.NewDust(npc.Center + distance * Vector2.UnitX.RotatedBy(rotation + MathHelper.TwoPi / 4 * i), 0, 0, 88, newColor: Color.White);
                     *      Main.dust[d].noGravity = true;
                     *      Main.dust[d].velocity *= npc.ai[1] > 315 ? 18f : 0.5f;
                     *      Main.dust[d].scale = 0.5f + 2.5f * modifier;
                     *  }
                     * }*/
                }
            }
            else
            {
                //if (npc.ai[3] == 0) npc.damage = 0;

                //about to begin moving for ritual: 0 39 0 12
                //begin transit for ritual: 1 34 0 12
                //pause just before ritual: 0 0 0 13
                //ritual: 5 0 0 -1

                if (!EnteredPhase2 && npc.life < npc.lifeMax / 2) //p2 transition, force a ritual immediately
                {
                    EnteredPhase2 = true;
                    npc.ai[0]     = 5;
                    npc.ai[1]     = 0;
                    npc.ai[2]     = 0;
                    npc.ai[3]     = -1;
                    SoundEngine.PlaySound(SoundID.Roar, npc.Center);

                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        npc.netUpdate = true;
                        NetSync(npc);
                    }
                }

                //necessary because calameme
                int damage = Math.Max(75, FargoSoulsUtil.ScaledProjectileDamage(npc.damage));
                damage /= 4;

                switch ((int)npc.ai[0])
                {
                case -1:
                    if (npc.ai[1] == 419f)     //always start fight with a ritual
                    {
                        npc.ai[0]     = 0f;
                        npc.ai[1]     = 0f;
                        npc.ai[3]     = 11f;
                        npc.netUpdate = true;
                    }
                    break;

                case 2:     //ice mist, frost wave support
                    if (EnteredPhase2)
                    {
                        if (npc.ai[1] < 60 && npc.ai[1] % 4 == 3)
                        {
                            int spacing = 14 - (int)(npc.ai[1] - 3) / 4; //start far and get closer
                            for (int j = -1; j <= 1; j += 2)             //from above and below
                            {
                                for (int i = -1; i <= 1; i += 2)         //waves beside you
                                {
                                    if (i == 0)
                                    {
                                        continue;
                                    }
                                    Vector2 spawnPos = Main.player[npc.target].Center;
                                    spawnPos.X += Math.Sign(i) * 150 * 2 + i * 120 * spacing;
                                    spawnPos.Y -= (700 + Math.Abs(i) * 50) * j;
                                    float speed = 8 + spacing * 0.8f;
                                    if (Main.netMode != NetmodeID.MultiplayerClient)
                                    {
                                        Projectile.NewProjectile(npc.GetSource_FromThis(), spawnPos, Vector2.UnitY * speed * j, ProjectileID.FrostWave, damage / 3, 0f, Main.myPlayer);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        if (npc.ai[1] == (FargoSoulsWorld.MasochistModeReal ? 5f : 60f) && Main.netMode != NetmodeID.MultiplayerClient)     //single wave
                        {
                            for (int i = 0; i < Main.maxNPCs; i++)
                            {
                                if (Main.npc[i].active && Main.npc[i].type == NPCID.CultistBossClone)
                                {
                                    Vector2 distance = Main.player[npc.target].Center - Main.npc[i].Center;
                                    distance.Normalize();
                                    distance *= Main.rand.NextFloat(8f, 9f);
                                    distance  = distance.RotatedByRandom(Math.PI / 24);
                                    Projectile.NewProjectile(npc.GetSource_FromThis(), Main.npc[i].Center, distance,
                                                             ProjectileID.FrostWave, damage / 3, 0f, Main.myPlayer);
                                }
                            }
                        }
                    }
                    break;

                case 3:     //fireballs
                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        if (EnteredPhase2)     //fireball ring
                        {
                            if (npc.ai[1] == 3f)
                            {
                                int max = NPC.CountNPCS(NPCID.CultistBossClone) * 2 + 6;

                                Vector2     baseOffset  = npc.DirectionTo(Main.player[npc.target].Center);
                                const float spawnOffset = 1200f;
                                const float speed       = 7f;
                                const float ai0         = spawnOffset / speed;
                                for (int i = 0; i < max; i++)
                                {
                                    Projectile.NewProjectile(npc.GetSource_FromThis(), Main.player[npc.target].Center + spawnOffset * baseOffset.RotatedBy(2 * Math.PI / max * i),
                                                             -speed * baseOffset.RotatedBy(2 * Math.PI / max * i), ModContent.ProjectileType <CultistFireball>(),
                                                             damage / 3, 0f, Main.myPlayer, ai0);
                                }

                                Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, Vector2.Zero, ModContent.ProjectileType <GlowRing>(), 0, 0f, Main.myPlayer, npc.whoAmI, npc.type);
                            }
                        }

                        if (npc.ai[1] % 20 == 6)     //homing flare support
                        {
                            for (int i = 0; i < Main.maxNPCs; i++)
                            {
                                if (Main.npc[i].active && Main.npc[i].type == NPCID.CultistBossClone)
                                {
                                    FargoSoulsUtil.NewNPCEasy(npc.GetSource_FromAI(), Main.npc[i].Center, NPCID.SolarFlare, target: npc.target);
                                }
                            }
                        }
                    }
                    break;

                case 4:     //lightning
                    if (npc.ai[1] == 19f && npc.HasPlayerTarget && Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        int cultistCount = 1;
                        for (int i = 0; i < Main.maxNPCs; i++)
                        {
                            if (Main.npc[i].active && Main.npc[i].type == NPCID.CultistBossClone)
                            {
                                if (EnteredPhase2)     //vortex lightning
                                {
                                    Projectile.NewProjectile(npc.GetSource_FromThis(), Main.npc[i].Center, Main.rand.NextVector2Square(-15, 15), ModContent.ProjectileType <CultistVortex>(),
                                                             damage / 15 * 6, 0, Main.myPlayer, 0f, cultistCount);
                                    cultistCount++;
                                }
                                else     //aimed lightning
                                {
                                    if (FargoSoulsWorld.MasochistModeReal)
                                    {
                                        Vector2 dir    = Main.player[npc.target].Center - Main.npc[i].Center;
                                        float   ai1New = Main.rand.Next(100);
                                        Vector2 vel    = Vector2.Normalize(dir.RotatedByRandom(Math.PI / 4)) * 24f;
                                        Projectile.NewProjectile(npc.GetSource_FromThis(), Main.npc[i].Center, vel, ModContent.ProjectileType <HostileLightning>(),
                                                                 damage / 15 * 6, 0, Main.myPlayer, dir.ToRotation(), ai1New);
                                    }
                                    else
                                    {
                                        Vector2 vel = Main.npc[i].DirectionTo(Main.player[npc.target].Center).RotatedByRandom(MathHelper.ToRadians(5));
                                        vel *= Main.rand.NextFloat(4f, 6f);
                                        Projectile.NewProjectile(npc.GetSource_FromThis(), Main.npc[i].Center, vel, ModContent.ProjectileType <LightningVortexHostile>(), damage / 15 * 6, 0, Main.myPlayer);
                                    }
                                }
                            }
                        }
                    }
                    break;

                case 7:
                    if (npc.ai[1] == 3f && Main.netMode != NetmodeID.MultiplayerClient)     //ancient light, jellyfish support
                    {
                        for (int i = 0; i < Main.maxProjectiles; i++)
                        {
                            if (Main.projectile[i].active && Main.projectile[i].type == ModContent.ProjectileType <CultistRitual>())
                            {
                                Projectile.NewProjectile(npc.GetSource_FromThis(), new Vector2(Main.projectile[i].Center.X, Main.player[npc.target].Center.Y - 700),
                                                         Vector2.Zero, ModContent.ProjectileType <StardustRain>(), damage / 3, 0f, Main.myPlayer);
                            }
                        }
                    }
                    break;

                case 8:
                    if (npc.ai[1] == 3f)     //ancient doom, nebula sphere support
                    {
                        int t = npc.HasPlayerTarget ? npc.target : npc.FindClosestPlayer();
                        if (t != -1 && Main.player[t].active)
                        {
                            for (int i = 0; i < Main.maxNPCs; i++)
                            {
                                if (Main.npc[i].active && Main.npc[i].type == NPCID.CultistBossClone)
                                {
                                    Projectile.NewProjectile(npc.GetSource_FromThis(), Main.npc[i].Center, Vector2.Zero, ProjectileID.NebulaSphere, damage / 15 * 6, 0f, Main.myPlayer);
                                }
                            }
                        }
                    }
                    break;

                default:
                    break;
                }
            }

            npc.defense = npc.defDefense; //prevent vanilla p2 from lowering defense!
            Lighting.AddLight(npc.Center, 1f, 1f, 1f);

            EModeUtils.DropSummon(npc, "CultistSummon", NPC.downedAncientCultist, ref DroppedSummon, NPC.downedGolemBoss);

            return(result);
        }