diff --git a/lang/en.json b/lang/en.json index f9e2c4d..ae06e73 100644 --- a/lang/en.json +++ b/lang/en.json @@ -212,10 +212,99 @@ "WW.GripOne": "One-Handed", "WW.GripTwo": "Two-Handed", "WW.GripOff": "Off-Hand", - "WW.Range": "Range", - "WW.Properties": "Properties", - "WW.PropertiesPH": "Brutal, Keen, etc", - "WW.Reload": "Reload", + + "WW.Properties": { + "Title": "Properties", + "PH": "Brutal, Sharp, etc", + "Ammunition": { + "Label": "Ammunition", + "Tip": "Tooltip" + }, + "Brutal": { + "Label": "Brutal", + "Tip": "Tooltip" + }, + "Concussing": { + "Label": "Concussing", + "Tip": "Tooltip" + }, + "Disarming": { + "Label": "Disarming", + "Tip": "Tooltip" + }, + "Driving": { + "Label": "Driving", + "Tip": "Tooltip" + }, + "Fast": { + "Label": "Fast", + "Tip": "Tooltip" + }, + "Firearm": { + "Label": "Firearm", + "Tip": "Tooltip" + }, + "Great": { + "Label": "Great", + "Tip": "Tooltip" + }, + "Light": { + "Label": "Light", + "Tip": "Tooltip" + }, + "Long": { + "Label": "Long", + "Tip": "Tooltip" + }, + "Nimble": { + "Label": "Nimble", + "Tip": "Tooltip" + }, + "Painful": { + "Label": "Painful", + "Tip": "Tooltip" + }, + "Precise": { + "Label": "Precise", + "Tip": "Tooltip" + }, + "Range": { + "Label": "Range", + "Tip": "Tooltip" + }, + "Reload": { + "Label": "Reload", + "Tip": "Tooltip" + }, + "Sharp": { + "Label": "Sharp", + "Tip": "Tooltip" + }, + "Shattering": { + "Label": "Shattering", + "Tip": "Tooltip" + }, + "Slow": { + "Label": "Slow", + "Tip": "Tooltip" + }, + "Special": { + "Label": "Special", + "Tip": "Tooltip" + }, + "Thrown": { + "Label": "Thrown", + "Tip": "Tooltip" + }, + "Unbalancing": { + "Label": "Unbalancing", + "Tip": "Tooltip" + }, + "Versatile": { + "Label": "Versatile", + "Tip": "Tooltip" + } + }, "WW.Effects": "Effects", "WW.EffectsAll": "All Effects", diff --git a/lang/pt.json b/lang/pt.json deleted file mode 100644 index 7835994..0000000 --- a/lang/pt.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "WEIRDWIZARD.ActorName": "Nome do Ator" -} \ No newline at end of file diff --git a/module/chat/chat-listeners.mjs b/module/chat/chat-listeners.mjs new file mode 100644 index 0000000..70e79b1 --- /dev/null +++ b/module/chat/chat-listeners.mjs @@ -0,0 +1,389 @@ +/* -------------------------------------------- */ +/* Chat methods */ +/* -------------------------------------------- */ + +/*import {buildActorInfo, formatDice, getChatBaseData} from './base-messages' +import {TokenManager} from '../pixi/token-manager'*/ +import { rollDamage } from '../sheets/apps/roll-damage.mjs'; + +//const tokenManager = new TokenManager() + +export function initChatListeners(html) { + //html.on('click', '.damage-roll', _onChatRollDamage.bind(this)) + /*html.on('click', '.healing-roll', _onChatApplyHealing.bind(this)) + html.on('click', '.apply-damage', _onChatApplyDamage.bind(this)) + html.on('click', '.apply-effect', _onChatApplyEffect.bind(this)) + html.on('click', '.use-talent', _onChatUseTalent.bind(this)) + html.on('click', '.place-template', _onChatPlaceTemplate.bind(this)) + html.on('click', '.request-challengeroll', _onChatRequestChallengeRoll.bind(this)) + html.on('click', '.make-challengeroll', _onChatMakeChallengeRoll.bind(this)) + html.on('click', '.request-initroll', _onChatRequestInitRoll.bind(this)) + html.on('click', '.make-initroll', _onChatMakeInitRoll.bind(this))*/ +} + +/* -------------------------------------------- */ + +async function _onChatRollDamage(event) { + console.log(event) + event.preventDefault() + const li = event.currentTarget + const token = li/*.closest('.weirdwizard')*/ + const actor = _getChatCardActor(token) + const item = li.children[0] + /*const damageformular = item.dataset.damage + const damagetype = item.dataset.damagetype + const selected = tokenManager.targets + const itemId = item.dataset.itemId || li.closest('.weirdwizard').dataset.itemId + const rollMode = game.settings.get('core', 'rollMode')*/ + console.log(item.system.damage) + let obj = { + actor: actor, + target: li, + label: i18n('WW.Damage.Of') + ' ' + item.name, + baseDamage: item.system.damage, + bonusDamage: actor.system.stats.bonusdamage + } + + new rollDamage(obj).render(true) + + /*const damageRoll = new Roll(damageformular, {}) + damageRoll.evaluate({async: false}) + + let totalDamage = '' + let totalDamageGM = '' + if (['blindroll'].includes(rollMode)) { + totalDamage = '?' + totalDamageGM = damageRoll.total + } else { + totalDamage = damageRoll.total + } + + var templateData = { + actor: actor, + item: { + id: itemId, + }, + data: {}, + diceData: formatDice(damageRoll), + } + templateData.data['damageTotal'] = totalDamage + templateData.data['damageTotalGM'] = totalDamageGM + templateData.data['damageDouble'] = +damageRoll.total * 2 + templateData.data['damageHalf'] = Math.floor(+damageRoll.total / 2) + templateData.data['damagetype'] = damagetype + templateData.data['isCreature'] = actor.type === 'creature' + templateData.data['actorInfo'] = buildActorInfo(actor) + + const chatData = getChatBaseData(actor, rollMode) + if (damageRoll) { + chatData.rolls = [damageRoll], + chatData.type = CONST.CHAT_MESSAGE_TYPES.ROLL + } + const template = 'systems/demonlord/templates/chat/damage.hbs' + renderTemplate(template, templateData).then(content => { + chatData.content = content + chatData.sound = CONFIG.sounds.dice + ChatMessage.create(chatData) + }) + Hooks.call('WW.RollDamage', { + sourceToken: tokenManager.getTokenByActorId(actor.id), + targets: selected, + itemId, + })*/ +} + +/* -------------------------------------------- */ +/* +async function _onChatApplyHealing(event) { + event.preventDefault() + const li = event.currentTarget + const item = li.children[0] + const isFullRate = +item.dataset.healing === 1 + + const selected = tokenManager.targets + if (selected.length === 0) { + ui.notifications.info(game.i18n.localize('WW.DialogWarningActorsNotSelected')) + return + } + + selected.forEach(token => token.actor.applyHealing(isFullRate)) + + const actor = _getChatCardActor(li.closest('.weirdwizard')) + const sourceToken = tokenManager.getTokenByActorId(actor.id) + const itemId = li.closest('.weirdwizard').dataset.itemId + Hooks.call('WW.ApplyHealing', { + sourceToken, + targets: selected, + itemId, + }) +} + +/* -------------------------------------------- */ +/* +async function _onChatApplyDamage(event) { + event.preventDefault() + const li = event.currentTarget + const item = li.children[0] + const damage = parseInt(item.dataset.damage) + + var selected = tokenManager.targets + if (selected.length == 0) { + ui.notifications.info(game.i18n.localize('WW.DialogWarningActorsNotSelected')) + return + } + + selected.forEach(token => token.actor.increaseDamage(+damage)) + + const actor = _getChatCardActor(li.closest('.weirdwizard')) + const sourceToken = tokenManager.getTokenByActorId(actor.id) + const itemId = li.closest('.weirdwizard').dataset.itemId + Hooks.call('WW.ApplyDamage', { + sourceToken, + targets: selected, + itemId, + damage, + }) +} + +/* -------------------------------------------- */ +/* +async function _onChatApplyEffect(event) { + event.preventDefault() + const htmlTarget = event.currentTarget + const effectUuid = htmlTarget.attributes.getNamedItem('data-effect-uuid').value + const activeEffect = await fromUuid(effectUuid) + + if (!activeEffect) { + console.warn('Demonlord | _onChatApplyEffect | Effect not found!') + return + } + const selected = tokenManager.targets + if (selected.length === 0) { + tokenManager.warnNotSelected() + return + } + + const effectData = activeEffect.toObject() + selected.forEach(target => { + ActiveEffect.create(effectData, {parent: target.actor}) + .then(e => ui.notifications.info(`Added "${e.name}" to "${target.actor.name}"`)) + }) +} + +/* -------------------------------------------- */ +/* +async function _onChatUseTalent(event) { + const token = event.currentTarget.closest('.weirdwizard') + const actor = _getChatCardActor(token) + if (!actor) return + + const div = event.currentTarget.children[0] + const talentId = div.dataset.itemId + actor.rollTalent(talentId) +} + +/* -------------------------------------------- */ +/* +async function _onChatRequestChallengeRoll(event) { + event.preventDefault() + const li = event.currentTarget + const item = li.children[0] + const attribute = item.dataset.attribute + + const start = li.closest('.request-challengeroll') + let boonsbanes = start.children[0].value + if (boonsbanes == undefined) boonsbanes = parseInt(item.dataset.boba) + if (isNaN(boonsbanes)) boonsbanes = 0 + + var selected = tokenManager.targets + if (selected.length == 0) { + ui.notifications.info(game.i18n.localize('WW.DialogWarningActorsNotSelected')) + } + + let boonsbanestext = '' + if (boonsbanes == 1) { + boonsbanestext = boonsbanes + ' ' + game.i18n.localize('WW.DialogBoon') + } + if (boonsbanes > 1) { + boonsbanestext = boonsbanes + ' ' + game.i18n.localize('WW.DialogBoons') + } + if (boonsbanes == -1) { + boonsbanestext = boonsbanes.toString().replace('-', '') + ' ' + game.i18n.localize('WW.DialogBane') + } + if (boonsbanes < -1) { + boonsbanestext = boonsbanes.toString().replace('-', '') + ' ' + game.i18n.localize('WW.DialogBanes') + } + + selected.forEach(token => { + const actor = token.actor + + var templateData = { + actor: actor, + data: { + attribute: { + value: game.i18n.localize(CONFIG.DL.attributes[attribute.toLowerCase()]), + }, + boonsbanes: { + value: boonsbanes, + }, + boonsbanestext: { + value: boonsbanestext, + }, + }, + } + + const chatData = { + user: game.user.id, + speaker: { + actor: actor.id, + token: actor.token, + alias: actor.name, + }, + } + + chatData.whisper = ChatMessage.getWhisperRecipients(actor.name) + + const template = 'systems/demonlord/templates/chat/makechallengeroll.hbs' + renderTemplate(template, templateData).then(content => { + chatData.content = content + + ChatMessage.create(chatData) + }) + }) +} + +/* -------------------------------------------- */ +/* +async function _onChatMakeChallengeRoll(event) { + event.preventDefault() + const li = event.currentTarget + const item = li.children[0] + const attributeName = item.dataset.attribute + const boonsbanes = item.dataset.boonsbanes + const actorId = item.dataset.actorid + const actor = game.actors.get(actorId) + const attribute = actor.getAttribute(attributeName) + const start = li.closest('.weirdwizard') + const boonsbanesEntered = start.children[1].children[0].children[0].children[1]?.value + + actor.rollAttribute(attribute, parseInt(boonsbanes) + parseInt(boonsbanesEntered), 0) +} + +/* -------------------------------------------- */ +/* +async function _onChatRequestInitRoll(event) { + event.preventDefault() + + var selected = tokenManager.targets + if (selected.length == 0) { + ui.notifications.info(game.i18n.localize('WW.DialogWarningActorsNotSelected')) + } + + selected.forEach(token => { + const actor = token.actor + + var templateData = { + actor: actor, + token: canvas.tokens.controlled[0]?.data, + data: {}, + } + + const chatData = { + user: game.user.id, + speaker: { + actor: actor.id, + token: actor.token, + alias: actor.name, + }, + } + + chatData.whisper = ChatMessage.getWhisperRecipients(actor.name) + + const template = 'systems/demonlord/templates/chat/makeinitroll.hbs' + renderTemplate(template, templateData).then(content => { + chatData.content = content + ChatMessage.create(chatData) + }) + }) +} + +/* -------------------------------------------- */ +/* +async function _onChatMakeInitRoll(event) { + event.preventDefault() + const li = event.currentTarget + const item = li.children[0] + const actorId = item.dataset.actorid + const actor = game.actors.get(actorId) + let combatantFound = null + + for (const combatant of game.combat.combatants) { + if (combatant.actor?._id === actor._id) { + combatantFound = combatant + } + } + + if (combatantFound) { + game.combat.rollInitiative(combatantFound._id) + } +} + +/* -------------------------------------------- */ + +/** + * Get the Actor which is the author of a chat card + * @param {HTMLElement} card The chat card being used + * @return {Actor|null} The Actor entity or null + * @private +*/ + +function _getChatCardActor(card) { + console.log(card) + // Case 1 - a synthetic actor from a Token + const tokenKey = card.dataset.tokenId + if (tokenKey) { + const [sceneId, tokenId] = tokenKey.split('.') + const scene = game.scenes.get(sceneId) + if (!scene) return null + const tokenData = scene.items.get(tokenId) + if (!tokenData) return null + const token = new Token(tokenData) + return token.actor + } + + // Case 2 - use Actor ID directory + const actorId = card.dataset.actorId + return game.actors.get(actorId) || null +} + +/* -------------------------------------------- */ + +/** + * Get the Actor which is the target of a chat card + * @param {HTMLElement} _card The chat card being used + * @return {Array.} An Array of Actor entities, if any + * @private + */ +// eslint-disable-next-line no-unused-vars +/*function _getChatCardTargets(_card) { + const character = game.user.character + const controlled = canvas.tokens.controlled + const targets = controlled.reduce((arr, t) => (t.actor ? arr.concat([t.actor]) : arr), []) + if (character && controlled.length === 0) targets.push(character) + return targets +} + +/* -------------------------------------------- */ + +/*async function _onChatPlaceTemplate(event) { + event.preventDefault() + const itemUuid = $(event.currentTarget).data('itemUuid') + const item = await fromUuid(itemUuid) + + const template = game.weirdwizard.canvas.ActionTemplate.fromItem(item) + if (template) { + template.drawPreview() + } +} + +/* -------------------------------------------- */ \ No newline at end of file diff --git a/module/config.mjs b/module/config.mjs index 57516ba..60cad2d 100644 --- a/module/config.mjs +++ b/module/config.mjs @@ -98,12 +98,125 @@ WW.itemQualities = { "inferior": "WW.QualityInferior" }; -WW.dropdownGrip = { +WW.weaponGrip = { "One": "WW.GripOne", "Two": "WW.GripTwo", "Off": "WW.GripOff" }; +WW.weaponProperties = { + "ammunition": { + "label": "WW.Properties.Ammunition.Label", + "tip": "WW.Properties.Ammunition.Tip", + "path": "system.properties.ammunition", + }, + "brutal": { + "label": "WW.Properties.Brutal.Label", + "tip": "WW.Properties.Brutal.Tip", + "path": "system.properties.brutal", + }, + "concussing": { + "label": "WW.Properties.Concussing.Label", + "tip": "WW.Properties.Concussing.Tip", + "path": "system.properties.concussing", + }, + "disarming": { + "label": "WW.Properties.Disarming.Label", + "tip": "WW.Properties.Disarming.Tip", + "path": "system.properties.disarming", + }, + "driving": { + "label": "WW.Properties.Driving.Label", + "tip": "WW.Properties.Driving.Tip", + "path": "system.properties.driving", + }, + "fast": { + "label": "WW.Properties.Fast.Label", + "tip": "WW.Properties.Fast.Tip", + "path": "system.properties.fast", + }, + "firearm": { + "label": "WW.Properties.Firearm.Label", + "tip": "WW.Properties.Firearm.Tip", + "path": "system.properties.firearm", + }, + "great": { + "label": "WW.Properties.Great.Label", + "tip": "WW.Properties.Great.Tip", + "path": "system.properties.great", + }, + "light": { + "label": "WW.Properties.Light.Label", + "tip": "WW.Properties.Light.Tip", + "path": "system.properties.light", + }, + "long": { + "label": "WW.Properties.Long.Label", + "tip": "WW.Properties.Long.Tip", + "path": "system.properties.long", + }, + "nimble": { + "label": "WW.Properties.Nimble.Label", + "tip": "WW.Properties.Nimble.Tip", + "path": "system.properties.nimble", + }, + "painful": { + "label": "WW.Properties.Painful.Label", + "tip": "WW.Properties.Painful.Tip", + "path": "system.properties.painful", + }, + "precise": { + "label": "WW.Properties.Precise.Label", + "tip": "WW.Properties.Precise.Tip", + "path": "system.properties.precise", + }, + "range": { + "label": "WW.Properties.Range.Label", + "tip": "WW.Properties.Range.Tip", + "path": "system.properties.range", + }, + "reload": { + "label": "WW.Properties.Reload.Label", + "tip": "WW.Properties.Reload.Tip", + "path": "system.properties.reload" + }, + "sharp": { + "label": "WW.Properties.Sharp.Label", + "tip": "WW.Properties.Sharp.Tip", + "path": "system.properties.sharp", + }, + "shattering": { + "label": "WW.Properties.Shattering.Label", + "tip": "WW.Properties.Shattering.Tip", + "path": "system.properties.shattering", + }, + "slow": { + "label": "WW.Properties.Slow.Label", + "tip": "WW.Properties.Slow.Tip", + "path": "system.properties.slow", + }, + "special": { + "label": "WW.Properties.Special.Label", + "tip": "WW.Properties.Special.Tip", + "path": "system.properties.special", + }, + "thrown": { + "label": "WW.Properties.Thrown.Label", + "tip": "WW.Properties.Thrown.Tip", + "path": "system.properties.thrown", + }, + "unbalancing": { + "label": "WW.Properties.Unbalancing.Label", + "tip": "WW.Properties.Unbalancing.Tip", + "path": "system.properties.unbalancing", + }, + "versatile": { + "label": "WW.Properties.Versatile.Label", + "tip": "WW.Properties.Versatile.Tip", + "path": "system.properties.versatile", + } +}; + WW.armorTypes = { "light": "WW.Armor.Light", "medium": "WW.Armor.Medium", diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 7392f72..880b230 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -48,8 +48,12 @@ export class WeirdWizardActor extends Actor { this.system.stats.speed.raw = this.system.stats.speed.value; // Reset Natural Defense and Defense before Active Effects - this.system.stats.defense.natural = 10; - this.system.stats.defense.total = 0; + + if (this.type == 'Character') { + this.system.stats.defense.natural = 10; + this.system.stats.defense.total = 0; + } + } async _preCreate(data, options, user) { @@ -112,6 +116,16 @@ export class WeirdWizardActor extends Actor { for (let [key, attribute] of Object.entries(system.attributes)) { if (key != 'luck') attribute.mod = attribute.value - 10; } + + // Create .statuses manually for v10 + if (this.statuses == undefined) { + this.statuses = this.effects.reduce((acc, eff) => { + if(!eff.modifiesActor) return acc; + const status = eff.flags.core?.statusId; + if(status) acc.add(status); + return acc; + }, new Set()); + } // Make separate methods for each Actor type (character, npc, etc.) to keep // things organized. diff --git a/module/documents/item.mjs b/module/documents/item.mjs index 98ab59c..ddb7fb4 100644 --- a/module/documents/item.mjs +++ b/module/documents/item.mjs @@ -3,6 +3,8 @@ * @extends {Item} */ +import { capitalize, i18n } from '../helpers/utils.mjs'; + export class WeirdWizardItem extends Item { /** * Augment the basic Item data model with additional dynamic data. @@ -12,9 +14,35 @@ export class WeirdWizardItem extends Item { super.prepareData(); // Get the Item's data - const itemData = this.system; + const system = this.system; const actorData = this.actor ? this.actor.system : {}; - const system = itemData; + + // Prepare properties list for weapons + if (system.subtype == 'weapon') { + let properties = system.properties; + + // Compatibility: Convert old string data to object + if (typeof properties == 'string') properties = {}; + + let list = ''; + + //console.log(Object.entries(properties)) + Object.entries(properties).map((x) => { + + if (x[1]) list = list.concat( + list ? + ', ' + i18n('WW.Properties.' + capitalize(x[0]) + '.Label') : + i18n('WW.Properties.' + capitalize(x[0]) + '.Label') + + ) + + }) + + this.system.propertiesList = list; + + console.log(this.system) + } + } async _preCreate(data, options, user) { diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs index 2f20f22..fe4b3fe 100644 --- a/module/helpers/utils.mjs +++ b/module/helpers/utils.mjs @@ -9,13 +9,11 @@ export function getEffectBoons (attribute) { } // Formatting - -//export const i18n = (s,d) => d ? game.i18n.format(s,d) : game.i18n.format(s) export const i18n = (s,d={}) => game.i18n.format(s,d); -/*export function capitalize(string) { +export function capitalize(string) { return string?.charAt(0).toUpperCase() + string?.toLowerCase().slice(1) -}*/ +} export function plusify(x) { return x >= 0 ? '+' + x : x diff --git a/module/sheets/actor-sheet.mjs b/module/sheets/actor-sheet.mjs index d587784..9e3c2f0 100644 --- a/module/sheets/actor-sheet.mjs +++ b/module/sheets/actor-sheet.mjs @@ -74,6 +74,8 @@ export class WeirdWizardActorSheet extends ActorSheet { CONFIG.statusEffects.forEach(function (e) { context.hasEffect[e.id] = actorData.statuses.has(e.id); }) + console.log(actorData.statuses) + console.log(actorData.effects) // Prepare character data and items. if (actorData.type == 'Character') { diff --git a/module/sheets/apps/defense-details.mjs b/module/sheets/apps/defense-details.mjs deleted file mode 100644 index f810dc1..0000000 --- a/module/sheets/apps/defense-details.mjs +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Extend FormApplication to make a window to edit Defense Details - * @extends {FormApplication} -*/ - -export class defenseDetails extends FormApplication { - static get defaultOptions() { - const options = super.defaultOptions; - options.id = "defense-details"; - options.template = "systems/weirdwizard/templates/apps/defense-details.hbs"; - options.height = "auto"; - options.width = 450; - options.title = "Defense Details"; - return options; - } - - getData(options = {}) { - let context = super.getData() - //context.choices = game.settings.get('ooct','choices').map(({label,icon}) => ({label,icon,rendered:iconToHTML({icon,label})})) - // Pass down actor data to application. - context.system = this.object.system; - - // Prepare dropdown menu objects. - context.armorObj = Object.fromEntries(Object.entries(CONFIG.WW.armor).map(i => [i[0], i[1].label])) - - return context - } - - activateListeners(html) { - super.activateListeners(html); - - // Handle resetting the window - html.find('#def-reset').click(() => this.render(true)) // Only kinda partially working - - // Handle closing the window without saving - html.find('#def-cancel').click(() => this.close({ submit: false })) // Let the Cancel button close without saving - - // Handle deleting the row - html.find('li a .fa-trash').click(ev => ev.target.parentElement.parentElement.remove()) - - // Handle adding a row - html.find('.add-row').click(ev => { - let currentcount = html[0].querySelectorAll(".action").length - let new_row = $(`
  • `) - new_row.insertBefore(ev.currentTarget) - //new_row.find('.icon-text').change(configIconUpdate) - //html.find('.label-text').change(configTextUpdate) - new_row.find('a .fa-trash').click(ev => ev.target.parentElement.parentElement.remove()) - }) - - function updateField(ev) { - //const totalHealth = parseInt(parent.querySelector('input[type=number].starting').value) + noviceBonus + expertBonus + masterBonus + parseInt(parent.querySelector('input[type=number].bonus').value) - parseInt(parent.querySelector('input[type=number].lost').value); - - //parent.querySelector('.health-display.total').innerHTML = totalHealth; - }; - - const el = html.find('input[type=number]'); - el.change((ev) => updateField(ev)); - el.change(); - } - - async _updateObject(event, formData) { // Update actor data. - - this.object.update({ - 'system.stats.defense': { - 'natural': formData.natural, - 'armor': formData.armor, - 'bonuses': Object.values(expandObject(formData)?.bonuses ?? { 0: { 'name': 'Unknown', 'bonus': '0' } }).filter(c => c.name && c.bonus) - } - }) - } -} \ No newline at end of file diff --git a/module/sheets/apps/roll-attribute.mjs b/module/sheets/apps/roll-attribute.mjs index cdc567c..ff3eeb4 100644 --- a/module/sheets/apps/roll-attribute.mjs +++ b/module/sheets/apps/roll-attribute.mjs @@ -119,7 +119,7 @@ export class rollAttribute extends FormApplication { let messageData = { speaker: ChatMessage.getSpeaker({ actor: this.actor }), flavor: label, - content: rollHtml + content, + content: rollHtml + content/* + ''*/, sound: CONFIG.sounds.dice }; diff --git a/module/sheets/item-sheet.mjs b/module/sheets/item-sheet.mjs index 9b16539..8e5a6a4 100644 --- a/module/sheets/item-sheet.mjs +++ b/module/sheets/item-sheet.mjs @@ -36,16 +36,11 @@ export class WeirdWizardItemSheet extends ItemSheet { const context = super.getData(); // Use a safe clone of the item data for further operations. - context.system = context.data.system; // Prepare enriched variables for editor. context.system.description.enriched = await TextEditor.enrichHTML(context.system.description.value, { async: true }) - if (context.item.type == 'Talent') { - - } - // Prepare dropdown menu objects. switch (context.item.type) { @@ -54,15 +49,20 @@ export class WeirdWizardItemSheet extends ItemSheet { context.coinsObj = CONFIG.WW.coins; context.qualitiesObj = CONFIG.WW.itemQualities; context.attributesObj = CONFIG.WW.dropdownAttributes; - context.frequenciesObj = CONFIG.WW.dropdownFrequencies; + //context.frequenciesObj = CONFIG.WW.dropdownFrequencies; context.armorObj = CONFIG.WW.armorTypes; - context.gripObj = CONFIG.WW.dropdownGrip; + + if (context.system.subtype == 'weapon') { + context.gripObj = CONFIG.WW.weaponGrip; + context.properties = CONFIG.WW.weaponProperties; + } + break; case 'Trait or Talent': context.subtypesObj = CONFIG.WW.dropdownSubtypes; context.sourcesObj = CONFIG.WW.talentSources; - context.frequenciesObj = CONFIG.WW.dropdownFrequencies; + //context.frequenciesObj = CONFIG.WW.dropdownFrequencies; context.attributesObj = CONFIG.WW.dropdownAttributes; break; @@ -87,7 +87,7 @@ export class WeirdWizardItemSheet extends ItemSheet { // Prepare effect change key-labels context.effectChangeKeys = CONFIG.WW.effectChangeKeys; - + return context; } @@ -111,9 +111,13 @@ export class WeirdWizardItemSheet extends ItemSheet { // Everything below here is only needed if the sheet is editable if (!this.options.editable) return; + const system = this.object.system; + ////////////////// EFFECTS //////////////////// // Active Effect management html.find('.effect-control').click(ev => onManageActiveEffect(ev, this.object)); + } + } diff --git a/module/weirdwizard.mjs b/module/weirdwizard.mjs index ceb7a42..0157de6 100644 --- a/module/weirdwizard.mjs +++ b/module/weirdwizard.mjs @@ -12,6 +12,7 @@ import { Global } from './helpers/utils.mjs'; import { preloadHandlebarsTemplates } from './helpers/templates.mjs'; import { WWAfflictions } from './active-effects/afflictions.mjs'; import { WWActiveEffectConfig } from './active-effects/effects-config.mjs'; +import { initChatListeners } from './chat/chat-listeners.mjs' /* -------------------------------------------- */ /* Init Hook */ @@ -118,4 +119,6 @@ Hooks.once('setup', function () { }); +Hooks.on('renderChatLog', (app, html, _data) => initChatListeners(html)) + console.log('weirdwizard.mjs loaded.') \ No newline at end of file diff --git a/packs/armor/000033.log b/packs/armor/000046.log similarity index 100% rename from packs/armor/000033.log rename to packs/armor/000046.log diff --git a/packs/armor/CURRENT b/packs/armor/CURRENT index d95f027..800d995 100644 --- a/packs/armor/CURRENT +++ b/packs/armor/CURRENT @@ -1 +1 @@ -MANIFEST-000031 +MANIFEST-000045 diff --git a/packs/armor/LOG b/packs/armor/LOG index 9329b29..3a26875 100644 --- a/packs/armor/LOG +++ b/packs/armor/LOG @@ -1,7 +1,3 @@ -2023/08/21-21:16:30.071 313c Recovering log #29 -2023/08/21-21:16:30.080 313c Delete type=0 #29 -2023/08/21-21:16:30.080 313c Delete type=3 #27 -2023/08/21-21:48:40.028 2a68 Level-0 table #34: started -2023/08/21-21:48:40.028 2a68 Level-0 table #34: 0 bytes OK -2023/08/21-21:48:40.030 2a68 Delete type=0 #32 -2023/08/21-21:48:40.042 2a68 Manual compaction at level-0 from '!items!8kdTjI16oQxvcKow' @ 72057594037927935 : 1 .. '!items.effects!r7Vjowz8ZGGAbD3n.UZZ9Tb2Wk7N68nYN' @ 0 : 0; will stop at (end) +2023/08/23-13:45:03.178 2914 Recovering log #44 +2023/08/23-13:45:03.186 2914 Delete type=0 #44 +2023/08/23-13:45:03.186 2914 Delete type=3 #43 diff --git a/packs/armor/LOG.old b/packs/armor/LOG.old index d9b820f..b832c8d 100644 --- a/packs/armor/LOG.old +++ b/packs/armor/LOG.old @@ -1,7 +1,3 @@ -2023/08/21-21:15:07.693 1d40 Recovering log #25 -2023/08/21-21:15:07.698 1d40 Delete type=0 #25 -2023/08/21-21:15:07.698 1d40 Delete type=3 #23 -2023/08/21-21:16:17.209 2a68 Level-0 table #30: started -2023/08/21-21:16:17.209 2a68 Level-0 table #30: 0 bytes OK -2023/08/21-21:16:17.210 2a68 Delete type=0 #28 -2023/08/21-21:16:17.230 2a68 Manual compaction at level-0 from '!items!8kdTjI16oQxvcKow' @ 72057594037927935 : 1 .. '!items.effects!r7Vjowz8ZGGAbD3n.UZZ9Tb2Wk7N68nYN' @ 0 : 0; will stop at (end) +2023/08/23-00:26:57.604 4e98 Recovering log #42 +2023/08/23-00:26:57.610 4e98 Delete type=0 #42 +2023/08/23-00:26:57.610 4e98 Delete type=3 #41 diff --git a/packs/armor/MANIFEST-000031 b/packs/armor/MANIFEST-000045 similarity index 58% rename from packs/armor/MANIFEST-000031 rename to packs/armor/MANIFEST-000045 index 37464fb..9001674 100644 Binary files a/packs/armor/MANIFEST-000031 and b/packs/armor/MANIFEST-000045 differ diff --git a/packs/weapons/000033.log b/packs/weapons/000046.log similarity index 100% rename from packs/weapons/000033.log rename to packs/weapons/000046.log diff --git a/packs/weapons/CURRENT b/packs/weapons/CURRENT index d95f027..800d995 100644 --- a/packs/weapons/CURRENT +++ b/packs/weapons/CURRENT @@ -1 +1 @@ -MANIFEST-000031 +MANIFEST-000045 diff --git a/packs/weapons/LOG b/packs/weapons/LOG index 6e85dd5..d4178ed 100644 --- a/packs/weapons/LOG +++ b/packs/weapons/LOG @@ -1,7 +1,3 @@ -2023/08/21-21:16:30.071 1d40 Recovering log #28 -2023/08/21-21:16:30.078 1d40 Delete type=0 #28 -2023/08/21-21:16:30.078 1d40 Delete type=3 #26 -2023/08/21-21:48:40.056 2a68 Level-0 table #34: started -2023/08/21-21:48:40.056 2a68 Level-0 table #34: 0 bytes OK -2023/08/21-21:48:40.057 2a68 Delete type=0 #32 -2023/08/21-21:48:40.071 2a68 Manual compaction at level-0 from '!items!0u3rLO1CFHSf8aJw' @ 72057594037927935 : 1 .. '!items.effects!qVKiDnaFCga0dvi5.htxuI15UT0BZgV1u' @ 0 : 0; will stop at (end) +2023/08/23-13:45:03.180 b28 Recovering log #44 +2023/08/23-13:45:03.186 b28 Delete type=0 #44 +2023/08/23-13:45:03.186 b28 Delete type=3 #43 diff --git a/packs/weapons/LOG.old b/packs/weapons/LOG.old index 558a161..98b3b47 100644 --- a/packs/weapons/LOG.old +++ b/packs/weapons/LOG.old @@ -1,14 +1,3 @@ -2023/08/21-21:15:07.693 1860 Recovering log #24 -2023/08/21-21:15:07.698 1860 Delete type=0 #24 -2023/08/21-21:15:07.698 1860 Delete type=3 #22 -2023/08/21-21:16:17.211 2a68 Level-0 table #29: started -2023/08/21-21:16:17.226 2a68 Level-0 table #29: 2149 bytes OK -2023/08/21-21:16:17.228 2a68 Delete type=0 #27 -2023/08/21-21:16:17.230 2a68 Manual compaction at level-0 from '!items!0u3rLO1CFHSf8aJw' @ 72057594037927935 : 1 .. '!items.effects!qVKiDnaFCga0dvi5.htxuI15UT0BZgV1u' @ 0 : 0; will stop at '!items.effects!qVKiDnaFCga0dvi5.htxuI15UT0BZgV1u' @ 16 : 1 -2023/08/21-21:16:17.230 2a68 Compacting 1@0 + 1@1 files -2023/08/21-21:16:17.235 2a68 Generated table #30@0: 16 keys, 9672 bytes -2023/08/21-21:16:17.235 2a68 Compacted 1@0 + 1@1 files => 9672 bytes -2023/08/21-21:16:17.240 2a68 compacted to: files[ 0 1 0 0 0 0 0 ] -2023/08/21-21:16:17.240 2a68 Delete type=2 #9 -2023/08/21-21:16:17.240 2a68 Delete type=2 #29 -2023/08/21-21:16:17.241 2a68 Manual compaction at level-0 from '!items.effects!qVKiDnaFCga0dvi5.htxuI15UT0BZgV1u' @ 16 : 1 .. '!items.effects!qVKiDnaFCga0dvi5.htxuI15UT0BZgV1u' @ 0 : 0; will stop at (end) +2023/08/23-00:26:57.604 c9c Recovering log #42 +2023/08/23-00:26:57.610 c9c Delete type=0 #42 +2023/08/23-00:26:57.610 c9c Delete type=3 #41 diff --git a/packs/weapons/MANIFEST-000031 b/packs/weapons/MANIFEST-000045 similarity index 58% rename from packs/weapons/MANIFEST-000031 rename to packs/weapons/MANIFEST-000045 index af2a454..f2b93e3 100644 Binary files a/packs/weapons/MANIFEST-000031 and b/packs/weapons/MANIFEST-000045 differ diff --git a/styles/weirdwizard.css b/styles/weirdwizard.css index 032b994..beb5854 100644 --- a/styles/weirdwizard.css +++ b/styles/weirdwizard.css @@ -268,8 +268,9 @@ border-bottom: 3px double black; font-family: var(--font-title); font-size: 24px; - padding-bottom: 2px; text-transform: uppercase; + padding-bottom: 2px; + margin-top: 5px; } .weirdwizard .window-content h3 { @@ -532,7 +533,9 @@ display: flex; flex-direction: row; align-items: center; - margin-bottom: 5px; +} +.weirdwizard .justify-between { + justify-content: space-between; } .weirdwizard .stat-inline, .stat-stretch { @@ -809,6 +812,21 @@ input[type="checkbox"].checkbox-reloaded { font-weight: bold; } +.weirdwizard .properties-list { + font-size: smaller; + display: flex; + flex-direction: row; + flex-wrap: wrap; + white-space: nowrap; + justify-content: space-between; + gap: 5px; + margin-top: 5px; +} + +.weirdwizard .properties-list > div { + +} + .weirdwizard .effect img { background-color: #606060; } @@ -884,22 +902,29 @@ input[type="checkbox"].checkbox-reloaded { /* Affliction Tab */ -.dl-item-row-header, .affliction { +.dl-item-row-header, .selectable { background: #00000005; border-radius: 2px; border: 1px solid #0000001a; } -.affliction { +.selectable { border-radius: 4px; box-sizing: content-box; padding: 2px; - padding-right: 6px; height: 16px; position: relative; display: inline-flex !important; width: fit-content; } +.affliction.selectable { + padding-right: 6px; +} +.selectable input[type=number] { + pointer-events: none !important; + margin-left: 5px !important; + cursor: default !important; +} .affliction i { width: 16px; height: 16px; @@ -919,30 +944,30 @@ input[type="checkbox"].checkbox-reloaded { padding-left: 2px; margin-left: 2px; } -.affliction:not(.nohover):hover, .affliction:not(.nohover):hover span { +.selectable:not(.nohover):hover, .selectable:not(.nohover):hover span { border-color: dimgray; cursor: pointer; } -.affliction.selectable input[type=checkbox] { +/*.affliction*/.selectable input[type=checkbox] { position: absolute; width: 100%; height: 100%; - opacity: 0; + opacity: 0; /* Hide the checkbox */ } -.affliction.selectable input[type=checkbox]:hover { +/*.affliction*/.selectable input[type=checkbox]:hover { cursor: pointer; } -.affliction.selectable:not(.selected) { +/*.affliction*/.selectable:not(.selected) { color: gray; } -.affliction.selectable:not(.selected) i { +/*.affliction*/.selectable:not(.selected) i { background-color: gray; } -.affliction.selectable.selected, .affliction.selectable.selected .sep { +/*.affliction*/.selectable.selected, /*.affliction*/.selectable.selected .sep { border-color: var(--highlight-title); background-color: var(--highlight); } -.affliction input { +.selectable input { text-align: center !important; margin: 0 !important; height: 100% !important; @@ -950,17 +975,14 @@ input[type="checkbox"].checkbox-reloaded { color: black !important; } -.affliction input:hover, .affliction input:focus { +.selectable input:hover, .selectable input:focus { cursor: text; box-shadow: 0 0 2px 1px var(--color-shadow-primary) !important; background-color: transparent !important; padding: 0 !important; border: 1px solid transparent !important; } -.affliction input:last-child { - margin-right: -4px !important; -} -.affliction.nohover:hover { +.selectable.nohover:hover { cursor: default; } diff --git a/system.json b/system.json index 4db3d2f..7d35b9b 100644 --- a/system.json +++ b/system.json @@ -28,12 +28,6 @@ "name": "English", "path": "lang/en.json", "flags": {} - }, - { - "lang": "pt", - "name": "Português (Brasil)", - "path": "lang/pt.json", - "flags": {} } ], "packs": [ diff --git a/template.json b/template.json index 1695083..75cdcef 100644 --- a/template.json +++ b/template.json @@ -209,11 +209,33 @@ "subtype": "generic", "quality": "standard", "attribute": "", - "damage": "1d6", + "damage": "", "grip": "One-Handed", - "reload": false, + "properties": { + "ammunition": false, + "brutal": false, + "concussing": false, + "disarming": false, + "driving": false, + "fast": false, + "firearm": false, + "great": false, + "light": false, + "long": false, + "nimble": false, + "painful": false, + "precise": false, + "range": false, + "reload": false, + "sharp": false, + "shattering": false, + "slow": false, + "special": false, + "thrown": false, + "unbalancing": false, + "versatile": false + }, "reloaded": true, - "properties": "", "armorType": "light", "capacity": 0, "consumableType": "potion", diff --git a/templates/actors/parts/Character-equipment.hbs b/templates/actors/parts/Character-equipment.hbs index 8d24ed9..07be2b6 100644 --- a/templates/actors/parts/Character-equipment.hbs +++ b/templates/actors/parts/Character-equipment.hbs @@ -34,7 +34,7 @@
    {{localize "WW.Name"}}
    {{localize "WW.Damage.Title"}}
    {{localize "WW.Grip"}}
    -
    {{localize "WW.Properties"}}
    +
    {{localize "WW.Properties.Title"}}
    {{localize "WW.Add"}} @@ -51,7 +51,7 @@
    {{item.system.grip}}
    -
    {{item.system.properties}}
    +
    {{item.system.propertiesList}}
    diff --git a/templates/actors/parts/Character-summary.hbs b/templates/actors/parts/Character-summary.hbs index bdc7130..74a4434 100644 --- a/templates/actors/parts/Character-summary.hbs +++ b/templates/actors/parts/Character-summary.hbs @@ -106,8 +106,8 @@ {{#if item.system.description.value}}{{/if}} {{#if item.system.reload}}{{/if}} - ({{item.system.grip}}{{#if item.system.properties}}; - {{item.system.properties}}{{/if}}) + ({{item.system.grip}}{{#if item.system.propertiesList}}; + {{item.system.propertiesList}}{{/if}}) {{item.system.attributeLabel}} {{#if item.system.boons}} {{localize "WW.Boons.With"}} {{item.system.boons}} diff --git a/templates/actors/parts/NPC-stats.hbs b/templates/actors/parts/NPC-stats.hbs index d4d49eb..b630cb6 100644 --- a/templates/actors/parts/NPC-stats.hbs +++ b/templates/actors/parts/NPC-stats.hbs @@ -24,11 +24,11 @@
    {{!-- Defense --}} - + + data-dtype="String" placeholder="{{localize "WW.Defense.Details"}}" />
    {{!-- Damage / Health --}} diff --git a/templates/actors/parts/NPC-summary.hbs b/templates/actors/parts/NPC-summary.hbs index bc716f2..7c58c0a 100644 --- a/templates/actors/parts/NPC-summary.hbs +++ b/templates/actors/parts/NPC-summary.hbs @@ -139,7 +139,7 @@ {{#if item.system.reload}}{{/if}} - {{#if item.system.properties}}({{item.system.properties}}) {{/if}} + {{#if item.system.propertiesList}}({{item.system.propertiesList}}) {{/if}} {{item.system.attributeLabel}} {{#if item.system.boons}} {{localize "WW.Boons.With"}} {{item.system.boons}} diff --git a/templates/items/item-Equipment-sheet.hbs b/templates/items/item-Equipment-sheet.hbs index 64c847d..aedb0fa 100644 --- a/templates/items/item-Equipment-sheet.hbs +++ b/templates/items/item-Equipment-sheet.hbs @@ -68,38 +68,47 @@
    - {{#if (eq system.subtype 'weapon')}} {{!-- Weapon Params --}} + {{!-- Weapon Params --}} + {{#if (eq system.subtype 'weapon')}}

    {{localize "WW.WeaponDetails"}}

    +
    - - - - {{!-- Grip --}} -
    - - -
    + + - {{!-- Range --}} -
    - - -
    + {{!-- Grip --}} +
    + + + +
    + +
    + + {{!-- Weapon Properties --}} +
    + + {{system.propertiesList}} +
    + +
    + {{#each properties as |property id|}} +
    + + + + {{localize property.label}} - {{!-- Reload --}} -
    - - + {{#if (or (eq id "range") (eq id "thrown"))}} + + {{/if}}
    -
    -
    - - -
    + {{/each}}
    +
    {{/if}}