private void ServerRemote_TransferLandClaimToFactionOwnership(ILogicObject area) { var character = ServerRemoteContext.Character; var areasGroup = SharedGetLandClaimAreasGroup(area); if (LandClaimAreasGroup.GetPublicState(areasGroup).ServerFaction is not null) { // already has a faction (and it's not possible to change the faction) Logger.Warning("The land claim areas group is already transferred to a faction."); return; } FactionSystem.ServerValidateHasAccessRights(character, FactionMemberAccessRights.LandClaimManagement, out var faction); var factionOwnedAreas = SharedEnumerateAllFactionAreas(FactionSystem.SharedGetClanTag(faction)); var claimLimitRemains = FactionConstants.SharedGetFactionLandClaimsLimit( Faction.GetPublicState(faction).Level) - factionOwnedAreas.Count(); claimLimitRemains -= LandClaimAreasGroup.GetPrivateState(areasGroup).ServerLandClaimsAreas.Count; if (claimLimitRemains < 0) { Logger.Warning( "Cannot transfer land claims to the faction as it will exceed the land claims number limit"); return; } Logger.Important("Will transfer land claims to the faction: after upgrade the remaining limit will be " + claimLimitRemains); // verify user has access to the land claim var owner = ServerRemoteContext.Character; if (!Server.World.IsInPrivateScope(area, owner)) { throw new Exception( "Cannot interact with the land claim object as the area is not in private scope: " + area); } if (!LandClaimArea.GetPrivateState(area).ServerGetLandOwners() .Contains(owner.Name)) { throw new Exception("Player is not an owner of the land claim area"); } ServerTransferAreasGroupToFactionOwnership(faction, character, areasGroup); var worldObject = InteractionCheckerSystem.SharedGetCurrentInteraction(character); InteractableWorldObjectHelper.ServerTryAbortInteraction(character, worldObject); }
public static string ServerSetOwners( IWorldObject worldObject, List <string> newOwners, ICharacter byOwner) { var protoObject = (IProtoObjectWithOwnersList)worldObject.ProtoGameObject; if (!protoObject.HasOwnersList) { throw new Exception("This object doesn't support owners list: " + worldObject); } var currentOwners = GetPrivateState(worldObject).Owners; if (!currentOwners.Contains(byOwner.Name) && !CreativeModeSystem.SharedIsInCreativeMode(byOwner)) { return(DialogCannotSetOwners_MessageNotOwner); } if (!((IProtoObjectWithOwnersList)worldObject.ProtoGameObject) .SharedCanEditOwners(worldObject, byOwner)) { return(DialogCannotSetOwners_MessageCannotEdit); } currentOwners.GetDiff(newOwners, out var ownersToAdd, out var ownersToRemove); if (ownersToRemove.Count > 0 && currentOwners.Count == ownersToRemove.Count) { return(DialogCannotSetOwners_MessageCannotRemoveLastOwner); } if (ownersToRemove.Contains(byOwner.Name)) { return(DialogCannotSetOwners_MessageCannotRemoveSelf); } if (ownersToAdd.Count == 0 && ownersToRemove.Count == 0) { Logger.Warning( "No need to change the owners - the new owners list is the same as the current owners list: " + worldObject, characterRelated: byOwner); return(null); } foreach (var n in ownersToAdd) { var name = n; var playerToAdd = Api.Server.Characters.GetPlayerCharacter(name); if (playerToAdd is null) { return(string.Format(DialogCannotSetOwners_MessageFormatPlayerNotFound, name)); } // get proper player name name = playerToAdd.Name; if (currentOwners.AddIfNotContains(name)) { Api.Logger.Important($"Added owner: {name}; {worldObject}", characterRelated: byOwner); } } foreach (var name in ownersToRemove) { if (!currentOwners.Remove(name)) { continue; } Api.Logger.Important($"Removed owner: {name}; {worldObject}", characterRelated: byOwner); var removedPlayer = Api.Server.Characters.GetPlayerCharacter(name); if (removedPlayer is null) { continue; } InteractableWorldObjectHelper.ServerTryAbortInteraction(removedPlayer, worldObject); } ServerInvokeOwnersChangedEvent(worldObject); return(null); }
private static void ServerCharacterExitVehicleNow(ICharacter character, IDynamicWorldObject vehicle) { if (ServerVehicleQuitRequests.TryGetValue(character, out var requestedVehicleToQuit)) { ServerVehicleQuitRequests.Remove(character); requestedVehicleToQuit.GetPublicState <VehiclePublicState>() .IsDismountRequested = false; } var characterPublicState = PlayerCharacter.GetPublicState(character); if (characterPublicState.CurrentVehicle != vehicle) { return; } InteractableWorldObjectHelper.ServerTryAbortInteraction(character, vehicle); vehicle.GetPublicState <VehiclePublicState>() .IsDismountRequested = false; characterPublicState.ServerSetCurrentVehicle(null); var vehiclePublicState = vehicle.GetPublicState <VehiclePublicState>(); vehiclePublicState.PilotCharacter = null; Logger.Important("Player exit vehicle: " + vehicle, character); if (!vehicle.IsDestroyed) { var characterPrivateState = PlayerCharacter.GetPrivateState(character); characterPrivateState.LastDismountedVehicleMapMark = new LastDismountedVehicleMapMark(vehicle); } character.ProtoWorldObject.SharedCreatePhysics(character); var protoVehicle = (IProtoVehicle)vehicle.ProtoGameObject; if (!vehicle.IsDestroyed) { vehicle.ProtoWorldObject.SharedCreatePhysics(vehicle); // ensure vehicle stopped Server.World.SetDynamicObjectPhysicsMovement(vehicle, Vector2D.Zero, targetVelocity: 0); Server.World.SetDynamicObjectMoveSpeed(vehicle, 0); Server.World.StopPhysicsBody(vehicle.PhysicsBody); // no need to do this here, as it's done automatically by vehicle's ServerUpdate method //protoVehicle.ServerSetUpdateRate(vehicle, isRare: true); protoVehicle.ServerOnCharacterExitVehicle(vehicle, character); } PlayerCharacter.SharedForceRefreshCurrentItem(character); if (vehicle.IsDestroyed) { return; } // notify player and other players in scope using var tempPlayers = Api.Shared.GetTempList <ICharacter>(); Server.World.GetScopedByPlayers(vehicle, tempPlayers); tempPlayers.Remove(character); Instance.CallClient(character, _ => _.ClientRemote_OnVehicleExitByCurrentPlayer(vehicle, protoVehicle)); Instance.CallClient(tempPlayers.AsList(), _ => _.ClientRemote_OnVehicleExitByOtherPlayer(vehicle, vehicle.Position, protoVehicle)); }