diff --git a/modules/pegasus-actor-sheet.js b/modules/pegasus-actor-sheet.js index 6f6fe23..bf06954 100644 --- a/modules/pegasus-actor-sheet.js +++ b/modules/pegasus-actor-sheet.js @@ -366,8 +366,10 @@ export class PegasusActorSheet extends ActorSheet { if (item == undefined) { item = this.actor.items.get( dragData.data._id ) } - this.actor.preprocessItem( event, item, true ) - super._onDropItem(event, dragData) + let ret = await this.actor.preprocessItem( event, item, true ) + if ( ret ) { + super._onDropItem(event, dragData) + } } /* -------------------------------------------- */ diff --git a/modules/pegasus-actor.js b/modules/pegasus-actor.js index 0731212..ab563de 100644 --- a/modules/pegasus-actor.js +++ b/modules/pegasus-actor.js @@ -5,6 +5,11 @@ import { PegasusRollDialog } from "./pegasus-roll-dialog.js"; /* -------------------------------------------- */ const coverBonusTable = { "nocover": 0, "lightcover": 2, "heavycover": 4, "entrenchedcover": 6 }; const statThreatLevel = ["agi", "str", "phy", "com", "def", "per"] +const __subkey2title = { + "melee-dmg": "Melee Damage", "melee-atk": "Melee Attack", "ranged-atk": "Ranged Attack", + "ranged-dmg": "Ranged Damage", "dmg-res": "Damare Resistance" +} + /* -------------------------------------------- */ /* -------------------------------------------- */ /** @@ -516,7 +521,6 @@ export class PegasusActor extends Actor { async addObjectToContainer(itemId, containerId) { let container = this.data.items.find(item => item.id == containerId && item.data.data.iscontainer) let object = this.data.items.find(item => item.id == itemId) - console.log("Found", container, object) if (container) { if (object.data.data.iscontainer) { ui.notifications.warn("Only 1 level of container allowed") @@ -534,10 +538,35 @@ export class PegasusActor extends Actor { await this.updateEmbeddedDocuments("Item", [{ _id: object.id, 'data.containerid': "" }]); } } + /* -------------------------------------------- */ + checkVirtue( virtue) { + let vices = this.getVices() + for (let vice of vices) { + let nonVirtues = vice.data.data.unavailablevirtue + for (let blockedVirtue of nonVirtues) { + if (blockedVirtue.name.toLowerCase() == virtue.name.toLowerCase()) { + return false + } + } + } + return true + } + /* -------------------------------------------- */ + checkVice( vice) { + let virtues = this.getVirtues() + for (let virtue of virtues) { + let nonVices = virtue.data.data.unavailablevice + for (let blockedVice of nonVices) { + if (blockedVice.name.toLowerCase() == vice.name.toLowerCase()) { + return false + } + } + } + return true + } /* -------------------------------------------- */ async preprocessItem(event, item, onDrop = false) { - console.log("Pre-process !!!", item) if (item.data.type == 'race') { this.applyRace(item.data) } else if (item.data.type == 'role') { @@ -546,18 +575,30 @@ export class PegasusActor extends Actor { this.applyAbility(item.data, [], true) if (!onDrop) { await this.createEmbeddedDocuments('Item', [item.data]) - return } } else { if (!onDrop) { await this.createEmbeddedDocuments('Item', [item.data]) - return } } + // Check virtue/vice validity + if ( item.data.type == "virtue") { + if ( !this.checkVirtue(item) ) { + ui.notifications.info("Virtue is not allowed due to Vice.") + return false + } + } + if ( item.data.type == "vice") { + if ( !this.checkVice(item) ) { + ui.notifications.info("Vice is not allowed due to Virtue.") + return false + } + } let dropID = $(event.target).parents(".item").attr("data-item-id") // Only relevant if container drop let objectID = item.id || item._id this.addObjectToContainer(objectID, dropID) + return true } /* -------------------------------------------- */ @@ -890,11 +931,12 @@ export class PegasusActor extends Actor { /* -------------------------------------------- */ getTraumaState() { this.traumaState = "none" + let negDelirium = -Math.floor((this.data.data.secondary.delirium.max + 1) / 2) if (this.type == "character") { - if (this.data.data.secondary.delirium.value >= 0 && this.data.data.secondary.delirium.value <= Math.floor((this.data.data.secondary.delirium.max + 1) / 2)) { + if (this.data.data.secondary.delirium.value <= 0 && this.data.data.secondary.delirium.value >= negDelirium) { this.traumaState = "trauma" } - if (this.data.data.secondary.delirium.value < 0) { + if (this.data.data.secondary.delirium.value < negDelirium) { this.traumaState = "severetrauma" } } @@ -1174,7 +1216,7 @@ export class PegasusActor extends Actor { effectsList.push({ label: "Stun Hindrance", type: "hindrance", applied: false, value: this.data.data.combat.stunlevel }) } if (this.data.data.combat.hindrancedice > 0) { - effectsList.push({ label: "Health/Delirium Hindrance", type: "hindrance", applied: false, value: this.data.data.combat.hindrancedice }) + effectsList.push({ label: "Wounds Hindrance", type: "hindrance", applied: false, value: this.data.data.combat.hindrancedice }) } let overCapacity = Math.floor(this.encCurrent / this.getEncumbranceCapacity()) if (overCapacity > 0) { @@ -1220,13 +1262,13 @@ export class PegasusActor extends Actor { if (statKey == 'phy') { let armors = this.getArmors() for (let armor of armors) { - rollData.armorsList.push({ label: `Armor ${armor.name}`, type: "other", applied: false, value: armor.data.resistance }) + rollData.armorsList.push({ label: `Armor ${armor.name}`, type: "armor", applied: false, value: armor.data.resistance }) } } if (useShield) { let shields = this.data.items.filter(item => item.type == "shield" && item.data.data.equipped) for (let sh of shields) { - rollData.armorsList.push({ label: `Shield ${sh.name}`, type: "other", applied: false, value: sh.data.data.level }) + rollData.armorsList.push({ label: `Shield ${sh.name}`, type: "shield", applied: false, value: sh.data.data.level }) } } } @@ -1234,13 +1276,13 @@ export class PegasusActor extends Actor { let weapons = this.getWeapons() for (let weapon of weapons) { if (weapon.data.equipped && weapon.data.statistic == statKey) { - rollData.weaponsList.push({ label: `Attack ${weapon.name}`, type: "attack", applied: false, weapon: weapon, value: 0 }) + rollData.weaponsList.push({ label: `Attack ${weapon.name}`, type: "attack", applied: false, weapon: weapon, value: 0, damageDice: PegasusUtility.getDiceFromLevel(0) }) } if (weapon.data.equipped && weapon.data.enhanced && weapon.data.enhancedstat == statKey) { - rollData.weaponsList.push({ label: `Enhanced Attack ${weapon.name}`, type: "enhanced", applied: false, weapon: weapon, value: weapon.data.enhancedlevel }) + rollData.weaponsList.push({ label: `Enhanced Attack ${weapon.name}`, type: "enhanced", applied: false, weapon: weapon, value: weapon.data.enhancedlevel, damageDice: PegasusUtility.getDiceFromLevel(weapon.data.enhancedlevel) }) } if (weapon.data.equipped && weapon.data.damagestatistic == statKey) { - rollData.weaponsList.push({ label: `Damage ${weapon.name}`, type: "damage", applied: false, weapon: weapon, value: weapon.data.damage }) + rollData.weaponsList.push({ label: `Damage ${weapon.name}`, type: "damage", applied: false, weapon: weapon, value: weapon.data.damage, damageDice: PegasusUtility.getDiceFromLevel(weapon.data.damage) }) } } } @@ -1328,7 +1370,11 @@ export class PegasusActor extends Actor { let rollData = this.getCommonRollData(statKey, useShield) rollData.mode = "stat" rollData.subKey = subKey - rollData.title = `Roll : ${stat.label} ` + let def = stat.label + if (subKey) { + def = __subkey2title[subKey] + } + rollData.title = `Roll : ${def} ` rollData.img = "icons/dice/d12black.svg" if (subKey == "melee-dmg" || subKey == "ranged-dmg" || subKey == "power-dmg") { rollData.isDamage = true diff --git a/modules/pegasus-item-sheet.js b/modules/pegasus-item-sheet.js index 145ac07..3ae817c 100644 --- a/modules/pegasus-item-sheet.js +++ b/modules/pegasus-item-sheet.js @@ -391,10 +391,65 @@ export class PegasusItemSheet extends ItemSheet { await this.object.update({ 'data.effects': effectArray }); } } + /* -------------------------------------------- */ + async addEffectVirtueVice(event, item, dataItem) { + let newItem = duplicate(item.data); + if (event.toElement.className == 'drop-virtue-vice-effect') { + let effectArray = duplicate(this.object.data.data.effectsgained); + effectArray.push(newItem); + await this.object.update({ 'data.effectsgained': effectArray }); + } + } + /* -------------------------------------------- */ + async addViceToVirtue(event, item, dataItem) { + let newItem = duplicate(item.data); + if (event.toElement.className == 'drop-virtue-vice') { + let viceArray = duplicate(this.object.data.data.unavailablevice); + viceArray.push(newItem); + await this.object.update({ 'data.unavailablevice': viceArray }); + } + } + /* -------------------------------------------- */ + async addVirtueToVice(event, item, dataItem) { + let newItem = duplicate(item.data); + if (event.toElement.className == 'drop-vice-virtue') { + let virtueArray = duplicate(this.object.data.data.unavailablevirtue); + virtueArray.push(newItem); + await this.object.update({ 'data.unavailablevirtue': virtueArray }); + } + } + /* -------------------------------------------- */ async _onDrop(event) { + if (this.object.type == 'virtue' ) { + let data = event.dataTransfer.getData('text/plain'); + if (data) { + let dataItem = JSON.parse(data); + let item = await PegasusUtility.searchItem(dataItem); + if (item.data.type == 'effect') { + return this.addEffectVirtueVice(event, item, dataItem); + } + if (item.data.type == 'vice') { + return this.addViceToVirtue(event, item, dataItem); + } + } + } + if (this.object.type == 'vice' ) { + let data = event.dataTransfer.getData('text/plain'); + if (data) { + let dataItem = JSON.parse(data); + let item = await PegasusUtility.searchItem(dataItem); + if (item.data.type == 'effect') { + return this.addEffectVirtueVice(event, item, dataItem); + } + if (item.data.type == 'virtue') { + return this.addVirtueToVice(event, item, dataItem); + } + } + } + if (this.object.type == 'weapon' || this.object.type == 'armor' || this.object.type == 'shield' || this.object.type == 'equipment') { let data = event.dataTransfer.getData('text/plain'); diff --git a/modules/pegasus-roll-dialog.js b/modules/pegasus-roll-dialog.js index 8d5058e..396b043 100644 --- a/modules/pegasus-roll-dialog.js +++ b/modules/pegasus-roll-dialog.js @@ -49,11 +49,6 @@ export class PegasusRollDialog extends Dialog { effect.applied = toggled let level, genre, idVal, key - if (effect.type == 'hindrance') { - level = effect.value - genre = 'positive' - idVal = "#hindranceDicesLevel" - } if (effect.type == 'effect') { let effectData = effect.effect level = effectData.data.effectlevel @@ -63,15 +58,6 @@ export class PegasusRollDialog extends Dialog { idVal = "#statDicesLevel" key = "statLevelBonus" } - if (effectData.data.otherdice) { - idVal = "#damageDiceLevel" - key = "damageLevelBonus" - } - if (effectData.data.hindrance) { - idVal = "#hindranceDicesLevel" - genre = 'positive' // Dynamic fix - key = "hindranceLevelBonus" - } } // Now process the dice level update if (idVal) { @@ -99,13 +85,10 @@ export class PegasusRollDialog extends Dialog { } //console.log("Effect", effect, toggled) this.rollData.statDicesLevel = Number($('#statDicesLevel').val()) - this.rollData.specDicesLevel = Number($('#specDicesLevel').val()) - //this.rollData.bonusDicesLevel = Number($('#bonusDicesLevel').val()) - //this.rollData.hindranceDicesLevel = Number($('#hindranceDicesLevel').val()) - this.rollData.damageDiceLevel = Number($('#damageDiceLevel').val()) PegasusUtility.updateSpecDicePool(this.rollData) PegasusUtility.updateDamageDicePool(this.rollData) PegasusUtility.updateEffectsBonusDice(this.rollData) + PegasusUtility.updateHindranceBonusDice(this.rollData) } /* -------------------------------------------- */ @@ -113,17 +96,9 @@ export class PegasusRollDialog extends Dialog { let armor = this.rollData.armorsList[armorIdx] if (armor) { armor.applied = toggled - if (armor.type == 'other') { - if (toggled) { - this.rollData.otherDicesLevel += Number(armor.value) - } else { - this.rollData.otherDicesLevel -= Number(armor.value) - this.rollData.otherDicesLevel = (this.rollData.otherDicesLevel < 0) ? 0 : this.rollData.otherDicesLevel - } - $("#otherDicesLevel").val(this.rollData.otherDicesLevel) - } } console.log("Armor", armorIdx, toggled) + PegasusUtility.updateArmorDicePool(this.rollData) } /* -------------------------------------------- */ @@ -136,18 +111,9 @@ export class PegasusRollDialog extends Dialog { this.rollData.weaponName = undefined } weapon.applied = toggled - if (weapon.type == 'damage' || weapon.type == 'enhanced') { - if (toggled) { - this.rollData.otherDicesLevel += Number(weapon.value) - } else { - this.rollData.weaponName = undefined - this.rollData.otherDicesLevel -= Number(weapon.value) - this.rollData.otherDicesLevel = (this.rollData.otherDicesLevel < 0) ? 0 : this.rollData.otherDicesLevel - } - $("#otherDicesLevel").val(this.rollData.otherDicesLevel) - } } - console.log("Weapon", weaponIdx, toggled, this.rollData.otherDicesLevel, weapon) + console.log("Weapon", weaponIdx, toggled, weapon) + PegasusUtility.updateDamageDicePool(this.rollData) } /* -------------------------------------------- */ @@ -178,7 +144,6 @@ export class PegasusRollDialog extends Dialog { this.rollData.specDicesLevel = Number($('#specDicesLevel').val()) this.rollData.bonusDicesLevel = Number($('#bonusDicesLevel').val()) this.rollData.hindranceDicesLevel = Number($('#hindranceDicesLevel').val()) - this.rollData.damageDiceLevel = Number($('#damageDiceLevel').val()) } } @@ -221,11 +186,6 @@ export class PegasusRollDialog extends Dialog { PegasusUtility.updateSpecDicePool(this.rollData) this.refreshDialog() }); - html.find('#damageDiceLevel').change(async (event) => { - this.rollData.damageDiceLevel = Number(event.currentTarget.value) - PegasusUtility.updateDamageDicePool(this.rollData) - this.refreshDialog() - }); html.find('.effect-clicked').change(async (event) => { let toggled = event.currentTarget.checked let effectIdx = $(event.currentTarget).data("effect-idx") @@ -236,11 +196,13 @@ export class PegasusRollDialog extends Dialog { let toggled = event.currentTarget.checked let armorIdx = $(event.currentTarget).data("armor-idx") this.manageArmors(armorIdx, toggled) + this.refreshDialog() }); html.find('.weapon-clicked').change((event) => { let toggled = event.currentTarget.checked let weaponIdx = $(event.currentTarget).data("weapon-idx") this.manageWeapons(weaponIdx, toggled) + this.refreshDialog() }); html.find('.equip-clicked').change((event) => { let toggled = event.currentTarget.checked diff --git a/modules/pegasus-utility.js b/modules/pegasus-utility.js index 47bfa56..19278d8 100644 --- a/modules/pegasus-utility.js +++ b/modules/pegasus-utility.js @@ -66,36 +66,75 @@ export class PegasusUtility { } /* -------------------------------------------- */ - static updateEffectsBonusDice( rollData) { + static updateEffectsBonusDice(rollData) { let newDicePool = rollData.dicePool.filter(dice => dice.name != "effect-bonus-dice") for (let effect of rollData.effectsList) { - if (effect && effect.applied && effect.effect.data.bonusdice) { + if (effect && effect.applied && effect.type == "effect" && effect.effect.data.bonusdice) { let diceKey = PegasusUtility.getDiceFromLevel(effect.effect.data.effectlevel) let newDice = { name: "effect-bonus-dice", key: diceKey, level: effect.effect.data.effectlevel, effect: effect.effect.name, img: `systems/fvtt-pegasus-rpg/images/dice/${diceKey}.webp` } - newDicePool.push(newDice) + newDicePool.push(newDice) } } rollData.dicePool = newDicePool } /* -------------------------------------------- */ - static updateDamageDicePool(rollData) { - if (rollData.isDamage) { - let newDicePool = rollData.dicePool.filter(dice => dice.name != "damage") - if (rollData.damageDiceLevel > 0) { - let diceKey = PegasusUtility.getDiceFromLevel(rollData.damageDiceLevel) + static updateHindranceBonusDice(rollData) { + let newDicePool = rollData.dicePool.filter(dice => dice.name != "effect-hindrance") + for (let hindrance of rollData.effectsList) { + if (hindrance && hindrance.applied && hindrance.type == "hindrance") { + console.log("Manage Hindrance", hindrance) + let diceKey = PegasusUtility.getDiceFromLevel(hindrance.value) + let newDice = { + name: "effect-hindrance", key: diceKey, level: hindrance.value, effect: hindrance.name, + img: `systems/fvtt-pegasus-rpg/images/dice/${diceKey}.webp` + } + newDicePool.push(newDice) + } + } + rollData.dicePool = newDicePool + } + + /* -------------------------------------------- */ + static updateArmorDicePool(rollData) { + let newDicePool = rollData.dicePool.filter(dice => dice.name != "armor-shield" ) + for (let armor of rollData.armorsList) { + if (armor.applied ) { + let diceKey = PegasusUtility.getDiceFromLevel(armor.value) let diceList = diceKey.split(" ") - for(let myDice of diceList) { + for (let myDice of diceList) { let newDice = { - name: "damage", key: myDice, level: rollData.damageDiceLevel, + name: "armor-shield", key: myDice, level: armor.value, img: `systems/fvtt-pegasus-rpg/images/dice/${myDice}.webp` } newDicePool.push(newDice) } } + } + rollData.dicePool = newDicePool + } + + + /* -------------------------------------------- */ + static updateDamageDicePool(rollData) { + if (rollData.isDamage) { + let newDicePool = rollData.dicePool.filter(dice => dice.name != "damage") + for (let weapon of rollData.weaponsList) { + if (weapon.applied && weapon.type == "damage") { + let diceKey = PegasusUtility.getDiceFromLevel(weapon.value) + let diceList = diceKey.split(" ") + for (let myDice of diceList) { + let newDice = { + name: "damage", key: myDice, level: weapon.value, + img: `systems/fvtt-pegasus-rpg/images/dice/${myDice}.webp` + } + newDicePool.push(newDice) + } + } + } rollData.dicePool = newDicePool } } @@ -106,7 +145,7 @@ export class PegasusUtility { if (rollData.specDicesLevel > 0) { let diceKey = PegasusUtility.getDiceFromLevel(rollData.specDicesLevel) let diceList = diceKey.split(" ") - for(let myDice of diceList) { + for (let myDice of diceList) { let newDice = { name: "spec", key: myDice, level: rollData.specDicesLevel, img: `systems/fvtt-pegasus-rpg/images/dice/${myDice}.webp` @@ -125,21 +164,21 @@ export class PegasusUtility { } rollData.dicePool.push(newDice) } - + /*-------------------------------------------- */ - static removeFromDicePool( rollData, diceIdx ) { + static removeFromDicePool(rollData, diceIdx) { let toRemove = rollData.dicePool[diceIdx] if (toRemove && toRemove.name != "spec" && toRemove.name != "stat" && toRemove.name != "damage") { let newDicePool = [] - for (let i=0; i { let rollId = $(event.currentTarget).data("roll-id") let rollData = this.getRollData(rollId) - rollData.reroll = true - this.rollPegasus( rollData) + rollData.reroll = true + this.rollPegasus(rollData) }) - + } /* -------------------------------------------- */ @@ -461,7 +500,7 @@ export class PegasusUtility { game.socket.emit("system.pegasus-rpg", { name: "msg_update_roll", data: rollData }); // Notify all other clients of the roll - this.updateRollData(rollData) + this.updateRollData(rollData) } /* -------------------------------------------- */ @@ -568,9 +607,9 @@ export class PegasusUtility { // De-actived used effects from perks let toRem = [] for (let effect of rollData.effectsList) { - if (effect.effect.data.isUsed && effect.effect.data.oneuse) { + if (effect.effect && effect.effect.data.isUsed && effect.effect.data.oneuse) { toRem.push(effect.effect._id) - ChatMessage.create({content: `One used effect ${effect.effect.name} has been auto-deleted.`}) + ChatMessage.create({ content: `One used effect ${effect.effect.name} has been auto-deleted.` }) } } if (toRem.length > 0) { @@ -594,25 +633,25 @@ export class PegasusUtility { } /* -------------------------------------------- */ - static async showMomentumDialog( actorId) { + static async showMomentumDialog(actorId) { let d = new Dialog({ title: "Momentum reroll", content: "

Do you want to re-roll your last roll ?

", buttons: { - one: { - icon: '', - label: "Cancel", - callback: () => this.close() - }, - two: { - icon: '', - label: "Reroll", - callback: () => PegasusUtility.momentumReroll(actorId) - } + one: { + icon: '', + label: "Cancel", + callback: () => this.close() + }, + two: { + icon: '', + label: "Reroll", + callback: () => PegasusUtility.momentumReroll(actorId) + } }, default: "Reroll", - }) - d.render(true) + }) + d.render(true) } /* -------------------------------------------- */ @@ -663,10 +702,10 @@ export class PegasusUtility { let diceFormulaTab = [] for (let dice of rollData.dicePool) { let level = dice.level - if (dice.name == "stat" ) { + if (dice.name == "stat") { level += rollData.statLevelBonus } - diceFormulaTab.push( this.getFoundryDiceFromLevel(level) ) + diceFormulaTab.push(this.getFoundryDiceFromLevel(level)) } let diceFormula = '{' + diceFormulaTab.join(', ') + '}kh + ' + (rollData.stat?.mod || 0) @@ -702,7 +741,7 @@ export class PegasusUtility { // Stun specific -> Suffere a stun level when dmg-res if (rollData.subKey && rollData.subKey == "dmg-res") { - actor.modifyStun(-1) + actor.modifyStun(+1) } //this.removeUsedPerkEffects( rollData) // Unused for now diff --git a/styles/simple.css b/styles/simple.css index ed8cf0d..aabbb79 100644 --- a/styles/simple.css +++ b/styles/simple.css @@ -1215,6 +1215,9 @@ ul, li { .drop-specialability, .drop-abilities, .drop-optionnal-abilities, +.drop-virtue-vice-effect, +.drop-virtue-vice, +.drop-vice-virtue, .drop-specialperk1, .drop-perk2, .drop-spec1 , diff --git a/templates/chat-generic-result.html b/templates/chat-generic-result.html index 23ade78..26bb4ed 100644 --- a/templates/chat-generic-result.html +++ b/templates/chat-generic-result.html @@ -22,7 +22,7 @@
  • Power : {{power.name}}
  • {{/if}} {{#if isDamage}} -
  • Weapon Damage Dice : {{weapon.data.damageDice}}
  • +
  • Weapon Damage Dice : {{weaponDamageDice}}
  • {{/if}} {{#if isResistance}}
  • Armor Resistance Dice : {{armor.data.resistanceDice}}
  • diff --git a/templates/item-vice-sheet.html b/templates/item-vice-sheet.html index 0f0a984..b29414c 100644 --- a/templates/item-vice-sheet.html +++ b/templates/item-vice-sheet.html @@ -18,7 +18,7 @@