예제 #1
0
        public void ListOwnedMarkets()
        {
            var character = Context.Player.Character;

            if (character == null)
            {
                Context.Respond("You cannot do this while dead.");
                return;
            }

            var manager = EconomyPlugin.GetManager <MarketManager>();

            manager.GetMarkets()
            .Then(markets =>
            {
                var ownedMarkets = markets
                                   .Where(m => m.CreatorId == Context.Player.SteamUserId)
                                   .ToArray();
                var responseBuilder = new StringBuilder("Markets:");
                responseBuilder.AppendLine();

                foreach (var ownedMarket in ownedMarkets)
                {
                    responseBuilder.AppendLine($"+ Mrkt#{ownedMarket.Id} ({ownedMarket.Name})");
                    responseBuilder.AppendLine($"+-- Account#{ownedMarket.AccountId}, Range: {ownedMarket.Range}m");
                }

                responseBuilder.AppendLine($"Total Markets: {ownedMarkets.Length}");

                SendMessage(Context.Player.SteamUserId, responseBuilder.ToString());
            })
            .Catch(error => Log.Error(error));;
        }
예제 #2
0
        public void CloseMarket(string marketNameOrId)
        {
            var character = Context.Player.Character;

            if (character == null)
            {
                Context.Respond("You cannot do this while dead.");
                return;
            }

            var manager = EconomyPlugin.GetManager <MarketManager>();

            manager.GetMarketByNameOrId(marketNameOrId, Context.Player.SteamUserId)
            .Then(market =>
            {
                if (!market.IsOpen)
                {
                    Context.Respond("Market is already closed!");
                    return;
                }

                manager.SetMarketOpenStatus(market.Id, false)
                .Then(() => Context.Respond($"Mrkt#{market.Id} ({market.Name}) has been closed."))
                .Catch(HandleError);
            })
            .Catch(HandleError);
        }
예제 #3
0
        public void SetMarketAccount(string marketNameOrId, string accountNameOrId)
        {
            var character = Context.Player.Character;

            if (character == null)
            {
                Context.Respond("You cannot do this while dead.");
                return;
            }

            var manager        = EconomyPlugin.GetManager <MarketManager>();
            var accountManager = EconomyPlugin.GetManager <AccountsManager>();

            manager.GetMarketByNameOrId(marketNameOrId, Context.Player.SteamUserId)
            .Then(market =>
            {
                accountManager.GetAccount(Context.Player.SteamUserId, accountNameOrId)
                .Then(account =>
                {
                    manager.SetMarketAccount(market.Id, account.Id)
                    .Then(() =>
                          Context.Respond(
                              $"Mrkt#{market.Id} ({market.Name}) has been successfully set to use Acct#{account.Id} ({account.Nickname}) as its coffer."))
                    .Catch(HandleError);
                })
                .Catch(HandleError);
            })
            .Catch(HandleError);
        }
예제 #4
0
        public void DeleteMarket(string marketNameOrId)
        {
            var manager = EconomyPlugin.GetManager <MarketManager>();

            manager.GetMarkets()
            .Then(markets =>
            {
                MarketDataObject market = null;
                if (long.TryParse(marketNameOrId, out var marketId))
                {
                    market = markets.FirstOrDefault(m => m.Id == marketId);
                }
                else
                {
                    market = markets.FirstOrDefault(m =>
                                                    m.Name.Equals(marketNameOrId, StringComparison.InvariantCultureIgnoreCase));
                }

                if (market == null)
                {
                    Context.Respond($"Unable to find market by name or id of '{marketNameOrId}'.");
                    return;
                }

                manager.DeleteMarket(market.Id)
                .Then(() => { Context.Respond($"Successfully deleted Mrkt#{market.Id}."); });
            }).Catch(HandleError);
        }
예제 #5
0
        private void UpdateOrderPrice(BuyOrderType orderType, string marketNameOrId, string itemName, decimal newPrice)
        {
            var character = Context.Player.Character;

            if (character == null)
            {
                Context.Respond("You cannot do this while dead.");
                return;
            }

            if (!DefinitionResolver.TryGetDefinitionByName(itemName, out var itemDefinition))
            {
                Context.Respond($"Unable to find an item by the name of {itemName}");
                return;
            }

            if (newPrice < new decimal(0.01))
            {
                Context.Respond($"{newPrice} is too small. Please use a higher value.");
                return;
            }

            var manager      = EconomyPlugin.GetManager <MarketManager>();
            var orderManager = EconomyPlugin.GetManager <MarketOrderManager>();

            manager.GetMarkets()
            .Then(markets =>
            {
                MarketDataObject market = null;
                if (long.TryParse(marketNameOrId, out var marketId))
                {
                    market = markets.FirstOrDefault(m => m.Id == marketId);
                }
                else
                {
                    market = markets.FirstOrDefault(m =>
                                                    m.Name.Equals(marketNameOrId, StringComparison.InvariantCultureIgnoreCase));
                }

                if (market == null)
                {
                    Context.Respond($"Unable to find market by name or id of '{marketNameOrId}'.");
                    return;
                }

                orderManager.GetMarketOrder(orderType, market.Id, itemDefinition.Id)
                .Then(order =>
                {
                    orderManager.UpdateOrderPrice(order.Id, newPrice)
                    .Then(() => Context.Respond(
                              $"Successfully updated Order#{order.Id}'s price to {Utilities.FriendlyFormatCurrency(newPrice)}."))
                    .Catch(HandleError);
                })
                .Catch(HandleError);
            })
            .Catch(HandleError);
        }
예제 #6
0
        public override void Start()
        {
            base.Start();

            _multiplayerManager.PlayerJoined += PlayerJoined;

            _messageRouter = EconomyPlugin.GetManager <MessageRouterManager>();

            _messageRouter.Subscribe <AdjustBalanceMessage>(OnAdjustBalance);
            _messageRouter.Subscribe <CreateAccountMessage>(OnCreateAccount);
            _messageRouter.Subscribe <GetAccountsMessage>(OnGetAccounts);
        }
예제 #7
0
        public void CreateMarket(string stationGridName, string marketName)
        {
            var character = Context.Player.Character;

            if (character == null)
            {
                Context.Respond("You cannot do this while dead.");
                return;
            }

            MyCubeGrid stationEntity = null;

            if (!Utilities.TryGetEntityByNameOrId(stationGridName, out IMyEntity entity))
            {
                Context.Respond($"Unable to find a station by the name of '{stationGridName}'.");
                return;
            }

            stationEntity = entity as MyCubeGrid;
            if (stationEntity == null ||
                !stationEntity.IsStatic)
            {
                Context.Respond($"Unable to find a station by the name of '{stationGridName}'.");
                return;
            }

            var manager = EconomyPlugin.GetManager <MarketManager>();

            // Check we have grid ownership.
            if (!stationEntity.BigOwners.Contains(Context.Player.IdentityId))
            {
                Context.Respond("You must own a majority of the grid to be able authorize a station as a market.");
                return;
            }

            // Market checks to see if the station is already registered.
            manager.GetMarkets()
            .Then(markets =>
            {
                Log.Info("Received markets");
                if (markets.Any(m => m.ParentGridId == entity.EntityId))
                {
                    Context.Respond("This station is already marked as a market.");
                    return;
                }

                manager.CreateMarket(entity.EntityId, Context.Player.SteamUserId, marketName,
                                     EconomyMarketsPlugin.Instance.Config.DefaultMarketRange)
                .Then(newMarket => { Context.Respond($"{marketName} has been successfully established."); })
                .Catch(error => { Context.Respond($"[ERROR] Unable to create market: {error.Message}"); });
            }).Catch(error => Log.Error(error));
        }
예제 #8
0
        private void CreateOrder(BuyOrderType orderType, string marketNameOrId, string itemName, decimal pricePerOne,
                                 decimal quantity)
        {
            var character = Context.Player.Character;

            if (character == null)
            {
                Context.Respond("You cannot do this while dead.");
                return;
            }

            if (quantity < new decimal(0.01))
            {
                Context.Respond($"{quantity} is too low. Please use a higher value.");
                return;
            }

            if (pricePerOne < new decimal(0.01))
            {
                Context.Respond($"{pricePerOne} is too low. Please use a higher value.");
                return;
            }

            if (!DefinitionResolver.TryGetDefinitionByName(itemName, out var itemDefinition))
            {
                Context.Respond($"Unable to find an item by the name of {itemName}");
                return;
            }

            var manager      = EconomyPlugin.GetManager <MarketManager>();
            var orderManager = EconomyPlugin.GetManager <MarketOrderManager>();

            manager.GetMarketByNameOrId(marketNameOrId, Context.Player.SteamUserId)
            .Then(market =>
            {
                if (market == null)
                {
                    Context.Respond($"Unable to find a market by the name or id of {marketNameOrId}.");
                    return;
                }

                orderManager.UpdateOrAddMarketOrder(orderType, market.Id,
                                                    itemDefinition.Id, pricePerOne, quantity)
                .Then(order =>
                {
                    Context.Respond(
                        $"Successfully created Order#{order.Id} for {quantity}x {itemDefinition.DisplayNameText} @ {Utilities.FriendlyFormatCurrency(pricePerOne)} per 1.");
                })
                .Catch(HandleError);
            })
            .Catch(HandleError);
        }
예제 #9
0
        public void OpenMarket(string marketNameOrId)
        {
            var character = Context.Player.Character;

            if (character == null)
            {
                Context.Respond("You cannot do this while dead.");
                return;
            }

            if (!EconomyMarketsPlugin.Instance.Config.PlayerOwnedMarkets)
            {
                Context.Respond("The server has disabled players from creating new markets.");
                return;
            }

            var manager        = EconomyPlugin.GetManager <MarketManager>();
            var accountManager = EconomyPlugin.GetManager <AccountsManager>();

            manager.GetMarketByNameOrId(marketNameOrId, Context.Player.SteamUserId)
            .Then(market =>
            {
                if (market.IsOpen)
                {
                    Context.Respond("Market is already open!");
                    return;
                }

                accountManager.GetPrimaryAccount(Context.Player.SteamUserId)
                .Then(account =>
                {
                    var createMarketCost = EconomyMarketsPlugin.Instance.Config.CreateMarketCost;
                    if (account.Balance < createMarketCost)
                    {
                        Context.Respond(
                            $"Insufficient funds to create market. Requires {Utilities.FriendlyFormatCurrency(createMarketCost)}.");
                        return;
                    }

                    accountManager.AdjustAccountBalance(account.Id, createMarketCost * -1, null,
                                                        "Opening new market.");
                    manager.SetMarketOpenStatus(market.Id, true)
                    .Then(() => Context.Respond($"Mrkt#{market.Id} ({market.Name}) has been opened for business."))
                    .Catch(HandleError);
                });
            })
            .Catch(HandleError);
        }
예제 #10
0
        private void UpdateOrderQuantity(BuyOrderType orderType, string marketNameOrId, string itemName, decimal newQuantity)
        {
            var character = Context.Player.Character;

            if (character == null)
            {
                Context.Respond("You cannot do this while dead.");
                return;
            }

            if (!DefinitionResolver.TryGetDefinitionByName(itemName, out var itemDefinition))
            {
                Context.Respond($"Unable to find an item by the name of {itemName}");
                return;
            }

            if (newQuantity < new decimal(0.01))
            {
                Context.Respond($"{newQuantity} is too small. Please use a higher value.");
                return;
            }

            var manager      = EconomyPlugin.GetManager <MarketManager>();
            var orderManager = EconomyPlugin.GetManager <MarketOrderManager>();

            manager.GetMarketByNameOrId(marketNameOrId, Context.Player.SteamUserId)
            .Then(market =>
            {
                if (market == null)
                {
                    Context.Respond($"Unable to find market by name or id of '{marketNameOrId}'.");
                    return;
                }

                orderManager.GetMarketOrder(orderType, market.Id, itemDefinition.Id)
                .Then(order =>
                {
                    orderManager.UpdateOrderQuantity(order.Id, newQuantity)
                    .Then(() => Context.Respond(
                              $"Successfully updated Order#{order.Id}'s quantity to {newQuantity}."))
                    .Catch(HandleError);
                })
                .Catch(HandleError);
            })
            .Catch(HandleError);
        }
예제 #11
0
        private void RemoveOrder(BuyOrderType orderType, string marketNameOrId, string itemName)
        {
            var character = Context.Player.Character;

            if (character == null)
            {
                Context.Respond("You cannot do this while dead.");
                return;
            }

            if (!DefinitionResolver.TryGetDefinitionByName(itemName, out var itemDefinition))
            {
                Context.Respond($"Unable to find an item by the name of {itemName}");
                return;
            }

            var manager      = EconomyPlugin.GetManager <MarketManager>();
            var orderManager = EconomyPlugin.GetManager <MarketOrderManager>();

            manager.GetMarketByNameOrId(marketNameOrId, Context.Player.SteamUserId)
            .Then(market =>
            {
                if (market == null)
                {
                    Context.Respond($"Unable to find market by name or id of '{marketNameOrId}'.");
                    return;
                }

                orderManager.GetMarketOrder(orderType, market.Id, itemDefinition.Id)
                .Then(order =>
                {
                    orderManager.DeleteOrder(order.Id)
                    .Then(() => Context.Respond(
                              $"Successfully removed Order#{order.Id}."))
                    .Catch(HandleError);
                })
                .Catch(HandleError);
            })
            .Catch(HandleError);
        }
        public override void Start()
        {
            base.Start();

            using (var connection = ConnectionFactory.Open())
            {
                var npcMarkets = connection.Query <MarketDataObject>(SQL.SELECT_MARKETS)
                                 .Where(m => m.IsNPC)
                                 .ToArray();
                var orderManager = EconomyPlugin.GetManager <MarketOrderManager>();
                var npcManager   = EconomyPlugin.GetManager <NPCManager>();

                foreach (var npcMarket in npcMarkets)
                {
                    orderManager.DeleteMarketOrders(npcMarket.Id)
                    .Then(() =>
                    {
                        npcManager.GetNPC((long)npcMarket.CreatorId)
                        .Then(npc => { GenerateNPCOrders(npc, npcMarket); });
                    });
                }
            }
        }
예제 #13
0
        public void List()
        {
            var marketManager      = EconomyPlugin.GetManager <MarketManager>();
            var marketOrderManager = EconomyPlugin.GetManager <MarketOrderManager>();
            var marketSimManager   = EconomyPlugin.GetManager <MarketSimulationManager>();

            var character = Context.Player.Character;

            if (character == null)
            {
                Context.Respond("You cannot do that while dead.");
                return;
            }

            var controllingCube = Context.Player.Controller.ControlledEntity as IMyCubeBlock;

            if (controllingCube == null)
            {
                Context.Respond("Trading by hand is not supported.");
                return;
            }

            marketManager.GetConnectedMarket(controllingCube.CubeGrid)
            .Then(market =>
            {
                if (market == null)
                {
                    Context.Respond("Unable to find any connected markets. Have you docked to a market?");
                    return;
                }

                marketOrderManager
                .GetMarketOrders(market.Id)
                .Then(orders =>
                {
                    var dataProvider    = GetDataProvider <MarketSimulationProvider>();
                    var responseBuilder = new StringBuilder();
                    responseBuilder.AppendLine();

                    var maxNameLength = 30;

                    responseBuilder.AppendLine("+-- Buy Orders:");
                    var buyOrders = orders.Where(o => o.OrderType == BuyOrderType.Buy).ToArray();
                    if (buyOrders.Length == 0)
                    {
                        responseBuilder.AppendLine("None");
                    }
                    else
                    {
                        foreach (var order in buyOrders)
                        {
                            responseBuilder.AppendLine(
                                $"+ {order.ToString(dataProvider, maxNameLength)}");
                        }
                    }

                    responseBuilder.AppendLine("+-- Sell Orders:");
                    var sellOrders = orders.Where(o => o.OrderType == BuyOrderType.Sell).ToArray();
                    if (sellOrders.Length == 0)
                    {
                        responseBuilder.AppendLine("None");
                    }
                    else
                    {
                        foreach (var order in sellOrders)
                        {
                            responseBuilder.AppendLine(
                                $"+ {order.ToString(dataProvider, maxNameLength)}");
                        }
                    }

                    responseBuilder.AppendLine($"Total Orders: {orders.Length}");
                    ModCommunication.SendMessageTo(
                        new DialogMessage($"Mrkt#{market.Id} ({market.Name}) Inventory:", null, null,
                                          responseBuilder.ToString()), Context.Player.SteamUserId);
                })
                .Catch(HandleError);
            })
            .Catch(HandleError);
        }
        public Promise GenerateNPCOrders(NPCDataObject npc, MarketDataObject market)
        {
            return(new Promise((resolve, reject) =>
            {
                decimal marginFlux = 0;
                var items = _simulationProvider.GetUniversalItems(npc.IndustryType);

                switch (npc.IndustryType)
                {
                case IndustryTypeEnum.Industrial:
                    // Industrial buys industrial trade goods at a high price.
                    // Industrial buys ore at a moderate price.
                    // Industrial sells ingots at a low price.
                    marginFlux = new decimal(0.04);
                    break;

                case IndustryTypeEnum.Consumer:
                    // Consumer buys ingots at a high price.
                    // Consumer sells components at a low price.
                    marginFlux = new decimal(0.08);
                    break;

                case IndustryTypeEnum.Research:
                    // Research buys components at a high price.
                    // Research sells research trade goods at a low price.
                    marginFlux = new decimal(0.12);
                    break;

                case IndustryTypeEnum.Military:
                    // Military buys research trade goods at a high price.
                    // Military sells industrial trade goods & ammo at a low price.
                    marginFlux = new decimal(0.16);
                    break;
                }

                var orderManager = EconomyPlugin.GetManager <MarketOrderManager>();
                var npcOrders = new List <NPCMarketOrder>();
                var random = new Random();
                foreach (var item in items)
                {
                    if (MarketConfig.Blacklist.Any(b => b.Value == item.Definition.Id.ToString()))
                    {
                        continue; // This entry is blacklisted.
                    }
                    var affinity = item.IndustryAffinities[npc.IndustryType];
                    var minMarginFlux = (double)((marginFlux / 2m) * -1m);
                    var maxMarginFlux = (double)marginFlux;
                    var orderMarginFlux = random.NextRange(minMarginFlux, maxMarginFlux);

                    var order = new NPCMarketOrder
                    {
                        DesiredStock = 10000,
                        Definition = item.Definition,
                        MarketId = market.Id,
                        MarginFlux = new decimal(orderMarginFlux),
                        DemandMultiplier = 1
                    };

                    var orderType = affinity == MarketAffinity.AmbivalentBuy ||
                                    affinity == MarketAffinity.ExtremeBuy ||
                                    affinity == MarketAffinity.Buy
                        ? BuyOrderType.Buy
                        : BuyOrderType.Sell;

                    var basePrice = _simulationProvider.GetUniversalItemValue(item.Definition.Id);
                    var price = basePrice;
                    if (orderType == BuyOrderType.Buy)
                    {
                        price = price * (1m + order.MarginFlux);
                    }
                    else
                    {
                        price = price * (1m - order.MarginFlux);
                    }

                    orderManager.UpdateOrAddMarketOrder(orderType, market.Id, item.Definition.Id,
                                                        price, -1)
                    .Then(newOrder => { order.OrderId = newOrder.Id; });
                    npcOrders.Add(order);
                }

                _npcMarketOrders[market.Id] = npcOrders;
                resolve();
            }));
        }
예제 #15
0
        public void CreateNPCMarket(string stationGridName, string industryName)
        {
            MyCubeGrid stationEntity = null;

            if (!Utilities.TryGetEntityByNameOrId(stationGridName, out IMyEntity entity))
            {
                Context.Respond($"Unable to find a station by the name of '{stationGridName}'.");
                return;
            }

            stationEntity = entity as MyCubeGrid;
            if (stationEntity == null ||
                !stationEntity.IsStatic)
            {
                Context.Respond($"Unable to find a station by the name of '{stationGridName}'.");
                return;
            }

            if (!Enum.TryParse(industryName, out IndustryTypeEnum industryType))
            {
                var types = string.Join(", ", Enum.GetNames(typeof(IndustryTypeEnum)));
                Context.Respond($"Unable to find industry type '{industryName}'. Valid industry types are: {types}.");
                return;
            }

            var marketManager = GetManager <MarketManager>();

            // Market checks to see if the station is already registered.
            marketManager.GetMarkets()
            .Then(markets =>
            {
                Log.Info("Received markets");
                if (markets.Any(m => m.ParentGridId == entity.EntityId))
                {
                    Context.Respond("This station is already marked as a market.");
                    return;
                }

                var npcManager = EconomyPlugin.GetManager <NPCManager>();
                var npcName    = NameGeneratorHelper.GetName();
                npcManager.CreateNPC(npcName, industryType)
                .Then(npc =>
                {
                    // NPC is now created.. Need to make them a bank account.
                    var accountsManager = GetManager <AccountsManager>();

                    accountsManager.CreateAccount((ulong)npc.Id, 0, "default", true)
                    .Then(npcAccount =>
                    {
                        // Now they have a bank account.. Time to make a station market.
                        var marketName = NameGeneratorHelper.GetIndustryName(industryType);

                        marketManager.CreateMarket(stationEntity.EntityId, (ulong)npc.Id, marketName,
                                                   3000, npcAccount.Id, true, true)
                        .Then(market =>
                        {
                            // Market is created.. Now to create buy orders.
                            var simManager = GetManager <MarketSimulationManager>();
                            simManager.GenerateNPCOrders(npc, market)
                            .Then(() =>
                            {
                                stationEntity.DisplayName = market.Name;
                                Context.Respond($"{npc.Name} has founded {market.Name}, specializing in {industryType} trade.");
                            })
                            .Catch(HandleError);
                        })
                        .Catch(HandleError);
                    })
                    .Catch(HandleError);
                })
                .Catch(HandleError);
            })
            .Catch(HandleError);
        }