Beispiel #1
0
        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);
        }
Beispiel #2
0
        public static void ServerOnDestroy(IStaticWorldObject tradingStation)
        {
            TradingStationsMapMarksSystem.ServerTryRemoveMark(tradingStation);

            var itemsContainer = GetPrivateState(tradingStation).StockItemsContainer;

            ObjectGroundItemsContainer.ServerTryDropOnGroundContainerContent(
                tradingStation.OccupiedTile,
                itemsContainer,
                DestroyedTradingStationDroppedItemsDestructionTimeout.TotalSeconds);
        }
Beispiel #3
0
        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);
 }
Beispiel #5
0
        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);
        }