Beispiel #1
0
 internal void SetupPathfinderMetas()
 {
     // these values don't like being initialized in Initialize() for some reason
     myTacticsPlayer = player.GetModPlayer <MinionTacticsPlayer>();
     pathfinderMetas = new PathfinderMetadata[MinionTacticsPlayer.TACTICS_GROUPS_COUNT];
     for (int i = 0; i < MinionTacticsPlayer.TACTICS_GROUPS_COUNT; i++)
     {
         pathfinderMetas[i] = new PathfinderMetadata(this, i);
     }
     for (int i = 0; i < Main.maxPlayers; i++)
     {
         Player p = Main.player[i];
         if (p.active)
         {
             MinionPathfindingPlayer pathPlayer = p.GetModPlayer <MinionPathfindingPlayer>();
         }
     }
 }
Beispiel #2
0
        public override void ModifyHitNPC(Projectile projectile, NPC target, ref int damage, ref float knockback, ref bool crit, ref int hitDirection)
        {
            // nerf all minion damage, even if they're not following the waypoint. Maybe a bit iffy
            if (!(projectile.minion ||
                  ProjectileID.Sets.MinionShot[projectile.type]))
            {
                return;
            }
            MinionPathfindingPlayer player = Main.player[projectile.owner].GetModPlayer <MinionPathfindingPlayer>();

            // no falloff if waypoint not placed
            if (player.pathfinderMetas.All(m => m.WaypointPosition == default))
            {
                return;
            }
            float maxDist         = player.WaypointPlacementRange;
            float damageReduction = player.WaypointDamageFalloff * Math.Min(maxDist, Vector2.Distance(projectile.Center, player.player.Center)) / maxDist;

            damage = (int)((1 - damageReduction) * damage);
        }
 internal BlockAwarePathfinder(MinionPathfindingPlayer player, int tacticsGroup)
 {
     modPlayer         = player;
     this.tacticsGroup = tacticsGroup;
 }
Beispiel #4
0
 internal PathfinderMetadata(MinionPathfindingPlayer player, int tacticsGroup)
 {
     pHelper = new BlockAwarePathfinder(player, tacticsGroup);
 }
Beispiel #5
0
        internal Vector2?NextPathfindingTarget()
        {
            // initialize late to avoid any lifecycle issues
            if (pathfinder is null)
            {
                Setup();
                DetachFromPath();
            }
            // need to re-check that we haven't been assigned to a different pathfinder
            SetPathfinder();
            if (pathfinder.searchFailed || pathfinder.waypointPosition == default)
            {
                DetachFromPath();
                return(null);
            }
            else if (pathfinder.InProgress())
            {
                DetachFromPath();
                // idle while the algorithm is still running
                return(pathfinder.playerPlacedWaypoint ? (Vector2?)Vector2.Zero : null);
            }
            // simple approach: Go towards a node until you get close enough, then go to the next node
            List <Vector2> path = pathfinder.orderedPath;

            if (nodeIndex > path.Count - 1 || nodeIndex < 0)
            {
                AttachToPath();
            }
            Vector2 currentNode = path.ElementAtOrDefault(nodeIndex);

            if (currentNode == default)
            {
                DetachFromPath();
                return(null);
            }
            if (Vector2.DistanceSquared(projectile.Center, currentNode) < nodeProximity * nodeProximity)
            {
                nodeIndex = Math.Min(path.Count - 1, nodeIndex + 1);
            }
            if (Math.Abs(projectile.velocity.Length()) < NO_PROGRESS_THRESHOLD)
            {
                noProgressFrames++;
            }
            if (noProgressFrames > 5)
            {
                isStuck = true;
            }
            // make sure the target exceeds a certain lenght threshold,
            // so the AI will speed up the minions
            Vector2 target = currentNode - projectile.position;

            // we're at the waypoint, rotate around it
            if (nodeIndex == path.Count - 1 && Vector2.Distance(projectile.Center, currentNode) <
                MinionPathfindingPlayer.WAYPOINT_PROXIMITY_THRESHOLD)
            {
                MinionPathfindingPlayer owner             = Main.player[projectile.owner].GetModPlayer <MinionPathfindingPlayer>();
                List <Projectile>       minionsAtWaypoint = owner.GetMinionsAtWaypoint(minion);
                if (minionsAtWaypoint.Count > 0)
                {
                    float animationAngle = MathHelper.TwoPi * (Main.GameUpdateCount % 120) / 120f;
                    animationAngle += MathHelper.TwoPi * minionsAtWaypoint.IndexOf(projectile) / (float)minionsAtWaypoint.Count;
                    target         += Math.Min(48, 24 + 2 * minionsAtWaypoint.Count) * animationAngle.ToRotationVector2();
                }
            }
            else if (target.Length() < 16)
            {
                // bump the minimum target distance up to 16, some idle AIs move too slowly otherwise
                target.SafeNormalize();
                target *= 16;
            }
            modifyPath?.Invoke(ref target);
            return(target);
        }