DND5e Core 1.2.3

DND5e Core 1.2.3 modded to SW5e System
This commit is contained in:
supervj 2021-01-19 21:28:45 -05:00
parent 063f924183
commit c208552f70
9 changed files with 82 additions and 68 deletions

View file

@ -459,8 +459,8 @@ export default class Actor5e extends Actor {
return weight + (q * w); return weight + (q * w);
}, 0); }, 0);
// [Optional] add Currency Weight // [Optional] add Currency Weight (for non-transformed actors)
if ( game.settings.get("sw5e", "currencyWeight") ) { if ( game.settings.get("sw5e", "currencyWeight") && actorData.data.currency ) {
const currency = actorData.data.currency; const currency = actorData.data.currency;
const numCoins = Object.values(currency).reduce((val, denom) => val += Math.max(denom, 0), 0); const numCoins = Object.values(currency).reduce((val, denom) => val += Math.max(denom, 0), 0);
weight += numCoins / CONFIG.SW5E.encumbrance.currencyPerWeight; weight += numCoins / CONFIG.SW5E.encumbrance.currencyPerWeight;
@ -554,26 +554,37 @@ export default class Actor5e extends Actor {
const isNPC = this.data.type === 'npc'; const isNPC = this.data.type === 'npc';
let initial = {}; let initial = {};
switch ( itemData.type ) { switch ( itemData.type ) {
case "weapon": case "weapon":
if ( getProperty(itemData, "data.equipped") === undefined ) {
initial["data.equipped"] = isNPC; // NPCs automatically equip weapons initial["data.equipped"] = isNPC; // NPCs automatically equip weapons
let hasWeaponProf = isNPC; // NPCs automatically have weapon proficiency }
if ( !isNPC ) { if ( getProperty(itemData, "data.proficient") === undefined ) {
if ( isNPC ) {
initial["data.proficient"] = true; // NPCs automatically have equipment proficiency
} else {
const weaponProf = { const weaponProf = {
"natural": true, "natural": true,
"simpleM": "sim", "simpleM": "sim",
"simpleR": "sim", "simpleR": "sim",
"martialM": "mar", "martialM": "mar",
"martialR": "mar" "martialR": "mar"
}[itemData.data?.weaponType]; }[itemData.data?.weaponType]; // Player characters check proficiency
const actorWeaponProfs = this.data.data.traits?.weaponProf?.value || []; const actorWeaponProfs = this.data.data.traits?.weaponProf?.value || [];
hasWeaponProf = (weaponProf === true) || actorWeaponProfs.includes(weaponProf); const hasWeaponProf = (weaponProf === true) || actorWeaponProfs.includes(weaponProf);
}
initial["data.proficient"] = hasWeaponProf; initial["data.proficient"] = hasWeaponProf;
}
}
break; break;
case "equipment": case "equipment":
if ( getProperty(itemData, "data.equipped") === undefined ) {
initial["data.equipped"] = isNPC; // NPCs automatically equip equipment initial["data.equipped"] = isNPC; // NPCs automatically equip equipment
let hasEquipmentProf = isNPC; // NPCs automatically have equipment proficiency }
if ( !isNPC ) { if ( getProperty(itemData, "data.proficient") === undefined ) {
if ( isNPC ) {
initial["data.proficient"] = true; // NPCs automatically have equipment proficiency
} else {
const armorProf = { const armorProf = {
"natural": true, "natural": true,
"clothing": true, "clothing": true,
@ -581,14 +592,18 @@ export default class Actor5e extends Actor {
"medium": "med", "medium": "med",
"heavy": "hvy", "heavy": "hvy",
"shield": "shl" "shield": "shl"
}[itemData.data?.armor?.type]; }[itemData.data?.armor?.type]; // Player characters check proficiency
const actorArmorProfs = this.data.data.traits?.armorProf?.value || []; const actorArmorProfs = this.data.data.traits?.armorProf?.value || [];
hasEquipmentProf = (armorProf === true) || actorArmorProfs.includes(armorProf); const hasEquipmentProf = (armorProf === true) || actorArmorProfs.includes(armorProf);
}
initial["data.proficient"] = hasEquipmentProf; initial["data.proficient"] = hasEquipmentProf;
}
}
break; break;
case "power": case "power":
initial["data.prepared"] = true; // NPCs automatically prepare powers if ( getProperty(itemData, "data.proficient") === undefined ) {
initial["data.prepared"] = isNPC; // NPCs automatically prepare powers
}
break; break;
} }
mergeObject(itemData, initial); mergeObject(itemData, initial);
@ -1108,7 +1123,7 @@ export default class Actor5e extends Actor {
// Recover power slots // Recover power slots
for ( let [k, v] of Object.entries(data.powers) ) { for ( let [k, v] of Object.entries(data.powers) ) {
updateData[`data.powers.${k}.value`] = !Number.isNaN(v.override) ? v.override : (v.max ?? 0); updateData[`data.powers.${k}.value`] = Number.isNumeric(v.override) ? v.override : (v.max ?? 0);
} }
// Recover pact slots. // Recover pact slots.
@ -1232,10 +1247,10 @@ export default class Actor5e extends Actor {
} }
// Get the original Actor data and the new source data // Get the original Actor data and the new source data
const o = this.toJSON(); const o = duplicate(this.toJSON());
o.flags.sw5e = o.flags.sw5e || {}; o.flags.sw5e = o.flags.sw5e || {};
o.flags.sw5e.transformOptions = {mergeSkills, mergeSaves}; o.flags.sw5e.transformOptions = {mergeSkills, mergeSaves};
const source = target.toJSON(); const source = duplicate(target.toJSON());
// Prepare new data to merge from the source // Prepare new data to merge from the source
const d = { const d = {
@ -1266,7 +1281,7 @@ export default class Actor5e extends Actor {
// Handle wildcard // Handle wildcard
if ( source.token.randomImg ) { if ( source.token.randomImg ) {
const images = await target.getTokenImages(); const images = await target.getTokenImages();
d.token.img = images[0]; d.token.img = images[Math.floor(Math.random() * images.length)];
} }
// Keep Token configurations // Keep Token configurations
@ -1350,7 +1365,7 @@ export default class Actor5e extends Actor {
newTokenData.actorId = newActor.id; newTokenData.actorId = newActor.id;
return newTokenData; return newTokenData;
}); });
return canvas.scene.updateEmbeddedEntity("Token", updates); return canvas.scene?.updateEmbeddedEntity("Token", updates);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */

View file

@ -619,6 +619,11 @@ export default class ActorSheet5e extends ActorSheet {
itemData = scroll.data; itemData = scroll.data;
} }
// Ignore certain statuses
if ( itemData.data ) {
["attunement", "equipped", "proficient", "prepared"].forEach(k => delete itemData.data[k]);
}
// Create the owned item as normal // Create the owned item as normal
return super._onDropItemCreate(itemData); return super._onDropItemCreate(itemData);
} }

View file

@ -168,6 +168,8 @@ export default class AbilityUseDialog extends Dialog {
type: item.data.consumableType, type: item.data.consumableType,
value: uses.value, value: uses.value,
quantity: item.data.quantity, quantity: item.data.quantity,
max: uses.max,
per: CONFIG.SW5E.limitedUsePeriods[uses.per]
}); });
} }

View file

@ -66,7 +66,7 @@ export const displayChatActionButtons = function(message, html, data) {
export const addChatMessageContextOptions = function(html, options) { export const addChatMessageContextOptions = function(html, options) {
let canApply = li => { let canApply = li => {
const message = game.messages.get(li.data("messageId")); const message = game.messages.get(li.data("messageId"));
return message.isRoll && message.isContentVisible && canvas.tokens.controlled.length; return message?.isRoll && message?.isContentVisible && canvas?.tokens.controlled.length;
}; };
options.push( options.push(
{ {
@ -103,15 +103,16 @@ export const addChatMessageContextOptions = function(html, options) {
* Apply rolled dice damage to the token or tokens which are currently controlled. * Apply rolled dice damage to the token or tokens which are currently controlled.
* This allows for damage to be scaled by a multiplier to account for healing, critical hits, or resistance * This allows for damage to be scaled by a multiplier to account for healing, critical hits, or resistance
* *
* @param {HTMLElement} roll The chat entry which contains the roll data * @param {HTMLElement} li The chat entry which contains the roll data
* @param {Number} multiplier A damage multiplier to apply to the rolled damage. * @param {Number} multiplier A damage multiplier to apply to the rolled damage.
* @return {Promise} * @return {Promise}
*/ */
function applyChatCardDamage(roll, multiplier) { function applyChatCardDamage(li, multiplier) {
const amount = roll.find('.dice-total').text(); const message = game.messages.get(li.data("messageId"));
const roll = message.roll;
return Promise.all(canvas.tokens.controlled.map(t => { return Promise.all(canvas.tokens.controlled.map(t => {
const a = t.actor; const a = t.actor;
return a.applyDamage(amount, multiplier); return a.applyDamage(roll.total, multiplier);
})); }));
} }

View file

@ -26,15 +26,3 @@ export const _getInitiativeFormula = function(combatant) {
if ( tiebreaker ) parts.push(actor.data.data.abilities.dex.value / 100); if ( tiebreaker ) parts.push(actor.data.data.abilities.dex.value / 100);
return parts.filter(p => p !== null).join(" + "); return parts.filter(p => p !== null).join(" + ");
}; };
/**
* When the Combat encounter updates - re-render open Actor sheets for combatants in the encounter.
*/
Hooks.on("updateCombat", (combat, data, options, userId) => {
const updateTurn = ("turn" in data) || ("round" in data);
if ( !updateTurn ) return;
for ( let t of combat.turns ) {
const a = t.actor;
if ( t.actor ) t.actor.sheet.render(false);
}
});

View file

@ -110,8 +110,8 @@ export async function d20Roll({parts=[], data={}, event={}, rollMode=null, templ
let adv = 0; let adv = 0;
fastForward = fastForward ?? (event && (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey)); fastForward = fastForward ?? (event && (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey));
if (fastForward) { if (fastForward) {
if ( advantage || event.altKey ) adv = 1; if ( advantage ?? event.altKey ) adv = 1;
else if ( disadvantage || event.ctrlKey || event.metaKey ) adv = -1; else if ( disadvantage ?? (event.ctrlKey || event.metaKey) ) adv = -1;
} }
// Define the inner roll function // Define the inner roll function

View file

@ -222,12 +222,14 @@ export default class Item5e extends Item {
// Item Actions // Item Actions
if ( data.hasOwnProperty("actionType") ) { if ( data.hasOwnProperty("actionType") ) {
// if this item is owned, we populate the label and saving throw during actor init
if (!this.isOwned) {
// Saving throws // Saving throws
this.getSaveDC(); this.getSaveDC();
// To Hit // To Hit
this.getAttackToHit(); this.getAttackToHit();
}
// Damage // Damage
let dam = data.damage || {}; let dam = data.damage || {};
@ -886,7 +888,8 @@ export default class Item5e extends Item {
if ( powerLevel ) rollData.item.level = powerLevel; if ( powerLevel ) rollData.item.level = powerLevel;
// Configure the damage roll // Configure the damage roll
const title = `${this.name} - ${game.i18n.localize("SW5E.DamageRoll")}`; const actionFlavor = game.i18n.localize(itemData.actionType === "heal" ? "SW5E.Healing" : "SW5E.DamageRoll");
const title = `${this.name} - ${actionFlavor}`;
const rollConfig = { const rollConfig = {
actor: this.actor, actor: this.actor,
critical: critical ?? event?.altKey ?? false, critical: critical ?? event?.altKey ?? false,

File diff suppressed because one or more lines are too long

View file

@ -2,7 +2,7 @@
"name": "sw5e", "name": "sw5e",
"title": "SW5e - Fifth Edition System", "title": "SW5e - Fifth Edition System",
"description": "A system for playing the fifth edition of the worlds most popular role-playing game in the Foundry Virtual Tabletop environment.", "description": "A system for playing the fifth edition of the worlds most popular role-playing game in the Foundry Virtual Tabletop environment.",
"version": "1.2.2", "version": "1.2.3",
"author": "Atropos", "author": "Atropos",
"scripts": [], "scripts": [],
"esmodules": ["sw5e.js"], "esmodules": ["sw5e.js"],
@ -95,5 +95,5 @@
"compatibleCoreVersion": "0.7.9", "compatibleCoreVersion": "0.7.9",
"url": "https://gitlab.com/foundrynet/sw5e", "url": "https://gitlab.com/foundrynet/sw5e",
"manifest": "https://gitlab.com/foundrynet/sw5e/raw/master/system.json", "manifest": "https://gitlab.com/foundrynet/sw5e/raw/master/system.json",
"download": "https://gitlab.com/foundrynet/sw5e/-/archive/release-1.2.2/sw5e-release-1.2.2.zip" "download": "https://gitlab.com/foundrynet/sw5e/-/archive/release-1.2.3/sw5e-release-1.2.3.zip"
} }