Ejemplo n.º 1
0
        /* return a string describing modifiers to road costs building between two tiles, and sets totalCostModifer */
        public static string CostModifersDescription(int fromTile_int, int toTile_int, ref float totalCostModifier)
        {
            StringBuilder         result   = new StringBuilder();
            RoadsOfTheRimSettings settings = LoadedModManager.GetMod <RoadsOfTheRim>().GetSettings <RoadsOfTheRimSettings>();
            // Show total cost modifiers
            float elevationModifier  = 0f;
            float hillinessModifier  = 0f;
            float swampinessModifier = 0f;
            float bridgeModifier     = 0f;

            WorldObjectComp_ConstructionSite.GetCostsModifiers(fromTile_int, toTile_int, ref elevationModifier, ref hillinessModifier, ref swampinessModifier, ref bridgeModifier);
            result.Append("RoadsOfTheRim_ConstructionSiteDescription_CostModifiers".Translate(
                              String.Format("{0:P0}", elevationModifier + hillinessModifier + swampinessModifier + bridgeModifier),
                              String.Format("{0:P0}", elevationModifier),
                              String.Format("{0:P0}", hillinessModifier),
                              String.Format("{0:P0}", swampinessModifier),
                              String.Format("{0:P0}", bridgeModifier)
                              ));
            totalCostModifier = (1 + elevationModifier + hillinessModifier + swampinessModifier + bridgeModifier) * ((float)settings.BaseEffort / 10);
            return(result.ToString());
        }
Ejemplo n.º 2
0
        public override string GetInspectString()
        {
            StringBuilder stringBuilder = new StringBuilder();

            stringBuilder.Append(base.GetInspectString());
            if (stringBuilder.Length != 0)
            {
                stringBuilder.AppendLine();
            }
            if (this.Next is null)
            {
                stringBuilder.Append("Goal");
            }
            else
            {
                stringBuilder.Append("RoadsOfTheRim_siteInspectString".Translate(this.GetSite().roadDef.label, string.Format("{0:0.0}", this.GetSite().roadDef.movementCostMultiplier)));

                float totalCostModifier = 0f;
                stringBuilder.Append(WorldObjectComp_ConstructionSite.CostModifersDescription(this.Tile, this.Next.Tile, ref totalCostModifier));

                // Show costs
                WorldObjectComp_ConstructionSite SiteComp = this.GetSite().GetComponent <WorldObjectComp_ConstructionSite>();
                foreach (string resourceName in DefModExtension_RotR_RoadDef.allResourcesAndWork)
                {
                    if (SiteComp.GetCost(resourceName) > 0)
                    {
                        // The cost modifier doesn't affect some advanced resources, as defined in static DefModExtension_RotR_RoadDef.allResourcesWithoutModifiers
                        // TO DO : COuld this be combined with WorldObjectComp_ConstructionSite.setCosts() ? shares a lot in common except rebates. Can we really calcualte rebate on a leg ?
                        float costModifierForThisResource = ((DefModExtension_RotR_RoadDef.allResourcesWithoutModifiers.Contains(resourceName)) ? 1 : totalCostModifier);
                        stringBuilder.AppendLine();
                        stringBuilder.Append((int)SiteComp.GetCost(resourceName) * costModifierForThisResource + " " + resourceName);
                    }
                }
            }

            return(stringBuilder.ToString());
        }
Ejemplo n.º 3
0
        public string progressDescription()
        {
            RoadConstructionSite parentSite    = this.parent as RoadConstructionSite;
            StringBuilder        stringBuilder = new StringBuilder();

            stringBuilder.Append("RoadsOfTheRim_ConstructionSiteDescription_Main".Translate(String.Format("{0:P1}", GetPercentageDone("Work"))));

            // Description of ally's help, if any
            if (parentSite.helpFromFaction != null)
            {
                stringBuilder.Append("RoadsOfTheRim_ConstructionSiteDescription_Help".Translate(parentSite.helpFromFaction.Name, (int)parentSite.helpAmount, String.Format("{0:0.0}", parentSite.helpWorkPerTick)));
                if (parentSite.helpFromTick > Find.TickManager.TicksGame)
                {
                    stringBuilder.Append("RoadsOfTheRim_ConstructionSiteDescription_HelpStartsWhen".Translate(String.Format("{0:0.00}", (float)(parentSite.helpFromTick - Find.TickManager.TicksGame) / (float)GenDate.TicksPerDay)));
                }
            }

            // Show total cost modifiers
            float totalCostModifier = 0f;

            stringBuilder.Append(WorldObjectComp_ConstructionSite.CostModifersDescription(parentSite.Tile, parentSite.GetNextLeg().Tile, ref totalCostModifier));

            List <Caravan> AllCaravansHere = new List <Caravan>();

            Find.WorldObjects.GetPlayerControlledCaravansAt(parentSite.Tile, AllCaravansHere);
            int ISR2G = 0;

            foreach (Caravan c in AllCaravansHere)
            {
                int caravanISR2G = c.GetComponent <WorldObjectComp_Caravan>().useISR2G();
                if (caravanISR2G > ISR2G)
                {
                    ISR2G = caravanISR2G;
                }
            }

            // Per resource : show costs & how much is left to do
            foreach (string resourceName in DefModExtension_RotR_RoadDef.allResourcesAndWork)
            {
                if (GetCost(resourceName) > 0)
                {
                    stringBuilder.AppendLine();
                    string ISR2Gmsg = "";
                    if (ISR2G > 0)
                    {
                        if (resourceName == "Work")
                        {
                            ISR2Gmsg = (ISR2G == 1 ? "RoadsOfTheRim_ConstructionSiteDescription_ISR2Gwork".Translate() : "RoadsOfTheRim_ConstructionSiteDescription_AISR2Gwork".Translate());
                        }
                        else if (DefModExtension_RotR_RoadDef.GetInSituModifier(resourceName, ISR2G))
                        {
                            ISR2Gmsg = (ISR2G == 1 ? "RoadsOfTheRim_ConstructionSiteDescription_ISR2GFree".Translate() : "RoadsOfTheRim_ConstructionSiteDescription_AISR2GFree".Translate());
                        }
                    }
                    stringBuilder.Append("RoadsOfTheRim_ConstructionSiteDescription_Resource".Translate(
                                             resourceName,
                                             String.Format((resourceName == "Work" ? "{0:##.00}" : "{0:##}"), GetLeft(resourceName)), // Only Work should be shown with 2 decimals
                                             (int)GetCost(resourceName),
                                             ISR2Gmsg
                                             ));
                }
            }

            return(stringBuilder.ToString());
        }
Ejemplo n.º 4
0
        /*
         * Based on the Caravan's resources, Pawns & the road's cost (modified by terrain) :
         * - Determine the amount of work done in a tick
         * - Consume the caravan's resources
         * - Return whether or not the Caravan must now stop because it ran out of resources
         * - NOTE : Does this need to be here ? Maybe better in Mod.cs
         * Returns TRUE if work finished
         * CALLED FROM : CompTick() of WorldObjectComp_Caravan
         */
        public static bool doSomeWork(Caravan caravan, RoadConstructionSite site, out bool noMoreResources)
        {
            WorldObjectComp_Caravan          caravanComp      = caravan.GetComponent <WorldObjectComp_Caravan>();
            WorldObjectComp_ConstructionSite siteComp         = site.GetComponent <WorldObjectComp_ConstructionSite>();
            DefModExtension_RotR_RoadDef     roadDefExtension = site.roadDef.GetModExtension <DefModExtension_RotR_RoadDef>();

            noMoreResources = false;
            int useISR2G = caravanComp.useISR2G();
            Dictionary <string, int>   available = new Dictionary <string, int>();
            Dictionary <string, int>   needed    = new Dictionary <string, int>();
            Dictionary <string, float> ratio     = new Dictionary <string, float>();
            float ratio_final = 1;

            //RoadsOfTheRim.DebugLog("[RotR] DEBUG ========== doSomeWork() ==========");
            //RoadsOfTheRim.DebugLog("[RotR] DEBUG ISR2G set to "+useISR2G);

            if (DebugSettings.godMode)
            {
                return(siteComp.finishWork(caravan));
            }

            if (caravanComp.CaravanCurrentState() != CaravanState.ReadyToWork)
            {
                RoadsOfTheRim.DebugLog("[RotR] DEBUG : doSomeWork() failed because the caravan can't work.");
                return(false);
            }

            // Percentage of total work that can be done in this batch, might be 0 if no pawn was found with enough skill
            float amountOfWork = caravanComp.amountOfWork(true);

            // Work was 0 (not enough skill)
            if (Math.Abs(amountOfWork) < Double.Epsilon)
            {
                Messages.Message("RoadsOfTheRim_CaravanNoWork".Translate(caravan.Name, site.roadDef.label), MessageTypeDefOf.RejectInput);
                caravanComp.stopWorking();
                return(false);
            }

            // calculate material present in the caravan
            foreach (string resourceName in DefModExtension_RotR_RoadDef.allResources)
            {
                available[resourceName] = 0;
            }

            foreach (Thing aThing in CaravanInventoryUtility.AllInventoryItems(caravan))
            {
                foreach (string resourceName in DefModExtension_RotR_RoadDef.allResources)
                {
                    if (isThis(aThing.def, resourceName))
                    {
                        available[resourceName] += aThing.stackCount;
                    }
                }
            }

            // What percentage of work will remain after amountOfWork is done ?
            float percentOfWorkLeftToDoAfter = (siteComp.GetLeft("Work") - amountOfWork) / siteComp.GetCost("Work");

            // The amount of each resource left to spend in total is : percentOfWorkLeftToDoAfter * {this resource cost}
            // Materials that would be needed to do that much work
            foreach (string resourceName in DefModExtension_RotR_RoadDef.allResources)
            {
                needed[resourceName] = (int)Math.Round(siteComp.GetLeft(resourceName) - (percentOfWorkLeftToDoAfter * siteComp.GetCost(resourceName)));
                // Check if there's enough material to go through this batch. Materials with a cost of 0 are always OK
                // Don't check when ISR2G is in use for this resource, don't check for work
                if (!DefModExtension_RotR_RoadDef.GetInSituModifier(resourceName, useISR2G) && resourceName != "Work")
                {
                    ratio[resourceName] = (needed[resourceName] == 0 ? 1f : Math.Min((float)available[resourceName] / (float)needed[resourceName], 1f));
                    if (ratio[resourceName] < ratio_final)
                    {
                        ratio_final = ratio[resourceName];
                    }
                }
            }

            // The caravan didn't have enough resources for a full batch of work. Use as much as we can then stop working
            if (ratio_final < 1f)
            {
                Messages.Message("RoadsOfTheRim_CaravanNoResource".Translate(caravan.Name, site.roadDef.label), MessageTypeDefOf.RejectInput);
                foreach (string resourceName in DefModExtension_RotR_RoadDef.allResources)
                {
                    needed[resourceName] = (int)(needed[resourceName] * ratio_final);
                }
                caravanComp.stopWorking();
            }
            //RoadsOfTheRim.DebugLog("[RotR] ISR2G DEBUG ratio final = " + ratio_final);

            // Consume resources from the caravan
            bool ResourcesHaveBeenConsumed = (site.roadDef.defName == "DirtPathBuilt");  // Always consider resources have been consumed when the road is a dirt path

            foreach (Thing aThing in CaravanInventoryUtility.AllInventoryItems(caravan))
            {
                foreach (string resourceName in DefModExtension_RotR_RoadDef.allResources)
                {
                    if (!DefModExtension_RotR_RoadDef.GetInSituModifier(resourceName, useISR2G))
                    {
                        if (needed[resourceName] > 0 && isThis(aThing.def, resourceName))
                        {
                            int amountUsed = (aThing.stackCount > needed[resourceName]) ? needed[resourceName] : aThing.stackCount;
                            aThing.stackCount -= amountUsed;
                            // Reduce how much of this resource is needed
                            needed[resourceName] -= amountUsed;
                            siteComp.ReduceLeft(resourceName, amountUsed);
                            //RoadsOfTheRim.DebugLog("[RotR] ISR2G consumption DEBUG =" + resourceName + " Qty consumed = " + amountUsed);
                        }
                    }
                    else
                    {
                        if (needed[resourceName] > 0)
                        {
                            //RoadsOfTheRim.DebugLog("[RotR] ISR2G consumption DEBUG =" + resourceName + " Qty freely awarded = " + needed[resourceName]);
                            siteComp.ReduceLeft(resourceName, needed[resourceName]);
                            needed[resourceName] = 0;
                        }
                    }
                }
                if (aThing.stackCount == 0)
                {
                    aThing.Destroy();
                }
            }

            caravanComp.teachPawns(ratio_final); // Pawns learn some construction
            // HARDCODED : ISR2G divides work done by 4 , AISR2G by 2 for all roads except dirt path
            if (useISR2G > 0 && site.roadDef.defName != "DirtPathBuilt")
            {
                amountOfWork = amountOfWork * 0.25f * useISR2G;
            }
            // Update amountOfWork based on the actual ratio worked & finally reducing the work & resources left
            amountOfWork = ratio_final * amountOfWork;
            return(siteComp.UpdateProgress(amountOfWork, caravan));
        }