protected sealed override void ServerUpdate(ServerUpdateData data) { var character = data.GameObject; var privateState = data.PrivateState; var publicState = data.PublicState; var objectTurret = privateState.ObjectTurret; if (objectTurret is null) { return; } var objectTurretPrivateState = objectTurret.GetPrivateState <ObjectTurretPrivateState>(); var turretMode = objectTurretPrivateState.TurretMode; if (turretMode == TurretMode.Disabled) { return; } var objectTurretPublicState = objectTurret.GetPublicState <ObjectTurretPublicState>(); if (objectTurretPublicState.ElectricityConsumerState != ElectricityConsumerState.PowerOnActive) { return; } if (LandClaimShieldProtectionSystem.SharedIsUnderShieldProtection(objectTurret)) { return; } this.ServerRebuildFinalCacheIfNeeded(privateState, publicState); ServerUpdateAggroState(privateState, data.DeltaTime); this.ServerUpdateTurret(data, turretMode); // update weapon state (fires the weapon if needed) WeaponSystem.SharedUpdateCurrentWeapon( character, privateState.WeaponState, data.DeltaTime); }
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)); } } }
public static bool CheckCanInteractForConstruction( ICharacter character, IStaticWorldObject worldObject, bool writeToLog, bool checkRaidblock) { var characterPosition = character.Position; var canInteract = false; var staticWorldObjectProto = ProtoObjectConstructionSite.SharedGetConstructionProto(worldObject) ?? worldObject.ProtoStaticWorldObject; var startTilePosition = worldObject.TilePosition; foreach (var tileOffset in staticWorldObjectProto.Layout.TileOffsets) { var tilePosition = startTilePosition + tileOffset; if (characterPosition.DistanceSquaredTo( new Vector2D(tilePosition.X + 0.5, tilePosition.Y + 0.5)) <= MaxDistanceForBuildRepairAction * MaxDistanceForBuildRepairAction) { canInteract = true; break; } } if (!canInteract) { canInteract = CreativeModeSystem.SharedIsInCreativeMode(character); } if (!canInteract) { if (writeToLog) { Logger.Warning( $"Character cannot interact with {worldObject} for (de)construction - too far.", character); if (IsClient) { CannotInteractMessageDisplay.ClientOnCannotInteract(worldObject, CoreStrings.Notification_TooFar, isOutOfRange: true); } } return(false); } if (checkRaidblock && LandClaimSystem.SharedIsUnderRaidBlock(character, worldObject)) { // the building is in an area under the raid if (writeToLog) { LandClaimSystem.SharedSendNotificationActionForbiddenUnderRaidblock(character); } return(false); } if (LandClaimShieldProtectionSystem.SharedIsUnderShieldProtection(worldObject)) { // the building is in an area under shield protection if (writeToLog) { LandClaimShieldProtectionSystem.SharedSendNotificationActionForbiddenUnderShieldProtection( character); } return(false); } return(true); }
public static bool SharedValidateCanCharacterRelocateStructure( ICharacter character, IStaticWorldObject objectStructure, Vector2Ushort toPosition, out string errorMessage, bool logErrors) { if (!SharedIsRelocatable(objectStructure)) { errorMessage = null; return(false); } if (!SharedCheckTileRequirementsForRelocation(character, objectStructure, toPosition, out errorMessage, logErrors)) { return(false); } if (!(objectStructure.ProtoGameObject is IProtoObjectStructure protoStructure)) { return(false); } var maxRelocationDistance = PveSystem.SharedIsPve(true) ? MaxRelocationDistancePvE : MaxRelocationDistancePvP; if (objectStructure.TilePosition.TileSqrDistanceTo(toPosition) > maxRelocationDistance * maxRelocationDistance) { if (logErrors) { ConstructionSystem.SharedShowCannotPlaceNotification( character, CoreStrings.Notification_TooFar, protoStructure); } errorMessage = CoreStrings.Notification_TooFar; return(false); } var itemInHands = character.SharedGetPlayerSelectedHotbarItem(); if (!(itemInHands.ProtoGameObject is IProtoItemToolToolbox)) { return(false); } if (CreativeModeSystem.SharedIsInCreativeMode(character)) { errorMessage = null; return(true); } if (!LandClaimSystem.SharedIsOwnedLand(objectStructure.TilePosition, character, requireFactionPermission: true, out var hasNoFactionPermission, ownedArea: out _) || !IsOwnedLand(toPosition, out hasNoFactionPermission)) { errorMessage = string.Format(CoreStrings.Faction_Permission_Required_Format, CoreStrings.Faction_Permission_LandClaimManagement_Title); // the building location or destination is in an area that is not owned by the player if (logErrors) { SharedShowCannotRelocateNotification( character, protoStructure, hasNoFactionPermission); } return(false); } if (LandClaimSystem.SharedIsUnderRaidBlock(character, objectStructure)) { // the building is in an area under the raid errorMessage = LandClaimSystem.ErrorRaidBlockActionRestricted_Message; if (logErrors) { ConstructionSystem.SharedShowCannotPlaceNotification( character, LandClaimSystem.ErrorRaidBlockActionRestricted_Message, protoStructure); } return(false); } if (LandClaimShieldProtectionSystem.SharedIsUnderShieldProtection(objectStructure)) { // the building is in an area under shield protection errorMessage = CoreStrings.ShieldProtection_ActionRestrictedBaseUnderShieldProtection; if (logErrors) { LandClaimShieldProtectionSystem.SharedSendNotificationActionForbiddenUnderShieldProtection( character); } return(false); } errorMessage = null; return(true); bool IsOwnedLand( Vector2Ushort startTilePosition, out bool hasNoFactionPermission) { var worldObjectLayoutTileOffsets = objectStructure.ProtoStaticWorldObject.Layout.TileOffsets; foreach (var tileOffset in worldObjectLayoutTileOffsets) { if (!LandClaimSystem.SharedIsOwnedLand(startTilePosition.AddAndClamp(tileOffset), character, requireFactionPermission: true, out hasNoFactionPermission, out _)) { return(false); } } hasNoFactionPermission = false; return(true); } }
public static bool SharedValidateCanCharacterRelocateStructure( ICharacter character, IStaticWorldObject objectStructure, Vector2Ushort toPosition, bool logErrors) { if (!SharedIsRelocatable(objectStructure)) { return(false); } if (!SharedCheckTileRequirementsForRelocation(character, objectStructure, toPosition, logErrors)) { return(false); } if (!(objectStructure.ProtoGameObject is IProtoObjectStructure protoStructure)) { return(false); } if (objectStructure.TilePosition.TileSqrDistanceTo(toPosition) > MaxRelocationDistance * MaxRelocationDistance) { if (logErrors) { ConstructionSystem.SharedShowCannotPlaceNotification( character, CoreStrings.Notification_TooFar, protoStructure); } return(false); } var itemInHands = character.SharedGetPlayerSelectedHotbarItem(); if (!(itemInHands.ProtoGameObject is IProtoItemToolToolbox)) { return(false); } if (CreativeModeSystem.SharedIsInCreativeMode(character)) { return(true); } if (!LandClaimSystem.SharedIsOwnedLand(objectStructure.TilePosition, character, out _) || !IsOwnedLand(toPosition)) { // the building location or destination is in an area that is not owned by the player if (logErrors) { ConstructionSystem.SharedShowCannotPlaceNotification( character, LandClaimSystem.ErrorNotLandOwner_Message, protoStructure); } return(false); } if (LandClaimSystem.SharedIsUnderRaidBlock(character, objectStructure)) { // the building is in an area under the raid if (logErrors) { ConstructionSystem.SharedShowCannotPlaceNotification( character, LandClaimSystem.ErrorRaidBlockActionRestricted_Message, protoStructure); } return(false); } if (LandClaimShieldProtectionSystem.SharedIsUnderShieldProtection(objectStructure)) { // the building is in an area under shield protection if (logErrors) { LandClaimShieldProtectionSystem.SharedSendNotificationActionForbiddenUnderShieldProtection( character); } return(false); } return(true); bool IsOwnedLand(Vector2Ushort startTilePosition) { var worldObjectLayoutTileOffsets = objectStructure.ProtoStaticWorldObject.Layout.TileOffsets; foreach (var tileOffset in worldObjectLayoutTileOffsets) { if (!LandClaimSystem.SharedIsOwnedLand(startTilePosition.AddAndClamp(tileOffset), character, out _)) { return(false); } } return(true); } }