Merge branch 'develop' into lasten
This commit is contained in:
+48
-44
@@ -90,6 +90,16 @@ Hooks.once("init", async () => {
|
||||
return label.toLowerCase().includes(contains.toLowerCase());
|
||||
});
|
||||
|
||||
Handlebars.registerHelper("count", (object: any) => {
|
||||
var length = 0;
|
||||
for (var key in object) {
|
||||
if (object.hasOwnProperty(key)) {
|
||||
++length;
|
||||
}
|
||||
}
|
||||
return length;
|
||||
});
|
||||
|
||||
// Default Sheet für Items definieren und das Standardsheet deaktivieren
|
||||
Items.unregisterSheet("core", ItemSheet);
|
||||
Items.registerSheet("midgard5", M5ItemSheet, { makeDefault: true });
|
||||
@@ -114,12 +124,10 @@ Hooks.on("getChatLogEntryContext", function (html, options) {
|
||||
name: "LP & AP Schaden",
|
||||
icon: '<i class="fas fa-tint"></i>',
|
||||
condition: (li) => {
|
||||
// Only show this context menu if there are re-rollable dice in the message
|
||||
const damageRolls = li.find(".apply-damage").length;
|
||||
const damageRolls = li.find(".damage").length;
|
||||
|
||||
// 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
|
||||
return game["user"].character && damageRolls > 0;
|
||||
return (game["user"].character || game["canvas"].tokens.controlled) && damageRolls > 0;
|
||||
},
|
||||
callback: (li) => applyDamage(li, 2),
|
||||
},
|
||||
@@ -127,12 +135,10 @@ Hooks.on("getChatLogEntryContext", function (html, options) {
|
||||
name: "AP Schaden",
|
||||
icon: '<i class="fas fa-shield-alt"></i>',
|
||||
condition: (li) => {
|
||||
// Only show this context menu if there are re-rollable dice in the message
|
||||
const damageRolls = li.find(".apply-damage").length;
|
||||
const damageRolls = li.find(".damage").length;
|
||||
|
||||
// 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
|
||||
return game["user"].character && damageRolls > 0;
|
||||
return (game["user"].character || game["canvas"].tokens.controlled) && damageRolls > 0;
|
||||
},
|
||||
callback: (li) => applyDamage(li, 1),
|
||||
},
|
||||
@@ -140,12 +146,10 @@ Hooks.on("getChatLogEntryContext", function (html, options) {
|
||||
name: "LP & AP Heilen",
|
||||
icon: '<i class="fas fa-heart"></i>',
|
||||
condition: (li) => {
|
||||
// Only show this context menu if there are re-rollable dice in the message
|
||||
const damageRolls = li.find(".apply-damage").length;
|
||||
const damageRolls = li.find(".heal").length;
|
||||
|
||||
// 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
|
||||
return game["user"].character && damageRolls > 0;
|
||||
return (game["user"].character || game["canvas"].tokens.controlled) && damageRolls > 0;
|
||||
},
|
||||
callback: (li) => applyDamage(li, -1),
|
||||
},
|
||||
@@ -153,12 +157,10 @@ Hooks.on("getChatLogEntryContext", function (html, options) {
|
||||
name: "AP Heilen",
|
||||
icon: '<i class="far fa-heart"></i>',
|
||||
condition: (li) => {
|
||||
// Only show this context menu if there are re-rollable dice in the message
|
||||
const damageRolls = li.find(".apply-damage").length;
|
||||
const damageRolls = li.find(".heal").length;
|
||||
|
||||
// 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
|
||||
return game["user"].character && damageRolls > 0;
|
||||
return (game["user"].character || game["canvas"].tokens.controlled) && damageRolls > 0;
|
||||
},
|
||||
callback: (li) => applyDamage(li, -2),
|
||||
}
|
||||
@@ -209,15 +211,6 @@ Hooks.on("updateCombat", function (combat: Combat, updateData: { round: number;
|
||||
}
|
||||
});
|
||||
|
||||
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");
|
||||
@@ -234,27 +227,29 @@ Hooks.once("ready", () => {
|
||||
});
|
||||
|
||||
async function applyDamage(roll, direction) {
|
||||
const damageValue = Array.from(roll.find(".apply-damage") as HTMLElement[])
|
||||
console.log(roll, direction);
|
||||
const damageValue = Array.from(roll.find(".apply") as HTMLElement[])
|
||||
.map((x) => Math.max(0, Number(x.innerText)))
|
||||
.reduce((prev, curr) => prev + curr, 0);
|
||||
const userId = game["user"].character.id;
|
||||
const viewedSceneId = game["user"].viewedScene;
|
||||
const token = game["actors"].get(userId).getDependentTokens(viewedSceneId)[0]?.delta.syntheticActor;
|
||||
const controlledTokens = game["canvas"].tokens.controlled;
|
||||
const actor = game["user"].character;
|
||||
|
||||
if (token) {
|
||||
switch (direction) {
|
||||
case 2:
|
||||
token["system"].lp.value -= Math.max(0, damageValue - token["system"].calc.stats.lpProtection.value);
|
||||
case 1:
|
||||
token["system"].ap.value -= Math.max(0, damageValue - token["system"].calc.stats.apProtection.value);
|
||||
break;
|
||||
case -1:
|
||||
token["system"].lp.value += limitHeal(damageValue, token["system"].lp.value, token["system"].lp.max);
|
||||
case -2:
|
||||
token["system"].ap.value += limitHeal(damageValue, token["system"].ap.value, token["system"].ap.max);
|
||||
}
|
||||
token.render();
|
||||
if (controlledTokens) {
|
||||
controlledTokens.forEach((controlledToken) => {
|
||||
let token = controlledToken.document.delta.syntheticActor;
|
||||
switch (direction) {
|
||||
case 2:
|
||||
token["system"].lp.value -= Math.max(0, damageValue - token["system"].calc.stats.lpProtection.value);
|
||||
case 1:
|
||||
token["system"].ap.value -= Math.max(0, damageValue - token["system"].calc.stats.apProtection.value);
|
||||
break;
|
||||
case -1:
|
||||
token["system"].lp.value += limitHeal(damageValue, token["system"].lp.value, token["system"].lp.max);
|
||||
case -2:
|
||||
token["system"].ap.value += limitHeal(damageValue, token["system"].ap.value, token["system"].ap.max);
|
||||
}
|
||||
token.render();
|
||||
});
|
||||
} else {
|
||||
switch (direction) {
|
||||
case 2:
|
||||
@@ -263,10 +258,19 @@ 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 += limitHeal(damageValue, token["system"].lp.value, token["system"].lp.max);
|
||||
actor["system"].lp.value += limitHeal(damageValue, actor["system"].lp.value, actor["system"].lp.max);
|
||||
case -2:
|
||||
actor["system"].ap.value += limitHeal(damageValue, token["system"].ap.value, token["system"].ap.max);
|
||||
actor["system"].ap.value += limitHeal(damageValue, actor["system"].ap.value, actor["system"].ap.max);
|
||||
}
|
||||
actor.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;
|
||||
}
|
||||
|
||||
@@ -61,6 +61,13 @@ export enum M5ItemType {
|
||||
EFFECT = "effect",
|
||||
}
|
||||
|
||||
export enum M5SkillType {
|
||||
INNATE = "innate",
|
||||
GENERAL = "general",
|
||||
LANGUAGE = "language",
|
||||
COMBAT = "combat",
|
||||
}
|
||||
|
||||
export enum M5EwResult {
|
||||
TBD = "",
|
||||
FUMBLE = "roll-ew-result-fumble",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { M5Item } from "../items/M5Item";
|
||||
import { M5Attribute, M5CharacterCalculatedData, M5ItemMod, M5ItemType, M5ModOperation, M5ModResult, M5ModType, M5RollData, M5Skill, M5SkillCalculated } from "../M5Base";
|
||||
import { M5Attribute, M5CharacterCalculatedData, M5ItemMod, M5ItemType, M5ModOperation, M5ModResult, M5ModType, M5RollData, M5Skill, M5SkillCalculated, M5SkillLearned, M5SkillType } from "../M5Base";
|
||||
import M5ModAggregate from "./M5ModAggregate";
|
||||
export class M5Character extends Actor {
|
||||
// constructor(
|
||||
@@ -666,10 +666,11 @@ export class M5Character extends Actor {
|
||||
});
|
||||
}
|
||||
|
||||
async createItem(itemName: string, itemType: M5ItemType): Promise<M5Item> {
|
||||
createItem(itemName: string, itemType: M5ItemType, options?: any): Promise<M5Item> {
|
||||
const itemData = {
|
||||
name: itemName,
|
||||
type: itemType,
|
||||
data: options,
|
||||
};
|
||||
|
||||
return (this as any).createEmbeddedDocuments("Item", [itemData]).then((docs) => {
|
||||
|
||||
@@ -269,27 +269,6 @@ export class M5Roll {
|
||||
return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.resistanceMind"));
|
||||
}
|
||||
|
||||
static async initativeRoll(actor: any) {
|
||||
let newInitiative; // the initiative value for the combatant
|
||||
|
||||
// ...
|
||||
// The intnitiative value is calculated here
|
||||
// ...
|
||||
|
||||
let combatant = game["combat"].getCombatantByActor(actor._id);
|
||||
if (!combatant) {
|
||||
await game["combat"].createEmbeddedDocuments("Combatant", [{ actorId: actor._id }]);
|
||||
combatant = game["combat"].getCombatantByActor(actor._id);
|
||||
}
|
||||
|
||||
const initiatives = {
|
||||
_id: combatant._id,
|
||||
initiative: actor.system.calc.attributes.gw.value,
|
||||
};
|
||||
|
||||
await game["combat"].updateEmbeddedDocuments("Combatant", [initiatives]);
|
||||
}
|
||||
|
||||
static resistanceBody(actor: any) {
|
||||
const rollData = actor.getRollData() as M5RollData;
|
||||
rollData.i = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Logger from "../../utils/Logger";
|
||||
import { M5Character } from "../actors/M5Character";
|
||||
import { M5Item } from "../items/M5Item";
|
||||
import { M5ItemType, M5SkillLearned, M5SkillUnlearned } from "../M5Base";
|
||||
import { M5ItemType, M5SkillLearned, M5SkillType, M5SkillUnlearned } from "../M5Base";
|
||||
import { M5Roll } from "../rolls/M5Roll";
|
||||
|
||||
export default class M5CharacterSheet extends ActorSheet {
|
||||
@@ -282,14 +282,7 @@ export default class M5CharacterSheet extends ActorSheet {
|
||||
const data = this.actor.system;
|
||||
|
||||
const character = this.actor as M5Character;
|
||||
character.createItem((game as Game).i18n.localize("TYPES.Item.item"), M5ItemType.ITEM).then((i) => {
|
||||
const item = i as any;
|
||||
item.update({
|
||||
data: {
|
||||
quantity: 1,
|
||||
},
|
||||
});
|
||||
});
|
||||
character.createItem((game as Game).i18n.localize("TYPES.Item.item"), M5ItemType.ITEM, { quantity: 1 });
|
||||
});
|
||||
|
||||
html.find(".add-weapon").on("click", async (event) => {
|
||||
@@ -317,42 +310,51 @@ export default class M5CharacterSheet extends ActorSheet {
|
||||
const data = this.actor.system;
|
||||
|
||||
const character = this.actor as M5Character;
|
||||
character.createItem((game as Game).i18n.localize("TYPES.Item.container"), M5ItemType.CONTAINER).then((i) => {
|
||||
const item = i as any;
|
||||
item.update({
|
||||
data: {
|
||||
quantity: 1,
|
||||
},
|
||||
});
|
||||
});
|
||||
character.createItem((game as Game).i18n.localize("TYPES.Item.container"), M5ItemType.CONTAINER, { quantity: 1 });
|
||||
});
|
||||
|
||||
html.find(".add-innate-skill").on("click", async (event) => {
|
||||
const data = this.actor.system;
|
||||
|
||||
const character = this.actor as M5Character;
|
||||
character.createItem((game as Game).i18n.localize("TYPES.Item.innate-ability"), M5ItemType.SKILL, { type: M5SkillType.INNATE });
|
||||
});
|
||||
|
||||
html.find(".add-general-skill").on("click", async (event) => {
|
||||
const data = this.actor.system;
|
||||
|
||||
const character = this.actor as M5Character;
|
||||
character.createItem((game as Game).i18n.localize("TYPES.Item.skill"), M5ItemType.SKILL, { type: M5SkillType.GENERAL });
|
||||
});
|
||||
|
||||
html.find(".add-combat-skill").on("click", async (event) => {
|
||||
const data = this.actor.system;
|
||||
|
||||
const character = this.actor as M5Character;
|
||||
character.createItem((game as Game).i18n.localize("TYPES.Item.weapon-skill"), M5ItemType.SKILL, { type: M5SkillType.COMBAT });
|
||||
});
|
||||
|
||||
html.find(".add-language-skill").on("click", async (event) => {
|
||||
const data = this.actor.system;
|
||||
|
||||
const character = this.actor as M5Character;
|
||||
character.createItem((game as Game).i18n.localize("TYPES.Item.language"), M5ItemType.SKILL, { type: M5SkillType.LANGUAGE });
|
||||
});
|
||||
|
||||
html.find(".add-spell").on("click", async (event) => {
|
||||
const data = this.actor.system;
|
||||
|
||||
const character = this.actor as M5Character;
|
||||
character.createItem((game as Game).i18n.localize("TYPES.Item.spell"), M5ItemType.SPELL).then((i) => {
|
||||
const item = i as any;
|
||||
item.update({
|
||||
data: {
|
||||
process: "none",
|
||||
},
|
||||
});
|
||||
});
|
||||
character.createItem((game as Game).i18n.localize("TYPES.Item.spell"), M5ItemType.SPELL, { process: "none" });
|
||||
});
|
||||
|
||||
html.find(".add-kampfkunst").on("click", async (event) => {
|
||||
const data = this.actor.system;
|
||||
|
||||
const character = this.actor as M5Character;
|
||||
character.createItem((game as Game).i18n.localize("TYPES.Item.kampfkunst"), M5ItemType.KAMPFKUNST).then((i) => {
|
||||
const item = i as any;
|
||||
item.update({
|
||||
data: {
|
||||
type: "angriff",
|
||||
variante: "anstuermen",
|
||||
},
|
||||
});
|
||||
character.createItem((game as Game).i18n.localize("TYPES.Item.kampfkunst"), M5ItemType.KAMPFKUNST, {
|
||||
type: "angriff",
|
||||
variante: "anstuermen",
|
||||
});
|
||||
});
|
||||
|
||||
@@ -363,6 +365,57 @@ export default class M5CharacterSheet extends ActorSheet {
|
||||
character.createItem((game as Game).i18n.localize("TYPES.Item.effect"), M5ItemType.EFFECT);
|
||||
});
|
||||
|
||||
html.find(".join-combat").on("click", async (event) => {
|
||||
if (!!game["combat"]) {
|
||||
let combatant = game["combat"].getCombatantByActor(this.actor._id);
|
||||
if (!combatant) {
|
||||
await game["combat"].createEmbeddedDocuments("Combatant", [{ actorId: this.actor._id }]);
|
||||
combatant = game["combat"].getCombatantByActor(this.actor._id);
|
||||
}
|
||||
|
||||
const initiatives = {
|
||||
_id: combatant._id,
|
||||
initiative: this.actor.system.calc.attributes.gw.value,
|
||||
};
|
||||
|
||||
await game["combat"].updateEmbeddedDocuments("Combatant", [initiatives]);
|
||||
}
|
||||
});
|
||||
|
||||
html.find(".ranged-combat").on("click", async (event) => {
|
||||
if (!!game["combat"]) {
|
||||
let combatant = game["combat"].getCombatantByActor(this.actor._id);
|
||||
if (!combatant) {
|
||||
await game["combat"].createEmbeddedDocuments("Combatant", [{ actorId: this.actor._id }]);
|
||||
combatant = game["combat"].getCombatantByActor(this.actor._id);
|
||||
}
|
||||
|
||||
const initiatives = {
|
||||
_id: combatant._id,
|
||||
initiative: 0.01 * this.actor.system.calc.attributes.gw.value,
|
||||
};
|
||||
|
||||
await game["combat"].updateEmbeddedDocuments("Combatant", [initiatives]);
|
||||
}
|
||||
});
|
||||
|
||||
html.find(".spell-combat").on("click", async (event) => {
|
||||
if (!!game["combat"]) {
|
||||
let combatant = game["combat"].getCombatantByActor(this.actor._id);
|
||||
if (!combatant) {
|
||||
await game["combat"].createEmbeddedDocuments("Combatant", [{ actorId: this.actor._id }]);
|
||||
combatant = game["combat"].getCombatantByActor(this.actor._id);
|
||||
}
|
||||
|
||||
const initiatives = {
|
||||
_id: combatant._id,
|
||||
initiative: 0.001 * this.actor.system.calc.attributes.gw.value,
|
||||
};
|
||||
|
||||
await game["combat"].updateEmbeddedDocuments("Combatant", [initiatives]);
|
||||
}
|
||||
});
|
||||
|
||||
// Drag & Drop
|
||||
const dragDrop = new DragDrop({
|
||||
dragSelector: ".items-list .item",
|
||||
|
||||
@@ -217,6 +217,10 @@
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.wide-button {
|
||||
margin: 0.25rem 0;
|
||||
}
|
||||
|
||||
.learn-button {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
Reference in New Issue
Block a user