import * as React from "react"; import { Tooltip } from "@dndbeyond/character-common-components/es"; import { ConditionUtils, DiceUtils, HigherLevelContract, HigherLevelEntryContract, ModifierUtils, RuleData, RuleDataUtils, Spell, SpellConditionContract, SpellModifierContract, SpellUtils, CharacterTheme, } from "@dndbeyond/character-rules-engine/es"; import { RollType, RollKind, IRollContext } from "@dndbeyond/dice"; import { GameLogContext } from "@dndbeyond/game-log-components"; import { HealingIcon } from "../Icons"; import { DiceComponentUtils } from "../utils"; import { DigitalDiceWrapper } from "../Dice"; import Damage from "../Damage"; interface Props { spell: Spell; castLevel: number; characterLevel: number; ruleData: RuleData; diceEnabled: boolean; theme: CharacterTheme; isCriticalHit?: boolean; rollContext: IRollContext; } class SpellDamageEffect extends React.PureComponent { static defaultProps = { diceEnabled: false, }; getPoints = ( atHigherLevels: HigherLevelContract | null ): Array => { let points: Array = []; if (atHigherLevels && atHigherLevels.points !== null) { points = atHigherLevels.points; } return points; }; render() { const { spell, castLevel, characterLevel, ruleData, diceEnabled, theme, isCriticalHit, rollContext, } = this.props; const [{ messageTargetOptions, defaultMessageTargetOption, userId }] = this.context; let isScaled: boolean = false; const modifiers = SpellUtils.getModifiers(spell); const tags = SpellUtils.getTags(spell); const conditions = SpellUtils.getConditions(spell); let displayNode: React.ReactNode; let damageModifiers = modifiers.filter((modifier) => ModifierUtils.isSpellDamageModifier(modifier) ); if (damageModifiers.length) { let modifier: SpellModifierContract = damageModifiers[0]; const friendlySubtypeName = ModifierUtils.getFriendlySubtypeName(modifier); const atHigherLevels = ModifierUtils.getAtHigherLevels(modifier); let scaleType = SpellUtils.getScaleType(spell); let points = this.getPoints(atHigherLevels); let atHigherDamage = SpellUtils.getSpellScaledAtHigher( spell, scaleType, points, characterLevel, castLevel ); let scaledDamageDie = SpellUtils.getSpellFinalScaledDie( spell, modifier, atHigherDamage ); isScaled = isScaled || SpellUtils.isSpellScaledByCastLevel( spell, scaleType, points, castLevel ); displayNode = ( ); } let hitPointHealingModifiers = modifiers.filter((modifier) => ModifierUtils.isSpellHealingHitPointsModifier(modifier) ); if (!displayNode && hitPointHealingModifiers.length) { let modifier: SpellModifierContract = hitPointHealingModifiers[0]; const atHigherLevels = ModifierUtils.getAtHigherLevels(modifier); let scaleType = SpellUtils.getScaleType(spell); let points = this.getPoints(atHigherLevels); let atHigherHealing = SpellUtils.getSpellScaledAtHigher( spell, scaleType, points, characterLevel, castLevel ); let scaledHealingDie = SpellUtils.getSpellFinalScaledDie( spell, modifier, atHigherHealing, castLevel ); isScaled = isScaled || SpellUtils.isSpellScaledByCastLevel( spell, scaleType, points, castLevel ); displayNode = ( {DiceUtils.renderDice(scaledHealingDie)}{" "} ); } const tempHitPointHealingModifiers = modifiers.filter((modifier) => ModifierUtils.isSpellHealingTempHitPointsModifier(modifier) ); if (!displayNode && tempHitPointHealingModifiers.length) { let modifier = tempHitPointHealingModifiers[0]; const atHigherLevels = ModifierUtils.getAtHigherLevels(modifier); let scaleType = SpellUtils.getScaleType(spell); let points = this.getPoints(atHigherLevels); let atHigherHealing = SpellUtils.getSpellScaledAtHigher( spell, scaleType, points, characterLevel, castLevel ); let scaledHealingDie = SpellUtils.getSpellFinalScaledDie( spell, modifier, atHigherHealing, castLevel ); isScaled = isScaled || SpellUtils.isSpellScaledByCastLevel( spell, scaleType, points, castLevel ); displayNode = ( {DiceUtils.renderDice(scaledHealingDie)}{" "} ); } if (!displayNode && conditions.length) { let spellCondition: SpellConditionContract = conditions[0]; let condition = RuleDataUtils.getCondition( spellCondition.conditionId, ruleData ); let name: string = condition === null ? "" : ConditionUtils.getName(condition); displayNode = ( {name} ); } if (!displayNode && tags.length) { displayNode = ( {tags[0]} ); } let hasMore: boolean = damageModifiers.length > 1; hasMore = hasMore || hitPointHealingModifiers.length > 1; hasMore = hasMore || tempHitPointHealingModifiers.length > 1; hasMore = hasMore || conditions.length > 1; hasMore = hasMore || tags.length > 1; return (
{displayNode} {hasMore ? "*" : ""}
); } } SpellDamageEffect.contextType = GameLogContext; export default SpellDamageEffect;