Adds mod management (WIP)
This commit is contained in:
+100
-1
@@ -1,4 +1,48 @@
|
||||
|
||||
export interface M5CharacterCalculatedData {
|
||||
level: number
|
||||
attributes: {
|
||||
st: { value: number, bonus: number }
|
||||
gs: { value: number, bonus: number }
|
||||
gw: { value: number, bonus: number }
|
||||
ko: { value: number, bonus: number }
|
||||
in: { value: number, bonus: number }
|
||||
zt: { value: number, bonus: number }
|
||||
au: { value: number, bonus: number }
|
||||
pa: { value: number, bonus: number }
|
||||
wk: { value: number, bonus: number }
|
||||
}
|
||||
stats: {
|
||||
armor: number
|
||||
defense: number
|
||||
damageBonus: number
|
||||
attackBonus: number
|
||||
defenseBonus: number
|
||||
movementBonus: number
|
||||
resistanceMind: number
|
||||
resistanceBody: number
|
||||
spellCasting: number
|
||||
brawl: number
|
||||
brawlEw: number
|
||||
poisonResistance: number
|
||||
enduranceBonus: number
|
||||
}
|
||||
skills: {
|
||||
innate: {}
|
||||
general: {}
|
||||
combat: {}
|
||||
language: {}
|
||||
custom: {}
|
||||
}
|
||||
gear: {
|
||||
weapons: {}
|
||||
defensiveWeapons: {}
|
||||
armor: {}
|
||||
items: {}
|
||||
}
|
||||
spells: {}
|
||||
}
|
||||
|
||||
export interface M5Skill {
|
||||
fw: number
|
||||
attribute: string
|
||||
@@ -13,6 +57,11 @@ export interface M5SkillLearned extends M5Skill {
|
||||
type: string
|
||||
}
|
||||
|
||||
export interface M5SkillCalculated extends M5Skill {
|
||||
label: string,
|
||||
calc: any
|
||||
}
|
||||
|
||||
export interface M5Attribute {
|
||||
value: number
|
||||
bonus: number
|
||||
@@ -47,4 +96,54 @@ export enum M5EwResult {
|
||||
HIGH = "roll-ew-result-high",
|
||||
FAIL = "roll-ew-result-fail",
|
||||
PASS = "roll-ew-result-pass"
|
||||
}
|
||||
}
|
||||
|
||||
export enum M5Attributes {
|
||||
ST = "st",
|
||||
GW = "gw",
|
||||
GS = "gs",
|
||||
KO = "ko",
|
||||
IN = "in",
|
||||
ZT = "zt",
|
||||
AU = "au",
|
||||
PA = "pa",
|
||||
WK = "wk"
|
||||
}
|
||||
|
||||
export enum M5Stats {
|
||||
DEFENSE = "defense",
|
||||
ATTACK = "attack",
|
||||
DAMAGE = "damage",
|
||||
MOVEMENT = "movement",
|
||||
RESISTANCE_MIND = "resistanceMind",
|
||||
RESISTANCE_BODY = "resistanceBody",
|
||||
SPELL_CASTING = "spellCasting",
|
||||
BRAWL = "brawl",
|
||||
POISON_RESISTANCE = "poisonResistance",
|
||||
LP = "lp",
|
||||
AP = "ap"
|
||||
}
|
||||
|
||||
export enum M5ModType {
|
||||
ATTRIBUTE = "attribute",
|
||||
STAT = "stat",
|
||||
SKILL = "skill"
|
||||
}
|
||||
|
||||
export enum M5ModOperation {
|
||||
ADD_100 = "add100",
|
||||
ADD = "add",
|
||||
SET = "set",
|
||||
FIXED = "fixed"
|
||||
}
|
||||
|
||||
export interface M5ItemMod {
|
||||
type: M5ModType
|
||||
id: string
|
||||
operation: M5ModOperation
|
||||
value: number
|
||||
}
|
||||
|
||||
export function enumKeys<O extends object, K extends keyof O = keyof O>(obj: O): K[] {
|
||||
return Object.keys(obj).filter(k => Number.isNaN(+k)) as K[]
|
||||
}
|
||||
|
||||
@@ -1,49 +1,5 @@
|
||||
import { M5Item } from "../items/M5Item"
|
||||
import { M5Attribute, M5RollData, M5Skill, M5SkillLearned } from "../M5Base"
|
||||
|
||||
export interface M5CharacterCalculatedData {
|
||||
level: number
|
||||
attributes: {
|
||||
st: { value: number, bonus: number }
|
||||
gs: { value: number, bonus: number }
|
||||
gw: { value: number, bonus: number }
|
||||
ko: { value: number, bonus: number }
|
||||
in: { value: number, bonus: number }
|
||||
zt: { value: number, bonus: number }
|
||||
au: { value: number, bonus: number }
|
||||
pa: { value: number, bonus: number }
|
||||
wk: { value: number, bonus: number }
|
||||
}
|
||||
stats: {
|
||||
armor: number
|
||||
defense: number
|
||||
damageBonus: number
|
||||
attackBonus: number
|
||||
defenseBonus: number
|
||||
movementBonus: number
|
||||
resistanceMind: number
|
||||
resistanceBody: number
|
||||
spellCasting: number
|
||||
brawl: number
|
||||
brawlEw: number
|
||||
poisonResistance: number
|
||||
enduranceBonus: number
|
||||
}
|
||||
skills: {
|
||||
innate: {}
|
||||
general: {}
|
||||
combat: {}
|
||||
language: {}
|
||||
custom: {}
|
||||
}
|
||||
gear: {
|
||||
weapons: {}
|
||||
defensiveWeapons: {}
|
||||
armor: {}
|
||||
items: {}
|
||||
}
|
||||
spells: {}
|
||||
}
|
||||
import { M5Attribute, M5CharacterCalculatedData, M5RollData, M5Skill, M5SkillCalculated, M5SkillLearned } from "../M5Base"
|
||||
|
||||
export class M5Character extends Actor {
|
||||
|
||||
@@ -118,7 +74,13 @@ export class M5Character extends Actor {
|
||||
} as M5CharacterCalculatedData
|
||||
|
||||
const context = (this as any).data
|
||||
if (!context)
|
||||
return null
|
||||
|
||||
const data = context.data
|
||||
if (!data)
|
||||
return null
|
||||
|
||||
ret.level = M5Character.levelFromExp(data.es)
|
||||
|
||||
ret.attributes.st.value = M5Character.attributeMinMax(data.attributes.st) // TODO item effects
|
||||
@@ -155,6 +117,23 @@ export class M5Character extends Actor {
|
||||
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)
|
||||
|
||||
if (!skip.items) {
|
||||
context.items?.filter(item => item.data.type === "item").forEach(item => {
|
||||
item.prepareDerivedData()
|
||||
|
||||
let label = item.data.name
|
||||
if (item.data.data.magic) {
|
||||
label += "*"
|
||||
}
|
||||
|
||||
ret.gear.items[item.data._id] = {
|
||||
label: label,
|
||||
magic: item.data.data.magic,
|
||||
calc: item.data.data.calc
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (!skip.skills) {
|
||||
context.items?.filter(item => item.data.type === "skill").forEach(item => {
|
||||
item.prepareDerivedData()
|
||||
@@ -164,7 +143,7 @@ export class M5Character extends Actor {
|
||||
fw: item.data.data.fw,
|
||||
attribute: item.data.data.attribute,
|
||||
calc: item.data.data.calc
|
||||
}
|
||||
} as M5SkillCalculated
|
||||
})
|
||||
}
|
||||
|
||||
@@ -227,23 +206,6 @@ export class M5Character extends Actor {
|
||||
})
|
||||
}
|
||||
|
||||
if (!skip.items) {
|
||||
context.items?.filter(item => item.data.type === "item").forEach(item => {
|
||||
item.prepareDerivedData()
|
||||
|
||||
let label = item.data.name
|
||||
if (item.data.data.magic) {
|
||||
label += "*"
|
||||
}
|
||||
|
||||
ret.gear.items[item.data._id] = {
|
||||
label: label,
|
||||
magic: item.data.data.magic,
|
||||
calc: item.data.data.calc
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (!skip.spells) {
|
||||
context.items?.filter(item => item.data.type === "spell").forEach(item => {
|
||||
item.prepareDerivedData()
|
||||
@@ -323,7 +285,7 @@ export class M5Character extends Actor {
|
||||
|
||||
attribute(name: string): M5Attribute {
|
||||
const context = (this as any).data
|
||||
return context.data.attributes[name]
|
||||
return context?.data?.attributes[name]
|
||||
}
|
||||
|
||||
createSkill(skillName: string): Promise<M5Item> {
|
||||
@@ -334,12 +296,14 @@ export class M5Character extends Actor {
|
||||
|
||||
return (this as any).createEmbeddedDocuments("Item", [itemData]).then(docs => {
|
||||
const item = docs[0]
|
||||
return item as M5Item
|
||||
return item
|
||||
})
|
||||
}
|
||||
|
||||
getSkill(skillId: string): M5Skill {
|
||||
return (this as any).getEmbeddedDocument("Item", skillId) as M5Skill
|
||||
getItem(itemId: string): any {
|
||||
if (!(this as any).data?.items)
|
||||
return null
|
||||
return (this as any).getEmbeddedDocument("Item", itemId)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { ItemData } from "@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/data/module.mjs"
|
||||
import { ConstructorDataType } from "@league-of-foundry-developers/foundry-vtt-types/src/types/helperTypes"
|
||||
import { M5Character } from "../actors/M5Character"
|
||||
import { M5RollData, M5RollResult, M5Skill } from "../M5Base"
|
||||
import { enumKeys, M5Attributes, M5ItemMod, M5ModType, M5RollData, M5RollResult, M5Skill, M5Stats } from "../M5Base"
|
||||
import { M5Roll } from "../rolls/M5Roll"
|
||||
|
||||
export class M5Item extends Item {
|
||||
@@ -16,7 +18,8 @@ export class M5Item extends Item {
|
||||
|
||||
if (context.data?.attribute && context.data?.attribute !== "" && character) {
|
||||
const attribute = character.attribute(context.data.attribute)
|
||||
calc.bonus += M5Character.attributeBonus(attribute)
|
||||
if (attribute)
|
||||
calc.bonus += M5Character.attributeBonus(attribute)
|
||||
}
|
||||
|
||||
calc.ew = context.data.fw + calc.bonus
|
||||
@@ -29,9 +32,12 @@ export class M5Item extends Item {
|
||||
|
||||
if (actor) {
|
||||
const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true })
|
||||
calc.ew += actorCalc.stats.attackBonus
|
||||
if (actorCalc) {
|
||||
calc.ew += actorCalc.stats.attackBonus
|
||||
calc.combatSkills = actorCalc.skills.combat
|
||||
}
|
||||
|
||||
const skill = character.getSkill(context.data.skillId) as any
|
||||
const skill = character.getItem(context.data.skillId)
|
||||
//console.log("M5Item.prepareDerivedData:weapon", context.data, skill?.data?.data)
|
||||
if (skill) {
|
||||
skill.prepareDerivedData()
|
||||
@@ -40,8 +46,6 @@ export class M5Item extends Item {
|
||||
calc.bonus += skillData.calc.bonus
|
||||
calc.fw += skillData.fw
|
||||
}
|
||||
|
||||
calc.combatSkills = actorCalc.skills.combat
|
||||
}
|
||||
} else if (context.type === "defensiveWeapon") {
|
||||
calc.fw = 0
|
||||
@@ -52,9 +56,12 @@ export class M5Item extends Item {
|
||||
|
||||
if (actor) {
|
||||
const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true })
|
||||
calc.ew += actorCalc.stats.defense + actorCalc.stats.defenseBonus
|
||||
if (actorCalc) {
|
||||
calc.ew += actorCalc.stats.defense + actorCalc.stats.defenseBonus
|
||||
calc.combatSkills = actorCalc.skills.combat
|
||||
}
|
||||
|
||||
const skill = character.getSkill(context.data.skillId) as any
|
||||
const skill = character.getItem(context.data.skillId)
|
||||
//console.log("M5Item.prepareDerivedData:weapon", context.data, skill?.data?.data)
|
||||
if (skill) {
|
||||
skill.prepareDerivedData()
|
||||
@@ -63,15 +70,90 @@ export class M5Item extends Item {
|
||||
calc.bonus += skillData.calc.bonus
|
||||
calc.fw += skillData.fw
|
||||
}
|
||||
|
||||
calc.combatSkills = actorCalc.skills.combat
|
||||
}
|
||||
} else if (context.type === "spell") {
|
||||
calc.ew = context.data.bonus
|
||||
if (actor) {
|
||||
const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true })
|
||||
calc.ew += actorCalc.stats.spellCasting
|
||||
if (actorCalc) {
|
||||
calc.ew += actorCalc.stats.spellCasting
|
||||
}
|
||||
}
|
||||
} else if (context.type === "mod") {
|
||||
const parent = (this as any).parent
|
||||
const actor = parent?.actor
|
||||
const character = actor as M5Character
|
||||
|
||||
calc.ids = {}
|
||||
|
||||
switch (context.data.type as M5ModType) {
|
||||
case M5ModType.ATTRIBUTE: {
|
||||
for (const key of enumKeys(M5Attributes)) {
|
||||
const val = M5Attributes[key]
|
||||
calc.ids[key] = (game as Game).i18n.localize(`midgard5.actor-${val}-long`)
|
||||
}
|
||||
break
|
||||
}
|
||||
case M5ModType.STAT: {
|
||||
for (const key of enumKeys(M5Stats)) {
|
||||
const val = M5Stats[key]
|
||||
calc.ids[key] = (game as Game).i18n.localize(`midgard5.mod-stat-${val}`)
|
||||
}
|
||||
break
|
||||
}
|
||||
case M5ModType.SKILL: {
|
||||
if (character) {
|
||||
const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true })
|
||||
if (actorCalc) {
|
||||
let category = (game as Game).i18n.localize("midgard5.innate-ability")
|
||||
Object.keys(actorCalc.skills.innate).forEach(skillId => {
|
||||
const skill = character.getItem(skillId)
|
||||
if (skill)
|
||||
calc.ids[skillId] = `${category}: ${skill.data.name}`
|
||||
})
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if (context.type === "item") {
|
||||
calc.mods = {}
|
||||
Object.keys(context.data?.mods).forEach(key => {
|
||||
const mod = context.data.mods[key]
|
||||
const modCalc = {}
|
||||
switch (mod.type) {
|
||||
case M5ModType.ATTRIBUTE: {
|
||||
for (const key of enumKeys(M5Attributes)) {
|
||||
const val = M5Attributes[key]
|
||||
modCalc[key] = (game as Game).i18n.localize(`midgard5.actor-${val}-long`)
|
||||
}
|
||||
break
|
||||
}
|
||||
case M5ModType.STAT: {
|
||||
for (const key of enumKeys(M5Stats)) {
|
||||
const val = M5Stats[key]
|
||||
modCalc[key] = (game as Game).i18n.localize(`midgard5.mod-stat-${val}`)
|
||||
}
|
||||
break
|
||||
}
|
||||
case M5ModType.SKILL: {
|
||||
if (character) {
|
||||
const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true })
|
||||
if (actorCalc) {
|
||||
let category = (game as Game).i18n.localize("midgard5.innate-ability")
|
||||
Object.keys(actorCalc.skills.innate).forEach(skillId => {
|
||||
const skill = character.getItem(skillId)
|
||||
if (skill)
|
||||
modCalc[skillId] = `${category}: ${skill.data.name}`
|
||||
})
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
calc.mods[key] = modCalc
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,6 +210,10 @@ export class M5Item extends Item {
|
||||
})
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getItem(itemId: string): any {
|
||||
return (this as any).getEmbeddedDocument("Item", itemId)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -57,9 +57,26 @@ export default class M5CharacterSheet extends ActorSheet {
|
||||
|
||||
const context = this.actor.data
|
||||
const item = context.items.get(itemId)
|
||||
console.log("edit-item", item)
|
||||
item.sheet.render(true)
|
||||
})
|
||||
|
||||
html.find(".item-delete").on("click", async (event) => {
|
||||
let row = event.target.parentElement
|
||||
let itemId = row.dataset["item"]
|
||||
while (!itemId) {
|
||||
row = row.parentElement
|
||||
if (!row)
|
||||
return
|
||||
itemId = row.dataset["item"]
|
||||
}
|
||||
|
||||
const context = this.actor.data
|
||||
const item = context.items.get(itemId)
|
||||
item.delete()
|
||||
this.render(false)
|
||||
})
|
||||
|
||||
html.find(".roll-learned-button").on("click", async (event) => {
|
||||
const row = event.target.parentElement.parentElement
|
||||
let skillId = row.dataset["item"]
|
||||
@@ -193,7 +210,6 @@ export default class M5CharacterSheet extends ActorSheet {
|
||||
if (!data.data)
|
||||
return false
|
||||
|
||||
|
||||
if (data.actorId === this.actor.id)
|
||||
return false
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { M5Item } from "../items/M5Item"
|
||||
import { M5Attributes, M5ItemMod, M5ModOperation, M5ModType } from "../M5Base"
|
||||
|
||||
export class M5ItemSheet extends ItemSheet {
|
||||
|
||||
@@ -41,4 +42,108 @@ export class M5ItemSheet extends ItemSheet {
|
||||
})
|
||||
}
|
||||
|
||||
override activateListeners(html: JQuery) {
|
||||
super.activateListeners(html)
|
||||
|
||||
html.find(".add-mod").on("click", async (event) => {
|
||||
const context = this.object.data
|
||||
const mods = context.data.mods
|
||||
const modIndex = Object.keys(mods).length
|
||||
mods[modIndex.toString()] = {
|
||||
type: M5ModType.ATTRIBUTE,
|
||||
id: M5Attributes.ST,
|
||||
operation: M5ModOperation.ADD,
|
||||
value: 0
|
||||
} as M5ItemMod
|
||||
this.object.update({
|
||||
data: {
|
||||
mods: mods
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
html.find(".item-delete").on("click", async (event) => {
|
||||
let row = event.target.parentElement
|
||||
let itemId = row.dataset["item"]
|
||||
while (!itemId) {
|
||||
row = row.parentElement
|
||||
if (!row)
|
||||
return
|
||||
itemId = row.dataset["item"]
|
||||
}
|
||||
|
||||
const context = this.item.data
|
||||
const item = context.items.get(itemId)
|
||||
item.delete()
|
||||
this.render(false)
|
||||
})
|
||||
|
||||
// Drag & Drop
|
||||
if (["item"].includes(this.object.data?.type)) {
|
||||
const itemToItemAssociation = new DragDrop({
|
||||
dragSelector: ".item",
|
||||
dropSelector: null,
|
||||
permissions: { dragstart: this._canDragStart.bind(this), drop: this._canDragDrop.bind(this) },
|
||||
callbacks: { drop: this._onDropItem.bind(this) },
|
||||
})
|
||||
itemToItemAssociation.bind(html[0])
|
||||
}
|
||||
}
|
||||
|
||||
_canDragStart(selector) {
|
||||
console.log("M5ItemSheet._canDragStart", selector)
|
||||
return this.options.editable && this.object.isOwner
|
||||
}
|
||||
|
||||
_canDragDrop(selector) {
|
||||
console.log("M5ItemSheet._canDragDrop", selector)
|
||||
return true
|
||||
}
|
||||
|
||||
async _onDropItem(event) {
|
||||
let data
|
||||
const obj = this.object
|
||||
const li = event.currentTarget
|
||||
|
||||
try {
|
||||
data = JSON.parse(event.dataTransfer.getData("text/plain"))
|
||||
if (data.type !== "Item")
|
||||
return false
|
||||
} catch (err) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Case 1 - Import from a Compendium pack
|
||||
let itemObject
|
||||
if (data.pack) {
|
||||
const compendiumObject = await (this as any).importItemFromCollection(data.pack, data.id)
|
||||
itemObject = compendiumObject.data
|
||||
}
|
||||
|
||||
// Case 2 - Import from World entity
|
||||
else {
|
||||
const originalItem = await (game as Game).items.get(data.id)
|
||||
itemObject = duplicate(originalItem)
|
||||
if (!itemObject)
|
||||
return
|
||||
}
|
||||
|
||||
if ((itemObject.type === "mod")) {
|
||||
let mods = obj?.data?.data?.mods
|
||||
if (!mods)
|
||||
mods = []
|
||||
|
||||
itemObject.id = randomID()
|
||||
console.log("M5ItemSheet._onDropItem", itemObject)
|
||||
mods.push(itemObject)
|
||||
|
||||
obj.update({
|
||||
data: {
|
||||
mods: mods
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async _onDragItemStart(event) { }
|
||||
}
|
||||
|
||||
@@ -47,6 +47,11 @@
|
||||
&.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&.fixed-value {
|
||||
width: 3rem;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
input.skill {
|
||||
|
||||
+28
-20
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"Actor": {
|
||||
"types": ["npc", "character"],
|
||||
"types": ["character"],
|
||||
"templates": {
|
||||
"characterDescription": {
|
||||
"info": {
|
||||
@@ -118,7 +118,7 @@
|
||||
}
|
||||
},
|
||||
"Item": {
|
||||
"types": ["skill", "item", "weapon", "defensiveWeapon", "armor", "spell"],
|
||||
"types": ["skill", "weapon", "defensiveWeapon", "armor", "spell", "item"],
|
||||
"templates": {
|
||||
"itemDescription": {
|
||||
"description": ""
|
||||
@@ -170,6 +170,10 @@
|
||||
"equippable": false,
|
||||
"equipped": true
|
||||
},
|
||||
"physical": {
|
||||
"value": 0,
|
||||
"magic": false
|
||||
},
|
||||
"spellSelection": {
|
||||
"spellProcessSelection": {
|
||||
"none": "midgard5.spell-process-none",
|
||||
@@ -214,31 +218,33 @@
|
||||
"0": {
|
||||
"formula": "1d20 + @i.fw + @i.calc.bonus",
|
||||
"type": "ew",
|
||||
"label": "EW"
|
||||
"label": "EW",
|
||||
"enabled": true
|
||||
}
|
||||
},
|
||||
"output": ""
|
||||
},
|
||||
"calc": {}
|
||||
},
|
||||
"item": {
|
||||
"templates": ["itemDescription", "stats", "equippable"],
|
||||
"quantity": 1,
|
||||
"mod": {
|
||||
"type": "",
|
||||
"id": "",
|
||||
"operation": "",
|
||||
"value": 0,
|
||||
"magic": false,
|
||||
"onbody": false,
|
||||
"attributes": {},
|
||||
"groups": {},
|
||||
"calc": {}
|
||||
},
|
||||
"item": {
|
||||
"templates": ["itemDescription", "equippable", "physical"],
|
||||
"rolls": {
|
||||
"formulas": {},
|
||||
"output": ""
|
||||
},
|
||||
"mods": {},
|
||||
"calc": {}
|
||||
},
|
||||
"weapon": {
|
||||
"templates": ["itemDescription", "stats", "equippable"],
|
||||
"templates": ["itemDescription", "stats", "equippable", "physical"],
|
||||
"special": false,
|
||||
"magic": false,
|
||||
"ranged": false,
|
||||
"skillId": "",
|
||||
"damageBase": "1d6",
|
||||
@@ -247,12 +253,14 @@
|
||||
"0": {
|
||||
"formula": "1d20 + @i.calc.fw + @i.calc.bonus + @i.calc.special + @c.calc.stats.attackBonus + @i.stats.attackBonus",
|
||||
"type": "ew",
|
||||
"label": "Angriff"
|
||||
"label": "Angriff",
|
||||
"enabled": true
|
||||
},
|
||||
"1": {
|
||||
"formula": "@i.damageBase + @i.stats.damageBonus + @c.calc.stats.damageBonus",
|
||||
"type": "dmg",
|
||||
"label": "Schaden"
|
||||
"label": "Schaden",
|
||||
"enabled": true
|
||||
}
|
||||
},
|
||||
"output": ""
|
||||
@@ -260,16 +268,16 @@
|
||||
"calc": {}
|
||||
},
|
||||
"defensiveWeapon": {
|
||||
"templates": ["itemDescription", "stats", "equippable"],
|
||||
"templates": ["itemDescription", "stats", "equippable", "physical"],
|
||||
"special": false,
|
||||
"magic": false,
|
||||
"skillId": "",
|
||||
"rolls": {
|
||||
"formulas": {
|
||||
"0": {
|
||||
"formula": "1d20 + @i.calc.fw + @i.calc.bonus + @i.calc.special + @c.calc.stats.defense + @c.calc.stats.defenseBonus + @i.stats.defenseBonus",
|
||||
"type": "ew",
|
||||
"label": "Abwehr"
|
||||
"label": "Abwehr",
|
||||
"enabled": true
|
||||
}
|
||||
},
|
||||
"output": ""
|
||||
@@ -277,8 +285,7 @@
|
||||
"calc": {}
|
||||
},
|
||||
"armor": {
|
||||
"templates": ["itemDescription", "stats", "equippable", "attributeMod"],
|
||||
"magic": false,
|
||||
"templates": ["itemDescription", "stats", "equippable", "attributeMod", "physical"],
|
||||
"lpProtection": 0,
|
||||
"apProtection": 0,
|
||||
"rolls": {
|
||||
@@ -304,7 +311,8 @@
|
||||
"0": {
|
||||
"formula": "1d20 + @c.calc.stats.spellCasting + @i.bonus",
|
||||
"type": "ew",
|
||||
"label": "Zaubern"
|
||||
"label": "Zaubern",
|
||||
"enabled": true
|
||||
}
|
||||
},
|
||||
"output": ""
|
||||
|
||||
Reference in New Issue
Block a user