Rewrite the !dice command from scratch
This commit is contained in:
parent
d7e313c9fa
commit
6d44960867
13 changed files with 376 additions and 126 deletions
107
Geekbot.net/Commands/Utils/Dice.cs
Normal file
107
Geekbot.net/Commands/Utils/Dice.cs
Normal file
|
@ -0,0 +1,107 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using Geekbot.net.Lib.DiceParser;
|
||||
using Geekbot.net.Lib.ErrorHandling;
|
||||
|
||||
namespace Geekbot.net.Commands.Utils
|
||||
{
|
||||
public class Dice : ModuleBase
|
||||
{
|
||||
private readonly IErrorHandler _errorHandler;
|
||||
private readonly IDiceParser _diceParser;
|
||||
|
||||
public Dice(IErrorHandler errorHandler, IDiceParser diceParser)
|
||||
{
|
||||
_errorHandler = errorHandler;
|
||||
_diceParser = diceParser;
|
||||
}
|
||||
|
||||
// ToDo: Separate representation and logic
|
||||
// ToDo: Translate
|
||||
[Command("dice", RunMode = RunMode.Async)]
|
||||
[Summary("Roll a dice. (use '!dice help' for a manual)")]
|
||||
public async Task RollCommand([Remainder] [Summary("input")] string diceInput = "1d20")
|
||||
{
|
||||
try
|
||||
{
|
||||
if (diceInput == "help")
|
||||
{
|
||||
await ShowDiceHelp();
|
||||
return;
|
||||
}
|
||||
|
||||
var parsed = _diceParser.Parse(diceInput);
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine($"{Context.User.Mention} :game_die:");
|
||||
foreach (var die in parsed.Dice)
|
||||
{
|
||||
sb.AppendLine($"**{die.DiceName}**");
|
||||
var diceResultList = new List<string>();
|
||||
var total = 0;
|
||||
|
||||
foreach (var roll in die.Roll())
|
||||
{
|
||||
diceResultList.Add(roll.ToString());
|
||||
total += roll.Result;
|
||||
}
|
||||
|
||||
sb.AppendLine(string.Join(" | ", diceResultList));
|
||||
|
||||
if (parsed.SkillModifier != 0)
|
||||
{
|
||||
sb.AppendLine($"Skill: {parsed.SkillModifier}");
|
||||
}
|
||||
|
||||
if (parsed.Options.ShowTotal)
|
||||
{
|
||||
var totalLine = $"Total: {total}";
|
||||
if (parsed.SkillModifier > 0)
|
||||
{
|
||||
totalLine += ($" (+{parsed.SkillModifier} = {total + parsed.SkillModifier})");
|
||||
}
|
||||
|
||||
if (parsed.SkillModifier < 0)
|
||||
{
|
||||
totalLine += ($" ({parsed.SkillModifier} = {total - parsed.SkillModifier})");
|
||||
}
|
||||
|
||||
sb.AppendLine(totalLine);
|
||||
}
|
||||
}
|
||||
|
||||
await Context.Channel.SendMessageAsync(sb.ToString());
|
||||
}
|
||||
catch (DiceException e)
|
||||
{
|
||||
await Context.Channel.SendMessageAsync($"**:warning: {e.DiceName} is invalid:** {e.Message}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await _errorHandler.HandleCommandException(e, Context);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ShowDiceHelp()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("**__Examples__**");
|
||||
sb.AppendLine("```");
|
||||
sb.AppendLine("'!dice' - throw a 1d20");
|
||||
sb.AppendLine("'!dice 1d12' - throw a 1d12");
|
||||
sb.AppendLine("'!dice +1d20' - throw with advantage");
|
||||
sb.AppendLine("'!dice -1d20' - throw with disadvantage");
|
||||
sb.AppendLine("'!dice 1d20 +2' - throw with a +2 skill bonus");
|
||||
sb.AppendLine("'!dice 1d20 -2' - throw with a -2 skill bonus");
|
||||
sb.AppendLine("'!dice 8d6' - throw ~~a fireball~~ a 8d6");
|
||||
sb.AppendLine("'!dice 8d6 total' - calculate the total");
|
||||
sb.AppendLine("'!dice 2d20 6d6 2d4 2d12' - drop your dice pouch");
|
||||
sb.AppendLine("```");
|
||||
|
||||
await Context.Channel.SendMessageAsync(sb.ToString());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,116 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using Geekbot.net.Lib.RandomNumberGenerator;
|
||||
|
||||
namespace Geekbot.net.Commands.Utils.Dice
|
||||
{
|
||||
public class Dice : ModuleBase
|
||||
{
|
||||
private readonly IRandomNumberGenerator _randomNumberGenerator;
|
||||
|
||||
public Dice(IRandomNumberGenerator randomNumberGenerator)
|
||||
{
|
||||
_randomNumberGenerator = randomNumberGenerator;
|
||||
}
|
||||
|
||||
[Command("dice", RunMode = RunMode.Async)]
|
||||
[Summary("Roll a dice.")]
|
||||
public async Task RollCommand([Remainder] [Summary("dice-type")] string diceType = "1d20")
|
||||
{
|
||||
var splitedDices = diceType.Split("+");
|
||||
var dices = new List<DiceTypeDto>();
|
||||
var mod = 0;
|
||||
foreach (var i in splitedDices)
|
||||
{
|
||||
var dice = ToDice(i);
|
||||
if (dice.Sides != 0 && dice.Times != 0)
|
||||
{
|
||||
dices.Add(dice);
|
||||
}
|
||||
else if (dice.Mod != 0)
|
||||
{
|
||||
if (mod != 0)
|
||||
{
|
||||
await ReplyAsync("You can only have one mod");
|
||||
return;
|
||||
}
|
||||
|
||||
mod = dice.Mod;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dices.Any())
|
||||
{
|
||||
await ReplyAsync(
|
||||
"That is not a valid dice, examples are: 1d20, 1d6, 2d6, 1d6+2, 1d6+2d8+1d20+6, etc...");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (dices.Any(d => d.Times > 20))
|
||||
{
|
||||
await ReplyAsync("You can't throw more than 20 dices");
|
||||
return;
|
||||
}
|
||||
|
||||
if (dices.Any(d => d.Sides > 144))
|
||||
{
|
||||
await ReplyAsync("A dice can't have more than 144 sides");
|
||||
return;
|
||||
}
|
||||
|
||||
var rep = new StringBuilder();
|
||||
rep.AppendLine($":game_die: {Context.User.Mention}");
|
||||
rep.Append("**Result:** ");
|
||||
var resultStrings = new List<string>();
|
||||
var total = 0;
|
||||
foreach (var dice in dices)
|
||||
{
|
||||
var results = new List<int>();
|
||||
for (var i = 0; i < dice.Times; i++)
|
||||
{
|
||||
var roll = _randomNumberGenerator.Next(1, dice.Sides);
|
||||
total += roll;
|
||||
results.Add(roll);
|
||||
}
|
||||
|
||||
resultStrings.Add($"{dice.DiceType} ({string.Join(",", results)})");
|
||||
}
|
||||
|
||||
rep.Append(string.Join(" + ", resultStrings));
|
||||
if (mod != 0)
|
||||
{
|
||||
rep.Append($" + {mod}");
|
||||
total += mod;
|
||||
}
|
||||
|
||||
rep.AppendLine();
|
||||
rep.AppendLine($"**Total:** {total}");
|
||||
await ReplyAsync(rep.ToString());
|
||||
}
|
||||
|
||||
private DiceTypeDto ToDice(string dice)
|
||||
{
|
||||
var diceParts = dice.Split('d');
|
||||
if (diceParts.Length == 2
|
||||
&& int.TryParse(diceParts[0], out var times)
|
||||
&& int.TryParse(diceParts[1], out var max))
|
||||
return new DiceTypeDto
|
||||
{
|
||||
DiceType = dice,
|
||||
Times = times,
|
||||
Sides = max
|
||||
};
|
||||
if (dice.Length == 1
|
||||
&& int.TryParse(diceParts[0], out var mod))
|
||||
return new DiceTypeDto
|
||||
{
|
||||
Mod = mod
|
||||
};
|
||||
return new DiceTypeDto();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
namespace Geekbot.net.Commands.Utils.Dice
|
||||
{
|
||||
internal class DiceTypeDto
|
||||
{
|
||||
public string DiceType { get; set; }
|
||||
public int Times { get; set; }
|
||||
public int Sides { get; set; }
|
||||
public int Mod { get; set; }
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue