@@ -29,20 +29,81 @@ def self.roll(*diceRolls)
2929 result
3030 end
3131
32+ # Formats the notation of the dice rolls.
33+ # Note: this does not actually reorder the dice rolls, it just formats them by removing
34+ # whitespace and ensuring the notation is valid.
35+ def self . format_notation ( *diceRolls )
36+ result = nil
37+ protect do
38+ context = v8
39+ result = context . call ( "formatNotation" , *diceRolls )
40+ end
41+ if result . is_a? ( Hash ) && result [ "type" ] == "error"
42+ raise Rollmaster ::DiceEngine ::RollError . new ( result [ "msg" ] )
43+ end
44+ result
45+ end
46+
3247 def self . attach_function ( ctx )
3348 ctx . eval <<~JS
3449 function roll(...diceRolls) {
3550 const roller = new rpgDiceRoller.DiceRoller;
3651 try {
3752 roller.roll(...diceRolls);
38- return JSON.parse(JSON.stringify(roller.log))
53+ return roller.log.map((r) => {
54+ const output = r.output;
55+ const start = output.lastIndexOf(': ');
56+ return output.substring(start + 2);
57+ });
58+ } catch (e) {
59+ return {
60+ type: "error",
61+ name: e.name,
62+ msg: e.message,
63+ };
64+ }
65+ }
66+
67+ function formatNotation(...diceRolls) {
68+ const parse = rpgDiceRoller.Parser.parse;
69+ const formatted = [];
70+ try {
71+ diceRolls.forEach((notation) => {
72+ const parsed = parse(notation);
73+ formatted.push(format(parsed));
74+ });
3975 } catch (e) {
4076 return {
4177 type: "error",
4278 name: e.name,
4379 msg: e.message,
4480 };
4581 }
82+ return formatted;
83+ }
84+
85+ function format(expressions) {
86+ removeDescription(expressions);
87+ return expressions
88+ .map((e) => {
89+ if (typeof e === "string" || typeof e === "number") {
90+ return e;
91+ }
92+ return e.notation;
93+ })
94+ .join("");
95+ }
96+
97+ function removeDescription(exp) {
98+ exp.forEach((e) => {
99+ if (typeof e === "object" && e.description) {
100+ e.description = null;
101+ if (e.expressions) {
102+ e.expressions.forEach((subExp) => removeDescription(subExp));
103+ }
104+ }
105+ });
106+ return exp;
46107 }
47108 JS
48109 end
0 commit comments