diff --git a/lang/en.json b/lang/en.json index 00b8d8f..dab5661 100644 --- a/lang/en.json +++ b/lang/en.json @@ -33,7 +33,7 @@ "WH.ui.hpprog": "HP Progression", "WH.ui.lan": "Languages", - "WH.ui.attrbonus": "Attribute (+4/Lvl4, +2/Lvl8)", + "WH.ui.attrbonus": "Attribute", "WH.ui.weapons": "Weapons", "WH.ui.armors": "Armors", "WH.ui.shields": "Shields", @@ -46,10 +46,13 @@ "WH.ui.Type": "Type", "WH.ui.HitPoints": "Hit Points", "WH.ui.Defence": "Defence", - "WH.ui.Throw2Hit": "Throw to Hit", + "WH.ui.Throw2HitM": "Throw to Hit (Melee)", + "WH.ui.Throw2HitR": "Throw to Hit (Ranged)", "WH.ui.Mana": "Mana", "WH.ui.Initiative": "Initiative", - "WH.ui.Movement": "Movement", + "WH.ui.Movement": "Movement (Earth)", + "WH.ui.MovementSwim": "Movement (Swim)", + "WH.ui.MovementFly": "Movement (Fly)", "WH.ui.power": "Power", "WH.ui.Qty": "Qty", @@ -57,5 +60,22 @@ "WH.ui.slotsused": "Slots used", "WH.ui.Damage": "Damage", "WH.ui.parrybonus": "Parry bonus", - "WH.ui.damagereduction": "Damage reduction" + "WH.ui.damagereduction": "Damage reduction", + "WH.ui.save": "Save", + "WH.ui.XP": "XP", + "WH.ui.xphp": "HP Progression", + "WH.ui.Knowledge": "Knowledge", + "WH.ui.malusmultiweapon": "Mult. Weapons malus", + "WH.ui.drbonus": "DR bonus", + "WH.ui.parrybonustotal": "Parry bonus total", + "WH.ui.drbonustotal": "DR bonus total", + "WH.ui.counterspell": "Counter spell", + "WH.ui.createitem": "Create item", + "WH.ui.classSkills": "Class Skills", + "WH.ui.skills": "Skills", + "WH.ui.isclassskill": "Class skill ?", + "WH.ui.unlimited": "Unlimited use ?", + "WH.ui.currentuse": "Current use", + "WH.ui.maxuse": "Max use", + "WH.ui.languages": "Languages" } \ No newline at end of file diff --git a/modules/warhero-actor-sheet.js b/modules/warhero-actor-sheet.js index b5a0832..585867f 100644 --- a/modules/warhero-actor-sheet.js +++ b/modules/warhero-actor-sheet.js @@ -24,7 +24,13 @@ export class WarheroActorSheet extends ActorSheet { /* -------------------------------------------- */ async getData() { + + this.actor.setLevel() + this.actor.computeDRTotal() + this.actor.computeParryBonusTotal() + this.actor.computeBonusLanguages() const objectData = duplicate(this.object.system) + let race = this.actor.getRace() let formData = { title: this.title, @@ -36,7 +42,9 @@ export class WarheroActorSheet extends ActorSheet { cssClass: this.isEditable ? "editable" : "locked", system: objectData, limited: this.object.limited, - skills: this.actor.getSkills( ), + skills: this.actor.getNormalSkills( ), + classSkills: this.actor.getClassSkills( ), + languages: this.actor.getLanguages( ), weapons: this.actor.checkAndPrepareEquipments( duplicate(this.actor.getWeapons()) ), armors: this.actor.checkAndPrepareEquipments( duplicate(this.actor.getArmors())), shields: this.actor.checkAndPrepareEquipments( duplicate(this.actor.getShields())), @@ -44,7 +52,7 @@ export class WarheroActorSheet extends ActorSheet { equipments: this.actor.checkAndPrepareEquipments(duplicate(this.actor.getEquipmentsOnly()) ), slotEquipments: this.actor.buildEquipmentsSlot(), subActors: duplicate(this.actor.getSubActors()), - race: duplicate(this.actor.getRace()), + race: duplicate(race), class: duplicate(this.actor.getClass()), moneys: duplicate(this.actor.getMoneys()), description: await TextEditor.enrichHTML(this.object.system.biodata.description, {async: true}), @@ -54,8 +62,10 @@ export class WarheroActorSheet extends ActorSheet { editScore: this.options.editScore, isGM: game.user.isGM } - this.formData = formData; - + if ( race && race.name) { + formData.hpprogression = game.system.warhero.config.progressionList[race.system.hpprogresion] + } + this.formData = formData console.log("PC : ", formData, this.object); return formData; } @@ -136,6 +146,11 @@ export class WarheroActorSheet extends ActorSheet { const statKey = $(event.currentTarget).data("key") this.actor.rollFromType(rollType, statKey) }); + html.find('.roll-save').click((event) => { + const rollType = $(event.currentTarget).data("type") + const statKey = $(event.currentTarget).data("key") + this.actor.rollSaveFromType(rollType, statKey) + }); html.find('.roll-weapon').click((event) => { const li = $(event.currentTarget).parents(".item") const weaponId = li.data("item-id") diff --git a/modules/warhero-actor.js b/modules/warhero-actor.js index 8fb4c96..e7d1915 100644 --- a/modules/warhero-actor.js +++ b/modules/warhero-actor.js @@ -170,7 +170,7 @@ export class WarheroActor extends Actor { && it.system.slotlocation == slotName ) let slotUsed = 0 for(let item of containers[slotName].content) { - slotUsed += item.system.slotused + slotUsed += item.system.slotused * ((item.system.quantity) ? item.system.quantity : 1) } containers[slotName].slotUsed = slotUsed } @@ -210,13 +210,25 @@ export class WarheroActor extends Actor { } return item; } - /* -------------------------------------------- */ + getLanguages() { + let comp = this.items.filter(it => it.type == "language") + WarheroUtility.sortArrayObjectsByName(comp) + return comp + } + /* -------------------------------------------- */ + getNormalSkills() { + let comp = this.items.filter(it => it.type == "skill" && !it.system.classskill) + WarheroUtility.sortArrayObjectsByName(comp) + return comp + } + getClassSkills() { + let comp = this.items.filter(it => it.type == "skill" && it.system.classskill) + WarheroUtility.sortArrayObjectsByName(comp) + return comp + } getSkills() { let comp = duplicate(this.items.filter(item => item.type == 'skill') || []) - for (let skill of comp) { - WarheroUtility.updateSkill(skill) - } WarheroUtility.sortArrayObjectsByName(comp) return comp } @@ -534,7 +546,33 @@ export class WarheroActor extends Actor { isAttackerAdvantage() { return this.items.find(cond => cond.type == "condition" && cond.system.targetadvantage) } - + /* -------------------------------------------- */ + setLevel() { + let xp = this.system.secondary.xp.value + this.system.secondary.xp.level = Math.floor(xp/10) + } + /* -------------------------------------------- */ + computeDRTotal() { + let armors = this.items.filter(it => it.type == "armor") + let dr = 0 + for (let armor of armors) { + dr += armor.system.damagereduction + } + this.system.secondary.drbonustotal.value = this.system.secondary.drbonus.value + dr + } + /* -------------------------------------------- */ + computeParryBonusTotal() { + let shields = this.items.filter(it => it.type == "shield") + let parry = 0 + for (let shield of shields) { + parry += shield.system.parrybonus + } + this.system.secondary.parrybonustotal.value = this.system.secondary.parrybonus.value + parry + } + /* -------------------------------------------- */ + computeBonusLanguages() { + this.system.secondary.nblanguage.value = Math.floor(this.system.statistics.min.value / 2) + } /* -------------------------------------------- */ spentMana( mana) { if ( Number(mana) > this.system.attributes.mana.value) { @@ -562,9 +600,21 @@ export class WarheroActor extends Actor { let rollData = this.getCommonRollData() rollData.mode = rollType rollData.stat = stat + if ( rollKey == "parrybonustotal") { + WarheroUtility.rollParry(rollData) + return + } this.startRoll(rollData) } - + /* -------------------------------------------- */ + rollSaveFromType(rollType, rollKey) { + let stat = duplicate(this.system[rollType][rollKey]) + let rollData = this.getCommonRollData() + rollData.mode = "save" + rollData.stat = stat + this.startRoll(rollData) + } + /* -------------------------------------------- */ rollWeapon(weaponId) { let weapon = this.items.get(weaponId) @@ -572,7 +622,13 @@ export class WarheroActor extends Actor { weapon = duplicate(weapon) let rollData = this.getCommonRollData() rollData.mode = "weapon" - rollData.stat = duplicate(this.system.statistics.dex) + if (weapon.system.weapontype ==="shooting" || weapon.system.weapontype ==="throwing") { + rollData.stat = duplicate(this.system.attributes.txcr) + } else { + rollData.stat = duplicate(this.system.attributes.txcm) + } + rollData.usemWeaponMalus = + rollData.mWeaponMalus = this.system.secondary.malusmultiweapon.value rollData.weapon = weapon rollData.img = weapon.img this.startRoll(rollData) diff --git a/modules/warhero-config.js b/modules/warhero-config.js index 9b5ffb0..02430d1 100644 --- a/modules/warhero-config.js +++ b/modules/warhero-config.js @@ -21,22 +21,22 @@ export const WARHERO_CONFIG = { }, slotNames : { - head: {nbslots: 1, label: "WH.conf.head"}, - cloak: {nbslots: 1, label: "WH.conf.cloak"}, - weapon1: {nbslots: 1, label: "WH.conf.weapon1"}, - weapon2: {nbslots: 1, label: "WH.conf.weapon2"}, - gloves: {nbslots: 1, label: "WH.conf.gloves"}, - ring: {nbslots: 10, label: "WH.conf.ring"}, - dress: {nbslots: 1, label: "WH.conf.dress"}, - boots: {nbslots: 1, label: "WH.conf.boots"}, - belt: {nbslots: 6, label: "WH.conf.belt"}, - quiver: {nbslots: 20, label: "WH.conf.quiver"}, - armor: {nbslots: 1, label: "WH.conf.armor"}, - shield: {nbslots: 1, label: "WH.conf.shield"}, - backpack: {nbslots: 12, label: "WH.conf.backpack"}, - beltpouch1: {nbslots: 4, label: "WH.conf.beltpouch1"}, - beltpouch2: {nbslots: 4, label: "WH.conf.beltpouch2"}, - beltpouch3: {nbslots: 4, label: "WH.conf.beltpouch3"}, + head: {nbslots: 1, itemtype:"armor", label: "WH.conf.head"}, + cloak: {nbslots: 1, itemtype:"equipment", label: "WH.conf.cloak"}, + weapon1: {nbslots: 1, itemtype:"weapon", label: "WH.conf.weapon1"}, + weapon2: {nbslots: 1, itemtype:"weapon", label: "WH.conf.weapon2"}, + gloves: {nbslots: 1, itemtype:"equipment",label: "WH.conf.gloves"}, + ring: {nbslots: 10, itemtype:"equipment",label: "WH.conf.ring"}, + dress: {nbslots: 1, itemtype:"equipment",label: "WH.conf.dress"}, + boots: {nbslots: 1, itemtype:"equipment",label: "WH.conf.boots"}, + belt: {nbslots: 6, itemtype:"equipment",label: "WH.conf.belt"}, + quiver: {nbslots: 20, itemtype:"equipment",label: "WH.conf.quiver"}, + armor: {nbslots: 1, itemtype:"armor",label: "WH.conf.armor"}, + shield: {nbslots: 1, itemtype:"shield",label: "WH.conf.shield"}, + backpack: {nbslots: 12, itemtype:"equipment",label: "WH.conf.backpack"}, + beltpouch1: {nbslots: 4, itemtype:"equipment",label: "WH.conf.beltpouch1"}, + beltpouch2: {nbslots: 4, itemtype:"equipment", label: "WH.conf.beltpouch2"}, + beltpouch3: {nbslots: 4, itemtype:"equipment", label: "WH.conf.beltpouch3"}, }, progressionList: { diff --git a/modules/warhero-item-sheet.js b/modules/warhero-item-sheet.js index a298a91..939ff93 100644 --- a/modules/warhero-item-sheet.js +++ b/modules/warhero-item-sheet.js @@ -49,9 +49,6 @@ export class WarheroItemSheet extends ItemSheet { /* -------------------------------------------- */ async getData() { - if ( this.object.type == "skill") { - WarheroUtility.updateSkill(this.object) - } let objectData = duplicate(this.object.system) let itemData = objectData @@ -66,6 +63,7 @@ export class WarheroItemSheet extends ItemSheet { config: game.system.warhero.config, description: await TextEditor.enrichHTML(this.object.system.description, {async: true}), system: itemData, + statistics: duplicate(game.system.template.Actor.templates.core.statistics), limited: this.object.limited, options: this.options, owner: this.document.isOwner, diff --git a/modules/warhero-roll-dialog.js b/modules/warhero-roll-dialog.js index da94df4..f641de9 100644 --- a/modules/warhero-roll-dialog.js +++ b/modules/warhero-roll-dialog.js @@ -5,7 +5,7 @@ export class WarheroRollDialog extends Dialog { /* -------------------------------------------- */ static async create(actor, rollData) { - let options = { classes: ["WarheroDialog"], width: 320, height: 'fit-content', 'z-index': 99999 }; + let options = { classes: ["WarheroDialog"], width: 420, height: 'fit-content', 'z-index': 99999 }; let html = await renderTemplate('systems/fvtt-warhero/templates/roll-dialog-generic.html', rollData); return new WarheroRollDialog(actor, rollData, html, options); @@ -64,6 +64,10 @@ export class WarheroRollDialog extends Dialog { html.find('#bonusMalus').change((event) => { this.rollData.bonusMalus = Number(event.currentTarget.value) }) + html.find('#usemWeaponMalus').change((event) => { + this.rollData.usemWeaponMalus = event.currentTarget.checked + }) + } } \ No newline at end of file diff --git a/modules/warhero-utility.js b/modules/warhero-utility.js index b1a117f..eac2f85 100644 --- a/modules/warhero-utility.js +++ b/modules/warhero-utility.js @@ -208,23 +208,6 @@ export class WarheroUtility { html.on("click", '.view-item-from-chat', event => { game.system.crucible.creator.openItemView(event) }) - html.on("click", '.roll-defense-melee', event => { - let rollId = $(event.currentTarget).data("roll-id") - let rollData = WarheroUtility.getRollData(rollId) - rollData.defenseWeaponId = $(event.currentTarget).data("defense-weapon-id") - let actor = game.canvas.tokens.get(rollData.defenderTokenId).actor - if (actor && (game.user.isGM || actor.isOwner)) { - actor.rollDefenseMelee(rollData) - } - }) - html.on("click", '.roll-defense-ranged', event => { - let rollId = $(event.currentTarget).data("roll-id") - let rollData = WarheroUtility.getRollData(rollId) - let defender = game.canvas.tokens.get(rollData.defenderTokenId).actor - if (defender && (game.user.isGM || defender.isOwner)) { - defender.rollDefenseRanged(rollData) - } - }) } @@ -319,11 +302,6 @@ export class WarheroUtility { this.updateRollData(rollData) } - /* -------------------------------------------- */ - static getRollData(id) { - return this.rollDataStore[id] - } - /* -------------------------------------------- */ static async displayDefenseMessage(rollData) { if (rollData.mode == "weapon" && rollData.defenderTokenId) { @@ -517,10 +495,6 @@ export class WarheroUtility { } } - /* -------------------------------------------- */ - static updateSkill(skill) { - } - /* -------------------------------------------- */ static getDiceFromCover(cover) { if (cover == "cover50") return 1 @@ -534,6 +508,30 @@ export class WarheroUtility { if (cover == "engaged") return 1 return 0 } + /* -------------------------------------------- */ + static async rollParry(rollData) { + let actor = game.actors.get(rollData.actorId) + // ability/save/size => 0 + let diceFormula = "1d12+" + rollData.stat.value + let myRoll = rollData.roll + if (!myRoll) { // New rolls only of no rerolls + myRoll = new Roll(diceFormula).roll({ async: false }) + await this.showDiceSoNice(myRoll, game.settings.get("core", "rollMode")) + } + rollData.roll = myRoll + rollData.isSuccess = false + if (myRoll.total >= 12 || myRoll.terms[0].results[0].result == 12) { + rollData.isSuccess = true + } + if (myRoll.terms[0].results[0].result == 1) { + rollData.isSuccess = false + } + let msg = await this.createChatWithRollMode(rollData.alias, { + content: await renderTemplate(`systems/fvtt-warhero/templates/chat-parry-result.html`, rollData) + }) + msg.setFlag("world", "rolldata", rollData) + console.log("Rolldata result", rollData) + } /* -------------------------------------------- */ static async rollWarhero(rollData) { @@ -569,6 +567,9 @@ export class WarheroUtility { if ( rollData.stat) { diceFormula += "+" + rollData.stat.value } + if ( rollData.usemWeaponMalus) { + diceFormula += "+" + rollData.mWeaponMalus + } diceFormula += "+" + rollData.bonusMalus rollData.diceFormula = diceFormula @@ -581,8 +582,6 @@ export class WarheroUtility { } rollData.roll = myRoll - actor.lastRoll = rollData - let msg = await this.createChatWithRollMode(rollData.alias, { content: await renderTemplate(`systems/fvtt-warhero/templates/chat-generic-result.html`, rollData) }) diff --git a/styles/simple.css b/styles/simple.css index 1624382..57106fe 100644 --- a/styles/simple.css +++ b/styles/simple.css @@ -562,8 +562,8 @@ .list-item { margin: 0.125rem; - box-shadow: inset 0px 0px 1px #00000096; - border-radius: 0.25rem; + /*box-shadow: inset 0px 0px 1px #00000096; + border-radius: 0.25rem;*/ padding: 0.125rem; flex: 1 1 5rem; display: flex !important; @@ -1388,6 +1388,9 @@ background: black; color: white; } + .items-title-bg-red { + background: darkred; + } .items-title-text { margin-left: 4px; } @@ -1465,8 +1468,8 @@ .item-field-label-vlong { flex-grow:1; margin-top: 4px; - max-width: 14rem; - min-width: 14rem; + max-width: 12rem; + min-width: 12rem; } .item-field-label-vlong2 { flex-grow:1; diff --git a/system.json b/system.json index 8ef098a..4266b1d 100644 --- a/system.json +++ b/system.json @@ -100,7 +100,7 @@ "styles": [ "styles/simple.css" ], - "version": "10.0.7", + "version": "10.0.18", "compatibility": { "minimum": "10", "verified": "10", @@ -108,7 +108,7 @@ }, "title": "Warhero RPG", "manifest": "https://www.uberwald.me/gitea/public/fvtt-warhero/raw/branch/master/system.json", - "download": "https://www.uberwald.me/gitea/uberwald/fvtt-warhero/archive/fvtt-warhero-10.0.7.zip", + "download": "https://www.uberwald.me/gitea/uberwald/fvtt-warhero/archive/fvtt-warhero-10.0.18.zip", "url": "https://www.uberwald.me/gitea/public/fvtt-warhero", "background": "images/ui/warhero_welcome_page.webp", "id": "fvtt-warhero" diff --git a/template.json b/template.json index a5827db..e884dc1 100644 --- a/template.json +++ b/template.json @@ -25,19 +25,28 @@ "str": { "label": "WH.ui.Strength", "abbrev": "str", - "style": "dropdown", + "style": "edit", + "hassave": true, + "roll": true, + "save": 0, "value": 0 }, "dex": { "label": "WH.ui.Dexterity", "abbrev": "dex", - "style": "dropdown", + "style": "edit", + "hassave": true, + "roll": true, + "save": 0, "value": 0 }, "min": { "label": "WH.ui.Mind", "abbrev": "min", - "style": "dropdown", + "style": "edit", + "hassave": true, + "roll": true, + "save": 0, "value": 0 } }, @@ -50,6 +59,15 @@ "max": 1, "value": 1 }, + "knowledge":{ + "label": "WH.ui.Knowledge", + "abbrev": "knowledge", + "style": "edit", + "hasmax": false, + "roll": true, + "max": 1, + "value": 1 + }, "def":{ "label": "WH.ui.Defence", "abbrev": "def", @@ -57,10 +75,21 @@ "max": 1, "value": 1 }, - "txc":{ - "label": "WH.ui.Throw2Hit", - "abbrev": "txc", + "txcm":{ + "label": "WH.ui.Throw2HitM", + "abbrev": "txcm", + "istxc": true, "style": "edit", + "roll": true, + "max": 1, + "value": 1 + }, + "txcr":{ + "label": "WH.ui.Throw2HitR", + "abbrev": "txcr", + "istxc": true, + "style": "edit", + "roll": true, "max": 1, "value": 1 }, @@ -75,16 +104,94 @@ "ini":{ "label": "WH.ui.Initiative", "abbrev": "ini", - "style": "dropdown", + "style": "edit", "max": 1, "value": 1 }, - "mov":{ + "movearth":{ "label": "WH.ui.Movement", "abbrev": "mov", - "style": "dropdown", + "style": "edit", "max": 1, "value": 1 + }, + "movswim":{ + "label": "WH.ui.MovementSwim", + "abbrev": "mov", + "style": "edit", + "max": 1, + "value": 1 + }, + "movfly":{ + "label": "WH.ui.MovementFly", + "abbrev": "mov", + "style": "edit", + "max": 1, + "value": 1 + } + }, + "secondary": { + "xp": { + "label": "WH.ui.XP", + "abbrev": "xp", + "islevel": true, + "style": "edit", + "value": 0 + }, + "malusmultiweapon": { + "label": "WH.ui.malusmultiweapon", + "abbrev": "malusmultiweapon", + "style": "edit", + "value": 0 + }, + "drbonus": { + "label": "WH.ui.drbonus", + "abbrev": "drbonus", + "style": "edit", + "value": 0 + }, + "drbonustotal": { + "label": "WH.ui.drbonustotal", + "abbrev": "drbonustotal", + "disabled": true, + "style": "edit", + "value": 0 + }, + "parrybonus": { + "label": "WH.ui.parrybonus", + "abbrev": "parrybonus", + "isparrybonus": true, + "style": "edit", + "value": 0 + }, + "parrybonustotal": { + "label": "WH.ui.parrybonustotal", + "abbrev": "parrybonustotal", + "disabled": true, + "style": "edit", + "roll": true, + "value": 0 + }, + "counterspell": { + "label": "WH.ui.counterspell", + "abbrev": "counterspell", + "style": "edit", + "hasmax": true, + "max": 1, + "value": 0 + }, + "createitem": { + "label": "WH.ui.createitem", + "abbrev": "createitem", + "style": "edit", + "value": 0 + }, + "nblanguage": { + "label": "WH.ui.languages", + "abbrev": "nblanguage", + "style": "edit", + "disabled": true, + "value": 0 } } }, @@ -101,40 +208,52 @@ } }, "Item": { - "types": [ "race", "weapon", "armor", "shield", "equipment", "money" , "skill", "power", "condition", "class"], + "types": [ "equipment", "race", "weapon", "armor", "shield", "money" , "skill", "power", "language", "condition", "class"], + "templates": { + "commonclassrace": { + "weapons": { + "short": false, + "long": false, + "twohanded": false, + "shotgun": false, + "throwing": false + }, + "armors": { + "light": false, + "medium": false, + "heavy": false + }, + "shields": { + "light": false, + "medium": false, + "tower": false + } + } + }, "condition": { "description": "" }, "class": { - "weapons": { - "short": false, - "long": false, - "twohanded": false, - "shotgun": false, - "throwing": false - }, - "armors": { - "light": false, - "medium": false, - "heavy": false - }, - "shields": { - "light": false, - "medium": false, - "tower": false - }, + "templates": ["commonclassrace"], "description": "" }, "race": { "description": "", "hpprogresion": "hp2", "languages": "", - "attributebonus": "", - "weapons": "", - "shields": "", - "armors": "" + "attributebonus1": "", + "attributebonus4": "", + "attributebonus8": "", + "templates": ["commonclassrace"] + }, + "language": { + "description": "" }, "skill": { + "classskill": false, + "unlimited": false, + "currentuse": 0, + "maxuse": 0, "description": "" }, "weapon": { diff --git a/templates/actor-sheet.html b/templates/actor-sheet.html index 63973a2..68864ea 100644 --- a/templates/actor-sheet.html +++ b/templates/actor-sheet.html @@ -12,32 +12,30 @@