diff --git a/content/index.md b/content/index.md index 9b1a613..d2f9188 100644 --- a/content/index.md +++ b/content/index.md @@ -8,7 +8,7 @@ 点击下面的骰子来掷骰: -:md-dice[2d6] +:md-dice[2d6] :md-dice[{d4, d8}] :md-dice[3d6kh1] :md-dice[3d6dl2-1] diff --git a/src/App.tsx b/src/App.tsx index 451875e..bbf8c97 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -42,8 +42,8 @@ const App: Component = () => {

TTRPG Tools

-
-
+
+
); diff --git a/src/components/md-dice.tsx b/src/components/md-dice.tsx index bdc7dea..d2c03c2 100644 --- a/src/components/md-dice.tsx +++ b/src/components/md-dice.tsx @@ -1,129 +1,11 @@ import { customElement, noShadowDOM } from "solid-element"; import { createSignal, onMount } from "solid-js"; +import {rollFormula} from "./md-commander/hooks"; export interface DiceProps { key?: string; } -interface RollResult { - total: number; - rolls: number[]; - detail: string; -} - -function rollDice(formula: string): RollResult { - const allRolls: number[] = []; - let total = 0; - const details: string[] = []; - - // 解析骰子公式,支持 + 和 - 运算符 - // 先按 + 和 - 分割,但保留运算符 - const tokens = formula - .split(/([+-])/) - .map((t) => t.trim()) - .filter((t) => t.length > 0); - - let sign = 1; - - for (let i = 0; i < tokens.length; i++) { - const token = tokens[i]; - - if (token === "+") { - sign = 1; - continue; - } - if (token === "-") { - sign = -1; - continue; - } - - // 处理 kh/kl/dh/dl 运算符 - let processedToken = token; - let keepHigh = false; - let keepLow = false; - let dropHigh = false; - let dropLow = false; - let keepCount = 0; - let dropCount = 0; - - const khMatch = token.match(/^(.+?)kh(\d+)$/i); - const klMatch = token.match(/^(.+?)kl(\d+)$/i); - const dhMatch = token.match(/^(.+?)dh(\d+)$/i); - const dlMatch = token.match(/^(.+?)dl(\d+)$/i); - - if (khMatch) { - processedToken = khMatch[1]; - keepHigh = true; - keepCount = parseInt(khMatch[2]); - } else if (klMatch) { - processedToken = klMatch[1]; - keepLow = true; - keepCount = parseInt(klMatch[2]); - } else if (dhMatch) { - processedToken = dhMatch[1]; - dropHigh = true; - dropCount = parseInt(dhMatch[2]); - } else if (dlMatch) { - processedToken = dlMatch[1]; - dropLow = true; - dropCount = parseInt(dlMatch[2]); - } - - const match = processedToken.match(/^(\d+)?d(\d+)$/i); - if (match) { - const count = parseInt(match[1] || "1"); - const sides = parseInt(match[2]); - const rolls: number[] = []; - - for (let j = 0; j < count; j++) { - rolls.push(Math.floor(Math.random() * sides) + 1); - } - - let processedRolls = [...rolls]; - let detail = `${count}d${sides}`; - - // 处理 keep/drop 运算符 - if (keepHigh || keepLow || dropHigh || dropLow) { - const sorted = [...processedRolls].sort((a, b) => a - b); - - if (dropHigh && dropCount > 0) { - processedRolls = sorted.slice(0, sorted.length - dropCount); - detail += `d${dropCount}h`; - } else if (dropLow && dropCount > 0) { - processedRolls = sorted.slice(dropCount); - detail += `d${dropCount}l`; - } else if (keepHigh && keepCount > 0) { - processedRolls = sorted.slice(-keepCount); - detail += `kh${keepCount}`; - } else if (keepLow && keepCount > 0) { - processedRolls = sorted.slice(0, keepCount); - detail += `kl${keepCount}`; - } - } - - const partTotal = processedRolls.reduce((a, b) => a + b, 0); - total += sign * partTotal; - allRolls.push(...processedRolls); - details.push( - `${detail}=[${processedRolls.join(",")}]${sign < 0 ? " (负)" : ""}`, - ); - } else { - // 处理固定数字 - const num = parseInt(token); - if (!isNaN(num)) { - total += sign * num; - details.push(`${num}${sign < 0 ? " (负)" : ""}`); - } - } - } - - return { - total, - rolls: allRolls, - detail: details.join(" + "), - }; -} - // 从 URL 参数获取骰子结果 function getDiceResultFromUrl(key: string): number | null { if (typeof window === "undefined") return null; @@ -174,7 +56,7 @@ customElement("md-dice", { key: "" }, (props, { element }) => { const handleRoll = () => { // 点击骰子图标:总是重 roll - const rollResult = rollDice(formula); + const rollResult = rollFormula(formula).result; setResult(rollResult.total); setRollDetail(rollResult.detail); setIsRolled(true);