/// <summary> /// Takes into account the target being downed and the projectile having been fired while the target was downed, and the target's bodySize /// </summary> private bool ImpactThroughBodySize(Thing thing, float height) { Pawn pawn = thing as Pawn; if (pawn != null) { //Add suppression CompSuppressable compSuppressable = pawn.TryGetComp <CompSuppressable>(); if (compSuppressable != null) { float suppressionAmount = this.def.projectile.damageAmountBase; ProjectilePropertiesCR propsCR = def.projectile as ProjectilePropertiesCR; float penetrationAmount = propsCR == null ? 0f : propsCR.armorPenetration; suppressionAmount *= 1 - Mathf.Clamp(compSuppressable.parentArmor - penetrationAmount, 0, 1); compSuppressable.AddSuppression(suppressionAmount, this.origin.ToIntVec3()); } //Check horizontal distance Vector3 dest = this.destination; Vector3 orig = this.origin; Vector3 pawnPos = pawn.DrawPos; float closestDistToPawn = Math.Abs((dest.z - orig.z) * pawnPos.x - (dest.x - orig.x) * pawnPos.z + dest.x * orig.z - dest.z * orig.x) / (float)Math.Sqrt((dest.z - orig.z) * (dest.z - orig.z) + (dest.x - orig.x) * (dest.x - orig.x)); if (closestDistToPawn <= Utility.GetCollisionWidth(pawn)) { //Check vertical distance float pawnHeight = Utility.GetCollisionHeight(pawn); if (height < pawnHeight) { this.Impact(thing); return(true); } } } if (thing.def.fillPercent > 0 || thing.def.Fillage == FillCategory.Full) { if (height < Utility.GetCollisionHeight(thing) || thing.def.Fillage == FillCategory.Full) { this.Impact(thing); return(true); } } return(false); }
protected override ThoughtState CurrentStateInternal(Pawn p) { CompSuppressable comp = p.TryGetComp <CompSuppressable>(); if (comp != null) { if (comp.isHunkering) { return(ThoughtState.ActiveAtStage(2)); } else if (comp.isSuppressed) { return(ThoughtState.ActiveAtStage(1)); } else if (comp.currentSuppression > 0) { return(ThoughtState.ActiveAtStage(0)); } } return(ThoughtState.Inactive); }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnBroken(TargetIndex.A); //Define Toil Toil toilWait = new Toil(); toilWait.initAction = () => { toilWait.actor.pather.StopDead(); }; Toil toilNothing = new Toil(); //toilNothing.initAction = () => {}; toilNothing.defaultCompleteMode = ToilCompleteMode.Delay; toilNothing.defaultDuration = getUpCheckInterval; // Start Toil yield return(toilWait); yield return(toilNothing); yield return(Toils_Jump.JumpIf(toilNothing, () => { CompSuppressable comp = pawn.TryGetComp <CompSuppressable>(); if (comp == null) { return false; } float distToSuppressor = (pawn.Position - comp.suppressorLoc).LengthHorizontal; if (distToSuppressor < CompSuppressable.minSuppressionDist) { return false; } return comp.isHunkering; })); }
/// <summary> /// Takes into account the target being downed and the projectile having been fired while the target was downed, and /// the target's bodySize /// </summary> private bool ImpactThroughBodySize(Thing thing, float height) { Pawn pawn = thing as Pawn; if (pawn != null) { PersonalShield shield = null; if (pawn.RaceProps.Humanlike) { // check for shield user List <Apparel> wornApparel = pawn.apparel.WornApparel; for (int i = 0; i < wornApparel.Count; i++) { if (wornApparel[i] is PersonalShield) { shield = (PersonalShield)wornApparel[i]; break; } } } //Add suppression CompSuppressable compSuppressable = pawn.TryGetComp <CompSuppressable>(); if (compSuppressable != null) { if (shield == null || (shield != null && shield?.ShieldState == ShieldState.Resetting)) { /* * if (pawn.skills.GetSkill(SkillDefOf.Shooting).level >= 1) * { * suppressionAmount = (def.projectile.damageAmountBase * (1f - ((pawn.skills.GetSkill(SkillDefOf.Shooting).level) / 100) * 3)); * } * else suppressionAmount = def.projectile.damageAmountBase; */ suppressionAmount = def.projectile.damageAmountBase; ProjectilePropertiesCR propsCR = def.projectile as ProjectilePropertiesCR; float penetrationAmount = propsCR == null ? 0f : propsCR.armorPenetration; suppressionAmount *= 1 - Mathf.Clamp(compSuppressable.parentArmor - penetrationAmount, 0, 1); compSuppressable.AddSuppression(suppressionAmount, origin.ToIntVec3()); } } //Check horizontal distance Vector3 dest = destination; Vector3 orig = origin; Vector3 pawnPos = pawn.DrawPos; float closestDistToPawn = Math.Abs((dest.z - orig.z) * pawnPos.x - (dest.x - orig.x) * pawnPos.z + dest.x * orig.z - dest.z * orig.x) / (float) Math.Sqrt((dest.z - orig.z) * (dest.z - orig.z) + (dest.x - orig.x) * (dest.x - orig.x)); if (closestDistToPawn <= CR_Utility.GetCollisionWidth(pawn)) { //Check vertical distance float pawnHeight = CR_Utility.GetCollisionHeight(pawn); if (height < pawnHeight) { Impact(thing); return(true); } } } if (thing.def.fillPercent > 0 || thing.def.Fillage == FillCategory.Full) { if (height < CR_Utility.GetCollisionHeight(thing) || thing.def.Fillage == FillCategory.Full) { Impact(thing); return(true); } } return(false); }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDespawnedOrNull(TargetIndex.A); //Define Toil maxTicks = Rand.Range(60, 600); ticksLeft = maxTicks; willPee = maxTicks > 500; toilHunkerDown = new Toil { initAction = delegate { //int num = 0; //IntVec3 intVec; //while (true) //{ // intVec = pawn.Position + GenAdj.AdjacentCellsAndInside[Rand.Range(0, 9)]; // num++; // if (num > 12) // { // intVec = pawn.Position; // break; // } // if (intVec.InBounds() && intVec.Standable()) // { // break; // } //} //pawn.CurJob.targetB = intVec; //pawn.Drawer.rotator.FaceCell(intVec); toilHunkerDown.actor.pather.StopDead(); }, tickAction = delegate { ticksLeft--; if (willPee) { if (ticksLeft % maxTicks == maxTicks - 1) { // MoteMaker.ThrowMetaIcon(pawn.Position, ThingDefOf.Mote_Heart); // FilthMaker.MakeFilth(pawn.CurJob.targetB.Cell, CR_ThingDefOf.FilthPee, pawn.LabelIndefinite(), 1); FilthMaker.MakeFilth(pawn.Position, pawn.Map, CR_ThingDefOf.FilthPee, pawn.LabelIndefinite(), 1); } } if (ticksLeft <= 0) { ReadyForNextToil(); if (willPee) { TaleRecorder.RecordTale(WetHimself, pawn); } } }, defaultCompleteMode = ToilCompleteMode.Never, }; CompSuppressable comp = pawn.TryGetComp <CompSuppressable>(); toilHunkerDown.FailOn(() => comp == null); if (comp != null) { float distToSuppressor = (pawn.Position - comp.suppressorLoc).LengthHorizontal; toilHunkerDown.FailOn(() => distToSuppressor < CompSuppressable.minSuppressionDist); toilHunkerDown.FailOn(() => !comp.isHunkering); } // bug can get the willPee if it's initialized, define the bool more accessable if (willPee) { toilHunkerDown.WithEffect(EffecterDef.Named("Pee"), TargetIndex.A); } // Start Toil yield return(toilHunkerDown); if (GetCoverPositionFrom(pawn, comp.suppressorLoc, maxCoverDist * 1.5f, out coverPosition) && Rand.Value > 0.5) { if (coverPosition != pawn.Position) { Toil toil = new Toil(); toil.initAction = delegate { Pawn actor = toil.actor; actor.Map.pawnDestinationManager.ReserveDestinationFor(pawn, coverPosition); actor.pather.StartPath(coverPosition, PathEndMode.OnCell); }; toil.defaultCompleteMode = ToilCompleteMode.PatherArrival; // Shame, shame, shame, shame! if (willPee) { toil.WithEffect(EffecterDef.Named("Pee"), TargetIndex.A); } yield return(toil); } } yield break; }