public virtual bool Valid(LocalTargetInfo target, bool throwMessages = false) { return(true); }
private void FindTargets() { bool flag = this.UseAbilityProps.AbilityTargetCategory == AbilityTargetCategory.TargetAoE; if (flag) { bool flag2 = this.UseAbilityProps.TargetAoEProperties == null; if (flag2) { Log.Error("Tried to Cast AoE-Ability without defining a target class"); } List <Thing> list = new List <Thing>(); IntVec3 aoeStartPosition = this.caster.PositionHeld; bool flag3 = !this.UseAbilityProps.TargetAoEProperties.startsFromCaster; if (flag3) { aoeStartPosition = this.currentTarget.Cell; } bool flag4 = !this.UseAbilityProps.TargetAoEProperties.friendlyFire; if (flag4) { list = (from x in this.caster.Map.listerThings.AllThings where x.Position.InHorDistOf(aoeStartPosition, (float)this.UseAbilityProps.TargetAoEProperties.range) && this.UseAbilityProps.TargetAoEProperties.targetClass.IsAssignableFrom(x.GetType()) && x.Faction != Faction.OfPlayer select x).ToList <Thing>(); } else { bool flag5 = this.UseAbilityProps.TargetAoEProperties.targetClass == typeof(Plant) || this.UseAbilityProps.TargetAoEProperties.targetClass == typeof(Building); if (flag5) { list = (from x in this.caster.Map.listerThings.AllThings where x.Position.InHorDistOf(aoeStartPosition, (float)this.UseAbilityProps.TargetAoEProperties.range) && this.UseAbilityProps.TargetAoEProperties.targetClass.IsAssignableFrom(x.GetType()) select x).ToList <Thing>(); foreach (Thing current in list) { LocalTargetInfo item = new LocalTargetInfo(current); this.TargetsAoE.Add(item); } return; } list.Clear(); list = (from x in this.caster.Map.listerThings.AllThings where x.Position.InHorDistOf(aoeStartPosition, (float)this.UseAbilityProps.TargetAoEProperties.range) && this.UseAbilityProps.TargetAoEProperties.targetClass.IsAssignableFrom(x.GetType()) && (x.HostileTo(Faction.OfPlayer) || this.UseAbilityProps.TargetAoEProperties.friendlyFire) select x).ToList <Thing>(); } int maxTargets = this.UseAbilityProps.abilityDef.MainVerb.TargetAoEProperties.maxTargets; List <Thing> list2 = new List <Thing>(list.InRandomOrder(null)); int num = 0; while (num < maxTargets && num < list2.Count <Thing>()) { TargetInfo targ = new TargetInfo(list2[num]); bool flag6 = this.UseAbilityProps.targetParams.CanTarget(targ); if (flag6) { this.TargetsAoE.Add(new LocalTargetInfo(list2[num])); } num++; } } else { this.TargetsAoE.Clear(); this.TargetsAoE.Add(this.currentTarget); } }
internal void Notify_AttackedTarget(LocalTargetInfo target) { lastAttackTargetTick = Find.TickManager.TicksGame; lastAttackedTarget = target; }
public void AddQueuedTarget(TargetIndex ind, LocalTargetInfo target) { this.GetTargetQueue(ind).Add(target); }
static public void OptimizePath(List <LocalTargetInfo> q, Thing Starter) { if (q.Count > 0) { int x = 0; int idx = 0; int n = 0; LocalTargetInfo out_of_all_things_they_didnt_add_a_simple_swap = null; if (Starter != null) { if (q[0].Cell == null) { n = int.MaxValue; } else { n = q[0].Cell.DistanceToSquared(Starter.Position); } for (int i = 1; i < q.Count(); i++) { if (q[i].Cell == null) { continue; } x = q[i].Cell.DistanceToSquared(Starter.Position); if (Math.Abs(x) < Math.Abs(n)) { n = x; idx = i; } } if (idx != 0) { out_of_all_things_they_didnt_add_a_simple_swap = q[idx]; q[idx] = q[0]; q[0] = out_of_all_things_they_didnt_add_a_simple_swap; } } for (int i = 0; i < q.Count() - 1; i++) { if (q[i + 1].Cell == null) { continue; } n = q[i].Cell.DistanceToSquared(q[i + 1].Cell); idx = i + 1; for (int c = i + 2; c < q.Count(); c++) { if (q[c].Cell == null) { continue; } x = q[i].Cell.DistanceToSquared(q[c].Cell); if (Math.Abs(x) < Math.Abs(n)) { n = x; idx = c; } } if (idx != i + 1) { out_of_all_things_they_didnt_add_a_simple_swap = q[idx]; q[idx] = q[i + 1]; q[i + 1] = out_of_all_things_they_didnt_add_a_simple_swap; } } } }
public override void DrawEffectPreview(LocalTargetInfo target) { GenDraw.DrawFieldEdges(this.AffectedCells(target, this.parent.pawn.Map).ToList <IntVec3>(), this.Valid(target, false) ? Color.white : Color.red); }
//public override bool TryMakePreToilReservations(bool errorOnFailed) //{ // if(TargetA.Thing != null) // { // return true; // } // if (pawn.Reserve(TargetA, this.job, 1, 1, null, errorOnFailed)) // { // return true; // } // return false; //} protected override IEnumerable <Toil> MakeNewToils() { yield return(Toils_Misc.ThrowColonistAttackingMote(TargetIndex.A)); this.verb = this.pawn.CurJob.verbToUse as Verb_UseAbility; if (base.TargetA.HasThing && base.TargetA.Thing is Pawn && (!pawn.Position.InHorDistOf(base.TargetA.Cell, pawn.CurJob.verbToUse.verbProps.range) || !Verb.UseAbilityProps.canCastInMelee)) { //if (!base.GetActor().IsFighting() ? true : !verb.UseAbilityProps.canCastInMelee && !this.job.endIfCantShootTargetFromCurPos) //{ Toil toil = Toils_Combat.GotoCastPosition(TargetIndex.A, false); yield return(toil); //toil = null; //} } if (this.Context == AbilityContext.Player) { Find.Targeter.targetingSource = this.verb; } Pawn targetPawn = null; if (this.TargetThingA != null) { targetPawn = TargetThingA as Pawn; } if (targetPawn != null) { //yield return Toils_Combat.CastVerb(TargetIndex.A, false); Toil combatToil = new Toil(); //combatToil.FailOnDestroyedOrNull(TargetIndex.A); //combatToil.FailOnDespawnedOrNull(TargetIndex.A); //combatToil.FailOnDowned(TargetIndex.A); //CompAbilityUserMagic comp = this.pawn.GetComp<CompAbilityUserMagic>(); //JobDriver curDriver = this.pawn.jobs.curDriver; combatToil.initAction = delegate { this.verb = combatToil.actor.jobs.curJob.verbToUse as Verb_UseAbility; if (verb != null && verb.verbProps != null) { this.duration = (int)((this.verb.verbProps.warmupTime * 60) * this.pawn.GetStatValue(StatDefOf.AimingDelayFactor, false)); if (this.pawn.RaceProps.Humanlike) { //if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.Faceless)) //{ // RemoveMimicAbility(verb); //} if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.TM_Psionic)) { PsionicEnergyCost(verb); } if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.DeathKnight)) { HateCost(verb); } if (verb.Ability?.CooldownTicksLeft != -1) { this.EndJobWith(JobCondition.Incompletable); } } LocalTargetInfo target = combatToil.actor.jobs.curJob.GetTarget(TargetIndex.A); if (target != null) { verb.TryStartCastOn(target, false, true); } using (IEnumerator <Hediff> enumerator = this.pawn.health.hediffSet.GetHediffs <Hediff>().GetEnumerator()) { while (enumerator.MoveNext()) { Hediff rec = enumerator.Current; if (rec.def == TorannMagicDefOf.TM_PossessionHD || rec.def == TorannMagicDefOf.TM_DisguiseHD || rec.def == TorannMagicDefOf.TM_DisguiseHD_I || rec.def == TorannMagicDefOf.TM_DisguiseHD_II || rec.def == TorannMagicDefOf.TM_DisguiseHD_III) { this.pawn.health.RemoveHediff(rec); } } } } else { this.EndJobWith(JobCondition.Errored); } }; combatToil.tickAction = delegate { if (this.pawn.Downed) { EndJobWith(JobCondition.InterruptForced); } if (Find.TickManager.TicksGame % 12 == 0) { if (verb.Ability.Def == TorannMagicDefOf.TM_Artifact_TraitThief || verb.Ability.Def == TorannMagicDefOf.TM_Artifact_TraitInfuse) { float direction = Rand.Range(0, 360); TM_MoteMaker.ThrowGenericMote(ThingDef.Named("Mote_Psi_Arcane"), pawn.DrawPos, pawn.Map, Rand.Range(.1f, .4f), 0.2f, .02f, .1f, 0, Rand.Range(8, 10), direction, direction); } else { TM_MoteMaker.ThrowCastingMote(pawn.DrawPos, pawn.Map, Rand.Range(1.2f, 2f)); } } this.duration--; if (!wildCheck && this.duration <= 6) { wildCheck = true; if (this.pawn.story != null && this.pawn.story.traits != null && this.pawn.story.traits.HasTrait(TorannMagicDefOf.ChaosMage) && Rand.Chance(.1f)) { verb.Ability.PostAbilityAttempt(); TM_Action.DoWildSurge(this.pawn, this.pawn.GetComp <CompAbilityUserMagic>(), (MagicAbility)verb.Ability, (TMAbilityDef)verb.Ability.Def, TargetA); EndJobWith(JobCondition.InterruptForced); } } }; combatToil.AddFinishAction(delegate { if (this.duration <= 5 && !this.pawn.DestroyedOrNull() && !this.pawn.Dead && !this.pawn.Downed) { //ShootLine shootLine; //bool validTarg = verb.TryFindShootLineFromTo(pawn.Position, TargetLocA, out shootLine); //bool inRange = (pawn.Position - TargetLocA).LengthHorizontal < verb.verbProps.range; //if (inRange && validTarg) //{ TMAbilityDef tmad = (TMAbilityDef)(verb.Ability.Def); if (tmad != null && tmad.relationsAdjustment != 0 && targetPawn.Faction != null && targetPawn.Faction != this.pawn.Faction && !targetPawn.Faction.HostileTo(this.pawn.Faction)) { targetPawn.Faction.TryAffectGoodwillWith(this.pawn.Faction, tmad.relationsAdjustment, true, false, null, null); } verb.Ability.PostAbilityAttempt(); this.pawn.ClearReservationsForJob(this.job); //} } }); //if (combatToil.actor.CurJob != this.job) //{ // curDriver.ReadyForNextToil(); //} combatToil.defaultCompleteMode = ToilCompleteMode.FinishedBusy; this.pawn.ClearReservationsForJob(this.job); yield return(combatToil); //Toil toil2 = new Toil() //{ // initAction = () => // { // if (curJob.UseAbilityProps.isViolent) // { // JobDriver_CastAbilityVerb.CheckForAutoAttack(this.pawn); // } // }, // defaultCompleteMode = ToilCompleteMode.Instant //}; //yield return toil2; //Toil toil1 = new Toil() //{ // initAction = () => curJob.Ability.PostAbilityAttempt(), // defaultCompleteMode = ToilCompleteMode.Instant //}; //yield return toil1; } else { if (verb != null && verb.verbProps != null && (pawn.Position - TargetLocA).LengthHorizontal < verb.verbProps.range) { if (TargetLocA.IsValid && TargetLocA.InBounds(pawn.Map) && !TargetLocA.Fogged(pawn.Map)) //&& TargetLocA.Walkable(pawn.Map) { ShootLine shootLine; bool validTarg = verb.TryFindShootLineFromTo(pawn.Position, TargetLocA, out shootLine); if (validTarg) { //yield return Toils_Combat.CastVerb(TargetIndex.A, false); //Toil toil2 = new Toil() //{ // initAction = () => // { // if (curJob.UseAbilityProps.isViolent) // { // JobDriver_CastAbilityVerb.CheckForAutoAttack(this.pawn); // } // }, // defaultCompleteMode = ToilCompleteMode.Instant //}; //yield return toil2; this.duration = (int)((verb.verbProps.warmupTime * 60) * this.pawn.GetStatValue(StatDefOf.AimingDelayFactor, false)); Toil toil = new Toil(); toil.initAction = delegate { this.verb = toil.actor.jobs.curJob.verbToUse as Verb_UseAbility; if (this.pawn.RaceProps.Humanlike) { //if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.Faceless)) //{ // RemoveMimicAbility(verb); //} if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.TM_Psionic)) { PsionicEnergyCost(verb); } if (verb.Ability?.CooldownTicksLeft != -1) { this.EndJobWith(JobCondition.Incompletable); } } LocalTargetInfo target = toil.actor.jobs.curJob.GetTarget(TargetIndex.A); //TargetLocA; // bool canFreeIntercept2 = false; if (target != null) { verb.TryStartCastOn(target, false, canFreeIntercept2); } using (IEnumerator <Hediff> enumerator = this.pawn.health.hediffSet.GetHediffs <Hediff>().GetEnumerator()) { while (enumerator.MoveNext()) { Hediff rec = enumerator.Current; if (rec.def == TorannMagicDefOf.TM_PossessionHD || rec.def == TorannMagicDefOf.TM_DisguiseHD || rec.def == TorannMagicDefOf.TM_DisguiseHD_I || rec.def == TorannMagicDefOf.TM_DisguiseHD_II || rec.def == TorannMagicDefOf.TM_DisguiseHD_III) { this.pawn.health.RemoveHediff(rec); } } } }; toil.tickAction = delegate { if (Find.TickManager.TicksGame % 12 == 0) { TM_MoteMaker.ThrowCastingMote(pawn.DrawPos, pawn.Map, Rand.Range(1.2f, 2f)); } this.duration--; if (!wildCheck && this.duration <= 6) { wildCheck = true; if (this.pawn.story != null && this.pawn.story.traits != null && this.pawn.story.traits.HasTrait(TorannMagicDefOf.ChaosMage) && Rand.Chance(.1f)) { bool completeJob = TM_Action.DoWildSurge(this.pawn, this.pawn.GetComp <CompAbilityUserMagic>(), (MagicAbility)verb.Ability, (TMAbilityDef)verb.Ability.Def, TargetA); if (!completeJob) { verb.Ability.PostAbilityAttempt(); EndJobWith(JobCondition.InterruptForced); } } } }; toil.AddFinishAction(delegate { if (this.duration <= 5 && !this.pawn.DestroyedOrNull() && !this.pawn.Dead && !this.pawn.Downed) { verb.Ability.PostAbilityAttempt(); } this.pawn.ClearReservationsForJob(this.job); }); toil.defaultCompleteMode = ToilCompleteMode.FinishedBusy; yield return(toil); //Toil toil1 = new Toil() //{ // initAction = () => curJob.Ability.PostAbilityAttempt(), // defaultCompleteMode = ToilCompleteMode.Instant //}; //yield return toil1; } else { //No LoS if (pawn.IsColonist) { Messages.Message("TM_OutOfLOS".Translate( pawn.LabelShort ), MessageTypeDefOf.RejectInput); } pawn.ClearAllReservations(false); } } else { pawn.ClearAllReservations(false); } } else { if (pawn.IsColonist) { //out of range Messages.Message("TM_OutOfRange".Translate(), MessageTypeDefOf.RejectInput); } } } }
protected override bool RemoveAllDesignationsAffects(LocalTargetInfo target) { return(target.Thing.def.plant.harvestTag == "Standard"); }
/// <summary> /// Checks for cover along the flight path of the bullet, doesn't check for walls or trees, only intended for cover with partial fillPercent /// </summary> /// <param name="target">The target of which to find cover of</param> /// <param name="cover">Output parameter, filled with the highest cover object found</param> /// <returns>True if cover was found, false otherwise</returns> private bool GetHighestCoverAndSmokeForTarget(LocalTargetInfo target, out Thing cover, out float smokeDensity) { Map map = caster.Map; Thing targetThing = target.Thing; Thing highestCover = null; float highestCoverHeight = 0f; smokeDensity = 0; // Iterate through all cells on line of sight and check for cover and smoke var cells = GenSight.PointsOnLineOfSight(target.Cell, caster.Position).ToArray(); if (cells.Length < 3) { cover = null; return(false); } for (int i = 0; i <= cells.Length / 2; i++) { var cell = cells[i]; if (cell.AdjacentTo8Way(caster.Position)) { continue; } // Check for smoke var gas = cell.GetGas(map); if (gas != null) { smokeDensity += gas.def.gas.accuracyPenalty; } // Check for cover in the second half of LoS if (i <= cells.Length / 2) { Pawn pawn = cell.GetFirstPawn(map); Thing newCover = pawn == null?cell.GetCover(map) : pawn; float newCoverHeight = new CollisionVertical(newCover).Max; // Cover check, if cell has cover compare collision height and get the highest piece of cover, ignore if cover is the target (e.g. solar panels, crashed ship, etc) if (newCover != null && (targetThing == null || !newCover.Equals(targetThing)) && (highestCover == null || highestCoverHeight < newCoverHeight) && newCover.def.Fillage == FillCategory.Partial && !newCover.IsPlant()) { highestCover = newCover; highestCoverHeight = newCoverHeight; if (Controller.settings.DebugDrawTargetCoverChecks) { map.debugDrawer.FlashCell(cell, highestCoverHeight, highestCoverHeight.ToString()); } } } } cover = highestCover; //Report success if found cover return(cover != null); }
public static bool CanReachShip(this Pawn pawn, LocalTargetInfo dest, PathEndMode peMode, Danger maxDanger, bool canBash = false, TraverseMode mode = TraverseMode.ByPawn) { return(pawn.Spawned && MapExtensionUtility.GetExtensionToMap(pawn.Map).getShipReachability.CanReachShip(pawn.Position, dest, peMode, TraverseParms.For(pawn, maxDanger, mode, canBash))); }
public static void Impact_DistortWeapon_Postfix(ref Projectile __instance, ref Thing ___launcher, ref LocalTargetInfo ___intendedTarget, Thing hitThing) { if (hitThing != null) { if (hitThing.def.thingClass == typeof(Pawn)) { Pawn hitPawn = (Pawn)hitThing; if (hitPawn != null) { if (__instance.def.projectile.damageDef == OGDamageDefOf.OG_E_Distortion_Damage) { bool explode = Rand.Chance(0.167f); if (explode) { MoteMaker.ThrowText(hitPawn.Position.ToVector3(), hitPawn.Map, "AMA_Distorting_Shot".Translate(__instance.LabelCap, hitPawn.LabelShortCap), 3f); WarpRift(__instance, ___launcher, hitPawn); } } else { // Log.Message(string.Format("damageDef not OG_E_Distortion_Damage: {0}", __instance.def.projectile.damageDef)); } } else { // Log.Message(string.Format("hitPawn is null: {0}", hitThing.def.thingClass)); } } else { // Log.Message(string.Format("Hitthing not pawn: {0}", hitThing.def.thingClass)); } } }
public override void CompTick() { if (this.age > 0) { if (!this.initialized) { if (this.Props.alwaysManhunter || this.Pawn.Faction != Faction.OfPlayer) { this.Pawn.mindState.mentalStateHandler.TryStartMentalState(MentalStateDefOf.ManhunterPermanent, null, true, false, null); } if (this.Pawn.def.defName == "TM_DemonR" || this.Pawn.def.defName == "TM_LesserDemonR") { HealthUtility.AdjustSeverity(this.Pawn, HediffDef.Named("TM_DemonHD"), .5f); } this.initialized = true; } if (this.Pawn.Spawned) { if (!this.Pawn.Downed) { if (this.NextTaunt < Find.TickManager.TicksGame) { DoTaunt(this.Pawn.Map); this.nextTaunt = this.Props.tauntCooldownTicks + Find.TickManager.TicksGame; } if (this.rangedBurstShots > 0 && this.rangedNextBurst < Find.TickManager.TicksGame) { DoRangedAttack(this.rangedTarget); this.rangedBurstShots--; this.rangedNextBurst = Find.TickManager.TicksGame + this.Props.rangedTicksBetweenBursts; } if (Find.TickManager.TicksGame % 30 == 0) { if (this.buildingThreats.Count() > 0) { Building randomBuildingThreat = this.buildingThreats.RandomElement(); if ((randomBuildingThreat.Position - this.Pawn.Position).LengthHorizontal < 50 && this.NextRangedAttack < Find.TickManager.TicksGame && TargetIsValid(randomBuildingThreat)) { this.rangedTarget = randomBuildingThreat; StartRangedAttack(); } } Thing currentTargetThing = this.Pawn.CurJob.targetA.Thing; if (currentTargetThing != null && this.Pawn.TargetCurrentlyAimingAt == null) { if ((currentTargetThing.Position - this.Pawn.Position).LengthHorizontal > (this.Props.maxRangeForCloseThreat * 2)) { if (Rand.Chance(.6f) && this.NextRangedAttack < Find.TickManager.TicksGame && TargetIsValid(currentTargetThing)) { this.rangedTarget = currentTargetThing; StartRangedAttack(); } else if (this.NextChargeAttack < Find.TickManager.TicksGame && TargetIsValid(currentTargetThing)) { DoChargeAttack(currentTargetThing); goto exitTick; } } } else if (this.Pawn.TargetCurrentlyAimingAt != null && this.closeThreats.Count() > 1) { if (Rand.Chance(.2f) && this.NextAoEAttack < Find.TickManager.TicksGame) { DoAoEAttack(this.Pawn.Position, true, 2f, DamageDefOf.Stun, Rand.Range(4, 8)); } if (Rand.Chance(.2f) && this.farThreats.Count() > (3 * this.closeThreats.Count())) { this.Pawn.CurJob.targetA = this.farThreats.RandomElement(); } } if (this.closeThreats.Count() > 1 && ((this.closeThreats.Count() * 2) > this.farThreats.Count() || Rand.Chance(.3f))) { if (Rand.Chance(.8f) && this.NextKnockbackAttack < Find.TickManager.TicksGame) { Pawn randomClosePawn = this.closeThreats.RandomElement(); if ((randomClosePawn.Position - this.Pawn.Position).LengthHorizontal < 3 && TargetIsValid(randomClosePawn)) { DoKnockbackAttack(this.Pawn.Position, randomClosePawn.Position, 1.4f, Rand.Range(3, 5f)); } } } if (this.farThreats.Count() > 2 * this.closeThreats.Count() && Rand.Chance(.3f)) { if (this.NextChargeAttack < Find.TickManager.TicksGame) { Thing tempTarget = this.farThreats.RandomElement(); if (TargetIsValid(tempTarget)) { this.Pawn.TryStartAttack(tempTarget); DoChargeAttack(tempTarget); goto exitTick; } } } if (this.farThreats.Count() > 2) { if (Rand.Chance(.4f) && this.NextRangedAttack < Find.TickManager.TicksGame) { Pawn randomRangedPawn = this.farThreats.RandomElement(); if ((randomRangedPawn.Position - this.Pawn.Position).LengthHorizontal < this.Props.maxRangeForFarThreat * 1.2f) { this.rangedTarget = randomRangedPawn; StartRangedAttack(); } } } if (currentTargetThing == null || currentTargetThing == this.Pawn) { if (this.closeThreats.Count() > 0) { Thing tempTarget = this.closeThreats.RandomElement(); if (TargetIsValid(tempTarget)) { this.Pawn.CurJob.targetA = tempTarget; this.Pawn.TryStartAttack(this.Pawn.CurJob.targetA); } } else if (this.farThreats.Count() > 0) { Thing tempTarget = this.farThreats.RandomElement(); if (TargetIsValid(tempTarget)) { this.Pawn.CurJob.targetA = tempTarget; this.Pawn.TryStartAttack(this.Pawn.CurJob.targetA); } } else if (this.buildingThreats.Count() > 0) { Thing tempTarget = this.buildingThreats.RandomElement(); if (TargetIsValid(tempTarget)) { this.Pawn.CurJob.targetA = tempTarget; this.Pawn.TryStartAttack(this.Pawn.CurJob.targetA); } } } } if (this.Pawn.Faction != Faction.OfPlayer && Find.TickManager.TicksGame % 300 == 0) { if (this.Props.alwaysManhunter) { this.Pawn.mindState.mentalStateHandler.TryStartMentalState(MentalStateDefOf.ManhunterPermanent, null, true, false, null); } } if (Find.TickManager.TicksGame % 120 == 0) { DetermineThreats(); } } if (this.Pawn.Downed && this.Pawn.def.defName == "TM_DemonR" && Find.TickManager.TicksGame % 18 == 0) { CellRect cellRect = CellRect.CenteredOn(this.Pawn.Position, 3); cellRect.ClipInsideMap(this.Pawn.Map); GenExplosion.DoExplosion(cellRect.RandomCell, this.Pawn.Map, 2f, DamageDefOf.Burn, this.Pawn, Rand.Range(6, 12), -1, DamageDefOf.Bomb.soundExplosion, null, null, null, null, 0f, 1, false, null, 0f, 0, 0.2f, true); DamageEntities(this.Pawn, 10f, TMDamageDefOf.DamageDefOf.TM_Shadow, this.Pawn); } } } exitTick :; age++; }
public void Launch(Thing launcher, LocalTargetInfo targ, Thing flyingThing) { this.Launch(launcher, base.Position.ToVector3Shifted(), targ, flyingThing, null); }
public void Launch(Thing launcher, LocalTargetInfo targ, Thing flyingThing, DamageInfo?impactDamage) { this.Launch(launcher, base.Position.ToVector3Shifted(), targ, flyingThing, impactDamage); }
private bool IsValidForestryTarget( LocalTargetInfo t ) { return t.HasThing && IsValidForestryTarget( t.Thing ); }
/// <summary> /// Checks if the shooter can hit the target from a certain position with regards to cover height /// </summary> /// <param name="root">The position from which to check</param> /// <param name="targ">The target to check for line of sight</param> /// <returns>True if shooter can hit target from root position, false otherwise</returns> public override bool CanHitTargetFrom(IntVec3 root, LocalTargetInfo targ) { string unused; return(CanHitTargetFrom(root, targ, out unused)); }
public override bool CanApplyOn(LocalTargetInfo target, LocalTargetInfo dest) { return(this.Valid(target, true)); }
public bool CanHitTarget(LocalTargetInfo targ, out string report) { return(CanHitTargetFrom(caster.Position, targ, out report)); }
public static IEnumerable <Toil> MakeFeedToils(JobDriver thisDriver, Pawn actor, LocalTargetInfo TargetA, float workLeft, Action effect, Func <Pawn, Pawn, bool> stopCondition) { yield return(Toils_Reserve.Reserve(TargetIndex.A, 1, -1, null)); Toil gotoToil = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch); yield return(gotoToil); Toil grappleToil = new Toil() { initAction = delegate { MoteMaker.MakeColonistActionOverlay(actor, ThingDefOf.Mote_ColonistAttacking); workLeft = JobDriver_Feed.BaseFeedTime; Pawn victim = (Pawn)TargetA.Thing; if (victim != null) { if (victim.InAggroMentalState || victim.Faction != actor.Faction) { if (!actor.CanGrapple(victim)) { thisDriver.EndJobWith(JobCondition.Incompletable); } } GenClamor.DoClamor(actor, 10f, ClamorType.Harm); if (!AllowFeeding(actor, victim)) { actor.jobs.EndCurrentJob(JobCondition.Incompletable, true); } if (actor?.VampComp()?.Bloodline?.bloodlineHediff?.CompProps <HediffCompProperties_VerbGiver>()?.verbs is List <VerbProperties> verbProps) { if (actor?.VerbTracker?.AllVerbs is List <Verb> verbs) { if (verbs.Find(x => verbProps.Contains(x.verbProps)) is Verb_MeleeAttack v) { victim.TakeDamage(new DamageInfo(v.verbProps.meleeDamageDef, v.verbProps.meleeDamageBaseAmount, -1, actor)); } } } victim.stances.stunner.StunFor((int)BaseFeedTime); } } }; yield return(grappleToil); Toil feedToil = new Toil() { tickAction = delegate { Pawn victim = (Pawn)TargetA.Thing; if (victim == null || !victim.Spawned || victim.Dead) { thisDriver.ReadyForNextToil(); } workLeft--; if (workLeft <= 0f) { if (actor?.VampComp() is CompVampire v && v.IsVampire && actor.Faction == Faction.OfPlayer) { MoteMaker.ThrowText(actor.DrawPos, actor.Map, "XP +" + 15, -1f); v.XP += 15; } workLeft = BaseFeedTime; MoteMaker.MakeColonistActionOverlay(actor, ThingDefOf.Mote_ColonistAttacking); effect(); if ((victim.HostileTo(actor.Faction) || victim.IsPrisoner) && !actor.CanGrapple(victim)) { thisDriver.EndJobWith(JobCondition.Incompletable); } if (!stopCondition(actor, victim)) { thisDriver.ReadyForNextToil(); } else { if (victim != null && !victim.Dead) { victim.stances.stunner.StunFor((int)BaseFeedTime); PawnUtility.ForceWait((Pawn)TargetA.Thing, (int)BaseFeedTime, actor); } } } },
public virtual bool CanHitTargetFrom(IntVec3 root, LocalTargetInfo targ, out string report) { report = ""; if (caster?.Map == null || !targ.Cell.InBounds(caster.Map) || !root.InBounds(caster.Map)) { report = "Out of bounds"; return(false); } // Check target self if (targ.Thing != null && targ.Thing == caster) { if (!verbProps.targetParams.canTargetSelf) { report = "Can't target self"; return(false); } return(true); } // Check thick roofs if (Projectile.projectile.flyOverhead) { RoofDef roofDef = caster.Map.roofGrid.RoofAt(targ.Cell); if (roofDef != null && roofDef.isThickRoof) { report = "Blocked by roof"; return(false); } } if (ShooterPawn != null) { // Check for capable of violence if (ShooterPawn.story != null && ShooterPawn.WorkTagIsDisabled(WorkTags.Violent)) { report = "IsIncapableOfViolenceLower".Translate(ShooterPawn.Name.ToStringShort); return(false); } // Check for apparel bool isTurretOperator = caster.def.building?.IsTurret ?? false; if (ShooterPawn.apparel != null) { List <Apparel> wornApparel = ShooterPawn.apparel.WornApparel; foreach (Apparel current in wornApparel) { //pawns can use turrets while wearing shield belts, but the shield is disabled for the duration via Harmony patch (see Harmony-ShieldBelt.cs) if (!current.AllowVerbCast(root, caster.Map, targ, this) && !(current is ShieldBelt && isTurretOperator)) { report = "Shooting disallowed by " + current.LabelShort; return(false); } } } } // Check for line of sight ShootLine shootLine; if (!TryFindCEShootLineFromTo(root, targ, out shootLine)) { float lengthHorizontalSquared = (root - targ.Cell).LengthHorizontalSquared; if (lengthHorizontalSquared > verbProps.range * verbProps.range) { report = "Out of range"; } else if (lengthHorizontalSquared < verbProps.minRange * verbProps.minRange) { report = "Within minimum range"; } else { report = "No line of sight"; } return(false); } return(true); }
public Job(JobDef def, LocalTargetInfo targetA) : this(def, targetA, null) { }
public bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine) { if (targ.HasThing && targ.Thing.Map != caster.Map) { resultingLine = default(ShootLine); return(false); } if (verbProps.range <= ShootTuning.MeleeRange) // If this verb has a MAX range up to melee range (NOT a MIN RANGE!) { resultingLine = new ShootLine(root, targ.Cell); return(ReachabilityImmediate.CanReachImmediate(root, targ, caster.Map, PathEndMode.Touch, null)); } CellRect cellRect = (!targ.HasThing) ? CellRect.SingleCell(targ.Cell) : targ.Thing.OccupiedRect(); float num = cellRect.ClosestDistSquaredTo(root); if (num > verbProps.range * verbProps.range || num < verbProps.minRange * verbProps.minRange) { resultingLine = new ShootLine(root, targ.Cell); return(false); } //if (!this.verbProps.NeedsLineOfSight) This method doesn't consider the currently loaded projectile if (Projectile.projectile.flyOverhead) { resultingLine = new ShootLine(root, targ.Cell); return(true); } // First check current cell for early opt-out IntVec3 dest; var shotSource = root.ToVector3Shifted(); shotSource.y = ShotHeight; // Adjust for multi-tile turrets if (caster.def.building?.IsTurret ?? false) { shotSource = ShotSource; } if (CanHitFromCellIgnoringRange(shotSource, targ, out dest)) { resultingLine = new ShootLine(root, dest); return(true); } // For pawns, calculate possible lean locations if (CasterIsPawn) { // Next check lean sources ShootLeanUtility.LeanShootingSourcesFromTo(root, cellRect.ClosestCellTo(root), caster.Map, tempLeanShootSources); foreach (var leanLoc in tempLeanShootSources) { var leanOffset = (leanLoc - root).ToVector3() * 0.5f; if (CanHitFromCellIgnoringRange(shotSource + leanOffset, targ, out dest)) { resultingLine = new ShootLine(leanLoc, dest); return(true); } } } resultingLine = new ShootLine(root, targ.Cell); return(false); }
public bool AnyTargetIs(LocalTargetInfo target) { return(target.IsValid && (this.targetA == target || this.targetB == target || this.targetC == target || (this.targetQueueA != null && this.targetQueueA.Contains(target)) || (this.targetQueueB != null && this.targetQueueB.Contains(target)))); }
protected string ReportStringProcessed(string str) { LocalTargetInfo localTargetInfo = LocalTargetInfo.Invalid; if (this.job.targetA.IsValid) { localTargetInfo = this.job.targetA; } else { localTargetInfo = this.job.targetQueueA.FirstValid(); } if (!localTargetInfo.IsValid) { str = str.Replace("TargetA", "UnknownLower".Translate()); } else if (localTargetInfo.HasThing) { str = str.Replace("TargetA", localTargetInfo.Thing.LabelShort); } else { str = str.Replace("TargetA", "AreaLower".Translate()); } LocalTargetInfo localTargetInfo2 = LocalTargetInfo.Invalid; if (this.job.targetB.IsValid) { localTargetInfo2 = this.job.targetB; } else { localTargetInfo2 = this.job.targetQueueB.FirstValid(); } if (!localTargetInfo2.IsValid) { str = str.Replace("TargetB", "UnknownLower".Translate()); } else if (localTargetInfo2.HasThing) { str = str.Replace("TargetB", localTargetInfo2.Thing.LabelShort); } else { str = str.Replace("TargetB", "AreaLower".Translate()); } LocalTargetInfo targetC = this.job.targetC; if (!targetC.IsValid) { str = str.Replace("TargetC", "UnknownLower".Translate()); } else if (targetC.HasThing) { str = str.Replace("TargetC", targetC.Thing.LabelShort); } else { str = str.Replace("TargetC", "AreaLower".Translate()); } return(str); }
public static IEnumerable <Filth> SelectAllFilth(Pawn pawn, LocalTargetInfo target, int Limit = int.MaxValue) { Room room = null; if (target.Thing == null) { if (target.Cell == null) { Log.Error("Invalid target: cell or thing it must be"); } else { room = GridsUtility.GetRoom(target.Cell, pawn.Map); } } else { room = target.Thing.GetRoom(); } if (room == null) { return(new List <Filth>()); } PathGrid pathGrid = pawn.Map.pathGrid; if (pathGrid == null) { return(new List <Filth>()); } if (cleanFilth == null) { cleanFilth = DefDatabase <WorkGiverDef> .GetNamed("CleanFilth"); } if (cleanFilth.Worker == null) { return(new List <Filth>()); } IEnumerable <Filth> enumerable = null; if (room.IsHuge || room.CellCount > largeRoomSize) { enumerable = new List <Filth>(); for (int i = 0; i < 200; i++) { IntVec3 intVec = target.Cell + GenRadial.RadialPattern[i]; if (intVec.InBounds(pawn.Map) && intVec.InAllowedArea(pawn) && intVec.GetRoom(pawn.Map) == room) { ((List <Filth>)enumerable).AddRange(intVec.GetThingList(pawn.Map).OfType <Filth>().Where(f => !f.Destroyed && ((WorkGiver_Scanner)cleanFilth.Worker).HasJobOnThing(pawn, f)).Take(Limit == 0 ? int.MaxValue : Limit)); } if (Limit > 0 && enumerable.Count() >= Limit) { break; } } } else { enumerable = room.ContainedAndAdjacentThings.OfType <Filth>().Where(delegate(Filth f) { if (f == null || f.Destroyed || !f.Position.InAllowedArea(pawn) || !((WorkGiver_Scanner)cleanFilth.Worker).HasJobOnThing(pawn, f)) { return(false); } Room room2 = f.GetRoom(); if (room2 == null || room2 != room && !room2.IsDoorway) { return(false); } return(true); }).Take(Limit == 0 ? int.MaxValue : Limit); } return(enumerable); }
public virtual bool ValidateTarget(LocalTargetInfo target) { return(CanHitTarget(target)); }
protected override void ApplyEffects(IEnumerable <CompAbilityEffect> effects, LocalTargetInfo target, LocalTargetInfo dest) { if (CanApplyPsycastTo(target)) { foreach (CompAbilityEffect effect in effects) { effect.Apply(target, dest); } } else { MoteMaker.ThrowText(target.CenterVector3, pawn.Map, "TextMote_Immune".Translate()); } }
public void OrderForceTarget(LocalTargetInfo target) { parent.QueueCastingJob(selectedTarget, target); selectedTarget = LocalTargetInfo.Invalid; }
public virtual void DrawEffectPreview(LocalTargetInfo target) { }
public void SetTarget(LocalTargetInfo target) { selectedTarget = target; }
public override Job JobOnCell(Pawn pawn, IntVec3 c, bool forced = false) { Map map = pawn.Map; if (c.IsForbidden(pawn)) { return(null); } if (!PlantUtility.GrowthSeasonNow(c, map, forSowing: true)) { return(null); } if (WorkGiver_Grower.wantedPlantDef == null) { WorkGiver_Grower.wantedPlantDef = WorkGiver_Grower.CalculateWantedPlantDef(c, map); if (WorkGiver_Grower.wantedPlantDef == null) { return(null); } } List <Thing> thingList = c.GetThingList(map); bool flag = false; for (int i = 0; i < thingList.Count; i++) { Thing thing = thingList[i]; if (thing.def == WorkGiver_Grower.wantedPlantDef) { return(null); } if ((thing is Blueprint || thing is Frame) && thing.Faction == pawn.Faction) { flag = true; } } if (flag) { Thing edifice = c.GetEdifice(map); if (edifice == null || edifice.def.fertility < 0f) { return(null); } } if (WorkGiver_Grower.wantedPlantDef.plant.cavePlant) { if (!c.Roofed(map)) { JobFailReason.Is(CantSowCavePlantBecauseUnroofedTrans); return(null); } if (map.glowGrid.GameGlowAt(c, ignoreCavePlants: true) > 0f) { JobFailReason.Is(CantSowCavePlantBecauseOfLightTrans); return(null); } } if (WorkGiver_Grower.wantedPlantDef.plant.interferesWithRoof && c.Roofed(pawn.Map)) { return(null); } Plant plant = c.GetPlant(map); if (plant != null && plant.def.plant.blockAdjacentSow) { LocalTargetInfo target = plant; bool ignoreOtherReservations = forced; if (!pawn.CanReserve(target, 1, -1, null, ignoreOtherReservations) || plant.IsForbidden(pawn)) { return(null); } return(new Job(JobDefOf.CutPlant, plant)); } Thing thing2 = PlantUtility.AdjacentSowBlocker(WorkGiver_Grower.wantedPlantDef, c, map); if (thing2 != null) { Plant plant2 = thing2 as Plant; if (plant2 != null) { LocalTargetInfo target = plant2; bool ignoreOtherReservations = forced; if (pawn.CanReserve(target, 1, -1, null, ignoreOtherReservations) && !plant2.IsForbidden(pawn)) { IPlantToGrowSettable plantToGrowSettable = plant2.Position.GetPlantToGrowSettable(plant2.Map); if (plantToGrowSettable == null || plantToGrowSettable.GetPlantDefToGrow() != plant2.def) { return(new Job(JobDefOf.CutPlant, plant2)); } } } return(null); } if (WorkGiver_Grower.wantedPlantDef.plant.sowMinSkill > 0 && pawn.skills != null && pawn.skills.GetSkill(SkillDefOf.Plants).Level < WorkGiver_Grower.wantedPlantDef.plant.sowMinSkill) { return(null); } for (int j = 0; j < thingList.Count; j++) { Thing thing3 = thingList[j]; if (thing3.def.BlockPlanting) { LocalTargetInfo target = thing3; bool ignoreOtherReservations = forced; if (!pawn.CanReserve(target, 1, -1, null, ignoreOtherReservations)) { return(null); } if (thing3.def.category == ThingCategory.Plant) { if (!thing3.IsForbidden(pawn)) { return(new Job(JobDefOf.CutPlant, thing3)); } return(null); } if (thing3.def.EverHaulable) { return(HaulAIUtility.HaulAsideJobFor(pawn, thing3)); } return(null); } } if (WorkGiver_Grower.wantedPlantDef.CanEverPlantAt(c, map) && PlantUtility.GrowthSeasonNow(c, map, forSowing: true)) { LocalTargetInfo target = c; bool ignoreOtherReservations = forced; if (pawn.CanReserve(target, 1, -1, null, ignoreOtherReservations)) { Job job = new Job(JobDefOf.Sow, c); job.plantDefToSow = WorkGiver_Grower.wantedPlantDef; return(job); } } return(null); }
private bool IsValidHuntingTarget( LocalTargetInfo t ) { return t.HasThing && t.Thing is Pawn && IsValidHuntingTarget( (Pawn) t.Thing ); }