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); }
/// <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); } } }
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); }