예제 #1
0
        public static bool ServerIsWateringRequired(
            IWorldObject objectPlant,
            ICharacter character,
            IProtoItem protoItem,
            IProtoObjectPlant protoPlant,
            double proposedWateringDuration)
        {
            var plantPrivateState = objectPlant.GetPrivateState <PlantPrivateState>();

            if (plantPrivateState.ServerTimeWateringEnds >= double.MaxValue ||
                (proposedWateringDuration < double.MaxValue &&
                 (plantPrivateState.ServerTimeWateringEnds
                  >= Server.Game.FrameTime + proposedWateringDuration - 60)))
            {
                // the plant is already watered enough
                Instance.CallClient(character, _ => _.ClientRemote_CannotWaterAlreadyWatered(protoItem));
                return(false);
            }

            if (!protoPlant.ServerCanBeWatered((IStaticWorldObject)objectPlant))
            {
                // no need to water the plant
                Instance.CallClient(character, _ => _.ClientRemote_CannotWaterLastHarvestOrRotten(protoItem));
                return(false);
            }

            return(true);
        }
예제 #2
0
        public ViewModelWorldObjectAccessModeEditor(IWorldObject worldObject, bool canSetAccessMode)
        {
            this.worldObject      = worldObject;
            this.CanSetAccessMode = canSetAccessMode;

            if (!(worldObject.ProtoGameObject is IProtoObjectWithAccessMode protoObjectWithAccessMode))
            {
                throw new Exception("This world object doesn't have an access mode");
            }

            var accessModes = Enum.GetValues(typeof(WorldObjectAccessMode))
                              .Cast <WorldObjectAccessMode>();

            if (!protoObjectWithAccessMode.IsClosedAccessModeAvailable)
            {
                accessModes = accessModes.ExceptOne(WorldObjectAccessMode.Closed);
            }

            this.AccessModes = accessModes
                               .Select(e => new ViewModelEnum <WorldObjectAccessMode>(e))
                               .OrderBy(vm => vm.Order)
                               .ToArray();

            this.privateState = worldObject.GetPrivateState <IObjectWithAccessModePrivateState>();

            this.privateState.ClientSubscribe(
                _ => _.AccessMode,
                _ => this.RefreshAccessMode(),
                this);

            this.RefreshAccessMode();
        }
예제 #3
0
        private void ServerRemote_SetMode(IWorldObject worldObject, WorldObjectAccessMode mode)
        {
            var character = ServerRemoteContext.Character;

            if (!InteractionCheckerSystem.SharedHasInteraction(character,
                                                               worldObject,
                                                               requirePrivateScope: true))
            {
                throw new Exception("The player character is not interacting with " + worldObject);
            }

            if (!WorldObjectOwnersSystem.SharedIsOwner(character, worldObject) &&
                !CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                throw new Exception("The player character is not the owner of " + worldObject);
            }

            if (!(worldObject.ProtoGameObject is IProtoObjectWithAccessMode protoObjectWithAccessMode))
            {
                throw new Exception("This world object doesn't have an access mode");
            }

            if (mode == WorldObjectAccessMode.Closed &&
                !protoObjectWithAccessMode.IsClosedAccessModeAvailable)
            {
                throw new Exception("Closed access mode is not supported for " + protoObjectWithAccessMode);
            }

            var privateState = worldObject.GetPrivateState <IObjectWithAccessModePrivateState>();

            privateState.AccessMode = mode;
            Logger.Important($"Access mode changed: {mode}; {worldObject}", character);
        }
예제 #4
0
        public static bool ServerHasAccess(
            IWorldObject worldObject,
            ICharacter character,
            bool writeToLog)
        {
            var privateState = worldObject.GetPrivateState <IObjectWithAccessModePrivateState>();

            return(ServerHasAccess(worldObject,
                                   character,
                                   privateState.AccessMode,
                                   writeToLog));
        }
예제 #5
0
        public ViewModelWorldObjectFactionAccessEditorControl(IWorldObject worldObject)
        {
            this.worldObject = worldObject;
            this.accessRight = WorldObjectAccessModeSystem.SharedGetFactionAccessRightRequirementForObject(worldObject);

            if (worldObject.ProtoGameObject is not IProtoObjectWithAccessMode protoObjectWithAccessMode)
            {
                throw new Exception("This world object doesn't have an access mode");
            }

            this.isClosedModeAvailable   = protoObjectWithAccessMode.IsClosedAccessModeAvailable;
            this.isEveryoneModeAvailable = protoObjectWithAccessMode.IsEveryoneAccessModeAvailable;

            this.privateState = worldObject.GetPrivateState <IObjectWithAccessModePrivateState>();
            this.privateState.ClientSubscribe(_ => _.FactionAccessMode,
                                              _ => this.RefreshCheckboxes(),
                                              this);

            FactionSystem.ClientCurrentFactionAccessRightsChanged += this.CurrentFactionAccessRightsChanged;

            this.RecreateViewModelAccessModes();
        }
 private static ObjectGeneratorWithFuelPrivateState GetPrivateState(
     IWorldObject objectManufacturer)
 {
     return(objectManufacturer.GetPrivateState <ObjectGeneratorWithFuelPrivateState>());
 }
예제 #7
0
 private static IObjectWithOwnersPrivateState GetPrivateState(IWorldObject structure)
 {
     return(structure.GetPrivateState <IObjectWithOwnersPrivateState>());
 }
예제 #8
0
        protected override void CheckInteractionQueue()
        {
            if (openedLootContainer != null)
            {
                if (InteractionCheckerSystem.SharedHasInteraction(CurrentCharacter, openedLootContainer, true))
                {
                    // We get container private state, now take all items from container.
                    var q      = openedLootContainer.GetPrivateState <LootContainerPrivateState>();
                    var result =
                        CurrentCharacter.ProtoCharacter.ClientTryTakeAllItems(CurrentCharacter, q.ItemsContainer, true);
                    if (result.MovedItems.Count > 0)
                    {
                        NotificationSystem.ClientShowItemsNotification(
                            itemsChangedCount: result.MovedItems
                            .GroupBy(p => p.Key.ProtoItem)
                            .ToDictionary(p => p.Key, p => p.Sum(v => v.Value)));
                    }
                    InteractionCheckerSystem.CancelCurrentInteraction(CurrentCharacter);
                }
                else if (openedLootContainer.ProtoWorldObject
                         .SharedCanInteract(CurrentCharacter, openedLootContainer, false))
                {
                    // Waiting for container private state from server.
                    return;
                }
                openedLootContainer = null;
                readyForInteraction = true;
            }

            if (!readyForInteraction)
            {
                return;
            }

            // Remove from queue while it have object and they in our whitelist if:
            //  - object is destroyed
            //  - if object is container that we already have looted
            //  - if object not IProtoObjectGatherable
            //  - if we can not interact with object right now
            //  - if we can not gather anything from object
            while (interactionQueue.Count != 0 && EnabledEntityList.Contains(interactionQueue[0].ProtoGameObject) &&
                   (interactionQueue[0].IsDestroyed ||
                    (lastActionState != null &&
                     lastActionState.TargetWorldObject == interactionQueue[0] &&
                     lastActionState.IsCompleted &&
                     !lastActionState.IsCancelled &&
                     !lastActionState.IsCancelledByServer) ||
                    !(interactionQueue[0].ProtoGameObject is IProtoObjectGatherable protoGatherable) ||
                    !protoGatherable.SharedCanInteract(CurrentCharacter, interactionQueue[0], false) ||
                    !protoGatherable.SharedIsCanGather(interactionQueue[0])))
            {
                interactionQueue.RemoveAt(0);
            }

            if (interactionQueue.Count == 0)
            {
                return;
            }

            var request = new WorldActionRequest(CurrentCharacter, interactionQueue[0]);

            GatheringSystem.Instance.SharedStartAction(request);
        }
예제 #9
0
        private void ServerRemote_SetFactionAccessMode(
            IWorldObject worldObject,
            WorldObjectFactionAccessModes modes)
        {
            var character = ServerRemoteContext.Character;

            if (!(worldObject.ProtoGameObject is IProtoObjectWithAccessMode protoObjectWithAccessMode))
            {
                throw new Exception("This world object doesn't have an access mode");
            }

            if (!protoObjectWithAccessMode.SharedCanInteract(character, worldObject, writeToLog: true))
            {
                return;
            }

            var faction = ServerGetOwningFaction(worldObject);

            if (faction is null)
            {
                throw new Exception("No faction");
            }

            if (!CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                // verify permission to access object
                FactionSystem.ServerValidateHasAccessRights(
                    character,
                    SharedGetFactionAccessRightRequirementForObject(worldObject),
                    out var characterFaction);

                if (!ReferenceEquals(faction, characterFaction))
                {
                    throw new Exception(worldObject + " belongs to another faction - cannot modify its access");
                }
            }

            if (modes == WorldObjectFactionAccessModes.Closed &&
                !protoObjectWithAccessMode.IsClosedAccessModeAvailable)
            {
                throw new Exception("Closed access mode is not supported for " + protoObjectWithAccessMode);
            }

            if ((modes == WorldObjectFactionAccessModes.Everyone ||
                 modes == WorldObjectFactionAccessModes.AllyFactionMembers) &&
                !protoObjectWithAccessMode.IsEveryoneAccessModeAvailable)
            {
                throw new Exception("Everyone and Ally access modes are not supported for "
                                    + protoObjectWithAccessMode);
            }

            var privateState  = worldObject.GetPrivateState <IObjectWithAccessModePrivateState>();
            var previousModes = privateState.FactionAccessMode;

            if (!protoObjectWithAccessMode.CanChangeFactionRoleAccessForSelfRole)
            {
                var role = FactionSystem.ServerGetRole(character);
                switch (role)
                {
                case FactionMemberRole.Officer1
                    when previousModes.HasFlag(WorldObjectFactionAccessModes.Officer1)
                    ^ modes.HasFlag(WorldObjectFactionAccessModes.Officer1):

                case FactionMemberRole.Officer2
                    when previousModes.HasFlag(WorldObjectFactionAccessModes.Officer2)
                    ^ modes.HasFlag(WorldObjectFactionAccessModes.Officer2):

                case FactionMemberRole.Officer3
                    when previousModes.HasFlag(WorldObjectFactionAccessModes.Officer3)
                    ^ modes.HasFlag(WorldObjectFactionAccessModes.Officer3):
                    throw new Exception("Cannot change access setting for self role " + protoObjectWithAccessMode);
                }
            }

            if (previousModes == modes)
            {
                return;
            }

            privateState.FactionAccessMode = modes;
            Logger.Info($"Faction access mode changed: {modes}; {worldObject}", character);
        }