Exemplo n.º 1
0
    private void CalculatePlacingPosition()
    {
        // If we are placing a multitile object we would like to modify the postilion where the mouse grabs it.
        if (currentMode == MouseMode.BUILD &&
            bmc.buildMode == BuildMode.NESTEDOBJECT &&
            PrototypeManager.NestedObject.Has(bmc.buildModeType) &&
            (PrototypeManager.NestedObject.Get(bmc.buildModeType).Width > 1 ||
             PrototypeManager.NestedObject.Get(bmc.buildModeType).Height > 1))
        {
            NestedObject nestedObjectToBuild = PrototypeManager.NestedObject.Get(bmc.buildModeType).Clone();
            nestedObjectToBuild.SetRotation(bmc.CurrentPreviewRotation);
            Sprite sprite = nosc.GetSpriteForNestedObject(nestedObjectToBuild.Type);

            // Use the center of the NestedObject.
            currPlacingPosition = currFramePosition - ImageUtils.SpritePivotOffset(sprite, bmc.CurrentPreviewRotation);
        }
        else
        {
            currPlacingPosition = currFramePosition;
        }
    }
Exemplo n.º 2
0
    public bool DoesBuildJobOverlapExistingBuildJob(Tile t, string nestedObjectType, float rotation = 0)
    {
        NestedObject nestedObjectToBuild = PrototypeManager.NestedObject.Get(nestedObjectType).Clone();

        nestedObjectToBuild.SetRotation(rotation);

        for (int x_off = t.X; x_off < (t.X + nestedObjectToBuild.Width); x_off++)
        {
            for (int y_off = t.Y; y_off < (t.Y + nestedObjectToBuild.Height); y_off++)
            {
                Job pendingBuildJob = WorldController.Instance.World.GetTileAt(x_off, y_off, t.Z).PendingBuildJob;
                if (pendingBuildJob != null)
                {
                    // if the existing buildJobs NestedObject is replaceable by the current NestedObject,
                    // we can pretend it does not overlap with the new build
                    return(!nestedObjectToBuild.ReplaceableNestedObject.Any(pendingBuildJob.buildablePrototype.HasTypeTag));
                }
            }
        }

        return(false);
    }
Exemplo n.º 3
0
    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.NESTEDOBJECT)
        {
            // Create the NestedObject and assign it to the tile
            // Can we build the NestedObject in the selected tile?
            // Run the ValidPlacement function!
            string nestedObjectType = buildModeType;

            if (
                World.Current.NestedObjectManager.IsPlacementValid(nestedObjectType, tile, CurrentPreviewRotation) &&
                World.Current.NestedObjectManager.IsWorkSpotClear(nestedObjectType, tile) &&
                DoesBuildJobOverlapExistingBuildJob(tile, nestedObjectType, CurrentPreviewRotation) == false)
            {
                // This tile position is valid for this NestedObject

                // Check if there is existing NestedObject in this tile. If so delete it.
                if (tile.NestedObject != null)
                {
                    tile.NestedObject.SetDeconstructJob();
                }

                // Create a job for it to be build
                Job job;

                if (PrototypeManager.NestedObjectConstructJob.Has(nestedObjectType))
                {
                    // Make a clone of the job prototype
                    job = PrototypeManager.NestedObjectConstructJob.Get(nestedObjectType).Clone();

                    // Assign the correct tile.
                    job.tile = tile;
                }
                else
                {
                    Debug.ULogErrorChannel("BuildModeController", "There is no NestedObject job prototype for '" + nestedObjectType + "'");
                    job                = new Job(tile, nestedObjectType, World.Current.NestedObjectManager.ConstructJobCompleted, 0.1f, null, Job.JobPriority.High);
                    job.adjacent       = true;
                    job.JobDescription = "Deconstructing: " + nestedObjectType + ".";
                }

                NestedObject nestedObjectToBuild = PrototypeManager.NestedObject.Get(nestedObjectType).Clone();
                nestedObjectToBuild.SetRotation(CurrentPreviewRotation);
                job.buildablePrototype = nestedObjectToBuild;

                // Add the job to the queue or build immediately if in Dev mode
                if (Settings.GetSetting("DialogBoxSettings_developerModeToggle", false))
                {
                    World.Current.NestedObjectManager.PlaceNestedObject(nestedObjectToBuild, 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);
                            offsetTile.PendingBuildJob = job;
                            job.OnJobStopped          += (theJob) => offsetTile.PendingBuildJob = null;
                        }
                    }

                    World.Current.jobQueue.Enqueue(job);

                    // Let our workspot tile know it is reserved for us
                    World.Current.ReserveTileAsWorkSpot((NestedObject)job.buildablePrototype, job.tile);
                }
            }
        }
        else if (buildMode == BuildMode.UTILITY)
        {
            // Create the NestedObject and assign it to the tile
            // Can we build the NestedObject in the selected tile?
            // Run the ValidPlacement function!
            string utilityType = buildModeType;

            // TODO: Reimplement this later: DoesBuildJobOverlapExistingBuildJob(t, nestedObjectType) == false)
            if (
                World.Current.UtilityManager.IsPlacementValid(utilityType, tile) &&
                DoesSameUtilityTypeAlreadyExist(tile, utilityType) == false)
            {
                // This tile position is valid for this NestedObject

                // 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 NestedObject job prototype for '" + utilityType + "'");
                    job = new Job(tile, utilityType, World.Current.UtilityManager.ConstructJobCompleted, 0.1f, null, Job.JobPriority.High);
                    job.JobDescription = "Building: " + utilityType + ".";
                }

                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.JobObjectType, job.tile);
                }
                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.PendingBuildJob = job;
                    job.OnJobStopped          += (theJob) => offsetTile.PendingBuildJob = null;

                    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.NestedObject == null &&
                tile.PendingBuildJob == null &&
                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.Type = buildingJob.JobTileType;
                }
                else
                {
                    // 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.PendingBuildJob      = buildingJob;
                    buildingJob.OnJobStopped += (theJob) => theJob.tile.PendingBuildJob = null;

                    WorldController.Instance.World.jobQueue.Enqueue(buildingJob);
                }
            }
        }
        else if (buildMode == BuildMode.DECONSTRUCT)
        {
            // TODO
            bool canDeconstructAll = Settings.GetSetting("DialogBoxSettings_developerModeToggle", false);
            if (tile.NestedObject != null && (canDeconstructAll || tile.NestedObject.HasTypeTag("Non-deconstructible") == false))
            {
                // check if this is a WALL neighbouring a pressured and pressureless environment, and if so, bail
                if (tile.NestedObject.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.NestedObject.SetDeconstructJob();
            }
            else if (tile.PendingBuildJob != null)
            {
                tile.PendingBuildJob.CancelJob();
            }
            else if (tile.Utilities.Count > 0)
            {
                tile.Utilities.Last().Value.SetDeconstructJob();
            }
        }
        else
        {
            Debug.ULogErrorChannel("BuildModeController", "UNIMPLEMENTED BUILD MODE");
        }
    }