Example #1
0
        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);
        }
Example #3
0
        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));
        }