ENH: Initiative and licensing

master
U~man 2020-07-10 01:38:06 +02:00
parent 83a1c7b717
commit f8265fc4ed
10 changed files with 150 additions and 23 deletions

View File

@ -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.
[![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/H2H21WMKA)

View File

@ -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": "<b>Attack fails</b> ({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"
}

View File

@ -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;

View File

@ -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);

85
src/module/combat.js Normal file
View File

@ -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(
`<a class='combatant-control flag' style='color:${color}' title="${CONFIG.OSE.colors[color]}"><i class='fas fa-flag'></i></a>`
);
});
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,
},
};
}
}

View File

@ -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"
}
};

View File

@ -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);

View File

@ -46,7 +46,8 @@
}
},
"movement": {
"base": 120
"base": 120,
"value": ""
},
"initiative": {
"value": 0,

View File

@ -61,7 +61,7 @@
<h4 class="attribute-name box-title" title="{{localize 'OSE.Movement'}}">{{ localize "OSE.MovementShort" }}
</h4>
<div class="attribute-value">
<input name="data.movement.value" type="text" value="{{data.movement.value}}" placeholder="0"
<input name="data.movement.base" type="text" value="{{data.movement.base}}" placeholder="0"
data-dtype="Number" />
</div>
</li>
@ -138,8 +138,8 @@
{{!-- Saving throws --}}
<div class="attribute-group">
<div class="attacks-description">
<label>{{ localize "OSE.Attacks" }}</label>
<input name="data.att" type="text" value="{{data.att}}" data-dtype="String" />
<label>{{ localize "OSE.MovementDetails" }}</label>
<input name="data.movement.value" type="text" value="{{data.movement.value}}" data-dtype="String" />
</div>
<ul class="attributes">
<li class="attribute saving-throw" data-save="death">

View File

@ -1,6 +1,6 @@
<div class="ose game-license">
<p class="ose game-license">
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 <a href="https://necroticgnome.com">here</a>.
</p>
<p>