15 add duration to active effects (#50)
* Add Effect Duration & Rework Combat tracker Changes: + rework combat tracker to display every uneven round as Movementphase + rework combat tracker to display every even round as actionphase + add possibility for effects durations + effects duration decreases with every actionphase + add enum for time Units + update localization + add display of remaining time on effects + add duration for spelleffect "Bärenwut" * add LP AP Manipulation through effects Changes: + add LimitHeal function + adjust LP AP Values if Mod exists in an effect * Fix linked actor not being updated
This commit is contained in:
parent
30e94741bf
commit
1e27e135cf
15
lang/de.json
15
lang/de.json
|
|
@ -5,11 +5,22 @@
|
|||
|
||||
"TYPES.Item.item": "Gegenstand",
|
||||
"TYPES.Item.weapon": "Waffe",
|
||||
"ITEM.TypeDefensiveWeapon": "Verteidigungswaffe",
|
||||
"TYPES.Item.defensiveWeapon": "Verteidigungswaffe",
|
||||
"TYPES.Item.armor": "Rüstung",
|
||||
"TYPES.Item.spell": "Zauber",
|
||||
"TYPES.Item.effect": "Aktive Effekte",
|
||||
"ITEM.type.kampfkunst": "Kampfkünste",
|
||||
"TYPES.Item.kampfkunst": "Kampfkünste",
|
||||
|
||||
"midgard5.phase-action": "Handlungsphase",
|
||||
"midgard5.phase-movement": "Bewegungsphase",
|
||||
"midgard5.no-encounter": "Kein Kampf",
|
||||
"midgard5.encounter-not-started": "Kein aktiver Kampf",
|
||||
|
||||
"midgard5.time-duration": "Dauer",
|
||||
"midgard5.time-round": "Runde(n)",
|
||||
"midgard5.time-minute": "Minute(n)",
|
||||
"midgard5.time-hour": "Stunde(n)",
|
||||
"midgard5.time-limitless": "Unbegrenzt",
|
||||
|
||||
"midgard5.doRoll": "Würfeln",
|
||||
"midgard5.learn": "Lernen",
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
"description": "<p>ARK S. 144</p>",
|
||||
"equippable": false,
|
||||
"equipped": true,
|
||||
"duration": { "time": 12, "unit": "round" },
|
||||
"value": 0,
|
||||
"magic": true,
|
||||
"rolls": { "formulas": {}, "output": "" },
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import Logger from "./utils/Logger";
|
|||
import M5CharacterSheet from "./module/sheets/M5CharacterSheet";
|
||||
import preloadTemplates from "./PreloadTemplates";
|
||||
import { M5Character } from "./module/actors/M5Character";
|
||||
import { M5Skill } from "./module/M5Base";
|
||||
import { M5ItemMod, M5ModOperation, M5Skill, M5TimeUnit } from "./module/M5Base";
|
||||
import { M5ItemSheet } from "./module/sheets/M5ItemSheet";
|
||||
import { M5Item } from "./module/items/M5Item";
|
||||
|
||||
|
|
@ -58,10 +58,10 @@ Hooks.once("init", async () => {
|
|||
return `${obj}`;
|
||||
});
|
||||
|
||||
Handlebars.registerHelper("actorItemValue", (actorId: any, itemId: string, path: string) => {
|
||||
Handlebars.registerHelper("actorItemValue", (actorId: any, itemId: string, path: string, token?: boolean) => {
|
||||
//console.log("actorItemValue", actorId, itemId, path)
|
||||
const actor = (game as Game).actors.get(actorId);
|
||||
let obj = actor.items.get(itemId).system;
|
||||
let obj = actor.items.get(itemId)?.system;
|
||||
path.split(".").forEach((p) => {
|
||||
if (obj) obj = obj[p];
|
||||
});
|
||||
|
|
@ -116,7 +116,6 @@ Hooks.on("getChatLogEntryContext", function (html, options) {
|
|||
condition: (li) => {
|
||||
// Only show this context menu if there are re-rollable dice in the message
|
||||
const damageRolls = li.find(".apply-damage").length;
|
||||
console.log(game["user"].isGm);
|
||||
|
||||
// All must be true to show the reroll dialogue
|
||||
// The button doesn't work for the GM right now, so we don't need to show it
|
||||
|
|
@ -166,6 +165,70 @@ Hooks.on("getChatLogEntryContext", function (html, options) {
|
|||
);
|
||||
});
|
||||
|
||||
Hooks.on("updateCombat", function (combat: Combat, updateData: { round: number; turn: number }, updateOptions: { advanceTime: number; direction: number }) {
|
||||
if (combat.round % 2 === 0 && combat.turn !== null) {
|
||||
const tokenId = combat.current.tokenId;
|
||||
const actorId = combat.combatant["actorId"];
|
||||
let currentToken = game["actors"].tokens[tokenId];
|
||||
if (!currentToken) {
|
||||
currentToken = game["actors"].get(actorId);
|
||||
}
|
||||
let activeEffects = currentToken.items.filter((x) => x.type === "effect" && x.system.equipped) || [];
|
||||
activeEffects.forEach((effect) => {
|
||||
if (effect.system?.duration?.time > 0) {
|
||||
if (effect.system.duration.unit === M5TimeUnit.ROUND) {
|
||||
effect.system.duration.time -= 1;
|
||||
}
|
||||
}
|
||||
if (effect.system?.duration.time === 0 && effect.system.duration.unit !== M5TimeUnit.LIMITLESS) {
|
||||
effect.system.equipped = false;
|
||||
}
|
||||
for (const key in effect.system.mods) {
|
||||
if (effect.system.mods[key].operation === M5ModOperation.SUBTRACT) {
|
||||
switch (effect.system.mods[key].id) {
|
||||
case "lp":
|
||||
currentToken["system"].lp.value -= effect.system.mods[key].value;
|
||||
break;
|
||||
case "ap":
|
||||
currentToken["system"].ap.value -= effect.system.mods[key].value;
|
||||
break;
|
||||
}
|
||||
} else if (effect.system.mods[key].operation === M5ModOperation.ADD) {
|
||||
switch (effect.system.mods[key].id) {
|
||||
case "lp":
|
||||
currentToken["system"].lp.value += limitHeal(effect.system.mods[key].value, currentToken["system"].lp.value, currentToken["system"].lp.max);
|
||||
break;
|
||||
case "ap":
|
||||
currentToken["system"].ap.value += limitHeal(effect.system.mods[key].value, currentToken["system"].ap.value, currentToken["system"].ap.max);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
currentToken.render();
|
||||
}
|
||||
});
|
||||
|
||||
function limitHeal(heal: number, current: number, max: number): number {
|
||||
if (current === max) {
|
||||
return 0;
|
||||
} else if (heal + current > max) {
|
||||
return max - current;
|
||||
}
|
||||
return heal;
|
||||
}
|
||||
|
||||
Hooks.on("renderCombatTracker", (combatTracker, html, context) => {
|
||||
if (context.combat === null) {
|
||||
html.find("h3.encounter-title")[0].innerHTML = game["i18n"].localize("midgard5.no-encounter");
|
||||
} else if (Math.ceil(context.round / 2) === 0) {
|
||||
html.find("h3.encounter-title")[0].innerHTML = game["i18n"].localize("midgard5.encounter-not-started");
|
||||
} else {
|
||||
html.find("h3.encounter-title")[0].innerHTML =
|
||||
(context.round % 2 == 1 ? game["i18n"].localize("midgard5.phase-movement") : game["i18n"].localize("midgard5.phase-action")) + " " + Math.ceil(context.round / 2);
|
||||
}
|
||||
});
|
||||
|
||||
Hooks.once("ready", () => {
|
||||
Logger.ok("Template module is now ready.");
|
||||
});
|
||||
|
|
@ -187,9 +250,9 @@ async function applyDamage(roll, direction) {
|
|||
token["system"].ap.value -= Math.max(0, damageValue - token["system"].calc.stats.apProtection.value);
|
||||
break;
|
||||
case -1:
|
||||
token["system"].lp.value += Math.min(damageValue, token["system"].lp.max - damageValue);
|
||||
token["system"].lp.value += limitHeal(damageValue, token["system"].lp.value, token["system"].lp.max);
|
||||
case -2:
|
||||
token["system"].ap.value += Math.min(damageValue, token["system"].ap.max - damageValue);
|
||||
token["system"].ap.value += limitHeal(damageValue, token["system"].ap.value, token["system"].ap.max);
|
||||
}
|
||||
token.render();
|
||||
} else {
|
||||
|
|
@ -200,9 +263,9 @@ async function applyDamage(roll, direction) {
|
|||
actor["system"].ap.value -= Math.max(0, damageValue - actor["system"].calc.stats.apProtection.value);
|
||||
break;
|
||||
case -1:
|
||||
actor["system"].lp.value += Math.min(damageValue, actor["system"].lp.max - damageValue);
|
||||
actor["system"].lp.value += limitHeal(damageValue, token["system"].lp.value, token["system"].lp.max);
|
||||
case -2:
|
||||
actor["system"].ap.value += Math.min(damageValue, actor["system"].ap.max - damageValue);
|
||||
actor["system"].ap.value += limitHeal(damageValue, token["system"].ap.value, token["system"].ap.max);
|
||||
}
|
||||
actor.render();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,6 +102,13 @@ export enum M5ModOperation {
|
|||
DIVISION = "division",
|
||||
}
|
||||
|
||||
export enum M5TimeUnit {
|
||||
ROUND = "round",
|
||||
MINUTE = "minute",
|
||||
HOUR = "hour",
|
||||
LIMITLESS = "limitless",
|
||||
}
|
||||
|
||||
export interface M5ItemMod {
|
||||
type: M5ModType;
|
||||
id: string;
|
||||
|
|
|
|||
|
|
@ -188,7 +188,8 @@ export class M5Character extends Actor {
|
|||
label: label,
|
||||
magic: item.system.magic,
|
||||
calc: item.system.calc,
|
||||
equipped: item.system?.equipped,
|
||||
equipped: item.system?.equipped || false,
|
||||
duration: item.system?.duration || { time: 0, unit: "" },
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -201,6 +201,14 @@
|
|||
"value": 0,
|
||||
"magic": false
|
||||
},
|
||||
"durationSelection": {
|
||||
"durationSelection": {
|
||||
"round": "midgard5.time-round",
|
||||
"minute": "midgard5.time-minute",
|
||||
"hour": "midgard5.time-hour",
|
||||
"limitless": "midgard5.time-limitless"
|
||||
}
|
||||
},
|
||||
"spellSelection": {
|
||||
"spellProcessSelection": {
|
||||
"none": "midgard5.spell-process-none",
|
||||
|
|
@ -295,7 +303,7 @@
|
|||
"calc": {}
|
||||
},
|
||||
"effect": {
|
||||
"templates": ["itemDescription", "equippable", "physical"],
|
||||
"templates": ["itemDescription", "equippable", "physical", "durationSelection"],
|
||||
"rolls": {
|
||||
"formulas": {},
|
||||
"output": ""
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@
|
|||
<span class="edit-item">{{item.label}}</span>
|
||||
{{#if item.equipped}}
|
||||
<span class="spell-process">{{localize "midgard5.active"}}</span>
|
||||
{{#unless (or (eq item.duration.unit "") (eq item.duration.unit "limitless"))}}
|
||||
<span class="spell-process">{{item.duration.time}} {{localize (concat "midgard5.time-" item.duration.unit)}}</span>
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
</td>
|
||||
<td class="fixed-value"><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="title">{{localize "ITEM.TypeDefensiveWeapon"}}</th>
|
||||
<th class="title">{{localize "TYPES.Item.defensiveWeapon"}}</th>
|
||||
<th class="title">{{localize "midgard5.ew"}}</th>
|
||||
<th class="title"></th>
|
||||
<th class="title"></th>
|
||||
|
|
@ -90,7 +90,7 @@
|
|||
<span class="spell-process">{{localize "midgard5.equipped"}}</span>
|
||||
{{/if}}
|
||||
</td>
|
||||
<td class="fixed-value">{{actorItemValue ../actor._id itemId "lpProtection"}}</td>
|
||||
<td class="fixed-value">{{actorItemValue ../actor._id itemId "lpProtection" ../actor.isToken}}</td>
|
||||
<td class="fixed-value">{{actorItemValue ../actor._id itemId "apProtection"}}</td>
|
||||
<td class="fixed-value">{{actorItemValue ../actor._id itemId "stats.attackBonus"}}</td>
|
||||
<td class="fixed-value">{{actorItemValue ../actor._id itemId "stats.defenseBonus"}}</td>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="title">{{localize "ITEM.type.kampfkunst"}}</th>
|
||||
<th class="title">{{localize "TYPES.Item.kampfkunst"}}</th>
|
||||
<th class="title">{{localize "midgard5.ew"}}</th>
|
||||
<th class="title"></th>
|
||||
<th class="title"></th>
|
||||
|
|
|
|||
|
|
@ -22,8 +22,17 @@
|
|||
<tr>
|
||||
<td>
|
||||
<div class="flexrow">
|
||||
<span>{{localize "midgard5.item-value"}}</span>
|
||||
<input name="data.value" type="text" value="{{data.value}}" data-dtype="Number" />
|
||||
<span>{{localize "midgard5.time-duration"}}</span>
|
||||
<input name="data.duration.time" type="text" value="{{data.duration.time}}" data-dtype="Number" />
|
||||
<select class="select-mod-operation" name="data.duration.unit" data-type="String">
|
||||
{{#select data.duration.unit}}
|
||||
<option value=""></option>
|
||||
<option value="round">{{localize "midgard5.time-round"}}</option>
|
||||
<option value="minute">{{localize "midgard5.time-minute"}}</option>
|
||||
<option value="hour">{{localize "midgard5.time-hour"}}</option>
|
||||
<option value="limitless">{{localize "midgard5.time-limitless"}}</option>
|
||||
{{/select}}
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
|||
Loading…
Reference in New Issue