Exemple #1
0
        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);
        }
Exemple #4
0
        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());
            }
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        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);
            }
        }