Skip to content

Commit

Permalink
[#2220] Add SizeAdvancement
Browse files Browse the repository at this point in the history
  • Loading branch information
arbron committed Nov 1, 2023
1 parent 73a7185 commit e6e31c3
Show file tree
Hide file tree
Showing 16 changed files with 249 additions and 2 deletions.
18 changes: 18 additions & 0 deletions dnd5e.css
Original file line number Diff line number Diff line change
Expand Up @@ -1427,6 +1427,9 @@ h5 {
/* ----------------------------------------- */
/* Scale Value */
/* ----------------------------------------- */
/* ----------------------------------------- */
/* Size */
/* ----------------------------------------- */
}
.dnd5e.advancement input[type="text"],
.dnd5e.advancement input[type="number"],
Expand Down Expand Up @@ -1604,6 +1607,16 @@ h5 {
.dnd5e.advancement.scale-value select option[value=""] {
color: var(--color-text-light-6);
}
.dnd5e.advancement.size .trait-list {
display: flex;
flex-wrap: wrap;
gap: 0.25rem;
padding: 0;
list-style: none;
}
.dnd5e.advancement.size .trait-list li {
flex: 1 1 40%;
}
.dnd5e.advancement-migration .items-list {
margin-block-end: 1em;
}
Expand Down Expand Up @@ -1682,6 +1695,11 @@ h5 {
.dnd5e.advancement.flow form[data-type="ScaleValue"] span.none {
font-style: italic;
}
.dnd5e.advancement.flow form[data-type="Size"] select {
width: 100%;
font-size: var(--font-size-16);
height: 2em;
}
.dnd5e.advancement.flow nav {
display: flex;
justify-content: flex-end;
Expand Down
1 change: 1 addition & 0 deletions icons/LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The dnd5e system for Foundry Virtual Tabletop includes icon artwork licensed fro
/svg/item-choice.svg - "Choice" by Delapouite under CC BY 3.0
/svg/item-grant.svg - "White book" by Willdabeast under CC BY 3.0
/svg/scale-value.svg - "Dice target" by Delapouite under CC BY 3.0
/svg/size.svg - "Body height" by Delapouite under CC BY 3.0
/svg/trait.svg - "Scroll unfurled" by Lorc under CC BY 3.0
/svg/trait-armor-proficiencies.svg - "Leather armor" by Delapouite under CC BY 3.0
/svg/trait-damage-immunities.svg - "Aura" by Lorc under CC BY 3.0
Expand Down
1 change: 1 addition & 0 deletions icons/svg/size.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,8 @@
"DND5E.AdvancementScaleValueTypeString": "Anything",
"DND5E.AdvancementSelectionCreateButton": "Create Advancement",
"DND5E.AdvancementSelectionTitle": "Select Advancement Type",
"DND5E.AdvancementSizeTitle": "Size",
"DND5E.AdvancementSizeHint": "Set a character's size.",
"DND5E.AdvancementTitle": "Advancement",
"DND5E.AdvancementTraitTitle": "Traits",
"DND5E.AdvancementTraitHint": "Grant a character certain traits or give them an option to select traits (such as proficiencies, skills, languages).",
Expand Down
26 changes: 26 additions & 0 deletions less/advancement.less
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,24 @@
}
}
}

/* ----------------------------------------- */
/* Size */
/* ----------------------------------------- */

&.size {
.trait-list {
display: flex;
flex-wrap: wrap;
gap: 0.25rem;
padding: 0;
list-style: none;

li {
flex: 1 1 40%;
}
}
}
}

.dnd5e.advancement-migration {
Expand Down Expand Up @@ -299,6 +317,14 @@
span.none { font-style: italic; }
}

form[data-type="Size"] {
select {
width: 100%;
font-size: var(--font-size-16);
height: 2em;
}
}

nav {
display: flex;
justify-content: flex-end;
Expand Down
2 changes: 2 additions & 0 deletions module/applications/advancement/_module.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ export {default as ItemGrantConfig} from "./item-grant-config.mjs";
export {default as ItemGrantFlow} from "./item-grant-flow.mjs";
export {default as ScaleValueConfig} from "./scale-value-config.mjs";
export {default as ScaleValueFlow} from "./scale-value-flow.mjs";
export {default as SizeConfig} from "./size-config.mjs";
export {default as SizeFlow} from "./size-flow.mjs";
39 changes: 39 additions & 0 deletions module/applications/advancement/size-config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { filteredKeys } from "../../utils.mjs";
import AdvancementConfig from "./advancement-config.mjs";

/**
* Configuration application for size advancement.
*/
export default class SizeConfig extends AdvancementConfig {

/** @inheritdoc */
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
classes: ["dnd5e", "advancement", "size"],
dragDrop: [{ dropSelector: ".drop-target" }],
dropKeyPath: "items",
template: "systems/dnd5e/templates/advancement/size-config.hbs"
});
}

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

/** @inheritdoc */
getData() {
return foundry.utils.mergeObject(super.getData(), {
showLevelSelector: false,
sizes: Object.entries(CONFIG.DND5E.actorSizes).reduce((obj, [key, label]) => {
obj[key] = { label, chosen: this.advancement.configuration.sizes.has(key) };
return obj;
}, {})
});
}

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

/** @inheritdoc */
async prepareConfigurationUpdate(configuration) {
configuration.sizes = filteredKeys(configuration.sizes ?? {});
return configuration;
}
}
27 changes: 27 additions & 0 deletions module/applications/advancement/size-flow.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import AdvancementFlow from "./advancement-flow.mjs";

/**
* Inline application that displays size advancement.
*/
export default class SizeFlow extends AdvancementFlow {

/** @inheritdoc */
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
template: "systems/dnd5e/templates/advancement/size-flow.hbs"
});
}

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

/** @inheritdoc */
getData() {
return foundry.utils.mergeObject(super.getData(), {
selectedSize: this.retainedData?.size ?? this.advancement.value.size,
sizes: Array.from(this.advancement.configuration.sizes).reduce((obj, key) => {
obj[key] = CONFIG.DND5E.actorSizes[key];
return obj;
}, {})
});
}
}
3 changes: 2 additions & 1 deletion module/config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1966,7 +1966,8 @@ DND5E.advancementTypes = {
HitPoints: advancement.HitPointsAdvancement,
ItemChoice: advancement.ItemChoiceAdvancement,
ItemGrant: advancement.ItemGrantAdvancement,
ScaleValue: advancement.ScaleValueAdvancement
ScaleValue: advancement.ScaleValueAdvancement,
Size: advancement.SizeAdvancement
};

/* -------------------------------------------- */
Expand Down
1 change: 1 addition & 0 deletions module/data/advancement/_module.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export * from "./ability-score-improvement.mjs";
export {default as ItemChoiceConfigurationData} from "./item-choice.mjs";
export {default as ItemGrantConfigurationData} from "./item-grant.mjs";
export * as scaleValue from "./scale-value.mjs";
export * from "./size.mjs";
export {TraitConfigurationData, TraitValueData} from "./trait.mjs";
26 changes: 26 additions & 0 deletions module/data/advancement/size.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Configuration data for the size advancement type.
*/
export class SizeConfigurationData extends foundry.abstract.DataModel {
/** @inheritdoc */
static defineSchema() {
return {
hint: new foundry.data.fields.StringField({label: "DND5E.AdvancementHint"}),
sizes: new foundry.data.fields.SetField(
new foundry.data.fields.StringField(), {required: false, initial: ["med"], label: "DND5E.Size"}
)
};
}
}

/**
* Value data for the size advancement type.
*/
export class SizeValueData extends foundry.abstract.DataModel {
/** @inheritdoc */
static defineSchema() {
return {
size: new foundry.data.fields.StringField({required: false, label: "DND5E.Size"})
};
}
}
1 change: 1 addition & 0 deletions module/documents/advancement/_module.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export {default as HitPointsAdvancement} from "./hit-points.mjs";
export {default as ItemChoiceAdvancement} from "./item-choice.mjs";
export {default as ItemGrantAdvancement} from "./item-grant.mjs";
export {default as ScaleValueAdvancement} from "./scale-value.mjs";
export {default as SizeAdvancement} from "./size.mjs";
82 changes: 82 additions & 0 deletions module/documents/advancement/size.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import Advancement from "./advancement.mjs";
import SizeConfig from "../../applications/advancement/size-config.mjs";
import SizeFlow from "../../applications/advancement/size-flow.mjs";
import { SizeConfigurationData, SizeValueData } from "../../data/advancement/size.mjs";

/**
* Advancement that handles player size.
*/
export default class SizeAdvancement extends Advancement {

/** @inheritdoc */
static get metadata() {
return foundry.utils.mergeObject(super.metadata, {
dataModels: {
configuration: SizeConfigurationData,
value: SizeValueData
},
order: 5,
icon: "systems/dnd5e/icons/svg/size.svg",
title: game.i18n.localize("DND5E.AdvancementSizeTitle"),
hint: game.i18n.localize("DND5E.AdvancementSizeHint"),
validItemTypes: new Set(["race"]),
apps: {
config: SizeConfig,
flow: SizeFlow
}
});
}

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

/** @inheritdoc */
get levels() {
return [0];
}

/* -------------------------------------------- */
/* Display Methods */
/* -------------------------------------------- */

/** @inheritdoc */
summaryForLevel(level, { configMode=false }={}) {
const sizes = configMode ? Array.from(this.configuration.sizes) : this.value.size ? [this.value.size] : [];
return sizes.map(s => `<span class="tag">${CONFIG.DND5E.actorSizes[s]}</span>`).join("");
}

/* -------------------------------------------- */
/* Editing Methods */
/* -------------------------------------------- */

/** @inheritdoc */
static availableForItem(item) {
return !item.advancement.byType.Race?.length;
}

/* -------------------------------------------- */
/* Application Methods */
/* -------------------------------------------- */

/** @inheritdoc */
async apply(level, data) {
this.actor.updateSource({"system.traits.size": data.size ?? "med"});
this.updateSource({ value: data });
}

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

/** @inheritdoc */
async restore(level, data) {
this.apply(level, data);
}

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

/** @inheritdoc */
async reverse(level) {
this.actor.updateSource({"system.traits.size": "med"});
this.updateSource({ "value.-=size": null });
}
}
10 changes: 10 additions & 0 deletions templates/advancement/size-config.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<form autocomplete="off">
{{> "dnd5e.advancement-controls"}}

<div class="form-group">
<label>{{localize "DND5E.AdvancementHint"}}</label>
<textarea name="configuration.hint">{{configuration.hint}}</textarea>
</div>

{{> "dnd5e.trait-list" choices=sizes prefix="configuration.sizes"}}
</form>
9 changes: 9 additions & 0 deletions templates/advancement/size-flow.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<form id="{{appId}}" data-level="{{level}}" data-id="{{advancement.id}}" data-type="{{type}}">
<h3>{{{this.title}}}</h3>

<p>{{advancement.configuration.hint}}</p>

<select name="size">
{{selectOptions sizes selected=selectedSize}}
</select>
</form>
3 changes: 2 additions & 1 deletion templates/items/race.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@

<ul class="summary flexrow">
<li>
<input type="text" name="system.source" value="{{system.source}}" placeholder="{{localize 'DND5E.Source'}}">
<input type="text" name="system.source.custom" value="{{system.source.custom}}"
placeholder="{{localize 'DND5E.Source'}}">
</li>
</ul>
</div>
Expand Down

0 comments on commit e6e31c3

Please sign in to comment.