diff --git a/modules/pegasus-actor-sheet.js b/modules/pegasus-actor-sheet.js index 3bc3840..7d79568 100644 --- a/modules/pegasus-actor-sheet.js +++ b/modules/pegasus-actor-sheet.js @@ -5,6 +5,7 @@ import { PegasusUtility } from "./pegasus-utility.js"; import { PegasusItemSheet } from "./pegasus-item-sheet.js"; +import { PegasusRollDialog } from "./pegasus-roll-dialog.js"; /* -------------------------------------------- */ export class PegasusActorSheet extends ActorSheet { @@ -68,6 +69,17 @@ export class PegasusActorSheet extends ActorSheet { return formData; } + /* -------------------------------------------- */ + async openGenericRoll() { + let rollData = PegasusUtility.getBasicRollData() + rollData.alias = "Dice Pool Roll", + rollData.mode = "generic" + rollData.title = `Dice Pool Roll`; + + let rollDialog = await PegasusRollDialog.create( this.actor, rollData); + rollDialog.render( true ); + } + /* -------------------------------------------- */ /** @override */ activateListeners(html) { @@ -75,6 +87,10 @@ export class PegasusActorSheet extends ActorSheet { // Everything below here is only needed if the sheet is editable if (!this.options.editable) return; + + html.bind("keydown", function(e) { // Ignore Enter in actores sheet + if (e.keyCode === 13) return false; + }); // Update Inventory Item html.find('.item-edit').click(ev => { @@ -120,6 +136,9 @@ export class PegasusActorSheet extends ActorSheet { html.find('.unarmed-attack').click((event) => { this.actor.rollUnarmedAttack(); }); + html.find('.generic-pool-roll').click((event) => { + this.openGenericRoll() + } ); html.find('.attack-melee').click((event) => { this.actor.rollPool( 'com'); }); @@ -227,6 +246,7 @@ export class PegasusActorSheet extends ActorSheet { async _onDropItem(event, dragData) { let item = await PegasusUtility.searchItem( dragData) this.actor.preprocessItem( event, item, true ) + super._onDropItem(event, dragData) } /* -------------------------------------------- */ diff --git a/modules/pegasus-actor.js b/modules/pegasus-actor.js index 06167cc..aa2ce23 100644 --- a/modules/pegasus-actor.js +++ b/modules/pegasus-actor.js @@ -66,10 +66,6 @@ export class PegasusActor extends Actor { for (let key in this.data.data.statistics) { let attr = this.data.data.statistics[key]; } - /*if ( h != this.data.data.secondary.health.max) { - this.data.data.secondary.health.max = h; - updates.push( {'data.secondary.health.max': h} ); - }*/ if (updates.length > 0) { this.update(updates); } @@ -262,11 +258,11 @@ export class PegasusActor extends Actor { this.applyRace(item.data) } else if ( item.data.type == 'ability') { this.applyAbility(item.data, [], true) - await this.createEmbeddedDocuments('Item', [item.data] ) + if ( !onDrop) { + await this.createEmbeddedDocuments('Item', [item.data] ) + } } else { - if ( onDrop) { - await super._onDropItem(event, dragData) - } else { + if ( !onDrop) { await this.createEmbeddedDocuments('Item', [item.data] ) } } @@ -428,6 +424,16 @@ export class PegasusActor extends Actor { //console.log("UPD", updates, this.data.data.biodata) await this.update(updates) } + + // Update current hindrance level + let hindrance = this.data.data.combat.hindrancedice + if ( this.data.data.secondary.health.value < 0) { + hindrance += Math.abs(this.data.data.secondary.health.value) + } + if ( this.data.data.secondary.delirium.value < 0) { + hindrance += Math.abs(this.data.data.secondary.delirium.value) + } + this.data.data.combat.hindrancedice = hindrance } /* -------------------------------------------- */ @@ -470,17 +476,63 @@ export class PegasusActor extends Actor { } /* -------------------------------------------- */ - applyAbility(ability, updates = [], directUpdate = false) { + async applyAbility(ability, updates = [], directUpdate = false) { + // manage stat bonus if (ability.data.affectedstat != "notapplicable") { let stat = duplicate(this.data.data.statistics[ability.data.affectedstat]) - stat.value += parseInt(ability.data.statlevelincrease) - stat.mod += parseInt(ability.data.statmodifier) + stat.mod += Number(ability.data.statmodifier) updates[`data.statistics.${ability.data.affectedstat}`] = stat - if(directUpdate) { - this.update(updates) + } + // manage status bonus + if (ability.data.statusaffected != "notapplicable") { + if ( ability.data.statusaffected == 'nrg' ) { + let nrg = duplicate( this.data.data.nrg) + nrg.mod += Number(ability.data.statusmodifier) + updates[`data.nrg`] = nrg + } + if ( ability.data.statusaffected == 'health' ) { + let health = duplicate( this.data.data.secondary.health) + health.bonus += Number(ability.data.statusmodifier) + updates[`data.secondary.health`] = health + } + if ( ability.data.statusaffected == 'delirium' ) { + let delirium = duplicate( this.data.data.secondary.delirium) + delirium.bonus += Number(ability.data.statusmodifier) + updates[`data.secondary.delirium`] = delirium } } + if ( directUpdate ) { + await this.update(updates) + } + let newItems = [] + if (ability.data.effectsgained) { + for (let effect of ability.data.effectsgained) { + newItems.push(effect); + } + } + if (ability.data.powersgained) { + for (let power of ability.data.powersgained) { + newItems.push(power); + } + } + if (ability.data.specialisations) { + for (let spec of ability.data.specialisations) { + newItems.push(spec); + } + } + if (ability.data.attackgained) { + for (let weapon of ability.data.attackgained) { + newItems.push(weapon); + } + } + if (ability.data.armorgained) { + for (let armor of ability.data.armorgained) { + newItems.push(armor); + } + } + await this.createEmbeddedDocuments('Item', newItems) } + /* -------------------------------------------- */ async applyRace(race) { let updates = { 'data.biodata.racename': race.name } @@ -492,26 +544,11 @@ export class PegasusActor extends Actor { newItems.push(ability) this.applyAbility(ability, updates) } - if (race.data.powersgained) { - for (let power of race.data.powersgained) { + if (race.data.perksgained) { + for (let power of race.data.perks) { newItems.push(power); } } - if (race.data.specialisations) { - for (let spec of race.data.specialisations) { - newItems.push(spec); - } - } - if (race.data.attackgained) { - for (let weapon of race.data.attackgained) { - newItems.push(weapon); - } - } - if (race.data.armorgained) { - for (let armor of race.data.armorgained) { - newItems.push(armor); - } - } await this.update(updates) await this.createEmbeddedDocuments('Item', newItems) @@ -551,6 +588,9 @@ export class PegasusActor extends Actor { if (this.data.data.combat.stunlevel > 0) { 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 } ) + } let effects = this.data.items.filter( item => item.type == 'effect' ) for( let effect of effects) { effect = duplicate(effect) @@ -576,6 +616,7 @@ export class PegasusActor extends Actor { } } } + /* -------------------------------------------- */ addArmorsShields( rollData, statKey = "none", useShield = false) { if (statKey == 'phy') { diff --git a/modules/pegasus-commands.js b/modules/pegasus-commands.js index 174bd1a..54995cb 100644 --- a/modules/pegasus-commands.js +++ b/modules/pegasus-commands.js @@ -68,11 +68,14 @@ export class PegasusCommands { return this.process(command, params, content, msg); } + /* -------------------------------------------- */ process(command, params, content, msg) { return this._processCommand(this.commandsTable, command, params, content, msg); } + /* -------------------------------------------- */ _processCommand(commandsTable, name, params, content = '', msg = {}, path = "") { + console.log("===> Processing command") let command = commandsTable[name]; path = path + name + " "; if (command && command.subTable) { diff --git a/modules/pegasus-item-sheet.js b/modules/pegasus-item-sheet.js index 9ad76c3..177d9f8 100644 --- a/modules/pegasus-item-sheet.js +++ b/modules/pegasus-item-sheet.js @@ -288,6 +288,16 @@ export class PegasusItemSheet extends ItemSheet { await this.object.update( { 'data.powersgained': powArray} ); } } + /* -------------------------------------------- */ + async addAbilityEffect( event, item, dataItem) { + let newItem = duplicate(item.data); + newItem._id = randomID( dataItem.id.length ); + if ( event.toElement.className == 'drop-ability-effect') { + let powArray = duplicate(this.object.data.data.effectsgained); + powArray.push( newItem ); + await this.object.update( { 'data.effectsgained': powArray} ); + } + } /* -------------------------------------------- */ async addAbilitySpec( event, item, dataItem) { @@ -399,6 +409,9 @@ export class PegasusItemSheet extends ItemSheet { if (data) { let dataItem = JSON.parse( data ); let item = await PegasusUtility.searchItem( dataItem); + if ( item.data.type == 'effect') { + return this.addAbilityEffect( event, item, dataItem); + } if ( item.data.type == 'power') { return this.addAbilityPower( event, item, dataItem); } diff --git a/packs/armour.db b/packs/armour.db index 30d5363..75f4f11 100644 --- a/packs/armour.db +++ b/packs/armour.db @@ -7,5 +7,6 @@ {"_id":"d92lH69S6ugOjEQy","name":"Fur","type":"armor","img":"systems/fvtt-pegasus-rpg/images/icons/icon_armour.webp","data":{"statistic":"phy","resistance":1,"weight":2,"cost":20,"idr":"2","equipped":false,"locationprotected":"","description":"
See Pegasus Engine CORE RPG
"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"iNL4aGohJ8v6YrUk":3},"flags":{}} {"_id":"h9swQ88G0dFG4wYu","name":"Tactical Suit","type":"armor","img":"systems/fvtt-pegasus-rpg/images/icons/icon_armour.webp","data":{"statistic":"phy","resistance":9,"weight":15,"cost":3000,"idr":"5","equipped":false,"locationprotected":"","description":"See Pegasus Engine CORE RPG
"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"iNL4aGohJ8v6YrUk":3},"flags":{}} {"_id":"m8nK6govnj9WMGSs","name":"Vac Suit","type":"armor","img":"systems/fvtt-pegasus-rpg/images/icons/icon_armour.webp","data":{"statistic":"phy","resistance":4,"weight":25,"cost":10000,"idr":"4","equipped":false,"locationprotected":"","description":"See Pegasus Engine CORE RPG
"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"iNL4aGohJ8v6YrUk":3},"flags":{}} +{"_id":"nEu11KzIsSfxzGia","name":"Metal Body","type":"armor","img":"systems/fvtt-pegasus-rpg/images/icons/icon_armour.webp","data":{"statistic":"phy","resistance":2,"weight":0,"cost":0,"idr":"0","equipped":false,"locationprotected":"All","description":""},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"iNL4aGohJ8v6YrUk":3},"flags":{"core":{"sourceId":"Item.nEu11KzIsSfxzGia"}}} {"_id":"wrJGYuvfKlrL6fv7","name":"Bronze Armour","type":"armor","img":"systems/fvtt-pegasus-rpg/images/icons/icon_armour.webp","data":{"statistic":"phy","resistance":4,"weight":20,"cost":1000,"idr":"5","equipped":false,"locationprotected":"","description":"See Pegasus Engine CORE RPG
"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"iNL4aGohJ8v6YrUk":3},"flags":{}} {"_id":"y0GPi66JRLx4qlUr","name":"Flak Vest","type":"armor","img":"systems/fvtt-pegasus-rpg/images/icons/icon_armour.webp","data":{"statistic":"phy","resistance":4,"weight":20,"cost":500,"idr":"4","equipped":false,"locationprotected":"","description":"See Pegasus Engine CORE RPG
"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"iNL4aGohJ8v6YrUk":3},"flags":{}} diff --git a/packs/racial-abilities.db b/packs/racial-abilities.db index e804ee3..d4ef69d 100644 --- a/packs/racial-abilities.db +++ b/packs/racial-abilities.db @@ -1,5 +1,5 @@ {"_id":"0DEuUiseNrqMtkpH","name":"Cybernetic Senses","type":"ability","img":"systems/fvtt-pegasus-rpg/images/icons/icon_raceability.webp","data":{"affectedstat":"per","statmodifier":1,"statlevelincrease":0,"bonusdice":0,"otherdice":0,"statusaffected":"notapplicable","statusmodifier":0,"powersgained":[],"specialisations":[],"aoe":"","affectedcircumstances":"","affectedspecialisations":"","nrgcost":1,"opponenthindrance":0,"attackgained":[],"armorgained":[],"description":"See Pegasus Engine CORE RPG
"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"iNL4aGohJ8v6YrUk":3},"flags":{}} -{"_id":"0bW374Onk2LEUKNO","name":"Metal Body","type":"ability","img":"systems/fvtt-pegasus-rpg/images/icons/icon_raceability.webp","data":{"affectedstat":"notapplicable","statmodifier":0,"statlevelincrease":0,"bonusdice":0,"otherdice":2,"statusaffected":"notapplicable","statusmodifier":0,"powersgained":[],"specialisations":[],"aoe":"","description":"See Pegasus Engine CORE RPG
"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"iNL4aGohJ8v6YrUk":3},"flags":{}} +{"_id":"0bW374Onk2LEUKNO","name":"Metal Body","type":"ability","img":"systems/fvtt-pegasus-rpg/images/icons/icon_raceability.webp","data":{"affectedstat":"notapplicable","statmodifier":0,"statlevelincrease":0,"bonusdice":0,"otherdice":2,"statusaffected":"notapplicable","statusmodifier":0,"powersgained":[],"specialisations":[],"aoe":"","affectedcircumstances":"","affectedspecialisations":"","nrgcost":0,"opponenthindrance":0,"attackgained":[],"armorgained":[{"_id":"y3aravy7qqveefeg","name":"Metal Body","type":"armor","img":"systems/fvtt-pegasus-rpg/images/icons/icon_armour.webp","data":{"statistic":"phy","resistance":2,"weight":0,"cost":0,"idr":"0","equipped":false,"locationprotected":"All","description":""},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"iNL4aGohJ8v6YrUk":3},"flags":{"core":{"sourceId":"Item.nEu11KzIsSfxzGia"}}}],"description":"See Pegasus Engine CORE RPG
"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"iNL4aGohJ8v6YrUk":3},"flags":{}} {"_id":"1y6qo5dvemTXe6JF","name":"Perception [PER] +2 Modifier","type":"ability","img":"systems/fvtt-pegasus-rpg/images/icons/icon_raceability.webp","data":{"affectedstat":"per","statmodifier":2,"statlevelincrease":0,"bonusdice":0,"otherdice":0,"statusaffected":"notapplicable","statusmodifier":0,"powersgained":[],"specialisations":[],"aoe":"","description":"Change the Stat Modifier to reflect the Statistic Modifier (+/- 1 etc).
"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"iNL4aGohJ8v6YrUk":3},"flags":{}} {"_id":"2XbpJr3oIIdXBQDX","name":"Red Eyes","type":"ability","img":"systems/fvtt-pegasus-rpg/images/icons/icon_raceability.webp","data":{"affectedstat":"notapplicable","statmodifier":0,"statlevelincrease":0,"bonusdice":0,"otherdice":0,"statusaffected":"notapplicable","statusmodifier":0,"powersgained":[],"specialisations":[],"aoe":"","description":"See Pegasus Engine CORE RPG
"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"iNL4aGohJ8v6YrUk":3},"flags":{}} {"_id":"3cq8bAvKZVewpPi0","name":"Strength [STR] +3 Modifier","type":"ability","img":"systems/fvtt-pegasus-rpg/images/icons/icon_raceability.webp","data":{"affectedstat":"str","statmodifier":3,"statlevelincrease":0,"bonusdice":0,"otherdice":0,"statusaffected":"notapplicable","statusmodifier":0,"powersgained":[],"specialisations":[],"aoe":"","description":"Change the Stat Modifier to reflect the Statistic Modifier (+/- 1 etc).
"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"iNL4aGohJ8v6YrUk":3},"flags":{}} diff --git a/styles/simple.css b/styles/simple.css index d6cd123..baa299e 100644 --- a/styles/simple.css +++ b/styles/simple.css @@ -1163,6 +1163,7 @@ ul, li { .ul-level1 { padding-left: 2rem; } +.drop-ability-effect, .drop-effect-specaffected, .drop-effect-spec, .drop-ability-weapon, diff --git a/system.json b/system.json index 06c83e9..76992a0 100644 --- a/system.json +++ b/system.json @@ -180,9 +180,9 @@ "styles": [ "styles/simple.css" ], - "templateVersion": 64, + "templateVersion": 66, "title": "Pegasus RPG", "url": "https://www.uberwald.me/data/files/fvtt-pegasus-rpg", - "version": "0.3.0", + "version": "0.4.0", "background" : "./images/ui/pegasus_welcome_page.webp" } diff --git a/template.json b/template.json index 0038df0..202167c 100644 --- a/template.json +++ b/template.json @@ -229,15 +229,14 @@ "description": "" }, "ability": { - "affectedstat": "", - "statmodifier": 0, - "statlevelincrease": 0, - "bonusdice": 0, - "otherdice": 0, + "affectedstat": "str", + "statmodifier": 1, + "statlevelincrease": 0, "statusaffected": "", "statusmodifier": 0, "powersgained": [], "specialisations": [], + "effectsgained": [], "aoe": "", "affectedcircumstances": "", "affectedspecialisations": "", diff --git a/templates/actor-sheet.html b/templates/actor-sheet.html index a438a36..2ae4e0f 100644 --- a/templates/actor-sheet.html +++ b/templates/actor-sheet.html @@ -5,7 +5,9 @@