Compare commits

..

9 Commits

Author SHA1 Message Date
241c7fa1ae Fix #6 Crew limits 2022-09-25 14:51:43 +02:00
857f36387a Fix #6 Crew limits 2022-09-25 14:45:02 +02:00
b185a3902d Fix #3 v10 fixes for processing embedded items 2022-09-25 14:26:18 +02:00
7d3f880633 Fix #1 for dropping items from compendium 2022-09-25 14:13:57 +02:00
7a1171b774 Vehicles enhancements 2022-09-25 09:26:12 +02:00
7a9ed39d02 Actor/Crew rolls 2022-09-21 16:58:02 +02:00
8345ee0ebb Actor/Crew rolls 2022-09-21 16:54:34 +02:00
343ac6ab9d NRG stuff 2022-09-18 17:30:15 +02:00
9a20a96cec Start vehicle automation 2022-09-16 17:36:58 +02:00
19 changed files with 895 additions and 502 deletions

View File

@ -246,7 +246,7 @@ export class PegasusActorSheet extends ActorSheet {
this.actor.rollPool( 'agi', false, "ranged-atk"); this.actor.rollPool( 'agi', false, "ranged-atk");
}); });
html.find('.defense-roll').click((event) => { html.find('.defense-roll').click((event) => {
this.actor.rollPool( 'def', true); this.actor.rollPool( 'def', true, "defence");
}); });
html.find('.damage-melee').click((event) => { html.find('.damage-melee').click((event) => {
this.actor.rollPool( 'str', false, "melee-dmg"); this.actor.rollPool( 'str', false, "melee-dmg");
@ -365,7 +365,10 @@ export class PegasusActorSheet extends ActorSheet {
if (item == undefined) { if (item == undefined) {
item = this.actor.items.get( dragData.uuid ) item = this.actor.items.get( dragData.uuid )
} }
let ret = await this.actor.preprocessItem( event, item, true ) console.log("Dropped", item)
let itemFull = await PegasusUtility.searchItem( item )
let ret = await this.actor.preprocessItem( event, itemFull, true )
if ( ret ) { if ( ret ) {
super._onDropItem(event, dragData) super._onDropItem(event, dragData)
} }

View File

@ -7,10 +7,55 @@ const coverBonusTable = { "nocover": 0, "lightcover": 2, "heavycover": 4, "entre
const statThreatLevel = ["agi", "str", "phy", "com", "def", "per"] const statThreatLevel = ["agi", "str", "phy", "com", "def", "per"]
const __subkey2title = { const __subkey2title = {
"melee-dmg": "Melee Damage", "melee-atk": "Melee Attack", "ranged-atk": "Ranged Attack", "melee-dmg": "Melee Damage", "melee-atk": "Melee Attack", "ranged-atk": "Ranged Attack",
"ranged-dmg": "Ranged Damage", "dmg-res": "Damare Resistance" "ranged-dmg": "Ranged Damage", "defence": "Defence", "dmg-res": "Damare Resistance"
}
const __statBuild = [
{ modules: ["vehiclehull"], field: "hr", itemfield: "hr" },
{ modules: ["vehiclehull", "vehiclemodule"], field: "hr", itemfield: "size", subfield: "size" },
//{ modules: ["vehiclehull"], field: "pc", itemfield: "vms", subfield: "avgnrg" },
//{ modules: ["powercoremodule"], field: "pc", itemfield: "nrg", subfield: "avgnrg" },
{ modules: ["vehiclehull", "mobilitymodule"], itemfield: "man", field: "man" },
{ modules: ["powercoremodule"], field: "pc", itemfield: "pc", additionnal1: "curnrg", additionnal2: "maxnrg" },
{ modules: ["mobilitymodule"], field: "mr", itemfield: "mr" },
{ modules: ["propulsionmodule"], field: "ad", itemfield: "ad" },
{ modules: ["combatmodule"], field: "fc", itemfield: "fc" },
]
const __isVehicleUnique = { vehiclehull: 1, powercoremodule: 1, mobilitymodule: 1, propulsionmodule: 1, combatmodule: 1 }
const __speed2Num = { fullstop: 0, crawling: 1, slow: 2, average: 3, fast: 4, extfast: 5 }
const __num2speed = ["fullstop", "crawling", "slow", "average", "fast", "extfast"]
const __isVehicle = { vehiclehull: 1, powercoremodule: 1, mobilitymodule: 1, combatmodule: 1, propulsionmodule: 1, vehiclemodule: 1, vehicleweaponmodule: 1, effect: 1 }
const __bonusEffect = {
name: "Crawling MAN Bonus", type: "effect", img: "systems/fvtt-pegasus-rpg/images/icons/icon_effect.webp",
system: {
type: "physical",
genre: "positive",
effectlevel: 3,
reducedicevalue: false,
stataffected: "man",
specaffected: [],
statdice: false,
bonusdice: true,
weapondamage: false,
hindrance: false,
resistedby: "notapplicable",
recoveryroll: false,
recoveryrollstat: "",
recoveryrollspec: [],
effectstatlevel: false,
effectstat: "",
oneuse: false,
ignorehealthpenalty: false,
isthispossible: "",
mentaldisruption: false,
physicaldisruption: false,
mentalimmunity: false,
physicalimmunity: false,
nobonusdice: false,
noperksallowed: false,
description: "",
otherdice: false
}
} }
/* -------------------------------------------- */
/* -------------------------------------------- */ /* -------------------------------------------- */
/** /**
* Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system. * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
@ -71,7 +116,9 @@ export class PegasusActor extends Actor {
this.system.encCapacity = this.getEncumbranceCapacity() this.system.encCapacity = this.getEncumbranceCapacity()
this.buildContainerTree() this.buildContainerTree()
} }
if (this.type == 'vehicle') {
this.computeVehicleStats();
}
super.prepareDerivedData(); super.prepareDerivedData();
} }
@ -322,7 +369,7 @@ export class PegasusActor extends Actor {
nrg.activated += item.system.costspent nrg.activated += item.system.costspent
nrg.value -= item.system.costspent nrg.value -= item.system.costspent
nrg.max -= item.system.costspent nrg.max -= item.system.costspent
await this.update({ 'data.nrg': nrg }) await this.update({ 'system.nrg': nrg })
let effects = [] let effects = []
for (let effect of item.system.effectsgained) { for (let effect of item.system.effectsgained) {
@ -338,7 +385,7 @@ export class PegasusActor extends Actor {
} else { } else {
nrg.activated -= item.system.costspent nrg.activated -= item.system.costspent
nrg.max += item.system.costspent nrg.max += item.system.costspent
await this.update({ 'data.nrg': nrg }) await this.update({ 'system.nrg': nrg })
let toRem = [] let toRem = []
for (let item of this.items) { for (let item of this.items) {
@ -427,7 +474,7 @@ export class PegasusActor extends Actor {
tl += equip.system.threatlevel tl += equip.system.threatlevel
} }
if (tl != this.system.biodata.threatlevel) { if (tl != this.system.biodata.threatlevel) {
this.update({ 'data.biodata.threatlevel': tl }) this.update({ 'system.biodata.threatlevel': tl })
} }
} }
@ -496,7 +543,7 @@ export class PegasusActor extends Actor {
let combat = duplicate(this.system.combat) let combat = duplicate(this.system.combat)
combat.stunlevel += incDec combat.stunlevel += incDec
if (combat.stunlevel >= 0) { if (combat.stunlevel >= 0) {
this.update({ 'data.combat': combat }) this.update({ 'system.combat': combat })
let chatData = { let chatData = {
user: game.user.id, user: game.user.id,
rollMode: game.settings.get("core", "rollMode"), rollMode: game.settings.get("core", "rollMode"),
@ -518,7 +565,7 @@ export class PegasusActor extends Actor {
if (incDec > 0 && stunAbove > 0) { if (incDec > 0 && stunAbove > 0) {
let delirium = duplicate(this.system.secondary.delirium) let delirium = duplicate(this.system.secondary.delirium)
delirium.value -= incDec delirium.value -= incDec
this.update({ 'data.secondary.delirium': delirium }) this.update({ 'system.secondary.delirium': delirium })
} }
} }
@ -526,7 +573,7 @@ export class PegasusActor extends Actor {
modifyMomentum(incDec) { modifyMomentum(incDec) {
let momentum = duplicate(this.system.momentum) let momentum = duplicate(this.system.momentum)
momentum.value += incDec momentum.value += incDec
this.update({ 'data.momentum': momentum }) this.update({ 'system.momentum': momentum })
let chatData = { let chatData = {
user: game.user.id, user: game.user.id,
rollMode: game.settings.get("core", "rollMode"), rollMode: game.settings.get("core", "rollMode"),
@ -576,11 +623,11 @@ export class PegasusActor extends Actor {
ui.notifications.warn("Container is already full !") ui.notifications.warn("Container is already full !")
return return
} else { } else {
await this.updateEmbeddedDocuments("Item", [{ _id: object.id, 'data.containerid': containerId }]) await this.updateEmbeddedDocuments("Item", [{ _id: object.id, 'system.containerid': containerId }])
} }
} else if (object && object.system.containerid) { // remove from container } else if (object && object.system.containerid) { // remove from container
console.log("Removeing: ", object) console.log("Removeing: ", object)
await this.updateEmbeddedDocuments("Item", [{ _id: object.id, 'data.containerid': "" }]); await this.updateEmbeddedDocuments("Item", [{ _id: object.id, 'system.containerid': "" }]);
} }
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -613,6 +660,12 @@ export class PegasusActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async preprocessItem(event, item, onDrop = false) { async preprocessItem(event, item, onDrop = false) {
console.log("Pre-process", item)
if (item.type != "effect" && __isVehicle[item.type]) {
ui.notifications.warn("You can't drop Vehicles item over a character sheet.")
return
}
// Pre-filter effects // Pre-filter effects
if (item.type == 'effect') { if (item.type == 'effect') {
if (this.checkMentalDisruption() && item.system.type == "mental" && item.system.genre == "positive") { if (this.checkMentalDisruption() && item.system.type == "mental" && item.system.genre == "positive") {
@ -633,12 +686,13 @@ export class PegasusActor extends Actor {
} }
} }
if (item.type == 'race') { if (item.type == 'race') {
this.applyRace(item.system) this.applyRace(item)
} else if (item.type == 'role') { } else if (item.type == 'role') {
this.applyRole(item.system) this.applyRole(item)
} else if (item.type == 'ability') { } else if (item.type == 'ability') {
this.applyAbility(item.system, [], true) this.applyAbility(item, [], true)
if (!onDrop) { if (!onDrop) {
await this.createEmbeddedDocuments('Item', [item]) await this.createEmbeddedDocuments('Item', [item])
} }
@ -689,17 +743,20 @@ export class PegasusActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
getSubActors() { getSubActors() {
let subActors = []; let subActors = [];
for (let id of this.system.subactors) { if (this.system.subactors) {
subActors.push(duplicate(game.actors.get(id))) for (let id of this.system.subactors) {
subActors.push(duplicate(game.actors.get(id)))
}
} }
return subActors; return subActors;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async addSubActor(subActorId) { async addSubActor(subActorId) {
let subActors = duplicate(this.system.subactors); let subActors = duplicate(this.system.subactors || []);
subActors.push(subActorId); subActors.push(subActorId);
await this.update({ 'data.subactors': subActors }); await this.update({ 'system.subactors': subActors });
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async delSubActor(subActorId) { async delSubActor(subActorId) {
let newArray = []; let newArray = [];
@ -708,7 +765,7 @@ export class PegasusActor extends Actor {
newArray.push(id); newArray.push(id);
} }
} }
await this.update({ 'data.subactors': newArray }); await this.update({ 'system.subactors': newArray });
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -724,12 +781,12 @@ export class PegasusActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
getStat(statKey) { getStat(statKey) {
let stat let stat
if (statKey == 'mr') { if (this.type == "character" && statKey == 'mr') {
stat = duplicate(this.system.mr); stat = duplicate(this.system.mr);
} else { } else {
stat = duplicate(this.system.statistics[statKey]); stat = duplicate(this.system.statistics[statKey]);
} }
stat.dice = PegasusUtility.getDiceFromLevel(stat.value); stat.dice = PegasusUtility.getDiceFromLevel(stat.value || stat.level);
return stat; return stat;
} }
@ -758,7 +815,7 @@ export class PegasusActor extends Actor {
if (powers.length > 0) { if (powers.length > 0) {
this.createEmbeddedDocuments('Item', powers) this.createEmbeddedDocuments('Item', powers)
} }
this.updateEmbeddedDocuments('Item', [{ _id: specId, 'data.powersactivated': true }]) this.updateEmbeddedDocuments('Item', [{ _id: specId, 'system.powersactivated': true }])
} }
} }
@ -773,7 +830,7 @@ export class PegasusActor extends Actor {
if (toRem.length > 0) { if (toRem.length > 0) {
this.deleteEmbeddedDocuments('Item', toRem) this.deleteEmbeddedDocuments('Item', toRem)
} }
this.updateEmbeddedDocuments('Item', [{ _id: specId, 'data.powersactivated': false }]) this.updateEmbeddedDocuments('Item', [{ _id: specId, 'system.powersactivated': false }])
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -788,7 +845,7 @@ export class PegasusActor extends Actor {
if (effects.length > 0) { if (effects.length > 0) {
this.createEmbeddedDocuments('Item', effects) this.createEmbeddedDocuments('Item', effects)
} }
this.updateEmbeddedDocuments('Item', [{ _id: itemId, 'data.activated': true }]) this.updateEmbeddedDocuments('Item', [{ _id: itemId, 'system.activated': true }])
} }
} }
@ -803,7 +860,7 @@ export class PegasusActor extends Actor {
if (toRem.length > 0) { if (toRem.length > 0) {
this.deleteEmbeddedDocuments('Item', toRem) this.deleteEmbeddedDocuments('Item', toRem)
} }
this.updateEmbeddedDocuments('Item', [{ _id: itemId, 'data.activated': false }]) this.updateEmbeddedDocuments('Item', [{ _id: itemId, 'system.activated': false }])
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -878,7 +935,7 @@ export class PegasusActor extends Actor {
let item = this.items.get(itemId) let item = this.items.get(itemId)
if (item && value) { if (item && value) {
value = Number(value) || 0 value = Number(value) || 0
await this.updateEmbeddedDocuments('Item', [{ _id: itemId, 'data.costspent': value }]) await this.updateEmbeddedDocuments('Item', [{ _id: itemId, 'system.costspent': value }])
} }
} }
@ -888,7 +945,7 @@ export class PegasusActor extends Actor {
for (let perk of this.items) { for (let perk of this.items) {
if (perk.type == "perk") { if (perk.type == "perk") {
this.cleanPerkEffects(perk.id) this.cleanPerkEffects(perk.id)
this.updateEmbeddedDocuments('Item', [{ _id: perk.id, 'data.status': "ready", 'data.used1': false, 'data.used2': false, 'data.used3': false }]) this.updateEmbeddedDocuments('Item', [{ _id: perk.id, 'system.status': "ready", 'system.used1': false, 'system.used2': false, 'system.used3': false }])
ChatMessage.create({ content: `Perk ${perk.name} has been deactivated due to Severe Trauma state !` }) ChatMessage.create({ content: `Perk ${perk.name} has been deactivated due to Severe Trauma state !` })
} }
} }
@ -897,10 +954,18 @@ export class PegasusActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
incDecNRG(value) { incDecNRG(value) {
let nrg = duplicate(this.system.nrg) if (this.type == "character") {
nrg.value += value let nrg = duplicate(this.system.nrg)
if (nrg.value >= 0 && nrg.value <= nrg.max) { nrg.value += value
this.update({ 'data.nrg': nrg }) if (nrg.value >= 0 && nrg.value <= nrg.max) {
this.update({ 'system.nrg': nrg })
}
} else {
let pc = duplicate(this.system.statistics.pc)
pc.curnrg += value
if (pc.curnrg >= 0 && pc.curnrg <= pc.maxnrg) {
this.update({ 'system.statistics.pc': pc })
}
} }
} }
@ -1038,13 +1103,15 @@ export class PegasusActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
getTraumaState() { getTraumaState() {
this.traumaState = "none" this.traumaState = "none"
let negDelirium = -Math.floor((this.system.secondary.delirium.max + 1) / 2)
if (this.type == "character") { if (this.type == "character") {
if (this.system.secondary.delirium.value <= 0 && this.system.secondary.delirium.value >= negDelirium) { let negDelirium = -Math.floor((this.system.secondary.delirium.max + 1) / 2)
this.traumaState = "trauma" if (this.type == "character") {
} if (this.system.secondary.delirium.value <= 0 && this.system.secondary.delirium.value >= negDelirium) {
if (this.system.secondary.delirium.value < negDelirium) { this.traumaState = "trauma"
this.traumaState = "severetrauma" }
if (this.system.secondary.delirium.value < negDelirium) {
this.traumaState = "severetrauma"
}
} }
} }
return this.traumaState return this.traumaState
@ -1058,7 +1125,7 @@ export class PegasusActor extends Actor {
modifyHeroLevelRemaining(incDec) { modifyHeroLevelRemaining(incDec) {
let biodata = duplicate(this.system.biodata) let biodata = duplicate(this.system.biodata)
biodata.currentlevelremaining = Math.max(biodata.currentlevelremaining + incDec, 0) biodata.currentlevelremaining = Math.max(biodata.currentlevelremaining + incDec, 0)
this.update({ "data.biodata": biodata }) this.update({ "system.biodata": biodata })
ChatMessage.create({ content: `${this.name} has used a Hero Level to reroll !` }) ChatMessage.create({ content: `${this.name} has used a Hero Level to reroll !` })
return biodata.currentlevelremaining return biodata.currentlevelremaining
} }
@ -1135,73 +1202,72 @@ export class PegasusActor extends Actor {
} }
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async computeNRGHealth() { async computeNRGHealth() {
if (this.type == "vehicle") {
return
}
if (this.isOwner || game.user.isGM) { if (this.isOwner || game.user.isGM) {
let updates = {} let updates = {}
let phyDiceValue = PegasusUtility.getDiceValue(this.system.statistics.phy.value) + this.system.secondary.health.bonus + this.system.statistics.phy.mod; let phyDiceValue = PegasusUtility.getDiceValue(this.system.statistics.phy.value) + this.system.secondary.health.bonus + this.system.statistics.phy.mod;
if (phyDiceValue != this.system.secondary.health.max) { if (phyDiceValue != this.system.secondary.health.max) {
updates['data.secondary.health.max'] = phyDiceValue updates['system.secondary.health.max'] = phyDiceValue
} }
if (this.computeValue) { if (this.computeValue) {
updates['data.secondary.health.value'] = phyDiceValue updates['system.secondary.health.value'] = phyDiceValue
} }
let mndDiceValue = PegasusUtility.getDiceValue(this.system.statistics.mnd.value) + this.system.secondary.delirium.bonus + this.system.statistics.mnd.mod; let mndDiceValue = PegasusUtility.getDiceValue(this.system.statistics.mnd.value) + this.system.secondary.delirium.bonus + this.system.statistics.mnd.mod;
if (mndDiceValue != this.system.secondary.delirium.max) { if (mndDiceValue != this.system.secondary.delirium.max) {
updates['data.secondary.delirium.max'] = mndDiceValue updates['system.secondary.delirium.max'] = mndDiceValue
} }
if (this.computeValue) { if (this.computeValue) {
updates['data.secondary.delirium.value'] = mndDiceValue updates['system.secondary.delirium.value'] = mndDiceValue
} }
let stlDiceValue = PegasusUtility.getDiceValue(this.system.statistics.stl.value) + this.system.secondary.stealthhealth.bonus + this.system.statistics.stl.mod; let stlDiceValue = PegasusUtility.getDiceValue(this.system.statistics.stl.value) + this.system.secondary.stealthhealth.bonus + this.system.statistics.stl.mod;
if (stlDiceValue != this.system.secondary.stealthhealth.max) { if (stlDiceValue != this.system.secondary.stealthhealth.max) {
updates['data.secondary.stealthhealth.max'] = stlDiceValue updates['system.secondary.stealthhealth.max'] = stlDiceValue
} }
if (this.computeValue) { if (this.computeValue) {
updates['data.secondary.stealthhealth.value'] = stlDiceValue updates['system.secondary.stealthhealth.value'] = stlDiceValue
} }
let socDiceValue = PegasusUtility.getDiceValue(this.system.statistics.soc.value) + this.system.secondary.socialhealth.bonus + this.system.statistics.soc.mod; let socDiceValue = PegasusUtility.getDiceValue(this.system.statistics.soc.value) + this.system.secondary.socialhealth.bonus + this.system.statistics.soc.mod;
if (socDiceValue != this.system.secondary.socialhealth.max) { if (socDiceValue != this.system.secondary.socialhealth.max) {
updates['data.secondary.socialhealth.max'] = socDiceValue updates['system.secondary.socialhealth.max'] = socDiceValue
} }
if (this.computeValue) { if (this.computeValue) {
updates['data.secondary.socialhealth.value'] = socDiceValue updates['system.secondary.socialhealth.value'] = socDiceValue
} }
let nrgValue = PegasusUtility.getDiceValue(this.system.statistics.foc.value) + this.system.nrg.mod + this.system.statistics.foc.mod let nrgValue = PegasusUtility.getDiceValue(this.system.statistics.foc.value) + this.system.nrg.mod + this.system.statistics.foc.mod
if (nrgValue != this.system.nrg.absolutemax) { if (nrgValue != this.system.nrg.absolutemax) {
updates['data.nrg.absolutemax'] = nrgValue updates['system.nrg.absolutemax'] = nrgValue
} }
if (this.computeValue) { if (this.computeValue) {
updates['data.nrg.max'] = nrgValue updates['system.nrg.max'] = nrgValue
updates['data.nrg.value'] = nrgValue updates['system.nrg.value'] = nrgValue
} }
let stunth = PegasusUtility.getDiceValue(this.system.statistics.phy.value) + PegasusUtility.getDiceValue(this.system.statistics.mnd.value) + PegasusUtility.getDiceValue(this.system.statistics.foc.value) let stunth = PegasusUtility.getDiceValue(this.system.statistics.phy.value) + PegasusUtility.getDiceValue(this.system.statistics.mnd.value) + PegasusUtility.getDiceValue(this.system.statistics.foc.value)
+ this.system.statistics.mnd.mod + this.system.statistics.phy.mod + this.system.statistics.foc.mod + this.system.statistics.mnd.mod + this.system.statistics.phy.mod + this.system.statistics.foc.mod
if (stunth != this.system.combat.stunthreshold) { if (stunth != this.system.combat.stunthreshold) {
updates['data.combat.stunthreshold'] = stunth updates['system.combat.stunthreshold'] = stunth
} }
let momentum = this.system.statistics.foc.value + this.system.statistics.foc.mod let momentum = this.system.statistics.foc.value + this.system.statistics.foc.mod
if (momentum != this.system.momentum.max) { if (momentum != this.system.momentum.max) {
updates['data.momentum.value'] = 0 updates['system.momentum.value'] = 0
updates['data.momentum.max'] = momentum updates['system.momentum.max'] = momentum
} }
let mrLevel = (this.system.statistics.agi.value + this.system.statistics.str.value) - this.system.statistics.phy.value let mrLevel = (this.system.statistics.agi.value + this.system.statistics.str.value) - this.system.statistics.phy.value
mrLevel = (mrLevel < 1) ? 1 : mrLevel; mrLevel = (mrLevel < 1) ? 1 : mrLevel;
if (mrLevel != this.system.mr.value) { if (mrLevel != this.system.mr.value) {
updates['data.mr.value'] = mrLevel updates['system.mr.value'] = mrLevel
} }
let moralitythreshold = - (Number(PegasusUtility.getDiceValue(this.system.statistics.foc.value)) + Number(this.system.statistics.foc.mod)) let moralitythreshold = - (Number(PegasusUtility.getDiceValue(this.system.statistics.foc.value)) + Number(this.system.statistics.foc.mod))
if (moralitythreshold != this.system.biodata.moralitythreshold) { if (moralitythreshold != this.system.biodata.moralitythreshold) {
updates['data.biodata.moralitythreshold'] = moralitythreshold updates['system.biodata.moralitythreshold'] = moralitythreshold
} }
if (!this.isToken) { if (!this.isToken) {
if (this.warnMorality != this.system.biodata.morality && this.system.biodata.morality < 0) { if (this.warnMorality != this.system.biodata.morality && this.system.biodata.morality < 0) {
@ -1215,11 +1281,11 @@ export class PegasusActor extends Actor {
let race = this.getRace() let race = this.getRace()
if (race && race.name && (race.name != this.system.biodata.racename)) { if (race && race.name && (race.name != this.system.biodata.racename)) {
updates['data.biodata.racename'] = race.name updates['system.biodata.racename'] = race.name
} }
let role = this.getRole() let role = this.getRole()
if (role && role.name && (role.name != this.system.biodata.rolename)) { if (role && role.name && (role.name != this.system.biodata.rolename)) {
updates['data.biodata.rolename'] = role.name updates['system.biodata.rolename'] = role.name
} }
if (Object.entries(updates).length > 0) { if (Object.entries(updates).length > 0) {
await this.update(updates) await this.update(updates)
@ -1281,7 +1347,7 @@ export class PegasusActor extends Actor {
if (objetQ) { if (objetQ) {
let newQ = objetQ.system.quantity + incDec let newQ = objetQ.system.quantity + incDec
if (newQ >= 0) { if (newQ >= 0) {
const updated = await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'data.quantity': newQ }]) // pdates one EmbeddedEntity const updated = await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantity': newQ }]) // pdates one EmbeddedEntity
} }
} }
} }
@ -1291,7 +1357,7 @@ export class PegasusActor extends Actor {
if (objetQ) { if (objetQ) {
let newQ = objetQ.system.ammocurrent + incDec; let newQ = objetQ.system.ammocurrent + incDec;
if (newQ >= 0 && newQ <= objetQ.system.ammomax) { if (newQ >= 0 && newQ <= objetQ.system.ammomax) {
const updated = await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'data.ammocurrent': newQ }]); // pdates one EmbeddedEntity const updated = await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.ammocurrent': newQ }]); // pdates one EmbeddedEntity
} }
} }
} }
@ -1328,26 +1394,31 @@ export class PegasusActor extends Actor {
let newItems = [] let newItems = []
if (ability.system.effectsgained) { if (ability.system.effectsgained) {
for (let effect of ability.system.effectsgained) { for (let effect of ability.system.effectsgained) {
if (!effect.system) effect.system = effect.data
newItems.push(effect); newItems.push(effect);
} }
} }
if (ability.system.powersgained) { if (ability.system.powersgained) {
for (let power of ability.system.powersgained) { for (let power of ability.system.powersgained) {
if (!power.system) power.system = power.data
newItems.push(power); newItems.push(power);
} }
} }
if (ability.system.specialisations) { if (ability.system.specialisations) {
for (let spec of ability.system.specialisations) { for (let spec of ability.system.specialisations) {
if (!spec.system) spec.system = spec.data
newItems.push(spec); newItems.push(spec);
} }
} }
if (ability.system.attackgained) { if (ability.system.attackgained) {
for (let weapon of ability.system.attackgained) { for (let weapon of ability.system.attackgained) {
if (!weapon.system) weapon.system = weapon.data
newItems.push(weapon); newItems.push(weapon);
} }
} }
if (ability.system.armorgained) { if (ability.system.armorgained) {
for (let armor of ability.system.armorgained) { for (let armor of ability.system.armorgained) {
if (!armor.system) armor.system = armor.data
newItems.push(armor); newItems.push(armor);
} }
} }
@ -1357,17 +1428,20 @@ export class PegasusActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async applyRace(race) { async applyRace(race) {
let updates = { 'data.biodata.racename': race.name } let updates = { 'system.biodata.racename': race.name }
let newItems = [] let newItems = []
await this.deleteAllItemsByType('race') await this.deleteAllItemsByType('race')
newItems.push(race); newItems.push(race);
console.log("DROPPED RACE", race)
for (let ability of race.system.abilities) { for (let ability of race.system.abilities) {
if (!ability.system) ability.system = ability.data
newItems.push(ability) newItems.push(ability)
this.applyAbility(ability, updates) this.applyAbility(ability, updates)
} }
if (race.system.perksgained) { if (race.system.perksgained) {
for (let power of race.system.perks) { for (let power of race.system.perks) {
if (!power.system) power.system = power.data
newItems.push(power); newItems.push(power);
} }
} }
@ -1389,7 +1463,7 @@ export class PegasusActor extends Actor {
async applyRole(role) { async applyRole(role) {
console.log("ROLE", role) console.log("ROLE", role)
let updates = { 'data.biodata.rolename': role.name } let updates = { 'system.biodata.rolename': role.name }
let newItems = [] let newItems = []
await this.deleteAllItemsByType('role') await this.deleteAllItemsByType('role')
newItems.push(role) newItems.push(role)
@ -1398,7 +1472,7 @@ export class PegasusActor extends Actor {
this.getIncreaseStatValue(updates, role.system.statincrease2) this.getIncreaseStatValue(updates, role.system.statincrease2)
if (role.system.specialability.length > 0) { if (role.system.specialability.length > 0) {
console.log("Adding ability", role.system.specialability) //console.log("Adding ability", role.system.specialability)
newItems = newItems.concat(duplicate(role.system.specialability)) // Add new ability newItems = newItems.concat(duplicate(role.system.specialability)) // Add new ability
this.applyAbility(role.system.specialability[0], newItems) this.applyAbility(role.system.specialability[0], newItems)
} }
@ -1410,24 +1484,46 @@ export class PegasusActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
addHindrancesList(effectsList) { addHindrancesList(effectsList) {
if (this.system.combat.stunlevel > 0) { if (this.type == "character") {
effectsList.push({ label: "Stun Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: this.system.combat.stunlevel }) if (this.system.combat.stunlevel > 0) {
effectsList.push({ label: "Stun Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: 2 })
}
if (this.system.combat.hindrancedice > 0) {
effectsList.push({ label: "Wounds Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: this.system.combat.hindrancedice })
}
let overCapacity = Math.floor(this.encCurrent / this.getEncumbranceCapacity())
if (overCapacity > 0) {
effectsList.push({ label: "Encumbrance Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: overCapacity })
}
if (this.system.biodata.morality <= 0) {
effectsList.push({ label: "Morality Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: 3 })
}
let effects = this.items.filter(item => item.type == 'effect')
for (let effect of effects) {
effect = duplicate(effect)
if (effect.system.hindrance) {
effectsList.push({ label: effect.name, type: "effect", foreign: true, actorId: this.id, applied: false, effect: effect, value: effect.system.effectlevel })
}
}
} }
if (this.system.combat.hindrancedice > 0) { if (this.type == "vehicle") {
effectsList.push({ label: "Wounds Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: this.system.combat.hindrancedice }) if (this.system.stun.value > 0) {
} effectsList.push({ label: "Stun Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: 2 })
let overCapacity = Math.floor(this.encCurrent / this.getEncumbranceCapacity()) }
if (overCapacity > 0) { if (this.isVehicleCrawling()) {
effectsList.push({ label: "Encumbrance Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: overCapacity }) effectsList.push({ label: "Crawling Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: 3 })
} }
if (this.system.biodata.morality <= 0) { if (this.isVehicleSlow()) {
effectsList.push({ label: "Morality Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: 3 }) effectsList.push({ label: "Slow Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: 1 })
} }
let effects = this.items.filter(item => item.type == 'effect') if (this.isVehicleAverage()) {
for (let effect of effects) { effectsList.push({ label: "Average Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: 1 })
effect = duplicate(effect) }
if (effect.system.hindrance) { if (this.isVehicleFast()) {
effectsList.push({ label: effect.name, type: "effect", foreign: true, actorId: this.id, applied: false, effect: effect, value: effect.system.effectlevel }) effectsList.push({ label: "Fast Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: 3 })
}
if (this.isVehicleExFast()) {
effectsList.push({ label: "Ext. Fast Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: 5 })
} }
} }
} }
@ -1435,7 +1531,6 @@ export class PegasusActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
/* ROLL SECTION /* ROLL SECTION
/* -------------------------------------------- */ /* -------------------------------------------- */
pushEffect(rollData, effect) { pushEffect(rollData, effect) {
if (this.getTraumaState() == "none" && !this.checkNoBonusDice()) { if (this.getTraumaState() == "none" && !this.checkNoBonusDice()) {
rollData.effectsList.push({ label: effect.name, type: "effect", applied: false, effect: effect, value: effect.system.effectlevel }) rollData.effectsList.push({ label: effect.name, type: "effect", applied: false, effect: effect, value: effect.system.effectlevel })
@ -1511,9 +1606,19 @@ export class PegasusActor extends Actor {
} }
} }
} }
addVehicleWeapons(rollData, vehicle) {
if (vehicle) {
let modules = vehicle.items.filter(vehicle => vehicle.type == "vehicleweaponmodule")
if (modules && modules.length > 0) {
for (let module of modules) {
rollData.vehicleWeapons.push({ label: `Weapon ${module.name}`, type: "item", applied: false, weapon: module, value: module.system.damagedicevalue })
}
}
}
}
/* -------------------------------------------- */ /* -------------------------------------------- */
getCommonRollData(statKey = undefined, useShield = false, isInit = false, isPower = false, isPowerDmg = false) { getCommonRollData(statKey = undefined, useShield = false, isInit = false, isPower = false, subKey = "", vehicle = undefined) {
let rollData = PegasusUtility.getBasicRollData(isInit) let rollData = PegasusUtility.getBasicRollData(isInit)
rollData.alias = this.name rollData.alias = this.name
rollData.actorImg = this.img rollData.actorImg = this.img
@ -1526,11 +1631,42 @@ export class PegasusActor extends Actor {
rollData.noBonusDice = this.checkNoBonusDice() rollData.noBonusDice = this.checkNoBonusDice()
rollData.dicePool = [] rollData.dicePool = []
if (subKey == "melee-dmg" || subKey == "ranged-dmg" || subKey == "power-dmg") {
rollData.isDamage = true
}
if (statKey) { if (statKey) {
rollData.statKey = statKey rollData.statKey = statKey
rollData.stat = this.getStat(statKey) rollData.stat = this.getStat(statKey)
rollData.statDicesLevel = rollData.stat.value rollData.statDicesLevel = rollData.stat.value || rollData.stat.level
rollData.statMod = rollData.stat.mod rollData.statMod = rollData.stat.mod
if (vehicle) {
rollData.vehicle = duplicate(vehicle)
if (subKey == "melee-dmg") {
if (vehicle.isVehicleFullStop()) {
ui.notifications.warn("MR not added to Melee Damage due to Full Stop.")
} else {
rollData.statVehicle = vehicle.system.statistics.mr
}
this.addVehicleWeapons(rollData, vehicle)
}
if (subKey == "ranged-atk") {
rollData.statVehicle = vehicle.system.statistics.fc
}
if (subKey == "ranged-dmg") {
this.addVehicleWeapons(rollData, vehicle)
}
if (subKey == "defense") {
if (vehicle.isVehicleFullStop()) {
ui.notifications.warn("MAN not added to Defense due to Full Stop.")
} else {
rollData.statVehicle = vehicle.system.statistics.man
}
}
//this.addVehiculeHindrances(rollData.effectsList, vehicle)
//this.addVehicleBonus(rollData, vehicle)
}
rollData.specList = this.getRelevantSpec(statKey) rollData.specList = this.getRelevantSpec(statKey)
rollData.selectedSpec = "0" rollData.selectedSpec = "0"
if (statKey.toLowerCase() == "mr") { if (statKey.toLowerCase() == "mr") {
@ -1538,21 +1674,13 @@ export class PegasusActor extends Actor {
} else { } else {
rollData.img = `systems/fvtt-pegasus-rpg/images/icons/${rollData.stat.abbrev}.webp` rollData.img = `systems/fvtt-pegasus-rpg/images/icons/${rollData.stat.abbrev}.webp`
} }
let diceKey = PegasusUtility.getDiceFromLevel(rollData.stat.value) rollData.dicePool = rollData.dicePool.concat(PegasusUtility.buildDicePool("stat", rollData.statDicesLevel, rollData.stat.mod))
let diceList = diceKey.split(" ") if (rollData.statVehicle) {
let mod = rollData.stat.mod rollData.dicePool = rollData.dicePool.concat(PegasusUtility.buildDicePool("statvehicle", rollData.statVehicle.currentlevel, 0))
for (let myDice of diceList) {
myDice = myDice.trim()
let newDice = {
name: "stat", key: myDice, level: PegasusUtility.getLevelFromDice(myDice), mod: mod,
img: `systems/fvtt-pegasus-rpg/images/dice/${myDice}.webp`
}
rollData.dicePool.push(newDice)
mod = 0 // Only first dice has modifier
} }
} }
this.addEffects(rollData, isInit, isPower, isPowerDmg) this.addEffects(rollData, isInit, isPower, subKey == "power-dmg")
this.addArmorsShields(rollData, statKey, useShield) this.addArmorsShields(rollData, statKey, useShield)
this.addWeapons(rollData, statKey, useShield) this.addWeapons(rollData, statKey, useShield)
this.addEquipments(rollData, statKey) this.addEquipments(rollData, statKey)
@ -1598,21 +1726,18 @@ export class PegasusActor extends Actor {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
rollPool(statKey, useShield = false, subKey = "none") { rollPool(statKey, useShield = false, subKey = "none", vehicle = undefined) {
let stat = this.getStat(statKey) let stat = this.getStat(statKey)
if (stat) { if (stat) {
let rollData = this.getCommonRollData(statKey, useShield, false, false, subKey == "power-dmg") let rollData = this.getCommonRollData(statKey, useShield, false, false, subKey, vehicle)
rollData.mode = "stat" rollData.mode = "stat"
rollData.subKey = subKey rollData.subKey = subKey
let def = stat.label let def = stat.label
if (subKey) { if (subKey) {
def = __subkey2title[subKey] def = __subkey2title[subKey]
} }
rollData.title = `Roll : ${def} ` rollData.title = `Roll : ${def} `
rollData.img = "icons/dice/d12black.svg" rollData.img = "icons/dice/d12black.svg"
if (subKey == "melee-dmg" || subKey == "ranged-dmg" || subKey == "power-dmg") {
rollData.isDamage = true
}
this.startRoll(rollData) this.startRoll(rollData)
} else { } else {
ui.notifications.warn("Statistic not found !"); ui.notifications.warn("Statistic not found !");
@ -1718,7 +1843,7 @@ export class PegasusActor extends Actor {
if (power) { if (power) {
power = duplicate(power) power = duplicate(power)
let rollData = this.getCommonRollData(power.system.statistic, false, false, true, false) let rollData = this.getCommonRollData(power.system.statistic, false, false, true)
rollData.mode = "power" rollData.mode = "power"
rollData.power = power rollData.power = power
@ -1760,4 +1885,273 @@ export class PegasusActor extends Actor {
this.update({ 'stun.value': stun }) this.update({ 'stun.value': stun })
} }
/* -------------------------------------------- */
addTopSpeedBonus(topspeed, bonus) {
let num = __speed2Num[topspeed] + Number(bonus)
num = Math.max(0, num)
num = Math.min(num, __num2speed.length - 1)
return __num2speed[num]
}
/* -------------------------------------------- */
manageVehicleSpeedBonus(speed, name, stat, level) {
if (this.system.statistics.ad.currentspeed == speed) {
if (!this.items.find(effect => effect.system.isspeed == speed)) {
let effect = duplicate(__bonusEffect)
effect.name = name
effect.system.stataffected = stat
effect.system.effectlevel = level
effect.system.isspeed = speed
this.createEmbeddedDocuments("Item", [effect])
}
} else {
let effect = this.items.find(effect => effect.system.isspeed == speed)
if (effect) {
this.deleteEmbeddedDocuments("Item", [effect.id])
}
}
}
/* -------------------------------------------- */
async computeVehicleStats() {
if (this.type == "vehicle") {
for (let statDef of __statBuild) {
let sum = 0
let list = []
for (let moduleType of statDef.modules) {
list = list.concat(this.items.filter(item => item.type == moduleType))
}
if (list && list.length > 0) {
sum = list.reduce((value, item2) => value + Number(item2.system[statDef.itemfield]), 0)
}
//console.log("Processing", statDef.field, this.system.statistics[statDef.field].level, list, sum)
if (statDef.subfield) {
if (sum != Number(this.system.statistics[statDef.field][statDef.subfield])) {
//console.log("Update", statDef.field, statDef.subfield, sum, this.system.statistics[statDef.field][statDef.subfield])
this.update({ [`system.statistics.${statDef.field}.${statDef.subfield}`]: sum })
}
} else {
if (sum != Number(this.system.statistics[statDef.field].level)) {
this.update({ [`system.statistics.${statDef.field}.level`]: sum, [`system.statistics.${statDef.field}.currentlevel`]: sum })
if (statDef.additionnal1) {
if (sum != Number(this.system.statistics[statDef.field][statDef.additionnal1])) {
this.update({ [`system.statistics.${statDef.field}.${statDef.additionnal1}`]: sum })
}
}
if (statDef.additionnal2) {
if (sum != Number(this.system.statistics[statDef.field][statDef.additionnal2])) {
this.update({ [`system.statistics.${statDef.field}.${statDef.additionnal2}`]: sum })
}
}
}
}
}
// Top speed management
let mobility = this.items.find(item => item.type == "mobilitymodule")
let arcs = duplicate(this.system.arcs)
if (mobility) {
let propulsion = this.items.find(item => item.type == "propulsionmodule")
let bonus = (propulsion) ? propulsion.system.topspeed : 0
arcs.frontarc.topspeed = this.addTopSpeedBonus(mobility.system.ts_f, bonus)
arcs.rightarc.topspeed = mobility.system.ts_s
arcs.leftarc.topspeed = mobility.system.ts_s
arcs.toparc.topspeed = mobility.system.ts_s
arcs.bottomarc.topspeed = mobility.system.ts_s
arcs.reararc.topspeed = mobility.system.ts_r
} else {
arcs.frontarc.topspeed = "fullstop"
arcs.rightarc.topspeed = "fullstop"
arcs.leftarc.topspeed = "fullstop"
arcs.toparc.topspeed = "fullstop"
arcs.bottomarc.topspeed = "fullstop"
arcs.reararc.topspeed = "fullstop"
}
for (let key in this.system.arcs) {
if (this.system.arcs[key].topspeed != arcs[key].topspeed) {
this.update({ 'system.arcs': arcs })
}
}
// VMS management
let hull = this.items.find(item => item.type == "vehiclehull")
let modules = duplicate(this.system.modules)
if (hull) {
modules.totalvms = Number(hull.system.vms)
} else {
modules.totalvms = 0
}
let spaceList = this.items.filter(item => item.type == "vehiclemodule") || []
spaceList = spaceList.concat(this.items.filter(item => item.type == "vehicleweaponmodule") || [])
let space = 0
if (spaceList && spaceList.length > 0) {
space = spaceList.reduce((value, item2) => value + Number(item2.system.space), 0)
}
modules.usedvms = space
if (modules.totalvms != this.system.modules.totalvms || modules.usedvms != this.system.modules.usedvms) {
this.update({ 'system.modules': modules })
}
if (modules.usedvms > modules.totalvms) {
ui.notifications.warn("Warning! No more space available in cargo !!")
}
}
// Speed effect management
this.manageVehicleSpeedBonus("crawling", "Crawling MAN Bonus", "man", 3)
this.manageVehicleSpeedBonus("slow", "Slow MAN Bonus", "man", 1)
this.manageVehicleSpeedBonus("average", "Avoid attack Bonus", "all", 1)
this.manageVehicleSpeedBonus("fast", "Avoid attack Bonus", "all", 3)
this.manageVehicleSpeedBonus("extfast", "Avoid attack Bonus", "all", 5)
}
/* -------------------------------------------- */
getTotalCost() {
let sumCost = 0
for (let item of this.items) {
if (__isVehicle[item.type]) {
if (item.system.cost) {
sumCost += Number(item.system.cost)
}
}
}
return sumCost
}
/* -------------------------------------------- */
async preprocessItemVehicle(event, item, onDrop = false) {
if (item.type != "effect" && !__isVehicle[item.type]) {
ui.notifications.warn("You can't drop Character items over a vehicle sheet.")
return
}
//console.log(">>>>> item", item.type, __isVehicleUnique[item.type])
if (__isVehicleUnique[item.type]) {
let toDelList = []
for (let toDel of this.items) {
if (toDel.type == item.type) {
toDelList.push(toDel.id)
}
}
//console.log("TODEL : ", toDelList)
if (toDelList.length > 0) {
await this.deleteEmbeddedDocuments('Item', toDelList)
}
}
// Check size
if (item.type == "vehiclemodule" || item.type == "vehicleweaponmodule") {
item.system.space = item.system.space || 0
if (this.system.modules.usedvms + Number(item.system.space) > this.system.modules.totalvms) {
ChatMessage.create({ content: `No more room available to host module ${item.name}. Module is not added to the vehicle.` })
return false
}
}
return true
}
/* -------------------------------------------- */
getCrewList() {
let crew = []
for (let actorDef of this.system.crew) {
let actor = game.actors.get(actorDef.id)
if (actor) {
crew.push({ name: actor.name, img: actor.img, id: actor.id })
}
}
return crew
}
/* -------------------------------------------- */
addCrew(actorId) {
if ( this.system.crew.length >= this.system.crewmax) {
ui.notifications.warn("Vehicle crew is already full.")
return
}
let crewList = duplicate(this.system.crew.filter(actorDef => actorDef.id != actorId) || [])
crewList.push({ id: actorId })
this.update({ 'system.crew': crewList })
}
/* -------------------------------------------- */
delCrew(actorId) {
let crewList = duplicate(this.system.crew.filter(actorDef => actorDef.id != actorId) || [])
this.update({ 'system.crew': crewList })
}
/* -------------------------------------------- */
isVehicleFullStop() {
return this.system.statistics.ad.currentspeed == "fullstop"
}
isVehicleCrawling() {
return this.system.statistics.ad.currentspeed == "crawling"
}
isVehicleSlow() {
return this.system.statistics.ad.currentspeed == "slow"
}
isVehicleAverage() {
return this.system.statistics.ad.currentspeed == "average"
}
isVehicleFast() {
return this.system.statistics.ad.currentspeed == "fast"
}
isVehicleExFast() {
return this.system.statistics.ad.currentspeed == "extfast"
}
/* -------------------------------------------- */
isValidActor() {
// Find relevant actor
let actor
for (let actorDef of this.system.crew) {
let actorTest = game.actors.get(actorDef.id)
if (actorTest.testUserPermission(game.user, "OWNER")) {
return actorTest
}
}
if (!actor) {
ui.notifications.warn("You do no own any actors in the crew of this vehicle.")
return
}
}
/* -------------------------------------------- */
rollPoolFromVehicle(statKey, useShield = false, subKey = "none") {
let actor = this.isValidActor()
if (actor) {
actor.rollPool(statKey, useShield, subKey, this)
}
}
/* -------------------------------------------- */
addVehicleShields(rollData) {
let shields = this.items.filter( shield => shield.type == "vehiclemodule" && shield.system.activated && shield.system.shielddicevalue > 0) || []
for (let shield of shields) {
rollData.vehicleShieldList.push({ label: `${shield.name} (${shield.system.arccoverage})`, type: "vehicleshield", applied: false, value: shield.system.shielddicevalue })
}
}
/* -------------------------------------------- */
rollVehicleDamageResistance() {
let actor = this.isValidActor()
if (actor) {
let stat = this.getStat("hr")
let rollData = this.getCommonRollData("hr")
rollData.mode = "stat"
rollData.title = `Stat ${stat.label}`;
this.addVehicleShields(rollData)
this.startRoll(rollData)
}
}
/* -------------------------------------------- */
activateVehicleModule(itemId) {
let mod = this.items.get(itemId)
if (mod) {
this.updateEmbeddedDocuments('Item', [{ _id: mod.id, 'system.activated': !mod.system.activated }])
}
}
} }

View File

@ -426,11 +426,15 @@ export class PegasusItemSheet extends ItemSheet {
let data = event.dataTransfer.getData('text/plain') let data = event.dataTransfer.getData('text/plain')
let dataItem = JSON.parse( data) let dataItem = JSON.parse( data)
console.log("DROP", event, dataItem ) console.log("DROP", event, dataItem )
const item = fromUuidSync(dataItem.uuid) let item = fromUuidSync(dataItem.uuid)
if (item.pack) {
item = await PegasusUtility.searchItem(item)
}
if (!item) { if (!item) {
ui.notifications.warn("Unable to find relevant item - Aborting drag&drop " + data.uuid) ui.notifications.warn("Unable to find relevant item - Aborting drag&drop " + data.uuid)
return return
} }
console.log("DROP REULT", this.object.type, item.type)
if (this.object.type == 'virtue' ) { if (this.object.type == 'virtue' ) {
if (item.type == 'effect') { if (item.type == 'effect') {

View File

@ -118,6 +118,36 @@ export class PegasusRollDialog extends Dialog {
PegasusUtility.updateDamageDicePool(this.rollData) PegasusUtility.updateDamageDicePool(this.rollData)
} }
/* -------------------------------------------- */
manageVehicleWeapon( weaponIdx, toggled) {
let weapon = this.rollData.vehicleWeapons[weaponIdx]
if (weapon) {
this.rollData.weapon = duplicate(weapon)
if (toggled) {
this.rollData.weaponName = weapon.weapon.name
} else {
this.rollData.weaponName = undefined
}
weapon.applied = toggled
}
PegasusUtility.updateDamageDicePool(this.rollData)
}
/* -------------------------------------------- */
manageVehicleShield( shieldIdx, toggled) {
let shield = this.rollData.vehicleShieldList[shieldIdx]
if (shield) {
this.rollData.shield = duplicate(shield)
if (toggled) {
this.rollData.shieldName = shield.name
} else {
this.rollData.shieldName = undefined
}
shield.applied = toggled
}
PegasusUtility.updateArmorDicePool(this.rollData)
}
/* -------------------------------------------- */ /* -------------------------------------------- */
manageEquip(equipIdx, toggled) { manageEquip(equipIdx, toggled) {
let equip = this.rollData.equipmentsList[equipIdx] let equip = this.rollData.equipmentsList[equipIdx]
@ -216,6 +246,19 @@ export class PegasusRollDialog extends Dialog {
let equipIdx = $(event.currentTarget).data("equip-idx") let equipIdx = $(event.currentTarget).data("equip-idx")
this.manageEquip(equipIdx, toggled) this.manageEquip(equipIdx, toggled)
}) })
html.find('.vehicle-weapon-clicked').change((event) => {
let toggled = event.currentTarget.checked
let weaponIdx = $(event.currentTarget).data("vehicle-weapon-idx")
this.manageVehicleWeapon(weaponIdx, toggled)
this.refreshDialog()
})
html.find('.vehicle-shield-clicked').change((event) => {
let toggled = event.currentTarget.checked
let shieldIdx = $(event.currentTarget).data("vehicle-shield-idx")
this.manageVehicleShield(shieldIdx, toggled)
this.refreshDialog()
})
html.find('.pool-add-dice').click(async (event) => { html.find('.pool-add-dice').click(async (event) => {
let diceKey = $(event.currentTarget).data("dice-key") let diceKey = $(event.currentTarget).data("dice-key")

View File

@ -7,7 +7,7 @@ import { PegasusRollDialog } from "./pegasus-roll-dialog.js";
/* -------------------------------------------- */ /* -------------------------------------------- */
const __level2Dice = ["d0", "d4", "d6", "d8", "d10", "d12"] const __level2Dice = ["d0", "d4", "d6", "d8", "d10", "d12"]
const __name2DiceValue = { "0": 0, "d0": 0, "d4": 4, "d6": 6, "d8": 8, "d10": 10, "d12": 12 } const __name2DiceValue = { "0": 0, "d0": 0, "d4": 4, "d6": 6, "d8": 8, "d10": 10, "d12": 12 }
const __dice2Level = {"d0": 0, "d4": 1, "d6": 2, "d8": 3, "d10": 4, "d12": 5} const __dice2Level = { "d0": 0, "d4": 1, "d6": 2, "d8": 3, "d10": 4, "d12": 5 }
/* -------------------------------------------- */ /* -------------------------------------------- */
export class PegasusUtility { export class PegasusUtility {
@ -61,8 +61,8 @@ export class PegasusUtility {
/* -------------------------------------------- */ /* -------------------------------------------- */
static initGenericRoll() { static initGenericRoll() {
let rollData = PegasusUtility.getBasicRollData() let rollData = PegasusUtility.getBasicRollData()
rollData.alias = "Dice Pool Roll", rollData.alias = "Dice Pool Roll",
rollData.mode = "generic" rollData.mode = "generic"
rollData.title = `Dice Pool Roll` rollData.title = `Dice Pool Roll`
rollData.img = "icons/dice/d12black.svg" rollData.img = "icons/dice/d12black.svg"
rollData.isGeneric = true rollData.isGeneric = true
@ -85,14 +85,14 @@ export class PegasusUtility {
event.preventDefault() event.preventDefault()
let rollData = PegasusUtility.initGenericRoll() let rollData = PegasusUtility.initGenericRoll()
rollData.isChatRoll = true rollData.isChatRoll = true
let rollDialog = await PegasusRollDialog.create( undefined, rollData) let rollDialog = await PegasusRollDialog.create(undefined, rollData)
rollDialog.render( true ) rollDialog.render(true)
}) })
} }
}) })
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static pushInitiativeOptions(html, options) { static pushInitiativeOptions(html, options) {
options.push({ name: "Apply -10", condition: true, icon: '<i class="fas fa-plus"></i>', callback: target => { PegasusCombat.decInitBy10(target.data('combatant-id'), -10); } }) options.push({ name: "Apply -10", condition: true, icon: '<i class="fas fa-plus"></i>', callback: target => { PegasusCombat.decInitBy10(target.data('combatant-id'), -10); } })
@ -105,20 +105,29 @@ export class PegasusUtility {
{ key: "d12", level: 5, img: "systems/fvtt-pegasus-rpg/images/dice/d12.webp" }] { key: "d12", level: 5, img: "systems/fvtt-pegasus-rpg/images/dice/d12.webp" }]
} }
/* -------------------------------------------- */
static buildDicePool(name, level, mod = 0, effectName = undefined) {
let dicePool = []
let diceKey = PegasusUtility.getDiceFromLevel(level)
let diceList = diceKey.split(" ")
for (let myDice of diceList) {
myDice = myDice.trim()
let newDice = {
name: name, key: myDice, level: PegasusUtility.getLevelFromDice(myDice), mod: mod, effect: effectName,
img: `systems/fvtt-pegasus-rpg/images/dice/${myDice}.webp`
}
dicePool.push(newDice)
mod = 0 // Only first dice has modifier
}
return dicePool
}
/* -------------------------------------------- */ /* -------------------------------------------- */
static updateEffectsBonusDice(rollData) { static updateEffectsBonusDice(rollData) {
let newDicePool = rollData.dicePool.filter(dice => dice.name != "effect-bonus-dice") let newDicePool = rollData.dicePool.filter(dice => dice.name != "effect-bonus-dice")
for (let effect of rollData.effectsList) { for (let effect of rollData.effectsList) {
if (effect && effect.applied && effect.type == "effect" && effect.effect.system.bonusdice) { if (effect && effect.applied && effect.type == "effect" && effect.effect.system.bonusdice) {
let diceKey = PegasusUtility.getDiceFromLevel(effect.effect.system.effectlevel) newDicePool = newDicePool.concat( this.buildDicePool("effect-bonus-dice", effect.effect.system.effectlevel, 0, effect.effect.name ))
let diceList = diceKey.split(" ")
for (let myDice of diceList) {
let newDice = {
name: "effect-bonus-dice", key: myDice, level: effect.effect.system.effectlevel, effect: effect.effect.name,
img: `systems/fvtt-pegasus-rpg/images/dice/${myDice}.webp`
}
newDicePool.push(newDice)
}
} }
} }
rollData.dicePool = newDicePool rollData.dicePool = newDicePool
@ -128,16 +137,8 @@ export class PegasusUtility {
static updateHindranceBonusDice(rollData) { static updateHindranceBonusDice(rollData) {
let newDicePool = rollData.dicePool.filter(dice => dice.name != "effect-hindrance") let newDicePool = rollData.dicePool.filter(dice => dice.name != "effect-hindrance")
for (let hindrance of rollData.effectsList) { for (let hindrance of rollData.effectsList) {
if (hindrance && hindrance.applied && (hindrance.type == "hindrance" || (hindrance.type == "effect" && hindrance.effect?.system?.hindrance) ) ) { if (hindrance && hindrance.applied && (hindrance.type == "hindrance" || (hindrance.type == "effect" && hindrance.effect?.system?.hindrance))) {
let diceKey = PegasusUtility.getDiceFromLevel( (hindrance.value) ? hindrance.value : hindrance.effect.system.effectlevel) newDicePool = newDicePool.concat( this.buildDicePool("effect-hindrance", (hindrance.value) ? hindrance.value : hindrance.effect.system.effectlevel, 0, hindrance.name ))
let diceList = diceKey.split(" ")
for (let myDice of diceList) {
let newDice = {
name: "effect-hindrance", key: myDice, level: hindrance.value, effect: hindrance.name,
img: `systems/fvtt-pegasus-rpg/images/dice/${myDice}.webp`
}
newDicePool.push(newDice)
}
} }
} }
rollData.dicePool = newDicePool rollData.dicePool = newDicePool
@ -148,15 +149,13 @@ export class PegasusUtility {
let newDicePool = rollData.dicePool.filter(dice => dice.name != "armor-shield") let newDicePool = rollData.dicePool.filter(dice => dice.name != "armor-shield")
for (let armor of rollData.armorsList) { for (let armor of rollData.armorsList) {
if (armor.applied) { if (armor.applied) {
let diceKey = PegasusUtility.getDiceFromLevel(armor.value) newDicePool = newDicePool.concat( this.buildDicePool("armor-shield", armor.value, 0))
let diceList = diceKey.split(" ") }
for (let myDice of diceList) { }
let newDice = { newDicePool = rollData.dicePool.filter(dice => dice.name != "vehicle-shield")
name: "armor-shield", key: myDice, level: armor.value, for (let shield of rollData.vehicleShieldList) {
img: `systems/fvtt-pegasus-rpg/images/dice/${myDice}.webp` if (shield.applied) {
} newDicePool = newDicePool.concat( this.buildDicePool("vehicle-shield", shield.value, 0))
newDicePool.push(newDice)
}
} }
} }
rollData.dicePool = newDicePool rollData.dicePool = newDicePool
@ -169,56 +168,41 @@ export class PegasusUtility {
let newDicePool = rollData.dicePool.filter(dice => dice.name != "damage") let newDicePool = rollData.dicePool.filter(dice => dice.name != "damage")
for (let weapon of rollData.weaponsList) { for (let weapon of rollData.weaponsList) {
if (weapon.applied && weapon.type == "damage") { if (weapon.applied && weapon.type == "damage") {
let diceKey = PegasusUtility.getDiceFromLevel(weapon.value) newDicePool = newDicePool.concat( this.buildDicePool("damage", weapon.value, 0))
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)
}
} }
} }
for (let weapon of rollData.vehicleWeapons) {
if (weapon.applied) {
newDicePool = newDicePool.concat( this.buildDicePool("damage", weapon.value, 0))
}
}
rollData.dicePool = newDicePool
}
}
/* -------------------------------------------- */
static updateStatDicePool(rollData) {
let newDicePool = rollData.dicePool.filter(dice => dice.name != "stat")
let statDice = rollData.dicePool.find(dice => dice.name == "stat")
if (statDice.level > 0) {
newDicePool = newDicePool.concat( this.buildDicePool( "stat", rollData.statDicesLevel, statDice.mod))
}
if (rollData.vehicleStat) {
newDicePool = rollData.dicePool.filter(dice => dice.name != "vehiclestat")
if (rollData.vehicleStat.currentlevel > 0 ) {
newDicePool = newDicePool.concat( this.buildDicePool( "vehiclestat", rollData.vehicleStat.currentlevel, 0))
}
rollData.dicePool = newDicePool rollData.dicePool = newDicePool
} }
} }
/* -------------------------------------------- */
static updateStatDicePool( rollData) {
let newDicePool = rollData.dicePool.filter(dice => dice.name != "stat")
let statDice = rollData.dicePool.find(dice => dice.name == "stat")
if (statDice.level > 0) {
let diceKey = PegasusUtility.getDiceFromLevel(rollData.statDicesLevel)
let diceList = diceKey.split(" ")
let mod = statDice.mod
for (let myDice of diceList) {
myDice = myDice.trim()
let newDice = {
name: "stat", key: myDice, level: PegasusUtility.getLevelFromDice(myDice), mod: mod,
img: `systems/fvtt-pegasus-rpg/images/dice/${myDice}.webp`
}
mod = 0 // Only first dice has modifier
newDicePool.push(newDice)
}
}
rollData.dicePool = newDicePool
}
/* -------------------------------------------- */ /* -------------------------------------------- */
static updateSpecDicePool(rollData) { static updateSpecDicePool(rollData) {
let newDicePool = rollData.dicePool.filter(dice => dice.name != "spec") let newDicePool = rollData.dicePool.filter(dice => dice.name != "spec")
if (rollData.specDicesLevel > 0) { if (rollData.specDicesLevel > 0) {
let diceKey = PegasusUtility.getDiceFromLevel(rollData.specDicesLevel) newDicePool = newDicePool.concat( this.buildDicePool( "spec", rollData.specDicesLevel, 0))
let diceList = diceKey.split(" ")
for (let myDice of diceList) {
myDice = myDice.trim()
let newDice = {
name: "spec", key: myDice, level: PegasusUtility.getLevelFromDice(myDice),
img: `systems/fvtt-pegasus-rpg/images/dice/${myDice}.webp`
}
newDicePool.push(newDice)
}
} }
rollData.dicePool = newDicePool rollData.dicePool = newDicePool
} }
@ -399,7 +383,7 @@ export class PegasusUtility {
this.rollPegasus(rollData) this.rollPegasus(rollData)
character.modifyHeroLevelRemaining(-1) character.modifyHeroLevelRemaining(-1)
} else { } else {
ui.notifications.warn(`No more Hero Level for ${actor.name} ! Unable to reroll.`) ui.notifications.warn(`No more Hero Level for ${character.name} ! Unable to reroll.`)
} }
} }
} }
@ -410,7 +394,7 @@ export class PegasusUtility {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static targetToken( user, token, flag) { static targetToken(user, token, flag) {
if (flag) { if (flag) {
token.actor.checkIfPossible() token.actor.checkIfPossible()
} }
@ -463,7 +447,7 @@ export class PegasusUtility {
static async getEffectFromCompendium(effectName) { static async getEffectFromCompendium(effectName) {
effectName = effectName.toLowerCase() effectName = effectName.toLowerCase()
let effect = game.items.contents.find(item => item.type == 'effect' && item.name.toLowerCase() == effectName) let effect = game.items.contents.find(item => item.type == 'effect' && item.name.toLowerCase() == effectName)
if (!effect ) { if (!effect) {
let effects = await this.loadCompendium('fvtt-pegasus-rpg.effects', item => item.name.toLowerCase() == effectName) let effects = await this.loadCompendium('fvtt-pegasus-rpg.effects', item => item.name.toLowerCase() == effectName)
let objs = effects.map(i => i.toObject()) let objs = effects.map(i => i.toObject())
effect = objs[0] effect = objs[0]
@ -636,7 +620,7 @@ export class PegasusUtility {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static removeForeignEffect( effectData) { static removeForeignEffect(effectData) {
if (game.user.isGM) { if (game.user.isGM) {
console.log("Remote removal of effects", effectData) console.log("Remote removal of effects", effectData)
let actor = game.canvas.tokens.get(effectData.defenderTokenId).actor let actor = game.canvas.tokens.get(effectData.defenderTokenId).actor
@ -714,7 +698,7 @@ export class PegasusUtility {
if (effect.foreign) { if (effect.foreign) {
if (game.user.isGM) { if (game.user.isGM) {
this.removeForeignEffect(effect) this.removeForeignEffect(effect)
} else { } else {
game.socket.emit("system.fvtt-pegasus-rpg", { msg: "msg_gm_remove_effect", data: effect }) game.socket.emit("system.fvtt-pegasus-rpg", { msg: "msg_gm_remove_effect", data: effect })
} }
} else { } else {
@ -767,7 +751,6 @@ export class PegasusUtility {
/* -------------------------------------------- */ /* -------------------------------------------- */
static async rollPegasus(rollData) { static async rollPegasus(rollData) {
let actor = game.actors.get(rollData.actorId) let actor = game.actors.get(rollData.actorId)
let diceFormulaTab = [] let diceFormulaTab = []
@ -815,6 +798,8 @@ export class PegasusUtility {
// And save the roll // And save the roll
this.saveRollData(rollData) this.saveRollData(rollData)
actor.lastRoll = rollData actor.lastRoll = rollData
console.log("Rolldata performed ", rollData, diceFormula)
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -905,7 +890,11 @@ export class PegasusUtility {
static async searchItem(dataItem) { static async searchItem(dataItem) {
let item let item
if (dataItem.pack) { if (dataItem.pack) {
item = await fromUuid("Compendium." + dataItem.pack + "." + dataItem.id) let id = dataItem.id || dataItem._id
let items = await this.loadCompendium( dataItem.pack, item => item.id == id)
//console.log(">>>>>> PACK", items)
item = items[0] || undefined
//item = await fromUuid(dataItem.pack + "." + id)
} else { } else {
item = game.items.get(dataItem.id) item = game.items.get(dataItem.id)
} }
@ -968,10 +957,12 @@ export class PegasusUtility {
effectsList: [], effectsList: [],
armorsList: [], armorsList: [],
weaponsList: [], weaponsList: [],
vehicleWeapons: [],
equipmentsList: [], equipmentsList: [],
vehicleShieldList: [],
optionsDiceList: PegasusUtility.getOptionsDiceList() optionsDiceList: PegasusUtility.getOptionsDiceList()
} }
if ( !isInit) { // For init, do not display target hindrances if (!isInit) { // For init, do not display target hindrances
PegasusUtility.updateWithTarget(rollData) PegasusUtility.updateWithTarget(rollData)
} }
return rollData return rollData
@ -981,7 +972,7 @@ export class PegasusUtility {
static updateWithTarget(rollData) { static updateWithTarget(rollData) {
let target = PegasusUtility.getTarget() let target = PegasusUtility.getTarget()
if (target) { if (target) {
console.log("TARGET ", target) console.log("TARGET ", target)
let defenderActor = target.actor let defenderActor = target.actor
rollData.defenderTokenId = target.id rollData.defenderTokenId = target.id
//rollData.attackerId = this.id //rollData.attackerId = this.id

View File

@ -40,6 +40,10 @@ export class PegasusVehicleSheet extends ActorSheet {
effects: this.object.effects.map(e => foundry.utils.deepClone(e.data)), effects: this.object.effects.map(e => foundry.utils.deepClone(e.data)),
limited: this.object.limited, limited: this.object.limited,
optionsDiceList: PegasusUtility.getOptionsDiceList(), optionsDiceList: PegasusUtility.getOptionsDiceList(),
vmsAvailable: objectData.system.modules.totalvms - objectData.system.modules.vmsused,
avgNRG: objectData.system.statistics.pc.maxnrg - objectData.system.statistics.pc.curnrg,
crewList: this.actor.getCrewList(),
totalCost: this.actor.getTotalCost(),
optionsLevel: PegasusUtility.getOptionsLevel(), optionsLevel: PegasusUtility.getOptionsLevel(),
subActors: duplicate(this.actor.getSubActors()), subActors: duplicate(this.actor.getSubActors()),
effects: duplicate(this.actor.getEffects()), effects: duplicate(this.actor.getEffects()),
@ -116,8 +120,19 @@ export class PegasusVehicleSheet extends ActorSheet {
html.find('.current-speed-change').click(ev => { html.find('.current-speed-change').click(ev => {
let speed = ev.currentTarget.value let speed = ev.currentTarget.value
this.actor.manageCurrentSpeed(speed) this.actor.manageCurrentSpeed(speed)
}); })
html.find('.vehicle-module-activate').click(ev => {
const li = $(ev.currentTarget).parents(".item")
let itemId = li.data("item-id")
this.actor.activateVehicleModule( itemId)
});
html.find('.vehicle-weapon-activate').click(ev => {
const li = $(ev.currentTarget).parents(".item")
let itemId = li.data("item-id")
this.actor.activateVehicleModule( itemId)
});
html.find('.equip-activate').click(ev => { html.find('.equip-activate').click(ev => {
const li = $(ev.currentTarget).parents(".item") const li = $(ev.currentTarget).parents(".item")
let itemId = li.data("item-id") let itemId = li.data("item-id")
@ -134,18 +149,11 @@ export class PegasusVehicleSheet extends ActorSheet {
let itemId = li.data("item-id"); let itemId = li.data("item-id");
this.actor.perkEffectUsed( itemId) this.actor.perkEffectUsed( itemId)
}); });
html.find('.subactor-edit').click(ev => { html.find('.member-delete').click(ev => {
const li = $(ev.currentTarget).parents(".item"); const li = $(ev.currentTarget).parents(".item")
let actorId = li.data("actor-id"); let actorId = li.data("actor-id")
let actor = game.actors.get( actorId ); this.actor.delCrew(actorId)
actor.sheet.render(true);
});
html.find('.subactor-delete').click(ev => {
const li = $(ev.currentTarget).parents(".item");
let actorId = li.data("actor-id");
this.actor.delSubActor(actorId);
}); });
html.find('.quantity-minus').click(event => { html.find('.quantity-minus').click(event => {
@ -156,10 +164,10 @@ export class PegasusVehicleSheet extends ActorSheet {
const li = $(event.currentTarget).parents(".item"); const li = $(event.currentTarget).parents(".item");
this.actor.incDecQuantity( li.data("item-id"), +1 ); this.actor.incDecQuantity( li.data("item-id"), +1 );
} ) } )
html.find('.current-nrg-minus').click(event => { html.find('.vehicle-current-nrg-minus').click(event => {
this.actor.incDecNRG( -1 ); this.actor.incDecNRG( -1 );
} ) } )
html.find('.current-nrg-plus').click(event => { html.find('.vehicle-current-nrg-plus').click(event => {
this.actor.incDecNRG( 1 ); this.actor.incDecNRG( 1 );
} ) } )
@ -193,23 +201,24 @@ export class PegasusVehicleSheet extends ActorSheet {
html.find('.generic-pool-roll').click((event) => { html.find('.generic-pool-roll').click((event) => {
this.openGenericRoll() this.openGenericRoll()
} ); } );
html.find('.attack-melee').click((event) => { html.find('.attack-melee').click((event) => {
this.actor.rollPool( 'com', false, "melee-atk"); this.actor.rollPoolFromVehicle( 'com', false, "melee-atk")
});
html.find('.attack-ranged').click((event) => {
this.actor.rollPool( 'agi', false, "ranged-atk");
});
html.find('.defense-roll').click((event) => {
this.actor.rollPool( 'def', true);
}); });
html.find('.damage-melee').click((event) => { html.find('.damage-melee').click((event) => {
this.actor.rollPool( 'str', false, "melee-dmg"); this.actor.rollPoolFromVehicle( 'str', false, "melee-dmg")
});
html.find('.attack-ranged').click((event) => {
this.actor.rollPoolFromVehicle( 'agi', false, "ranged-atk")
}); });
html.find('.damage-ranged').click((event) => { html.find('.damage-ranged').click((event) => {
this.actor.rollPool( 'per', false, "ranged-dmg"); this.actor.rollPoolFromVehicle( 'per', false, "ranged-dmg");
});
html.find('.defense-roll').click((event) => {
this.actor.rollPoolFromVehicle( 'def', true, "defence");
}); });
html.find('.damage-resistance').click((event) => { html.find('.damage-resistance').click((event) => {
this.actor.rollPool( 'phy', false, "dmg-res"); this.actor.rollVehicleDamageResistance( );
}); });
html.find('.roll-stat').click((event) => { html.find('.roll-stat').click((event) => {
@ -267,7 +276,14 @@ export class PegasusVehicleSheet extends ActorSheet {
const fieldName = $(ev.currentTarget).data("field-name"); const fieldName = $(ev.currentTarget).data("field-name");
let value = Number(ev.currentTarget.value); let value = Number(ev.currentTarget.value);
this.actor.update( { [`${fieldName}`]: value } ); this.actor.update( { [`${fieldName}`]: value } );
}); })
html.find('.member-view').click((event) => {
const li = $(event.currentTarget).parents(".item")
let actorId = li.data("actor-id")
const actor = game.actors.get( actorId )
actor.sheet.render(true)
})
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -286,12 +302,23 @@ export class PegasusVehicleSheet extends ActorSheet {
if (item == undefined) { if (item == undefined) {
item = this.actor.items.get( dragData.uuid ) item = this.actor.items.get( dragData.uuid )
} }
let ret = await this.actor.preprocessItem( event, item, true ) let ret = await this.actor.preprocessItemVehicle( event, item, true )
if ( ret ) { if ( ret ) {
super._onDropItem(event, dragData) super._onDropItem(event, dragData)
} }
} }
/* -------------------------------------------- */
async _onDropActor(event, dragData) {
const actor = fromUuidSync(dragData.uuid)
if (actor) {
this.actor.addCrew(actor.id)
}else {
ui.notifications.warn("This actor is not found and can't be added to the Vehicle's crew.")
}
super._onDropActor(event)
}
/* -------------------------------------------- */ /* -------------------------------------------- */
/** @override */ /** @override */
_updateObject(event, formData) { _updateObject(event, formData) {

View File

@ -1,6 +1,5 @@
{ {
"description": "Pegasus RPG system for FoundryVTT", "description": "Pegasus RPG system for FoundryVTT",
"download": "https://www.uberwald.me/gitea/uberwald/fvtt-pegasus-rpg/archive/fvtt-pegasus-rpg-v10.0.6.zip",
"esmodules": [ "esmodules": [
"modules/pegasus-main.js" "modules/pegasus-main.js"
], ],
@ -24,7 +23,7 @@
"manifest": "https://www.uberwald.me/gitea/uberwald/fvtt-pegasus-rpg/raw/branch/master/system.json", "manifest": "https://www.uberwald.me/gitea/uberwald/fvtt-pegasus-rpg/raw/branch/master/system.json",
"compatibility": { "compatibility": {
"minimum": "10", "minimum": "10",
"verified": "10.284", "verified": "10.285",
"maximum": "10" "maximum": "10"
}, },
"id": "fvtt-pegasus-rpg", "id": "fvtt-pegasus-rpg",
@ -254,6 +253,7 @@
], ],
"title": "Pegasus RPG", "title": "Pegasus RPG",
"url": "https://www.uberwald.me/data/files/fvtt-pegasus-rpg", "url": "https://www.uberwald.me/data/files/fvtt-pegasus-rpg",
"version": "10.0.6", "version": "10.0.15",
"download": "https://www.uberwald.me/gitea/uberwald/fvtt-pegasus-rpg/archive/fvtt-pegasus-rpg-v10.0.15.zip",
"background": "systems/fvtt-pegasus-rpg/images/ui/pegasus_welcome_page.webp" "background": "systems/fvtt-pegasus-rpg/images/ui/pegasus_welcome_page.webp"
} }

View File

@ -10,6 +10,7 @@
"name": "", "name": "",
"age": 0, "age": 0,
"size": "", "size": "",
"sizenum": 0,
"weight": "", "weight": "",
"hair": "", "hair": "",
"sex": "", "sex": "",
@ -199,7 +200,9 @@
"description": "" "description": ""
}, },
"vehicle": { "vehicle": {
"subactors": [], "crew": [],
"crewmax": 0,
"crewmin": 0,
"statistics": { "statistics": {
"fc": { "fc": {
"label": "FC", "label": "FC",
@ -232,6 +235,7 @@
"currentlevel": 0, "currentlevel": 0,
"avgnrg": 0, "avgnrg": 0,
"curnrg": 0, "curnrg": 0,
"maxnrg": 0,
"col": 2 "col": 2
}, },
"mr": { "mr": {
@ -265,7 +269,7 @@
"activatedmoduleenergy": 0, "activatedmoduleenergy": 0,
"vdp": 0, "vdp": 0,
"vehiculevalue": 0, "vehiculevalue": 0,
"availablevms": 0, "totalvms": 0,
"vmsused": 0, "vmsused": 0,
"totalcost": 0 "totalcost": 0
}, },
@ -675,6 +679,7 @@
"range": "", "range": "",
"idr": "", "idr": "",
"cost": 0, "cost": 0,
"size": 0,
"space": 0 "space": 0
}, },
"vehicleweaponmodule": { "vehicleweaponmodule": {
@ -686,12 +691,15 @@
"effects": [], "effects": [],
"damagedicevalue": "", "damagedicevalue": "",
"damagetype": "", "damagetype": "",
"damagetypelevel": 0,
"aoe": "", "aoe": "",
"range": "", "range": "",
"turret": "", "turret": "",
"linkedweapon": "", "linkedweapon": "",
"idr": "", "idr": "",
"cost": 0 "cost": 0,
"extradamage": false,
"extradamagevalue": 0
} }
} }
} }

View File

@ -839,17 +839,16 @@
<div> <div>
<ul class="item-list alternate-list"> <ul class="item-list alternate-list">
<li class="item flexrow"> <li class="item flexrow">
<label class="generic-label">Origin</label> <label class="generic-label">Sex</label>
<input type="text" class="" name="system.biodata.origin" value="{{data.biodata.origin}}" <input type="text" class="" name="system.biodata.sex" value="{{data.biodata.sex}}" data-dtype="String" />
data-dtype="String" />
</li> </li>
<li class="item flexrow"> <li class="item flexrow">
<label class="generic-label">Age</label> <label class="generic-label">Age</label>
<input type="text" class="" name="system.biodata.age" value="{{data.biodata.age}}" data-dtype="String" /> <input type="text" class="" name="system.biodata.age" value="{{data.biodata.age}}" data-dtype="String" />
</li> </li>
<li class="item flexrow"> <li class="item flexrow">
<label class="generic-label">Height</label> <label class="generic-label">Height/Weight</label>
<input type="text" class="" name="system.biodata.size" value="{{data.biodata.size}}" data-dtype="String" /> <input type="text" class="" name="system.biodata.weight" value="{{data.biodata.weight}}" data-dtype="String" />
</li> </li>
<li class="item flexrow"> <li class="item flexrow">
<label class="generic-label">Eyes</label> <label class="generic-label">Eyes</label>
@ -864,13 +863,14 @@
<div> <div>
<ul> <ul>
<li class="flexrow item"> <li class="flexrow item">
<label class="generic-label">Weight</label> <label class="generic-label">Size</label>
<input type="text" class="" name="system.biodata.weight" value="{{data.biodata.weight}}" <input type="text" class="" name="system.biodata.sizenum" value="{{data.biodata.sizenum}}"
data-dtype="String" /> data-dtype="Number" />
</li> </li>
<li class="flexrow item"> <li class="flexrow item">
<label class="generic-label">Sex</label> <label class="generic-label">Origin</label>
<input type="text" class="" name="system.biodata.sex" value="{{data.biodata.sex}}" data-dtype="String" /> <input type="text" class="" name="system.biodata.origin" value="{{data.biodata.origin}}"
data-dtype="String" />
</li> </li>
<li class="flexrow item"> <li class="flexrow item">
<label class="generic-label">Preferred Hand</label> <label class="generic-label">Preferred Hand</label>
@ -986,6 +986,14 @@
<label class="attribute-value checkbox"><input type="checkbox" class="change-desires" <label class="attribute-value checkbox"><input type="checkbox" class="change-desires"
name="system.biodata.desiresactive" {{checked data.biodata.desiresactive}} /> Active ?</label> name="system.biodata.desiresactive" {{checked data.biodata.desiresactive}} /> Active ?</label>
</li> </li>
<li class="flexrow">
<label class="short-label">Morality : </label>
<input type="text" class="" name="system.biodata.morality" value="{{data.biodata.morality}}" data-dtype="Number" />
</li>
<li class="flexrow">
<label class="short-label">Morality threshold : </label>
<input type="text" class="" name="system.biodata.moralitythreshold" value="{{data.biodata.moralitythreshold}}" disabled data-dtype="Number" />
</li>
</ul> </ul>
<h3>Catchphrase : </h3> <h3>Catchphrase : </h3>
@ -1026,14 +1034,6 @@
<label class="short-label">Bonus selection : </label> <label class="short-label">Bonus selection : </label>
<input type="text" class="" name="system.biodata.bonusselection" value="{{data.biodata.bonusselection}}" data-dtype="String" /> <input type="text" class="" name="system.biodata.bonusselection" value="{{data.biodata.bonusselection}}" data-dtype="String" />
</li> </li>
<li class="flexrow">
<label class="short-label">Morality : </label>
<input type="text" class="" name="system.biodata.morality" value="{{data.biodata.morality}}" data-dtype="Number" />
</li>
<li class="flexrow">
<label class="short-label">Morality threshold : </label>
<input type="text" class="" name="system.biodata.moralitythreshold" value="{{data.biodata.moralitythreshold}}" disabled data-dtype="Number" />
</li>
<li class="flexrow"> <li class="flexrow">
<label class="short-label">Hero Level (max) : </label> <label class="short-label">Hero Level (max) : </label>
<select class="status-small-label color-class-common" type="text" name="system.biodata.maxlevelremaining" value="{{data.biodata.maxlevelremaining}}" data-dtype="Number" {{#unless @root.editScore}}disabled{{/unless}}> <select class="status-small-label color-class-common" type="text" name="system.biodata.maxlevelremaining" value="{{data.biodata.maxlevelremaining}}" data-dtype="Number" {{#unless @root.editScore}}disabled{{/unless}}>

View File

@ -25,7 +25,7 @@
<li>Weapon Damage Dice : {{weaponDamageDice}}</li> <li>Weapon Damage Dice : {{weaponDamageDice}}</li>
{{/if}} {{/if}}
{{#if isResistance}} {{#if isResistance}}
<li>Armor Resistance Dice : {{armor.data.resistanceDice}}</li> <li>Armor Resistance Dice : {{armor.system.resistanceDice}}</li>
{{/if}} {{/if}}
{{#if stat}} {{#if stat}}
<li>Statistic : {{stat.label}}</li> <li>Statistic : {{stat.label}}</li>
@ -38,7 +38,11 @@
<li>Weapon : {{weaponName}}</li> <li>Weapon : {{weaponName}}</li>
{{/if}} {{/if}}
{{#if weapon}} {{#if weapon}}
<li>Damage type : {{weapon.weapon.data.damagetype}} {{weapon.weapon.data.damagetypelevel}}</li> {{#if vehicle}}
<li>Damage type : {{weapon.weapon.system.damagetype}}</li>
{{else}}
<li>Damage type : {{weapon.weapon.system.damagetype}} {{weapon.weapon.system.damagetypelevel}}</li>
{{/if}}
{{/if}} {{/if}}
{{#if isResistance}} {{#if isResistance}}

View File

@ -124,7 +124,7 @@
<input type="text" class="padd-right" name="system.deactivatedtext" value="{{data.deactivatedtext}}" data-dtype="String"/> <input type="text" class="padd-right" name="system.deactivatedtext" value="{{data.deactivatedtext}}" data-dtype="String"/>
</li> </li>
<li class="flexrow"><label class="generic-label">Power Level Cost</label> <li class="flexrow"><label class="generic-label">PPP Used to Purchase</label>
<input type="text" class="input-numeric-short padd-right" name="system.powerlevelcost" value="{{data.powerlevelcost}}" <input type="text" class="input-numeric-short padd-right" name="system.powerlevelcost" value="{{data.powerlevelcost}}"
data-dtype="Number" /> data-dtype="Number" />
</li> </li>

View File

@ -29,7 +29,7 @@
<input type="text" class="" name="system.ad" value="{{data.ad}}" data-dtype="Number"/> <input type="text" class="" name="system.ad" value="{{data.ad}}" data-dtype="Number"/>
</li> </li>
<li class="flexrow"><label class="generic-label">Top Speed (TS)</label> <li class="flexrow"><label class="generic-label">Top Speed (TS) bonus</label>
<input type="text" class="" name="system.topspeed" value="{{data.topspeed}}" data-dtype="Number"/> <input type="text" class="" name="system.topspeed" value="{{data.topspeed}}" data-dtype="Number"/>
</li> </li>

View File

@ -50,7 +50,7 @@
<label class="attribute-value checkbox"><input type="checkbox" name="system.activated" {{checked data.activated}}/></label> <label class="attribute-value checkbox"><input type="checkbox" name="system.activated" {{checked data.activated}}/></label>
</li> </li>
<li class="flexrow"><label class="generic-label">NRG</label> <li class="flexrow"><label class="generic-label">NRG Cost</label>
<input type="text" class="" name="system.nrg" value="{{data.nrg}}" data-dtype="Number"/> <input type="text" class="" name="system.nrg" value="{{data.nrg}}" data-dtype="Number"/>
</li> </li>

View File

@ -67,7 +67,21 @@
</select> </select>
</li> </li>
<li class="flexrow"><label class="generic-label">Optimal Range</label> <li class="flexrow"><label class="generic-label">Damage type level</label>
<input type="text" class="" name="system.damagetypelevel" value="{{data.damagetypelevel}}" data-dtype="Number"/>
</li>
<li class="flexrow"><label class="generic-label">Extra damage ?</label>
<label class="attribute-value checkbox"><input type="checkbox" name="system.extradamage" {{checked data.extradamage}}/></label>
</li>
{{#if data.extradamage}}
<li class="flexrow"><label class="generic-label">Extra damage value (D12)</label>
<input type="text" class="" name="system.extradamagevalue" value="{{data.extradamagevalue}}" data-dtype="Number"/>
</li>
{{/if}}
<li class="flexrow"><label class="generic-label">Optimal Range</label>
<select class="competence-base flexrow" type="text" name="system.range" value="{{data.range}}" data-dtype="String"> <select class="competence-base flexrow" type="text" name="system.range" value="{{data.range}}" data-dtype="String">
{{#select data.range}} {{#select data.range}}
{{> systems/fvtt-pegasus-rpg/templates/partial-options-range.html notapplicable=true}} {{> systems/fvtt-pegasus-rpg/templates/partial-options-range.html notapplicable=true}}

View File

@ -125,3 +125,33 @@
</ul> </ul>
{{/if}} {{/if}}
{{#if (notEmpty vehicleWeapons)}}
<label>Vehicle Weapons</label>
<ul>
{{#each vehicleWeapons as |weapon idx|}}
<li class="flex-group-left">
<label class="attribute-value checkbox"><input type="checkbox" class="vehicle-weapon-clicked" id="vehicle-weapon-{{idx}}" data-vehicle-weapon-idx="{{idx}}" {{checked weapon.applied}}/></label>
<label class="generic-label padd-right">{{weapon.label}} ({{weapon.value}})</label>
</li>
{{/each}}
</ul>
{{/if}}
{{#if (notEmpty vehicleShieldList)}}
<label>Vehicle Shields</label>
<ul>
{{#each vehicleShieldList as |shield idx|}}
<li class="flex-group-left">
<label class="attribute-value checkbox"><input type="checkbox" class="vehicle-shield-clicked" id="vehicle-shield-{{idx}}" data-vehicle-shield-idx="{{idx}}" {{checked shield.applied}}/></label>
<label class="generic-label padd-right">{{shield.label}} ({{shield.value}})</label>
</li>
{{/each}}
</ul>
{{/if}}

View File

@ -19,7 +19,7 @@
<span class="item-name-label-long">&nbsp;</span> <span class="item-name-label-long">&nbsp;</span>
<span class="item-field-label-long"> <span class="item-field-label-long">
<select type="text" name="system.arcs.{{idx}}.topspeed" value="{{arc.topspeed}}" data-dtype="String"> <select type="text" name="system.arcs.{{idx}}.topspeed" value="{{arc.topspeed}}" data-dtype="String" disabled>
{{#select arc.topspeed}} {{#select arc.topspeed}}
{{> systems/fvtt-pegasus-rpg/templates/partial-options-vehicle-speed.html}} {{> systems/fvtt-pegasus-rpg/templates/partial-options-vehicle-speed.html}}
{{/select}} {{/select}}

View File

@ -9,9 +9,13 @@
data-stat-key="{{key}}">{{upper stat.abbrev}}</a></h4> data-stat-key="{{key}}">{{upper stat.abbrev}}</a></h4>
</span> </span>
<select class="status-small-label color-class-common" type="text" name="system.statistics.{{key}}.level" <select class="status-small-label color-class-common" type="text" name="system.statistics.{{key}}.level"
value="{{stat.level}}" data-dtype="Number" {{#unless @root.editScore}}disabled{{/unless}}> value="{{stat.level}}" data-dtype="Number" disabled>
{{#select stat.level}} {{#select stat.level}}
{{{@root.optionsDiceList}}} {{#if (eq key "ad")}}
{{{@root.optionsLevel}}}
{{else}}
{{{@root.optionsDiceList}}}
{{/if}}
{{/select}} {{/select}}
</select> </select>
</div> </div>
@ -20,8 +24,12 @@
<select class="status-small-label color-class-common" type="text" name="system.statistics.{{key}}.currentlevel" <select class="status-small-label color-class-common" type="text" name="system.statistics.{{key}}.currentlevel"
value="{{stat.currentlevel}}" data-dtype="Number" {{#unless @root.editScore}}disabled{{/unless}}> value="{{stat.currentlevel}}" data-dtype="Number" {{#unless @root.editScore}}disabled{{/unless}}>
{{#select stat.currentlevel}} {{#select stat.currentlevel}}
{{{@root.optionsLevel}}} {{#if (eq key "ad")}}
{{/select}} {{{@root.optionsLevel}}}
{{else}}
{{{@root.optionsDiceList}}}
{{/if}}
{{/select}}
</select> </select>
</div> </div>
{{#if (eq key "man")}} {{#if (eq key "man")}}
@ -45,10 +53,16 @@
{{#if (eq key "pc")}} {{#if (eq key "pc")}}
<div class="flexrow stat-text-white"> <div class="flexrow stat-text-white">
<span class="stat-label stat-margin" name="{{key}}">Av NRG</span>
<input type="text" class="input-numeric-short" name="system.statistics.{{key}}.avgnrg" value="{{stat.avgnrg}}" data-dtype="Number" />
<span class="stat-label stat-margin" name="{{key}}">Cur NRG</span> <span class="stat-label stat-margin" name="{{key}}">Cur NRG</span>
<input type="text" class="input-numeric-short" name="system.statistics.{{key}}.curnrg" value="{{stat.curnrg}}" data-dtype="Number" /> <input type="text" class="input-numeric-short" name="system.statistics.{{key}}.curnrg" value="{{stat.curnrg}}" data-dtype="Number" />
<span class="padd-right status-small-label no-grow">
<a class="vehicle-current-nrg-plus plus-minus-button">+</a>
<a class="vehicle-current-nrg-minus plus-minus-button">&nbsp;-</a>
</span>
<span class="stat-label stat-margin" name="{{key}}">Av NRG</span>
<input type="text" class="input-numeric-short" value="{{@root.avgNRG}}" data-dtype="Number" disabled/>
<span class="stat-label stat-margin" name="{{key}}">Max NRG</span>
<input type="text" class="input-numeric-short" name="system.statistics.{{key}}.maxnrg" value="{{stat.maxnrg}}" data-dtype="Number" disabled />
</div> </div>
{{/if}} {{/if}}

View File

@ -3,7 +3,7 @@
{{#if img}} {{#if img}}
<img class="actor-icon" src="{{img}}" data-edit="img" title="{{name}}" /> <img class="actor-icon" src="{{img}}" data-edit="img" title="{{name}}" />
{{/if}} {{/if}}
<h1 class="dialog-roll-title roll-dialog-header">{{title}}</h1> <h1 class="dialog-roll-title roll-dialog-header">{{title}} {{#if vehicle}} from {{vehicle.name}} {{/if}}</h1>
</header> </header>
<div class="grid grid-2col"> <div class="grid grid-2col">
@ -14,7 +14,7 @@
{{else}} {{else}}
<div class="flexrow"> <div class="flexrow">
<span class="roll-dialog-label">Stat Dice ({{stat.label}}) : </span> <span class="roll-dialog-label">{{upper stat.label}} :</span>
<select class="roll-dialog-label" id="statDicesLevel" type="text" name="statDicesLevel" <select class="roll-dialog-label" id="statDicesLevel" type="text" name="statDicesLevel"
value="{{statDicesLevel}}" data-dtype="Number" {{#if statKey}}disabled{{/if}}> value="{{statDicesLevel}}" data-dtype="Number" {{#if statKey}}disabled{{/if}}>
{{#select statDicesLevel}} {{#select statDicesLevel}}
@ -24,6 +24,19 @@
<span class="small-label">&nbsp;+&nbsp;{{statMod}}</span> <span class="small-label">&nbsp;+&nbsp;{{statMod}}</span>
</div> </div>
{{#if statVehicle}}
<div class="flexrow">
<span class="roll-dialog-label">{{upper statVehicle.label}} :</span>
<select class="roll-dialog-label" id="statVehicleLevel" type="text" name="statVehicleLevel"
value="{{statVehicle.currentlevel}}" data-dtype="Number" {{#if statKey}}disabled{{/if}}>
{{#select statVehicle.currentlevel}}
{{{optionsDiceList}}}
{{/select}}
</select>
<span class="small-label">&nbsp;</span>
</div>
{{/if}}
{{#if specList}} {{#if specList}}
<div class="flexrow"> <div class="flexrow">
<span class="roll-dialog-label">Spec : </span> <span class="roll-dialog-label">Spec : </span>

View File

@ -49,6 +49,7 @@
<nav class="sheet-tabs tabs" data-group="primary"> <nav class="sheet-tabs tabs" data-group="primary">
<a class="item" data-tab="combat">Combat</a> <a class="item" data-tab="combat">Combat</a>
<a class="item" data-tab="modules">Vehicle Modules</a> <a class="item" data-tab="modules">Vehicle Modules</a>
<a class="item" data-tab="crew">Crew</a>
<a class="item" data-tab="cargo">Cargo Hold</a> <a class="item" data-tab="cargo">Cargo Hold</a>
<a class="item" data-tab="details">Vehicle Details</a> <a class="item" data-tab="details">Vehicle Details</a>
</nav> </nav>
@ -139,6 +140,7 @@
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
<div class="flexrow"> <div class="flexrow">
@ -248,13 +250,39 @@
</div> </div>
</div> </div>
{{!-- Other Tab --}} {{!-- Modules Tab --}}
<div class="tab items" data-group="primary" data-tab="modules"> <div class="tab items" data-group="primary" data-tab="modules">
<div class="stat-item">
<ul class="stat-list alternate-list">
<li class="item stat flexrow list-item">
<span class="generic-label small-label "><strong>VDP</strong></span>
<input type="text" class="input-numeric-short padd-right" name="system.modules.vdp" value="{{data.modules.vdp}}"
data-dtype="Number" />
<span class="generic-label small-label"><strong>Vehicle Value</strong></span>
<input type="text" class="input-numeric-short" name="system.modules.vehiculevalue" value="{{data.modules.vehiculevalue}}"
data-dtype="Number" />
<span class="generic-label small-label"><strong>Total cost</strong></span>
<input type="text" class="" value="{{totalCost}}"
data-dtype="Number" disabled />
<span class="generic-label small-label "><strong>VMS</strong></span>
<span class="generic-label small-label">Total</span>
<input type="text" class="input-numeric-short" name="system.modules.totalvms" value="{{data.modules.totalvms}}"
data-dtype="Number" disabled />
<span class="generic-label small-label">Available</span>
<input type="text" class="input-numeric-short" name="system.modules.vmsavailable" value="{{data.modules.vmsAvailable}}"
data-dtype="Number" disabled />
<span class="generic-label small-label">Used</span>
<input type="text" class="input-numeric-short" name="system.modules.vmsused" value="{{data.modules.vmsused}}"
data-dtype="Number" disabled />
</li>
</ul>
</div>
<ul class="stat-list alternate-list"> <ul class="stat-list alternate-list">
<li class="item flexrow list-item items-title-bg"> <li class="item flexrow list-item items-title-bg">
<span class="item-name-label-header-long"> <span class="item-name-label-header-long">
<h3><label class="items-title-text">STEP 1 - HULL TYPE</label></h3> <h3><label class="items-title-text">1 - Hull</label></h3>
</span> </span>
<span class="item-field-label-short"> <span class="item-field-label-short">
<label class="short-label">Size</label> <label class="short-label">Size</label>
@ -276,7 +304,8 @@
<li class="item stat flexrow list-item list-item-shadow" data-item-id="{{hull._id}}"> <li class="item stat flexrow list-item list-item-shadow" data-item-id="{{hull._id}}">
<a class="item-edit item-name-img" title="Edit Item"><img class="sheet-competence-img" <a class="item-edit item-name-img" title="Edit Item"><img class="sheet-competence-img"
src="{{hull.img}}" /></a> src="{{hull.img}}" /></a>
<span class="item-name-label"><a class="roll-spec">{{hull.name}}</a></span> <span class="item-name-label-long"><a class="roll-spec">{{hull.name}}</a></span>
<span class="item-field-label-short">{{hull.system.size}}</span>
<span class="item-field-label-medium">{{hull.system.hulltype}}</span> <span class="item-field-label-medium">{{hull.system.hulltype}}</span>
<span class="item-field-label-short">{{hull.system.hr}}</span> <span class="item-field-label-short">{{hull.system.hr}}</span>
<span class="item-field-label-short">{{hull.system.man}}</span> <span class="item-field-label-short">{{hull.system.man}}</span>
@ -292,12 +321,12 @@
<ul class="stat-list alternate-list"> <ul class="stat-list alternate-list">
<li class="item flexrow list-item items-title-bg"> <li class="item flexrow list-item items-title-bg">
<span class="item-name-label-header-long"> <span class="item-name-label-header-long">
<h3><label class="items-title-text">STEP 2 - POWER CORE MODULE</label></h3> <h3><label class="items-title-text">2 - Power core</label></h3>
</span> </span>
<span class="item-field-label-long"> <span class="item-field-label-medium">
<label class="short-label">Power Core Type</label> <label class="short-label">Type</label>
</span> </span>
<span class="item-field-label-sjort"> <span class="item-field-label-short">
<label class="short-label">PC</label> <label class="short-label">PC</label>
</span> </span>
<span class="item-field-label-short"> <span class="item-field-label-short">
@ -308,7 +337,7 @@
<li class="item stat flexrow list-item list-item-shadow" data-item-id="{{powercore._id}}"> <li class="item stat flexrow list-item list-item-shadow" data-item-id="{{powercore._id}}">
<a class="item-edit item-name-img" title="Edit Item"><img class="sheet-competence-img" <a class="item-edit item-name-img" title="Edit Item"><img class="sheet-competence-img"
src="{{powercore.img}}" /></a> src="{{powercore.img}}" /></a>
<span class="item-name-label"><a class="roll-spec">{{powercore.name}}</a></span> <span class="item-name-label-long"><a class="roll-spec">{{powercore.name}}</a></span>
<span class="item-field-label-medium">{{powercore.system.coretype}}</span> <span class="item-field-label-medium">{{powercore.system.coretype}}</span>
<span class="item-field-label-short">{{powercore.system.pc}}</span> <span class="item-field-label-short">{{powercore.system.pc}}</span>
<span class="item-field-label-short">{{powercore.system.nrg}}</span> <span class="item-field-label-short">{{powercore.system.nrg}}</span>
@ -323,7 +352,7 @@
<ul class="stat-list alternate-list"> <ul class="stat-list alternate-list">
<li class="item flexrow list-item items-title-bg"> <li class="item flexrow list-item items-title-bg">
<span class="item-name-label-header-long"> <span class="item-name-label-header-long">
<h3><label class="items-title-text">STEP 3 - MOBILITY MODULE</label></h3> <h3><label class="items-title-text">3 -Mobility</label></h3>
</span> </span>
<span class="item-field-label-long"> <span class="item-field-label-long">
<label class="short-label">Vehicle Category</label> <label class="short-label">Vehicle Category</label>
@ -351,7 +380,7 @@
<li class="item stat flexrow list-item list-item-shadow" data-item-id="{{mobility._id}}"> <li class="item stat flexrow list-item list-item-shadow" data-item-id="{{mobility._id}}">
<a class="item-edit item-name-img" title="Edit Item"><img class="sheet-competence-img" <a class="item-edit item-name-img" title="Edit Item"><img class="sheet-competence-img"
src="{{mobility.img}}" /></a> src="{{mobility.img}}" /></a>
<span class="item-name-label"><a class="roll-spec">{{mobility.name}}</a></span> <span class="item-name-label-long"><a class="roll-spec">{{mobility.name}}</a></span>
<span class="item-field-label-long">{{mobility.system.vehiclecategory}}</span> <span class="item-field-label-long">{{mobility.system.vehiclecategory}}</span>
<span class="item-field-label-medium">{{mobility.system.quality}}</span> <span class="item-field-label-medium">{{mobility.system.quality}}</span>
<span class="item-field-label-short">{{mobility.system.mr}}</span> <span class="item-field-label-short">{{mobility.system.mr}}</span>
@ -370,7 +399,7 @@
<ul class="stat-list alternate-list"> <ul class="stat-list alternate-list">
<li class="item flexrow list-item items-title-bg"> <li class="item flexrow list-item items-title-bg">
<span class="item-name-label-header-long"> <span class="item-name-label-header-long">
<h3><label class="items-title-text">STEP 4 - PROPULSION MODULE</label></h3> <h3><label class="items-title-text">4 - Propulsion</label></h3>
</span> </span>
<span class="item-field-label-medium"> <span class="item-field-label-medium">
<label class="short-label">Quality</label> <label class="short-label">Quality</label>
@ -386,7 +415,7 @@
<li class="item stat flexrow list-item list-item-shadow" data-item-id="{{propulsion._id}}"> <li class="item stat flexrow list-item list-item-shadow" data-item-id="{{propulsion._id}}">
<a class="item-edit item-name-img" title="Edit Item"><img class="sheet-competence-img" <a class="item-edit item-name-img" title="Edit Item"><img class="sheet-competence-img"
src="{{propulsion.img}}" /></a> src="{{propulsion.img}}" /></a>
<span class="item-name-label"><a class="roll-spec">{{propulsion.name}}</a></span> <span class="item-name-label-long"><a class="roll-spec">{{propulsion.name}}</a></span>
<span class="item-field-label-medium">{{propulsion.system.quality}}</span> <span class="item-field-label-medium">{{propulsion.system.quality}}</span>
<span class="item-field-label-short">{{propulsion.system.ad}}</span> <span class="item-field-label-short">{{propulsion.system.ad}}</span>
<span class="item-field-label-short">{{propulsion.system.topspeed}}</span> <span class="item-field-label-short">{{propulsion.system.topspeed}}</span>
@ -401,9 +430,9 @@
<ul class="stat-list alternate-list"> <ul class="stat-list alternate-list">
<li class="item flexrow list-item items-title-bg"> <li class="item flexrow list-item items-title-bg">
<span class="item-name-label-header-long"> <span class="item-name-label-header-long">
<h3><label class="items-title-text">STEP 5 - COMBAT MODULE</label></h3> <h3><label class="items-title-text">5 - Combat</label></h3>
</span> </span>
<span class="item-field-label-medium"> <span class="item-field-label-long">
<label class="short-label">Quality</label> <label class="short-label">Quality</label>
</span> </span>
<span class="item-field-label-short"> <span class="item-field-label-short">
@ -414,8 +443,8 @@
<li class="item stat flexrow list-item list-item-shadow" data-item-id="{{combat._id}}"> <li class="item stat flexrow list-item list-item-shadow" data-item-id="{{combat._id}}">
<a class="item-edit item-name-img" title="Edit Item"><img class="sheet-competence-img" <a class="item-edit item-name-img" title="Edit Item"><img class="sheet-competence-img"
src="{{combat.img}}" /></a> src="{{combat.img}}" /></a>
<span class="item-name-label"><a class="roll-spec">{{combat.name}}</a></span> <span class="item-name-label-long"><a class="roll-spec">{{combat.name}}</a></span>
<span class="item-field-label-medium">{{combat.system.quality}}</span> <span class="item-field-label-long">{{combat.system.combattype}}</span>
<span class="item-field-label-short">{{combat.system.fc}}</span> <span class="item-field-label-short">{{combat.system.fc}}</span>
<div class="item-filler">&nbsp;</div> <div class="item-filler">&nbsp;</div>
<div class="item-controls item-controls-fixed"> <div class="item-controls item-controls-fixed">
@ -428,7 +457,7 @@
<ul class="stat-list alternate-list"> <ul class="stat-list alternate-list">
<li class="item flexrow list-item items-title-bg"> <li class="item flexrow list-item items-title-bg">
<span class="item-name-label-header-long"> <span class="item-name-label-header-long">
<h3><label class="items-title-text">VEHICLES MODULES</label></h3> <h3><label class="items-title-text">Vehicles modules</label></h3>
</span> </span>
<span class="item-field-label-long"> <span class="item-field-label-long">
<label class="short-label">Category</label> <label class="short-label">Category</label>
@ -453,7 +482,7 @@
<li class="item stat flexrow list-item list-item-shadow" data-item-id="{{vehiclemod._id}}"> <li class="item stat flexrow list-item list-item-shadow" data-item-id="{{vehiclemod._id}}">
<a class="item-edit item-name-img" title="Edit Item"><img class="sheet-competence-img" <a class="item-edit item-name-img" title="Edit Item"><img class="sheet-competence-img"
src="{{vehiclemod.img}}" /></a> src="{{vehiclemod.img}}" /></a>
<span class="item-name-label"><a class="roll-spec">{{vehiclemod.name}}</a></span> <span class="item-name-label-long"><a class="roll-spec">{{vehiclemod.name}}</a></span>
<span class="item-field-label-long">{{vehiclemod.system.category}}</span> <span class="item-field-label-long">{{vehiclemod.system.category}}</span>
<span class="item-field-label-long">{{vehiclemod.system.location}}</span> <span class="item-field-label-long">{{vehiclemod.system.location}}</span>
<span class="item-field-label-long">{{vehiclemod.system.security}}</span> <span class="item-field-label-long">{{vehiclemod.system.security}}</span>
@ -462,6 +491,8 @@
<span class="item-field-label-short">{{vehiclemod.system.idr}}</span> <span class="item-field-label-short">{{vehiclemod.system.idr}}</span>
<div class="item-filler">&nbsp;</div> <div class="item-filler">&nbsp;</div>
<div class="item-controls item-controls-fixed"> <div class="item-controls item-controls-fixed">
<a class="item-control vehicle-module-activate" title="Activated">{{#if vehiclemod.system.activated}}<i
class="fas fa-circle"></i>{{else}}<i class="fas fa-genderless"></i>{{/if}}</a>
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a> <a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div> </div>
</li> </li>
@ -471,7 +502,7 @@
<ul class="stat-list alternate-list"> <ul class="stat-list alternate-list">
<li class="item flexrow list-item items-title-bg"> <li class="item flexrow list-item items-title-bg">
<span class="item-name-label-header-long"> <span class="item-name-label-header-long">
<h3><label class="items-title-text">VEHICLES WEAPONS</label></h3> <h3><label class="items-title-text">Vehicles weapons</label></h3>
</span> </span>
<span class="item-field-label-long"> <span class="item-field-label-long">
<label class="short-label">Site</label> <label class="short-label">Site</label>
@ -499,7 +530,7 @@
<li class="item stat flexrow list-item list-item-shadow" data-item-id="{{weapon._id}}"> <li class="item stat flexrow list-item list-item-shadow" data-item-id="{{weapon._id}}">
<a class="item-edit item-name-img" title="Edit Item"><img class="sheet-competence-img" <a class="item-edit item-name-img" title="Edit Item"><img class="sheet-competence-img"
src="{{weapon.img}}" /></a> src="{{weapon.img}}" /></a>
<span class="item-name-label"><a class="roll-spec">{{weapon.name}}</a></span> <span class="item-name-label-long"><a class="roll-spec">{{weapon.name}}</a></span>
<span class="item-field-label-long">{{weapon.system.site}}</span> <span class="item-field-label-long">{{weapon.system.site}}</span>
<span class="item-field-label-long">{{weapon.system.location}}</span> <span class="item-field-label-long">{{weapon.system.location}}</span>
<span class="item-field-label-short">{{weapon.system.dmg}}</span> <span class="item-field-label-short">{{weapon.system.dmg}}</span>
@ -509,6 +540,8 @@
<span class="item-field-label-short">{{weapon.system.idr}}</span> <span class="item-field-label-short">{{weapon.system.idr}}</span>
<div class="item-filler">&nbsp;</div> <div class="item-filler">&nbsp;</div>
<div class="item-controls item-controls-fixed"> <div class="item-controls item-controls-fixed">
<a class="item-control vehicle-weapon-activate" title="Activated">{{#if weapon.system.activated}}<i
class="fas fa-circle"></i>{{else}}<i class="fas fa-genderless"></i>{{/if}}</a>
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a> <a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div> </div>
</li> </li>
@ -518,6 +551,43 @@
</div> </div>
{{!-- Crew Tab --}}
<div class="tab items" data-group="primary" data-tab="crew">
<div class="stat-item">
<ul class="stat-list alternate-list">
<li class="item stat flexrow list-item">
<span class="generic-label small-label "><strong>Maximum Crew Capacity</strong></span>
<input type="text" class="input-numeric-short padd-right" name="system.crewmax" value="{{data.crewmax}}"
data-dtype="Number" />
<span class="generic-label small-label"><strong>Minimum Crew Required</strong></span>
<input type="text" class="input-numeric-short" name="system.crewmin" value="{{data.crewmin}}"
data-dtype="Number" />
</li>
</ul>
</div>
<ul class="item-list alternate-list">
<li class="item flexrow list-item items-title-bg">
<span class="item-name-label-header">
<h3><label class="items-title-text">Crew</label></h3>
</span>
<div class="item-filler">&nbsp;</div>
</li>
{{#each crewList as |member key|}}
<li class="item flexrow list-item list-item-shadow" data-actor-id="{{member.id}}">
<a class="member-view item-name-img" title="View Actor"><img class="sheet-competence-img"
src="{{member.img}}" /></a>
<span class="item-name-label">{{member.name}}</span>
<div class="item-filler">&nbsp;</div>
<div class="item-controls item-controls-fixed">
<a class="item-control member-delete" title="Delete Member"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ul>
</div>
{{!-- Cargo Tab --}} {{!-- Cargo Tab --}}
<div class="tab equipment" data-group="primary" data-tab="cargo"> <div class="tab equipment" data-group="primary" data-tab="cargo">
@ -829,230 +899,8 @@
{{!-- Details Tab --}} {{!-- Details Tab --}}
<div class="tab biodata" data-group="primary" data-tab="details"> <div class="tab biodata" data-group="primary" data-tab="details">
<div class="grid grid-2col">
<div>
<ul class="item-list alternate-list">
<li class="item flexrow">
<label class="generic-label">Origin</label>
<input type="text" class="" name="system.biodata.origin" value="{{data.biodata.origin}}"
data-dtype="String" />
</li>
<li class="item flexrow">
<label class="generic-label">Age</label>
<input type="text" class="" name="system.biodata.age" value="{{data.biodata.age}}" data-dtype="String" />
</li>
<li class="item flexrow">
<label class="generic-label">Height</label>
<input type="text" class="" name="system.biodata.size" value="{{data.biodata.size}}" data-dtype="String" />
</li>
<li class="item flexrow">
<label class="generic-label">Eyes</label>
<input type="text" class="" name="system.biodata.eyes" value="{{data.biodata.eyes}}" data-dtype="String" />
</li>
<li class="item flexrow">
<label class="generic-label">Hair</label>
<input type="text" class="" name="system.biodata.hair" value="{{data.biodata.hair}}" data-dtype="String" />
</li>
</ul>
</div>
<div>
<ul>
<li class="flexrow item">
<label class="generic-label">Weight</label>
<input type="text" class="" name="system.biodata.weight" value="{{data.biodata.weight}}"
data-dtype="String" />
</li>
<li class="flexrow item">
<label class="generic-label">Sex</label>
<input type="text" class="" name="system.biodata.sex" value="{{data.biodata.sex}}" data-dtype="String" />
</li>
<li class="flexrow item">
<label class="generic-label">Preferred Hand</label>
<input type="text" class="" name="system.biodata.preferredhand" value="{{data.biodata.preferredhand}}"
data-dtype="String" />
</li>
<li class="flexrow item" data-item-id="{{race._id}}">
<label class="generic-label">Race</label>
<a class="item-edit"><img class="stat-icon" src="{{race.img}}"></a>
<input type="text" class="" name="system.biodata.racename" value="{{race.name}}" disabled
data-dtype="String" />
<div class="item-controls">
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div>
</li>
<li class="flexrow item" data-item-id="{{role._id}}">
<label class="generic-label">Role</label>
<a class="item-edit"><img class="stat-icon" src="{{role.img}}"></a>
<input type="text" class="" name="system.biodata.rolename" value="{{role.name}}" disabled
data-dtype="String" />
<div class="item-controls">
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div>
</li>
</ul>
</div>
</div>
<div>
<ul class="stat-list alternate-list">
<li class="item flexrow list-item items-title-bg">
<span class="item-name-label-header">
<h3><label class="items-title-text">Virtues</label></h3>
</span>
<span class="item-field-label-short">Status</label></span>
</li>
{{#each virtues as |virtue key|}}
<li class="item stat flexrow list-item list-item-shadow" data-arme-id="{{virtue.id}}"
data-item-id="{{virtue._id}}">
<a class="item-edit item-name-img" title="Edit Item"><img class="sheet-competence-img"
src="{{virtue.img}}" /></a>
<span class="item-name-label">{{virtue.name}}</span>
<span class="item-field-label-short"><label class="short-label">
{{#if virtue.system.activated}}
Activated
{{else}}
&nbsp;-&nbsp;
{{/if}}
</label>
</span>
<div class="item-filler">&nbsp;</div>
<div class="item-controls item-controls-fixed">
<a class="item-control vice-virtue-activate" title="Activated">{{#if virtue.system.activated}}<i
class="fas fa-circle"></i>{{else}}<i class="fas fa-genderless"></i>{{/if}}</a>
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ul>
</div>
<div>
<ul class="stat-list alternate-list">
<li class="item flexrow list-item items-title-bg">
<span class="item-name-label-header">
<h3><label class="items-title-text">Vices</label></h3>
</span>
<span class="item-field-label-short">Status</label></span>
</li>
{{#each vices as |vice key|}}
<li class="item stat flexrow list-item list-item-shadow" data-arme-id="{{vice.id}}"
data-item-id="{{vice._id}}">
<a class="item-edit item-name-img" title="Edit Item"><img class="sheet-competence-img"
src="{{vice.img}}" /></a>
<span class="item-name-label">{{vice.name}}</span>
<span class="item-field-label-short"><label class="short-label">
{{#if vice.system.activated}}
Activated
{{else}}
&nbsp;-&nbsp;
{{/if}}
</label>
</span>
<div class="item-filler">&nbsp;</div>
<div class="item-controls item-controls-fixed">
<a class="item-control vice-virtue-activate" title="Activated">{{#if vice.system.activated}}<i
class="fas fa-circle"></i>{{else}}<i class="fas fa-genderless"></i>{{/if}}</a>
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ul>
</div>
<ul>
<li class="item flexrow list-item items-title-bg">
<span class="item-name-label-header">
<h3><label class="items-title-text">Psychology</label></h3>
</span>
</li>
<li class="flexrow">
<label class="short-label">Worst Fear </label>
<input type="text" class="" name="system.biodata.worstfear" value="{{data.biodata.worstfear}}"
data-dtype="String" />
<label class="attribute-value checkbox"><input type="checkbox" class="change-worstfear"
name="system.biodata.worstfearactive" {{checked data.biodata.worstfearactive}} /> Active ?</label>
</li>
<li class="flexrow">
<label class="short-label">Desires </label>
<input type="text" class="" name="system.biodata.desires" value="{{data.biodata.desires}}"
data-dtype="String" />
<label class="attribute-value checkbox"><input type="checkbox" class="change-desires"
name="system.biodata.desiresactive" {{checked data.biodata.desiresactive}} /> Active ?</label>
</li>
</ul>
<h3>Catchphrase : </h3>
<ul>
<li class="flexrow">
<label class="short-label">Catchphrase </label>
<input type="text" class="" name="system.biodata.catchphrase" value="{{data.biodata.catchphrase}}"
data-dtype="String" />
</li>
<li class="flexrow">
<label class="short-label">Catchphrase Trigger : </label>
<input type="text" class="" name="system.biodata.catchphrasetrigger" value="{{data.biodata.catchphrasetrigger}}"
data-dtype="String" />
</li>
<li class="flexrow">
<label class="short-label">Catchphrase used </label>
<label class="attribute-value checkbox"><input type="checkbox" name="system.biodata.catchphraseused" {{checked
data.biodata.catchphraseused}} /></label>
</li>
</ul>
<ul>
<li class="item flexrow list-item items-title-bg">
<span class="item-name-label-header">
<h3><label class="items-title-text">Development</label></h3>
</span>
</li>
<li class="flexrow">
<label class="short-label">Character Value : </label>
<input type="text" class="" name="system.biodata.charactervalue" value="{{data.biodata.charactervalue}}"
data-dtype="String" />
</li>
<li class="flexrow">
<label class="short-label">Character Development Points Total (CDP total) : </label>
<input type="text" class="" name="system.biodata.cdp" value="{{data.biodata.cdp}}" data-dtype="Number" />
</li>
<li class="flexrow">
<label class="short-label">Bonus selection : </label>
<input type="text" class="" name="system.biodata.bonusselection" value="{{data.biodata.bonusselection}}" data-dtype="String" />
</li>
<li class="flexrow">
<label class="short-label">Morality : </label>
<input type="text" class="" name="system.biodata.morality" value="{{data.biodata.morality}}" data-dtype="Number" />
</li>
<li class="flexrow">
<label class="short-label">Morality threshold : </label>
<input type="text" class="" name="system.biodata.moralitythreshold" value="{{data.biodata.moralitythreshold}}" disabled data-dtype="Number" />
</li>
<li class="flexrow">
<label class="short-label">Hero Level (max) : </label>
<select class="status-small-label color-class-common" type="text" name="system.biodata.maxlevelremaining" value="{{data.biodata.maxlevelremaining}}" data-dtype="Number" {{#unless @root.editScore}}disabled{{/unless}}>
{{#select data.biodata.maxlevelremaining}}
{{{@root.maxLevelRemainingList}}}
{{/select}}
</select>
</li>
<li class="flexrow">
<label class="short-label">Hero Levels Remaining : </label>
<select class="status-small-label color-class-common" type="text" name="system.biodata.currentlevelremaining" value="{{data.biodata.currentlevelremaining}}" data-dtype="Number" {{#unless @root.editScore}}disabled{{/unless}}>
{{#select data.biodata.currentlevelremaining}}
{{{@root.levelRemainingList}}}
{{/select}}
</select>
</li>
<li class="flexrow">
<label class="short-label">Threat Level : </label>
<input type="text" class="" name="system.biodata.threatlevel" value="{{data.biodata.threatlevel}}"
data-dtype="Number" />
</li>
</ul>
<hr> <hr>
<h3>Background : </h3> <h3>Description : </h3>
<div class="form-group editor"> <div class="form-group editor">
{{editor data.biodata.description target="system.biodata.description" button=true owner=owner {{editor data.biodata.description target="system.biodata.description" button=true owner=owner
editable=editable}} editable=editable}}