public static void ClientToggleConstructionMenu() { if (ClientCloseConstructionMenu()) { // just closed the construction menu return; } if (ClientCurrentCharacterHelper.PublicState.CurrentVehicle is not null) { Logger.Important("Construction menu is not accessible while in a vehicle"); return; } WindowConstructionMenu.Open( onStructureProtoSelected: selectedProtoStructure => { ClientEnsureConstructionToolIsSelected(); currentSelectedProtoConstruction = selectedProtoStructure; componentObjectPlacementHelper = Client.Scene .CreateSceneObject("ConstructionHelper") .AddComponent <ClientComponentObjectPlacementHelper>(); // repeat placement for held button only for walls, floor and farms var isRepeatCallbackIfHeld = selectedProtoStructure.IsRepeatPlacement; componentObjectPlacementHelper .Setup(selectedProtoStructure, isCancelable: true, isRepeatCallbackIfHeld: isRepeatCallbackIfHeld, isDrawConstructionGrid: true, isBlockingInput: true, validateCanPlaceCallback: ClientValidateCanBuild, placeSelectedCallback: ClientConstructionPlaceSelectedCallback, delayRemainsSeconds: 0.4); }, onClosed: OnStructureSelectWindowOpenedOrClosed); OnStructureSelectWindowOpenedOrClosed(); }
public static void ClientToggleConstructionMenu() { if (ClientCloseConstructionMenu()) { // just closed the construction menu return; } WindowConstructionMenu.Open( onStructureProtoSelected: selectedProtoStructure => { ClientEnsureConstructionToolIsSelected(); currentSelectedProtoConstruction = selectedProtoStructure; componentObjectPlacementHelper = Client.Scene .CreateSceneObject( "ConstructionHelper", Vector2D.Zero) .AddComponent < ClientComponentObjectPlacementHelper>(); // repeat placement for held button only for walls, floor and farms var isRepeatCallbackIfHeld = selectedProtoStructure is IProtoObjectWall || selectedProtoStructure is IProtoObjectFloor || selectedProtoStructure is IProtoObjectFarm; componentObjectPlacementHelper .Setup(selectedProtoStructure, isCancelable: true, isRepeatCallbackIfHeld: isRepeatCallbackIfHeld, isDrawConstructionGrid: true, isBlockingInput: true, validateCanPlaceCallback: ClientValidateCanBuild, placeSelectedCallback: ClientConstructionPlaceSelectedCallback, delayRemainsSeconds: 0.4); }, onClosed: OnStructureSelectWindowOpenedOrClosed); OnStructureSelectWindowOpenedOrClosed(); }
public static void Setup(IItem item, bool isSelected) { if (!isSelected) { item = null; } if (currentSelectedSeedItem == item) { return; } currentSelectedSeedItem = item; currentSelectedProtoSeed = currentSelectedSeedItem?.ProtoItem as IProtoItemSeed; if (currentSelectedProtoSeed == null) { // seed is not selected anymore blueprintComponent?.SceneObject.Destroy(); blueprintComponent = null; return; } // seed is selected - create blueprint component if (blueprintComponent == null) { blueprintComponent = Client.Scene.CreateSceneObject("Seed placer helper") .AddComponent <ClientComponentObjectPlacementHelper>(); } blueprintComponent.Setup( protoStaticWorldObject: currentSelectedProtoSeed.ObjectPlantProto, isCancelable: false, isRepeatCallbackIfHeld: true, isDrawConstructionGrid: true, isBlockingInput: false, validateCanPlaceCallback: OnValidate, placeSelectedCallback: OnPlaceSelected, maxDistance: MaxSeedPlacementDistance); }
public static void ClientDisableConstructionPlacement() { componentObjectPlacementHelper?.SceneObject.Destroy(); componentObjectPlacementHelper = null; }
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 errorMessage, logErrors: logErrors)) { // time requirements are not valid canPlace = false; isTooFar = false; return; } if (!SharedValidateCanCharacterRelocateStructure(character, objectStructure, tilePosition, out errorMessage, logErrors: logErrors)) { canPlace = true; isTooFar = true; 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; } 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)); } } }