forked from GitHub-Mirrors/foundry-sw5e
Added experimental automation for classes
Added automation for saving throws and skills, prepared for adding item proficiencies and class feats. Only class setup for this is sentinel
This commit is contained in:
parent
76ef89b518
commit
e1c45c5f7e
4 changed files with 109 additions and 14 deletions
|
@ -98,11 +98,17 @@ export default class Actor5e extends Actor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Class features
|
||||||
|
if (this.data.type === "character") this._prepareClassFeatures();
|
||||||
|
|
||||||
// Ability modifiers and saves
|
// Ability modifiers and saves
|
||||||
const dcBonus = Number.isNumeric(data.bonuses?.power?.dc) ? parseInt(data.bonuses.power.dc) : 0;
|
const dcBonus = Number.isNumeric(data.bonuses?.power?.dc) ? parseInt(data.bonuses.power.dc) : 0;
|
||||||
const saveBonus = Number.isNumeric(bonuses.save) ? parseInt(bonuses.save) : 0;
|
const saveBonus = Number.isNumeric(bonuses.save) ? parseInt(bonuses.save) : 0;
|
||||||
const checkBonus = Number.isNumeric(bonuses.check) ? parseInt(bonuses.check) : 0;
|
const checkBonus = Number.isNumeric(bonuses.check) ? parseInt(bonuses.check) : 0;
|
||||||
for (let [id, abl] of Object.entries(data.abilities)) {
|
for (let [id, abl] of Object.entries(data.abilities)) {
|
||||||
|
// Either proficient because the class says so, or the user has set it
|
||||||
|
abl.proficient = abl?.classProficient || abl.proficientOverride;
|
||||||
|
|
||||||
abl.mod = Math.floor((abl.value - 10) / 2);
|
abl.mod = Math.floor((abl.value - 10) / 2);
|
||||||
abl.prof = (abl.proficient || 0) * data.attributes.prof;
|
abl.prof = (abl.proficient || 0) * data.attributes.prof;
|
||||||
abl.saveBonus = saveBonus;
|
abl.saveBonus = saveBonus;
|
||||||
|
@ -362,6 +368,49 @@ export default class Actor5e extends Actor {
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepares the derived data from the character's classes
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_prepareClassFeatures() {
|
||||||
|
let data = this.data.data;
|
||||||
|
// Automatic class data
|
||||||
|
for (let theClass of Object.values(this.classes)) {
|
||||||
|
// Only the original class provides the saving throws, skills, and most item proficiencies
|
||||||
|
if (theClass.data._id === data.details.originalClass) {
|
||||||
|
// Saving throws
|
||||||
|
for (let save of theClass.data.data.saves) {
|
||||||
|
data.abilities[save].classProficient = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skills
|
||||||
|
for (let skill of theClass.data.data.skills.value) {
|
||||||
|
data.skills[skill].classValue = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// OG Item Proficiencies
|
||||||
|
// Armour
|
||||||
|
for (let item of theClass.data.data.itemProficiencies.armour) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Weapons
|
||||||
|
for (let item of theClass.data.data.itemProficiencies.weapons) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Items
|
||||||
|
for (let item of theClass.data.data.itemProficiencies.tools) {
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Multiclass Item Proficiencies
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare skill checks.
|
* Prepare skill checks.
|
||||||
* @param actorData
|
* @param actorData
|
||||||
|
@ -383,6 +432,9 @@ export default class Actor5e extends Actor {
|
||||||
const observant = flags.observantFeat;
|
const observant = flags.observantFeat;
|
||||||
const skillBonus = Number.isNumeric(bonuses.skill) ? parseInt(bonuses.skill) : 0;
|
const skillBonus = Number.isNumeric(bonuses.skill) ? parseInt(bonuses.skill) : 0;
|
||||||
for (let [id, skl] of Object.entries(data.skills)) {
|
for (let [id, skl] of Object.entries(data.skills)) {
|
||||||
|
// Use the highest out of the value provided by the class, and the value provided by the user
|
||||||
|
skl.value = (skl?.classValue > skl.valueOverride ? skl?.classValue : skl.valueOverride);
|
||||||
|
|
||||||
skl.value = Math.clamped(Number(skl.value).toNearest(0.5), 0, 2) ?? 0;
|
skl.value = Math.clamped(Number(skl.value).toNearest(0.5), 0, 2) ?? 0;
|
||||||
let round = Math.floor;
|
let round = Math.floor;
|
||||||
|
|
||||||
|
|
|
@ -538,22 +538,27 @@ export default class ActorSheet5e extends ActorSheet {
|
||||||
*/
|
*/
|
||||||
_onCycleSkillProficiency(event) {
|
_onCycleSkillProficiency(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const field = $(event.currentTarget).siblings('input[type="hidden"]');
|
// Like _onToggleAbilityProficiency
|
||||||
|
// const field = $(event.currentTarget).siblings('input[type="hidden"]');
|
||||||
|
const field = event.currentTarget.previousElementSibling;
|
||||||
|
|
||||||
// Get the current level and the array of levels
|
// Get the current level and the array of levels
|
||||||
const level = parseFloat(field.val());
|
const level = parseFloat(field.value);
|
||||||
const levels = [0, 1, 0.5, 2];
|
const levels = [0, 0.5, 1, 2];
|
||||||
let idx = levels.indexOf(level);
|
let idx = levels.indexOf(level);
|
||||||
|
|
||||||
// Toggle next level - forward on click, backwards on right
|
// Toggle next level - forward on click, backwards on right
|
||||||
if ( event.type === "click" ) {
|
if ( event.type === "click" ) {
|
||||||
field.val(levels[(idx === levels.length - 1) ? 0 : idx + 1]);
|
field.value = (levels[(idx === levels.length - 1) ? 0 : idx + 1]);
|
||||||
} else if ( event.type === "contextmenu" ) {
|
} else if ( event.type === "contextmenu" ) {
|
||||||
field.val(levels[(idx === 0) ? levels.length - 1 : idx - 1]);
|
field.value = (levels[(idx === 0) ? levels.length - 1 : idx - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the field value and save the form
|
// Update the field value and save the form
|
||||||
this._onSubmit(event);
|
|
||||||
|
// I've no idea why onsubmit was used, but it doesn't work if we want it to set a different value, thus we replace it with an actor update statement
|
||||||
|
// this._onSubmit(event);
|
||||||
|
return this.actor.update({[field.name + "Override"]: parseFloat(field.value)});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
@ -922,7 +927,7 @@ _onItemCollapse(event) {
|
||||||
_onToggleAbilityProficiency(event) {
|
_onToggleAbilityProficiency(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const field = event.currentTarget.previousElementSibling;
|
const field = event.currentTarget.previousElementSibling;
|
||||||
return this.actor.update({[field.name]: 1 - parseInt(field.value)});
|
return this.actor.update({[field.name + "Override"]: 1 - parseInt(field.value)});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -6,27 +6,33 @@
|
||||||
"abilities": {
|
"abilities": {
|
||||||
"str": {
|
"str": {
|
||||||
"value": 10,
|
"value": 10,
|
||||||
"proficient": 0
|
"proficient": 0,
|
||||||
|
"proficientOverride": 0
|
||||||
},
|
},
|
||||||
"dex": {
|
"dex": {
|
||||||
"value": 10,
|
"value": 10,
|
||||||
"proficient": 0
|
"proficient": 0,
|
||||||
|
"proficientOverride": 0
|
||||||
},
|
},
|
||||||
"con": {
|
"con": {
|
||||||
"value": 10,
|
"value": 10,
|
||||||
"proficient": 0
|
"proficient": 0,
|
||||||
|
"proficientOverride": 0
|
||||||
},
|
},
|
||||||
"int": {
|
"int": {
|
||||||
"value": 10,
|
"value": 10,
|
||||||
"proficient": 0
|
"proficient": 0,
|
||||||
|
"proficientOverride": 0
|
||||||
},
|
},
|
||||||
"wis": {
|
"wis": {
|
||||||
"value": 10,
|
"value": 10,
|
||||||
"proficient": 0
|
"proficient": 0,
|
||||||
|
"proficientOverride": 0
|
||||||
},
|
},
|
||||||
"cha": {
|
"cha": {
|
||||||
"value": 10,
|
"value": 10,
|
||||||
"proficient": 0
|
"proficient": 0,
|
||||||
|
"proficientOverride": 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"attributes": {
|
"attributes": {
|
||||||
|
@ -134,74 +140,92 @@
|
||||||
"skills": {
|
"skills": {
|
||||||
"acr": {
|
"acr": {
|
||||||
"value": 0,
|
"value": 0,
|
||||||
|
"valueOverride": 0,
|
||||||
"ability": "dex"
|
"ability": "dex"
|
||||||
},
|
},
|
||||||
"ani": {
|
"ani": {
|
||||||
"value": 0,
|
"value": 0,
|
||||||
|
"valueOverride": 0,
|
||||||
"ability": "wis"
|
"ability": "wis"
|
||||||
},
|
},
|
||||||
"ath": {
|
"ath": {
|
||||||
"value": 0,
|
"value": 0,
|
||||||
|
"valueOverride": 0,
|
||||||
"ability": "str"
|
"ability": "str"
|
||||||
},
|
},
|
||||||
"dec": {
|
"dec": {
|
||||||
"value": 0,
|
"value": 0,
|
||||||
|
"valueOverride": 0,
|
||||||
"ability": "cha"
|
"ability": "cha"
|
||||||
},
|
},
|
||||||
"ins": {
|
"ins": {
|
||||||
"value": 0,
|
"value": 0,
|
||||||
|
"valueOverride": 0,
|
||||||
"ability": "wis"
|
"ability": "wis"
|
||||||
},
|
},
|
||||||
"itm": {
|
"itm": {
|
||||||
"value": 0,
|
"value": 0,
|
||||||
|
"valueOverride": 0,
|
||||||
"ability": "cha"
|
"ability": "cha"
|
||||||
},
|
},
|
||||||
"inv": {
|
"inv": {
|
||||||
"value": 0,
|
"value": 0,
|
||||||
|
"valueOverride": 0,
|
||||||
"ability": "int"
|
"ability": "int"
|
||||||
},
|
},
|
||||||
"lor": {
|
"lor": {
|
||||||
"value": 0,
|
"value": 0,
|
||||||
|
"valueOverride": 0,
|
||||||
"ability": "int"
|
"ability": "int"
|
||||||
},
|
},
|
||||||
"med": {
|
"med": {
|
||||||
"value": 0,
|
"value": 0,
|
||||||
|
"valueOverride": 0,
|
||||||
"ability": "wis"
|
"ability": "wis"
|
||||||
},
|
},
|
||||||
"nat": {
|
"nat": {
|
||||||
"value": 0,
|
"value": 0,
|
||||||
|
"valueOverride": 0,
|
||||||
"ability": "int"
|
"ability": "int"
|
||||||
},
|
},
|
||||||
"pil": {
|
"pil": {
|
||||||
"value": 0,
|
"value": 0,
|
||||||
|
"valueOverride": 0,
|
||||||
"ability": "int"
|
"ability": "int"
|
||||||
},
|
},
|
||||||
"prc": {
|
"prc": {
|
||||||
"value": 0,
|
"value": 0,
|
||||||
|
"valueOverride": 0,
|
||||||
"ability": "wis"
|
"ability": "wis"
|
||||||
},
|
},
|
||||||
"prf": {
|
"prf": {
|
||||||
"value": 0,
|
"value": 0,
|
||||||
|
"valueOverride": 0,
|
||||||
"ability": "cha"
|
"ability": "cha"
|
||||||
},
|
},
|
||||||
"per": {
|
"per": {
|
||||||
"value": 0,
|
"value": 0,
|
||||||
|
"valueOverride": 0,
|
||||||
"ability": "cha"
|
"ability": "cha"
|
||||||
},
|
},
|
||||||
"slt": {
|
"slt": {
|
||||||
"value": 0,
|
"value": 0,
|
||||||
|
"valueOverride": 0,
|
||||||
"ability": "dex"
|
"ability": "dex"
|
||||||
},
|
},
|
||||||
"ste": {
|
"ste": {
|
||||||
"value": 0,
|
"value": 0,
|
||||||
|
"valueOverride": 0,
|
||||||
"ability": "dex"
|
"ability": "dex"
|
||||||
},
|
},
|
||||||
"sur": {
|
"sur": {
|
||||||
"value": 0,
|
"value": 0,
|
||||||
|
"valueOverride": 0,
|
||||||
"ability": "wis"
|
"ability": "wis"
|
||||||
},
|
},
|
||||||
"tec": {
|
"tec": {
|
||||||
"value": 0,
|
"value": 0,
|
||||||
|
"valueOverride": 0,
|
||||||
"ability": "int"
|
"ability": "int"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -882,7 +906,21 @@
|
||||||
"class": {
|
"class": {
|
||||||
"templates": ["classDescription"],
|
"templates": ["classDescription"],
|
||||||
"className": "",
|
"className": "",
|
||||||
|
"classFeatures": {},
|
||||||
|
"itemProficiencies": {
|
||||||
|
"armour": [],
|
||||||
|
"weapons": [],
|
||||||
|
"tools": []
|
||||||
|
},
|
||||||
|
"multiclassProficiencies": {
|
||||||
|
"armour": [],
|
||||||
|
"weapons": [],
|
||||||
|
"tools": []
|
||||||
|
},
|
||||||
"levels": 1,
|
"levels": 1,
|
||||||
|
"multiclassPrerequisite": [
|
||||||
|
[]
|
||||||
|
],
|
||||||
"archetype": "",
|
"archetype": "",
|
||||||
"hitDice": "d6",
|
"hitDice": "d6",
|
||||||
"hitDiceUsed": 0,
|
"hitDiceUsed": 0,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue