public override async Task <NpcAction> Interact(int action, User activeUser)
        {
            var response = new NpcAction();

            if (action == (int)Actions.TakeAGift)
            {
                using (var trans = transactionFactory.Create())
                {
                    var states = await domain.GetNpcStates(Id, activeUser.Id);

                    if (states?.Count() > 0)
                    {
                        response.Message = "Come back tomorrow, don't be greedy!";
                        response.Title   = "Uh oh!";
                        //response.ImagePath = "" seems like it should be configurable, but this is code...
                    }
                    else
                    {
                        //get config
                        var cfgs = await GetItemConfigs(configRepo);

                        if (cfgs.Count() > 1)
                        {
                            Log.Logger.Warning($"NPC {Id} has {cfgs.Count()} valid item generation cfgs right now, thats a weird state!");
                        }
                        //create item
                        var items = new List <InventoryItemDetails>();
                        foreach (var cfg in cfgs.Where(c => !c.StoreId.HasValue))
                        {
                            items.AddRange(await domain.SelectItemsFromConfig(cfg, activeUser));
                        }
                        //give it
                        foreach (var item in items)
                        {
                            if (item.Item.OwnerUserId == null) //give
                            {
                                if (await domain.ChangeItemOwner(item.Item.Id, activeUser.Id, null))
                                {
                                    response.AddedItems.Add(item);
                                }
                            }
                            if (item.Item.OwnerUserId == activeUser.Id) //take //TODO remove this, just using MrLF as a proof of concept. MrLF is a giver.
                            {
                                if (await domain.ChangeItemOwner(item.Item.Id, null, activeUser.Id))
                                {
                                    response.RemovedItems.Add(item);
                                }
                            }
                            else //do nothing - log and skip
                            {
                                Log.Logger.Error($"NPC {Id} has selected an invalid item to reappropriate - item {item.Item.Id} is owned by" +
                                                 $" {item.Item.OwnerUserId} and not fit for an action with {activeUser.Id}");
                            }
                        }

                        response.Message = $"Merry Happy! Mr. Legitly Festive gives you {response.AddedItems.Count()} items!";

                        //save state
                        var state = new NpcState();
                        state.NpcId      = Id;
                        state.UserId     = activeUser.Id;
                        state.Expiration = DateTime.UtcNow.Date.AddDays(1);
                        await domain.SaveNpcState(state);
                    }
                    //respond
                    trans.Complete();
                    return(response);
                }
            }

            throw new CritterException("Invalid action for Mr Legitly Festive! Try a different action.", $"User {activeUser.Id} tried to {action} Mr. LegitlyFestive.", System.Net.HttpStatusCode.BadRequest);
        }
        public override async Task <NpcAction> Interact(int action, User activeUser)
        {
            var response = new NpcAction();

            if (action == (int)Actions.TakePizza)
            {
                using (var trans = transactionFactory.Create())
                {
                    var states = await domain.GetNpcStates(Id, activeUser.Id);

                    if (states?.Count() > 0)
                    {
                        response.Message = "Come back tomorrow, you've had your full allotment of pizza for the day!";
                        response.Title   = "Pizza denied.";
                        //response.ImagePath = "" seems like it should be configurable, but this is code...
                    }
                    else
                    {
                        //get config
                        var cfgs = (await GetItemConfigs(configRepo)).Where(c => !c.StoreId.HasValue);

                        //create item
                        var items = new List <InventoryItemDetails>();
                        var cfg   = cfgs.SelectRandom();
                        {
                            items.AddRange(await domain.SelectItemsFromConfig(cfg, activeUser));
                        }
                        //give it
                        foreach (var item in items)
                        {
                            if (item.Item.OwnerUserId == null) //give
                            {
                                if (await domain.ChangeItemOwner(item.Item.Id, activeUser.Id, null))
                                {
                                    response.AddedItems.Add(item);
                                }
                            }
                            else //do nothing - log and skip
                            {
                                Log.Logger.Error($"NPC {Id} has selected an invalid item to reappropriate - item {item.Item.Id} is owned by" +
                                                 $" {item.Item.OwnerUserId} and not fit for an action with {activeUser.Id}");
                            }
                        }

                        response.Message = $"The World Pizza Organization has allocated pizza for everyone.";

                        //save state
                        var state = new NpcState();
                        state.NpcId      = Id;
                        state.UserId     = activeUser.Id;
                        state.Expiration = DateTime.UtcNow.Date.AddDays(1);
                        await domain.SaveNpcState(state);
                    }
                    //respond
                    trans.Complete();
                    return(response);
                }
            }

            throw new CritterException($"Invalid action for the World Pizza Organization! Try a different action.", $"User {activeUser.Id} tried to {action} {Id.ToString()}.", System.Net.HttpStatusCode.BadRequest);
        }