diff --git a/lang/en.json b/lang/en.json index 9a80fae0..e3242844 100644 --- a/lang/en.json +++ b/lang/en.json @@ -331,8 +331,18 @@ "SW5E.DeathSavingThrow": "Death Saving Throw", "SW5E.Default": "Default", "SW5E.DefaultAbilityCheck": "Default Ability Check", - "SW5E.Deployment": "Deployment", - "SW5E.DeploymentPl": "Deployments", + "SW5E.Deployment": "Deployment", + "SW5E.DeploymentAcceptSettings": "Deploy Actor", + "SW5E.DeploymentPl": "Deployments", + "SW5E.DeploymentPromptTitle": "Deploying Actor", + "SW5E.DeploymentTypeCoordinator": "Coordinator", + "SW5E.DeploymentTypeCrew": "Crew", + "SW5E.DeploymentTypeGunner": "Gunner", + "SW5E.DeploymentTypeMechanic": "Mechanic", + "SW5E.DeploymentTypeOperator": "Operator", + "SW5E.DeploymentTypePilot": "Pilot", + "SW5E.DeploymentTypePassenger" : "Passenger", + "SW5E.DeploymentTypeTechnician": "Technician", "SW5E.description": "A comprehensive game system for running games of Star Wars 5th Edition in the Foundry VTT environment.", "SW5E.Description": "Description", "SW5E.DestructionSave": "Destruction Saves", diff --git a/module/actor/entity.js b/module/actor/entity.js index f2c47c16..604db1e7 100644 --- a/module/actor/entity.js +++ b/module/actor/entity.js @@ -1859,6 +1859,88 @@ export default class Actor5e extends Actor { /* -------------------------------------------- */ + + /** + * Deploy an Actor into this one. + * + * @param {Actor} target The Actor to be deployed. + * @param {boolean} [coord] Deploy as Coordinator + * @param {boolean} [gunner] Deploy as Gunner + * @param {boolean} [mech] Deploy as Mechanic + * @param {boolean} [oper] Deploy as Operator + * @param {boolean} [pilot] Deploy as Pilot + * @param {boolean} [tech] Deploy as Technician + * @param {boolean} [crew] Deploy as Crew + * @param {boolean} [pass] Deploy as Passenger + */ + async deployInto(target, { coord=false, gunner=false, mech=false, oper=false, + pilot=false, tech=false, crew=false, pass=false}={}) { + + // Get the starship Actor data and the new char data + const sship = duplicate(this.toJSON()); + const ssDeploy = sship.data.attributes.deployment; + const char = target; + const charUUID = char.uuid; + const charName = char.data.name; + const charRank = char.data.data.attributes.rank; + let charProf = 0; + if (charRank.total > 0) { + charProf = char.data.data.attributes.prof; + } + + if (coord){ + ssDeploy.coord.uuid = charUUID; + ssDeploy.coord.name = charName; + ssDeploy.coord.rank = charRank.coord; + ssDeploy.coord.prof = charProf; + } + + if (gunner){ + ssDeploy.gunner.uuid = charUUID; + ssDeploy.gunner.name = charName; + ssDeploy.gunner.rank = charRank.gunner; + ssDeploy.gunner.prof = charProf; + } + + if (mech){ + ssDeploy.mechanic.uuid = charUUID; + ssDeploy.mechanic.name = charName; + ssDeploy.mechanic.rank = charRank.mechanic; + ssDeploy.mechanic.prof = charProf; + } + + if (oper){ + ssDeploy.operator.uuid = charUUID; + ssDeploy.operator.name = charName; + ssDeploy.operator.rank = charRank.operator; + ssDeploy.operator.prof = charProf; + } + + if (pilot){ + ssDeploy.pilot.uuid = charUUID; + ssDeploy.pilot.name = charName; + ssDeploy.pilot.rank = charRank.pilot; + ssDeploy.pilot.prof = charProf; + } + + if (tech){ + ssDeploy.technician.uuid = charUUID; + ssDeploy.technician.name = charName; + ssDeploy.technician.rank = charRank.technician; + ssDeploy.technician.prof = charProf; + } + + if (crew){ + ssDeploy.crew.push({"uuid": charUUID, "name": charName, "rank": charRank, "prof": charProf}); + } + + if (pass){ + ssDeploy.passenger.push({"uuid": charUUID, "name": charName, "rank": charRank, "prof": charProf}); + } + this.update({"data.attributes.deployment": ssDeploy}); + } + + /** * Transform this Actor into another one. * diff --git a/module/actor/sheets/newSheet/base.js b/module/actor/sheets/newSheet/base.js index d6636c0b..476c3b73 100644 --- a/module/actor/sheets/newSheet/base.js +++ b/module/actor/sheets/newSheet/base.js @@ -560,7 +560,7 @@ export default class ActorSheet5e extends ActorSheet { /** @override */ async _onDropActor(event, data) { - const canPolymorph = game.user.isGM || (this.actor.isOwner && game.settings.get('sw5e', 'allowPolymorphing')); + const canPolymorph = game.user.isGM || (this.actor.data.type === "starship") || (this.actor.owner && game.settings.get('sw5e', 'allowPolymorphing')); if ( !canPolymorph ) return false; // Get the target actor @@ -585,49 +585,76 @@ export default class ActorSheet5e extends ActorSheet { }; // Create and render the Dialog - return new Dialog({ - title: game.i18n.localize('SW5E.PolymorphPromptTitle'), - content: { - options: game.settings.get('sw5e', 'polymorphSettings'), - i18n: SW5E.polymorphSettings, - isToken: this.actor.isToken - }, - default: 'accept', - buttons: { - accept: { - icon: '', - label: game.i18n.localize('SW5E.PolymorphAcceptSettings'), - callback: html => this.actor.transformInto(sourceActor, rememberOptions(html)) + + if (this.actor.data.type === "starship") { + return new Dialog({ + title: game.i18n.localize('SW5E.DeploymentPromptTitle') + " " + sourceActor.data.name + " into " + this.actor.data.name, + content: { + i18n: SW5E.deploymentTypes, + isToken: this.actor.isToken }, - wildshape: { - icon: '', - label: game.i18n.localize('SW5E.PolymorphWildShape'), - callback: html => this.actor.transformInto(sourceActor, { - keepBio: true, - keepClass: true, - keepMental: true, - mergeSaves: true, - mergeSkills: true, - transformTokens: rememberOptions(html).transformTokens - }) - }, - polymorph: { - icon: '', - label: game.i18n.localize('SW5E.Polymorph'), - callback: html => this.actor.transformInto(sourceActor, { - transformTokens: rememberOptions(html).transformTokens - }) - }, - cancel: { - icon: '', - label: game.i18n.localize('Cancel') + default: 'accept', + buttons: { + deploy: { + icon: '', + label: game.i18n.localize('SW5E.DeploymentAcceptSettings'), + callback: html => this.actor.deployInto(sourceActor, rememberOptions(html)) + }, + cancel: { + icon: '', + label: game.i18n.localize('Cancel') + } } - } - }, { - classes: ['dialog', 'sw5e'], - width: 600, - template: 'systems/sw5e/templates/apps/polymorph-prompt.html' - }).render(true); + }, { + classes: ['dialog', 'sw5e'], + width: 600, + template: 'systems/sw5e/templates/apps/deployment-prompt.html' + }).render(true); + } else { + return new Dialog({ + title: game.i18n.localize('SW5E.PolymorphPromptTitle'), + content: { + options: game.settings.get('sw5e', 'polymorphSettings'), + i18n: SW5E.polymorphSettings, + isToken: this.actor.isToken + }, + default: 'accept', + buttons: { + accept: { + icon: '', + label: game.i18n.localize('SW5E.PolymorphAcceptSettings'), + callback: html => this.actor.transformInto(sourceActor, rememberOptions(html)) + }, + wildshape: { + icon: '', + label: game.i18n.localize('SW5E.PolymorphWildShape'), + callback: html => this.actor.transformInto(sourceActor, { + keepBio: true, + keepClass: true, + keepMental: true, + mergeSaves: true, + mergeSkills: true, + transformTokens: rememberOptions(html).transformTokens + }) + }, + polymorph: { + icon: '', + label: game.i18n.localize('SW5E.Polymorph'), + callback: html => this.actor.transformInto(sourceActor, { + transformTokens: rememberOptions(html).transformTokens + }) + }, + cancel: { + icon: '', + label: game.i18n.localize('Cancel') + } + } + }, { + classes: ['dialog', 'sw5e'], + width: 600, + template: 'systems/sw5e/templates/apps/polymorph-prompt.html' + }).render(true); + } } /* -------------------------------------------- */ diff --git a/module/config.js b/module/config.js index 5c072bde..394346bf 100644 --- a/module/config.js +++ b/module/config.js @@ -673,114 +673,24 @@ SW5E.baseUpgradeCost = [0, 3900, 77500, 297000, 620000, 1150000]; /* -------------------------------------------- */ - -/** - * Enumerate the base stat and feature settings for starships based on size. - * @type {Array.} - */ - -SW5E.baseStarshipSettings = { - "tiny": {"changes":[{"key":"data.abilities.dex.value","value":4,"mode":2,"priority":20},{"key":"data.abilities.dex.proficient","value":1,"mode":4,"priority":20}, {"key":"data.abilities.con.value","value":-4,"mode":2,"priority":20}, {"key":"data.abilities.int.proficient","value":1,"mode":4,"priority":20}], "attributes":{"crewcap":null, "hd":"1d4", "hp":{"value":4, "max":4, "temp":4, "tempmax":4}, "hsm":1, "sd":"1d4", "mods":{"open":10, "max":10}, "suites":{"open":0, "max":0}, "movement":{"fly":300, "turn":300}}}, - "sm": {"changes":[{"key":"data.abilities.dex.value","value":2,"mode":2,"priority":20},{"key":"data.abilities.dex.proficient","value":1,"mode":4,"priority":20},{"key":"data.abilities.con.value","value":-2,"mode":2,"priority":20},{"key":"data.abilities.str.proficient","value":1,"mode":4,"priority":20}], "attributes":{"crewcap":1, "hd":"3d6", "hp":{"value":6, "max":6, "temp":6, "tempmax":6}, "hsm":2, "sd":"3d6", "mods":{"open":20, "max":20}, "suites":{"open":-1, "max":-1}, "movement":{"fly":300, "turn":250}}}, - "med": {"attributes":{"crewcap":1, "hd":"5d8", "hp":{"value":8, "max":8, "temp":8, "tempmax":8}, "hsm":3, "sd":"5d8", "mods":{"open":30, "max":30}, "suites":{"open":3, "max":3}, "movement":{"fly":300, "turn":200}}}, - "lg": {"changes":[{"key":"data.abilities.dex.value","value":-2,"mode":2,"priority":20},{"key":"data.abilities.wis.proficient","value":1,"mode":4,"priority":20},{"key":"data.abilities.con.value","value":2,"mode":2,"priority":20}], "attributes":{"crewcap":200, "hd":"7d10", "hp":{"value":10, "max":10, "temp":10, "tempmax":10}, "hsm":4, "sd":"7d10", "mods":{"open":50, "max":50}, "suites":{"open":3, "max":3}, "movement":{"fly":300, "turn":150}}}, - "huge": {"changes":[{"key":"data.abilities.dex.value","value":-4,"mode":2,"priority":20},{"key":"data.abilities.wis.proficient","value":1,"mode":4,"priority":20},{"key":"data.abilities.con.value","value":4,"mode":2,"priority":20}], "attributes":{"crewcap":4000, "hd":"9d12", "hp":{"value":12, "max":12, "temp":12, "tempmax":12}, "hsm":2, "sd":"9d12", "mods":{"open":60, "max":60}, "suites":{"open":6, "max":6}, "movement":{"fly":300, "turn":100}}}, - "grg": {"changes":[{"key":"data.abilities.dex.value","value":-6,"mode":2,"priority":20},{"key":"data.abilities.wis.proficient","value":1,"mode":4,"priority":20},{"key":"data.abilities.con.value","value":6,"mode":2,"priority":20}], "attributes":{"crewcap":80000, "hd":"11d20", "hp":{"value":20, "max":20, "temp":20, "tempmax":20}, "hsm":3, "sd":"11d20", "mods":{"open":70, "max":70}, "suites":{"open":10, "max":10}, "movement":{"fly":300, "turn":50}}} -} - -/* -------------------------------------------- */ /** - * The set of starship roles which can be selected in SW5e - * @type {Object} + * Starship Deployment types */ - SW5E.starshipRolestiny = { -}; -SW5E.starshipRolessm = { - "bmbr": "SW5E.StarshipBomber", - "intc": "SW5E.StarshipInterceptor", - "scout": "SW5E.StarshipScout", - "scrm": "SW5E.StarshipScrambler", - "shtl": "SW5E.StarshipShuttle", - "strf": "SW5E.StarshipStrikeFighter" -}; -SW5E.starshipRolesmed = { - "cour": "SW5E.StarshipCourier", - "frtr": "SW5E.StarshipFreighter", - "gnbt": "SW5E.StarshipGunboat", - "msbt": "SW5E.StarshipMissileBoat", - "nvgt": "SW5E.StarshipNavigator", - "yacht": "SW5E.StarshipYacht" -}; -SW5E.starshipRoleslg = { - "ambd": "SW5E.StarshipAmbassador", - "corv": "SW5E.StarshipCorvette", - "crui": "SW5E.StarshipCruiser", - "expl": "SW5E.StarshipExplorer", - "pics": "SW5E.StarshipPicketShip", - "shtd": "SW5E.StarshipShipsTender" -}; -SW5E.starshipRoleshuge = { - "btls": "SW5E.StarshipBattleship", - "carr": "SW5E.StarshipCarrier", - "colo": "SW5E.StarshipColonizer", - "cmds": "SW5E.StarshipCommandShip", - "intd": "SW5E.StarshipInterdictor", - "jugg": "SW5E.StarshipJuggernaut" -}; -SW5E.starshipRolesgrg = { - "blks": "SW5E.StarshipBlockadeShip", - "flgs": "SW5E.StarshipFlagship", - "inct": "SW5E.StarshipIndustrialCenter", - "mbmt": "SW5E.StarshipMobileMetropolis", - "rsrc": "SW5E.StarshipResearcher", - "wars": "SW5E.StarshipWarship" + SW5E.deploymentTypes = { + "coord": "SW5E.DeploymentTypeCoordinator", + "gunner": "SW5E.DeploymentTypeGunner", + "mech": "SW5E.DeploymentTypeMechanic", + "oper": "SW5E.DeploymentTypeOperator", + "pilot": "SW5E.DeploymentTypePilot", + "tech": "SW5E.DeploymentTypeTechnician", + "crew": "SW5E.DeploymentTypeCrew", + "pass": "SW5E.DeploymentTypePassenger" }; /* -------------------------------------------- */ -/** - * The set of starship role bonuses to starships which can be selected in SW5e - * @type {Object} - */ - - SW5E.starshipRoleBonuses = { - "bmbr": {"changes":[{"key":"data.abilities.wis.value","value":1,"mode":2,"priority":20}]}, - "intc": {"changes":[{"key":"data.abilities.dex.value","value":1,"mode":2,"priority":20}]}, - "scout": {"changes":[{"key":"data.abilities.int.value","value":1,"mode":2,"priority":20}]}, - "scrm": {"changes":[{"key":"data.abilities.cha.value","value":1,"mode":2,"priority":20}]}, - "shtl": {"changes":[{"key":"data.abilities.con.value","value":1,"mode":2,"priority":20}]}, - "strf": {"changes":[{"key":"data.abilities.str.value","value":1,"mode":2,"priority":20}]}, - "cour": {"changes":[{"key":"data.abilities.dex.value","value":1,"mode":2,"priority":20}]}, - "frtr": {"changes":[{"key":"data.abilities.con.value","value":1,"mode":2,"priority":20}]}, - "gnbt": {"changes":[{"key":"data.abilities.str.value","value":1,"mode":2,"priority":20}]}, - "msbt": {"changes":[{"key":"data.abilities.wis.value","value":1,"mode":2,"priority":20}]}, - "nvgt": {"changes":[{"key":"data.abilities.int.value","value":1,"mode":2,"priority":20}]}, - "yacht": {"changes":[{"key":"data.abilities.cha.value","value":1,"mode":2,"priority":20}]}, - "ambd": {"changes":[{"key":"data.abilities.cha.value","value":1,"mode":2,"priority":20},{"key":"data.abilities.con.value","value":1,"mode":2,"priority":20}]}, - "corv": {"changes":[{"key":"data.abilities.str.value","value":1,"mode":2,"priority":20},{"key":"data.abilities.dex.value","value":1,"mode":2,"priority":20}]}, - "crui": {"changes":[{"key":"data.abilities.wis.value","value":1,"mode":2,"priority":20},{"key":"data.abilities.str.value","value":1,"mode":2,"priority":20}]}, - "expl": {"changes":[{"key":"data.abilities.dex.value","value":1,"mode":2,"priority":20},{"key":"data.abilities.int.value","value":1,"mode":2,"priority":20}]}, - "pics": {"changes":[{"key":"data.abilities.dex.value","value":1,"mode":2,"priority":20},{"key":"data.abilities.wis.value","value":1,"mode":2,"priority":20}]}, - "shtd": {"changes":[{"key":"data.abilities.con.value","value":1,"mode":2,"priority":20},{"key":"data.abilities.str.value","value":1,"mode":2,"priority":20}]}, - "btls": {"changes":[{"key":"data.abilities.wis.value","value":1,"mode":2,"priority":20},{"key":"data.abilities.str.value","value":1,"mode":2,"priority":20}]}, - "carr": {"changes":[{"key":"data.abilities.cha.value","value":1,"mode":2,"priority":20},{"key":"data.abilities.int.value","value":1,"mode":2,"priority":20}]}, - "colo": {"changes":[{"key":"data.abilities.con.value","value":1,"mode":2,"priority":20},{"key":"data.abilities.int.value","value":1,"mode":2,"priority":20}]}, - "cmds": {"changes":[{"key":"data.abilities.cha.value","value":1,"mode":2,"priority":20},{"key":"data.abilities.wis.value","value":1,"mode":2,"priority":20}]}, - "intd": {"changes":[{"key":"data.abilities.dex.value","value":1,"mode":2,"priority":20},{"key":"data.abilities.str.value","value":1,"mode":2,"priority":20}]}, - "jugg": {"changes":[{"key":"data.abilities.con.value","value":1,"mode":2,"priority":20},{"key":"data.abilities.str.value","value":1,"mode":2,"priority":20}]}, - "blks": {"changes":[{"key":"data.abilities.dex.value","value":1,"mode":2,"priority":20},{"key":"data.abilities.str.value","value":1,"mode":2,"priority":20}]}, - "flgs": {"changes":[{"key":"data.abilities.cha.value","value":1,"mode":2,"priority":20},{"key":"data.abilities.wis.value","value":1,"mode":2,"priority":20}]}, - "inct": {"changes":[{"key":"data.abilities.con.value","value":1,"mode":2,"priority":20},{"key":"data.abilities.str.value","value":1,"mode":2,"priority":20}]}, - "mbmt": {"changes":[{"key":"data.abilities.con.value","value":1,"mode":2,"priority":20},{"key":"data.abilities.wis.value","value":1,"mode":2,"priority":20}]}, - "rsrc": {"changes":[{"key":"data.abilities.int.value","value":1,"mode":2,"priority":20},{"key":"data.abilities.wis.value","value":1,"mode":2,"priority":20}]}, - "wars": {"changes":[{"key":"data.abilities.wis.value","value":1,"mode":2,"priority":20},{"key":"data.abilities.str.value","value":1,"mode":2,"priority":20}]} -}; - -/* -------------------------------------------- */ - - /** * The set of possible sensory perception types which an Actor may have diff --git a/sw5e.js b/sw5e.js index 70960e28..88cbd4db 100644 --- a/sw5e.js +++ b/sw5e.js @@ -175,16 +175,15 @@ Hooks.once("setup", function() { const toLocalize = [ "abilities", "abilityAbbreviations", "abilityActivationTypes", "abilityConsumptionTypes", "actorSizes", "alignments", "armorProficiencies", "armorPropertiesTypes", "conditionTypes", "consumableTypes", "cover", "currencies", "damageResistanceTypes", - "damageTypes", "distanceUnits", "equipmentTypes", "healingTypes", "itemActionTypes", "languages", + "damageTypes", "deploymentTypes", "distanceUnits", "equipmentTypes", "healingTypes", "itemActionTypes", "languages", "limitedUsePeriods", "movementTypes", "movementUnits", "polymorphSettings", "proficiencyLevels", "senses", "skills", - "starshipRolessm", "starshipRolesmed", "starshipRoleslg", "starshipRoleshuge", "starshipRolesgrg", "starshipSkills", - "powerComponents", "powerLevels", "powerPreparationModes", "powerScalingModes", "powerSchools", "targetTypes", + "starshipSkills", "powerComponents", "powerLevels", "powerPreparationModes", "powerScalingModes", "powerSchools", "targetTypes", "timePeriods", "toolProficiencies", "weaponProficiencies", "weaponProperties", "weaponSizes", "weaponTypes" ]; // Exclude some from sorting where the default order matters const noSort = [ - "abilities", "alignments", "currencies", "distanceUnits", "movementUnits", "itemActionTypes", "proficiencyLevels", + "abilities", "alignments", "currencies", "deploymentTypes", "distanceUnits", "movementUnits", "itemActionTypes", "proficiencyLevels", "limitedUsePeriods", "powerComponents", "powerLevels", "powerPreparationModes", "weaponTypes" ]; diff --git a/template.json b/template.json index 048478a7..33eede14 100644 --- a/template.json +++ b/template.json @@ -89,6 +89,15 @@ }, "creature": { "attributes": { + "rank": { + "total": 0, + "coord": 0, + "gunner": 0, + "mechanic": 0, + "operator": 0, + "pilot": 0, + "technician": 0 + }, "senses": { "darkvision": 0, "blindsight": 0, @@ -429,23 +438,43 @@ }, "deployment": { "coord": { - "uuid": null + "uuid": null, + "name": null, + "rank": null, + "prof": null }, "gunner": { - "uuid": null + "uuid": null, + "name": null, + "rank": null, + "prof": null }, "mechanic": { - "uuid": null + "uuid": null, + "name": null, + "rank": null, + "prof": null }, "operator": { - "uuid": null + "uuid": null, + "name": null, + "rank": null, + "prof": null }, "pilot": { - "uuid": null + "uuid": null, + "name": null, + "rank": null, + "prof": null }, "technician": { - "uuid": null - } + "uuid": null, + "name": null, + "rank": null, + "prof": null + }, + "crew": [], + "passenger": [] }, "equip": { "armor": { @@ -616,7 +645,7 @@ } }, "traits": { - "size": "med" + "size": null } }, "vehicle": { diff --git a/templates/apps/deployment-prompt.html b/templates/apps/deployment-prompt.html new file mode 100644 index 00000000..5ecb4e6f --- /dev/null +++ b/templates/apps/deployment-prompt.html @@ -0,0 +1,18 @@ + + {{#each content.i18n}} + + + + {{this}} + + + {{/each}} + + + {{#each buttons as |button id|}} + + {{{button.icon}}} + {{{button.label}}} + + {{/each}} +