Merge pull request #7 from Cynicide/added-skill-category-import

Added system to skill category import
This commit is contained in:
Cynicide 2022-10-25 22:05:07 +11:00 committed by GitHub
commit 03fffa2f19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 1432 additions and 1065 deletions

View File

@ -6,10 +6,12 @@ This is an in-development implementation of the Rolemaster Standard System for F
If you need access to the Rolemaster Standard System you may be out of luck as the system has been out of print for some time. However it's successor Rolemaster Fantasy Roleplaying is broadly compatible and can be purchased as a PDF via Drive Thru RPG here: https://www.drivethrurpg.com/product/91995/Rolemaster-Fantasy-Role-Playing?cPath=1361_6495 If you need access to the Rolemaster Standard System you may be out of luck as the system has been out of print for some time. However it's successor Rolemaster Fantasy Roleplaying is broadly compatible and can be purchased as a PDF via Drive Thru RPG here: https://www.drivethrurpg.com/product/91995/Rolemaster-Fantasy-Role-Playing?cPath=1361_6495
## How to Use ## How to Use
Download the latest release from this repository and then extract the rmss folder. Drag it into the systems folder of your FoundryVTT Data Directory. More detailed instructions can be found here in the docs directory. Download the latest release from this repository and then extract the rmss folder. Drag it into the systems folder of your FoundryVTT Data Directory. More detailed instructions can be found [here](docs/INSTALL.md) in the docs directory.
If you are using this system I highly recommend the "Simple Dice Roller" module which will allow you to roll dice easily while this feature is in development. You can install it in the Foundry Modules section or you can visit the following link for more instructions: https://foundryvtt.com/packages/simple-dice-roller/ If you are using this system I highly recommend the "Simple Dice Roller" module which will allow you to roll dice easily while this feature is in development. You can install it in the Foundry Modules section or you can visit the following link for more instructions: https://foundryvtt.com/packages/simple-dice-roller/
Further information on how the system works can be found [here](docs/USAGE.md)
## Goals/ToDo ## Goals/ToDo
Project goals include: Project goals include:
- A functionaing character sheet that automates some of the basic maths. - A functionaing character sheet that automates some of the basic maths.

4
rmss/.gitignore vendored
View File

@ -1 +1,3 @@
node_modules/ node_modules/
.jshintrc
.eslintrc

View File

@ -0,0 +1 @@
<svg style="height: 512px; width: 512px;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><g class="" style="" transform="translate(0,0)"><path d="M488 348.78h-70.24l-15.1 87.44-48.78-87.44H169v-50h190v-157h129zm-145-273v207H158.13l-48.79 87.47-15.11-87.47H24v-207zM136.724 215.324c0-10.139-12.257-15.214-19.425-8.046-7.168 7.168-2.093 19.426 8.046 19.426 6.285 0 11.38-5.095 11.38-11.38zm60.945 0c-.068-10.12-12.32-15.122-19.452-7.943-7.131 7.18-2.047 19.399 8.073 19.399 6.314 0 11.422-5.141 11.38-11.456zm60.945 0c0-10.139-12.257-15.214-19.425-8.046-7.169 7.168-2.093 19.426 8.046 19.426 6.284 0 11.38-5.095 11.38-11.38z" fill="#fff" fill-opacity="1"></path></g></svg>

After

Width:  |  Height:  |  Size: 680 B

View File

@ -33,6 +33,9 @@
"stat_total": "Total" "stat_total": "Total"
} }
}, },
"pc_sheet": {
"import_skillcat": "Import"
},
"pc_sheet_tabs": { "pc_sheet_tabs": {
"record": "Record", "record": "Record",
"skill_categories": "Skill Categories", "skill_categories": "Skill Categories",
@ -128,10 +131,11 @@
"prof_bonus": "Prof Bonus", "prof_bonus": "Prof Bonus",
"special_bonus": "Special Bonus", "special_bonus": "Special Bonus",
"total_bonus": "Total Bonus", "total_bonus": "Total Bonus",
"add_skillcat": "Add Skill Category" "import_skillcat": "Import Skill Categories"
}, },
"pc_sheet_items": { "pc_sheet_items": {
"equipped": "Equipped", "equipped": "Equipped",
"worn": "Worn",
"favorite": "Favorite", "favorite": "Favorite",
"quantity": "Quantity", "quantity": "Quantity",
"item_name": "Item Name", "item_name": "Item Name",
@ -149,6 +153,11 @@
"range": "Range", "range": "Range",
"type": "Type" "type": "Type"
}, },
"pc_sheet_language": {
"name": "Name",
"spoken": "Spoken",
"written": "Written"
},
"entity_sheet": { "entity_sheet": {
"spell": "RMSS Spell", "spell": "RMSS Spell",
"weapon": "RMSS Weapon", "weapon": "RMSS Weapon",
@ -171,6 +180,7 @@
"cp": "Copper Pieces" "cp": "Copper Pieces"
}, },
"item": { "item": {
"worn": "Worn",
"description": "Other Notes", "description": "Other Notes",
"quantity": "Quantity", "quantity": "Quantity",
"weight": "Weight", "weight": "Weight",
@ -245,6 +255,11 @@
"special_bonus_2": "Special Bonus 2:", "special_bonus_2": "Special Bonus 2:",
"total_bonus": "Total Bonus:", "total_bonus": "Total Bonus:",
"description": "Description:" "description": "Description:"
},
"language": {
"spoken": "Spoken",
"written": "Written",
"description": "Description"
} }
} }
} }

View File

@ -1,6 +1,6 @@
.items-grid-container { .items-grid-container {
display: grid; display: grid;
grid-template-columns: [name] 30% [quantity] 17% [weight] 17% [cost] 18% [controls] 18%; grid-template-columns: [worn] 10% [name] 30% [quantity] 15% [weight] 15% [cost] 15% [controls] 15%;
} }
.items-grid-container > div { .items-grid-container > div {
@ -16,11 +16,12 @@
justify-content: center; justify-content: center;
} }
.items-grid-container > div:nth-child(10n+1), .items-grid-container > div:nth-child(12n+1),
.items-grid-container > div:nth-child(10n+2), .items-grid-container > div:nth-child(12n+2),
.items-grid-container > div:nth-child(10n+3), .items-grid-container > div:nth-child(12n+3),
.items-grid-container > div:nth-child(10n+4), .items-grid-container > div:nth-child(12n+4),
.items-grid-container > div:nth-child(10n+5) .items-grid-container > div:nth-child(12n+5),
.items-grid-container > div:nth-child(12n+6)
{ {
font-family: Signika, sans-serif; font-family: Signika, sans-serif;
font-size: 12px; font-size: 12px;

View File

@ -0,0 +1,18 @@
.resistances-grid-container {
outline: 1px solid; /* use instead of border */
margin-top: 1px;
margin-left: 1px;
padding: 5px;
display: grid;
grid-template-columns: [Name] 40% [Value] 20% [Race_Mod] 20% [Total] 20%;
}
.resistances-grid-heading {
font-weight: bold;
border-bottom: 1px solid;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.resistance-input {
width: 50%
}

View File

@ -27,6 +27,12 @@
padding: 1px; padding: 1px;
} }
.settings-button, .playersheet-settings {
font-family: Signika, sans-serif;
font-size: 12px;
margin-right: 6px
}
// Resource Elements in Headers // Resource Elements in Headers
.resource-container { .resource-container {
@ -133,6 +139,7 @@
padding: 5px; padding: 5px;
} }
// Remove Me
.resistance-block { .resistance-block {
outline: 1px solid; /* use instead of border */ outline: 1px solid; /* use instead of border */
margin-top: 1px; margin-top: 1px;

View File

@ -9,6 +9,7 @@
@import "./actor-sheet/actor-sheet-armor.less"; @import "./actor-sheet/actor-sheet-armor.less";
@import "./actor-sheet/actor-sheet-herbs.less"; @import "./actor-sheet/actor-sheet-herbs.less";
@import "./actor-sheet/actor-sheet-spells.less"; @import "./actor-sheet/actor-sheet-spells.less";
@import "./actor-sheet/actor-sheet-resistances.less";
//Skill Category Sheet //Skill Category Sheet

View File

@ -1,11 +1,11 @@
.skillcat-name, .skill-name, .item-name, .spell-name, .equipable-name{ .skillcat-name, .skill-name, .item-name, .spell-name, .equipable-name {
font-family: Signika, sans-serif; font-family: Signika, sans-serif;
font-size: 12px; font-size: 12px;
font-weight: bold; font-weight: bold;
text-align: center; text-align: center;
} }
.skillcat-entry, .skill-entry, .item-entry, .spell-entry, .equipable-entry{ .skillcat-entry, .skill-entry, .item-entry, .spell-entry, .equipable-entry {
font-family: Signika, sans-serif; font-family: Signika, sans-serif;
font-size: 12px; font-size: 12px;
text-align: center; text-align: center;

View File

@ -1,60 +1,60 @@
export const rmss = {}; export const rmss = {};
rmss.curreny_type = { rmss.curreny_type = {
mp: "rmss.curreny_type.mp", mp: "rmss.curreny_type.mp",
pp: "rmss.curreny_type.pp", pp: "rmss.curreny_type.pp",
gp: "rmss.curreny_type.gp", gp: "rmss.curreny_type.gp",
sp: "rmss.curreny_type.sp", sp: "rmss.curreny_type.sp",
bp: "rmss.curreny_type.bp", bp: "rmss.curreny_type.bp",
cp: "rmss.curreny_type.cp" cp: "rmss.curreny_type.cp"
}; };
rmss.stats = { rmss.stats = {
agility: { agility: {
fullname: "Agility", fullname: "Agility",
shortname: "Ag" shortname: "Ag"
}, },
constitution: { constitution: {
fullname: "Constitution", fullname: "Constitution",
shortname: "Co" shortname: "Co"
}, },
memory: { memory: {
fullname: "Memory", fullname: "Memory",
shortname: "Me" shortname: "Me"
}, },
reasoning: { reasoning: {
fullname: "Reasoning", fullname: "Reasoning",
shortname: "Re" shortname: "Re"
}, },
self_discipline: { self_discipline: {
fullname: "Self Discipline", fullname: "Self Discipline",
shortname: "SD" shortname: "SD"
}, },
empathy: { empathy: {
fullname: "Empathy", fullname: "Empathy",
shortname: "Em" shortname: "Em"
}, },
intuition: { intuition: {
fullname: "Intuition", fullname: "Intuition",
shortname: "In" shortname: "In"
}, },
presence: { presence: {
fullname: "Presence", fullname: "Presence",
shortname: "Pr" shortname: "Pr"
}, },
quickness: { quickness: {
fullname: "Quickness", fullname: "Quickness",
shortname: "Qu" shortname: "Qu"
}, },
strength: { strength: {
fullname: "Strength", fullname: "Strength",
shortname: "St" shortname: "St"
} }
}; };
rmss.skill_designations = { rmss.skill_designations = {
None: "None", None: "None",
Occupational: "Occupational", Occupational: "Occupational",
Everyman: "Everyman", Everyman: "Everyman",
Restricted: "Restricted" Restricted: "Restricted"
}; };

View File

@ -1,5 +1,5 @@
export class RMSSActor extends Actor { export class RMSSActor extends Actor {
/** @override */ /** @override */
prepareData() { prepareData() {
// Prepare data for the actor. Calling the super version of this executes // Prepare data for the actor. Calling the super version of this executes
@ -8,83 +8,157 @@ export class RMSSActor extends Actor {
// prepareDerivedData(). // prepareDerivedData().
super.prepareData(); super.prepareData();
} }
prepareDerivedData() { prepareDerivedData() {
const actorData = this; const actorData = this;
const systemData = actorData.system; const systemData = actorData.system;
const flags = actorData.flags.rmss || {}; const flags = actorData.flags.rmss || {};
// Make separate methods for each Actor type (character, npc, etc.) to keep // Make separate methods for each Actor type (character, npc, etc.) to keep
// things organized. // things organized.
this._prepareCharacterData(actorData); this._prepareCharacterData(actorData);
this._prepareNpcData(actorData); this._prepareNpcData(actorData);
} }
/** /**
* Prepare Character type specific data * Prepare Character specific data.
*/ * @param {Actor} actorData The NPC Object to prepare data for
*/
_prepareCharacterData(actorData) { _prepareCharacterData(actorData) {
if (actorData.type !== 'character') return; if (actorData.type !== "character") return;
// Calculate Stat Bonuses for the Actor // Calculate Stat Bonuses for the Actor
this.calculateStatBonuses(actorData); this.calculateStatBonuses(actorData);
// Calculate Resistance Rolls for the Actor // Calculate Resistance Rolls for the Actor
this.calculateResistanceRolls(actorData); this.calculateResistanceRolls(actorData);
// Iterate through and apply Stat bonuses for Skill Category Items // Iterate through and apply Stat bonuses for Skill Category Items
this.calculateSkillCategoryStatBonuses(); this.calculateSkillCategoryStatBonuses();
// Iterate through and apply Skill Category Bonuses for Skill items // Iterate through and apply Skill Category Bonuses for Skill items
this.calculateSkillBonuses(); this.calculateSkillBonuses();
} }
/** /**
* Prepare NPC type specific data. * Prepare NPC specific data.
*/ * @param {Actor} actorData The NPC Object to prepare data for
*/
_prepareNpcData(actorData) { _prepareNpcData(actorData) {
if (actorData.type !== 'npc') return; if (actorData.type !== "npc") return;
// Make modifications to data here. For example: // Make modifications to data here. For example:
const data = actorData.data; const data = actorData.data;
} }
// Tally each stat bonus and populate the total field. // Tally each stat bonus and populate the total field.
calculateStatBonuses(actorData) { calculateStatBonuses(actorData) {
const systemData = actorData.system; const systemData = actorData.system;
actorData.system.stats.agility.stat_bonus = Number(systemData.stats.agility.racial_bonus)+Number(systemData.stats.agility.special_bonus)+Number(systemData.stats.agility.basic_bonus);
actorData.system.stats.constitution.stat_bonus = Number(systemData.stats.constitution.racial_bonus)+Number(systemData.stats.constitution.special_bonus)+Number(systemData.stats.constitution.basic_bonus); actorData.system.stats.agility.stat_bonus = Number(systemData.stats.agility.racial_bonus)
actorData.system.stats.memory.stat_bonus = Number(systemData.stats.memory.racial_bonus)+Number(systemData.stats.memory.special_bonus)+Number(systemData.stats.memory.basic_bonus); + Number(systemData.stats.agility.special_bonus)
actorData.system.stats.reasoning.stat_bonus = Number(systemData.stats.reasoning.racial_bonus)+Number(systemData.stats.reasoning.special_bonus)+Number(systemData.stats.reasoning.basic_bonus); + Number(systemData.stats.agility.basic_bonus);
actorData.system.stats.self_discipline.stat_bonus = Number(systemData.stats.self_discipline.racial_bonus)+Number(systemData.stats.self_discipline.special_bonus)+Number(systemData.stats.self_discipline.basic_bonus);
actorData.system.stats.empathy.stat_bonus = Number(systemData.stats.empathy.racial_bonus)+Number(systemData.stats.empathy.special_bonus)+Number(systemData.stats.empathy.basic_bonus); actorData.system.stats.constitution.stat_bonus = Number(systemData.stats.constitution.racial_bonus)
actorData.system.stats.intuition.stat_bonus = Number(systemData.stats.intuition.racial_bonus)+Number(systemData.stats.intuition.special_bonus)+Number(systemData.stats.intuition.basic_bonus); + Number(systemData.stats.constitution.special_bonus)
actorData.system.stats.presence.stat_bonus = Number(systemData.stats.presence.racial_bonus)+Number(systemData.stats.presence.special_bonus)+Number(systemData.stats.presence.basic_bonus); + Number(systemData.stats.constitution.basic_bonus);
actorData.system.stats.quickness.stat_bonus = Number(systemData.stats.quickness.racial_bonus)+Number(systemData.stats.quickness.special_bonus)+Number(systemData.stats.quickness.basic_bonus);
actorData.system.stats.strength.stat_bonus = Number(systemData.stats.strength.racial_bonus)+Number(systemData.stats.strength.special_bonus)+Number(systemData.stats.strength.basic_bonus); actorData.system.stats.memory.stat_bonus = Number(systemData.stats.memory.racial_bonus)
+ Number(systemData.stats.memory.special_bonus)
+ Number(systemData.stats.memory.basic_bonus);
actorData.system.stats.reasoning.stat_bonus = Number(systemData.stats.reasoning.racial_bonus)
+ Number(systemData.stats.reasoning.special_bonus)
+ Number(systemData.stats.reasoning.basic_bonus);
actorData.system.stats.self_discipline.stat_bonus = Number(systemData.stats.self_discipline.racial_bonus)
+ Number(systemData.stats.self_discipline.special_bonus)
+ Number(systemData.stats.self_discipline.basic_bonus);
actorData.system.stats.empathy.stat_bonus = Number(systemData.stats.empathy.racial_bonus)
+ Number(systemData.stats.empathy.special_bonus)
+ Number(systemData.stats.empathy.basic_bonus);
actorData.system.stats.intuition.stat_bonus = Number(systemData.stats.intuition.racial_bonus)
+ Number(systemData.stats.intuition.special_bonus)
+ Number(systemData.stats.intuition.basic_bonus);
actorData.system.stats.presence.stat_bonus = Number(systemData.stats.presence.racial_bonus)
+ Number(systemData.stats.presence.special_bonus)
+ Number(systemData.stats.presence.basic_bonus);
actorData.system.stats.quickness.stat_bonus = Number(systemData.stats.quickness.racial_bonus)
+ Number(systemData.stats.quickness.special_bonus)
+ Number(systemData.stats.quickness.basic_bonus);
actorData.system.stats.strength.stat_bonus = Number(systemData.stats.strength.racial_bonus)
+ Number(systemData.stats.strength.special_bonus)
+ Number(systemData.stats.strength.basic_bonus);
} }
// Calculate each Resistance Roll with the formula on the character sheet. // Calculate each Resistance Roll with the formula on the character sheet.
calculateResistanceRolls(actorData) { // TODO: Add Racial modifiers to resistance calculateResistanceRolls(actorData) {
const systemData = actorData.system; const systemData = actorData.system;
actorData.system.resistance_rolls.essence = Number(systemData.stats.empathy.stat_bonus * 3);
actorData.system.resistance_rolls.channeling = Number(systemData.stats.intuition.stat_bonus * 3); actorData.system.resistance_rolls.essence.value = Number(systemData.stats.empathy.stat_bonus * 3);
actorData.system.resistance_rolls.mentalism = Number(systemData.stats.presence.stat_bonus * 3);
actorData.system.resistance_rolls.fear = Number(systemData.stats.self_discipline.stat_bonus * 3); actorData.system.resistance_rolls.channeling.value = Number(systemData.stats.intuition.stat_bonus * 3);
actorData.system.resistance_rolls.poison_disease = Number(systemData.stats.constitution.stat_bonus * 3);
actorData.system.resistance_rolls.chann_ess = Number(systemData.stats.intuition.stat_bonus) + Number(systemData.stats.empathy.stat_bonus); actorData.system.resistance_rolls.mentalism.value = Number(systemData.stats.presence.stat_bonus * 3);
actorData.system.resistance_rolls.chann_ment = Number(systemData.stats.intuition.stat_bonus) + Number(systemData.stats.presence.stat_bonus);
actorData.system.resistance_rolls.ess_ment = Number(systemData.stats.empathy.stat_bonus) + Number(systemData.stats.presence.stat_bonus); actorData.system.resistance_rolls.fear.value = Number(systemData.stats.self_discipline.stat_bonus * 3);
actorData.system.resistance_rolls.arcane = Number(systemData.stats.empathy.stat_bonus) + Number(systemData.stats.intuition.stat_bonus) + Number(systemData.stats.presence.stat_bonus);
actorData.system.resistance_rolls.poison_disease.value = Number(systemData.stats.constitution.stat_bonus * 3);
actorData.system.resistance_rolls.chann_ess.value = Number(systemData.stats.intuition.stat_bonus)
+ Number(systemData.stats.empathy.stat_bonus);
actorData.system.resistance_rolls.chann_ment.value = Number(systemData.stats.intuition.stat_bonus)
+ Number(systemData.stats.presence.stat_bonus);
actorData.system.resistance_rolls.ess_ment.value = Number(systemData.stats.empathy.stat_bonus)
+ Number(systemData.stats.presence.stat_bonus);
actorData.system.resistance_rolls.arcane.value = Number(systemData.stats.empathy.stat_bonus)
+ Number(systemData.stats.intuition.stat_bonus)
+ Number(systemData.stats.presence.stat_bonus);
actorData.system.resistance_rolls.essence.total = actorData.system.resistance_rolls.essence.value
+ actorData.system.resistance_rolls.essence.race_mod;
actorData.system.resistance_rolls.channeling.total = actorData.system.resistance_rolls.channeling.value
+ actorData.system.resistance_rolls.channeling.race_mod;
actorData.system.resistance_rolls.mentalism.total = actorData.system.resistance_rolls.mentalism.value
+ actorData.system.resistance_rolls.mentalism.race_mod;
actorData.system.resistance_rolls.fear.total = actorData.system.resistance_rolls.fear.value
+ actorData.system.resistance_rolls.fear.race_mod;
actorData.system.resistance_rolls.poison_disease.total = actorData.system.resistance_rolls.poison_disease.value
+ actorData.system.resistance_rolls.poison_disease.race_mod;
actorData.system.resistance_rolls.chann_ess.total = actorData.system.resistance_rolls.chann_ess.value
+ actorData.system.resistance_rolls.chann_ess.race_mod;
actorData.system.resistance_rolls.chann_ment.total = actorData.system.resistance_rolls.chann_ment.value
+ actorData.system.resistance_rolls.chann_ment.race_mod;
actorData.system.resistance_rolls.ess_ment.total = actorData.system.resistance_rolls.ess_ment.value
+ actorData.system.resistance_rolls.ess_ment.race_mod;
actorData.system.resistance_rolls.arcane.total = actorData.system.resistance_rolls.arcane.value
+ actorData.system.resistance_rolls.arcane.race_mod;
} }
calculateSkillBonuses() { calculateSkillBonuses() {
for (const item of this.items) { for (const item of this.items) {
if (item.type === "skill") { if (item.type === "skill") {
console.log("rmss | actor.js | Calculating skill bonus for Skill: " + item.name); console.log(`rmss | actor.js | Calculating skill bonus for Skill: ${item.name}`);
console.log("rmss | actor.js | Updating Skill Category Bonus for Skill: " + item.name); console.log(`rmss | actor.js | Updating Skill Category Bonus for Skill: ${item.name}`);
item.calculateSelectedSkillCategoryBonus(item); item.calculateSelectedSkillCategoryBonus(item);
console.log("rmss | actor.js | Updating Skill Total Bonus for Skill: " + item.name); console.log(`rmss | actor.js | Updating Skill Total Bonus for Skill: ${item.name}`);
item.calculateSkillTotalBonus(item); item.calculateSkillTotalBonus(item);
} }
} }
@ -94,25 +168,25 @@ export class RMSSActor extends Actor {
calculateSkillCategoryStatBonuses() { calculateSkillCategoryStatBonuses() {
for (const item of this.items) { for (const item of this.items) {
if (item.type === "skill_category") { if (item.type === "skill_category") {
console.log("rmss | actor.js | Calculating Skill Category Stat Bonuses for: " + item.name); console.log(`rmss | actor.js | Calculating Skill Category Stat Bonuses for: ${item.name}`);
// Get all the applicable stats for this skill category // Get all the applicable stats for this skill category
var app_stat_1 = item.system.app_stat_1; let app_stat_1 = item.system.app_stat_1;
var app_stat_2 = item.system.app_stat_2; let app_stat_2 = item.system.app_stat_2;
var app_stat_3 = item.system.app_stat_3; let app_stat_3 = item.system.app_stat_3;
// If the first one is None we don't need to do anything further // If the first one is None we don't need to do anything further
if (app_stat_1 === "None") { if (app_stat_1 === "None") {
continue; continue;
} }
else else
{ {
var applicable_stat_bonus = 0; let applicable_stat_bonus = 0;
var app_stat_1_found = false; let app_stat_1_found = false;
var app_stat_2_found = false; let app_stat_2_found = false;
var app_stat_3_found = false; let app_stat_3_found = false;
// Iterate through the applicable stats and find their full names // Iterate through the applicable stats and find their full names
for (const stat in CONFIG.rmss.stats) { for (const stat in CONFIG.rmss.stats) {
// If the configured App Stat matches the one of the stats in config // If the configured App Stat matches the one of the stats in config
@ -130,11 +204,25 @@ export class RMSSActor extends Actor {
applicable_stat_bonus = applicable_stat_bonus + this.system.stats[stat].stat_bonus; applicable_stat_bonus = applicable_stat_bonus + this.system.stats[stat].stat_bonus;
} }
} }
//console.log("Applicable Stat Bonus: " + applicable_stat_bonus)
if (app_stat_1_found === true && app_stat_2_found === true && app_stat_3_found === true) { if (app_stat_1_found === true && app_stat_2_found === true && app_stat_3_found === true) {
// Apply the update if we found stat bonuses for every applicable stat // Apply the update if we found stat bonuses for every applicable stat
item.system.stat_bonus = applicable_stat_bonus; item.system.stat_bonus = applicable_stat_bonus;
// Update the total in the Item
item.calculateSkillCategoryTotalBonus(item);
}
else if (app_stat_1_found === true && app_stat_2_found === true && app_stat_3_found === false) {
// Apply the update if we found stat bonuses for the first two applicable stats
item.system.stat_bonus = applicable_stat_bonus;
// Update the total in the Item
item.calculateSkillCategoryTotalBonus(item);
}
else if (app_stat_1_found === true && app_stat_2_found === false && app_stat_3_found === false) {
// Apply the update if we found stat bonuses for the first applicable stat
item.system.stat_bonus = applicable_stat_bonus;
// Update the total in the Item // Update the total in the Item
item.calculateSkillCategoryTotalBonus(item); item.calculateSkillCategoryTotalBonus(item);
} }
@ -148,15 +236,13 @@ export class RMSSActor extends Actor {
// This is the format that the select helper on the skill sheet needs // This is the format that the select helper on the skill sheet needs
getOwnedItemsByType(item_type) { getOwnedItemsByType(item_type) {
var ownedItems = {None: "None"}; let ownedItems = {None: "None"};
console.log("rmss | actor.js | Getting owned " + item_type + " for: " + this.name); console.log(`rmss | actor.js | Getting owned ${item_type} for: ${this.name}`);
for (const item of this.items) { for (const item of this.items) {
if (item.type === item_type) { if (item.type === item_type) {
ownedItems[item._id] = item.name; ownedItems[item._id] = item.name;
} }
} }
return(ownedItems); return (ownedItems);
} }
}
}

View File

@ -1,117 +1,118 @@
export class RMSSItem extends Item { export class RMSSItem extends Item {
/** @override */ /** @override */
prepareData() { prepareData() {
// Prepare data for the item. Calling the super version of this executes // Prepare data for the item. Calling the super version of this executes
// the following, in order: data reset (to clear active effects), // the following, in order: data reset (to clear active effects),
// prepareBaseData(), prepareEmbeddedDocuments() (including active effects), // prepareBaseData(), prepareEmbeddedDocuments() (including active effects),
// prepareDerivedData(). // prepareDerivedData().
console.log("rmss | item.js | prepareData for:" + this.name); console.log(`rmss | item.js | prepareData for: ${this.name}`);
super.prepareData(); super.prepareData();
} }
// Set the icon images for newly created images. // Set the icon images for newly created images.
async _preCreate(data, options, userId) { async _preCreate(data, options, userId) {
await super._preCreate(data, options, userId); await super._preCreate(data, options, userId);
// Do not set on copied items if they have a custom Icon.
if (!data.name.includes("(Copy)"))
{
if (this.type == "armor") {
await this.updateSource({img: "systems/rmss/assets/default/armor.svg"});
}
else if (this.type == "weapon") {
await this.updateSource({img: "systems/rmss/assets/default/weapon.svg"});
}
else if (this.type == "skill") {
await this.updateSource({img: "systems/rmss/assets/default/skill.svg"});
}
else if (this.type == "skill_category") {
await this.updateSource({img: "systems/rmss/assets/default/skill_category.svg"});
}
else if (this.type == "spell") {
await this.updateSource({img: "systems/rmss/assets/default/spell.svg"});
}
else if (this.type == "herb_or_poison") {
await this.updateSource({img: "systems/rmss/assets/default/herb_or_poison.svg"});
}
else if (this.type == "transport") {
await this.updateSource({img: "systems/rmss/assets/default/transport.svg"});
}
}
}
prepareDerivedData() {
const itemData = this;
const systemData = itemData.system;
const flags = itemData.flags.rmss || {};
// Make separate methods for each item type to keep things organized.
if (itemData.type === 'skill') {
this._prepareSkillCategoryData(itemData);
}
if (itemData.type === 'skill') {
this._prepareSkillData(itemData);
}
// Do not set on copied items if they have a custom Icon.
if (!data.name.includes("(Copy)"))
{
if (this.type === "armor") {
await this.updateSource({img: "systems/rmss/assets/default/armor.svg"});
} }
else if (this.type === "weapon") {
await this.updateSource({img: "systems/rmss/assets/default/weapon.svg"});
}
else if (this.type === "skill") {
await this.updateSource({img: "systems/rmss/assets/default/skill.svg"});
}
else if (this.type === "skill_category") {
await this.updateSource({img: "systems/rmss/assets/default/skill_category.svg"});
}
else if (this.type === "spell") {
await this.updateSource({img: "systems/rmss/assets/default/spell.svg"});
}
else if (this.type === "herb_or_poison") {
await this.updateSource({img: "systems/rmss/assets/default/herb_or_poison.svg"});
}
else if (this.type === "transport") {
await this.updateSource({img: "systems/rmss/assets/default/transport.svg"});
}
}
}
_prepareSkillCategoryData(itemData) { prepareDerivedData() {
if (itemData.type !== 'skill_category') return; const itemData = this;
console.log("rmss | item.js | Preparing Skill Category Data for: " + itemData.name); const systemData = itemData.system;
// Calculate Skill Category Total Bonus const flags = itemData.flags.rmss || {};
this.calculateSkillCategoryTotalBonus(itemData);
// Make separate methods for each item type to keep things organized.
if (itemData.type === "skill") {
this._prepareSkillCategoryData(itemData);
} }
_prepareSkillData(itemData) { if (itemData.type === "skill") {
if (itemData.type !== 'skill') return; this._prepareSkillData(itemData);
console.log("rmss | item.js | Preparing Skill Data for: " + itemData.name);
// Make modifications to data here. For example:
const systemData = itemData.system;
// Calculate Skill Category Bonus
this.calculateSelectedSkillCategoryBonus(itemData);
// Calculate Skill Total Bonus
this.calculateSkillTotalBonus(itemData);
} }
}
calculateSkillCategoryTotalBonus(itemData) { _prepareSkillCategoryData(itemData) {
if (this.type === "skill_category") { if (itemData.type !== "skill_category") return;
console.log("rmss | item.js | Calculating Skill Category Total Bonus for: " + itemData.name); console.log(`rmss | item.js | Preparing Skill Category Data for: ${itemData.name}`);
const systemData = itemData.system; // Calculate Skill Category Total Bonus
itemData.system.total_bonus = Number(systemData.rank_bonus)+Number(systemData.stat_bonus)+Number(systemData.prof_bonus)+Number(systemData.special_bonus_1)+Number(systemData.special_bonus_2); this.calculateSkillCategoryTotalBonus(itemData);
}
} _prepareSkillData(itemData) {
if (itemData.type !== "skill") return;
console.log(`rmss | item.js | Preparing Skill Data for: ${itemData.name}`);
// Make modifications to data here. For example:
// const systemData = itemData.system;
// Calculate Skill Category Bonus
this.calculateSelectedSkillCategoryBonus(itemData);
// Calculate Skill Total Bonus
this.calculateSkillTotalBonus(itemData);
}
calculateSkillCategoryTotalBonus(itemData) {
if (this.type === "skill_category") {
console.log(`rmss | item.js | Calculating Skill Category Total Bonus for: ${itemData.name}`);
const systemData = itemData.system;
itemData.system.total_bonus = Number(systemData.rank_bonus)
+ Number(systemData.stat_bonus)
+ Number(systemData.prof_bonus)
+ Number(systemData.special_bonus_1)
+ Number(systemData.special_bonus_2);
} }
}
calculateSkillTotalBonus(itemData) { calculateSkillTotalBonus(itemData) {
if (this.type === "skill") { if (this.type === "skill") {
const systemData = itemData.system; const systemData = itemData.system;
console.log(`rmss | item.js | Calculating Skill Total Bonus for: ${itemData.name}`);
console.log("rmss | item.js | Calculating Skill Total Bonus for: " + itemData.name) itemData.system.total_bonus = Number(systemData.rank_bonus)
itemData.system.total_bonus = Number(systemData.rank_bonus)+Number(systemData.category_bonus)+Number(systemData.item_bonus)+Number(systemData.special_bonus_1)+Number(systemData.special_bonus_2); + Number(systemData.category_bonus)
} + Number(systemData.item_bonus)
+ Number(systemData.special_bonus_1)
+ Number(systemData.special_bonus_2);
} }
}
calculateSelectedSkillCategoryBonus(itemData) { calculateSelectedSkillCategoryBonus(itemData) {
if (this.isEmbedded === null) { if (this.isEmbedded === null) {
console.log("rmss | item.js | Skill " + this.name + " has no owner. Not calculating Skill Category bonus"); console.log(`rmss | item.js | Skill ${this.name} has no owner. Not calculating Skill Category bonus`);
} }
else else
{ {
const items = this.parent.items; const items = this.parent.items;
console.log("rmss | item.js | Skill " + this.name + " has owner, calculating skill category bonus."); console.log(`rmss | item.js | Skill ${this.name} has owner, calculating skill category bonus.`);
for (const item of items) { for (const item of items) {
if (item.type === "skill_category" && item._id === itemData.system.category) { if (item.type === "skill_category" && item._id === itemData.system.category) {
console.log("rmss | item.js | Calculating Skill Category bonus for skill: " + this.name); console.log(`rmss | item.js | Calculating Skill Category bonus for skill: ${this.name}`);
this.system.category_bonus = item.system.total_bonus; this.system.category_bonus = item.system.total_bonus;
}
}
} }
}
} }
} }
}

View File

@ -1,306 +1,390 @@
export default class RMSSPlayerSheet extends ActorSheet { export default class RMSSPlayerSheet extends ActorSheet {
// Override Default Options, Set CSS Classes, Set Default Sheet, Set up Sheet Tabs
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
template: "systems/rmss/templates/sheets/actors/rmss-character-sheet.html",
classes: ["rmss", "sheet", "actor"],
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "features" }]
});
}
// Make the data available to the sheet template
getData() {
const context = super.getData();
// Use a safe clone of the actor data for further operations.
const actorData = this.actor.toObject(false);
// Add the actor's data to context.data for easier access, as well as flags. // Override Default Options, Set CSS Classes, Set Default Sheet, Set up Sheet Tabs
context.system = actorData.system; static get defaultOptions() {
context.flags = actorData.flags; return mergeObject(super.defaultOptions, {
width: 860,
// Prepare character data and items. height: 780,
if (actorData.type == 'character') { template: "systems/rmss/templates/sheets/actors/rmss-character-sheet.html",
this._prepareItems(context); classes: ["rmss", "sheet", "actor"],
this._prepareCharacterData(context); tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "features" }]
} });
}
// Prepare NPC data and items.
if (actorData.type == 'npc') {
this._prepareItems(context);
}
return context;
}
//Override this method to check for duplicates when things are dragged to the sheet
// We don't want duplicate skills and skill categories.
async _onDropItem(event, data) {
// Reconstruct the item from the event
const newitem = await Item.implementation.fromDropData(data);
const itemData = newitem.toObject();
// To Do: Seperate Skills and Skill Categories. Increment Counts for items
if (itemData.type === "skill_category"){
// Get the already owned Items from the actor and push into an array // Make the data available to the sheet template
const owneditems = this.object.getOwnedItemsByType("skill_category"); async getData() {
const context = super.getData();
var ownedskillcatlist = Object.values(owneditems); // Use a safe clone of the actor data for further operations.
const actorData = this.actor.toObject(false);
// Check if the dragged item is not in the array and not owned
if (!ownedskillcatlist.includes(itemData.name)) {
console.log("Not Owned!");
super._onDropItem(event, data);
}
} else if ( itemData.type === "skill") {
// Get the already owned Items from the actor and push into an array
const owneditems = this.object.getOwnedItemsByType("skill");
var ownedskilllist = Object.values(owneditems); let enrichedDescription = await TextEditor.enrichHTML(this.actor.system.description, {async: true});
// Check if the dragged item is not in the array and not owned // Add the actor's data to context.data for easier access, as well as flags.
if (!ownedskilllist.includes(itemData.name)) { context.system = actorData.system;
console.log("Not Owned!"); context.flags = actorData.flags;
super._onDropItem(event, data); context.enrichedDescription = enrichedDescription;
}
} // Prepare character data and items.
else { if (actorData.type === "character") {
super._onDropItem(event, data); this._prepareItems(context);
} this._prepareCharacterData(context);
} }
_prepareCharacterData(context) { // Prepare NPC data and items.
if (actorData.type === "npc") {
this._prepareItems(context);
} }
return context;
_prepareItems(context) { }
console.log("rmss | rmss_player_sheet.js | Preparing items for: "+ this.name);
// Initialize containers.
const gear = [];
const playerskill= [];
const skillcat = [];
const weapons = [];
const armor = [];
const herbs = [];
const spells = [];
const equipables = [];
// Iterate through items, allocating to containers
for (let i of context.items) {
i.img = i.img || DEFAULT_TOKEN;
// Append to gear.
if (i.type === 'item') {
gear.push(i);
}
else if (i.type === 'weapon') {
weapons.push(i);
}
else if (i.type === 'herb_or_poison') {
herbs.push(i);
}
// Append to skill categories.
else if (i.type === 'skill_category') {
skillcat.push(i);
}
// Append to playerskill
else if (i.type === 'skill') {
playerskill.push(i);
}
else if (i.type === 'armor') {
armor.push(i);
}
else if (i.type === 'spell') {
spells.push(i);
}
}
// Sort Skill/Skillcat Arrays
skillcat.sort(function (a, b){
if (a.name < b.name) {
return -1;
}
if (a.name > b.name) {
return 1;
}
return 0;
});
playerskill.sort(function (a, b){ // Override this method to check for duplicates when things are dragged to the sheet
if (a.name < b.name) { // We don't want duplicate skills and skill categories.
return -1; async _onDropItem(event, data) {
}
if (a.name > b.name) {
return 1;
}
return 0;
});
// Assign and return // Reconstruct the item from the event
context.gear = gear; const newitem = await Item.implementation.fromDropData(data);
context.skillcat = skillcat; const itemData = newitem.toObject();
context.playerskill = playerskill;
context.weapons = weapons; // To Do: Seperate Skills and Skill Categories. Increment Counts for items
context.armor = armor; if (itemData.type === "skill_category") {
context.herbs = herbs;
context.spells = spells; // Get the already owned Items from the actor and push into an array
const owneditems = this.object.getOwnedItemsByType("skill_category");
let ownedskillcatlist = Object.values(owneditems);
// Check if the dragged item is not in the array and not owned
if (!ownedskillcatlist.includes(itemData.name)) {
console.log("Not Owned!");
super._onDropItem(event, data);
}
} else if ( itemData.type === "skill") {
// Get the already owned Items from the actor and push into an array
const owneditems = this.object.getOwnedItemsByType("skill");
let ownedskilllist = Object.values(owneditems);
// Check if the dragged item is not in the array and not owned
if (!ownedskilllist.includes(itemData.name)) {
console.log("Not Owned!");
super._onDropItem(event, data);
}
} }
else {
activateListeners(html) { super._onDropItem(event, data);
super.activateListeners(html);
// Render the item sheet for viewing/editing prior to the editable check.
html.find('.item-edit').click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
//console.log(this);
item.sheet.render(true);
});
// -------------------------------------------------------------
// Everything below here is only needed if the sheet is editable
if (!this.isEditable) return;
// Add Item
html.find('.item-create').click(this._onItemCreate.bind(this));
// Delete Item
html.find('.item-delete').click(ev => {
console.log(ev.currentTarget.getAttribute("data-item-id"));
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
item.delete();
});
// Check/Uncheck Favorite Skill
html.find('.skill-favorite').click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
console.log(item);
console.log("Before change: " + item.system.favorite);
if (item.system.favorite === true) {
console.log("Setting False");
item.update({system: {"favorite": false}});
} else {
console.log("Setting True");
item.update({system: {"favorite": true}});
}
console.log("After change: " + item.system.favorite);
});
// Check/Uncheck Favorite Spell
html.find('.spell-favorite').click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
console.log(item);
console.log("Before change: " + item.system.favorite);
if (item.system.favorite === true) {
console.log("Setting False");
item.update({system: {"favorite": false}});
} else {
console.log("Setting True");
item.update({system: {"favorite": true}});
}
console.log("After change: " + item.system.favorite);
});
// Equip/Unequip Item
html.find('.equippable').click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
console.log(item);
console.log("Before change: " + item.system.equipped);
if (item.system.equipped === true) {
console.log("Setting False");
item.update({system: {"equipped": false}});
} else {
console.log("Setting True");
item.update({system: {"equipped": true}});
}
console.log("After change: " + item.system.equipped);
});
// Change New Ranks value when clicked in player sheet. From 0-3.
html.find('.skill-newrank').click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
console.log("Firing in the Player Sheet");
console.log(ev.currentTarget.getAttribute("value"));
console.log(ev.currentTarget.getAttribute("data-item-id"));
switch(ev.currentTarget.getAttribute("value")) {
case "0":
console.log("Skill NewRanks is 0 setting to 1");
item.update({system: {new_ranks:{ "value": 1 }}});
break;
case "1":
console.log("Skill NewRanks is 1 setting to 2");
item.update({system: {new_ranks:{ "value": 2 }}});
break;
case "2":
console.log("Skill NewRanks is 2 setting to 3");
item.update({system: {new_ranks:{ "value": 3 }}});
break;
case "3":
console.log("Skill NewRanks is 3 setting to 0");
item.update({system: {new_ranks:{ "value": 0 }}});
break;
}
});
// Change New Ranks value when clicked in player sheet. From 0-3.
html.find('.skillcategory-newrank').click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
console.log("Firing in the Player Sheet");
console.log(ev.currentTarget.getAttribute("value"));
console.log(ev.currentTarget.getAttribute("data-item-id"));
switch(ev.currentTarget.getAttribute("value")) {
case "0":
console.log("Skill Category NewRanks is 0 setting to 1");
item.update({system: {new_ranks:{ "value": 1 }}});
break;
case "1":
console.log("Skill Category NewRanks is 1 setting to 2");
item.update({system: {new_ranks:{ "value": 2 }}});
break;
case "2":
console.log("Skill Category NewRanks is 2 setting to 3");
item.update({system: {new_ranks:{ "value": 3 }}});
break;
case "3":
console.log("Skill Category NewRanks is 3 setting to 0");
item.update({system: {new_ranks:{ "value": 0 }}});
break;
}
});
} }
}
async _onItemCreate(event) {
event.preventDefault(); _prepareCharacterData(context) {
const header = event.currentTarget; // Calculate Power Point Exhaustion
let powerpointPercentage = (Number(context.system.attributes.power_points.current) / Number(context.system.attributes.power_points.max)) * 100;
// Get the type of item to create.
const type = header.dataset.type; console.log(true);
// Grab any data associated with this control. switch (true) {
const data = duplicate(header.dataset); case (powerpointPercentage < 25):
context.system.attributes.power_points.modifier = "PP Exhaustion Penalty: -30 ";
// Initialize a default name. break;
const name = `New ${type.capitalize()}`; case (powerpointPercentage < 50):
context.system.attributes.power_points.modifier = "PP Exhaustion Penalty: -20 ";
// Prepare the item object. break;
const itemData = { case (powerpointPercentage < 75):
name: name, console.log("Less than 75");
type: type, context.system.attributes.power_points.modifier = "PP Exhaustion Penalty: -10 ";
data: data break;
}; default:
// Remove the type from the dataset since it's in the itemData.type prop. console.log("Setting Default");
delete itemData.data.type; context.system.attributes.power_points.modifier = "PP Exhaustion Penalty: 0 ";
// Finally, create the item!
return await Item.create(itemData, {parent: this.actor});
} }
}
// Calculate Exhaustion Point Penalty
let exhaustionPercentage = (Number(context.system.attributes.exhaustion_points.current) / Number(context.system.attributes.exhaustion_points.max)) * 100;
console.log(true);
switch (true) {
case (exhaustionPercentage < 1):
context.system.attributes.exhaustion_points.modifier = "Exhaustion Penalty: -100 ";
break;
case (exhaustionPercentage < 10):
context.system.attributes.exhaustion_points.modifier = "Exhaustion Penalty: -60 ";
break;
case (exhaustionPercentage < 25):
context.system.attributes.exhaustion_points.modifier = "Exhaustion Penalty: -30 ";
break;
case (exhaustionPercentage < 50):
context.system.attributes.exhaustion_points.modifier = "Exhaustion Penalty: -15 ";
break;
case (exhaustionPercentage < 75):
console.log("Less than 75");
context.system.attributes.exhaustion_points.modifier = "Exhaustion Penalty: -5 ";
break;
default:
console.log("Setting Default");
context.system.attributes.exhaustion_points.modifier = "Exhaustion Penalty: 0 ";
}
}
_prepareItems(context) {
console.log(`rmss | rmss_player_sheet.js | Preparing items for: ${this.name}`);
// Initialize containers.
const gear = [];
const playerskill= [];
const skillcat = [];
const weapons = [];
const armor = [];
const herbs = [];
const spells = [];
const equipables = [];
// Iterate through items, allocating to containers
for (let i of context.items) {
i.img = i.img || DEFAULT_TOKEN;
// Append to gear.
if (i.type === "item") {
gear.push(i);
}
else if (i.type === "weapon") {
weapons.push(i);
}
else if (i.type === "herb_or_poison") {
herbs.push(i);
}
// Append to skill categories.
else if (i.type === "skill_category") {
skillcat.push(i);
}
// Append to playerskill
else if (i.type === "skill") {
playerskill.push(i);
}
else if (i.type === "armor") {
armor.push(i);
}
else if (i.type === "spell") {
spells.push(i);
}
}
// Sort Skill/Skillcat Arrays
skillcat.sort(function(a, b) {
if (a.name < b.name) {
return -1;
}
if (a.name > b.name) {
return 1;
}
return 0;
});
playerskill.sort(function(a, b) {
if (a.name < b.name) {
return -1;
}
if (a.name > b.name) {
return 1;
}
return 0;
});
// Assign and return
context.gear = gear;
context.skillcat = skillcat;
context.playerskill = playerskill;
context.weapons = weapons;
context.armor = armor;
context.herbs = herbs;
context.spells = spells;
}
async renderCharacterSettings(data) {
console.log(data);
const configSheet = await renderTemplate("systems/rmss/templates/sheets/actors/dialogs/actor-settings.html", data);
return (configSheet);
}
activateListeners(html) {
super.activateListeners(html);
// Render the item sheet for viewing/editing prior to the editable check.
html.find(".item-edit").click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
item.sheet.render(true);
});
// -------------------------------------------------------------
// Everything below here is only needed if the sheet is editable
if (!this.isEditable) return;
// Add Item
html.find(".item-create").click(this._onItemCreate.bind(this));
// Delete Item
html.find(".item-delete").click(ev => {
console.log(ev.currentTarget.getAttribute("data-item-id"));
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
item.delete();
});
// Show Sheet Settings
html.find(".import-skillcats").click(async ev => {
let selectOptions = {};
for (const pack of game.packs) {
selectOptions[pack.metadata.id] = pack.metadata.label;
}
new game.rmss.applications.RMSSActorSheetConfig(selectOptions, this.actor).render(true);
});
// Check/Uncheck Favorite Skill
html.find(".skill-favorite").click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
console.log(item);
console.log(`Before change: ${item.system.favorite}`);
if (item.system.favorite === true) {
console.log("Setting False");
item.update({system: {favorite: false}});
} else {
console.log("Setting True");
item.update({system: {favorite: true}});
}
console.log(`After change: ${item.system.favorite}`);
});
// Check/Uncheck Favorite Spell
html.find(".spell-favorite").click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
console.log(item);
console.log(`Before change: ${item.system.favorite}`);
if (item.system.favorite === true) {
console.log("Setting False");
item.update({system: {favorite: false}});
} else {
console.log("Setting True");
item.update({system: {favorite: true}});
}
console.log(`After change: ${item.system.favorite}`);
});
// Equip/Unequip Weapon/Armor
html.find(".equippable").click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
console.log(item);
console.log(`Before change: ${item.system.equipped}`);
if (item.system.equipped === true) {
console.log("Setting False");
item.update({system: {equipped: false}});
} else {
console.log("Setting True");
item.update({system: {equipped: true}});
}
console.log(`After change: ${item.system.equipped}`);
});
// Wear/Remove Item
html.find(".wearable").click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
console.log(item);
console.log(`Before change: ${item.system.equipped}`);
if (item.system.worn === true) {
console.log("Setting False");
item.update({system: {worn: false}});
} else {
console.log("Setting True");
item.update({system: {worn: true}});
}
console.log(`After change: ${item.system.equipped}`);
});
// Change New Ranks value when clicked in player sheet. From 0-3.
html.find(".skill-newrank").click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
console.log("Firing in the Player Sheet");
console.log(ev.currentTarget.getAttribute("value"));
console.log(ev.currentTarget.getAttribute("data-item-id"));
switch (ev.currentTarget.getAttribute("value")) {
case "0":
console.log("Skill NewRanks is 0 setting to 1");
item.update({system: {new_ranks: { value: 1 }}});
break;
case "1":
console.log("Skill NewRanks is 1 setting to 2");
item.update({system: {new_ranks: { value: 2 }}});
break;
case "2":
console.log("Skill NewRanks is 2 setting to 3");
item.update({system: {new_ranks: { value: 3 }}});
break;
case "3":
console.log("Skill NewRanks is 3 setting to 0");
item.update({system: {new_ranks: { value: 0 }}});
break;
}
});
// Change New Ranks value when clicked in player sheet. From 0-3.
html.find(".skillcategory-newrank").click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
console.log("Firing in the Player Sheet");
console.log(ev.currentTarget.getAttribute("value"));
console.log(ev.currentTarget.getAttribute("data-item-id"));
switch (ev.currentTarget.getAttribute("value")) {
case "0":
console.log("Skill Category NewRanks is 0 setting to 1");
item.update({system: {new_ranks: { value: 1 }}});
break;
case "1":
console.log("Skill Category NewRanks is 1 setting to 2");
item.update({system: {new_ranks: { value: 2 }}});
break;
case "2":
console.log("Skill Category NewRanks is 2 setting to 3");
item.update({system: {new_ranks: { value: 3 }}});
break;
case "3":
console.log("Skill Category NewRanks is 3 setting to 0");
item.update({system: {new_ranks: { value: 0 }}});
break;
}
});
}
async _onItemCreate(event) {
event.preventDefault();
const header = event.currentTarget;
// Get the type of item to create.
const type = header.dataset.type;
// Grab any data associated with this control.
const data = duplicate(header.dataset);
// Initialize a default name.
const name = `New ${type.capitalize()}`;
// Prepare the item object.
const itemData = {
name: name,
type: type,
data: data
};
// Remove the type from the dataset since it's in the itemData.type prop.
delete itemData.data.type;
// Finally, create the item!
return await Item.create(itemData, {parent: this.actor});
}
}

View File

@ -0,0 +1,55 @@
export default class RMSSActorSheetConfig extends FormApplication {
constructor(selectOptions, character) {
super();
this.selectOptions = selectOptions;
this.character = character;
}
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
classes: ["form"],
popOut: true,
template: "systems/rmss/templates/sheets/actors/apps/actor-settings.html"
});
}
getData() {
// Send data to the template
return {
selectOptions: this.selectOptions
};
}
activateListeners(html) {
super.activateListeners(html);
}
async _updateObject(event, formData) {
console.log("Deleting Old Skill Categories.");
for (const item of this.character.items) {
if (item.type === "skill_category") {
item.delete();
}
}
const pack = game.packs.get(formData.selectOptions);
const skillCategoryData = await pack.getIndex();
console.log("Importing New Skill Categories.");
for (const sc of skillCategoryData) {
const newitem = await pack.getDocument(sc._id);
let newDocuments = [];
if (newitem.type === "skill_category") {
console.log(newitem);
newDocuments.push(newitem);
}
if (newDocuments.length > 0) {
await Item.createDocuments(newDocuments, {parent: this.character});
}
}
}
}

View File

@ -1,36 +1,36 @@
// Our Item Sheet extends the default // Our Item Sheet extends the default
export default class RMSSArmorSheet extends ItemSheet { export default class RMSSArmorSheet extends ItemSheet {
// Set the height and width // Set the height and width
static get defaultOptions() { static get defaultOptions() {
return mergeObject(super.defaultOptions, { return mergeObject(super.defaultOptions, {
width: 530, width: 530,
height: 440, height: 440,
template: "systems/rmss/templates/sheets/items/rmss-armor-sheet.html", template: "systems/rmss/templates/sheets/items/rmss-armor-sheet.html",
classes: ["rmss", "sheet", "item"] classes: ["rmss", "sheet", "item"]
}); });
} }
// If our sheet is called here it is.
get template() {
return `systems/rmss/templates/sheets/items/rmss-armor-sheet.html`;
}
// Make the data available to the sheet template // If our sheet is called here it is.
async getData() { get template() {
const baseData = await super.getData(); return "systems/rmss/templates/sheets/items/rmss-armor-sheet.html";
}
var enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true}); // Make the data available to the sheet template
async getData() {
const baseData = await super.getData();
let sheetData = { let enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
owner: this.item.isOwner,
editable :this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData; let sheetData = {
} owner: this.item.isOwner,
} editable: this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData;
}
}

View File

@ -1,36 +1,36 @@
// Our Item Sheet extends the default // Our Item Sheet extends the default
export default class RMSSHerbAndPoisonSheet extends ItemSheet { export default class RMSSHerbAndPoisonSheet extends ItemSheet {
// Set the height and width // Set the height and width
static get defaultOptions() { static get defaultOptions() {
return mergeObject(super.defaultOptions, { return mergeObject(super.defaultOptions, {
width: 530, width: 530,
height: 440, height: 440,
template: "systems/rmss/templates/sheets/items/rmss-herb-or-poison-sheet.html", template: "systems/rmss/templates/sheets/items/rmss-herb-or-poison-sheet.html",
classes: ["rmss", "sheet", "item"] classes: ["rmss", "sheet", "item"]
}); });
} }
// If our sheet is called here it is.
get template() {
return `systems/rmss/templates/sheets/items/rmss-herb-or-poison-sheet.html`;
}
// Make the data available to the sheet template // If our sheet is called here it is.
async getData() { get template() {
const baseData = await super.getData(); return "systems/rmss/templates/sheets/items/rmss-herb-or-poison-sheet.html";
}
var enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true}); // Make the data available to the sheet template
async getData() {
const baseData = await super.getData();
let sheetData = { let enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
owner: this.item.isOwner,
editable :this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData; let sheetData = {
} owner: this.item.isOwner,
} editable: this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData;
}
}

View File

@ -1,36 +1,36 @@
// Our Item Sheet extends the default // Our Item Sheet extends the default
export default class RMSSItemSheet extends ItemSheet { export default class RMSSItemSheet extends ItemSheet {
// Set the height and width // Set the height and width
static get defaultOptions() { static get defaultOptions() {
return mergeObject(super.defaultOptions, { return mergeObject(super.defaultOptions, {
width: 530, width: 530,
height: 440, height: 440,
template: "systems/rmss/templates/sheets/items/rmss-item-sheet.html", template: "systems/rmss/templates/sheets/items/rmss-item-sheet.html",
classes: ["rmss", "sheet", "item"] classes: ["rmss", "sheet", "item"]
}); });
} }
// If our sheet is called here it is.
get template() {
return `systems/rmss/templates/sheets/items/rmss-item-sheet.html`;
}
// Make the data available to the sheet template // If our sheet is called here it is.
async getData() { get template() {
const baseData = await super.getData(); return "systems/rmss/templates/sheets/items/rmss-item-sheet.html";
}
var enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true}); // Make the data available to the sheet template
async getData() {
const baseData = await super.getData();
let sheetData = { let enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
owner: this.item.isOwner,
editable :this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData; let sheetData = {
} owner: this.item.isOwner,
} editable: this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData;
}
}

View File

@ -1,36 +1,36 @@
// Our Item Sheet extends the default // Our Item Sheet extends the default
export default class RMSSTransportSheet extends ItemSheet { export default class RMSSTransportSheet extends ItemSheet {
// Set the height and width // Set the height and width
static get defaultOptions() { static get defaultOptions() {
return mergeObject(super.defaultOptions, { return mergeObject(super.defaultOptions, {
width: 530, width: 530,
height: 440, height: 440,
template: "systems/rmss/templates/sheets/items/rmss-transport-sheet.html", template: "systems/rmss/templates/sheets/items/rmss-transport-sheet.html",
classes: ["rmss", "sheet", "item"] classes: ["rmss", "sheet", "item"]
}); });
} }
// If our sheet is called here it is.
get template() {
return `systems/rmss/templates/sheets/items/rmss-transport-sheet.html`;
}
// Make the data available to the sheet template // If our sheet is called here it is.
async getData() { get template() {
const baseData = await super.getData(); return "systems/rmss/templates/sheets/items/rmss-transport-sheet.html";
}
var enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true}); // Make the data available to the sheet template
async getData() {
const baseData = await super.getData();
let sheetData = { let enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
owner: this.item.isOwner,
editable :this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData; let sheetData = {
} owner: this.item.isOwner,
} editable: this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData;
}
}

View File

@ -1,36 +1,36 @@
// Our Item Sheet extends the default // Our Item Sheet extends the default
export default class RMSSWeaponSheet extends ItemSheet { export default class RMSSWeaponSheet extends ItemSheet {
// Set the height and width // Set the height and width
static get defaultOptions() { static get defaultOptions() {
return mergeObject(super.defaultOptions, { return mergeObject(super.defaultOptions, {
width: 530, width: 530,
height: 440, height: 440,
template: "systems/rmss/templates/sheets/items/rmss-weapon-sheet.html", template: "systems/rmss/templates/sheets/items/rmss-weapon-sheet.html",
classes: ["rmss", "sheet", "item"] classes: ["rmss", "sheet", "item"]
}); });
} }
// If our sheet is called here it is.
get template() {
return `systems/rmss/templates/sheets/items/rmss-weapon-sheet.html`;
}
// Make the data available to the sheet template // If our sheet is called here it is.
async getData() { get template() {
const baseData = await super.getData(); return "systems/rmss/templates/sheets/items/rmss-weapon-sheet.html";
}
var enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true}); // Make the data available to the sheet template
async getData() {
const baseData = await super.getData();
let sheetData = { let enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
owner: this.item.isOwner,
editable :this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData; let sheetData = {
} owner: this.item.isOwner,
} editable: this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData;
}
}

View File

@ -1,132 +1,133 @@
// Our Item Sheet extends the default // Our Item Sheet extends the default
export default class RMSSSkillCategorySheet extends ItemSheet { export default class RMSSSkillCategorySheet extends ItemSheet {
// Set the height and width // Set the height and width
static get defaultOptions() { static get defaultOptions() {
return mergeObject(super.defaultOptions, { return mergeObject(super.defaultOptions, {
width: 580, width: 580,
height: 440, height: 440,
template: "systems/rmss/templates/sheets/skills/rmss-skill-category-sheet.html", template: "systems/rmss/templates/sheets/skills/rmss-skill-category-sheet.html",
classes: ["rmss", "sheet", "item"] classes: ["rmss", "sheet", "item"]
}); });
}
// If our sheet is called here it is.
get template() {
return "systems/rmss/templates/sheets/skills/rmss-skill-category-sheet.html";
}
// Make the data available to the sheet template
async getData() {
const context = await super.getData();
// Get a list of stats that can be used as applicable stats
let applicableStatList = this.prepareApplicableStatNames(CONFIG);
// Get the currently selected value for all three applicable stats
let firstApplicableStat = this.prepareApplicableSelectedStat("app_stat_1");
let secondApplicableStat = this.prepareApplicableSelectedStat("app_stat_2");
let thirdApplicableStat = this.prepareApplicableSelectedStat("app_stat_3");
// Build and apply the display string for Applicable Stats
let applicableStatText =
this.buildApplicableStatsText(firstApplicableStat, secondApplicableStat, thirdApplicableStat);
context.item.system.applicable_stats = applicableStatText;
let enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
let sheetData = {
owner: this.item.isOwner,
editable: this.isEditable,
item: context.item,
system: context.item.system,
config: CONFIG.rmss,
applicable_stat_list: applicableStatList,
applicable_stat_1_selected: firstApplicableStat,
applicable_stat_2_selected: secondApplicableStat,
applicable_stat_3_selected: thirdApplicableStat,
enrichedDescription: enrichedDescription
};
return sheetData;
}
async _setApplicableStat(item, ev) {
// Build a JSON Object from the selected tag value and selected name (item data attribute key)
let updateKey = ev.currentTarget.getAttribute("name");
let updateData = ev.target.value;
// Update Item Data
await item.update({[updateKey]: updateData});
}
// Each Skill Category can have up to three Applicable Stats that apply to it. We need to get a list of
// the Stat Shortnames from Config so the user can select which stats are applicable to this Skill Category
prepareApplicableStatNames(config) {
let applicableStatList = {None: "None"};
for (const item in config.rmss.stats) {
applicableStatList[config.rmss.stats[item].shortname] = config.rmss.stats[item].shortname;
} }
return applicableStatList;
// If our sheet is called here it is. }
get template() {
return `systems/rmss/templates/sheets/skills/rmss-skill-category-sheet.html`; // Get the values for the currently selected Applicable Stat so we can display it on the Skill Category Sheet
// If nothing is selected return an empty string.
prepareApplicableSelectedStat(appStat) {
let applicableStatSelected = "";
applicableStatSelected = this.item.system[appStat];
return applicableStatSelected;
}
// The character sheet has an information field that displays the applicable stats in the following format
// St/Ag/St. This method checks the current applicable stats and builds that field so
// it can be displayed to the user.
buildApplicableStatsText(firstAppStat, secondAppStat, thirdAppStat) {
if (firstAppStat === "None") {
return ("None");
} }
else if (firstAppStat !== "None" && secondAppStat === "None") {
return (firstAppStat);
}
else if (firstAppStat !== "None" && secondAppStat !== "None" && thirdAppStat === "None" ) {
return (`${firstAppStat}/${secondAppStat}`);
}
else if (firstAppStat !== "None" && secondAppStat !== "None" && thirdAppStat !== "None" ) {
return (`${firstAppStat}/${secondAppStat}/${thirdAppStat}`);
}
else {
return ("None");
}
}
// Make the data available to the sheet template activateListeners(html) {
async getData() { super.activateListeners(html);
const context = await super.getData();
// Get a list of stats that can be used as applicable stats // -------------------------------------------------------------
var applicableStatList = this.prepareApplicableStatNames(CONFIG); // Everything below here is only needed if the sheet is editable
if (!this.isEditable) return;
//Get the currently selected value for all three applicable stats // Every time the user selects one of the Applicable Stat dropdowns
var firstApplicableStat = this.prepareApplicableSelectedStat("app_stat_1"); // fire an event to change the value in the Skill Category
var secondApplicableStat = this.prepareApplicableSelectedStat("app_stat_2"); html.find(".stat-selector").change(ev => {
var thirdApplicableStat = this.prepareApplicableSelectedStat("app_stat_3"); this._setApplicableStat(this.item, ev);
});
// Build and apply the display string for Applicable Stats // Catch the event when the user clicks one of the New Ranks Checkboxes in a Skill Category.
var applicableStatText = this.buildApplicableStatsText(firstApplicableStat, secondApplicableStat, thirdApplicableStat); // It will increment by one or wrap back to zero on a value of three
context.item.system.applicable_stats = applicableStatText; html.find(".skillcategorysheet-newrank").click(ev => {
switch (ev.currentTarget.getAttribute("value")) {
var enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true}); case "0":
this.object.update({system: {new_ranks: { value: 1 }}});
let sheetData = { break;
owner: this.item.isOwner, case "1":
editable :this.isEditable, this.object.update({system: {new_ranks: { value: 2 }}});
item: context.item, break;
system: context.item.system, case "2":
config: CONFIG.rmss, this.object.update({system: {new_ranks: { value: 3 }}});
applicable_stat_list: applicableStatList, break;
applicable_stat_1_selected: firstApplicableStat, case "3":
applicable_stat_2_selected: secondApplicableStat, this.object.update({system: {new_ranks: { value: 0 }}});
applicable_stat_3_selected: thirdApplicableStat, break;
enrichedDescription: enrichedDescription }
}; });
return sheetData; }
} }
async _setApplicableStat(item, ev) {
// Build a JSON Object from the selected tag value and selected name (item data attribute key)
var updateKey = ev.currentTarget.getAttribute("name");
var updateData = ev.target.value;
// Update Item Data
await item.update({[updateKey]: updateData});
}
// Each Skill Category can have up to three Applicable Stats that apply to it. We need to get a list of
// the Stat Shortnames from Config so the user can select which stats are applicable to this Skill Category
prepareApplicableStatNames(config) {
var applicableStatList = {None: "None"};
for (const item in config.rmss.stats) {
applicableStatList[config.rmss.stats[item].shortname] = config.rmss.stats[item].shortname;
}
return applicableStatList;
}
// Get the values for the currently selected Applicable Stat so we can display it on the Skill Category Sheet
// If nothing is selected return an empty string.
prepareApplicableSelectedStat(appStat) {
var applicableStatSelected = "";
applicableStatSelected = this.item.system[appStat];
return applicableStatSelected;
}
// The character sheet has an information field that displays the applicable stats in the following format
// St/Ag/St. This method checks the current applicable stats and builds that field so
// it can be displayed to the user.
buildApplicableStatsText(firstAppStat, secondAppStat, thirdAppStat) {
if (firstAppStat === "None") {
return("None");
}
else if (firstAppStat !== "None" && secondAppStat === "None") {
return(firstAppStat);
}
else if (firstAppStat !== "None" && secondAppStat !== "None" && thirdAppStat === "None" ) {
return(firstAppStat + "/" + secondAppStat );
}
else if (firstAppStat !== "None" && secondAppStat !== "None" && thirdAppStat !== "None" ) {
return(firstAppStat + "/" + secondAppStat + "/" + thirdAppStat );
}
else {
return("None");
}
}
activateListeners(html) {
super.activateListeners(html);
// -------------------------------------------------------------
// Everything below here is only needed if the sheet is editable
if (!this.isEditable) return;
// Every time the user selects one of the Applicable Stat dropdowns
// fire an event to change the value in the Skill Category
html.find('.stat-selector').change(ev => {
this._setApplicableStat(this.item, ev);
});
// Catch the event when the user clicks one of the New Ranks Checkboxes in a Skill Category.
// It will increment by one or wrap back to zero on a value of three
html.find('.skillcategorysheet-newrank').click(ev => {
switch(ev.currentTarget.getAttribute("value")) {
case "0":
this.object.update({system: {new_ranks:{ "value": 1 }}});
break;
case "1":
this.object.update({system: {new_ranks:{ "value": 2 }}});
break;
case "2":
this.object.update({system: {new_ranks:{ "value": 3 }}});
break;
case "3":
this.object.update({system: {new_ranks:{ "value": 0 }}});
break;
}
});
}
}

View File

@ -1,115 +1,115 @@
// Our Item Sheet extends the default // Our Item Sheet extends the default
export default class RMSSSkillSheet extends ItemSheet { export default class RMSSSkillSheet extends ItemSheet {
// Set the height and width // Set the height and width
static get defaultOptions() { static get defaultOptions() {
return mergeObject(super.defaultOptions, { return mergeObject(super.defaultOptions, {
width: 530, width: 530,
height: 440, height: 440,
template: "systems/rmss/templates/sheets/skills/rmss-skill-sheet.html", template: "systems/rmss/templates/sheets/skills/rmss-skill-sheet.html",
classes: ["rmss", "sheet", "item"] classes: ["rmss", "sheet", "item"]
}); });
}
// If our sheet is called here it is.
get template() {
return "systems/rmss/templates/sheets/skills/rmss-skill-sheet.html";
}
// Make the data available to the sheet template
async getData() {
const baseData = await super.getData();
let enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
// Get a list of the parent item's skill categories for the dropdown
let ownedSkillCategories = this.prepareSkillCategoryValues();
// Figure out if a valid Skill Category is already selected
let selectedSkillCategory = this.prepareSelectedSkillCategory(ownedSkillCategories, this.object.system.category);
let sheetData = {
owner: this.item.isOwner,
editable: this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
owned_skillcats: ownedSkillCategories,
enrichedDescription: enrichedDescription,
selected_skillcat: selectedSkillCategory,
designations: CONFIG.rmss.skill_designations
};
return sheetData;
}
activateListeners(html) {
super.activateListeners(html);
// Catch the event when the user clicks one of the New Ranks Checkboxes in a Skill.
// It will increment by one or wrap back to zero on a value of three
html.find(".skillsheet-newrank").click(ev => {
switch (ev.currentTarget.getAttribute("value")) {
case "0":
this.object.update({system: {new_ranks: { value: 1 }}});
break;
case "1":
this.object.update({system: {new_ranks: { value: 2 }}});
break;
case "2":
this.object.update({system: {new_ranks: { value: 3 }}});
break;
case "3":
this.object.update({system: {new_ranks: { value: 0 }}});
break;
}
});
}
// Skills are related to Skill Categories so we need something to allow the user to choose that relationship
// If this Skill is owned then we will return a list of Skill Categories and allow them to choose
// Otherwise we'll just return 'Skill has no owner'
prepareSkillCategoryValues() {
let skillNoOwner = {None: "Skill Has No Owner"};
if (this.item.isEmbedded === null) {
return (skillNoOwner);
} }
else
// If our sheet is called here it is. {
get template() { const skillCategories = this.item.parent.getOwnedItemsByType("skill_category");
return `systems/rmss/templates/sheets/skills/rmss-skill-sheet.html`; return (skillCategories);
} }
}
// Make the data available to the sheet template // Determine which Skill Category is selected and test that it is in the current list of categories.
async getData() { // If it isn't set it to None.
const baseData = await super.getData(); prepareSelectedSkillCategory(ownedSkillCategories, selectedSkillCategory) {
let defaultSelectedCategory = "None";
if (Object.keys(ownedSkillCategories).includes(selectedSkillCategory)) {
return (selectedSkillCategory);
} else {
return (defaultSelectedCategory);
}
}
var enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true}); // Populate the Skill Category Bonus field on the Skill Sheet.
// Iterate through the owned skill categories and if one of them matches the item id of currently
// selected skill category then set the Skill Category Bonus field to the Total Bonus field of the Skill Category
prepareSelectedSkillCategoryBonus(selected_skillcat) {
if (this.item.isEmbedded === null) {
console.log("Skill has no owner");
}
else
{
const items = this.object.parent.items;
// Get a list of the parent item's skill categories for the dropdown for (const item of items) {
var ownedSkillCategories = this.prepareSkillCategoryValues(); if (item.type === "skill_category" && item._id === selected_skillcat) {
console.log(`rmss | rmss_skill_sheet | Calculating Skill Category bonus for skill: ${this.object.name}`);
// Figure out if a valid Skill Category is already selected this.object.system.category_bonus = item.system.total_bonus;
var selectedSkillCategory = this.prepareSelectedSkillCategory(ownedSkillCategories, this.object.system.category);
let sheetData = {
owner: this.item.isOwner,
editable :this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
owned_skillcats: ownedSkillCategories,
enrichedDescription: enrichedDescription,
selected_skillcat: selectedSkillCategory,
designations: CONFIG.rmss.skill_designations
};
return sheetData;
} }
}
activateListeners(html) {
super.activateListeners(html);
// Catch the event when the user clicks one of the New Ranks Checkboxes in a Skill.
// It will increment by one or wrap back to zero on a value of three
html.find('.skillsheet-newrank').click(ev => {
switch(ev.currentTarget.getAttribute("value")) {
case "0":
this.object.update({system: {new_ranks:{ "value": 1 }}});
break;
case "1":
this.object.update({system: {new_ranks:{ "value": 2 }}});
break;
case "2":
this.object.update({system: {new_ranks:{ "value": 3 }}});
break;
case "3":
this.object.update({system: {new_ranks:{ "value": 0 }}});
break;
}
});
} }
}
// Skills are related to Skill Categories so we need something to allow the user to choose that relationship }
// If this Skill is owned then we will return a list of Skill Categories and allow them to choose
// Otherwise we'll just return 'Skill has no owner'
prepareSkillCategoryValues() {
var skillNoOwner = {None: "Skill Has No Owner", };
if (this.item.isEmbedded === null) {
return(skillNoOwner);
}
else
{
const skillCategories = this.item.parent.getOwnedItemsByType("skill_category");
return(skillCategories);
}
}
// Determine which Skill Category is selected and test that it is in the current list of categories.
// If it isn't set it to None.
prepareSelectedSkillCategory(ownedSkillCategories, selectedSkillCategory) {
var defaultSelectedCategory = "None";
if (Object.keys(ownedSkillCategories).includes(selectedSkillCategory)) {
return(selectedSkillCategory);
} else {
return(defaultSelectedCategory);
}
}
// Populate the Skill Category Bonus field on the Skill Sheet.
// Iterate through the owned skill categories and if one of them matches the item id of currently select skill category
// then set the Skill Category Bonus field to the Total Bonus field of the Skill Category
prepareSelectedSkillCategoryBonus(selected_skillcat) {
if (this.item.isEmbedded === null) {
console.log("Skill has no owner");
}
else
{
const items = this.object.parent.items;
for (const item of items) {
if (item.type === "skill_category" && item._id === selected_skillcat) {
console.log("rmss | rmss_skill_sheet | Calculating Skill Category bonus for skill: " + this.object.name);
this.object.system.category_bonus = item.system.total_bonus;
}
}
}
}
}

View File

@ -1,35 +1,35 @@
// Our Item Sheet extends the default // Our Item Sheet extends the default
export default class RMSSSpellSheet extends ItemSheet { export default class RMSSSpellSheet extends ItemSheet {
// Set the height and width // Set the height and width
static get defaultOptions() { static get defaultOptions() {
return mergeObject(super.defaultOptions, { return mergeObject(super.defaultOptions, {
width: 530, width: 530,
height: 440, height: 440,
classes: ["rmss", "sheet", "item"] classes: ["rmss", "sheet", "item"]
}); });
} }
// If our sheet is called here it is.
get template() {
return `systems/rmss/templates/sheets/spells/rmss-spell-sheet.html`;
}
// Make the data available to the sheet template // If our sheet is called here it is.
async getData() { get template() {
const baseData = await super.getData(); return "systems/rmss/templates/sheets/spells/rmss-spell-sheet.html";
}
var enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true}); // Make the data available to the sheet template
async getData() {
const baseData = await super.getData();
let sheetData = { let enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
owner: this.item.isOwner,
editable :this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData; let sheetData = {
} owner: this.item.isOwner,
} editable: this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData;
}
}

View File

@ -65,6 +65,12 @@
align-items: center; align-items: center;
padding: 1px; padding: 1px;
} }
.settings-button,
.playersheet-settings {
font-family: Signika, sans-serif;
font-size: 12px;
margin-right: 6px;
}
.resource-container { .resource-container {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@ -231,7 +237,7 @@
} }
.items-grid-container { .items-grid-container {
display: grid; display: grid;
grid-template-columns: [name] 30% [quantity] 17% [weight] 17% [cost] 18% [controls] 18%; grid-template-columns: [worn] 10% [name] 30% [quantity] 15% [weight] 15% [cost] 15% [controls] 15%;
} }
.items-grid-container > div { .items-grid-container > div {
font-family: Signika, sans-serif; font-family: Signika, sans-serif;
@ -245,11 +251,12 @@
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
} }
.items-grid-container > div:nth-child(10n+1), .items-grid-container > div:nth-child(12n+1),
.items-grid-container > div:nth-child(10n+2), .items-grid-container > div:nth-child(12n+2),
.items-grid-container > div:nth-child(10n+3), .items-grid-container > div:nth-child(12n+3),
.items-grid-container > div:nth-child(10n+4), .items-grid-container > div:nth-child(12n+4),
.items-grid-container > div:nth-child(10n+5) { .items-grid-container > div:nth-child(12n+5),
.items-grid-container > div:nth-child(12n+6) {
font-family: Signika, sans-serif; font-family: Signika, sans-serif;
font-size: 12px; font-size: 12px;
text-align: center; text-align: center;
@ -431,6 +438,23 @@
border-bottom: 1px solid; border-bottom: 1px solid;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0); background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
} }
.resistances-grid-container {
outline: 1px solid;
/* use instead of border */
margin-top: 1px;
margin-left: 1px;
padding: 5px;
display: grid;
grid-template-columns: [Name] 40% [Value] 20% [Race_Mod] 20% [Total] 20%;
}
.resistances-grid-heading {
font-weight: bold;
border-bottom: 1px solid;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.resistance-input {
width: 50%;
}
.skillcat-name, .skillcat-name,
.skill-name, .skill-name,
.item-name, .item-name,

View File

@ -1,14 +1,11 @@
// Import Configuration Object // Import Configuration Object
console.log("rmss | Importing configuration javascript"); import { rmss } from "./module/config.js";
import {rmss} from "./module/config.js";
// Import document classes. // Import document classes.
console.log("rmss | Importing document classes");
import { RMSSActor } from "./module/documents/actor.js"; import { RMSSActor } from "./module/documents/actor.js";
import { RMSSItem } from "./module/documents/item.js"; import { RMSSItem } from "./module/documents/item.js";
// Import Sheets // Import Sheets
console.log("rmss | Importing actor and item sheet");
import RMSSItemSheet from "./module/sheets/items/rmss_item_sheet.js"; import RMSSItemSheet from "./module/sheets/items/rmss_item_sheet.js";
import RMSSArmorSheet from "./module/sheets/items/rmss_armor_sheet.js"; import RMSSArmorSheet from "./module/sheets/items/rmss_armor_sheet.js";
import RMSSTransportSheet from "./module/sheets/items/rmss_transport_sheet.js"; import RMSSTransportSheet from "./module/sheets/items/rmss_transport_sheet.js";
@ -19,8 +16,9 @@ import RMSSSkillCategorySheet from "./module/sheets/skills/rmss_skill_category_s
import RMSSSkillSheet from "./module/sheets/skills/rmss_skill_sheet.js"; import RMSSSkillSheet from "./module/sheets/skills/rmss_skill_sheet.js";
import RMSSPlayerSheet from "./module/sheets/actors/rmss_player_sheet.js"; import RMSSPlayerSheet from "./module/sheets/actors/rmss_player_sheet.js";
import RMSSActorSheetConfig from "./module/sheets/actors/rmss_player_sheet_config.js";
// Preload handlebars templates for character sheets /** Preload handlebars templates for character sheets */
async function preloadHandlebarsTemplates() { async function preloadHandlebarsTemplates() {
const templatePaths = [ const templatePaths = [
"systems/rmss/templates/sheets/actors/parts/actor-stats.html", "systems/rmss/templates/sheets/actors/parts/actor-stats.html",
@ -42,68 +40,72 @@ async function preloadHandlebarsTemplates() {
"systems/rmss/templates/sheets/actors/parts/actor-herbs.html", "systems/rmss/templates/sheets/actors/parts/actor-herbs.html",
"systems/rmss/templates/sheets/actors/parts/actor-spells.html", "systems/rmss/templates/sheets/actors/parts/actor-spells.html",
"systems/rmss/templates/sheets/actors/parts/actor-fav-spells.html", "systems/rmss/templates/sheets/actors/parts/actor-fav-spells.html",
"systems/rmss/templates/sheets/actors/parts/actor-fav-items.html" "systems/rmss/templates/sheets/actors/parts/actor-fav-items.html",
"systems/rmss/templates/sheets/actors/apps/actor-settings.html"
]; ];
return loadTemplates(templatePaths); return loadTemplates(templatePaths);
} }
// Hook the init function and set up our system // Hook the init function and set up our system
Hooks.once("init", function () { Hooks.once("init", function() {
console.log("rmss | Initialising Rolemaster Standard System"); console.log("rmss | Initialising Rolemaster Standard System");
// Load our custom actor and item classes // Load our custom actor and item classes
console.log("rmss | Loading Rolemaster Actor and Item classes"); console.log("rmss | Loading Rolemaster Actor and Item classes");
game.rmss = { game.rmss = {
RMSSActor, RMSSActor,
RMSSItem RMSSItem,
applications: {
RMSSActorSheetConfig
}
}; };
// Define custom Document classes // Define custom Document classes
CONFIG.Actor.documentClass = RMSSActor; CONFIG.Actor.documentClass = RMSSActor;
CONFIG.Item.documentClass = RMSSItem; CONFIG.Item.documentClass = RMSSItem;
// Make Config Data Available // Make Config Data Available
CONFIG.rmss = rmss; CONFIG.rmss = rmss;
// Unregister Default Sheets // Unregister Default Sheets
console.log("rmss | Unregistering core sheets"); console.log("rmss | Unregistering core sheets");
Items.unregisterSheet("core", ItemSheet); Items.unregisterSheet("core", ItemSheet);
Actors.unregisterSheet("core", ActorSheet); Actors.unregisterSheet("core", ActorSheet);
// Register RMSS Sheets // Register RMSS Sheets
console.log("rmss | Registering RMSS sheets"); console.log("rmss | Registering RMSS sheets");
// Items // Items
Items.registerSheet("rmss", RMSSItemSheet, {makeDefault: true, label: "rmss.entity_sheet.item", types: ['item']}); Items.registerSheet("rmss", RMSSItemSheet, {makeDefault: true, label: "rmss.entity_sheet.item", types: ["item"]});
Items.registerSheet("rmss", RMSSArmorSheet, {makeDefault: true, label: "rmss.entity_sheet.armor", types: ['armor']}); Items.registerSheet("rmss", RMSSArmorSheet, {makeDefault: true, label: "rmss.entity_sheet.armor", types: ["armor"]});
Items.registerSheet("rmss", RMSSTransportSheet, {makeDefault: true, label: "rmss.entity_sheet.transport", types: ['transport']}); Items.registerSheet("rmss", RMSSTransportSheet, {makeDefault: true, label: "rmss.entity_sheet.transport", types: ["transport"]});
Items.registerSheet("rmss", RMSSWeaponSheet, {makeDefault: true, label: "rmss.entity_sheet.weapon", types: ['weapon']}); Items.registerSheet("rmss", RMSSWeaponSheet, {makeDefault: true, label: "rmss.entity_sheet.weapon", types: ["weapon"]});
Items.registerSheet("rmss", RMSSHerbOrPoisonSheet, {makeDefault: true, label: "rmss.entity_sheet.herb_or_poison", types: ['herb_or_poison']}); Items.registerSheet("rmss", RMSSHerbOrPoisonSheet, {makeDefault: true, label: "rmss.entity_sheet.herb_or_poison", types: ["herb_or_poison"]});
// Spells // Spells
Items.registerSheet("rmss", RMSSSpellSheet, {makeDefault: true, label: "rmss.entity_sheet.spell", types: ['spell']}); Items.registerSheet("rmss", RMSSSpellSheet, {makeDefault: true, label: "rmss.entity_sheet.spell", types: ["spell"]});
// Skills // Skills
Items.registerSheet("rmss", RMSSSkillCategorySheet, {makeDefault: true, label: "rmss.entity_sheet.skill_category", types: ['skill_category']}); Items.registerSheet("rmss", RMSSSkillCategorySheet, {makeDefault: true, label: "rmss.entity_sheet.skill_category", types: ["skill_category"]});
Items.registerSheet("rmss", RMSSSkillSheet, {makeDefault: true, label: "rmss.entity_sheet.skill", types: ['skill']}); Items.registerSheet("rmss", RMSSSkillSheet, {makeDefault: true, label: "rmss.entity_sheet.skill", types: ["skill"]});
// Actors // Actors
Actors.registerSheet("rmss", RMSSPlayerSheet, {makeDefault: true, label: "rmss.entity_sheet.player_characrer", types: ['character']}); Actors.registerSheet("rmss", RMSSPlayerSheet, {makeDefault: true, label: "rmss.entity_sheet.player_characrer", types: ["character"]});
// Preload Handlebars Templates // Preload Handlebars Templates
console.log("rmss | Preloading Handlebars Templates"); console.log("rmss | Preloading Handlebars Templates");
preloadHandlebarsTemplates(); preloadHandlebarsTemplates();
// Handlebars Helpers // Handlebars Helpers
Handlebars.registerHelper('switch', function(value, options) { Handlebars.registerHelper("switch", function(value, options) {
this.switch_value = value; this.switch_value = value;
return options.fn(this); return options.fn(this);
}); });
Handlebars.registerHelper('case', function(value, options) { Handlebars.registerHelper("case", function(value, options) {
if (value == this.switch_value) { if (value === this.switch_value) {
return options.fn(this); return options.fn(this);
} }
}); });
}); });

View File

@ -3,7 +3,7 @@
"title": "Rolemaster Standard System", "title": "Rolemaster Standard System",
"description": "The Rolemaster Standard System system for FoundryVTT.", "description": "The Rolemaster Standard System system for FoundryVTT.",
"author": "Cynicide", "author": "Cynicide",
"version": "0.0.2", "version": "0.0.3",
"minimumCoreVersion": "0.8.6", "minimumCoreVersion": "0.8.6",
"compatibleCoreVersion": "10", "compatibleCoreVersion": "10",
"esmodules":[ "esmodules":[

View File

@ -54,15 +54,51 @@
}, },
"resistance_rolls": { "resistance_rolls": {
"resistance_rolls": { "resistance_rolls": {
"channeling": 0, "channeling": {
"essence": 0, "value": 0,
"mentalism": 0, "race_mod": 0,
"chann_ess": 0, "total": 0
"chann_ment": 0, },
"ess_ment": 0, "essence": {
"arcane": 0, "value": 0,
"poison_disease": 0, "race_mod": 0,
"fear": 0 "total": 0
},
"mentalism": {
"value": 0,
"race_mod": 0,
"total": 0
},
"chann_ess": {
"value": 0,
"race_mod": 0,
"total": 0
},
"chann_ment": {
"value": 0,
"race_mod": 0,
"total": 0
},
"ess_ment": {
"value": 0,
"race_mod": 0,
"total": 0
},
"arcane": {
"value": 0,
"race_mod": 0,
"total": 0
},
"poison_disease": {
"value": 0,
"race_mod": 0,
"total": 0
},
"fear": {
"value": 0,
"race_mod": 0,
"total": 0
}
} }
}, },
"background": { "background": {
@ -184,9 +220,8 @@
} }
} }
}, },
"character": { "character": {
"templates": ["background", "stats", "resistance_rolls", "armor_info", "fixed_info", "race_stat_fixed_info", "role_traits", "money"], "templates": ["background", "stats", "resistance_rolls", "armor_info", "fixed_info", "race_stat_fixed_info", "role_traits", "money", "description"],
"attributes": { "attributes": {
"level": { "level": {
"value": 1 "value": 1
@ -206,11 +241,12 @@
"experience_points": { "experience_points": {
"value": 0 "value": 0
} }
} },
"description": ""
} }
}, },
"Item": { "Item": {
"types": ["item", "skill_category", "skill", "armor", "weapon", "transport", "herb_or_poison", "spell"], "types": ["item", "skill_category", "skill", "armor", "weapon", "transport", "herb_or_poison", "spell", "language"],
"templates": { "templates": {
"base": { "base": {
"description": "Description here." "description": "Description here."
@ -218,6 +254,7 @@
}, },
"item": { "item": {
"templates": ["base"], "templates": ["base"],
"worn": false,
"quantity": 1, "quantity": 1,
"weight": 0, "weight": 0,
"cost": 0, "cost": 0,
@ -270,7 +307,7 @@
"category" : "", "category" : "",
"ranks": 0, "ranks": 0,
"new_ranks": { "new_ranks": {
"value": [0], "value": 0,
"max": 3, "max": 3,
"max_default": 3 "max_default": 3
}, },

View File

@ -0,0 +1,17 @@
<form>
<div>
<h3>Import Skill Categories</h3>
<div>
WARNING: This will erase your existing Skill Categories and import all Skill Categories from the selected Compendium.
</div>
<div>
Select Compendium:
<select name="selectOptions" class="compendium-selector" value="None" itemid="blah">
{{selectOptions selectOptions}}
</select></div>
<div>
<button class="import-skillcats" title="Import">Import</button>
</div>
</div>
</form>

View File

@ -2,6 +2,7 @@
<!-- LOCALIZE THE LAST STRINGS IN THIS PAGE. ALSO SKILLS AND SKILL CATEGORIES--> <!-- LOCALIZE THE LAST STRINGS IN THIS PAGE. ALSO SKILLS AND SKILL CATEGORIES-->
<div class="items-grid-heading">{{ localize "rmss.pc_sheet_items.item_name" }}</div> <div class="items-grid-heading">{{ localize "rmss.pc_sheet_items.item_name" }}</div>
<div class="items-grid-heading">{{ localize "rmss.pc_sheet_items.worn" }}</div>
<div class="items-grid-heading">{{ localize "rmss.pc_sheet_items.quantity" }}</div> <div class="items-grid-heading">{{ localize "rmss.pc_sheet_items.quantity" }}</div>
<div class="items-grid-heading">{{ localize "rmss.pc_sheet_items.weight" }}</div> <div class="items-grid-heading">{{ localize "rmss.pc_sheet_items.weight" }}</div>
<div class="items-grid-heading">{{ localize "rmss.pc_sheet_items.cost" }}</div> <div class="items-grid-heading">{{ localize "rmss.pc_sheet_items.cost" }}</div>
@ -10,6 +11,11 @@
</div> </div>
{{#each gear as |item id|}} {{#each gear as |item id|}}
<div>{{item.name}}</div> <div>{{item.name}}</div>
{{#if item.system.worn}}
<div><a class="wearable" data-item-id="{{item._id}}"><i class="fa-regular fa-square-check"></i></a></div>
{{else}}
<div><a class="wearable" data-item-id="{{item._id}}"><i class="fa-regular fa-square"></i></a></div>
{{/if}}
<div>{{item.system.quantity}}</div> <div>{{item.system.quantity}}</div>
<div>{{item.system.weight}}</div> <div>{{item.system.weight}}</div>
<div>{{item.system.cost}}</div> <div>{{item.system.cost}}</div>

View File

@ -0,0 +1,19 @@
<table>
<th><div class="language-name language-headeritem">{{ localize "rmss.pc_sheet_language.name" }}</div></th>
<th><div class="language-entry language-headeritem">{{ localize "rmss.pc_sheet_language.spoken" }}</div></th>
<th><div class="language-entry language-headeritem">{{ localize "rmss.pc_sheet_language.written" }}</div></th>
<th><div class="language-entry language-headeritem"> </div></th>
{{#each languages as |language id|}}
<tr class="item" data-item-id="{{language._id}}">
<td><div class="language-name">
<h4>{{language.name}}</h4>
</div></td>
<td><div class="language-entry item-prop">{{language.system.spoken}}</div></td>
<td><div class="language-entry item-prop">{{language.system.written}}</div></td>
<td><div class="language-entry item-prop">
<a class="item-edit" title="Edit Language" data-item-id="{{language._id}}"><i class="fas fa-edit"></i></a>
<a class="item-delete" title="Delete Language" data-item-id="{{language._id}}"><i class="fas fa-trash"></i></a>
</div></td>
</tr>
{{/each}}
</table>

View File

@ -1,84 +1,53 @@
<section class="resistance-block"> <section class="resistances-grid-container">
<ol class="labels-list">
<li class="stat flexrow" > <div class="resistances-grid-heading">Name</div>
<div class="label-name"> <div class="resistances-grid-heading">Value</div>
<h4>{{ localize "rmss.pc_sheet_resistances.channeling" }}</h4> <div class="resistances-grid-heading">Racial Mod</div>
</div> <div class="resistances-grid-heading">Total</div>
<div class="label-name">
<h4>{{system.resistance_rolls.channeling}}</h4>
</div>
</li>
<li class="stat flexrow" > <div>{{ localize "rmss.pc_sheet_resistances.channeling" }}</div>
<div class="label-name"> <div>{{system.resistance_rolls.channeling.value}}</div>
<h4>{{ localize "rmss.pc_sheet_resistances.essence" }}</h4> <div class="resistance-input"><input type="text" name="system.resistance_rolls.channeling.race_mod" value="{{system.resistance_rolls.channeling.race_mod}}" data-dtype="Number"/></div>
</div> <div>{{system.resistance_rolls.channeling.total}}</div>
<div class="label-name">
<h4>{{system.resistance_rolls.essence}}</h4>
</div>
</li>
<li class="stat flexrow" > <div>{{ localize "rmss.pc_sheet_resistances.essence" }}</div>
<div class="label-name"> <div>{{system.resistance_rolls.essence.value}}</div>
<h4>{{ localize "rmss.pc_sheet_resistances.mentalism" }}</h4> <div class="resistance-input"><input type="text" name="system.resistance_rolls.essence.race_mod" value="{{system.resistance_rolls.essence.race_mod}}" data-dtype="Number"/></div>
</div> <div>{{system.resistance_rolls.essence.total}}</div>
<div class="label-name">
<h4>{{system.resistance_rolls.mentalism}}</h4>
</div>
</li>
<li class="stat flexrow" > <div>{{ localize "rmss.pc_sheet_resistances.mentalism" }}</div>
<div class="label-name"> <div>{{system.resistance_rolls.mentalism.value}}</div>
<h4>{{ localize "rmss.pc_sheet_resistances.chann_ess" }}</h4> <div class="resistance-input"><input type="text" name="system.resistance_rolls.mentalism.race_mod" value="{{system.resistance_rolls.mentalism.race_mod}}" data-dtype="Number"/></div>
</div> <div>{{system.resistance_rolls.mentalism.total}}</div>
<div class="label-name">
<h4>{{system.resistance_rolls.chann_ess}}</h4>
</div>
</li>
<li class="stat flexrow" > <div>{{ localize "rmss.pc_sheet_resistances.chann_ess" }}</div>
<div class="label-name"> <div>{{system.resistance_rolls.chann_ess.value}}</div>
<h4>{{ localize "rmss.pc_sheet_resistances.chann_ment" }}</h4> <div class="resistance-input"><input type="text" name="system.resistance_rolls.chann_ess.race_mod" value="{{system.resistance_rolls.chann_ess.race_mod}}" data-dtype="Number"/></div>
</div> <div>{{system.resistance_rolls.chann_ess.total}}</div>
<div class="label-name">
<h4>{{system.resistance_rolls.chann_ment}}</h4> <div>{{ localize "rmss.pc_sheet_resistances.chann_ment" }}</div>
</div> <div>{{system.resistance_rolls.chann_ment.value}}</div>
</li> <div class="resistance-input"><input type="text" name="system.resistance_rolls.chann_ment.race_mod" value="{{system.resistance_rolls.chann_ment.race_mod}}" data-dtype="Number"/></div>
<div>{{system.resistance_rolls.chann_ment.total}}</div>
<div>{{ localize "rmss.pc_sheet_resistances.ess_ment" }}</div>
<div>{{system.resistance_rolls.ess_ment.value}}</div>
<div class="resistance-input"><input type="text" name="system.resistance_rolls.ess_ment.race_mod" value="{{system.resistance_rolls.ess_ment.race_mod}}" data-dtype="Number"/></div>
<div>{{system.resistance_rolls.ess_ment.total}}</div>
<div>{{ localize "rmss.pc_sheet_resistances.arcane" }}</div>
<div>{{system.resistance_rolls.arcane.value}}</div>
<div class="resistance-input"><input type="text" name="system.resistance_rolls.arcane.race_mod" value="{{system.resistance_rolls.arcane.race_mod}}" data-dtype="Number"/></div>
<div>{{system.resistance_rolls.arcane.total}}</div>
<div>{{ localize "rmss.pc_sheet_resistances.poison_disease" }}</div>
<div>{{system.resistance_rolls.poison_disease.value}}</div>
<div class="resistance-input"><input type="text" name="system.resistance_rolls.poison_disease.race_mod" value="{{system.resistance_rolls.poison_disease.race_mod}}" data-dtype="Number"/></div>
<div>{{system.resistance_rolls.poison_disease.total}}</div>
<div>{{ localize "rmss.pc_sheet_resistances.fear" }}</div>
<div>{{system.resistance_rolls.fear.value}}</div>
<div class="resistance-input"><input type="text" name="system.resistance_rolls.fear.race_mod" value="{{system.resistance_rolls.fear.race_mod}}" data-dtype="Number"/></div>
<div>{{system.resistance_rolls.fear.total}}</div>
<li class="stat flexrow" >
<div class="label-name">
<h4>{{ localize "rmss.pc_sheet_resistances.ess_ment" }}</h4>
</div>
<div class="label-name">
<h4>{{system.resistance_rolls.ess_ment}}</h4>
</div>
</li>
<li class="stat flexrow" >
<div class="label-name">
<h4>{{ localize "rmss.pc_sheet_resistances.arcane" }}</h4>
</div>
<div class="label-name">
<h4>{{system.resistance_rolls.arcane}}</h4>
</div>
</li>
<li class="stat flexrow" >
<div class="label-name">
<h4>{{ localize "rmss.pc_sheet_resistances.poison_disease" }}</h4>
</div>
<div class="label-name">
<h4>{{system.resistance_rolls.poison_disease}}</h4>
</div>
</li>
<li class="stat flexrow" >
<div class="label-name">
<h4>Fear</h4>
</div>
<div class="label-name">
<h4>{{system.resistance_rolls.fear}}</h4>
</div>
</li>
</ol>
</section> </section>

View File

@ -11,7 +11,9 @@
<div class="skillcat-grid-heading">{{ localize "rmss.pc_sheet_skill_categories.special_bonus" }}</div> <div class="skillcat-grid-heading">{{ localize "rmss.pc_sheet_skill_categories.special_bonus" }}</div>
<div class="skillcat-grid-heading">{{ localize "rmss.pc_sheet_skill_categories.total_bonus" }}</div> <div class="skillcat-grid-heading">{{ localize "rmss.pc_sheet_skill_categories.total_bonus" }}</div>
<div class="skillcat-grid-heading"> <div class="skillcat-grid-heading">
<!-- <a class="item-create" title="Create Skill Category" data-type="skill_category"><i class="fas fa-plus"></i>{{ localize "rmss.pc_sheet_skill_categories.add_skillcat" }}</a>--> <div class="settings-button">
<button type="button" class="import-skillcats" title="Import" acotr_id="">{{ localize "rmss.pc_sheet.import_skillcat" }}</button>
</div>
</div> </div>
{{#each skillcat as |skill_category id|}} {{#each skillcat as |skill_category id|}}
<div>{{skill_category.name}}</div> <div>{{skill_category.name}}</div>

View File

@ -6,9 +6,10 @@
<div class="container"> <div class="container">
<!-- Actor Icon Section--> <!-- Actor Icon Section-->
<div>
<div class="actor-icon"> <div class="actor-icon">
<img src="{{actor.img}}" data-edit="img" title="{{actor.name}}" height="64" width="64"/> <img src="{{actor.img}}" data-edit="img" title="{{actor.name}}" height="64" width="64"/>
</div>
</div> </div>
<!-- Resource Boxes Section--> <!-- Resource Boxes Section-->
@ -17,17 +18,27 @@
<div class="resource-entry"> <div class="resource-entry">
{{ localize "rmss.player_character.resources.hits" }} {{ localize "rmss.player_character.resources.hits" }}
<h4><input name="system.attributes.hits.current" type="text" value="{{system.attributes.hits.current}}"/>/<input name="system.attributes.hits.max" type="text" value="{{system.attributes.hits.max}}"/></h4> <h4><input name="system.attributes.hits.current" type="Number" value="{{system.attributes.hits.current}}"/>/<input name="system.attributes.hits.max" type="Number" value="{{system.attributes.hits.max}}"/></h4>
</div> </div>
<div class="resource-entry"> <div class="resource-entry">
{{ localize "rmss.player_character.resources.exhaustion_points" }} <div class="exhaustion-resources">
<h4><input name="system.attributes.exhaustion_points.current" type="text" value="{{system.attributes.exhaustion_points.current}}"/>/<input name="system.attributes.exhaustion_points.max" type="text" value="{{system.attributes.exhaustion_points.max}}"/></h4> {{ localize "rmss.player_character.resources.exhaustion_points" }}
<h4><input name="system.attributes.exhaustion_points.current" type="Number" value="{{system.attributes.exhaustion_points.current}}"/>/<input name="system.attributes.exhaustion_points.max" type="Number" value="{{system.attributes.exhaustion_points.max}}"/></h4>
</div>
<div class="exhaustion-modifier">
<label>{{system.attributes.exhaustion_points.modifier}}</label>
</div>
</div> </div>
<div class="resource-entry"> <div class="resource-entry">
{{ localize "rmss.player_character.resources.power_points" }} <div class="pp-resources">
<h4><input name="system.attributes.power_points.current" type="text" value="{{system.attributes.power_points.current}}"/>/<input name="system.attributes.power_points.max" type="text" value="{{system.attributes.power_points.max}}"/></h4> {{ localize "rmss.player_character.resources.power_points" }}
<h4><input name="system.attributes.power_points.current" type="Number" value="{{system.attributes.power_points.current}}"/>/<input name="system.attributes.power_points.max" type="Number" value="{{system.attributes.power_points.max}}"/></h4>
</div>
<div class="pp-exhaustion">
<label>{{system.attributes.power_points.modifier}}</label>
</div>
</div> </div>
</div> </div>
@ -41,12 +52,12 @@
<div class="header-text flexrow"> <div class="header-text flexrow">
<label for="level">{{ localize "rmss.player_character.level" }}</label> <label for="level">{{ localize "rmss.player_character.level" }}</label>
<input name="level" type="text" value="{{system.attributes.level.value}}"/> <input name="system.attributes.level.value" type="text" value="{{system.attributes.level.value}}"/>
</div> </div>
<div class="header-text flexrow"> <div class="header-text flexrow">
<label for="experience">{{ localize "rmss.player_character.experience" }}</label> <label for="experience">{{ localize "rmss.player_character.experience" }}</label>
<input name="experience" type="text" value="{{system.attributes.experience_points.value}}"/> <input name="system.attributes.experience_points.value" type="text" value="{{system.attributes.experience_points.value}}"/>
</div> </div>
</div> </div>
@ -88,6 +99,8 @@
{{> "systems/rmss/templates/sheets/actors/parts/actor-fav-spells.html" }} {{> "systems/rmss/templates/sheets/actors/parts/actor-fav-spells.html" }}
<h2>Equipped Items</h2> <h2>Equipped Items</h2>
{{> "systems/rmss/templates/sheets/actors/parts/actor-fav-items.html" }} {{> "systems/rmss/templates/sheets/actors/parts/actor-fav-items.html" }}
<h2>Description</h2>
{{editor enrichedDescription target="system.description" button=true owner=owner editable=editable}}
</div> </div>
</div> </div>

View File

@ -7,11 +7,15 @@
<div> <div>
<table> <table>
<tr> <tr>
<th>{{localize "rmss.item.worn"}}</th>
<th>{{localize "rmss.item.quantity"}}</th> <th>{{localize "rmss.item.quantity"}}</th>
<th>{{localize "rmss.item.weight"}}</th> <th>{{localize "rmss.item.weight"}}</th>
<th>{{localize "rmss.item.cost"}}</th> <th>{{localize "rmss.item.cost"}}</th>
<th>{{localize "rmss.item.prod_time"}}</th> <th>{{localize "rmss.item.prod_time"}}</th>
</tr> </tr>
<td>
<input type="checkbox" name="system.worn" {{checked system.worn}}/>
</td>
<td> <td>
<input name="system.quantity" type="text" value="{{system.quantity}}" data-dtype="Number"/> <input name="system.quantity" type="text" value="{{system.quantity}}" data-dtype="Number"/>
</td> </td>