private IItem ServerRemote_ClientUseItem(IItem item)
        {
            var character = ServerRemoteContext.Character;

            this.ServerValidateItemForRemoteCall(item, character);

            var protoDataLog = this.ServerGetDataLogProtoToSpawn();

            if (protoDataLog == null)
            {
                throw new Exception(
                          $"Prototype for data log is not returned by {nameof(this.ServerGetDataLogProtoToSpawn)}() method");
            }

            Logger.Important($"{character} has used data log {item} and received {protoDataLog}");

            var slotId    = item.ContainerSlotId;
            var container = item.Container;

            Server.Items.SetCount(item, item.Count - 1);

            CreateItemResult result;

            if (item.IsDestroyed)
            {
                // try to spawn right there
                result = Server.Items.CreateItem(protoDataLog, container, slotId: slotId);
            }
            else
            {
                // try to spawn simply in player
                var tempDropItemsList = new DropItemsList().Add(protoDataLog).AsReadOnly();
                result = ServerDroplistHelper.TryDropToCharacter(
                    tempDropItemsList,
                    character,
                    sendNoFreeSpaceNotification: true,
                    probabilityMultiplier: 1,
                    context: new DropItemContext(character, null));
            }

            if (!result.IsEverythingCreated)
            {
                // rollback, try spawn data log back
                if (item.IsDestroyed)
                {
                    // this item was destroyed - need to spawn it back
                    Server.Items.CreateItem(this, container, slotId: slotId);
                }
                else
                {
                    // this item was not destroyed - restore count
                    Server.Items.SetCount(item, item.Count + 1);
                }

                return(null);
            }

            return(result.ItemAmounts.FirstOrDefault().Key);
        }
Пример #2
0
        private void ServerCreateDroppedArrow(WeaponFinalCache weaponCache, Vector2D endPosition)
        {
            var shotSourcePosition = WeaponSystemClientDisplay.SharedCalculateWeaponShotWorldPositon(
                weaponCache.Character,
                weaponCache.ProtoWeapon,
                weaponCache.Character.ProtoCharacter,
                weaponCache.Character.Position,
                hasTrace: true);

            var timeToHit = WeaponSystemClientDisplay.SharedCalculateTimeToHit(
                weaponCache.ProtoWeapon.FireTracePreset
                ?? weaponCache.ProtoAmmo.FireTracePreset,
                shotSourcePosition,
                endPosition);

            ServerTimersSystem.AddAction(
                timeToHit,
                () =>
            {
                var droplist        = ServerGetDroplistFor(weaponCache.ProtoAmmo);
                var endTilePosition = endPosition.ToVector2Ushort();

                var result = ServerDroplistHelper.TryDropToGround(
                    droplist,
                    endTilePosition,
                    // compensate for the server rate to ensure that
                    // it doesn't affect the number of arrows spawned
                    probabilityMultiplier: 1.0 / DropItemsList.DropListItemsCountMultiplier,
                    context: new DropItemContext(weaponCache.Character),
                    out _);

                if (!result.IsEverythingCreated)
                {
                    return;
                }

                using var charactersObserving = Api.Shared.GetTempList <ICharacter>();
                Server.World.GetCharactersInRadius(endTilePosition,
                                                   charactersObserving,
                                                   radius: 15,
                                                   onlyPlayers: true);

                this.CallClient(charactersObserving.AsList(),
                                _ => _.ClientRemote_OnArrowHitGround(endTilePosition));
            });
        }