Merge pull request #7696 from nmbradley/nb-wfrp-v1.0.2

Warhammer Fantasy 4e Official - v1.0.3
This commit is contained in:
Miguel Peres
2020-11-16 09:53:12 -03:00
committed by GitHub
28 changed files with 2696 additions and 1142 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

@@ -5,5 +5,192 @@
"roll20userid": "45398",
"preview": "preview.png",
"compendium": "WFRP",
"instructions": ""
"instructions": "",
"useroptions": [
{
"attribute": "npc",
"displayname": "NPC",
"displaytranslationkey": "settings_npc",
"type": "checkbox",
"value": "on",
"description": "The NPC option sets new characters to default to the NPC card style sheet. Useful if the player characters have already been created and all new character sheets added to the game will likely represent non player characters.",
"descriptiontranslationkey": "settings_npc_desc"
},
{
"attribute": "setting_whisper",
"displayname": "Whisper Rolls to GM",
"displaytranslationkey": "settings_whisper",
"type": "select",
"options": [
"Off|1",
"On|0"
],
"optiontranslationkeys": [
"On",
"Off"
],
"default": "Off|1",
"description": "All sheet rolls are sent to all players in chat by default. If enabled, rolls from this sheet will be visible only to the GM.",
"descriptiontranslationkey": "settings_whisper_desc"
},
{
"attribute": "setting_diff_option",
"displayname": "Query Difficulty",
"displaytranslationkey": "settings_difficulty",
"type": "select",
"options": [
"On|0",
"Off|1"
],
"optiontranslationkeys": [
"On",
"Off"
],
"default": "On",
"description": "This will enable or disable the difficulty query window when rolls are made. When off, all rolls are made at the base target number.",
"descriptiontranslationkey": "settings_difficulty_desc"
},
{
"attribute": "setting_bonus_option",
"displayname": "Query Bonuses",
"displaytranslationkey": "settings_bonuses",
"type": "select",
"options": [
"On|0",
"Off|1"
],
"optiontranslationkeys": [
"On",
"Off"
],
"default": "On",
"description": "This will enable or disable the additional bonus and SL bonus windows when rolls are made.",
"descriptiontranslationkey": "settings_bonuses_desc"
},
{
"attribute": "setting_crit_option",
"displayname": "Automatic Success & Failure",
"displaytranslationkey": "settings_auto",
"type": "select",
"options": [
"Default|1",
"01/96-100|2",
"01/100|3"
],
"optiontranslationkeys": [
"Default"
],
"default": "Default",
"description": "This will change the boundaries for automatic success and failure on a roll. The default boundaries set the automatic success point at 01-05 and 96-100.",
"descriptiontranslationkey": "settings_auto_desc"
},
{
"attribute": "setting_init_option",
"displayname": "Initiative Roll",
"displaytranslationkey": "settings_initiative",
"type": "select",
"options": [
"Default|1",
"1d10+I|2",
"1d10+IB+AgB|3"
],
"optiontranslationkeys": [
"Default"
],
"default": "Default",
"description": "This changes the way initiative will be sent to the turn tracker. In the default setting, a character's whole initiative characteristic will be sent to the turntracker. When using the other options, a d10 will be rolled and different configurations of characteristic bonuses will be added to it.",
"descriptiontranslationkey": "settings_initiative_desc"
},
{
"attribute": "setting_max_advantage",
"displayname": "Max Advantage",
"displaytranslationkey": "settings_maxadvantage",
"type": "text",
"default": "",
"description": "Sets the maximum advantage possible.",
"descriptiontranslationkey": "settings_bar1_value_desc"
},
{
"attribute": "bar1_v",
"displayname": "BAR 1 VALUE",
"displaytranslationkey": "settings_bar1_value",
"type": "text",
"default": "wounds",
"description": "On Default Tokens created by doing a drop onto the virtual table top, set the Bar 1's value to this attribute.",
"descriptiontranslationkey": "settings_bar1_value_desc"
},
{
"attribute": "bar1_m",
"displayname": "BAR 1 MAX",
"displaytranslationkey": "settings_bar1_max",
"type": "text",
"default": "wounds",
"description": "On Default Tokens created by doing a drop onto the virtual table top, set the Bar 1's max to this attribute.",
"descriptiontranslationkey": "settings_bar1_max_desc"
},
{
"attribute": "bar1_l",
"displayname": "BAR 1 LINK",
"displaytranslationkey": "settings_bar1_link",
"type": "text",
"default": "",
"description": "On Default Tokens created by doing a drop onto the virtual table top, link the Bar 1's value to this attribute. If set this will override all other bar settings.",
"descriptiontranslationkey": "settings_bar1_link_desc"
},
{
"attribute": "bar2_v",
"displayname": "BAR 2 VALUE",
"displaytranslationkey": "settings_bar2_value",
"type": "text",
"default": "toughness_bonus",
"description": "On Default Tokens created by doing a drop onto the virtual table top, set the Bar 2's value to this attribute.",
"descriptiontranslationkey": "settings_bar2_value_desc"
},
{
"attribute": "bar2_m",
"displayname": "BAR 2 MAX",
"displaytranslationkey": "settings_bar2_max",
"type": "text",
"default": "",
"description": "On Default Tokens created by doing a drop onto the virtual table top, set the Bar 2's max to this attribute.",
"descriptiontranslationkey": "settings_bar2_max_desc"
},
{
"attribute": "bar2_l",
"displayname": "BAR 2 LINK",
"displaytranslationkey": "settings_bar2_link",
"type": "text",
"default": "",
"description": "On Default Tokens created by doing a drop onto the virtual table top, link the Bar 2's value to this attribute. If set this will override all other bar settings.",
"descriptiontranslationkey": "settings_bar2_link_desc"
},
{
"attribute": "bar3_v",
"displayname": "BAR 3 VALUE",
"displaytranslationkey": "settings_bar3_value",
"type": "text",
"default": "",
"description": "On Default Tokens created by doing a drop onto the virtual table top, set the Bar 3's value to this attribute.",
"descriptiontranslationkey": "settings_bar3_value_desc"
},
{
"attribute": "bar3_m",
"displayname": "BAR 3 MAX",
"displaytranslationkey": "settings_bar3_max",
"type": "text",
"default": "",
"description": "On Default Tokens created by doing a drop onto the virtual table top, set the Bar 3's max to this attribute.",
"descriptiontranslationkey": "settings_bar3_max_desc"
},
{
"attribute": "bar3_l",
"displayname": "BAR 3 LINK",
"displaytranslationkey": "settings_bar3_link",
"type": "text",
"default": "",
"description": "On Default Tokens created by doing a drop onto the virtual table top, link the Bar 3's value to this attribute. If set this will override all other bar settings.",
"descriptiontranslationkey": "settings_bar3_link_desc"
}
]
}
@@ -1,21 +1,23 @@
const wfrpDragAndDrop = ( () => {
const handleDrop = (values, overwrite = false) => {
const handleDrop = (values, name) => {
const {drop_name, drop_content, drop_data} = values;
const page_name = (name) ? name : drop_name;
if (drop_name === ""|| typeof drop_data === "") return;
let parsed_data = helperFunctions.parseJSON(drop_data);
if (parsed_data.Category === "Careers") handleCareer(drop_name, parsed_data);
else if (parsed_data.Category === "Blessings" || parsed_data.Category === "Spells" || parsed_data.Category === "Miracles" ) handleSpell(drop_name, parsed_data, drop_content);
else if (parsed_data.Category === "Items") handleItem(drop_name, parsed_data);
else if (parsed_data.Category === "Monsters") handleMonster(drop_name, parsed_data, drop_content);
else if (parsed_data.Category === "Talents") handleTalent(drop_name, parsed_data);
else if (parsed_data.Category === "Conditions") handleCondition(drop_name, parsed_data);
else if (parsed_data.Category === "Creature Traits") handleCreatureTrait(drop_name, parsed_data);
if (parsed_data.Category === "Careers") handleCareer(dpage_name, parsed_data);
else if (parsed_data.Category === "Blessings" || parsed_data.Category === "Spells" || parsed_data.Category === "Miracles" ) handleSpell(page_name, parsed_data, drop_content);
else if (parsed_data.Category === "Items") handleItem(page_name, parsed_data);
else if (parsed_data.Category === "Monsters") handleMonster(page_name, parsed_data, drop_content);
else if (parsed_data.Category === "Talents") handleTalent(page_name, parsed_data);
else if (parsed_data.Category === "Conditions") handleCondition(page_name, parsed_data);
else if (parsed_data.Category === "Creature Traits") handleCreatureTrait(page_name, parsed_data);
else console.warn(`${parsed_data.Category} drop is not supported by the sheet`);
setAttrs({drop_name: "", drop_content: "", drop_data: ""});
@@ -177,8 +179,11 @@ const wfrpDragAndDrop = ( () => {
for (const characteristic in characteristics) {
updateAttrs[characteristic.replace(/ /g,"_")] = characteristics[characteristic];
updateAttrs[`${characteristic.replace(/ /g,"_")}_bonus`] = Math.floor(characteristics[characteristic]/10);
}
console.log(updateAttrs);
const trait_map = new Map();
for (const trait of traits) {
@@ -490,6 +495,8 @@ const wfrpDragAndDrop = ( () => {
}
getAttrs(token_values, settings => {
console.log(settings)
const default_attr = {
width: 70,
@@ -504,6 +511,8 @@ const wfrpDragAndDrop = ( () => {
getAttrs(attrs, values => {
console.log(values)
for (const item in settings) {
if (settings[item] !== "") {
default_attr[item] = settings[item];
@@ -3,7 +3,7 @@ const wfrpModule = ( () => {
// Global Variables
const wfrp = {
sheet_version: "1.0.0",
sheet_version: "1.0.3",
characteristics: [
"weapon_skill",
@@ -148,6 +148,18 @@ const wfrpModule = ( () => {
recalculateEarnedXP();
calculateArmour();
getAttrs(["setting_init_option","setting_whisper","setting_bonus_option","setting_crit_option"], values => {
toggleInitOption(values["setting_init_option"]);
toggleWhisper(values["setting_whisper"]);
toggleRollBonus(values["setting_bonus_option"]);
toggleRollCrits(values["setting_crit_option"]);
})
}
const updateSheet = (version) => {
@@ -166,14 +178,16 @@ const wfrpModule = ( () => {
const difficulty = (new_value === "1") ? `?{Difficulty|Average (+20), 20|Very Easy (+60), 60|Easy (+40), 40|Average (+20), 20|Challenging (0), 0|Difficult (-10), -10|Hard (-20), -20|Very Hard (-30), -30}` :
0;
setAttrs({difficulty_query:difficulty});
setAttrs({
difficulty_query:difficulty
});
}
const toggleRollBonus = (new_value) => {
let query = 0;
let slbonus = "";
if (new_value === 1) {
if (new_value === "1") {
query = "?{Bonus|0}";
slbonus = "{{sl_bonus=?{SL Bonus|0}}}"
}
@@ -196,7 +210,10 @@ const wfrpModule = ( () => {
(new_value === "3") ? 1 :
5;
setAttrs({roll_cs:cs, roll_cf:cf});
setAttrs({
roll_cs:cs,
roll_cf:cf
});
}
const toggleInitOption = (new_value) => {
@@ -208,6 +225,13 @@ const wfrpModule = ( () => {
setAttrs({roll_init:init});
}
const toggleWhisper = (new_value) => {
const whisper = (new_value === "2") ? `/w gm` :
``;
setAttrs({roll_whisper:whisper});
}
const parseModField = (new_value="", previous_value) => {
const mods = new_value.toLowerCase().split(",").map(item=>item.trim());
const prev_mods = (previous_value) ? previous_value.toLowerCase().split(",").map(item=>item.trim()) : [];
@@ -336,46 +360,121 @@ const wfrpModule = ( () => {
new_value = new_value.toLowerCase();
const update = {
fate: 0,
resilience: 0,
movement: 0,
size: 0
}
if (new_value === "human") {
setAttrs({
fate: 2,
resilience: 1,
movement: 4,
size: "average"
});
update["fate"] = 2;
update["resilience"] = 1;
update["movement"] = 4;
update["size"] = "average";
}
if (new_value === "dwarf") {
setAttrs({
fate: 0,
resilience: 2,
movement: 3,
size: "average"
});
update["fate"] = 0;
update["resilience"] = 2;
update["movement"] = 3;
update["size"] = "average";
}
if (new_value === "halfling") {
setAttrs({
fate: 0,
resilience: 2,
movement: 3,
size: "average"
});
update["fate"] = 0;
update["resilience"] = 2;
update["movement"] = 3;
update["size"] = "small";
}
if (new_value === "elf") {
setAttrs({
fate: 0,
resilience: 0,
movement: 5,
size: "average"
});
if (new_value === "wood elf") {
update["fate"] = 0;
update["resilience"] = 0;
update["movement"] = 4;
update["size"] = "average";
}
if (new_value === "high elf") {
setAttrs({
fate: 0,
resilience: 0,
movement: 5,
size: "average"
});
update["fate"] = 0;
update["resilience"] = 0;
update["movement"] = 5;
update["size"] = "average";
}
if (new_value !== "custom") {
getCompendiumPage(`Species:${new_value}`, page => {
const skills = helperFunctions.parseJSON(page.data.Skills);
const talents = helperFunctions.parseJSON(page.data.Talents);
const skills_fixed = skills.Fixed.split(",").map(item=>item.trim()) || [];
const talents_fixed = talents.Fixed.split(",").map(item=>item.trim()) || [];
let talents_choices = [];
let skill_index = 1;
let talent_index = 1;
if (talents.Choices) talents.Choices.forEach(choice => talents_choices = [...talents_choices, ...choice]);
for (let index = 1; index <= 12; index++) {
update[`species_skill_${index}_name`] = "";
update[`species_skill_${index}_advances`] = "0";
}
for (let index = 1; index <= 10; index++) {
update[`species_talent_${index}_name`] = "";
update[`species_talent_${index}_advances`] = "0";
}
for (const skill of skills_fixed) {
update[`species_skill_${skill_index}_name`] = skill;
update[`species_talent_${skill_index}_advances`] = "0";
skill_index++;
}
for (const talent of talents_fixed) {
update[`species_talent_${talent_index}_name`] = talent;
update[`species_talent_${talent_index}_advances`] = "1";
talent_index++;
}
for (const talent of talents_choices) {
update[`species_talent_${talent_index}_name`] = talent;
update[`species_talent_${talent_index}_advances`] = "0";
talent_index++;
}
setAttrs(update, {silent:true}, callback => calculateTalentAdvances());
});
} else {
setAttrs(update);
}
}
const checkSpeciesAdvances = () => {
const attrs = [];
for (let i = 1; i <= 12; i++) {
attrs.push(`species_skill_${i}_advances`);
}
getAttrs(attrs, values => {
let threes = 0;
let fives = 0;
Object.values(values).forEach(value => {
if (value === "3") threes++;
if (value === "5") fives++;
});
const update = {};
update["species_disable3"] = (threes >= 3) ? 1 : 0;
update["species_disable5"] = (fives >= 3) ? 1 : 0;
setAttrs(update);
});
}
// Characteristic Functions
@@ -733,15 +832,17 @@ const wfrpModule = ( () => {
const attrs = [];
wfrp.characteristics.forEach(characteristic => attrs.push(`${repeating_id}_career_${characteristic}_advances`))
wfrp.characteristics.forEach(characteristic => attrs.push(`${repeating_id}_career_${characteristic}_advances`));
for (let i = 1; i <= 4; i++) {
for (let j = 1; j <= 10; j++) {
attrs.push(`${repeating_id}_career_skill_${i}_${j}_advances`);
attrs.push(`${repeating_id}_career_skill_${i}_${j}_init`);
}
for (let k = 1; k <= 5; k++) {
attrs.push(`${repeating_id}_career_talent_${i}_${k}_advances`);
attrs.push(`${repeating_id}_career_talent_${i}_${j}_init`);
}
}
@@ -757,88 +858,87 @@ const wfrpModule = ( () => {
let total_skills_advances = skills_values.reduce((a,b) => a+b);
let total_talents_advances = talents_values.reduce((a,b) => a+b);
const xp = [];
wfrp.characteristics.forEach(characteristic => xp.push(calculateCharacteristicXP(values[`${repeating_id}_career_${characteristic}_advances`])));
skills_values.forEach(skill => xp.push(calculateSkillXP(skill)));
talents_values.forEach(talent => xp.push(calculateTalentXP(talent)));
const total_xp = (xp.length > 0) ? xp.reduce((a,b) => a+b) : "" || "";
const abs_total = total_skills_advances + total_talents_advances || "";
const updateAttrs = {};
updateAttrs[`${repeating_id}_career_advances`] = (abs_total > 0) ? abs_total : "";
updateAttrs[`${repeating_id}_career_xp`] = total_xp;
setAttrs(updateAttrs, recalculateSpentXP());
});
}
const calculateCharacteristicXP = (value) => {
let int = parseInt(value);
const calculateCharacteristicXP = (value, free) => {
let int = parseInt(value) + parseInt(free);
let countdown = parseInt(free);
let accumulator = 0;
while (int > 0) {
accumulator +=
(int <= 5) ? 25 :
(int <= 10) ? 30 :
(int <= 15) ? 40 :
(int <= 20) ? 50 :
(int <= 25) ? 70 :
(int <= 30) ? 90 :
(int <= 35) ? 120 :
(int <= 40) ? 150 :
(int <= 45) ? 190 :
(int <= 50) ? 230 :
(int <= 55) ? 280 :
(int <= 60) ? 330 :
(int <= 65) ? 390 :
(int <= 70) ? 450 :
520;
if (int > countdown) {
accumulator +=
(int <= 5) ? 25 :
(int <= 10) ? 30 :
(int <= 15) ? 40 :
(int <= 20) ? 50 :
(int <= 25) ? 70 :
(int <= 30) ? 90 :
(int <= 35) ? 120 :
(int <= 40) ? 150 :
(int <= 45) ? 190 :
(int <= 50) ? 230 :
(int <= 55) ? 280 :
(int <= 60) ? 330 :
(int <= 65) ? 390 :
(int <= 70) ? 450 :
520;
}
int--;
}
return accumulator;
}
const calculateSkillXP = (value) => {
let int = parseInt(value);
const calculateSkillXP = (value, free) => {
let int = parseInt(value) + parseInt(free);
let countdown = parseInt(free);
let accumulator = 0;
while (int > 0) {
accumulator +=
(int <= 5) ? 10 :
(int <= 10) ? 15 :
(int <= 15) ? 20 :
(int <= 20) ? 30 :
(int <= 25) ? 40 :
(int <= 30) ? 60 :
(int <= 35) ? 80 :
(int <= 40) ? 110 :
(int <= 45) ? 140 :
(int <= 50) ? 180 :
(int <= 55) ? 220 :
(int <= 60) ? 270 :
(int <= 65) ? 320 :
(int <= 70) ? 380 :
440;
if (int > countdown) {
accumulator +=
(int <= 5) ? 10 :
(int <= 10) ? 15 :
(int <= 15) ? 20 :
(int <= 20) ? 30 :
(int <= 25) ? 40 :
(int <= 30) ? 60 :
(int <= 35) ? 80 :
(int <= 40) ? 110 :
(int <= 45) ? 140 :
(int <= 50) ? 180 :
(int <= 55) ? 220 :
(int <= 60) ? 270 :
(int <= 65) ? 320 :
(int <= 70) ? 380 :
440;
}
int--;
}
return accumulator;
}
const calculateTalentXP = (value) => {
let int = parseInt(value);
const calculateTalentXP = (value, free) => {
let int = parseInt(value) + parseInt(free);
let countdown = parseInt(free);
let accumulator = 0;
while (int > 0) {
accumulator += int * 100
if (int > countdown) accumulator += int * 100
int--;
}
@@ -846,21 +946,158 @@ const wfrpModule = ( () => {
}
const recalculateSpentXP = () => {
const attrs = [];
getSectionIDs("careers", id_array => {
helperFunctions.aggregateRepeatingIDs([`careers`, `experience`, `experiencespent`], ids => {
id_array.forEach(id => {
attrs.push(`repeating_careers_${id}_career_xp`);
});
const attrs = [];
for (const id of ids.careers) {
for (const characteristic of wfrp.characteristics) {
attrs.push(`repeating_careers_${id}_career_${characteristic}_advances`);
attrs.push(`repeating_careers_${id}_career_${characteristic}_init`);
}
for (let i = 1; i <= 4; i++) {
for (let j = 1; j <= 10; j++) {
attrs.push(`repeating_careers_${id}_career_skill_${i}_${j}_name`);
attrs.push(`repeating_careers_${id}_career_skill_${i}_${j}_advances`);
attrs.push(`repeating_careers_${id}_career_skill_${i}_${j}_init`);
}
for (let k = 1; k <= 5; k++) {
attrs.push(`repeating_careers_${id}_career_talent_${i}_${k}_name`);
attrs.push(`repeating_careers_${id}_career_talent_${i}_${k}_advances`);
attrs.push(`repeating_careers_${id}_career_talent_${i}_${k}_init`);
}
}
}
for (let i = 1; i <= 10; i++) {
attrs.push(`species_talent_${i}_name`);
attrs.push(`species_talent_${i}_advances`);
}
for (let i = 1; i <= 12; i++) {
attrs.push(`species_skill_${i}_name`);
attrs.push(`species_skill_${i}_advances`);
}
for (const id of ids.experience) {
attrs.push(`repeating_experience_${id}_experience_amount`);
}
console.log(ids.experiencespent)
for (const id of ids.experiencespent) {
attrs.push(`repeating_experiencespent_${id}_experience_amount`);
}
getAttrs(attrs, values => {
const int_values = Object.values(values).map(item => parseInt(item) || 0);
const total_xp = (int_values.length > 0) ? int_values.reduce((a,b) => a+b) : "" || "";
const entries = Object.entries(values).filter(([key, value]) => value !== "");
const characteristic_advances = new Map();
const characteristic_advances_free = new Map();
const skill_advances = new Map();
const skill_advances_free = new Map();
const talent_advances = new Map();
const talent_advances_free = new Map();
for (const id of ids.careers) {
wfrp.characteristics.forEach(characteristic => {
const value = parseInt(values[`repeating_careers_${id}_career_${characteristic}_advances`]) || 0;
const current = characteristic_advances.get(characteristic) || 0;
const total = value + current;
const value_free = parseInt(values[`repeating_careers_${id}_career_${characteristic}_init`]) || 0;
const current_free = characteristic_advances_free.get(characteristic) || 0;
const total_free = value_free + current_free;
characteristic_advances.set(characteristic, total);
characteristic_advances_free.set(characteristic, total_free);
});
for (let i = 1; i <= 4; i++) {
for (let j = 1; j <= 10; j++) {
const skill = values[`repeating_careers_${id}_career_skill_${i}_${j}_name`];
const value = parseInt(values[`repeating_careers_${id}_career_skill_${i}_${j}_advances`]) || 0;
const current = skill_advances.get(skill) || 0;
const total = current + value;
const value_free = parseInt(values[`repeating_careers_${id}_career_skill_${i}_${j}_init`]) || 0;
const current_free = skill_advances_free.get(skill) || 0;
const total_free = current_free + value_free;
skill_advances.set(skill, total);
skill_advances_free.set(skill, total_free);
}
for (let k = 1; k <= 5; k++) {
const talent = values[`repeating_careers_${id}_career_talent_${i}_${k}_name`];
const value = parseInt(values[`repeating_careers_${id}_career_talent_${i}_${k}_advances`]) || 0;
const current = talent_advances.get(talent) || 0;
const total = current + value;
const value_free = parseInt(values[`repeating_careers_${id}_career_talent_${i}_${k}_init`]) || 0;
const current_free = talent_advances_free.get(talent) || 0;
const total_free = current_free + value_free;
talent_advances.set(talent, total);
talent_advances_free.set(talent, total_free);
}
}
}
for (let i = 1; i <= 12; i++) {
const skill = values[`species_skill_${i}_name`];
const value_free = parseInt(values[`species_skill_${i}_advances`]) || 0;
const current_free = skill_advances_free.get(skill) || 0;
const total_free = current_free + value_free;
skill_advances_free.set(skill, total_free);
}
for (let i = 1; i <= 10; i++) {
const talent = values[`species_talent_${i}_name`];
const value_free = parseInt(values[`species_talent_${i}_advances`]) || 0;
const current_free = talent_advances_free.get(talent) || 0;
const total_free = current_free + value_free;
}
let xp = 0;
characteristic_advances.forEach((value, key) => xp += calculateCharacteristicXP(value, characteristic_advances_free.get(key)));
skill_advances.forEach((value, key) => xp += calculateSkillXP(value, skill_advances_free.get(key)));
talent_advances.forEach((value, key) => xp += calculateTalentXP(value, talent_advances_free.get(key)));
console.log(ids.experiencespent)
for (const id of ids.experiencespent) {
const value = parseInt(values[`repeating_experiencespent_${id}_experience_amount`]);
console.log(value)
xp += value;
}
const updateAttrs = {};
updateAttrs[`spent_xp`] = xp;
setAttrs(updateAttrs, recalculateCurrentXP());
setAttrs({spent_xp: total_xp})
});
});
}
const recalculateEarnedXP = () => {
@@ -872,8 +1109,10 @@ const wfrpModule = ( () => {
attrs.push(`repeating_experience_${id}_experience_amount`);
});
attrs.push(`experience_mod`);
getAttrs(attrs, values => {
const int_values = Object.values(values).map(item => parseInt(item) || 0);
const int_values = Object.values(values).map(item => parseInt(item) || 0).filter(item => item > 0);
const total_xp = int_values.reduce((a,b) => a+b, 0);
setAttrs({total_xp: total_xp}, recalculateCurrentXP());
@@ -918,7 +1157,8 @@ const wfrpModule = ( () => {
const attrs = [];
id_array.forEach(id => {
attrs.push(`repeating_careers_${id}_career_${characteristic}_advances`);
attrs.push(`repeating_careers_${id}_career_${characteristic}_advances`);
attrs.push(`repeating_careers_${id}_career_${characteristic}_init`);
});
attrs.push(`${characteristic}_noncareer`);
@@ -954,6 +1194,11 @@ const wfrpModule = ( () => {
attrs.push(`repeating_noncareer-skills_${id}_advance_name`)
attrs.push(`repeating_noncareer-skills_${id}_advance_advances`)
});
for (let i = 1; i <= 12; i++) {
attrs.push(`species_skill_${i}_name`);
attrs.push(`species_skill_${i}_advances`);
}
getAttrs(attrs, values => {
const skill_list = Object.entries(values);
@@ -975,7 +1220,6 @@ const wfrpModule = ( () => {
const updateAttrs = {};
skills.forEach((value, key) => {
let parsed_key = key.replace(/ /g,"-").toLowerCase();
if (wfrp.skills.includes(parsed_key)) {
@@ -1062,10 +1306,15 @@ const wfrpModule = ( () => {
for (let j = 1; j <= 5; j++) {
attrs.push(`repeating_careers_${id}_career_talent_${i}_${j}_name`);
attrs.push(`repeating_careers_${id}_career_talent_${i}_${j}_advances`);
if (index === 1) attrs.push(`repeating_careers_${id}_career_skill_${i}_${j}_init`);
if (index === 0) attrs.push(`repeating_careers_${id}_career_talent_${i}_${j}_init`);
}
}
});
for (let i = 1; i <= 10; i++) {
attrs.push(`species_talent_${i}_name`);
attrs.push(`species_talent_${i}_advances`);
}
getAttrs(attrs, values => {
const talent_list = Object.entries(values);
@@ -1085,7 +1334,6 @@ const wfrpModule = ( () => {
});
talents.forEach((value, key) => {
if (value !== 0) {
getSectionIDs("talent", id_array => {
@@ -1103,29 +1351,33 @@ const wfrpModule = ( () => {
const key_array = Object.keys(values).filter(item => item !== "");
if (value_array_test.includes(key.toLowerCase())) {
const index = value_array_test.indexOf(key.toLowerCase());
let page_name = key.split("(")[0].trim() || key;
if (value_array_test.includes(page_name.toLowerCase())) {
const index = value_array_test.indexOf(page_name.toLowerCase());
const array_key = key_array[index];
const new_key = `${array_key.substring(0, array_key.length-5)}_ranks`;
updateAttrs[new_key] = value;
} else if (value > 0) {
getCompendiumPage(key, page => {
getCompendiumPage(`Talents:${page_name}`, page => {
if (page.expansion !== 0 && page.expansion) {
wfrpDragAndDrop.handleDrop({drop_name:page.name, drop_content:page.content, drop_data:page.data}, key);
if (page.expansion !== 0) {
wfrpDragAndDrop.handleDrop({drop_name:page.name, drop_content:page.content, drop_data:page.data});
} else {
const new_id = generateRowID();
updateAttrs[`repeating_talent_${new_id}_talent_name`] = key;
updateAttrs[`repeating_talent_${new_id}_talent_ranks`] = value;
setAttrs(updateAttrs);
}
});
}
setAttrs(updateAttrs);
});
});
@@ -1163,7 +1415,7 @@ const wfrpModule = ( () => {
getAttrs(attrs, values => {
const spent = Object.values(values).filter(item => item !== "").map(item => parseInt(item));
const total = spent.reduce((a,b) => a+b);
const total = spent.reduce((a,b) => a+b) || 0;
const maximum_allowed = (source_type === "skill") ? 40 : 1;
if (total > maximum_allowed) {
@@ -1526,15 +1778,13 @@ const wfrpModule = ( () => {
.replace(/\)/g, "")
.replace(/ /, "_")
.toLowerCase();
const value = values[type_parsed];
const update = {};
update[`${repeating_id}_attack_target`] = value;
console.log(update)
setAttrs(update);
}
});
@@ -1591,6 +1841,34 @@ const wfrpModule = ( () => {
})
}
const updateNPCButtons = () => {
const attrs = [
"npc",
"dodge",
"endurance",
"intuition",
"perception",
"cool",
...wfrp.characteristics
];
getAttrs(attrs, values => {
if (values[`NPC`] === "0") return;
const update = {};
if (!values[`dodge`]) update[`dodge`] = values[`agility`];
if (!values[`endurance`]) update[`endurance`] = values[`toughness`];
if (!values[`intuition`]) update[`intuition`] = values[`initiative`];
if (!values[`perception`]) update[`perception`] = values[`initiative`];
if (!values[`cool`]) update[`cool`] = values[`willpower`];
setAttrs(update);
});
}
// MODULE INTERFACE
return {
@@ -1603,10 +1881,12 @@ const wfrpModule = ( () => {
toggleRollBonus:toggleRollBonus,
toggleRollCrits:toggleRollCrits,
toggleInitOption:toggleInitOption,
toggleWhisper:toggleWhisper,
parseModField:parseModField,
// Class and Species Controls
changeSpecies:changeSpecies,
checkSpeciesAdvances:checkSpeciesAdvances,
// Characteristic Functions
calculateCharacteristic: calculateCharacteristic,
@@ -1631,6 +1911,7 @@ const wfrpModule = ( () => {
calculateTotalAdvances:calculateTotalAdvances,
recalculateEarnedXP:recalculateEarnedXP,
recalculateCurrentXP:recalculateCurrentXP,
recalculateSpentXP:recalculateSpentXP,
calculateCharacteristicAdvances:calculateCharacteristicAdvances,
calculateSkillAdvances:calculateSkillAdvances,
calculateTalentAdvances:calculateTalentAdvances,
@@ -1656,6 +1937,7 @@ const wfrpModule = ( () => {
// NPC Functions
getAttackValue:getAttackValue,
cascadeNPCAttacks:cascadeNPCAttacks,
updateNPCButtons:updateNPCButtons,
};
})();
@@ -1672,6 +1954,7 @@ on(`change:setting_diff_option`, eventInfo => wfrpModule.toggleRollDifficulty(ev
on(`change:setting_bonus_option`, eventInfo => wfrpModule.toggleRollBonus(eventInfo.newValue));
on(`change:setting_crit_option`, eventInfo => wfrpModule.toggleRollCrits(eventInfo.newValue));
on(`change:setting_init_option`, eventInfo => wfrpModule.toggleInitOption(eventInfo.newValue));
on(`change:setting_whisper`, eventInfo => wfrpModule.toggleWhisper(eventInfo.newValue));
[
"repeating_talent:talent_mods",
@@ -1693,6 +1976,10 @@ on(`clicked:remove_custom_species`, eventInfo => setAttrs({"species":""}));
on(`change:species`, eventInfo => wfrpModule.changeSpecies(eventInfo.newValue));
for (let index = 1; index <= 12; index++) {
on(`change:species_skill_${index}_advances`, eventInfo => wfrpModule.checkSpeciesAdvances());
}
// CHARACTERISTIC CALCULATIONS
wfrpModule.wfrp.characteristics.forEach(characteristic => {
@@ -1756,12 +2043,14 @@ on(`change:repeating_careers:career_level_current`, eventInfo => wfrpModule.upda
// EXPERIENCE CHANGES
on(`change:repeating_experience`, eventInfo => wfrpModule.recalculateEarnedXP());
on(`change:repeating_experience change:repeating_experiencespent change:experience_mod remove:repeating_experiencespent remove:repeating_experience`, eventInfo => wfrpModule.recalculateEarnedXP());
on(`change:current_xp change:spent_xp change:total_xp`, eventInfo => wfrpModule.recalculateCurrentXP());
on(`change:current_xp change:spent_xp change:total_xp remove:repeating_experience`, eventInfo => wfrpModule.recalculateCurrentXP());
on(`change:repeating_experience change:repeating_experiencespent change:experience_mod remove:repeating_experiencespent remove:repeating_experience`, eventInfo => wfrpModule.recalculateSpentXP());
wfrpModule.wfrp.characteristics.forEach(characteristic => {
on(`change:repeating_careers:career_${characteristic}_advances`, eventInfo => wfrpModule.calculateCharacteristicAdvances(characteristic))
on(`change:repeating_careers:career_${characteristic}_advances change:repeating_careers:career_${characteristic}_init`, eventInfo => wfrpModule.calculateCharacteristicAdvances(characteristic))
});
[1,2,3,4].forEach(level => {
@@ -1780,8 +2069,24 @@ wfrpModule.wfrp.characteristics.forEach(characteristic => {
});
});
for (let index = 1; index <= 12; index++) {
on(`clicked:remove_skill_${index}`, eventInfo => setAttrs({[`species_skill_${index}_advances`]:"0"}));
on(`change:species_skill_${index}_advances`, eventInfo => wfrpModule.calculateSkillAdvances());
}
for (let index = 1; index <= 10; index++) {
on(`change:species_talent_${index}_advances`, eventInfo => wfrpModule.calculateTalentAdvances())
};
on(`clicked:combinexp`, eventInfo => wfrpModule.consolidateXP());
on(`clicked:advance`, eventInfo => wfrpModule.advanceXP());
on(`clicked:career_incomplete`, eventInfo => wfrpModule.incompleteCareerXP());
on(`clicked:career_complete`, eventInfo => wfrpModule.completeCareerXP());
on(`change:repeating_noncareer-skills delete:repeating_noncareer-skills`, eventInfo => wfrpModule.calculateSkillAdvances());
on(`change:repeating_careers`, eventInfo => wfrpModule.calculateInitColumns(eventInfo.sourceAttribute, eventInfo.newValue));
@@ -1804,7 +2109,7 @@ on(`change:strength_bonus change:toughness_bonus change:encumbrance_bonus change
on(`change:strength_bonus change:toughness_bonus change:willpower_bonus change:wound_mod change:size`, eventInfo => wfrpModule.calculateMaxWounds());
on(`change:strength_bonus change:toughness_bonus change:encumbrance_bonus`, eventInfo => wfrpModule.calculateMaxEncumbrance());
on(`change:strength_bonus change:toughness_bonus change:encumbrance_mod`, eventInfo => wfrpModule.calculateMaxEncumbrance());
on(`clicked:increment_advantage`, eventInfo => wfrpModule.incrementAdvantage());
@@ -1822,5 +2127,11 @@ on(`change:repeating_attacks:attack_name change:repeating_attacks:attack_type`,
on(`change:weapon_skill change:ballistic_skill`, eventInfo => wfrpModule.cascadeNPCAttacks());
wfrpModule.wfrp.characteristics.forEach(characteristic => {
on(`change:${characteristic} change:${characteristic}_bonus`, eventInfo => wfrpModule.updateNPCButtons())
});
on(`change:npc sheet:opened`, eventInfo => wfrpModule.updateNPCButtons());
//# sourceURL=sheetworkers.js
@@ -66,10 +66,10 @@
const navigation = [
"main",
"careers",
"combat",
"spells",
"settings"
"magic",
"advances",
"settings",
]
const characteristics = [
@@ -4,6 +4,7 @@ include character-field.pug
include characteristic-col.pug
include skill.pug
include skill-grouped.pug
include species.pug
include generic/generic-display.pug
include generic/generic-field.pug
@@ -28,5 +29,6 @@ include repeating/weapon-row.pug
include npc-characteristic-col.pug
include npc-skill.pug
include repeating/npc-attack-row.pug
include repeating/npc-talent-row.pug
include repeating/npc-trait-row.pug
include repeating/npc-opttrait-row.pug
@@ -1,77 +1,77 @@
mixin career-level(level, first)
.wfrp-settings__titlewrap
.wfrp-settings__controlwrap
input(name=`attr_career_level_current`, type="hidden", value="1")
button(data-i18n="Switch", name=`act_newcareerlevel-${level}`, type="action")
span(data-i18n="Current" class=`wfrp-current_level--${level}`)
h2(data-i18n=`Tier ${level}`)
.wfrp-settings__titlewrap
.wfrp-settings__controlwrap
input(name=`attr_career_level_current`, type="hidden", value="1")
button(data-i18n="Switch", name=`act_newcareerlevel-${level}`, type="action")
span(data-i18n="Current" class=`wfrp-current_level--${level}`)
h2(data-i18n=`Level ${level}`)
.wfrp-settings__row--invert
.wfrp-settings__label(data-i18n=`Name`)
input.wfrp-settings__input(name=`attr_career_level${level}_name`, type="text")
.wfrp-settings__row--invert
.wfrp-settings__label(data-i18n=`Name`)
input.wfrp-settings__input(name=`attr_career_level${level}_name`, type="text")
.wfrp-settings__row--invert
.wfrp-settings__label(data-i18n=`Status`)
input.wfrp-settings__input(name=`attr_career_level${level}_status`, type="text")
.wfrp-settings__row--invert
.wfrp-settings__label(data-i18n=`Status`)
input.wfrp-settings__input(name=`attr_career_level${level}_status`, type="text")
.wfrp-settings__col
if (level === 1 && first === true)
.wfrp-settings__row--skillinit
.wfrp-settings__header(data-i18n="Skill Name")
.wfrp-settings__header(data-i18n="Initial")
.wfrp-settings__header(data-i18n="Advances")
else
.wfrp-settings__row--skill
.wfrp-settings__header(data-i18n="Skill Name")
.wfrp-settings__header(data-i18n="Advances")
each skill in [1,2,3,4,5,6,7,8,9,10]
if (level === 1 && first === true)
.wfrp-settings__row--skillinit
input.wfrp-settings__input(data-i18n-placeholder=`Skill ${skill}`, name=`attr_career_skill_${level}_${skill}_name`, type="text")
input.wfrp-settings__input--init(name=`attr_career_skill_${level}_${skill}_init`, type="number")
input.wfrp-settings__input(name=`attr_career_skill_${level}_${skill}_advances`, type="number")
else
.wfrp-settings__row--skill
input.wfrp-settings__input(data-i18n-placeholder=`Skill ${skill}`, name=`attr_career_skill_${level}_${skill}_name`, type="text")
input.wfrp-settings__input(name=`attr_career_skill_${level}_${skill}_advances`, type="number")
.wfrp-settings__col
if (level === 1 && first === true)
.wfrp-settings__row--talentinit
.wfrp-settings__header(data-i18n="Talent Name")
.wfrp-settings__header(data-i18n="Initial")
.wfrp-settings__header(data-i18n="Advances")
else
.wfrp-settings__row--talent
.wfrp-settings__header(data-i18n="Talent Name")
.wfrp-settings__header(data-i18n="Advances")
each talent in [1,2,3,4,5]
if (level === 1 && first === true)
.wfrp-settings__row--talentinit
input.wfrp-settings__input(data-i18n-placeholder=`Talent ${talent}`, name=`attr_career_talent_${level}_${talent}_name`, type="text")
input.wfrp-settings__input(name=`attr_career_talent_${level}_${talent}_init`, type="number")
input.wfrp-settings__input(name=`attr_career_talent_${level}_${talent}_advances`, type="number")
else
.wfrp-settings__row--talent
input.wfrp-settings__input(data-i18n-placeholder=`Talent ${talent}`, name=`attr_career_talent_${level}_${talent}_name`, type="text")
input.wfrp-settings__input(name=`attr_career_talent_${level}_${talent}_advances`, type="number")
.wfrp-settings__col
if (level === 1 && first === true)
.wfrp-settings__row--skillinit
.wfrp-settings__header(data-i18n="Skill Name")
.wfrp-settings__header(data-i18n="Initial")
.wfrp-settings__header(data-i18n="Advances")
else
.wfrp-settings__row--skill
.wfrp-settings__header(data-i18n="Skill Name")
.wfrp-settings__header(data-i18n="Advances")
.wfrp-settings__row
.wfrp-settings__label--full(data-i18n=`Trappings`)
textarea.wfrp-settings__textarea(name=`attr_career_${level}_trappings`)
each skill in [1,2,3,4,5,6,7,8,9,10]
if (level === 1 && first === true)
.wfrp-settings__row--skillinit
input.wfrp-settings__input(data-i18n-placeholder=`Skill ${skill}`, name=`attr_career_skill_${level}_${skill}_name`, type="text")
input.wfrp-settings__input--init(name=`attr_career_skill_${level}_${skill}_init`, type="number")
input.wfrp-settings__input(name=`attr_career_skill_${level}_${skill}_advances`, type="number")
else
.wfrp-settings__row--skill
input.wfrp-settings__input(data-i18n-placeholder=`Skill ${skill}`, name=`attr_career_skill_${level}_${skill}_name`, type="text")
input.wfrp-settings__input(name=`attr_career_skill_${level}_${skill}_advances`, type="number")
.wfrp-settings__col
if (level === 1 && first === true)
.wfrp-settings__row--talentinit
.wfrp-settings__header(data-i18n="Talent Name")
.wfrp-settings__header(data-i18n="Initial")
.wfrp-settings__header(data-i18n="Advances")
else
.wfrp-settings__row--talent
.wfrp-settings__header(data-i18n="Talent Name")
.wfrp-settings__header(data-i18n="Advances")
each talent in [1,2,3,4,5]
if (level === 1 && first === true)
.wfrp-settings__row--talentinit
input.wfrp-settings__input(data-i18n-placeholder=`Talent ${talent}`, name=`attr_career_talent_${level}_${talent}_name`, type="text")
input.wfrp-settings__input(name=`attr_career_talent_${level}_${talent}_init`, type="number")
input.wfrp-settings__input(name=`attr_career_talent_${level}_${talent}_advances`, type="number")
else
.wfrp-settings__row--talent
input.wfrp-settings__input(data-i18n-placeholder=`Talent ${talent}`, name=`attr_career_talent_${level}_${talent}_name`, type="text")
input.wfrp-settings__input(name=`attr_career_talent_${level}_${talent}_advances`, type="number")
.wfrp-settings__row
.wfrp-settings__label--full(data-i18n=`Trappings`)
textarea.wfrp-settings__textarea(name=`attr_career_${level}_trappings`)
mixin careers-row
input(name=`attr_career_settings`, type="hidden", value=1)
@@ -95,7 +95,7 @@ mixin careers-row
.wfrp-careertable__cell--last
span(name=`attr_career_advances`)
.wfrp-conditiontable__row.wfrp-settings.control__hide--condition_settings
.wfrp-careertable__row.wfrp-settings.control__hide--career_settings
.wfrp-settings__row--career_name
input.wfrp-settings__checkbox(name=`attr_career_current`, type="hidden")
@@ -109,6 +109,11 @@ mixin careers-row
h2(data-i18n="Characteristic Advances")
.wfrp-settings__row--characteristics
.wfrp-settings__item
.wfrp_settings__title
.wfrp_settings__title.wfrp-career__characteristic--first(data-i18n="Initial")
.wfrp_settings__title(data-i18n="Advances")
each characteristic in characteristics
-
@@ -119,7 +124,10 @@ mixin careers-row
label.wfrp-settings__label
input.wfrp-settings__checkbox(name=`attr_career_${attr}`, type="checkbox")
span(data-i18n=characteristic.abbreviation)
input.wfrp-settings__input(name=`attr_career_${attr}_advances`, type="number")
div.wfrp-career__characteristic--first
input.wfrp-settings__input(name=`attr_career_${attr}_init`, type="number")
div.wfrp-career__characteristic
input.wfrp-settings__input(name=`attr_career_${attr}_advances`, type="number")
.wfrp-settings__row--span(class=`wfrp-career__row--first`)
@@ -0,0 +1,37 @@
mixin npc-talent-row
input(name=`attr_talent_settings`, type="hidden", value=1)
.wfrp-npctalent__row
.wfrp-npctalent__cell--settingstoggle
+display-toggle(`talent_settings`, true)
.wfrp-npctalent__cell--title
button(type="roll", value=rolls.npctalent)
span(name=`attr_talent_name`)
span(name=`attr_talent_enabled_display`)
span.wfrp-npctalent__ranks(name=`attr_talent_ranks`)
.wfrp-npctalent__cell--description
span(name=`attr_talent_description`)
.wfrp-settings.control__hide--npctalent_settings
.wfrp-settings__row--span
.wfrp-settings__label(data-i18n=`Name`)
input.wfrp-settings__input(name=`attr_talent_name`, type="text")
.wfrp-settings__row
.wfrp-settings__label(data-i18n=`Ranks`)
input.wfrp-settings__input(name=`attr_talent_ranks`, type="number")
.wfrp-settings__row
.wfrp-settings__label(data-i18n=`Max`)
input.wfrp-settings__input(name=`attr_talent_ranks_max`, type="number")
.wfrp-settings__row--span
.wfrp-settings__label(data-i18n=`Modifiers`)
input.wfrp-settings__input(name=`attr_talent_mods`, type="text")
.wfrp-settings__row--span
.wfrp-settings__label--full(data-i18n=`Description`)
textarea.wfrp-settings__textarea(name=`attr_talent_description`)
@@ -40,7 +40,7 @@ mixin weapon-row
-
const all_specs = [...skills.basic[18].specialisations, ...skills.advanced[11].specialisations]
each specialisation in all_specs
option(data-i18n=specialisation)
option(value=specialisation, data-i18n=specialisation)
.wfrp-settings__row
.wfrp-settings__label(data-i18n=`Range`)
@@ -0,0 +1,60 @@
mixin species
input(name=`attr_species_settings`, type="hidden", value=1)
.wfrp-speciestable__row
.wfrp-speciestable__cell--settingstoggle
+display-toggle(`species_settings`, true)
.wfrp-speciestable__cell--title
span(name=`attr_species`)
.wfrp-speciestable__row.wfrp-settings.control__hide--species_settings
.wfrp-settings__row--span
.wfrp-settings__label(data-i18n=`Name`)
.wfrp-settings__wrapper
input.sheet-control__custom(name=`attr_species`, type="hidden")
select.wfrp-settings__select.sheet-control__custom(name=`attr_species`)
each option in character[1].options
option(data-i18n=option)
option(data-i18n="Custom", value="Custom")
.wfrp-header__customwrapper.sheet-control__custom
input.wfrp-header__input(name=`attr_species_custom`, type="text")
button.wfrp-header__hidecustom(name=`act_remove_custom_species`, type="action") ╳
.wfrp-settings__col
input(name="attr_species_disable3", type="hidden", value="0")
input(name="attr_species_disable5", type="hidden", value="0")
.wfrp-settings__row--speciesskill
.wfrp-settings__header(data-i18n="Skill Name")
.wfrp-settings__header +3
.wfrp-settings__header +5
.wfrp-settings__header x
each skill in [1,2,3,4,5,6,7,8,9,10,11,12]
.wfrp-settings__row--speciesskill
input.wfrp-settings__input(data-i18n-placeholder=`Skill ${skill}`, name=`attr_species_skill_${skill}_name`, type="text")
input(name=`attr_species_skill_${skill}_advances`, type="radio", value=3)
input(name=`attr_species_skill_${skill}_advances`, type="radio", value=5)
button.wfrp-header__hidecustom(name=`act_remove_skill_${skill}`, type="action") ╳
.wfrp-settings__col
.wfrp-settings__row--talent
.wfrp-settings__header(data-i18n="Talent Name")
.wfrp-settings__header(data-i18n="Taken")
each talent in [1,2,3,4,5,6,7,8,9,10]
.wfrp-settings__row--talent
input.wfrp-settings__input(data-i18n-placeholder=`Talent ${talent}`, name=`attr_species_talent_${talent}_name`, type="text")
input.wfrp-settings__input(name=`attr_species_talent_${talent}_advances`, type="checkbox", value="1")
@@ -185,6 +185,10 @@
h2.wfrp-npc__subtitle(data-i18n="Traits")
+repeating-section("traits","npc-trait-row")
.wfrp-npctrait
h2.wfrp-npc__subtitle(data-i18n="Talents")
+repeating-section("talent","npc-talent-row")
.wfrp-npctrait
h2.wfrp-npc__subtitle(data-i18n="Optional Traits")
+repeating-section("optional-traits","npc-opttrait-row")
@@ -7,16 +7,21 @@ input(name="attr_setting_button_hide", type="hidden")
+character-field(field)
.wfrp-navigation.wfrp-panel
each item in navigation
-
const settings = (item === "settings") ? "wfrp-navigation__item--settings" : "wfrp-navigation__item";
.wfrp-navigation__roll
label.wfrp-navigation__item
input(name="attr_setting_whisper", type="checkbox", value="2")
span(data-i18n="Whisper to GM")
.wfrp-navigation__items
each item in navigation
-
const settings = (item === "settings") ? "wfrp-navigation__item--settings" : "wfrp-navigation__item";
label(class=settings)
input(name="attr_nav", type="radio", value=item)
if (item === "settings")
span y
else
span=item
label(class=settings)
input(name="attr_nav", type="radio", value=item)
if (item === "settings")
span y
else
span(data-i18n=item)
.wfrp-characteristics.wfrp-panel.page__main
input(name="attr_control_hide--characteristics", type="hidden")
@@ -117,12 +122,12 @@ input(name="attr_setting_button_hide", type="hidden")
.wfrp-corruptiontable__cell--last
+repeating-section("corruption","corruption-row")
.wfrp-ambitions.wfrp-panel.page__main
.wfrp-ambitions.wfrp-panel.page__main--grid
h1.wfrp-panel__header(data-i18n="Ambitions")
each ambition in ambitions
+generic-textarea(ambition.name, "1-25", ambition.attr)
.wfrp-party.wfrp-panel.page__main
.wfrp-party.wfrp-panel.page__main--grid
h1.wfrp-panel__header(data-i18n="Party")
each ambition in party
if (ambition.field === "text")
@@ -130,32 +135,6 @@ input(name="attr_setting_button_hide", type="hidden")
else
+generic-textarea(ambition.name, "1-25", ambition.attr)
.wfrp-careers.wfrp-panel.page__careers
input(name="attr_control_hide--characteristics", type="hidden")
h1.wfrp-panel__header(data-i18n="Careers")
.wfrp-careertable__row--head
.wfrp-careertable__cell(data-i18n="Career")
.wfrp-careertable__cell(data-i18n="Level")
.wfrp-careertable__cell(data-i18n="Status")
.wfrp-careertable__cell--last(data-i18n="Advances")
+repeating-section("careers","careers-row")
.wfrp-experience--alt.page__careers--flex
.wfrp-panel
h1.wfrp-panel__header(data-i18n="Experience")
each field in experience
+generic-display(field, "text", "2-1")
.wfrp-panel.wfrp-panel--awards.page__careers
h1.wfrp-panel__header(data-i18n="Experience Awards")
.wfrp-experiencetable__row--head
.wfrp-experiencetable__cell(data-i18n="Source")
.wfrp-experiencetable__cell--last(data-i18n="XP")
+repeating-section("experience","experience-row")
.wfrp-panel__footer.wfrp-controls
.wfrp-controls__button
button(data-i18n="Consolidate Rewards", name="act_combinexp", type="action")
.wfrp-trappings.page__combat--flex
.wfrp-panel.wfrp-panel--trappings
h1.wfrp-panel__header(data-i18n="Trappings")
@@ -268,11 +247,9 @@ input(name="attr_setting_button_hide", type="hidden")
.wfrp-wounds.wfrp-panel.page__combat
h1.wfrp-panel__header(data-i18n="Wounds")
.wfrp-wounds__current
+generic-field({name:"Current Wounds", attr:"wounds"},"number","2-1")
.wfrp-wounds__max
+generic-display({name:"Max Wounds", attr:"wounds_max"}, "number", "2-1")
input(name="attr_wounds_mod", type="hidden")
+generic-field({name:"Current Wounds", attr:"wounds"},"number","2-1")
+generic-display({name:"Max Wounds", attr:"wounds_max"}, "number", "2-1")
.wfrp-wounds.wfrp-panel.page__combat
h1.wfrp-panel__header(data-i18n="Critical Wounds")
@@ -306,7 +283,7 @@ input(name="attr_setting_button_hide", type="hidden")
.wfrp-weapontable
+repeating-section("weapons","weapon-row")
.wfrp-spells.wfrp-panel.page__spells
.wfrp-spells.wfrp-panel.page__magic
h1.wfrp-panel__header(data-i18n="Spells & Prayers")
.wfrp-spelltable
.wfrp-spelltable__row--head
@@ -322,4 +299,41 @@ input(name="attr_setting_button_hide", type="hidden")
.wfrp-spell__sin
+generic-field({name:"Sin", attr:"sin"}, "number", "1-1")
.wfrp-careers.page__advances--grid
.wfrp-panel
input(name="attr_control_hide--characteristics", type="hidden")
h1.wfrp-panel__header(data-i18n="Careers")
.wfrp-careertable__row--head
.wfrp-careertable__cell(data-i18n="Career")
.wfrp-careertable__cell(data-i18n="Level")
.wfrp-careertable__cell(data-i18n="Status")
.wfrp-careertable__cell--last(data-i18n="Advances")
+repeating-section("careers","careers-row")
.wfrp-panel
input(name="attr_control_hide--characteristics", type="hidden")
h1.wfrp-panel__header(data-i18n="Species")
+species("spells","spell-row")
.wfrp-experience--alt.page__advances--flex
.wfrp-panel
h1.wfrp-panel__header(data-i18n="Experience")
each field in experience
+generic-display(field, "text", "2-1")
.wfrp-panel.wfrp-panel--awards.page__advances
h1.wfrp-panel__header(data-i18n="Experience Awards")
.wfrp-experiencetable__row--head
.wfrp-experiencetable__cell(data-i18n="Source")
.wfrp-experiencetable__cell--last(data-i18n="XP")
+repeating-section("experience","experience-row")
.wfrp-panel__footer.wfrp-controls
.wfrp-controls__button
button(data-i18n="Consolidate Rewards", name="act_combinexp", type="action")
h1.wfrp-panel__header(data-i18n="Experience Spends")
.wfrp-experiencetable__row--head
.wfrp-experiencetable__cell(data-i18n="Use")
.wfrp-experiencetable__cell--last(data-i18n="XP")
+repeating-section("experiencespent","experience-row")
include settings.pug
@@ -68,6 +68,12 @@
option(value="2") 1d10+I
option(value="3") 1d10+IB+AgB
.wfrp-settingstable__row
.wfrp-settingstable__label(data-i18n="Whisper to GM")
select.wfrp-settingstable__select(name="attr_setting_whisper")
option(data-i18n="Off", value="1", selected)
option(data-i18n="On", value="2")
.wfrp-settingspanel.wfrp-panel.page__settings
h1.wfrp-panel__header(data-i18n="Combat Options")
@@ -195,6 +195,17 @@
rolls.npctrait = makeRoll(roll_values)
}
{
const roll_values = {
roll_name: `@{talent_name}`,
roll_type: `Talent`,
roll_text: `@{talent_description}`,
}
rolls.npctalent = makeRoll(roll_values)
}
rolls.combat = {};
["Dodge","Endurance","Intuition","Perception","Cool"].forEach(button => {
@@ -3,7 +3,7 @@ include rolls.pug
include components/_component-index.pug
input(name="attr_sheet_version", type="hidden", value="1.0.1")
input(name="attr_sheet_version", type="hidden", value="1.0.3")
input(name="attr_npc", type="hidden", value="0")
input(name="attr_nav", type="hidden", value="main")
input(name="attr_difficulty_query", type="hidden", value="?{Difficulty|Average (+20), 20|Very Easy (+60), 60|Easy (+40), 40|Average (+20), 20|Challenging (0), 0|Difficult (-10), -10|Hard (-20), -20|Very Hard (-30), -30}")
@@ -16,14 +16,14 @@ input(name="attr_roll_init", type="hidden", value="{{init=[[@{initiative} &{trac
input(name="attr_roll_cs", type="hidden", value="5")
input(name="attr_roll_whisper", type="hidden", value="")
input(name="attr_bar1_v", type="hidden", value="wounds")
input(name="attr_bar1_m", type="hidden", value="wounds")
input(name="attr_bar1_v", type="hidden")
input(name="attr_bar1_m", type="hidden")
input(name="attr_bar1_l", type="hidden")
input(name="attr_bar2_v", type="hidden")
input(name="attr_bar2_m", type="hidden")
input(name="attr_bar2_l", type="hidden")
input(name="attr_bar3_v", type="hidden")
input(name="attr_bar3_m", type="hidden", value="toughness_bonus")
input(name="attr_bar3_m", type="hidden")
input(name="attr_bar3_l", type="hidden")
.wfrp-wrapper.compendium-drop-target.monsters
@@ -40,8 +40,38 @@
@extend .sheet-wfrp-settings__row;
grid-column: 1 / -1;
grid-template-columns: repeat(10, 1fr);
gap: $margin-general;
grid-template-columns: 1.5fr repeat(10, 1fr);
> * {
display: grid;
grid-auto-rows: 2rem;
border-right: 1px solid #000;
&:last-child {
border: none;
}
> div {
border-bottom: 1px solid #000;
&:last-child {
border: none;
}
}
}
input[type="number"],
input[type="text"] {
border-radius: 0 !important;
&:last-child {
border: none;
}
}
label {
border-bottom: 1px solid #000;
}
}
@@ -59,6 +89,19 @@
margin-bottom: 3px;
}
&--speciesskill {
@extend .sheet-wfrp-settings__row;
grid-template-columns: 1fr .15fr .15fr .15fr;
gap: 3px;
margin-bottom: 3px;
> button {
justify-self: center;
text-align: center;
}
}
&--skillinit,
&--talentinit {
@extend .sheet-wfrp-settings__row;
@@ -108,7 +151,7 @@
input[type="hidden"][value="on"] {
& ~ input.sheet-wfrp-settings__input.sheet-wfrp-settings__input[type="number"] {
& ~ * input.sheet-wfrp-settings__input.sheet-wfrp-settings__input[type="number"] {
pointer-events: auto;
background: $form-input-background;
@@ -119,7 +162,7 @@
input[type="hidden"][value="1"] {
& ~ input.sheet-wfrp-settings__input.sheet-wfrp-settings__input[type="number"] {
& ~ * input.sheet-wfrp-settings__input.sheet-wfrp-settings__input[type="number"] {
pointer-events: auto;
background: $form-input-background;
@@ -130,7 +173,7 @@
input[type="hidden"][value="2"] {
& ~ input.sheet-wfrp-settings__input.sheet-wfrp-settings__input[type="number"] {
& ~ * input.sheet-wfrp-settings__input.sheet-wfrp-settings__input[type="number"] {
pointer-events: auto;
background: rgba(darkgoldenrod, 0.25);
@@ -141,7 +184,7 @@
input[type="hidden"][value="3"] {
& ~ input.sheet-wfrp-settings__input.sheet-wfrp-settings__input[type="number"] {
& ~ * input.sheet-wfrp-settings__input.sheet-wfrp-settings__input[type="number"] {
pointer-events: auto;
background: rgba(silver, 0.25);
@@ -152,7 +195,7 @@
input[type="hidden"][value="4"] {
& ~ input.sheet-wfrp-settings__input.sheet-wfrp-settings__input[type="number"] {
& ~ * input.sheet-wfrp-settings__input.sheet-wfrp-settings__input[type="number"] {
pointer-events: auto;
background: rgba(gold, 0.25);
@@ -104,7 +104,7 @@ input.sheet-control__custom[value*=Custom] {
// Talent Setting Control
@each $block in "talent", "condition", "psychology", "corruption", "critical" {
@each $block in "talent", "condition", "psychology", "corruption", "critical", "career", "species" {
.sheet-control__hide--#{$block}_settings {
@extend %hide;
}
@@ -114,7 +114,7 @@ input.sheet-control__custom[value*=Custom] {
}
input[name*="settings"] {
@each $block in "talent", "condition", "psychology", "corruption", "critical" {
@each $block in "talent", "condition", "psychology", "corruption", "critical", "career", "species" {
&[value="1"] + div > .sheet-control__hide--#{$block}_settings {
@extend %show-grid;
}
@@ -241,7 +241,7 @@ input[name*=setting_button_hide] {
// NPC Settings Control
@each $block in "npcattack", "npctrait" {
@each $block in "npcattack", "npctrait", "npctalent" {
.sheet-control__hide--#{$block}_settings {
@extend %hide;
}
@@ -251,7 +251,7 @@ input[name*=setting_button_hide] {
}
input[name*="settings"] {
@each $block in "npcattack", "npctrait" {
@each $block in "npcattack", "npctrait", "npctalent" {
&[value="1"] + div > .sheet-control__hide--#{$block}_settings {
@extend %show-grid;
}
@@ -328,4 +328,26 @@ input[name*="trapping_flag"][value="on"] + .sheet-wfrp-npctrappings {
.sheet-wfrp-wrapper.active-drop-target.dropping .sheet-wfrp-compendium_warning {
display: block;
}
input[type="hidden"][name*="species_disable3"]{
&[value="1"] {
& ~ * input[type="radio"][value="3"]:not(:checked) {
pointer-events: none;
opacity: .5;
}
}
}
input[type="hidden"][name*="species_disable5"]{
&[value="1"] {
& ~ * input[type="radio"][value="5"]:not(:checked) {
pointer-events: none;
opacity: .5;
}
}
}
@@ -1,9 +1,9 @@
.sheet-wfrp-wrapper {
.sheet-page__main,
.sheet-page__careers,
.sheet-page__advances,
.sheet-page__combat,
.sheet-page__spells,
.sheet-page__magic,
.sheet-page__settings {
display: none;
@@ -18,9 +18,9 @@
input[type="hidden"][name="attr_nav"] {
&[value="main"] ~ * .sheet-page__main,
&[value="careers"] ~ * .sheet-page__careers,
&[value="advances"] ~ * .sheet-page__advances,
&[value="combat"] ~ * .sheet-page__combat,
&[value="spells"] ~ * .sheet-page__spells,
&[value="magic"] ~ * .sheet-page__magic,
&[value="settings"] ~ * .sheet-page__settings {
display: block;
@@ -299,11 +299,13 @@
}
}
&talent,
&trait,
&attack {
font-family: $font-family-alt;
.repitem:first-child .sheet-wfrp-npctalent__row,
.repitem:first-child .sheet-wfrp-npctrait__row,
.repitem:first-child .sheet-wfrp-npcattack__row {
padding-top: 0;
@@ -352,6 +354,29 @@
}
}
&__ranks {
display: inline-flex;
flex-direction: row;
margin-left: .35em;
&:not(:empty) {
&:before,
&:after {
display: block;
}
&:before {
content: "(";
}
&:after {
content: ")";
}
}
}
&__label {
margin-right: .33rem;
@@ -229,7 +229,8 @@
// CAREERS
&-experiencetable,
&-careertable {
&-careertable,
&-speciestable {
&__row {
@extend %row;
@@ -258,6 +259,11 @@
@extend %cell;
}
&--ltitle {
@extend %cell;
text-align: left;
}
&--span2 {
grid-column: span 2;
}
@@ -1,18 +1,40 @@
.sheet-wfrp {
&-navigation {
display: flex;
align-items: center;
justify-content: end;
display: grid;
grid-template-columns: 1fr 1fr;
label {
width: auto;
margin: $margin-general;
&__roll {
display: flex;
align-items: center;
justify-content: start;
cursor: pointer;
label {
width: auto;
margin: $margin-general;
input {
display: none;
cursor: pointer;
input[type="checkbox"] {
display: none;
}
}
}
&__items {
display: flex;
align-items: center;
justify-content: end;
label {
width: auto;
margin: $margin-general;
cursor: pointer;
input {
display: none;
}
}
}
}
@@ -45,7 +45,10 @@
}
&-ambitions {
grid-column: span 3;
grid-column: span 3;
display: grid;
grid-template-rows: 2.5rem auto;
}
&-party {
@@ -98,6 +101,11 @@
}
&-career {
&__characteristic--first {
display: none;
}
&__row {
display: grid;
grid-template-columns: 1fr 1fr;
@@ -126,6 +134,8 @@
&-careers {
grid-column: 1 / span 4;
display: grid;
grid-template-rows: 1fr minmax(5rem, auto);
+ .sheet-wfrp-experience {
grid-column: span 2;
@@ -137,6 +147,14 @@
display: grid;
}
& .sheet-wfrp-career__characteristic--first {
display: grid;
}
& .sheet-wfrp-career__row--1 {
display: none;
}
& .sheet-wfrp-career__row--1 {
display: none;
}
@@ -75,7 +75,7 @@
}
}
@each $table in "skill", "talent", "condition", "psychology", "corruption", "trapping", "armour", "critical", "weapon", "spell", "career", "experience" {
@each $table in "skill", "talent", "condition", "psychology", "corruption", "trapping", "armour", "critical", "weapon", "spell", "career", "experience", "wounds" {
.sheet-wfrp-#{$table}table__row--head {
@extend %grid-row-head;
@@ -2,6 +2,7 @@
&__item {
input[type="checkbox"],
input[type="radio"] {
&:checked + span {
@@ -16,6 +16,12 @@
border-radius: 3px;
}
&--noborder {
@extend .sheet-wfrp-settings;
border: 0;
}
&__header {
margin-top: $margin-general;
border-bottom: $grid-border;
@@ -30,7 +36,6 @@
&__label {
span {
display: block;
border-bottom: $grid-border;
}
}
}
@@ -254,10 +254,10 @@
"Notes":"Notes",
"Characteristic Advances":"Characteristic Advances",
"Current Career":"Current Career",
"Tier 1":"Tier 1",
"Tier 2":"Tier 2",
"Tier 3":"Tier 3",
"Tier 4":"Tier 4",
"Level 1":"Level 1",
"Level 2":"Level 2",
"Level 3":"Level 3",
"Level 4":"Level 4",
"Skill 1":"Skill 1",
"Skill 2":"Skill 2",
"Skill 3":"Skill 3",
@@ -268,11 +268,18 @@
"Skill 8":"Skill 8",
"Skill 9":"Skill 9",
"Skill 10":"Skill 10",
"Skill 11":"Skill 11",
"Skill 12":"Skill 12",
"Talent 1":"Talent 1",
"Talent 2":"Talent 2",
"Talent 3":"Talent 3",
"Talent 4":"Talent 4",
"Talent 5":"Talent 5",
"Talent 6":"Talent 6",
"Talent 7":"Talent 7",
"Talent 8":"Talent 8",
"Talent 9":"Talent 9",
"Talent 10":"Talent 10",
"Skill Name":"Skill Name",
"Talent Name":"Talent Name",
"Experience Awards":"Experience Awards",
@@ -366,5 +373,37 @@
"Ranged (Entangling)":"Ranged (Entangling)",
"Ranged (Explosives)":"Ranged (Explosives)",
"Ranged (Sling)":"Ranged (Sling)",
"Ranged (Throwing)":"Ranged (Throwing)"
"Ranged (Throwing)":"Ranged (Throwing)",
"Taken":"Taken",
"main":"main",
"combat":"combat",
"magic":"magic",
"advances":"advances",
"Experience Spends":"Experience Spends",
"Use":"Use",
"Advance Career Tier":"Advance Career Tier",
"Change Career (Incomplete)":"Change Career (Incomplete)",
"Change Career (Complete)":"Change Career (Complete)",
"settings_npc":"NPC",
"settings_npc_desc":"The NPC option sets new characters to default to the NPC card style sheet. Useful if the player characters have already been created and all new character sheets added to the game will likely represent non player characters.",
"setting_whisper":"Whisper Rolls to GM",
"settings_whisper_desc":"All sheet rolls are sent to all players in chat by default. If enabled, rolls from this sheet will be visible only to the GM.",
"setting_diff_option":"Query Difficulty",
"settings_difficulty_desc":"This will enable or disable the difficulty query window when rolls are made. When off, all rolls are made at the base target number.",
"settings_bonuses":"Query Bonuses",
"settings_bonuses_desc":"This will enable or disable the additional bonus and SL bonus windows when rolls are made.",
"settings_auto":"Automatic Success & Failure",
"settings_auto_desc":"This will change the boundaries for automatic success and failure on a roll. The default boundaries set the automatic success point at 01-05 and 96-100.",
"settings_initiative":"Initiative Roll",
"settings_initiative_desc":"This changes the way initiative will be sent to the turn tracker. In the default setting, a character's whole initiative characteristic will be sent to the turntracker. When using the other options, a d10 will be rolled and different configurations of characteristic bonuses will be added to it.",
"settings_maxadvantage":"Max Advantage",
"settings_bar1_value":"BAR 1 VALUE",
"settings_bar1_max":"BAR 1 MAX",
"settings_bar1_link":"BAR 1 LINK",
"settings_bar2_value":"BAR 2 VALUE",
"settings_bar2_max":"BAR 2 MAX",
"settings_bar2_link":"BAR 2 LINK",
"settings_bar3_value":"BAR 3 VALUE",
"settings_bar3_max":"BAR 3 MAX",
"settings_bar3_link":"BAR 3 LINK"
}
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff