Compare commits

...
7 Commits
Author SHA1 Message Date
Byroks e85fd1c41f fix Zaubern EW display in spell
Changes:
 + fix Zaubern EW display in spell list
2023-11-19 21:13:29 +01:00
Byroks d9e7152b4d verson change v1.2.2 2023-11-19 20:58:03 +01:00
Byroks 9e7d81f413 version change to v1.2.2 2023-11-19 20:57:16 +01:00
Byroks 8dd29e8da5 hide skill when learned
Changes:
 + Hide learned skills from unlearned skill list
2023-11-19 20:52:29 +01:00
Byroks 0d259f40a7 adjust version to 1.2.1 2023-11-17 16:10:31 +01:00
Byroks 4ec3cc9570 add race boni and default resistance rolls
Changes:
 + add Race Selection Dropdown
 + change resistance/defense value calculation, based on race, stats and class
 + add default rolls for defense and resistances
2023-11-17 16:09:24 +01:00
Byroks 2b02f787f2 fix spelling mistake in macros 2023-11-17 09:27:33 +01:00
14 changed files with 314 additions and 186 deletions
+5 -2
View File
@@ -1,6 +1,6 @@
{
"name": "foundry-system-midgard5",
"version": "1.2.0",
"version": "1.2.2",
"description": "",
"main": "index.js",
"scripts": {
@@ -13,7 +13,7 @@
"build:watch:target": "gulp watchTarget",
"clean": "gulp clean && gulp link --clean"
},
"author": "Simon Gustavs",
"author": "Byroks",
"license": "MIT",
"devDependencies": {
"@babel/core": "^7.15.0",
@@ -54,5 +54,8 @@
"vinyl-buffer": "^1.0.1",
"vinyl-source-stream": "^2.0.0",
"yargs": "^17.1.1"
},
"dependencies": {
"handlebars-helpers": "^0.10.0"
}
}
@@ -11,7 +11,7 @@
}
},
"scope": "global",
"command": "await game.tables.getName(\"Kritische Fehler beim Zaubern\").draw()",
"command": "await game.tables.getName(\"Kritischer Fehler beim Zaubern\").draw()",
"author": "CBq5YXAqbO7HoJ03",
"img": "systems/midgard5/assets/icons/macro/kritfehlerzauber.svg",
"actorIds": [],
@@ -11,7 +11,7 @@
}
},
"scope": "global",
"command": "await game.tables.getName(\"Kritische Erfolg bei der Abwehr\").draw()",
"command": "await game.tables.getName(\"Kritischer Erfolg bei der Abwehr\").draw()",
"author": "CBq5YXAqbO7HoJ03",
"img": "systems/midgard5/assets/icons/macro/kriterfolgabwehr.svg",
"actorIds": [],
@@ -11,7 +11,7 @@
}
},
"scope": "global",
"command": "await game.tables.getName(\"Kritische Fehler bei Angriffen\").draw()",
"command": "await game.tables.getName(\"Kritischer Fehler bei Angriffen\").draw()",
"author": "CBq5YXAqbO7HoJ03",
"img": "systems/midgard5/assets/icons/macro/kritfehlerangriff.svg",
"actorIds": [],
@@ -11,7 +11,7 @@
}
},
"scope": "global",
"command": "await game.tables.getName(\"Kritische Fehler bei der Abwehr\").draw()",
"command": "await game.tables.getName(\"Kritischer Fehler bei der Abwehr\").draw()",
"author": "CBq5YXAqbO7HoJ03",
"img": "systems/midgard5/assets/icons/macro/kritfehlerabwehr.svg",
"actorIds": [],
+64 -57
View File
@@ -1,98 +1,105 @@
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 { M5ItemSheet } from "./module/sheets/M5ItemSheet"
import { M5Item } from "./module/items/M5Item"
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 { M5ItemSheet } from "./module/sheets/M5ItemSheet";
import { M5Item } from "./module/items/M5Item";
Hooks.once("init", async () => {
Logger.log("M5 | Initialisierung Midgard 5")
Logger.log("M5 | Initialisierung Midgard 5");
Handlebars.registerHelper("times", (n: number, block) => {
var accum = ""
for(let i = 0; i < n; ++i)
accum += block.fn(i)
return accum
})
var accum = "";
for (let i = 0; i < n; ++i) accum += block.fn(i);
return accum;
});
Handlebars.registerHelper("array", (arr: any[], index: number) => {
return arr[index]
})
return arr[index];
});
Handlebars.registerHelper("m5concat", (...values) => {
const options = values.pop();
const join = options.hash?.join || "";
//return new Handlebars.SafeString(values.join(join));
return values.map(val => val.toString()).join(join)
})
return values.map((val) => val.toString()).join(join);
});
Handlebars.registerHelper("add", (...values) => {
const options = values.pop();
return values.reduce((prev, cur) => prev + cur)
})
return values.reduce((prev, cur) => prev + cur);
});
Handlebars.registerHelper("localizeMidgard", (str: string) => {
const template = Handlebars.compile("{{localize value}}")
const template = Handlebars.compile("{{localize value}}");
return template({
value: "midgard5." + str
})
})
value: "midgard5." + str,
});
});
Handlebars.registerHelper("skillBonus", (actorId: string, skill: M5Skill) => {
const actor = (game as Game).actors.get(actorId) as M5Character
return actor.skillBonus(skill).toString()
})
const actor = (game as Game).actors.get(actorId) as M5Character;
return actor.skillBonus(skill).toString();
});
Handlebars.registerHelper("skillEw", (actorId: string, skill: M5Skill) => {
const actor = (game as Game).actors.get(actorId) as M5Character
return actor.skillEw(skill).toString()
})
const actor = (game as Game).actors.get(actorId) as M5Character;
return actor.skillEw(skill).toString();
});
Handlebars.registerHelper("skill", (skillId: string) => {
return (game as Game).items.get(skillId)
})
return (game as Game).items.get(skillId);
});
Handlebars.registerHelper("itemValue", (id: string, path: string) => {
let obj = (game as Game).items.get(id)
path.split(".").forEach(p => obj = obj[p])
return `${obj}`
})
let obj = (game as Game).items.get(id);
path.split(".").forEach((p) => (obj = obj[p]));
return `${obj}`;
});
Handlebars.registerHelper("actorItemValue", (actorId: any, itemId: string, path: string) => {
//console.log("actorItemValue", actorId, itemId, path)
const actor = (game as Game).actors.get(actorId)
let obj = actor.items.get(itemId).system
path.split(".").forEach(p => {
if (obj)
obj = obj[p]
})
return `${obj}`
})
const actor = (game as Game).actors.get(actorId);
let obj = actor.items.get(itemId).system;
path.split(".").forEach((p) => {
if (obj) obj = obj[p];
});
return `${obj}`;
});
Handlebars.registerHelper("icon", (relpath: string) => {
return `systems/midgard5/assets/icons/${relpath}`
})
return `systems/midgard5/assets/icons/${relpath}`;
});
Handlebars.registerHelper("isSkillInList", (skillName: string, list: any) => {
for (let key in list) {
if (list[key]?.label?.toLowerCase() === skillName?.toLowerCase()) {
return true;
}
}
return false;
});
// Default Sheet für Items definieren und das Standardsheet deaktivieren
Items.unregisterSheet("core", ItemSheet)
Items.registerSheet("midgard5", M5ItemSheet, { makeDefault: true })
Items.unregisterSheet("core", ItemSheet);
Items.registerSheet("midgard5", M5ItemSheet, { makeDefault: true });
// Default Sheet für Actors definieren und das Standardsheet deaktivieren
Actors.unregisterSheet("core", ActorSheet)
Actors.registerSheet("midgard5", M5CharacterSheet, { makeDefault: true })
Actors.unregisterSheet("core", ActorSheet);
Actors.registerSheet("midgard5", M5CharacterSheet, { makeDefault: true });
CONFIG.Actor.documentClass = M5Character
CONFIG.Item.documentClass = M5Item
CONFIG.Actor.documentClass = M5Character;
CONFIG.Item.documentClass = M5Item;
//RegisterSettings();
await preloadTemplates()
})
await preloadTemplates();
});
Hooks.once("setup", () => {
Logger.log("Template module is being setup.")
})
Logger.log("Template module is being setup.");
});
Hooks.once("ready", () => {
Logger.ok("Template module is now ready.")
})
Logger.ok("Template module is now ready.");
});
+21 -2
View File
@@ -108,8 +108,12 @@ export class M5Character extends Actor {
ret.stats.attackBonus = this.modResult(ret.attributes.gs.bonus);
ret.stats.defenseBonus = this.modResult(ret.attributes.gw.bonus);
ret.stats.movementBonus = this.modResult(0);
ret.stats.resistanceMind = this.modResult(ret.stats.defense.value);
ret.stats.resistanceBody = this.modResult(ret.stats.defense.value + 1);
ret.stats.resistanceMind = this.modResult(
(data.info.magicUsing ? 2 : 0) + ret.stats.defense.value + (data.info.race === "Mensch" ? ret.attributes.in.bonus : this.raceBonus(data.info.race))
);
ret.stats.resistanceBody = this.modResult(
(data.info.magicUsing ? 2 : 1) + ret.stats.defense.value + (data.info.race === "Mensch" ? ret.attributes.ko.bonus : this.raceBonus(data.info.race))
);
ret.stats.spellCasting = this.modResult((data.info.magicUsing ? M5Character.spellCastingFromLevel(ret.level) : 3) + ret.attributes.zt.bonus);
ret.stats.brawl = this.modResult(Math.floor((ret.attributes.st.value + ret.attributes.gw.value) / 20));
ret.stats.brawlEw = ret.stats.brawl.value + ret.stats.attackBonus.value;
@@ -251,6 +255,21 @@ export class M5Character extends Actor {
return ret;
}
raceBonus(race: string) {
switch (race) {
case "Elf":
return 2;
case "Gnom":
return 4;
case "Halbling":
return 4;
case "Zwerg":
return 3;
default:
return 0;
}
}
prepareDerivedData() {
console.log("M5Character", "prepareDerivedData");
const data = (this as any).system;
+1 -1
View File
@@ -110,7 +110,7 @@ export class M5Item extends Item {
if (actor) {
const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true });
if (actorCalc) {
calc.ew += actorCalc.stats.spellCasting.value;
calc.ew = actorCalc.stats.spellCasting.value;
}
}
} else if (itemType === "item") {
+156 -103
View File
@@ -2,12 +2,13 @@ import { Evaluated } from "@league-of-foundry-developers/foundry-vtt-types/src/f
import { M5Character } from "../actors/M5Character";
import { M5EwResult, M5RollData, M5RollResult, M5SkillUnlearned } from "../M5Base";
export class M5Roll { // extends Roll<M5RollData>
static readonly TEMPLATE_PATH = "systems/midgard5/templates/chat/roll-m5.hbs"
export class M5Roll {
// extends Roll<M5RollData>
static readonly TEMPLATE_PATH = "systems/midgard5/templates/chat/roll-m5.hbs";
public _evaluated: boolean = false
public _total: number = 0
public pool: PoolTerm = null
public _evaluated: boolean = false;
public _total: number = 0;
public pool: PoolTerm = null;
constructor(public data: M5RollData, public actor: any, public label: string) {
//super(null)
@@ -17,116 +18,108 @@ export class M5Roll { // extends Roll<M5RollData>
// @ts-ignore
//override evaluate(options?: InexactPartial<RollTerm.EvaluationOptions>): Evaluated<Roll<M5RollData>> | Promise<Evaluated<Roll<M5RollData>>> {
evaluate() {
const indexMap = new Map<number, string>()
const rollNames = Object.keys(this.data.rolls)
const rolls = rollNames.filter(rollName => this.data.rolls[rollName].enabled).map((rollName, index) => {
indexMap.set(index, rollName)
const formula = this.data.rolls[rollName]
const roll = new Roll(formula.formula, this.data)
return roll
})
const indexMap = new Map<number, string>();
const rollNames = Object.keys(this.data.rolls);
const rolls = rollNames
.filter((rollName) => this.data.rolls[rollName].enabled)
.map((rollName, index) => {
indexMap.set(index, rollName);
const formula = this.data.rolls[rollName];
const roll = new Roll(formula.formula, this.data);
return roll;
});
this.pool = PoolTerm.fromRolls(rolls)
console.log("evaluate", this._evaluated, this.pool)
return this.pool.evaluate({ async: true }).then(results => {
this._total = 0
this.pool = PoolTerm.fromRolls(rolls);
console.log("evaluate", this._evaluated, this.pool);
return this.pool.evaluate({ async: true }).then((results) => {
this._total = 0;
results.rolls.forEach((roll, index) => {
const rollIndex = indexMap.get(index)
const rollResult = this.data.rolls[rollIndex] as M5RollResult
const rollIndex = indexMap.get(index);
const rollResult = this.data.rolls[rollIndex] as M5RollResult;
rollResult.result = roll.result
rollResult.total = roll.total
rollResult.totalStr = roll.total.toString()
rollResult.result = roll.result;
rollResult.total = roll.total;
rollResult.totalStr = roll.total.toString();
this._total += roll.total
this._total += roll.total;
let rowRes = M5EwResult.TBD
let face100 = -1
let rowRes = M5EwResult.TBD;
let face100 = -1;
roll.dice.forEach((d, dIndex) => {
rollResult.dice[dIndex.toString()] = d.total
rollResult.dice[dIndex.toString()] = d.total;
if (rowRes === M5EwResult.TBD && dIndex === 0) {
if (d.faces === 20) {
//if (rollResult.type === "ew") {
if (d.total === 1)
rowRes = M5EwResult.FUMBLE
else if (d.total === 20)
rowRes = M5EwResult.CRITICAL
else if (d.total >= 16)
rowRes = M5EwResult.HIGH
if (d.total === 1) rowRes = M5EwResult.FUMBLE;
else if (d.total === 20) rowRes = M5EwResult.CRITICAL;
else if (d.total >= 16) rowRes = M5EwResult.HIGH;
} else if (d.faces === 100) {
face100 = d.total as number
face100 = d.total as number;
}
}
})
});
const parseResult = M5Roll.parseDiceSides(rollResult.formula)
const parseResult = M5Roll.parseDiceSides(rollResult.formula);
//console.log("evaluate roll", parseResult)
if (parseResult?.sides === 20) {
if (roll.total < 20) {
if (rowRes === M5EwResult.TBD || rowRes === M5EwResult.HIGH)
rowRes = M5EwResult.FAIL
if (rowRes === M5EwResult.TBD || rowRes === M5EwResult.HIGH) rowRes = M5EwResult.FAIL;
} else {
if (rowRes === M5EwResult.TBD)
rowRes = M5EwResult.PASS
if (rowRes === M5EwResult.TBD) rowRes = M5EwResult.PASS;
}
} else if (face100 >= 0) {
const threshold100 = roll.total + face100
const threshold = Math.floor(threshold100 / 10)
const threshold100 = roll.total + face100;
const threshold = Math.floor(threshold100 / 10);
if (face100 === 100) {
if (rowRes === M5EwResult.TBD)
rowRes = M5EwResult.FUMBLE
if (rowRes === M5EwResult.TBD) rowRes = M5EwResult.FUMBLE;
} else if (roll.total < 0) {
if (rowRes === M5EwResult.TBD)
rowRes = M5EwResult.FAIL
if (rowRes === M5EwResult.TBD) rowRes = M5EwResult.FAIL;
} else if (face100 <= threshold) {
if (rowRes === M5EwResult.TBD)
rowRes = M5EwResult.CRITICAL
if (rowRes === M5EwResult.TBD) rowRes = M5EwResult.CRITICAL;
} else {
if (rowRes === M5EwResult.TBD)
rowRes = M5EwResult.PASS
if (rowRes === M5EwResult.TBD) rowRes = M5EwResult.PASS;
}
}
rollResult.css = rowRes
})
rollResult.css = rowRes;
});
this.data.res.label = this.label
this.data.res.label = this.label;
this._evaluated = true
return this
})
this._evaluated = true;
return this;
});
}
async render(): Promise<string> {
return renderTemplate(M5Roll.TEMPLATE_PATH, this.data)
return renderTemplate(M5Roll.TEMPLATE_PATH, this.data);
}
async toMessage() {
if (!this._evaluated)
await this.evaluate()
if (!this._evaluated) await this.evaluate();
const rMode = (game as Game).settings.get("core", "rollMode")
const rMode = (game as Game).settings.get("core", "rollMode");
const chatData = {
type: CONST.CHAT_MESSAGE_TYPES.ROLL,
content: await this.render(),
speaker: ChatMessage.getSpeaker({actor: this.actor}),
speaker: ChatMessage.getSpeaker({ actor: this.actor }),
sound: CONFIG.sounds.dice,
roll: Roll.fromTerms([this.pool])
}
roll: Roll.fromTerms([this.pool]),
};
ChatMessage.applyRollMode(chatData, rMode)
return ChatMessage.create(chatData)
ChatMessage.applyRollMode(chatData, rMode);
return ChatMessage.create(chatData);
}
static fromAttribute(actor: any, attributeKey: string) {
const character = actor as M5Character
const attribute = character.attribute(attributeKey)
const character = actor as M5Character;
const attribute = character.attribute(attributeKey);
const rollData = actor.getRollData() as M5RollData
rollData.i = attribute.value + attribute.bonus
const rollData = actor.getRollData() as M5RollData;
rollData.i = attribute.value + attribute.bonus;
rollData.rolls["0"] = {
formula: "@i - 1d100",
enabled: true,
@@ -135,15 +128,15 @@ export class M5Roll { // extends Roll<M5RollData>
total: 0,
totalStr: "",
dice: {},
css: ""
} as M5RollResult
css: "",
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize(`midgard5.actor-${attributeKey}-long`))
return new M5Roll(rollData, actor, (game as Game).i18n.localize(`midgard5.actor-${attributeKey}-long`));
}
static fromAttributeValue(actor: any, attributeKey: string, attributeValue: number) {
const rollData = actor.getRollData() as M5RollData
rollData.i = attributeValue
const rollData = actor.getRollData() as M5RollData;
rollData.i = attributeValue;
rollData.rolls["0"] = {
formula: "@i - 1d100",
enabled: true,
@@ -152,19 +145,19 @@ export class M5Roll { // extends Roll<M5RollData>
total: 0,
totalStr: "",
dice: {},
css: ""
} as M5RollResult
css: "",
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize(`midgard5.actor-${attributeKey}-long`))
return new M5Roll(rollData, actor, (game as Game).i18n.localize(`midgard5.actor-${attributeKey}-long`));
}
static fromUnlearnedSkill(actor: any, skill: M5SkillUnlearned, skillName: string) {
const rollData = actor.getRollData() as M5RollData
const rollData = actor.getRollData() as M5RollData;
rollData.i = {
fw: skill.fw,
bonus: actor.system.calc?.attributes[skill.attribute]?.bonus ?? 0
}
rollData.iType = "skill"
bonus: actor.system.calc?.attributes[skill.attribute]?.bonus ?? 0,
};
rollData.iType = "skill";
rollData.rolls["0"] = {
formula: "1d20 + @i.fw + @i.bonus",
@@ -174,18 +167,18 @@ export class M5Roll { // extends Roll<M5RollData>
total: 0,
totalStr: "",
dice: {},
css: ""
} as M5RollResult
css: "",
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize(`midgard5.${skillName}`))
return new M5Roll(rollData, actor, (game as Game).i18n.localize(`midgard5.${skillName}`));
}
static brawl(actor: any) {
const rollData = actor.getRollData() as M5RollData
const rollData = actor.getRollData() as M5RollData;
rollData.i = {
attackBonus: 0,
damageBonus: 0
}
damageBonus: 0,
};
rollData.rolls["0"] = {
formula: "1d20 + @c.calc.stats.brawl + @c.calc.stats.attackBonus + @i.attackBonus",
@@ -195,8 +188,8 @@ export class M5Roll { // extends Roll<M5RollData>
total: 0,
totalStr: "",
dice: {},
css: ""
} as M5RollResult
css: "",
} as M5RollResult;
rollData.rolls["1"] = {
formula: "1d6 - 4 + @c.calc.stats.damageBonus + @i.damageBonus",
@@ -206,40 +199,100 @@ export class M5Roll { // extends Roll<M5RollData>
total: 0,
totalStr: "",
dice: {},
css: ""
} as M5RollResult
css: "",
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.brawl"))
return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.brawl"));
}
static defense(actor: any) {
const rollData = actor.getRollData() as M5RollData;
rollData.i = {
defenseBonus: 0,
};
rollData.rolls["0"] = {
formula: "1d20 + @c.calc.stats.defense.value + @c.calc.stats.defenseBonus.value",
enabled: true,
label: (game as Game).i18n.localize("midgard5.defense"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: "",
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.defense"));
}
static resistanceMind(actor: any) {
const rollData = actor.getRollData() as M5RollData;
rollData.i = {
defenseBonus: 0,
};
rollData.rolls["0"] = {
formula: "1d20 + @c.calc.stats.resistanceMind.value",
enabled: true,
label: (game as Game).i18n.localize("midgard5.resistanceMind"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: "",
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.resistanceMind"));
}
static resistanceBody(actor: any) {
const rollData = actor.getRollData() as M5RollData;
rollData.i = {
defenseBonus: 0,
};
rollData.rolls["0"] = {
formula: "1d20 + @c.calc.stats.resistanceBody.value",
enabled: true,
label: (game as Game).i18n.localize("midgard5.resistanceBody"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: "",
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.resistanceBody"));
}
static parseDiceSides(formula: string): FormulaParseResult {
const ewMatcher: RegExp = /\d*[dD]20/g
const pwMatcher: RegExp = /(\d+)\s*\-\s*\d*[dD]100/g
const ewMatcher: RegExp = /\d*[dD]20/g;
const pwMatcher: RegExp = /(\d+)\s*\-\s*\d*[dD]100/g;
let res = formula.match(ewMatcher)
let res = formula.match(ewMatcher);
if (res && !!res[0]) {
return {
sides: 20,
type: "ew",
threshold: null
}
threshold: null,
};
}
res = formula.match(pwMatcher)
res = formula.match(pwMatcher);
if (res && !!res[1]) {
return {
sides: 100,
type: "pw",
threshold: parseInt(res[1])
}
threshold: parseInt(res[1]),
};
}
return null
return null;
}
}
interface FormulaParseResult {
sides: number,
type: string,
threshold: number
sides: number;
type: string;
threshold: number;
}
+14
View File
@@ -167,6 +167,20 @@ export default class M5CharacterSheet extends ActorSheet {
await roll.toMessage();
});
html.find(".roll-defense-button").on("click", async (event) => {
const roll = M5Roll.defense(this.actor);
await roll.toMessage();
});
html.find(".roll-resistanceMind-button").on("click", async (event) => {
const roll = M5Roll.resistanceMind(this.actor);
await roll.toMessage();
});
html.find(".roll-resistanceBody-button").on("click", async (event) => {
const roll = M5Roll.resistanceBody(this.actor);
await roll.toMessage();
});
// Drag & Drop
const dragDrop = new DragDrop({
dragSelector: ".items-list .item",
+3 -3
View File
@@ -2,7 +2,7 @@
"id": "midgard5",
"title": "Midgard 5. Edition",
"description": "The German RPG Midgard 5. Edition",
"version": "1.2.0",
"version": "1.2.2",
"compatibility": {
"minimum": "10",
"verified": "10"
@@ -66,8 +66,8 @@
"primaryTokenAttribute": "lp",
"secondaryTokenAttribute": "ap",
"url": "https://github.com/Byroks/foundry-vtt-system-midgard5",
"manifest": "https://github.com/Byroks/foundry-vtt-system-midgard5/releases/download/v1.2.0/system.json",
"download": "https://github.com/Byroks/foundry-vtt-system-midgard5/releases/download/v1.2.0/midgard5-v1.2.0.zip",
"manifest": "https://github.com/Byroks/foundry-vtt-system-midgard5/releases/download/v1.2.2/system.json",
"download": "https://github.com/Byroks/foundry-vtt-system-midgard5/releases/download/v1.2.2/midgard5-v1.2.2.zip",
"initiative": "@calc.attributes.gw.value",
"license": "LICENSE.txt"
}
+10 -1
View File
@@ -126,7 +126,16 @@
<tbody>
<tr>
<td>{{localize "midgard5.race"}}</td>
<td><input name="data.info.race" type="text" value="{{data.info.race}}" data-dtype="String" /></td>
<td>
<input list="races" type="search" name="data.info.race" value="{{data.info.race}}" />
<datalist id="races">
<option value="Mensch">
<option value="Elf">
<option value="Gnom">
<option value="Halbling">
<option value="Zwerg">
</datalist>
</td>
<td>{{localize "midgard5.gender"}}</td>
<td><input name="data.info.gender" type="text" value="{{data.info.gender}}" data-dtype="String" /></td>
</tr>
+21
View File
@@ -44,6 +44,27 @@
<td class="fixed-value"><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/each}}
<tr data-item="{{itemId}}">
<td class="padding edit-item">{{localize "midgard5.defense"}}</td>
<td class="center">{{add data.calc.stats.defense.value data.calc.stats.defenseBonus.value}}</td>
<td class="fixed-value"><button class="roll-button roll-defense-button"></button></td>
<td class="fixed-value"></td>
</tr>
<tr data-item="{{itemId}}">
<td class="padding edit-item">{{localize "midgard5.resistanceMind"}}</td>
<td class="center">{{data.calc.stats.resistanceMind.value}}</td>
<td class="fixed-value"><button class="roll-button roll-resistanceMind-button"></button></td>
<td class="fixed-value"></td>
</tr>
<tr data-item="{{itemId}}">
<td class="padding edit-item">{{localize "midgard5.resistanceBody"}}</td>
<td class="center">{{data.calc.stats.resistanceBody.value}}</td>
<td class="fixed-value"><button class="roll-button roll-resistanceBody-button"></button></td>
<td class="fixed-value"></td>
</tr>
</tbody>
</table>
+2
View File
@@ -119,6 +119,7 @@
</thead>
<tbody>
{{#each data.skills.general as |skill key|}}
{{#unless (isSkillInList (localizeMidgard key) ../actor.system.calc.skills.general) }}
<tr data-skill="{{key}}">
<td><button class="learn-button">{{localize "midgard5.learn"}}</button></td>
<td class="padding">{{localizeMidgard key}}</td>
@@ -129,6 +130,7 @@
<td class="fixed-value"><button class="roll-button roll-general-button"></button></td>
<td class="fixed-value"></td>
</tr>
{{/unless}}
{{/each}}
</tbody>
</table>