From 0bc6b43ffe93bbbc4ea528bb21e1e23caf363978 Mon Sep 17 00:00:00 2001 From: LeRatierBretonnien Date: Mon, 12 Jan 2026 10:45:20 +0100 Subject: [PATCH] Add spells rolls and enhance CSS styling --- css/fvtt-prism-rpg.css | 776 +++++++++++++++++- lang/en.json | 45 +- .../applications/sheets/character-sheet.mjs | 28 + module/config/characteristic-tables.mjs | 150 ++-- module/config/system.mjs | 46 +- module/documents/actor.mjs | 57 +- module/documents/roll.mjs | 189 ++++- module/models/armor.mjs | 2 +- module/models/character.mjs | 15 +- module/models/equipment.mjs | 29 +- module/models/shield.mjs | 2 +- module/models/weapon.mjs | 19 +- prism-rpg.mjs | 23 +- styles/chat.less | 422 +++++++++- styles/fvtt-prism-rpg.less | 3 +- styles/roll-dialog-modern.less | 305 +++++++ styles/roll.less | 54 ++ templates/character-biography.hbs | 4 +- templates/character-combat.hbs | 30 +- templates/character-equipment.hbs | 10 +- templates/character-main.hbs | 15 +- templates/character-miracles.hbs | 10 +- templates/character-spells.hbs | 24 +- templates/character-subattributes-old.hbs | 257 ------ templates/chat-message.hbs | 287 ++++--- templates/roll-dialog-old.hbs | 119 --- templates/roll-dialog-v2.hbs | 195 +++++ templates/roll-dialog.hbs | 149 +++- templates/weapon.hbs | 41 +- 29 files changed, 2428 insertions(+), 878 deletions(-) create mode 100644 styles/roll-dialog-modern.less delete mode 100644 templates/character-subattributes-old.hbs delete mode 100644 templates/roll-dialog-old.hbs create mode 100644 templates/roll-dialog-v2.hbs diff --git a/css/fvtt-prism-rpg.css b/css/fvtt-prism-rpg.css index 3261d6f..34c2800 100644 --- a/css/fvtt-prism-rpg.css +++ b/css/fvtt-prism-rpg.css @@ -2669,44 +2669,6 @@ i.prismrpg { .prismrpg .vulnerability-content input[type="checkbox"]:checked::after { color: rgba(0, 0, 0, 0.1); } -.prismrpg.fortune img { - border: 0px; -} -.prismrpg.fortune .intro-chat { - border-radius: 20px; - display: flex; - flex-direction: row; -} -.prismrpg.fortune .intro-chat .intro-img { - padding: 5px; - width: 80px; - align-self: center; -} -.prismrpg.fortune .intro-chat .intro-right { - display: flex; - flex-direction: column; -} -.prismrpg.fortune .intro-chat .intro-right .introText { - font-family: var(--font-secondary); - font-size: calc(var(--font-size-standard) * 1.2); - width: 210px; - text-align: center; -} -.prismrpg.fortune .button.control, -.prismrpg.fortune .fortune-accepted { - display: flex; - justify-content: center; - align-items: center; - font-size: calc(var(--font-size-standard) * 1.3); -} -.prismrpg.ask-roll { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-family: var(--font-secondary); - font-size: calc(var(--font-size-standard) * 1.2); -} .prismrpg .equipment-content { font-family: var(--font-primary); font-size: calc(var(--font-size-standard) * 1); @@ -3700,6 +3662,446 @@ i.prismrpg { gap: 1rem; align-items: flex-start; } +.chat-log .message-content .prismrpg-chat-card { + font-family: var(--font-primary); + border-radius: 6px; + overflow: hidden; + background: linear-gradient(135deg, rgba(0, 0, 0, 0.05) 0%, rgba(0, 0, 0, 0.02) 100%); + border: 1px solid rgba(0, 0, 0, 0.2); + margin: 2px 0; +} +.chat-log .message-content .prismrpg-chat-card .chat-header { + display: flex; + gap: 8px; + padding: 6px 8px; + background: linear-gradient(135deg, #2c2c2c 0%, #1a1a1a 100%); + border-bottom: 1px solid #444; +} +.chat-log .message-content .prismrpg-chat-card .chat-header .chat-portrait { + flex-shrink: 0; + width: 36px; + height: 36px; + border-radius: 50%; + overflow: hidden; + border: 2px solid #666; + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4); +} +.chat-log .message-content .prismrpg-chat-card .chat-header .chat-portrait img { + width: 100%; + height: 100%; + object-fit: cover; +} +.chat-log .message-content .prismrpg-chat-card .chat-header .chat-title { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + gap: 2px; +} +.chat-log .message-content .prismrpg-chat-card .chat-header .chat-title .actor-name { + font-weight: bold; + font-size: 0.95em; + color: #e0e0e0; + text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); + line-height: 1.1; +} +.chat-log .message-content .prismrpg-chat-card .chat-header .chat-title .roll-name { + font-size: 0.8em; + color: #aaa; + line-height: 1.1; +} +.chat-log .message-content .prismrpg-chat-card .chat-header .chat-title .roll-type-badge { + display: inline-block; + padding: 1px 6px; + border-radius: 10px; + font-size: 0.7em; + font-weight: bold; + text-transform: uppercase; + margin-top: 2px; + width: fit-content; +} +.chat-log .message-content .prismrpg-chat-card .chat-header .chat-title .roll-type-badge.attack { + background: linear-gradient(135deg, #c41e3a 0%, #8b0000 100%); + color: white; + box-shadow: 0 1px 2px rgba(196, 30, 58, 0.4); +} +.chat-log .message-content .prismrpg-chat-card .chat-header .chat-title .bad-result { + color: #ff6b6b; + font-size: 0.75em; + margin-top: 1px; +} +.chat-log .message-content .prismrpg-chat-card .chat-content { + padding: 6px 8px; + display: flex; + flex-direction: column; + gap: 6px; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card { + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 4px; + padding: 6px; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-header, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-header, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-header, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-header { + display: flex; + align-items: center; + gap: 6px; + margin-bottom: 4px; + padding-bottom: 4px; + border-bottom: 1px solid rgba(255, 255, 255, 0.1); +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-header .weapon-name, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-header .weapon-name, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-header .weapon-name, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-header .weapon-name, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-header .spell-name, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-header .spell-name, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-header .spell-name, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-header .spell-name { + font-size: 0.95em; + color: #d4af37; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-header .badge, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-header .badge, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-header .badge, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-header .badge { + padding: 1px 4px; + border-radius: 3px; + font-size: 0.65em; + font-weight: bold; + text-transform: uppercase; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-header .badge.implement, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-header .badge.implement, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-header .badge.implement, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-header .badge.implement { + background: #4a5cf7; + color: white; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-header .badge.upcast, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-header .badge.upcast, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-header .badge.upcast, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-header .badge.upcast { + background: #9b59b6; + color: white; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-header .attribute-used, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-header .attribute-used, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-header .attribute-used, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-header .attribute-used { + font-size: 0.75em; + color: #999; + font-style: italic; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-stats, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-stats, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-stats, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-stats { + display: flex; + flex-wrap: wrap; + gap: 4px; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-stats .stat-item, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-stats .stat-item, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-stats .stat-item, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-stats .stat-item { + display: flex; + align-items: center; + gap: 3px; + padding: 2px 6px; + background: rgba(0, 0, 0, 0.2); + border-radius: 3px; + font-size: 0.75em; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-stats .stat-item i, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-stats .stat-item i, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-stats .stat-item i, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-stats .stat-item i { + color: #888; + font-size: 0.85em; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-stats .stat-item.apc, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-stats .stat-item.apc, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-stats .stat-item.apc, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-stats .stat-item.apc { + background: rgba(255, 193, 7, 0.2); + border: 1px solid rgba(255, 193, 7, 0.4); +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-stats .stat-item.apc i, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-stats .stat-item.apc i, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-stats .stat-item.apc i, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-stats .stat-item.apc i { + color: #ffc107; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-stats .stat-item.damage, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-stats .stat-item.damage, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-stats .stat-item.damage, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-stats .stat-item.damage { + background: rgba(244, 67, 54, 0.2); + border: 1px solid rgba(244, 67, 54, 0.4); +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-stats .stat-item.damage i, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-stats .stat-item.damage i, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-stats .stat-item.damage i, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-stats .stat-item.damage i { + color: #f44336; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-stats .stat-item.range, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-stats .stat-item.range, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-stats .stat-item.range, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-stats .stat-item.range { + background: rgba(76, 175, 80, 0.2); + border: 1px solid rgba(76, 175, 80, 0.4); +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-stats .stat-item.range i, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-stats .stat-item.range i, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-stats .stat-item.range i, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-stats .stat-item.range i { + color: #4caf50; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-stats .stat-item.reload, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-stats .stat-item.reload, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-stats .stat-item.reload, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-stats .stat-item.reload { + background: rgba(255, 152, 0, 0.2); + border: 1px solid rgba(255, 152, 0, 0.4); +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-stats .stat-item.reload i, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-stats .stat-item.reload i, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-stats .stat-item.reload i, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-stats .stat-item.reload i { + color: #ff9800; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-stats .stat-item.mana, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-stats .stat-item.mana, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-stats .stat-item.mana, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-stats .stat-item.mana { + background: rgba(33, 150, 243, 0.2); + border: 1px solid rgba(33, 150, 243, 0.4); +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-stats .stat-item.mana i, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-stats .stat-item.mana i, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-stats .stat-item.mana i, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-stats .stat-item.mana i { + color: #2196f3; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-stats .stat-item.upkeep, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-stats .stat-item.upkeep, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-stats .stat-item.upkeep, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-stats .stat-item.upkeep { + background: rgba(156, 39, 176, 0.2); + border: 1px solid rgba(156, 39, 176, 0.4); +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-stats .stat-item.upkeep i, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-stats .stat-item.upkeep i, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-stats .stat-item.upkeep i, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-stats .stat-item.upkeep i { + color: #9c27b0; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-stats .stat-item.characteristic, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-stats .stat-item.characteristic, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-stats .stat-item.characteristic, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-stats .stat-item.characteristic { + background: rgba(103, 58, 183, 0.2); + border: 1px solid rgba(103, 58, 183, 0.4); +} +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .weapon-stats .stat-item.characteristic i, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .weapon-stats .stat-item.characteristic i, +.chat-log .message-content .prismrpg-chat-card .chat-content .weapon-info-card .spell-stats .stat-item.characteristic i, +.chat-log .message-content .prismrpg-chat-card .chat-content .spell-info-card .spell-stats .stat-item.characteristic i { + color: #673ab7; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .special-badge { + display: inline-block; + padding: 2px 6px; + background: linear-gradient(135deg, #ff6b6b 0%, #c92a2a 100%); + color: white; + border-radius: 3px; + font-size: 0.75em; + font-weight: bold; + width: fit-content; + box-shadow: 0 1px 2px rgba(255, 107, 107, 0.4); +} +.chat-log .message-content .prismrpg-chat-card .chat-content .aiming-info { + display: flex; + align-items: center; + gap: 4px; + padding: 3px 6px; + background: rgba(76, 175, 80, 0.1); + border-left: 2px solid #4caf50; + border-radius: 3px; + font-size: 0.8em; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .aiming-info i { + color: #4caf50; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .formula-display { + display: flex; + align-items: center; + gap: 6px; + padding: 4px 8px; + background: rgba(0, 0, 0, 0.3); + border-radius: 3px; + font-family: 'Courier New', monospace; + font-size: 0.85em; + border: 1px dashed rgba(255, 255, 255, 0.2); +} +.chat-log .message-content .prismrpg-chat-card .chat-content .formula-display i { + color: #888; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .modifier-info { + display: flex; + gap: 8px; + padding: 3px 6px; + background: rgba(255, 255, 255, 0.05); + border-radius: 3px; + font-size: 0.75em; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .modifier-info span { + color: #aaa; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .dice-breakdown { + display: flex; + align-items: center; + gap: 4px; + padding: 2px 6px; + background: rgba(255, 255, 255, 0.05); + border-radius: 3px; + font-size: 0.8em; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .dice-breakdown i { + color: #888; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .roll-damage-button { + padding: 4px 10px; + background: linear-gradient(135deg, #c41e3a 0%, #8b0000 100%); + color: white; + border: none; + border-radius: 4px; + font-weight: bold; + font-size: 0.85em; + cursor: pointer; + display: flex; + align-items: center; + gap: 6px; + justify-content: center; + transition: all 0.2s; + box-shadow: 0 1px 3px rgba(196, 30, 58, 0.4); + margin-top: 4px; +} +.chat-log .message-content .prismrpg-chat-card .chat-content .roll-damage-button:hover { + transform: translateY(-1px); + box-shadow: 0 2px 4px rgba(196, 30, 58, 0.6); +} +.chat-log .message-content .prismrpg-chat-card .chat-content .roll-damage-button i { + font-size: 1em; +} +.chat-log .message-content .prismrpg-chat-card .roll-result { + padding: 8px; + background: linear-gradient(135deg, rgba(212, 175, 55, 0.2) 0%, rgba(212, 175, 55, 0.1) 100%); + border-top: 1px solid rgba(212, 175, 55, 0.5); +} +.chat-log .message-content .prismrpg-chat-card .roll-result .result-total { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; +} +.chat-log .message-content .prismrpg-chat-card .roll-result .result-total .total-label { + font-size: 0.85em; + color: #aaa; + text-transform: uppercase; + letter-spacing: 0.5px; +} +.chat-log .message-content .prismrpg-chat-card .roll-result .result-total .total-value { + font-size: 1.8em; + font-weight: bold; + color: #d4af37; + text-shadow: 0 1px 3px rgba(212, 175, 55, 0.5); + line-height: 1; +} +.chat-log .message-content .prismrpg-chat-card .roll-result .d30-result { + margin-top: 4px; + padding: 3px 6px; + background: rgba(0, 0, 0, 0.2); + border-radius: 3px; + font-size: 0.8em; + text-align: center; +} +.chat-log .message-content .prismrpg-chat-card .roll-result .d30-result i { + color: #d4af37; + margin-right: 4px; +} +.chat-log .message-content .prismrpg-chat-card .result-badge { + padding: 6px; + text-align: center; + font-size: 0.9em; + font-weight: bold; + border-top: 1px solid; +} +.chat-log .message-content .prismrpg-chat-card .result-badge.success { + background: linear-gradient(135deg, rgba(76, 175, 80, 0.3) 0%, rgba(76, 175, 80, 0.1) 100%); + border-color: #4caf50; + color: #4caf50; +} +.chat-log .message-content .prismrpg-chat-card .result-badge.failure { + background: linear-gradient(135deg, rgba(244, 67, 54, 0.3) 0%, rgba(244, 67, 54, 0.1) 100%); + border-color: #f44336; + color: #f44336; +} +.chat-log .message-content .prismrpg-chat-card .result-badge i { + margin-right: 6px; + font-size: 1em; +} +.chat-log .message-content .prismrpg-chat-card .damage-info { + padding: 6px; + background: rgba(255, 255, 255, 0.05); + border-radius: 3px; + font-size: 0.8em; + color: #aaa; +} +.chat-log .message-content.fortune img { + border: 0px; +} +.chat-log .message-content.fortune .intro-chat { + border-radius: 20px; + display: flex; + flex-direction: row; +} +.chat-log .message-content.fortune .intro-chat .intro-img { + padding: 5px; + width: 80px; + align-self: center; +} +.chat-log .message-content.fortune .intro-chat .intro-right { + display: flex; + flex-direction: column; +} +.chat-log .message-content.fortune .intro-chat .intro-right .introText { + font-family: var(--font-secondary); + font-size: calc(var(--font-size-standard) * 1.2); + width: 210px; + text-align: center; +} +.chat-log .message-content.fortune .button.control, +.chat-log .message-content.fortune .fortune-accepted { + display: flex; + justify-content: center; + align-items: center; + font-size: calc(var(--font-size-standard) * 1.3); +} +.chat-log .message-content.ask-roll { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-family: var(--font-secondary); + font-size: calc(var(--font-size-standard) * 1.2); +} .application.dialog.prismrpg { color: var(--color-dark-1); } @@ -3724,6 +4126,25 @@ i.prismrpg { border-radius: 4px; padding: 0.5rem; } +.prismrpg-roll-dialog .dialog-weapon-options { + margin-top: 8px; +} +.prismrpg-roll-dialog .dialog-weapon-options .dialog-save { + margin: 4px 0; +} +.prismrpg-roll-dialog .dialog-weapon-options .dialog-save label { + display: flex; + align-items: center; + cursor: pointer; +} +.prismrpg-roll-dialog .dialog-weapon-options .dialog-save label input[type="checkbox"] { + margin-right: 8px; + cursor: pointer; +} +.prismrpg-roll-dialog .dialog-weapon-options .dialog-save select { + margin-left: 8px; + min-width: 10rem; +} .prismrpg-range-defense-dialog { width: 18rem; } @@ -3847,6 +4268,285 @@ i.prismrpg { font-size: calc(var(--font-size-standard) * 1); text-shadow: 0 0 10px var(--color-shadow-primary); } +.dice-roll .damage-roll-button { + margin-top: 0.5em; + margin-bottom: 0.25em; +} +.dice-roll .damage-roll-button .roll-damage-button { + background: linear-gradient(135deg, #8b0000 0%, #dc143c 100%); + color: white; + border: 1px solid #6b0000; + border-radius: 3px; + padding: 4px 10px; + font-weight: 600; + cursor: pointer; + font-size: 0.85em; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); + transition: all 0.2s ease; +} +.dice-roll .damage-roll-button .roll-damage-button:hover { + background: linear-gradient(135deg, #a00000 0%, #ff1744 100%); + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); + transform: translateY(-1px); +} +.dice-roll .damage-roll-button .roll-damage-button i { + margin-right: 4px; + font-size: 0.9em; +} +.prismrpg-roll-dialog-modern { + font-family: var(--font-primary); +} +.prismrpg-roll-dialog-modern .dialog-header { + background: linear-gradient(135deg, rgba(33, 33, 33, 0.95) 0%, rgba(66, 66, 66, 0.95) 100%); + border-bottom: 2px solid #d4af37; + padding: 8px 10px; + margin: -8px -8px 8px -8px; + border-radius: 4px 4px 0 0; +} +.prismrpg-roll-dialog-modern .dialog-header .character-info { + display: flex; + flex-direction: column; + gap: 4px; +} +.prismrpg-roll-dialog-modern .dialog-header .character-info .character-name { + font-size: 1em; + font-weight: bold; + color: #d4af37; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); +} +.prismrpg-roll-dialog-modern .dialog-header .character-info .item-name { + display: flex; + align-items: center; + gap: 4px; + font-size: 0.9em; + color: #e0e0e0; +} +.prismrpg-roll-dialog-modern .dialog-header .character-info .item-name i { + color: #d4af37; + font-size: 0.85em; +} +.prismrpg-roll-dialog-modern .dialog-header .character-info .item-name.weapon i { + color: #f44336; +} +.prismrpg-roll-dialog-modern .dialog-header .character-info .item-name.spell i { + color: #9c27b0; +} +.prismrpg-roll-dialog-modern .dialog-content { + display: flex; + flex-direction: column; + gap: 8px; +} +.prismrpg-roll-dialog-modern .option-section { + background: rgba(0, 0, 0, 0.1); + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 4px; + padding: 6px 8px; +} +.prismrpg-roll-dialog-modern .option-section.weapon-section { + border-left: 3px solid #f44336; +} +.prismrpg-roll-dialog-modern .option-section.spell-section { + border-left: 3px solid #9c27b0; +} +.prismrpg-roll-dialog-modern .option-section .section-title { + display: flex; + align-items: center; + gap: 4px; + font-weight: bold; + font-size: 0.9em; + color: var(--color-dark-1); + margin-bottom: 6px; + padding-bottom: 4px; + border-bottom: 1px solid rgba(0, 0, 0, 0.15); +} +.prismrpg-roll-dialog-modern .option-section .section-title i { + color: #d4af37; + font-size: 0.85em; +} +.prismrpg-roll-dialog-modern .info-display { + display: flex; + align-items: center; + gap: 4px; + padding: 4px 6px; + background: rgba(0, 0, 0, 0.15); + border-radius: 3px; + margin-bottom: 6px; + font-size: 0.8em; + color: #666; +} +.prismrpg-roll-dialog-modern .info-display i { + color: #4caf50; + font-size: 0.85em; +} +.prismrpg-roll-dialog-modern .info-display .info-text { + flex: 1; +} +.prismrpg-roll-dialog-modern .spell-info-display { + display: flex; + flex-wrap: wrap; + gap: 4px; + margin-bottom: 6px; +} +.prismrpg-roll-dialog-modern .spell-info-display .info-badge { + display: flex; + align-items: center; + gap: 3px; + padding: 3px 6px; + border-radius: 3px; + font-size: 0.75em; + font-weight: 500; +} +.prismrpg-roll-dialog-modern .spell-info-display .info-badge i { + font-size: 0.85em; +} +.prismrpg-roll-dialog-modern .spell-info-display .info-badge.characteristic { + background: rgba(103, 58, 183, 0.2); + border: 1px solid rgba(103, 58, 183, 0.4); + color: #673ab7; +} +.prismrpg-roll-dialog-modern .spell-info-display .info-badge.characteristic i { + color: #673ab7; +} +.prismrpg-roll-dialog-modern .spell-info-display .info-badge.mana { + background: rgba(33, 150, 243, 0.2); + border: 1px solid rgba(33, 150, 243, 0.4); + color: #2196f3; +} +.prismrpg-roll-dialog-modern .spell-info-display .info-badge.mana i { + color: #2196f3; +} +.prismrpg-roll-dialog-modern .spell-info-display .info-badge.apc { + background: rgba(255, 193, 7, 0.2); + border: 1px solid rgba(255, 193, 7, 0.4); + color: #ffc107; +} +.prismrpg-roll-dialog-modern .spell-info-display .info-badge.apc i { + color: #ffc107; +} +.prismrpg-roll-dialog-modern .spell-info-display .info-badge.upkeep { + background: rgba(156, 39, 176, 0.2); + border: 1px solid rgba(156, 39, 176, 0.4); + color: #9c27b0; +} +.prismrpg-roll-dialog-modern .spell-info-display .info-badge.upkeep i { + color: #9c27b0; +} +.prismrpg-roll-dialog-modern .option-row { + display: flex; + align-items: center; + gap: 6px; + margin-bottom: 4px; +} +.prismrpg-roll-dialog-modern .option-row:last-child { + margin-bottom: 0; +} +.prismrpg-roll-dialog-modern .option-row label { + font-size: 0.85em; + font-weight: 500; + color: var(--color-dark-2); + min-width: 90px; +} +.prismrpg-roll-dialog-modern .option-row select { + flex: 1; +} +.prismrpg-roll-dialog-modern .styled-select { + background: rgba(255, 255, 255, 0.9); + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 3px; + padding: 4px 8px; + font-size: 0.85em; + color: var(--color-dark-1); + cursor: pointer; + transition: all 0.2s ease; +} +.prismrpg-roll-dialog-modern .styled-select:hover { + border-color: #d4af37; + box-shadow: 0 0 4px rgba(212, 175, 55, 0.3); +} +.prismrpg-roll-dialog-modern .styled-select:focus { + outline: none; + border-color: #d4af37; + box-shadow: 0 0 6px rgba(212, 175, 55, 0.5); +} +.prismrpg-roll-dialog-modern .styled-select.advantage-select, +.prismrpg-roll-dialog-modern .styled-select.modifier-select { + text-align: center; + font-weight: 500; +} +.prismrpg-roll-dialog-modern .checkbox-group { + display: flex; + flex-direction: column; + gap: 3px; + margin-bottom: 6px; +} +.prismrpg-roll-dialog-modern .checkbox-group .checkbox-label { + display: flex; + align-items: center; + cursor: pointer; + padding: 3px 4px; + border-radius: 3px; + transition: background 0.2s ease; +} +.prismrpg-roll-dialog-modern .checkbox-group .checkbox-label:hover { + background: rgba(0, 0, 0, 0.05); +} +.prismrpg-roll-dialog-modern .checkbox-group .checkbox-label input[type="checkbox"] { + margin-right: 6px; + cursor: pointer; + width: 14px; + height: 14px; + accent-color: #d4af37; +} +.prismrpg-roll-dialog-modern .checkbox-group .checkbox-label .checkbox-text { + display: flex; + align-items: center; + gap: 4px; + font-size: 0.8em; + color: var(--color-dark-2); +} +.prismrpg-roll-dialog-modern .checkbox-group .checkbox-label .checkbox-text i { + color: #888; + font-size: 0.85em; +} +.prismrpg-roll-dialog-modern .checkbox-group .checkbox-label input[type="checkbox"]:checked ~ .checkbox-text { + color: var(--color-dark-1); + font-weight: 500; +} +.prismrpg-roll-dialog-modern .checkbox-group .checkbox-label input[type="checkbox"]:checked ~ .checkbox-text i { + color: #d4af37; +} +.application.dialog.prismrpg .window-content { + background: linear-gradient(135deg, #f5f5f5 0%, #e0e0e0 100%); + padding: 8px; +} +.application.dialog.prismrpg .dialog-buttons { + padding: 6px 8px; + gap: 6px; +} +.application.dialog.prismrpg .dialog-buttons button { + background: linear-gradient(135deg, #4a4a4a 0%, #6a6a6a 100%); + border: 1px solid #3a3a3a; + color: white; + font-weight: 600; + padding: 6px 12px; + border-radius: 4px; + transition: all 0.2s ease; +} +.application.dialog.prismrpg .dialog-buttons button:hover { + background: linear-gradient(135deg, #5a5a5a 0%, #7a7a7a 100%); + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + transform: translateY(-1px); +} +.application.dialog.prismrpg .dialog-buttons button.default, +.application.dialog.prismrpg .dialog-buttons button[data-button="roll"] { + background: linear-gradient(135deg, #d4af37 0%, #f4cf67 100%); + border-color: #b49030; + color: #2a2a2a; +} +.application.dialog.prismrpg .dialog-buttons button.default:hover, +.application.dialog.prismrpg .dialog-buttons button[data-button="roll"]:hover { + background: linear-gradient(135deg, #e4bf47 0%, #ffdf77 100%); +} #token-hud .hp-loss-wrap { position: absolute; left: 75px; diff --git a/lang/en.json b/lang/en.json index 8a13676..c72c16e 100644 --- a/lang/en.json +++ b/lang/en.json @@ -140,34 +140,34 @@ }, "FIELDS": { "moneys": { - "tinbit": { - "label": "Tin Bits", + "coppercoin": { + "label": "Copper Coin", "value": { - "label": "Tin Bits" + "label": "Copper Coin" } }, - "silver": { - "label": "Silver", + "silvercoin": { + "label": "Silver Coin", "value": { - "label": "Silver" + "label": "Silver Coin" } }, - "copper": { - "label": "Copper", + "goldcoin": { + "label": "Gold Coin", "value": { - "label": "Copper" + "label": "Gold Coin" } }, - "gold": { - "label": "Gold", + "note": { + "label": "Note", "value": { - "label": "Gold" + "label": "Note" } }, - "platinum": { - "label": "Platinum", + "steam": { + "label": "Steam", "value": { - "label": "Platinum" + "label": "Steam" } } }, @@ -415,7 +415,7 @@ "rollProgressionDice": "Roll progression/Lethargy dice", "earned": "Earned", "divinityPoints": "Divinity points", - "aetherPoints": "Aether points", + "manaPoints": "Mana points", "attacks": "Attacks", "monster": "Monster", "Resist" :"Resist", @@ -588,7 +588,8 @@ "piercing": "Piercing (P)", "bludgeoning": "Bludgeoning (B)", "slashing": "Slashing (S)", - "isProjectile": "Is Projectile?", + "shortRange": "Short Range", + "longRange": "Long Range", "range": "Range", "reloadAPC": "Reload APC", "bonuses": "Bonuses", @@ -879,11 +880,11 @@ } }, "Money": { - "Coppers": "Copper", - "Golds": "Gold", - "Platinums": "Platinum", - "Silvers": "Silver", - "Tinbits": "Tin Bits" + "CopperCoin": "Copper Coin", + "SilverCoin": "Silver Coin", + "GoldCoin": "Gold Coin", + "Note": "Note", + "Steam": "Steam" }, "Notifications": { "rollFromWeapon": "Roll from an equipped weapon", diff --git a/module/applications/sheets/character-sheet.mjs b/module/applications/sheets/character-sheet.mjs index a542f66..0992d44 100644 --- a/module/applications/sheets/character-sheet.mjs +++ b/module/applications/sheets/character-sheet.mjs @@ -18,6 +18,10 @@ export default class PrismRPGCharacterSheet extends PrismRPGActorSheet { rollInitiative: PrismRPGCharacterSheet.#onRollInitiative, armorHitPointsPlus: PrismRPGCharacterSheet.#onArmorHitPointsPlus, armorHitPointsMinus: PrismRPGCharacterSheet.#onArmorHitPointsMinus, + manaPointsPlus: PrismRPGCharacterSheet.#onManaPointsPlus, + manaPointsMinus: PrismRPGCharacterSheet.#onManaPointsMinus, + hpPlus: PrismRPGCharacterSheet.#onHpPlus, + hpMinus: PrismRPGCharacterSheet.#onHpMinus, }, } @@ -166,6 +170,30 @@ export default class PrismRPGCharacterSheet extends PrismRPGActorSheet { this.actor.update({ "system.combat.armorHitPoints": Math.max(armorHP, 0) }) } + static #onManaPointsPlus(event, target) { + let mana = this.actor.system.manaPoints.value + mana += 1 + this.actor.update({ "system.manaPoints.value": Math.min(mana, this.actor.system.manaPoints.max) }) + } + + static #onManaPointsMinus(event, target) { + let mana = this.actor.system.manaPoints.value + mana -= 1 + this.actor.update({ "system.manaPoints.value": Math.max(mana, 0) }) + } + + static #onHpPlus(event, target) { + let hp = this.actor.system.hp.value + hp += 1 + this.actor.update({ "system.hp.value": Math.min(hp, this.actor.system.hp.max) }) + } + + static #onHpMinus(event, target) { + let hp = this.actor.system.hp.value + hp -= 1 + this.actor.update({ "system.hp.value": Math.max(hp, 0) }) + } + static #onCreateEquipment(event, target) { } diff --git a/module/config/characteristic-tables.mjs b/module/config/characteristic-tables.mjs index e80aad3..950a5d1 100644 --- a/module/config/characteristic-tables.mjs +++ b/module/config/characteristic-tables.mjs @@ -9,7 +9,7 @@ export const TABLES = { "damage": -7, "attack": -4, "challenge": -9, - "aether_points": -20, + "mana_points": -20, "hp": -3, "encumbered": 1, "lift": 3, @@ -20,7 +20,7 @@ export const TABLES = { "damage": -6, "attack": -4, "challenge": -8, - "aether_points": -20, + "mana_points": -20, "hp": -2, "encumbered": 1, "lift": 4, @@ -31,7 +31,7 @@ export const TABLES = { "damage": -5, "attack": -3, "challenge": -7, - "aether_points": -20, + "mana_points": -20, "hp": -1, "encumbered": 1, "lift": 5, @@ -42,7 +42,7 @@ export const TABLES = { "damage": -4, "attack": -3, "challenge": -6, - "aether_points": -20, + "mana_points": -20, "hp": -1, "encumbered": 2, "lift": 6, @@ -53,7 +53,7 @@ export const TABLES = { "damage": -3, "attack": -2, "challenge": -5, - "aether_points": -20, + "mana_points": -20, "hp": 0, "encumbered": 2, "lift": 7, @@ -64,7 +64,7 @@ export const TABLES = { "damage": -2, "attack": -1, "challenge": -4, - "aether_points": -10, + "mana_points": -10, "hp": 0, "encumbered": 3, "lift": 8, @@ -75,7 +75,7 @@ export const TABLES = { "damage": -2, "attack": 0, "challenge": -3, - "aether_points": -10, + "mana_points": -10, "hp": 0, "encumbered": 3, "lift": 9, @@ -86,7 +86,7 @@ export const TABLES = { "damage": -1, "attack": 0, "challenge": -2, - "aether_points": 0, + "mana_points": 0, "hp": 0, "encumbered": 4, "lift": 11, @@ -97,7 +97,7 @@ export const TABLES = { "damage": -1, "attack": 0, "challenge": -1, - "aether_points": 0, + "mana_points": 0, "hp": 0, "encumbered": 5, "lift": 12, @@ -108,7 +108,7 @@ export const TABLES = { "damage": 0, "attack": 0, "challenge": 0, - "aether_points": 0, + "mana_points": 0, "hp": 0, "encumbered": 6, "lift": 13, @@ -119,7 +119,7 @@ export const TABLES = { "damage": 0, "attack": 0, "challenge": 0, - "aether_points": 0, + "mana_points": 0, "hp": 0, "encumbered": 7, "lift": 15, @@ -130,7 +130,7 @@ export const TABLES = { "damage": 1, "attack": 0, "challenge": 1, - "aether_points": 0, + "mana_points": 0, "hp": 0, "encumbered": 8, "lift": 17, @@ -141,7 +141,7 @@ export const TABLES = { "damage": 1, "attack": 0, "challenge": 2, - "aether_points": 0, + "mana_points": 0, "hp": 0, "encumbered": 9, "lift": 20, @@ -152,7 +152,7 @@ export const TABLES = { "damage": 2, "attack": 1, "challenge": 3, - "aether_points": 0, + "mana_points": 0, "hp": 1, "encumbered": 10, "lift": 22, @@ -163,7 +163,7 @@ export const TABLES = { "damage": 3, "attack": 1, "challenge": 4, - "aether_points": 0, + "mana_points": 0, "hp": 2, "encumbered": 11, "lift": 24, @@ -174,7 +174,7 @@ export const TABLES = { "damage": 4, "attack": 2, "challenge": 5, - "aether_points": 0, + "mana_points": 0, "hp": 3, "encumbered": 12, "lift": 26, @@ -185,7 +185,7 @@ export const TABLES = { "damage": 5, "attack": 2, "challenge": 6, - "aether_points": 10, + "mana_points": 10, "hp": 4, "encumbered": 13, "lift": 28, @@ -196,7 +196,7 @@ export const TABLES = { "damage": 6, "attack": 3, "challenge": 7, - "aether_points": 20, + "mana_points": 20, "hp": 5, "encumbered": 14, "lift": 30, @@ -207,7 +207,7 @@ export const TABLES = { "damage": 7, "attack": 3, "challenge": 8, - "aether_points": 20, + "mana_points": 20, "hp": 6, "encumbered": 15, "lift": 31, @@ -218,7 +218,7 @@ export const TABLES = { "damage": 8, "attack": 4, "challenge": 9, - "aether_points": 30, + "mana_points": 30, "hp": 7, "encumbered": 15, "lift": 32, @@ -229,7 +229,7 @@ export const TABLES = { "damage": 9, "attack": 4, "challenge": 10, - "aether_points": 30, + "mana_points": 30, "hp": 8, "encumbered": 16, "lift": 33, @@ -240,7 +240,7 @@ export const TABLES = { "damage": 10, "attack": 5, "challenge": 11, - "aether_points": 40, + "mana_points": 40, "hp": 9, "encumbered": 16, "lift": 34, @@ -251,7 +251,7 @@ export const TABLES = { "damage": 12, "attack": 5, "challenge": 12, - "aether_points": 40, + "mana_points": 40, "hp": 10, "encumbered": 17, "lift": 35, @@ -262,7 +262,7 @@ export const TABLES = { "damage": 14, "attack": 5, "challenge": 13, - "aether_points": 50, + "mana_points": 50, "hp": 11, "encumbered": 18, "lift": 36, @@ -273,7 +273,7 @@ export const TABLES = { "damage": 16, "attack": 6, "challenge": 14, - "aether_points": 60, + "mana_points": 60, "hp": 12, "encumbered": 19, "lift": 38, @@ -286,7 +286,7 @@ export const TABLES = { "attack": -5, "defense": -3, "development_points": 0, - "aether": -50, + "mana": -50, "spell_cognition": 0, "arkane_casting_mod": -4 }, @@ -295,7 +295,7 @@ export const TABLES = { "attack": -4, "defense": -3, "development_points": 0, - "aether": -50, + "mana": -50, "spell_cognition": 0, "arkane_casting_mod": -4 }, @@ -304,7 +304,7 @@ export const TABLES = { "attack": -3, "defense": -3, "development_points": 0, - "aether": -50, + "mana": -50, "spell_cognition": 0.01, "arkane_casting_mod": -3 }, @@ -313,7 +313,7 @@ export const TABLES = { "attack": -2, "defense": -2, "development_points": 0, - "aether": -45, + "mana": -45, "spell_cognition": 0.05, "arkane_casting_mod": -3 }, @@ -322,7 +322,7 @@ export const TABLES = { "attack": -2, "defense": -2, "development_points": 0, - "aether": -45, + "mana": -45, "spell_cognition": 0.1, "arkane_casting_mod": -2 }, @@ -331,7 +331,7 @@ export const TABLES = { "attack": -2, "defense": -2, "development_points": 0, - "aether": -40, + "mana": -40, "spell_cognition": 0.15, "arkane_casting_mod": -2 }, @@ -340,7 +340,7 @@ export const TABLES = { "attack": -1, "defense": -1, "development_points": 0, - "aether": -40, + "mana": -40, "spell_cognition": 0.2, "arkane_casting_mod": -1 }, @@ -349,7 +349,7 @@ export const TABLES = { "attack": -1, "defense": 0, "development_points": 0, - "aether": -30, + "mana": -30, "spell_cognition": 0.25, "arkane_casting_mod": -1 }, @@ -358,7 +358,7 @@ export const TABLES = { "attack": -1, "defense": 0, "development_points": 0, - "aether": -30, + "mana": -30, "spell_cognition": 0.3, "arkane_casting_mod": 0 }, @@ -367,7 +367,7 @@ export const TABLES = { "attack": 0, "defense": 0, "development_points": 0, - "aether": -20, + "mana": -20, "spell_cognition": 0.35, "arkane_casting_mod": 0 }, @@ -376,7 +376,7 @@ export const TABLES = { "attack": 0, "defense": 0, "development_points": 1, - "aether": -10, + "mana": -10, "spell_cognition": 0.45, "arkane_casting_mod": 0 }, @@ -385,7 +385,7 @@ export const TABLES = { "attack": 1, "defense": 0, "development_points": 2, - "aether": 0, + "mana": 0, "spell_cognition": 0.5, "arkane_casting_mod": 1 }, @@ -394,7 +394,7 @@ export const TABLES = { "attack": 1, "defense": 0, "development_points": 3, - "aether": 0, + "mana": 0, "spell_cognition": 0.6, "arkane_casting_mod": 1 }, @@ -403,7 +403,7 @@ export const TABLES = { "attack": 1, "defense": 1, "development_points": 4, - "aether": 10, + "mana": 10, "spell_cognition": 0.65, "arkane_casting_mod": 2 }, @@ -412,7 +412,7 @@ export const TABLES = { "attack": 2, "defense": 1, "development_points": 5, - "aether": 20, + "mana": 20, "spell_cognition": 0.75, "arkane_casting_mod": 2 }, @@ -421,7 +421,7 @@ export const TABLES = { "attack": 2, "defense": 1, "development_points": 7, - "aether": 30, + "mana": 30, "spell_cognition": 0.8, "arkane_casting_mod": 3 }, @@ -430,7 +430,7 @@ export const TABLES = { "attack": 2, "defense": 1, "development_points": 9, - "aether": 40, + "mana": 40, "spell_cognition": 0.85, "arkane_casting_mod": 3 }, @@ -439,7 +439,7 @@ export const TABLES = { "attack": 3, "defense": 2, "development_points": 11, - "aether": 50, + "mana": 50, "spell_cognition": 0.9, "arkane_casting_mod": 4 }, @@ -448,7 +448,7 @@ export const TABLES = { "attack": 3, "defense": 2, "development_points": 13, - "aether": 60, + "mana": 60, "spell_cognition": 0.92, "arkane_casting_mod": 5 }, @@ -457,7 +457,7 @@ export const TABLES = { "attack": 3, "defense": 2, "development_points": 15, - "aether": 70, + "mana": 70, "spell_cognition": 0.94, "arkane_casting_mod": 6 }, @@ -466,7 +466,7 @@ export const TABLES = { "attack": 4, "defense": 2, "development_points": 18, - "aether": 80, + "mana": 80, "spell_cognition": 0.95, "arkane_casting_mod": 7 }, @@ -475,7 +475,7 @@ export const TABLES = { "attack": 4, "defense": 3, "development_points": 21, - "aether": 90, + "mana": 90, "spell_cognition": 0.96, "arkane_casting_mod": 7 }, @@ -484,7 +484,7 @@ export const TABLES = { "attack": 4, "defense": 3, "development_points": 24, - "aether": 100, + "mana": 100, "spell_cognition": 0.97, "arkane_casting_mod": 8 }, @@ -493,7 +493,7 @@ export const TABLES = { "attack": 5, "defense": 3, "development_points": 27, - "aether": 110, + "mana": 110, "spell_cognition": 0.98, "arkane_casting_mod": 8 }, @@ -502,7 +502,7 @@ export const TABLES = { "attack": 5, "defense": 4, "development_points": 30, - "aether": 125, + "mana": 125, "spell_cognition": 0.99, "arkane_casting_mod": 9 } @@ -688,7 +688,7 @@ export const TABLES = { { "value": 1, "hp ": 1, - "aether_points": -50, + "mana_points": -50, "pain_save": 1, "toughness_save": -5, "stabilization_dice": "D6", @@ -698,7 +698,7 @@ export const TABLES = { "value": 2, "hp ": 2, - "aether_points": -40, + "mana_points": -40, "pain_save": 2, "toughness_saave": -4, "stabilization_dice": "D6", @@ -708,7 +708,7 @@ export const TABLES = { "value": 3, "hp ": 3, - "aether_points": -35, + "mana_points": -35, "pain_save": 2, "toughness_save": -3, "stabilization_dice": "D6", @@ -718,7 +718,7 @@ export const TABLES = { "value": 4, "hp ": 4, - "aether_points": -30, + "mana_points": -30, "pain_save": 2, "toughness_save": -3, "stabilization_dice": "D6", @@ -728,7 +728,7 @@ export const TABLES = { "value": 5, "hp ": 5, - "aether_points": -25, + "mana_points": -25, "pain_save": 3, "toughness_save": -2, "stabilization_dice": "D6", @@ -737,7 +737,7 @@ export const TABLES = { { "value": 6, "hp ": 6, - "aether_points": -20, + "mana_points": -20, "pain_save": 3, "toughness_save": -2, "stabilization_dice": "D6", @@ -746,7 +746,7 @@ export const TABLES = { { "value": 7, "hp ": 7, - "aether_points": -15, + "mana_points": -15, "pain_save": 3, "toughness_save": -1, "stabilization_dice": "D6", @@ -756,7 +756,7 @@ export const TABLES = { "value": 8, "hp ": 8, - "aether_points": -10, + "mana_points": -10, "pain_save": 4, "toughness_save": -1, "stabilization_dice": "D8", @@ -766,7 +766,7 @@ export const TABLES = { "value": 9, "hp ": 9, - "aether_points": -5, + "mana_points": -5, "pain_save": 4, "toughness_save": 0, "stabilization_dice": "D8", @@ -776,7 +776,7 @@ export const TABLES = { "value": 10, "hp ": 10, - "aether_points": 0, + "mana_points": 0, "pain_save": 5, "toughness_save": 0, "stabilization_dice": "D8", @@ -786,7 +786,7 @@ export const TABLES = { "value": 11, "hp ": 11, - "aether_points": 0, + "mana_points": 0, "pain_save": 5, "toughness_save": 0, "stabilization_dice": "D8", @@ -796,7 +796,7 @@ export const TABLES = { "value": 12, "hp ": 12, - "aether_points": 5, + "mana_points": 5, "pain_save": 6, "toughness_save": 0, "stabilization_dice": "D10", @@ -806,7 +806,7 @@ export const TABLES = { "value": 13, "hp ": 13, - "aether_points": 10, + "mana_points": 10, "pain_save": 7, "toughness_save": 1, "stabilization_dice": "D10", @@ -816,7 +816,7 @@ export const TABLES = { "value": 14, "hp ": 14, - "aether_points": 20, + "mana_points": 20, "pain_save": 7, "toughness_save": 2, "stabilization_dice": "D10", @@ -826,7 +826,7 @@ export const TABLES = { "value": 15, "hp ": 15, - "aether_points": 30, + "mana_points": 30, "pain_save": 8, "toughness_save": 3, "stabilization_dice": "D12", @@ -836,7 +836,7 @@ export const TABLES = { "value": 16, "hp ": 16, - "aether_points": 40, + "mana_points": 40, "pain_save": 8, "toughness_save": 4, "stabilization_dice": "D12", @@ -846,7 +846,7 @@ export const TABLES = { "value": 17, "hp ": 17, - "aether_points": 50, + "mana_points": 50, "pain_save": 9, "toughness_save": 5, "stabilization_dice": "D12", @@ -856,7 +856,7 @@ export const TABLES = { "value": 18, "hp ": 18, - "aether_points": 60, + "mana_points": 60, "pain_save": 9, "toughness_save": 6, "stabilization_dice": "D12", @@ -866,7 +866,7 @@ export const TABLES = { "value": 19, "hp ": 19, - "aether_points": 70, + "mana_points": 70, "pain_save": 10, "toughness_save": 7, "stabilization_dice": "D12", @@ -876,7 +876,7 @@ export const TABLES = { "value": 20, "hp ": 20, - "aether_points": 80, + "mana_points": 80, "pain_save": 10, "toughness_save": 8, "stabilization_dice": "D12", @@ -886,7 +886,7 @@ export const TABLES = { "value": 21, "hp ": 21, - "aether_points": 90, + "mana_points": 90, "pain_save": 11, "toughness_save": 9, "stabilization_dice": "D20", @@ -896,7 +896,7 @@ export const TABLES = { "value": 22, "hp ": 22, - "aether_points": 100, + "mana_points": 100, "pain_save": 11, "toughness_save": 10, "stabilization_dice": "D20", @@ -906,7 +906,7 @@ export const TABLES = { "value": 23, "hp ": 23, - "aether_points": 110, + "mana_points": 110, "pain_save": 12, "toughness_save": 11, "stabilization_dice": "D20", @@ -916,7 +916,7 @@ export const TABLES = { "value": 24, "hp ": 24, - "aether_points": 120, + "mana_points": 120, "pain_save": 12, "toughness_save": 12, "stabilization_dice": "D20", @@ -925,7 +925,7 @@ export const TABLES = { { "value": 25, "hp ": 25, - "aether_points": 130, + "mana_points": 130, "pain_save": 13, "toughness_save": 13, "stabilization_dice": "D20", diff --git a/module/config/system.mjs b/module/config/system.mjs index 294bfb3..2428016 100644 --- a/module/config/system.mjs +++ b/module/config/system.mjs @@ -14,35 +14,35 @@ export const SYSTEM_ID = "fvtt-prism-rpg" export const DEV_MODE = false export const MONEY = { - tinbit: { - id: "tinbit", - abbrev: "tb", - label: "PRISMRPG.Money.Tinbits", + coppercoin: { + id: "coppercoin", + abbrev: "cc", + label: "PRISMRPG.Money.CopperCoin", valuetb: 1 }, - copper: { - id: "copper", - abbrev: "cp", - label: "PRISMRPG.Money.Coppers", + silvercoin: { + id: "silvercoin", + abbrev: "sc", + label: "PRISMRPG.Money.SilverCoin", + valuetb: 5 + }, + goldcoin: { + id: "goldcoin", + abbrev: "gc", + label: "PRISMRPG.Money.GoldCoin", valuetb: 10 }, - silver: { - id: "silver", - abbrev: "sp", - label: "PRISMRPG.Money.Silvers", + note: { + id: "note", + abbrev: "nt", + label: "PRISMRPG.Money.Note", valuetb: 100 }, - gold: { - id: "gold", - abbrev: "gp", - label: "PRISMRPG.Money.Golds", + steam: { + id: "steam", + abbrev: "st", + label: "PRISMRPG.Money.Steam", valuetb: 1000 - }, - platinum: { - id: "platinum", - abbrev: "pp", - label: "PRISMRPG.Money.Platinums", - valuetb: 10000 } } @@ -156,7 +156,7 @@ export const INITIATIVE_DICE_CHOICES_PER_CLASS = { { "name": "Aware and know exactly where the enemy is (1D4)", "value": "1D4" }*/ ], "magicuser": [ - { "name": "Sleeping to recover Aether Points (2D20)", "value": "2D20" }, + { "name": "Sleeping to recover Mana Points (2D20)", "value": "2D20" }, { "name": "Asleep or totally distracted (1D20)", "value": "1D20" }, { "name": "Awake but unsuspecting (1D12)", "value": "1D12" }, { "name": "Declared Ready on Alert (1)", "value": "1" }, diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 55aabc4..17744fb 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -1,4 +1,6 @@ import PrismRPGUtils from "../utils.mjs" +import PrismRPGRoll from "./roll.mjs" + export default class PrismRPGActor extends Actor { static async create(data, options) { @@ -42,31 +44,12 @@ export default class PrismRPGActor extends Actor { } /* *************************************************/ + // This method is no longer needed in D&D 5e style system + // Weapon proficiency is handled through character class/race features getBestWeaponClassSkill(skills, rollType, multiplier = 1.0) { - let maxValue = 0 - let goodSkill = skills[0] - for (let s of skills) { - if (rollType === "weapon-attack") { - if (s.system.weaponBonus.attack > maxValue) { - maxValue = Number(s.system.weaponBonus.attack) - goodSkill = s - } - } - if (rollType === "weapon-defense") { - if (s.system.weaponBonus.defense > maxValue) { - maxValue = Number(s.system.weaponBonus.defense) - goodSkill = s - } - } - if (rollType.includes("weapon-damage")) { - if (s.system.weaponBonus.damage > maxValue) { - maxValue = Number(s.system.weaponBonus.damage) - goodSkill = s - } - } - } - goodSkill.weaponSkillModifier = maxValue * multiplier - return goodSkill + // In D&D 5e, we don't need weapon skills with bonuses + // Just return the first skill (or could be removed entirely) + return skills[0] } /* *************************************************/ @@ -150,6 +133,7 @@ export default class PrismRPGActor extends Actor { break case "spell-attack": case "spell-power": + case "spell-cast": case "miracle-attack": case "miracle-power": rollTarget = this.items.find((i) => (i.type === "miracle" || i.type === "spell") && i.id === rollKey) @@ -164,8 +148,7 @@ export default class PrismRPGActor extends Actor { break; case "weapon-damage-small": case "weapon-damage-medium": - case "weapon-attack": - case "weapon-defense": { + case "weapon-attack": { let weapon = this.items.find((i) => i.type === "weapon" && i.id === rollKey) let skill let skills = this.items.filter((i) => i.type === "skill" && i.name.toLowerCase() === weapon.name.toLowerCase()) @@ -195,19 +178,15 @@ export default class PrismRPGActor extends Actor { ui.notifications.warn(game.i18n.localize("PRISMRPG.Notifications.skillNotFound")) return } - rollTarget = skill - rollTarget.weapon = weapon - rollTarget.weaponSkillModifier = skill.weaponSkillModifier - rollTarget.rollKey = rollKey - rollTarget.combat = foundry.utils.duplicate(this.system.combat) - if (rollType === "weapon-damage-small" || rollType === "weapon-damage-medium") { - rollTarget.grantedDice = this.system.granted.damageDice - } - if (rollType === "weapon-attack") { - rollTarget.grantedDice = this.system.granted.attackDice - } - if (rollType === "weapon-defense") { - rollTarget.grantedDice = this.system.granted.defenseDice + + // Create a plain object for rollTarget to ensure weapon data is preserved + rollTarget = { + ...skill.toObject(), + weapon: weapon.toObject(), + rollKey: rollKey, + combat: foundry.utils.duplicate(this.system.combat), + strMod: PrismRPGRoll.getAbilityModifier(this.system.characteristics.str.value), + dexMod: PrismRPGRoll.getAbilityModifier(this.system.characteristics.dex.value) } } break diff --git a/module/documents/roll.mjs b/module/documents/roll.mjs index 4064d48..9663b24 100644 --- a/module/documents/roll.mjs +++ b/module/documents/roll.mjs @@ -136,30 +136,40 @@ export default class PrismRPGRoll extends Roll { case "weapon-attack": options.rollName = options.rollTarget.name + // Default to STR for melee, DEX for ranged (will be updated by dialog choice) if (options.rollTarget.weapon.system.weaponType === "melee") { - options.rollTarget.value = options.rollTarget.combat.attackModifier + - options.rollTarget.weaponSkillModifier + + options.rollTarget.value = options.rollTarget.strMod + options.rollTarget.weapon.system.bonuses.attackBonus } else { - options.rollTarget.value = options.rollTarget.combat.rangedAttackModifier + - options.rollTarget.weaponSkillModifier + + options.rollTarget.value = options.rollTarget.dexMod + options.rollTarget.weapon.system.bonuses.attackBonus } break - case "weapon-defense": - options.rollName = options.rollTarget.name - options.rollTarget.value = options.rollTarget.combat.defenseModifier + - options.rollTarget.weaponSkillModifier + - options.rollTarget.weapon.system.bonuses.defenseBonus - break - case "spell": case "spell-attack": case "spell-power": + case "spell-cast": options.rollName = options.rollTarget.name - options.rollTarget.value = options.rollTarget.actorModifiers.levelSpellModifier + - options.rollTarget.actorModifiers.intSpellModifier + // Find best mental characteristic (INT, WIS, CHA) + const actor = game.actors.get(options.actorId) + const intMod = this.getAbilityModifier(actor.system.characteristics.int.value) + const wisMod = this.getAbilityModifier(actor.system.characteristics.wis.value) + const chaMod = this.getAbilityModifier(actor.system.characteristics.cha.value) + const bestMentalMod = Math.max(intMod, wisMod, chaMod) + options.rollTarget.value = bestMentalMod + + // Store which characteristic is being used + if (bestMentalMod === intMod) { + options.rollTarget.mentalCharacteristic = "INT" + options.rollTarget.mentalCharValue = actor.system.characteristics.int.value + } else if (bestMentalMod === wisMod) { + options.rollTarget.mentalCharacteristic = "WIS" + options.rollTarget.mentalCharValue = actor.system.characteristics.wis.value + } else { + options.rollTarget.mentalCharacteristic = "CHA" + options.rollTarget.mentalCharValue = actor.system.characteristics.cha.value + } break case "miracle": @@ -188,17 +198,18 @@ export default class PrismRPGRoll extends Roll { if (options.rollType.includes("weapon-damage")) { isDamageRoll = true hasAdvantage = false - options.rollName = options.rollTarget.name - let damageBonus = options.rollTarget.combat.damageModifier - options.rollTarget.value = damageBonus + - options.rollTarget.weaponSkillModifier + - options.rollTarget.weapon.system.bonuses.damageBonus - - if (options.rollType.includes("small")) { - dice = options.rollTarget.weapon.system.damage.damageS + options.rollName = options.rollTarget.weapon.name + // Default to STR for melee, DEX for ranged (will be updated by dialog choice) + if (options.rollTarget.weapon.system.weaponType === "melee") { + options.rollTarget.value = options.rollTarget.strMod + + options.rollTarget.weapon.system.bonuses.damageBonus } else { - dice = options.rollTarget.weapon.system.damage.damageM + options.rollTarget.value = options.rollTarget.dexMod + + options.rollTarget.weapon.system.bonuses.damageBonus } + + // Use the weapon's damage dice + dice = options.rollTarget.weapon.system.damage || "1d6" dice = dice.replace(/E/gi, "") } else if (options.rollType.includes("monster-damage")) { isDamageRoll = true @@ -218,6 +229,44 @@ export default class PrismRPGRoll extends Roll { const rollModes = foundry.utils.duplicate(CONFIG.Dice.rollModes) const choiceModifier = SYSTEM.CHOICE_MODIFIERS const choiceAdvantage = SYSTEM.ADVANTAGE_CHOICES + const attackerAimChoices = SYSTEM.ATTACKER_AIM_CHOICES + + // For weapon damage rolls, skip dialog and roll directly + if (options.rollType.includes("weapon-damage")) { + // Just roll the weapon's damage dice, no modifiers + const finalFormula = dice + + const rollData = { + type: options.rollType, + rollType: options.rollType, + target: options.rollTarget, + rollName: options.rollName, + actorId: options.actorId, + actorName: options.actorName, + actorImage: options.actorImage, + rollMode: "publicroll", + hasTarget: options.hasTarget, + titleFormula: finalFormula + } + + if (Hooks.call("fvtt-prism-rpg.preRoll", options, rollData) === false) return + + // Execute the roll + let roll = new this(finalFormula, options.data, rollData) + await roll.evaluate() + + // Store results + const duplicatedRollTarget = foundry.utils.duplicate(options.rollTarget) + roll.options.resultType = "success" + roll.options.rollTotal = roll.total + roll.options.rollTarget = duplicatedRollTarget + roll.options.titleFormula = finalFormula + roll.options.rollData = foundry.utils.duplicate(rollData) + + if (Hooks.call("fvtt-prism-rpg.Roll", options, rollData, roll) === false) return + + return roll + } let dialogContext = { rollType: options.rollType, @@ -232,13 +281,14 @@ export default class PrismRPGRoll extends Roll { dice, choiceModifier, choiceAdvantage, + attackerAimChoices, hasTarget: options.hasTarget, modifier: "+0", advantage: "none" } const content = await foundry.applications.handlebars.renderTemplate( - "systems/fvtt-prism-rpg/templates/roll-dialog.hbs", + "systems/fvtt-prism-rpg/templates/roll-dialog-v2.hbs", dialogContext ) @@ -255,7 +305,13 @@ export default class PrismRPGRoll extends Roll { callback: (event, button, dialog) => { game.user.setFlag(SYSTEM.id, "roll-dialog-pos", foundry.utils.duplicate(dialog.position)) const output = Array.from(button.form.elements).reduce((obj, input) => { - if (input.name) obj[input.name] = input.value + if (input.name) { + if (input.type === "checkbox") { + obj[input.name] = input.checked + } else { + obj[input.name] = input.value + } + } return obj }, {}) return output @@ -272,9 +328,29 @@ export default class PrismRPGRoll extends Roll { if (hasModifier) { let bonus = Number(options.rollTarget.value) || 0 - let extraModifier = rollContext.modifier === "" ? 0 : parseInt(rollContext.modifier, 10) + + // Recalculate bonus if player chose different attribute for weapon attack/damage + if (rollContext.attackAttribute && options.rollTarget.weapon) { + const chosenMod = rollContext.attackAttribute === "str" ? options.rollTarget.strMod : options.rollTarget.dexMod + const weaponBonus = options.rollTarget.weapon.system.bonuses.attackBonus || 0 + const damageBonus = options.rollTarget.weapon.system.bonuses.damageBonus || 0 + + if (options.rollType === "weapon-attack") { + bonus = chosenMod + weaponBonus + } else if (options.rollType.includes("weapon-damage")) { + bonus = chosenMod + damageBonus + } + } + + let extraModifier = rollContext.modifier === "" ? 0 : Number.parseInt(rollContext.modifier, 10) totalModifier = bonus + extraModifier + // Apply aiming modifier for ranged attacks + if (rollContext.attackerAim && rollContext.attackerAim !== "0") { + const aimModifier = Number.parseInt(rollContext.attackerAim, 10) + totalModifier += aimModifier + } + if (totalModifier !== 0) { finalFormula = totalModifier > 0 ? `${dice} + ${totalModifier}` : @@ -289,6 +365,35 @@ export default class PrismRPGRoll extends Roll { finalFormula = finalFormula.replace(dice, `2${dice}kl`) } + // Special ranged weapon modifiers + if (rollContext.letItFly) { + // Let it Fly: Pure D20E (replace with 1d20 if it was modified) + finalFormula = finalFormula.replace(/2d20k[hl]/, "1d20") + } + if (rollContext.pointBlank) { + // Point Blank: Add special advantage or bonus (implement based on your rules) + // This could add advantage or a flat bonus + } + + // Handle spell upcast + let upcastLevel = 0 + let totalManaCost = 0 + let totalAPC = 0 + let manaUpkeep = 0 + let mentalCharacteristic = null + let mentalCharValue = null + + if (options.rollType === "spell-cast") { + upcastLevel = rollContext.upcastLevel ? Number.parseInt(rollContext.upcastLevel, 10) : 0 + totalManaCost = options.rollTarget.system.manaCost + upcastLevel + totalAPC = options.rollTarget.system.apc + upcastLevel + manaUpkeep = options.rollTarget.system.manaUpkeep + + // Get mental characteristic info from rollTarget + mentalCharacteristic = options.rollTarget.mentalCharacteristic + mentalCharValue = options.rollTarget.mentalCharValue + } + const rollData = { type: options.rollType, rollType: options.rollType, @@ -300,19 +405,49 @@ export default class PrismRPGRoll extends Roll { rollMode: rollContext.visibility, hasTarget: options.hasTarget, titleFormula: finalFormula, + upcastLevel, + totalManaCost, + totalAPC, + manaUpkeep, + mentalCharacteristic, + mentalCharValue, ...rollContext, } if (Hooks.call("fvtt-prism-rpg.preRoll", options, rollData) === false) return + // Handle mana spending for spell-cast + if (options.rollType === "spell-cast" && totalManaCost > 0) { + const actor = game.actors.get(options.actorId) + const currentMana = actor.system.manaPoints.value + + // Check if enough mana + if (currentMana < totalManaCost) { + ui.notifications.error( + `Not enough Mana! Need ${totalManaCost}, but only have ${currentMana} Mana points.` + ) + return null + } + + // Spend mana + await actor.update({ + "system.manaPoints.value": currentMana - totalManaCost + }) + + ui.notifications.info( + `Spent ${totalManaCost} Mana (${currentMana} → ${currentMana - totalManaCost})` + ) + } + // Execute the roll let roll = new this(finalFormula, options.data, rollData) await roll.evaluate() - // Store results + // Store results - duplicate rollTarget to properly serialize weapon Item + const duplicatedRollTarget = foundry.utils.duplicate(options.rollTarget) roll.options.resultType = "success" roll.options.rollTotal = roll.total - roll.options.rollTarget = options.rollTarget + roll.options.rollTarget = duplicatedRollTarget roll.options.titleFormula = finalFormula roll.options.rollData = foundry.utils.duplicate(rollData) diff --git a/module/models/armor.mjs b/module/models/armor.mjs index 4407f92..4e1053d 100644 --- a/module/models/armor.mjs +++ b/module/models/armor.mjs @@ -24,7 +24,7 @@ export default class PrismRPGArmor extends foundry.abstract.TypeDataModel { schema.isHelmet = new fields.BooleanField({ required: true, initial: false }) schema.cost = new fields.NumberField({ required: true, initial: 0, min: 0 }) - schema.money = new fields.StringField({ required: true, initial: "tinbit", choices: SYSTEM.MONEY }) + schema.money = new fields.StringField({ required: true, initial: "coppercoin", choices: SYSTEM.MONEY }) return schema } diff --git a/module/models/character.mjs b/module/models/character.mjs index 187f2d6..7c3b9ff 100644 --- a/module/models/character.mjs +++ b/module/models/character.mjs @@ -84,11 +84,6 @@ export default class PrismRPGCharacter extends foundry.abstract.TypeDataModel { temp: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) }) - schema.magicPoints = new fields.SchemaField({ - value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), - max: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) - }) - schema.armorPoints = new fields.SchemaField({ value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), max: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) @@ -110,15 +105,7 @@ export default class PrismRPGCharacter extends foundry.abstract.TypeDataModel { total: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), remaining: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) }) - schema.spellMiraclePoints = new fields.SchemaField({ - total: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), - used: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) - }) - schema.aetherPoints = new fields.SchemaField({ - max: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), - value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) - }) - schema.divinityPoints = new fields.SchemaField({ + schema.manaPoints = new fields.SchemaField({ max: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) }) diff --git a/module/models/equipment.mjs b/module/models/equipment.mjs index d6957a2..1ffe3c5 100644 --- a/module/models/equipment.mjs +++ b/module/models/equipment.mjs @@ -7,11 +7,11 @@ export default class PrismRPGEquipment extends foundry.abstract.TypeDataModel { const requiredInteger = { required: true, nullable: false, integer: true } schema.description = new fields.HTMLField({ required: true, textSearch: true }) - schema.category = new fields.StringField({ required: true, initial: "tinbit", choices: SYSTEM.EQUIPMENT_CATEGORIES }) + schema.category = new fields.StringField({ required: true, initial: "coppercoin", choices: SYSTEM.EQUIPMENT_CATEGORIES }) schema.encLoad = new fields.NumberField({ required: true, initial: 0, min: 0 }) schema.cost = new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }) - schema.money = new fields.StringField({ required: true, initial: "tinbit", choices: SYSTEM.MONEY }) + schema.money = new fields.StringField({ required: true, initial: "coppercoin", choices: SYSTEM.MONEY }) // Kit properties schema.isKit = new fields.BooleanField({ @@ -54,4 +54,29 @@ export default class PrismRPGEquipment extends foundry.abstract.TypeDataModel { /** @override */ static LOCALIZATION_PREFIXES = ["PRISMRPG.Equipment"] + static migrateData(data) { + // Migrate old money types to new ones + if (data?.money) { + const moneyMigration = { + "tinbit": "coppercoin", + "copper": "coppercoin", + "silver": "silvercoin", + "gold": "goldcoin", + "platinum": "note" + } + + if (moneyMigration[data.money]) { + data.money = moneyMigration[data.money] + } + + // If still invalid, default to coppercoin + if (!SYSTEM.MONEY[data.money]) { + console.warn(`Prism RPG | Migrate equipment: Invalid money type "${data.money}", defaulting to coppercoin`) + data.money = "coppercoin" + } + } + + return super.migrateData(data) + } + } diff --git a/module/models/shield.mjs b/module/models/shield.mjs index 64105ae..4e42267 100644 --- a/module/models/shield.mjs +++ b/module/models/shield.mjs @@ -61,7 +61,7 @@ export default class PrismRPGShield extends foundry.abstract.TypeDataModel { // Equipment properties schema.encLoad = new fields.NumberField({ required: true, initial: 0, min: 0 }) schema.cost = new fields.NumberField({ required: true, initial: 0, min: 0 }) - schema.money = new fields.StringField({ required: true, initial: "tinbit", choices: SYSTEM.MONEY }) + schema.money = new fields.StringField({ required: true, initial: "coppercoin", choices: SYSTEM.MONEY }) schema.equipped = new fields.BooleanField({ required: true, initial: false }) return schema diff --git a/module/models/weapon.mjs b/module/models/weapon.mjs index 6f4daaf..ad9df6f 100644 --- a/module/models/weapon.mjs +++ b/module/models/weapon.mjs @@ -96,16 +96,17 @@ export default class PrismRPGWeapon extends foundry.abstract.TypeDataModel { initial: "" }) - // Projectile-specific properties - schema.isProjectile = new fields.BooleanField({ - required: true, - initial: false + // Range properties + schema.shortRange = new fields.NumberField({ + ...requiredInteger, + initial: 0, + min: 0 }) - schema.range = new fields.SchemaField({ - short: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), - medium: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), - long: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) + schema.longRange = new fields.NumberField({ + ...requiredInteger, + initial: 0, + min: 0 }) schema.reloadAPC = new fields.NumberField({ @@ -123,7 +124,7 @@ export default class PrismRPGWeapon extends foundry.abstract.TypeDataModel { schema.encLoad = new fields.NumberField({ required: true, initial: 0, min: 0 }) schema.cost = new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }) - schema.money = new fields.StringField({ required: true, initial: "tinbit", choices: SYSTEM.MONEY }) + schema.money = new fields.StringField({ required: true, initial: "coppercoin", choices: SYSTEM.MONEY }) schema.equipped = new fields.BooleanField({ required: true, initial: false }) schema.isImplement = new fields.BooleanField({ required: true, initial: false }) diff --git a/prism-rpg.mjs b/prism-rpg.mjs index ab093a4..73436f6 100644 --- a/prism-rpg.mjs +++ b/prism-rpg.mjs @@ -171,15 +171,19 @@ if (foundry.utils.isNewerVersion(game.version, "12.0",)) { } Hooks.on(hookName, (message, html, data) => { const typeMessage = data.message.flags.prismRPG?.typeMessage + + // Convertir html en jQuery pour compatibilité avec le code existant si nécessaire + const $html = html instanceof jQuery ? html : $(html) + // Message de demande de jet de dés if (typeMessage === "askRoll") { // Affichage des boutons de jet de dés uniquement pour les joueurs if (game.user.isGM) { - html.find(".ask-roll-dice").each((i, btn) => { + $html.find(".ask-roll-dice").each((i, btn) => { btn.style.display = "none" }) } else { - html.find(".ask-roll-dice").click((event) => { + $html.find(".ask-roll-dice").click((event) => { const btn = $(event.currentTarget) const type = btn.data("type") const value = btn.data("value") @@ -190,6 +194,21 @@ Hooks.on(hookName, (message, html, data) => { }) } } + + // Handle Roll Damage button click in weapon attack messages + $html.find(".roll-damage-button").click(async (event) => { + const btn = event.currentTarget + const actorId = btn.dataset.actorId + const weaponId = btn.dataset.weaponId + + const actor = game.actors.get(actorId) + if (!actor) { + ui.notifications.error("Actor not found") + return + } + + await actor.prepareRoll("weapon-damage-medium", weaponId) + }) }) Hooks.on("getCombatTrackerEntryContext", (html, options) => { diff --git a/styles/chat.less b/styles/chat.less index 7c6ce7a..60429d0 100644 --- a/styles/chat.less +++ b/styles/chat.less @@ -1,33 +1,406 @@ -&.fortune { - img { - border: 0px; +// Chat Message Card Styles - Applied globally for chat messages +.chat-log .message-content { + .prismrpg-chat-card { + font-family: var(--font-primary); + border-radius: 6px; + overflow: hidden; + background: linear-gradient(135deg, rgba(0,0,0,0.05) 0%, rgba(0,0,0,0.02) 100%); + border: 1px solid rgba(0,0,0,0.2); + margin: 2px 0; + + .chat-header { + display: flex; + gap: 8px; + padding: 6px 8px; + background: linear-gradient(135deg, #2c2c2c 0%, #1a1a1a 100%); + border-bottom: 1px solid #444; + + .chat-portrait { + flex-shrink: 0; + width: 36px; + height: 36px; + border-radius: 50%; + overflow: hidden; + border: 2px solid #666; + box-shadow: 0 1px 4px rgba(0,0,0,0.4); + + img { + width: 100%; + height: 100%; + object-fit: cover; } - .intro-chat { - border-radius: 20px; - display: flex; - flex-direction: row; - .intro-img { - padding: 5px; - width: 80px; - align-self: center; + } + + .chat-title { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + gap: 2px; + + .actor-name { + font-weight: bold; + font-size: 0.95em; + color: #e0e0e0; + text-shadow: 1px 1px 2px rgba(0,0,0,0.5); + line-height: 1.1; + } + + .roll-name { + font-size: 0.8em; + color: #aaa; + line-height: 1.1; + } + + .roll-type-badge { + display: inline-block; + padding: 1px 6px; + border-radius: 10px; + font-size: 0.7em; + font-weight: bold; + text-transform: uppercase; + margin-top: 2px; + width: fit-content; + + &.attack { + background: linear-gradient(135deg, #c41e3a 0%, #8b0000 100%); + color: white; + box-shadow: 0 1px 2px rgba(196, 30, 58, 0.4); } - .intro-right { + } + + .bad-result { + color: #ff6b6b; + font-size: 0.75em; + margin-top: 1px; + } + } + } + + .chat-content { + padding: 6px 8px; + display: flex; + flex-direction: column; + gap: 6px; + + .weapon-info-card, + .spell-info-card { + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 4px; + padding: 6px; + + .weapon-header, + .spell-header { + display: flex; + align-items: center; + gap: 6px; + margin-bottom: 4px; + padding-bottom: 4px; + border-bottom: 1px solid rgba(255, 255, 255, 0.1); + + .weapon-name, + .spell-name { + font-size: 0.95em; + color: #d4af37; + } + + .badge { + padding: 1px 4px; + border-radius: 3px; + font-size: 0.65em; + font-weight: bold; + text-transform: uppercase; + + &.implement { + background: #4a5cf7; + color: white; + } + + &.upcast { + background: #9b59b6; + color: white; + } + } + + .attribute-used { + font-size: 0.75em; + color: #999; + font-style: italic; + } + } + + .weapon-stats, + .spell-stats { + display: flex; + flex-wrap: wrap; + gap: 4px; + + .stat-item { display: flex; - flex-direction: column; - .introText { - font-family: var(--font-secondary); - font-size: calc(var(--font-size-standard) * 1.2); - width: 210px; - text-align: center; + align-items: center; + gap: 3px; + padding: 2px 6px; + background: rgba(0, 0, 0, 0.2); + border-radius: 3px; + font-size: 0.75em; + + i { + color: #888; + font-size: 0.85em; + } + + &.apc { + background: rgba(255, 193, 7, 0.2); + border: 1px solid rgba(255, 193, 7, 0.4); + i { color: #ffc107; } + } + + &.damage { + background: rgba(244, 67, 54, 0.2); + border: 1px solid rgba(244, 67, 54, 0.4); + i { color: #f44336; } + } + + &.range { + background: rgba(76, 175, 80, 0.2); + border: 1px solid rgba(76, 175, 80, 0.4); + i { color: #4caf50; } + } + + &.reload { + background: rgba(255, 152, 0, 0.2); + border: 1px solid rgba(255, 152, 0, 0.4); + i { color: #ff9800; } + } + + &.mana { + background: rgba(33, 150, 243, 0.2); + border: 1px solid rgba(33, 150, 243, 0.4); + i { color: #2196f3; } + } + + &.upkeep { + background: rgba(156, 39, 176, 0.2); + border: 1px solid rgba(156, 39, 176, 0.4); + i { color: #9c27b0; } + } + + &.characteristic { + background: rgba(103, 58, 183, 0.2); + border: 1px solid rgba(103, 58, 183, 0.4); + i { color: #673ab7; } } } } - .button.control, .fortune-accepted { - display: flex; - justify-content: center; - align-items: center; - font-size: calc(var(--font-size-standard) * 1.3); + } + + .special-badge { + display: inline-block; + padding: 2px 6px; + background: linear-gradient(135deg, #ff6b6b 0%, #c92a2a 100%); + color: white; + border-radius: 3px; + font-size: 0.75em; + font-weight: bold; + width: fit-content; + box-shadow: 0 1px 2px rgba(255, 107, 107, 0.4); + } + + .aiming-info { + display: flex; + align-items: center; + gap: 4px; + padding: 3px 6px; + background: rgba(76, 175, 80, 0.1); + border-left: 2px solid #4caf50; + border-radius: 3px; + font-size: 0.8em; + + i { + color: #4caf50; } + } + + .formula-display { + display: flex; + align-items: center; + gap: 6px; + padding: 4px 8px; + background: rgba(0, 0, 0, 0.3); + border-radius: 3px; + font-family: 'Courier New', monospace; + font-size: 0.85em; + border: 1px dashed rgba(255, 255, 255, 0.2); + + i { + color: #888; + } + } + + .modifier-info { + display: flex; + gap: 8px; + padding: 3px 6px; + background: rgba(255, 255, 255, 0.05); + border-radius: 3px; + font-size: 0.75em; + + span { + color: #aaa; + } + } + + .dice-breakdown { + display: flex; + align-items: center; + gap: 4px; + padding: 2px 6px; + background: rgba(255, 255, 255, 0.05); + border-radius: 3px; + font-size: 0.8em; + + i { + color: #888; + } + } + + .roll-damage-button { + padding: 4px 10px; + background: linear-gradient(135deg, #c41e3a 0%, #8b0000 100%); + color: white; + border: none; + border-radius: 4px; + font-weight: bold; + font-size: 0.85em; + cursor: pointer; + display: flex; + align-items: center; + gap: 6px; + justify-content: center; + transition: all 0.2s; + box-shadow: 0 1px 3px rgba(196, 30, 58, 0.4); + margin-top: 4px; + + &:hover { + transform: translateY(-1px); + box-shadow: 0 2px 4px rgba(196, 30, 58, 0.6); + } + + i { + font-size: 1em; + } + } + } + + .roll-result { + padding: 8px; + background: linear-gradient(135deg, rgba(212, 175, 55, 0.2) 0%, rgba(212, 175, 55, 0.1) 100%); + border-top: 1px solid rgba(212, 175, 55, 0.5); + + .result-total { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + + .total-label { + font-size: 0.85em; + color: #aaa; + text-transform: uppercase; + letter-spacing: 0.5px; + } + + .total-value { + font-size: 1.8em; + font-weight: bold; + color: #d4af37; + text-shadow: 0 1px 3px rgba(212, 175, 55, 0.5); + line-height: 1; + } + } + + .d30-result { + margin-top: 4px; + padding: 3px 6px; + background: rgba(0, 0, 0, 0.2); + border-radius: 3px; + font-size: 0.8em; + text-align: center; + + i { + color: #d4af37; + margin-right: 4px; + } + } + } + + .result-badge { + padding: 6px; + text-align: center; + font-size: 0.9em; + font-weight: bold; + border-top: 1px solid; + + &.success { + background: linear-gradient(135deg, rgba(76, 175, 80, 0.3) 0%, rgba(76, 175, 80, 0.1) 100%); + border-color: #4caf50; + color: #4caf50; + } + + &.failure { + background: linear-gradient(135deg, rgba(244, 67, 54, 0.3) 0%, rgba(244, 67, 54, 0.1) 100%); + border-color: #f44336; + color: #f44336; + } + + i { + margin-right: 6px; + font-size: 1em; + } + } + + .damage-info { + padding: 6px; + background: rgba(255, 255, 255, 0.05); + border-radius: 3px; + font-size: 0.8em; + color: #aaa; + } +} + +// Old fortune and ask-roll styles +&.fortune { + img { + border: 0px; + } + .intro-chat { + border-radius: 20px; + display: flex; + flex-direction: row; + .intro-img { + padding: 5px; + width: 80px; + align-self: center; + } + .intro-right { + display: flex; + flex-direction: column; + .introText { + font-family: var(--font-secondary); + font-size: calc(var(--font-size-standard) * 1.2); + width: 210px; + text-align: center; + } + } + } + .button.control, + .fortune-accepted { + display: flex; + justify-content: center; + align-items: center; + font-size: calc(var(--font-size-standard) * 1.3); + } } &.ask-roll { @@ -37,4 +410,5 @@ justify-content: center; font-family: var(--font-secondary); font-size: calc(var(--font-size-standard) * 1.2); -} \ No newline at end of file +} +} diff --git a/styles/fvtt-prism-rpg.less b/styles/fvtt-prism-rpg.less index d5a7f48..6546247 100644 --- a/styles/fvtt-prism-rpg.less +++ b/styles/fvtt-prism-rpg.less @@ -13,7 +13,6 @@ @import "armor.less"; @import "spell.less"; @import "vulnerability.less"; - @import "chat.less"; @import "equipment.less"; @import "shield.less"; @import "miracle.less"; @@ -24,5 +23,7 @@ @import "weapon-types-config.less"; } +@import "chat.less"; @import "roll.less"; +@import "roll-dialog-modern.less"; @import "hud.less"; diff --git a/styles/roll-dialog-modern.less b/styles/roll-dialog-modern.less new file mode 100644 index 0000000..ad14d0b --- /dev/null +++ b/styles/roll-dialog-modern.less @@ -0,0 +1,305 @@ +// Modern Roll Dialog Styling +// Matches the new chat message card design + +.prismrpg-roll-dialog-modern { + font-family: var(--font-primary); + + // Header section + .dialog-header { + background: linear-gradient(135deg, rgba(33, 33, 33, 0.95) 0%, rgba(66, 66, 66, 0.95) 100%); + border-bottom: 2px solid #d4af37; + padding: 8px 10px; + margin: -8px -8px 8px -8px; + border-radius: 4px 4px 0 0; + + .character-info { + display: flex; + flex-direction: column; + gap: 4px; + + .character-name { + font-size: 1em; + font-weight: bold; + color: #d4af37; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); + } + + .item-name { + display: flex; + align-items: center; + gap: 4px; + font-size: 0.9em; + color: #e0e0e0; + + i { + color: #d4af37; + font-size: 0.85em; + } + + &.weapon i { + color: #f44336; + } + + &.spell i { + color: #9c27b0; + } + } + } + } + + // Content area + .dialog-content { + display: flex; + flex-direction: column; + gap: 8px; + } + + // Section styling + .option-section { + background: rgba(0, 0, 0, 0.1); + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 4px; + padding: 6px 8px; + + &.weapon-section { + border-left: 3px solid #f44336; + } + + &.spell-section { + border-left: 3px solid #9c27b0; + } + + .section-title { + display: flex; + align-items: center; + gap: 4px; + font-weight: bold; + font-size: 0.9em; + color: var(--color-dark-1); + margin-bottom: 6px; + padding-bottom: 4px; + border-bottom: 1px solid rgba(0, 0, 0, 0.15); + + i { + color: #d4af37; + font-size: 0.85em; + } + } + } + + // Info displays (ranges, spell stats) + .info-display { + display: flex; + align-items: center; + gap: 4px; + padding: 4px 6px; + background: rgba(0, 0, 0, 0.15); + border-radius: 3px; + margin-bottom: 6px; + font-size: 0.8em; + color: #666; + + i { + color: #4caf50; + font-size: 0.85em; + } + + .info-text { + flex: 1; + } + } + + // Spell info badges (like in chat) + .spell-info-display { + display: flex; + flex-wrap: wrap; + gap: 4px; + margin-bottom: 6px; + + .info-badge { + display: flex; + align-items: center; + gap: 3px; + padding: 3px 6px; + border-radius: 3px; + font-size: 0.75em; + font-weight: 500; + + i { + font-size: 0.85em; + } + + &.characteristic { + background: rgba(103, 58, 183, 0.2); + border: 1px solid rgba(103, 58, 183, 0.4); + color: #673ab7; + i { color: #673ab7; } + } + + &.mana { + background: rgba(33, 150, 243, 0.2); + border: 1px solid rgba(33, 150, 243, 0.4); + color: #2196f3; + i { color: #2196f3; } + } + + &.apc { + background: rgba(255, 193, 7, 0.2); + border: 1px solid rgba(255, 193, 7, 0.4); + color: #ffc107; + i { color: #ffc107; } + } + + &.upkeep { + background: rgba(156, 39, 176, 0.2); + border: 1px solid rgba(156, 39, 176, 0.4); + color: #9c27b0; + i { color: #9c27b0; } + } + } + } + + // Option rows (label + control) + .option-row { + display: flex; + align-items: center; + gap: 6px; + margin-bottom: 4px; + + &:last-child { + margin-bottom: 0; + } + + label { + font-size: 0.85em; + font-weight: 500; + color: var(--color-dark-2); + min-width: 90px; + } + + select { + flex: 1; + } + } + + // Styled selects + .styled-select { + background: rgba(255, 255, 255, 0.9); + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 3px; + padding: 4px 8px; + font-size: 0.85em; + color: var(--color-dark-1); + cursor: pointer; + transition: all 0.2s ease; + + &:hover { + border-color: #d4af37; + box-shadow: 0 0 4px rgba(212, 175, 55, 0.3); + } + + &:focus { + outline: none; + border-color: #d4af37; + box-shadow: 0 0 6px rgba(212, 175, 55, 0.5); + } + + &.advantage-select, + &.modifier-select { + text-align: center; + font-weight: 500; + } + } + + // Checkbox group + .checkbox-group { + display: flex; + flex-direction: column; + gap: 3px; + margin-bottom: 6px; + + .checkbox-label { + display: flex; + align-items: center; + cursor: pointer; + padding: 3px 4px; + border-radius: 3px; + transition: background 0.2s ease; + + &:hover { + background: rgba(0, 0, 0, 0.05); + } + + input[type="checkbox"] { + margin-right: 6px; + cursor: pointer; + width: 14px; + height: 14px; + accent-color: #d4af37; + } + + .checkbox-text { + display: flex; + align-items: center; + gap: 4px; + font-size: 0.8em; + color: var(--color-dark-2); + + i { + color: #888; + font-size: 0.85em; + } + } + + input[type="checkbox"]:checked ~ .checkbox-text { + color: var(--color-dark-1); + font-weight: 500; + + i { + color: #d4af37; + } + } + } + } +} + +// Dialog application styling +.application.dialog.prismrpg { + .window-content { + background: linear-gradient(135deg, #f5f5f5 0%, #e0e0e0 100%); + padding: 8px; + } + + // Make buttons match the modern style + .dialog-buttons { + padding: 6px 8px; + gap: 6px; + + button { + background: linear-gradient(135deg, #4a4a4a 0%, #6a6a6a 100%); + border: 1px solid #3a3a3a; + color: white; + font-weight: 600; + padding: 6px 12px; + border-radius: 4px; + transition: all 0.2s ease; + + &:hover { + background: linear-gradient(135deg, #5a5a5a 0%, #7a7a7a 100%); + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + transform: translateY(-1px); + } + + &.default, + &[data-button="roll"] { + background: linear-gradient(135deg, #d4af37 0%, #f4cf67 100%); + border-color: #b49030; + color: #2a2a2a; + + &:hover { + background: linear-gradient(135deg, #e4bf47 0%, #ffdf77 100%); + } + } + } + } +} diff --git a/styles/roll.less b/styles/roll.less index 4c5fadb..da477e3 100644 --- a/styles/roll.less +++ b/styles/roll.less @@ -25,6 +25,30 @@ border-radius: 4px; padding: 0.5rem; } + + .dialog-weapon-options { + margin-top: 8px; + + .dialog-save { + margin: 4px 0; + + label { + display: flex; + align-items: center; + cursor: pointer; + + input[type="checkbox"] { + margin-right: 8px; + cursor: pointer; + } + } + + select { + margin-left: 8px; + min-width: 10rem; + } + } + } } .prismrpg-range-defense-dialog { @@ -156,4 +180,34 @@ font-size: calc(var(--font-size-standard) * 1); text-shadow: 0 0 10px var(--color-shadow-primary); } + + // Roll Damage button in weapon attack messages + .damage-roll-button { + margin-top: 0.5em; + margin-bottom: 0.25em; + + .roll-damage-button { + background: linear-gradient(135deg, #8b0000 0%, #dc143c 100%); + color: white; + border: 1px solid #6b0000; + border-radius: 3px; + padding: 4px 10px; + font-weight: 600; + cursor: pointer; + font-size: 0.85em; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); + transition: all 0.2s ease; + + &:hover { + background: linear-gradient(135deg, #a00000 0%, #ff1744 100%); + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); + transform: translateY(-1px); + } + + i { + margin-right: 4px; + font-size: 0.9em; + } + } + } } diff --git a/templates/character-biography.hbs b/templates/character-biography.hbs index f8dd423..6a46fab 100644 --- a/templates/character-biography.hbs +++ b/templates/character-biography.hbs @@ -82,13 +82,13 @@ value=system.biodata.magicUser }} -
+
Save bonus (1/5levels) {{formInput diff --git a/templates/character-combat.hbs b/templates/character-combat.hbs index 74f87e9..5dd8e57 100644 --- a/templates/character-combat.hbs +++ b/templates/character-combat.hbs @@ -41,43 +41,17 @@ > - - - - - - S - - M + >
diff --git a/templates/character-equipment.hbs b/templates/character-equipment.hbs index 8c8e3ae..f869dd6 100644 --- a/templates/character-equipment.hbs +++ b/templates/character-equipment.hbs @@ -4,11 +4,11 @@
{{localize "PRISMRPG.Label.money"}}
- {{formField systemFields.moneys.fields.tinbit.fields.value value=system.moneys.tinbit.value localize=true}} - {{formField systemFields.moneys.fields.copper.fields.value value=system.moneys.copper.value localize=true}} - {{formField systemFields.moneys.fields.silver.fields.value value=system.moneys.silver.value localize=true}} - {{formField systemFields.moneys.fields.gold.fields.value value=system.moneys.gold.value localize=true}} - {{formField systemFields.moneys.fields.platinum.fields.value value=system.moneys.platinum.value localize=true}} + {{formField systemFields.moneys.fields.coppercoin.fields.value value=system.moneys.coppercoin.value localize=true}} + {{formField systemFields.moneys.fields.silvercoin.fields.value value=system.moneys.silvercoin.value localize=true}} + {{formField systemFields.moneys.fields.goldcoin.fields.value value=system.moneys.goldcoin.value localize=true}} + {{formField systemFields.moneys.fields.note.fields.value value=system.moneys.note.value localize=true}} + {{formField systemFields.moneys.fields.steam.fields.value value=system.moneys.steam.value localize=true}}
diff --git a/templates/character-main.hbs b/templates/character-main.hbs index 00eac80..4d84bf0 100644 --- a/templates/character-main.hbs +++ b/templates/character-main.hbs @@ -46,6 +46,7 @@
HP
+
{{formInput systemFields.hp.fields.value @@ -53,6 +54,7 @@ disabled=isPlayMode }}
+
/
{{formInput @@ -63,19 +65,21 @@
-
MAGIC
+
MANA
+
{{formInput - systemFields.magicPoints.fields.value - value=system.magicPoints.value + systemFields.manaPoints.fields.value + value=system.manaPoints.value disabled=isPlayMode }}
+
/
{{formInput - systemFields.magicPoints.fields.max - value=system.magicPoints.max + systemFields.manaPoints.fields.max + value=system.manaPoints.max disabled=isPlayMode }}
@@ -327,6 +331,5 @@
- \ No newline at end of file diff --git a/templates/character-miracles.hbs b/templates/character-miracles.hbs index c20842e..342f547 100644 --- a/templates/character-miracles.hbs +++ b/templates/character-miracles.hbs @@ -2,16 +2,16 @@
- {{localize "PRISMRPG.Label.divinityPoints"}} + {{localize "PRISMRPG.Label.manaPoints"}}
Current - {{formField systemFields.divinityPoints.fields.value value=system.divinityPoints.value localize=true}} - - + {{formField systemFields.manaPoints.fields.value value=system.manaPoints.value localize=true}} + + Max - {{formField systemFields.divinityPoints.fields.max value=system.divinityPoints.max localize=true + {{formField systemFields.manaPoints.fields.max value=system.manaPoints.max localize=true disabled=isPlayMode}}
diff --git a/templates/character-spells.hbs b/templates/character-spells.hbs index 5dbc767..f97214d 100644 --- a/templates/character-spells.hbs +++ b/templates/character-spells.hbs @@ -1,22 +1,6 @@
-
- {{localize "PRISMRPG.Label.aetherPoints"}} -
-
- Current - {{formField systemFields.aetherPoints.fields.value value=system.aetherPoints.value localize=true}} - - - - Max - {{formField systemFields.aetherPoints.fields.max value=system.aetherPoints.max localize=true - disabled=isPlayMode}} -
-
-
-
{{localize "PRISMRPG.Label.spells"}}{{#if isEditMode}} - - - - - - + +
diff --git a/templates/character-subattributes-old.hbs b/templates/character-subattributes-old.hbs deleted file mode 100644 index 6755e71..0000000 --- a/templates/character-subattributes-old.hbs +++ /dev/null @@ -1,257 +0,0 @@ -
- {{log "character-subattributes" this}} - -
-

- - Sub-Attributes -

-

- Sub-attributes are derived from the average of two primary characteristics. -

- -
- {{#each (entries config.SUB_ATTRIBUTES) as |entry|}} - {{#with entry.1 as |subAttr|}} -
-
-
- - {{localize subAttr.label}} -
-
- -
-
-
-
- From: - {{#each subAttr.parents as |parentKey|}} - - {{uppercase parentKey}} - ({{lookup ../../system.characteristics parentKey 'value'}}) - - {{/each}} -
-
- {{localize subAttr.description}} -
-
-
- {{/with}} - {{/each}} -
-
-
- -
- {{! Character Header with Age, Length, Weight, Sex, Skin, Hair }} -
-
-
- - {{formInput - systemFields.bio.fields.age - value=system.bio.age - disabled=isPlayMode - }} -
-
- - {{formInput - systemFields.bio.fields.length - value=system.bio.length - disabled=isPlayMode - }} -
-
- - {{formInput - systemFields.bio.fields.weight - value=system.bio.weight - disabled=isPlayMode - }} -
-
-
-
- - {{formInput - systemFields.bio.fields.sex - value=system.bio.sex - disabled=isPlayMode - }} -
-
- - {{formInput - systemFields.bio.fields.skin - value=system.bio.skin - disabled=isPlayMode - }} -
-
- - {{formInput - systemFields.bio.fields.hair - value=system.bio.hair - disabled=isPlayMode - }} -
-
-
- - {{! Sub-Attributes Table }} -
-

Sub-Attribute

-
-
-
Prowess
-
- {{formInput - systemFields.subattributes.fields.prowess - value=system.subattributes.prowess - disabled=isPlayMode - }} -
-
Vigor
-
- {{formInput - systemFields.subattributes.fields.vigor - value=system.subattributes.vigor - disabled=isPlayMode - }} -
-
Competence
-
- {{formInput - systemFields.subattributes.fields.competence - value=system.subattributes.competence - disabled=isPlayMode - }} -
-
Authority
-
- {{formInput - systemFields.subattributes.fields.authority - value=system.subattributes.authority - disabled=isPlayMode - }} -
-
Presence
-
- {{formInput - systemFields.subattributes.fields.presence - value=system.subattributes.presence - disabled=isPlayMode - }} -
-
- -
-
Willpower
-
- {{formInput - systemFields.subattributes.fields.willpower - value=system.subattributes.willpower - disabled=isPlayMode - }} -
-
Resilience
-
- {{formInput - systemFields.subattributes.fields.resilience - value=system.subattributes.resilience - disabled=isPlayMode - }} -
-
Cunning
-
- {{formInput - systemFields.subattributes.fields.cunning - value=system.subattributes.cunning - disabled=isPlayMode - }} -
-
Guile
-
- {{formInput - systemFields.subattributes.fields.guile - value=system.subattributes.guile - disabled=isPlayMode - }} -
-
Sovereignty
-
- {{formInput - systemFields.subattributes.fields.sovereignty - value=system.subattributes.sovereignty - disabled=isPlayMode - }} -
-
- -
-
Stamina
-
- {{formInput - systemFields.subattributes.fields.stamina - value=system.subattributes.stamina - disabled=isPlayMode - }} -
-
Initiative
-
- {{formInput - systemFields.subattributes.fields.initiative - value=system.subattributes.initiative - disabled=isPlayMode - }} -
-
Wit
-
- {{formInput - systemFields.subattributes.fields.wit - value=system.subattributes.wit - disabled=isPlayMode - }} -
-
Grace
-
- {{formInput - systemFields.subattributes.fields.grace - value=system.subattributes.grace - disabled=isPlayMode - }} -
-
Tenacity
-
- {{formInput - systemFields.subattributes.fields.tenacity - value=system.subattributes.tenacity - disabled=isPlayMode - }} -
-
-
-
- - {{! Proficiencies Section }} -
-

Proficiencies

-
- {{formInput - systemFields.proficiencies - value=system.proficiencies - disabled=isPlayMode - type="textarea" - }} -
-
-
-
\ No newline at end of file diff --git a/templates/chat-message.hbs b/templates/chat-message.hbs index f22d5c1..cc74082 100644 --- a/templates/chat-message.hbs +++ b/templates/chat-message.hbs @@ -1,110 +1,205 @@ -{{!log 'chat-message' this}} -
-
-
+{{!log "chat-message" this}} +{{!log "rollTarget" rollTarget}} +{{!log "rollData" rollData}} +
+
+
- -
- {{actingCharName}} - {{upperFirst rollName}} - +
+
{{actingCharName}}
+
{{upperFirst rollName}}
{{#if (match rollType "attack")}} - Attack roll ! - {{/if}} - {{#if (match rollType "defense")}} - Defense roll ! - {{/if}} - - {{#if (eq rollData.favor "favor")}} - Favor roll - {{/if}} - {{#if (eq rollData.favor "disfavor")}} - Disfavor roll +
Attack Roll
{{/if}} {{#if badResult}} - {{localize "PRISMRPG.Label.otherResult"}} - : - {{badResult}} +
{{localize "PRISMRPG.Label.otherResult"}}: {{badResult}}
{{/if}} - - {{#if rollTarget.weapon}} - {{rollTarget.weapon.name}} - {{/if}} - - {{#if rollData.letItFly}} - Let It Fly attack ! - {{/if}} - {{#if rollData.pointBlank}} - Point Blank Range Attack ! - {{/if}} - {{#if rollData.beyondSkill}} - Beyond Skill Range Attack ! - {{/if}} - - Formula : {{titleFormula}} - - {{#if (eq rollType "save")}} - {{#if rollTarget.abilityModifier}} - - (Ability Mod: - {{#if - (gt rollTarget.abilityModifier 0) - }}+{{/if}}{{rollTarget.abilityModifier}}, Save Bonus: - {{#if - (gt rollTarget.saveProficiency 0) - }}+{{/if}}{{rollTarget.saveProficiency}}) - - {{/if}} - {{/if}} - - {{#each diceResults as |result|}} - {{result.dice}} : {{result.value}} - {{/each}} -
- {{#if isSave}} -
- {{#if (eq resultType "success")}} - {{#if isPrivate}}?{{else}}{{localize "PRISMRPG.Roll.success"}}{{/if}} - {{else}} - {{#if isPrivate}}?{{else}}{{localize "PRISMRPG.Roll.failure"}}{{/if}} - {{/if}} -
- {{/if}} - {{#if isResource}} -
- {{#if (eq resultType "success")}} - {{#if isPrivate}}?{{else}}{{localize "PRISMRPG.Roll.success"}}{{/if}} - {{else}} - {{#if isPrivate}}?{{else}}{{localize "PRISMRPG.Roll.failure"}}{{#if - isFailure - }} ({{localize "PRISMRPG.Roll.resourceLost"}}){{/if}}{{/if}} - {{/if}} -
- {{/if}} - {{#if isDamage}} -
- {{#if (and isGM hasTarget)}} - {{{localize - "PRISMRPG.Roll.displayArmor" - targetName=targetName - targetArmor=targetArmor - realDamage=realDamage - }}} - {{/if}} -
- {{/if}} - {{#unless isPrivate}} -
-

{{total}}

-
- {{#if D30result}} -
-

D30 result: {{D30result}}

+
+ {{#if rollTarget.weapon}} +
+
+ {{rollTarget.weapon.name}} + {{#if rollTarget.weapon.system.isImplement}} + Implement + {{/if}} + {{#if rollData.attackAttribute}} + + ({{#if (eq rollData.attackAttribute "str")}}Strength{{else}}Dexterity{{/if}}) + + {{/if}} +
+ +
+ {{#if rollTarget.weapon.system.weaponGroup}} +
+ + {{rollTarget.weapon.system.weaponGroup}} +
+ {{/if}} + {{#if rollTarget.weapon.system.apc}} +
+ + {{rollTarget.weapon.system.apc}} APC +
+ {{/if}} + {{#if rollTarget.weapon.system.damage}} +
+ + {{rollTarget.weapon.system.damage}} +
+ {{/if}} + {{#if rollTarget.weapon.system.damageType}} +
+ + + {{#if rollTarget.weapon.system.damageType.piercing}}P{{/if}}{{#if rollTarget.weapon.system.damageType.bludgeoning}}{{#if rollTarget.weapon.system.damageType.piercing}}/{{/if}}B{{/if}}{{#if rollTarget.weapon.system.damageType.slashing}}{{#if (or rollTarget.weapon.system.damageType.piercing rollTarget.weapon.system.damageType.bludgeoning)}}/{{/if}}S{{/if}} + +
+ {{/if}} + {{#if (or (gt rollTarget.weapon.system.shortRange 0) (gt rollTarget.weapon.system.longRange 0))}} +
+ + + {{#if (gt rollTarget.weapon.system.shortRange 0)}}{{rollTarget.weapon.system.shortRange}}{{/if}}{{#if (and (gt rollTarget.weapon.system.shortRange 0) (gt rollTarget.weapon.system.longRange 0))}}/{{/if}}{{#if (gt rollTarget.weapon.system.longRange 0)}}{{rollTarget.weapon.system.longRange}}{{/if}}ft + +
+ {{/if}} + {{#if (gt rollTarget.weapon.system.reloadAPC 0)}} +
+ + Reload {{rollTarget.weapon.system.reloadAPC}} +
+ {{/if}} +
{{/if}} + {{#if (eq rollType "spell-cast")}} +
+
+ Spell Cast + {{#if (gt rollData.upcastLevel 0)}} + +{{rollData.upcastLevel}} Levels + {{/if}} +
+
+ {{#if rollData.mentalCharacteristic}} +
+ + {{rollData.mentalCharacteristic}} ({{rollData.mentalCharValue}}) +
+ {{/if}} +
+ + {{rollData.totalManaCost}} Mana +
+
+ + {{rollData.totalAPC}} APC +
+ {{#if (gt rollData.manaUpkeep 0)}} +
+ + {{rollData.manaUpkeep}}/round +
+ {{/if}} +
+
+ {{/if}} + + {{#if rollData.letItFly}} +
Let It Fly!
+ {{/if}} + {{#if rollData.pointBlank}} +
Point Blank
+ {{/if}} + {{#if rollData.beyondSkill}} +
Beyond Skill Range
+ {{/if}} + {{#if (and rollData.attackerAim (ne rollData.attackerAim "0"))}} +
+ Aiming: {{rollData.attackerAim}} +
+ {{/if}} + +
+ {{titleFormula}} +
+ + {{#if (eq rollType "save")}} + {{#if rollTarget.abilityModifier}} +
+ Ability Mod: {{#if (gt rollTarget.abilityModifier 0)}}+{{/if}}{{rollTarget.abilityModifier}} + Save Bonus: {{#if (gt rollTarget.saveProficiency 0)}}+{{/if}}{{rollTarget.saveProficiency}} +
+ {{/if}} + {{/if}} + + {{#each diceResults as |result|}} +
+ {{result.dice}}: {{result.value}} +
+ {{/each}} + + {{#if (eq rollType "weapon-attack")}} + + {{/if}} +
+ + {{#unless isPrivate}} +
+
+ Result + {{total}} +
+ {{#if D30result}} +
+ D30: {{D30result}} +
+ {{/if}} +
{{/unless}} + + {{#if isSave}} +
+ {{#if isPrivate}} + ? + {{else}} + {{#if (eq resultType "success")}} + {{localize "PRISMRPG.Roll.success"}} + {{else}} + {{localize "PRISMRPG.Roll.failure"}} + {{/if}} + {{/if}} +
+ {{/if}} + + {{#if isResource}} +
+ {{#if isPrivate}} + ? + {{else}} + {{#if (eq resultType "success")}} + {{localize "PRISMRPG.Roll.success"}} + {{else}} + {{localize "PRISMRPG.Roll.failure"}}{{#if isFailure}} ({{localize "PRISMRPG.Roll.resourceLost"}}){{/if}} + {{/if}} + {{/if}} +
+ {{/if}} + + {{#if isDamage}} + {{#if (and isGM hasTarget)}} +
+ {{{localize "PRISMRPG.Roll.displayArmor" targetName=targetName targetArmor=targetArmor realDamage=realDamage}}} +
+ {{/if}} + {{/if}}
\ No newline at end of file diff --git a/templates/roll-dialog-old.hbs b/templates/roll-dialog-old.hbs deleted file mode 100644 index 626b376..0000000 --- a/templates/roll-dialog-old.hbs +++ /dev/null @@ -1,119 +0,0 @@ -
- -
- {{localize (concat "PRISMRPG.Label." rollType)}} - {{actorName}} - - {{#if rollTarget.tokenId}} - - {{/if}} - - {{#if (match rollType "attack")}} -
Attack roll ! - {{rollTarget.name}}
- {{/if}} - {{#if (match rollType "defense")}} -
Defense roll ! - {{rollTarget.name}}
- {{/if}} - - {{#if hasModifier}} -
{{upperFirst rollName}} : {{baseFormula}} + {{baseValue}}
- {{else}} -
{{upperFirst rollName}} : {{baseFormula}}
- {{/if}} - {{#if rollTarget.weapon}} -
{{localize "PRISMRPG.Label.baseModifier"}} : {{rollTarget.charModifier}}
-
{{localize "PRISMRPG.Label.weapon"}} : {{rollTarget.weapon.name}}
-
{{localize "PRISMRPG.Label.skill"}} : {{rollTarget.name}}
-
{{localize "PRISMRPG.Label.skillBonus"}} : {{rollTarget.weaponSkillModifier}}
- {{/if}} - - {{#if (match rollType "attack")}} -
Add Granted Attack Dice - -
- {{#if rollTarget.weapon}} - {{#if (eq rollTarget.weapon.system.weaponType "melee")}} - {{else}} -
Point Blank Range Attack - -
-
Beyond Skill Range Attack - -
-
Let it Fly (Pure D20E) - -
-
Aiming - -
- {{/if}} - {{/if}} - - {{/if}} - {{#if (match rollType "defense")}} -
Add Granted Defense Dice - -
- {{/if}} - {{#if (match rollType "damage")}} -
Add Granted Damage Dice - -
- {{/if}} - - {{#if rollTarget.staticModifier}} -
Static modifier : +{{rollTarget.staticModifier}}
- {{/if}} - -
- - - {{#if hasFavor}} -
- {{localize "PRISMRPG.Roll.favorDisfavor"}} - -
- {{/if}} - - {{#if hasModifier}} -
- {{localize "PRISMRPG.Roll.modifierBonusMalus"}} - - - {{#if (eq rollType "save")}} - {{#if rollTarget.magicUser}} -
- Save against spell (+{{rollTarget.actorModifiers.saveModifier}}) ? - -
- {{/if}} - {{/if}} -
- {{/if}} - - {{#if hasChangeDice}} -
- {{localize "PRISMRPG.Roll.changeDice"}} - -
- {{/if}} - -
- {{localize "PRISMRPG.Roll.visibility"}} - -
- - -
\ No newline at end of file diff --git a/templates/roll-dialog-v2.hbs b/templates/roll-dialog-v2.hbs new file mode 100644 index 0000000..aaddc3d --- /dev/null +++ b/templates/roll-dialog-v2.hbs @@ -0,0 +1,195 @@ +
+ {{! Header with character info }} +
+
+
{{actorName}}
+ {{#if rollTarget.weapon}} +
+ + {{rollTarget.weapon.name}} +
+ {{/if}} + {{#if rollTarget.type}} + {{#if (eq rollTarget.type "spell")}} +
+ + {{rollTarget.name}} +
+ {{/if}} + {{/if}} +
+
+ +
+ {{! Weapon Options }} + {{#if rollTarget.weapon}} +
+
+ + Weapon Options +
+ + {{! Display weapon ranges }} + {{#if (or (gt rollTarget.weapon.system.shortRange 0) (gt rollTarget.weapon.system.longRange 0))}} +
+ + + {{#if (gt rollTarget.weapon.system.shortRange 0)}} + Short: {{rollTarget.weapon.system.shortRange}} ft + {{/if}} + {{#if (gt rollTarget.weapon.system.longRange 0)}} + {{#if (gt rollTarget.weapon.system.shortRange 0)}} • {{/if}} + Long: {{rollTarget.weapon.system.longRange}} ft + {{/if}} + +
+ {{/if}} + + {{! STR or DEX choice }} + {{#if (or (eq rollType "weapon-attack") (eq rollType "weapon-damage-small") (eq rollType "weapon-damage-medium"))}} +
+ + +
+ {{/if}} + + {{! Ranged weapon checkboxes }} + {{#if (eq rollTarget.weapon.system.weaponType "ranged")}} + {{#if (or (eq rollType "weapon-attack") (eq rollType "monster-attack"))}} +
+ + + +
+ +
+ + +
+ {{/if}} + {{/if}} +
+ {{/if}} + + {{! Spell Options }} + {{#if rollTarget.type}} + {{#if (eq rollTarget.type "spell")}} +
+
+ + Spell Options +
+ + {{! Spell info display }} +
+
+ + {{rollTarget.mentalCharacteristic}} ({{rollTarget.mentalCharValue}}, +{{rollTarget.value}}) +
+
+ + {{rollTarget.system.manaCost}} Mana +
+
+ + {{rollTarget.system.apc}} APC +
+ {{#if (gt rollTarget.system.manaUpkeep 0)}} +
+ + {{rollTarget.system.manaUpkeep}}/round +
+ {{/if}} +
+ + {{! Upcast option }} + {{#if rollTarget.system.canAscend}} +
+ + +
+ {{/if}} +
+ {{/if}} + {{/if}} + + {{! Advantage/Disadvantage }} + {{#if hasAdvantage}} +
+
+ + {{localize "PRISMRPG.Roll.advantageDisadvantage"}} +
+
+ +
+
+ {{/if}} + + {{! Modifier }} + {{#if hasModifier}} +
+
+ + {{localize "PRISMRPG.Roll.modifierBonusMalus"}} +
+
+ +
+
+ {{/if}} + + {{! Visibility }} +
+
+ + {{localize "PRISMRPG.Roll.visibility"}} +
+
+ +
+
+
+
diff --git a/templates/roll-dialog.hbs b/templates/roll-dialog.hbs index 4b0420d..f470147 100644 --- a/templates/roll-dialog.hbs +++ b/templates/roll-dialog.hbs @@ -1,51 +1,122 @@
- {{localize (concat "PRISMRPG.Label." rollType)}} - - - {{actorName}} - - {{#if hasModifier}} -
- {{upperFirst rollName}} - : - {{dice}} - + - {{baseValue}} -
- {{#if (eq rollType "save")}} -
- (Ability Mod: - {{#if - (gt rollTarget.abilityModifier 0) - }}+{{/if}}{{rollTarget.abilityModifier}} - + Save Bonus: - {{#if - (gt rollTarget.saveProficiency 0) - }}+{{/if}}{{rollTarget.saveProficiency}}) -
- {{/if}} - {{else}} -
- {{upperFirst rollName}} - : - {{dice}} -
- {{/if}} + {{actorName}} {{#if rollTarget.weapon}}
- {{localize "PRISMRPG.Label.weapon"}} - : - {{rollTarget.weapon.name}} -
-
- {{localize "PRISMRPG.Label.skill"}} - : - {{rollTarget.name}} + {{rollTarget.weapon.name}}
{{/if}}
+ {{#if rollTarget.weapon}} + {{! Weapon-specific options }} +
+ Weapon Options + + {{! Display weapon ranges if set }} + {{#if (or (gt rollTarget.weapon.system.shortRange 0) (gt rollTarget.weapon.system.longRange 0))}} +
+ {{#if (gt rollTarget.weapon.system.shortRange 0)}} + Short Range: {{rollTarget.weapon.system.shortRange}} ft + {{/if}} + {{#if (gt rollTarget.weapon.system.longRange 0)}} + {{#if (gt rollTarget.weapon.system.shortRange 0)}} • {{/if}} + Long Range: {{rollTarget.weapon.system.longRange}} ft + {{/if}} +
+ {{/if}} + + {{! Choose STR or DEX for attack/damage rolls }} + {{#if (or (eq rollType "weapon-attack") (eq rollType "weapon-damage-small") (eq rollType "weapon-damage-medium"))}} +
+ + +
+ {{/if}} + + {{! Ranged weapon specific options }} + {{#if (eq rollTarget.weapon.system.weaponType "ranged")}} + {{#if + (or (eq rollType "weapon-attack") (eq rollType "monster-attack")) + }} +
+ +
+
+ +
+
+ +
+
+ + +
+ {{/if}} + {{/if}} +
+ {{/if}} + + {{#if rollTarget.type}} + {{#if (eq rollTarget.type "spell")}} + {{! Spell-specific options }} +
+ Spell Options + +
+ Casting with: {{rollTarget.mentalCharacteristic}} ({{rollTarget.mentalCharValue}}, +{{rollTarget.value}}) +
Base Cost: {{rollTarget.system.manaCost}} Mana, {{rollTarget.system.apc}} APC + {{#if (gt rollTarget.system.manaUpkeep 0)}} +
Upkeep: {{rollTarget.system.manaUpkeep}} Mana/round + {{/if}} +
+ + {{#if rollTarget.system.canAscend}} +
+ + +
+ {{/if}} +
+ {{/if}} + {{/if}} + {{#if hasAdvantage}}
{{localize "PRISMRPG.Roll.advantageDisadvantage"}} diff --git a/templates/weapon.hbs b/templates/weapon.hbs index 0bba688..89fa0c6 100644 --- a/templates/weapon.hbs +++ b/templates/weapon.hbs @@ -71,27 +71,26 @@
- {{! Prism RPG: Projectile Properties }} - {{#if system.isProjectile}} - {{formField - systemFields.isProjectile - value=system.isProjectile - localize=true - label="PRISMRPG.Label.isProjectile" - }} - {{formField - systemFields.range - value=system.range - localize=true - label="PRISMRPG.Label.range" - }} - {{formField - systemFields.reloadAPC - value=system.reloadAPC - localize=true - label="PRISMRPG.Label.reloadAPC" - }} - {{/if}} + {{formField + systemFields.shortRange + value=system.shortRange + localize=true + label="PRISMRPG.Label.shortRange" + }} + + {{formField + systemFields.longRange + value=system.longRange + localize=true + label="PRISMRPG.Label.longRange" + }} + + {{formField + systemFields.reloadAPC + value=system.reloadAPC + localize=true + label="PRISMRPG.Label.reloadAPC" + }} {{formField systemFields.encLoad