Exemplo n.º 1
0
        private static void ClientValidateCanBuild(
            Vector2Ushort tilePosition,
            bool logErrors,
            out string errorMessage,
            out bool canPlace,
            out bool isTooFar)
        {
            var protoStructure = currentSelectedProtoConstruction;

            if (Client.World.GetTile(tilePosition)
                .StaticObjects
                .Any(so => so.ProtoStaticWorldObject == protoStructure ||
                     ProtoObjectConstructionSite.SharedIsConstructionOf(so, protoStructure)))
            {
                // this building is already built here
                canPlace     = false;
                isTooFar     = false;
                errorMessage = null;
                return;
            }

            var character = Client.Characters.CurrentPlayerCharacter;

            if (!protoStructure.CheckTileRequirements(
                    tilePosition,
                    character,
                    errorCodeOrMessage: out var errorCodeOrMessage,
                    logErrors: logErrors))
            {
                // time requirements are not valid
                canPlace     = false;
                isTooFar     = false;
                errorMessage = ConstructionSystem.SharedConvertCodeOrErrorMessageToString(errorCodeOrMessage);
                return;
            }

            errorMessage = null;

            var configBuild = protoStructure.ConfigBuild;

            if (configBuild.CheckStageCanBeBuilt(character))
            {
                canPlace = true;
                isTooFar = SharedIsTooFarToPlace(protoStructure,
                                                 tilePosition,
                                                 character,
                                                 logErrors);
                return;
            }

            // not enough items to build the stage
            // close construction menu
            ClientCloseConstructionMenu();
            canPlace = false;
            isTooFar = false;
        }
Exemplo n.º 2
0
        public static void ClientStartRelocation(IStaticWorldObject objectStructure)
        {
            var protoStructure = objectStructure.ProtoStaticWorldObject;
            var character      = Client.Characters.CurrentPlayerCharacter;

            if (IsInObjectPlacementMode ||
                ConstructionPlacementSystem.IsInObjectPlacementMode)
            {
                // already relocating/placing something
                return;
            }

            if (!SharedIsRelocatable(objectStructure))
            {
                return;
            }

            if (!CreativeModeSystem.SharedIsInCreativeMode(character) &&
                !LandClaimSystem.SharedIsOwnedLand(objectStructure.TilePosition,
                                                   character,
                                                   requireFactionPermission: true,
                                                   out var hasNoFactionPermission,
                                                   out _))
            {
                // the building location or destination is in an area that is not owned by the player
                SharedShowCannotRelocateNotification(
                    character,
                    protoStructure,
                    hasNoFactionPermission);
                return;
            }

            var isPvEorWithinInteractionArea = PveSystem.SharedIsPve(false) ||
                                               protoStructure.SharedIsInsideCharacterInteractionArea(
                Api.Client.Characters.CurrentPlayerCharacter,
                objectStructure,
                writeToLog: false);

            if (!isPvEorWithinInteractionArea)
            {
                CannotInteractMessageDisplay.ClientOnCannotInteract(
                    character,
                    CoreStrings.Notification_TooFar,
                    isOutOfRange: true);
                return;
            }

            if (LandClaimSystem.SharedIsUnderRaidBlock(character, objectStructure))
            {
                // the building is in an area under the raid
                ConstructionSystem.SharedShowCannotBuildNotification(
                    character,
                    LandClaimSystem.ErrorRaidBlockActionRestricted_Message,
                    protoStructure);
                return;
            }

            if (LandClaimShieldProtectionSystem.SharedIsUnderShieldProtection(objectStructure))
            {
                // the building is in an area under shield protection
                LandClaimShieldProtectionSystem.SharedSendNotificationActionForbiddenUnderShieldProtection(
                    character);
                return;
            }

            ClientDisableConstructionRelocation();

            var sceneObject = Client.Scene.CreateSceneObject("StructureRelocationHelper");

            componentObjectPlacementHelper = sceneObject.AddComponent <ClientComponentObjectPlacementHelper>();
            componentRelocationHelper      = sceneObject.AddComponent <ClientComponentObjectRelocationHelper>();

            componentObjectPlacementHelper
            .Setup(protoStructure,
                   isCancelable: true,
                   isRepeatCallbackIfHeld: false,
                   isDrawConstructionGrid: true,
                   isBlockingInput: true,
                   validateCanPlaceCallback: ClientValidateCanRelocate,
                   placeSelectedCallback: ClientConstructionPlaceSelectedCallback,
                   delayRemainsSeconds: 0.1);
            componentObjectPlacementHelper.HideBlueprintOnOverlapWithTheSameObject = false;

            componentRelocationHelper.Setup(objectStructure);

            void ClientValidateCanRelocate(
                Vector2Ushort tilePosition,
                bool logErrors,
                out string errorMessage,
                out bool canPlace,
                out bool isTooFar)
            {
                if (tilePosition == objectStructure.TilePosition)
                {
                    canPlace     = true;
                    isTooFar     = false;
                    errorMessage = null;
                    return;
                }

                if (!SharedCheckTileRequirementsForRelocation(character,
                                                              objectStructure,
                                                              tilePosition,
                                                              out var errorCodeOrMessage,
                                                              logErrors: logErrors))
                {
                    // time requirements are not valid
                    canPlace     = false;
                    isTooFar     = false;
                    errorMessage = ConstructionSystem.SharedConvertCodeOrErrorMessageToString(errorCodeOrMessage);
                    return;
                }

                if (!SharedValidateCanCharacterRelocateStructure(character,
                                                                 objectStructure,
                                                                 tilePosition,
                                                                 out errorCodeOrMessage,
                                                                 logErrors: logErrors))
                {
                    canPlace     = true;
                    isTooFar     = true;
                    errorMessage = ConstructionSystem.SharedConvertCodeOrErrorMessageToString(errorCodeOrMessage);
                    return;
                }

                if (SharedHasObstacle(
                        character,
                        objectStructure,
                        tilePosition.ToVector2D() + protoStructure.Layout.Center))
                {
                    if (logErrors)
                    {
                        CannotInteractMessageDisplay.ClientOnCannotInteract(
                            character,
                            CoreStrings.Notification_ObstaclesOnTheWay,
                            isOutOfRange: true);
                    }

                    errorMessage = CoreStrings.Notification_ObstaclesOnTheWay;
                    canPlace     = true;
                    isTooFar     = true;
                    return;
                }

                canPlace     = true;
                isTooFar     = false;
                errorMessage = null;
            }

            void ClientConstructionPlaceSelectedCallback(Vector2Ushort tilePosition)
            {
                if (SharedHasObstacle(
                        character,
                        objectStructure,
                        tilePosition.ToVector2D() + protoStructure.Layout.Center))
                {
                    CannotInteractMessageDisplay.ClientOnCannotInteract(
                        character,
                        CoreStrings.Notification_ObstaclesOnTheWay,
                        isOutOfRange: true);
                    return;
                }

                ClientTimersSystem.AddAction(0.1, ClientDisableConstructionRelocation);
                if (tilePosition != objectStructure.TilePosition)
                {
                    Instance.CallServer(_ => _.ServerRemote_RelocateStructure(objectStructure, tilePosition));
                }
            }
        }