public ErrorCodes DoResearchKitMerge(PublicContainer publicContainer, Character character, int nextDefinition, int nextLevel, double fullPrice, int availableQuantity, int searchDefinition, out Dictionary <string, object> result, bool useCorporationWallet) { var ec = ErrorCodes.NoError; var foundQuantity = 0; result = new Dictionary <string, object>(); var amountToLookFor = availableQuantity * 2; foreach (var item in publicContainer.GetItems().Where(i => i.Definition == searchDefinition)) { if (item.Quantity <= amountToLookFor - foundQuantity) { foundQuantity += item.Quantity; Repository.Delete(item); } else { item.Quantity = item.Quantity - (amountToLookFor - foundQuantity); foundQuantity = amountToLookFor; break; } } if (foundQuantity != amountToLookFor) { //safe check return(ErrorCodes.ItemNotFound); } publicContainer.CreateAndAddItem(nextDefinition, true, item => { item.Owner = character.Eid; item.Quantity = availableQuantity; }); var wallet = character.GetWalletWithAccessCheck(useCorporationWallet, TransactionType.ResearchKitMerge, CorporationRole.ProductionManager); wallet.Balance -= fullPrice; var b = TransactionLogEvent.Builder() .SetTransactionType(TransactionType.ResearchKitMerge) .SetCreditBalance(wallet.Balance) .SetCreditChange(-fullPrice) .SetCharacter(character); var corpWallet = wallet as CorporationWallet; if (corpWallet != null) { b.SetCorporation(corpWallet.Corporation); corpWallet.Corporation.LogTransaction(b); } else { character.LogTransaction(b); } result = new Dictionary <string, object> { { k.container, publicContainer.ToDictionary() } }; return(ec); }
// A sell order was found so the deal is done instantly public void FulfillBuyOrderInstantly(Character buyer, bool useBuyerCorporationWallet, MarketOrder marketSellOrder, double pricePerPiece, int duration, int quantity, PublicContainer publicContainer, long?forMembersOf) { var forCorporation = forMembersOf != null; var seller = Character.GetByEid(marketSellOrder.submitterEID); Item itemOnMarket; if (!marketSellOrder.isVendorItem) { //the seller is NOT a vendor itemOnMarket = GetItemByMarketOrder(marketSellOrder); seller.ThrowIfEqual(null, ErrorCodes.CharacterNotFound); if (itemOnMarket.Quantity > quantity) { // unstack a fraction var fractionItem = itemOnMarket.Unstack(quantity); fractionItem.Owner = buyer.Eid; // save the remaining item itemOnMarket.Save(); // add to public container and change owner publicContainer.AddItem(fractionItem, true); //the remaining amount marketSellOrder.quantity = itemOnMarket.Quantity; // update remaining amount _orderRepository.UpdateQuantity(marketSellOrder); //cash in _marketHelper.CashIn(buyer, useBuyerCorporationWallet, marketSellOrder.price, marketSellOrder.itemDefinition, quantity, TransactionType.marketBuy); //pay out this.PayOutToSeller(seller, marketSellOrder.useCorporationWallet, itemOnMarket.Definition, marketSellOrder.price, quantity, TransactionType.marketSell, marketSellOrder.IsAffectsAverage(), forCorporation); } else if (itemOnMarket.Quantity == quantity) { itemOnMarket.Owner = buyer.Eid; // add to public container and change owner publicContainer.AddItem(itemOnMarket, true); //delete the sell order coz it's done _orderRepository.Delete(marketSellOrder); //cash in _marketHelper.CashIn(buyer, useBuyerCorporationWallet, marketSellOrder.price, marketSellOrder.itemDefinition, quantity, TransactionType.marketBuy); //pay out this.PayOutToSeller(seller, marketSellOrder.useCorporationWallet, itemOnMarket.Definition, marketSellOrder.price, quantity, TransactionType.marketSell, marketSellOrder.IsAffectsAverage(), forCorporation); marketSellOrder.quantity = 0; //signal the sell order delete to the client } else if (itemOnMarket.Quantity < quantity) { //a part of the buy order is fulfilled immediately itemOnMarket.Owner = buyer.Eid; // add to public container and change owner publicContainer.AddItem(itemOnMarket, true); _orderRepository.Delete(marketSellOrder); // create a buy order for the rest of the quantity var newBuyOrder = CreateBuyOrder(buyer, marketSellOrder.itemDefinition, duration, pricePerPiece, quantity - itemOnMarket.Quantity, marketSellOrder.useCorporationWallet, forMembersOf); // cash in for the actual transaction _marketHelper.CashIn(buyer, useBuyerCorporationWallet, marketSellOrder.price, marketSellOrder.itemDefinition, itemOnMarket.Quantity, TransactionType.marketBuy); // cash in for the deposit - for the rest of the quantity _marketHelper.CashIn(buyer, useBuyerCorporationWallet, pricePerPiece, marketSellOrder.itemDefinition, quantity - itemOnMarket.Quantity, TransactionType.buyOrderDeposit); AddCentralBank(TransactionType.buyOrderDeposit, pricePerPiece * (quantity - itemOnMarket.Quantity)); //pay out for the current market item this.PayOutToSeller(seller, marketSellOrder.useCorporationWallet, itemOnMarket.Definition, marketSellOrder.price, itemOnMarket.Quantity, TransactionType.marketSell, marketSellOrder.IsAffectsAverage(), forCorporation); marketSellOrder.quantity = 0; //signal to the client //the item he just bought, the sell order update //the new buy order Message.Builder.SetCommand(Commands.MarketBuyOrderCreated) .WithData(new Dictionary <string, object> { { k.buyOrder, newBuyOrder.ToDictionary() } }) .ToCharacter(buyer) .Send(); } Market.SendMarketItemBoughtMessage(buyer, itemOnMarket); Message.Builder.SetCommand(Commands.MarketSellOrderUpdate) .WithData(new Dictionary <string, object> { { k.sellOrder, marketSellOrder.ToDictionary() } }) .ToCharacters(seller, buyer) .Send(); return; } //check VENDOR sell order's quantity if (marketSellOrder.quantity > 0) { //finite order cases var boughtQuantity = quantity; if (marketSellOrder.quantity == quantity) { _orderRepository.Delete(marketSellOrder); marketSellOrder.quantity = 0; //signal client } else if (marketSellOrder.quantity > quantity) { marketSellOrder.quantity -= quantity; //signal client _orderRepository.UpdateQuantity(marketSellOrder); } else if (marketSellOrder.quantity < quantity) { _orderRepository.Delete(marketSellOrder); boughtQuantity = marketSellOrder.quantity; //create buyorder for the rest of the quantity var buyOrder = CreateBuyOrder(buyer, marketSellOrder.itemDefinition, duration, pricePerPiece, quantity - marketSellOrder.quantity, marketSellOrder.useCorporationWallet, forMembersOf); Message.Builder.SetCommand(Commands.MarketBuyOrderCreated) .WithData(new Dictionary <string, object> { { k.item, buyOrder.ToDictionary() } }) .ToCharacter(buyer) .Send(); marketSellOrder.quantity = 0; //signal client //cash in deposit _marketHelper.CashIn(buyer, useBuyerCorporationWallet, pricePerPiece, marketSellOrder.itemDefinition, quantity - boughtQuantity, TransactionType.buyOrderDeposit); AddCentralBank(TransactionType.buyOrderDeposit, pricePerPiece * (quantity - boughtQuantity)); } //take the money for the quantity bought _marketHelper.CashIn(buyer, useBuyerCorporationWallet, marketSellOrder.price, marketSellOrder.itemDefinition, boughtQuantity, TransactionType.marketBuy); Message.Builder.SetCommand(Commands.MarketSellOrderUpdate) .WithData(new Dictionary <string, object> { { k.sellOrder, marketSellOrder.ToDictionary() } }) .ToCharacter(buyer) .Send(); // vendor stuff itemOnMarket = publicContainer.CreateAndAddItem(marketSellOrder.itemDefinition, false, item => { item.Owner = buyer.Eid; item.Quantity = boughtQuantity; }); Market.SendMarketItemBoughtMessage(buyer, itemOnMarket); //average price _marketHandler.InsertAveragePrice(this, marketSellOrder.itemDefinition, boughtQuantity * marketSellOrder.price, boughtQuantity); AddCentralBank(TransactionType.marketBuy, boughtQuantity * pricePerPiece); //vendor income return; } //infinite quantity case _marketHelper.CashIn(buyer, useBuyerCorporationWallet, marketSellOrder.price, marketSellOrder.itemDefinition, quantity, TransactionType.marketBuy); itemOnMarket = publicContainer.CreateAndAddItem(marketSellOrder.itemDefinition, false, item => { item.Owner = buyer.Eid; item.Quantity = quantity; }); Market.SendMarketItemBoughtMessage(buyer, itemOnMarket); //average price _marketHandler.InsertAveragePrice(this, marketSellOrder.itemDefinition, quantity * marketSellOrder.price, quantity); AddCentralBank(TransactionType.marketBuy, quantity * pricePerPiece); //vendor income }