예제 #1
0
        public override void AI()
        {
            if (npc.localAI[2] == 0)
            {
                npc.TargetClosest(false);
                Movement(Main.player[npc.target].Center, 0.8f, 32f);
                if (npc.Distance(Main.player[npc.target].Center) < 1500)
                {
                    npc.localAI[2] = 1;
                }
                else
                {
                    return;
                }
            }

            EModeGlobalNPC.championBoss = npc.whoAmI;

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

            npc.direction = npc.spriteDirection = npc.position.X < player.position.X ? 1 : -1;

            switch ((int)npc.ai[0])
            {
            case -1:     //mourning wood movement
            {
                npc.noTileCollide = true;
                npc.noGravity     = true;

                if (Math.Abs(player.Center.X - npc.Center.X) < npc.width / 2)
                {
                    npc.velocity.X *= 0.9f;
                    if (Math.Abs(npc.velocity.X) < 0.1f)
                    {
                        npc.velocity.X = 0f;
                    }
                }
                else
                {
                    float accel = 4f;
                    if (npc.direction > 0)
                    {
                        npc.velocity.X = (npc.velocity.X * 20 + accel) / 21;
                    }
                    else
                    {
                        npc.velocity.X = (npc.velocity.X * 20 - accel) / 21;
                    }
                }

                bool onPlatforms = false;
                for (int i = (int)npc.position.X; i <= npc.position.X + npc.width; i += 16)
                {
                    if (Framing.GetTileSafely(new Vector2(i, npc.position.Y + npc.height + npc.velocity.Y + 1)).type == TileID.Platforms)
                    {
                        onPlatforms = true;
                        break;
                    }
                }

                bool onCollision = Collision.SolidCollision(npc.position, npc.width, npc.height);

                if (npc.position.X < player.position.X && npc.position.X + npc.width > player.position.X + player.width &&
                    npc.position.Y + npc.height < player.position.Y + player.height - 16)
                {
                    npc.velocity.Y += 0.5f;
                }
                else if (onCollision || (onPlatforms && player.position.Y + player.height <= npc.position.Y + npc.height))
                {
                    if (npc.velocity.Y > 0f)
                    {
                        npc.velocity.Y = 0f;
                    }

                    if (onCollision)
                    {
                        if (npc.velocity.Y > -0.2f)
                        {
                            npc.velocity.Y -= 0.025f;
                        }
                        else
                        {
                            npc.velocity.Y -= 0.2f;
                        }

                        if (npc.velocity.Y < -4f)
                        {
                            npc.velocity.Y = -4f;
                        }
                    }
                }
                else
                {
                    if (npc.velocity.Y < 0f)
                    {
                        npc.velocity.Y = 0f;
                    }

                    if (npc.velocity.Y < 0.1f)
                    {
                        npc.velocity.Y += 0.025f;
                    }
                    else
                    {
                        npc.velocity.Y += 0.5f;
                    }
                }

                if (npc.velocity.Y > 10f)
                {
                    npc.velocity.Y = 10f;
                }
            }
            break;

            case 0:     //jump at player
                npc.noTileCollide = false;
                npc.noGravity     = false;

                if (++npc.ai[1] == 60)
                {
                    npc.TargetClosest();

                    if (npc.localAI[0] == 0 && npc.life < npc.lifeMax * .66f)     //spawn palm tree supports
                    {
                        npc.localAI[0] = 1;
                        if (Main.netMode != NetmodeID.MultiplayerClient)
                        {
                            Projectile.NewProjectile(npc.Center, Vector2.Zero, ModContent.ProjectileType <PalmTreeHostile>(), npc.damage / 4, 0f, Main.myPlayer, npc.whoAmI);
                        }
                    }

                    if (npc.localAI[1] == 0 && npc.life < npc.lifeMax * .33f)     //spawn palm tree supports
                    {
                        npc.localAI[1] = 1;
                        if (Main.netMode != NetmodeID.MultiplayerClient)
                        {
                            Projectile.NewProjectile(npc.Center, Vector2.Zero, ModContent.ProjectileType <PalmTreeHostile>(), npc.damage / 4, 0f, Main.myPlayer, npc.whoAmI);
                        }
                    }

                    const float gravity = 0.4f;
                    const float time    = 90f;

                    Vector2 distance = player.Center - npc.Center;
                    distance.Y -= npc.height;

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

                    npc.noTileCollide = true;
                    npc.noGravity     = true;
                    npc.netUpdate     = true;

                    if (Main.netMode != NetmodeID.MultiplayerClient)     //explosive jump
                    {
                        Projectile.NewProjectile(npc.Center, Vector2.Zero, ProjectileID.DD2OgreSmash, npc.damage / 4, 0, Main.myPlayer);
                    }

                    Main.PlaySound(SoundID.Item, (int)npc.position.X, (int)npc.position.Y, 14);

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

                        for (int i = 0; i < 30; i++)
                        {
                            int dust = Dust.NewDust(dustPos, 32, 32, 31, 0f, 0f, 100, default(Color), 3f);
                            Main.dust[dust].velocity *= 1.4f;
                        }

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

                        float scaleFactor9 = 0.5f;
                        for (int j = 0; j < 4; j++)
                        {
                            int gore = Gore.NewGore(dustPos, default(Vector2), Main.rand.Next(61, 64));
                            Main.gore[gore].velocity   *= scaleFactor9;
                            Main.gore[gore].velocity.X += 1f;
                            Main.gore[gore].velocity.Y += 1f;
                        }
                    }
                }
                else if (npc.ai[1] > 60)
                {
                    npc.noTileCollide = true;
                    npc.noGravity     = true;
                    npc.velocity.Y   += 0.4f;

                    if (npc.ai[1] > 60 + 90)
                    {
                        npc.TargetClosest();
                        npc.ai[0]++;
                        npc.ai[1]     = 0;
                        npc.netUpdate = true;
                    }
                }
                else     //less than 60
                {
                    if (Math.Abs(npc.velocity.X) > Math.Abs(npc.velocity.Y))
                    {
                        npc.velocity.X = Math.Abs(npc.velocity.Y) * Math.Sign(npc.velocity.X);
                    }
                    if (npc.velocity.Y == 0)
                    {
                        npc.velocity.X *= 0.99f;
                    }

                    if (!player.active || player.dead || Vector2.Distance(npc.Center, player.Center) > 2500f)
                    {
                        npc.TargetClosest();
                        if (npc.timeLeft > 30)
                        {
                            npc.timeLeft = 30;
                        }

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

                        npc.ai[0] = 0;     //prevent proceeding to next steps of ai while despawning
                    }
                    else
                    {
                        npc.timeLeft = 600;
                    }

                    goto case -1;
                }
                break;

            case 1:     //acorn sprays
                if (++npc.ai[2] > 35)
                {
                    npc.ai[2] = 0;
                    const float gravity  = 0.2f;
                    float       time     = 60f;
                    Vector2     distance = player.Center - npc.Center;// + player.velocity * 30f;
                    distance.X = distance.X / time;
                    distance.Y = distance.Y / time - 0.5f * gravity * time;
                    for (int i = 0; i < 20; i++)
                    {
                        Projectile.NewProjectile(npc.Center, distance + Main.rand.NextVector2Square(-0.5f, 0.5f) * 3,
                                                 ModContent.ProjectileType <Acorn>(), npc.damage / 5, 0f, Main.myPlayer);
                    }
                }

                if (++npc.ai[1] > 120)
                {
                    npc.ai[0]++;
                    npc.ai[1]     = 0;
                    npc.ai[2]     = 0;
                    npc.netUpdate = true;
                    npc.TargetClosest();
                }
                goto case -1;

            case 2:
                goto case 0;

            case 3:     //snowball barrage
                if (++npc.ai[2] > 5)
                {
                    npc.ai[2] = 0;
                    if (Main.netMode != NetmodeID.MultiplayerClient && npc.ai[1] > 30 && npc.ai[1] < 120)
                    {
                        Vector2 offset;
                        offset.X = Main.rand.NextFloat(0, npc.width / 2) * npc.direction;
                        offset.Y = 16;
                        Projectile.NewProjectile(npc.Center + offset,
                                                 Vector2.UnitY * -12f, ModContent.ProjectileType <Snowball>(), npc.damage / 4, 0f, Main.myPlayer);
                    }
                }

                if (++npc.ai[1] > 150)
                {
                    npc.ai[0]++;
                    npc.ai[1]     = 0;
                    npc.ai[2]     = 0;
                    npc.netUpdate = true;
                    npc.TargetClosest();
                }
                goto case -1;

            case 4:
                goto case 0;

            case 5:     //spray squirrels
                if (++npc.ai[2] > 6)
                {
                    npc.ai[2] = 0;
                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        int n = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <LesserSquirrel>());
                        if (n != Main.maxNPCs)
                        {
                            Main.npc[n].velocity.X = Main.rand.NextFloat(-10, 10);
                            Main.npc[n].velocity.Y = Main.rand.NextFloat(-20, -10);
                            Main.npc[n].netUpdate  = true;
                            if (Main.netMode == NetmodeID.Server)
                            {
                                NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n);
                            }
                        }
                    }
                }

                if (++npc.ai[1] > 180)
                {
                    npc.ai[0]++;
                    npc.ai[1]     = 0;
                    npc.ai[2]     = 0;
                    npc.netUpdate = true;
                    npc.TargetClosest();
                }
                goto case -1;

            case 6:
                goto case 0;

            case 7:
                goto case 3;

            case 8:
                goto case 0;

            case 9:                 //grappling hook
                if (npc.ai[2] == 0) //shoot hook
                {
                    npc.ai[2] = 1;
                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        Projectile.NewProjectile(npc.Center, npc.DirectionTo(player.Center) * 16, ModContent.ProjectileType <SquirrelHook>(), 0, 0f, Main.myPlayer, npc.whoAmI);
                    }
                }

                if (++npc.ai[1] < 240)     //charge power
                {
                    for (int i = 0; i < 5; i++)
                    {
                        int d = Dust.NewDust(npc.position, npc.width, npc.height, DustID.Shadowflame, 0f, 0f, 0, default(Color), 2f);
                        Main.dust[d].noGravity = true;
                        Main.dust[d].velocity *= 8f;
                        d = Dust.NewDust(npc.Center, 0, 0, DustID.Shadowflame, 0f, 0f, 0, default(Color), 3f);
                        Main.dust[d].noGravity = true;
                        Main.dust[d].velocity *= 16f;
                    }

                    for (int i = 0; i < 20; i++)
                    {
                        Vector2 offset = new Vector2();
                        double  angle  = Main.rand.NextDouble() * 2d * Math.PI;
                        offset.X += (float)(Math.Sin(angle) * 500);
                        offset.Y += (float)(Math.Cos(angle) * 500);
                        Dust dust = Main.dust[Dust.NewDust(npc.Center + offset - new Vector2(4, 4), 0, 0, DustID.Shadowflame, 0, 0, 100, Color.White, 2f)];
                        dust.velocity = npc.velocity;
                        if (Main.rand.Next(3) == 0)
                        {
                            dust.velocity += Vector2.Normalize(offset) * -5f;
                        }
                        dust.noGravity = true;
                    }
                }
                else if (npc.ai[1] == 240)     //explode
                {
                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        Projectile.NewProjectile(npc.Center, Vector2.Zero, ModContent.ProjectileType <ShadowflameBlast>(), npc.damage / 2, 0f, Main.myPlayer);
                    }
                }
                else if (npc.ai[1] > 300)
                {
                    npc.ai[0]++;
                    npc.ai[1]     = 0;
                    npc.ai[2]     = 0;
                    npc.netUpdate = true;
                    npc.TargetClosest();
                }
                goto case -1;

            default:
                npc.ai[0] = 0;
                goto case 0;
            }
        }
예제 #2
0
        public override void AI()
        {
            bool     flag64    = projectile.type == mod.ProjectileType("DoomiteProbe");
            Player   player    = Main.player[projectile.owner];
            AAPlayer modPlayer = player.GetModPlayer <AAPlayer>();

            player.AddBuff(mod.BuffType("DoomiteProbe"), 3600);
            if (flag64)
            {
                if (player.dead)
                {
                    modPlayer.DoomiteProbe = false;
                }
                if (modPlayer.DoomiteProbe)
                {
                    projectile.timeLeft = 2;
                }
            }

            float num633 = 700f;
            float num634 = 800f;
            float num635 = 1200f;
            float num636 = 150f;
            float num637 = 0.05f;

            for (int num638 = 0; num638 < 1000; num638++)
            {
                bool flag23 = Main.projectile[num638].type == mod.ProjectileType("ProbeMinion");
                if (num638 != projectile.whoAmI && Main.projectile[num638].active && Main.projectile[num638].owner == projectile.owner && flag23 && Math.Abs(projectile.position.X - Main.projectile[num638].position.X) + Math.Abs(projectile.position.Y - Main.projectile[num638].position.Y) < projectile.width)
                {
                    if (projectile.position.X < Main.projectile[num638].position.X)
                    {
                        projectile.velocity.X = projectile.velocity.X - num637;
                    }
                    else
                    {
                        projectile.velocity.X = projectile.velocity.X + num637;
                    }
                    if (projectile.position.Y < Main.projectile[num638].position.Y)
                    {
                        projectile.velocity.Y = projectile.velocity.Y - num637;
                    }
                    else
                    {
                        projectile.velocity.Y = projectile.velocity.Y + num637;
                    }
                }
            }
            bool flag24 = false;

            if (flag24)
            {
                return;
            }
            Vector2 vector46 = projectile.position;
            bool    flag25   = false;

            if (projectile.ai[0] != 1f)
            {
                projectile.tileCollide = false;
            }
            if (projectile.tileCollide && WorldGen.SolidTile(Framing.GetTileSafely((int)projectile.Center.X / 16, (int)projectile.Center.Y / 16)))
            {
                projectile.tileCollide = false;
            }
            if (player.HasMinionAttackTargetNPC)
            {
                NPC nPC2 = Main.npc[player.MinionAttackTargetNPC];
                if (nPC2.CanBeChasedBy(projectile, false))
                {
                    float num646 = Vector2.Distance(nPC2.Center, projectile.Center);
                    if (((Vector2.Distance(projectile.Center, vector46) > num646 && num646 < num633) || !flag25) && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, nPC2.position, nPC2.width, nPC2.height))
                    {
                        num633   = num646;
                        vector46 = nPC2.Center;
                        flag25   = true;
                    }
                }
            }
            else
            {
                for (int num645 = 0; num645 < 200; num645++)
                {
                    NPC nPC2 = Main.npc[num645];
                    if (nPC2.CanBeChasedBy(projectile, false))
                    {
                        float num646 = Vector2.Distance(nPC2.Center, projectile.Center);
                        if (((Vector2.Distance(projectile.Center, vector46) > num646 && num646 < num633) || !flag25) && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, nPC2.position, nPC2.width, nPC2.height))
                        {
                            num633   = num646;
                            vector46 = nPC2.Center;
                            flag25   = true;
                        }
                    }
                }
            }
            float num647 = num634;

            if (flag25)
            {
                num647 = num635;
            }
            if (Vector2.Distance(player.Center, projectile.Center) > num647)
            {
                projectile.ai[0]       = 1f;
                projectile.tileCollide = false;
                projectile.netUpdate   = true;
            }
            if (flag25 && projectile.ai[0] == 0f)
            {
                Vector2 vector47 = vector46 - projectile.Center;
                float   num648   = vector47.Length();
                vector47.Normalize();
                if (num648 > 200f)
                {
                    float scaleFactor2 = 6f;
                    vector47           *= scaleFactor2;
                    projectile.velocity = (projectile.velocity * 40f + vector47) / 41f;
                }
                else
                {
                    float num649 = 4f;
                    vector47           *= -num649;
                    projectile.velocity = (projectile.velocity * 40f + vector47) / 41f;
                }
            }
            else
            {
                bool flag26 = false;
                if (!flag26)
                {
                    flag26 = projectile.ai[0] == 1f;
                }
                float num650 = 6f;
                if (flag26)
                {
                    num650 = 15f;
                }
                Vector2 center2  = projectile.Center;
                Vector2 vector48 = player.Center - center2 + new Vector2(0f, -60f);
                float   num651   = vector48.Length();
                if (num651 > 200f && num650 < 8f)
                {
                    num650 = 8f;
                }
                if (num651 < num636 && flag26 && !Collision.SolidCollision(projectile.position, projectile.width, projectile.height))
                {
                    projectile.ai[0]     = 0f;
                    projectile.netUpdate = true;
                }
                if (num651 > 2000f)
                {
                    projectile.position.X = Main.player[projectile.owner].Center.X - projectile.width / 2;
                    projectile.position.Y = Main.player[projectile.owner].Center.Y - projectile.height / 2;
                    projectile.netUpdate  = true;
                }
                if (num651 > 70f)
                {
                    vector48.Normalize();
                    vector48           *= num650;
                    projectile.velocity = (projectile.velocity * 40f + vector48) / 41f;
                }
                else if (projectile.velocity.X == 0f && projectile.velocity.Y == 0f)
                {
                    projectile.velocity.X = -0.15f;
                    projectile.velocity.Y = -0.05f;
                }
            }
            if (projectile.direction == 1)
            {
                projectile.spriteDirection = 1;
            }
            else
            {
                projectile.spriteDirection = -1;
            }

            projectile.frameCounter++;
            if (projectile.frameCounter >= 5)
            {
                projectile.frameCounter = 0;
                projectile.frame++;
            }
            if (projectile.frame > 3)
            {
                projectile.frame = 0;
            }
            if (projectile.ai[1] > 0f)
            {
                projectile.ai[1] += Main.rand.Next(1, 4);
            }
            if (projectile.ai[1] > 60f)
            {
                projectile.ai[1]     = 0f;
                projectile.netUpdate = true;
            }
            if (projectile.ai[0] == 0f)
            {
                float scaleFactor3 = 8f;
                int   num658       = 389;
                if (flag25 && projectile.ai[1] == 0f)
                {
                    projectile.ai[1] += 1f;
                    if (Main.myPlayer == projectile.owner && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, vector46, 0, 0))
                    {
                        Vector2 value19 = vector46 - projectile.Center;
                        value19.Normalize();
                        value19 *= scaleFactor3;
                        int num659 = Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, value19.X, value19.Y, num658, projectile.damage, 0f, Main.myPlayer, 0f, 0f);
                        Main.projectile[num659].penetrate = 1;
                        Main.projectile[num659].timeLeft  = 300;
                        projectile.netUpdate = true;
                    }
                }
            }
        }
예제 #3
0
        public override bool SpawnConditions(int i, int j)
        {
            var tile = Framing.GetTileSafely(i, j);

            return(tile.frameX < 16 && tile.frameY == 0);
        }
예제 #4
0
        public override void AI()
        {
            if (npc.localAI[3] == 0) //spawn friends
            {
                npc.TargetClosest(false);
                Movement(Main.player[npc.target].Center, 0.8f, 32f);
                if (npc.Distance(Main.player[npc.target].Center) < 2000)
                {
                    npc.localAI[3] = 1;
                }
                else
                {
                    return;
                }

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

            EModeGlobalNPC.championBoss = npc.whoAmI;

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

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

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

            case -3:     //final you think you're safe
                if (npc.localAI[2] == 0)
                {
                    npc.localAI[2] = 1;
                }

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

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

                    return;
                }

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

                npc.dontTakeDamage = true;

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

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

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

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

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

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

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

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

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

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

                if (++npc.ai[1] > 600)
                {
                    npc.dontTakeDamage = false;
                }
                break;

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

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

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

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

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

                    return;
                }

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

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

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

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

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

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

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

                            for (int i = 0; i < 12; i++)
                            {
                                Projectile.NewProjectile(npc.position.X + Main.rand.Next(npc.width), npc.position.Y + Main.rand.Next(npc.height),
                                                         Main.rand.NextFloat(-8f, 8f), Main.rand.NextFloat(-8f, 8f), ModContent.ProjectileType <SpiritCrossBone>(), npc.damage / 4, 0f, Main.myPlayer);
                            }
                        }
                        else     //sandnado
                        {
                            Vector2 target = player.Center;
                            target.X += player.velocity.X * 90;
                            target.Y -= 150;
                            Projectile.NewProjectile(target, Vector2.Zero, ProjectileID.SandnadoHostileMark, 0, 0f, Main.myPlayer);

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

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

            case 2:
                goto case 0;

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

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

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

            case 4:
                goto case 0;

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

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

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

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

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

            case 6:
                goto case 0;

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

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

                const float distance = 150;

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

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

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

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

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

                            //x.netUpdate = true;
                        }
                    });

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

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

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

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

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

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

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

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

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

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

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

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

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

                for (int i = 0; i < 20; i++) //dust
                {
                    int d = Dust.NewDust(npc.Center + auraDistance * Vector2.UnitX.RotatedBy(Math.PI * 2 * Main.rand.NextDouble()), 0, 0, 87);
                    Main.dust[d].velocity  = npc.velocity;
                    Main.dust[d].noGravity = true;
                    Main.dust[d].scale++;
                }
            }
        }
예제 #5
0
        public override void AI()
        {
            Player           player    = Main.player[Projectile.owner];
            FargoSoulsPlayer modPlayer = player.GetModPlayer <FargoSoulsPlayer>();

            if (player.dead || player.ghost)
            {
                modPlayer.ChibiDevi = false;
            }
            if (modPlayer.ChibiDevi)
            {
                Projectile.timeLeft = 2;
            }

            DelegateMethods.v3_1 = new Vector3(1f, 0.5f, 0.9f) * 0.75f;
            Utils.PlotTileLine(Projectile.Center, Projectile.Center + Projectile.velocity * 6f, 20f, DelegateMethods.CastLightOpen);
            Utils.PlotTileLine(Projectile.Left, Projectile.Right, 20f, DelegateMethods.CastLightOpen);

            bool asleep = Projectile.ai[0] == 1;

            if (asleep)
            {
                Projectile.tileCollide = true;
                Projectile.ignoreWater = false;

                Projectile.frameCounter = 0;
                Projectile.frame        = Projectile.velocity.Y == 0 ? 5 : 4;

                Projectile.velocity.X *= 0.95f;
                Projectile.velocity.Y += 0.3f;

                if (Projectile.owner == Main.myPlayer && Projectile.Distance(Main.MouseWorld) > 180)
                {
                    Projectile.ai[0] = 0;

                    TryTalkWithCD(TalkType.Wake, ShortCD);
                }
            }
            else
            {
                if (Projectile.owner == Main.myPlayer)
                {
                    Projectile.tileCollide = false;
                    Projectile.ignoreWater = true;

                    Projectile.direction = Projectile.Center.X < Main.MouseWorld.X ? 1 : -1;

                    float distance     = 2500;
                    float possibleDist = Main.player[Projectile.owner].Distance(Main.MouseWorld) / 2 + 100;
                    if (distance < possibleDist)
                    {
                        distance = possibleDist;
                    }
                    if (Projectile.Distance(Main.player[Projectile.owner].Center) > distance && Projectile.Distance(Main.MouseWorld) > distance)
                    {
                        Projectile.Center   = player.Center;
                        Projectile.velocity = Vector2.Zero;
                    }

                    if (Projectile.Distance(Main.MouseWorld) > 30)
                    {
                        Movement(Main.MouseWorld, 0.15f, 32f);
                    }

                    if (oldMouse == Main.MouseWorld)
                    {
                        Projectile.ai[1]++;
                        if (Projectile.ai[1] > 600)
                        {
                            bool okToRest = !Collision.SolidCollision(Projectile.position, Projectile.width, Projectile.height);

                            if (okToRest)
                            {
                                okToRest = false;

                                Vector2 targetPos = new Vector2(Projectile.Center.X, Projectile.position.Y + Projectile.height);
                                for (int i = 0; i < 10; i++) //collision check below self
                                {
                                    targetPos.Y += 16;
                                    Tile tile = Framing.GetTileSafely(targetPos); //if solid, ok
                                    if (tile.HasUnactuatedTile && Main.tileSolid[tile.TileType])
                                    {
                                        okToRest = true;
                                        break;
                                    }
                                }
                            }

                            if (okToRest) //not in solid tiles, but found tiles within a short distance below
                            {
                                Projectile.ai[0] = 1;
                                Projectile.ai[1] = 0;

                                TryTalkWithCD(TalkType.Sleep, ShortCD);
                            }
                            else //try again in a bit
                            {
                                Projectile.ai[1] = 540;
                            }
                        }
                    }
                    else
                    {
                        Projectile.ai[1] = 0;
                        oldMouse         = Main.MouseWorld;
                    }
                }

                if (++Projectile.frameCounter > 6)
                {
                    Projectile.frameCounter = 0;
                    if (++Projectile.frame >= 4)
                    {
                        Projectile.frame = 0;
                    }
                }
            }

            Projectile.spriteDirection = Projectile.direction;

            bool bossAlive = FargoSoulsUtil.AnyBossAlive();

            if (bossAlive)
            {
                TryTalkWithCD(TalkType.BossSpawn, ShortCD);

                if (Main.npc[FargoSoulsGlobalNPC.boss].life < Main.npc[FargoSoulsGlobalNPC.boss].lifeMax / 4)
                {
                    TryTalkWithCD(TalkType.BossAlmostDead, MediumCD);
                }
            }
            else
            {
                //only do idle talk when awake, not a boss fight, and not in danger
                if (asleep)
                {
                    TalkCDs[(int)TalkType.Idle] = Math.Max(TalkCDs[(int)TalkType.Idle], 12 * 60);
                }
                else if (player.statLife > player.statLifeMax2 / 2)
                {
                    TryTalkWithCD(TalkType.Idle, MediumCD);
                }

                //wont cheer in boss fight unless over 30 seconds
                const int timeRequirement = 30 * 60;
                TalkCDs[(int)TalkType.BossAlmostDead] = Math.Max(TalkCDs[(int)TalkType.BossAlmostDead], timeRequirement);
                TalkCDs[(int)TalkType.KillBoss]       = Math.Max(TalkCDs[(int)TalkType.KillBoss], timeRequirement);
            }

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

            if (Projectile.owner == Main.myPlayer)
            {
                for (int i = 0; i < TalkCDs.Length; i++)
                {
                    //dont run these timer during a boss fight
                    if (bossAlive && (i == (int)TalkType.Idle || i == (int)TalkType.BossSpawn))
                    {
                        continue;
                    }

                    if (TalkCDs[i] > 0)
                    {
                        TalkCDs[i]--;
                    }
                }
            }
        }
예제 #6
0
        public bool PlaceWell(int i, int j)
        {
            if (!WorldGen.SolidTile(i, j + 1))
            {
                return(false);
            }
            if (Main.tile[i, j].active())
            {
                return(false);
            }
            if (j < 150)
            {
                return(false);
            }

            for (int y = 0; y < wellshape.GetLength(0); y++)
            {
                for (int x = 0; x < wellshape.GetLength(1); x++)
                {
                    int k = i - 3 + x;
                    int l = j - 6 + y;
                    if (WorldGen.InWorld(k, l, 30))
                    {
                        Tile tile = Framing.GetTileSafely(k, l);
                        switch (wellshape[y, x])
                        {
                        case 1:
                            tile.type = TileID.RedBrick;
                            tile.active(true);
                            break;

                        case 2:
                            tile.type = TileID.RedBrick;
                            tile.active(true);
                            tile.halfBrick(true);
                            break;

                        case 3:
                            tile.type = TileID.RedBrick;
                            tile.active(true);
                            tile.slope(2);
                            break;

                        case 4:
                            tile.type = TileID.RedBrick;
                            tile.active(true);
                            tile.slope(1);
                            break;

                        case 5:
                            tile.active(false);
                            break;

                        case 6:
                            tile.type = TileID.Rope;
                            tile.active(true);
                            break;
                        }
                        switch (wellshapeWall[y, x])
                        {
                        case 1:
                            tile.wall = WallID.RedBrick;
                            break;
                        }
                        switch (wellshapeWater[y, x])
                        {
                        case 1:
                            tile.liquid = 255;
                            break;
                        }
                    }
                }
            }
            return(true);
        }
예제 #7
0
        /// <summary>Used to make sure associated tiles on the tree die when any given tile is killed.
        /// Note: This is a very long checklist of every possible way to destroy a tile; in short, custom framing. If you want to change something, you might have to rewrite a good amount of it.</summary>
        public override void KillTile(int i, int j, ref bool fail, ref bool effectOnly, ref bool noItem)
        {
            if (fail)
            {
                return;                           //Do nothing if this doesn't kill the tile
            }
            Tile t = Framing.GetTileSafely(i, j); //For quick reference

            bool FramedTreeTile(int x, int y, params int[] frm)
            {
                Tile tile = Framing.GetTileSafely(x, y);

                return(tile.active() && tile.type == Type && frm.Contains(tile.frameX));
            }

            void CullTree(int x, int startY, bool leftOrigin = false)
            {
                Tile tile = Framing.GetTileSafely(x, startY);
                int  y    = startY;

                while (tile.active() && tile.type == Type)
                {
                    if (y != startY)
                    {
                        WorldGen.KillTile(x, y, false, false, false);
                        WorldGen.KillTile(x + 1, y, false, false, false);
                        WorldGen.KillTile(x, y, false, false, false); //I hate this. works tho
                    }

                    y--;
                    tile = Framing.GetTileSafely(x, y);
                }

                WorldGen.KillTile(x + (leftOrigin ? 1 : 0), startY, false, false, false);
            }

            //This if-else statement was written many months after this had all been done. It may deprecate any amount of code below. I don't care.
            if (((FramedTreeTile(i, j, 360, 396) && FramedTreeTile(i + 1, j, 378, 414)) || (FramedTreeTile(i, j, 378, 414) && FramedTreeTile(i - 1, j, 360, 396))) && !CullingTree)
            {
                CullingTree = true;

                if (t.frameX == 360 || t.frameX == 396)
                {
                    WorldGen.KillTile(i + 1, j, false, false, false);
                }
                else if (t.frameX == 378 || t.frameX == 414)
                {
                    WorldGen.KillTile(i - 1, j, false, false, false);
                }

                CullingTree = false;
            }
            else if ((FramedTreeTile(i - 1, j, 0, 72, 198) || FramedTreeTile(i + 1, j, 18, 216, 306)) && Framing.GetTileSafely(i, j - 1).type == TileType <BigTree_Purity>()) //Kill any tree tiles above self if both sides are cut
            {
                if (t.frameX == 198 || t.frameX == 72)                                                                                                                        //Kill tile to the left if it's a branch
                {
                    WorldGen.KillTile(i - 1, j, false, false, false);
                }
                if (t.frameX == 0 || t.frameX == 72 || t.frameX == 198)
                {
                    t.frameX = 432;
                }

                if (t.frameX == 216 || t.frameX == 306)
                {
                    WorldGen.KillTile(i + 1, j, false, false, false);
                }
                if (t.frameX == 18 || t.frameX == 216 || t.frameX == 306)
                {
                    t.frameX = 450;
                }

                fail = true;
                return; //Change the frame to the wedge frame and stop this from dying
            }
            else if ((FramedTreeTile(i - 1, j, 432) || FramedTreeTile(i + 1, j, 450)) && Framing.GetTileSafely(i, j - 1).type == TileType <BigTree_Purity>())
            {
                if (!CullingTree)
                {
                    CullingTree = true;

                    if (t.frameX == 18 || t.frameX == 216 || t.frameX == 306)
                    {
                        CullTree(i - 1, j);
                    }
                    else
                    {
                        CullTree(i, j, true);
                    }

                    CullingTree = false;
                }
            }

            Item.NewItem(new Vector2(i, j) * 16, drop, Main.rand.Next(1, 3)); //Drops extra wood to be proportional to vanilla tree wood loot

            if (t.frameX == 108 || t.frameX == 270)
            {
                Framing.GetTileSafely(i + 1, j).frameX = 162;                                     //Adjust frame for the middle branch
            }
            if (t.frameX == 126 || t.frameX == 288)
            {
                Framing.GetTileSafely(i - 1, j).frameX = 180; //Same as above, but the right side
            }
            if (t.frameX == 90)                               //[Left] Middle branch killed, kill branch tip and adjust trunk frame
            {
                Framing.GetTileSafely(i + 1, j).frameX = 0;
                WorldGen.KillTile(i - 1, j);
            }
            if (t.frameX == 162)
            {
                Framing.GetTileSafely(i + 1, j).frameX = 0; //Adjust trunk when cut branch is killed
            }
            if (t.frameX == 144)                            //[Right] Middle branch killed, kill branch tip and adjust trunk frame
            {
                Framing.GetTileSafely(i - 1, j).frameX = 18;
                WorldGen.KillTile(i + 1, j);
            }
            if (t.frameX == 180)
            {
                Framing.GetTileSafely(i - 1, j).frameX = 18;                  //Adjust trunk when cut branch is killed
            }
            if (t.frameX == 36)
            {
                Framing.GetTileSafely(i + 1, j).frameX = 0;                 //Base left side, adjust trunk frame
            }
            if (t.frameX == 54)
            {
                Framing.GetTileSafely(i - 1, j).frameX = 18; //Base right side, adjust trunk frame
            }
            if (t.frameX == 198 || t.frameX == 396)          //If adjacent to a branch, kill the branch
            {
                WorldGen.KillTile(i - 1, j, false, false, false);
            }
            if (t.frameX == 216 || t.frameX == 414) //If adjacent to a branch, kill the branch
            {
                WorldGen.KillTile(i + 1, j, false, false, false);
            }

            if (t.frameX == 72 || t.frameX == 324) //Base is killed
            {
                t.frameX++;
                WorldGen.KillTile(i - 1, j, false, false, false); //Kills left base root
                if (Framing.GetTileSafely(i + 1, j).frameX == 306 || Framing.GetTileSafely(i + 1, j).frameX == 342)
                {
                    WorldGen.KillTile(i + 1, j, false, false, false); //Kills the rest of the base
                }
            }
            if (t.frameX == 306 || t.frameX == 342) //Base is killed
            {
                t.frameX++;
                WorldGen.KillTile(i + 1, j, false, false, false); //Kills right base root
                if (Framing.GetTileSafely(i - 1, j).frameX == 72 || Framing.GetTileSafely(i + 1, j).frameX == 324)
                {
                    WorldGen.KillTile(i - 1, j, false, false, false); //Kills rest of the base
                }
            }

            void CutTrunkFrames(int adj) //Cuts the trunk. Please help me
            {
                if (Framing.GetTileSafely(i - adj, j + 1).frameX == 0)
                {
                    Framing.GetTileSafely(i - adj, j + 1).frameX = 360; //Cut trunk
                }
                if (Framing.GetTileSafely(i - adj, j + 1).frameX == 198)
                {
                    Framing.GetTileSafely(i - adj, j + 1).frameX = 396; //Cut trunk w/ adjacent branch
                }
                if (Framing.GetTileSafely(i - adj, j + 1).frameX == 72)
                {
                    Framing.GetTileSafely(i - adj, j + 1).frameX = 324;
                }
                if (Framing.GetTileSafely(i - adj + 1, j + 1).frameX == 18)
                {
                    Framing.GetTileSafely(i - adj + 1, j + 1).frameX = 378; //Cut trunk (right)
                }
                if (Framing.GetTileSafely(i - adj + 1, j + 1).frameX == 216)
                {
                    Framing.GetTileSafely(i - adj + 1, j + 1).frameX = 414; //Cut trunk w/ adjacent branch (right)
                }
                if (Framing.GetTileSafely(i - adj + 1, j + 1).frameX == 306)
                {
                    Framing.GetTileSafely(i - adj + 1, j + 1).frameX = 342;
                }
            }

            if (t.frameX == 0 || t.frameX == 198 || t.frameX == 360)       //Kill adjacent tiles if this is a trunk or the very base of the tree - left
            {
                t.frameX++;                                                //This makes sure there's no infinite loop without messing with anything
                CutTrunkFrames(0);                                         //Cuts the trunk
            }
            else if (t.frameX == 18 || t.frameX == 216 || t.frameX == 378) //This is the same as the if above - right
            {
                t.frameX++;
                CutTrunkFrames(1);
            }

            if (t.frameX == 360) //Check #29907832: killed adjacent cut trunk
            {
                t.frameX++;
                if (Framing.GetTileSafely(i + 1, j).frameX == 378)
                {
                    WorldGen.KillTile(i + 1, j);
                }
            }
            else if (t.frameX == 378)
            {
                t.frameX++;
                if (Framing.GetTileSafely(i - 1, j).frameX == 360)
                {
                    WorldGen.KillTile(i - 1, j);
                }
            }

            if (t.frameX == 234) //Drops loot & gores from the treetop
            {
                Vector2 topPos = new Vector2(i - (TreeTopSize.X / 2), j - TreeTopSize.Y) * 16f;
                Item.NewItem(topPos + new Vector2(Main.rand.Next(TreeTopSize.Width), Main.rand.Next(TreeTopSize.Height)), drop, Main.rand.Next(18, 25));        //Replace Acorn (below) with whatever if you want
                Item.NewItem(topPos + new Vector2(Main.rand.Next(TreeTopSize.Width), Main.rand.Next(TreeTopSize.Height)), ItemID.Acorn, Main.rand.Next(7, 12)); //And obviously, add whatever extra items too if needed

                int leaves = Main.rand.Next(20, 28);                                                                                                            //Randomized leaf count
                for (int l = 0; l < leaves; ++l)                                                                                                                //Spawns leaf gores - note, these values are adjusted specifically for the size of the top; change TreeTopSize to adjust it easily.
                {
                    Gore.NewGore(topPos + new Vector2(Main.rand.Next(TreeTopSize.Width), Main.rand.Next(TreeTopSize.Height)), new Vector2(), LeafType, Main.rand.Next(120, 160) * 0.01f);
                }

                t.frameX++;
                if (Framing.GetTileSafely(i + 1, j).frameX == 252)
                {
                    WorldGen.KillTile(i + 1, j, false, false, false);
                }

                CutTrunkFrames(0); //Cuts the trunk
            }
            if (t.frameX == 252)   //Right side top, kill adjacent
            {
                t.frameX++;
                if (Framing.GetTileSafely(i - 1, j).frameX == 234)
                {
                    WorldGen.KillTile(i - 1, j, false, false, false);
                }
                CutTrunkFrames(1); //Cuts the trunk
            }
            if (t.frameX == 270)   //Drops loot & gores from branch (left)
            {
                Vector2 branchPos = new Vector2(i - BranchSize.X, j - (BranchSize.Y / 2)) * 16;
                Item.NewItem(branchPos + new Vector2(Main.rand.Next(BranchSize.Width), Main.rand.Next(BranchSize.Height)), ItemID.Acorn, Main.rand.Next(3, 5));

                int leaves = Main.rand.Next(12, 22);
                for (int l = 0; l < leaves; ++l)
                {
                    Gore.NewGore(branchPos + new Vector2(Main.rand.Next(BranchSize.Width), Main.rand.Next(BranchSize.Height)), new Vector2(), LeafType, Main.rand.Next(90, 130) * 0.01f);
                }
            }
            if (t.frameX == 288) //Drops loot & gores from branch (left)
            {
                Vector2 branchPos = new Vector2(i, j - (BranchSize.Y / 2)) * 16;
                Item.NewItem(branchPos + new Vector2(Main.rand.Next(BranchSize.Width), Main.rand.Next(BranchSize.Height)), ItemID.Acorn, Main.rand.Next(3, 5));

                int leaves = Main.rand.Next(12, 22);
                for (int l = 0; l < leaves; ++l)
                {
                    Gore.NewGore(branchPos + new Vector2(Main.rand.Next(BranchSize.Width), Main.rand.Next(BranchSize.Height)), new Vector2(), LeafType, Main.rand.Next(90, 130) * 0.01f);
                }
            }
        }
예제 #8
0
 public override void PostUpdate()
 {
     if (!Main.hardMode && !madeSunkenTreasure)
     {
         wofAlive = true;
     }
     if (NPC.AnyNPCs(398))
     {
         moonlordAlive = true;
     }
     if (wofAlive && Main.hardMode && !madeSunkenTreasure)
     {
         wofAlive = false;
         wofDead  = true;
     }
     if (moonlordAlive && !NPC.AnyNPCs(398))
     {
         moonlordDead  = true;
         moonlordAlive = false;
     }
     if (NPC.AnyNPCs(245))
     {
         golemAlive = true;
     }
     if (golemAlive && !NPC.AnyNPCs(245))
     {
         golemDead  = true;
         golemAlive = false;
     }
     if (NPC.AnyNPCs(262))
     {
         planteraAlive = true;
     }
     if (planteraAlive && !NPC.AnyNPCs(262))
     {
         planteraDead  = true;
         planteraAlive = false;
     }
     if (wofDead)
     {
         int  ymodifier = 0;
         bool landed    = false;
         for (ymodifier = 0; ymodifier < Main.maxTilesY - 1; ymodifier++)
         {
             if (Main.tile[64, ymodifier + 1].active() && !landed)
             {
                 WorldGen.PlaceChest(64, ymodifier, Convert.ToUInt16(TileType <SunkenTreasureTile>()), false, 0);
                 landed = true;
                 Main.NewText("A treasure has sunken in the ocean!", 0, 0, 255);
                 for (int chestIndex = 0; chestIndex < 1000; chestIndex++)
                 {
                     Chest chest        = Main.chest[chestIndex];
                     int[] ItemForChest = new int[104] {
                         74, 78, 82, 17, 79, 83, 91, 92, 108, 107, 264, 327, 355, 517, 554, 696, 697, 698, 709, 712, 715, 744, 741, 743, 855, 864, 955, 1355, 1522, 1523, 1524, 1525, 1526, 1527, 1704, 1705, 1710, 1716, 1720, 1987, 2133, 2137, 2143, 2147, 2155, 2238, 2294, 2308, 2336, 2335, 2334, 2379, 2389, 2405, 2630, 2663, 2843, 2889, 2890, 2891, 2892, 2893, 2894, 2895, 3070, 3071, 3072, 3073, 3074, 3075, 3076, 3096, 3183, 3229, 3230, 3231, 3232, 3233, 3510, 3511, 3512, 3513, 3514, 3515, 3516, 3517, 3518, 3519, 3520, 3521, 3480, 3481, 3482, 3483, 3484, 3485, 3564, 3566, 3643, 3816, 3885, 3887, 3904, 3910
                     };
                     int[] OtherForChest = new int[10] {
                         177, 178, 179, 180, 181, 182, 999, 1348, 3027, 3828
                     };
                     int[] SunkenTreasureExclus = new int[] { ItemType <Items.Pickanch>(), ItemType <Items.Riptide>(), ItemType <Items.NautilusSlicer>() };
                     int   Which = Main.rand.Next(7, 8);
                     if (chest != null && Main.tile[chest.x, chest.y].type == TileType <SunkenTreasureTile>())
                     {
                         for (int inventoryIndex = 0; inventoryIndex < Main.rand.Next(13, 15); inventoryIndex++)
                         {
                             if (chest.item[inventoryIndex].type == 0 && inventoryIndex == 0)
                             {
                                 chest.item[inventoryIndex].SetDefaults(19);
                                 chest.item[inventoryIndex].stack = Main.rand.Next(10, 35);
                             }
                             if (chest.item[inventoryIndex].type == 0 && inventoryIndex == 1)
                             {
                                 chest.item[inventoryIndex].SetDefaults(21);
                                 chest.item[inventoryIndex].stack = Main.rand.Next(10, 35);
                             }
                             if (chest.item[inventoryIndex].type == 0 && inventoryIndex == 2)
                             {
                                 chest.item[inventoryIndex].SetDefaults(706);
                                 chest.item[inventoryIndex].stack = Main.rand.Next(10, 35);
                             }
                             if (chest.item[inventoryIndex].type == 0 && inventoryIndex == 3)
                             {
                                 chest.item[inventoryIndex].SetDefaults(72);
                                 chest.item[inventoryIndex].stack = Main.rand.Next(10, 99);
                             }
                             if (chest.item[inventoryIndex].type == 0 && inventoryIndex == 4)
                             {
                                 chest.item[inventoryIndex].SetDefaults(73);
                                 chest.item[inventoryIndex].stack = Main.rand.Next(1, 35);
                             }
                             if (chest.item[inventoryIndex].type == 0 && inventoryIndex < Which)
                             {
                                 chest.item[inventoryIndex].SetDefaults(ItemForChest[Main.rand.Next(1, 104)]);
                             }
                             if (chest.item[inventoryIndex].type == 0 && inventoryIndex >= Which && inventoryIndex < 12)
                             {
                                 chest.item[inventoryIndex].SetDefaults(OtherForChest[Main.rand.Next(1, 10)]);
                                 chest.item[inventoryIndex].stack = Main.rand.Next(1, 20);
                             }
                             if (chest.item[inventoryIndex].type == 0 && inventoryIndex >= 12)
                             {
                                 chest.item[inventoryIndex].SetDefaults(SunkenTreasureExclus[Main.rand.Next(1, 3)]);
                             }
                         }
                     }
                 }
             }
         }
         wofDead = false;
     }
     if (moonlordDead)
     {
         for (int k = 0; k < (int)((Main.maxTilesX * Main.maxTilesY) * 6E-05); k++)
         {
             int x = WorldGen.genRand.Next(0, Main.maxTilesX);
             int y = WorldGen.genRand.Next((int)Main.maxTilesY - 200, Main.maxTilesY);
             WorldGen.TileRunner(x, y, WorldGen.genRand.Next(5, 15), WorldGen.genRand.Next(2, 6), TileType <Volcanite>());
         }
         for (int k = 0; k < (int)((Main.maxTilesX * Main.maxTilesY) * 6E-04); k++)
         {
             int  x    = WorldGen.genRand.Next(0, Main.maxTilesX);
             int  y    = WorldGen.genRand.Next((int)0, 0 + 200);
             Tile tile = Framing.GetTileSafely(x, y);
             if (tile.active() && tile.type == TileID.Dirt)
             {
                 WorldGen.TileRunner(x, y, WorldGen.genRand.Next(5, 15), WorldGen.genRand.Next(2, 6), TileType <Twilite>());
             }
         }
         Main.NewText("The depths of Hell rise and the sky has truly emerged.", 255, 255, 255);
         moonlordDead = false;
         volcaniteGen = false;
     }
     if (golemDead)
     {
         for (int k = 0; k < (int)((Main.maxTilesX * Main.maxTilesY) * 6E-05); k++)
         {
             int  x    = WorldGen.genRand.Next(0, Main.maxTilesX);
             int  y    = WorldGen.genRand.Next((int)WorldGen.worldSurfaceLow + 200, Main.maxTilesY);
             Tile tile = Framing.GetTileSafely(x, y);
             if (tile.active() && tile.type == TileID.Crimstone)
             {
                 WorldGen.TileRunner(x, y, WorldGen.genRand.Next(5, 15), WorldGen.genRand.Next(2, 6), TileType <Scarlet>());
             }
             if (tile.active() && tile.type == TileID.Ebonstone)
             {
                 WorldGen.TileRunner(x, y, WorldGen.genRand.Next(5, 15), WorldGen.genRand.Next(2, 6), TileType <CursedOre>());
             }
         }
         Main.NewText("It spreads.", 255, 255, 0);
         golemDead = false;
     }
     if (planteraDead)
     {
         for (int k = 0; k < (int)((Main.maxTilesX * Main.maxTilesY) * 6E-05); k++)
         {
             int  x    = WorldGen.genRand.Next(0, Main.maxTilesX);
             int  y    = WorldGen.genRand.Next((int)WorldGen.worldSurfaceLow + 200, Main.maxTilesY);
             Tile tile = Framing.GetTileSafely(x, y);
             if (tile.active() && tile.type == TileID.Pearlstone)
             {
                 WorldGen.TileRunner(x, y, WorldGen.genRand.Next(5, 15), WorldGen.genRand.Next(2, 6), TileType <Crystal>());
             }
         }
         Main.NewText("The crystals are starting their new growth.", 100, 0, 255);
         planteraDead = false;
     }
     if (NPC.downedGolemBoss && Main.rand.Next(40000) == 0)
     {
         int  ymodifier = 0;
         int  xmodifier = Main.rand.Next(Main.maxTilesX);
         bool landed    = false;
         for (ymodifier = 0; ymodifier < Main.maxTilesY - 1; ymodifier++)
         {
             if (Main.tile[xmodifier, ymodifier + 1].active() && !landed)
             {
                 WorldGen.PlaceObject(xmodifier, ymodifier, TileType <SpecialCloud>(), false, 0);
                 landed = true;
                 Main.NewText("A cloud has fallen!", 200, 200, 200);
             }
         }
     }
 }
예제 #9
0
        public override void PostWorldGen()
        {
            /*WorldGen.PlaceTile(Main.spawnTileX - 1, Main.spawnTileY, TileID.GrayBrick, false, true);
             * WorldGen.PlaceTile(Main.spawnTileX, Main.spawnTileY, TileID.GrayBrick, false, true);
             * WorldGen.PlaceTile(Main.spawnTileX + 1, Main.spawnTileY, TileID.GrayBrick, false, true);
             * Main.tile[Main.spawnTileX - 1, Main.spawnTileY].slope(0);
             * Main.tile[Main.spawnTileX, Main.spawnTileY].slope(0);
             * Main.tile[Main.spawnTileX + 1, Main.spawnTileY].slope(0);
             * WorldGen.PlaceTile(Main.spawnTileX, Main.spawnTileY - 1, ModLoader.GetMod("Fargowiltas").TileType("RegalStatueSheet"), false, true);*/

            int        positionX   = Main.spawnTileX - 1; //offset by dimensions of statue
            int        positionY   = Main.spawnTileY - 4;
            bool       placed      = false;
            List <int> legalBlocks = new List <int> {
                TileID.Stone, TileID.Grass, TileID.Dirt, TileID.SnowBlock, TileID.IceBlock, TileID.ClayBlock
            };

            for (int offsetX = -50; offsetX <= 50; offsetX++)
            {
                for (int offsetY = -30; offsetY <= 10; offsetY++)
                {
                    int baseCheckX = positionX + offsetX;
                    int baseCheckY = positionY + offsetY;

                    bool canPlaceStatueHere = true;
                    for (int i = 0; i < 3; i++) //check no obstructing blocks
                    {
                        for (int j = 0; j < 4; j++)
                        {
                            Tile tile = Framing.GetTileSafely(baseCheckX + i, baseCheckY + j);
                            if (WorldGen.SolidOrSlopedTile(tile))
                            {
                                canPlaceStatueHere = false;
                                break;
                            }
                        }
                    }
                    for (int i = 0; i < 3; i++) //check for solid foundation
                    {
                        Tile tile = Framing.GetTileSafely(baseCheckX + i, baseCheckY + 4);
                        if (!WorldGen.SolidTile(tile) || !legalBlocks.Contains(tile.type))
                        {
                            canPlaceStatueHere = false;
                            break;
                        }
                    }

                    if (canPlaceStatueHere)
                    {
                        for (int i = 0; i < 3; i++) //MAKE SURE nothing in the way
                        {
                            for (int j = 0; j < 4; j++)
                            {
                                WorldGen.KillTile(baseCheckX + i, baseCheckY + j);
                            }
                        }

                        WorldGen.PlaceTile(baseCheckX, baseCheckY + 4, TileID.GrayBrick, false, true);
                        WorldGen.PlaceTile(baseCheckX + 1, baseCheckY + 4, TileID.GrayBrick, false, true);
                        WorldGen.PlaceTile(baseCheckX + 2, baseCheckY + 4, TileID.GrayBrick, false, true);
                        Main.tile[baseCheckX, baseCheckY + 4].slope(0);
                        Main.tile[baseCheckX + 1, baseCheckY + 4].slope(0);
                        Main.tile[baseCheckX + 2, baseCheckY + 4].slope(0);
                        WorldGen.PlaceTile(baseCheckX + 1, baseCheckY + 3, mod.TileType("MutantStatueGift"), false, true);

                        placed = true;
                        break;
                    }
                }
                if (placed)
                {
                    break;
                }
            }
        }
예제 #10
0
        public override void AI()
        {
            EModeGlobalNPC.championBoss = npc.whoAmI;

            if (npc.localAI[3] == 0) //just spawned
            {
                if (!npc.HasValidTarget)
                {
                    npc.TargetClosest(false);
                }

                if (npc.ai[1] == 0)
                {
                    npc.Center = Main.player[npc.target].Center + new Vector2(500 * Math.Sign(npc.Center.X - Main.player[npc.target].Center.X), -250);
                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        Projectile.NewProjectile(npc.Center + Vector2.UnitY * 1000, Vector2.Zero, ModContent.ProjectileType <EarthChainBlast2>(), 0, 0f, Main.myPlayer, -Vector2.UnitY.ToRotation(), 10);
                        Projectile.NewProjectile(npc.Center - Vector2.UnitY * 1000, Vector2.Zero, ModContent.ProjectileType <EarthChainBlast2>(), 0, 0f, Main.myPlayer, Vector2.UnitY.ToRotation(), 10);
                    }
                }

                if (++npc.ai[1] > 6 * 9) //nice
                {
                    npc.localAI[3] = 1;
                    npc.ai[1]      = 0;
                    npc.netUpdate  = true;

                    if (!Main.dedServ && Main.LocalPlayer.active)
                    {
                        Main.LocalPlayer.GetModPlayer <FargoPlayer>().Screenshake = 30;
                    }

                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        const int   max          = 8;
                        const float baseRotation = MathHelper.TwoPi / max;
                        for (int i = 0; i < max; i++)
                        {
                            float rotation = baseRotation * (i + Main.rand.NextFloat(-0.5f, 0.5f));
                            Projectile.NewProjectile(npc.Center, Vector2.Zero, ModContent.ProjectileType <EarthChainBlast2>(), 0, 0f, Main.myPlayer, rotation, 3);
                        }

                        int n = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <EarthChampionHand>(), npc.whoAmI, 0, 0, npc.whoAmI, 1);
                        if (n < Main.maxNPCs && Main.netMode == NetmodeID.Server)
                        {
                            NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n);
                        }

                        n = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, ModContent.NPCType <EarthChampionHand>(), npc.whoAmI, 0, 0, npc.whoAmI, -1);
                        if (n < Main.maxNPCs && Main.netMode == NetmodeID.Server)
                        {
                            NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n);
                        }
                    }
                }
                return;
            }

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

            if (npc.HasValidTarget && npc.Distance(player.Center) < 2500 && player.ZoneUnderworldHeight)
            {
                npc.timeLeft = 600;
            }

            npc.dontTakeDamage = false;
            npc.alpha          = 0;

            switch ((int)npc.ai[0])
            {
            case -1:
                npc.localAI[2] = 1;

                //npc.dontTakeDamage = true;
                npc.ai[1]++;

                npc.velocity *= 0.95f;

                /*if (npc.ai[1] < 120)
                 * {
                 *  targetPos = player.Center;
                 *  targetPos.Y -= 375;
                 *  if (npc.Distance(targetPos) > 50)
                 *      Movement(targetPos, 0.6f, 24f, true);
                 * }
                 * else*/
                if (npc.ai[1] == 120)     //begin healing
                {
                    Main.PlaySound(SoundID.NPCDeath10, npc.Center);

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

                        if (!Main.dedServ && Main.LocalPlayer.active)
                        {
                            Main.LocalPlayer.GetModPlayer <FargoPlayer>().Screenshake = 30;
                        }

                        if (Main.netMode != NetmodeID.MultiplayerClient)
                        {
                            const int max          = 8;
                            float     baseRotation = MathHelper.TwoPi / max * Main.rand.NextFloat();
                            for (int i = 0; i < max; i++)
                            {
                                float rotation = baseRotation + MathHelper.TwoPi / max * (i + Main.rand.NextFloat(-0.5f, 0.5f));
                                Projectile.NewProjectile(npc.Center, Vector2.Zero, ModContent.ProjectileType <EarthChainBlast2>(), 0, 0f, Main.myPlayer, rotation, 3);
                            }
                        }
                    }
                }
                else if (npc.ai[1] > 120)     //healing
                {
                    npc.velocity *= 0.9f;

                    int heal = (int)(npc.lifeMax / 2 / 120 * Main.rand.NextFloat(1f, 1.5f));
                    npc.life += heal;
                    if (npc.life > npc.lifeMax)
                    {
                        npc.life = npc.lifeMax;
                    }
                    CombatText.NewText(npc.Hitbox, CombatText.HealLife, heal);

                    for (int i = 0; i < 5; i++)
                    {
                        int d = Dust.NewDust(npc.Center, 0, 0, 174, 0f, 0f, 0, default(Color), 1.5f);
                        Main.dust[d].noGravity = true;
                        Main.dust[d].velocity *= 8f;
                    }

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

            case 0:                               //float over player
                if (!player.active || player.dead || Vector2.Distance(npc.Center, player.Center) > 2500f ||
                    !player.ZoneUnderworldHeight) //despawn code
                {
                    npc.TargetClosest(false);
                    if (npc.timeLeft > 30)
                    {
                        npc.timeLeft = 30;
                    }

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

                    return;
                }
                else
                {
                    targetPos    = player.Center;
                    targetPos.Y -= 325;
                    if (npc.Distance(targetPos) > 50)
                    {
                        Movement(targetPos, 0.4f, 16f, true);
                    }
                }

                if (npc.localAI[2] == 0 && npc.life < npc.lifeMax / 2)
                {
                    npc.ai[0] = -1;
                    npc.ai[1] = 0;
                    npc.ai[2] = 0;
                    npc.ai[3] = 0;

                    for (int i = 0; i < Main.maxNPCs; i++)     //find hands, update
                    {
                        if (Main.npc[i].active && Main.npc[i].type == ModContent.NPCType <EarthChampionHand>() && Main.npc[i].ai[2] == npc.whoAmI)
                        {
                            Main.npc[i].ai[0]      = -1;
                            Main.npc[i].ai[1]      = 0;
                            Main.npc[i].localAI[0] = 0;
                            Main.npc[i].localAI[1] = 0;
                            Main.npc[i].netUpdate  = true;
                        }
                    }
                }
                break;

            case 1:                               //fireballs
                if (!player.active || player.dead || Vector2.Distance(npc.Center, player.Center) > 2500f ||
                    !player.ZoneUnderworldHeight) //despawn code
                {
                    npc.TargetClosest(false);
                    if (npc.timeLeft > 30)
                    {
                        npc.timeLeft = 30;
                    }

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

                    return;
                }
                else
                {
                    targetPos = player.Center;
                    for (int i = 0; i < 22; i++)     //collision check above player's head
                    {
                        targetPos.Y -= 16;
                        Tile tile = Framing.GetTileSafely(targetPos);     //if solid, stay below it
                        if (tile.active() && !tile.inActive() && Main.tileSolid[tile.type] && !Main.tileSolidTop[tile.type])
                        {
                            targetPos.Y += 50 + 16;
                            break;
                        }
                    }

                    if (npc.Distance(targetPos) > 50)
                    {
                        Movement(targetPos, 0.2f, 12f, true);
                        npc.position += (targetPos - npc.Center) / 30;
                    }

                    if (--npc.ai[2] < 0)
                    {
                        npc.ai[2] = 75;
                        Main.PlaySound(4, npc.Center, 13);
                        if (npc.ai[1] > 10 && Main.netMode != NetmodeID.MultiplayerClient)     //shoot spread of fireballs, but not the first time
                        {
                            for (int i = -1; i <= 1; i++)
                            {
                                Projectile.NewProjectile(npc.Center + Vector2.UnitY * 60,
                                                         (npc.localAI[2] == 1 ? 12 : 8) * npc.DirectionTo(player.Center).RotatedBy(MathHelper.ToRadians(8 * i)),
                                                         ProjectileID.Fireball, npc.damage / 4, 0f, Main.myPlayer);
                            }
                        }
                    }

                    if (++npc.ai[1] > 480)
                    {
                        npc.ai[0]++;
                        npc.ai[1]     = 0;
                        npc.netUpdate = true;
                    }
                }

                if (npc.localAI[2] == 0 && npc.life < npc.lifeMax / 2)
                {
                    npc.ai[0] = -1;
                    npc.ai[1] = 0;
                    npc.ai[2] = 0;
                    npc.ai[3] = 0;

                    for (int i = 0; i < Main.maxNPCs; i++)     //find hands, update
                    {
                        if (Main.npc[i].active && Main.npc[i].type == ModContent.NPCType <EarthChampionHand>() && Main.npc[i].ai[2] == npc.whoAmI)
                        {
                            Main.npc[i].ai[0]      = -1;
                            Main.npc[i].ai[1]      = 0;
                            Main.npc[i].localAI[0] = 0;
                            Main.npc[i].localAI[1] = 0;
                            Main.npc[i].netUpdate  = true;
                        }
                    }
                }
                break;

            default:
                npc.ai[0] = 0;
                goto case 0;
            }
        }
예제 #11
0
        public override void AI()
        {
            Idle = false;
            if (FirstFrame)
            {
                int tileX = (int)(npc.Center.X * (1f / 16)), tileY = (int)(npc.Center.Y * (1f / 16));
                for (int y = 0; y >= -4; y--)
                {
                    for (int x = -2; x < 3; x++)
                    {
                        int TileX = tileX + x, TileY = tileY + y;
                        if (Main.tile[TileX, TileY].active() && Main.tile[TileX, TileY].type == Terraria.ID.TileID.Trees)
                        {
                            int SizeCount = 0;
                            while (Main.tile[TileX, TileY].active() && Main.tile[TileX, TileY].type == Terraria.ID.TileID.Trees)
                            {
                                TileY--;
                                SizeCount++;
                            }
                            TileY += 3;
                            if (SizeCount >= 9 && Main.tile[TileX, TileY].active() && Main.tile[TileX, TileY].type == Terraria.ID.TileID.Trees)
                            {
                                npc.position.X = TileX * 16 + 8 - npc.width * 0.25f;
                                npc.position.Y = TileY * 16 - npc.height * 0.5f;
                                return;
                            }
                        }
                    }
                }
            }
            if (Sleeping)
            {
                npc.velocity  = Vector2.Zero;
                npc.noGravity = true;
                int  TileCenterX     = (int)((npc.position.X + npc.width * 0.25f) * (1f / 16));
                int  TileCenterY     = (int)(npc.Center.Y * (1f / 16));
                bool SuspendedByTree = false;
                Tile tile            = Framing.GetTileSafely(TileCenterX, TileCenterY);
                if (tile != null && tile.active())
                {
                    SuspendedByTree = true;
                }
                if (!SuspendedByTree)
                {
                    Sleeping = false;
                    SayMessage("*W-what?!*", true);
                    npc.TargetClosest();
                }
                return;
            }
            npc.noGravity = false;
            bool PlayerKnowsGuardian = PlayerMod.PlayerHasGuardian(Main.player[npc.target], GuardianID);

            if (Step > 0)
            {
                if (Step < 5 && Math.Abs(Main.player[npc.target].Center.X - npc.Center.X) >= 1200)
                {
                    SayMessage("*Hey! I'm talking to you!*");
                    Step            = 1;
                    Timer           = 0;
                    Idle            = true;
                    PlayerMovedAway = true;
                }
                else
                {
                    if (PlayerMovedAway)
                    {
                        SayMessage("*You returned, now you have to listen to me.*");
                        Timer           = -120;
                        PlayerMovedAway = false;
                    }
                    if (Main.player[npc.target].Center.X < npc.Center.X)
                    {
                        npc.direction = -1;
                    }
                    else
                    {
                        npc.direction = 1;
                    }
                }
            }
            switch (Step)
            {
            case 0:
                if (npc.velocity.Y == 0)
                {
                    Timer++;
                    if (Timer >= 150)
                    {
                        Timer = 0;
                        Step++;
                    }
                }
                break;

            case 1:
                if (Timer == 50)
                {
                    if (PlayerKnowsGuardian)
                    {
                        SayMessage("*Again you destroyed the tree I was sleeping on.*", true);
                    }
                    else
                    {
                        SayMessage("*What is your problem? Didn't see me there?*", true);
                    }
                }
                Timer++;
                if (Timer >= 260)
                {
                    Timer = 0;
                    Step++;
                }
                break;

            case 2:
                if (Timer == 0)
                {
                    if (PlayerKnowsGuardian)
                    {
                        SayMessage("*Do you have anything against me sleeping on trees or something.*", true);
                    }
                    else
                    {
                        SayMessage("*Next time you want to get some lumber, look up-!*", true);
                    }
                }
                Timer++;
                if (Timer >= 210)
                {
                    Timer = 0;
                    Step++;
                }
                break;

            case 3:
                if (Timer == 0)
                {
                    if (PlayerKnowsGuardian)
                    {
                        SayMessage("*Ugh... Whatever...*", true);
                    }
                    else
                    {
                        SayMessage("*Wait a minute, aren't you a Terrarian.*", true);
                    }
                }
                Timer++;
                if (Timer >= 180)
                {
                    Timer = 0;
                    Step++;
                }
                break;

            case 4:
                if (Timer == 0)
                {
                    if (PlayerKnowsGuardian)
                    {
                        SayMessage("*I'm here if you ever need a medic... Now I need to look for a safe place for a nap.*", true);
                        NpcMod.AddGuardianMet(GuardianID, GuardianModID);
                        WorldMod.TurnNpcIntoGuardianTownNpc(npc, GuardianID, GuardianModID);
                        return;
                    }
                    else
                    {
                        SayMessage("*Hm... I wonder if...*", true);
                    }
                }
                Timer++;
                if (Timer >= 180)
                {
                    Timer = 0;
                    Step++;
                }
                break;

            case 5:
                if (Timer == 0)
                {
                    SayMessage("*If you can understand me, could you try speaking to me?*", true);
                    Timer++;
                }
                break;

            default:
                if (Step >= 6)
                {
                    bool AnyoneSpeakingToMe = false;
                    for (int i = 0; i < 255; i++)
                    {
                        if (Main.player[i].active && Main.player[i].talkNPC == npc.whoAmI)
                        {
                            AnyoneSpeakingToMe = true;
                            break;
                        }
                    }
                    if (!AnyoneSpeakingToMe)
                    {
                        Step  = 5;
                        Timer = 1;
                        SayMessage("*I still would like if we could speak some more, Terrarian.*");
                    }
                }
                break;
            }
            base.AI();
        }
예제 #12
0
        public bool ExposedToSunlight()
        {
            Vampire _Vampire = ModContent.GetInstance <Vampire>();

            Tile[] smallWallTiles       = new Tile[2];
            Point  playerTilePointSmall = (Main.LocalPlayer.position / 16).ToPoint();

            smallWallTiles[0] = Framing.GetTileSafely(playerTilePointSmall.X, playerTilePointSmall.Y);
            smallWallTiles[1] = Framing.GetTileSafely(playerTilePointSmall.X + 1, playerTilePointSmall.Y);
            bool behindSmallWall = false;

            foreach (var tile in smallWallTiles)
            {
                if (tile.wall > 0)
                {
                    behindSmallWall = true;
                }
                else
                {
                    behindSmallWall = false;
                    break;
                }
            }
            Tile[] wallTiles       = new Tile[6];
            Point  playerTilePoint = (Main.LocalPlayer.position / 16).ToPoint();

            wallTiles[0] = Framing.GetTileSafely(playerTilePoint.X, playerTilePoint.Y);
            wallTiles[1] = Framing.GetTileSafely(playerTilePoint.X, playerTilePoint.Y + 1);
            wallTiles[2] = Framing.GetTileSafely(playerTilePoint.X, playerTilePoint.Y + 2);
            wallTiles[3] = Framing.GetTileSafely(playerTilePoint.X + 1, playerTilePoint.Y);
            wallTiles[4] = Framing.GetTileSafely(playerTilePoint.X + 1, playerTilePoint.Y + 1);
            wallTiles[5] = Framing.GetTileSafely(playerTilePoint.X + 1, playerTilePoint.Y + 2);
            bool behindWall = false;

            foreach (var tile in wallTiles)
            {
                if (tile.wall > 0)
                {
                    behindWall = true;
                }
                else
                {
                    behindWall = false;
                    break;
                }
            }
            Tile[] largeWallTiles       = new Tile[36];
            Point  playerTilePointLarge = (Main.LocalPlayer.position / 16).ToPoint();

            largeWallTiles[0]  = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 15);
            largeWallTiles[1]  = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 14);
            largeWallTiles[2]  = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 13);
            largeWallTiles[3]  = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 12);
            largeWallTiles[4]  = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 11);
            largeWallTiles[5]  = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 10);
            largeWallTiles[6]  = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 9);
            largeWallTiles[7]  = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 8);
            largeWallTiles[8]  = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 7);
            largeWallTiles[9]  = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 6);
            largeWallTiles[10] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 5);
            largeWallTiles[11] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 4);
            largeWallTiles[12] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 3);
            largeWallTiles[13] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 2);
            largeWallTiles[14] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y - 1);
            largeWallTiles[15] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y);
            largeWallTiles[16] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y + 1);
            largeWallTiles[17] = Framing.GetTileSafely(playerTilePointLarge.X, playerTilePointLarge.Y + 2);
            largeWallTiles[18] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 15);
            largeWallTiles[19] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 14);
            largeWallTiles[20] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 13);
            largeWallTiles[21] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 12);
            largeWallTiles[22] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 11);
            largeWallTiles[23] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 10);
            largeWallTiles[24] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 9);
            largeWallTiles[25] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 8);
            largeWallTiles[26] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 7);
            largeWallTiles[27] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 6);
            largeWallTiles[28] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 5);
            largeWallTiles[29] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 4);
            largeWallTiles[30] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 3);
            largeWallTiles[31] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 2);
            largeWallTiles[32] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y - 1);
            largeWallTiles[33] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y);
            largeWallTiles[34] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y + 1);
            largeWallTiles[35] = Framing.GetTileSafely(playerTilePointLarge.X + 1, playerTilePointLarge.Y + 2);
            bool behindLargeWall = false;

            foreach (var tile in largeWallTiles)
            {
                if (tile.wall > 0)
                {
                    behindLargeWall = true;
                }
                else
                {
                    behindLargeWall = false;
                    break;
                }
            }
            bool    hasCeilingTile = false;
            Vector2 playerLocation = new Vector2(player.Center.X / 16, player.Center.Y / 16);

            for (int i = 0; i < 60; i++)
            {
                Tile ceilingTile = Main.tile[(int)playerLocation.X, (int)playerLocation.Y];
                if (ceilingTile != null && Main.tileSolid[ceilingTile.type] && ceilingTile.nactive())
                {
                    hasCeilingTile = true;
                }
                if (playerLocation.Y > 0)
                {
                    playerLocation.Y -= 1;
                }
            }
            bool hasCeilingAbove = false;

            if (behindLargeWall || hasCeilingTile)
            {
                hasCeilingAbove = true;
            }
            else
            {
                hasCeilingAbove = false;
            }
            if (!_Vampire.VampireTransformation)
            {
                return((!hasCeilingAbove || !behindWall) && !((double)player.Center.Y > Main.worldSurface * 16.0) && Main.dayTime && !(Collision.DrownCollision(player.position, player.width, player.height, player.gravDir)));
            }
            else
            {
                return((!hasCeilingAbove || !behindSmallWall) && !((double)player.Center.Y > Main.worldSurface * 16.0) && Main.dayTime && !(Collision.DrownCollision(player.position, player.width, player.height, player.gravDir)));
            }
        }
예제 #13
0
        /// <summary>Generates a large island at X/Y.</summary>
        /// <param name="x">X position.</param>
        /// <param name="y">Y position.</param>
        private static void CreateIsland(int x, int y, bool small = false)
        {
            int wid = genRand.Next(32, 42);

            if (small)
            {
                wid = genRand.Next(10, 18);
            }
            int top   = 5;
            int depth = 2;

            bool peak      = false;
            int  peakEnd   = 0;
            int  peakStart = 0;
            int  offset    = 0;

            for (int i = x - (int)(wid / 2f); i < x + (wid / 2f); ++i)
            {
                if (i == x - (int)(wid / 2f) + 1)
                {
                    top++;
                }
                else if (i == (x + (int)(wid / 2f)) - 1)
                {
                    top--;
                }

                if (!peak)
                {
                    if (depth <= 2)
                    {
                        depth += genRand.Next(2);
                    }
                    else
                    {
                        depth += genRand.Next(-1, 2);
                    }

                    if (genRand.Next(3) == 0)
                    {
                        peak      = true;
                        peakStart = i;
                        peakEnd   = i + genRand.Next(3, 8);
                        if (peakEnd > (x + (wid / 2f)) - 1)
                        {
                            peakEnd = (int)(x + (wid / 2f)) - 1;
                        }
                    }
                }
                else
                {
                    int dist = peakEnd - i;
                    int dif  = peakEnd - peakStart;
                    int deep = (7 - dif);

                    if (dist > (int)(dif / 2f))
                    {
                        depth += genRand.Next(deep, deep + 2);
                    }
                    else
                    {
                        depth -= genRand.Next(deep, deep + 2);
                    }

                    if (x >= peakEnd)
                    {
                        peak = false;
                    }
                }

                if (i % 4 == 0)
                {
                    if (i < x)
                    {
                        top += genRand.Next(2);
                    }
                    else
                    {
                        top -= genRand.Next(2);
                    }
                }

                if (i % 8 == 2)
                {
                    offset += genRand.Next(-1, 2);
                }

                if (top < 3)
                {
                    top = 3;
                }

                if (i > x + (wid / 2f) - 4 && depth > 4)
                {
                    depth--;
                }
                if (i > x + (wid / 2f) - 4 && depth > 8)
                {
                    depth--;
                }

                for (int j = y - top + offset; j < y + depth + offset; j++)
                {
                    int t = j > (y + depth + offset) - 4 ? TileType <VitricSand>() : TileType <VitricSoftSand>();
                    PlaceTile(i, j, t, false, true);
                }
            }

            //Place crystal if needed
            if (crystalsPlaced <= (VitricBiome.Width / 240) + 2 && !small)
            {
                int tries = 0;
                while (true)
                {
                    int cX = x + genRand.Next((int)(wid * -0.60f), (int)(wid * 0.60f)) - 3;
                    int cY = y - 5;
                    while (Main.tile[cX, cY].active())
                    {
                        cY--;
                    }
                    cY = Math.Max(
                        FindType(cX, cY, -1, ValidGround),
                        FindType(cX + 1, cY, -1, ValidGround)
                        );
                    if (ValidGround.Any(v => v == Main.tile[cX + 1, cY].type) && ValidGround.Any(v => v == Main.tile[cX + 2, cY].type) && ScanRectangle(cX, cY - 6, 4, 6) < 3)
                    {
                        StructureHelper.StructureHelper.GenerateStructure(
                            "Structures/Vitric/VitricSmallCrystal_" + genRand.Next(2),
                            new Point16(cX, cY - 6),
                            StarlightRiver.Instance
                            );
                        crystalsPlaced++;
                        break;
                    }
                    else
                    if (tries++ >= 20)
                    {
                        break;
                    }
                }
            }
            else if (small)
            {
                // Input variables
                int spawnAttempts = 30;
                int cX, cY;

                // Perform several checks
                while (spawnAttempts-- > 0)
                {
                    cX = x + genRand.Next((int)(wid * -0.60f), (int)(wid * 0.60f)) - 3;
                    cY = y - 5;
                    cY = FindType(cX, cY, -1, ValidGround);
                    // If the left side of the crystal isn't valid,
                    // or if the right side is occupied,
                    // skip.
                    if (cY == -1)
                    {
                        continue;
                    }

                    // If there are solid tiles in the way, skip.
                    if (ScanRectangle(cX, cY - 3, 2, 3) > 2)
                    {
                        continue;
                    }

                    // Success! Halve the spawnAttempts count so we don't spam crystals.
                    PlaceTile(cX + 1, cY, Framing.GetTileSafely(cX, cY).type, true, true);
                    Helper.PlaceMultitile(new Point16(cX, cY - 3), TileType <VitricOre>());
                    spawnAttempts /= 4;
                }
            }
        }
예제 #14
0
        /// <summary>Generates basic biome shape, such as curved walls, noise on floor and ceiling, and spikes on the bottom.</summary>
        /// <seealso cref="https://github.com/Auburns/FastNoise_CSharp"/>
        private static void GenerateBase(int minCeilingDepth, int maxCeilingDepth, int minFloorDepth)
        {
            genNoise.Seed              = _genRandSeed;
            genNoise.FractalGain       = 0.04f;
            genNoise.Frequency         = 0.004f;
            genNoise.FractalLacunarity = 3.0f;
            genNoise.FractalOctaves    = 2;
            genNoise.NoiseType         = FastNoise.NoiseTypes.SimplexFractal; //Sets noise to proper type
            float[] heights = new float[VitricBiome.Width];                   //2D heightmap to create terrain

            for (int x = 0; x < heights.Length; x++)
            {
                heights[x] = genNoise.GetNoise(x, 0);
            }

            float leftCurveConst  = 13f; // 15f - ((0.3f + heights[0]) * VitricNoiseHeight); //For curving down into the noise properly, left side
            float rightCurveConst = 13f; // 15f - ((0.3f + heights[heights.Length - 1]) * VitricNoiseHeight); //Right side

            //Controls Y location of the top, ceiling, floor and bottom of the biome
            Dictionary <string, int> layers = new Dictionary <string, int> {
                { "TOP", 0 }, { "CEILING", 0 }, { "FLOOR", 0 }, { "BOTTOM", 0 }
            };

            for (int x = VitricBiome.X; x < VitricBiome.X + VitricBiome.Width; x++) //Basic biome shape
            {
                int xDif    = x - VitricBiome.X;
                int adjXDif = (VitricBiome.Width - xDif);

                if (xDif < VitricSlopeOffset)                                                        //Start curve
                {
                    layers["CEILING"] = (int)((VitricBiome.Center.Y) - (17f * Math.Log(-8 + xDif))); //17f is the constant that goes to the roof
                    layers["TOP"]     = (int)((VitricBiome.Center.Y) - (17f * Math.Log(-8 + (xDif + 12)))) - 12;

                    if (xDif < 10)
                    {
                        layers["CEILING"] = VitricBiome.Y + VitricBiome.Height / 2;
                    }
                    else if (xDif < 17)
                    {
                        layers["CEILING"] += genRand.Next(-1, 2);
                    }

                    if (layers["TOP"] < VitricBiome.Y)
                    {
                        layers["TOP"] = VitricBiome.Y;                                                                           //Caps off top
                    }
                    layers["FLOOR"]  = (int)(VitricBiome.Y + (leftCurveConst * Math.Log(-8 + xDif))) + (VitricBiome.Height / 2); //Curves down towards floor
                    layers["BOTTOM"] = (int)(VitricBiome.Y + (leftCurveConst * Math.Log(-8 + (xDif + 12)))) + (VitricBiome.Height / 2) + 32;

                    if (xDif < 10)
                    {
                        layers["FLOOR"] = VitricBiome.Y + VitricBiome.Height / 2;
                    }
                    else if (xDif < 17)
                    {
                        layers["FLOOR"] += genRand.Next(-1, 2);
                    }

                    if (layers["BOTTOM"] > VitricBiome.Y + VitricBiome.Height)
                    {
                        layers["BOTTOM"] = VitricBiome.Y + VitricBiome.Height;                                                        //Caps off bottom
                    }
                }
                else if (xDif == VitricSlopeOffset)
                {
                    layers["CEILING"] = minCeilingDepth;                                           //Flatway start
                }
                else if (xDif > VitricSlopeOffset && xDif < VitricBiome.Width - VitricSlopeOffset) //Flatway
                {
                    if (genRand.Next(2) == 0 && x % 2 == 1)
                    {
                        if (layers["CEILING"] >= minCeilingDepth && layers["CEILING"] <= maxCeilingDepth)
                        {
                            layers["CEILING"] += genRand.Next(-1, 2);
                        }
                    }

                    if (layers["TOP"] >= layers["CEILING"])
                    {
                        layers["TOP"] = layers["CEILING"];
                    }
                    if (layers["CEILING"] < minCeilingDepth)
                    {
                        layers["CEILING"] += genRand.Next(2);
                    }
                    if (layers["CEILING"] > maxCeilingDepth || (layers["CEILING"] > VitricBiome.Y + 12 && x > VitricBiome.Center.X - 30 && x < VitricBiome.Center.X + 30))
                    {
                        layers["CEILING"] -= genRand.Next(2);
                    }

                    if (xDif < (VitricBiome.Width / 2) - 81 && xDif > (VitricBiome.Width / 2) + 84 && layers["CEILING"] > VitricBiome.Y + 7) //Adjust for boss pillars
                    {
                        layers["CEILING"]--;
                    }
                    if (x < VitricBiome.Y - VitricSlopeOffset - 16 && layers["CEILING"] > VitricBiome.Y + 4)
                    {
                        layers["CEILING"]--;
                    }

                    layers["FLOOR"] = (int)Math.Floor(minFloorDepth - ((0.3f + heights[x - VitricBiome.X]) * VitricNoiseHeight));

                    if (x < VitricBiome.Center.X - 35 && genRand.Next(4) == 0)
                    {
                        layers["TOP"] -= genRand.Next(2);
                    }
                    if (x > VitricBiome.Center.X + 35 && genRand.Next(4) == 0)
                    {
                        layers["TOP"] += genRand.Next(2);
                    }
                    if (layers["TOP"] > VitricBiome.Y)
                    {
                        layers["TOP"] = VitricBiome.Y;
                    }
                }
                else //End curve
                {
                    layers["CEILING"] = (int)(VitricBiome.Center.Y - (17f * Math.Log(-8 + adjXDif)));
                    layers["TOP"]     = (int)(VitricBiome.Center.Y - (17f * Math.Log(-8 + (adjXDif + 12)))) - 12;

                    if (layers["TOP"] < VitricBiome.Y)
                    {
                        layers["TOP"] = VitricBiome.Y;                                //Caps off top
                    }
                    if (xDif > VitricBiome.Width - 10)
                    {
                        layers["CEILING"] = VitricBiome.Center.Y;
                    }
                    else if (xDif > VitricBiome.Width - 17)
                    {
                        layers["CEILING"] += genRand.Next(-1, 2);
                    }

                    layers["FLOOR"]  = (int)(VitricBiome.Y + (rightCurveConst * Math.Log(-8 + adjXDif))) + (VitricBiome.Height / 2);
                    layers["BOTTOM"] = (int)(VitricBiome.Y + (rightCurveConst * Math.Log(-8 + (adjXDif + 12)))) + (VitricBiome.Height / 2) + 27;

                    if (xDif < 10)
                    {
                        layers["FLOOR"] = VitricBiome.Center.Y;
                    }
                    else if (xDif < 17)
                    {
                        layers["FLOOR"] += genRand.Next(-1, 2);
                    }

                    if (layers["BOTTOM"] > VitricBiome.Bottom)
                    {
                        layers["BOTTOM"] = VitricBiome.Bottom;                                        //Caps off bottom
                    }
                }

                if (layers["CEILING"] > VitricBiome.Y + VitricBiome.Height / 2)
                {
                    layers["CEILING"] = VitricBiome.Y + VitricBiome.Height / 2;
                }
                if (layers["FLOOR"] < VitricBiome.Y + VitricBiome.Height / 2)
                {
                    layers["FLOOR"] = VitricBiome.Y + VitricBiome.Height / 2;
                }

                for (int y = layers["CEILING"]; y < layers["FLOOR"]; ++y) //Dig out cave
                {
                    Framing.GetTileSafely(x, y).ClearEverything();
                }

                for (int y = layers["TOP"] - 8; y < layers["CEILING"]; ++y)
                {
                    if (x > VitricBiome.Center.X - 35 && x <= VitricBiome.Center.X + 36)
                    {
                        break;
                    }
                    int  xRand = xDif < 20 ? xDif : VitricBiome.Width - xDif;
                    Tile t     = Main.tile[x, y];
                    if ((y < layers["TOP"] && genRand.Next(layers["TOP"] - y) == 0 && t.active() && Main.tileSolid[t.type]) || ((xDif <8 || xDif> VitricBiome.Width - 8) && genRand.Next(xRand) == 0) || y >= layers["TOP"])
                    {
                        PlaceTile(x, y, TileType <VitricSand>(), false, true);
                        t.slope(0);
                        KillWall(x, y, false);
                    }
                }

                for (int y = layers["FLOOR"] - (9 - genRand.Next(2)); y < layers["BOTTOM"] + 8; ++y)
                {
                    bool validSpike = y < layers["FLOOR"] && y >= (VitricBiome.Y + (VitricBiome.Height / 2f));
                    int  xRand      = xDif < 20 ? xDif : VitricBiome.Width - xDif;
                    Tile t          = Main.tile[x, y];
                    if ((y > layers["BOTTOM"] && genRand.Next(y - layers["BOTTOM"]) == 0 && t.active() && Main.tileSolid[t.type]) || ((xDif <8 || xDif> VitricBiome.Width - 8) && genRand.Next(xRand) == 0) || y <= layers["BOTTOM"])
                    {
                        PlaceTile(x, y, validSpike ? TileType <VitricSpike>() : TileType <VitricSand>(), false, true);
                        t.slope(0);
                        KillWall(x, y, false);
                    }
                }
            }
        }
예제 #15
0
        public override bool NewRightClick(int i, int j)
        {
            Player player         = Main.LocalPlayer;
            Tile   tile           = Main.tile[i, j];
            bool   anycursedarmor = false;

            for (int indexX = -70; indexX <= 70; indexX++)
            {
                for (int indexY = -90; indexY <= 90; indexY++)
                {
                    if (Framing.GetTileSafely(indexX + i, indexY + j).type == mod.TileType("CursedArmor"))
                    {
                        WorldGen.KillTile(indexX + i, indexY + j);

                        if (Main.netMode != NetmodeID.SinglePlayer)
                        {
                            NetMessage.SendData(MessageID.TileChange, -1, -1, null, 0, indexX + i, indexY + j);
                        }

                        anycursedarmor = true;
                    }
                }
            }
            if (anycursedarmor)
            {
                CombatText.NewText(new Rectangle(i * 16, j * 16, 20, 10), Color.GreenYellow, "Trapped!");
                return(true);
            }
            else if (NPC.AnyNPCs(ModContent.NPCType <Enchanted_Armor>()))
            {
                Main.PlaySound(new LegacySoundStyle(SoundID.NPCKilled, 6).WithPitchVariance(0.2f).WithVolume(0.5f), new Vector2(i * 16, j * 16));
                foreach (NPC npc in Main.npc.Where(x => x.active && x.type == ModContent.NPCType <Enchanted_Armor>()))
                {
                    npc.ai[1] = 30;
                }

                return(true);
            }

            Main.mouseRightRelease = false;
            int left = i;
            int top  = j;

            if (tile.frameX % 36 != 0)
            {
                left--;
            }
            if (tile.frameY != 0)
            {
                top--;
            }
            if (player.sign >= 0)
            {
                Main.PlaySound(SoundID.MenuClose);
                player.sign      = -1;
                Main.editSign    = false;
                Main.npcChatText = "";
            }
            if (Main.editChest)
            {
                Main.PlaySound(SoundID.MenuTick);
                Main.editChest   = false;
                Main.npcChatText = "";
            }
            if (player.editedChestName)
            {
                NetMessage.SendData(MessageID.SyncPlayerChest, -1, -1, NetworkText.FromLiteral(Main.chest[player.chest].name), player.chest, 1f, 0f, 0f, 0, 0, 0);
                player.editedChestName = false;
            }
            if (Main.netMode == NetmodeID.MultiplayerClient)
            {
                if (left == player.chestX && top == player.chestY && player.chest >= 0)
                {
                    player.chest = -1;
                    Recipe.FindRecipes();
                    Main.PlaySound(SoundID.MenuClose);
                }
                else
                {
                    NetMessage.SendData(MessageID.RequestChestOpen, -1, -1, null, left, top, 0f, 0f, 0, 0, 0);
                    Main.stackSplit = 600;
                }
            }
            else
            {
                int chest = Chest.FindChest(left, top);
                if (chest >= 0)
                {
                    Main.stackSplit = 600;
                    if (chest == player.chest)
                    {
                        player.chest = -1;
                        Main.PlaySound(SoundID.MenuClose);
                    }
                    else
                    {
                        player.chest         = chest;
                        Main.playerInventory = true;
                        Main.recBigList      = false;
                        player.chestX        = left;
                        player.chestY        = top;
                        Main.PlaySound(player.chest < 0 ? SoundID.MenuOpen : SoundID.MenuTick);
                    }
                    Recipe.FindRecipes();
                }
            }
            return(true);
        }
예제 #16
0
        public override void AI()
        {
            projectile.frameCounter++;
            if (projectile.frameCounter >= 8)
            {
                projectile.frameCounter = 0;
                projectile.frame       += 1;
            }
            if (projectile.frame > 5)
            {
                projectile.frame = 0;
            }

            Player   player    = Main.player[projectile.owner];
            AAPlayer modPlayer = player.GetModPlayer <AAPlayer>();

            if (player.dead)
            {
                modPlayer.TerraMinion = false;
            }
            if (modPlayer.TerraMinion)
            {
                projectile.timeLeft = 2;
            }

            dust--;
            if (dust >= 0)
            {
                int num501 = 50;
                for (int num502 = 0; num502 < num501; num502++)
                {
                    int num503 = Dust.NewDust(new Vector2(projectile.position.X, projectile.position.Y + 16f), projectile.width, projectile.height - 16, 107, 0f, 0f, 0);
                    Main.dust[num503].noGravity = true;
                    Main.dust[num503].velocity *= 2f;
                    Main.dust[num503].scale    *= 1.15f;
                }
            }
            projectile.frameCounter++;
            if (projectile.frameCounter > 8)
            {
                projectile.frame++;
                projectile.frameCounter = 0;
            }
            if (projectile.frame > 4)
            {
                projectile.frame = 0;
            }
            float num = Main.rand.Next(90, 111) * 0.01f;

            num *= Main.essScale;
            Lighting.AddLight(projectile.Center, 1f * num, 0f * num, 0.15f * num);
            projectile.rotation = projectile.velocity.X * 0.04f;

            float num633 = 700f;
            float num634 = 800f;
            float num635 = 1200f;
            float num636 = 150f;
            float num637 = 0.05f;

            for (int num638 = 0; num638 < 1000; num638++)
            {
                bool flag23 = Main.projectile[num638].type == mod.ProjectileType("TerraWizard");
                if (num638 != projectile.whoAmI && Main.projectile[num638].active && Main.projectile[num638].owner == projectile.owner && flag23 && Math.Abs(projectile.position.X - Main.projectile[num638].position.X) + Math.Abs(projectile.position.Y - Main.projectile[num638].position.Y) < projectile.width)
                {
                    if (projectile.position.X < Main.projectile[num638].position.X)
                    {
                        projectile.velocity.X = projectile.velocity.X - num637;
                    }
                    else
                    {
                        projectile.velocity.X = projectile.velocity.X + num637;
                    }
                    if (projectile.position.Y < Main.projectile[num638].position.Y)
                    {
                        projectile.velocity.Y = projectile.velocity.Y - num637;
                    }
                    else
                    {
                        projectile.velocity.Y = projectile.velocity.Y + num637;
                    }
                }
            }
            bool flag24 = false;

            if (projectile.ai[0] == 2f)
            {
                projectile.ai[1]       += 1f;
                projectile.extraUpdates = 1;
                if (projectile.ai[1] > 40f)
                {
                    projectile.ai[1]        = 1f;
                    projectile.ai[0]        = 0f;
                    projectile.extraUpdates = 0;
                    projectile.numUpdates   = 0;
                    projectile.netUpdate    = true;
                }
                else
                {
                    flag24 = true;
                }
            }
            if (flag24)
            {
                return;
            }
            Vector2 vector46 = projectile.position;
            bool    flag25   = false;

            if (projectile.ai[0] != 1f)
            {
                projectile.tileCollide = false;
            }
            if (projectile.tileCollide && WorldGen.SolidTile(Framing.GetTileSafely((int)projectile.Center.X / 16, (int)projectile.Center.Y / 16)))
            {
                projectile.tileCollide = false;
            }
            if (player.HasMinionAttackTargetNPC)
            {
                NPC nPC2 = Main.npc[player.MinionAttackTargetNPC];
                if (nPC2.CanBeChasedBy(projectile, false))
                {
                    float num646 = Vector2.Distance(nPC2.Center, projectile.Center);
                    if (((Vector2.Distance(projectile.Center, vector46) > num646 && num646 < num633) || !flag25) && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, nPC2.position, nPC2.width, nPC2.height))
                    {
                        num633   = num646;
                        vector46 = nPC2.Center;
                        flag25   = true;
                    }
                }
            }
            else
            {
                for (int num645 = 0; num645 < 200; num645++)
                {
                    NPC nPC2 = Main.npc[num645];
                    if (nPC2.CanBeChasedBy(projectile, false))
                    {
                        float num646 = Vector2.Distance(nPC2.Center, projectile.Center);
                        if (((Vector2.Distance(projectile.Center, vector46) > num646 && num646 < num633) || !flag25) && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, nPC2.position, nPC2.width, nPC2.height))
                        {
                            num633   = num646;
                            vector46 = nPC2.Center;
                            flag25   = true;
                        }
                    }
                }
            }
            float num647 = num634;

            if (flag25)
            {
                num647 = num635;
            }

            if (flag25)
            {
                projectile.spriteDirection = ((vector46 - projectile.Center).X > 0? -1: 1);
            }
            else
            {
                projectile.spriteDirection = (projectile.velocity.X > 0? -1: 1);
            }

            if (Vector2.Distance(player.Center, projectile.Center) > num647)
            {
                projectile.ai[0]       = 1f;
                projectile.tileCollide = false;
                projectile.netUpdate   = true;
            }
            if (flag25 && projectile.ai[0] == 0f)
            {
                Vector2 vector47 = vector46 - projectile.Center;
                float   num648   = vector47.Length();
                vector47.Normalize();
                if (num648 > 200f)
                {
                    float scaleFactor2 = 8f;
                    vector47           *= scaleFactor2;
                    projectile.velocity = (projectile.velocity * 40f + vector47) / 41f;
                }
                else
                {
                    float num649 = 4f;
                    vector47           *= -num649;
                    projectile.velocity = (projectile.velocity * 40f + vector47) / 41f;
                }
            }
            else
            {
                bool flag26 = false;
                if (!flag26)
                {
                    flag26 = projectile.ai[0] == 1f;
                }
                float num650 = 5f; //6
                if (flag26)
                {
                    num650 = 12f; //15
                }
                Vector2 center2  = projectile.Center;
                Vector2 vector48 = player.Center - center2 + new Vector2(0f, -30f); //-60
                float   num651   = vector48.Length();
                if (num651 > 200f && num650 < 6.5f)                                 //200 and 8
                {
                    num650 = 6.5f;                                                  //8
                }
                if (num651 < num636 && flag26 && !Collision.SolidCollision(projectile.position, projectile.width, projectile.height))
                {
                    projectile.ai[0]     = 0f;
                    projectile.netUpdate = true;
                }
                if (num651 > 2000f)
                {
                    projectile.position.X = Main.player[projectile.owner].Center.X - (projectile.width / 2);
                    projectile.position.Y = Main.player[projectile.owner].Center.Y - (projectile.height / 2);
                    projectile.netUpdate  = true;
                }
                if (num651 > 70f)
                {
                    vector48.Normalize();
                    vector48           *= num650;
                    projectile.velocity = (projectile.velocity * 40f + vector48) / 41f;
                }
                else if (projectile.velocity.X == 0f && projectile.velocity.Y == 0f)
                {
                    projectile.velocity.X = -0.2f;
                    projectile.velocity.Y = -0.1f;
                }
            }
            if (projectile.ai[1] > 0f)
            {
                projectile.ai[1] += Main.rand.Next(1, 4);
            }
            if (projectile.ai[1] > 80f)
            {
                projectile.ai[1]     = 0f;
                projectile.netUpdate = true;
            }
            if (projectile.ai[0] == 0f)
            {
                float scaleFactor3 = 8f;
                int   num658       = ModContent.ProjectileType <TerraBlast>();
                if (flag25 && projectile.ai[1] == 0f)
                {
                    projectile.ai[1] += 1f;
                    if (Main.myPlayer == projectile.owner && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, vector46, 0, 0))
                    {
                        Vector2 value19 = vector46 - projectile.Center;
                        value19.Normalize();
                        value19 *= scaleFactor3;
                        int num659 = Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, value19.X, value19.Y, num658, projectile.damage, 0f, Main.myPlayer, 0f, 0f);
                        Main.projectile[num659].timeLeft = 300;
                        projectile.netUpdate             = true;
                    }
                }
            }
        }
예제 #17
0
        private PlantStage GetStage(int i, int j)
        {
            Tile tile = Framing.GetTileSafely(i, j);

            return((PlantStage)(tile.frameX / FrameWidth));
        }
예제 #18
0
        public override void RandomUpdate(int i, int j, int type)
        {
            if (type == 367)
            {
                if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && TileArray2.Contains(Framing.GetTileSafely(i, j - 2).type))
                {
                    if (Main.rand.Next(800) == 0)
                    {
                        WorldGen.PlaceObject(i - 1, j - 1, mod.TileType("Medustalk"));
                        NetMessage.SendObjectPlacment(-1, i - 1, j - 1, mod.TileType("Medustalk"), 0, 0, -1, -1);
                    }
                }
            }

            if (type == 147)
            {
                if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && TileArray2.Contains(Framing.GetTileSafely(i, j - 2).type))
                {
                    if (Main.rand.Next(1800) == 0)
                    {
                        WorldGen.PlaceObject(i - 1, j - 1, mod.TileType("FrostShine"));
                        NetMessage.SendObjectPlacment(-1, i - 1, j - 1, mod.TileType("FrostShine"), 0, 0, -1, -1);
                    }
                }
            }

            if (type == 2)
            {
                if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && (i < (Main.maxTilesX / 5) || i > Main.maxTilesX - (Main.maxTilesX / 5)))
                {
                    if (Main.rand.Next(400) == 0)
                    {
                        int why = Main.rand.Next(8);
                        WorldGen.PlaceObject(i, j - why, mod.TileType("Bamboo"));
                        NetMessage.SendObjectPlacment(-1, i, j - why, mod.TileType("Bamboo"), 0, 0, -1, -1);
                    }
                }
            }

            if (type == 2)             //add water support later
            {
                bool place = false;
                for (int x = i - 5; x < i + 5; x++)
                {
                    for (int y = j; y < j + 5; y++)
                    {
                        if (Main.tile[x, y].liquid == 255)
                        {
                            place = true;
                        }
                    }
                }

                if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && TileArray2.Contains(Framing.GetTileSafely(i, j - 2).type) && place)
                {
                    if (Main.rand.Next(800) == 1)
                    {
                        WorldGen.PlaceObject(i - 1, j - 1, mod.TileType("CatTail"));
                        NetMessage.SendObjectPlacment(-1, i - 1, j - 1, mod.TileType("CatTail"), 0, 0, -1, -1);
                    }
                }
            }

            if (type == 1)             //magma corn
            {
                bool place = false;
                for (int x = i - 7; x < i + 7; x++)
                {
                    for (int y = j; y < j + 7; y++)
                    {
                        if (Main.tile[x, y].liquid == 255 && Main.tile[x, y].lava())
                        {
                            place = true;
                        }
                    }
                }

                if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && TileArray2.Contains(Framing.GetTileSafely(i, j - 2).type) && place)
                {
                    if (Main.rand.Next(800) == 1)
                    {
                        WorldGen.PlaceObject(i - 1, j - 1, mod.TileType("MagmaCorn"));
                        NetMessage.SendObjectPlacment(-1, i - 1, j - 1, mod.TileType("MagmaCorn"), 0, 0, -1, -1);
                    }
                }
            }

            if (type == 2)             //add water support later
            {
                if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && TileArray2.Contains(Framing.GetTileSafely(i, j - 2).type))
                {
                    if (Main.rand.Next(1800) == 2)
                    {
                        WorldGen.PlaceObject(i - 1, j - 1, mod.TileType("StrawberryPlant"));
                        NetMessage.SendObjectPlacment(-1, i - 1, j - 1, mod.TileType("StrawberryPlant"), 0, 0, -1, -1);
                    }
                }
            }


            if (type == 368)
            {
                if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && TileArray2.Contains(Framing.GetTileSafely(i, j - 2).type))
                {
                    if (Main.rand.Next(1400) == 0)
                    {
                        WorldGen.PlaceObject(i - 1, j - 1, mod.TileType("FluxCoral"));
                        NetMessage.SendObjectPlacment(-1, i - 1, j - 1, mod.TileType("FluxCoral"), 0, 0, -1, -1);
                    }
                }
            }

            if (type == 70)
            {
                if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && TileArray2.Contains(Framing.GetTileSafely(i, j - 2).type))
                {
                    if (Main.rand.Next(1400) == 0)
                    {
                        WorldGen.PlaceObject(i - 1, j - 1, mod.TileType("Gelon"));
                        NetMessage.SendObjectPlacment(-1, i - 1, j - 1, mod.TileType("Gelon"), 0, 0, -1, -1);
                    }
                }
            }

            if (type == 396)
            {
                if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && TileArray2.Contains(Framing.GetTileSafely(i, j - 2).type))
                {
                    if (Main.rand.Next(1200) == 0)
                    {
                        WorldGen.PlaceObject(i - 1, j - 1, mod.TileType("Jaderose"));
                        NetMessage.SendObjectPlacment(-1, i - 1, j - 1, mod.TileType("Jaderose"), 0, 0, -1, -1);
                    }
                }

/*			}
 *
 *                      if (type == 396)
 *                      {
 *          if(TileArray2.Contains(Framing.GetTileSafely(i,j-1).type) &&TileArray2.Contains(Framing.GetTileSafely(i,j-2).type))
 *          {
 *                      if(Main.rand.Next(2500)==0)
 *                      {
 *                          WorldGen.PlaceObject(i-1,j-1,mod.TileType("JungleFungus"));
 *                          NetMessage.SendObjectPlacment(-1,i-1,j-1,mod.TileType("JungleFungus"),0,0,-1,-1);
 *                      }
 *
 *          } */
            }

            if (type == 60 && Main.hardMode)
            {
                if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && TileArray2.Contains(Framing.GetTileSafely(i, j - 2).type))
                {
                    if (Main.rand.Next(2500) == 0)
                    {
                        WorldGen.PlaceObject(i - 1, j - 1, mod.TileType("VenomRadish"));
                        NetMessage.SendObjectPlacment(-1, i - 1, j - 1, mod.TileType("VenomRadish"), 0, 0, -1, -1);
                    }
                }
            }

            if (type == 2)             //add water support later
            {
                if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && TileArray2.Contains(Framing.GetTileSafely(i, j - 2).type))
                {
                    if (Main.rand.Next(1800) == 2)
                    {
                        WorldGen.PlaceObject(i - 1, j - 1, mod.TileType("ForestPlant"));
                        NetMessage.SendObjectPlacment(-1, i - 1, j - 1, mod.TileType("ForestPlant"), 0, 0, -1, -1);
                    }
                }
            }

            if (type == 1)             //add water support later
            {
                bool place = false;
                for (int x = i - 5; x < i + 5; x++)
                {
                    for (int y = j; y < j + 5; y++)
                    {
                        if (Main.tile[x, y].liquid == 255)
                        {
                            place = true;
                        }
                    }
                }

                if (TileArray2.Contains(Framing.GetTileSafely(i, j - 1).type) && TileArray2.Contains(Framing.GetTileSafely(i, j - 2).type) && place)
                {
                    if (Main.rand.Next(4000) == 1)
                    {
                        WorldGen.PlaceObject(i - 1, j - 1, mod.TileType("StoneberryPlant"));
                        NetMessage.SendObjectPlacment(-1, i - 1, j - 1, mod.TileType("StoneberryPlant"), 0, 0, -1, -1);
                    }
                }
            }
        }
예제 #19
0
 /// <summary>Just makes it easier to place tiles with good framing.</summary>
 private static void Place(int x, int y, short frameX, short frameY)
 {
     PlaceTile(x, y, TileType <BigTree_Purity>(), true, false, -1, 0);
     Framing.GetTileSafely(x, y).frameX = frameX;
     Framing.GetTileSafely(x, y).frameY = frameY;
 }
예제 #20
0
        public static bool GetSittingTargetInfo(Player player, int x, int y, out int targetDirection, out Vector2 playerSittingPosition, out Vector2 seatDownOffset)
        {
            Tile tileSafely = Framing.GetTileSafely(x, y);

            if (!TileID.Sets.CanBeSatOnForPlayers[tileSafely.type] || !tileSafely.active())
            {
                targetDirection       = 1;
                seatDownOffset        = Vector2.Zero;
                playerSittingPosition = default(Vector2);
                return(false);
            }
            int num  = x;
            int num2 = y;

            targetDirection = 1;
            seatDownOffset  = Vector2.Zero;
            int     num3 = 6;
            Vector2 zero = Vector2.Zero;

            switch (tileSafely.type)
            {
            case 15:
            case 497:
                seatDownOffset.Y = (tileSafely.type == 15 && tileSafely.frameY / 40 == 27).ToInt() * 4;
                if (tileSafely.frameY % 40 != 0)
                {
                    num2--;
                }
                targetDirection = -1;
                if (tileSafely.frameX != 0)
                {
                    targetDirection = 1;
                }
                break;

            case 102:
            {
                int num4 = tileSafely.frameX / 18;
                if (num4 == 0)
                {
                    num++;
                }
                if (num4 == 2)
                {
                    num--;
                }
                int num5 = tileSafely.frameY / 18;
                if (num5 == 0)
                {
                    num2 += 2;
                }
                if (num5 == 1)
                {
                    num2++;
                }
                if (num5 == 3)
                {
                    num2--;
                }
                targetDirection = player.direction;
                num3            = 0;
                break;
            }

            case 487:
            {
                int num6 = tileSafely.frameX % 72 / 18;
                if (num6 == 1)
                {
                    num--;
                }
                if (num6 == 2)
                {
                    num++;
                }
                if (tileSafely.frameY / 18 != 0)
                {
                    num2--;
                }
                targetDirection   = (num6 <= 1).ToDirectionInt();
                num3              = 0;
                seatDownOffset.Y -= 1f;
                break;
            }

            case 89:
            {
                targetDirection = player.direction;
                num3            = 0;
                Vector2 vector  = new Vector2(-4f, 2f);
                Vector2 vector2 = new Vector2(4f, 2f);
                Vector2 vector3 = new Vector2(0f, 2f);
                Vector2 zero2   = Vector2.Zero;
                zero2.X = 1f;
                zero.X  = -1f;
                switch (tileSafely.frameX / 54)
                {
                case 0:
                    vector3.Y = (vector.Y = (vector2.Y = 1f));
                    break;

                case 1:
                    vector3.Y = 1f;
                    break;

                case 2:
                case 14:
                case 15:
                case 17:
                case 20:
                case 21:
                case 22:
                case 23:
                case 25:
                case 26:
                case 27:
                case 28:
                case 35:
                case 37:
                case 38:
                case 39:
                case 40:
                case 41:
                case 42:
                    vector3.Y = (vector.Y = (vector2.Y = 1f));
                    break;

                case 3:
                case 4:
                case 5:
                case 7:
                case 8:
                case 9:
                case 10:
                case 11:
                case 12:
                case 13:
                case 16:
                case 18:
                case 19:
                case 36:
                    vector3.Y = (vector.Y = (vector2.Y = 0f));
                    break;

                case 6:
                    vector3.Y = (vector.Y = (vector2.Y = -1f));
                    break;

                case 24:
                    vector3.Y = 0f;
                    vector.Y  = -4f;
                    vector.X  = 0f;
                    vector2.X = 0f;
                    vector2.Y = -4f;
                    break;
                }
                if (tileSafely.frameY % 40 != 0)
                {
                    num2--;
                }
                if ((tileSafely.frameX % 54 == 0 && targetDirection == -1) || (tileSafely.frameX % 54 == 36 && targetDirection == 1))
                {
                    seatDownOffset = vector;
                }
                else if ((tileSafely.frameX % 54 == 0 && targetDirection == 1) || (tileSafely.frameX % 54 == 36 && targetDirection == -1))
                {
                    seatDownOffset = vector2;
                }
                else
                {
                    seatDownOffset = vector3;
                }
                seatDownOffset += zero2;
                break;
            }
            }
            playerSittingPosition    = new Point(num, num2 + 1).ToWorldCoordinates(8f, 16f);
            playerSittingPosition.X += targetDirection * num3;
            playerSittingPosition   += zero;
            return(true);
        }
예제 #21
0
        /// <summary>Spawns a tree at x, y, origin being the left side of the trunk.</summary>
        /// <param name="r">Pass WorldGen.genRand if you plan to use this during worldgen. Defaults to Main.rand.</param>
        /// <param name="height">Height of the tree in tiles.</param>
        /// <param name="requireHeight">If true, this tree will not grow in too small of a space. If false, this will fit the space.</param>
        /// <param name="minHeight">Stops the spawn if height is too low, or, if requireHeight is false, the adjusted height is too low.</param>
        public static void Spawn(int x, int y, int height, UnifiedRandom r = null, bool requireHeight = false, int minHeight = 8, bool spawnLeaves = true)
        {
            //Feel free to move this method wherever; in my main project I have it under a TileHelper class that also takes a type param for brevity.
            r = r ?? Main.rand; //Defaults to Main.rand. Again, should be WorldGen.genRand if you want this to work in world generaiton.

            if (y < minHeight * 2)
            {
                return;                      //There may not be enough space in the world for this, abort now
            }
            for (int i = 1; i < height; ++i) //Checks height for obstructions so it doesn't grow into the ceiling
            {
                if ((Framing.GetTileSafely(x, y - i).active() && Main.tileSolid[Framing.GetTileSafely(x, y - i).type]) || (Framing.GetTileSafely(x + 1, y - i).active() && Main.tileSolid[Framing.GetTileSafely(x + 1, y - i).type]))
                {
                    if (!requireHeight) //Adjust height
                    {
                        height = i - 1;
                    }
                    else //Stop spawning if you require a specific height
                    {
                        return;
                    }
                }
            }

            if (height <= minHeight)
            {
                return;                                                                                                               //Tree is too small, stop the spawn
            }
            bool FullTile(int i, int j) => Framing.GetTileSafely(i, j).active() && !Main.tileCut[Framing.GetTileSafely(i, j).type];   //True if a tile is active & not overrideable
            bool SolidTile(int i, int j) => Framing.GetTileSafely(i, j).active() && Main.tileSolid[Framing.GetTileSafely(i, j).type]; //Self explanatory

            Place(x, y, (short)(!FullTile(x - 1, y) && SolidTile(x - 1, y + 1) ? 72 : 0), (short)(18 * r.Next(3)));                   //Middle base
            Place(x + 1, y, (short)(!FullTile(x + 2, y) && SolidTile(x + 2, y + 1) ? 306 : 18), (short)(18 * r.Next(3)));
            if (!FullTile(x - 1, y) && SolidTile(x - 1, y + 1))
            {
                Place(x - 1, y, 36, (short)(18 * r.Next(3)));                                                  //Left root if space is open & has footing
            }
            if (!FullTile(x + 2, y) && SolidTile(x + 2, y + 1))
            {
                Place(x + 2, y, 54, (short)(18 * r.Next(3)));                                              //Right root if space is open & has footing
            }
            int[] lastBranch = new int[2];                                                                 //Makes sure the gen doesn't spam branches

            for (int i = 1; i < height; ++i)                                                               //Trunk
            {
                Place(x, y - i, 0, (short)(18 * r.Next(3)));                                               //Place trunk
                Place(x + 1, y - i, 18, (short)(18 * r.Next(3)));                                          //Trunk, part 2

                if ((lastBranch[0] < 0 || lastBranch[1] < 0) && i > 3 && i < height - 2 && r.Next(2) == 0) //Branch chance and conditions
                {
                    bool leaf = r.Next(4) > 0;                                                             //Leaf chance

                    //There's probably a cleaner way to do this but I didn't think of it.
                    bool left = r.Next(2) == 0; //Direction logic -->
                    if (lastBranch[0] > 0)
                    {
                        left = false;                    //'Timer' checks
                    }
                    else if (lastBranch[1] > 0)
                    {
                        left = true;
                    }
                    else if (lastBranch[0] < 0 && lastBranch[1] < 0)
                    {
                        left = r.Next(2) == 0;
                    }

                    if (Framing.GetTileSafely(x - 1, y - i).active() || Framing.GetTileSafely(x - 2, y - i).active() && left) //Tile-based placement checks
                    {
                        if ((lastBranch[1] > 0))
                        {
                            goto skipBranch;                                                                                   //If this branch cannot, in any way, be placed, skip
                        }
                        left = false;                                                                                          //Adjust side
                    }
                    if (Framing.GetTileSafely(x + 2, y - i).active() || Framing.GetTileSafely(x + 3, y - i).active() && !left) //Tile-based placement checks
                    {
                        if ((lastBranch[0] > 0))
                        {
                            goto skipBranch;                                                                              //If this branch cannot, in any way, be placed, skip
                        }
                        left = true;                                                                                      //Adjust side
                    }
                    if ((Framing.GetTileSafely(x - 1, y - i).active() || Framing.GetTileSafely(x - 2, y - i).active()) && //If both placements are invalid, skip this entirely
                        (Framing.GetTileSafely(x + 2, y - i).active() || Framing.GetTileSafely(x + 3, y - i).active()))
                    {
                        goto skipBranch; //Eww goto but I didn't wanna reformat this <--
                    }
                    if (left)            //Place left branch; adjust trunk
                    {
                        Framing.GetTileSafely(x, y - i).frameX = 198;
                        Place(x - 1, y - i, 90, (short)(18 * r.Next(3)));
                        Place(x - 2, y - i, (short)(leaf ? 270 : 108), (short)(18 * r.Next(3)));

                        lastBranch[0] = 3 + Main.rand.Next(2); //Make them unable to place within 3-4 tiles of each other. You can change this as you please.
                    }
                    else //Same as lines 68-75, but for right branch
                    {
                        Framing.GetTileSafely(x + 1, y - i).frameX = 216;
                        Place(x + 2, y - i, 144, (short)(18 * r.Next(3)));
                        Place(x + 3, y - i, (short)(leaf ? 288 : 126), (short)(18 * r.Next(3)));

                        lastBranch[1] = 3 + Main.rand.Next(2);
                    }

                    int leaves = r.Next(3, 6); //Random leaf spawns for trunk
                    if (spawnLeaves)           //Spawns leaf gores
                    {
                        for (int l = 0; l < leaves; ++l)
                        {
                            Gore.NewGore((new Vector2(x + r.Next(2), y - i) * 16) + new Vector2(r.Next(16), r.Next(16)), new Vector2(), LeafType, r.Next(90, 130) * 0.01f);
                        }
                    }
                }

skipBranch:                                                           //Case for skipping branch placement
                lastBranch[0]--;                                      //Branch countdown
                lastBranch[1]--;                                      //Branch countdown 2

                if (i == height - 1)                                  //Treetop
                {
                    Framing.GetTileSafely(x, y - i).frameX     = 234; //Treetop tiles for drawing the tops
                    Framing.GetTileSafely(x + 1, y - i).frameX = 252;
                    int leaves = r.Next(20, 28);
                    if (spawnLeaves) //Spawns leaf gores
                    {
                        for (int l = 0; l < leaves; ++l)
                        {
                            Gore.NewGore((new Vector2(x - 12, y - i - 20) * 16) + new Vector2(r.Next(360), r.Next(320)), new Vector2(), LeafType, r.Next(120, 160) * 0.01f);
                        }
                    }
                }
            }
        }
예제 #22
0
        public override void AI()
        {
            bool     flag64    = projectile.type == mod.ProjectileType("SockPuppet");
            Player   player    = Main.player[projectile.owner];
            AAPlayer modPlayer = player.GetModPlayer <AAPlayer>();

            player.AddBuff(mod.BuffType("SockPuppet"), 3600);
            if (flag64)
            {
                if (player.dead)
                {
                    modPlayer.Sock = false;
                }
                if (modPlayer.Sock)
                {
                    projectile.timeLeft = 2;
                }
            }

            float num633 = 700f;
            float num634 = 800f;
            float num635 = 1200f;
            float num636 = 150f;
            float num637 = 0.05f;

            for (int num638 = 0; num638 < 1000; num638++)
            {
                bool flag23 = Main.projectile[num638].type == mod.ProjectileType("SockPuppet");
                if (num638 != projectile.whoAmI && Main.projectile[num638].active && Main.projectile[num638].owner == projectile.owner && flag23 && Math.Abs(projectile.position.X - Main.projectile[num638].position.X) + Math.Abs(projectile.position.Y - Main.projectile[num638].position.Y) < projectile.width)
                {
                    if (projectile.position.X < Main.projectile[num638].position.X)
                    {
                        projectile.velocity.X = projectile.velocity.X - num637;
                    }
                    else
                    {
                        projectile.velocity.X = projectile.velocity.X + num637;
                    }
                    if (projectile.position.Y < Main.projectile[num638].position.Y)
                    {
                        projectile.velocity.Y = projectile.velocity.Y - num637;
                    }
                    else
                    {
                        projectile.velocity.Y = projectile.velocity.Y + num637;
                    }
                }
            }
            bool flag24 = false;

            if (flag24)
            {
                return;
            }
            Vector2 vector46 = projectile.position;
            bool    flag25   = false;

            if (projectile.ai[0] != 1f)
            {
                projectile.tileCollide = false;
            }
            if (projectile.tileCollide && WorldGen.SolidTile(Framing.GetTileSafely((int)projectile.Center.X / 16, (int)projectile.Center.Y / 16)))
            {
                projectile.tileCollide = false;
            }
            bool AttackFrame = false;

            if (player.HasMinionAttackTargetNPC)
            {
                NPC npc = Main.npc[player.MinionAttackTargetNPC];
                AttackFrame = true;
                if (Collision.CanHitLine(projectile.position, projectile.width, projectile.height, npc.position, npc.width, npc.height))
                {
                    num633   = Vector2.Distance(projectile.Center, vector46);
                    vector46 = npc.Center;
                    flag25   = true;
                }
            }
            else
            {
                for (int k = 0; k < 200; k++)
                {
                    NPC npc = Main.npc[k];
                    if (npc.CanBeChasedBy(this, false))
                    {
                        AttackFrame = true;
                        float num646 = Vector2.Distance(npc.Center, projectile.Center);
                        if ((num646 < num633 || !flag25) && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, npc.position, npc.width, npc.height))
                        {
                            num633   = num646;
                            vector46 = npc.Center;
                            flag25   = true;
                        }
                    }
                }
            }
            float num647 = num634;

            if (flag25)
            {
                num647 = num635;
            }
            if (Vector2.Distance(player.Center, projectile.Center) > num647)
            {
                projectile.ai[0]       = 1f;
                projectile.tileCollide = false;
                projectile.netUpdate   = true;
            }
            if (flag25 && projectile.ai[0] == 0f)
            {
                Vector2 vector47 = vector46 - projectile.Center;
                float   num648   = vector47.Length();
                vector47.Normalize();
                if (num648 > 200f)
                {
                    float scaleFactor2 = 6f;
                    vector47           *= scaleFactor2;
                    projectile.velocity = (projectile.velocity * 40f + vector47) / 41f;
                }
                else
                {
                    float num649 = 4f;
                    vector47           *= -num649;
                    projectile.velocity = (projectile.velocity * 40f + vector47) / 41f;
                }
            }
            else
            {
                bool flag26 = false;
                if (!flag26)
                {
                    flag26 = projectile.ai[0] == 1f;
                }
                float num650 = 6f;
                if (flag26)
                {
                    num650 = 15f;
                }
                Vector2 center2  = projectile.Center;
                Vector2 vector48 = player.Center - center2 + new Vector2(0f, -60f);
                float   num651   = vector48.Length();
                if (num651 > 200f && num650 < 8f)
                {
                    num650 = 8f;
                }
                if (num651 < num636 && flag26 && !Collision.SolidCollision(projectile.position, projectile.width, projectile.height))
                {
                    projectile.ai[0]     = 0f;
                    projectile.netUpdate = true;
                }
                if (num651 > 2000f)
                {
                    projectile.position.X = Main.player[projectile.owner].Center.X - projectile.width / 2;
                    projectile.position.Y = Main.player[projectile.owner].Center.Y - projectile.height / 2;
                    projectile.netUpdate  = true;
                }
                if (num651 > 70f)
                {
                    vector48.Normalize();
                    vector48           *= num650;
                    projectile.velocity = (projectile.velocity * 40f + vector48) / 41f;
                }
                else if (projectile.velocity.X == 0f && projectile.velocity.Y == 0f)
                {
                    projectile.velocity.X = -0.15f;
                    projectile.velocity.Y = -0.05f;
                }
            }
            projectile.rotation = projectile.velocity.X * 0.04f;

            if (flag25)
            {
                projectile.spriteDirection = ((vector46 - projectile.Center).X > 0? -1: 1);
            }
            else
            {
                projectile.spriteDirection = (projectile.velocity.X > 0? -1: 1);
            }

            if (++projectile.frameCounter >= 10)
            {
                projectile.frameCounter = 0;
                if (!AttackFrame)
                {
                    if (++projectile.frame > 3)
                    {
                        projectile.frame = 0;
                    }
                }
                else
                {
                    if (++projectile.frame < 3 || projectile.frame > 7)
                    {
                        projectile.frame = 3;
                    }
                }
            }
            if (projectile.ai[1] > 0f)
            {
                projectile.ai[1] += Main.rand.Next(1, 4);
            }
            if (projectile.ai[1] > 90f)
            {
                projectile.ai[1]     = 0f;
                projectile.netUpdate = true;
            }
            if (projectile.ai[0] == 0f)
            {
                float scaleFactor3 = 16f;
                if (flag25 && projectile.ai[1] == 0f)
                {
                    projectile.ai[1] += 1f;
                    if (Main.myPlayer == projectile.owner && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, vector46, 0, 0))
                    {
                        Vector2 value19 = vector46 - projectile.Center;
                        value19.Normalize();
                        value19 *= scaleFactor3;
                        int proj = Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, value19.X, value19.Y, 449, projectile.damage, projectile.knockBack, Main.myPlayer, 0f, 0f);
                        Main.projectile[proj].hostile   = false;
                        Main.projectile[proj].friendly  = true;
                        Main.projectile[proj].magic     = false;
                        Main.projectile[proj].minion    = true;
                        Main.projectile[proj].netUpdate = true;
                        projectile.netUpdate            = true;
                    }
                }
            }
        }
예제 #23
0
        public override void RandomUpdate(int i, int j)
        {
            if (!Framing.GetTileSafely(i, j - 1).active() && Main.rand.Next(400) == 0)
            {
                switch (Main.rand.Next(9))
                {
                case 0:
                    ReachGrassTile.PlaceObject(i, j - 1, mod.TileType("GlowShard1"));
                    NetMessage.SendObjectPlacment(-1, i, j - 1, mod.TileType("GlowShard1"), 0, 0, -1, -1);
                    break;

                case 1:
                    ReachGrassTile.PlaceObject(i, j - 1, mod.TileType("GlowShard2"));
                    NetMessage.SendObjectPlacment(-1, i, j - 1, mod.TileType("GlowShard2"), 0, 0, -1, -1);
                    break;

                case 2:
                    ReachGrassTile.PlaceObject(i, j - 1, mod.TileType("GlowShard3"));
                    NetMessage.SendObjectPlacment(-1, i, j - 1, mod.TileType("GlowShard3"), 0, 0, -1, -1);
                    break;

                case 3:
                    ReachGrassTile.PlaceObject(i, j - 1, mod.TileType("GlowShard4"));
                    NetMessage.SendObjectPlacment(-1, i, j - 1, mod.TileType("GlowShard4"), 0, 0, -1, -1);
                    break;
                }
            }
            if (!Framing.GetTileSafely(i, j + 1).active() && Main.rand.Next(400) == 0)
            {
                switch (Main.rand.Next(3))
                {
                case 0:
                    ReachGrassTile.PlaceObject(i, j + 1, mod.TileType("GlowShard1"));
                    NetMessage.SendObjectPlacment(-1, i, j + 1, mod.TileType("GlowShard1"), 0, 0, -1, -1);
                    break;

                case 1:
                    ReachGrassTile.PlaceObject(i, j + 1, mod.TileType("GlowShard2"));
                    NetMessage.SendObjectPlacment(-1, i, j + 1, mod.TileType("GlowShard2"), 0, 0, -1, -1);
                    break;

                case 2:
                    ReachGrassTile.PlaceObject(i, j + 1, mod.TileType("GlowShard3"));
                    NetMessage.SendObjectPlacment(-1, i, j + 1, mod.TileType("GlowShard3"), 0, 0, -1, -1);
                    break;

                case 3:
                    ReachGrassTile.PlaceObject(i, j + 1, mod.TileType("GlowShard4"));
                    NetMessage.SendObjectPlacment(-1, i, j + 1, mod.TileType("GlowShard4"), 0, 0, -1, -1);
                    break;
                }
            }
            if (!Framing.GetTileSafely(i - 1, j).active() && Main.rand.Next(4) == 0)
            {
                switch (Main.rand.Next(3))
                {
                case 0:
                    ReachGrassTile.PlaceObject(i - 1, j, mod.TileType("GlowShard1"));
                    NetMessage.SendObjectPlacment(-1, i - 1, j, mod.TileType("GlowShard1"), 0, 0, -1, -1);
                    break;

                case 1:
                    ReachGrassTile.PlaceObject(i - 1, j, mod.TileType("GlowShard2"));
                    NetMessage.SendObjectPlacment(-1, i - 1, j, mod.TileType("GlowShard2"), 0, 0, -1, -1);
                    break;

                case 2:
                    ReachGrassTile.PlaceObject(i - 1, j, mod.TileType("GlowShard3"));
                    NetMessage.SendObjectPlacment(-1, i - 1, j, mod.TileType("GlowShard3"), 0, 0, -1, -1);
                    break;

                case 3:
                    ReachGrassTile.PlaceObject(i - 1, j, mod.TileType("GlowShard4"));
                    NetMessage.SendObjectPlacment(-1, i - 1, j, mod.TileType("GlowShard4"), 0, 0, -1, -1);
                    break;
                }
            }
            if (!Framing.GetTileSafely(i + 1, j).active() && Main.rand.Next(4) == 0)
            {
                switch (Main.rand.Next(3))
                {
                case 0:
                    ReachGrassTile.PlaceObject(i + 1, j, mod.TileType("GlowShard1"));
                    NetMessage.SendObjectPlacment(-1, i + 1, j, mod.TileType("GlowShard1"), 0, 0, -1, -1);
                    break;

                case 1:
                    ReachGrassTile.PlaceObject(i + 1, j, mod.TileType("GlowShard2"));
                    NetMessage.SendObjectPlacment(-1, i + 1, j, mod.TileType("GlowShard2"), 0, 0, -1, -1);
                    break;

                case 2:
                    ReachGrassTile.PlaceObject(i + 1, j, mod.TileType("GlowShard3"));
                    NetMessage.SendObjectPlacment(-1, i + 1, j, mod.TileType("GlowShard3"), 0, 0, -1, -1);
                    break;

                case 3:
                    ReachGrassTile.PlaceObject(i + 1, j, mod.TileType("GlowShard4"));
                    NetMessage.SendObjectPlacment(-1, i + 1, j, mod.TileType("GlowShard4"), 0, 0, -1, -1);
                    break;
                }
            }
        }
예제 #24
0
        public override void PostUpdateMiscEffects()
        {
            nurseCooldown--;
            if (!MyWorld.awakenedMode)
            {
                sanity = sanityMax;
            }
            PlayerUtils playerUtils = player.GetModPlayer <PlayerUtils>(mod);

            sanityMax = sanityIncreaser;
            craftWeaponCooldown--;
            // decreases
            if (MyWorld.awakenedMode)
            {
                // if (sanity > 0)
                {
                    // low life
                    if (player.statLife < player.statLifeMax2 * 0.25f)
                    {
                        int sanityRegenLoss = (int)Math.Round(MathHelper.Lerp(4, 1, player.statLife / (player.statLifeMax2 * 0.25f)));
                        //ElementsAwoken.DebugModeText(sanityRegenLoss);
                        sanityRegen -= sanityRegenLoss;

                        AddSanityDrain(sanityRegenLoss, "Low Health");
                    }
                    // in the dark
                    if (playerUtils.playerLight < 0.2)
                    {
                        int sanityRegenLoss = (int)Math.Round(MathHelper.Lerp(3, 1, playerUtils.playerLight / 0.2f));
                        //ElementsAwoken.DebugModeText(playerUtils.playerLight);
                        sanityRegen -= sanityRegenLoss;

                        AddSanityDrain(sanityRegenLoss, "Darkness");
                    }
                    // events
                    if (Main.bloodMoon)
                    {
                        sanityRegen--;
                        AddSanityDrain(1, "Blood Moon");
                    }
                    if (MyWorld.darkMoon)
                    {
                        sanityRegen -= 2;
                        AddSanityDrain(2, "Dark Moon");
                    }
                    if (MyWorld.voidInvasionUp && Main.time >= 16220 && !Main.dayTime)
                    {
                        sanityRegen -= 3;
                        AddSanityDrain(2, "Dawn of the Void");
                    }
                    if (player.ZoneUnderworldHeight)
                    {
                        sanityRegen -= 2;
                        AddSanityDrain(2, "In Hell");
                    }
                    if (player.ZoneSkyHeight)
                    {
                        sanityRegen -= 1;
                        AddSanityDrain(1, "In Space");
                    }
                    if (miningCounter > 3600 * 10)
                    {
                        if (mineTileCooldown > mineTileCooldownMax - 300)
                        {
                            sanityRegen -= 3;// first 5 seconds after mining a tile reduces sanity
                            AddSanityDrain(3, "Mining For Too Long");
                        }
                    }
                    if (NPC.AnyNPCs(NPCID.MoonLordCore))
                    {
                        player.AddBuff(mod.BuffType("EldritchHorror"), 2);
                    }
                }

                // increases
                //if (sanity < sanityMax)
                {
                    for (int i = 0; i < 22; i++)
                    {
                        if (Main.vanityPet[player.buffType[i]])
                        {
                            sanityRegen++;
                            AddSanityRegen(1, "Pet");
                            //if (Main.time % 100 == 0) ElementsAwoken.DebugModeText("has pet");
                            break;
                        }
                    }
                    #region flowers and campfires nearby
                    int   distance    = 15 * 16;
                    Point topLeft     = ((player.position - new Vector2(distance, distance)) / 16).ToPoint();
                    Point bottomRight = ((player.BottomRight + new Vector2(distance, distance)) / 16).ToPoint();

                    Tile    closest    = null;
                    Vector2 closestPos = new Vector2();
                    for (int i = topLeft.X; i <= bottomRight.X; i++)
                    {
                        for (int j = topLeft.Y; j <= bottomRight.Y; j++)
                        {
                            Tile t = Framing.GetTileSafely(i, j);
                            if (CheckValidSanityTile(t))
                            {
                                Vector2 tileCenter = new Vector2(i * 16, j * 16);
                                if (closest != null)
                                {
                                    if (Vector2.Distance(tileCenter, player.Center) < Vector2.Distance(closestPos, player.Center))
                                    {
                                        closest    = t;
                                        closestPos = new Vector2(i * 16, j * 16);
                                    }
                                }
                                else
                                {
                                    closest    = t;
                                    closestPos = new Vector2(i * 16, j * 16);
                                }
                            }
                        }
                    }
                    if (Vector2.Distance(closestPos, player.Center) < distance && CheckValidSanityTile(closest))
                    {
                        int amount = (int)Math.Round(MathHelper.Lerp(3, 1, Vector2.Distance(closestPos, player.Center) / distance));
                        sanityRegen += amount;
                        string type = "";
                        if (closest.type == TileID.Campfire)
                        {
                            type = "Campfire";
                        }
                        if (closest.type == TileID.Sunflower)
                        {
                            type = "Sunflower";
                        }
                        if (closest.type == TileID.PlanterBox)
                        {
                            type = "Planter Box";
                        }
                        AddSanityRegen(amount, "Nearby " + type);
                    }
                    #endregion

                    int townSanityRegen = 0;
                    int numNPCs         = CountNearbyTownNPCs();
                    if (numNPCs > 5)
                    {
                        townSanityRegen++;
                    }
                    if (numNPCs > 10)
                    {
                        townSanityRegen++;
                    }
                    if (numNPCs > 15)
                    {
                        townSanityRegen++;
                    }
                    if (numNPCs > 20)
                    {
                        townSanityRegen++;
                    }
                    if (numNPCs > 25)
                    {
                        townSanityRegen++;
                    }
                    if (townSanityRegen > 0)
                    {
                        sanityRegen += townSanityRegen;
                        AddSanityRegen(townSanityRegen, "In a Town");
                    }

                    if (miningCounter < 3600 * 10)
                    {
                        if (mineTileCooldown > mineTileCooldownMax - 300)
                        {
                            sanityRegen += 3; // first 5 seconds after mining a tile gives sanity
                            AddSanityRegen(3, "Mining");
                        }
                    }
                }

                if (sanity < sanityMax * 0.25f && sanity > sanityMax * 0.1f)
                {
                    player.magicDamage  *= 0.9f;
                    player.meleeDamage  *= 0.9f;
                    player.minionDamage *= 0.9f;
                    player.rangedDamage *= 0.9f;
                    player.thrownDamage *= 0.9f;
                }
                if (sanity < sanityMax * 0.1f)
                {
                    ElementsAwoken.screenshakeAmount = 2f;
                    if (sanity != 0)
                    {
                        player.magicDamage  *= 0.75f;
                        player.meleeDamage  *= 0.75f;
                        player.minionDamage *= 0.75f;
                        player.rangedDamage *= 0.75f;
                        player.thrownDamage *= 0.75f;
                    }
                    if (Main.rand.Next(1200) == 0)
                    {
                        int choice = Main.rand.Next(2);
                        if (choice == 0)
                        {
                            player.AddBuff(BuffID.Darkness, 600);
                        }
                        else if (choice == 1)
                        {
                            player.AddBuff(BuffID.Confused, 120);
                        }
                    }
                }
                if (sanity == 0)
                {
                    player.magicDamage  *= 0.5f;
                    player.meleeDamage  *= 0.5f;
                    player.minionDamage *= 0.5f;
                    player.rangedDamage *= 0.5f;
                    player.thrownDamage *= 0.5f;
                }
                // sanity regen logic
                sanityRegenCount = Math.Abs(sanityRegen);
                sanityRegenTime -= sanityRegenCount;
                if (sanityRegenTime <= 0)
                {
                    sanityRegenTime = 450;
                    sanity         += Math.Sign(sanityRegen);
                }
                if (sanity > sanityMax)
                {
                    sanity = sanityMax;
                }
                if (sanity < 0)
                {
                    sanity = 0;
                }

                if (mineTileCooldown > 0)
                {
                    mineTileCooldown--;
                    miningCounter++;
                }
                if (mineTileCooldown <= 0)
                {
                    miningCounter = 0;
                }
                InsanityOverlay.Update();

                #region glitch anim
                sanityGlitchCooldown--;
                if (sanityGlitchCooldown <= 0)
                {
                    sanityGlitchCooldown = 120;
                }
                if (sanityGlitchCooldown <= 12)
                {
                    sanityGlitch--;
                    if (sanityGlitch <= 0)
                    {
                        sanityGlitchFrame++;
                        sanityGlitch = 3;
                    }
                }
                else
                {
                    sanityGlitchFrame = 0;
                }
                if (sanityGlitchFrame > 4)
                {
                    sanityGlitchFrame = 1;
                }
                #endregion
                #region arrow anim
                sanityArrow--;
                if (sanityArrow <= 0)
                {
                    sanityArrowFrame++;
                    sanityArrow = 5;
                }
                if (sanityArrowFrame > 12)
                {
                    sanityArrowFrame = 0;
                }
                #endregion
            }
        }
        //Explosion
        #region Explosion
        /// <summary>
        /// Takes the projectiles radius attribute in place of passing variables
        /// Creates a circular explosion in the radius defined
        /// Efficient but most blocks don't drop due to optimization methods
        /// </summary>
        public virtual void Explosion()
        {
            // x and y are the tile offset of the current tile relative to the player
            // i and j are the true tile cords relative to 0,0 in the world
            Player player = Main.player[projectile.owner];

            if (pickPower < -1)
            {
                return;
            }
            if (player.EE().BombardEmblem)
            {
                return;
            }

            Vector2 position = new Vector2(projectile.Center.X / 16f, projectile.Center.Y / 16f);    // Converts to tile cords for convenience

            radius = (int)((radius + player.EE().RadiusBonus) * player.EE().RadiusMulti);
            for (int x = -radius;
                 x <= radius;
                 x++)
            {
                //int x = (int)(i + position.X);
                for (int y = -radius;
                     y <= radius;
                     y++)
                {
                    //int y = (int)(j + position.Y);
                    int i = (int)(x + position.X);
                    int j = (int)(y + position.Y);
                    if (!WorldGen.InWorld(i, j))
                    {
                        continue;
                    }
                    if (Math.Sqrt(x * x + y * y) <= radius + 0.5) //Circle
                    {
                        Tile tile = Framing.GetTileSafely(i, j);

                        if (!WorldGen.TileEmpty(i, j) && tile.active())
                        {
                            if (!CanBreakTile(tile.type, pickPower))
                            {
                                continue;
                            }
                            //if (!CanBreakTiles) continue;
                            // Using KillTile is laggy, use ClearTile when working with larger tile sets    (also stops sound spam)
                            // But it must be done on outside tiles to ensure propper updates so use it only on outermost tiles
                            if (Math.Abs(x) >= radius - 1 || Math.Abs(y) >= radius - 1 || Terraria.ID.TileID.Sets.Ore[tile.type])
                            {
                                int type = tile.type;
                                WorldGen.KillTile((int)(i), (int)(j), false, false, false);

                                if (Main.netMode == NetmodeID.MultiplayerClient) //update if in mp
                                {
                                    WorldGen.SquareTileFrame(i, j, true);        //Updates Area
                                    NetMessage.SendData(MessageID.TileChange, -1, -1, null, 2, (float)i, (float)j, 0f, 0, 0, 0);
                                }

                                if (player.EE().DropOresTwice&& Main.rand.NextFloat() <= player.EE().dropChanceOre)  //chance to drop 2 ores
                                {
                                    WorldGen.PlaceTile(i, j, type);
                                    WorldGen.KillTile((int)(i), (int)(j), false, false, false);

                                    if (Main.netMode == NetmodeID.MultiplayerClient)
                                    {
                                        WorldGen.SquareTileFrame(i, j, true); //Updates Area
                                        NetMessage.SendData(MessageID.TileChange, -1, -1, null, 2, (float)i, (float)j, 0f, 0, 0, 0);
                                    }
                                }
                            }

                            else
                            {
                                if (!TileID.Sets.BasicChest[Main.tile[i, j - 1].type] && !TileLoader.IsDresser(Main.tile[i, j - 1].type) && Main.tile[i, j - 1].type != 26)
                                {
                                    tile.ClearTile();
                                    tile.active(false);

                                    if (Main.netMode == NetmodeID.MultiplayerClient)
                                    {
                                        WorldGen.SquareTileFrame(i, j, true); //Updates Area
                                        NetMessage.SendData(MessageID.TileChange, -1, -1, null, 2, (float)i, (float)j, 0f, 0, 0, 0);
                                    }
                                }

                                if (tile.liquid == Tile.Liquid_Water || tile.liquid == Tile.Liquid_Lava || tile.liquid == Tile.Liquid_Honey)
                                {
                                    WorldGen.SquareTileFrame(i, j, true);
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #26
0
        public static Point[] FindShortestPath(Point a, Point b, int maxIterations = 3000)
        {
            try
            {
                if (WorldGen.InWorld(a.X, a.Y, 10))
                {
                    if (!(!Framing.GetTileSafely(a).active() || !Main.tileSolid[Framing.GetTileSafely(a).type]))
                    {
                        return new Point[] { a }
                    }
                }
                ;
                List <Point> pointCache     = new List <Point>();
                Point        CurrentTilePos = a;
                int          CMD            = 0;

                Dictionary <Point, FNode> OpenList   = new Dictionary <Point, FNode>();
                Dictionary <Point, FNode> ClosedList = new Dictionary <Point, FNode>();

                ClosedList.Add(CurrentTilePos, new FNode(0, Manhattan(CurrentTilePos, b), CurrentTilePos));

                void AddToOpenList(Point from, Point to, float Cost)
                {
                    OpenList.Add(to, new FNode(ClosedList[from].GCost + Cost, Manhattan(to, b), from));
                }
                int iteration = 0;

                bool Valid(Point tile)
                {
                    if (WorldGen.InWorld(tile.X, tile.Y, 10))
                    {
                        Tile T = Framing.GetTileSafely(tile);

                        return(!ClosedList.ContainsKey(tile) && !T.active() || !Main.tileSolid[T.type] || TileID.Sets.Platforms[T.type]);
                    }

                    return(false);
                }

                Point LowestPoint()
                {
                    Point lowestPoint = new Point(-1, -1);

                    foreach (KeyValuePair <Point, FNode> entry in OpenList)
                    {
                        if (Valid(entry.Key))
                        {
                            float Score = float.MaxValue;

                            if (OpenList.ContainsKey(lowestPoint))
                            {
                                Score = OpenList[lowestPoint].FCost;
                                if (entry.Value.FCost == Score && entry.Value.HCost < OpenList[lowestPoint].HCost)
                                {
                                    lowestPoint = entry.Key;
                                }
                            }
                            if (entry.Value.FCost < Score)
                            {
                                lowestPoint = entry.Key;
                            }
                        }
                    }
                    return(lowestPoint);
                }
                while ((CMD == 0 || CMD > 1) && iteration < maxIterations)
                {
                    iteration++;
                    CMD = Manhattan(CurrentTilePos, b);

                    //Add to Open List
                    Point Right = new Point(CurrentTilePos.X + 1, CurrentTilePos.Y);
                    Point Left  = new Point(CurrentTilePos.X - 1, CurrentTilePos.Y);
                    Point Up    = new Point(CurrentTilePos.X, CurrentTilePos.Y - 1);
                    Point Down  = new Point(CurrentTilePos.X, CurrentTilePos.Y + 1);

                    Point BR = new Point(CurrentTilePos.X + 1, CurrentTilePos.Y + 1);
                    Point BL = new Point(CurrentTilePos.X - 1, CurrentTilePos.Y + 1);
                    Point TL = new Point(CurrentTilePos.X - 1, CurrentTilePos.Y - 1);
                    Point TR = new Point(CurrentTilePos.X + 1, CurrentTilePos.Y - 1);

                    if (OpenList.ContainsKey(Right))
                    {
                        OpenList.Remove(Right);
                    }
                    if (OpenList.ContainsKey(Left))
                    {
                        OpenList.Remove(Left);
                    }
                    if (OpenList.ContainsKey(Up))
                    {
                        OpenList.Remove(Up);
                    }
                    if (OpenList.ContainsKey(Down))
                    {
                        OpenList.Remove(Down);
                    }

                    if (OpenList.ContainsKey(BR))
                    {
                        OpenList.Remove(BR);
                    }
                    if (OpenList.ContainsKey(BL))
                    {
                        OpenList.Remove(BL);
                    }
                    if (OpenList.ContainsKey(TL))
                    {
                        OpenList.Remove(TL);
                    }
                    if (OpenList.ContainsKey(TR))
                    {
                        OpenList.Remove(TR);
                    }

                    if (Valid(Right))
                    {
                        AddToOpenList(CurrentTilePos, Right, 1f);
                    }
                    if (Valid(Left))
                    {
                        AddToOpenList(CurrentTilePos, Left, 1f);
                    }
                    if (Valid(Up))
                    {
                        AddToOpenList(CurrentTilePos, Up, 1f);
                    }
                    if (Valid(Down))
                    {
                        AddToOpenList(CurrentTilePos, Down, 1f);
                    }

                    if (Valid(BR))
                    {
                        AddToOpenList(CurrentTilePos, BR, 1f);
                    }
                    if (Valid(BL))
                    {
                        AddToOpenList(CurrentTilePos, BL, 1f);
                    }
                    if (Valid(TL))
                    {
                        AddToOpenList(CurrentTilePos, TL, 1f);
                    }
                    if (Valid(TR))
                    {
                        AddToOpenList(CurrentTilePos, TR, 1f);
                    }

                    CurrentTilePos = LowestPoint();
                    if (!ClosedList.ContainsKey(CurrentTilePos))
                    {
                        ClosedList.Add(CurrentTilePos, OpenList[CurrentTilePos]);
                    }
                    if (!OpenList.ContainsKey(CurrentTilePos))
                    {
                        OpenList.Remove(CurrentTilePos);
                    }
                    pointCache.Add(CurrentTilePos);
                }

                Point BackTrack = pointCache[pointCache.Count - 1];
                pointCache.Clear();
                while (Manhattan(BackTrack, a) >= 2)
                {
                    BackTrack = ClosedList[BackTrack].parent;
                    pointCache.Add(BackTrack);
                }
                return(pointCache.ToArray());
            }
            catch
            {
                return(new Point[] { a });
            }
        }
예제 #27
0
        public override bool CanUseItem(Item item, Player player)
        {
            FargoPlayer modPlayer = player.GetModPlayer <FargoPlayer>();

            if (modPlayer.IronGuard)
            {
                //Main.NewText($"iron {modPlayer.ironShieldCD}, {modPlayer.ironShieldTimer}");
                modPlayer.IronGuard          = false;
                modPlayer.wasHoldingShield   = false;
                player.shield_parry_cooldown = 0; //prevent that annoying tick sound
                //check is necessary so if player does a real parry then switches to right click weapon, using it won't reset cooldowns
                if (modPlayer.ironShieldCD == 40 && modPlayer.ironShieldTimer == 20)
                {
                    modPlayer.ironShieldCD    = 0;
                    modPlayer.ironShieldTimer = 0;
                }
            }

            //dont use hotkeys in stasis
            if (player.HasBuff(ModContent.BuffType <GoldenStasis>()))
            {
                if (item.type == ItemID.RodofDiscord)
                {
                    player.ClearBuff(ModContent.BuffType <Buffs.Souls.GoldenStasis>());
                }
                else
                {
                    return(false);
                }
            }

            if (FargoSoulsWorld.EternityMode)
            {
                if (item.type == ItemID.RodofDiscord &&
                    (modPlayer.LihzahrdCurse ||
                     (Framing.GetTileSafely(Main.MouseWorld).wall == WallID.LihzahrdBrickUnsafe &&
                      !player.buffImmune[ModContent.BuffType <Buffs.Masomode.LihzahrdCurse>()])))
                {
                    return(false);
                }

                if (modPlayer.LihzahrdCurse &&
                    (item.type == ItemID.WireKite || item.type == ItemID.WireCutter))
                {
                    return(false);
                }
            }

            if (item.damage > 0 && (item.melee || item.ranged || item.magic) && item.pick == 0 && item.axe == 0 && item.hammer == 0)
            {
                modPlayer.MasomodeWeaponUseTimer = Math.Max(item.useTime + item.reuseDelay, 30);
            }

            if (item.magic && player.GetModPlayer <FargoPlayer>().ReverseManaFlow)
            {
                int damage = (int)(item.mana / (1f - player.endurance) + player.statDefense);
                player.Hurt(PlayerDeathReason.ByCustomReason(player.name + " was destroyed by their own magic."), damage, 0);
                player.immune     = false;
                player.immuneTime = 0;
            }

            if (modPlayer.BuilderMode && (item.createTile != -1 || item.createWall != -1) && item.type != ItemID.PlatinumCoin && item.type != ItemID.GoldCoin)
            {
                item.useTime      = 1;
                item.useAnimation = 1;
            }

            if (item.damage > 0 && player.HasAmmo(item, true) && !(item.mana > 0 && player.statMana < item.mana) && //non weapons and weapons with no ammo begone
                item.type != ItemID.ExplosiveBunny && item.type != ItemID.Cannonball &&
                item.useTime > 0 && item.createTile == -1 && item.createWall == -1 && item.ammo == AmmoID.None && item.hammer == 0 && item.pick == 0 && item.axe == 0)
            {
                modPlayer.TryAdditionalAttacks(item.damage, item.melee, item.ranged, item.magic, item.summon);
            }

            //critter attack timer
            if (modPlayer.WoodEnchant && player.altFunctionUse == ItemAlternativeFunctionID.ActivatedAndUsed && item.makeNPC > 0)
            {
                if (modPlayer.CritterAttackTimer == 0)
                {
                    Vector2 vel = Vector2.Normalize(Main.MouseWorld - player.Center);
                    float   damageMultiplier = player.minionDamage;

                    int type           = -1;
                    int damage         = 0;
                    int attackCooldown = 0;

                    switch (item.type)
                    {
                    //case ItemID.Bunny:
                    //    type = ProjectileID.ExplosiveBunny;
                    //    damage = 10;
                    //    attackCooldown = 10;
                    //    break;

                    case ItemID.Bird:
                        type           = ModContent.ProjectileType <BirdProj>();
                        damage         = 15;
                        attackCooldown = 15;
                        break;

                    case ItemID.BlueJay:
                        type           = ModContent.ProjectileType <BlueJayProj>();
                        damage         = 10;
                        attackCooldown = 10;
                        break;

                    case ItemID.Cardinal:
                        type           = ModContent.ProjectileType <CardinalProj>();
                        damage         = 20;
                        attackCooldown = 20;
                        break;
                    }

                    if (type != -1)
                    {
                        Projectile.NewProjectile(player.Center, vel * 2f, type, damage, 2, player.whoAmI);
                        modPlayer.CritterAttackTimer = attackCooldown;
                    }
                }



                return(false);
            }

            if (item.type == ItemID.RodofDiscord)
            {
                if (FargoSoulsWorld.EternityMode && FargoSoulsUtil.AnyBossAlive())
                {
                    /*player.AddBuff(ModContent.BuffType<Buffs.Masomode.ChaosLife>(), 30);
                     * modPlayer.MaxLifeReduction += 100;*/
                    player.chaosState = true;

                    /*player.statLife -= player.statLifeMax2 / 5;
                     * PlayerDeathReason damageSource = PlayerDeathReason.ByOther(13);
                     * if (Main.rand.NextBool())
                     *  damageSource = PlayerDeathReason.ByOther(player.Male ? 14 : 15);
                     * if (player.statLife <= 0 && !player.chaosState) //since chaos state will check and kill anyway, avoid doublekill
                     *  player.KillMe(damageSource, 1, 0);
                     * player.lifeRegenCount = 0;
                     * player.lifeRegenTime = 0;*/
                }

                if (player.chaosState)
                {
                    player.GetModPlayer <FargoPlayer>().WasHurtBySomething = true; //with abom rebirth, die to chaos state
                }
            }

            return(true);
        }
예제 #28
0
        public override void AI()
        {
            EModeGlobalNPC.championBoss = NPC.whoAmI;

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

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

                    if (FargoSoulsWorld.downedBoss[(int)FargoSoulsWorld.Downed.SpiritChampion] && NPC.ai[1] < 120)
                    {
                        NPC.ai[1] = 120;
                    }

                    if (NPC.ai[1] == 180)
                    {
                        SoundEngine.PlaySound(SoundID.Roar, NPC.Center);

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

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

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

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

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

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

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

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

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

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

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

                return;
            }

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

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

            NPC.dontTakeDamage = false;

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

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

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

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

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

                    return;
                }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                    return;
                }

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

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

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

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

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

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

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

                            for (int i = 0; i < 12; i++)
                            {
                                Projectile.NewProjectile(NPC.GetSource_FromThis(), NPC.position.X + Main.rand.Next(NPC.width), NPC.position.Y + Main.rand.Next(NPC.height),
                                                         Main.rand.NextFloat(-8f, 8f), Main.rand.NextFloat(-8f, 8f), ModContent.ProjectileType <SpiritCrossBone>(), FargoSoulsUtil.ScaledProjectileDamage(NPC.damage), 0f, Main.myPlayer);
                            }
                        }
                        else     //sandnado
                        {
                            doPredictiveSandnado = !doPredictiveSandnado;

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

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

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

            case 2:
                goto case 0;

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

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

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

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

            case 4:
                goto case 0;

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

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

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

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

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

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

            case 6:
                goto case 0;

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

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

                const float distance = 150;

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

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

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

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

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

                                //x.netUpdate = true;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                for (int i = 0; i < 20; i++) //dust
                {
                    int d = Dust.NewDust(NPC.Center + auraDistance * Vector2.UnitX.RotatedBy(Math.PI * 2 * Main.rand.NextDouble()), 0, 0, 87);
                    Main.dust[d].velocity  = NPC.velocity;
                    Main.dust[d].noGravity = true;
                    Main.dust[d].scale++;
                }
            }
        }
예제 #29
0
        public override void Kill(int timeLeft)
        {
            SoundEngine.PlaySound(SoundID.Item14, Projectile.Center);

            if (Main.netMode == NetmodeID.MultiplayerClient)
            {
                return;
            }

            int xPos = (int)Projectile.Center.X / 16;
            int yPos = (int)Projectile.Center.Y / 16;

            bool WipeColumn(int i)
            {
                for (int j = 0; j >= -50; j--)
                {
                    int tileX = xPos + i;
                    int tileY = yPos + j;

                    if (tileX < 0 || tileX > Main.maxTilesX || tileY <= 0 || tileY > Main.maxTilesY)
                    {
                        if (j == 0)
                        {
                            return(false);
                        }
                        continue;
                    }

                    Tile tile = Framing.GetTileSafely(tileX, tileY);

                    if (tile.type == TileID.LihzahrdAltar)
                    {
                        continue;
                    }

                    if (tile.wall != WallID.LihzahrdBrickUnsafe)
                    {
                        if (j == 0)
                        {
                            return(false);
                        }
                        continue;
                    }

                    //check for chest above this block
                    Tile tileAbove = Framing.GetTileSafely(tileX, tileY - 1);
                    if (TileID.Sets.BasicChest[tileAbove.type])
                    {
                        TileObjectData data = TileObjectData.GetTileData(tileAbove.type, 0);
                        int            x    = tileX - (tile.frameX / 18 % data.Width);
                        int            y    = tileY - 1 - (tile.frameY / 18 % data.Height); //get top left of chest

                        WorldGen.KillTile(x, y);
                        if (Main.netMode == NetmodeID.Server)
                        {
                            NetMessage.SendTileSquare(-1, x, y, 3);
                        }

                        //if couldnt destroy chest, ignore this block
                        if (TileID.Sets.BasicChest[tileAbove.type])
                        {
                            continue;
                        }
                    }

                    if (TileID.Sets.BasicChest[tile.type])
                    {
                        TileObjectData data = TileObjectData.GetTileData(tile.type, 0);
                        int            x    = tileX - tile.frameX / 18 % data.Width;
                        int            y    = tileY - tile.frameY / 18 % data.Height; //get top left of chest

                        WorldGen.KillTile(x, y);                                      //try to kill chest
                        if (Main.netMode == NetmodeID.Server)
                        {
                            NetMessage.SendTileSquare(-1, x, y, 3);
                        }

                        continue;
                    }

                    if (tile.type == TileID.LihzahrdBrick)
                    {
                        tile.IsActuated = true; //actuate it
                        if (Main.netMode == NetmodeID.Server)
                        {
                            NetMessage.SendTileSquare(-1, tileX, tileY, 1);
                        }

                        continue;
                    }

                    WorldGen.KillTile(tileX, tileY);
                    if (Main.netMode == NetmodeID.Server)
                    {
                        NetMessage.SendTileSquare(-1, tileX, tileY, 1);
                    }
                }

                return(true);
            }

            int leftMax  = 50;
            int rightMax = 50;

            int leftTry = 0;

            for (; leftTry >= -leftMax; leftTry--)           //try clearing left side
            {
                if (!WipeColumn(leftTry))                    //if went OOB or exited temple before reaching normal left limit, give up
                {
                    rightMax += leftMax - Math.Abs(leftTry); //try to extend right side by this much
                    //Main.NewText($"Extended right max to {rightMax}");
                    break;
                }
            }

            for (int rightTry = 0; rightTry <= rightMax; rightTry++) //try clearing right side
            {
                if (!WipeColumn(rightTry))                           //if went OOB or exited temple before reaching normal right limit, give up
                {
                    leftMax += rightMax - rightTry;                  //try to extend left side by this much
                    //Main.NewText($"Extended left max to {leftMax}");
                    for (; leftTry >= -leftMax; leftTry--)           //try left one more time with the new extended limit
                    {
                        if (!WipeColumn(leftTry))
                        {
                            break;
                        }
                    }
                    break;
                }
            }
        }
예제 #30
0
        public override void HoldItem(Player player)
        {
            if (Main.mouseRight)
            {
                if (charge < 1)
                {
                    charge += 1f / (item.useTime * 2f);
                }
                else
                {
                    if (!charged)
                    {
                        Main.PlaySound(SoundID.MaxMana);
                    }
                    charged = true;
                    charge  = 1;
                }

                player.itemAnimation = (int)(charge * player.itemAnimationMax);
                player.itemRotation  = (1.3f - charge * 3.2f) * player.direction;
            }
            else if (charge > 0 && charged)
            {
                bool inRange = Vector2.DistanceSquared(player.Center, new Vector2(Player.tileTargetX, Player.tileTargetY) * 16) < Math.Pow(Player.tileRangeX * 16, 2);

                charge -= 0.1f;
                player.itemAnimation = (int)(charge * player.itemAnimationMax);

                if (charge > 0.69f && charge < 0.71f && inRange) //trigger VFX early so they line up
                {
                    Vector2 pos = new Vector2(Player.tileTargetX + 0.5f, Player.tileTargetY + 0.5f) * 16;
                    Projectile.NewProjectile(pos, Vector2.Zero, ProjectileType <AuroraPickVFX>(), 0, 0, player.whoAmI);
                    Main.PlaySound(SoundID.DD2_WitherBeastAuraPulse.SoundId, (int)pos.X, (int)pos.Y, SoundID.DD2_WitherBeastAuraPulse.Style, 1.5f, 2f);
                }

                if (charge <= 0)
                {
                    if (inRange)
                    {
                        for (int x = -1; x <= 1; x++)
                        {
                            for (int y = -1; y <= 1; y++)
                            {
                                int xReal = Player.tileTargetX + x;
                                int yReal = Player.tileTargetY + y;

                                if (Framing.GetTileSafely(xReal, yReal).type != TileID.Trees)
                                {
                                    player.PickTile(xReal, yReal, item.pick);
                                }
                            }
                        }
                    }

                    charged = false;
                    player.itemAnimation = 0;
                }
            }
            else
            {
                charge  = 0;
                charged = false;
            }
        }