public override float PowerScoreFor(AbilityAIDef abilityDef, Pawn pawn)
        {
            var baseScore = abilityDef.power;

            //Grab enemies \ allies
            var potentionalTargets = new List <Thing>(GrabTargets(abilityDef, pawn,
                                                                  CustomGrabTargetsPredicate(abilityDef, pawn), MaxTargetsToCheck));

            //Add self if can target allies.
            if (abilityDef.canTargetAlly)
            {
                potentionalTargets.Add(pawn);
            }

            //Get the highest intersecting target.
            var targetInfos = new List <LocalTargetInfo>();

            foreach (var target in potentionalTargets)
            {
                targetInfos.Add(new LocalTargetInfo(target));
            }

            var bestTarget = AbilityMaths.PickMostRadialIntersectingTarget(targetInfos, abilityDef.abilityRadius);

            //If we found no valid target, return negative power.
            if (bestTarget == LocalTargetInfo.Invalid)
            {
                return(-abilityDef.power);
            }

            //Calculate final score from best target.
            var finalScore = baseScore;

            foreach (var targetPawn in AbilityUtility.GetPawnsInsideRadius(bestTarget, pawn.Map,
                                                                           abilityDef.abilityRadius,
                                                                           predPawn => abilityDef.abilityRadiusNeedSight &&
                                                                           GenSight.LineOfSight(pawn.Position, predPawn.Position, pawn.Map, true) ||
                                                                           abilityDef.abilityRadiusNeedSight == false))
            {
                if (targetPawn.HostileTo(pawn) || targetPawn.AnimalOrWildMan()
                    ) //Hostile pawns or animals increase score.
                {
                    finalScore += abilityDef.power;
                }
                else //Friendly pawns decrease score.
                {
                    finalScore -= abilityDef.power;
                }
            }

            //Log.Message("AbilityWorker_AreaOfEffect, finalScore=" + finalScore);
            return(finalScore);
        }
Example #2
0
        /// <summary>
        /// Gets all Pawns inside the supplied radius. If any.
        /// </summary>
        /// <param name="center">Radius center.</param>
        /// <param name="map">Map to look in.</param>
        /// <param name="radius">The radius from the center.</param>
        /// <param name="targetPredicate">Optional predicate on each candidate.</param>
        /// <returns>Matching Pawns inside the Radius.</returns>
        public static IEnumerable <Pawn> GetPawnsInsideRadius(LocalTargetInfo center, Map map, float radius, Predicate <Pawn> targetPredicate)
        {
            //With no predicate, just grab everything.
            if (targetPredicate == null)
            {
                targetPredicate = thing => true;
            }

            foreach (Pawn pawn in map.listerThings.ThingsInGroup(ThingRequestGroup.Pawn))
            {
                if (AbilityMaths.CircleIntersectionTest(pawn.Position.x, pawn.Position.y, 1f, center.Cell.x, center.Cell.y, radius) && targetPredicate(pawn))
                {
                    yield return(pawn);
                }
            }
        }
Example #3
0
        public override LocalTargetInfo TargetAbilityFor(AbilityAIDef abilityDef, Pawn pawn)
        {
            //Grab enemies \ allies
            List <Thing> potentionalTargets = new List <Thing>(GrabTargets(abilityDef, pawn, CustomGrabTargetsPredicate(abilityDef, pawn), MaxTargetsToCheck));

            //Add self if can target allies.
            if (abilityDef.canTargetAlly)
            {
                potentionalTargets.Add(pawn);
            }

            //Get the highest intersecting target.
            List <LocalTargetInfo> targetInfos = new List <LocalTargetInfo>();

            foreach (Thing target in potentionalTargets)
            {
                targetInfos.Add(new LocalTargetInfo(target));
            }

            LocalTargetInfo bestTarget = AbilityMaths.PickMostRadialIntersectingTarget(targetInfos, abilityDef.abilityRadius);

            return(bestTarget);
        }