protected User GetUser(IDialogContext context) { var userId = context.UserData.Get <int>(StateKeys.UserId); var db = new DrugBotDataContext(); return(db.Users.FirstOrDefault(x => x.UserId == userId)); }
private static string DoDrugSpikeDown(int userId, DrugBotDataContext db, IDialogContext context) { // randomize the drug to spike var drugs = db.GetDrugs().ToList(); var drug = drugs.ElementAt(rand.Next(0, drugs.Count())); // todo: put these bounds somewhere static or configurable // adjust drug price, % of the min var spikeRate = GetRandomDoubleBetween(0.20, 0.40); var minPrice = drug.MinPrice; var spikePrice = (int)(minPrice * spikeRate); if (spikePrice <= 0) { spikePrice = 1; } var drugPrices = context.UserData.Get <Dictionary <int, int> >(StateKeys.DrugPrices); drugPrices[drug.DrugId] = spikePrice; context.UserData.SetValue(StateKeys.DrugPrices, drugPrices); var spikeText = RandomDownSpikeText(); return($"{spikeText} {drug.Name} prices have bottomed out!"); }
protected Location GetLocation(IDialogContext context) { var locationId = context.UserData.Get <int>(StateKeys.LocationId); var db = new DrugBotDataContext(); return(db.Locations.Single(x => x.LocationId == locationId)); }
public async Task StartAsync(IDialogContext context) { var db = new DrugBotDataContext(); // check inventory to see if they have anything to sell var userId = context.UserData.Get <int>(StateKeys.UserId); var user = db.Users.Single(x => x.UserId == userId); if (!user.Inventory.Any(x => x.Quantity > 0)) { await context.PostAsync("You don't have anything to sell..."); this.Done(context); } else { var buttons = this.GetDrugButtons(context); this.AddCancelButton(buttons); await context.PostAsync(this.SetupHeroResponse(context, buttons, "What do you want to sell?")); context.Wait(MessageReceivedAsync); } }
protected Gun GetRandomGun(int dayOfGame) { var db = new DrugBotDataContext(); var guns = db.Guns.Where(x => x.MinimumDayOfGame <= dayOfGame).ToList(); return(guns.ElementAt(RandomEvent.GetRandomNumberBetween(0, guns.Count))); }
public override bool IsValid(object value) { var proposedName = value.ToString(); var db = new DrugBotDataContext(); return(!db.Users.Any(x => x.Name == proposedName)); }
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable <IMessageActivity> result) { var message = await result; if (message.Text.ToLower() == "cancel") { this.Done(context); } else { var db = new DrugBotDataContext(); var drugs = db.GetDrugs().ToList() .Select(x => new { Name = x.Name.ToLower(), DrugId = x.DrugId, }); var drugPrices = this.GetDrugPrices(context); if (drugs.Any(x => x.Name == message.Text.ToLower())) { var drug = drugs.Single(x => x.Name == message.Text.ToLower()); var user = this.GetUser(context); var inventory = user.Inventory.FirstOrDefault(x => x.DrugId == drug.DrugId); if (inventory != null && inventory.Quantity > 0) { if (drugPrices.Any(x => x.Key == drug.DrugId)) { context.UserData.SetValue(StateKeys.DrugToSell, drug.Name); // get inventory var qty = user.Inventory.Single(x => x.DrugId == drug.DrugId).Quantity; // prompt for quantity PromptDialog.Number(context, SellQuantityAsync, $"You have {qty:n0}. How much do you want to sell?"); } } else { await context.PostAsync("You don't have any of that. Type CANCEL if you don't want to sell anything."); context.Wait(MessageReceivedAsync); } } else { await context.PostAsync("You can't sell that...Type CANCEL if you don't want to sell anything."); context.Wait(MessageReceivedAsync); } } }
protected void SetupLoan(IDialogContext context, int amount, double rate) { var db = new DrugBotDataContext(); var userId = context.UserData.Get <int>(StateKeys.UserId); var user = db.Users.FirstOrDefault(x => x.UserId == userId); user.LoanDebt = amount; user.LoanRate = rate; user.Wallet = user.Wallet + amount; db.Commit(); }
public static EventInfo Get(IDialogContext context, int userId) { var eventText = string.Empty; // random weighted event var eventOdd = rand.Next(1, 7); System.Diagnostics.Debug.WriteLine($"eventOdd: {eventOdd}"); // todo: some kind of weighted dictionary/enum/whatevs to handle this randomization var db = new DrugBotDataContext(); switch (eventOdd) { // event: mugging case 1: eventText = DoMugging(userId, db); break; // event: police raid case 2: eventText = DoDrugSpike(userId, db, context); break; // event: drug spike down case 3: eventText = DoDrugSpikeDown(userId, db, context); break; // event: found a trenchcoat case 4: eventText = DoTrenchcoat(userId, db); break; // event: option to buy a gun, handled later case 5: return(new EventInfo { IsGunEvent = true }); // event: cops! case 6: return(new EventInfo { IsCombatEvent = true }); } return(new EventInfo { EventText = eventText }); }
protected async Task ShowLeaderboard(IDialogContext context) { var db = new DrugBotDataContext(); // show leaderboard var leaders = db.GetLeaderboard(); var sb = new StringBuilder("Leaderboard:\n\n"); foreach (var leader in leaders) { sb.Append($"{leader.User.Name}: {leader.Score:C0}\n\n"); } await context.PostAsync(sb.ToString()); }
private static string DoMugging(int userId, DrugBotDataContext db) { var user = db.Users.Single(x => x.UserId == userId); // get current wallet var wallet = user.Wallet; // todo: put bounds somewhere static or configurable var lossRate = GetRandomDoubleBetween(0.05, 0.10); var moneyLost = (int)(wallet * lossRate); var muggingText = RandomMuggingText(); user.Wallet = user.Wallet - moneyLost; db.Commit(); return($"{muggingText} You lost {moneyLost:C0}!"); }
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable <IMessageActivity> result) { var message = await result; var proposedName = message.Text; var db = new DrugBotDataContext(); this.BotUserId = message.Conversation.Id; var validationError = db.ValidateUser(this.BotUserId, proposedName); // hack: check specifically for a unique name if (db.Users.Any(x => x.Name == proposedName)) { validationError = "Your name must be unique...try again."; } // validate username, etc if (string.IsNullOrWhiteSpace(validationError)) { var user = db.AddUser(this.BotUserId, proposedName); var records = db.Commit(); this.Name = proposedName; context.UserData.SetValue <int>(StateKeys.UserId, user.UserId); await context.PostAsync($"Thanks {this.Name}...let's make some money!"); // start in washington, dc context.UserData.SetValue <int>(StateKeys.LocationId, 1); // go back this.Done(context, new GameState { IsNameReady = true }); } else { await context.PostAsync(validationError); // loop context.Wait(MessageReceivedAsync); } }
private async Task PlayerDead(IDialogContext context) { context.UserData.RemoveValue(StateKeys.CombatContext); var lostInventory = string.Empty; var lostWallet = 0; InventoryItem stolenDrug = null; var stolenQuantity = 0; var db = new DrugBotDataContext(); var userId = context.UserData.Get <int>(StateKeys.UserId); var user = db.Users.Single(x => x.UserId == userId); // randomize some losses if (user.Wallet > 0) { var lossRate = RandomEvent.GetRandomDoubleBetween(0.05, 0.10); lostWallet = (int)(user.Wallet * lossRate); user.Wallet = user.Wallet - lostWallet; } if (user.Inventory.Any(x => x.Quantity > 0)) { var availableInventory = db.InventoryItems .Where(x => x.UserId == userId && x.Quantity > 0); var count = availableInventory.Count(); var drugIndex = RandomEvent.GetRandomNumberBetween(0, count); stolenDrug = availableInventory.ToList().ElementAt(drugIndex); var stealRate = RandomEvent.GetRandomDoubleBetween(0.05, 0.10); stolenQuantity = (int)(stolenDrug.Quantity * stealRate); stolenDrug.Quantity = stolenDrug.Quantity - stolenQuantity; } db.Commit(); lostInventory = $"{(lostWallet > 0 ? $"{lostWallet:C0} from your wallet" : string.Empty)}" + $"{(lostWallet > 0 && stolenQuantity > 0 ? " and " : string.Empty)}" + $"{(stolenQuantity > 0 ? $"{stolenQuantity} {stolenDrug.Drug.Name} from you" : string.Empty)}"; await context.PostAsync($"They beat you unconscious and took {lostInventory}."); this.Done(context); }
public virtual async Task MessageReceivedAsync(IDialogContext context, IAwaitable <IMessageActivity> result) { var message = await result; this.BotUserId = message.Conversation.Id; if (message.Text.ToLower() == "play") { var db = new DrugBotDataContext(); var user = db.FindUser(this.BotUserId); // start in washington, dc context.UserData.SetValue <int>(StateKeys.LocationId, 1); db.Commit(); if (user == null) { // first time playing, create user, prompt for name... context.Call(new SetupNameDialog(), BackToSetupNameAsync); } else { // todo: greet user await context.PostAsync("I know you..."); context.UserData.SetValue <int>(StateKeys.UserId, user.UserId); context.Call(new MainMenuDialog(), BackToSetupNameAsync); } } else if (message.Text.ToLower() == "leaderboard") { await this.ShowLeaderboard(context); context.Wait(MessageReceivedAsync); } else { // tell them to trigger the game start await context.PostAsync("You should probably type PLAY to start the game..."); context.Wait(MessageReceivedAsync); } }
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable <IMessageActivity> result) { var message = await result; if (message.Text.ToLower() == "cancel") { this.Done(context); } else { var db = new DrugBotDataContext(); var drugs = db.GetDrugs().ToList() .Select(x => new { DrugId = x.DrugId, Name = x.Name.ToLower(), }); if (drugs.Any(x => x.Name == message.Text.ToLower())) { // send intended drug to state // confirm db record matches, so we store a good drug name to bot state var drug = drugs.Single(x => x.Name == message.Text.ToLower()); context.UserData.SetValue(StateKeys.DrugToBuy, drug.Name); // get affordability var user = this.GetUser(context); var drugPrice = this.GetDrugPrices(context).Single(x => x.Key == drug.DrugId).Value; var canAfford = user.Wallet / drugPrice; var canHold = user.InventorySize - user.Inventory.Sum(x => x.Quantity); // prompt for quantity PromptDialog.Number(context, BuyQuantityAsync, $"You can afford {canAfford:n0} and hold {canHold}. How much do you want to buy?"); } else { await context.PostAsync("You can't buy that...Type CANCEL if you don't want to buy anything."); context.Wait(MessageReceivedAsync); } } }
private static string DoTrenchcoat(int userId, DrugBotDataContext db) { var user = db.Users.Single(x => x.UserId == userId); // get storage var currentSpace = user.InventorySize; // get increase rate // todo: make static/configurable var newSpaceRate = GetRandomDoubleBetween(0.30, 0.50); var newSpace = (int)(currentSpace * newSpaceRate); // commit to user user.InventorySize = user.InventorySize + newSpace; db.Commit(); var trenchcoatText = RandomTrenchcoatText(); return($"{trenchcoatText} You can hold {newSpace} more drugs!"); }
protected bool PayLoan(IDialogContext context) { var db = new DrugBotDataContext(); var userId = context.UserData.Get <int>(StateKeys.UserId); var user = db.Users.FirstOrDefault(x => x.UserId == userId); if (user.Wallet >= user.LoanDebt) { user.Wallet = user.Wallet - user.LoanDebt; user.LoanDebt = 0; user.LoanRate = 0.0; db.Commit(); context.UserData.SetValue <double>(StateKeys.LoanRate, 0.0); return(true); } return(false); }
protected int TravelUser(int userId, int locationId) { var db = new DrugBotDataContext(); var user = db.Users.FirstOrDefault(x => x.UserId == userId); if (user != null) { user.LocationId = locationId; user.DayOfGame = user.DayOfGame + 1; if (user.LoanDebt > 0) { user.LoanDebt = user.LoanDebt + (int)(user.LoanDebt * user.LoanRate); } db.Commit(); return(user.DayOfGame); } return(0); }
private static string DoDrugSpike(int userId, DrugBotDataContext db, IDialogContext context) { // randomize the drug to spike var drugs = db.GetDrugs().ToList(); var drug = drugs.ElementAt(rand.Next(0, drugs.Count())); // todo: put these bounds somewhere static or configurable // adjust drug price, 50% to 400% over the max var spikeRate = GetRandomDoubleBetween(0.50, 4.0); var maxPrice = drug.MaxPrice; var spikePrice = (int)(maxPrice + (maxPrice * spikeRate)); var drugPrices = context.UserData.Get <Dictionary <int, int> >(StateKeys.DrugPrices); drugPrices[drug.DrugId] = spikePrice; context.UserData.SetValue(StateKeys.DrugPrices, drugPrices); var spikeText = RandomSpikeText(); return($"{spikeText} {drug.Name} prices have gone through the roof!"); }
protected BuyGunInfo BuyGun(IDialogContext context) { var db = new DrugBotDataContext(); var gun = context.UserData.Get <Gun>(StateKeys.GunToBuy); var userId = context.UserData.Get <int>(StateKeys.UserId); var user = db.Users.FirstOrDefault(x => x.UserId == userId); if (user.Wallet >= gun.Cost) { user.Wallet = user.Wallet - gun.Cost; user.GunId = gun.GunId; db.Commit(); return(new BuyGunInfo { IsSuccessful = true }); } return(new BuyGunInfo { IsSuccessful = false, ReasonText = "You ain't got the cash for this piece." }); }
protected Dictionary <int, int> GetDrugPrices(IDialogContext context, bool newPrices = false) { var drugPrices = new Dictionary <int, int>(); var db = new DrugBotDataContext(); var drugs = db.GetDrugs().ToList(); if (!context.UserData.TryGetValue(StateKeys.DrugPrices, out drugPrices) || newPrices) { drugPrices = new Dictionary <int, int>(); foreach (var drug in drugs) { var price = rand.Next(drug.MinPrice, drug.MaxPrice); drugPrices.Add(drug.DrugId, price); } // store to state context.UserData.SetValue(StateKeys.DrugPrices, drugPrices); } return(drugPrices); }
protected void ResetUser(IDialogContext context) { var db = new DrugBotDataContext(); var userId = context.UserData.Get <int>(StateKeys.UserId); var user = db.Users.FirstOrDefault(x => x.UserId == userId); var money = user.Wallet; user.Wallet = Defaults.StartingMoney; user.DayOfGame = Defaults.GameStartDay; user.LocationId = Defaults.LocationId; user.LoanDebt = 0; user.LoanRate = 0.0; user.GunId = null; user.InventorySize = Defaults.InventorySize; // clear out inventory db.InventoryItems.RemoveRange(user.Inventory); // regenerate drug prices for this user this.GetDrugPrices(context, true); db.Commit(); }
protected IQueryable <Location> GetLocations() { var db = new DrugBotDataContext(); return(db.Locations); }
protected IQueryable <Drug> GetDrugs() { var db = new DrugBotDataContext(); return(db.Drugs); }
private async Task SellQuantityAsync(IDialogContext context, IAwaitable <long> result) { var qty = await result; if (qty < 1) { await context.PostAsync("Looks like you don't want to sell any--thanks for wasting my time"); this.Done(context); } else { // yeah, i know this could truncate var quantity = Convert.ToInt32(qty); var db = new DrugBotDataContext(); var userId = context.UserData.Get <int>(StateKeys.UserId); var user = db.Users.Single(x => x.UserId == userId); var drugs = db.GetDrugs().ToList() .Select(x => new { Name = x.Name, NameLower = x.Name.ToLower(), DrugId = x.DrugId, }); // determine drug price var drugPrices = this.GetDrugPrices(context); var drugToSell = context.UserData.Get <string>(StateKeys.DrugToSell); var drug = drugs.Single(x => x.NameLower == drugToSell); if (user.Inventory.Any(x => x.DrugId == drug.DrugId && x.Quantity >= quantity)) { var price = drugPrices[drug.DrugId]; var total = price * quantity; user.Wallet += total; var item = user.Inventory.Single(x => x.DrugId == drug.DrugId); item.Quantity -= quantity; try { db.Commit(); } catch { await context.PostAsync("Something happened when saving your sell inventory. Yeah, I'm still an alpha bot..."); } await context.PostAsync($"You sold {qty} for {total:C0}."); await context.PostAsync($"You have {user.Wallet:C0} in your wallet."); this.Done(context); } else { await context.PostAsync("You don't have that much to sell..."); this.Done(context); } } }
private async Task BuyQuantityAsync(IDialogContext context, IAwaitable <long> result) { var qty = await result; // yeah, i know this could truncate if (qty < 1) { await context.PostAsync("Looks like you don't want to buy any--thanks for wasting my time"); this.Done(context); } else { var quantity = Convert.ToInt32(qty); // todo: put this somewhere common var db = new DrugBotDataContext(); var userId = context.UserData.Get <int>(StateKeys.UserId); var user = db.Users.FirstOrDefault(x => x.UserId == userId); if (user.InventorySize >= user.Inventory.Sum(x => x.Quantity) + qty) { var drugs = db.GetDrugs().ToList() .Select(x => new { Name = x.Name, NameLower = x.Name.ToLower(), DrugId = x.DrugId, }); if (user != null) { // determine drug price var drugPrices = this.GetDrugPrices(context); var drugToBuy = context.UserData.Get <string>(StateKeys.DrugToBuy); var drug = drugs.Single(x => x.NameLower == drugToBuy); var price = drugPrices[drug.DrugId]; // check wallet for enough money if (user.Wallet >= price * qty) { var cost = price * quantity; // do transaction user.Wallet -= cost; await context.PostAsync($"You spent {cost:C0} on {qty} units of {drug.Name}"); await context.PostAsync($"You have {user.Wallet:C0} remaining"); // add inventory if (user.Inventory.Any(x => x.Drug.Name == drug.Name)) { // already has zero or more of this drug, add to it var inventory = user.Inventory.FirstOrDefault(x => x.Drug.Name == drug.Name); inventory.Quantity += quantity; } else { // add this inventory for the firs time var inventory = new InventoryItem { UserId = user.UserId, DrugId = drug.DrugId, Quantity = quantity, }; db.AddInventory(inventory); } try { db.SaveChanges(); } catch { await context.PostAsync("Something happened when saving your buy inventory. Yeah, I'm still an alpha bot..."); } this.Done(context); } else { await context.PostAsync("You don't have enough money to buy that."); this.Done(context); } } } else { // not enough inventory space await context.PostAsync("You don't have enough inventory space to buy all that."); this.Done(context); } } }
private async Task ResumeMainMenu(IDialogContext context, IAwaitable <GameState> result) { var state = await result; if (state.IsGameOver) { var user = this.GetUser(context); var score = user.Wallet; if (user.LoanDebt > 0) { await context.PostAsync($"Ya' punk #$%! kid--I'm gonna break both your legs and take back my {user.LoanDebt:C0}!"); await context.PostAsync("The loan shark proceeds to break your legs and take his money."); score = user.Wallet - user.LoanDebt; } // record log of game before resetting var db = new DrugBotDataContext(); var game = new Game { UserId = user.UserId, Score = score }; db.Games.Add(game); db.Commit(); // get their rank var orderedGame = db.Games .OrderByDescending(x => x.Score) .AsEnumerable() .Select((x, i) => new { Game = x, Rank = i + 1 }) .Single(x => x.Game.GameId == game.GameId); await context.PostAsync("Game Over."); await context.PostAsync($"You finished with {score:C0} " + $"({StringHelper.AddOrdinal(orderedGame.Rank)} overall)"); await this.ShowLeaderboard(context); await context.PostAsync("Type PLAY to start another game!"); // reset user (this commits db changes) this.ResetUser(context); this.Done(context); } else if (state.IsTraveling) { var user = this.GetUser(context); // todo: random events for the day if (RandomEvent.IsGoingToHappen) { // pass context and user to do db things, receive event info var randomEvent = RandomEvent.Get(context, user.UserId); context.UserData.SetValue(StateKeys.RandomEvent, randomEvent); } // get day and location var location = this.GetLocations().Single(x => x.LocationId == user.LocationId); await context.PostAsync($"It's day {user.DayOfGame}. You're in {location.Name}."); await StartAsync(context); } else { // print menu and start again--hopefully await StartAsync(context); } }