diff --git a/README.md b/README.md index 74591b1..a726338 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,16 @@ # Old School Essentials System for Foundry VTT +## Installation +You can now find this Foundry VTT game system within Foundry VTT in the system browser. + ## License -Old-School Essentials is a trademark of Necrotic Gnome. -This Foundry VTT system requires Old-School Essentials Core Rules and does not contain any copyrighted material. +This Foundry VTT system requires Old-School Essentials Core Rules that you can find here [here](https://necroticgnome.com). + +This third party product is not affiliated with or approved by Necrotic Gnome. +Old-School Essentials is a trademark of Necrotic Gnome.The trademark and Old-School Essentials logo are used with permission of Necrotic Gnome, under license ## Contributions -This system is currently under heavy development. +This system is currently in Beta. Feel free to grab a TO DO issue from the gitlab board. You can then do a merge request on the `development` branch. [](https://ko-fi.com/H2H21WMKA) \ No newline at end of file diff --git a/src/lang/en.json b/src/lang/en.json index 9974b4d..1426889 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -72,6 +72,7 @@ "OSE.HitDice": "Hit Dice", "OSE.HitDiceShort": "HD", "OSE.Movement": "Movement Rate", + "OSE.MovementDetails": "Movement Details", "OSE.MovementEncounter": "Encounter Movement Rate", "OSE.MovementEncounterShort": "En", "OSE.MovementOverland": "Overland Movement Rate", @@ -197,5 +198,13 @@ "OSE.messages.AttackFailure": "Attack fails ({bonus})", "OSE.messages.InflictsDamage": "Inflicts damage!", "OSE.ChatContextDamage": "Apply Damage", - "OSE.ChatContextHealing": "Apply Healing" + "OSE.ChatContextHealing": "Apply Healing", + + "OSE.colors.green": "Green", + "OSE.colors.red": "Red", + "OSE.colors.yellow": "Yellow", + "OSE.colors.purple": "Purple", + "OSE.colors.blue": "Blue", + "OSE.colors.orange": "Orange", + "OSE.colors.white": "White" } \ No newline at end of file diff --git a/src/module/actor/character-sheet.js b/src/module/actor/character-sheet.js index 9553cb1..5378ca3 100644 --- a/src/module/actor/character-sheet.js +++ b/src/module/actor/character-sheet.js @@ -110,7 +110,9 @@ export class OseActorSheetCharacter extends OseActorSheet { _calculateMovement(data, weight) { if (data.config.encumbrance == "detailed") { - if (weight > 800) { + if (weight > data.encumbrance.max) { + data.data.movement.base = 0; + } else if (weight > 800) { data.data.movement.base = 30; } else if (weight > 600) { data.data.movement.base = 60; diff --git a/src/module/actor/monster-sheet.js b/src/module/actor/monster-sheet.js index 6f13cf5..d3f2a08 100644 --- a/src/module/actor/monster-sheet.js +++ b/src/module/actor/monster-sheet.js @@ -80,7 +80,6 @@ export class OseActorSheetMonster extends OseActorSheet { } async _onCountChange(event) { - console.log("CHANGE", event); event.preventDefault(); const itemId = event.currentTarget.closest(".item").dataset.itemId; const item = this.actor.getOwnedItem(itemId); diff --git a/src/module/combat.js b/src/module/combat.js new file mode 100644 index 0000000..0637674 --- /dev/null +++ b/src/module/combat.js @@ -0,0 +1,85 @@ +import { OseDice } from "./dice.js"; + +export class OseCombat { + static rollInitiative(combat, data, diff, id) { + // Check groups + data.combatants = []; + let groups = {}; + combat.data.combatants.forEach((cbt) => { + groups[cbt.flags.ose.group] = {present: true}; + data.combatants.push(cbt); + }); + + // Roll init + Object.keys(groups).forEach((group) => { + let roll = new Roll("1d6").roll(); + roll.toMessage({flavor: `${CONFIG.OSE.colors[group]} group rolls initiative`}); + groups[group].initiative = roll.total; + }) + + // Set init + for (let i = 0; i < data.combatants.length; ++i) { + data.combatants[i].initiative = groups[data.combatants[i].flags.ose.group].initiative; + } + } + + static format(object, html, user) { + html.find('.combat-control[data-control="rollNPC"]').remove(); + html.find('.combat-control[data-control="rollAll"]').remove(); + html.find(".combatant").each((_, ct) => { + // Can't roll individual inits + $(ct).find(".roll").remove(); + + // Get group color + let cmbtant = object.combat.getCombatant(ct.dataset.combatantId); + let color = cmbtant.flags.ose.group; + + // Append colored flag + let controls = $(ct).find(".combatant-controls"); + controls.prepend( + `` + ); + }); + OseCombat.addListeners(html); + } + + static addListeners(html) { + // Cycle through colors + html.find(".combatant-control.flag").click((ev) => { + let currentColor = ev.currentTarget.style.color; + let colors = Object.keys(CONFIG.OSE.colors); + let index = colors.indexOf(currentColor); + if (index + 1 == colors.length) { + index = 0; + } else { + index++; + } + let id = $(ev.currentTarget).closest(".combatant")[0].dataset.combatantId; + game.combat.updateCombatant({ + _id: id, + flags: { ose: { group: colors[index] } }, + }); + }); + } + + static addCombatant(combat, data, options, id) { + let token = canvas.tokens.get(data.tokenId); + let color = "black"; + switch (token.data.disposition) { + case -1: + color = "red"; + break; + case 0: + color = "yellow"; + break; + case 1: + color = "green"; + break; + } + data.flags = { + ose: { + group: color, + }, + }; + } +} diff --git a/src/module/config.js b/src/module/config.js index b158219..991d1a1 100644 --- a/src/module/config.js +++ b/src/module/config.js @@ -26,5 +26,14 @@ export const OSE = { light: "OSE.armor.light", heavy: "OSE.armor.heavy", shield: "OSE.armor.shield", + }, + colors: { + green: "OSE.colors.green", + red: "OSE.colors.red", + yellow: "OSE.colors.yellow", + purple: "OSE.colors.purple", + blue: "OSE.colors.blue", + orange: "OSE.colors.orange", + white: "OSE.colors.white" } }; diff --git a/src/ose.js b/src/ose.js index 322ed3b..4115135 100644 --- a/src/ose.js +++ b/src/ose.js @@ -10,6 +10,7 @@ import { registerSettings } from "./module/settings.js"; import { registerHelpers } from "./module/helpers.js"; import * as chat from "./module/chat.js"; import * as macros from "./module/macros.js"; +import { OseCombat } from "./module/combat.js"; /* -------------------------------------------- */ /* Foundry VTT Initialization */ @@ -61,7 +62,7 @@ Hooks.once("init", async function () { */ Hooks.once("setup", function () { // Localize CONFIG objects once up-front - const toLocalize = ["saves_short", "saves_long", "scores", "armor"]; + const toLocalize = ["saves_short", "saves_long", "scores", "armor", "colors"]; for (let o of toLocalize) { CONFIG.OSE[o] = Object.entries(CONFIG.OSE[o]).reduce((obj, e) => { obj[e[0]] = game.i18n.localize(e[1]); @@ -74,21 +75,37 @@ Hooks.once("ready", async () => { Hooks.on("hotbarDrop", (bar, data, slot) => macros.createOseMacro(data, slot) ); - const template = 'systems/ose/templates/chat/license.html'; + const template = "systems/ose/templates/chat/license.html"; const html = await renderTemplate(template); - $('#settings .game-system').append(html); + $("#settings .game-system").append(html); }); -Hooks.on( - "preUpdateCombat", - async (combat, updateData, options, userId) => { - if (!updateData.round) { - return; - } - if (game.settings.get('ose', 'individualInit')) { - } +Hooks.on("preCreateCombatant", (combat, data, options, id) => { + OseCombat.addCombatant(combat, data, options, id); +}); + +Hooks.on("preUpdateCombatant", (combat, combatant, data, diff, id) => { + if (data.initiative) { + let groupInit = data.initiative; + combat.combatants.forEach((ct) => { + if (ct.initiative && ct._id != data._id && ct.flags.ose.group == combatant.flags.ose.group) { + groupInit = ct.initiative; + data.initiative = parseInt(groupInit); + } + }); } -); +}); + +Hooks.on("renderCombatTracker", (object, html, data) => { + OseCombat.format(object, html, data); +}); + +Hooks.on("preUpdateCombat", async (combat, data, diff, id) => { + if (!data.round) { + return; + } + OseCombat.rollInitiative(combat, data, diff, id); +}); Hooks.on("renderChatLog", (app, html, data) => OseItem.chatListeners(html)); Hooks.on("getChatLogEntryContext", chat.addChatMessageContextOptions); diff --git a/src/template.json b/src/template.json index 94d748b..6072050 100644 --- a/src/template.json +++ b/src/template.json @@ -46,7 +46,8 @@ } }, "movement": { - "base": 120 + "base": 120, + "value": "" }, "initiative": { "value": 0, diff --git a/src/templates/actors/partials/monster-attributes-tab.html b/src/templates/actors/partials/monster-attributes-tab.html index d3249bb..90a4e93 100644 --- a/src/templates/actors/partials/monster-attributes-tab.html +++ b/src/templates/actors/partials/monster-attributes-tab.html @@ -61,7 +61,7 @@
- This fan-made system requires requires Old-School Essentials Core Rules that + This fan-made system requires Old-School Essentials Core Rules that you can find here.