public static bool ClientTryStartDrone(
            IItem itemDrone,
            Vector2Ushort worldPosition,
            bool showErrorNotification)
        {
            var character = ClientCurrentCharacterHelper.Character;

            if (SharedIsMaxDronesToControlNumberExceeded(character,
                                                         showErrorNotification) ||
                SharedIsTargetAlreadyScheduledForAnyActiveDrone(character,
                                                                worldPosition,
                                                                showErrorNotification))
            {
                return(false);
            }

            var targetObject = SharedGetCompatibleTarget(character,
                                                         worldPosition,
                                                         out var hasIncompatibleTarget,
                                                         out var isPveActionForbidden);

            if (targetObject is null)
            {
                // nothing to mine there
                if (showErrorNotification)
                {
                    if (isPveActionForbidden)
                    {
                        PveSystem.ClientShowNotificationActionForbidden();
                    }

                    CannotInteractMessageDisplay.ClientOnCannotInteract(
                        character,
                        hasIncompatibleTarget
                            ? Notification_CannotMineThat
                            : Notification_NothingToMineThere,
                        isOutOfRange: false);
                }

                return(false);
            }

            if (!SharedIsValidStartLocation(character, worldPosition, out var hasObstacles))
            {
                if (showErrorNotification)
                {
                    CannotInteractMessageDisplay.ClientOnCannotInteract(
                        character,
                        hasObstacles
                            ? CoreStrings.Notification_ObstaclesOnTheWay
                            : CoreStrings.Notification_TooFar,
                        isOutOfRange: true);
                }

                return(false);
            }

            ClientDroneStartQueue.Add(itemDrone, worldPosition);
            return(true);
        }
Пример #2
0
        public override bool SharedCanInteract(ICharacter character, IStaticWorldObject worldObject, bool writeToLog)
        {
            if (!base.SharedCanInteract(character, worldObject, writeToLog))
            {
                return(false);
            }

            var ownerName = GetPublicState(worldObject).OwnerName;

            if (ownerName == character.Name)
            {
                return(true);
            }

            if (PveSystem.SharedIsPve(false))
            {
                if (IsClient && PartySystem.ClientIsPartyMember(ownerName) ||
                    (IsServer &&
                     PartySystem.ServerIsSameParty(Server.Characters.GetPlayerCharacter(ownerName),
                                                   character)))
                {
                    // in PvE party members can pickup items of their party members
                }
                else
                {
                    // other players in PvE cannot pickup player's loot
                    if (writeToLog && IsClient)
                    {
                        PveSystem.ClientShowNotificationActionForbidden();
                    }

                    return(false);
                }
            }

            if (NewbieProtectionSystem.SharedIsNewbie(character))
            {
                // newbie cannot pickup other players' loot
                if (writeToLog)
                {
                    NewbieProtectionSystem.SharedShowNewbieCannotDamageOtherPlayersOrLootBags(character,
                                                                                              isLootBag: true);
                }

                return(false);
            }

            // non-newbie character can pickup players' loot
            // please note this validation has an override for derived ObjectPlayerLootContainerProtected
            return(true);
        }
        protected override bool ClientItemUseFinish(ClientItemData data)
        {
            var character             = ClientCurrentCharacterHelper.Character;
            var characterTilePosition = character.TilePosition;
            var mouseTilePosition     = Client.Input.MousePointedTilePosition;
            var dronesNumberToLaunch  = Api.Client.Input.IsKeyHeld(InputKey.Shift, evenIfHandled: true)
                                           ? this.MaxDronesToControl
                                           : 1;

            using var tempExceptDrones  = Api.Shared.GetTempList <IItem>();
            using var tempExceptTargets = Api.Shared.GetTempList <Vector2Ushort>();

            for (var index = 0; index < dronesNumberToLaunch; index++)
            {
                var showErrorNotification = index == 0;
                var itemDrone             = CharacterDroneControlSystem.ClientSelectNextDrone(tempExceptDrones.AsList());
                if (itemDrone is null)
                {
                    if (CharacterDroneControlSystem.SharedIsMaxDronesToControlNumberExceeded(
                            character,
                            clientShowErrorNotification: showErrorNotification))
                    {
                        break;
                    }

                    if (showErrorNotification)
                    {
                        CannotInteractMessageDisplay.ClientOnCannotInteract(
                            character,
                            CharacterDroneControlSystem.Notification_ErrorNoDrones_Title,
                            isOutOfRange: false);
                    }

                    break;
                }

                tempExceptDrones.Add(itemDrone);
                Vector2Ushort targetPosition;

                if (index == 0)
                {
                    targetPosition = mouseTilePosition;
                    var targetObject = CharacterDroneControlSystem
                                       .SharedGetCompatibleTarget(character,
                                                                  mouseTilePosition,
                                                                  out var hasIncompatibleTarget,
                                                                  out var isPveActionForbidden);
                    if (targetObject is null)
                    {
                        if (showErrorNotification)
                        {
                            if (isPveActionForbidden)
                            {
                                PveSystem.ClientShowNotificationActionForbidden();
                            }

                            CannotInteractMessageDisplay.ClientOnCannotInteract(
                                character,
                                hasIncompatibleTarget
                                    ? CharacterDroneControlSystem.Notification_CannotMineThat
                                    : CharacterDroneControlSystem.Notification_NothingToMineThere,
                                isOutOfRange: false);
                        }

                        return(false);
                    }

                    if (!WorldObjectClaimSystem.SharedIsAllowInteraction(character,
                                                                         targetObject,
                                                                         showClientNotification: showErrorNotification))
                    {
                        return(false);
                    }

                    if (CharacterDroneControlSystem.SharedIsTargetAlreadyScheduledForAnyActiveDrone(
                            character,
                            mouseTilePosition,
                            logError: false))
                    {
                        // already scheduled a drone mining there...try find another target of the same type
                        targetPosition = TryGetNextTargetPosition();
                        if (targetPosition == default)
                        {
                            // no further targets
                            CannotInteractMessageDisplay.ClientOnCannotInteract(
                                character,
                                CharacterDroneControlSystem.Notification_DroneAlreadySent,
                                isOutOfRange: false);
                            return(false);
                        }
                    }
                }
                else
                {
                    targetPosition = TryGetNextTargetPosition();
                    if (targetPosition == default)
                    {
                        // no further targets
                        break;
                    }
                }

                if (!CharacterDroneControlSystem.ClientTryStartDrone(itemDrone,
                                                                     targetPosition,
                                                                     showErrorNotification: showErrorNotification))
                {
                    break;
                }

                tempExceptTargets.Add(targetPosition);
            }

            // always return false as we don't want to play any device sounds
            return(false);

            Vector2Ushort TryGetNextTargetPosition()
            {
                var targetObjectProto = CharacterDroneControlSystem
                                        .SharedGetCompatibleTarget(character,
                                                                   mouseTilePosition,
                                                                   out _,
                                                                   out _)?
                                        .ProtoWorldObject;

                if (targetObjectProto is null)
                {
                    return(default);