public ThingDef GiveResources(ResourceRequest req, out MoteType mote, out bool singleSpawn, out bool eventTriggered) { // Increment the jobs completed jobsCompleted++; eventTriggered = false; mote = MoteType.None; singleSpawn = true; // Decrease the amount this quarry can be mined, eventually depleting it if (QuarrySettings.QuarryMaxHealth != int.MaxValue) { QuarryMined(); } // Determine if the mining job resulted in a sinkhole event, based on game difficulty if (jobsCompleted % SinkholeFrequency == 0 && Rand.Chance(Find.Storyteller.difficulty.difficulty / 50f)) { eventTriggered = true; // The sinkhole damages the quarry a little QuarryMined(Rand.RangeInclusive(1, 3)); } // Cache values since this process is convoluted and the values need to remain the same bool junkMined = Rand.Chance(QuarrySettings.junkChance / 100f); // Check for blocks first to prevent spawning chunks (these would just be cut into blocks) if (req == ResourceRequest.Blocks) { if (!junkMined) { singleSpawn = false; return(BlocksUnder.RandomElement()); } // The rock didn't break into a usable size, spawn rubble mote = MoteType.Failure; return(ThingDefOf.RockRubble); } // Try to give junk before resources. This simulates only mining chunks or useless rubble if (junkMined) { if (Rand.Chance(QuarrySettings.chunkChance / 100f)) { return(ChunksUnder.RandomElement()); } else { mote = MoteType.Failure; return(ThingDefOf.RockRubble); } } // Try to give resources if (req == ResourceRequest.Resources) { singleSpawn = false; return(OreDictionary.TakeOne()); } // The quarry was most likely toggled off while a pawn was still working. Give junk else { return(ThingDefOf.RockRubble); } }
private Toil Collect() { return(new Toil() { initAction = delegate { // Increment the record for how many cells this pawn has mined since this counts as mining // TODO: B19 - change to quarry m3 pawn.records.Increment(RecordDefOf.CellsMined); // Start with None to act as a fallback. Rubble will be returned with this parameter ResourceRequest req = ResourceRequest.None; // Use the mineModeToggle to determine the request req = (ResourceRequest)(((int)Quarry.mineModeToggle) + 1); MoteType mote = MoteType.None; int stackCount = 1; // Get the resource from the quarry ThingDef def = Quarry.GiveResources(req, out mote, out bool singleSpawn, out bool eventTriggered); // If something went wrong, bail out if (def == null || def.thingClass == null) { Log.Warning("Quarry:: Tried to quarry mineable ore, but the ore given was null."); mote = MoteType.None; singleSpawn = true; // This shouldn't happen at all, but if it does let's add a little reward instead of just giving rubble def = ThingDefOf.ChunkSlagSteel; } Thing haulableResult = ThingMaker.MakeThing(def); if (!singleSpawn && def != ThingDefOf.ComponentIndustrial) { int sub = (int)(def.BaseMarketValue / 2f); sub = Mathf.Clamp(sub, 0, 10); stackCount += Mathf.Min(Rand.RangeInclusive(15 - sub, 40 - (sub * 2)), def.stackLimit - 1); } if (def == ThingDefOf.ComponentIndustrial) { stackCount += Random.Range(0, 1); } haulableResult.stackCount = stackCount; if (stackCount >= 30) { mote = MoteType.LargeVein; } bool usesQuality = false; // Adjust quality for items that use it if (haulableResult.TryGetComp <CompQuality>() != null) { usesQuality = true; haulableResult.TryGetComp <CompQuality>().SetQuality(QualityUtility.GenerateQualityTraderItem(), ArtGenerationContext.Outsider); } // Adjust hitpoints, this was just mined from under the ground after all if (def.useHitPoints && !def.thingCategories.Contains(QuarryDefOf.StoneChunks) && def != ThingDefOf.ComponentIndustrial) { float minHpThresh = 0.25f; if (usesQuality) { minHpThresh = Mathf.Clamp((float)haulableResult.TryGetComp <CompQuality>().Quality / 10f, 0.1f, 0.7f); } int hp = Mathf.RoundToInt(Rand.Range(minHpThresh, 1f) * haulableResult.MaxHitPoints); hp = Mathf.Max(1, hp); haulableResult.HitPoints = hp; } // Place the resource near the pawn GenPlace.TryPlaceThing(haulableResult, pawn.Position, Map, ThingPlaceMode.Near); // If the resource had a mote, throw it if (mote == MoteType.LargeVein) { MoteMaker.ThrowText(haulableResult.DrawPos, Map, Static.TextMote_LargeVein, Color.green, 3f); } else if (mote == MoteType.Failure) { MoteMaker.ThrowText(haulableResult.DrawPos, Map, Static.TextMote_MiningFailed, Color.red, 3f); } // If the sinkhole event was triggered, damage the pawn and end this job // Even if the sinkhole doesn't incapacitate the pawn, they will probably want to seek medical attention if (eventTriggered) { NamedArgument pawnName = new NamedArgument(0, pawn.NameShortColored); Messages.Message("QRY_MessageSinkhole".Translate(pawnName), pawn, MessageTypeDefOf.NegativeEvent); DamageInfo dInfo = new DamageInfo(DamageDefOf.Crush, 9, category: DamageInfo.SourceCategory.Collapse); dInfo.SetBodyRegion(BodyPartHeight.Bottom, BodyPartDepth.Inside); pawn.TakeDamage(dInfo); EndJobWith(JobCondition.Succeeded); } else { // Prevent the colonists from trying to haul rubble, which just makes them visit the platform if (def == ThingDefOf.Filth_RubbleRock) { EndJobWith(JobCondition.Succeeded); } else { // If this is a chunk or slag, mark it as haulable if allowed to if (def.designateHaulable && Quarry.autoHaul) { Map.designationManager.AddDesignation(new Designation(haulableResult, DesignationDefOf.Haul)); } // Try to find a suitable storage spot for the resource, removing it from the quarry // If there are no platforms with free space, or if the resource is a chunk, try to haul it to a storage area if (Quarry.autoHaul) { if (!def.thingCategories.Contains(QuarryDefOf.StoneChunks) && Quarry.HasConnectedPlatform && Quarry.TryFindBestPlatformCell(haulableResult, pawn, Map, pawn.Faction, out IntVec3 c)) { job.SetTarget(TargetIndex.B, haulableResult); job.count = haulableResult.stackCount; job.SetTarget(TargetIndex.C, c); } else { StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(haulableResult); Job result; if (!StoreUtility.TryFindBestBetterStorageFor(haulableResult, pawn, Map, currentPriority, pawn.Faction, out c, out IHaulDestination haulDestination, true)) { JobFailReason.Is("NoEmptyPlaceLower".Translate(), null); } else if (haulDestination is ISlotGroupParent) { result = HaulAIUtility.HaulToCellStorageJob(pawn, haulableResult, c, false); } else { job.SetTarget(TargetIndex.B, haulableResult); job.count = haulableResult.stackCount; job.SetTarget(TargetIndex.C, c); } } }
private Toil Collect() { Toil toil = new Toil(); toil.initAction = delegate { // Increment the record for how many cells this pawn has mined since this counts as mining pawn.records.Increment(RecordDefOf.CellsMined); // Start with None to act as a fallback. Rubble will be returned with this parameter ResourceRequest req = ResourceRequest.None; // Use the mineModeToggle to determine the request req = (Quarry.mineModeToggle ? ResourceRequest.Resources : ResourceRequest.Blocks); MoteType mote = MoteType.None; bool singleSpawn = true; bool eventTriggered = false; int stackCount = 1; // Get the resource from the quarry ThingDef def = Quarry.GiveResources(req, out mote, out singleSpawn, out eventTriggered); // If something went wrong, bail out if (def == null || def.thingClass == null) { Log.Warning("Quarry:: Tried to quarry mineable ore, but the ore given was null."); mote = MoteType.None; singleSpawn = true; // This shouldn't happen at all, but if it does let's add a little reward instead of just giving rubble def = ThingDefOf.ChunkSlagSteel; } Thing haulableResult = ThingMaker.MakeThing(def); if (!singleSpawn && def != ThingDefOf.Component) { int sub = (int)(def.BaseMarketValue / 3f); if (sub >= 10) { sub = 9; } stackCount += Mathf.Min(Rand.RangeInclusive(15 - sub, 40 - (sub * 2)), def.stackLimit - 1); } if (def == ThingDefOf.Component) { stackCount += Random.Range(0, 1); } haulableResult.stackCount = stackCount; if (stackCount >= 30) { mote = MoteType.LargeVein; } // Place the resource near the pawn GenPlace.TryPlaceThing(haulableResult, pawn.Position, Map, ThingPlaceMode.Near); // If the resource had a mote, throw it if (mote == MoteType.LargeVein) { MoteMaker.ThrowText(haulableResult.DrawPos, Map, Static.TextMote_LargeVein, Color.green, 3f); } else if (mote == MoteType.Failure) { MoteMaker.ThrowText(haulableResult.DrawPos, Map, Static.TextMote_MiningFailed, Color.red, 3f); } // If the sinkhole event was triggered, damage the pawn and end this job // Even if the sinkhole doesn't incapacitate the pawn, they will probably want to seek medical attention if (eventTriggered) { Messages.Message("QRY_MessageSinkhole".Translate(pawn.NameStringShort), pawn, MessageTypeDefOf.ThreatSmall); DamageInfo dInfo = new DamageInfo(DamageDefOf.Crush, 9, -1f, category: DamageInfo.SourceCategory.Collapse); dInfo.SetBodyRegion(BodyPartHeight.Bottom, BodyPartDepth.Inside); pawn.TakeDamage(dInfo); pawn.TakeDamage(dInfo); EndJobWith(JobCondition.Succeeded); } // Prevent the colonists from trying to haul rubble, which just makes them visit the platform if (haulableResult.def == ThingDefOf.RockRubble) { EndJobWith(JobCondition.Succeeded); } // If this is a chunk or slag, mark it as haulable if allowed to if (haulableResult.def.designateHaulable && Quarry.autoHaul) { Map.designationManager.AddDesignation(new Designation(haulableResult, DesignationDefOf.Haul)); } // Setup IntVec for assigning IntVec3 c; // Try to find a suitable storage spot for the resource, removing it from the quarry // If there are no platforms with free space, try to haul it to a storage area if (Quarry.autoHaul) { if (Quarry.HasConnectedPlatform && Quarry.TryFindBestStoreCellFor(haulableResult, pawn, Map, pawn.Faction, out c)) { job.SetTarget(TargetIndex.B, haulableResult); job.count = haulableResult.stackCount; job.SetTarget(TargetIndex.C, c); } else { StoragePriority currentPriority = HaulAIUtility.StoragePriorityAtFor(haulableResult.Position, haulableResult); if (StoreUtility.TryFindBestBetterStoreCellFor(haulableResult, pawn, Map, currentPriority, pawn.Faction, out c)) { job.SetTarget(TargetIndex.B, haulableResult); job.count = haulableResult.stackCount; job.SetTarget(TargetIndex.C, c); } } } // If there is no spot to store the resource, end this job else { EndJobWith(JobCondition.Succeeded); } }; toil.defaultCompleteMode = ToilCompleteMode.Instant; return(toil); }
public Thing GiveResources(ResourceRequest req, out MoteType mote) { mote = MoteType.None; // Decrease the amount this quarry can be mined, eventually depleting it if (QuarryMod.QuarryMaxHealth != int.MaxValue) { quarryHealth--; } // Cache values since this process is convoluted and the values need to remain the same bool cachedJunkChance = Rand.Chance(QuarryMod.JunkChance); // Check for blocks first to prevent spawning chunks (these would just be cut into blocks) if (req == ResourceRequest.Blocks) { if (!cachedJunkChance) { string blockType = RockTypesUnder.RandomElement(); return(new QuarryResource(QuarryMod.Database.Find(t => t.defName == "Blocks" + blockType), Rand.RangeInclusive(5, 10)).ToThing()); } // The rock didn't break into a usable size, spawn rubble mote = MoteType.Failure; return(new QuarryResource(ThingDefOf.RockRubble, 1).ToThing()); } // Try to give junk before resources. This simulates only mining chunks or useless rubble if (cachedJunkChance) { if (Rand.Chance(QuarryMod.ChunkChance)) { return(new QuarryResource(QuarryMod.Database.Find(t => t.defName == "Chunk" + RockTypesUnder.RandomElement()), 1).ToThing()); } else { mote = MoteType.Failure; return(new QuarryResource(ThingDefOf.RockRubble, 1).ToThing()); } } System.Random rand = new System.Random(); // Try to give resources if (req == ResourceRequest.Resources) { int maxProb = QuarryMod.Resources.Sum(c => c.probability); int choice = rand.Next(maxProb); int sum = 0; foreach (QuarryResource resource in QuarryMod.Resources) { for (int i = sum; i < resource.probability + sum; i++) { if (i >= choice) { if (resource.largeVein) { mote = MoteType.LargeVein; } return(resource.ToThing()); } } sum += resource.probability; } QuarryResource qr = QuarryMod.Resources.First(); if (qr.largeVein) { mote = MoteType.LargeVein; } return(qr.ToThing()); } // The quarry was most likely toggled off while a pawn was still working. Give junk else { return(new QuarryResource(ThingDefOf.RockRubble, 1).ToThing()); } }
private Toil Collect() { Toil toil = new Toil(); toil.initAction = delegate { // Increment the record for how many cells this pawn has mined since this counts as mining pawn.records.Increment(RecordDefOf.CellsMined); // Start with None to act as a fallback. Rubble will be returned with this parameter ResourceRequest req = ResourceRequest.None; // Use the mineModeToggle to determine the request req = (Quarry.mineModeToggle ? ResourceRequest.Resources : ResourceRequest.Blocks); MoteType mote = MoteType.None; // Get the resource from the quarry Thing haulableResult = Quarry.GiveResources(req, out mote); // Place the resource near the pawn GenPlace.TryPlaceThing(haulableResult, pawn.Position, Map, ThingPlaceMode.Near); // If the resource had a mote, throw it if (mote == MoteType.LargeVein) { MoteMaker.ThrowText(haulableResult.DrawPos, Map, Static.TextMote_LargeVein, Color.green, 3f); } else if (mote == MoteType.Failure) { MoteMaker.ThrowText(haulableResult.DrawPos, Map, Static.TextMote_MiningFailed, Color.red, 3f); } // Prevent the colonists from trying to haul rubble, which just makes them visit the platform if (haulableResult.def == ThingDefOf.RockRubble) { EndJobWith(JobCondition.Succeeded); } // If this is a chunk or slag, mark it as haulable if allowed to if (haulableResult.def.designateHaulable && Quarry.autoHaul) { Map.designationManager.AddDesignation(new Designation(haulableResult, DesignationDefOf.Haul)); } // Setup IntVec for assigning IntVec3 c; // Try to find a suitable storage spot for the resource, removing it from the quarry // If there are no platforms, hauling will be done by haulers if (Quarry.autoHaul && Quarry.TryFindBestStoreCellFor(haulableResult, pawn, Map, pawn.Faction, out c)) { CurJob.SetTarget(TargetIndex.B, haulableResult); CurJob.count = haulableResult.stackCount; CurJob.SetTarget(TargetIndex.C, c); } // If there is no spot to store the resource, end this job else { EndJobWith(JobCondition.Succeeded); } }; toil.defaultCompleteMode = ToilCompleteMode.Instant; return(toil); }
public ThingDef GiveResources(ResourceRequest req, out MoteType mote, out bool singleSpawn, out bool eventTriggered) { // Increment the jobs completed jobsCompleted++; eventTriggered = false; mote = MoteType.None; singleSpawn = true; // Decrease the amount this quarry can be mined, eventually depleting it if (QuarrySettings.QuarryMaxHealth != int.MaxValue) { quarryHealth--; } // Determine if the mining job resulted in a sinkhole event, based on game difficulty if (jobsCompleted % 100 == 0 && Rand.Chance(Find.Storyteller.difficulty.difficulty / 50f)) { eventTriggered = true; } // Cache values since this process is convoluted and the values need to remain the same bool cachedJunkChance = Rand.Chance(QuarrySettings.junkChance / 100f); // Check for blocks first to prevent spawning chunks (these would just be cut into blocks) if (req == ResourceRequest.Blocks) { if (!cachedJunkChance) { singleSpawn = false; string blockType = RockTypesUnder.RandomElement(); return(QuarrySettings.database.Find(t => t.defName == "Blocks" + blockType)); } // The rock didn't break into a usable size, spawn rubble mote = MoteType.Failure; return(ThingDefOf.RockRubble); } // Try to give junk before resources. This simulates only mining chunks or useless rubble if (cachedJunkChance) { if (Rand.Chance(QuarrySettings.chunkChance / 100f)) { return(QuarrySettings.database.Find(t => t.defName == "Chunk" + RockTypesUnder.RandomElement())); } else { mote = MoteType.Failure; return(ThingDefOf.RockRubble); } } System.Random rand = new System.Random(); // Try to give resources if (req == ResourceRequest.Resources) { singleSpawn = false; return(OreDictionary.From(QuarryMod.oreDictionary).TakeOne()); } // The quarry was most likely toggled off while a pawn was still working. Give junk else { return(ThingDefOf.RockRubble); } }