Exemple #1
0
        public async Task <bool> CreateRandomEvent(User recipient, User activeDev)
        {
            RandomEventNotification notify = new RandomEventNotification();

            var eventDefs = await RandomEvents.GetEventDefinitions();

            if (eventDefs.Count() == 0)
            {
                return(false);
            }

            var definition = eventDefs.SelectRandom();

            using (var trans = TransactionScopeFactory.Create())
            {
                //generate or take items
                if (definition.ItemTransferMaxQuantity.HasValue && definition.ItemTransferMinQuantity.HasValue)
                {
                    if (definition.GiveItemEvent && definition.SpecificItemTypes?.Count > 0)
                    {
                        int qtyMoved = 0;
                        foreach (var item in definition.SpecificItemTypes)
                        {
                            if (qtyMoved >= definition.ItemTransferMaxQuantity)
                            {
                                break;
                            }

                            int itemQty = Utilities.Extensions.Random.Next(definition.ItemTransferMinQuantity.Value, definition.ItemTransferMaxQuantity.Value - qtyMoved);
                            qtyMoved += itemQty;
                            var newItems = (await InventoryDomain.GenerateItems(item.Id, recipient.Id, itemQty)).ToList();
                            newItems.AddRange(notify.AddedItems);
                            notify.AddedItems = newItems;
                        }
                    }
                    else if (definition.SpecificItemTypes?.Count > 0) //take stuff away!
                    {
                        var currentItems = await InventoryDomain.GetInventory(recipient);

                        int qtyMoved = 0;
                        foreach (var item in definition.SpecificItemTypes)
                        {
                            if (qtyMoved >= definition.ItemTransferMaxQuantity)
                            {
                                break;
                            }

                            var foundItems = currentItems.Where(i => i.ItemTypeId == item.Id);
                            if (foundItems.Count() != 0)
                            {
                                int itemQty = Utilities.Extensions.Random.Next(definition.ItemTransferMinQuantity.Value, Math.Min(foundItems.Count(), definition.ItemTransferMaxQuantity.Value - qtyMoved));
                                qtyMoved += itemQty;
                                var selectedItems = foundItems.Take(itemQty).ToList();
                                await Task.WhenAll(selectedItems.Select(i => InventoryDomain.DiscardItem(i.Id, recipient)));

                                var lostItems = await InventoryDomain.GetItemDetails(selectedItems.Select(i => i.Id).ToArray());

                                lostItems.AddRange(notify.RemovedItems);
                                notify.RemovedItems = lostItems;
                            }
                        }
                    }
                }

                if (definition.CashDeltaMax.HasValue && definition.CashDeltaMin.HasValue)
                {
                    int changeMin = definition.CashDeltaMin.Value;
                    int changeMax = definition.CashDeltaMax.Value;
                    if (changeMin < 0)                                        //stealing event, try not to steal too much from them
                    {
                        changeMin = Math.Max(recipient.Cash / -2, changeMin); //max because they're negatives
                        if (changeMax < changeMin)
                        {
                            changeMax = changeMin;
                        }
                    }
                    int cashDelta = Utilities.Extensions.Random.Next(changeMin, changeMax);
                    await UserDomain.ChangeUserCash(cashDelta, recipient);

                    notify.CashChangedAmount = cashDelta;
                }
                notify.ImagePath = definition.ImagePath;
                notify.AlertText = definition.DisplayMessage;

                trans.Complete();
            }
            await HubContext.Clients.User(recipient.Username).ReceiveNotification(notify);

            //todo if cant deliver now, deliver later (put in DB, return on login)

            return(true);
        }
Exemple #2
0
        internal async Task <IEnumerable <InventoryItemDetails> > SelectItemsFromConfig(ItemGenerationConfig cfg, User activeUser)
        {
            List <InventoryItemDetails>        items         = new List <InventoryItemDetails>();
            IEnumerable <InventoryItemDetails> userInventory = null;
            IEnumerable <IGrouping <int, InventoryItemDetails> > userInvGroupedByType = null;
            IEnumerable <ItemTypeConfig> types = null;

            if (cfg.Quantity < 0)
            {
                userInventory = await InventoryDomain.GetFullInventory(activeUser);
            }

            if (cfg.ItemId.HasValue)
            {
                var specificItem = (await InventoryRepo.RetrieveFullItemsByIds(cfg.ItemId.Value)).First();
                if (specificItem.Item.OwnerUserId == null || (cfg.Quantity < 0 && specificItem.Item.OwnerUserId == activeUser.Id))
                {
                    items.Add(specificItem);
                }
            }

            do
            {
                if (cfg.ItemType.HasValue && items.Count <= Math.Abs(cfg.Quantity))
                {
                    if (cfg.Quantity < 0) //taking away
                    {
                        items.AddRange(userInventory.Where(inv => inv.Item.ItemTypeId == cfg.ItemType).Take(-1 * (cfg.Quantity + items.Count())));
                    }
                    else //creating and giving
                    {
                        items.AddRange(await InventoryDomain.GenerateItems(cfg.ItemType.Value, null, Utilities.Extensions.Random.Next(cfg.Quantity - items.Count())));
                    }
                }

                if (cfg.ItemRarityRangeLowerBound.HasValue || cfg.ItemRarityRangeUpperBound.HasValue)
                {
                    if (userInvGroupedByType == null)
                    {
                        userInvGroupedByType = userInventory.GroupBy(i => i.Item.ItemTypeId);
                    }
                    if (types == null)
                    {
                        types = (await ConfigRepo.RetrieveItemTypesByRarity(cfg.ItemRarityRangeLowerBound, cfg.ItemRarityRangeUpperBound)).OrderBy(x => Utilities.Extensions.Random.Next());
                    }
                    foreach (var type in types)
                    {
                        if (cfg.ItemType.HasValue && items.Count <= Math.Abs(cfg.Quantity))
                        {
                            if (cfg.Quantity < 0) //steal
                            {
                                items.AddRange(userInventory.Where(inv => inv.Item.ItemTypeId == cfg.ItemType).Take(-1 * (cfg.Quantity + items.Count())));
                            }
                            else //give
                            {
                                items.AddRange(await InventoryDomain.GenerateItems(type.Id, null, Utilities.Extensions.Random.Next(cfg.Quantity - items.Count())));
                            }
                        }
                    }
                }
            }while (cfg.Quantity > items.Count()); //while only for the giving case, because we can give with randomness, taking has a hard limit of the user's inv
            return(items);
        }