public static void ServerInitialize(IStaticWorldObject tradingStation) { if (!(tradingStation.ProtoStaticWorldObject is IProtoObjectTradingStation protoTradingStation)) { throw new Exception($"Not an {typeof(IProtoObjectTradingStation).FullName}: {tradingStation}"); } TradingStationsMapMarksSystem.ServerTryAddMark(tradingStation); var privateState = GetPrivateState(tradingStation); var publicState = GetPublicState(tradingStation); if (privateState.StockItemsContainer == null) { privateState.StockItemsContainer = ServerItems.CreateContainer(tradingStation, protoTradingStation .StockItemsContainerSlotsCount); } else { ServerItems.SetSlotsCount(privateState.StockItemsContainer, protoTradingStation.StockItemsContainerSlotsCount); } var lots = publicState.Lots; if (lots == null) { publicState.Lots = lots = new NetworkSyncList <TradingStationLot>(capacity: protoTradingStation.LotsCount); } // ensure that the lots count is not exceeded while (lots.Count > protoTradingStation.LotsCount) { lots.RemoveAt(protoTradingStation.LotsCount - 1); } for (var i = 0; i < protoTradingStation.LotsCount; i++) { if (lots.Count <= i) { lots.Add(new TradingStationLot()); } else if (lots[i] == null) { lots[i] = new TradingStationLot(); } } ServerRefreshTradingStationLots(tradingStation, privateState, publicState); }
public static void ServerOnDestroy(IStaticWorldObject tradingStation) { TradingStationsMapMarksSystem.ServerTryRemoveMark(tradingStation); var itemsContainer = GetPrivateState(tradingStation).StockItemsContainer; ObjectGroundItemsContainer.ServerTryDropOnGroundContainerContent( tradingStation.OccupiedTile, itemsContainer, DestroyedTradingStationDroppedItemsDestructionTimeout.TotalSeconds); }
public static void ServerOnDestroy(IStaticWorldObject tradingStation) { TradingStationsMapMarksSystem.ServerTryRemoveMark(tradingStation); var itemsContainer = GetPrivateState(tradingStation).StockItemsContainer; if (itemsContainer.OccupiedSlotsCount == 0) { return; } var groundContainer = ObjectGroundItemsContainer.ServerTryDropOnGroundContainerContent( tradingStation.OccupiedTile, itemsContainer); if (groundContainer != null) { // set custom timeout for the dropped ground items container ObjectGroundItemsContainer.ServerSetDestructionTimeout( (IStaticWorldObject)groundContainer.Owner, DestroyedTradingStationDroppedItemsDestructionTimeout.TotalSeconds); } }
public static void ServerOnDestroy(IStaticWorldObject tradingStation) { TradingStationsMapMarksSystem.ServerRemoveMark(tradingStation); }
private static void ServerRefreshTradingStationLots( IStaticWorldObject tradingStation, ObjectTradingStationPrivateState privateState, ObjectTradingStationPublicState publicState) { var stockContainer = privateState.StockItemsContainer; privateState.LastStockItemsContainerHash = stockContainer.StateHash; int availableCoinPenny = stockContainer.CountItemsOfType(ProtoItemCoinPenny.Value), availableCoinShiny = stockContainer.CountItemsOfType(ProtoItemCoinShiny.Value); var isStationSelling = publicState.Mode == TradingStationMode.StationSelling; foreach (var lot in publicState.Lots) { if (lot.State == TradingStationLotState.Disabled) { lot.CountAvailable = 0; lot.ItemOnSale = null; continue; } if (lot.ProtoItem == null || !(lot.PriceCoinPenny > 0 || lot.PriceCoinShiny > 0) || lot.LotQuantity < 1 || lot.LotQuantity > TradingStationLot.MaxLotQuantity) { lot.CountAvailable = 0; lot.ItemOnSale = null; lot.State = TradingStationLotState.Disabled; continue; } uint countAvailable; if (isStationSelling) { // calculate how much items the station can sell countAvailable = (uint)stockContainer.CountItemsOfType(lot.ProtoItem); if (countAvailable > 0) { lot.ItemOnSale = stockContainer.Items.FirstOrDefault(i => i.ProtoItem == lot.ProtoItem); // it can accomodate at least one item // check that there is enough space to accomodate money if (lot.PriceCoinPenny > 0 && !ServerItems.CanCreateItem(stockContainer, ProtoItemCoinPenny.Value, count: lot.PriceCoinPenny) || lot.PriceCoinShiny > 0 && !ServerItems.CanCreateItem(stockContainer, ProtoItemCoinShiny.Value, count: lot.PriceCoinShiny)) { lot.CountAvailable = 0; lot.State = TradingStationLotState.NoSpace; continue; } } else { lot.ItemOnSale = null; } } else // if station is buying { lot.ItemOnSale = null; // calculate how much station can buy considering the available amount of coins and the price of the lot var canAffordWithPenny = lot.PriceCoinPenny > 0 ? availableCoinPenny / lot.PriceCoinPenny : int.MaxValue; var canAffordWithShiny = lot.PriceCoinShiny > 0 ? availableCoinShiny / lot.PriceCoinShiny : int.MaxValue; countAvailable = (uint)(Math.Min(canAffordWithPenny, canAffordWithShiny) * lot.LotQuantity); if (countAvailable > 0) { // it can afford at least one item // check that there is enough space to accomodate item if (!ServerItems.CanCreateItem(stockContainer, lot.ProtoItem, count: lot.LotQuantity)) { lot.CountAvailable = 0; lot.State = TradingStationLotState.NoSpace; continue; } } } if (PveSystem.ServerIsPvE) { lot.CountAvailable = countAvailable; } else { // It's important to not disclose this info on PvP servers. lot.CountAvailable = countAvailable >= lot.LotQuantity ? 1u : 0u; } lot.State = countAvailable >= lot.LotQuantity ? TradingStationLotState.Available : isStationSelling ? TradingStationLotState.OutOfStock : TradingStationLotState.NoMoney; } TradingStationsMapMarksSystem.ServerRefreshMark(tradingStation); }