protected override IntVec3 GetExactWanderDest(Pawn pawn) { Area outpostArea = OG_Util.FindOutpostArea(); if ((outpostArea != null) && outpostArea.ActiveCells.Contains(pawn.Position)) { return(RCellFinder.RandomWanderDestFor(pawn, pawn.Position, this.wanderRadius, this.wanderDestValidator, PawnUtility.ResolveMaxDanger(pawn, this.maxDanger))); } else { Building_OutpostCommandConsole console = OG_Util.FindOutpostCommandConsole(OG_Util.FactionOfMiningCo); if (console != null) { IntVec3 cell1 = WanderUtility.BestCloseWanderRoot(console.Position, pawn); return(cell1); } else { for (int cellIndex = 0; cellIndex < 50; cellIndex++) { IntVec3 cell2 = outpostArea.ActiveCells.RandomElement(); if (pawn.CanReserveAndReach(cell2, PathEndMode.Touch, Danger.Some)) { return(cell2); } } IntVec3 cell3 = WanderUtility.BestCloseWanderRoot(pawn.Position, pawn); return(cell3); } } }
private static void UnforbidItemsToLoadInCargoBay() { // Unforbid any weapon, apparel, raw food or corpse in the outpost area so it can be carried to a cargo bay. if (OG_Util.FindOutpostArea() != null) { foreach (IntVec3 cell in OG_Util.FindOutpostArea().ActiveCells) { foreach (Thing thing in cell.GetThingList()) { if (thing.def.thingCategories == null) { continue; } if (thing.def.thingCategories.Contains(ThingCategoryDefOf.Apparel) || thing.def.thingCategories.Contains(ThingCategoryDef.Named("Headgear")) || thing.def.thingCategories.Contains(ThingCategoryDef.Named("WeaponsMelee")) || thing.def.thingCategories.Contains(ThingCategoryDef.Named("WeaponsRanged")) || thing.def.thingCategories.Contains(ThingCategoryDef.Named("CorpsesHumanlike")) || thing.def.thingCategories.Contains(ThingCategoryDef.Named("Textiles")) || (thing.def == ThingDef.Named("RawHops")) || (thing.def.thingCategories.Contains(ThingCategoryDef.Named("PlantFoodRaw")) && (thing.def != ThingDef.Named("Hay")))) { thing.SetForbidden(false); } } } } }
private void SpawnNecessarySupply() { const int mealsInStockTarget = 80; const int beersInStockTarget = 100; const int componentsInStockTarget = 20; int mealsInOutpost = 0; int beersInOutpost = 0; int componentsInOutpost = 0; int mealsToSupply = 0; int beersToSupply = 0; int componentsToSupply = 0; if (OG_Util.FindOutpostArea() == null) { // Outpost has been captured, do not resupply. return; } CountResourcesInOutpost(out mealsInOutpost, out beersInOutpost, out componentsInOutpost); mealsToSupply = mealsInStockTarget - mealsInOutpost; beersToSupply = beersInStockTarget - beersInOutpost; componentsToSupply = componentsInStockTarget - componentsInOutpost; SpawnSupplyNearPosition(ThingDefOf.MealSurvivalPack, mealsToSupply, this.Position); SpawnSupplyNearPosition(ThingDefOf.Beer, beersToSupply, this.Position); SpawnSupplyNearPosition(ThingDefOf.Components, componentsToSupply, this.Position); }
private static void CountResourcesInOutpost(out int meals, out int beers, out int components) { meals = 0; beers = 0; components = 0; if (OG_Util.FindOutpostArea() != null) { foreach (IntVec3 cell in OG_Util.FindOutpostArea().ActiveCells) { foreach (Thing thing in cell.GetThingList()) { if (thing.def == ThingDefOf.MealSurvivalPack) { meals += thing.stackCount; } if (thing.def == ThingDefOf.Beer) { beers += thing.stackCount; } if (thing.def == ThingDefOf.Components) { components += thing.stackCount; } } } } }
public override bool HasJobOnThing(Pawn pawn, Thing t) { Fire fire = t as Fire; if (fire == null) { return(false); } Pawn pawn2 = fire.parent as Pawn; if (pawn2 != null) { if (pawn2 == pawn) { return(false); } if ((pawn2.Faction == pawn.Faction || pawn2.HostFaction == pawn.Faction || pawn2.HostFaction == pawn.HostFaction) && ((OG_Util.FindOutpostArea() == null) || (OG_Util.FindOutpostArea().ActiveCells.Contains(t.Position) == false)) && Gen.ManhattanDistanceFlat(pawn.Position, pawn2.Position) > 15) { return(false); } } else if ((OG_Util.FindOutpostArea() == null) || (OG_Util.FindOutpostArea().ActiveCells.Contains(t.Position) == false)) { return(false); } return(((pawn.Position - fire.Position).LengthHorizontalSquared <= 225f || pawn.CanReserve(fire, 1)) && !WorkGiver_FightFiresOutpost.FireIsBeingHandled(fire, pawn)); }
/// <summary> /// Destroy the outpost area if it exists. /// </summary> public static void DestroyOutpostArea() { if (OG_Util.FindOutpostArea() != null) { OG_Util.FindOutpostArea().Delete(); } }
protected override Job TryGiveTerminalJob(Pawn pawn) { if (OG_Util.FindOutpostArea() == null) { return(null); } return(base.TryGiveTerminalJob(pawn)); }
public override Job JobOnThing(Pawn pawn, Thing t) { if ((OG_Util.FindOutpostArea() != null) && (OG_Util.FindOutpostArea().ActiveCells.Contains(t.Position))) { return(base.JobOnThing(pawn, t)); } return(null); }
public override bool HasJobOnThing(Pawn pawn, Thing t) { Filth filth = t as Filth; return(filth != null && (OG_Util.FindOutpostArea() != null) && OG_Util.FindOutpostArea().ActiveCells.Contains(t.Position) && pawn.CanReserveAndReach(t, PathEndMode.ClosestTouch, pawn.NormalMaxDanger(), 1) && filth.TicksSinceThickened >= this.MinTicksSinceThickened); }
public JobGiver_WanderOutpost() { this.wanderRadius = 10f; this.ticksBetweenWandersRange = new IntRange(125, 200); this.locomotionUrgency = LocomotionUrgency.Walk; this.wanderDestValidator = delegate(Pawn pawn, IntVec3 loc) { Area outpostArea = OG_Util.FindOutpostArea(); return((outpostArea != null) && outpostArea.ActiveCells.Contains(loc)); }; }
protected override Job TryGiveJob(Pawn pawn) { Area outpostArea = OG_Util.FindOutpostArea(); if (outpostArea == null) { return(null); } if (outpostArea.ActiveCells.Count() == 0) { return(null); } return(base.TryGiveJob(pawn)); }
public JobGiver_WanderOutpost() { this.wanderRadius = 10f; this.ticksBetweenWandersRange = new IntRange(125, 200); this.locomotionUrgency = LocomotionUrgency.Amble; this.wanderDestValidator = delegate(Pawn pawn, IntVec3 loc) { if ((OG_Util.FindOutpostArea() != null) && (OG_Util.FindOutpostArea().ActiveCells.Contains(loc))) { return(true); } return(false); }; }
public override Job JobOnThing(Pawn pawn, Thing t) { Area outpostArea = OG_Util.FindOutpostArea(); if ((outpostArea != null) && (outpostArea.ActiveCells.Contains(t.Position))) { Building_Grave bestGrave = FindBestGrave(pawn, t as Corpse); if ((bestGrave != null) && outpostArea.ActiveCells.Contains(bestGrave.Position)) { return(base.JobOnThing(pawn, t)); } } return(null); }
public override AcceptanceReport CanDesignateCell(IntVec3 c) { if (c.InBounds() && (c.Fogged() == false)) { Area outpostArea = OG_Util.FindOutpostArea(); if ((outpostArea != null) && outpostArea.ActiveCells.Contains(c)) { return("You cannot manage MiningCo. Outpost roof. This area does not belong to your colony."); } if (Find.RoofGrid.RoofAt(c) == OG_Util.IronedRoofDef) { return(true); } } return(base.CanDesignateCell(c)); }
public override Job JobOnThing(Pawn pawn, Thing t) { if (!(t is Corpse)) { return(null); } Area outpostArea = OG_Util.FindOutpostArea(); if ((outpostArea != null) && (outpostArea.ActiveCells.Contains(t.Position))) { // Get potential storage cell and check it is in the outpost area. StoragePriority currentPriority = HaulAIUtility.StoragePriorityAtFor(t.Position, t); IntVec3 storeCell; if (StoreUtility.TryFindBestBetterStoreCellFor(t, pawn, currentPriority, pawn.Faction, out storeCell, true)) { if (outpostArea.ActiveCells.Contains(storeCell)) { return(base.JobOnThing(pawn, t)); } } } return(null); }
private void UpdateLord() { IntVec3 rallyPoint = IntVec3.Invalid; Log.Message("UpdateLord1"); // Check there is no already existing defense lord. if ((Find.LordManager.lords != null) && (Find.LordManager.lords.Count > 0)) { foreach (Lord lord in Find.LordManager.lords) { if ((lord.faction != null) && (lord.faction == OG_Util.FactionOfMiningCo)) { return; } } } Log.Message("UpdateLord2"); // Look for hostile in outpost perimeter. IntVec3 hostilePosition = FindHostileInPerimeter(); if (hostilePosition.IsValid) { Log.Message("UpdateLord2"); Area outpostArea = OG_Util.FindOutpostArea(); if ((outpostArea != null) && (outpostArea.ActiveCells.Contains(hostilePosition))) { Log.Message("UpdateLord4"); // Ennemy is inside outpost area. rallyPoint = hostilePosition; } else { Log.Message("UpdateLord5"); const int sectionsNumber = 100; Vector3 sectionVector = (this.outpostCenter - hostilePosition).ToVector3(); sectionVector = sectionVector / sectionsNumber; // Default value if OutpostArea does not exist (should not occur, just a safety...). rallyPoint = (hostilePosition.ToVector3() + sectionVector * 0.2f * (float)sectionsNumber).ToIntVec3(); for (int i = 1; i <= sectionsNumber; i++) { Vector3 potentialRallyPoint = hostilePosition.ToVector3() + sectionVector * i; if ((outpostArea != null) && (outpostArea.ActiveCells.Contains(potentialRallyPoint.ToIntVec3()))) { // Ensure rallyPoint is completely inside the outpost area. rallyPoint = (potentialRallyPoint + sectionVector * 0.1f * (float)sectionsNumber).ToIntVec3(); break; } } } } else { Log.Message("UpdateLord6"); // Look for damaged turret to defend. Rot4 turretRotation = Rot4.Invalid; IntVec3 turretPosition = IntVec3.Invalid; FindDamagedTurret(out turretPosition, out turretRotation); if (turretPosition.IsValid) { if (OG_Util.IsModActive("MiningCo. ForceField")) { // Look for nearest force field to cover behind. foreach (Thing thing in Find.ListerThings.ThingsOfDef(OG_Util.ForceFieldGeneratorDef)) { if (thing.Position.InHorDistOf(turretPosition, 23f)) { rallyPoint = thing.Position + new IntVec3(0, 0, -2).RotatedBy(thing.Rotation); break; } } } else { // Just go near the attacked turret. rallyPoint = turretPosition + new IntVec3(0, 0, -5).RotatedBy(turretRotation); } } } Log.Message("UpdateLord7"); if (rallyPoint.IsValid) { Log.Message("rallyPoint = " + rallyPoint.ToString()); // Generate defense lord. LordJob_Joinable_DefendOutpost lordJob = new LordJob_Joinable_DefendOutpost(rallyPoint); LordMaker.MakeNewLord(OG_Util.FactionOfMiningCo, lordJob); SoundDef soundDef = SoundDefOf.MessageSeriousAlert; // TODO: add a siren like in alert speaker! soundDef.PlayOneShot(rallyPoint); // Stop all pawns job. foreach (Pawn pawn in Find.MapPawns.AllPawns) { if ((pawn.Faction != null) && (pawn.Faction == OG_Util.FactionOfMiningCo) && (pawn.kindDef != OG_Util.OutpostTechnicianDef)) { pawn.ClearMind(); } } } }
/*private static void AddJoyAndComfortNeed(Pawn pawn) * { * // TODO: does not work anymore... * Log.Message("Try to add joy to " + pawn.Name.ToStringShort); * if (pawn.needs.TryGetNeed(NeedDefOf.Joy) == null) * { * MethodInfo addNeed = typeof(Pawn_NeedsTracker).GetMethod("AddNeed", BindingFlags.Instance | BindingFlags.NonPublic); * addNeed.Invoke(pawn.needs, new object[] * { * DefDatabase<NeedDef>.GetNamed("Joy", true) * }); * pawn.needs.joy.CurLevel = Rand.Range(0.5f, 1f); * } * if (pawn.needs.comfort == null) * { * MethodInfo addNeed = typeof(Pawn_NeedsTracker).GetMethod("AddNeed", BindingFlags.Instance | BindingFlags.NonPublic); * addNeed.Invoke(pawn.needs, new object[] * { * DefDatabase<NeedDef>.GetNamed("Comfort", true) * }); * pawn.needs.comfort.CurLevel = Rand.Range(0.75f, 1f); * } * }*/ public static Pawn GeneratePawn(PawnKindDef kindDef) { Pawn pawn = null; // Generate a new pawn until it respects all criteria. PawnGenerationRequest request = new PawnGenerationRequest( kind: kindDef, faction: OG_Util.FactionOfMiningCo, forceGenerateNewPawn: true, mustBeCapableOfViolence: true, canGeneratePawnRelations: false); for (int tryIndex = 0; tryIndex <= 20; tryIndex++) { pawn = PawnGenerator.GeneratePawn(kindDef, OG_Util.FactionOfMiningCo); if (kindDef == OG_Util.OutpostTechnicianDef) { if (pawn.story.WorkTagIsDisabled(WorkTags.Hauling) || pawn.story.WorkTagIsDisabled(WorkTags.Cleaning) || pawn.story.WorkTagIsDisabled(WorkTags.ManualDumb) || pawn.story.WorkTagIsDisabled(WorkTags.PlantWork) || pawn.story.WorkTagIsDisabled(WorkTags.Firefighting) || pawn.story.WorkTagIsDisabled(WorkTags.Scary)) { pawn.Destroy(); pawn = null; if (tryIndex == 20) { Log.Message("MiningCo. OutpostGenerator: cannot generate requested technician pawn."); } } } else { if (pawn.story.WorkTagIsDisabled(WorkTags.Violent) || pawn.story.WorkTagIsDisabled(WorkTags.Firefighting)) { pawn.Destroy(); pawn = null; if (tryIndex == 20) { Log.Message("MiningCo. OutpostGenerator: cannot generate requested soldier pawn."); } } } if (pawn != null) { break; } } ; // Generate apparel and weapon. GeneratePawnApparelAndWeapon(ref pawn, kindDef); // TODO: add joy and comfort needs. // Enable work settings. pawn.workSettings.EnableAndInitialize(); if (kindDef == OG_Util.OutpostTechnicianDef) { List <WorkTypeDef> allDefsListForReading = DefDatabase <WorkTypeDef> .AllDefsListForReading; for (int workTypeIndex = 0; workTypeIndex < allDefsListForReading.Count; workTypeIndex++) { // Ensure doctor, repair and growing are enabled. WorkTypeDef workTypeDef = allDefsListForReading[workTypeIndex]; if (workTypeDef.alwaysStartActive || (workTypeDef == WorkTypeDefOf.Doctor) || (workTypeDef == WorkTypeDefOf.Repair) || (workTypeDef == WorkTypeDefOf.Growing)) { if (pawn.story.WorkTypeIsDisabled(workTypeDef) == false) { pawn.workSettings.SetPriority(workTypeDef, 3); if (workTypeDef == WorkTypeDefOf.Repair) { pawn.workSettings.SetPriority(workTypeDef, 4); // So dead bodies are hauled away before repairing walls. } } } else { pawn.workSettings.Disable(workTypeDef); } } } // For soldiers, restrict allowed works to only firefighting and doctor (to rescue downed pawns). else { List <WorkTypeDef> allDefsListForReading = DefDatabase <WorkTypeDef> .AllDefsListForReading; for (int workTypeIndex = 0; workTypeIndex < allDefsListForReading.Count; workTypeIndex++) { WorkTypeDef workTypeDef = allDefsListForReading[workTypeIndex]; if ((workTypeDef == WorkTypeDefOf.Firefighter) || (workTypeDef == WorkTypeDefOf.Doctor)) { if (pawn.story.WorkTypeIsDisabled(workTypeDef) == false) { pawn.workSettings.SetPriority(workTypeDef, 3); } } else { pawn.workSettings.Disable(workTypeDef); } } } // Set allowed area. pawn.playerSettings = new Pawn_PlayerSettings(pawn); pawn.playerSettings.AreaRestriction = OG_Util.FindOutpostArea(); // Add a bonus mood boost. pawn.needs.mood.thoughts.memories.TryGainMemoryThought(OG_Util.MiningCoEmployeeThoughtDef); return(pawn); }