Пример #1
0
        public static void ServerReplaceConstructionSiteWithStructure(
            IStaticWorldObject worldObject,
            IProtoObjectStructure protoStructure,
            ICharacter byCharacter)
        {
            if (worldObject?.IsDestroyed ?? true)
            {
                throw new Exception("Construction site doesn't exist or already destroyed: " + worldObject);
            }

            var tilePosition = worldObject.TilePosition;

            // destroy construction site
            Server.World.DestroyObject(worldObject);

            // create structure
            var structure = ConstructionSystem.ServerCreateStructure(
                protoStructure,
                tilePosition,
                byCharacter: byCharacter);

            if (byCharacter == null)
            {
                return;
            }

            Instance.ServerNotifyOnStructurePlacedOrRelocated(structure, byCharacter);
            Api.SafeInvoke(() => ServerStructureBuilt?.Invoke(byCharacter, structure));
        }
Пример #2
0
        private void ServerRemote_PlaceStructure(
            IProtoObjectStructure protoStructure,
            Vector2Ushort tilePosition)
        {
            var character = ServerRemoteContext.Character;

            if (!protoStructure.SharedIsTechUnlocked(character))
            {
                Logger.Error(
                    $"Cannot build {protoStructure} at {tilePosition}: player character doesn't have unlocked tech node for this structure.",
                    character);
                return;
            }

            if (SharedIsTooFarToPlace(protoStructure,
                                      tilePosition,
                                      character,
                                      logErrors: true))
            {
                return;
            }

            // validate if the structure can be placed there
            if (!protoStructure.CheckTileRequirements(tilePosition, character, logErrors: true))
            {
                return;
            }

            // validate if there are enough required items/resources to build the structure
            var configBuild = protoStructure.ConfigBuild;

            if (!configBuild.CheckStageCanBeBuilt(character))
            {
                Logger.Error(
                    $"Cannot build {protoStructure} at {tilePosition}: player character doesn't have enough resources (or not allowed).",
                    character);
                return;
            }

            var selectedHotbarItem = PlayerCharacter.GetPublicState(character).SelectedItem;

            if (!(selectedHotbarItem?.ProtoItem is IProtoItemToolToolbox))
            {
                Logger.Error(
                    $"Cannot build {protoStructure} at {tilePosition}: player character doesn't have selected construction tool.",
                    character);
                return;
            }

            // consume required items/resources (for 1 stage)
            configBuild.ServerDestroyRequiredItems(character);

            if (configBuild.StagesCount > 1)
            {
                if (AllowInstantPlacementInCreativeMode &&
                    CreativeModeSystem.SharedIsInCreativeMode(character))
                {
                    // instant placement allowed
                }
                else
                {
                    // there are multiple construction stages - spawn and setup a construction site
                    var constructionSite = this.ServerCreateConstructionSite(tilePosition, protoStructure, character);
                    this.ServerNotifyOnStructurePlacedOrRelocated(constructionSite, character);
                    return;
                }
            }

            ServerDecalsDestroyHelper.DestroyAllDecals(tilePosition, protoStructure.Layout);

            // there is only one construction stage - simply spawn the structure
            var structure = ConstructionSystem.ServerCreateStructure(
                protoStructure,
                tilePosition,
                character);

            this.ServerNotifyOnStructurePlacedOrRelocated(structure, character);
            Api.SafeInvoke(() => ServerStructureBuilt?.Invoke(character, structure));
        }