diff --git a/gulpfile.ts b/gulpfile.ts
index b2dc842..0d88760 100644
--- a/gulpfile.ts
+++ b/gulpfile.ts
@@ -157,7 +157,7 @@ function buildTS() {
const bundleModule = () => {
const debug = argv.dbg || argv.debug
const bsfy = browserify(path.join(__dirname, "source/index.ts"), { debug: debug })
- return bsfy.on('error', Logger.Err)
+ return bsfy.on('error', Logger.err)
.plugin(tsify)
.bundle()
.pipe(source(path.join(distPath, "bundle.js")))
@@ -252,7 +252,7 @@ const copyFiles = async() => {
return Promise.resolve()
const filter = (src: string, dest: string): boolean => {
- Logger.Ok("Copying file: " + dest)
+ Logger.ok("Copying file: " + dest)
return true
}
@@ -292,7 +292,7 @@ const cleanDist = async () => {
if (file.endsWith("bundle.js") || file.endsWith(".css") || file.endsWith("module.json"))
continue
- Logger.Warn("Cleaning " + path.relative(process.cwd(), file))
+ Logger.warn("Cleaning " + path.relative(process.cwd(), file))
await fs.promises.unlink(file)
}
}
@@ -364,12 +364,12 @@ const linkUserData = async () => {
}
//if (argv.clean || argv.c) {
- Logger.Warn(`Removing build in ${linkDir}`)
+ Logger.warn(`Removing build in ${linkDir}`)
fs.rmSync(linkDir, { recursive: true, force: true })
fs.mkdirSync(linkDir)
//}
- Logger.Ok(`Copying build to ${linkDir}`)
+ Logger.ok(`Copying build to ${linkDir}`)
fs.copySync(path.resolve(distPath), linkDir, { overwrite: true })
return Promise.resolve()
@@ -388,7 +388,7 @@ const linkUserData = async () => {
async function packageBuild() {
const manifest = getManifest()
if (manifest === null) {
- Logger.Err("Manifest file could not be loaded.")
+ Logger.err("Manifest file could not be loaded.")
throw Error()
}
@@ -396,7 +396,7 @@ async function packageBuild() {
try {
// Remove the package dir without doing anything else
if (argv.clean || argv.c) {
- Logger.Warn("Removing all packaged files")
+ Logger.warn("Removing all packaged files")
fs.rmSync(distPath, { force: true, recursive: true })
return
}
@@ -411,8 +411,8 @@ async function packageBuild() {
const zip = archiver("zip", { zlib: { level: 9 } })
zipFile.on("close", () => {
- Logger.Ok(zip.pointer() + " total bytes")
- Logger.Ok(`Zip file ${zipName} has been written`)
+ Logger.ok(zip.pointer() + " total bytes")
+ Logger.ok(`Zip file ${zipName} has been written`)
return resolve(true)
})
@@ -492,7 +492,7 @@ const updateManifest = (cb: any) => {
return cb(Error("Error: Target version is identical to current version."))
}
- Logger.Ok(`Updating version number to '${targetVersion}'`)
+ Logger.ok(`Updating version number to '${targetVersion}'`)
packageJson.version = targetVersion
manifest.file.version = targetVersion
diff --git a/lang/de.json b/lang/de.json
index 12109ab..21f3728 100644
--- a/lang/de.json
+++ b/lang/de.json
@@ -143,5 +143,11 @@
"midgard5.learned-skill": "Gelernte Fertigkeit",
"midgard5.language": "Sprache",
"midgard5.weapon-skill": "Waffenfertigkeit",
- "midgard5.unlearned-skill": "Ungelernte Fertigkeit"
+ "midgard5.unlearned-skill": "Ungelernte Fertigkeit",
+
+ "midgard5.base-damage": "Grundschaden",
+ "midgard5.defensive-weapon": "Verteidigungswaffe",
+ "midgard5.no-skill": "Keine Fertigkeit",
+ "midgard5.magic": "magisch",
+ "midgard5.rangedWeapon": "Schusswaffe"
}
diff --git a/source/index.ts b/source/index.ts
index d6eb4d7..cbb959c 100644
--- a/source/index.ts
+++ b/source/index.ts
@@ -62,5 +62,5 @@ Hooks.once("setup", () => {
})
Hooks.once("ready", () => {
- Logger.Ok("Template module is now ready.")
+ Logger.ok("Template module is now ready.")
})
diff --git a/source/module/actors/M5Character.ts b/source/module/actors/M5Character.ts
index 15351af..02ddf05 100644
--- a/source/module/actors/M5Character.ts
+++ b/source/module/actors/M5Character.ts
@@ -30,6 +30,14 @@ export interface M5CharacterCalculatedData {
}
skills: {
general: {}
+ combat: {}
+ language: {}
+ custom: {}
+ }
+ gear: {
+ weapons: {}
+ armor: {}
+ items: {}
}
}
@@ -60,10 +68,8 @@ export class M5Character extends Actor {
return -2
}
- prepareDerivedData() {
- const context = (this as any).data
-
- context.data.calc = {
+ derivedData(skipSkills: boolean, skipWeapons: boolean): M5CharacterCalculatedData {
+ let ret: M5CharacterCalculatedData = {
level: 0,
attributes: {
st: { value: 0, bonus: 0 },
@@ -95,56 +101,93 @@ export class M5Character extends Actor {
combat: {},
language: {},
custom: {}
+ },
+ gear: {
+ weapons: {},
+ armor: {},
+ items: {}
}
} as M5CharacterCalculatedData
+ const context = (this as any).data
const data = context.data
- const calc = context.data.calc as M5CharacterCalculatedData
- calc.level = M5Character.levelFromExp(data.es)
+ ret.level = M5Character.levelFromExp(data.es)
- calc.attributes.st.value = M5Character.attributeMinMax(data.attributes.st) // TODO item effects
- calc.attributes.gs.value = M5Character.attributeMinMax(data.attributes.gs)
- calc.attributes.gw.value = M5Character.attributeMinMax(data.attributes.gw)
- calc.attributes.ko.value = M5Character.attributeMinMax(data.attributes.ko)
- calc.attributes.in.value = M5Character.attributeMinMax(data.attributes.in)
- calc.attributes.zt.value = M5Character.attributeMinMax(data.attributes.zt)
- calc.attributes.au.value = M5Character.attributeMinMax(data.attributes.au)
- calc.attributes.pa.value = M5Character.attributeMinMax(data.attributes.pa)
- calc.attributes.wk.value = M5Character.attributeMinMax(data.attributes.wk)
+ ret.attributes.st.value = M5Character.attributeMinMax(data.attributes.st) // TODO item effects
+ ret.attributes.gs.value = M5Character.attributeMinMax(data.attributes.gs)
+ ret.attributes.gw.value = M5Character.attributeMinMax(data.attributes.gw)
+ ret.attributes.ko.value = M5Character.attributeMinMax(data.attributes.ko)
+ ret.attributes.in.value = M5Character.attributeMinMax(data.attributes.in)
+ ret.attributes.zt.value = M5Character.attributeMinMax(data.attributes.zt)
+ ret.attributes.au.value = M5Character.attributeMinMax(data.attributes.au)
+ ret.attributes.pa.value = M5Character.attributeMinMax(data.attributes.pa)
+ ret.attributes.wk.value = M5Character.attributeMinMax(data.attributes.wk)
- calc.attributes.st.bonus = M5Character.attributeBonus(data.attributes.st)
- calc.attributes.gs.bonus = M5Character.attributeBonus(data.attributes.gs)
- calc.attributes.gw.bonus = M5Character.attributeBonus(data.attributes.gw)
- calc.attributes.ko.bonus = M5Character.attributeBonus(data.attributes.ko)
- calc.attributes.in.bonus = M5Character.attributeBonus(data.attributes.in)
- calc.attributes.zt.bonus = M5Character.attributeBonus(data.attributes.zt)
- calc.attributes.au.bonus = M5Character.attributeBonus(data.attributes.au)
- calc.attributes.pa.bonus = M5Character.attributeBonus(data.attributes.pa)
- calc.attributes.wk.bonus = M5Character.attributeBonus(data.attributes.wk)
+ ret.attributes.st.bonus = M5Character.attributeBonus(data.attributes.st)
+ ret.attributes.gs.bonus = M5Character.attributeBonus(data.attributes.gs)
+ ret.attributes.gw.bonus = M5Character.attributeBonus(data.attributes.gw)
+ ret.attributes.ko.bonus = M5Character.attributeBonus(data.attributes.ko)
+ ret.attributes.in.bonus = M5Character.attributeBonus(data.attributes.in)
+ ret.attributes.zt.bonus = M5Character.attributeBonus(data.attributes.zt)
+ ret.attributes.au.bonus = M5Character.attributeBonus(data.attributes.au)
+ ret.attributes.pa.bonus = M5Character.attributeBonus(data.attributes.pa)
+ ret.attributes.wk.bonus = M5Character.attributeBonus(data.attributes.wk)
- calc.stats.armor = 0
- calc.stats.defense = M5Character.defenseFromLevel(calc.level)
- calc.stats.damageBonus = Math.floor(calc.attributes.st.value/20) + Math.floor(calc.attributes.gs.value/30) - 3
- calc.stats.attackBonus = calc.attributes.gs.bonus
- calc.stats.defenseBonus = calc.attributes.gw.bonus
- calc.stats.movementBonus = 0
- calc.stats.resistanceMind = calc.stats.defense
- calc.stats.resistanceBody = calc.stats.defense + 1
- calc.stats.spellCasting = (data.info.magicUsing ? M5Character.spellCastingFromLevel(calc.level) : 3) + calc.attributes.zt.bonus
- calc.stats.brawl = Math.floor((calc.attributes.st.value + calc.attributes.gw.value) / 20)
- calc.stats.poisonResistance = 30 + Math.floor(calc.attributes.ko.value / 2)
- calc.stats.enduranceBonus = Math.floor(calc.attributes.ko.value/10) + Math.floor(calc.attributes.st.value/20)
+ ret.stats.armor = 0
+ ret.stats.defense = M5Character.defenseFromLevel(ret.level)
+ ret.stats.damageBonus = Math.floor(ret.attributes.st.value/20) + Math.floor(ret.attributes.gs.value/30) - 3
+ ret.stats.attackBonus = ret.attributes.gs.bonus
+ ret.stats.defenseBonus = ret.attributes.gw.bonus
+ ret.stats.movementBonus = 0
+ ret.stats.resistanceMind = ret.stats.defense
+ ret.stats.resistanceBody = ret.stats.defense + 1
+ ret.stats.spellCasting = (data.info.magicUsing ? M5Character.spellCastingFromLevel(ret.level) : 3) + ret.attributes.zt.bonus
+ ret.stats.brawl = Math.floor((ret.attributes.st.value + ret.attributes.gw.value) / 20)
+ ret.stats.poisonResistance = 30 + Math.floor(ret.attributes.ko.value / 2)
+ ret.stats.enduranceBonus = Math.floor(ret.attributes.ko.value/10) + Math.floor(ret.attributes.st.value/20)
- context.items?.filter(item => item.data.type === "skill").forEach(item => {
- item.prepareDerivedData()
- const skillMap = calc.skills[item.data.data.type]
- skillMap[item.data._id] = {
- label: item.data.name,
- fw: item.data.data.fw,
- attribute: item.data.data.attribute,
- calc: item.data.data.calc
- }
- })
+ if (!skipSkills) {
+ context.items?.filter(item => item.data.type === "skill").forEach(item => {
+ item.prepareDerivedData()
+ const skillMap = ret.skills[item.data.data.type]
+ skillMap[item.data._id] = {
+ label: item.data.name,
+ fw: item.data.data.fw,
+ attribute: item.data.data.attribute,
+ calc: item.data.data.calc
+ }
+ })
+ }
+
+ if (!skipWeapons) {
+ context.items?.filter(item => item.data.type === "weapon").forEach(item => {
+ item.prepareDerivedData()
+
+ let label = item.data.name
+ if (item.data.data.magic) {
+ label += "*("
+ + (item.data.data.stats.attackBonus < 0 ? "" : "+")
+ + item.data.data.stats.attackBonus + "/"
+ + (item.data.data.stats.damageBonus < 0 ? "" : "+")
+ + item.data.data.stats.damageBonus + ")"
+ }
+
+ ret.gear.weapons[item.data._id] = {
+ label: label,
+ skillId: item.data.data.skillId,
+ defensive: item.data.data.defensive,
+ magic: item.data.data.magic,
+ calc: item.data.data.calc
+ }
+ })
+ }
+
+ return ret
+ }
+
+ prepareDerivedData() {
+ const context = (this as any).data
+ context.data.calc = this.derivedData(false, false)
}
override getRollData(): any {
@@ -220,4 +263,8 @@ export class M5Character extends Actor {
})
}
+ getSkill(skillId: string): M5Skill {
+ return (this as any).getEmbeddedDocument("Item", skillId) as M5Skill
+ }
+
}
diff --git a/source/module/items/M5Item.ts b/source/module/items/M5Item.ts
index f1d5885..f932e98 100644
--- a/source/module/items/M5Item.ts
+++ b/source/module/items/M5Item.ts
@@ -14,17 +14,33 @@ export class M5Item extends Item {
calc.bonus = 0
if (context.data.attribute && context.data.attribute !== "") {
- //console.log(context.name, context.data)
const attribute = character.attribute(context.data.attribute)
calc.bonus += M5Character.attributeBonus(attribute)
}
- if (context._id === actor.data.data.skills.preferredCombatSkill) {
+ if (context._id === actor.data?.data?.skills.preferredCombatSkill) {
calc.bonus += 2
}
calc.ew = context.data.fw + calc.bonus
} else if (context.type === "weapon") {
+ calc.ew = context.data.stats.attackBonus
+ calc.combatSkills = null
+
+ if (actor) {
+ const actorCalc = character.derivedData(false, true)
+ calc.ew += actorCalc.stats.attackBonus
+
+ const skill = character.getSkill(context.data.skillId) as any
+ //console.log("M5Item.prepareDerivedData:weapon", context.data, skill?.data?.data)
+ if (skill) {
+ skill.prepareDerivedData()
+ const skillData = skill.data.data
+ calc.ew += skillData.calc.ew
+ }
+
+ calc.combatSkills = actorCalc.skills.combat
+ }
}
}
diff --git a/source/module/sheets/M5CharacterSheet.ts b/source/module/sheets/M5CharacterSheet.ts
index 44cdc25..c56b34a 100644
--- a/source/module/sheets/M5CharacterSheet.ts
+++ b/source/module/sheets/M5CharacterSheet.ts
@@ -37,18 +37,18 @@ export default class M5CharacterSheet extends ActorSheet {
override activateListeners(html: JQuery) {
super.activateListeners(html)
- html.find(".edit-skill").on("click", async (event) => {
+ html.find(".edit-item").on("click", async (event) => {
const row = event.target.parentElement
- let skillId = row.dataset["skill"]
+ let itemId = row.dataset["item"]
const context = this.actor.data
- const item = context.items.get(skillId)
+ const item = context.items.get(itemId)
item.sheet.render(true)
})
html.find(".change-special-combat-skill").on("click", async (event) => {
const row = event.target.parentElement.parentElement
- let skillId = row.dataset["skill"]
+ let skillId = row.dataset["item"]
const actor = this.actor as any
actor.update({
@@ -62,7 +62,7 @@ export default class M5CharacterSheet extends ActorSheet {
html.find(".roll-learned-button").on("click", async (event) => {
const row = event.target.parentElement.parentElement
- let skillId = row.dataset["skill"]
+ let skillId = row.dataset["item"]
const actor = this.actor as any
const context = this.actor.data
@@ -139,6 +139,18 @@ export default class M5CharacterSheet extends ActorSheet {
})
})
+ html.find(".roll-weapon-button").on("click", async (event) => {
+ const row = event.target.parentElement.parentElement
+ let itemId = row.dataset["item"]
+
+ const actor = this.actor as any
+ const context = this.actor.data
+ const data = context.data
+
+ const item = context.items.get(itemId) as M5Item
+ await item.roll()
+ })
+
// Drag & Drop
const dragDrop = new DragDrop({
dragSelector: ".items-list .item",
diff --git a/source/module/sheets/M5ItemSheet.ts b/source/module/sheets/M5ItemSheet.ts
index 1e6322a..d845dcb 100644
--- a/source/module/sheets/M5ItemSheet.ts
+++ b/source/module/sheets/M5ItemSheet.ts
@@ -30,6 +30,7 @@ export class M5ItemSheet extends ItemSheet {
let actor = this.object?.parent ?? null
if (actor) {
context.rollData = actor.getRollData()
+ } else {
}
// Add the actor's data to context.data for easier access, as well as flags.
diff --git a/source/template.json b/source/template.json
index 212f21e..200ecba 100644
--- a/source/template.json
+++ b/source/template.json
@@ -116,9 +116,6 @@
"templates": ["characterBars", "attributes", "characterDescription", "characterHeader", "skills"],
"calc": {}
},
- "npc": {
- "templates": ["characterBars", "attributes", "characterDescription"]
- },
"vehicle": {
"templates": ["characterBars", "attributes"]
}
@@ -130,13 +127,15 @@
"description": ""
},
"stats": {
- "damageBonus": 0,
- "attackBonus": 0,
- "defenseBonus": 0,
- "movementBonus": 0,
- "resistanceMind": 0,
- "resistanceBody": 0,
- "spellBonus": 0
+ "stats": {
+ "damageBonus": 0,
+ "attackBonus": 0,
+ "defenseBonus": 0,
+ "movementBonus": 0,
+ "resistanceMind": 0,
+ "resistanceBody": 0,
+ "spellBonus": 0
+ }
},
"attributeSelection": {
"attributes": {
@@ -190,30 +189,46 @@
"rolls": {
"formulas": {},
"output": ""
- }
+ },
+ "calc": {}
},
"weapon": {
"templates": ["itemDescription", "stats", "equippable"],
+ "magic": false,
+ "ranged": false,
"defensive": false,
- "skill": "",
+ "skillId": "",
+ "damageBase": "1d6",
"rolls": {
- "formulas": {},
+ "formulas": {
+ "1": {
+ "formula": "1d20 + @i.calc.ew",
+ "type": "ew"
+ },
+ "2": {
+ "formula": "@i.damageBase + @i.stats.damageBonus + @c.calc.stats.damageBonus",
+ "type": "dmg"
+ }
+ },
"output": ""
- }
+ },
+ "calc": {}
},
"armor": {
"templates": ["itemDescription", "stats", "equippable"],
"rolls": {
"formulas": {},
"output": ""
- }
+ },
+ "calc": {}
},
"spell": {
"templates": ["itemDescription"],
"rolls": {
"formulas": {},
"output": ""
- }
+ },
+ "calc": {}
}
}
}
\ No newline at end of file
diff --git a/templates/sheets/character/gear.hbs b/templates/sheets/character/gear.hbs
index e69de29..c3c985a 100644
--- a/templates/sheets/character/gear.hbs
+++ b/templates/sheets/character/gear.hbs
@@ -0,0 +1,18 @@
+
+
+
+ | {{localize "ITEM.TypeWeapon"}} |
+ {{localize "midgard5.ew"}} |
+ |
+
+
+
+ {{#each data.calc.gear.weapons as |weapon itemId|}}
+
+ | {{weapon.label}} |
+ {{weapon.calc.ew}} |
+ |
+
+ {{/each}}
+
+
diff --git a/templates/sheets/character/skills.hbs b/templates/sheets/character/skills.hbs
index bc3fc2a..6fd2db8 100644
--- a/templates/sheets/character/skills.hbs
+++ b/templates/sheets/character/skills.hbs
@@ -10,8 +10,8 @@
{{#each data.calc.skills.general as |skill skillId|}}
-
- | {{skill.label}} |
+
+ | {{skill.label}} |
{{skill.fw}} |
{{skill.calc.bonus}} |
{{skill.calc.ew}} |
@@ -41,8 +41,8 @@
{{#each data.calc.skills.language as |skill skillId|}}
-
- | {{skill.label}} |
+
+ | {{skill.label}} |
{{skill.fw}} |
{{skill.calc.bonus}} |
{{skill.calc.ew}} |
@@ -73,8 +73,8 @@
{{#each data.calc.skills.combat as |skill skillId|}}
-
- | {{skill.label}} |
+
+ | {{skill.label}} |
{{#if (eq skillId ../data.skills.preferredCombatSkill)}}
diff --git a/templates/sheets/item/weapon.hbs b/templates/sheets/item/weapon.hbs
index 0f256a2..e3b3e45 100644
--- a/templates/sheets/item/weapon.hbs
+++ b/templates/sheets/item/weapon.hbs
@@ -4,7 +4,56 @@
-
+
{{editor content=data.description target="data.description" button=true owner=owner editable=editable}}
\ No newline at end of file
|