protected override Job TryGiveJob(Pawn pawn) { var comp = pawn.TryGetComp <CompSuppressable>(); if (comp == null) { return(null); } Job reactJob = SuppressionUtility.GetRunForCoverJob(pawn); // Hunker down if (reactJob == null && comp.IsHunkering) { LessonAutoActivator.TeachOpportunity(CE_ConceptDefOf.CE_Hunkering, pawn, OpportunityType.Critical); reactJob = JobMaker.MakeJob(CE_JobDefOf.HunkerDown, pawn); reactJob.checkOverrideOnExpire = true; return(reactJob); } else { // Run for cover LessonAutoActivator.TeachOpportunity(CE_ConceptDefOf.CE_SuppressionReaction, pawn, OpportunityType.Critical); } return(reactJob); }
public override void CompTick() { base.CompTick(); // Update suppressed tick counter and check for mental breaks if (!isSuppressed) { ticksHunkered = 0; } else if (IsHunkering) { ticksHunkered++; } if (ticksHunkered > MinTicksUntilMentalBreak && Rand.Chance(ChanceBreakPerTick)) { var pawn = (Pawn)parent; if (pawn.mindState != null && !pawn.mindState.mentalStateHandler.InMentalState) { var possibleBreaks = SuppressionUtility.GetPossibleBreaks(pawn); if (possibleBreaks.Any()) { pawn.mindState.mentalStateHandler.TryStartMentalState(possibleBreaks.RandomElement()); } } } //Apply decay once per second if (ticksUntilDecay > 0) { ticksUntilDecay--; } else if (currentSuppression > 0) { //Decay global suppression if (Controller.settings.DebugShowSuppressionBuildup && Gen.IsHashIntervalTick(parent, 30)) { MoteMaker.ThrowText(parent.DrawPos, parent.Map, "-" + (SuppressionDecayRate * 30), Color.red); } currentSuppression -= Mathf.Min(SuppressionDecayRate, currentSuppression); isSuppressed = currentSuppression > 0; // Clear crouch-walking if (!isSuppressed) { isCrouchWalking = false; } //Decay location suppression locSuppressionAmount -= Mathf.Min(SuppressionDecayRate, locSuppressionAmount); } //Throw mote at set interval if (parent.IsHashIntervalTick(TicksPerMote) && CanReactToSuppression) { if (IsHunkering) { MoteMaker.ThrowMetaIcon(parent.Position, parent.Map, CE_ThingDefOf.Mote_HunkerIcon); } else if (this.isSuppressed) { //MoteMaker.ThrowText(this.parent.Position.ToVector3Shifted(), parent.Map, "CE_SuppressedMote".Translate()); MoteMaker.ThrowMetaIcon(parent.Position, parent.Map, CE_ThingDefOf.Mote_SuppressIcon); } } /*if (Gen.IsHashIntervalTick(parent, ticksPerMote + Rand.Range(30, 300)) * && parent.def.race.Humanlike && !robotBodyList.Contains(parent.def.race.body.defName)) * { * if (isHunkering || isSuppressed) * { * AGAIN: string rndswearsuppressed = RulePackDef.Named("SuppressedMote").Rules.RandomElement().Generate(); * * if (rndswearsuppressed == "[suppressed]" || rndswearsuppressed == "" || rndswearsuppressed == " ") * { * goto AGAIN; * } * MoteMaker.ThrowText(this.parent.Position.ToVector3Shifted(), Find.CurrentMap, rndswearsuppressed); * } * //standard MoteMaker.ThrowText(parent.Position.ToVector3Shifted(), "CE_SuppressedMote".Translate()); * }*/ }
public void AddSuppression(float amount, IntVec3 origin) { Pawn pawn = parent as Pawn; if (pawn == null) { Log.Error("CE trying to suppress non-pawn " + parent.ToString() + ", this should never happen"); return; } // No suppression on berserking or fleeing pawns if (!CanReactToSuppression) { currentSuppression = 0f; isSuppressed = false; return; } // Add suppression to global suppression counter var suppressAmount = amount * pawn.GetStatValue(CE_StatDefOf.Suppressability); currentSuppression += suppressAmount; if (Controller.settings.DebugShowSuppressionBuildup) { MoteMaker.ThrowText(pawn.DrawPos, pawn.Map, suppressAmount.ToString()); } ticksUntilDecay = TicksForDecayStart; if (currentSuppression > maxSuppression) { currentSuppression = maxSuppression; } // Add suppression to current suppressor location if appropriate if (suppressorLoc == origin) { locSuppressionAmount += amount; } else if (locSuppressionAmount < SuppressionThreshold) { suppressorLoc = origin; locSuppressionAmount = currentSuppression; } // Assign suppressed status and assign reaction job if (currentSuppression > SuppressionThreshold) { isSuppressed = true; Job reactJob = SuppressionUtility.GetRunForCoverJob(pawn); if (reactJob == null && IsHunkering) { reactJob = new Job(CE_JobDefOf.HunkerDown, pawn); LessonAutoActivator.TeachOpportunity(CE_ConceptDefOf.CE_Hunkering, pawn, OpportunityType.Critical); } if (reactJob != null && reactJob.def != pawn.CurJob?.def) { //only reserve destination when we know for certain the pawn isn't already running for cover pawn.Map.pawnDestinationReservationManager.Reserve(pawn, reactJob, reactJob.GetTarget(TargetIndex.A).Cell); pawn.jobs.StartJob(reactJob, JobCondition.InterruptForced, null, pawn.jobs.curJob?.def == JobDefOf.ManTurret); LessonAutoActivator.TeachOpportunity(CE_ConceptDefOf.CE_SuppressionReaction, pawn, OpportunityType.Critical); } else { // Crouch-walk isCrouchWalking = true; } // Throw taunt if (Rand.Chance(0.01f)) { var tauntThrower = (TauntThrower)(pawn.Map.GetComponent(typeof(TauntThrower))); tauntThrower?.TryThrowTaunt(CE_RulePackDefOf.SuppressedMote, pawn); } } }
public override void CompTick() { base.CompTick(); // Update suppressed tick counter and check for mental breaks if (!isSuppressed) { ticksHunkered = 0; } else if (IsHunkering) { ticksHunkered++; } if (ticksHunkered > MinTicksUntilMentalBreak && Rand.Chance(ChanceBreakPerTick)) { var pawn = (Pawn)parent; if (pawn.mindState != null && !pawn.mindState.mentalStateHandler.InMentalState) { var possibleBreaks = SuppressionUtility.GetPossibleBreaks(pawn); if (possibleBreaks.Any()) { pawn.mindState.mentalStateHandler.TryStartMentalState(possibleBreaks.RandomElement()); } } } //Apply decay once per second if (ticksUntilDecay > 0) { ticksUntilDecay--; } else if (currentSuppression > 0) { //Decay global suppression if (Controller.settings.DebugShowSuppressionBuildup && Gen.IsHashIntervalTick(parent, 30)) { MoteMaker.ThrowText(parent.DrawPos, parent.Map, "-" + (SuppressionDecayRate * 30), Color.red); } currentSuppression -= Mathf.Min(SuppressionDecayRate, currentSuppression); isSuppressed = currentSuppression > 0; // Clear crouch-walking if (!isSuppressed) { isCrouchWalking = false; } //Decay location suppression locSuppressionAmount -= Mathf.Min(SuppressionDecayRate, locSuppressionAmount); } // Throw mote at set interval if (parent.IsHashIntervalTick(TicksPerMote) && CanReactToSuppression) { if (this.IsHunkering) { CE_Utility.MakeIconOverlay((Pawn)parent, CE_ThingDefOf.Mote_HunkerIcon); } else if (this.isSuppressed) { CE_Utility.MakeIconOverlay((Pawn)parent, CE_ThingDefOf.Mote_SuppressIcon); } } }