public void CrawlerAI(NPC n, float speed, int gravityType = 0, bool useRotation = true, bool fullSpeedOnSlopes = false)
        {
            // This AI is based on the vanilla snail AI (because it can crawl on all surfaces)
            // with some modifications that make it work better on slopes.
            // To make it work, the NPC needs the same aiStyle value of 67
            // which allows it to use the same slope collision checks as that AI.
            n.ai[2] = 2f;             // <-- So don't remove this because of potential shinanigans with vanilla code.

            // We also have to define our own 'rotation' and 'directionY' variables, because the vanilla code screws with them on slopes.
            // Also make sure this is run in PreAI and return false so that it doesn't use the full extent of the vanilla AI.

            float speedCheck = Math.Max(speed, 1f);

            if (CollideMethods.CheckCollide(n.position + new Vector2(speedCheck * n.direction, 0f), n.width, n.height))
            {
                n.collideX = true;
            }
            if (CollideMethods.CheckCollide(n.position + new Vector2(0f, speedCheck * directionY), n.width, n.height))
            {
                n.collideY = true;
            }

            if (n.ai[0] == 0f)
            {
                n.TargetClosest(true);
                directionY = 1;
                n.ai[0]    = 1f;

                n.direction = 1;
                if (Main.rand.Next(2) == 0)
                {
                    n.direction = -1;
                }

                if (n.direction > 0)
                {
                    n.spriteDirection = 1;
                }
                n.netUpdate = true;
            }
            bool flag = false;

            //if (Main.netMode != 1)
            //{
            if (!n.collideX && !n.collideY)
            {
                n.localAI[3] += 1f;
                if (n.localAI[3] > 5f)
                {
                    n.ai[3] = 2f;
                    //n.netUpdate = true;
                }
            }
            else
            {
                n.localAI[3] = 0f;
            }
            //}
            if (n.ai[3] > 0f)
            {
                n.ai[1] = 0f;
                n.ai[0] = 1f;
                if (n.velocity.Y > speed && useRotation)
                {
                    rotation += (float)n.direction * 0.1f;
                }
                else
                {
                    rotation = 0f;
                }
                n.spriteDirection = n.direction;
                n.velocity.X      = speed * (float)n.direction;

                if (gravityType == 0)
                {
                    directionY  = 1;
                    n.noGravity = false;
                }
                else if (gravityType == 1)
                {
                    n.velocity.Y = speed * directionY;
                }

                if (n.collideX || n.collideY)
                {
                    n.ai[3] -= 1f;
                }
            }
            if (n.ai[3] != 0f)
            {
                return;
            }

            n.noGravity = true;

            bool flag2 = false;

            if (CollideMethods.CheckCollide(n.position, n.width, n.height))
            {
                flag2 = true;

                bool flag3 = false;
                if (!CollideMethods.CheckCollide(n.position + new Vector2(n.width, 0f), 1, n.height))
                {
                    n.direction = 1;
                }
                else if (!CollideMethods.CheckCollide(n.position + new Vector2(-1f, 0f), 1, n.height))
                {
                    n.direction = -1;
                }
                else
                {
                    n.direction *= -1;
                    flag3        = true;
                }

                if (!CollideMethods.CheckCollide(n.position + new Vector2(0f, n.height), n.width, 1))
                {
                    directionY = 1;
                }
                else if (CollideMethods.CheckCollide(n.position + new Vector2(0f, -1f), n.width, 1) || flag3)
                {
                    directionY = -1;
                }
                else
                {
                    directionY *= -1;
                }
            }
            else
            {
                if (n.ai[1] == 0f)
                {
                    if (n.collideY)
                    {
                        if (n.ai[0] < 2f)
                        {
                            n.ai[0] = 2f;
                        }
                    }
                    if (!n.collideY && n.ai[0] >= 2f)
                    {
                        n.ai[0] += 1f;
                        if (n.ai[0] > 3f)
                        {
                            n.direction = -n.direction;
                            n.ai[1]     = 1f;
                            n.ai[0]     = 1f;
                        }
                    }
                    if (n.collideX)
                    {
                        directionY = -directionY;
                        n.ai[1]    = 1f;
                    }
                }
                else
                {
                    if (n.collideX)
                    {
                        if (n.ai[0] < 2f)
                        {
                            n.ai[0] = 2f;
                        }
                    }
                    if (!n.collideX && n.ai[0] >= 2f)
                    {
                        n.ai[0] += 1f;
                        if (n.ai[0] > 3f)
                        {
                            directionY = -directionY;
                            n.ai[1]    = 0f;
                            n.ai[0]    = 1f;
                        }
                    }
                    if (n.collideY)
                    {
                        n.direction = -n.direction;
                        n.ai[1]     = 0f;
                    }
                }
            }

            if (!flag && useRotation)
            {
                float bottom_rot = 0f;
                float left_rot   = 1.57f;
                float top_rot    = 3.14f;
                float right_rot  = 4.71f;

                float rot = rotation;
                if (directionY < 0)
                {
                    if (n.direction < 0)
                    {
                        if (n.collideX)
                        {
                            rotation          = left_rot;
                            n.spriteDirection = -1;
                        }
                        else if (n.collideY)
                        {
                            rotation          = top_rot;
                            n.spriteDirection = 1;
                        }
                    }
                    else if (n.collideY)
                    {
                        rotation          = top_rot;
                        n.spriteDirection = -1;
                    }
                    else if (n.collideX)
                    {
                        rotation          = right_rot;
                        n.spriteDirection = 1;
                    }
                }
                else if (n.direction < 0)
                {
                    if (n.collideY)
                    {
                        rotation          = bottom_rot;
                        n.spriteDirection = -1;
                    }
                    else if (n.collideX)
                    {
                        rotation          = left_rot;
                        n.spriteDirection = 1;
                    }
                }
                else if (n.collideX)
                {
                    rotation          = right_rot;
                    n.spriteDirection = -1;
                }
                else if (n.collideY)
                {
                    rotation          = bottom_rot;
                    n.spriteDirection = 1;
                }

                float bl_slope_rot = 0.79f;
                float tl_slope_rot = 2.36f;
                float tr_slope_rot = 3.93f;
                float br_slope_rot = 5.50f;
                float offY         = 0f;
                bool  bottom       = CollideMethods.CheckCollide(n.position + new Vector2(0f, 2f), n.width, n.height);
                bool  left         = CollideMethods.CheckCollide(n.position + new Vector2(-2f, 0f), n.width, n.height);
                bool  top          = CollideMethods.CheckCollide(n.position + new Vector2(0f, -2f), n.width, n.height);
                bool  right        = CollideMethods.CheckCollide(n.position + new Vector2(2f, 0f), n.width, n.height);
                if (left)
                {
                    if (bottom)
                    {
                        rotation = bl_slope_rot;
                        offY     = 6f;
                    }
                    if (top)
                    {
                        rotation = tl_slope_rot;
                        offY     = 6f;
                    }
                }
                if (right)
                {
                    if (bottom)
                    {
                        rotation = br_slope_rot;
                        offY     = 6f;
                    }
                    if (top)
                    {
                        rotation = tr_slope_rot;
                        offY     = 6f;
                    }
                }
                if (yOffset < offY)
                {
                    yOffset = Math.Min(yOffset + 1f, offY);
                }
                else
                {
                    yOffset = Math.Max(yOffset - 1f, offY);
                }

                float rot2 = rotation;
                rotation = rot;
                if ((double)rotation > 6.28)
                {
                    rotation -= 6.28f;
                }
                if (rotation < 0f)
                {
                    rotation += 6.28f;
                }
                float rot3    = Math.Abs(rotation - rot2);
                float rotRate = 0.1f;
                if (rotation > rot2)
                {
                    if ((double)rot3 > 3.14)
                    {
                        rotation += rotRate;
                    }
                    else
                    {
                        rotation -= rotRate;
                        if (rotation < rot2)
                        {
                            rotation = rot2;
                        }
                    }
                }
                if (rotation < rot2)
                {
                    if ((double)rot3 > 3.14)
                    {
                        rotation -= rotRate;
                    }
                    else
                    {
                        rotation += rotRate;
                        if (rotation > rot2)
                        {
                            rotation = rot2;
                        }
                    }
                }
            }
            float speed2 = speed;

            if (!CollideMethods.CheckCollide(n.position + new Vector2(speedCheck * n.direction, speedCheck * directionY), n.width, n.height) && !fullSpeedOnSlopes)
            {
                speed2 = (float)Math.Cos(Math.PI / 4) * speed;
            }
            n.velocity.X = speed2 * (float)n.direction;
            n.velocity.Y = speed2 * (float)directionY;
            if (flag2)
            {
                n.position += n.velocity;
            }
        }
Exemple #2
0
        public override void AI()
        {
            Projectile P    = projectile;
            Player     O    = Main.player[P.owner];
            Vector2    oPos = O.RotatedRelativePoint(O.MountedCenter, true);

            Lead = Main.projectile[(int)P.ai[0]];
            if (!Lead.active || Lead.owner != P.owner || Lead.type != mod.ProjectileType("ChargeLead") || !O.controlUseItem)
            {
                P.Kill();
                return;
            }
            else
            {
                if (!initialize)
                {
                    initialize = true;
                }

                if (P.owner == Main.myPlayer)
                {
                    if (soundInstance == null || soundInstance.State != SoundState.Playing)
                    {
                        Main.PlaySound(SoundLoader.customSoundType, (int)O.position.X, (int)O.position.Y, mod.GetSoundSlot(SoundType.Custom, "Sounds/SolarComboSoundStart"));
                        soundInstance = Main.PlaySound(SoundLoader.customSoundType, (int)O.position.X, (int)O.position.Y, mod.GetSoundSlot(SoundType.Custom, "Sounds/SolarComboSoundLoop"));
                        if (Main.soundVolume > 0f)
                        {
                            soundInstance.Volume = 0f;
                        }
                        soundInstance2 = Main.PlaySound(SoundLoader.customSoundType, (int)O.position.X, (int)O.position.Y, mod.GetSoundSlot(SoundType.Custom, "Sounds/NovaLaserLoop"));
                    }
                    else if (P.numUpdates == 0 && Main.soundVolume > 0f)
                    {
                        soundInstance.Volume  = Math.Min(soundInstance.Volume + 0.05f * Main.soundVolume, 0.75f * Main.soundVolume);
                        soundInstance2.Volume = Math.Min(soundInstance2.Volume + 0.05f * Main.soundVolume, 0.75f * Main.soundVolume);
                    }
                }
                P.velocity = Vector2.Normalize(Lead.velocity);
                P.Center   = oPos;
                P.timeLeft = 2;
                P.rotation = P.velocity.ToRotation() - 1.57f;

                maxRange = Math.Min(maxRange + 16f, Max_Range);

                for (P.ai[1] = 0f; P.ai[1] <= maxRange; P.ai[1] += 4f)
                {
                    Vector2 end = oPos + P.velocity * P.ai[1];
                    if (CollideMethods.CheckCollide(end, 0, 0))
                    {
                        P.ai[1] -= 4f;
                        if (num <= 0)
                        {
                            end = oPos + P.velocity * P.ai[1];
                            int proj = Projectile.NewProjectile(end.X, end.Y, 0f, 0f, mod.ProjectileType("SolarLaserFlameTrail"), P.damage, P.knockBack, P.owner);
                            num = 4;
                        }
                        break;
                    }
                }
                if (num > 0 && P.numUpdates == 0)
                {
                    num--;
                }

                float leadDist = Vector2.Distance(oPos, Lead.Center);
                for (float i = leadDist; i < P.ai[1]; i += P.width)
                {
                    Vector2 sPos = oPos + P.velocity * i;
                    if (sPos.X > Main.screenPosition.X - 100f && sPos.X < Main.screenPosition.X + Main.screenWidth + 100f &&
                        sPos.Y > Main.screenPosition.Y - 100f && sPos.Y < Main.screenPosition.Y + Main.screenHeight + 100f)
                    {
                        if (Main.rand.Next(50) == 0 && P.ai[1] > leadDist)
                        {
                            int numX = 1;
                            if (Main.rand.Next(2) == 0)
                            {
                                numX = -1;
                            }

                            int        proj  = Projectile.NewProjectile(sPos.X, sPos.Y, P.velocity.X, P.velocity.Y, mod.ProjectileType("SolarLaserFlareShot"), P.damage, P.knockBack, P.owner);
                            Projectile sProj = Main.projectile[proj];
                            sProj.ai[0]      = Lead.whoAmI;
                            sProj.ai[1]      = P.whoAmI;
                            sProj.localAI[0] = i;
                            sProj.localAI[1] = (Main.rand.Next(50) + 60) * numX;
                        }

                        if (Main.rand.Next(10) == 0)
                        {
                            float   k    = Math.Min(i, P.ai[1]);
                            Vector2 dPos = (oPos - (P.Size / 2f) * scaleUp) + P.velocity * k;
                            Main.dust[Dust.NewDust(dPos, (int)((float)P.width * scaleUp), (int)((float)P.width * scaleUp), 6, 0, 0, 100, default(Color), 3f)].noGravity = true;
                        }
                    }
                }

                Vector2 dustPos = oPos - (P.Size / 2f) * scaleUp + P.velocity * P.ai[1];
                int     size    = (int)((float)P.width * scaleUp);
                float   num1    = P.velocity.ToRotation() + (Main.rand.Next(2) == 1 ? -1.0f : 1.0f) * 1.57f;
                float   num2    = (float)(Main.rand.NextDouble() * 0.8f + 1.0f);
                Vector2 dustVel = new Vector2((float)Math.Cos(num1) * num2, (float)Math.Sin(num1) * num2);
                Dust    dust    = Main.dust[Dust.NewDust(dustPos, size, size, 6, dustVel.X, dustVel.Y, 100, default(Color), 4f)];
                dust.noGravity = true;
                dust.velocity *= 3f;

                Color color = MetroidMod.novColor;
                DelegateMethods.v3_1 = new Vector3(color.R / 255f, color.G / 255f, color.B / 255f);
                Utils.PlotTileLine(P.Center, P.Center + P.velocity * P.ai[1], 26, DelegateMethods.CastLight);

                if (P.numUpdates == 0)
                {
                    scaleUp = Math.Min(scaleUp + 0.1f, 1.7f);                    //2f);
                    P.frame++;
                    if (P.frame >= Main.projFrames[projectile.type])
                    {
                        P.frame = 0;
                    }
                }
                ChargeLead chLead = (ChargeLead)Lead.modProjectile;
                chLead.extraScale = 1.125f * scaleUp;
            }
        }
Exemple #3
0
        public override void AI()
        {
            Projectile P    = projectile;
            Player     O    = Main.player[P.owner];
            Vector2    oPos = O.RotatedRelativePoint(O.MountedCenter, true);

            Lead = Main.projectile[(int)P.ai[0]];
            if (!Lead.active || Lead.owner != P.owner || Lead.type != mod.ProjectileType("ChargeLead") || !O.controlUseItem)
            {
                P.Kill();
                return;
            }
            else
            {
                if (!initialize)
                {
                    initialize = true;
                }

                if (P.owner == Main.myPlayer)
                {
                    if (soundInstance == null || soundInstance.State != SoundState.Playing)
                    {
                        soundInstance = Main.PlaySound(SoundLoader.customSoundType, (int)O.position.X, (int)O.position.Y, mod.GetSoundSlot(SoundType.Custom, "Sounds/NovaLaserLoop"));
                    }
                }
                P.velocity = Vector2.Normalize(Lead.velocity);
                P.Center   = oPos;
                P.timeLeft = 2;
                P.rotation = P.velocity.ToRotation() - 1.57f;

                maxRange = Math.Min(maxRange + 16f, Max_Range);

                for (P.ai[1] = 0f; P.ai[1] <= maxRange; P.ai[1] += 4f)
                {
                    Vector2 end = oPos + P.velocity * P.ai[1];
                    if (CollideMethods.CheckCollide(end, 0, 0))
                    {
                        P.ai[1] -= 4f;
                        break;
                    }
                }

                float leadDist = Vector2.Distance(oPos, Lead.Center);
                for (float i = leadDist; i < P.ai[1]; i += P.width)
                {
                    if (Main.rand.Next(25) == 0)
                    {
                        float   k    = Math.Min(i, P.ai[1]);
                        Vector2 dPos = (oPos - P.Size / 2) + P.velocity * k;
                        Main.dust[Dust.NewDust(dPos, P.width, P.width, 75, 0, 0, 100, default(Color), 2f)].noGravity = true;
                    }
                }

                Vector2 dustPos = oPos + P.velocity * P.ai[1];
                float   num1    = P.velocity.ToRotation() + (Main.rand.Next(2) == 1 ? -1.0f : 1.0f) * 1.57f;
                float   num2    = (float)(Main.rand.NextDouble() * 0.8f + 1.0f);
                Vector2 dustVel = new Vector2((float)Math.Cos(num1) * num2, (float)Math.Sin(num1) * num2);
                Dust    dust    = Main.dust[Dust.NewDust(dustPos, 0, 0, 75, dustVel.X, dustVel.Y, 100, default(Color), 2f)];
                dust.noGravity = true;
                dust.velocity *= 3f;
                dust.position  = dustPos;

                Color color = MetroidMod.novColor;
                DelegateMethods.v3_1 = new Vector3(color.R / 255f, color.G / 255f, color.B / 255f);
                Utils.PlotTileLine(P.Center, P.Center + P.velocity * P.ai[1], 26, DelegateMethods.CastLight);

                if (P.numUpdates == 0)
                {
                    scaleUp = Math.Min(scaleUp + 0.1f, 1f);
                    P.frame++;
                    if (P.frame >= Main.projFrames[projectile.type])
                    {
                        P.frame = 0;
                    }
                }
                ChargeLead chLead = (ChargeLead)Lead.modProjectile;
                chLead.extraScale = 0.75f * scaleUp;
            }
        }