public override void ExecuteCommand(IChatChannel channel, StreamCommand command) { long userid = playermodule.GetPlayer(command.Service, command.User).UserID; HoldemGame game = casino.GetGame(userid); if (game == null) { SendMessage(channel, command.User, "You have no active holdem game. Use !holdem to start a new game."); return; } casino.RemoveGame(userid); RPGMessageBuilder message = messagemodule.Create().User(userid).Text(" folds the hand. "); HandEvaluation dealerevaluation = HandEvaluator.Evaluate(game.Board + game.DealerHand); HandEvaluation playerevaluation = HandEvaluator.Evaluate(game.Board + game.PlayerHand); if (dealerevaluation < playerevaluation || dealerevaluation.Rank < HandRank.Pair || (dealerevaluation.Rank == HandRank.Pair && dealerevaluation.HighCard < CardRank.Four)) { message.ShopKeeper().Text(" laughs and shows "); foreach (Card card in game.DealerHand) { message.Image(cardimages.GetCardUrl(card), $"{card} "); } message.Text("while grabbing ").Gold(game.Pot); } else { message.ShopKeeper().Text(" gladly rakes in ").Gold(game.Pot); } message.Send(); }
public void CheckSplit(Board board, RPGMessageBuilder messages) { if (IsSplitPossible(board)) { messages.Text(" Split possible."); } }
void PlayerDefeated(IBattleEntity target, RPGMessageBuilder message) { IBattleEntity attacker = Actors.FirstOrDefault(a => a is MonsterBattleEntity); message?.BattleActor(target).Text(" dies miserably and ").BattleActor(attacker).Text(" is laughing."); lock (actors) actors.Remove(target); }
void ITimerService.Process(double time) { if (currentbets.Count > 0) { int index = RNG.XORShift64.NextInt(numbers.Length); int number = numbers[index]; RouletteColor color = colors[index]; lock (historylock) { history.Enqueue(new RouletteField(number, color)); while (history.Count > 10) { history.Dequeue(); } } RPGMessageBuilder builder = context.GetModule <RPGMessageModule>().Create(); builder.Text("The ball fell to field ").Text($"{number} {color}", GetColor(color), FontWeight.Bold).Text(". "); Dictionary <long, int> winnings = new Dictionary <long, int>(); lock (betlock) { foreach (RouletteBet bet in currentbets) { int factor = GetFactor(bet, number, color); if (factor > 0) { if (!winnings.ContainsKey(bet.UserID)) { winnings[bet.UserID] = 0; } winnings[bet.UserID] += bet.Gold * factor; } } currentbets.Clear(); } foreach (KeyValuePair <long, int> win in winnings) { builder.User(win.Key).Text(" won ").Gold(win.Value); context.GetModule <PlayerModule>().UpdateGold(win.Key, win.Value); } builder.Send(); } else { if (nextbets.Count > 0) { lock (betlock) { currentbets.AddRange(nextbets); nextbets.Clear(); } context.GetModule <RPGMessageModule>().Create().Text("A new roulette round has started.").Send(); } } }
public void Remove(IBattleEntity entity, RPGMessageBuilder message = null) { lock (actorlock) { actors.Remove(entity); if (entity is MonsterBattleEntity) { MonsterDefeated((MonsterBattleEntity)entity, message); } } }
public override void ExecuteCommand(IChatChannel channel, StreamCommand command) { BlackJackGame game = blackjack.GetGame(command.Service, command.User); if (game == null) { SendMessage(channel, command.User, "There is active black jack game. Start another one with !bj <bet>"); return; } game.PlayerBoards[game.ActiveBoard].Board += game.Stack.Pop(); int value = logic.Evaluate(game.PlayerBoards[game.ActiveBoard].Board); RPGMessageBuilder message = messages.Create(); message.User(game.PlayerID).Text(" has "); foreach (Card card in game.PlayerBoards[game.ActiveBoard].Board) { message.Image(images.GetCardUrl(card), $"{card} "); } message.Text(". "); if (value > 21) { message.Text("Bust!"); game.PlayerBoards.RemoveAt(game.ActiveBoard); } else { message.Text($"({value}). "); if (value == 21) { ++game.ActiveBoard; } } if (game.PlayerBoards.Count == 0) { message.Text(" All hands are busted.").ShopKeeper().Text(" laughs at you."); blackjack.RemoveGame(game.PlayerID); } else { if (game.ActiveBoard >= game.PlayerBoards.Count) { message.Text(" All hands have been played."); logic.PlayoutDealer(game, message, playermodule, images); blackjack.RemoveGame(game.PlayerID); } } message.Send(); }
AdventureStatus CheckStatus(IBattleEntity attacker, IBattleEntity target, RPGMessageBuilder message) { if (target.HP <= 0) { if (attacker is PlayerBattleEntity) { MonsterDefeated(target as MonsterBattleEntity, message); return(AdventureStatus.Exploration); } PlayerDefeated(target, message); return(AdventureStatus.SpiritRealm); } return(AdventureStatus.MonsterBattle); }
public override void Process(IBattleEntity attacker, IBattleEntity target) { float hitprobability = MathCore.Sigmoid(GetModifiedDexterity(attacker) - target.Dexterity, 1.1f, 0.68f); RPGMessageBuilder message = context.GetModule <RPGMessageModule>().Create().BattleActor(attacker).Text(" tries to bite ").BattleActor(target); if (RNG.XORShift64.NextFloat() < hitprobability) { int hp = Math.Min(target.HP, (int)(target.MaxHP * (0.1 + 0.05 * Level))); message.Text(", sucks on him and heals").Health(attacker.Heal(hp)).Text("."); target.Hit(hp); } else { message.Text(" but fails miserably."); } message.Send(); }
public void ProcessStatusEffect(double time) { cooldown -= time; if (cooldown <= 0) { int damage = Math.Max(1, (int)(GetDamage() * (0.5 + RNG.XORShift64.NextDouble() * 0.5))); RPGMessageBuilder message = messages.Create().Text("The ").Color(AdventureColors.Poison).Text("Poison").Reset().Text(" is draining the body of ").BattleActor(target).Text(" for ").Damage(damage).Text(".").Reset(); target.Hit(damage); if (target.HP <= 0) { target.BattleLogic.Remove(target); message.Text(" ").BattleActor(target).Text(" dies to the ").Color(AdventureColors.Poison).Text("Poison").Reset().Text("."); adventuremodule.ChangeStatus(target.Adventure, AdventureStatus.SpiritRealm); } message.Send(); cooldown += GetCooldown(); } }
public void MonsterDefeated(MonsterBattleEntity monster, RPGMessageBuilder message) { IBattleEntity attacker = Actors.FirstOrDefault(a => a is PlayerBattleEntity); BattleReward reward = attacker?.Reward(monster); if (reward != null) { message?.BattleActor(attacker).Text(" has killed ").BattleActor(monster).Text(" and receives ").Experience(reward.XP).Text(" and ").Gold(reward.Gold).Text("."); if (reward.Item != null) { message?.BattleActor(attacker).Text(" finds ").Item(reward.Item).Text(" in the remains."); } } lock (actors) actors.Remove(monster); }
public void CraftItem(long playerid, Item[] ingredients) { ItemRecipe recipe = context.GetModule <ItemModule>().GetRecipe(ingredients.Select(i => i.ID).ToArray()); if (recipe != null) { foreach (RecipeIngredient item in recipe.Ingredients.Where(i => i.Consumed)) { RemoveItem(playerid, item.Item, 1); } } else { foreach (Item item in ingredients) { RemoveItem(playerid, item.ID, 1); } } User user = context.GetModule <UserModule>().GetUser(playerid); Item targetitem = recipe != null?context.GetModule <ItemModule>().GetItem(recipe.ItemID) : context.GetModule <ItemModule>().GetItem("Garbage"); if (targetitem != null) { AddItem(playerid, targetitem.ID, 1, true); RPGMessageBuilder message = context.GetModule <RPGMessageModule>().Create(); message.User(user).Text(" has created ").Item(targetitem).Text(" out of "); for (int i = 0; i < ingredients.Length; ++i) { if (i == ingredients.Length - 1) { message.Text(" and "); } else if (i > 0) { message.Text(", "); } message.Item(ingredients[i]); } message.Text(".").Send(); } }
public void ProcessStatusEffect(double time) { cooldown -= time; if (cooldown <= 0) { if (RNG.XORShift64.NextFloat() < GetSuppurationChance()) { RPGMessageBuilder message = messages.Create(); int damage = Math.Max(1, (int)(GetDamage() * (0.5 + RNG.XORShift64.NextDouble() * 0.5))); message.Text("The wound of ").BattleActor(target).Text(" suppurates, inflicting pain for ").Damage(damage).Text("."); target.Hit(damage); if (target.HP <= 0) { target.BattleLogic.Remove(target, message); } message.Send(); } cooldown += 5.0; } }
void BuyFromTravelingMerchant(string service, string channel, string username, Player player, Item item, int quantity, double discount) { User user = context.GetModule <UserModule>().GetExistingUser(service, username); int price = (int)(item.Value * (travelingmerchant.Price - discount)); if (price > player.Gold) { context.GetModule <StreamModule>().SendMessage(service, channel, username, $"Sadly you don't have enough gold. You would need {price} gold to buy {item.GetCountName(quantity)}"); return; } AddInventoryItemResult result = context.GetModule <InventoryModule>().AddItem(player.UserID, item.ID, quantity); switch (result) { case AddInventoryItemResult.Success: case AddInventoryItemResult.SuccessFull: Aggregate agg = Aggregate.Max(Constant.Create(0), EntityField.Create <Player>(pl => pl.Gold)); context.Database.Update <Player>().Set(p => p.Gold == agg.Int - price).Where(p => p.UserID == player.UserID).Execute(); RPGMessageBuilder message = context.GetModule <RPGMessageModule>().Create().User(user).Text(" bought ").Item(item, quantity).Text(" and spent ").Gold(price); if (result == AddInventoryItemResult.SuccessFull) { message.Text(" and is now encumbered."); } else { message.Text("."); } message.Send(); break; case AddInventoryItemResult.InventoryFull: context.GetModule <StreamModule>().SendMessage(service, channel, username, $"You don't have room in your inventory to buy {quantity} {item.Name}"); break; } }
public override void ExecuteCommand(IChatChannel channel, StreamCommand command) { BlackJackGame game = blackjack.GetGame(command.Service, command.User); if (game == null) { SendMessage(channel, command.User, "There is no active black jack game. Start another one with !bj <bet>"); return; } ++game.ActiveBoard; RPGMessageBuilder message = messages.Create(); message.User(game.PlayerID).Text(" is satisfied."); if (game.ActiveBoard >= game.PlayerBoards.Count) { message.Text(" All hands have been played."); logic.PlayoutDealer(game, message, playermodule, images); blackjack.RemoveGame(game.PlayerID); } else { if (game.PlayerBoards[game.ActiveBoard].Board.Count == 1) { game.PlayerBoards[game.ActiveBoard].Board += game.Stack.Pop(); } message.Text(" Next hand is "); foreach (Card card in game.PlayerBoards[game.ActiveBoard].Board) { message.Image(images.GetCardUrl(card), $"{card} "); } int value = logic.Evaluate(game.PlayerBoards[game.ActiveBoard].Board); message.Text($"({value}). "); logic.CheckSplit(game.PlayerBoards[game.ActiveBoard].Board, message); } message.Send(); }
void ExecuteChest(Player player) { double chance = 0.8; List <FoundItem> items = new List <FoundItem>(); while (RNG.XORShift64.NextDouble() < chance) { Item item = context.GetModule <ItemModule>().SelectItem(player.Level, player.Luck * 2); if (item == null) { return; } FoundItem found = items.FirstOrDefault(i => i.Item.ID == item.ID); if (found == null) { found = new FoundItem { Item = item }; items.Add(found); } if (item.Type == ItemType.Gold) { found.Quantity += 1 + player.Luck * 30 + RNG.XORShift64.NextInt((int)Math.Max(1, player.Level * player.Luck * 0.75)); } else { ++found.Quantity; } chance *= 0.8; } User user = context.GetModule <UserModule>().GetUser(player.UserID); if (items.Count == 0) { context.GetModule <RPGMessageModule>().Create().User(user).Text(" has found a chest ... which was empty.").Emotion(EmotionType.FuckYou).Send(); return; } List <FoundItem> dropped = new List <FoundItem>(); AddInventoryItemResult allresult = AddInventoryItemResult.Success; for (int i = items.Count - 1; i >= 0; --i) { FoundItem item = items[i]; if (item.Item.Type == ItemType.Gold) { context.GetModule <PlayerModule>().UpdateGold(player.UserID, item.Quantity); continue; } AddInventoryItemResult result = context.GetModule <InventoryModule>().AddItem(player.UserID, item.Item.ID, item.Quantity); if (result == AddInventoryItemResult.InvalidItem) { continue; } if (result > allresult) { allresult = result; } if (result == AddInventoryItemResult.InventoryFull) { context.GetModule <ShopModule>().AddItem(item.Item.ID, item.Quantity); dropped.Add(item); items.RemoveAt(i); } } RPGMessageBuilder message = context.GetModule <RPGMessageModule>().Create(); message.User(user).Text(" opened a chest "); if (items.Count > 0) { if (dropped.Count == 0 && allresult <= AddInventoryItemResult.Success) { message.Text(" and found"); } else { message.Text(" found"); } for (int i = 0; i < items.Count; ++i) { if (i == 0) { message.Text(" "); } else if (i == items.Count - 1) { message.Text(" and "); } else { message.Text(", "); } FoundItem item = items[i]; message.Item(item.Item, item.Quantity); } } if (dropped.Count > 0) { if (allresult > AddInventoryItemResult.Success) { message.Text(", dropped"); } else { message.Text(" and dropped"); } for (int i = 0; i < dropped.Count; ++i) { if (i == 0) { message.Text(" "); } else if (i == items.Count - 1) { message.Text(" and "); } else { message.Text(", "); } FoundItem item = dropped[i]; message.Item(item.Item, item.Quantity); } } if (allresult > AddInventoryItemResult.Success) { message.Text(" and is now encumbered."); } else { message.Text("."); } message.Send(); foreach (FoundItem item in items) { context.GetModule <AdventureModule>().TriggerItemFound(player.UserID, item.Item.ID, item.Quantity); } }
public override void ExecuteCommand(IChatChannel channel, StreamCommand command) { long userid = playermodule.GetPlayer(command.Service, command.User).UserID; HoldemGame game = casino.GetGame(userid); if (game == null) { SendMessage(channel, command.User, "You have no active holdem game. Use !holdem to start a new game."); return; } int bet = Math.Min(playermodule.GetPlayerGold(userid), game.Bet); if (bet > 0) { playermodule.UpdateGold(userid, -bet); game.Pot += bet; } game.Muck.Push(game.Deck.Pop()); game.Board += game.Deck.Pop(); RPGMessageBuilder message = messagemodule.Create(); if (game.Board.Count == 5) { // showdown message.Text("Showdown! "); } message.Text("The board shows "); foreach (Card card in game.Board) { message.Image(cardimages.GetCardUrl(card), $"{card} "); } message.Text(". You have "); foreach (Card card in game.PlayerHand) { message.Image(cardimages.GetCardUrl(card), $"{card} "); } HandEvaluation evaluation = HandEvaluator.Evaluate(game.Board + game.PlayerHand); message.Text($" ({evaluation})"); if (game.Board.Count == 5) { message.Text(". ").ShopKeeper().Text(" shows "); foreach (Card card in game.DealerHand) { message.Image(cardimages.GetCardUrl(card), $"{card} "); } HandEvaluation dealerevaluation = HandEvaluator.Evaluate(game.Board + game.DealerHand); message.Text($" ({dealerevaluation}). "); int multiplier = 0; if (dealerevaluation.Rank < HandRank.Pair || (dealerevaluation.Rank == HandRank.Pair && dealerevaluation.HighCard < CardRank.Four)) { message.ShopKeeper().Text(" isn't qualified for a showdown."); multiplier = GetMultiplier(evaluation.Rank); } else if (dealerevaluation > evaluation) { message.ShopKeeper().Text(" wins the hand and ").Gold(game.Pot).Text(" laughing at your face."); } else if (dealerevaluation == evaluation) { message.ShopKeeper().Text(" Has the same hand as you."); multiplier = 1; } else { message.Text(" You win the hand."); multiplier = GetMultiplier(evaluation.Rank); } if (multiplier > 0) { message.Text(" Payout is ").Gold(game.Pot * multiplier); playermodule.UpdateGold(userid, game.Pot * multiplier); } casino.RemoveGame(userid); } message.Send(); }
public void PlayoutDealer(BlackJackGame game, RPGMessageBuilder messages, PlayerModule playermodule, CardImageModule images) { messages.ShopKeeper().Text(" is drawing his hand to "); int value = 0; do { game.DealerBoard += game.Stack.Pop(); value = Evaluate(game.DealerBoard); }while(value < 17); foreach (Card card in game.DealerBoard) { messages.Image(images.GetCardUrl(card), $"{card} "); } if (value > 21) { messages.Text(" Bust!"); } else { messages.Text($"({value}) "); } int payout = 0; if (value > 21) { foreach (BlackJackBoard board in game.PlayerBoards) { payout = board.Bet * 2; } } else { foreach (BlackJackBoard board in game.PlayerBoards) { int boardvalue = Evaluate(board.Board); if (boardvalue > value) { payout = board.Bet * 2; } else if (boardvalue == value) { payout = board.Bet; } } } if (payout > 0) { messages.Text("Payout is ").Gold(payout); playermodule.UpdateGold(game.PlayerID, payout); } else { messages.ShopKeeper().Text(" laughs at you."); } }
AdventureStatus ProcessEffectResult(EffectResult result, IBattleEntity attacker, IBattleEntity target, RPGMessageBuilder message) { if (result == null) { return(AdventureStatus.MonsterBattle); } switch (result.Type) { case EffectResultType.DamageSelf: attacker.Hit((int)result.Argument); return(CheckStatus(attacker, target, message)); case EffectResultType.NewEffectTarget: (target as MonsterBattleEntity)?.AddEffect((ITemporaryEffect)result.Argument); return(AdventureStatus.MonsterBattle); default: return(AdventureStatus.MonsterBattle); } }
public AdventureStatus ProcessPlayer(long playerid) { IBattleEntity attacker; IBattleEntity target; lock (actors) { if (actors.Count < 2) { return(AdventureStatus.Exploration); } foreach (IBattleEntity entity in actors) { entity.Refresh(); } attacker = actors[actor]; actor = (actor + 1) % actors.Count; target = actors[actor]; } RPGMessageBuilder message = messages?.Create(); foreach (IBattleEffect effect in attacker.Effects.Where(t => t is IBattleEffect && ((IBattleEffect)t).Type == BattleEffectType.Persistent).Cast <IBattleEffect>()) { EffectResult result = effect.ProcessEffect(attacker, target); if (result.Type == EffectResultType.CancelAttack) { return(AdventureStatus.MonsterBattle); } AdventureStatus status = ProcessEffectResult(result, attacker, target, message); if (status != AdventureStatus.MonsterBattle) { message?.Send(); attacker.CleanUp(); target.CleanUp(); return(status); } } MonsterSkill skill = (attacker as MonsterBattleEntity)?.DetermineSkill(); if (skill != null) { skill.Process(attacker, target); AdventureStatus status = CheckStatus(attacker, target, message); message?.Send(); return(status); } float hitprobability = MathCore.Sigmoid(attacker.Dexterity - target.Dexterity, 1.1f, 0.7f); float dice = RNG.XORShift64.NextFloat(); AdventureStatus returnstatus = AdventureStatus.MonsterBattle; if (dice < hitprobability) { bool hit = true; foreach (IBattleEffect effect in target.Effects.Where(t => (t as IBattleEffect)?.Type == BattleEffectType.Defense).Cast <IBattleEffect>()) { if (effect.ProcessEffect(attacker, target).Type == EffectResultType.CancelAttack) { hit = false; break; } } if (hit) { bool damagecritical = attacker.WeaponOptimum > 0 && RNG.XORShift64.NextFloat() < (float)attacker.Luck / attacker.WeaponOptimum; bool armorcritical = target.ArmorOptimum > 0 && RNG.XORShift64.NextFloat() < (float)target.Luck / target.ArmorOptimum; int power = damagecritical ? attacker.Power * 2 : attacker.Power; int armor = armorcritical ? target.Defense * 2 : target.Defense; int damage = (int)Math.Max(0, (power - armor) * (0.5f + 0.5f * dice / hitprobability)); if (damage <= 0) { message?.BattleActor(target); if (armorcritical) { message?.Bold(); } message?.Text(" deflects ").Reset().BattleActor(attacker).Text("'s attack."); target.Hit(0); } else { message?.BattleActor(attacker); if (damagecritical) { message?.Bold(); } message?.Text(armorcritical ? " clashes with " : " hits "); message?.Reset().BattleActor(target).Text(" for ").Damage(damage).Text("."); IBattleEffect effect = attacker.Effects.FirstOrDefault(e => e is ShittyWeaponEffect) as IBattleEffect; ProcessEffectResult(effect?.ProcessEffect(attacker, target), attacker, target, message); target.Hit(damage); returnstatus = CheckStatus(attacker, target, message); if (returnstatus == AdventureStatus.MonsterBattle) { if (target is PlayerBattleEntity) { message?.Text(" ").BattleActor(target).Text(" has ").Health(target.HP).Text(" left."); } } else { attacker.CleanUp(); target.CleanUp(); } } } } else { message?.BattleActor(attacker).Text(" attacks ").BattleActor(target).Text(" but ").Color(AdventureColors.Miss).Text("misses").Reset().Text("."); } message?.Send(); return(returnstatus); }
public override void ExecuteCommand(IChatChannel channel, StreamCommand command) { BlackJackGame existing = blackjack.GetGame(command.Service, command.User); if(existing != null) { SendMessage(channel, command.User, "There is already a game running for you."); return; } if(command.Arguments.Length == 0) { SendMessage(channel, command.User, "You have to specify a bet amount"); return; } long userid = playermodule.GetPlayer(command.Service, command.User).UserID; int bet; int.TryParse(command.Arguments[0], out bet); if (bet <= 0) { SendMessage(channel, command.User, $"{command.Arguments[0]} is no valid bet"); return; } if (bet > playermodule.GetPlayerGold(userid)) { SendMessage(channel, command.User, "You can't bet more than you have."); return; } int maxbet = playermodule.GetLevel(userid) * 40; if (bet > maxbet) { SendMessage(channel, command.User, $"On your level you're only allowed to bet up to {maxbet} gold."); return; } BlackJackGame game = blackjack.StartGame(command.Service, command.User); game.Stack.Shuffle(); game.DealerBoard += game.Stack.Pop(); game.PlayerBoards = new List<BlackJackBoard>(); game.PlayerBoards.Add(new BlackJackBoard() { Bet = bet }); game.PlayerBoards[0].Board += game.Stack.Pop(); game.PlayerBoards[0].Board += game.Stack.Pop(); playermodule.UpdateGold(game.PlayerID, -bet); RPGMessageBuilder message = messages.Create(); message.User(userid).Text(" has "); foreach(Card card in game.PlayerBoards[0].Board) message.Image(images.GetCardUrl(card), $"{card} "); message.Text("."); int value = logic.Evaluate(game.PlayerBoards[0].Board); if(value == 21) { message.Text("Black Jack!"); int winnings = (int)(game.PlayerBoards[0].Bet * 2.5); message.Text("Winnings: ").Gold(winnings); playermodule.UpdateGold(userid, winnings); blackjack.RemoveGame(userid); } else { message.Text($"({value}). "); message.ShopKeeper().Text(" shows "); foreach (Card card in game.DealerBoard) message.Image(images.GetCardUrl(card), $"{card} "); message.Text($"({logic.Evaluate(game.DealerBoard)}). "); logic.CheckSplit(game.PlayerBoards[0].Board, message); } message.Send(); }
public override void ExecuteCommand(IChatChannel channel, StreamCommand command) { BlackJackGame game = blackjack.GetGame(command.Service, command.User); if (game == null) { SendMessage(channel, command.User, "There is no active black jack game. Start another one with !bj <bet>"); return; } if (!logic.IsSplitPossible(game.PlayerBoards[game.ActiveBoard].Board)) { SendMessage(channel, command.User, "A split is not possible on the current hand."); return; } int bet = game.PlayerBoards[game.ActiveBoard].Bet; if (bet > playermodule.GetPlayerGold(game.PlayerID)) { SendMessage(channel, command.User, "You don't have enough gold to split the hand."); return; } playermodule.UpdateGold(game.PlayerID, -bet); game.PlayerBoards.Add(new BlackJackBoard { Bet = bet, Board = new Board(game.PlayerBoards[game.ActiveBoard].Board[1]) }); game.PlayerBoards[game.ActiveBoard].Board = game.PlayerBoards[game.ActiveBoard].Board.ChangeCard(1, game.Stack.Pop()); RPGMessageBuilder message = messages.Create(); message.User(game.PlayerID).Text(" current hand is "); foreach (Card card in game.PlayerBoards[game.ActiveBoard].Board) { message.Image(images.GetCardUrl(card), $"{card} "); } int value = logic.Evaluate(game.PlayerBoards[game.ActiveBoard].Board); message.Text($"({value}). "); while (value == 21 || (game.ActiveBoard < game.PlayerBoards.Count && game.PlayerBoards[game.ActiveBoard].Board[0].Rank == CardRank.Ace)) { ++game.ActiveBoard; if (game.ActiveBoard >= game.PlayerBoards.Count) { message.Text(" All hands are played."); logic.PlayoutDealer(game, message, playermodule, images); value = 0; } else { if (game.PlayerBoards[game.ActiveBoard].Board.Count == 0) { game.PlayerBoards[game.ActiveBoard].Board += game.Stack.Pop(); } message.User(game.PlayerID).Text(" next hand is "); foreach (Card card in game.PlayerBoards[0].Board) { message.Image(images.GetCardUrl(card), $"{card} "); } value = logic.Evaluate(game.PlayerBoards[game.ActiveBoard].Board); message.Text($"({value}). "); } } if (value > 0) { logic.CheckSplit(game.PlayerBoards[game.ActiveBoard].Board, message); } message.Send(); }
public void Buy(string service, string channel, string username, string[] arguments) { int argumentindex = 0; int quantity = arguments.RecognizeQuantity(ref argumentindex); if (arguments.Length <= argumentindex) { context.GetModule <StreamModule>().SendMessage(service, channel, username, "You have to specify the name of the item to buy."); return; } Item item = context.GetModule <ItemModule>().RecognizeItem(arguments, ref argumentindex); if (item == null) { context.GetModule <StreamModule>().SendMessage(service, channel, username, "I don't understand what exactly you want to buy."); return; } if (quantity == -1) { quantity = 1; } if (quantity <= 0) { context.GetModule <StreamModule>().SendMessage(service, channel, username, $"It wouldn't make sense to buy {item.GetCountName(quantity)}."); return; } bool insulted = messageevaluator.HasInsult(arguments, argumentindex); User user = context.GetModule <UserModule>().GetExistingUser(service, username); Player player = context.GetModule <PlayerModule>().GetPlayer(service, username); double discount = GetDiscount(context.GetModule <SkillModule>().GetSkillLevel(player.UserID, SkillType.Haggler)); if (insulted) { discount -= 0.2; } int price; if (item.Type == ItemType.Special) { price = GetSpecialPriceToBuy(item.Value, discount); } else { ShopItem shopitem = context.Database.LoadEntities <ShopItem>().Where(i => i.ItemID == item.ID).Execute().FirstOrDefault(); if (shopitem == null || shopitem.Quantity < quantity) { if (travelingmerchant != null && travelingmerchant.Type == item.Type) { if (item.LevelRequirement > player.Level && !insulted) { context.GetModule <StreamModule>().SendMessage(service, channel, username, $"The merchant denies you access to the item as you wouldn't be able to use it. (Level {item.LevelRequirement})"); return; } BuyFromTravelingMerchant(service, channel, username, player, item, quantity, discount); return; } if (shopitem == null || shopitem.Quantity == 0) { context.GetModule <StreamModule>().SendMessage(service, channel, username, "The shopkeeper tells you that he has nothing on stock."); } else { context.GetModule <StreamModule>().SendMessage(service, channel, username, $"The shopkeeper tells you that he only has {item.GetCountName(shopitem.Quantity)}."); } return; } if (!insulted) { if (Mood < 0.5) { context.GetModule <StreamModule>().SendMessage(service, channel, username, "The shopkeeper does not see a point in doing anything anymore."); return; } if (context.Database.Load <ShopQuirk>(DBFunction.Count).Where(q => q.Type == ShopQuirkType.Phobia && q.ID == item.ID).ExecuteScalar <int>() > 0) { context.GetModule <RPGMessageModule>().Create().ShopKeeper().Text(" tells ").User(user).Text(" that no one should mess with ").ItemMultiple(item).Text(" since it is devil's work.").Send(); return; } if (context.Database.Load <ShopQuirk>(DBFunction.Count).Where(q => q.Type == ShopQuirkType.Nerd && q.ID == item.ID).ExecuteScalar <int>() > 0) { context.GetModule <RPGMessageModule>().Create().ShopKeeper().Text(" does not want to share his beloved ").ItemMultiple(item).Text(".").Send(); return; } if (context.Database.Load <ShopQuirk>(DBFunction.Count).Where(q => q.Type == ShopQuirkType.Grudge && q.ID == player.UserID).ExecuteScalar <int>() > 0) { context.GetModule <RPGMessageModule>().Create().ShopKeeper().Text(" casually ignores ").User(user).Text(".").Send(); return; } } if (item.LevelRequirement > player.Level && !insulted) { context.GetModule <StreamModule>().SendMessage(service, channel, username, $"The shopkeeper denies you access to the item as you wouldn't be able to use it. (Level {item.LevelRequirement})"); return; } price = (int)(item.Value * quantity * (1.0 + GetQuantityFactor(shopitem.Quantity) * 2 - discount) * shopitem.Discount); } if (price > player.Gold) { context.GetModule <StreamModule>().SendMessage(service, channel, username, $"Sadly you don't have enough gold. You would need {price} gold to buy {item.GetCountName(quantity)}"); return; } AddInventoryItemResult result = context.GetModule <InventoryModule>().AddItem(player.UserID, item.ID, quantity); switch (result) { case AddInventoryItemResult.Success: case AddInventoryItemResult.SuccessFull: Aggregate agg = Aggregate.Max(Constant.Create(0), EntityField.Create <Player>(pl => pl.Gold)); context.Database.Update <Player>().Set(p => p.Gold == agg.Int - price).Where(p => p.UserID == player.UserID).Execute(); if (item.Type != ItemType.Special) { context.Database.Update <ShopItem>().Set(i => i.Quantity == i.Quantity - quantity).Where(i => i.ItemID == item.ID).Execute(); } RPGMessageBuilder message = context.GetModule <RPGMessageModule>().Create(); message.User(user).Text(" has bought ").Item(item, quantity).Text(" from ").ShopKeeper().Text(" for ").Gold(price).Text("."); if (result == AddInventoryItemResult.SuccessFull) { message.User(user).Text(" is now encumbered."); } message.Send(); Mood += 0.05 * (1.0 - discount); break; case AddInventoryItemResult.InventoryFull: context.GetModule <RPGMessageModule>().Create().User(user).Text(" carries to much to buy ").Item(item, quantity).Text(".").Send(); break; } }
public override void ExecuteCommand(IChatChannel channel, StreamCommand command) { long userid = playermodule.GetPlayer(command.Service, command.User).UserID; HoldemGame game = casino.GetGame(userid); if (game != null) { SendMessage(channel, command.User, "You are already active in a holdem game. Use !fold to fold your hand or !call to stay active in the game."); return; } int bet; if (command.Arguments.Length == 0) { bet = 1; } else { int.TryParse(command.Arguments[0], out bet); } if (bet <= 0) { SendMessage(channel, command.User, $"{command.Arguments[0]} is no valid bet"); return; } int gold = playermodule.GetPlayerGold(userid); if (bet > 1 && bet > gold) { SendMessage(channel, command.User, "You can't bet more than you have."); return; } int maxbet = playermodule.GetLevel(userid) * 10; if (bet > maxbet) { SendMessage(channel, command.User, $"On your level you're only allowed to bet up to {maxbet} gold."); return; } // allow the player to play for one gold even if he has no gold if (gold > 0) { playermodule.UpdateGold(userid, -bet); } game = casino.CreateGame(userid, bet); game.Deck.Shuffle(); game.PlayerHand += game.Deck.Pop(); game.DealerHand += game.Deck.Pop(); game.PlayerHand += game.Deck.Pop(); game.DealerHand += game.Deck.Pop(); game.Muck.Push(game.Deck.Pop()); for (int i = 0; i < 3; ++i) { game.Board += game.Deck.Pop(); } RPGMessageBuilder message = messagemodule.Create(); message.Text("You have "); foreach (Card card in game.PlayerHand) { message.Image(imagemodule.GetCardUrl(card), $"{card} "); } message.Text(". The board shows "); foreach (Card card in game.Board) { message.Image(imagemodule.GetCardUrl(card), $"{card} "); } HandEvaluation evaluation = HandEvaluator.Evaluate(game.Board + game.PlayerHand); message.Text($" ({evaluation})").Send(); }
void CreateFreeInsult(string service, string user) { RPGMessageBuilder response = context.GetModule <RPGMessageModule>().Create(); response.ShopKeeper(); int mode = 0; switch (RNG.XORShift64.NextInt(21)) { case 0: response.Text(" points out that "); break; case 1: response.Text(" thinks "); break; case 2: response.Text(" imagines "); break; case 3: response.Text(" declares "); break; case 4: response.Text(" says "); break; case 5: response.Text(" feels like "); break; case 6: response.Text(" exposes his "); mode = 1; break; case 7: response.Text(" decides "); break; case 8: response.Text(" exclaims "); break; case 9: response.Text(" pontificates "); break; case 10: response.Text(" knows "); break; case 11: response.Text(" realizes "); break; case 12: response.Text(" has come to understand "); break; case 13: response.Text(" reached the conclusion "); break; case 14: response.Text(" summarizes "); break; case 15: response.Text(" sums up that "); break; case 16: response.Text(" distills "); break; case 17: response.Text(" has proven "); mode = 2; break; case 18: response.Text(" demonstrates his "); mode = 1; break; case 19: response.Text(" arranges a "); mode = 3; break; case 20: response.Text(" research finds "); mode = 2; break; } if (mode != 1 && mode != 3) { response.User(context.GetModule <UserModule>().GetUser(service, user)); switch (RNG.XORShift64.NextInt(5)) { case 0: response.Text("'s mother"); break; case 1: response.Text("'s father"); break; } } string insult; switch (mode) { default: case 0: insult = factory.CreateInsult(); response.Text($" is {(insult.StartsWithVocal() ? "an" : "a")} ").Text(insult); break; case 1: response.Text(factory.CreateInsult()).Text(" to ").User(context.GetModule <UserModule>().GetUser(service, user)); break; case 2: insult = factory.CreateInsult(); response.Text($" to be {(insult.StartsWithVocal() ? "an" : "a")} ").Text(insult); break; case 3: response.Text(factory.CreateInsult()).Text(" for ").User(context.GetModule <UserModule>().GetUser(service, user)); break; } response.Send(); }
public void UseItem(string channel, User user, Player player, Item item, params string[] arguments) { if (player.CurrentHP == 0) { context.GetModule <StreamModule>().SendMessage(user.Service, channel, user.Name, "I am terribly sorry to inform you that you died quite a while ago."); return; } if (!RemoveItem(player.UserID, item.ID, 1)) { context.GetModule <StreamModule>().SendMessage(user.Service, channel, user.Name, $"And you are absolutely sure {item.GetEnumerationName()} is in your possession?."); return; } if (!string.IsNullOrEmpty(item.Command)) { string[] commandarguments = item.Command.Split(' ').ToArray(); IModule module = context.GetModuleByKey <IModule>(commandarguments[0]); if (module == null) { Logger.Error(this, $"Invalid command in item {item.Name}.", $"Module '{commandarguments[0]}' not found."); } else if (!(module is IItemCommandModule) && !(module is ICommandModule)) { Logger.Error(this, $"Invalid command in item {item.Name}.", $"Module '{commandarguments[0]}' is not able to execute commands."); } else { try { if (module is IItemCommandModule) { ((IItemCommandModule)module).ExecuteItemCommand(user, player, commandarguments[1], commandarguments.Skip(2).Concat(arguments).ToArray()); } else { ((ICommandModule)module).ProcessCommand(commandarguments[1], new[] { user.Service, user.Name }.Concat(commandarguments.Skip(2)).Concat(arguments).ToArray()); } } catch (ItemUseException e) { context.GetModule <StreamModule>().SendMessage(user.Service, channel, user.Name, e.Message); Logger.Warning(this, e.Message); AddItem(player.UserID, item.ID, 1, true); } catch (Exception e) { Logger.Error(this, $"Error executing item command of item '{item.Name}'.", e); context.GetModule <StreamModule>().SendMessage(user.Service, channel, user.Name, "Something went wrong when using the item."); AddItem(player.UserID, item.ID, 1, true); return; } } } if (!string.IsNullOrEmpty(item.CommandMessage)) { new ItemUseContext(context.GetModule <RPGMessageModule>().Create(), user, item).Send(item.CommandMessage); } if (item.Type != ItemType.Consumable && item.Type != ItemType.Potion) { return; } RPGMessageBuilder message = context.GetModule <RPGMessageModule>().Create(); bool critical = RNG.XORShift64.NextFloat() < (float)player.Luck / Math.Max(1, item.UsageOptimum); int hp = Math.Min(item.HP * (critical ? 2 : 1), player.MaximumHP - player.CurrentHP); int mp = Math.Min(item.MP * (critical ? 2 : 1), player.MaximumMP - player.CurrentMP); message.User(user).Text(item.IsFluid ? " drinks " : " eats ").ItemUsage(item, critical); if (hp > 0 || mp > 0) { player.CurrentHP = Math.Min(player.CurrentHP + hp, player.MaximumHP); player.CurrentMP = Math.Min(player.CurrentMP + mp, player.MaximumMP); context.GetModule <PlayerModule>().UpdateRunningStats(player.UserID, player.CurrentHP, player.CurrentMP); message.Text(" and regenerates "); if (hp > 0) { message.Color(AdventureColors.Health).Text($"{hp} HP").Reset(); } if (mp > 0) { if (hp > 0) { message.Text(" and "); } message.Color(AdventureColors.Mana).Text($"{mp} MP").Reset(); } message.Text("."); } else { message.Text(string.IsNullOrEmpty(item.Command) ? " for no reason." : "."); } player.Pee += item.Pee; player.Poo += item.Poo; player.Vomit += item.Pee + item.Poo; bool pee = player.Pee > 100; bool poo = player.Poo > 100; bool vomit = player.Vomit > 100; if (pee || poo || vomit) { message.Text(" Proudly ").User(user).Text(" produces "); if (player.Poo >= 100) { player.Poo -= 100; Item pooitem = context.GetModule <ItemModule>().GetItem("Poo"); message.Text(" a pile of ").Item(pooitem); context.GetModule <InventoryModule>().AddItem(player.UserID, pooitem.ID, 1, true); } if (player.Pee >= 100) { if (poo) { message.Text(vomit ? ", " : " and "); } player.Pee -= 100; Item peeitem = context.GetModule <ItemModule>().GetItem("Pee"); message.Text(" a puddle of ").Item(peeitem); context.GetModule <InventoryModule>().AddItem(player.UserID, peeitem.ID, 1, true); } if (player.Vomit >= 100) { player.Vomit -= 100; if (pee || poo) { message.Text(" and "); } Item vomititem = context.GetModule <ItemModule>().GetItem("Vomit"); message.Text(" an accumulation of finest ").Item(vomititem); context.GetModule <InventoryModule>().AddItem(player.UserID, vomititem.ID, 1, true); } message.Text("."); } message.Send(); context.GetModule <PlayerModule>().UpdatePeeAndPoo(player.UserID, player.Pee, player.Poo, player.Vomit); }
public override void ExecuteCommand(IChatChannel channel, StreamCommand command) { VideoPokerGame game = pokermodule.GetGame(command.Service, command.User); long userid = playermodule.GetPlayer(command.Service, command.User).UserID; HandEvaluation evaluation; if (game == null) { if(command.Arguments.Length == 0) { SendMessage(channel, command.User, "You have to specify a bet amount"); return; } int bet; int.TryParse(command.Arguments[0], out bet); if(bet <= 0) { SendMessage(channel, command.User, $"{command.Arguments[0]} is no valid bet"); return; } if (bet > playermodule.GetPlayerGold(userid)) { SendMessage(channel, command.User, "You can't bet more than you have."); return; } int maxbet = playermodule.GetLevel(userid) * 10; if (bet > maxbet) { SendMessage(channel, command.User, $"On your level you're only allowed to bet up to {maxbet} gold."); return; } game = pokermodule.CreateGame(command.Service, command.User, bet); game.IsMaxBet = bet == maxbet; game.Deck.Shuffle(); for(int i = 0; i < 5; ++i) game.Hand += game.Deck.Pop(); RPGMessageBuilder message = messagemodule.Create(); message.User(userid).Text(" has "); foreach(Card card in game.Hand) message.Image(imagemodule.GetCardUrl(card), $"{card} "); evaluation = HandEvaluator.Evaluate(game.Hand); message.Text($"({evaluation})").Send(); } else { RPGMessageBuilder message = messagemodule.Create(); if(command.Arguments.Length > 0) { int redraw = 0; foreach(string argument in command.Arguments) { if(argument.All(c => char.IsDigit(c))) { int index = int.Parse(argument); if(index < 1 || index > 5) { SendMessage(channel, command.User, $"{index} is not a valid slot to redraw"); return; } redraw |= 1 << (index - 1); } else if(argument.ToLower() == "all") { redraw |= 31; } else { int index = game.Hand.IndexOf(c => c.ToString().ToLower() == argument.ToLower()); if(index == -1) { SendMessage(channel, command.User, $"{argument} points not to a card in your hand"); return; } redraw |= 1 << index; } } int cards = 0; for(int i = 0; i < 5; ++i) { if((redraw & (1 << i)) != 0) { game.Hand = game.Hand.ChangeCard(i, game.Deck.Pop()); ++cards; } } message.User(userid).Text($" is redrawing {cards} cards. "); foreach (Card card in game.Hand) message.Image(imagemodule.GetCardUrl(card), $"{card} "); evaluation = HandEvaluator.Evaluate(game.Hand); message.Text($"({evaluation})."); } else { evaluation = HandEvaluator.Evaluate(game.Hand); message.User(userid).Text(" is satisfied with the hand."); } int multiplicator = GetMultiplicator(evaluation, game.IsMaxBet); if(multiplicator == 0) message.Text(" ").ShopKeeper().Text(" laughs about that shitty hand."); else { int payout = game.Bet * multiplicator; playermodule.UpdateGold(userid, payout); message.Text(" Payout is ").Gold(payout); } message.Send(); pokermodule.RemoveGame(command.Service, command.User); } }
public ItemUseContext(RPGMessageBuilder message, User user, Item item) { this.message = message; this.user = user; this.item = item; }