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); }
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)); }); }