public void DoBuild(Tile tile) { if (buildMode == BuildMode.ROOMBEHAVIOR) { string roomBehaviorType = buildModeType; if (tile.Room != null && WorldController.Instance.World.IsRoomBehaviorValidForRoom(roomBehaviorType, tile.Room)) { RoomBehavior proto = PrototypeManager.RoomBehavior.Get(roomBehaviorType); tile.Room.DesignateRoomBehavior(proto.Clone()); } } else if (buildMode == BuildMode.FURNITURE) { // Create the Furniture and assign it to the tile // Can we build the furniture in the selected tile? // Run the ValidPlacement function! string furnitureType = buildModeType; if ( World.Current.FurnitureManager.IsPlacementValid(furnitureType, tile, CurrentPreviewRotation) && World.Current.FurnitureManager.IsWorkSpotClear(furnitureType, tile) && DoesFurnitureBuildJobOverlapExistingBuildJob(tile, furnitureType, CurrentPreviewRotation) == false) { // This tile position is valid for this furniture // Check if there is existing furniture in this tile. If so delete it. if (tile.Furniture != null) { tile.Furniture.SetDeconstructJob(); } // Create a job for it to be build Job job; if (PrototypeManager.FurnitureConstructJob.Has(furnitureType)) { // Make a clone of the job prototype job = PrototypeManager.FurnitureConstructJob.Get(furnitureType).Clone(); // Assign the correct tile. job.tile = tile; } else { Debug.ULogErrorChannel("BuildModeController", "There is no furniture job prototype for '" + furnitureType + "'"); job = new Job(tile, furnitureType, World.Current.FurnitureManager.ConstructJobCompleted, 0.1f, null, Job.JobPriority.High); job.adjacent = true; job.Description = "job_build_" + furnitureType + "_desc"; } Furniture furnituteToBuild = PrototypeManager.Furniture.Get(furnitureType).Clone(); furnituteToBuild.SetRotation(CurrentPreviewRotation); job.buildablePrototype = furnituteToBuild; // Add the job to the queue or build immediately if in Dev mode if (Settings.GetSetting("DialogBoxSettings_developerModeToggle", false)) { World.Current.FurnitureManager.PlaceFurniture(furnituteToBuild, job.tile); } else { for (int x_off = tile.X; x_off < (tile.X + job.buildablePrototype.Width); x_off++) { for (int y_off = tile.Y; y_off < (tile.Y + job.buildablePrototype.Height); y_off++) { // FIXME: I don't like having to manually and explicitly set // flags that prevent conflicts. It's too easy to forget to set/clear them! Tile offsetTile = World.Current.GetTileAt(x_off, y_off, tile.Z); HashSet <Job> pendingBuildJobs = WorldController.Instance.World.GetTileAt(x_off, y_off, tile.Z).PendingBuildJobs; if (pendingBuildJobs != null) { // if the existing buildJobs furniture is replaceable by the current furnitureType, // we can pretend it does not overlap with the new build // We should only have 1 furniture building job per tile, so this should return that job and only that job IEnumerable <Job> pendingFurnitureJob = pendingBuildJobs.Where(pendingJob => pendingJob.buildablePrototype.GetType() == typeof(Furniture)); if (pendingFurnitureJob.Count() == 1) { pendingFurnitureJob.Single().CancelJob(); } } offsetTile.PendingBuildJobs.Add(job); job.OnJobStopped += (theJob) => offsetTile.PendingBuildJobs.Remove(job); } } World.Current.jobQueue.Enqueue(job); // Let our workspot tile know it is reserved for us World.Current.ReserveTileAsWorkSpot((Furniture)job.buildablePrototype, job.tile); } } } else if (buildMode == BuildMode.UTILITY) { // Create the Furniture and assign it to the tile // Can we build the furniture in the selected tile? // Run the ValidPlacement function! string utilityType = buildModeType; // TODO: Reimplement this later: DoesBuildJobOverlapExistingBuildJob(t, furnitureType) == false) if ( World.Current.UtilityManager.IsPlacementValid(utilityType, tile) && DoesSameUtilityTypeAlreadyExist(utilityType, tile) == false && DoesUtilityBuildJobOverlapExistingBuildJob(utilityType, tile) == false) { // This tile position is valid for this furniture // Create a job for it to be build Job job; if (PrototypeManager.UtilityConstructJob.Has(utilityType)) { // Make a clone of the job prototype job = PrototypeManager.UtilityConstructJob.Get(utilityType).Clone(); // Assign the correct tile. job.tile = tile; } else { Debug.ULogErrorChannel("BuildModeController", "There is no furniture job prototype for '" + utilityType + "'"); job = new Job(tile, utilityType, World.Current.UtilityManager.ConstructJobCompleted, 0.1f, null, Job.JobPriority.High); job.Description = "job_build_" + utilityType + "_desc"; } job.buildablePrototype = PrototypeManager.Utility.Get(utilityType); // Add the job to the queue or build immediately if in dev mode if (Settings.GetSetting("DialogBoxSettings_developerModeToggle", false)) { World.Current.UtilityManager.PlaceUtility(job.Type, job.tile, true); } else { // FIXME: I don't like having to manually and explicitly set // flags that preven conflicts. It's too easy to forget to set/clear them! Tile offsetTile = World.Current.GetTileAt(tile.X, tile.Y, tile.Z); offsetTile.PendingBuildJobs.Add(job); job.OnJobStopped += (theJob) => offsetTile.PendingBuildJobs.Remove(job); World.Current.jobQueue.Enqueue(job); } } } else if (buildMode == BuildMode.FLOOR) { // We are in tile-changing mode. ////t.Type = buildModeTile; TileType tileType = buildModeTile; if ( tile.Type != tileType && tile.Furniture == null && tile.PendingBuildJobs.Count == 0 && tileType.CanBuildHere(tile)) { // This tile position is valid tile type // Create a job for it to be build Job buildingJob = tileType.BuildingJob; buildingJob.tile = tile; // Add the job to the queue or build immediately if in Dev mode if (Settings.GetSetting("DialogBoxSettings_developerModeToggle", false)) { buildingJob.tile.SetTileType(buildingJob.JobTileType); } else { buildingJob.OnJobStopped += (theJob) => theJob.tile.PendingBuildJobs.Remove(theJob); WorldController.Instance.World.jobQueue.Enqueue(buildingJob); } } } else if (buildMode == BuildMode.DECONSTRUCT) { // TODO bool canDeconstructAll = Settings.GetSetting("DialogBoxSettings_developerModeToggle", false); if (tile.Furniture != null && (canDeconstructAll || tile.Furniture.HasTypeTag("Non-deconstructible") == false)) { // check if this is a WALL neighbouring a pressured and pressureless environment, and if so, bail if (tile.Furniture.HasTypeTag("Wall")) { Tile[] neighbors = tile.GetNeighbours(); // diagOkay?? int pressuredNeighbors = 0; int vacuumNeighbors = 0; foreach (Tile neighbor in neighbors) { if (neighbor != null && neighbor.Room != null) { if (neighbor.Room.IsOutsideRoom() || MathUtilities.IsZero(neighbor.Room.GetTotalGasPressure())) { vacuumNeighbors++; } else { pressuredNeighbors++; } } } if (vacuumNeighbors > 0 && pressuredNeighbors > 0) { Debug.ULogChannel("BuildModeController", "Someone tried to deconstruct a wall between a pressurized room and vacuum!"); return; } } tile.Furniture.SetDeconstructJob(); } else if (tile.PendingBuildJobs != null) { tile.PendingBuildJobs.Last().CancelJob(); } else if (tile.Utilities.Count > 0) { tile.Utilities.Last().Value.SetDeconstructJob(); } } else { Debug.ULogErrorChannel("BuildModeController", "UNIMPLEMENTED BUILD MODE"); } }
public void DoBuild(Tile tile) { if (buildMode == BuildMode.ROOMBEHAVIOR) { string roomBehaviorType = buildModeType; if (tile.Room != null && WorldController.Instance.World.IsRoomBehaviorValidForRoom(roomBehaviorType, tile.Room)) { RoomBehavior proto = PrototypeManager.RoomBehavior.Get(roomBehaviorType); tile.Room.DesignateRoomBehavior(proto.Clone()); } } else if (buildMode == BuildMode.FURNITURE) { // Create the Furniture and assign it to the tile // Can we build the furniture in the selected tile? // Run the ValidPlacement function! string furnitureType = buildModeType; if ( World.Current.FurnitureManager.IsPlacementValid(furnitureType, tile, CurrentPreviewRotation) && World.Current.FurnitureManager.IsWorkSpotClear(furnitureType, tile) && DoesFurnitureBuildJobOverlapExistingBuildJob(tile, furnitureType, CurrentPreviewRotation) == false) { // This tile position is valid for this furniture // Check if there is existing furniture in this tile. If so delete it. if (tile.Furniture != null) { tile.Furniture.SetDeconstructJob(); } // Create a job for it to be build Job job; Furniture toBuildProto = PrototypeManager.Furniture.Get(furnitureType); OrderAction orderAction = toBuildProto.GetOrderAction <Build>(); if (orderAction != null) { job = orderAction.CreateJob(tile, furnitureType); if (useCratedObject) { // We want to use a crated furniture, so set requested items to crated version. job.RequestedItems.Clear(); job.RequestedItems.Add(this.buildModeType, new ProjectPorcupine.Jobs.RequestedItem(this.buildModeType, 1)); useCratedObject = false; } // this is here so OrderAction can be used for utility as well as furniture job.OnJobCompleted += (theJob) => World.Current.FurnitureManager.ConstructJobCompleted(theJob); } else { UnityDebugger.Debugger.LogError("BuildModeController", "There is no furniture job prototype for '" + furnitureType + "'"); job = new Job(tile, furnitureType, World.Current.FurnitureManager.ConstructJobCompleted, 0.1f, null, Job.JobPriority.High); job.adjacent = true; job.Description = "job_build_" + furnitureType + "_desc"; } Furniture furnitureToBuild = PrototypeManager.Furniture.Get(furnitureType).Clone(); furnitureToBuild.SetRotation(CurrentPreviewRotation); job.buildablePrototype = furnitureToBuild; // Add the job to the queue or build immediately if in Dev mode if (SettingsKeyHolder.DeveloperMode) { World.Current.FurnitureManager.PlaceFurniture(furnitureToBuild, job.tile); } else { for (int x_off = tile.X; x_off < (tile.X + job.buildablePrototype.Width); x_off++) { for (int y_off = tile.Y; y_off < (tile.Y + job.buildablePrototype.Height); y_off++) { // FIXME: I don't like having to manually and explicitly set // flags that prevent conflicts. It's too easy to forget to set/clear them! Tile offsetTile = World.Current.GetTileAt(x_off, y_off, tile.Z); HashSet <Job> pendingBuildJobs = WorldController.Instance.World.GetTileAt(x_off, y_off, tile.Z).PendingBuildJobs; if (pendingBuildJobs != null) { // if the existing buildJobs furniture is replaceable by the current furnitureType, // we can pretend it does not overlap with the new build // We should only have 1 furniture building job per tile, so this should return that job and only that job IEnumerable <Job> pendingFurnitureJob = pendingBuildJobs.Where(pendingJob => pendingJob.buildablePrototype.GetType() == typeof(Furniture)); if (pendingFurnitureJob.Count() == 1) { pendingFurnitureJob.Single().CancelJob(); } } offsetTile.PendingBuildJobs.Add(job); job.OnJobStopped += (theJob) => offsetTile.PendingBuildJobs.Remove(job); } } World.Current.jobQueue.Enqueue(job); // Let our workspot tile know it is reserved for us World.Current.ReserveTileAsWorkSpot((Furniture)job.buildablePrototype, job.tile); } } } else if (buildMode == BuildMode.UTILITY) { // Create the Furniture and assign it to the tile // Can we build the furniture in the selected tile? // Run the ValidPlacement function! string utilityType = buildModeType; if ( World.Current.UtilityManager.IsPlacementValid(utilityType, tile) && DoesSameUtilityTypeAlreadyExist(utilityType, tile) == false && DoesUtilityBuildJobOverlapExistingBuildJob(utilityType, tile) == false) { // This tile position is valid for this furniture // Create a job for it to be build Job job; Utility toBuildProto = PrototypeManager.Utility.Get(utilityType); OrderAction orderAction = toBuildProto.GetOrderAction <Build>(); if (orderAction != null) { job = orderAction.CreateJob(tile, utilityType); // this is here so OrderAction can be used for utility as well as furniture job.OnJobCompleted += (theJob) => World.Current.UtilityManager.ConstructJobCompleted(theJob); } else { UnityDebugger.Debugger.LogError("BuildModeController", "There is no furniture job prototype for '" + utilityType + "'"); job = new Job(tile, utilityType, World.Current.UtilityManager.ConstructJobCompleted, 0.1f, null, Job.JobPriority.High); job.Description = "job_build_" + utilityType + "_desc"; } job.buildablePrototype = PrototypeManager.Utility.Get(utilityType); // Add the job to the queue or build immediately if in dev mode if (SettingsKeyHolder.DeveloperMode) { World.Current.UtilityManager.PlaceUtility(job.Type, job.tile, true); } else { // FIXME: I don't like having to manually and explicitly set // flags that preven conflicts. It's too easy to forget to set/clear them! Tile offsetTile = World.Current.GetTileAt(tile.X, tile.Y, tile.Z); offsetTile.PendingBuildJobs.Add(job); job.OnJobStopped += (theJob) => offsetTile.PendingBuildJobs.Remove(job); World.Current.jobQueue.Enqueue(job); } } } else if (buildMode == BuildMode.FLOOR) { // We are in tile-changing mode. ////t.Type = buildModeTile; TileType tileType = buildModeTile; if ( tile.Type != tileType && tile.Furniture == null && tile.PendingBuildJobs.Count == 0 && tileType.CanBuildHere(tile)) { // This tile position is valid tile type // Create a job for it to be build Job buildingJob = tileType.BuildingJob; buildingJob.tile = tile; // Add the job to the queue or build immediately if in Dev mode if (SettingsKeyHolder.DeveloperMode) { buildingJob.tile.SetTileType(buildingJob.JobTileType); } else { buildingJob.OnJobStopped += (theJob) => theJob.tile.PendingBuildJobs.Remove(theJob); WorldController.Instance.World.jobQueue.Enqueue(buildingJob); } } } else if (buildMode == BuildMode.DECONSTRUCT) { bool canDeconstructAll = SettingsKeyHolder.DeveloperMode; if (tile.Furniture != null && (canDeconstructAll || tile.Furniture.HasTypeTag("Non-deconstructible") == false)) { // check if this is a WALL neighbouring a pressured and pressureless environment, and if so, bail if (IsTilePartOfPressuredRoom(tile)) { return; } tile.Furniture.SetDeconstructJob(); } else if (tile.PendingBuildJobs != null && tile.PendingBuildJobs.Count > 0) { tile.PendingBuildJobs.Last().CancelJob(); } else if (tile.Utilities.Count > 0) { tile.Utilities.Last().Value.SetDeconstructJob(); } } else if (buildMode == BuildMode.MINE) { if (tile.Furniture != null) { Job existingMineJob; bool hasMineJob = tile.Furniture.Jobs.HasJobWithPredicate(x => x.OrderName == typeof(Mine).Name, out existingMineJob); if (!hasMineJob) { OrderAction mineAction = tile.Furniture.GetOrderAction <Mine>(); if (mineAction != null) { // check if this is a WALL neighbouring a pressured and pressureless environment, and if so, bail if (IsTilePartOfPressuredRoom(tile)) { return; } Job job = mineAction.CreateJob(tile, null); if (SettingsKeyHolder.DeveloperMode) { // complete job right away, needs buildable job.buildable = tile.Furniture; job.DoWork(0); } else { tile.Furniture.Jobs.Add(job); } } } } } else { UnityDebugger.Debugger.LogError("BuildModeController", "UNIMPLEMENTED BUILD MODE"); } }
public void DoBuild(Tile t) { if (buildMode == BuildMode.FURNITURE) { // Create the Furniture and assign it to the tile // Can we build the furniture in the selected tile? // Run the ValidPlacement function! string furnitureType = buildModeObjectType; if ( WorldController.Instance.World.IsFurniturePlacementValid(furnitureType, t) && DoesBuildJobOverlapExistingBuildJob(t, furnitureType) == false) { // This tile position is valid for this furniture // Check if there is existing furniture in this tile. If so delete it. // TODO Possibly return resources. Will the Deconstruct() method handle that? If so what will happen if resources drop ontop of new non-passable structure. if (t.Furniture != null) { t.Furniture.Deconstruct(); } // Create a job for it to be build Job j; if (PrototypeManager.FurnitureJob.Has(furnitureType)) { // Make a clone of the job prototype j = PrototypeManager.FurnitureJob.Get(furnitureType).Clone(); // Assign the correct tile. j.tile = t; } else { Debug.ULogErrorChannel("BuildModeController", "There is no furniture job prototype for '" + furnitureType + "'"); j = new Job(t, furnitureType, FunctionsManager.JobComplete_FurnitureBuilding, 0.1f, null, Job.JobPriority.High); j.JobDescription = "job_build_" + furnitureType + "_desc"; } j.furniturePrototype = PrototypeManager.Furniture.Get(furnitureType); // Add the job to the queue or build immediately if in dev mode if (Settings.GetSetting("DialogBoxSettings_developerModeToggle", false)) { WorldController.Instance.World.PlaceFurniture(j.JobObjectType, j.tile); } else { for (int x_off = t.X; x_off < (t.X + j.furniturePrototype.Width); x_off++) { for (int y_off = t.Y; y_off < (t.Y + j.furniturePrototype.Height); y_off++) { // FIXME: I don't like having to manually and explicitly set // flags that preven conflicts. It's too easy to forget to set/clear them! Tile offsetTile = WorldController.Instance.World.GetTileAt(x_off, y_off, t.Z); offsetTile.PendingBuildJob = j; j.OnJobStopped += (theJob) => { offsetTile.PendingBuildJob = null; }; } } WorldController.Instance.World.jobQueue.Enqueue(j); } } } else if (buildMode == BuildMode.FLOOR) { // We are in tile-changing mode. ////t.Type = buildModeTile; TileType tileType = buildModeTile; if ( t.Type != tileType && t.Furniture == null && t.PendingBuildJob == null && tileType.CanBuildHere(t)) { // This tile position is valid tile type // Create a job for it to be build Job buildingJob = tileType.BuildingJob; buildingJob.tile = t; // Add the job to the queue or build immediately if in dev mode if (Settings.GetSetting("DialogBoxSettings_developerModeToggle", false)) { buildingJob.tile.Type = buildingJob.JobTileType; } else { // FIXME: I don't like having to manually and explicitly set // flags that preven conflicts. It's too easy to forget to set/clear them! t.PendingBuildJob = buildingJob; buildingJob.OnJobStopped += (theJob) => theJob.tile.PendingBuildJob = null; WorldController.Instance.World.jobQueue.Enqueue(buildingJob); } } } else if (buildMode == BuildMode.DECONSTRUCT) { // TODO if (t.Furniture != null) { // check if this is a WALL neighbouring a pressured and pressureless environ & if so bail if (t.Furniture.HasTypeTag("Wall")) { Tile[] neighbors = t.GetNeighbours(); // diagOkay?? int pressuredNeighbors = 0; int vacuumNeighbors = 0; foreach (Tile neighbor in neighbors) { if (neighbor != null && neighbor.Room != null) { if ((neighbor.Room == World.Current.GetOutsideRoom()) || MathUtilities.IsZero(neighbor.Room.GetTotalGasPressure())) { vacuumNeighbors++; } else { pressuredNeighbors++; } } } if (vacuumNeighbors > 0 && pressuredNeighbors > 0) { Debug.ULogChannel("BuildModeController", "Someone tried to deconstruct a wall between a pressurised room and vacuum!"); return; } } t.Furniture.Deconstruct(); } else if (t.PendingBuildJob != null) { t.PendingBuildJob.CancelJob(); } } else { Debug.ULogErrorChannel("BuildModeController", "UNIMPLEMENTED BUILD MODE"); } }