Exemplo n.º 1
0
        protected BaseUserControlWithWindow ClientOpenUI(ClientObjectData data)
        {
            var worldObject = data.GameObject;
            var publicState = data.SyncPublicState;

            if (worldObject.ClientHasPrivateState &&
                !Client.Input.IsKeyHeld(InputKey.Alt))
            {
                // open admin window
                return(WindowTradingStationAdmin.Open(
                           new ViewModelWindowTradingStationAdmin(worldObject,
                                                                  data.SyncPrivateState,
                                                                  publicState)));
            }

            // open user window (if has any lots)
            if (publicState.Lots.Any(l => l.State != TradingStationLotState.Disabled))
            {
                return(WindowTradingStationUser.Open(
                           new ViewModelWindowTradingStationUser(worldObject,
                                                                 publicState)));
            }

            CannotInteractMessageDisplay.ShowOn(worldObject,
                                                publicState.Mode == TradingStationMode.StationSelling
                                                    ? NotificationNothingForSale
                                                    : NotificationNoTradingLots);
            return(null);
        }
Exemplo n.º 2
0
        protected override async void ClientInteractStart(ClientObjectData data)
        {
            var bedObject = data.GameObject;
            var (isSuccess, name) = await this.CallServer(_ => _.ServerRemote_GetBedOwnerName(bedObject));
            if (!isSuccess)
            {
                ClientOnCannotInteract(bedObject, CoreStrings.Notification_TooFar, isOutOfRange: true);
                return;
            }

            var isFree = string.IsNullOrEmpty(name);
            if (isFree)
            {
                DialogWindow.ShowDialog(
                    DialogClaimBed_Title,
                    DialogClaimBed_Message,
                    okText: CoreStrings.Yes,
                    okAction: () => this.ClientMakeCurrentBed(bedObject),
                    hideCancelButton: false);
                return;
            }

            var message = name == Client.Characters.CurrentPlayerCharacter.Name
                              ? MessageBedBelongsToCurrentPlayer
                              : string.Format(MessageFormatBedBelongsToAnotherPlayer, name);

            CannotInteractMessageDisplay.ShowOn(bedObject, message);
            this.SoundPresetObject.PlaySound(ObjectSound.InteractSuccess);
        }
Exemplo n.º 3
0
        protected override void SharedValidateRequest(WorldActionRequest request)
        {
            var worldObject = request.WorldObject;

            if (!(worldObject?.ProtoWorldObject is IProtoObjectGatherable))
            {
                throw new Exception("The world object must be gatherable");
            }

            if (!worldObject.ProtoWorldObject.SharedCanInteract(request.Character, worldObject, true))
            {
                throw new Exception("Cannot interact with " + worldObject);
            }

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

            if (!protoGatherable.SharedIsCanGather((IStaticWorldObject)worldObject))
            {
                Logger.Warning("Cannot gather now: " + worldObject, request.Character);
                if (Api.IsClient)
                {
                    CannotInteractMessageDisplay.ShowOn(worldObject, NotificationNothingToHarvestYet);
                    worldObject.ProtoWorldObject.SharedGetObjectSoundPreset()
                    .PlaySound(ObjectSound.InteractFail);
                }

                throw new Exception("Cannot gather now: " + worldObject);
            }
        }
Exemplo n.º 4
0
        public virtual void ClientOnCannotInteract(
            TWorldObject worldObject,
            string message,
            bool isOutOfRange = false)
        {
            CannotInteractMessageDisplay.ShowOn(worldObject, message);

            var soundKey = isOutOfRange ? ObjectSound.InteractOutOfRange : ObjectSound.InteractFail;

            worldObject.ProtoWorldObject.SharedGetObjectSoundPreset()
            .PlaySound(soundKey);
        }
Exemplo n.º 5
0
        public static bool SharedCheckCanInteract(
            ICharacter character,
            IWorldObject worldObject,
            bool writeToLog)
        {
            if (worldObject == null ||
                worldObject.IsDestroyed)
            {
                return(false);
            }

            // Can deconstruct only if the character can contact directly
            // with the object click area (if object has the click area)
            // or with the object collider (if object don't has the click area).
            var isObjectHasClickArea = worldObject.PhysicsBody
                                       .Shapes
                                       .Any(s => s.CollisionGroup == CollisionGroups.ClickArea);

            var result = worldObject.ProtoWorldObject.SharedIsInsideCharacterInteractionArea(
                character,
                worldObject,
                writeToLog: false,
                requiredCollisionGroup: isObjectHasClickArea
                                            ? CollisionGroups.ClickArea
                                            : CollisionGroups
                .DefaultWithCollisionToInteractionArea);

            if (result)
            {
                return(true);
            }

            if (writeToLog)
            {
                Logger.Warning(
                    $"Cannot deconstruct - {character} cannot interact with the {worldObject} - there is no direct (physics) line of sight between them (the object click area or static/dynamic colliders must be inside the character interaction area)");

                if (IsClient)
                {
                    CannotInteractMessageDisplay.ShowOn(worldObject, CoreStrings.Notification_TooFar);
                    worldObject.ProtoWorldObject.SharedGetObjectSoundPreset()
                    .PlaySound(ObjectSound.InteractOutOfRange);
                }
            }

            return(false);
        }
Exemplo n.º 6
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 (!protoGatherable.SharedIsCanGather(staticWorldObject))
            {
                Logger.Warning("Cannot gather now: " + worldObject, character);
                if (Api.IsClient)
                {
                    CannotInteractMessageDisplay.ShowOn(worldObject, NotificationNothingToHarvestYet);
                    worldObject.ProtoWorldObject.SharedGetObjectSoundPreset()
                    .PlaySound(ObjectSound.InteractFail);
                }

                return(null);
            }

            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));
        }
Exemplo n.º 7
0
        protected override void SharedValidateRequest(WorldActionRequest request)
        {
            var worldObject = (IStaticWorldObject)request.WorldObject;

            if (!(worldObject?.ProtoWorldObject is IProtoObjectGatherable protoGatherable))
            {
                throw new Exception("The world object must be gatherable");
            }

            if (!worldObject.ProtoWorldObject.SharedCanInteract(request.Character, worldObject, true))
            {
                throw new Exception("Cannot interact with " + worldObject);
            }

            if (!WorldObjectClaimSystem.SharedIsAllowInteraction(request.Character,
                                                                 worldObject,
                                                                 showClientNotification: true))
            {
                throw new Exception("Locked for another player: " + worldObject);
            }

            if (protoGatherable.SharedIsCanGather(worldObject))
            {
                return;
            }

            Logger.Warning("Cannot gather now: " + worldObject, request.Character);
            if (Api.IsClient)
            {
                CannotInteractMessageDisplay.ShowOn(worldObject, NotificationNothingToHarvestYet);
                worldObject.ProtoWorldObject.SharedGetObjectSoundPreset()
                .PlaySound(ObjectSound.InteractFail);
            }

            throw new Exception("Cannot gather now: " + worldObject);
        }
Exemplo n.º 8
0
        public static bool SharedCheckCanInteract(
            ICharacter character,
            IWorldObject worldObject,
            bool writeToLog)
        {
            if (worldObject == null ||
                worldObject.IsDestroyed)
            {
                return(false);
            }

            // Can build/repair only if the character can contact directly
            // with the object click area (if object has the click area)
            // or with the object collider (if object don't has the click area).
            var isObjectHasClickArea =
                worldObject.PhysicsBody.Shapes.Any(s => s.CollisionGroup == CollisionGroups.ClickArea);

            var result = worldObject.ProtoWorldObject.SharedIsInsideCharacterInteractionArea(
                character,
                worldObject,
                writeToLog: false,
                requiredCollisionGroup: isObjectHasClickArea
                                            ? CollisionGroups.ClickArea
                                            : CollisionGroups
                .DefaultWithCollisionToInteractionArea);

            if (!result)
            {
                if (writeToLog)
                {
                    Logger.Warning(
                        $"Cannot build/repair - {character} cannot interact with the {worldObject} - there is no direct (physics) line of sight between them (the object click area or static/dynamic colliders must be inside the character interaction area)");

                    if (IsClient)
                    {
                        CannotInteractMessageDisplay.ShowOn(worldObject, CoreStrings.Notification_TooFar);
                        worldObject.ProtoWorldObject.SharedGetObjectSoundPreset()
                        .PlaySound(ObjectSound.InteractOutOfRange);
                    }
                }

                return(false);
            }

            if (worldObject is IStaticWorldObject staticWorldObject)
            {
                // ensure the building is not in an area under the raid
                var world = IsClient
                                ? (IWorldService)Client.World
                                : Server.World;

                var protoStaticWorldObject = staticWorldObject.ProtoStaticWorldObject;
                var validatorNoRaid        = LandClaimSystem.ValidatorNoRaid;
                foreach (var tileOffset in protoStaticWorldObject.Layout.TileOffsets)
                {
                    var occupiedTile = world.GetTile(
                        worldObject.TilePosition.X + tileOffset.X,
                        worldObject.TilePosition.Y + tileOffset.Y,
                        logOutOfBounds: false);

                    if (!occupiedTile.IsValidTile)
                    {
                        continue;
                    }

                    if (validatorNoRaid.Function(
                            new ConstructionTileRequirements.Context(
                                occupiedTile,
                                character,
                                protoStaticWorldObject,
                                tileOffset)))
                    {
                        continue;
                    }

                    // raid is under way - cannot build/repair
                    SharedShowCannotBuildNotification(
                        character,
                        validatorNoRaid.ErrorMessage,
                        protoStaticWorldObject);
                    return(false);
                }
            }

            return(true);
        }