Esempio n. 1
0
        private NPC getTarget()
        {
            float lowestD = 1100;
            NPC   closest = null;

            for (int i = 0; i < 200; i++)
            {
                NPC   npc      = Main.npc[i];
                float distance = (float)Math.Sqrt((npc.Center.X - projectile.Center.X) * (npc.Center.X - projectile.Center.X) + (npc.Center.Y - projectile.Center.Y) * (npc.Center.Y - projectile.Center.Y));
                if (npc.townNPC || npc.catchItem > 0)
                {
                }
                else if (lowestD > distance && npc.CanBeChasedBy() && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, npc.Center, 1, 1))
                {
                    closest = npc;
                    lowestD = distance;
                }
            }
            target = closest;
            return(closest);
        }
Esempio n. 2
0
 public override void AI()
 {
     if (Main.rand.Next(200) == 0)
     {
         Main.dust[Dust.NewDust(projectile.Center + new Vector2(6, 6).RotatedBy(projectile.rotation), 0, 0, 204, 0f, 0f, 0, new Color(255, 255, 255), 1f)].velocity *= 0.2f;
     }
     if (projectile.damage == 1)
     {
         Vector2 center = projectile.Center;                                     // - new Vector2(0, 4).RotatedBy(projectile.rotation);
         double  rot    = Math.Round(projectile.rotation / MathHelper.PiOver4);
         Vector2 offset = new Vector2(0, 8).RotatedBy(rot * MathHelper.PiOver4); //new Vector2(4, 0).RotatedBy(projectile.rotation);
         //Main.dust[Dust.NewDust(center-offset, 0, 0, 204, 0f, 0f, 0, new Color(255,255,255), 1f)].velocity*=0f;
         //Main.dust[Dust.NewDust(center+offset, 0, 0, 204, 0f, 0f, 0, new Color(255,255,255), 1f)].velocity*=0f;
         if (Collision.CanHitLine(center - offset, 0, 0, center + offset, 0, 0))
         {
             //Main.dust[Dust.NewDust(center, 0, 0, 27, 0f, 0f, 0, new Color(255,0,0), 1f)].velocity*=0.2f;
             Item.NewItem(projectile.Center, ModContent.ItemType <Fiberglass_Shard>());
             projectile.Kill();
         }
     }
 }
        public override Vector2 IdleBehavior()
        {
            animationFrame++;
            gHelper.SetIsOnGround();
            // the ground-based slime can sometimes bounce its way around
            // a corner, but the flying version can't
            noLOSPursuitTime = gHelper.isFlying ? 15 : 300;
            List <Projectile> minions = GetActiveMinions();
            int     order             = minions.IndexOf(projectile);
            Vector2 idlePosition      = player.Center;

            idlePosition.X += (40 + order * 38) * -player.direction;
            if (!Collision.CanHitLine(idlePosition, 1, 1, player.Center, 1, 1))
            {
                idlePosition = player.Center;
            }
            Vector2 vectorToIdlePosition = idlePosition - projectile.Center;

            TeleportToPlayer(ref vectorToIdlePosition, 2000f);
            return(vectorToIdlePosition);
        }
        private void TargetEnemies()
        {
            float maxDistance    = 1000f;
            int   possibleTarget = -1;

            for (int i = 0; i < Main.maxPlayers; i++)
            {
                Player player = Main.player[i];
                if (player.active && Collision.CanHitLine(projectile.Center, 0, 0, player.Center, 0, 0))
                {
                    float Distance = projectile.Distance(player.Center);
                    if (Distance < maxDistance)
                    {
                        maxDistance    = Distance;
                        possibleTarget = i;
                    }
                }
            }
            projectile.localAI[1] = possibleTarget;
            projectile.netUpdate  = true;
        }
Esempio n. 5
0
        public override void AI()
        {
            npc.TargetClosest(true);
            Player target = Main.player[npc.target];

            if (Collision.CanHitLine(npc.position, npc.width, npc.height, target.position, target.width, target.height))
            {
                npc.ai[3]++;
            }
            if (npc.ai[3] > 120 && Main.netMode != NetmodeID.MultiplayerClient)
            {
                float   speedX = target.MountedCenter.X - npc.Center.X;
                float   speedY = target.MountedCenter.Y - npc.Center.Y;
                Vector2 spd    = new Vector2(speedX, speedY);
                spd.Normalize();
                spd *= 14;
                Projectile.NewProjectile(npc.Center, spd, ModContent.ProjectileType <Projectiles.Smokedevil>(), npc.damage / 4, 0f);
                npc.ai[3]     = Main.rand.Next(0, 30);
                npc.netUpdate = true;
            }
        }
Esempio n. 6
0
        public Vector2?ClosestEnemyInRange(float maxRange, Vector2?centeredOn = null, float noLOSRange = 0, bool maxRangeFromPlayer = true, Vector2?losCenter = null)
        {
            Vector2 center          = centeredOn ?? projectile.Center;
            Vector2 targetCenter    = projectile.position;
            Vector2 losCenterVector = losCenter ?? projectile.Center;
            bool    foundTarget     = false;

            for (int i = 0; i < Main.maxNPCs; i++)
            {
                NPC npc = Main.npc[i];
                if (!npc.CanBeChasedBy())
                {
                    continue;
                }
                float between = Vector2.Distance(npc.Center, center);
                bool  closest = Vector2.Distance(center, targetCenter) > between;
                // don't let a minion infinitely chain attacks off progressively further enemies
                bool inRange      = Vector2.Distance(npc.Center, maxRangeFromPlayer ? player.Center : projectile.Center) < maxRange;
                bool inNoLOSRange = Vector2.Distance(npc.Center, player.Center) < noLOSRange;
                bool lineOfSight  = inNoLOSRange || Collision.CanHitLine(losCenterVector, 1, 1, npc.position, npc.width, npc.height);
                if ((inNoLOSRange || (lineOfSight && inRange)) && (closest || !foundTarget))
                {
                    targetNPCIndex = i;
                    targetCenter   = npc.Center;
                    foundTarget    = true;
                }
            }
            if (foundTarget)
            {
                return(targetCenter);
            }
            else if (useBeacon)
            {
                return(BeaconPosition(center, maxRange, noLOSRange));
            }
            else
            {
                return(null);
            }
        }
Esempio n. 7
0
        public override Vector2 IdleBehavior()
        {
            // hover behind the player
            Vector2 idlePosition = player.Top;

            idlePosition.X += 24 * -player.direction;
            idlePosition.Y += -8;
            // not sure what side effects changing this each frame might have
            if (attackSpeedCanBeModified)
            {
                projectile.localNPCHitCooldown = (int)(baseLocalIFrames * player.GetModPlayer <SquireModPlayer>().squireAttackSpeedMultiplier);
            }
            if (!Collision.CanHitLine(idlePosition, 1, 1, player.Center, 1, 1))
            {
                idlePosition.X = player.Center.X;
                idlePosition.Y = player.Center.Y - 24;
            }
            Vector2 vectorToIdlePosition = idlePosition - projectile.Center;

            TeleportToPlayer(ref vectorToIdlePosition, 2000f);
            return(vectorToIdlePosition);
        }
Esempio n. 8
0
        public override void AI()
        {
            Player P = Main.player[npc.target];

            npc.netUpdate = true;
            if (Vector2.Distance(npc.Center, P.Center) > 1500 || npc.target < 0 || npc.target == 255 || Main.player[npc.target].dead || !Main.player[npc.target].active)
            {
                npc.TargetClosest(true);
                P = Main.player[npc.target];
                if (!P.active || P.dead || Vector2.Distance(npc.Center, P.Center) > 1500)
                {
                    regen = true;
                }
            }
            if (!regen)
            {
                npc.life = npc.life < npc.lifeMax ? npc.life + 1 + (int)((float)npc.lifeMax * 0.001f) : npc.lifeMax;
                if (Collision.CanHitLine(new Vector2(npc.Center.X, npc.Center.Y), 1, 1, new Vector2(P.Center.X, P.Center.Y), 1, 1) || Vector2.Distance(npc.Center, P.Center) < 400)
                {
                    regen = true;
                }
            }
            if (npc.velocity.Y == 0)
            {
                if (chance != 0)
                {
                    chance = Main.rand.Next(150);
                }
                else
                {
                    if (Collision.CanHitLine(new Vector2(npc.Center.X, npc.Center.Y), 1, 1, new Vector2(P.Center.X, P.Center.Y), 1, 1))
                    {
                        npc.velocity.Y = -(float)Math.Sqrt(2 * 0.3f * Math.Abs((P.position.Y - 100) - npc.Center.Y));
                        npc.velocity.X = (P.Center.X + P.velocity.X - npc.Center.X) / 90;
                        chance         = 1;
                    }
                }
            }
        }
        public override bool?Colliding(Rectangle projHitbox, Rectangle targetHitbox)
        {
            // use a computed weapon hitbox instead of the projectile's natural hitbox
            if (!IsAttacking())
            {
                return(false);
            }
            Vector2 unitAngle = UnitVectorFromWeaponAngle();

            for (int i = WeaponHitboxStart(); i < WeaponHitboxEnd(); i += 8)
            {
                Vector2   tipCenter = projectile.Center + WeaponCenterOfRotation + i * unitAngle;
                Rectangle tipHitbox = new Rectangle((int)tipCenter.X - 8, (int)tipCenter.Y - 8, 16, 16);
                if (tipHitbox.Intersects(targetHitbox))
                {
                    return(Collision.CanHitLine(
                               tipHitbox.Center.ToVector2(), 1, 1,
                               projectile.Center, 1, 1));
                }
            }
            return(false);
        }
Esempio n. 10
0
        public Vector2?AnyEnemyInRange(float maxRange, Vector2?centeredOn = null, bool noLOS = false)
        {
            Vector2 center = centeredOn ?? projectile.Center;

            for (int i = 0; i < Main.maxNPCs; i++)
            {
                NPC npc = Main.npc[i];
                if (!npc.CanBeChasedBy())
                {
                    continue;
                }
                //
                bool inRange     = Vector2.Distance(center, npc.Center) < maxRange;
                bool lineOfSight = noLOS || (inRange && Collision.CanHitLine(center, 1, 1, npc.Center, 1, 1));
                if (lineOfSight && inRange)
                {
                    targetNPCIndex = npc.whoAmI;
                    return(npc.Center);
                }
            }
            return(null);
        }
Esempio n. 11
0
        public static NPC FindNearestNPC(Vector2 position, float maxDist, bool ignoreLineOfSight = true, bool ignoreFriendlies = true, bool ignoreDontTakeDamage = false, bool ignoreChaseable = false)
        {
            NPC   nearest     = null;
            float distNearest = maxDist * maxDist;

            for (int i = 0; i < 200; i++)
            {
                NPC     npc       = Main.npc[i];
                Vector2 npcCenter = npc.Center;
                if (npc.active && (ignoreChaseable || npc.chaseable && npc.lifeMax > 5) &&
                    (ignoreDontTakeDamage || !npc.dontTakeDamage) && (!ignoreFriendlies || !npc.friendly) && !npc.immortal)
                {
                    float distCurrent = Vector2.DistanceSquared(position, npcCenter);
                    if (distCurrent < distNearest && (ignoreLineOfSight || Collision.CanHitLine(position, 0, 0, npcCenter, 0, 0)))
                    {
                        nearest     = npc;
                        distNearest = distCurrent;
                    }
                }
            }
            return(nearest);
        }
Esempio n. 12
0
        public override void AI(NPC npc)
        {
            base.AI(npc);

            if (npc.velocity.Y < 0f)
            {
                CanDoLavaJump = true;
            }
            else if (npc.velocity.Y > 0f) //coming down
            {
                //when below target, in hell, with line of sight
                if (CanDoLavaJump && Main.netMode != NetmodeID.MultiplayerClient && npc.HasValidTarget && npc.Bottom.Y > Main.player[npc.target].Bottom.Y &&
                    npc.Center.ToTileCoordinates().Y > Main.maxTilesY - 200 && Collision.CanHitLine(npc.Center, 0, 0, Main.player[npc.target].Center, 0, 0))
                {
                    CanDoLavaJump = false;
                    //Projectile.NewProjectile(npc.Center, Vector2.Zero, ProjectileID.DD2ExplosiveTrapT1Explosion, 0, 0, Main.myPlayer);

                    int  tileX = (int)(npc.Center.X + npc.velocity.X) / 16;
                    int  tileY = (int)(npc.Center.Y + npc.velocity.Y) / 16;
                    Tile tile  = Framing.GetTileSafely(tileX, tileY);
                    if (tile != null && !tile.HasTile && tile.LiquidAmount == 0)
                    {
                        tile.LiquidType = LiquidID.Lava; //does this still spawn the liquid properly??
                        if (Main.netMode == NetmodeID.Server)
                        {
                            NetMessage.SendTileSquare(-1, tileX, tileY, 1);
                        }
                        WorldGen.SquareTileFrame(tileX, tileY, true);
                        npc.velocity.Y = 0;
                        npc.netUpdate  = true;
                    }
                }
            }
            else //npc vel y = 0
            {
                CanDoLavaJump = false;
            }
        }
Esempio n. 13
0
        /// <summary>
        /// The AI of the projectile
        /// </summary>
        public override void AI()
        {
            Vector2 start = projectile.Center;
            Vector2 unit  = velocity;

            unit.Normalize();
            Vector2 samplingPoint = projectile.Center;

            // Overriding that, if the player shoves the Prism into or through a wall, the interpolation starts at the player's center.
            // This last part prevents the player from projecting beams through walls under any circumstances.
            Player player = Main.player[projectile.owner];

            if (projectile.timeLeft == 32)
            {
                velocity             = Vector2.Normalize(Main.MouseWorld - player.MountedCenter);
                projectile.position += velocity * 16;
                if (!Collision.CanHitLine(player.Center, 0, 0, projectile.Center, 0, 0))
                {
                    samplingPoint = projectile.Center = player.Center;
                }
            }
            float[] laserScanResults = new float[sample_points];
            Collision.LaserScan(samplingPoint, unit, collision_size * projectile.scale, 1200f, laserScanResults);
            float averageLengthSample = 0f;

            for (int i = 0; i < laserScanResults.Length; ++i)
            {
                averageLengthSample += laserScanResults[i];
            }
            averageLengthSample /= sample_points;
            _targetPos           = projectile.Center + (unit * averageLengthSample);

            if (++projectile.frameCounter > 5)
            {
                projectile.frame        = (projectile.frame + 1) % 4;
                projectile.frameCounter = 0;
            }
        }
Esempio n. 14
0
        public override bool Shoot(Player player, ref Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack)
        {
            Vector2 speed = new Vector2(speedX, speedY);

            int projectiles = 6;

            for (int i = 0; i < projectiles; i++)
            {
                float   roTATe         = (int)((360f / projectiles * i) + circleCounter);
                float   maxCursorReach = 192f;
                float   distance       = Math.Abs((player.MountedCenter - Main.MouseWorld).Length());
                float   positionOffset = -MathHelper.Clamp(distance, 0f, maxCursorReach);
                Vector2 spawnPosition  = new Vector2(0f, positionOffset).RotatedBy(MathHelper.ToRadians(roTATe));
                Vector2 shootSpeed     = new Vector2(0f, -speed.Length()).RotatedBy(MathHelper.ToRadians(roTATe)) * MathHelper.Clamp((rotationIncrement / minMax[1]), 0.05f, (rotationIncrement / minMax[1]));

                if (Collision.CanHitLine(position, 0, 0, position + spawnPosition, 0, 0))
                {
                    Projectile projectile = Projectile.NewProjectileDirect(position + spawnPosition, shootSpeed, type, (int)(damage * (rotationIncrement / minMax[1])), knockBack * (rotationIncrement / minMax[1]), player.whoAmI);
                    projectile.timeLeft = 45;
                    projectile.scale    = 1.1f;
                    projectile.frame    = Main.rand.Next(14);
                    //projectile.timeLeft = 600;

                    int rings = 16;
                    for (int j = 0; j < rings; j++)
                    {
                        for (int k = 0; k < 10; k++)
                        {
                            Vector2 dustVelocity = (new Vector2(0f, rings).RotatedBy(j * (MathHelper.ToRadians(360f) / rings)) * new Vector2(2f, 4f)).RotatedBy(MathHelper.ToRadians(360f / projectiles * i + circleCounter));
                            Dust    dust1        = Dust.NewDustPerfect(projectile.Center + dustVelocity, dustType, Vector2.Zero, 0, dustColor, 0.5f);
                            dust1.noGravity = true;
                        }
                    }
                }
            }

            return(false);
        }
        public static void DoAwarenessChecks(int distance, bool checkwalls, bool sound = false, Vector2 soundLoc = default)
        {
            if (watchers.Count < 1)
            {
                return;
            }


            if (!Main.gameMenu && sound == false && SGAPocketDim.WhereAmI != null)
            {
                if (SLWorld.currentSubworld is SGAPocketDim sub && sub.GetType() == typeof(LimboDim))
                {
                    distance *= 2;
                }
            }

            foreach (NullWatcher watcher in watchers)
            {
                if (!sound)
                {
                    List <Player> players = Main.player.Where(playercheck => playercheck != null && playercheck.active && !playercheck.dead && (((!playercheck.invis || playercheck.itemTime > 0) && !playercheck.SGAPly().magatsuSet) || playercheck.SGAPly().watcherDebuff >= 500) && playercheck.Distance(watcher.npc.Center) < (distance + playercheck.SGAPly().watcherDebuff) &&
                                                              (!checkwalls || Collision.CanHitLine(playercheck.Center, 1, 1, watcher.npc.Center, 1, 1))).ToList();
                    players = players.OrderBy(playercheck2 => playercheck2.Distance(watcher.npc.Center)).ToList();

                    if (players != null && players.Count > 0)
                    {
                        Player them = players[0];
                        int    add  = them.SGAPly().watcherDebuff > 0 ? 2 : 1;
                        watcher.GrowAwareness(soundLoc, add, distance, true, them);
                    }
                }

                if (sound && (soundLoc - watcher.npc.Center).Length() < distance)
                {
                    watcher.GrowAwareness(soundLoc, 30, distance, false);
                }
            }
        }
Esempio n. 16
0
        // A simpler version of SelectedEnemyInRange that doesn't require any tactics/teams stuff
        public NPC GetClosestEnemyToPosition(Vector2 position, float searchRange, bool requireLOS = true)
        {
            float minDist = float.MaxValue;
            NPC   closest = null;

            for (int i = 0; i < Main.maxNPCs; i++)
            {
                NPC npc = Main.npc[i];
                if (ShouldIgnoreNPC(npc))
                {
                    continue;
                }
                float distanceSq  = Vector2.DistanceSquared(npc.Center, position);
                bool  inRange     = distanceSq < searchRange * searchRange;
                bool  lineOfSight = (!requireLOS) || (inRange && Collision.CanHitLine(position, 1, 1, npc.position, npc.width, npc.height));
                if (lineOfSight && inRange && distanceSq < minDist)
                {
                    minDist = distanceSq;
                    closest = npc;
                }
            }
            return(closest);
        }
Esempio n. 17
0
        public override Vector2 IdleBehavior()
        {
            base.IdleBehavior();
            noLOSPursuitTime = gHelper.isFlying ? 15 : 300;
            Vector2 idlePosition = gHelper.isFlying ? player.Top : player.Bottom;
            Vector2 idleHitLine  = player.Center;

            idlePosition.X += -player.direction * IdleLocationSets.GetXOffsetInSet(IdleLocationSets.trailingOnGround, projectile);
            if (!Collision.CanHitLine(idleHitLine, 1, 1, player.Center, 1, 1))
            {
                idlePosition = player.Bottom;
            }
            Vector2 vectorToIdlePosition = idlePosition - projectile.Center;

            TeleportToPlayer(ref vectorToIdlePosition, 2000f);
            gHelper.SetIsOnGround();
            if (gHelper.offTheGroundFrames == 20 || (gHelper.offTheGroundFrames > 60 && Main.rand.Next(120) == 0) || (gHelper.isOnGround && gHelper.offTheGroundFrames > 20))
            {
                DrawPlatformDust();
            }
            Lighting.AddLight(projectile.Center, Color.PaleGreen.ToVector3() * 0.75f);
            return(vectorToIdlePosition);
        }
Esempio n. 18
0
        public override bool Shoot(Player player, ref Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack)
        {
            if (player == Main.player[Main.myPlayer])
            {
                Vector2 speed = new Vector2(speedX, speedY);

                int rings = 8;
                for (int i = 0; i < rings; i++)
                {
                    float distance = MathHelper.Clamp(Vector2.Distance(Main.MouseWorld, player.MountedCenter), 0f, 128f);
                    position  = new Vector2(0f, -distance).RotatedBy(MathHelper.ToRadians(360f / rings * i));
                    position *= new Vector2((float)Math.Abs(Vector2.Normalize(position).X), (float)Math.Abs(Vector2.Normalize(position).Y)).RotatedBy(MathHelper.ToRadians(0f));
                    position  = position.RotatedBy(MathHelper.ToRadians(45f) + speed.ToRotation());
                    Vector2 velocity = Vector2.Normalize(position) * speed.Length();
                    position += player.MountedCenter;
                    if (Collision.CanHitLine(player.MountedCenter, 0, 0, position, 0, 0))
                    {
                        Projectile projectile = Projectile.NewProjectileDirect(position, velocity, type, damage, knockBack, player.whoAmI);
                    }
                }
            }

            return(false);
        }
Esempio n. 19
0
 public override void HitEffect(int hitDirection, double damage)
 {
     npc.ai[2]++;
     for (int n = 0; n < 200; n++)
     {
         NPC N = Main.npc[n];
         if (N.active && N.Distance(npc.Center) < 400 && Collision.CanHitLine(npc.Center, 1, 1, N.Center, 1, 1) && (N.type == mod.NPCType("Cactite") || N.type == mod.NPCType("Cactoid")))
         {
             N.target = npc.target;
             N.ai[2]++;
             N.netUpdate = true;
         }
     }
     if (npc.life <= 0)
     {
         Gore.NewGore(npc.position, npc.velocity, mod.GetGoreSlot("Gores/Cactite1"), 1f);
         Gore.NewGore(npc.position, npc.velocity, mod.GetGoreSlot("Gores/Cactite2"), 1f);
         Gore.NewGore(npc.position, npc.velocity, mod.GetGoreSlot("Gores/Cactite2"), 1f);
     }
     if (npc.friendly)
     {
         npc.ai[3] = 45;
     }
 }
Esempio n. 20
0
        public override void OnKill(NPC npc)
        {
            base.OnKill(npc);

            if (npc.type == NPCID.Shark)
            {
                if (Main.hardMode && Main.rand.NextBool(4) && Collision.CanHitLine(npc.Top, 0, 0, npc.Top - 30 * 16f * Vector2.UnitY, 0, 0))
                {
                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        Projectile.NewProjectile(npc.GetSource_FromThis(), npc.Center, Vector2.Zero, ProjectileID.Sharknado, FargoSoulsUtil.ScaledProjectileDamage(npc.defDamage, 0.5f), 0f, Main.myPlayer, 15, 15);
                    }
                }

                if (!Main.dedServ && Main.rand.NextBool(1000))
                {
                    SoundEngine.PlaySound(new SoundStyle("FargowiltasSouls/Sounds/a"), npc.Center);

                    CombatText.NewText(npc.Hitbox, Color.Blue, "a", true);

                    for (int i = 0; i < 100; i++)
                    {
                        int d = Dust.NewDust(npc.position, npc.width, npc.height, Main.rand.Next(new int[]
                        {
                            DustID.Confetti,
                            DustID.Confetti_Blue,
                            DustID.Confetti_Green,
                            DustID.Confetti_Pink,
                            DustID.Confetti_Yellow
                        }), 0f, 0f, 0, default(Color), 2.5f);
                        Main.dust[d].noGravity = Main.rand.NextBool(3);
                        Main.dust[d].velocity *= 6f;
                    }
                }
            }
        }
Esempio n. 21
0
        public override void AI()
        {
            bool     flag64    = projectile.type == mod.ProjectileType("SoccMinion");
            Player   player    = Main.player[projectile.owner];
            AAPlayer modPlayer = player.GetModPlayer <AAPlayer>();

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

            float num633 = 700f;
            float num634 = 800f;

            for (int num638 = 0; num638 < 1000; num638++)
            {
                bool flag23 = Main.projectile[num638].type == mod.ProjectileType("SoccMinion");
                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 - 0.02f;
                    }
                    else
                    {
                        projectile.velocity.X = projectile.velocity.X + 0.02f;
                    }
                    if (projectile.position.Y < Main.projectile[num638].position.Y)
                    {
                        projectile.velocity.Y = projectile.velocity.Y - 0.02f;
                    }
                    else
                    {
                        projectile.velocity.Y = projectile.velocity.Y + 0.02f;
                    }
                }
            }
            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 = 1200f;
            }
            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 < 150f && 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 (Math.Abs(projectile.velocity.X) > 0.2)
            {
                projectile.spriteDirection = projectile.direction;
            }

            if (projectile.ai[1] > 0f)
            {
                projectile.ai[1] += Main.rand.Next(1, 4);
            }
            if (projectile.ai[1] > 20)
            {
                projectile.ai[1]     = 0f;
                projectile.netUpdate = true;
            }
            if (projectile.ai[0] == 0f)
            {
                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 *= 9f;
                        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].extraUpdates = 1;
                        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;
                    }
                }
            }


            if (!AttackFrame)
            {
                if (projectile.frameCounter++ >= 10)
                {
                    projectile.frameCounter = 0;
                    if (++projectile.frame > 5)
                    {
                        projectile.frame = 0;
                    }
                }
            }
            else
            {
                if (projectile.frameCounter++ >= 5)
                {
                    projectile.frameCounter = 0;
                    if (projectile.frame < 6 || projectile.frame > 10)
                    {
                        projectile.frame = 6;
                    }
                }
            }
        }
Esempio n. 22
0
        public override void AI()
        {
            if (++projectile.frameCounter >= 3)
            {
                projectile.frame++;
                projectile.frameCounter = 0;
                if (projectile.frame >= 4)
                {
                    projectile.frame = 0;
                }
            }

            projectile.velocity *= 0.5f;

            if (projectile.ai[1] == 0f)
            {
                projectile.ai[1] = 1f;
                Main.PlaySound(SoundID.Item34, projectile.position);
            }

            Lighting.AddLight(projectile.Center, 1.1f, 0.9f, 0.4f);

            for (int i = 0; i < 1000; i++)
            {
                if (Main.projectile[i].Hitbox.Intersects(projectile.Hitbox))
                {
                    if (combineCount < combineCap)
                    {
                        projectile.width    *= 2;
                        projectile.height   *= 2;
                        projectile.scale    += 2f;
                        projectile.damage   += 10;
                        combineCount        += 1;
                        projectile.timeLeft += 25;
                    }
                }
            }
            if (projectile.timeLeft == 1)
            {
                for (int i = 0; i < 1000; i++)
                {
                    NPC target = Main.npc[i];


                    float distanceX = target.position.X - projectile.Center.X;
                    float distanceY = target.position.Y - projectile.Center.Y;
                    float distance  = (float)System.Math.Sqrt((double)(distanceX * distanceX + distanceY * distanceY));
                    float growthVar = 0f;
                    float rotation  = MathHelper.ToRadians(25);


                    if (!target.friendly && target.active && target.type != 488 && !target.dontTakeDamage && Collision.CanHitLine(projectile.Center, 1, 1, target.Center, 1, 1))
                    {
                        if (combineCount == 1)
                        {
                            if (!target.friendly && target.active && target.type != 488 && !target.dontTakeDamage && Collision.CanHitLine(projectile.Center, 1, 1, target.Center, 1, 1))
                            {
                                distance   = 3f / distance;
                                distanceX *= distance * 3;
                                distanceY *= distance * 3;

                                Vector2 perturbedSpeed = new Vector2(distanceX, distanceY).RotatedBy(MathHelper.Lerp(-rotation, rotation, i / (growthVar - 1))) * .2f;
                                Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, perturbedSpeed.X, perturbedSpeed.Y, mod.ProjectileType("FriendlyLightning"), (int)(projectile.damage * 1f), 0, projectile.owner, 0f, 0f);
                            }
                        }

                        if (combineCount == 2)
                        {
                            growthVar = 2f;

                            distance   = 3f / distance;
                            distanceX *= distance * 3;
                            distanceY *= distance * 3;

                            for (int k = 0; k < growthVar; k++)
                            {
                                Vector2 perturbedSpeed = new Vector2(distanceX, distanceY).RotatedBy(MathHelper.Lerp(-rotation, rotation, i / (growthVar - 1))) * .2f;
                                Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, perturbedSpeed.X, perturbedSpeed.Y, mod.ProjectileType("FriendlyLightning"), (int)(projectile.damage * 1f), 0, projectile.owner, 0f, 0f);
                            }
                        }

                        if (combineCount == 3)
                        {
                            growthVar = 3f;

                            distance   = 3f / distance;
                            distanceX *= distance * 3;
                            distanceY *= distance * 3;

                            for (int k = 0; k < growthVar; k++)
                            {
                                Vector2 perturbedSpeed = new Vector2(distanceX, distanceY).RotatedBy(MathHelper.Lerp(-rotation, rotation, i / (growthVar - 1))) * .2f;
                                Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, perturbedSpeed.X, perturbedSpeed.Y, mod.ProjectileType("FriendlyLightning"), (int)(projectile.damage * 1f), 0, projectile.owner, 0f, 0f);
                            }
                        }

                        if (combineCount == 4)
                        {
                            growthVar = 4f;

                            distance   = 3f / distance;
                            distanceX *= distance * 3;
                            distanceY *= distance * 3;

                            for (int k = 0; k < growthVar; k++)
                            {
                                Vector2 perturbedSpeed = new Vector2(distanceX, distanceY).RotatedBy(MathHelper.Lerp(-rotation, rotation, i / (growthVar - 1))) * .2f;
                                Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, perturbedSpeed.X, perturbedSpeed.Y, mod.ProjectileType("FriendlyLightning"), (int)(projectile.damage * 1f), 0, projectile.owner, 0f, 0f);
                            }
                        }

                        if (combineCount == 5)
                        {
                            growthVar  = 5f;
                            distance   = 3f / distance;
                            distanceX *= distance * 3;
                            distanceY *= distance * 3;

                            for (int k = 0; k < growthVar; k++)
                            {
                                Vector2 perturbedSpeed = new Vector2(distanceX, distanceY).RotatedBy(MathHelper.Lerp(-rotation, rotation, i / (growthVar - 1))) * .2f;
                                Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, perturbedSpeed.X, perturbedSpeed.Y, mod.ProjectileType("FriendlyLightning"), (int)(projectile.damage * 1f), 0, projectile.owner, 0f, 0f);
                            }
                        }
                    }
                }
            }
        }
Esempio n. 23
0
        private int HomeOnTarget()
        {
            const bool  homingCanAimAtWetEnemies   = true;
            const float homingMaximumRangeInPixels = 1000;

            int selectedTarget = -1;

            for (int i = 0; i < Main.maxNPCs; i++)
            {
                NPC n = Main.npc[i];
                if (n.CanBeChasedBy(projectile) && (!n.wet || homingCanAimAtWetEnemies) && Collision.CanHitLine(projectile.Center, 0, 0, n.Center, 0, 0))
                {
                    float distance = projectile.Distance(n.Center);
                    if (distance <= homingMaximumRangeInPixels &&
                        (
                            selectedTarget == -1 ||                                          //there is no selected target
                            projectile.Distance(Main.npc[selectedTarget].Center) > distance) //or we are closer to this target than the already selected target
                        )
                    {
                        selectedTarget = i;
                    }
                }
            }

            return(selectedTarget);
        }
Esempio n. 24
0
        public override void Behavior()
        {
            Player player  = Main.player[projectile.owner];
            float  spacing = (float)projectile.width * spacingMult;

            for (int k = 0; k < 1000; k++)
            {
                Projectile otherProj = Main.projectile[k];
                if (k != projectile.whoAmI && otherProj.active && otherProj.owner == projectile.owner && otherProj.Name.Contains("Elemental Spirit") && System.Math.Abs(projectile.position.X - otherProj.position.X) + System.Math.Abs(projectile.position.Y - otherProj.position.Y) < spacing)
                {
                    if (projectile.position.X < Main.projectile[k].position.X)
                    {
                        projectile.velocity.X -= idleAccel;
                    }
                    else
                    {
                        projectile.velocity.X += idleAccel;
                    }
                    if (projectile.position.Y < Main.projectile[k].position.Y)
                    {
                        projectile.velocity.Y -= idleAccel;
                    }
                    else
                    {
                        projectile.velocity.Y += idleAccel;
                    }
                }
            }
            Vector2 targetPos  = projectile.position;
            float   targetDist = viewDist;
            bool    target     = false;

            projectile.tileCollide = true;
            for (int k = 0; k < 200; k++)
            {
                NPC npc = Main.npc[k];
                if (npc.CanBeChasedBy(this, false))
                {
                    float distance = Vector2.Distance(npc.Center, projectile.Center);
                    if ((distance < targetDist || !target) && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, npc.position, npc.width, npc.height))
                    {
                        targetDist = distance;
                        targetPos  = npc.Center;
                        target     = true;
                    }
                }
            }
            if (Vector2.Distance(player.Center, projectile.Center) > (target ? 1000f : 500f))
            {
                projectile.ai[0]     = 1f;
                projectile.netUpdate = true;
            }
            if (projectile.ai[0] == 1f)
            {
                projectile.tileCollide = false;
            }
            if (target && projectile.ai[0] == 0f)
            {
                Vector2 direction = targetPos - projectile.Center;
                if (direction.Length() > chaseDist)
                {
                    direction.Normalize();
                    projectile.velocity = (projectile.velocity * inertia + direction * chaseAccel) / (inertia + 1);
                }
                else
                {
                    projectile.velocity *= (float)Math.Pow(0.97, 40.0 / inertia);
                }
            }
            else
            {
                if (!Collision.CanHitLine(projectile.Center, 1, 1, player.Center, 1, 1))
                {
                    projectile.ai[0] = 1f;
                }
                float speed = 6f;
                if (projectile.ai[0] == 1f)
                {
                    speed = 15f;
                }
                Vector2 center    = projectile.Center;
                Vector2 direction = player.Center - center;
                projectile.ai[1]     = 3600f;
                projectile.netUpdate = true;
                int num = 1;
                for (int k = 0; k < projectile.whoAmI; k++)
                {
                    if (Main.projectile[k].active && Main.projectile[k].owner == projectile.owner && Main.projectile[k].type == projectile.type)
                    {
                        num++;
                    }
                }
                direction.X -= (float)((10 + num * 40) * player.direction);
                direction.Y -= 70f;
                float distanceTo = direction.Length();
                if (distanceTo > 200f && speed < 9f)
                {
                    speed = 9f;
                }
                if (distanceTo < 100f && projectile.ai[0] == 1f && !Collision.SolidCollision(projectile.position, projectile.width, projectile.height))
                {
                    projectile.ai[0]     = 0f;
                    projectile.netUpdate = true;
                }
                if (distanceTo > 2000f)
                {
                    projectile.Center = player.Center;
                }
                if (distanceTo > 48f)
                {
                    direction.Normalize();
                    direction *= speed;
                    float temp = inertia / 2f;
                    projectile.velocity = (projectile.velocity * temp + direction) / (temp + 1);
                }
                else
                {
                    projectile.direction = Main.player[projectile.owner].direction;
                    projectile.velocity *= (float)Math.Pow(0.9, 40.0 / inertia);
                }
            }
            projectile.rotation = projectile.velocity.X * 0.05f;
            SelectFrame();
            CreateDust();
            if (projectile.velocity.X > 0f)
            {
                projectile.spriteDirection = (projectile.direction = -1);
            }
            else if (projectile.velocity.X < 0f)
            {
                projectile.spriteDirection = (projectile.direction = 1);
            }
            if (projectile.ai[1] > 0f)
            {
                projectile.ai[1] += 1f;
            }
            if (projectile.ai[1] > shootCool)
            {
                projectile.ai[1]     = 0f;
                projectile.netUpdate = true;
            }
            if (projectile.ai[0] == 0f)
            {
                if (target)
                {
                    if ((targetPos - projectile.Center).X > 0f)
                    {
                        projectile.spriteDirection = (projectile.direction = -1);
                    }
                    else if ((targetPos - projectile.Center).X < 0f)
                    {
                        projectile.spriteDirection = (projectile.direction = 1);
                    }
                    if (projectile.ai[1] == 0f)
                    {
                        projectile.ai[1] = 1f;
                        if (Main.myPlayer == projectile.owner)
                        {
                            Vector2 shootVel = targetPos - projectile.Center;
                            if (shootVel == Vector2.Zero)
                            {
                                shootVel = new Vector2(0f, 1f);
                            }
                            shootVel.Normalize();
                            shootVel *= shootSpeed;
                            int proj = Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, shootVel.X, shootVel.Y, shoot, projectile.damage, projectile.knockBack, Main.myPlayer, 0f, 0f);
                            Main.projectile[proj].timeLeft  = 300;
                            Main.projectile[proj].netUpdate = true;
                            projectile.netUpdate            = true;
                        }
                    }
                }
            }
        }
Esempio n. 25
0
        public override void AI()
        {
            bool     flag64    = projectile.type == mod.ProjectileType("CrimeraMinion");
            Player   player    = Main.player[projectile.owner];
            AAPlayer modPlayer = player.GetModPlayer <AAPlayer>();

            player.AddBuff(mod.BuffType("CrimeraMinion"), 3600);
            if (flag64)
            {
                if (player.dead)
                {
                    modPlayer.CrimeraMinion = false;
                }
                if (modPlayer.CrimeraMinion)
                {
                    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("CrimeraMinion");
                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;
                projectile.rotation     = projectile.velocity.ToRotation() + 3.14159274f;
                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;
            }
            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 = 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 = 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.ToRotation() + 3.14159274f;
            if (projectile.ai[1] > 0f)
            {
                projectile.ai[1] += Main.rand.Next(1, 4);
            }
            if (projectile.ai[1] > 40f)
            {
                projectile.ai[1]     = 0f;
                projectile.netUpdate = true;
            }
            if (projectile.ai[0] == 0f)
            {
                if (projectile.ai[1] == 0f && flag25 && num633 < 500f)
                {
                    projectile.ai[1] += 1f;
                    if (Main.myPlayer == projectile.owner)
                    {
                        projectile.ai[0] = 2f;
                        Vector2 value20 = vector46 - projectile.Center;
                        value20.Normalize();
                        projectile.velocity  = value20 * 8f;
                        projectile.netUpdate = true;
                        return;
                    }
                }
            }
        }
Esempio n. 26
0
        public override void AI()
        {
            npc.reflectingProjectiles = false;
            npc.takenDamageMultiplier = 1f;
            int   num27        = 6;
            int   num28        = 10;
            float scaleFactor3 = 16f;

            if (npc.ai[2] > 0f)
            {
                npc.ai[2] -= 1f;
            }
            if (npc.ai[2] == 0f)
            {
                if (((Main.player[npc.target].Center.X < npc.Center.X && npc.direction < 0) || (Main.player[npc.target].Center.X > npc.Center.X && npc.direction > 0)) && Collision.CanHit(npc.Center, 1, 1, Main.player[npc.target].Center, 1, 1))
                {
                    npc.ai[2]     = -1f;
                    npc.netUpdate = true;
                    npc.TargetClosest(true);
                }
            }
            else
            {
                if (npc.ai[2] < 0f && npc.ai[2] > -num27)
                {
                    npc.ai[2]     -= 1f;
                    npc.velocity.X = npc.velocity.X * 0.9f;
                    return;
                }
                if (npc.ai[2] == -num27)
                {
                    npc.ai[2] -= 1f;
                    npc.TargetClosest(true);
                    Vector2 vec = npc.DirectionTo(Main.player[npc.target].Top + new Vector2(0f, -30f));
                    if (vec.HasNaNs())
                    {
                        vec = Vector2.Normalize(new Vector2(npc.spriteDirection, -1f));
                    }
                    npc.velocity  = vec * scaleFactor3;
                    npc.netUpdate = true;
                    return;
                }
                if (npc.ai[2] < -num27)
                {
                    npc.ai[2] -= 1f;
                    if (npc.velocity.Y == 0f)
                    {
                        npc.ai[2] = 60f;
                    }
                    else if (npc.ai[2] < -(float)num27 - num28)
                    {
                        npc.velocity.Y = npc.velocity.Y + 0.15f;
                        if (npc.velocity.Y > 24f)
                        {
                            npc.velocity.Y = 24f;
                        }
                    }
                    npc.reflectingProjectiles = true;
                    npc.takenDamageMultiplier = 3f;
                    if (npc.justHit)
                    {
                        npc.ai[2]     = 60f;
                        npc.netUpdate = true;
                    }
                    return;
                }
            }
            int num36 = 60;

            bool flag5 = false;
            bool flag6 = true;
            bool flag7 = false;
            bool flag8 = true;

            if (npc.ai[2] > 0f)
            {
                flag8 = false;
            }
            if (!flag7 && flag8)
            {
                if (npc.velocity.Y == 0f && ((npc.velocity.X > 0f && npc.direction < 0) || (npc.velocity.X < 0f && npc.direction > 0)))
                {
                    flag5 = true;
                }
                if (npc.position.X == npc.oldPosition.X || npc.ai[3] >= num36 || flag5)
                {
                    npc.ai[3] += 1f;
                }
                else if (Math.Abs(npc.velocity.X) > 0.9 && npc.ai[3] > 0f)
                {
                    npc.ai[3] -= 1f;
                }
                if (npc.ai[3] > num36 * 10)
                {
                    npc.ai[3] = 0f;
                }
                if (npc.justHit)
                {
                    npc.ai[3] = 0f;
                }
                if (npc.ai[3] == num36)
                {
                    npc.netUpdate = true;
                }
            }

            if (npc.ai[3] < num36)
            {
                npc.TargetClosest(true);
            }
            float num75        = 5f;
            float num76        = 0.25f;
            float scaleFactor5 = 0.7f;

            num75        = 6f;
            num76        = 0.15f;
            scaleFactor5 = 0.85f;
            if (npc.velocity.X < -num75 || npc.velocity.X > num75)
            {
                if (npc.velocity.Y == 0f)
                {
                    npc.velocity *= scaleFactor5;
                }
            }
            else if (npc.velocity.X < num75 && npc.direction == 1)
            {
                npc.velocity.X = npc.velocity.X + num76;
                if (npc.velocity.X > num75)
                {
                    npc.velocity.X = num75;
                }
            }
            else if (npc.velocity.X > -num75 && npc.direction == -1)
            {
                npc.velocity.X = npc.velocity.X - num76;
                if (npc.velocity.X < -num75)
                {
                    npc.velocity.X = -num75;
                }
            }

            if (Main.player[npc.target].Center.Y + 100f < npc.position.Y && Collision.CanHit(npc.position, npc.width, npc.height, Main.player[npc.target].position, Main.player[npc.target].width, Main.player[npc.target].height))
            {
                {
                    npc.velocity.Y = -5f;
                    npc.ai[2]      = 1f;
                }
                if (Main.netMode != 1)
                {
                    npc.localAI[2] += 1f;
                    if (npc.localAI[2] >= 360 + Main.rand.Next(360) && npc.Distance(Main.player[npc.target].Center) < 400f && Math.Abs(npc.DirectionTo(Main.player[npc.target].Center).Y) < 0.5f && Collision.CanHitLine(npc.Center, 0, 0, Main.player[npc.target].Center, 0, 0))
                    {
                        npc.localAI[2] = 0f;
                        Vector2 vector13 = npc.Center + new Vector2(npc.direction * 30, 2f);
                        Vector2 vector14 = npc.DirectionTo(Main.player[npc.target].Center) * 7f;
                        if (vector14.HasNaNs())
                        {
                            vector14 = new Vector2(npc.direction * 8, 0f);
                        }
                        int num85 = Main.expertMode ? 50 : 75;
                        for (int num86 = 0; num86 < 4; num86++)
                        {
                            Vector2 vector15 = vector14 + Utils.RandomVector2(Main.rand, -0.8f, 0.8f);
                            Projectile.NewProjectile(vector13.X, vector13.Y, vector15.X, vector15.Y, 577, num85, 1f, Main.myPlayer, 0f, 0f);
                        }
                    }
                }
            }

            bool flag23 = false;

            if (npc.velocity.Y == 0f)
            {
                int num167 = (int)(npc.position.Y + npc.height + 7f) / 16;
                int num168 = (int)npc.position.X / 16;
                int num169 = (int)(npc.position.X + npc.width) / 16;
                for (int num170 = num168; num170 <= num169; num170++)
                {
                    if (Main.tile[num170, num167] == null)
                    {
                        return;
                    }
                    if (Main.tile[num170, num167].nactive() && Main.tileSolid[Main.tile[num170, num167].type])
                    {
                        flag23 = true;
                        break;
                    }
                }
            }

            if (npc.velocity.Y >= 0f)
            {
                int num171 = 0;
                if (npc.velocity.X < 0f)
                {
                    num171 = -1;
                }
                if (npc.velocity.X > 0f)
                {
                    num171 = 1;
                }
                Vector2 position2 = npc.position;
                position2.X += npc.velocity.X;
                int num172 = (int)((position2.X + npc.width / 2 + (npc.width / 2 + 1) * num171) / 16f);
                int num173 = (int)((position2.Y + npc.height - 1f) / 16f);
                if (Main.tile[num172, num173] == null)
                {
                    Main.tile[num172, num173] = new Tile();
                }
                if (Main.tile[num172, num173 - 1] == null)
                {
                    Main.tile[num172, num173 - 1] = new Tile();
                }
                if (Main.tile[num172, num173 - 2] == null)
                {
                    Main.tile[num172, num173 - 2] = new Tile();
                }
                if (Main.tile[num172, num173 - 3] == null)
                {
                    Main.tile[num172, num173 - 3] = new Tile();
                }
                if (Main.tile[num172, num173 + 1] == null)
                {
                    Main.tile[num172, num173 + 1] = new Tile();
                }
                if (Main.tile[num172 - num171, num173 - 3] == null)
                {
                    Main.tile[num172 - num171, num173 - 3] = new Tile();
                }
                if (num172 * 16 < position2.X + npc.width && num172 * 16 + 16 > position2.X && ((Main.tile[num172, num173].nactive() && !Main.tile[num172, num173].topSlope() && !Main.tile[num172, num173 - 1].topSlope() && Main.tileSolid[Main.tile[num172, num173].type] && !Main.tileSolidTop[Main.tile[num172, num173].type]) || (Main.tile[num172, num173 - 1].halfBrick() && Main.tile[num172, num173 - 1].nactive())) && (!Main.tile[num172, num173 - 1].nactive() || !Main.tileSolid[Main.tile[num172, num173 - 1].type] || Main.tileSolidTop[Main.tile[num172, num173 - 1].type] || (Main.tile[num172, num173 - 1].halfBrick() && (!Main.tile[num172, num173 - 4].nactive() || !Main.tileSolid[Main.tile[num172, num173 - 4].type] || Main.tileSolidTop[Main.tile[num172, num173 - 4].type]))) && (!Main.tile[num172, num173 - 2].nactive() || !Main.tileSolid[Main.tile[num172, num173 - 2].type] || Main.tileSolidTop[Main.tile[num172, num173 - 2].type]) && (!Main.tile[num172, num173 - 3].nactive() || !Main.tileSolid[Main.tile[num172, num173 - 3].type] || Main.tileSolidTop[Main.tile[num172, num173 - 3].type]) && (!Main.tile[num172 - num171, num173 - 3].nactive() || !Main.tileSolid[Main.tile[num172 - num171, num173 - 3].type]))
                {
                    float num174 = num173 * 16;
                    if (Main.tile[num172, num173].halfBrick())
                    {
                        num174 += 8f;
                    }
                    if (Main.tile[num172, num173 - 1].halfBrick())
                    {
                        num174 -= 8f;
                    }
                    if (num174 < position2.Y + npc.height)
                    {
                        float num175 = position2.Y + npc.height - num174;
                        float num176 = 16.1f;
                        if (num175 <= num176)
                        {
                            npc.gfxOffY   += npc.position.Y + npc.height - num174;
                            npc.position.Y = num174 - npc.height;
                            if (num175 < 9f)
                            {
                                npc.stepSpeed = 1f;
                            }
                            else
                            {
                                npc.stepSpeed = 2f;
                            }
                        }
                    }
                }
            }
            if (flag23)
            {
                int num177 = (int)((npc.position.X + npc.width / 2 + 15 * npc.direction) / 16f);
                int num178 = (int)((npc.position.Y + npc.height - 15f) / 16f);

                if (Main.tile[num177, num178] == null)
                {
                    Main.tile[num177, num178] = new Tile();
                }
                if (Main.tile[num177, num178 - 1] == null)
                {
                    Main.tile[num177, num178 - 1] = new Tile();
                }
                if (Main.tile[num177, num178 - 2] == null)
                {
                    Main.tile[num177, num178 - 2] = new Tile();
                }
                if (Main.tile[num177, num178 - 3] == null)
                {
                    Main.tile[num177, num178 - 3] = new Tile();
                }
                if (Main.tile[num177, num178 + 1] == null)
                {
                    Main.tile[num177, num178 + 1] = new Tile();
                }
                if (Main.tile[num177 + npc.direction, num178 - 1] == null)
                {
                    Main.tile[num177 + npc.direction, num178 - 1] = new Tile();
                }
                if (Main.tile[num177 + npc.direction, num178 + 1] == null)
                {
                    Main.tile[num177 + npc.direction, num178 + 1] = new Tile();
                }
                if (Main.tile[num177 - npc.direction, num178 + 1] == null)
                {
                    Main.tile[num177 - npc.direction, num178 + 1] = new Tile();
                }
                Main.tile[num177, num178 + 1].halfBrick();
            }
            else if (flag6)
            {
                npc.ai[1] = 0f;
                npc.ai[2] = 0f;
            }
        }
Esempio n. 27
0
        public override void AI()
        {
            if (++projectile.frameCounter >= 5)
            {
                projectile.frameCounter = 0;
                if (++projectile.frame >= 4)
                {
                    projectile.frame = 0;
                }
            }
            projectile.timeLeft = 10;

            Player player = Main.player[projectile.owner];
            if (!player.HasBuff(ModContent.BuffType<Spawned>()))
            {
                projectile.timeLeft = 0;
            }
            if (player.dead || !player.active)
            {
                player.ClearBuff(ModContent.BuffType<Spawned>());
            }
            if (player.HasBuff(ModContent.BuffType<Spawned>()))
            {
                projectile.timeLeft = 2;
            }
            Vector2 idlePosition = player.Center;
            idlePosition.Y -= 48f;
            float minionPositionOffsetX = (10 + projectile.minionPos * 40) * -player.direction;
            idlePosition.X += minionPositionOffsetX;
            Vector2 vectorToIdlePosition = idlePosition - projectile.Center;
            float distanceToIdlePosition = vectorToIdlePosition.Length();
            // Starting search distance
            float distanceFromTarget = 700f;
            Vector2 targetCenter = projectile.position;
            bool foundTarget = false;
            if (player.HasMinionAttackTargetNPC)
            {
                NPC npc = Main.npc[player.MinionAttackTargetNPC];
                float between = Vector2.Distance(npc.Center, projectile.Center);
                // Reasonable distance away so it doesn't target across multiple screens
                if (between < 2000f)
                {
                    distanceFromTarget = between;
                    targetCenter = npc.Center;
                    foundTarget = true;
                    if (timer > 50)
                    {
                        Vector2 noscope = npc.Center - projectile.Center;
                        noscope.Normalize();
                        Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, noscope.X * 10f, noscope.Y * 10f, ModContent.ProjectileType<NightmareProjectile>(), projectile.damage, 5, Main.myPlayer);
                        timer = 0;
                    }
                }
            }
            if (timer < 500)
            {
                timer++;
            }
            
            if (!foundTarget)
            {
                for (int i = 0; i < Main.maxNPCs; i++)
                {
                    
                    NPC npc = Main.npc[i];
                    if (npc.CanBeChasedBy())
                    {
                        float between = Vector2.Distance(npc.Center, projectile.Center);
                        bool closest = Vector2.Distance(projectile.Center, npc.Center) > between;
                        bool inRange = between < distanceFromTarget;
                        bool lineOfSight = Collision.CanHitLine(projectile.position, projectile.width, projectile.height, npc.position, npc.width, npc.height);
                        if (((closest && inRange) || !foundTarget) && lineOfSight)
                        {
                            
                            if (timer > 50)
                            {
                                Vector2 noscope = npc.Center - projectile.Center;
                                noscope.Normalize();
                                Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, noscope.X * 10f, noscope.Y * 10f, ModContent.ProjectileType<NightmareProjectile>(), projectile.damage, 5, Main.myPlayer);
                                timer = 0;
                            }
                        }
                    }
                }
            }
            float speed = 8f;
            float inertia = 60f;
            Vector2 direction = idlePosition - projectile.Center;
            direction.Normalize();
            direction *= speed;
            projectile.velocity = (projectile.velocity * (inertia - 1) + direction) / inertia;
        }
Esempio n. 28
0
        public override void AI()
        {
            projectile.ai[1]++;
            if (projectile.ai[1] % 10 == 0)
            {
                for (int i = 0; i < 200; i++)
                {
                    NPC target = Main.npc[i];
                    if (!target.friendly && target.type != 488 && !target.dontTakeDamage)
                    {
                        float shootToX = target.position.X + (float)target.width * 0.5f - projectile.Center.X;
                        float shootToY = target.position.Y - projectile.Center.Y;
                        float distance = (float)System.Math.Sqrt((double)(shootToX * shootToX + shootToY * shootToY));

                        //If the distance between the live targeted npc and the projectile is less than 480 pixels
                        if (distance < 200f && target.CanBeChasedBy(this, false) && !target.friendly && target.active && distance > 50f && Collision.CanHitLine(projectile.Center, 1, 1, target.Center, 1, 1))
                        {
                            //Divide the factor, 3f, which is the desired velocity
                            distance = 3f / distance;

                            //Multiply the distance by a multiplier if you wish the projectile to have go faster
                            shootToX *= distance * 5;
                            shootToY *= distance * 5;

                            //Set the velocities to the shoot values
                            projectile.velocity.X = shootToX;
                            projectile.velocity.Y = shootToY;
                        }
                    }
                }
            }
        }
Esempio n. 29
0
        public override void AI()
        {
            Player player = Main.player[projectile.owner];

            #region Active check

            // This is the "active check", makes sure the minion is alive while the player is alive, and despawns if not
            if (player.dead || !player.active)
            {
                player.ClearBuff(BuffType <HallowedCross>());
            }
            if (player.HasBuff(BuffType <HallowedCross>()))
            {
                projectile.timeLeft = 2;
            }

            #endregion Active check

            #region General behavior

            Vector2 idlePosition = player.Center;
            idlePosition.Y -= 48f;             // Go up 48 coordinates (three tiles from the center of the player)

            // If your minion doesn't aimlessly move around when it's idle, you need to "put" it into the line of other summoned minions
            // The index is projectile.minionPos
            float minionPositionOffsetX = (10 + projectile.minionPos * 40) * -player.direction;
            idlePosition.X += minionPositionOffsetX;             // Go behind the player

            // All of this code below this line is adapted from Spazmamini code (ID 388, aiStyle 66)

            // Teleport to player if distance is too big
            Vector2 vectorToIdlePosition   = idlePosition - projectile.Center;
            float   distanceToIdlePosition = vectorToIdlePosition.Length();
            if (Main.myPlayer == player.whoAmI && distanceToIdlePosition > 2000f)
            {
                // Whenever you deal with non-regular events that change the behavior or position drastically, make sure to only run the code on the owner of the projectile,
                // and then set netUpdate to true
                projectile.position  = idlePosition;
                projectile.velocity *= 0.1f;
                projectile.netUpdate = true;
            }

            // If your minion is flying, you want to do this independently of any conditions
            float overlapVelocity = 0.04f;
            for (int i = 0; i < Main.maxProjectiles; i++)
            {
                // Fix overlap with other minions
                Projectile other = Main.projectile[i];
                if (i != projectile.whoAmI && other.active && other.owner == projectile.owner && Math.Abs(projectile.position.X - other.position.X) + Math.Abs(projectile.position.Y - other.position.Y) < projectile.width)
                {
                    if (projectile.position.X < other.position.X)
                    {
                        projectile.velocity.X -= overlapVelocity;
                    }
                    else
                    {
                        projectile.velocity.X += overlapVelocity;
                    }

                    if (projectile.position.Y < other.position.Y)
                    {
                        projectile.velocity.Y -= overlapVelocity;
                    }
                    else
                    {
                        projectile.velocity.Y += overlapVelocity;
                    }
                }
            }

            #endregion General behavior

            #region Find target

            // Starting search distance
            float   distanceFromTarget = 700f;
            Vector2 targetCenter       = projectile.position;
            bool    foundTarget        = false;

            // This code is required if your minion weapon has the targeting feature
            if (player.HasMinionAttackTargetNPC)
            {
                NPC   npc     = Main.npc[player.MinionAttackTargetNPC];
                float between = Vector2.Distance(npc.Center, projectile.Center);
                // Reasonable distance away so it doesn't target across multiple screens
                if (between < 2000f)
                {
                    distanceFromTarget = between;
                    targetCenter       = npc.Center;
                    foundTarget        = true;
                }
            }
            if (!foundTarget)
            {
                // This code is required either way, used for finding a target
                for (int i = 0; i < Main.maxNPCs; i++)
                {
                    NPC npc = Main.npc[i];
                    if (npc.CanBeChasedBy())
                    {
                        float between     = Vector2.Distance(npc.Center, projectile.Center);
                        bool  closest     = Vector2.Distance(projectile.Center, targetCenter) > between;
                        bool  inRange     = between < distanceFromTarget;
                        bool  lineOfSight = Collision.CanHitLine(projectile.position, projectile.width, projectile.height, npc.position, npc.width, npc.height);
                        // Additional check for this specific minion behavior, otherwise it will stop attacking once it dashed through an enemy while flying though tiles afterwards
                        // The number depends on various parameters seen in the movement code below. Test different ones out until it works alright
                        bool closeThroughWall = between < 100f;
                        if (((closest && inRange) || !foundTarget) && (lineOfSight || closeThroughWall))
                        {
                            distanceFromTarget = between;
                            targetCenter       = npc.Center;
                            foundTarget        = true;
                        }
                    }
                }
            }

            // friendly needs to be set to true so the minion can deal contact damage
            // friendly needs to be set to false so it doesn't damage things like target dummies while idling
            // Both things depend on if it has a target or not, so it's just one assignment here
            // You don't need this assignment if your minion is shooting things instead of dealing contact damage
            projectile.friendly = foundTarget;

            #endregion Find target

            #region Movement

            // Default movement parameters (here for attacking)
            float speed   = 12f;
            float inertia = 20f;

            if (foundTarget)
            {
                // Minion has a target: attack (here, fly towards the enemy)
                if (distanceFromTarget > 40f)
                {
                    // The immediate range around the target (so it doesn't latch onto it when close)
                    Vector2 direction = targetCenter - projectile.Center;
                    direction.Normalize();
                    direction          *= speed;
                    projectile.velocity = (projectile.velocity * (inertia - 1) + direction) / inertia;
                }
            }
            else
            {
                // Minion doesn't have a target: return to player and idle
                if (distanceToIdlePosition > 600f)
                {
                    // Speed up the minion if it's away from the player
                    speed   = 14f;
                    inertia = 60f;
                }
                else
                {
                    // Slow down the minion if closer to the player
                    speed   = 8f;
                    inertia = 80f;
                }
                if (distanceToIdlePosition > 20f)
                {
                    // The immediate range around the player (when it passively floats about)

                    // This is a simple movement formula using the two parameters and its desired direction to create a "homing" movement
                    vectorToIdlePosition.Normalize();
                    vectorToIdlePosition *= speed;
                    projectile.velocity   = (projectile.velocity * (inertia - 1) + vectorToIdlePosition) / inertia;
                }
                else if (projectile.velocity == Vector2.Zero)
                {
                    // If there is a case where it's not moving at all, give it a little "poke"
                    projectile.velocity.X = -0.15f;
                    projectile.velocity.Y = -0.05f;
                }
            }

            #endregion Movement

            #region Animation and visuals

            // So it will lean slightly towards the direction it's moving
            projectile.rotation = projectile.velocity.X * 0.05f;

            // This is a simple "loop through all frames from top to bottom" animation
            int frameSpeed = 5;
            projectile.frameCounter++;
            if (projectile.frameCounter >= frameSpeed)
            {
                projectile.frameCounter = 0;
                projectile.frame++;
                if (projectile.frame >= Main.projFrames[projectile.type])
                {
                    projectile.frame = 0;
                }
            }

            // Some visuals here
            Lighting.AddLight(projectile.Center, Color.White.ToVector3() * 0.78f);

            #endregion Animation and visuals
        }
        public override void AI()
        {
            SelectAnimation();
            UpdateStandInfo();
            if (shootCount > 0)
            {
                shootCount--;
            }
            Player   player    = Main.player[projectile.owner];
            MyPlayer modPlayer = player.GetModPlayer <MyPlayer>();

            Lighting.AddLight((int)(projectile.Center.X / 16f), (int)(projectile.Center.Y / 16f), 0.6f, 0.9f, 0.3f);
            Dust.NewDust(projectile.position + projectile.velocity, projectile.width, projectile.height, 35, projectile.velocity.X * -0.5f, projectile.velocity.Y * -0.5f);
            projectile.scale = ((50 - player.ownedProjectileCounts[mod.ProjectileType("EmeraldStringPoint2")]) * 2f) / 100f;

            Vector2 vector131 = player.Center;

            if (!attackFrames)
            {
                vector131.X -= (float)((15 + player.width / 2) * player.direction);
            }
            if (attackFrames)
            {
                vector131.X -= (float)((15 + player.width / 2) * (player.direction * -1));
            }
            vector131.Y         -= 5f;
            projectile.Center    = Vector2.Lerp(projectile.Center, vector131, 0.2f);
            projectile.velocity *= 0.8f;
            projectile.direction = (projectile.spriteDirection = player.direction);

            if (modPlayer.StandOut)
            {
                projectile.timeLeft = 2;
            }

            if (!modPlayer.StandAutoMode)
            {
                if (Main.mouseLeft && projectile.owner == Main.myPlayer)
                {
                    attackFrames         = true;
                    normalFrames         = false;
                    Main.mouseRight      = false;   //so that the player can't just stop time while punching
                    projectile.netUpdate = true;
                    if (shootCount <= 0)
                    {
                        Main.PlaySound(SoundID.Item21, projectile.position);
                        shootCount += newShootTime;
                        Vector2 shootVel = Main.MouseWorld - projectile.Center;
                        if (shootVel == Vector2.Zero)
                        {
                            shootVel = new Vector2(0f, 1f);
                        }
                        shootVel.Normalize();
                        shootVel *= shootSpeed;
                        float numberProjectiles = 4;                        //incraeses by 1 each tier
                        float rotation          = MathHelper.ToRadians(20); //increases by 3 every tier
                        float random            = Main.rand.NextFloat(-6f, 6f);
                        for (int i = 0; i < numberProjectiles; i++)
                        {
                            Vector2 perturbedSpeed = new Vector2(shootVel.X + random, shootVel.Y).RotatedBy(MathHelper.Lerp(-rotation, rotation, i / (numberProjectiles - 1))) * .2f;
                            int     proj           = Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, perturbedSpeed.X, perturbedSpeed.Y, mod.ProjectileType("Emerald"), newProjectileDamage, 2f, player.whoAmI);
                            Main.projectile[proj].netUpdate = true;
                        }
                        projectile.netUpdate = true;
                    }
                }
                else
                {
                    if (player.whoAmI == Main.myPlayer)
                    {
                        normalFrames = true;
                        attackFrames = false;
                    }
                }
                if (Main.mouseRight && shootCount <= 0 && !linkShot && projectile.scale >= 0.5f && projectile.owner == Main.myPlayer)
                {
                    Main.mouseLeft = false;
                    linkShot       = true;
                    Main.PlaySound(SoundID.Item21, projectile.position);
                    shootCount += 15;
                    Vector2 shootVel = Main.MouseWorld - projectile.Center;
                    if (shootVel == Vector2.Zero)
                    {
                        shootVel = new Vector2(0f, 1f);
                    }
                    shootVel.Normalize();
                    shootVel *= shootSpeed;
                    Vector2 perturbedSpeed = new Vector2(shootVel.X + Main.rand.NextFloat(-3f, 3f), shootVel.Y);
                    int     proj           = Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, perturbedSpeed.X, perturbedSpeed.Y, mod.ProjectileType("EmeraldStringPoint"), 0, 3f, player.whoAmI);
                    Main.projectile[proj].netUpdate = true;
                }
                if (Main.mouseRight && shootCount <= 0 && linkShot && projectile.scale >= 0.5f && projectile.owner == Main.myPlayer)
                {
                    Main.mouseLeft = false;
                    linkShot       = false;
                    Main.PlaySound(SoundID.Item21, projectile.position);
                    shootCount += 15;
                    Vector2 shootVel = Main.MouseWorld - projectile.Center;
                    if (shootVel == Vector2.Zero)
                    {
                        shootVel = new Vector2(0f, 1f);
                    }
                    shootVel.Normalize();
                    shootVel *= shootSpeed;
                    Vector2 perturbedSpeed = new Vector2(shootVel.X + Main.rand.NextFloat(-3f, 3f), shootVel.Y);
                    int     proj           = Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, perturbedSpeed.X, perturbedSpeed.Y, mod.ProjectileType("EmeraldStringPoint2"), 0, 3f, player.whoAmI);
                    Main.projectile[proj].netUpdate = true;
                }
            }
            if (modPlayer.StandAutoMode)
            {
                NPC     target     = null;
                Vector2 targetPos  = projectile.position;
                float   targetDist = 350f;
                if (target == null)
                {
                    for (int k = 0; k < 200; k++)       //the targeting system
                    {
                        NPC npc = Main.npc[k];
                        if (npc.CanBeChasedBy(this, false))
                        {
                            float distance = Vector2.Distance(npc.Center, player.Center);
                            if (distance < targetDist && Collision.CanHitLine(projectile.position, projectile.width, projectile.height, npc.position, npc.width, npc.height))
                            {
                                if (npc.boss)       //is gonna try to detect bosses over anything
                                {
                                    targetDist = distance;
                                    targetPos  = npc.Center;
                                    target     = npc;
                                }
                                else        //if it fails to detect a boss, it'll detect the next best thing
                                {
                                    targetDist = distance;
                                    targetPos  = npc.Center;
                                    target     = npc;
                                }
                            }
                        }
                    }
                }
                if (target != null)
                {
                    attackFrames = true;
                    normalFrames = false;
                    if ((targetPos - projectile.Center).X > 0f)
                    {
                        projectile.spriteDirection = projectile.direction = 1;
                    }
                    else if ((targetPos - projectile.Center).X < 0f)
                    {
                        projectile.spriteDirection = projectile.direction = -1;
                    }
                    if (shootCount <= 0)
                    {
                        shootCount += newShootTime;
                        Main.PlaySound(SoundID.Item21, projectile.position);
                        if (Main.myPlayer == projectile.owner)
                        {
                            Vector2 shootVel = targetPos - projectile.Center;
                            if (shootVel == Vector2.Zero)
                            {
                                shootVel = new Vector2(0f, 1f);
                            }
                            shootVel.Normalize();
                            shootVel *= shootSpeed;
                            float numberProjectiles = 4;
                            float rotation          = MathHelper.ToRadians(20);
                            float random            = Main.rand.NextFloat(-6f, 6f);
                            for (int i = 0; i < numberProjectiles; i++)
                            {
                                Vector2 perturbedSpeed = new Vector2(shootVel.X + random, shootVel.Y).RotatedBy(MathHelper.Lerp(-rotation, rotation, i / (numberProjectiles - 1))) * .2f;
                                int     proj           = Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, perturbedSpeed.X, perturbedSpeed.Y, mod.ProjectileType("Emerald"), (int)((projectileDamage * modPlayer.standDamageBoosts) * 0.9f), 2f, player.whoAmI);
                                Main.projectile[proj].netUpdate = true;
                            }
                            projectile.netUpdate = true;
                        }
                    }
                }
                else
                {
                    normalFrames = true;
                    attackFrames = false;
                }
            }
        }