Rework roll window

This commit is contained in:
LeRatierBretonnien 2024-07-29 09:28:42 +02:00
parent 3ba8fdd641
commit e25c51a570
21 changed files with 449 additions and 373 deletions

View File

@ -1,4 +1,5 @@
{
"rmss": {
"player_character": {
"name": "Name:",
@ -43,7 +44,8 @@
"equipment": "Equipment",
"spells": "Spells",
"status_record": "Status Record",
"experience_points": "Experience Points"
"experience_points": "Experience Points",
"background": "Background"
},
"pc_sheet_fixed_info": {
"race": "Race:",

View File

@ -15,6 +15,11 @@
.roll-button-container {
display: flex;
flex-direction: column;
justify-content: flex-end;
flex-direction: row;
justify-content: flex-start;
}
.roll-button {
margin-top: 2px;
width: 96px;
max-width: 96px;
}

View File

@ -1,6 +1,6 @@
export const rmss = {};
rmss.curreny_type = {
rmss.currency_type = {
mp: "rmss.curreny_type.mp",
pp: "rmss.curreny_type.pp",
gp: "rmss.curreny_type.gp",
@ -9,6 +9,43 @@ rmss.curreny_type = {
cp: "rmss.curreny_type.cp"
};
rmss.difficulties = {
routine: {key: "routine", label:"Routine (+30)", value: 30},
easy: {key: "easy", label:"Easy (+20)", value: 20},
light: {key: "light", label:"Light (+10)", value: 10},
medium: {key: "medium", label:"Medium (0)", value: 0},
hard: {key: "hard", label:"Hard (-10)", value: -10},
very_hard: {key: "very_hard", label:"Very Hard (-20)", value: -20},
extremely_hard: {key: "extremely_hard", label:"Extremely Hard (-30)", value: -30},
sheer_folly: {key: "sheer_folly", label:"Sheer Folly (-50)", value: -50},
absurd: {key: "absurd", label:"Absurd (-70)", value: -70},
};
rmss.combatSituations = [
{key: "none", label:"None (0)", modifier: 0},
{key: "melee", label:"Melee environment (-20)", modifier: -20},
{key: "missile", label:"Under missile fire (-10)", modifier: -10},
];
rmss.lightOrDarknessModifiers = [
{key: "none", label:"None", modifierLight: 0, modifierDark: 0},
{key: "noshadows", label:"No shadows", modifierLight: 10, modifierDark: -30},
{key: "lightshadows", label:"Light shadows", modifierLight: 5, modifierDark: -20},
{key: "mediumshadows", label:"Medium shadows", modifierLight: 0, modifierDark: 0},
{key: "heavyshadows", label:"Heavy shadows", modifierLight: -10, modifierDark: 10},
{key: "dark", label:"Darkness", modifierLight: -25, modifierDark: 30},
{key: "pitchblack", label:"Pitch black", modifierLight: -40, modifierDark: 40},
]
rmss.hitsPerRound = [
{key: "none", label:"None", modifier: 0},
{key: "one", label:"One", modifier: -5},
{key: "two", label:"Two", modifier: -10},
{key: "three", label:"Three", modifier: -20},
{key: "four", label:"Four", modifier: -25},
{key: "five", label:"Five", modifier: -30},
]
rmss.stats = {
agility: {
fullname: "Agility",

View File

@ -40,6 +40,31 @@ export class RMSSActor extends Actor {
// Iterate through and apply Skill Category Bonuses for Skill items
this.calculateSkillBonuses();
this.computeWoundsMalus();
}
getStunnedModifier() {
if (this.system.state.stunned) {
return Math.min(-50 + (3*this.system.stats.self_discipline.stat_bonus), 0)
} else {
return 0;
}
}
computeWoundsMalus() {
// Compute % of wounds
let percent = 100 - (this.system.attributes.hits.current*100/this.system.attributes.hits.max);
let modifier = 0;
if (percent > 25 && percent < 50) {
modifier = -10;
} else if (percent >= 51 && percent < 75) {
modifier = -20;
} else if (percent >= 76) {
modifier = -30;
}
this.system.modifiers.woundsModifier = modifier;
console.log(`rmss | actor.js | Wounds Malus: ${this.system.modifiers.woundsModifier} ${percent}`);
}
/**
@ -233,52 +258,36 @@ export class RMSSActor extends Actor {
}
else
{
let applicable_stat_bonus = 0;
let app_stat_1_found = false;
let app_stat_2_found = false;
let app_stat_3_found = false;
let applicable_stat_bonuses = [];
// Iterate through the applicable stats and find their full names
for (const stat in CONFIG.rmss.stats) {
// If the configured App Stat matches the one of the stats in config
if (app_stat_1 === CONFIG.rmss.stats[stat].shortname) {
app_stat_1_found = true;
// Get the Stat Bonus
applicable_stat_bonus = applicable_stat_bonus + this.system.stats[stat].stat_bonus;
// Add the Stat Bonus to the array
applicable_stat_bonuses.push(this.system.stats[stat].stat_bonus);
}
if (app_stat_2 === CONFIG.rmss.stats[stat].shortname) {
app_stat_2_found = true;
applicable_stat_bonus = applicable_stat_bonus + this.system.stats[stat].stat_bonus;
// Add the Stat Bonus to the array
applicable_stat_bonuses.push(this.system.stats[stat].stat_bonus);
}
if (app_stat_3 === CONFIG.rmss.stats[stat].shortname) {
app_stat_3_found = true;
applicable_stat_bonus = applicable_stat_bonus + this.system.stats[stat].stat_bonus;
// Add the Stat Bonus to the array
applicable_stat_bonuses.push(this.system.stats[stat].stat_bonus);
}
}
if (app_stat_1_found === true && app_stat_2_found === true && app_stat_3_found === true) {
// Compute the total bonus for the applicable stats
let applicable_stat_bonus = 0;
for (const bonus of applicable_stat_bonuses) {
applicable_stat_bonus += bonus;
}
// Apply the update if we found stat bonuses for every applicable stat
if ( 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
item.calculateSkillCategoryTotalBonus(item);
}
}
}
}
}

View File

@ -217,7 +217,7 @@ export default class RMSSPlayerSheet extends ActorSheet {
html.find(".item-roll").click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
new game.rmss.applications.RMSSToolsDiceRoller(item.name, item.system.total_bonus).render(true);
new game.rmss.applications.RMSSToolsDiceRoller(item, this.actor).render(true);
});
// -------------------------------------------------------------

View File

@ -1,27 +1,17 @@
import {
roll_one_to_onehundred,
roll_low_open_ended,
roll_high_open_ended,
roll_open_ended
} from "./rmss_dice_roller_rolls.js";
import {
getOpenEndedRollModifier,
processOpenEndedSixtySixRoll,
processOpenEndedRoll,
processHighOpenEndedRoll,
processLowOpenEndedRoll
} from "./rmss_dice_roller_processing.js";
export default class RMSSToolsDiceRoller extends FormApplication {
constructor(itemName, characterBonus) {
constructor(item, actor) {
super();
this.itemName = itemName;
this.characterBonus = characterBonus;
this.item = foundry.utils.duplicate(item);
this.actor = actor;
this.itemName = item.name;
this.characterBonus = Number(item.system.total_bonus);
this.stunnedModifier = actor.getStunnedModifier()
this.rollType = [
{value: "one_to_onehundred", text: "1-100", selected: false},
{value: "open_ended", text: "Open-Ended", selected: true},
{value: "high_open_ended", text: "High Open-Ended", selected: false},
{value: "low_open_ended", text: "Low Open-Ended", selected: false}
{ value: "one_to_onehundred", text: "1-100", selected: false },
{ value: "open_ended", text: "Open-Ended", selected: true },
{ value: "high_open_ended", text: "High Open-Ended", selected: false },
{ value: "low_open_ended", text: "Low Open-Ended", selected: false }
];
}
@ -30,8 +20,8 @@ export default class RMSSToolsDiceRoller extends FormApplication {
classes: ["form"],
title: "Rolemaster Dice Roller",
popOut: true,
width: 380,
height: 210,
width: 480,
height: 440,
template: "systems/fvtt-rolemaster-frp/templates/sheets/apps/app_dice_roller.html"
});
}
@ -42,6 +32,15 @@ export default class RMSSToolsDiceRoller extends FormApplication {
itemName: this.itemName,
characterBonus: this.characterBonus,
selectOptions: this.rollType,
woundsModifier: this.actor.system.modifiers.woundsModifier,
config: CONFIG.rmss,
difficulty: 0,
combatSituation: 0,
lightningModifier: 0,
darknessModifier: 0,
hitsPerRound: 0,
isStunned: this.actor.system.state.stunned,
stunnedModifier: this.stunnedModifier
};
}
@ -53,33 +52,112 @@ export default class RMSSToolsDiceRoller extends FormApplication {
console.log("Rolling Dice");
console.log(formData);
console.log(event);
switch (formData.rollType) {
case "one_to_onehundred":
this.roll_one_to_onehundred();
this.roll(event.submitter?.dataset?.value, formData);
}
/* -------------------------------------------- */
async showDiceSoNice(roll, rollMode) {
if (game.modules.get("dice-so-nice")?.active) {
if (game.dice3d) {
let whisper = null;
let blind = false;
rollMode = rollMode ?? game.settings.get("core", "rollMode");
switch (rollMode) {
case "blindroll": //GM only
blind = true;
case "gmroll": //GM + rolling player
whisper = this.getUsers(user => user.isGM);
break;
case "open_ended":
this.roll_open_ended();
case "roll": //everybody
whisper = this.getUsers(user => user.active);
break;
case "high_open_ended":
this.roll_high_open_ended();
break;
case "low_open_ended":
this.roll_low_open_ended();
case "selfroll":
whisper = [game.user.id];
break;
}
await game.dice3d.showForRoll(roll, game.user, true, whisper, blind);
}
}
}
/* -------------------------------------------- */
async roll(rollKey, formData) {
let baseRoll = await new Roll("1d100").roll();
await this.showDiceSoNice(baseRoll, game.settings.get("core", "rollMode"))
let rollType = this.rollType.find(r => r.value == rollKey)?.text;
let rollData = {
name: this.itemName,
rollKey: rollKey,
rollType: rollType,
difficulty: Number(formData.difficulty),
combatSituation: Number(formData?.combatSituation || 0),
lightningModifier: Number(formData?.lightningModifier || 0),
darknessModifier: Number(formData?.darknessModifier || 0),
characterBonus: Number(this.characterBonus),
woundsModifier: Number(this.actor.system.modifiers.woundsModifier),
hitsPerRound: Number(formData.hitsPerRound),
isStunned: this.actor.system.state.stunned,
stunnedModifier: this.stunnedModifier,
rolls: [baseRoll],
}
if (baseRoll.result == 66) {
rollData.content = "You rolled a 66!";
}
// Process the for low open ended rolls
if (rollKey === "open_ended" || rollKey === "low_open_ended") {
if (baseRoll.result < 6) {
rollData.lowopen = true
let newRoll = await new Roll("-1d100").roll();
await this.showDiceSoNice(newRoll, game.settings.get("core", "rollMode"))
rollData.rolls.push(newRoll);
while (newRoll.result > 95) {
newRoll = await new Roll("-1d100").roll();
await this.showDiceSoNice(newRoll, game.settings.get("core", "rollMode"))
rollData.rolls.push(newRoll);
}
}
}
// Process the for high open ended rolls
if (rollKey === "open_ended" || rollKey === "high_open_ended") {
if (baseRoll.result > 95) {
rollData.highopen = true
let newRoll = await new Roll("1d100").roll();
await this.showDiceSoNice(newRoll, game.settings.get("core", "rollMode"))
rollData.rolls.push(newRoll);
while (newRoll.result > 95) {
newRoll = await new Roll("1d100").roll();
await this.showDiceSoNice(newRoll, game.settings.get("core", "rollMode"))
rollData.rolls.push(newRoll);
}
}
}
// Compute total of rolls
rollData.totalRolls = rollData.rolls.reduce((acc, roll) => Number(acc) + Number(roll.result), 0);
rollData.totalFinal = rollData.totalRolls + Number(rollData.combatSituation) +
Number(rollData.lightningModifier) +
Number(rollData.darknessModifier) +
Number(this.actor.system.modifiers.woundsModifier) +
Number(formData.difficulty) +
Number(rollData.hitsPerRound) +
Number(rollData.stunnedModifier) +
Number(this.characterBonus);
console.log(">>> Roll Data: ", rollData);
// Define the Chat Message Template
let chatTemplate = "systems/fvtt-rolemaster-frp/templates/chat/chat_dice_roll.html";
// Pass the Data through to be used in the Chat Message
let chatData = rollData
// Render the Rolls to the Chat Window
renderTemplate(chatTemplate, chatData).then((html) => {
let chatOptions = {
style: CONST.CHAT_MESSAGE_STYLES.ROLL,
flavor: rollType,
rollMode: game.settings.get("core", "rollMode"),
content: html,
};
ChatMessage.create(chatOptions);
});
}
}
RMSSToolsDiceRoller.prototype.roll_one_to_onehundred = roll_one_to_onehundred;
RMSSToolsDiceRoller.prototype.roll_low_open_ended = roll_low_open_ended;
RMSSToolsDiceRoller.prototype.roll_high_open_ended = roll_high_open_ended;
RMSSToolsDiceRoller.prototype.roll_open_ended = roll_open_ended;
RMSSToolsDiceRoller.prototype.getOpenEndedRollModifier =
getOpenEndedRollModifier;
RMSSToolsDiceRoller.prototype.processOpenEndedSixtySixRoll =
processOpenEndedSixtySixRoll;
RMSSToolsDiceRoller.prototype.processOpenEndedRoll = processOpenEndedRoll;
RMSSToolsDiceRoller.prototype.processHighOpenEndedRoll =
processHighOpenEndedRoll;
RMSSToolsDiceRoller.prototype.processLowOpenEndedRoll = processLowOpenEndedRoll;

View File

@ -1,131 +0,0 @@
export async function getOpenEndedRollModifier() {
return await new Roll("1d100x>95").roll();
}
export function processOpenEndedSixtySixRoll(baseroll, rolltype) {
// Log the Roll to Chat
let chatOptions = {
type: CONST.CHAT_MESSAGE_TYPES.ROLL,
rolls: [baseroll],
flavor: rolltype,
rollMode: game.settings.get("core", "rollMode"),
content: "You rolled a 66!",
};
ChatMessage.create(chatOptions);
}
export function processOpenEndedRoll(baseroll, rolltype) {
// Define the Chat Message Template
let chatTemplate = "systems/fvtt-rolemaster-frp/templates/chat/chat_dice_roll.html";
// Pass the Data through to be used in the Chat Message
let chatData = {
baseroll: baseroll,
total: baseroll.result,
highopen: false,
lowopen: false,
};
// Render the Rolls to the Chat Window
renderTemplate(chatTemplate, chatData).then((html) => {
let chatOptions = {
type: CONST.CHAT_MESSAGE_TYPES.ROLL,
rolls: [baseroll],
flavor: rolltype,
rollMode: game.settings.get("core", "rollMode"),
content: html,
};
ChatMessage.create(chatOptions);
});
}
export async function processHighOpenEndedRoll(baseroll, rolltype) {
// Get the Base Roll followed by the High Open Ended Roll
let originalRoll = baseroll;
let openendedRoll = await this.getOpenEndedRollModifier();
// Create a rolls array for Dice So Nice integration.
let rolls = [originalRoll, openendedRoll];
// Create an Array to hold the High Open Ended Roll Results and set the total to base roll
let openendedResults = [];
let total = Number(originalRoll.result);
// Each time the High Open Ended Roll is triggered add the result to an array and add it to the total.
for (const rollResult of openendedRoll.dice[0].results) {
openendedResults.push(rollResult.result);
total = total + Number(rollResult.result);
}
// Define the Chat Message Template
let chatTemplate = "systems/fvtt-rolemaster-frp/templates/chat/chat_dice_roll.html";
// Pass the Data through to be used in the Chat Message
let chatData = {
baseroll: baseroll,
opeendedresults: [openendedResults],
highopen: true,
lowopen: false,
total: total,
};
// Render the Rolls to the Chat Window
renderTemplate(chatTemplate, chatData).then((html) => {
let chatOptions = {
style: CONST.CHAT_MESSAGE_STYLES.ROLL,
rolls: rolls,
flavor: rolltype,
rollMode: game.settings.get("core", "rollMode"),
content: html,
};
ChatMessage.create(chatOptions);
});
}
export async function processLowOpenEndedRoll(baseroll, rolltype) {
// Get the Base Roll followed by the Low Open Ended Roll
let originalRoll = baseroll;
let openendedRoll = await this.getOpenEndedRollModifier();
// Create a rolls array for Dice So Nice integration.
let rolls = [originalRoll, openendedRoll];
// Create an Array to hold the Low Open Ended Roll Results and set the total to base roll
let openendedResults = [];
let total = Number(originalRoll.result);
// Each time the Low Open Ended Roll is triggered add the result to an array and subtract it from the total.
for (const rollResult of openendedRoll.dice[0].results) {
openendedResults.push(rollResult.result);
total = total - Number(rollResult.result);
}
// Define the Chat Message Template
let chatTemplate = "systems/fvtt-rolemaster-frp/templates/chat/chat_dice_roll.html";
// Pass the Data through to be used in the Chat Message
let chatData = {
baseroll: baseroll,
rolls: rolls,
opeendedresults: [openendedResults],
highopen: false,
lowopen: true,
total: total,
};
// Render the Rolls to the Chat Window
renderTemplate(chatTemplate, chatData).then((html) => {
let chatOptions = {
style: CONST.CHAT_MESSAGE_STYLES.ROLL,
rolls: rolls,
flavor: rolltype,
rollMode: game.settings.get("core", "rollMode"),
content: html,
};
ChatMessage.create(chatOptions);
});
}

View File

@ -1,71 +0,0 @@
export async function roll_one_to_onehundred() {
// Construct the Roll instance
let baseroll = await new Roll("1d100 + @characterBonus", {characterBonus: this.characterBonus}).roll({async: true});
let rolltype = "Roll Type: 1-100";
// Log the Roll to Chat
let chatOptions = {
type: CONST.CHAT_MESSAGE_TYPES.ROLL,
rolls: [baseroll],
flavor: rolltype,
rollMode: game.settings.get("core", "rollMode")
};
ChatMessage.create(chatOptions);
this.close();
};
export async function roll_low_open_ended() {
// Construct the Roll instance
let baseroll = await new Roll("1d100").roll({async: true});
console.log(baseroll.result);
let rolltype = "Roll Type: Low Open-Ended";
switch (true) {
case (baseroll.result < 6):
this.processLowOpenEndedRoll(baseroll, rolltype);
break;
case (baseroll.result === 66):
this.processOpenEndedSixtySixRoll(baseroll, rolltype);
break;
default:
this.processOpenEndedRoll(baseroll, rolltype);
}
}
export async function roll_high_open_ended() {
// Construct the Roll instance
let baseroll = await new Roll("1d100").roll({async: true});
console.log(baseroll.result);
let rolltype = "Roll Type: High Open-Ended";
switch (true) {
case (baseroll.result === 66):
this.processOpenEndedSixtySixRoll(baseroll, rolltype);
break;
case (baseroll.result > 95):
this.processHighOpenEndedRoll(baseroll, rolltype);
break;
default:
this.processOpenEndedRoll(baseroll, rolltype);
}
}
export async function roll_open_ended() {
// Construct the Roll instance
let baseroll = await new Roll("1d100").roll({async: true});
console.log(baseroll.result);
let rolltype = "Roll Type: Open-Ended";
switch (true) {
case (baseroll.result < 6):
this.processLowOpenEndedRoll(baseroll, rolltype);
break;
case (baseroll.result === 66):
this.processOpenEndedSixtySixRoll(baseroll, rolltype);
break;
case (baseroll.result > 95):
this.processHighOpenEndedRoll(baseroll, rolltype);
break;
default:
this.processOpenEndedRoll(baseroll, rolltype);
}
}

View File

@ -1 +1 @@
MANIFEST-000010
MANIFEST-000036

View File

@ -1,8 +1,8 @@
2024/07/26-14:23:44.308792 7f70f96006c0 Recovering log #8
2024/07/26-14:23:44.319859 7f70f96006c0 Delete type=3 #6
2024/07/26-14:23:44.320012 7f70f96006c0 Delete type=0 #8
2024/07/26-18:27:58.297420 7f70f3e006c0 Level-0 table #13: started
2024/07/26-18:27:58.297474 7f70f3e006c0 Level-0 table #13: 0 bytes OK
2024/07/26-18:27:58.371139 7f70f3e006c0 Delete type=0 #11
2024/07/26-18:27:58.497430 7f70f3e006c0 Manual compaction at level-0 from '!items!1HevhbCbvMonyQXe' @ 72057594037927935 : 1 .. '!items!yRIFroc5VC9Oj3qY' @ 0 : 0; will stop at (end)
2024/07/26-18:27:58.497486 7f70f3e006c0 Manual compaction at level-1 from '!items!1HevhbCbvMonyQXe' @ 72057594037927935 : 1 .. '!items!yRIFroc5VC9Oj3qY' @ 0 : 0; will stop at (end)
2024/07/28-21:56:25.081245 7f61a16006c0 Recovering log #34
2024/07/28-21:56:25.092625 7f61a16006c0 Delete type=3 #32
2024/07/28-21:56:25.092815 7f61a16006c0 Delete type=0 #34
2024/07/28-21:58:38.763455 7f619e8006c0 Level-0 table #39: started
2024/07/28-21:58:38.763505 7f619e8006c0 Level-0 table #39: 0 bytes OK
2024/07/28-21:58:38.770667 7f619e8006c0 Delete type=0 #37
2024/07/28-21:58:38.788630 7f619e8006c0 Manual compaction at level-0 from '!items!1HevhbCbvMonyQXe' @ 72057594037927935 : 1 .. '!items!yRIFroc5VC9Oj3qY' @ 0 : 0; will stop at (end)
2024/07/28-21:58:38.788705 7f619e8006c0 Manual compaction at level-1 from '!items!1HevhbCbvMonyQXe' @ 72057594037927935 : 1 .. '!items!yRIFroc5VC9Oj3qY' @ 0 : 0; will stop at (end)

View File

@ -1,8 +1,8 @@
2024/07/26-13:01:33.184951 7f70fa0006c0 Recovering log #4
2024/07/26-13:01:33.276590 7f70fa0006c0 Delete type=0 #4
2024/07/26-13:01:33.276711 7f70fa0006c0 Delete type=3 #2
2024/07/26-14:15:40.712242 7f70f3e006c0 Level-0 table #9: started
2024/07/26-14:15:40.712297 7f70f3e006c0 Level-0 table #9: 0 bytes OK
2024/07/26-14:15:40.750893 7f70f3e006c0 Delete type=0 #7
2024/07/26-14:15:40.806643 7f70f3e006c0 Manual compaction at level-0 from '!items!1HevhbCbvMonyQXe' @ 72057594037927935 : 1 .. '!items!yRIFroc5VC9Oj3qY' @ 0 : 0; will stop at (end)
2024/07/26-14:15:40.863267 7f70f3e006c0 Manual compaction at level-1 from '!items!1HevhbCbvMonyQXe' @ 72057594037927935 : 1 .. '!items!yRIFroc5VC9Oj3qY' @ 0 : 0; will stop at (end)
2024/07/28-20:52:49.342374 7f61a0c006c0 Recovering log #30
2024/07/28-20:52:49.352664 7f61a0c006c0 Delete type=3 #28
2024/07/28-20:52:49.352840 7f61a0c006c0 Delete type=0 #30
2024/07/28-21:24:37.661095 7f619e8006c0 Level-0 table #35: started
2024/07/28-21:24:37.661145 7f619e8006c0 Level-0 table #35: 0 bytes OK
2024/07/28-21:24:37.667298 7f619e8006c0 Delete type=0 #33
2024/07/28-21:24:37.684364 7f619e8006c0 Manual compaction at level-0 from '!items!1HevhbCbvMonyQXe' @ 72057594037927935 : 1 .. '!items!yRIFroc5VC9Oj3qY' @ 0 : 0; will stop at (end)
2024/07/28-21:24:37.684461 7f619e8006c0 Manual compaction at level-1 from '!items!1HevhbCbvMonyQXe' @ 72057594037927935 : 1 .. '!items!yRIFroc5VC9Oj3qY' @ 0 : 0; will stop at (end)

Binary file not shown.

View File

@ -522,8 +522,13 @@
}
.roll-button-container {
display: flex;
flex-direction: column;
justify-content: flex-end;
flex-direction: row;
justify-content: flex-start;
}
.roll-button {
margin-top: 2px;
width: 96px;
max-width: 96px;
}
.sheet form {
display: flex;

34
rmss.js
View File

@ -52,7 +52,7 @@ async function preloadHandlebarsTemplates() {
// registerGetSceneControlButtonsHook();
// Hook the init function and set up our system
Hooks.once("init", function() {
Hooks.once("init", function () {
console.log("rmss | Initialising Rolemaster Standard System");
// Load our custom actor and item classes
@ -74,7 +74,7 @@ Hooks.once("init", function() {
CONFIG.fontDefinitions["PragRoman"] = {
editor: true,
fonts: [
{urls: ["systems/fvtt-rolemaster-frp/assets/fonts/PragRoman.woff2"]}
{ urls: ["systems/fvtt-rolemaster-frp/assets/fonts/PragRoman.woff2"] }
]
};
@ -91,35 +91,43 @@ Hooks.once("init", function() {
console.log("rmss | Registering RMSS sheets");
// Items
Items.registerSheet("fvtt-rolemaster-frp", RMSSItemSheet, {makeDefault: true, label: "rmss.entity_sheet.item", types: ["item"]});
Items.registerSheet("fvtt-rolemaster-frp", RMSSArmorSheet, {makeDefault: true, label: "rmss.entity_sheet.armor", types: ["armor"]});
Items.registerSheet("fvtt-rolemaster-frp", RMSSTransportSheet, {makeDefault: true, label: "rmss.entity_sheet.transport", types: ["transport"]});
Items.registerSheet("fvtt-rolemaster-frp", RMSSWeaponSheet, {makeDefault: true, label: "rmss.entity_sheet.weapon", types: ["weapon"]});
Items.registerSheet("fvtt-rolemaster-frp", RMSSHerbOrPoisonSheet, {makeDefault: true, label: "rmss.entity_sheet.herb_or_poison", types: ["herb_or_poison"]});
Items.registerSheet("fvtt-rolemaster-frp", RMSSItemSheet, { makeDefault: true, label: "rmss.entity_sheet.item", types: ["item"] });
Items.registerSheet("fvtt-rolemaster-frp", RMSSArmorSheet, { makeDefault: true, label: "rmss.entity_sheet.armor", types: ["armor"] });
Items.registerSheet("fvtt-rolemaster-frp", RMSSTransportSheet, { makeDefault: true, label: "rmss.entity_sheet.transport", types: ["transport"] });
Items.registerSheet("fvtt-rolemaster-frp", RMSSWeaponSheet, { makeDefault: true, label: "rmss.entity_sheet.weapon", types: ["weapon"] });
Items.registerSheet("fvtt-rolemaster-frp", RMSSHerbOrPoisonSheet, { makeDefault: true, label: "rmss.entity_sheet.herb_or_poison", types: ["herb_or_poison"] });
// Spells
Items.registerSheet("fvtt-rolemaster-frp", RMSSSpellSheet, {makeDefault: true, label: "rmss.entity_sheet.spell", types: ["spell"]});
Items.registerSheet("fvtt-rolemaster-frp", RMSSSpellSheet, { makeDefault: true, label: "rmss.entity_sheet.spell", types: ["spell"] });
// Skills
Items.registerSheet("fvtt-rolemaster-frp", RMSSSkillCategorySheet, {makeDefault: true, label: "rmss.entity_sheet.skill_category", types: ["skill_category"]});
Items.registerSheet("fvtt-rolemaster-frp", RMSSSkillSheet, {makeDefault: true, label: "rmss.entity_sheet.skill", types: ["skill"]});
Items.registerSheet("fvtt-rolemaster-frp", RMSSSkillCategorySheet, { makeDefault: true, label: "rmss.entity_sheet.skill_category", types: ["skill_category"] });
Items.registerSheet("fvtt-rolemaster-frp", RMSSSkillSheet, { makeDefault: true, label: "rmss.entity_sheet.skill", types: ["skill"] });
// Actors
Actors.registerSheet("fvtt-rolemaster-frp", RMSSPlayerSheet, {makeDefault: true, label: "rmss.entity_sheet.player_characrer", types: ["character"]});
Actors.registerSheet("fvtt-rolemaster-frp", RMSSPlayerSheet, { makeDefault: true, label: "rmss.entity_sheet.player_characrer", types: ["character"] });
// Preload Handlebars Templates
console.log("rmss | Preloading Handlebars Templates");
preloadHandlebarsTemplates();
// Handlebars Helpers
Handlebars.registerHelper("switch", function(value, options) {
Handlebars.registerHelper("switch", function (value, options) {
this.switch_value = value;
return options.fn(this);
});
Handlebars.registerHelper("case", function(value, options) {
Handlebars.registerHelper("case", function (value, options) {
if (value === this.switch_value) {
return options.fn(this);
}
});
// Handle v12 removal of this helper
Handlebars.registerHelper('select', function (selected, options) {
const escapedValue = RegExp.escape(Handlebars.escapeExpression(selected));
const rgx = new RegExp(' value=[\"\']' + escapedValue + '[\"\']');
const html = options.fn(this);
return html.replace(rgx, "$& selected");
});
});

View File

@ -3,7 +3,7 @@
"title": "Rolemaster FRP System",
"description": "The Rolemaster FRP system for FoundryVTT.",
"manifest": "https://www.uberwald.me/gitea/public/fvtt-rolemaster-frp/raw/branch/develop/system.json",
"download": "https://www.uberwald.me/gitea/public/fvtt-rolemaster-frp/archive/v12.0.1.zip",
"download": "https://www.uberwald.me/gitea/public/fvtt-rolemaster-frp/archive/v12.0.3.zip",
"authors": [
{
"name": "Cynicide",
@ -14,7 +14,7 @@
"email": ""
}
],
"version": "12.0.1",
"version": "12.0.3",
"compatibility": {
"minimum": "12",
"verified": "12"

View File

@ -222,6 +222,14 @@
},
"character": {
"templates": ["background", "stats", "resistance_rolls", "armor_info", "fixed_info", "race_stat_fixed_info", "role_traits", "money", "description"],
"modifiers": {
"woundsModifier": 0
},
"state": {
"stunned": false,
"prone": false,
"noparry": false
},
"attributes": {
"level": {
"value": 1

View File

@ -1,28 +1,70 @@
<div class="dice-roll">
<div class="dice-result">
Original Roll:
<h4 class="dice-total" >{{ baseroll.result }}</h4>
Rolling for : {{name}}
</div>
{{#if highopen }}
<div class=dice-result>
Rolled over 95 - High Open-Ended!
{{#each opeendedresults as |rollresult|}}
<h4 class="dice-total" >{{ rollresult }}</h4>
{{/each}}
</div>
{{/if}}
{{#if lowopen }}
<div class=dice-result>
Rolled under 6 - Low Open-Ended!
{{#each opeendedresults as |rollresult|}}
<h4 class="dice-total" >{{ rollresult }}</h4>
{{/each}}
</div>
{{/if}}
{{#if difficulty}}
<div class=dice-result>
Difficulty : {{difficulty}}
</div>
{{/if}}
{{#if combatSituation}}
<div class=dice-result>
Combat situation : {{combatSituation}}
</div>
{{/if}}
{{#if stunnedModifier}}
<div class=dice-result>
Stunned : {{stunnedModifier}}
</div>
{{/if}}
{{#if hitsPerRound}}
<div class=dice-result>
Hits/round malus : {{hitsPerRound}}
</div>
{{/if}}
{{#if lightningModifier}}
<div class=dice-result>
Lightning modifierLight : {{lightningModifier}}
</div>
{{/if}}
{{#if darknessModifier}}
<div class=dice-result>
Darkness modifierDark : {{darknessModifier}}
</div>
{{/if}}
{{#if woundsModifier}}
<div class="dice-result">
<div>% of hits malus : {{woundsModifier}}</div>
</div>
{{/if}}
<div class="dice-result">
Total:
<h4 class="dice-total" >{{ total }}</h4>
Total of d100 rolls:
<h4 class="dice-total">{{totalRolls}}<br>
({{#each rolls as |roll|}}{{roll.total}}{{#unless @last}}, {{/unless}}{{/each}})</h4>
</div>
<div class=dice-result>
Character Bonus : {{characterBonus}}
</div>
<div class="dice-result">
Total :
<h4 class="dice-total">{{totalFinal}}</h4>
</div>
</div>

View File

@ -19,6 +19,7 @@
<div class="resource-entry">
{{ localize "rmss.player_character.resources.hits" }}
<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>Wounds Modifier : {{system.modifiers.woundsModifier}}</div>
</div>
<div class="resource-entry">
@ -73,6 +74,7 @@
<a class="item" data-tab="Skills">{{ localize "rmss.pc_sheet_tabs.skills" }}</a>
<a class="item" data-tab="Equipment">{{ localize "rmss.pc_sheet_tabs.equipment" }}</a>
<a class="item" data-tab="Spells">{{ localize "rmss.pc_sheet_tabs.spells" }}</a>
<a class="item" data-tab="Background">{{ localize "rmss.pc_sheet_tabs.background" }}</a>
<a class="item" data-tab="StatusRecord">{{ localize "rmss.pc_sheet_tabs.status_record" }}</a>
<a class="item" data-tab="ExperiencePoints">{{ localize "rmss.pc_sheet_tabs.experience_points" }}</a>
</nav>
@ -84,14 +86,16 @@
{{> "systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-fixed-info.html" }}
{{> "systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-armor-info.html" }}
{{> "systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-resistance.html" }}
{{> "systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-race-stat-fixed-info.html" }}
{{> "systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-role-traits.html" }}
{{> "systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-background-info.html" }}
</div>
<div class="stat-container">
{{> "systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-stats.html" }}
<div class="favorite-container">
<span class="label-name">Stunned : </span><input type="checkbox" name="system.state.stunned" {{checked system.state.stunned}}/>
<span class="label-name">Prone : </span><input type="checkbox" name="system.state.prone" {{checked system.state.prone}}/>
</div>
<div class="favorite-container">
<h2>Favorite Skills</h2>
{{> "systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-fav-skills.html" }}
@ -103,8 +107,6 @@
{{editor enrichedDescription target="system.description" button=true owner=owner editable=editable}}
</div>
</div>
</div>
</div>
@ -140,6 +142,19 @@
{{> "systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-spells.html" }}
</div>
</div>
<div class="tab background" data-group="primary" data-tab="Background">
<div class="container">
<div class="fixed-info-container">
{{> "systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-race-stat-fixed-info.html" }}
</div>
<div class="fixed-info-container">
{{> "systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-role-traits.html" }}
{{> "systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-background-info.html" }}
</div>
</div>
</div>
</section>
</form>

View File

@ -2,26 +2,95 @@
<div class="dice-roller-container">
<div class="dice-roller-options">
<div class="dice-roller-item">
<div>Rolling for:</div><div>{{itemName}}</div>
<div>Rolling for:</div>
<div>{{itemName}}</div>
</div>
<div class="dice-roller-item">
<div>Character Bonus:</div><div>{{characterBonus}}</div>
<div>Character Bonus:</div>
<div>{{characterBonus}}</div>
</div>
<div class="dice-roller-item">
<div>Misc Bonus:</div><div><input name="miscBonus" value="0" /></div>
</div>
<div class="dice-roller-item">
<div>Select Roll Type:</div>
<div>Difficulty:</div>
<div>
<select name="rollType" value="None" itemid="blah">
{{#each selectOptions as |option|}}
<option value="{{option.value}}" {{#if option.selected}}selected{{/if}}>{{option.text}}</option>
{{/each}}
<select name="difficulty">
{{selectOptions config.difficulties selected="0" valueKey="value" labelKey="label"}}
</select>
</div>
</div>
<div class="dice-roller-item">
<div>% of hits taken malus:</div>
<div>{{woundsModifier}}</div>
</div>
{{#if isStunned}}
<div class="dice-roller-item">
<div>Stunned:</div>
<div>{{stunnedModifier}}</div>
</div>
{{/if}}
<div class="dice-roller-item">
<div>Combat situations:</div>
<div>
<select name="combatSituation">
{{#select combatSituation}}
{{#each config.combatSituations as |situation|}}
<option value="{{situation.modifier}}">{{situation.label}}</option>
{{/each}}
{{/select}}
</select>
</div>
</div>
<div class="dice-roller-item">
<div>Hits/round taken:</div>
<div>
<select name="hitsPerRound">
{{#select hitsPerRound}}
{{#each config.hitsPerRound as |hit|}}
<option value="{{hit.modifier}}">{{hit.label}}</option>
{{/each}}
{{/select}}
</select>
</div>
</div>
<div class="dice-roller-item">
<div>Lightning, if required:</div>
<div>
<select name="lightningModifier">
{{#select lightningModifier}}
{{#each config.lightOrDarknessModifiers as |lightning|}}
<option value="{{lightning.modifierLight}}">{{lightning.label}}</option>
{{/each}}
{{/select}}
</select>
</div>
</div>
<div class="dice-roller-item">
<div>Darkness, if advantageous:</div>
<div>
<select name="darknessModifier">
{{#select lightningModifier}}
{{#each config.lightOrDarknessModifiers as |darkness|}}
<option value="{{darkness.modifierDark}}">{{darkness.label}}</option>
{{/each}}
{{/select}}
</select>
</div>
</div>
<div class="dice-roller-item">
<div>Misc Bonus:</div>
<div><input name="miscBonus" value="0" /></div>
</div>
<div class="roll-button-container">
<button type="submit">Roll</button>
{{#each selectOptions as |option|}}
<button type="submit" class="roll-button" data-value="{{option.value}}">{{option.text}}</button>
{{/each}}
</div>
</div>
</div>
</form>