Revert "Pendragon 3.0 by Chaosium"

This commit is contained in:
Nora Cahill
2024-08-02 22:29:12 -07:00
committed by GitHub
parent c12c153c57
commit 4e9f888fec
40 changed files with 282 additions and 1467 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "pendragon6thedition",
"version": "3.0.0",
"version": "2.4.2",
"description": "You need to run npm start to get the compilers going.",
"dependencies": {
"20": "^3.1.9",
+50 -61
View File
@@ -393,9 +393,9 @@ div.sheet-attacks input[name="attr_damage"],
div.sheet-attacks span[name*="damage"] {
text-align: center; }
div.sheet-attacks div.sheet-table.sheet-damage div.sheet-header,
div.sheet-attacks div.sheet-table.sheet-damage div.sheet-body div.sheet-row {
grid-template-columns: 2fr 1fr 2.5em; }
div.sheet-attacks div.sheet-table.sheet-brawling div.sheet-header,
div.sheet-attacks div.sheet-table.sheet-brawling div.sheet-body div.sheet-row {
grid-template-columns: 2fr 1fr 5em 2.5em; }
div.sheet-attacks div.sheet-repeating-container div.sheet-row,
div.sheet-attacks div.sheet-repeating-container div.sheet-header {
@@ -407,14 +407,6 @@ div.sheet-attacks label[data-i18n-title="other skill"] {
div.sheet-attacks input[name="attr_skill"][value*="other"] + label {
visibility: visible; }
div.sheet-attacks select[name="attr_skill"] {
margin-left: -5px; }
div.sheet-attacks h3,
div.sheet-attacks span[data-i18n*="brawling"],
div.sheet-attacks span[name*="damage"] {
color: #000; }
div.sheet-character div.sheet-horse input[type="text"],
div.sheet-character div.sheet-horse input[type="number"] {
text-align: center;
@@ -473,22 +465,8 @@ div.sheet-character div.sheet-squire div.sheet-skill {
div.sheet-character div.sheet-squire input[name="attr_squire_age"] {
text-align: center; }
div.sheet-character div.sheet-squire div.sheet-notes {
grid-template-columns: 1fr 10px;
padding: 1% 2%; }
div.sheet-character div.sheet-squire div.sheet-notes input.sheet-flag,
div.sheet-character div.sheet-squire div.sheet-notes span.sheet-pictos {
grid-area: 1/2/2/3; }
div.sheet-character div.sheet-squire div.sheet-notes textarea,
div.sheet-character div.sheet-squire div.sheet-notes span.sheet-display {
grid-area: 1/1/2/2; }
div.sheet-character div.sheet-equipment span[name="attr_value"],
div.sheet-character div.sheet-equipment input[name="attr_value"] {
text-align: center; }
div.sheet-character div.sheet-equipment div.sheet-col {
grid-template-rows: min-content 1fr; }
div.sheet-character div.sheet-equipment input[name="attr_category"] {
font-weight: bold; }
div.sheet-character div.sheet-equipment div.sheet-2autocolumn {
align-content: end; }
@@ -497,9 +475,6 @@ div.sheet-character div.sheet-equipment span[name="attr_equipment"],
div.sheet-character div.sheet-equipment span[name="attr_category"] {
min-height: 20px; }
div.sheet-character div.sheet-equipment div.sheet-category {
grid-template-columns: 3fr 1fr; }
div.sheet-character div.sheet-equipment div.sheet-repeating-container div.sheet-flags {
grid-template-columns: 1fr 25px; }
@@ -520,9 +495,6 @@ div.sheet-character div.sheet-characteristics div.sheet-core {
grid-auto-flow: column;
grid-column-gap: 2%; }
div.sheet-character div.sheet-characteristics span {
color: #000; }
div.sheet-character h2 {
text-overflow: ellipsis;
width: fit-content; }
@@ -807,18 +779,25 @@ div.sheet-table {
/* TABLE
============================= */
div.sheet-shield {
border-radius: 50% 50% 50% 50% / 12% 12% 88% 88%;
border: 5px solid #240202;
height: 50px;
width: 50px; }
width: 50px;
border: 5px solid #240202;
border-radius: 50% 50% 50% 50% / 12% 12% 88% 88%; }
div.sheet-shield label,
div.sheet-shield span {
align-items: center;
display: grid;
font-weight: bold;
height: 100%;
justify-content: center;
text-align: center;
width: 100%; }
div.sheet-shield:hover span,
div.sheet-shield input[type="number"] {
font-weight: bolder;
width: 3em; }
div.sheet-shield input[type="number"]:placeholder-shown, div.sheet-shield input[type="number"]:hover {
background-color: #fffde7; }
div.sheet-shield input[type="number"]::-webkit-outer-spin-button, div.sheet-shield input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0; }
display: none; }
div.sheet-shield:hover input[type="number"] {
display: inline;
background-color: #fffde7; }
/* ROLL TEMPLATE STYLE
----------------------------- */
@@ -927,33 +906,43 @@ div.sheet-repeating-container div.sheet-notes {
font-family: "pictos";
z-index: 100;
position: absolute;
right: 1.5%; }
left: 85%; }
/* DRAG & DROP
============================= */
.sheet-dropzone.active-drop-target.dropping {
opacity: 0.5;
transition: opacity 0.15s ease-in-out;
-moz-transition: opacity 0.15s ease-in-out;
-webkit-transition: opacity 0.15s ease-in-out;
background-color: transparent;
opacity: 0.5;
transition: opacity 0.15s ease-in-out; }
background-color: transparent; }
.sheet-compendium_warning {
.sheet-compendium_warning,
.sheet-monster_confirm {
display: none; }
.sheet-dropzone.active-drop-target.dropping ~ .sheet-compendium_warning {
position: absolute;
background: white;
border-radius: 0.5em;
border: 2px solid #000;
box-shadow: 0 0 50px #000;
.sheet-dropzone.active-drop-target.dropping ~ .sheet-compendium_warning,
.sheet-monster_confirm_flag[value="1"] ~ .sheet-monster_confirm {
display: block;
height: 100px;
left: 50%;
margin: -70px 0 0 -170px;
min-height: max-content;
padding: 2em;
text-align: center;
position: fixed;
top: 50%;
background: white;
left: 50%;
z-index: 100;
border: 2px solid black;
width: 300px;
z-index: 100; }
height: 100px;
text-align: center;
margin: -70px 0 0 -170px; }
.charsheet input.sheet-licensedsheet[value="1"] ~ .sheet-compendium_warning,
.charsheet input.sheet-licensedsheet[value="1"] ~ .sheet-monster_confirm {
position: absolute !important;
padding: 2em 0 !important;
min-height: max-content;
box-shadow: 0 0 50px #000;
border: 2px solid #000 !important;
border-radius: 0.5em; }
.sheet-dropzone.active-drop-target.dropping ~ .sheet-compendium_warning span {
line-height: 100px; }
File diff suppressed because one or more lines are too long
@@ -1,16 +0,0 @@
const getRepUpdate = (attrs, row, page) => {
let update = {};
attrs.forEach((attr) => {
if (page?.[attr] ?? page?.data?.[attr]) {
update[`${row}_${attr}`] =
page[attr] ?? roll20Attribute(attr, page.data[attr]);
}
});
if (attrs.includes("notes")) {
update[`${row}_flag`] = false;
}
return update;
};
@@ -1,24 +0,0 @@
const handle_horse = (page) => {
const attrs = [
"armor",
"charge_damage",
"con",
"damage",
"dex",
"hp",
"move",
"siz",
"str",
"type",
];
const warHorseAttrs = attrs.map((attr) => `warhorse_${attr}`);
let update = getStaticUpdate([...warHorseAttrs, "equestrian_notes"], page);
update["warhorse_type"] = page.name;
update["flag_equestrian_notes"] = false;
if (!update["warhorse_charge_damage"]) {
update["warhorse_charge_damage"] = "0";
}
setAttrs(update);
};
@@ -1,4 +0,0 @@
const handle_item = (page, row) => {
const update = update_item(page, row);
setAttrs(update);
};
@@ -1,7 +0,0 @@
const handle_squire = (page) => {
const attrs = ["squire_age", "squire_skill", "squire_notes"];
const update = getStaticUpdate(attrs, page);
update["squire_name"] = page.name;
update["flag_squire_notes"] = false;
setAttrs(update);
};
@@ -1,4 +0,0 @@
const handle_weapon = (page) => {
const update = update_attack(page);
setAttrs(update);
};
@@ -1,28 +0,0 @@
const parseJSON = (jsonString) => {
try {
return JSON.parse(jsonString);
} catch (e) {
console.log(`Error parsing JSON: ${jsonString}`);
return undefined;
}
};
const processDataArrays = (array, callback) => {
const parsed = typeof array === "string" ? parseJSON(array) : array;
const map = parsed.map((e) => callback(e));
return map.reduce((acc, val) => ({ ...acc, ...val }));
};
const getRow = (section) => `repeating_${section}_${generateRowID()}`;
const getStaticUpdate = (attrs, page) => {
let update = {};
attrs.forEach((attr) => {
if (page?.[attr] ?? page?.data?.[attr]) {
update[attr] = page[attr] ?? roll20Attribute(attr, page.data[attr]);
}
});
return update;
};
@@ -1,9 +0,0 @@
const resetRepeatingRows = (sections) => {
sections.forEach((section) => {
getSectionIDs(`repeating_${section}`, (ids) => {
ids.forEach((id) => {
removeRepeatingRow(`repeating_${section}_${id}`);
});
});
});
};
@@ -1,13 +0,0 @@
const resetSkillList = (skills) => {
const skillList = parseJSON(skills);
const names = skillList.map(({ name }) => name.toLowerCase());
const update = {};
[...skills, ...combatSkills].forEach((skill) => {
if (!names.includes(skill)) {
update[skill] = 0;
}
});
setAttrs(update);
};
@@ -1,7 +0,0 @@
const roll20Attribute = (attr, value) => {
if (attr === "skill") {
return `@{${attrName(value)}}`;
}
return value;
};
@@ -1,44 +0,0 @@
const update_attack = (page) => {
const row = getRow("attacks");
const attrs = ["name", "skill"];
const { damage, damage_type } = page.data;
const update = getRepUpdate(attrs, row, page);
const type = damage_type.toLowerCase();
const modifier = damage ? `+${damage}` : "";
if (["brawling", "character"].includes(type)) {
const attr = `${type}_damage`;
getAttrs([attr], (v) => {
if (v) {
setAttrs({ [`${row}_damage`]: `${v[attr]}${modifier}` });
} else {
dropWarning(`Unknown damage type: ${damage_type}`);
}
});
} else if (["horse"].includes(type)) {
getAttrs(
["warhorse_charge_damage", "warhorse_damage"],
({ warhorse_charge_damage, warhorse_damage }) => {
if (warhorse_charge_damage || warhorse_damage) {
const damage = warhorse_charge_damage || warhorse_damage;
setAttrs({
[`${row}_damage`]: `${damage}${modifier}`,
});
} else {
dropWarning(`Could not get values for warhorse damage`);
}
}
);
} else if (damage) {
update[`${row}_damage`] = damage;
}
console.table({
type,
});
return update;
};
@@ -1,13 +0,0 @@
const update_item = (page, row) => {
let update = getRepUpdate(
["name", "value", "notes", "period_restriction"],
row,
page
);
if (page?.data?.["subcategory"]) {
update[`${row}_category`] = page.data["subcategory"];
}
return update;
};
@@ -1,5 +0,0 @@
const update_section = (page, section) => {
const row = getRow(section);
const attrs = ["name", "target_value"];
return getRepUpdate(attrs, row, page);
};
-210
View File
@@ -1,210 +0,0 @@
const dropWarning = (v) => {
console.log(
`%c Pendragon 6th Edition: ${v}`,
"color: orange; font-weight:bold"
);
};
const handle_npc = (page) => {
const attrs = [
"size",
"dexterity",
"strength",
"constitution",
"appearance",
"type",
"hit_points",
"knockdown",
"major_wound",
"unconscious",
"movement",
"armor_points",
"current_glory",
"healing_rate",
"glory_award",
"description",
];
let update = getStaticUpdate(attrs, page);
update["character_name"] = page.name;
//TODO: handle all repeating sections
};
const handle_equipment = (page) => handle_item(page, getRow("equipment"));
const handle_arms = (page) => handle_item(page, getRow("arms"));
const handle_character = (page) => {
const attrs = [
"appearance",
"armor_points",
"constitution",
"dexterity",
"healing_rate",
"hit_points",
"knockdown",
"major_wound",
"movement",
"size",
"strength",
"unconscious",
"squire_name",
"squire_age",
"squire_skill",
"squire_note",
];
const update = getStaticUpdate(attrs, page);
update["character_name"] = page.name;
const addEntries = (object) => {
Object.entries(object).forEach(([key, value]) => {
update[key] = value;
});
};
const arms = processDataArrays(page.data.arms, (data) =>
update_item(data, getRow("arms"))
);
addEntries(arms);
const attacks = processDataArrays(page.data.attacks, (data) =>
update_attack(data)
);
addEntries(attacks);
const updateSection = (section) => {
return (data) => update_section(data, section);
};
const passions = processDataArrays(
page.data.passions,
updateSection("passions")
);
addEntries(passions);
const dataSkills = parseJSON(page.data.skills);
dataSkills.forEach(({ name, target_value }) => {
const isStaticSkill = [...skills, ...combatSkills].includes(
name.toLowerCase()
);
if (isStaticSkill) {
update[attrName(name)] = target_value;
} else {
const custom = processDataArrays(
[{ name, target_value }],
updateSection("skills")
);
addEntries(custom);
}
});
const dataTraits = parseJSON(page.data.traits);
dataTraits.forEach(({ name, target_value }) => {
const isStaticTrait = traits.includes(name.toLowerCase());
if (isStaticTrait) {
update[attrName(name)] = target_value;
} else {
const custom = processDataArrays(
[{ name, target_value }],
updateSection("traits")
);
addEntries(custom);
}
});
if (page.data.squire_notes) {
update["flag_squire_notes"] = false;
}
setAttrs(update, {
silent: true,
});
};
const handle_items = (page) => {
const subcategory = page.data["subcategory"];
switch (subcategory) {
case "Armor":
handle_arms(page);
break;
case "Animal":
case "Service":
case "Item":
handle_equipment(page);
break;
case "Shield":
handle_arms(page);
break;
case "Horse Armor":
handle_arms(page);
break;
case "Ranged Weapon":
case "Weapon":
handle_weapon(page);
handle_arms(page);
break;
default:
dropWarning(`Unknown subcategory: ${subcategory}`);
}
};
const dropAttrs = ["drop_name", "drop_data", "drop_content"];
const handle_drop = () => {
getAttrs(dropAttrs, (v) => {
if (!v.drop_name || !v.drop_data) {
return;
}
const page = {
name: v.drop_name,
data: parseJSON(v.drop_data) ?? v.drop_data,
content: v.drop_content,
};
const { Category } = page.data;
switch (Category) {
case "Creatures":
handle_npc(page);
break;
case "Horses":
handle_horse(page);
break;
case "Items":
handle_items(page);
break;
case "Squires":
handle_squire(page);
break;
case "Pre-generated Characters":
resetRepeatingRows(repeatingSections);
resetSkillList(page.data.skills);
handle_character(page);
break;
default:
dropWarning(`Unknown category: ${Category}`);
}
setAttrs(
{
drop_name: "",
drop_data: "",
drop_content: "",
},
{
silent: true,
}
);
});
};
["data"].forEach((attr) => {
on(`change:drop_${attr}`, () => {
handle_drop();
});
});
+39 -43
View File
@@ -1,44 +1,40 @@
const convertIntegerNegative = (number) =>
number > 0 ? -Math.abs(number) : number;
const convertIntegersNegatives = (numbers) => {
for (let [key, value] of Object.entries(numbers)) {
numbers[key] = convertIntegerNegative(value);
}
return numbers;
const helpers = {
convertIntegerNegative: (number) => (number > 0 ? -Math.abs(number) : number),
convertIntegersNegatives: (numbers) => {
for (let [key, value] of Object.entries(numbers)) {
numbers[key] = helpers.convertIntegerNegative(value);
}
return numbers;
},
findRepeatingField: (trigger) => trigger.split("_")[1],
getReprowid: (trigger) => {
const split = trigger.split("_");
return `${split[0]}_${split[1]}_${split[2]}`;
},
getReprowAttribute: (key) => {
const getReprowid = helpers.getReprowid(key);
return key.split(`${getReprowid}_`)[1];
},
getTranslations: (translationKeys) => {
let translations = {};
translationKeys.forEach(
(key) => (translations[`${key}`] = getTranslationByKey(key))
);
return translations;
},
parseInteger: (string) => parseFloat(string) || 0,
parseIntegers: (numbers) => {
for (let [key, value] of Object.entries(numbers)) {
numbers[key] = parseFloat(value) || 0;
}
return numbers;
},
setcharacteristics: (update, silent) =>
silent && typeof update === "object"
? setAttrs(update, { silent: true })
: typeof update === "object"
? setAttrs(update)
: console.error(`${update} is not an object`),
sliceAttr: (attribute) => attribute.slice(2, -1),
sumIntegers: (numbers) => numbers.reduce((a, b) => a + b, 0),
};
const findRepeatingField = (trigger) => trigger.split("_")[1];
const getReprowid = (trigger) => {
const split = trigger.split("_");
return `${split[0]}_${split[1]}_${split[2]}`;
};
const getReprowAttribute = (key) => {
const reprowid = getReprowid(key);
return key.split(`${reprowid}_`)[1];
};
const getTranslations = (translationKeys) => {
let translations = {};
translationKeys.forEach(
(key) => (translations[`${key}`] = getTranslationByKey(key))
);
return translations;
};
const parseInteger = (string) => parseFloat(string) || 0;
const parseIntegers = (numbers) => {
for (let [key, value] of Object.entries(numbers)) {
numbers[key] = parseFloat(value) || 0;
}
return numbers;
};
const sliceAttr = (attribute) => attribute.slice(2, -1);
const sumIntegers = (numbers) => numbers.reduce((a, b) => a + b, 0);
const attrName = (name) => name.replace(/ /g, "_").toLowerCase();
+13 -4
View File
@@ -1,3 +1,13 @@
const characteristics = {
movement: ["strength", "dexterity"],
hp: ["size", "constitution"],
unconscious: ["hit_points"],
knockdown: ["size"],
majorWound: ["constitution"],
healingRate: ["constitution"],
brawlDamage: ["strength", "size"],
};
//When performing calculations in King Arthur Pendragon, round
//0.5 and higher fractions upward and lesser fractions downward.
//For example, a character with a Damage value of 4.43 would
@@ -13,7 +23,6 @@ const updateBrawling = () => {
//Brawl Damage = (STR+SIZ)/6
const damage = round(total(values) / 6);
return {
character_damage: `${damage}D6`,
brawling_damage: `${damage}`,
brawling_damage_open: `${round(damage / 2)}`,
};
@@ -94,7 +103,7 @@ on(`change:sheet_select`, ({ newValue }) => {
});
on(`change:repeating_events:new_glory`, ({ triggerName }) => {
const repeatingRow = getReprowid(triggerName);
const repeatingRow = helpers.getReprowid(triggerName);
getSectionIDs("events", (idArray) => {
let characteristics = [];
@@ -103,9 +112,9 @@ on(`change:repeating_events:new_glory`, ({ triggerName }) => {
);
getAttrs(characteristics, (values) => {
const parsedNums = parseIntegers(values);
const parsedNums = helpers.parseIntegers(values);
const gloryValues = Object.values(parsedNums);
const sum = sumIntegers(gloryValues);
const sum = helpers.sumIntegers(gloryValues);
setAttrs({
glory_total: sum,
-76
View File
@@ -1,76 +0,0 @@
const characteristics = {
movement: ["strength", "dexterity"],
hp: ["size", "constitution"],
unconscious: ["hit_points"],
knockdown: ["size"],
majorWound: ["constitution"],
healingRate: ["constitution"],
brawlDamage: ["strength", "size"],
};
const repeatingSections = [
"equipment",
"arms",
"attacks",
"passions",
"skills",
"traits",
];
const personalityTraits = {
chaste: "lustful",
energetic: "lazy",
forgiving: "vengeful",
generous: "selfish",
honest: "deceitful",
just: "arbitrary",
merciful: "cruel",
modest: "proud",
prudent: "reckless",
spiritual: "worldly",
temperate: "indulgent",
trusting: "suspicious",
valorous: "cowardly",
};
const traits = [
...Object.keys(personalityTraits),
...Object.values(personalityTraits),
];
const skills = [
"awareness",
"chirurgery",
"compose",
"courtesy",
"dancing",
"falconry",
"fashion",
"first aid",
"flirting",
"folklore",
"gaming",
"hunting",
"intrigue",
"literacy",
"orate",
"play instrument",
"recognize",
"religion",
"singing",
"stewardship",
];
const combatSkills = [
"battle",
"bow",
"brawling",
"charge",
"crossbow",
"hafted",
"two-handed hafted",
"horsemanship",
"spear",
"sword",
"thrown weapon",
];
-96
View File
@@ -1,7 +1,6 @@
const versioningAttr = "latest_versioning_upgrade";
on("sheet:opened", () => {
//setAttrs({ latest_versioning_upgrade: 2.5 }); used for testing versioning
getAttrs([versioningAttr], (v) => {
versioning(parseFloat(v[versioningAttr]) || 1);
});
@@ -17,81 +16,6 @@ const versionTwoFour = () => {
});
};
const versionTwoFive = () => {
const renameSectionAttrTargetValue = (section, attribute) => {
getSectionIDs(section, (ids) => {
const map = ids.map((id) => `${section}_${id}_${attribute}`);
getAttrs(map, (v) => {
let update = {};
map.forEach((e) => {
const rowId = getReprowid(e);
update[`${rowId}_target_value`] = v[`${e}`] ? v[`${e}`] : 0;
});
setAttrs(update);
});
});
};
renameSectionAttrTargetValue("repeating_passion", "passion");
renameSectionAttrTargetValue("repeating_directed-trait", "trait");
renameSectionAttrTargetValue("repeating_skill", "skill");
};
const versionTwoFiveOne = () => {
const renameRepeatingSectionName = (section, newName) => {
const attrs = ["name", "target_value", "check"];
getSectionIDs(section, (ids) => {
const map = ids
.map((id) => attrs.map((e) => `repeating_${section}_${id}_${e}`))
.flat();
getAttrs(map, (v) => {
const newSection = getRow(newName);
let update = {};
Object.entries(v).forEach(([key, value]) => {
const attr = getReprowAttribute(key);
update[`${newSection}_${attr}`] = value;
});
setAttrs(update);
});
});
};
renameRepeatingSectionName("passion", "passions");
renameRepeatingSectionName("direct-trait", "traits");
};
const versionTwoFiveTwo = () => {
getAttrs(["play", "sing"], (v) => {
setAttrs({
"play instrument": v.play,
singing: v.sing,
});
});
};
const versionTwoFiveThree = () => {
const renameSectionAttrTargetValue = (section, attribute) => {
getSectionIDs(section, (ids) => {
const map = ids.map((id) => `${section}_${id}_${attribute}`);
getAttrs(map, (v) => {
let update = {};
map.forEach((e) => {
const rowId = getReprowid(e);
update[`${rowId}_name`] = v[`${e}`] ? v[`${e}`] : 0;
});
setAttrs(update);
});
});
};
renameSectionAttrTargetValue("repeating_equipment", "equipment");
renameSectionAttrTargetValue("repeating_arms", "equipment");
};
const versioning = async (version) => {
const updateMessage = (v) =>
console.log(
@@ -114,26 +38,6 @@ const versioning = async (version) => {
updateBrawling();
versioning(2.41);
break;
case version < 2.5:
updateMessage(2.5);
versionTwoFive();
versioning(2.5);
break;
case version < 2.51:
updateMessage(2.51);
versionTwoFiveOne();
versioning(2.51);
break;
case version < 2.52:
updateMessage(2.52);
versionTwoFiveTwo();
versioning(2.52);
break;
case version < 2.53:
updateMessage(2.53);
versionTwoFiveThree();
versioning(2.53);
break;
default:
console.log(
`%c Pendragon 6th Edition is update to date.`,
@@ -6,10 +6,10 @@ div.sheet-attacks {
text-align: center;
}
div.sheet-table.sheet-damage {
div.sheet-table.sheet-brawling {
div.sheet-header,
div.sheet-body div.sheet-row {
grid-template-columns: 2fr 1fr 2.5em;
grid-template-columns: $attack-cols;
}
}
@@ -27,14 +27,4 @@ div.sheet-attacks {
input[name="attr_skill"][value*="other"] + label {
visibility: visible;
}
select[name="attr_skill"] {
margin-left: -5px;
}
h3,
span[data-i18n*="brawling"],
span[name*="damage"] {
color: $dark-font;
}
}
@@ -3,8 +3,4 @@ div.sheet-characteristics {
grid-auto-flow: column;
grid-column-gap: 2%;
}
span {
color: $dark-font;
}
}
@@ -1,11 +1,6 @@
div.sheet-equipment {
span[name="attr_value"],
input[name="attr_value"] {
text-align: center;
}
div.sheet-col {
grid-template-rows: min-content 1fr;
input[name="attr_category"] {
font-weight: bold;
}
div.sheet-2autocolumn {
@@ -17,10 +12,6 @@ div.sheet-equipment {
min-height: 20px;
}
div.sheet-category {
grid-template-columns: 3fr 1fr;
}
div.sheet-repeating-container {
div.sheet-flags {
grid-template-columns: 1fr 25px;
@@ -17,6 +17,4 @@ div.sheet-squire {
@extend %repeatingCheckboxRollRow;
}
}
@include notes();
}
@@ -1,37 +1,40 @@
.grid.attacks
.header
h1(data-i18n='attacks')
.table.damage
.grid.header
h3.small-caps.text-left(data-i18n='damage type')
h3.small-caps.center(data-i18n='damage')
.grid.body
each attack in attacks
- const { name, value } = attack
- const i18n = attack.i18n ? attack.i18n : name
- const attr = attrName(name)
.row.align-center
input.hidden(name=`attr_${attr}` type='hidden' value=value ? value : '0')
h3.text-left(data-i18n=i18n)
span.display.text-center.uppercase(name=`attr_${attr}`)
+damageButtonD20(name, i18n)
.repeating-container.table
.table.brawling
.grid.header
h3.small-caps.text-left(data-i18n='weapon')
h3.small-caps.text-left(data-i18n='skill')
h3.small-caps.center(data-i18n='damage')
each value in ['skill', 'damage']
if value === 'skill'
.row
h3.small-caps.text-left(data-i18n=value)
else
.flex-center(class=value)
h3.small-caps(data-i18n=value)
.grid.body
.row.align-center
h3.text-left(data-i18n='brawling')
h3.text-left.ml(data-i18n='brawling')
span.capitalize(data-i18n='brawling')
span.display.text-center(name=`attr_brawling_damage`)
+brawlDamageRollButton('brawling damage', 'brawling')
.row.align-center
h3.text-left(data-i18n='brawling (open hand)')
h3.text-left.ml(data-i18n='brawling (open hand)')
span.capitalize(data-i18n='brawling')
span.display.text-center(name=`attr_brawling_damage_open`)
+brawlDamageRollButton('brawling damage open', 'brawling (open hand)')
.row.align-center
input.hidden(name='attr_critical_damage' type='hidden' value='2d6')
h3.text-left.ml(data-i18n='critical damage')
span.capitalize -
span.display.text-center(name=`attr_critical_damage`)
+criticalDamageButton()
.row.subheader
+primarySubheader('other')
.repeating-container.table
.grid.header
h3.small-caps.text-left(data-i18n='weapon')
each value in ['skill', 'damage']
h3.small-caps.text-left(data-i18n=value)
fieldset(class='repeating_attacks')
.row.grid
+textInput('name')
@@ -6,7 +6,7 @@
.grid.row.centered
+attributeButton(value)
.shield.mt
+numberInput(value)
+hoverSpan(value)
.row.grid.2column.statistic
.row
+primarySubheader('health')
@@ -1,31 +1,19 @@
mixin equipment(name)
.grid.gap.col
.equipment.grid
.header
h1(data-i18n=name)
h1(data-i18n='equipment')
.repeating-container
fieldset(class=`repeating_${attrName(name)}`)
.row.grid.flags
+repeatingFlags()
.row.grid.2autocolumn
+subHeader('name')
span.display.bottom-border(name=`attr_${attrName('name')}`)
+textInput('name')
.row.grid
.grid.gap.category
each val in ['category', 'value']
.row.grid.2autocolumn
+subHeader(val)
span.display.bottom-border(name=`attr_${val}`)
+textInput(val)
each val in ['period restriction']
.row.grid.2autocolumn
+subHeader(val)
span.display.bottom-border(name=`attr_${val}`)
+textInput(val)
.row.notes
span.display(name='attr_notes')
+textArea('notes')
fieldset(class='repeating_equipment')
.row.grid.flags
+repeatingFlags()
.row.grid.2autocolumn
+subHeader('category')
span.display.bottom-border(name='attr_category')
+textInput('category')
.row.grid.2autocolumn
+subHeader('equipment')
span.display.bottom-border(name='attr_equipment')
+textInput('equipment')
.row.notes
span.display(name='attr_notes')
+textArea('notes')
.equipment.grid.gap.2column
+equipment('equipment')
+equipment('arms')
@@ -5,7 +5,7 @@
.body.grid
.col.grid
.row.grid.2column
.flex-center
.flex-center
+accentSubheader('warhorse')
.grid.2autocolumn
.flex-center
@@ -17,18 +17,9 @@
if val === 'damage'
.row.grid.2autocolumn
.flex-center
+boldSubheader(val)
.grid.2column
.grid.2autocolumn
.flex-center
+damageButtonD20(horseAttr, val)
label(data-i18n-title=`damage` title=`damage`)
input(name=`attr_warhorse_damage` placeholder='3D6' title=`@{warhorse_damage}` type='text' value='3D6')
.grid.2autocolumn
.flex-center
+damageButtonD20(`warhorse_charge_damage`, `charge damage`)
label(data-i18n-title=`charge damage` title=`charge damage`)
input(name=`attr_warhorse_charge_damage` placeholder='6D6' title=`@{warhorse_charge_damage}` type='text' value='6D6')
+damageButton(horseAttr, val)
label(data-i18n-title=`damage` title=`damage`)
input(name=`attr_warhorse_damage` placeholder='4d6' title=`@{warhorse_damage}` type='text' value='4d6')
else
.row.grid.2autocolumn
.flex-center
@@ -2,9 +2,9 @@
.header
h1(data-i18n='passions')
.repeating-container
fieldset(class='repeating_passions')
fieldset(class='repeating_passion')
.row
+checkboxInput(`check`)
+textInput('name')
+numberInput('target value')
+repeatingRollButton('target value')
+numberInput('passion')
+repeatingRollButton('passion')
@@ -14,9 +14,9 @@
+rollButton(val)
+checkboxInput(`${val} check`)
.repeating-container
fieldset(class='repeating_traits')
fieldset(class='repeating_directed-trait')
.row
+checkboxInput(`check`)
+textInput('name')
+numberInput('target value')
+repeatingRollButton('target value')
+numberInput('trait')
+repeatingRollButton('trait')
@@ -22,5 +22,5 @@
.row
+checkboxInput(`check`)
+textInput('name')
+numberInput('target value')
+repeatingRollButton('target value')
+numberInput('skill')
+repeatingRollButton('skill')
@@ -22,9 +22,4 @@
+checkboxInput(`check`)
+textInput('name')
+numberInput('skill')
+repeatingRollButton('skill')
.row.grid
.flex-center
+accentSubheader('squire notes')
.grid.notes
+notesTextarea('squire notes')
+repeatingRollButton('skill')
+1
View File
@@ -12,6 +12,7 @@
.shield.mt
+hoverSpan(value)
.grid.statistic.auto-flow-col
.col
+primarySubheader('health')
+npcTable(healthRows)
+31 -46
View File
@@ -1,5 +1,5 @@
//- Semantic Versioning MAJOR.MINORPATCH
input(name='attr_version' type='hidden' value='3.0')
input(name='attr_version' type='hidden' value='2.42')
//- Do not manually change this. Hidden attribute used by versioning script
input(name='attr_latest_versioning_upgrade' type='hidden' value='1')
@@ -12,40 +12,39 @@ include pug/abstracts/mixins.pug
=============================
include pug/abstracts/variables.pug
.dropzone.compendium-drop-target(data-licensedsheet='attr_licensedsheet')
div
//- TABS
=============================
input(name='attr_settings_toggle' type='hidden' value='')
input(name='attr_sheet_type' type='hidden' value='character')
input(name='attr_character_type' type='hidden' value='knight')
each val in ['Name', 'data', 'Content']
input(name=`attr_drop_${val.toLowerCase()}` type='hidden' value='' accept=val)
//- .dropzone.compendium-drop-target(data-licensedsheet='attr_licensedsheet')
div
//- TABS
=============================
input(name='attr_settings_toggle' type='hidden' value='')
input(name='attr_sheet_type' type='hidden' value='character')
input(name='attr_character_type' type='hidden' value='knight')
.grid.tabs
.col.sheet-type.grid
each val in ['character', 'holdings']
- const defaultSelected = val === 'character' ? true : false
+tabButtons(val, 'character', defaultSelected)
.col.settings.grid
label(data-i18n-title='settings')
input(name=`attr_settings_toggle` title=`@{settings_toggle}` type='checkbox' value='settings')
span.pictos.text-lowercase.text-center y
.grid.tabs
.col.sheet-type.grid
each val in ['character', 'holdings']
- const defaultSelected = val === 'character' ? true : false
+tabButtons(val, 'character', defaultSelected)
//-NPC SHEET
=============================
include pages/npc.pug
.col.settings.grid
label(data-i18n-title='settings')
input(name=`attr_settings_toggle` title=`@{settings_toggle}` type='checkbox' value='settings')
span.pictos.text-lowercase.text-center y
//-PC SHEET
=============================
include pages/character.pug
include pages/holdings.pug
//-NPC SHEET
=============================
include pages/npc.pug
//-PC SHEET
=============================
include pages/character.pug
include pages/holdings.pug
include pages/settings.pug
include pages/settings.pug
.compendium_warning
@@ -67,20 +66,6 @@ include pug/vendor/rolltemplate.pug
//- SCRIPTS
script(type="text/worker")
include js/variables.js
include js/helpers.js
include js/scripts.js
include js/versioning.js
include js/drop.js
include js/drag_and_drop/get_rep_update.js
include js/drag_and_drop/roll_20_attribute.js
include js/drag_and_drop/helpers.js
include js/drag_and_drop/handle_horse.js
include js/drag_and_drop/handle_item.js
include js/drag_and_drop/handle_squire.js
include js/drag_and_drop/handle_weapon.js
include js/drag_and_drop/update_attack.js
include js/drag_and_drop/update_item.js
include js/drag_and_drop/update_section.js
include js/drag_and_drop/reset_skill_list.js
include js/drag_and_drop/reset_repeating_rows.js
include js/helpers.js
include js/versioning.js
@@ -50,13 +50,16 @@ mixin rollButton(name)
mixin squireButton(name)
button.d20.capitalize(name=`roll_${buttonName(name)}` type='roll' value!=`${templateHeader("squire")} ^{skill}}} ${rollFormula(attrName(`${name}`))}`) t
mixin damageButton(name, i18n)
- i18n = i18n ? i18n : name
button.capitalize(data-i18n=i18n name=`roll_${buttonName(name)}` type='roll' value!=`${templateHeader(name)} ${damageFormula(attrName(name))}`)
mixin brawlDamageRollButton(name, i18n)
- i18n = i18n ? i18n : name
button.d20.capitalize(name=`roll_${buttonName(name)}` type='roll' value!=`${templateHeader(i18n)} ${rollFormula("brawling")} {{damage=[[(@{${attrName(name)}}+(?{Modifier|0}))]]}}`) t
mixin damageButtonD20(name, i18n)
- i18n = i18n ? i18n : name
button.d20.capitalize(name=`roll_${buttonName(name)}` type='roll' value!=`${templateHeader(i18n)} ${damageFormula(attrName(name))}`) t
mixin criticalDamageButton
button.d20.capitalize(name=`roll_critical_damage` type='roll' value!=`${templateHeader('critical damage')} {{damage=[[(@{critical_damage})]]}}`) t
mixin repeatingRollButton(name)
button.d20.capitalize(name=`roll_${buttonName(name)}` type='roll' value!=`&{template:rolls} {{header=@{name}}} ${rollFormula(attrName(name))}`) t
@@ -108,12 +111,11 @@ mixin repeatingFlags(name)
mixin notesTextarea(name)
-const attr = attrName(name)
+repeatingFlags(name)
span.display(name=`attr_${attr}`)
+textArea(name)
+repeatingFlags(name)
span.display(name=`attr_${attr}`)
+textArea(name)
mixin hoverSpan(name)
-const attr = attrName(name)
span.display(name=`attr_${attr}`)
+numberInput(attr)
+numberInput(attr)
@@ -2,7 +2,7 @@
- const christianTraits = ['chaste','forgiving','merciful', 'modest','spiritual','temperate']
- const paganTraits = ['energetic','lustful','generous','honest','proud','spiritual']
- const characteristics = ['size', 'dex', 'str', 'con', 'app'];
- const skills = ['awareness', 'chirurgery', 'compose', 'courtesy', 'dancing', 'falconry', 'fashion', 'first aid', 'flirting', 'folklore', 'gaming', 'hunting', 'intrigue', 'literacy', 'orate', 'play instrument', 'recognize', 'religion', 'singing', 'stewardship'];
- const skills = ['awareness', 'chirurgery', 'compose', 'courtesy', 'dancing', 'falconry', 'fashion', 'first aid', 'flirting', 'folklore', 'gaming', 'hunting', 'intrigue', 'literacy', 'orate', 'play', 'recognize', 'religion', 'sing', 'stewardship'];
- const gmCharacters = ['name', 'glory', 'app', 'courtesy', 'flirting', 'intrigue', 'chaste', 'modest', 'temperate'];
- const combatSkills = ['battle', 'bow', 'brawling', 'charge', 'crossbow', 'hafted', 'two-handed hafted', 'horsemanship', 'spear', 'sword', 'thrown weapon']
@@ -10,7 +10,5 @@
- const otherRows = ['movement', 'armor points', 'current glory', 'healing rate']
- const npcOtherRows = otherRows.map(e => e === 'current glory' ? 'glory award' : e)
- const attacks = [{name: 'brawling damage'}, {name: 'brawling damage open', i18n: 'brawling (open hand)'}, {name: 'character damage'}, {name: 'critical damage', value: '4D6'}]
- const imageSource = 'https://github.com/clevett/roll20-character-sheets/blob/6c62396ad2bdfcafb13255fc70a6ab878f5725d7/Pendragon6thEdition/src/pendragonlogo.png?raw=true'
@@ -1,22 +1,8 @@
div.sheet-shield {
border-radius: 50% 50% 50% 50% / 12% 12% 88% 88%;
border: 5px solid $dark;
height: 50px;
width: 50px;
border: 5px solid $dark;
border-radius: 50% 50% 50% 50% / 12% 12% 88% 88%;
& input[type="number"] {
font-weight: bolder;
width: 3em;
&:placeholder-shown,
&:hover {
background-color: $light;
}
&::-webkit-outer-spin-button,
&::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
}
@include hoverSpan();
}
@@ -22,5 +22,5 @@ div.sheet-repeating-container {
font-family: "pictos";
z-index: 100;
position: absolute;
right: 1.5%;
left: 85%;
}
+28 -16
View File
@@ -1,29 +1,41 @@
.sheet-dropzone.active-drop-target.dropping {
opacity: 0.5;
transition: opacity 0.15s ease-in-out;
-moz-transition: opacity 0.15s ease-in-out;
-webkit-transition: opacity 0.15s ease-in-out;
background-color: transparent;
opacity: 0.5;
transition: opacity 0.15s ease-in-out;
}
.sheet-compendium_warning {
.sheet-compendium_warning,
.sheet-monster_confirm {
display: none;
}
.sheet-dropzone.active-drop-target.dropping ~ .sheet-compendium_warning {
position: absolute;
background: white;
border-radius: 0.5em;
border: 2px solid #000;
box-shadow: 0 0 50px #000;
.sheet-dropzone.active-drop-target.dropping ~ .sheet-compendium_warning,
.sheet-monster_confirm_flag[value="1"] ~ .sheet-monster_confirm {
display: block;
height: 100px;
left: 50%;
margin: -70px 0 0 -170px;
min-height: max-content;
padding: 2em;
text-align: center;
position: fixed;
top: 50%;
width: 300px;
background: white;
left: 50%;
z-index: 100;
border: 2px solid black;
width: 300px;
height: 100px;
text-align: center;
margin: -70px 0 0 -170px;
}
.charsheet input.sheet-licensedsheet[value="1"] ~ .sheet-compendium_warning,
.charsheet input.sheet-licensedsheet[value="1"] ~ .sheet-monster_confirm {
position: absolute !important;
padding: 2em 0 !important;
min-height: max-content;
box-shadow: 0 0 50px #000;
border: 2px solid #000 !important;
border-radius: 0.5em;
}
.sheet-dropzone.active-drop-target.dropping ~ .sheet-compendium_warning span {
line-height: 100px;
}
+3 -11
View File
@@ -4,7 +4,6 @@
"age": "age",
"aggravation damage": "aggravation damage",
"app": "app",
"arms": "arms",
"appearance": "appearance",
"arbitrary": "arbitrary",
"armor points": "armor points",
@@ -15,22 +14,17 @@
"born": "born",
"bow": "bow",
"brawling": "brawling",
"brawling damage": "brawling damage",
"character damage": "character damage",
"brawling (open hand)": "brawling (open hand)",
"category": "category",
"character name": "character name",
"character sheet type": "character sheet type",
"character": "character",
"characteristics": "characteristics",
"damage type": "damage type",
"charge": "charge",
"charge damage": "charge damage",
"chaste": "chaste",
"children": "children",
"chirurgery": "chirurgery",
"critical damage": "critical damage",
"weapons": "weapons",
"class": "class",
"combat skills": "combat skills",
"compose": "compose",
@@ -138,7 +132,7 @@
"passive glory": "passive glory",
"personal data": "personal data",
"personality traits": "personality traits",
"play instrument": "play (instrument)",
"play": "play (instrument)",
"points": "points",
"proud": "proud",
"prudent": "prudent",
@@ -152,7 +146,7 @@
"selfish": "selfish",
"servant": "servant",
"session glory": "session glory",
"singing": "singing",
"sing": "sing",
"siz": "siz",
"size": "size",
"skill": "skill",
@@ -200,7 +194,5 @@
"knight value": "knight value",
"hide sections": "hide sections",
"npc knight attributes": "npc knight attributes",
"other skill": "other skill",
"squire notes": "squire notes",
"period restriction": "period restriction"
"other skill": "other skill"
}