Exemplo n.º 1
0
        // TO DO : Use the below to dynamically draw the window based on number of buildable roads (which could include technolcogy limits)
        // public bool resizeable = true ;
        // private bool resizeLater = true ;
        // private Rect resizeLaterRect ;


        public ConstructionMenu(RoadConstructionSite site, Caravan caravan)
        {
            this.site      = site;
            this.caravan   = caravan;
            buildableRoads = new List <RoadDef>();
            // TO DO : COunt number of buildable roads, set the resize later rect based on that
        }
Exemplo n.º 2
0
 /*Delete Cosntruction Site once it's been confirmed, or no confirmation was necessary */
 public static void DeleteConstructionSiteConfirmed(RoadConstructionSite ConstructionSite)
 {
     if (ConstructionSite.helpFromFaction != null)
     {
         RoadsOfTheRim.factionsHelp.helpFinished(ConstructionSite.helpFromFaction);
     }
     RoadConstructionSite.DeleteSite(ConstructionSite);
 }
Exemplo n.º 3
0
        /*Delete Cosntruction Site once it's been confirmed, or no confirmation was necessary */
        private static void DeleteConstructionSiteConfirmed(RoadConstructionSite ConstructionSite)
        {
            if (ConstructionSite.helpFromFaction != null)
            {
                FactionsHelp.HelpFinished(ConstructionSite.helpFromFaction);
            }

            RoadConstructionSite.DeleteSite(ConstructionSite);
        }
Exemplo n.º 4
0
        /********************************
        * Gizmos commands              *
        ********************************/

        public static Command AddConstructionSite(Caravan caravan)
        {
            Command_Action command_Action = new Command_Action();

            command_Action.defaultLabel = "RoadsOfTheRimAddConstructionSite".Translate();
            command_Action.defaultDesc  = "RoadsOfTheRimAddConstructionSiteDescription".Translate();
            command_Action.icon         = ContentFinder <Texture2D> .Get("UI/Commands/AddConstructionSite", true);

            command_Action.action = delegate()
            {
                RoadConstructionSite constructionSite = (RoadConstructionSite)WorldObjectMaker.MakeWorldObject(DefDatabase <WorldObjectDef> .GetNamed("RoadConstructionSite", true));
                constructionSite.Tile = caravan.Tile;
                Find.WorldObjects.Add(constructionSite);

                ConstructionMenu menu = new ConstructionMenu(constructionSite, caravan);

                if (menu.CountBuildableRoads() == 0)
                {
                    Find.WorldObjects.Remove(constructionSite);
                    Messages.Message("RoadsOfTheRim_NoBetterRoadCouldBeBuilt".Translate(), MessageTypeDefOf.RejectInput);
                }
                else
                {
                    menu.closeOnClickedOutside = true;
                    menu.forcePause            = true;
                    Find.WindowStack.Add(menu);
                }
            };

            // Disable if there's already a construction site here
            if (Find.WorldObjects.AnyWorldObjectOfDefAt(DefDatabase <WorldObjectDef> .GetNamed("RoadConstructionSite", true), caravan.Tile))
            {
                command_Action.Disable("RoadsOfTheRimBuildConstructionSiteAlreadyHere".Translate());
            }

            // disable if the caravan can't work OR if the site is not ready
            if (caravan.GetComponent <WorldObjectComp_Caravan>().CaravanCurrentState() != CaravanState.ReadyToWork)
            {
                command_Action.Disable("RoadsOfTheRimBuildWorkOnSiteCantWork".Translate());
            }

            // Disable on biomes that don't allow roads
            // TO DO : did that ever belong here ? testing for each leg should be enough except if somehow a caravan is in an ocean (glitter road ?) building a lower tier road towards the shore ?
            // In which case, problem is easy to resolve : limit the roads that can be chosen in the menu

            /*
             * BiomeDef biomeHere = Find.WorldGrid.tiles[caravan.Tile].biome ;
             * if (!biomeHere.allowRoads)
             * {
             *  command_Action.Disable("RoadsOfTheRim_BiomePreventsConstruction".Translate(biomeHere.label));
             * }
             */
            return(command_Action);
        }
Exemplo n.º 5
0
 public static void FinaliseConstructionSite(RoadConstructionSite site)
 {
     if (site.GetNextLeg() != null)
     {
         site.GetComponent <WorldObjectComp_ConstructionSite>().SetCosts();
         RoadBuildingState.Caravan.GetComponent <WorldObjectComp_Caravan>().StartWorking();
     }
     else
     {
         RoadConstructionSite.DeleteSite(site);
     }
 }
 private void SetSiteFromTile()
 {
     try
     {
         site = (RoadConstructionSite)Find.WorldObjects.WorldObjectOfDefAt(
             DefDatabase <WorldObjectDef> .GetNamed("RoadConstructionSite"), GetCaravan().Tile);
     }
     catch (Exception e)
     {
         RoadsOfTheRim.DebugLog("", e);
     }
 }
Exemplo n.º 7
0
        public void setCosts()
        {
            try
            {
                RoadsOfTheRimSettings settings   = LoadedModManager.GetMod <RoadsOfTheRim>().GetSettings <RoadsOfTheRimSettings>();
                RoadConstructionSite  parentSite = this.parent as RoadConstructionSite;

                float elevationModifier  = 0f;
                float hillinessModifier  = 0f;
                float swampinessModifier = 0f;
                float bridgeModifier     = 0f;
                GetCostsModifiers(parentSite.Tile, parentSite.GetNextLeg().Tile, ref elevationModifier, ref hillinessModifier, ref swampinessModifier, ref bridgeModifier);

                // Total cost modifier
                float totalCostModifier = (1 + elevationModifier + hillinessModifier + swampinessModifier + bridgeModifier) * ((float)settings.BaseEffort / 10);

                DefModExtension_RotR_RoadDef roadDefExtension = parentSite.roadDef.GetModExtension <DefModExtension_RotR_RoadDef>();

                // Check existing roads for potential rebates when upgrading
                GetUpgradeModifiers(parentSite.Tile, parentSite.GetNextLeg().Tile, parentSite.roadDef, out Dictionary <string, int> rebate);

                List <string> s = new List <string>();
                foreach (string resourceName in DefModExtension_RotR_RoadDef.allResourcesAndWork)
                {
                    if (roadDefExtension.GetCost(resourceName) > 0)
                    {
                        int thisRebate = 0;
                        // The cost modifier doesn't affect some advanced resources, as defined in static DefModExtension_RotR_RoadDef.allResourcesWithoutModifiers
                        float costModifierForThisResource = ((DefModExtension_RotR_RoadDef.allResourcesWithoutModifiers.Contains(resourceName)) ? 1 : totalCostModifier);
                        rebate.TryGetValue(resourceName, out thisRebate);
                        // Minimum cost of anything that's needed is 1
                        costs[resourceName] = Math.Max((int)((roadDefExtension.GetCost(resourceName) - thisRebate) * costModifierForThisResource), 1);
                        left[resourceName]  = Math.Max(costs[resourceName], 1f);
                        if (thisRebate > 0)
                        {
                            s.Add("RoadsOfTheRim_UpgradeRebateDetail".Translate((int)(thisRebate * costModifierForThisResource), resourceName));
                        }
                    }
                }

                if (s.Count > 0)
                {
                    Messages.Message("RoadsOfTheRim_UpgradeRebate".Translate(parentSite.roadDef.label, string.Join(", ", s.ToArray())), MessageTypeDefOf.PositiveEvent);
                }

                parentSite.UpdateProgressBarMaterial();
            }
            catch (Exception e)
            {
                Log.Error("[RotR] : Exception when setting constructionSite costs = " + e);
            }
        }
Exemplo n.º 8
0
 public bool setSiteFromTile()
 {
     try
     {
         site = (RoadConstructionSite)Find.WorldObjects.WorldObjectOfDefAt(DefDatabase <WorldObjectDef> .GetNamed("RoadConstructionSite", true), (GetCaravan().Tile));
         return(true);
     }
     catch (Exception e)
     {
         RoadsOfTheRim.DebugLog("", e);
         return(false);
     }
 }
Exemplo n.º 9
0
 public static void Target(RoadConstructionSite site)
 {
     // Log.Warning("[RotR] - Target(site)");
     Find.WorldTargeter.BeginTargeting(delegate(GlobalTargetInfo target)
     {
         return(RoadConstructionLeg.ActionOnTile(site, target.Tile));
     },
                                       true, RotR_StaticConstructorOnStartup.ConstructionLeg_MouseAttachment, false, null,
                                       delegate(GlobalTargetInfo target)
     {
         return("RoadsOfTheRim_BuildToHere".Translate());
     });
 }
Exemplo n.º 10
0
        public float helpWorkPerTick;   // How much will the faction help per tick

        public static void DeleteSite(RoadConstructionSite site)
        {
            IEnumerable <WorldObject> constructionLegs = Find.WorldObjects.AllWorldObjects.Cast <WorldObject>().Where(
                leg => leg.def == DefDatabase <WorldObjectDef> .GetNamed("RoadConstructionLeg", true) &&
                ((RoadConstructionLeg)leg).GetSite() == site
                ).ToArray();

            foreach (RoadConstructionLeg l in constructionLegs)
            {
                Find.WorldObjects.Remove(l);
            }
            Find.WorldObjects.Remove(site);
        }
Exemplo n.º 11
0
        public bool UpdateProgress(float amountOfWork, Caravan caravan = null)
        {
            RoadConstructionSite parentSite = this.parent as RoadConstructionSite;

            ReduceLeft("Work", amountOfWork);

            parentSite.UpdateProgressBarMaterial();

            // Work is done
            if (GetLeft("Work") <= 0)
            {
                return(finishWork(caravan));
            }
            return(false);
        }
Exemplo n.º 12
0
        public void EndConstruction(Caravan caravan = null)
        {
            RoadConstructionSite parentSite = this.parent as RoadConstructionSite;

            // On the last leg, send letter & remove the construction site
            Find.LetterStack.ReceiveLetter(
                "RoadsOfTheRim_RoadBuilt".Translate(),
                "RoadsOfTheRim_RoadBuiltLetterText".Translate(parentSite.roadDef.label, (caravan != null ? (TaggedString)caravan.Label : "RoadsOfTheRim_RoadBuiltByAlly".Translate())),
                LetterDefOf.PositiveEvent,
                new GlobalTargetInfo(parentSite.Tile)
                );
            Find.World.worldObjects.Remove(parentSite);
            if (parentSite.helpFromFaction != null)
            {
                RoadsOfTheRim.factionsHelp.helpFinished(parentSite.helpFromFaction);
            }
        }
Exemplo n.º 13
0
        public void startHelping(Faction faction, RoadConstructionSite site, Pawn negotiator)
        {
            // Test success or failure of the negotiator, plus amount of help obtained (based on negotiation value & roll)
            float negotiationValue = negotiator.GetStatValue(StatDefOf.NegotiationAbility, true);
            float failChance       = helpRequestFailChance / negotiationValue;
            float roll             = Rand.Value;
            float amountOfHelp     = helpBaseAmount * (1 + negotiationValue * roll * 5);
            //Log.Message(String.Format("[RotR] - Negotiation for road construction help : negotiation value = {0:0.00} , fail chance = {1:P} , roll = {2:0.00} , help = {3:0.00}", negotiationValue , failChance, roll , amountOfHelp));

            // Calculate how long the faction needs to start helping
            SettlementInfo closestSettlement = site.closestSettlementOfFaction(faction);
            int            tick = Find.TickManager.TicksGame + closestSettlement.distance;

            // Determine amount of help per tick
            float amountPerTick = Math.Max(Rand.Gaussian(helpPerTickMedian, helpPerTickVariance), helpPerTickMin);

            setCurrentlyHelping(faction);
            site.initiateFactionHelp(faction, tick, amountOfHelp, amountPerTick);
        }
Exemplo n.º 14
0
        /*Delete Construction Site    */
        public static void DeleteConstructionSite(int tile)
        {
            RoadConstructionSite ConstructionSite = (RoadConstructionSite)Find.WorldObjects.WorldObjectOfDefAt(DefDatabase <WorldObjectDef> .GetNamed("RoadConstructionSite", true), tile);

            if (ConstructionSite != null)
            {
                // Confirm construction site deletion if resources were already consumed
                string s = ConstructionSite.ResourcesAlreadyConsumed();
                if (!s.NullOrEmpty())
                {
                    Find.WindowStack.Add(Dialog_MessageBox.CreateConfirmation("RoadsOfTheRim_ConfirmDestroyResourcesAlreadyConsumed".Translate(s), delegate
                    {
                        DeleteConstructionSiteConfirmed(ConstructionSite);
                    }, false, null));
                }
                else
                {
                    DeleteConstructionSiteConfirmed(ConstructionSite);
                }
            }
        }
Exemplo n.º 15
0
        /*
         * Remove all legs up to and including the one passed in argument
         */
        public static void Remove(RoadConstructionLeg leg)
        {
            RoadConstructionSite site       = leg.site;
            RoadConstructionLeg  CurrentLeg = (RoadConstructionLeg)site.LastLeg;

            while (CurrentLeg != leg.previous)
            {
                if (CurrentLeg.previous != null)
                {
                    RoadConstructionLeg PreviousLeg = CurrentLeg.previous;
                    PreviousLeg.SetNext(null);
                    site.LastLeg = PreviousLeg;
                    Find.WorldObjects.Remove(CurrentLeg);
                    CurrentLeg = PreviousLeg;
                }
                else
                {
                    Find.WorldObjects.Remove(CurrentLeg);
                    site.LastLeg = site;
                    break;
                }
            }
        }
Exemplo n.º 16
0
        /*
         * Build the road and move the construction site
         */
        public bool finishWork(Caravan caravan = null)
        {
            RoadConstructionSite parentSite = this.parent as RoadConstructionSite;
            int  fromTile_int = parentSite.Tile;
            int  toTile_int   = parentSite.GetNextLeg().Tile;
            Tile fromTile     = Find.WorldGrid[fromTile_int];
            Tile toTile       = Find.WorldGrid[toTile_int];

            // Remove lesser roads, they don't deserve to live
            if (fromTile.potentialRoads != null)
            {
                foreach (Tile.RoadLink aLink in fromTile.potentialRoads.ToArray())
                {
                    if (aLink.neighbor == toTile_int & RoadsOfTheRim.isRoadBetter(parentSite.roadDef, aLink.road))
                    {
                        fromTile.potentialRoads.Remove(aLink);
                    }
                }
            }
            else
            {
                fromTile.potentialRoads = new List <Tile.RoadLink>();
            }

            if (toTile.potentialRoads != null)
            {
                foreach (Tile.RoadLink aLink in toTile.potentialRoads.ToArray())
                {
                    if (aLink.neighbor == parentSite.Tile & RoadsOfTheRim.isRoadBetter(parentSite.roadDef, aLink.road))
                    {
                        toTile.potentialRoads.Remove(aLink);
                    }
                }
            }
            else
            {
                toTile.potentialRoads = new List <Tile.RoadLink>();
            }

            // Add the road to fromTile & toTile
            fromTile.potentialRoads.Add(new Tile.RoadLink {
                neighbor = toTile_int, road = parentSite.roadDef
            });
            toTile.potentialRoads.Add(new Tile.RoadLink {
                neighbor = fromTile_int, road = parentSite.roadDef
            });
            try
            {
                Find.World.renderer.SetDirty <WorldLayer_Roads>();
                Find.World.renderer.SetDirty <WorldLayer_Paths>();
                Find.WorldPathGrid.RecalculatePerceivedMovementDifficultyAt(fromTile_int);
                Find.WorldPathGrid.RecalculatePerceivedMovementDifficultyAt(toTile_int);
            }
            catch (Exception e)
            {
                RoadsOfTheRim.DebugLog("[RotR] Exception : ", e);
            }

            // The Construction site and the caravan can move to the next leg
            RoadConstructionLeg nextLeg = parentSite.GetNextLeg();

            if (nextLeg != null)
            {
                int CurrentTile = parentSite.Tile;
                parentSite.Tile = nextLeg.Tile;
                RoadConstructionLeg nextNextLeg = nextLeg.Next;
                // TO DO Here : Check if there's an existing road that is the same or better as the one being built. If there is, skip the next leg
                if (nextNextLeg != null)
                {
                    nextNextLeg.Previous = null;
                    setCosts();
                    parentSite.MoveWorkersToNextLeg(CurrentTile); // Move any caravans working on this site to the next leg, and delay faction help if any
                }
                else
                {
                    EndConstruction(caravan);  // We have built the last leg. Notify & remove the site
                }
                Find.World.worldObjects.Remove(nextLeg);
            }

            return(true);
        }
Exemplo n.º 17
0
 public WorldComponent_RoadBuildingState(World world) : base(world)
 {
     currentlyTargeting = null;
 }
Exemplo n.º 18
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());
        }
Exemplo n.º 19
0
        // Here, test if we picked a tile that's already part of the chain for this construction site (different construction sites can cross each other's paths)
        // Yes ->
        //      Was it the construction site itself ?
        //      Yes -> We are done creating the site
        //      No ->  delete this leg and all legs after it
        // No -> create a new Leg
        public static bool ActionOnTile(RoadConstructionSite site, int tile)
        {
            if (site.def != DefDatabase <WorldObjectDef> .GetNamed("RoadConstructionSite", true))
            {
                Log.Error("[RotR] - The RoadConstructionSite given is somehow wrong");
                return(true);
            }
            try
            {
                foreach (WorldObject o in Find.WorldObjects.ObjectsAt(tile))
                {
                    // Action on the construction site = we're done
                    if ((o.def == DefDatabase <WorldObjectDef> .GetNamed("RoadConstructionSite", true)) && (RoadConstructionSite)o == site)
                    {
                        return(true);
                    }
                    // Action on a leg that's part of this chain = we should delete all legs after that & keep targetting
                    if ((o.def == DefDatabase <WorldObjectDef> .GetNamed("RoadConstructionLeg", true)) && ((RoadConstructionLeg)o).site == site)
                    {
                        RoadConstructionLeg.Remove((RoadConstructionLeg)o);
                        Target(site);
                        return(false);
                    }
                }

                // Check whether we clicked on a neighbour
                List <int> neighbouringTiles = new List <int>();
                Find.WorldGrid.GetTileNeighbors(tile, neighbouringTiles);
                // This is not a neighbour : do nothing
                if (!neighbouringTiles.Contains(site.LastLeg.Tile))
                {
                    Target(site);
                    return(false);
                }

                // There can be no ConstructionLeg on a biome that doesn't allow roads
                if (!DefModExtension_RotR_RoadDef.BiomeAllowed(tile, site.roadDef, out BiomeDef biomeHere))
                {
                    Messages.Message("RoadsOfTheRim_BiomePreventsConstruction".Translate(site.roadDef.label, biomeHere.label), MessageTypeDefOf.RejectInput);
                    Target(site);
                    return(false);
                }
                else if (!DefModExtension_RotR_RoadDef.ImpassableAllowed(tile, site.roadDef))
                {
                    Messages.Message("RoadsOfTheRim_BiomePreventsConstruction".Translate(site.roadDef.label, " impassable mountains"), MessageTypeDefOf.RejectInput);
                    Target(site);
                    return(false);
                }

                RoadConstructionLeg newLeg = (RoadConstructionLeg)WorldObjectMaker.MakeWorldObject(DefDatabase <WorldObjectDef> .GetNamed("RoadConstructionLeg", true));
                newLeg.Tile = tile;
                newLeg.site = site;
                // This is not the first Leg
                if (site.LastLeg.def == DefDatabase <WorldObjectDef> .GetNamed("RoadConstructionLeg", true))
                {
                    RoadConstructionLeg l = site.LastLeg as RoadConstructionLeg;
                    l.SetNext(newLeg);
                    newLeg.previous = l;
                }
                else
                {
                    newLeg.previous = null;
                }
                newLeg.SetNext(null);
                Find.WorldObjects.Add(newLeg);
                site.LastLeg = newLeg;
                Target(site);
                return(false);
            }
            catch (Exception e)
            {
                Log.Error("[RotR] Exception : " + e);
                return(true);
            }
        }
Exemplo n.º 20
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)
        {
            var caravanComp = caravan.GetComponent <WorldObjectComp_Caravan>();
            var siteComp    = site.GetComponent <WorldObjectComp_ConstructionSite>();

            _ = site.roadDef.GetModExtension <DefModExtension_RotR_RoadDef>();
            noMoreResources = false;
            var   useISR2G    = caravanComp.UseISR2G();
            var   available   = new Dictionary <string, int>();
            var   needed      = new Dictionary <string, int>();
            var   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)
            {
                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
            var 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 (var resourceName in DefModExtension_RotR_RoadDef.allResources)
            {
                available[resourceName] = 0;
            }

            foreach (var aThing in CaravanInventoryUtility.AllInventoryItems(caravan))
            {
                foreach (var 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 ?
            var 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 (var 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")
                {
                    continue;
                }

                ratio[resourceName] = needed[resourceName] == 0
                    ? 1f
                    : Math.Min(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 (var 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
            _ = site.roadDef.defName ==
                "DirtPathBuilt"; // Always consider resources have been consumed when the road is a dirt path
            foreach (var aThing in CaravanInventoryUtility.AllInventoryItems(caravan))
            {
                foreach (var resourceName in DefModExtension_RotR_RoadDef.allResources)
                {
                    if (!DefModExtension_RotR_RoadDef.GetInSituModifier(resourceName, useISR2G))
                    {
                        if (needed[resourceName] <= 0 || !IsThis(aThing.def, resourceName))
                        {
                            continue;
                            //RoadsOfTheRim.DebugLog("[RotR] ISR2G consumption DEBUG =" + resourceName + " Qty consumed = " + amountUsed);
                        }

                        var 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);
                    }
                    else
                    {
                        if (needed[resourceName] <= 0)
                        {
                            continue;
                        }

                        //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));
        }
Exemplo n.º 21
0
 public void unsetSite()
 {
     site = null;
 }
 private void UnsetSite()
 {
     site = null;
 }