示例#1
0
        public void TryToSkipBetterRoads(Caravan caravan = null)
        {
            RoadConstructionLeg nextLeg = GetNextLeg();

            if (nextLeg != null) // nextLeg == null should never happen
            {
                RoadDef bestExistingRoad = RoadsOfTheRim.BestExistingRoad(Tile, nextLeg.Tile);
                // We've found an existing road that is better than the one we intend to build : skip this leg and move to the next
                if (!RoadsOfTheRim.isRoadBetter(roadDef, bestExistingRoad))
                {
                    Messages.Message("RoadsOfTheRim_BetterRoadFound".Translate(caravan.Name, bestExistingRoad.label, roadDef.label), MessageTypeDefOf.NeutralEvent);
                    int currentTile = Tile;
                    Tile = nextLeg.Tile; // The construction site moves to the next leg
                    RoadConstructionLeg nextNextLeg = nextLeg.Next;
                    if (nextNextLeg != null)
                    {
                        nextNextLeg.Previous = null;  // The nextNext leg is now the next
                        GetComponent <WorldObjectComp_ConstructionSite>().setCosts();
                        MoveWorkersToNextLeg(currentTile);
                    }
                    else // Finish construction
                    {
                        GetComponent <WorldObjectComp_ConstructionSite>().EndConstruction(caravan);
                    }
                    Find.World.worldObjects.Remove(nextLeg);
                }
            }
        }
示例#2
0
        public void MoveWorkersToNextLeg(int fromTile)
        {
            RoadConstructionLeg nextLeg = GetNextLeg();

            if (nextLeg != null)
            {
                List <Caravan> CaravansWorkingHere = new List <Caravan>();
                Find.WorldObjects.GetPlayerControlledCaravansAt(fromTile, CaravansWorkingHere);
                foreach (Caravan c in CaravansWorkingHere) // Move to the nextLeg all caravans that are currently set to work on this site
                {
                    if (c.GetComponent <WorldObjectComp_Caravan>().getSite() == this)
                    {
                        c.pather.StartPath(Tile, new CaravanArrivalAction_StartWorkingOnRoad());
                    }
                }
                if (helpFromFaction != null) // Delay when the help starts on the next leg by as many ticks as it would take a caravan to travel from the site to the next leg
                {
                    int delay = CaravanArrivalTimeEstimator.EstimatedTicksToArrive(fromTile, Tile, null);
                    if (helpFromTick > Find.TickManager.TicksGame)
                    {
                        helpFromTick += delay;
                    }
                    else
                    {
                        helpFromTick = Find.TickManager.TicksGame + delay;
                    }
                }
            }
        }
示例#3
0
 public void SetNext(RoadConstructionLeg nextLeg)
 {
     try
     {
         next = nextLeg;
     }
     catch (Exception e)
     {
         Log.Error("[RotR] Exception : " + e);
     }
 }
示例#4
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());
     });
 }
示例#5
0
 /*
  * Returns the next leg in the chain, or null if all is left is the construction site (which should never happen, since it should get destroyed when the last leg is built)
  */
 public RoadConstructionLeg GetNextLeg()
 {
     if (LastLeg != this)
     {
         RoadConstructionLeg CurrentLeg = (RoadConstructionLeg)LastLeg;
         while (CurrentLeg.Previous != null)
         {
             CurrentLeg = CurrentLeg.Previous;
         }
         return((RoadConstructionLeg)CurrentLeg);
     }
     return(null);
 }
示例#6
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;
                }
            }
        }
示例#7
0
        public override void DoWindowContents(Rect inRect)
        {
            if (Event.current.isKey && site != null)
            {
                RoadsOfTheRim.DeleteConstructionSite(site.Tile);
                Close();
            }

            //Resources icons
            for (var i = 0; i < 9; i++)
            {
                // Icon
                var      ResourceRect = new Rect(0, 202f + (i * 40f), 32f, 32f);
                ThingDef theDef;
                switch (i)
                {
                case 0:
                    theDef = ThingDefOf.Spark;
                    break;

                case 1:
                    theDef = ThingDefOf.WoodLog;
                    break;

                case 2:
                    theDef = ThingDefOf.BlocksGranite;
                    break;

                case 3:
                    theDef = ThingDefOf.Steel;
                    break;

                case 4:
                    theDef = ThingDefOf.Chemfuel;
                    break;

                case 5:
                    theDef = ThingDefOf.Plasteel;
                    break;

                case 6:
                    theDef = ThingDefOf.Uranium;
                    break;

                case 7:
                    theDef = ThingDefOf.ComponentIndustrial;
                    break;

                default:
                    theDef = ThingDefOf.ComponentSpacer;
                    break;
                }

                if (i == 0)
                {
                    Widgets.ButtonImage(ResourceRect, ContentFinder <Texture2D> .Get("UI/Commands/AddConstructionSite"));
                }
                else
                {
                    Widgets.ThingIcon(ResourceRect, theDef);
                }
            }

            // Sections : one per type of buildable road
            var nbOfSections = 0;
            var groupSize    = new Vector2(144, 512 + 128);

            foreach (var aDef in buildableRoads)
            {
                var roadDefExtension = aDef.GetModExtension <DefModExtension_RotR_RoadDef>();

                // Check if a tech is necessary to build this road, don't display the road if it isn't researched yet
                var NeededTech     = roadDefExtension.techNeededToBuild;
                var TechResearched = NeededTech == null || NeededTech.IsFinished;

                if (!TechResearched)
                {
                    continue;
                }

                GUI.BeginGroup(new Rect(new Vector2(64 + (144 * nbOfSections), 32f), groupSize));

                // Buildable Road icon
                var theButton = ContentFinder <Texture2D> .Get("UI/Commands/Build_" + aDef.defName);

                var ButtonRect = new Rect(8, 8, 128, 128);
                if (Widgets.ButtonImage(ButtonRect, theButton))
                {
                    if (Event.current.button == 0)
                    {
                        SoundDefOf.Tick_High.PlayOneShotOnCamera();
                        if (site != null)
                        {
                            site.roadDef = aDef;
                            Close();
                            RoadsOfTheRim.RoadBuildingState.CurrentlyTargeting = site;
                            RoadsOfTheRim.RoadBuildingState.Caravan            = caravan;
                            RoadConstructionLeg.Target(site);
                        }
                    }
                }

                // Buildable Road label
                Text.Anchor = TextAnchor.MiddleCenter;
                Text.Font   = GameFont.Medium;
                var NameRect = new Rect(0, 144, 144f, 32f);
                Widgets.Label(NameRect, aDef.label);

                // Resources amounts
                Text.Font = GameFont.Small;
                var i = 0;
                foreach (var resourceName in DefModExtension_RotR_RoadDef.allResourcesAndWork)
                {
                    var ResourceAmountRect = new Rect(0, 176f + (i++ *40f), 144f, 32f);
                    Widgets.Label(ResourceAmountRect,
                                  roadDefExtension.GetCost(resourceName) > 0
                            ? (roadDefExtension.GetCost(resourceName) *
                               ((float)RoadsOfTheRim.settings.BaseEffort / 10)).ToString()
                            : "-"
                                  );
                }

                GUI.EndGroup();
                nbOfSections++;
            }

            Text.Anchor = TextAnchor.UpperLeft;
        }
示例#8
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);
            }
        }
示例#9
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);
        }