New source found from dndbeyond.com

This commit is contained in:
2026-07-08 01:00:09 -07:00
parent 9a983a6d7b
commit dcefa0d2f2
2865 changed files with 222467 additions and 49053 deletions
@@ -1,4 +1,5 @@
import * as React from "react";
import {
AbilityLookup,
Action,
@@ -12,23 +13,23 @@ import {
RuleData,
RuleDataUtils,
} from "@dndbeyond/character-rules-engine/es";
import {
Dice,
RollType,
DiceEvent,
RollKind,
IRollContext,
} from "@dndbeyond/dice";
import { GameLogContext } from "@dndbeyond/game-log-components";
import {
RollKinds,
RollTypes,
} from "@dndbeyond/pocket-dimension-dice/constants";
import { RollContext } from "@dndbeyond/pocket-dimension-dice/types";
import { NumberDisplay } from "~/components/NumberDisplay";
import ActionName from "../../ActionName";
import Damage from "../../Damage";
import { DigitalDiceWrapper } from "../../Dice";
import { AttackTypeIcon } from "../../Icons";
import NoteComponents from "../../NoteComponents";
import { DiceComponentUtils } from "../../utils";
import CombatAttack from "../CombatAttack";
import { CombatActionAttackComponentRangeInfo } from "./CombatActionAttackTypings";
import { DigitalDiceWrapper } from "../../Dice";
import Damage from "../../Damage";
interface Props {
attack: Attack;
@@ -40,7 +41,7 @@ interface Props {
className: string;
diceEnabled: boolean;
theme: CharacterTheme;
rollContext: IRollContext;
rollContext: RollContext;
proficiencyBonus: number;
}
@@ -48,6 +49,7 @@ interface State {
isCriticalHit: boolean;
}
class CombatActionAttack extends React.PureComponent<Props, State> {
private elementRef = React.createRef<React.ReactNode>();
diceEventHandler: (eventData: any) => void;
static defaultProps = {
@@ -64,17 +66,6 @@ class CombatActionAttack extends React.PureComponent<Props, State> {
};
}
componentDidMount = () => {
this.diceEventHandler = DiceComponentUtils.setupResetCritStateOnRoll(
ActionUtils.getName(this.props.attack.data as Action),
this
);
};
componentWillUnmount = () => {
Dice.removeEventListener(DiceEvent.ROLL, this.diceEventHandler);
};
handleClick = (): void => {
const { onClick, attack } = this.props;
@@ -107,7 +98,7 @@ class CombatActionAttack extends React.PureComponent<Props, State> {
if (longRange) {
rangeValueNode = (
<React.Fragment>
<>
<span
className={`ddbc-combat-attack__range-value-close ${
theme.isDarkMode
@@ -126,7 +117,7 @@ class CombatActionAttack extends React.PureComponent<Props, State> {
>
({longRange})
</span>
</React.Fragment>
</>
);
rangeLabel = "";
} else {
@@ -380,9 +371,6 @@ class CombatActionAttack extends React.PureComponent<Props, State> {
rollContext,
} = this.props;
const [{ messageTargetOptions, defaultMessageTargetOption, userId }] =
this.context;
const { isCriticalHit } = this.state;
const proficiency = ActionUtils.isProficient(action);
@@ -411,19 +399,18 @@ class CombatActionAttack extends React.PureComponent<Props, State> {
? damage.value.toString()
: DiceUtils.renderDice(damage.value)
}
rollType={RollType.Damage}
rollAction={ActionUtils.getName(attack.data as Action)}
rollKind={isCriticalHit ? RollKind.CriticalHit : RollKind.None}
diceEnabled={diceEnabled}
themeColor={theme.themeColor}
rollContext={rollContext}
rollTargetOptions={
messageTargetOptions
? Object.values(messageTargetOptions?.entities)
: undefined
}
rollTargetDefault={defaultMessageTargetOption}
userId={userId}
rollType={RollTypes.Damage}
action={ActionUtils.getName(attack.data as Action)}
rollKind={isCriticalHit ? RollKinds.CriticalHit : undefined}
isDiceEnabled={diceEnabled}
entityId={String(rollContext.entityId)}
entityType={String(rollContext.entityType)}
name={String(rollContext.name)}
rollCallback={() => {
if (isCriticalHit) {
this.setState({ isCriticalHit: false });
}
}}
>
<Damage
type={damage.type ? damage.type.name : null}
@@ -1,4 +1,5 @@
import * as React from "react";
import {
Action,
ActionUtils,
@@ -10,16 +11,17 @@ import {
SpellUtils,
} from "@dndbeyond/character-rules-engine/es";
import { AttackSourceTypeEnum } from "@dndbeyond/character-rules-engine/es/engine/Character";
import {
DiceTools,
RollType,
RollRequest,
IRollContext,
} from "@dndbeyond/dice";
import { GameLogContext } from "@dndbeyond/game-log-components";
import { DiceComponentUtils } from "../utils";
import { RollTypes } from "@dndbeyond/pocket-dimension-dice/constants";
import {
RollContext,
RollDicePayload,
} from "@dndbeyond/pocket-dimension-dice/types";
import { NumberDisplay } from "~/components/NumberDisplay";
import { DigitalDiceWrapper } from "../Dice";
import { DiceComponentUtils } from "../utils";
interface Props {
attack: Attack;
@@ -36,7 +38,7 @@ interface Props {
damage: React.ReactNode;
notes?: React.ReactNode;
theme: CharacterTheme;
rollContext: IRollContext;
rollContext: RollContext;
onClick?: (attack: Attack) => void;
showNotes: boolean;
@@ -65,7 +67,7 @@ class CombatAttack extends React.PureComponent<Props, {}> {
}
};
handleRollResults = (result: RollRequest) => {
handleRollResults = (result: RollDicePayload["data"]) => {
const { onRoll } = this.props;
let wasCrit = DiceComponentUtils.isCriticalRoll(result);
@@ -94,9 +96,6 @@ class CombatAttack extends React.PureComponent<Props, {}> {
rollContext,
} = this.props;
const [{ messageTargetOptions, defaultMessageTargetOption, userId }] =
this.context;
let actionNode: React.ReactNode = null;
if (toHit !== null) {
let rollAction: string;
@@ -116,26 +115,18 @@ class CombatAttack extends React.PureComponent<Props, {}> {
actionNode = (
<div className="ddbc-combat-attack__tohit">
<DigitalDiceWrapper
diceNotation={DiceTools.CustomD20(toHit)}
rollType={RollType.ToHit}
rollAction={rollAction}
diceEnabled={diceEnabled}
onRollResults={this.handleRollResults}
themeColor={theme.themeColor}
rollContext={rollContext}
rollTargetOptions={
messageTargetOptions
? Object.values(messageTargetOptions?.entities)
: undefined
}
rollTargetDefault={defaultMessageTargetOption}
userId={userId}
diceNotation={`1d20${
toHit > 0 ? `+${toHit}` : toHit !== 0 ? toHit : ""
}`}
rollType={RollTypes.ToHit}
action={rollAction}
isDiceEnabled={diceEnabled}
rollCallback={this.handleRollResults}
entityId={String(rollContext.entityId)}
entityType={String(rollContext.entityType)}
name={String(rollContext.name)}
>
<NumberDisplay
number={toHit}
type="signed"
isModified={false}
/>
<NumberDisplay number={toHit} type="signed" isModified={false} />
</DigitalDiceWrapper>
</div>
);
@@ -8,20 +8,19 @@ import {
DiceUtils,
FormatUtils,
Item,
ItemPlan,
ItemUtils,
RuleData,
RuleDataUtils,
WeaponSpellDamageGroup,
} from "@dndbeyond/character-rules-engine/es";
import {
Dice,
RollType,
DiceEvent,
RollKind,
IRollContext,
} from "@dndbeyond/dice";
import StarIcon from "@dndbeyond/fontawesome-cache/svgs/solid/star.svg";
import { GameLogContext } from "@dndbeyond/game-log-components";
import {
RollKinds,
RollTypes,
} from "@dndbeyond/pocket-dimension-dice/constants";
import { RollContext } from "@dndbeyond/pocket-dimension-dice/types";
import { ItemName } from "~/components/ItemName";
import { NumberDisplay } from "~/components/NumberDisplay";
@@ -45,14 +44,16 @@ interface Props {
className: string;
diceEnabled: boolean;
theme: CharacterTheme;
rollContext: IRollContext;
rollContext: RollContext;
proficiencyBonus: number;
itemPlans: Array<ItemPlan>;
}
interface State {
isCriticalHit: boolean;
}
class CombatItemAttack extends React.PureComponent<Props, State> {
private elementRef = React.createRef<React.ReactNode>();
diceEventHandler: (eventData: any) => void;
constructor(props: Props) {
@@ -69,17 +70,6 @@ class CombatItemAttack extends React.PureComponent<Props, State> {
diceEnabled: false,
};
componentDidMount = () => {
this.diceEventHandler = DiceComponentUtils.setupResetCritStateOnRoll(
ItemUtils.getName(this.props.attack.data as Item),
this
);
};
componentWillUnmount = () => {
Dice.removeEventListener(DiceEvent.ROLL, this.diceEventHandler);
};
handleClick = (): void => {
const { onClick, attack } = this.props;
@@ -97,6 +87,7 @@ class CombatItemAttack extends React.PureComponent<Props, State> {
showNotes,
proficiencyBonus,
theme,
itemPlans,
} = this.props;
if (!showNotes) {
@@ -111,7 +102,8 @@ class CombatItemAttack extends React.PureComponent<Props, State> {
weaponSpellDamageGroups,
ruleData,
abilityLookup,
proficiencyBonus
proficiencyBonus,
ItemUtils.getItemPlan(item, itemPlans)
)}
theme={theme}
/>
@@ -136,9 +128,6 @@ class CombatItemAttack extends React.PureComponent<Props, State> {
ruleData,
} = this.props;
const [{ messageTargetOptions, defaultMessageTargetOption, userId }] =
this.context;
const { isCriticalHit } = this.state;
const toHit = ItemUtils.getToHit(item);
@@ -219,19 +208,13 @@ class CombatItemAttack extends React.PureComponent<Props, State> {
versatileDamageNode = (
<DigitalDiceWrapper
diceNotation={DiceUtils.renderDice(versatileDamage)}
rollType={RollType.Damage}
rollAction={ItemUtils.getName(attack.data as Item)}
rollKind={isCriticalHit ? RollKind.CriticalHit : RollKind.None}
diceEnabled={diceEnabled}
themeColor={theme.themeColor}
rollContext={rollContext}
rollTargetOptions={
messageTargetOptions
? Object.values(messageTargetOptions?.entities)
: undefined
}
rollTargetDefault={defaultMessageTargetOption}
userId={userId}
rollType={RollTypes.Damage}
action={ItemUtils.getName(attack.data as Item)}
rollKind={isCriticalHit ? RollKinds.CriticalHit : undefined}
isDiceEnabled={diceEnabled}
entityId={String(rollContext.entityId)}
entityType={String(rollContext.entityType)}
name={String(rollContext.name)}
>
<Damage
damage={DiceComponentUtils.getDamageDiceNotation(
@@ -261,19 +244,18 @@ class CombatItemAttack extends React.PureComponent<Props, State> {
? damage.toString()
: DiceUtils.renderDice(damage)
}
rollType={RollType.Damage}
rollAction={ItemUtils.getName(attack.data as Item)}
rollKind={isCriticalHit ? RollKind.CriticalHit : RollKind.None}
diceEnabled={diceEnabled}
themeColor={theme.themeColor}
rollContext={rollContext}
rollTargetOptions={
messageTargetOptions
? Object.values(messageTargetOptions?.entities)
: undefined
}
rollTargetDefault={defaultMessageTargetOption}
userId={userId}
rollType={RollTypes.Damage}
action={ItemUtils.getName(attack.data as Item)}
rollKind={isCriticalHit ? RollKinds.CriticalHit : undefined}
isDiceEnabled={diceEnabled}
entityId={String(rollContext.entityId)}
entityType={String(rollContext.entityType)}
name={String(rollContext.name)}
rollCallback={() => {
if (isCriticalHit) {
this.setState({ isCriticalHit: false });
}
}}
>
<Damage
damage={DiceComponentUtils.getDamageDiceNotation(
@@ -303,7 +285,7 @@ class CombatItemAttack extends React.PureComponent<Props, State> {
let rangeLabel: React.ReactNode;
if (showRange) {
rangeValue = (
<React.Fragment>
<>
<span
className={`ddbc-combat-attack__range-value-close ${
theme.isDarkMode
@@ -324,7 +306,7 @@ class CombatItemAttack extends React.PureComponent<Props, State> {
({longRange})
</span>
)}
</React.Fragment>
</>
);
rangeLabel = "";
} else {
@@ -13,7 +13,7 @@ import {
RuleData,
CharacterTheme,
} from "@dndbeyond/character-rules-engine/es";
import { Dice, DiceEvent, IRollContext } from "@dndbeyond/dice";
import { RollContext } from "@dndbeyond/pocket-dimension-dice/types";
import { NumberDisplay } from "~/components/NumberDisplay";
import { SpellName } from "~/components/SpellName";
@@ -36,7 +36,7 @@ interface Props {
className: string;
diceEnabled: boolean;
theme: CharacterTheme;
rollContext: IRollContext;
rollContext: RollContext;
dataOriginRefData: DataOriginRefData;
proficiencyBonus: number;
}
@@ -49,6 +49,7 @@ export default class CombatSpellAttack extends React.PureComponent<
Props,
State
> {
private elementRef = React.createRef<React.ReactNode>();
diceEventHandler: (eventData: any) => void;
constructor(props: Props) {
@@ -65,17 +66,6 @@ export default class CombatSpellAttack extends React.PureComponent<
diceEnabled: false,
};
componentDidMount = () => {
this.diceEventHandler = DiceComponentUtils.setupResetCritStateOnRoll(
SpellUtils.getName(this.props.spell),
this
);
};
componentWillUnmount = () => {
Dice.removeEventListener(DiceEvent.ROLL, this.diceEventHandler);
};
handleClick = (): void => {
const { onClick, attack } = this.props;
@@ -220,7 +210,10 @@ export default class CombatSpellAttack extends React.PureComponent<
saveDcValue = attackSaveValue;
saveDcLabel = SpellUtils.getSaveDcAbilityShortName(spell, ruleData);
}
let attackClassNames: Array<string> = ["ddbc-combat-attack--spell", className];
let attackClassNames: Array<string> = [
"ddbc-combat-attack--spell",
className,
];
if (isCriticalHit) {
attackClassNames.push("ddbc-combat-attack--crit");
@@ -263,6 +256,11 @@ export default class CombatSpellAttack extends React.PureComponent<
theme={theme}
isCriticalHit={isCriticalHit}
rollContext={rollContext}
rollCallback={() => {
if (isCriticalHit) {
this.setState({ isCriticalHit: false });
}
}}
/>
}
onClick={this.handleClick}