Esempio n. 1
0
        private bool ValidateRequirements()
        {
            // ensure player cannot install the same implant prototype as already installed in another slot
            var itemToInstallProto = this.GetProtoItemToInstall();

            if (itemToInstallProto is not null)
            {
                foreach (var equippedItem in this.ContainerEquipment.Items)
                {
                    if (equippedItem.ProtoItem == itemToInstallProto)
                    {
                        NotificationSystem.ClientShowNotification(NotificationAlreadyInstalled_Title,
                                                                  NotificationAlreadyInstalled_Message,
                                                                  color: NotificationColor.Bad,
                                                                  icon: itemToInstallProto.Icon);
                        return(false);
                    }
                }
            }

            // check biomaterial requirement
            if (!CreativeModeSystem.ClientIsInCreativeMode() &&
                !ClientCurrentCharacterHelper.Character.ContainsItemsOfType(
                    ProtoItemBiomaterialVial,
                    this.Price))
            {
                NotificationSystem.ClientShowNotification(NotificationNotEnoughBiomaterial,
                                                          color: NotificationColor.Bad,
                                                          icon: ProtoItemBiomaterialVial.Icon);
                return(false);
            }

            return(true);
        }
        public static bool SharedCanInteract(
            ICharacter character,
            IWorldObject worldObject,
            bool writeToLog)
        {
            if (IsClient)
            {
                // cannot perform this check on the client side
                return(true);
            }

            if (SharedIsOwner(character, worldObject) ||
                CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                return(true);
            }

            // not an owner
            if (writeToLog)
            {
                ServerNotifyNotOwner(character, worldObject);
            }

            return(false);
        }
Esempio n. 3
0
        public static void Init(ICharacter currentCharacter)
        {
            Reset();

            isInitialized = true;

            if (currentCharacter is null)
            {
                return;
            }

            ClientCurrentCharacterHelper.Init(currentCharacter);
            InitCallback?.Invoke(currentCharacter);

            if (currentCharacter.ProtoCharacter == Api.GetProtoEntity <PlayerCharacter>() ||
                currentCharacter.ProtoCharacter == Api.GetProtoEntity <PlayerCharacterSpectator>() ||
                currentCharacter.ProtoCharacter == Api.GetProtoEntity <PlayerCharacterMob>())
            {
                InitGameplayMode(currentCharacter);
            }

            CreativeModeSystem.ClientRequestCurrentUserIsInCreativeMode();
            ServerOperatorSystem.ClientRequestCurrentUserIsOperator();

            InitEndCallback?.Invoke(currentCharacter);
        }
Esempio n. 4
0
        private void ServerRemote_SetMode(IStaticWorldObject 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.ProtoStaticWorldObject 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);
        }
Esempio n. 5
0
        public override bool SharedCanInteract(ICharacter character, IStaticWorldObject worldObject, bool writeToLog)
        {
            if (!base.SharedCanInteract(character, worldObject, writeToLog))
            {
                return(false);
            }

            if (CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                return(true);
            }

            if (LandClaimSystem.SharedIsObjectInsideOwnedOrFreeArea(worldObject,
                                                                    character,
                                                                    requireFactionPermission: true))
            {
                return(true);
            }

            if (writeToLog)
            {
                if (IsServer)
                {
                    LandClaimSystem.ServerNotifyCannotInteractNotOwner(character, worldObject);
                }
                else
                {
                    LandClaimSystem.ClientCannotInteractNotOwner(worldObject);
                }
            }

            return(false);
        }
Esempio n. 6
0
        public static bool ServerHasAccess(
            IStaticWorldObject worldObject,
            ICharacter character,
            WorldObjectAccessMode currentAccessMode,
            bool writeToLog)
        {
            if (CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                return(true);
            }

            switch (currentAccessMode)
            {
            case WorldObjectAccessMode.Closed:
            default:
                if (writeToLog)
                {
                    Logger.Warning(
                        $"Character cannot interact with {worldObject} - no access.",
                        character);

                    Instance.CallClient(
                        character,
                        _ => _.ClientRemote_OnCannotInteractNoAccess(worldObject));
                }

                return(false);

            case WorldObjectAccessMode.OpensToEveryone:
                return(true);

            case WorldObjectAccessMode.OpensToObjectOwners:
            case WorldObjectAccessMode.OpensToObjectOwnersOrAreaOwners:
            {
                if (WorldObjectOwnersSystem.SharedIsOwner(character, worldObject))
                {
                    // an object owner
                    return(true);
                }

                // not an object owner
                if (currentAccessMode == WorldObjectAccessMode.OpensToObjectOwnersOrAreaOwners)
                {
                    if (LandClaimSystem.SharedIsOwnedLand(worldObject.TilePosition, character, out _))
                    {
                        // an area owner
                        return(true);
                    }
                }

                // not an object owner and not an area owner
                if (writeToLog)
                {
                    WorldObjectOwnersSystem.ServerNotifyNotOwner(character, worldObject);
                }

                return(false);
            }
            }
        }
Esempio n. 7
0
        public ViewModelWindowCrateContainer(
            IStaticWorldObject worldObjectCrate,
            ObjectCratePrivateState privateState,
            Action callbackCloseWindow)
        {
            this.WorldObjectCrate = worldObjectCrate;

            this.ViewModelItemsContainerExchange = new ViewModelItemsContainerExchange(
                privateState.ItemsContainer,
                callbackCloseWindow)
            {
                IsContainerTitleVisible = false
            };

            var isOwner = WorldObjectOwnersSystem.SharedIsOwner(
                ClientCurrentCharacterHelper.Character,
                worldObjectCrate);

            this.ViewModelOwnersEditor = new ViewModelWorldObjectOwnersEditor(
                privateState.Owners,
                canEditOwners: isOwner ||
                CreativeModeSystem.ClientIsInCreativeMode(),
                callbackServerSetOwnersList:
                ownersList => WorldObjectOwnersSystem.ClientSetOwners(this.WorldObjectCrate,
                                                                      ownersList),
                title: CoreStrings.ObjectOwnersList_Title2);

            this.ViewModelAccessModeEditor = new ViewModelWorldObjectAccessModeEditor(
                worldObjectCrate,
                canSetAccessMode: isOwner);
        }
Esempio n. 8
0
        public override bool SharedCanInteract(ICharacter character, IStaticWorldObject worldObject, bool writeToLog)
        {
            if (!base.SharedCanInteract(character, worldObject, writeToLog))
            {
                return(false);
            }

            if (LandClaimSystem.SharedIsObjectInsideOwnedOrFreeArea(worldObject, character) ||
                CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                return(true);
            }

            // not the land owner
            if (writeToLog)
            {
                Logger.Warning(
                    $"Character cannot interact with {worldObject} - not the land owner.",
                    character);

                if (IsClient)
                {
                    WorldObjectOwnersSystem.ClientOnCannotInteractNotOwner(worldObject);
                }
            }

            return(false);
        }
Esempio n. 9
0
        protected override GatheringActionState SharedTryCreateState(WorldActionRequest request)
        {
            var worldObject = request.WorldObject;
            var character   = request.Character;

            var staticWorldObject = (IStaticWorldObject)worldObject;

            if (!(worldObject.ProtoGameObject is IProtoObjectGatherable protoGatherable))
            {
                throw new Exception("Not a gatherable resource: " + worldObject);
            }

            if (IsServer)
            {
                WorldObjectClaimSystem.ServerTryClaim(staticWorldObject,
                                                      character,
                                                      WorldObjectClaimDuration.RegularObjects);
            }

            var durationSeconds = protoGatherable.DurationGatheringSeconds;
            var multiplier      = protoGatherable.GetGatheringSpeedMultiplier(staticWorldObject, character);

            durationSeconds /= multiplier;

            if (CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                durationSeconds = 0.1;
            }

            return(new GatheringActionState(
                       character,
                       staticWorldObject,
                       durationSeconds));
        }
Esempio n. 10
0
            public string ServerRemote_Teleport(Vector2D worldPosition)
            {
                try
                {
                    var character = ServerRemoteContext.Character;
                    if (character.ProtoCharacter is PlayerCharacterSpectator ||
                        ServerOperatorSystem.SharedIsOperator(character) ||
                        CreativeModeSystem.SharedIsInCreativeMode(character))
                    {
                        ServerTeleport(character, worldPosition);
                        var message = CreateResultMessage(character);
                        Logger.Important(message);
                        return(message);
                    }

                    return
                        ("Error: you're not in creative mode and not a spectator. You cannot use the teleport system.");
                }
                catch (Exception ex)
                {
                    var message = ex.Message;
                    Logger.Important(message);
                    return("Error: " + message);
                }
            }
Esempio n. 11
0
        public override bool SharedCanInteract(ICharacter character, IStaticWorldObject worldObject, bool writeToLog)
        {
            if (!base.SharedCanInteract(character, worldObject, writeToLog))
            {
                return(false);
            }

            if (IsClient)
            {
                // cannot perform further checks on client side
                return(true);
            }

            if (PlayerCharacterSpectator.SharedIsSpectator(character) ||
                CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                return(true);
            }

            var publicState = GetPublicState(worldObject);
            var areasGroup  = LandClaimSystem.SharedGetLandClaimAreasGroup(worldObject);

            if (areasGroup is not null &&
                LandClaimAreasGroup.GetPublicState(areasGroup).FactionClanTag is var claimFactionClanTag &&
                !string.IsNullOrEmpty(claimFactionClanTag))
            {
                // the land claim is owned by faction - verify permission
                if (claimFactionClanTag == FactionSystem.SharedGetClanTag(character) &&
                    FactionSystem.SharedHasAccessRight(character, FactionMemberAccessRights.LandClaimManagement))
                {
                    return(true);
                }
            }
Esempio n. 12
0
        public bool SharedIsTechUnlocked(ICharacter character, bool allowIfAdmin = true)
        {
            if (allowIfAdmin &&
                CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                return(true);
            }

            if (this.listedInTechNodes == null ||
                this.listedInTechNodes.Count == 0)
            {
                return(this.IsAutoUnlocked);
            }

            var techs = character.SharedGetTechnologies();

            foreach (var node in this.listedInTechNodes)
            {
                if (techs.SharedIsNodeUnlocked(node))
                {
                    return(true);
                }
            }

            return(false);
        }
Esempio n. 13
0
        public double SharedGetDurationForPlayer(ICharacter character)
        {
            double result;

            if (CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                result = 1; // creative mode - craft in one second
            }
            else
            {
                result = this.OriginalDuration;
            }

            if (this.RecipeType != RecipeType.Hand &&
                this.RecipeType != RecipeType.StationCrafting)
            {
                return(result);
            }

            var multiplier = character.SharedGetFinalStatMultiplier(StatName.CraftingSpeed);

            if (multiplier <= 0)
            {
                // infinitely long! cannot craft
                return(double.MaxValue);
            }

            return(result / multiplier);
        }
Esempio n. 14
0
        private void ServerRemote_CompleteTask(IStaticWorldObject objectLaunchpad, int taskIndex)
        {
            this.VerifyGameObject(objectLaunchpad);
            var character = ServerRemoteContext.Character;

            if (!this.SharedCanInteract(character, objectLaunchpad, writeToLog: true))
            {
                return;
            }

            if (!this.SharedValidateCanCompleteTask(objectLaunchpad, taskIndex, character))
            {
                return;
            }

            // consume items
            if (CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                Logger.Important(character + " is in creative mode - no items deduction on task completion.");
            }
            else
            {
                InputItemsHelper.ServerDestroyItems(character, this.TasksList[taskIndex].InputItems);
            }

            var privateState        = GetPrivateState(objectLaunchpad);
            var taskCompletionState = privateState.TaskCompletionState;

            taskCompletionState              = taskCompletionState.ToArray();
            taskCompletionState[taskIndex]   = true;
            privateState.TaskCompletionState = taskCompletionState;

            Logger.Important(objectLaunchpad + " task completed: #" + taskIndex, character);
        }
        private double CalculateStageDurationSeconds(ICharacter character, bool isFirstStage)
        {
            if (CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                // force instant deconstruct
                return(0);
            }

            var durationSeconds = DefaultDeconstructionStepDurationSeconds;

            durationSeconds /= this.ProtoItemCrowbarTool?.DeconstructionSpeedMultiplier ?? 1;
            durationSeconds /= character.SharedGetFinalStatMultiplier(StatName.BuildingSpeed);
            durationSeconds  = Api.Shared.RoundDurationByServerFrameDuration(durationSeconds);

            if (isFirstStage && Api.IsClient)
            {
                // Add ping to all client action durations.
                // Otherwise the client will not see immediately the result of the action
                // - the client will receive it only after RTT (ping) time.
                // TODO: currently it's possible to cancel action earlier and start a new one, but completed action result will come from server - which looks like a bug to player
                durationSeconds += Api.Client.CurrentGame.PingGameSeconds;
            }

            return(durationSeconds);
        }
Esempio n. 16
0
        private static bool SharedIsTooFarToPlace(
            IProtoObjectStructure protoStructure,
            Vector2Ushort tilePosition,
            ICharacter character,
            bool logErrors)
        {
            if (character.TilePosition.TileDistanceTo(tilePosition)
                <= MaxDistanceToBuild ||
                CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                return(false);
            }

            if (!logErrors)
            {
                return(true);
            }

            Logger.Info(
                $"Cannot place {protoStructure} at {tilePosition}: player character is too far.",
                character);

            if (IsClient)
            {
                Instance.ClientRemote_CannotBuildTooFar(protoStructure);
            }
            else
            {
                Instance.CallClient(character, _ => _.ClientRemote_CannotBuildTooFar(protoStructure));
            }

            return(true);
        }
 void IInteractableProtoWorldObject.ServerOnClientInteract(ICharacter who, IWorldObject worldObject)
 {
     if (WorldObjectOwnersSystem.SharedIsOwner(who, (IStaticWorldObject)worldObject) ||
         CreativeModeSystem.SharedIsInCreativeMode(who))
     {
         Server.World.EnterPrivateScope(who, worldObject);
     }
 }
Esempio n. 18
0
        public static bool SharedCheckCanDeconstruct(IStaticWorldObject worldObject, ICharacter character)
        {
            // Please note: the game already have validated that the target object is a structure
            if (worldObject.ProtoGameObject is ObjectWallDestroyed)
            {
                // always allow deconstruct a destroyed wall object even if it's in another player's land claim
                return(true);
            }

            if (CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                // operator can deconstruct any structure
                return(true);
            }

            RectangleInt worldObjectBounds;
            {
                var temp         = worldObject.ProtoStaticWorldObject.Layout.Bounds;
                var tilePosition = worldObject.TilePosition;
                worldObjectBounds = new RectangleInt(
                    temp.MinX + tilePosition.X,
                    temp.MinY + tilePosition.Y,
                    temp.Size.X,
                    temp.Size.Y);
            }

            var isThereAnyArea = false;

            foreach (var area in sharedLandClaimAreas)
            {
                var areaBounds = SharedGetLandClaimAreaBounds(area);
                if (!areaBounds.IntersectsLoose(worldObjectBounds))
                {
                    continue;
                }

                isThereAnyArea = true;
                // intersection with area found - check if player owns the area
                if (SharedIsOwnedArea(area, character))
                {
                    // player own the area
                    return(true);
                }
            }

            // no area or not owned area
            if (!isThereAnyArea)
            {
                // no area
                if (worldObject.ProtoGameObject is ProtoObjectConstructionSite)
                {
                    // can deconstruct blueprints if there is no land claim area
                    return(true);
                }
            }

            return(false);
        }
Esempio n. 19
0
        private void ServerRemote_RelocateStructure(IStaticWorldObject objectStructure, Vector2Ushort toPosition)
        {
            if (objectStructure.TilePosition == toPosition)
            {
                // relocation not required
                return;
            }

            var character = ServerRemoteContext.Character;

            if (!SharedValidateCanCharacterRelocateStructure(character,
                                                             objectStructure,
                                                             toPosition,
                                                             errorMessage: out _,
                                                             logErrors: true))
            {
                return;
            }

            var fromPosition = objectStructure.TilePosition;

            Api.SafeInvoke(
                () => ServerStructureBeforeRelocating?.Invoke(character, fromPosition, objectStructure));

            Server.World.SetPosition(objectStructure, toPosition);

            try
            {
                // ensure the structure is reinitialized (has its physics rebuilt, etc)
                objectStructure.ServerInitialize();
            }
            catch (Exception ex)
            {
                Logger.Exception(ex);
            }

            ConstructionPlacementSystem.Instance.ServerNotifyOnStructurePlacedOrRelocated(objectStructure, character);

            Api.SafeInvoke(
                () => ServerStructureRelocated?.Invoke(character, fromPosition, objectStructure));

            // let's deduct the tool durability
            if (CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                return;
            }

            // the item in hotbar is definitely a construction tool as it was validated above
            var itemConstructionTool = character.SharedGetPlayerSelectedHotbarItem();

            ItemDurabilitySystem.ServerModifyDurability(
                itemConstructionTool,
                delta: -((IProtoObjectStructure)objectStructure.ProtoGameObject).RelocationToolDurabilityCost);
        }
Esempio n. 20
0
        private void ControlWorldMapMouseRightButtonUpHandler(object sender, MouseButtonEventArgs e)
        {
            var mapPositionWithOffset = this.controlWorldMap.WorldMapController.PointedMapPositionWithOffset;

            this.CloseContextMenu();

            var contextMenu = new ContextMenu();

            contextMenu.Items.Add(new MenuItem()
            {
                Header  = ContextMenuCopyCoordinates,
                Command = new ActionCommand(
                    () => Api.Client.Core.CopyToClipboard(mapPositionWithOffset.ToString()))
            });

            var character = Api.Client.Characters.CurrentPlayerCharacter;

            if (character.ProtoCharacter is PlayerCharacterSpectator ||
                ServerOperatorSystem.SharedIsOperator(character) ||
                CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                var mapPositionWithoutOffset = this.controlWorldMap.WorldMapController.PointedMapPositionWithoutOffset;
                contextMenu.Items.Add(new MenuItem()
                {
                    Header  = ContextMenuTeleport,
                    Command = new ActionCommand(
                        () => this.CallTeleport(mapPositionWithoutOffset.ToVector2D()))
                });
            }

            var position = Mouse.GetPosition(this);

            contextMenu.PlacementRectangle = new Rect(position.X, position.Y, 0, 0);

            this.ContextMenu    = contextMenu;
            contextMenu.Closed += ContextMenuOnClosed;
            contextMenu.IsOpen  = true;

            void ContextMenuOnClosed(object s, RoutedEventArgs _)
            {
                contextMenu.Closed -= ContextMenuOnClosed;
                // remove context menu with the delay (to avoid teleport-on-click when context menu is closed)
                ClientTimersSystem.AddAction(
                    delaySeconds: 0.1,
                    () =>
                {
                    if (this.ContextMenu == contextMenu)
                    {
                        this.ContextMenu = null;
                    }
                });
            }
        }
Esempio n. 21
0
        private void ServerRemote_SetDirectAccessMode(IStaticWorldObject worldObject, WorldObjectDirectAccessMode mode)
        {
            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 areasGroup = LandClaimSystem.SharedGetLandClaimAreasGroup(worldObject);

            if (areasGroup is not null &&
                LandClaimAreasGroup.GetPublicState(areasGroup).ServerFaction is not null)
            {
                throw new Exception(
                          "Cannot modify direct access mode for an object within a faction land claim area");
            }

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

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

            if (mode == WorldObjectDirectAccessMode.OpensToEveryone &&
                !protoObjectWithAccessMode.IsEveryoneAccessModeAvailable)
            {
                throw new Exception("Everyone access mode is not supported for " + protoObjectWithAccessMode);
            }

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

            if (privateState.DirectAccessMode == mode)
            {
                return;
            }

            privateState.DirectAccessMode = mode;
            Logger.Info($"Direct access mode changed: {mode}; {worldObject}", character);
        }
Esempio n. 22
0
        private void ServerRemote_BuildReactor(IStaticWorldObject worldObjectGenerator, byte reactorIndex)
        {
            this.VerifyGameObject(worldObjectGenerator);
            var character = ServerRemoteContext.Character;

            if (!this.SharedCanInteract(character, worldObjectGenerator, writeToLog: true))
            {
                return;
            }

            if (reactorIndex >= this.ReactorsCountMax)
            {
                throw new ArgumentOutOfRangeException(nameof(reactorIndex));
            }

            var privateState = GetPrivateState(worldObjectGenerator);
            var publicState  = GetPublicState(worldObjectGenerator);

            var reactorPrivateStates = privateState.ReactorStates;
            var reactorPrivateState  = reactorPrivateStates[reactorIndex];

            if (reactorPrivateState is not null)
            {
                throw new Exception($"The reactor is already built: #{reactorIndex} in {worldObjectGenerator}");
            }

            if (!InputItemsHelper.SharedPlayerHasRequiredItems(character,
                                                               this.BuildAdditionalReactorRequiredItems,
                                                               noCheckInCreativeMode: true))
            {
                throw new Exception($"Not enough items to build a reactor: #{reactorIndex} in {worldObjectGenerator}");
            }

            if (!CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                InputItemsHelper.ServerDestroyItems(character, this.BuildAdditionalReactorRequiredItems);
            }

            reactorPrivateState = new ObjectGeneratorPragmiumReactorPrivateState();
            reactorPrivateStates[reactorIndex] = reactorPrivateState;

            this.ServerSetupReactorPrivateState(worldObjectGenerator, reactorPrivateState);

            var reactorPublicStates = publicState.ReactorStates;

            reactorPublicStates[reactorIndex] = new ObjectGeneratorPragmiumReactorPublicState();

            // force refresh over the network and properly binding the state owner object
            privateState.ReactorStates = reactorPrivateStates.ToArray();
            publicState.ReactorStates  = reactorPublicStates.ToArray();
        }
Esempio n. 23
0
        private static void ValidateCanAdminAndInteract(ICharacter character, IStaticWorldObject tradingStation)
        {
            if (!tradingStation.ProtoStaticWorldObject
                .SharedCanInteract(character, tradingStation, writeToLog: true))
            {
                throw new Exception($"{character} cannot interact with {tradingStation}");
            }

            if (!WorldObjectOwnersSystem.SharedIsOwner(character, tradingStation) &&
                !CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                throw new Exception($"{character} is not owner of {tradingStation}");
            }
        }
Esempio n. 24
0
        protected override void ServerOnStaticObjectZeroStructurePoints(
            WeaponFinalCache weaponCache,
            ICharacter byCharacter,
            IWorldObject targetObject)
        {
            // do not use default implementation because it will destroy the object automatically
            //base.ServerOnStaticObjectZeroStructurePoints(weaponCache, targetObject);

            var worldObject = (IStaticWorldObject)targetObject;
            var publicState = GetPublicState(worldObject);

            if (byCharacter != null &&
                (LandClaimSystem.ServerIsOwnedArea(publicState.LandClaimAreaObject, byCharacter) ||
                 CreativeModeSystem.SharedIsInCreativeMode(byCharacter)))
            {
                // this is the owner of the area or the player is in a creative mode
                if (byCharacter.SharedGetPlayerSelectedHotbarItemProto() is ProtoItemToolCrowbar)
                {
                    publicState.ServerTimeForDestruction = 0;
                    Logger.Important(
                        $"Land claim object {targetObject} destroyed by the owner with a crowbar - no destruction timer",
                        byCharacter);

                    this.ServerForceUpdate(worldObject, publicState);
                    return;
                }
            }

            if (byCharacter != null)
            {
                var areaPrivateState = LandClaimArea.GetPrivateState(publicState.LandClaimAreaObject);
                areaPrivateState.IsDestroyedByPlayers = true;
            }

            if (publicState.ServerTimeForDestruction.HasValue)
            {
                // destruction timer is already set
                return;
            }

            // the land claim structure points is zero - it's broken now - set timer for destruction
            var timeout = PveSystem.ServerIsPvE
                              ? 0
                              : this.DestructionTimeout.TotalSeconds;

            publicState.ServerTimeForDestruction = Server.Game.FrameTime + timeout;

            Logger.Important($"Timer for destruction set: {targetObject}. Timeout: {timeout}");
            this.ServerForceUpdate(worldObject, publicState);
        }
Esempio n. 25
0
        public bool SharedCanEditOwners(IStaticWorldObject worldObject, ICharacter byOwner)
        {
            var area         = GetPublicState(worldObject).LandClaimAreaObject;
            var privateState = LandClaimArea.GetPrivateState(area);

            if (privateState.LandClaimFounder == byOwner.Name ||
                CreativeModeSystem.SharedIsInCreativeMode(byOwner))
            {
                // only founder or character in creative mode can edit the owners list
                return(true);
            }

            return(false);
        }
Esempio n. 26
0
        public override bool CanRemoveItem(CanRemoveItemContext context)
        {
            if (!(context.Item.ProtoItem is IProtoItemEquipment protoItem))
            {
                return(true);
            }

            var itemEquipmentType = protoItem.EquipmentType;

            //MOD
            if (itemEquipmentType == EquipmentType.Device &&
                context.Item.ProtoGameObject is ProtoItemBackpack backpack)
            {
                return(backpack.SharedCanRemoveItem(context.Item, context.ByCharacter, false));
            }

            if (!(context.Item.ProtoItem is IProtoItemEquipmentImplant protoItemEquipment))
            {
                // impossible - how did it end up here?
                return(true);
            }

            if (itemEquipmentType == EquipmentType.Implant)
            {
                // implant item
                if (context.ByCharacter is null ||
                    CreativeModeSystem.SharedIsInCreativeMode(context.ByCharacter))
                {
                    // Allowed to add/remove implant item by the game only (via medical station).
                    // But allow to characters in the creative mode to do this directly.
                    return(true);
                }

                if (IsClient)
                {
                    ClientShowNotificationCannotRemoveImplant(protoItemEquipment);
                }
                else
                {
                    this.CallClient(context.ByCharacter,
                                    _ => _.ClientRemote_ClientShowNotificationCannotRemoveImplant(protoItemEquipment));
                }

                return(false);
            }

            // can remove anything
            return(true);
        }
Esempio n. 27
0
        public ViewModelWindowCrateContainer(
            IStaticWorldObject worldObjectCrate,
            ObjectCratePrivateState privateState,
            Action callbackCloseWindow)
        {
            this.WorldObjectCrate = worldObjectCrate;

            this.ViewModelItemsContainerExchange = new ViewModelItemsContainerExchange(
                privateState.ItemsContainer,
                callbackCloseWindow)
            {
                IsContainerTitleVisible = false
            };

            this.IsInsideFactionClaim = LandClaimSystem.SharedIsWorldObjectOwnedByFaction(worldObjectCrate);

            if (!this.HasOwnersList)
            {
                return;
            }

            if (this.IsInsideFactionClaim)
            {
                if (FactionSystem.ClientHasAccessRight(FactionMemberAccessRights.LandClaimManagement))
                {
                    this.ViewModelFactionAccessEditor = new ViewModelWorldObjectFactionAccessEditorControl(
                        worldObjectCrate);
                }
            }
            else
            {
                var isOwner = WorldObjectOwnersSystem.SharedIsOwner(
                    ClientCurrentCharacterHelper.Character,
                    worldObjectCrate);

                this.ViewModelOwnersEditor = new ViewModelWorldObjectOwnersEditor(
                    privateState.Owners,
                    canEditOwners: isOwner ||
                    CreativeModeSystem.ClientIsInCreativeMode(),
                    callbackServerSetOwnersList:
                    ownersList => WorldObjectOwnersSystem.ClientSetOwners(this.WorldObjectCrate,
                                                                          ownersList),
                    title: CoreStrings.ObjectOwnersList_Title2);

                this.ViewModelDirectAccessEditor = new ViewModelWorldObjectDirectAccessEditor(
                    worldObjectCrate,
                    canSetAccessMode: isOwner);
            }
        }
Esempio n. 28
0
        private void MapClickHandler(Vector2D worldPosition)
        {
            if (this.ContextMenu != null)
            {
                // context menu is still exist, don't process this click
                return;
            }

            var character = ClientCurrentCharacterHelper.Character;

            if (character.ProtoCharacter is PlayerCharacterSpectator ||
                CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                this.CallTeleport(worldPosition);
            }
        }
Esempio n. 29
0
        private void ServerRemote_Repair()
        {
            var character         = ServerRemoteContext.Character;
            var tinkerTableObject =
                InteractionCheckerSystem.SharedGetCurrentInteraction(character) as IStaticWorldObject;

            this.VerifyGameObject(tinkerTableObject);

            var worldObjectPrivateState = GetPrivateState(tinkerTableObject);
            var containerInput          = worldObjectPrivateState.ContainerInput;
            var containerOutput         = worldObjectPrivateState.ContainerOutput;
            var inputItem1 = containerInput.GetItemAtSlot(0);
            var inputItem2 = containerInput.GetItemAtSlot(1);

            if (!ValidateCanRepair(character, tinkerTableObject, out var error))
            {
                Logger.Warning(tinkerTableObject + " cannot repair: " + error, character);
                return;
            }

            if (!CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                InputItemsHelper.ServerDestroyItems(character, RequiredRepairComponentItems);
            }

            var resultDurabilityFraction = SharedCalculateResultDurabilityFraction(inputItem1, inputItem2, character);

            Server.Items.DestroyItem(inputItem2);
            Server.Items.MoveOrSwapItem(inputItem1,
                                        containerOutput,
                                        out _);

            var resultItemProto        = (IProtoItemWithDurablity)inputItem1.ProtoGameObject;
            var resultItemPrivateState = inputItem1.GetPrivateState <IItemWithDurabilityPrivateState>();

            resultItemPrivateState.DurabilityCurrent = (uint)Math.Round(
                resultDurabilityFraction * resultItemProto.DurabilityMax,
                MidpointRounding.AwayFromZero);

            character.ServerAddSkillExperience <SkillMaintenance>(
                SkillMaintenance.ExperiencePerItemRepaired);

            Logger.Info(
                $"Item repaired: {inputItem1}. Second item was destroyed to use for repair components: {inputItem2}");
        }
Esempio n. 30
0
        private static bool SharedValidateHasRequiredComponentItems(ICharacter character)
        {
            if (CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                return(true);
            }

            foreach (var requiredItem in RequiredRepairComponentItems)
            {
                if (!character.ContainsItemsOfType(requiredItem.ProtoItem, requiredItem.Count))
                {
                    // some item is not available
                    return(false);
                }
            }

            return(true);
        }