Skip to content

Commit

Permalink
[foundryvtt#4790] Death save bonus and config
Browse files Browse the repository at this point in the history
  • Loading branch information
krbz999 committed Dec 10, 2024
1 parent 58c4548 commit 38808f6
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 2 deletions.
1 change: 1 addition & 0 deletions lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1371,6 +1371,7 @@
"DND5E.Dawn": "Dawn",
"DND5E.Day": "Day",
"DND5E.DeathSave": "Death Saves",
"DND5E.DeathSaveBonus": "Death Save Bonus",
"DND5E.DeathSaveCriticalSuccess": "{name} critically succeeded on a death saving throw and has regained 1 Hit Point!",
"DND5E.DeathSaveHide": "Hide Death Saves",
"DND5E.DeathSaveShow": "Show Death Saves",
Expand Down
7 changes: 6 additions & 1 deletion less/v2/character.less
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@
justify-content: center;
padding: 10px;
}

.pips .pip.filled.death::before {
content: "\f54c";
font-family: var(--font-awesome);
Expand Down Expand Up @@ -492,6 +492,11 @@
--icon-fill: var(--dnd5e-color-gold);
}

.fas {
color: var(--dnd5e-color-gold);
font-size: 32px;
}

&:hover {
background: none;
box-shadow: none;
Expand Down
4 changes: 4 additions & 0 deletions module/applications/actor/base-sheet.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import ActorSheetMixin from "./sheet-mixin.mjs";
import AbilityConfig from "./config/ability-config.mjs";
import ArmorClassConfig from "./config/armor-class-config.mjs";
import ConcentrationConfig from "./config/concentration-config.mjs";
import DeathConfig from "./config/death-config.mjs";
import DamagesConfig from "./config/damages-config.mjs";
import HitDiceConfig from "./config/hit-dice-config.mjs";
import HitPointsConfig from "./config/hit-points-config.mjs";
Expand Down Expand Up @@ -753,6 +754,9 @@ export default class ActorSheet5e extends ActorSheetMixin(ActorSheet) {
case "armor":
app = new ArmorClassConfig({ document: this.actor });
break;
case "death":
app = new DeathConfig({ document: this.actor });
break;
case "hitDice":
app = new HitDiceConfig({ document: this.actor });
break;
Expand Down
57 changes: 57 additions & 0 deletions module/applications/actor/config/death-config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import BaseConfigSheet from "../api/base-config-sheet.mjs";

/**
* Configuration application for an actor's concentration checks.
*/
export default class DeathConfig extends BaseConfigSheet {
/** @override */
static DEFAULT_OPTIONS = {
ability: null,
position: {
width: 500
}
};

/* -------------------------------------------- */

/** @override */
static PARTS = {
config: {
template: "systems/dnd5e/templates/actors/config/death-config.hbs"
}
};

/* -------------------------------------------- */
/* Properties */
/* -------------------------------------------- */

/** @override */
get title() {
return game.i18n.format("DND5E.ABILITY.Configure.Title", { ability: game.i18n.localize("DND5E.DeathSavingThrow") });
}

/* -------------------------------------------- */
/* Rendering */
/* -------------------------------------------- */

/** @inheritDoc */
async _preparePartContext(partId, context, options) {
context = await super._preparePartContext(partId, context, options);
const source = this.document.system._source;

context.data = source.attributes?.death ?? {};
context.fields = this.document.system.schema.getField("attributes.death").fields;
context.advantageModeOptions = [
{ value: -1, label: game.i18n.localize("DND5E.Disadvantage") },
{ value: 0, label: game.i18n.localize("DND5E.Normal") },
{ value: 1, label: game.i18n.localize("DND5E.Advantage") }
];

if ( this.document.system.bonuses?.abilities ) context.global = {
data: source.bonuses?.abilities ?? {},
fields: this.document.system.schema.getField("bonuses.abilities").fields
};

return context;
}
}
3 changes: 3 additions & 0 deletions module/data/actor/character.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ export default class CharacterData extends CreatureTemplate {
}),
failure: new NumberField({
required: true, nullable: false, integer: true, min: 0, initial: 0, label: "DND5E.DeathSaveFailures"
}),
bonuses: new SchemaField({
save: new FormulaField({ required: true, label: "DND5E.DeathSaveBonus" })
})
}, { label: "DND5E.DeathSave" }),
inspiration: new BooleanField({ required: true, label: "DND5E.Inspiration" })
Expand Down
3 changes: 3 additions & 0 deletions module/data/actor/npc.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ export default class NPCData extends CreatureTemplate {
}),
failure: new NumberField({
required: true, nullable: false, integer: true, min: 0, initial: 0, label: "DND5E.DeathSaveFailures"
}),
bonuses: new SchemaField({
save: new FormulaField({ required: true, label: "DND5E.DeathSaveBonus" })
})
}, {label: "DND5E.DeathSave"})
}, {label: "DND5E.Attributes"}),
Expand Down
5 changes: 4 additions & 1 deletion module/documents/actor/actor.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1757,7 +1757,7 @@ export default class Actor5e extends SystemDocumentMixin(Actor) {
*/
async rollDeathSave(config={}, dialog={}, message={}) {
let oldFormat = false;
const death = this.system.attributes.death;
const death = this.system.attributes?.death;
if ( !death ) throw new Error(`Actors of the type '${this.type}' don't support death saves.`);

// Handle deprecated config object
Expand Down Expand Up @@ -1794,6 +1794,9 @@ export default class Actor5e extends SystemDocumentMixin(Actor) {
data.prof = new Proficiency(this.system.attributes.prof, 1).term;
}

// Death save bonus
if ( death.bonuses.save ) parts.push(death.bonuses.save);

const initialRoll = config.rolls?.pop();
if ( initialRoll?.data ) data = { ...data, ...initialRoll.data };
if ( initialRoll?.parts ) parts.unshift(...initialRoll.parts);
Expand Down
6 changes: 6 additions & 0 deletions templates/actors/character-sheet-2.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -309,11 +309,17 @@
</div>

{{!-- Roll Death Save --}}
{{#if editable}}
<button type="button" class="death-save config-button unbutton" data-action="death">
<i class="fas fa-cog"></i>
</button>
{{else}}
<button type="button" data-action="rollDeathSave" data-tooltip="DND5E.DeathSaveRoll"
aria-label="{{ localize "DND5E.DeathSaveRoll" }}"
class="{{ rollableClass }} death-save unbutton">
<dnd5e-icon src="systems/dnd5e/icons/svg/statuses/dead.svg"></dnd5e-icon>
</button>
{{/if}}

{{!-- Failures --}}
<div class="pips" data-prop="system.attributes.death.failure">
Expand Down
34 changes: 34 additions & 0 deletions templates/actors/config/death-config.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<section class="flexcol">
{{!-- Death --}}
<fieldset class="card">
<legend>{{ localize "DND5E.DeathSave" }}</legend>
{{ formField fields.bonuses.fields.save value=data.bonuses.save localize=true rootId=partId }}
</fieldset>

{{!-- Rolls --}}
<fieldset class="card">
<legend>{{ localize "DND5E.ROLL.Section" label=(localize "DND5E.DeathSave") }}</legend>
{{ formField fields.roll.fields.mode value=data.roll.mode options=advantageModeOptions localize=true
rootId=partId }}
<div class="form-group split-group">
<label>{{ localize "DND5E.ROLL.Range.Label" }}</label>
<div class="form-fields">
{{ formField fields.roll.fields.min value=data.roll.min placeholder="1" type="number" localize=true
label=(localize "DND5E.Minimum") hint=false classes="label-top" rootId=partId }}
{{ formField fields.roll.fields.max value=data.roll.max placeholder="20" type="number" localize=true
label=(localize "DND5E.Maximum") hint=false classes="label-top" rootId=partId }}
</div>
</div>
</fieldset>

{{!-- Global Bonus --}}
{{#if global}}
<fieldset class="card">
<legend>{{ localize "DND5E.ABILITY.SECTIONS.Global.Label" }}</legend>
<div class="form-group">
<p class="hint">{{ localize "DND5E.ABILITY.SECTIONS.Global.Hint" }}</p>
</div>
{{ formField global.fields.save value=global.data.save localize=true rootId=partId }}
</fieldset>
{{/if}}
</section>

0 comments on commit 38808f6

Please sign in to comment.