diff --git a/assets/icons/icon_armor.webp b/assets/icons/icon_armor.webp index 0e9e7fb..dc25e18 100644 Binary files a/assets/icons/icon_armor.webp and b/assets/icons/icon_armor.webp differ diff --git a/assets/icons/icon_class.webp b/assets/icons/icon_class.webp new file mode 100644 index 0000000..ed58855 Binary files /dev/null and b/assets/icons/icon_class.webp differ diff --git a/assets/icons/icon_equipment.webp b/assets/icons/icon_equipment.webp index b8a4249..93f5d6f 100644 Binary files a/assets/icons/icon_equipment.webp and b/assets/icons/icon_equipment.webp differ diff --git a/assets/icons/icon_gift.webp b/assets/icons/icon_gift.webp deleted file mode 100644 index 70927d4..0000000 Binary files a/assets/icons/icon_gift.webp and /dev/null differ diff --git a/assets/icons/icon_race.webp b/assets/icons/icon_race.webp new file mode 100644 index 0000000..daedab1 Binary files /dev/null and b/assets/icons/icon_race.webp differ diff --git a/assets/icons/icon_racial-ability.webp b/assets/icons/icon_racial-ability.webp new file mode 100644 index 0000000..92f07d9 Binary files /dev/null and b/assets/icons/icon_racial-ability.webp differ diff --git a/assets/icons/icon_shield.webp b/assets/icons/icon_shield.webp index df0bfe9..8ddee1a 100644 Binary files a/assets/icons/icon_shield.webp and b/assets/icons/icon_shield.webp differ diff --git a/assets/icons/icon_skill.webp b/assets/icons/icon_skill.webp index 2211197..59fd66e 100644 Binary files a/assets/icons/icon_skill.webp and b/assets/icons/icon_skill.webp differ diff --git a/assets/icons/icon_spell.webp b/assets/icons/icon_spell.webp index e9538c7..e59c7bd 100644 Binary files a/assets/icons/icon_spell.webp and b/assets/icons/icon_spell.webp differ diff --git a/assets/icons/icon_weapon.webp b/assets/icons/icon_weapon.webp index d929a97..04f4d1a 100644 Binary files a/assets/icons/icon_weapon.webp and b/assets/icons/icon_weapon.webp differ diff --git a/assets/ui/lf_logo_small_02.webp b/assets/ui/lf_logo_small_02.webp deleted file mode 100644 index 97e31b8..0000000 Binary files a/assets/ui/lf_logo_small_02.webp and /dev/null differ diff --git a/assets/ui/prism-rpg-logo-01.webp b/assets/ui/prism-rpg-logo-01.webp new file mode 100644 index 0000000..2adb719 Binary files /dev/null and b/assets/ui/prism-rpg-logo-01.webp differ diff --git a/assets/ui/prism_rpg_main_picture.webp b/assets/ui/prism_rpg_main_picture.webp deleted file mode 100644 index efa0e1c..0000000 Binary files a/assets/ui/prism_rpg_main_picture.webp and /dev/null differ diff --git a/css/fvtt-prism-rpg.css b/css/fvtt-prism-rpg.css index f46fbf0..03871fc 100644 --- a/css/fvtt-prism-rpg.css +++ b/css/fvtt-prism-rpg.css @@ -11,7 +11,7 @@ --font-size-standard: 0.8rem; --background-image-base: url("../assets/ui/prism_rpg_background.webp"); --font-secondary: "BaskervilleBold", serif; - --logo-standard: url("../assets/ui/lf_logo_small_02.webp"); + --logo-standard: url("../assets/ui/prism-rpg-logo-01.webp"); } .initiative-area { min-width: 8rem; @@ -431,21 +431,21 @@ i.prismrpg { .prismrpg .tab.character-skills .main-div .skills .skill .name { min-width: 12rem; } -.prismrpg .tab.character-skills .main-div .gifts { +.prismrpg .tab.character-skills .main-div .racial-abilities { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; } -.prismrpg .tab.character-skills .main-div .gifts .gift { +.prismrpg .tab.character-skills .main-div .racial-abilities .racial-ability { display: flex; align-items: center; gap: 4px; } -.prismrpg .tab.character-skills .main-div .gifts .gift .item-img { +.prismrpg .tab.character-skills .main-div .racial-abilities .racial-ability .item-img { width: 24px; height: 24px; } -.prismrpg .tab.character-skills .main-div .gifts .gift .name { +.prismrpg .tab.character-skills .main-div .racial-abilities .racial-ability .name { min-width: 12rem; } .prismrpg .tab.character-skills .main-div .vulnerabilities { @@ -1058,21 +1058,21 @@ i.prismrpg { .prismrpg .tab.monster-skills .main-div .skills .skill .name { min-width: 12rem; } -.prismrpg .tab.monster-skills .main-div .gifts { +.prismrpg .tab.monster-skills .main-div .racial-abilities { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; } -.prismrpg .tab.monster-skills .main-div .gifts .gift { +.prismrpg .tab.monster-skills .main-div .racial-abilities .racial-ability { display: flex; align-items: center; gap: 4px; } -.prismrpg .tab.monster-skills .main-div .gifts .gift .item-img { +.prismrpg .tab.monster-skills .main-div .racial-abilities .racial-ability .item-img { width: 24px; height: 24px; } -.prismrpg .tab.monster-skills .main-div .gifts .gift .name { +.prismrpg .tab.monster-skills .main-div .racial-abilities .racial-ability .name { min-width: 12rem; } .prismrpg .tab.monster-skills .main-div .vulnerabilities { @@ -1339,7 +1339,7 @@ i.prismrpg { .prismrpg .skill-content input[type="checkbox"]:checked::after { color: rgba(0, 0, 0, 0.1); } -.prismrpg .gift-content { +.prismrpg .racial-ability-content { font-family: var(--font-primary); font-size: calc(var(--font-size-standard) * 1); color: var(--color-dark-1); @@ -1348,26 +1348,26 @@ i.prismrpg { background-size: 100% 100%; overflow: auto; } -.prismrpg .gift-content nav.tabs [data-tab] { +.prismrpg .racial-ability-content nav.tabs [data-tab] { color: #636060; } -.prismrpg .gift-content nav.tabs [data-tab].active { +.prismrpg .racial-ability-content nav.tabs [data-tab].active { color: #252424; } -.prismrpg .gift-content input:disabled, -.prismrpg .gift-content select:disabled { +.prismrpg .racial-ability-content input:disabled, +.prismrpg .racial-ability-content select:disabled { background-color: rgba(0, 0, 0, 0.2); border-color: transparent; color: var(--color-dark-3); } -.prismrpg .gift-content input, -.prismrpg .gift-content select { +.prismrpg .racial-ability-content input, +.prismrpg .racial-ability-content select { height: 1.5rem; background-color: rgba(0, 0, 0, 0.1); border-color: var(--color-dark-6); color: var(--color-dark-2); } -.prismrpg .gift-content input[name="name"] { +.prismrpg .racial-ability-content input[name="name"] { height: 2.5rem; margin-right: 4px; font-family: var(--font-secondary); @@ -1375,78 +1375,78 @@ i.prismrpg { font-weight: bold; border: none; } -.prismrpg .gift-content fieldset { +.prismrpg .racial-ability-content fieldset { margin-bottom: 4px; border-radius: 4px; } -.prismrpg .gift-content .form-fields input, -.prismrpg .gift-content .form-fields select { +.prismrpg .racial-ability-content .form-fields input, +.prismrpg .racial-ability-content .form-fields select { text-align: center; font-size: calc(var(--font-size-standard) * 1); } -.prismrpg .gift-content .form-fields select { +.prismrpg .racial-ability-content .form-fields select { font-family: var(--font-secondary); font-size: calc(var(--font-size-standard) * 1); } -.prismrpg .gift-content legend { +.prismrpg .racial-ability-content legend { font-family: var(--font-secondary); font-size: calc(var(--font-size-standard) * 1.2); font-weight: bold; letter-spacing: 1px; } -.prismrpg .gift-content .form-fields { +.prismrpg .racial-ability-content .form-fields { padding-top: 4px; } -.prismrpg .gift-content .form-group { +.prismrpg .racial-ability-content .form-group { display: flex; flex: 1; flex-direction: row; } -.prismrpg .gift-content .form-group label { +.prismrpg .racial-ability-content .form-group label { align-content: center; min-width: 10rem; max-width: 10rem; } -.prismrpg .gift-content .form-group select, -.prismrpg .gift-content .form-group input { +.prismrpg .racial-ability-content .form-group select, +.prismrpg .racial-ability-content .form-group input { text-align: left; min-width: 12rem; max-width: 12rem; } -.prismrpg .gift-content .form-group input[type="checkbox"] { +.prismrpg .racial-ability-content .form-group input[type="checkbox"] { min-width: 1.2rem; max-width: 1.2rem; margin-right: 0.5rem; } -.prismrpg .gift-content label { +.prismrpg .racial-ability-content label { font-family: var(--font-secondary); font-size: calc(var(--font-size-standard) * 1); flex: 50%; } -.prismrpg .gift-content .align-top { +.prismrpg .racial-ability-content .align-top { align-self: flex-start; padding: 0.1rem; margin-right: 0.2rem; } -.prismrpg .gift-content .shift-right { +.prismrpg .racial-ability-content .shift-right { margin-left: 2rem; } -.prismrpg .gift-content .header { +.prismrpg .racial-ability-content .header { display: flex; } -.prismrpg .gift-content .header img { +.prismrpg .racial-ability-content .header img { width: 50px; height: 50px; } -.prismrpg .gift-content input[type="checkbox"] { +.prismrpg .racial-ability-content input[type="checkbox"] { font-size: var(--font-size-14); width: 20px; padding-top: 0; } -.prismrpg .gift-content input[type="checkbox"]:checked { +.prismrpg .racial-ability-content input[type="checkbox"]:checked { background-color: rgba(0, 0, 0, 0.1); } -.prismrpg .gift-content input[type="checkbox"]:checked::after { +.prismrpg .racial-ability-content input[type="checkbox"]:checked::after { color: rgba(0, 0, 0, 0.1); } .prismrpg .weapon-content { @@ -2209,6 +2209,210 @@ i.prismrpg { .prismrpg .miracle-content label { flex: 10%; } +.prismrpg .race-content { + font-family: var(--font-primary); + font-size: calc(var(--font-size-standard) * 1); + color: var(--color-dark-1); + background-image: var(--background-image-base); + background-repeat: no-repeat; + background-size: 100% 100%; + overflow: auto; +} +.prismrpg .race-content nav.tabs [data-tab] { + color: #636060; +} +.prismrpg .race-content nav.tabs [data-tab].active { + color: #252424; +} +.prismrpg .race-content input:disabled, +.prismrpg .race-content select:disabled { + background-color: rgba(0, 0, 0, 0.2); + border-color: transparent; + color: var(--color-dark-3); +} +.prismrpg .race-content input, +.prismrpg .race-content select { + height: 1.5rem; + background-color: rgba(0, 0, 0, 0.1); + border-color: var(--color-dark-6); + color: var(--color-dark-2); +} +.prismrpg .race-content input[name="name"] { + height: 2.5rem; + margin-right: 4px; + font-family: var(--font-secondary); + font-size: calc(var(--font-size-standard) * 1.2); + font-weight: bold; + border: none; +} +.prismrpg .race-content fieldset { + margin-bottom: 4px; + border-radius: 4px; +} +.prismrpg .race-content .form-fields input, +.prismrpg .race-content .form-fields select { + text-align: center; + font-size: calc(var(--font-size-standard) * 1); +} +.prismrpg .race-content .form-fields select { + font-family: var(--font-secondary); + font-size: calc(var(--font-size-standard) * 1); +} +.prismrpg .race-content legend { + font-family: var(--font-secondary); + font-size: calc(var(--font-size-standard) * 1.2); + font-weight: bold; + letter-spacing: 1px; +} +.prismrpg .race-content .form-fields { + padding-top: 4px; +} +.prismrpg .race-content .form-group { + display: flex; + flex: 1; + flex-direction: row; +} +.prismrpg .race-content .form-group label { + align-content: center; + min-width: 10rem; + max-width: 10rem; +} +.prismrpg .race-content .form-group select, +.prismrpg .race-content .form-group input { + text-align: left; + min-width: 12rem; + max-width: 12rem; +} +.prismrpg .race-content .form-group input[type="checkbox"] { + min-width: 1.2rem; + max-width: 1.2rem; + margin-right: 0.5rem; +} +.prismrpg .race-content label { + font-family: var(--font-secondary); + font-size: calc(var(--font-size-standard) * 1); + flex: 50%; +} +.prismrpg .race-content .align-top { + align-self: flex-start; + padding: 0.1rem; + margin-right: 0.2rem; +} +.prismrpg .race-content .shift-right { + margin-left: 2rem; +} +.prismrpg .race-content .header { + display: flex; +} +.prismrpg .race-content .header img { + width: 50px; + height: 50px; +} +.prismrpg .race-content label { + flex: 10%; +} +.prismrpg .class-content { + font-family: var(--font-primary); + font-size: calc(var(--font-size-standard) * 1); + color: var(--color-dark-1); + background-image: var(--background-image-base); + background-repeat: no-repeat; + background-size: 100% 100%; + overflow: auto; +} +.prismrpg .class-content nav.tabs [data-tab] { + color: #636060; +} +.prismrpg .class-content nav.tabs [data-tab].active { + color: #252424; +} +.prismrpg .class-content input:disabled, +.prismrpg .class-content select:disabled { + background-color: rgba(0, 0, 0, 0.2); + border-color: transparent; + color: var(--color-dark-3); +} +.prismrpg .class-content input, +.prismrpg .class-content select { + height: 1.5rem; + background-color: rgba(0, 0, 0, 0.1); + border-color: var(--color-dark-6); + color: var(--color-dark-2); +} +.prismrpg .class-content input[name="name"] { + height: 2.5rem; + margin-right: 4px; + font-family: var(--font-secondary); + font-size: calc(var(--font-size-standard) * 1.2); + font-weight: bold; + border: none; +} +.prismrpg .class-content fieldset { + margin-bottom: 4px; + border-radius: 4px; +} +.prismrpg .class-content .form-fields input, +.prismrpg .class-content .form-fields select { + text-align: center; + font-size: calc(var(--font-size-standard) * 1); +} +.prismrpg .class-content .form-fields select { + font-family: var(--font-secondary); + font-size: calc(var(--font-size-standard) * 1); +} +.prismrpg .class-content legend { + font-family: var(--font-secondary); + font-size: calc(var(--font-size-standard) * 1.2); + font-weight: bold; + letter-spacing: 1px; +} +.prismrpg .class-content .form-fields { + padding-top: 4px; +} +.prismrpg .class-content .form-group { + display: flex; + flex: 1; + flex-direction: row; +} +.prismrpg .class-content .form-group label { + align-content: center; + min-width: 10rem; + max-width: 10rem; +} +.prismrpg .class-content .form-group select, +.prismrpg .class-content .form-group input { + text-align: left; + min-width: 12rem; + max-width: 12rem; +} +.prismrpg .class-content .form-group input[type="checkbox"] { + min-width: 1.2rem; + max-width: 1.2rem; + margin-right: 0.5rem; +} +.prismrpg .class-content label { + font-family: var(--font-secondary); + font-size: calc(var(--font-size-standard) * 1); + flex: 50%; +} +.prismrpg .class-content .align-top { + align-self: flex-start; + padding: 0.1rem; + margin-right: 0.2rem; +} +.prismrpg .class-content .shift-right { + margin-left: 2rem; +} +.prismrpg .class-content .header { + display: flex; +} +.prismrpg .class-content .header img { + width: 50px; + height: 50px; +} +.prismrpg .class-content label { + flex: 10%; +} .application.dialog.prismrpg { color: var(--color-dark-1); } diff --git a/lang/en.json b/lang/en.json index e77ebfd..d67667a 100644 --- a/lang/en.json +++ b/lang/en.json @@ -285,11 +285,8 @@ } } }, - "Gift": { + "RacialAbility": { "FIELDS": { - "cost": { - "label": "Cost" - }, "description": { "label": "Description" } @@ -321,6 +318,7 @@ "grantedDefenseDice": "Granted defense", "damageResistance": "Damage resistance", "damageResistanceShort": "DR", + "damageReduction": "Damage Reduction", "stealth": "Stealth", "progressionDice": "Progression/Lethargy dice", "rollProgressionCount": "Roll progression count", @@ -377,7 +375,7 @@ "dex": "DEX", "equipment": "Equipment", "experience": "Experience", - "gifts": "Gifts", + "racialAbilities": "Racial Abilities", "grit": "Grit", "gritEarned": "Grit earned", "int": "INT", @@ -496,6 +494,9 @@ "range": "Range", "reloadAPC": "Reload APC", "bonuses": "Bonuses", + "attackBonus": "Attack Bonus", + "damageBonus": "Damage Bonus", + "hands": "Hands Required", "groupPassive": "Weapon Group Passive", "groupPassiveName": "Group Passive Name", "weaponPassive": "Weapon Passive", @@ -531,11 +532,51 @@ "areaAffected": "Area Affected", "savingThrow": "Saving Throw", "keywords": "Keywords", + "targets": "Targets", + "resolve": "Resolve", "miracleType": "Miracle Type", "faithCost": "Faith Cost", "divineFavor": "Divine Favor", "miracleAugment": "Miracle Augment", - "prayerTime": "Prayer Time" + "prayerTime": "Prayer Time", + "basicInformation": "Basic Information", + "racialPassive": "Racial Passive", + "racialPassiveName": "Racial Passive Name", + "subrace": "Sub-race", + "subraceName": "Sub-race Name", + "subraceAbility": "Sub-race Ability", + "subraceAbilityName": "Sub-race Ability Name", + "senses": "Senses", + "size": "Size", + "sizeSmall": "Small", + "sizeMedium": "Medium", + "sizeLarge": "Large", + "ageCategory": "Age Category", + "ageShort": "Short", + "ageMedium": "Medium", + "ageLong": "Long", + "language": "Language", + "classInformation": "Class Information", + "archetype": "Archetype", + "archetypeFaith": "Faith", + "archetypeMana": "Mana", + "archetypeWanderer": "Wanderer", + "archetypeWarrior": "Warrior", + "classType": "Class Type", + "classTypeCore": "Core Class", + "classTypeContinental": "Continental Class", + "continent": "Continent", + "classLevel": "Class Level", + "proficiencies": "Proficiencies", + "weaponProficiencies": "Weapon Proficiencies", + "armorProficiencies": "Armor Proficiencies", + "spellcasting": "Spellcasting", + "hasSpellcasting": "Has Spellcasting", + "spellcastingType": "Spellcasting Type", + "spellcastingTypeMana": "Mana", + "spellcastingTypeFaith": "Faith", + "attributeBonuses": "Attribute Bonuses", + "classFeatures": "Class Features" }, "CoreSkill": { "acrobatics": "Acrobatics", @@ -629,7 +670,8 @@ "attributeBonus": "Choose which attribute receives the +2 bonus", "advancedChecks": "Only Core Skills allow advanced checks", "spellAscension": "Spell Ascension increases mana cost and APC by +1 per level", - "groupPassive": "Passive ability from weapon group (auto-filled)" + "groupPassive": "Passive ability from weapon group (auto-filled)", + "classLevel": "Current progression level in this class (1-10)" }, "Tooltip": { "coreSkill": "Your character's chosen Core Skill provides +5 to basic checks and access to advanced checks", @@ -637,7 +679,8 @@ "advancedChecks": "Advanced checks are only available for your Core Skill", "addEquipment": "New equipment", "addSpell": "New spells", - "skill": "Skills list" + "skill": "Skills list", + "racialAbilities": "Racial Abilities from your character's race and sub-race" }, "Message": { "selectCoreSkill": "You must select a Core Skill for your character. Each character chooses one Core Skill at creation." @@ -1041,6 +1084,101 @@ } } } + }, + "Race": { + "Size": { + "small": "Small", + "medium": "Medium", + "large": "Large" + }, + "AgeCategory": { + "short": "Short", + "medium": "Medium", + "long": "Long" + }, + "FIELDS": { + "senses": { + "label": "Senses" + }, + "size": { + "label": "Size" + }, + "ageCategory": { + "label": "Age Category" + }, + "language": { + "label": "Language" + }, + "racialPassive": { + "label": "Racial Passive Name" + }, + "racialPassiveDescription": { + "label": "Racial Passive Description" + }, + "subrace": { + "label": "Sub-race" + }, + "subraceAbility": { + "label": "Sub-race Ability Name" + }, + "subraceAbilityDescription": { + "label": "Sub-race Ability Description" + }, + "notes": { + "label": "Notes" + } + } + }, + "Class": { + "Archetype": { + "faith": "Faith", + "mana": "Mana", + "wanderer": "Wanderer", + "warrior": "Warrior" + }, + "ClassType": { + "core": "Core Class", + "continental": "Continental Class" + }, + "SpellcastingType": { + "mana": "Mana", + "faith": "Faith" + }, + "FIELDS": { + "archetype": { + "label": "Archetype" + }, + "classType": { + "label": "Class Type" + }, + "continent": { + "label": "Continent" + }, + "level": { + "label": "Class Level" + }, + "weaponProficiencies": { + "label": "Weapon Proficiencies" + }, + "armorProficiencies": { + "label": "Armor Proficiencies" + }, + "spellcasting": { + "label": "Has Spellcasting" + }, + "spellcastingType": { + "label": "Spellcasting Type" + }, + "attributeBonuses": { + "label": "Attribute Bonuses" + }, + "notes": { + "label": "Notes" + }, + "features": { + "label": "Class Features" + } + } } }, "TYPES": { @@ -1051,14 +1189,16 @@ "Item": { "armor": "Armor", "equipment": "Equipment", - "gift": "Gift", + "racial-ability": "Racial Ability", "miracle": "Miracle", "save": "Save", "shield": "Shield", "skill": "Skill", "spell": "Spell", "vulnerability": "Vulnerability", - "weapon": "Weapon" + "weapon": "Weapon", + "race": "Race", + "class": "Class" } } } \ No newline at end of file diff --git a/module/applications/_module.mjs b/module/applications/_module.mjs index a480499..dd6b4f0 100644 --- a/module/applications/_module.mjs +++ b/module/applications/_module.mjs @@ -2,11 +2,12 @@ export { default as PrismRPGCharacterSheet } from "./sheets/character-sheet.mjs" export { default as PrismRPGMonsterSheet } from "./sheets/monster-sheet.mjs" export { default as PrismRPGWeaponSheet } from "./sheets/weapon-sheet.mjs" export { default as PrismRPGSkillSheet } from "./sheets/skill-sheet.mjs" -export { default as PrismRPGGiftSheet } from "./sheets/gift-sheet.mjs" +export { default as PrismRPGRacialAbilitySheet } from "./sheets/racial-ability-sheet.mjs" export { default as PrismRPGVulnerabilitySheet } from "./sheets/vulnerability-sheet.mjs" export { default as PrismRPGArmorSheet } from "./sheets/armor-sheet.mjs" export { default as PrismRPGSpellSheet } from "./sheets/spell-sheet.mjs" export { default as PrismRPGEquipmentSheet } from "./sheets/equipment-sheet.mjs" export { default as PrismRPGShieldSheet } from "./sheets/shield-sheet.mjs" export { default as PrismRPGMiracleSheet } from "./sheets/miracle-sheet.mjs" - +export { default as PrismRPGRaceSheet } from "./sheets/race-sheet.mjs" +export { default as PrismRPGClassSheet } from "./sheets/class-sheet.mjs" diff --git a/module/applications/sheets/armor-sheet.mjs b/module/applications/sheets/armor-sheet.mjs index 0dc7332..edca4d2 100644 --- a/module/applications/sheets/armor-sheet.mjs +++ b/module/applications/sheets/armor-sheet.mjs @@ -24,6 +24,8 @@ export default class PrismRPGArmorSheet extends PrismRPGItemSheet { async _prepareContext() { const context = await super._prepareContext() context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true }) + context.enrichedPassiveDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.passiveDescription, { async: true }) + context.enrichedAugmentDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.augmentDescription, { async: true }) return context } diff --git a/module/applications/sheets/character-sheet.mjs b/module/applications/sheets/character-sheet.mjs index 89294e9..bee8ef3 100644 --- a/module/applications/sheets/character-sheet.mjs +++ b/module/applications/sheets/character-sheet.mjs @@ -45,9 +45,11 @@ export default class PrismRPGCharacterSheet extends PrismRPGActorSheet { spells: { template: "systems/fvtt-prism-rpg/templates/character-spells.hbs", }, + /* Miracles disabled - Legacy from Lethal Fantasy miracles: { template: "systems/fvtt-prism-rpg/templates/character-miracles.hbs", }, + */ biography: { template: "systems/fvtt-prism-rpg/templates/character-biography.hbs", }, @@ -72,9 +74,11 @@ export default class PrismRPGCharacterSheet extends PrismRPGActorSheet { if (this.actor.system.biodata.magicUser) { tabs.spells = { id: "spells", group: "sheet", icon: "fa-sharp-duotone fa-solid fa-wand-magic-sparkles", label: "PRISMRPG.Label.spells" } } + /* Miracles disabled - Legacy from Lethal Fantasy if (this.actor.system.biodata.clericUser) { tabs.miracles = { id: "miracles", group: "sheet", icon: "fa-sharp-duotone fa-solid fa-hands-praying", label: "PRISMRPG.Label.miracles" } } + */ for (const v of Object.values(tabs)) { v.active = this.tabGroups[v.group] === v.id v.cssClass = v.active ? "active" : "" @@ -99,7 +103,7 @@ export default class PrismRPGCharacterSheet extends PrismRPGActorSheet { case "skills": context.tab = context.tabs.skills context.skills = doc.itemTypes.skill - context.gifts = doc.itemTypes.gift + context.racialAbilities = doc.itemTypes["racial-ability"] context.vulnerabilities = doc.itemTypes.vulnerability break case "spells": @@ -107,11 +111,13 @@ export default class PrismRPGCharacterSheet extends PrismRPGActorSheet { context.spells = doc.itemTypes.spell context.hasSpells = context.spells.length > 0 break + /* Miracles disabled - Legacy from Lethal Fantasy case "miracles": context.tab = context.tabs.miracles context.miracles = doc.itemTypes.miracle context.hasMiracles = context.miracles.length > 0 break + */ case "combat": context.tab = context.tabs.combat context.weapons = doc.itemTypes.weapon diff --git a/module/applications/sheets/class-sheet.mjs b/module/applications/sheets/class-sheet.mjs new file mode 100644 index 0000000..8dd8c66 --- /dev/null +++ b/module/applications/sheets/class-sheet.mjs @@ -0,0 +1,39 @@ +import PrismRPGItemSheet from "./base-item-sheet.mjs" + +export default class PrismRPGClassSheet extends PrismRPGItemSheet { + /** @override */ + static DEFAULT_OPTIONS = { + classes: ["class"], + position: { + width: 700, + height: 800, + }, + window: { + contentClasses: ["class-content"], + }, + } + + /** @override */ + static PARTS = { + main: { + template: "systems/fvtt-prism-rpg/templates/class.hbs", + }, + } + + /** @override */ + async _prepareContext() { + const context = await super._prepareContext() + context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true }) + context.enrichedAttributeBonuses = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.attributeBonuses, { async: true }) + context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.notes, { async: true }) + + // Enrich all feature levels + context.enrichedFeatures = {} + for (let i = 1; i <= 10; i++) { + const key = `level${i}` + context.enrichedFeatures[key] = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.features[key], { async: true }) + } + + return context + } +} diff --git a/module/applications/sheets/race-sheet.mjs b/module/applications/sheets/race-sheet.mjs new file mode 100644 index 0000000..30e21b9 --- /dev/null +++ b/module/applications/sheets/race-sheet.mjs @@ -0,0 +1,31 @@ +import PrismRPGItemSheet from "./base-item-sheet.mjs" + +export default class PrismRPGRaceSheet extends PrismRPGItemSheet { + /** @override */ + static DEFAULT_OPTIONS = { + classes: ["race"], + position: { + width: 650, + }, + window: { + contentClasses: ["race-content"], + }, + } + + /** @override */ + static PARTS = { + main: { + template: "systems/fvtt-prism-rpg/templates/race.hbs", + }, + } + + /** @override */ + async _prepareContext() { + const context = await super._prepareContext() + context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true }) + context.enrichedRacialPassiveDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.racialPassiveDescription, { async: true }) + context.enrichedSubraceAbilityDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.subraceAbilityDescription, { async: true }) + context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.notes, { async: true }) + return context + } +} diff --git a/module/applications/sheets/gift-sheet.mjs b/module/applications/sheets/racial-ability-sheet.mjs similarity index 50% rename from module/applications/sheets/gift-sheet.mjs rename to module/applications/sheets/racial-ability-sheet.mjs index 9bfde9b..0040f92 100644 --- a/module/applications/sheets/gift-sheet.mjs +++ b/module/applications/sheets/racial-ability-sheet.mjs @@ -1,21 +1,21 @@ import PrismRPGItemSheet from "./base-item-sheet.mjs" -export default class PrismRPGGiftSheet extends PrismRPGItemSheet { +export default class PrismRPGRacialAbilitySheet extends PrismRPGItemSheet { /** @override */ static DEFAULT_OPTIONS = { - classes: ["gift"], + classes: ["racial-ability"], position: { width: 600, }, window: { - contentClasses: ["gift-content"], + contentClasses: ["racial-ability-content"], }, } /** @override */ static PARTS = { main: { - template: "systems/fvtt-prism-rpg/templates/gift.hbs", + template: "systems/fvtt-prism-rpg/templates/racial-ability.hbs", }, } diff --git a/module/applications/sheets/shield-sheet.mjs b/module/applications/sheets/shield-sheet.mjs index 49102f9..21ffe94 100644 --- a/module/applications/sheets/shield-sheet.mjs +++ b/module/applications/sheets/shield-sheet.mjs @@ -23,6 +23,7 @@ export default class PrismRPGShieldSheet extends PrismRPGItemSheet { async _prepareContext() { const context = await super._prepareContext() context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true }) + context.enrichedBlockAugmentDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.blockAugmentDescription, { async: true }) return context } } diff --git a/module/applications/sheets/skill-sheet.mjs b/module/applications/sheets/skill-sheet.mjs index 858d1af..b882f0b 100644 --- a/module/applications/sheets/skill-sheet.mjs +++ b/module/applications/sheets/skill-sheet.mjs @@ -1,4 +1,5 @@ import PrismRPGItemSheet from "./base-item-sheet.mjs" +import { SYSTEM } from "../../config/system.mjs" export default class PrismRPGSkillSheet extends PrismRPGItemSheet { /** @override */ @@ -22,7 +23,9 @@ export default class PrismRPGSkillSheet extends PrismRPGItemSheet { /** @override */ async _prepareContext() { const context = await super._prepareContext() + context.config = SYSTEM context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true }) + context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.notes, { async: true }) return context } } diff --git a/module/applications/sheets/spell-sheet.mjs b/module/applications/sheets/spell-sheet.mjs index 9b140b2..b3acd6b 100644 --- a/module/applications/sheets/spell-sheet.mjs +++ b/module/applications/sheets/spell-sheet.mjs @@ -23,6 +23,8 @@ export default class PrismRPGSpellSheet extends PrismRPGItemSheet { async _prepareContext() { const context = await super._prepareContext() context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true }) + context.enrichedColorEffect = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.colorEffect, { async: true }) + context.enrichedAscensionEffect = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.ascensionEffect, { async: true }) return context } diff --git a/module/applications/sheets/weapon-sheet.mjs b/module/applications/sheets/weapon-sheet.mjs index cba2402..7391c74 100644 --- a/module/applications/sheets/weapon-sheet.mjs +++ b/module/applications/sheets/weapon-sheet.mjs @@ -23,6 +23,8 @@ export default class PrismRPGWeaponSheet extends PrismRPGItemSheet { async _prepareContext() { const context = await super._prepareContext() context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true }) + context.enrichedPassiveDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.passiveDescription, { async: true }) + context.enrichedManeuverDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.maneuverDescription, { async: true }) return context } diff --git a/module/config/class.mjs b/module/config/class.mjs new file mode 100644 index 0000000..f6c8ec8 --- /dev/null +++ b/module/config/class.mjs @@ -0,0 +1,20 @@ +/** + * Class configuration for Prism RPG + */ + +export const ARCHETYPE = { + faith: "PRISMRPG.Class.Archetype.faith", + mana: "PRISMRPG.Class.Archetype.mana", + wanderer: "PRISMRPG.Class.Archetype.wanderer", + warrior: "PRISMRPG.Class.Archetype.warrior" +} + +export const CLASS_TYPE = { + core: "PRISMRPG.Class.ClassType.core", + continental: "PRISMRPG.Class.ClassType.continental" +} + +export const SPELLCASTING_TYPE = { + mana: "PRISMRPG.Class.SpellcastingType.mana", + faith: "PRISMRPG.Class.SpellcastingType.faith" +} diff --git a/module/config/race.mjs b/module/config/race.mjs new file mode 100644 index 0000000..2909eac --- /dev/null +++ b/module/config/race.mjs @@ -0,0 +1,15 @@ +/** + * Race configuration for Prism RPG + */ + +export const SIZE = { + small: "PRISMRPG.Race.Size.small", + medium: "PRISMRPG.Race.Size.medium", + large: "PRISMRPG.Race.Size.large" +} + +export const AGE_CATEGORY = { + short: "PRISMRPG.Race.AgeCategory.short", + medium: "PRISMRPG.Race.AgeCategory.medium", + long: "PRISMRPG.Race.AgeCategory.long" +} diff --git a/module/config/shield.mjs b/module/config/shield.mjs index 8b1aae8..f72a4b4 100644 --- a/module/config/shield.mjs +++ b/module/config/shield.mjs @@ -38,6 +38,15 @@ export const TYPE = Object.freeze({ } }); +/** + * Simplified Shield Types object for form choices (label-only format) + */ +export const TYPE_CHOICES = Object.freeze( + Object.fromEntries( + Object.entries(TYPE).map(([key, value]) => [key, value.label]) + ) +); + /** * Block augment descriptions for reference * These are activated when using the Block action with the shield diff --git a/module/config/skill.mjs b/module/config/skill.mjs index 869bf41..ff9bdae 100644 --- a/module/config/skill.mjs +++ b/module/config/skill.mjs @@ -99,6 +99,30 @@ export const CORE_SKILLS = Object.freeze({ } }); +/** + * Simplified Core Skills object for form choices (label-only format) + */ +export const CORE_SKILLS_CHOICES = { + acrobatics: "PRISMRPG.Skill.CoreSkill.acrobatics", + animalHandling: "PRISMRPG.Skill.CoreSkill.animalHandling", + arcana: "PRISMRPG.Skill.CoreSkill.arcana", + athletics: "PRISMRPG.Skill.CoreSkill.athletics", + deception: "PRISMRPG.Skill.CoreSkill.deception", + history: "PRISMRPG.Skill.CoreSkill.history", + insight: "PRISMRPG.Skill.CoreSkill.insight", + intimidate: "PRISMRPG.Skill.CoreSkill.intimidate", + investigation: "PRISMRPG.Skill.CoreSkill.investigation", + medicine: "PRISMRPG.Skill.CoreSkill.medicine", + nature: "PRISMRPG.Skill.CoreSkill.nature", + perception: "PRISMRPG.Skill.CoreSkill.perception", + performance: "PRISMRPG.Skill.CoreSkill.performance", + persuasion: "PRISMRPG.Skill.CoreSkill.persuasion", + religion: "PRISMRPG.Skill.CoreSkill.religion", + sleightOfHand: "PRISMRPG.Skill.CoreSkill.sleightOfHand", + stealth: "PRISMRPG.Skill.CoreSkill.stealth", + survival: "PRISMRPG.Skill.CoreSkill.survival" +}; + /** * Core Skill bonus values */ diff --git a/module/config/spell.mjs b/module/config/spell.mjs index d15f751..b55cd3e 100644 --- a/module/config/spell.mjs +++ b/module/config/spell.mjs @@ -40,6 +40,15 @@ export const COLORS = Object.freeze({ } }); +/** + * Simplified Spell Colors object for form choices (label-only format) + */ +export const COLORS_CHOICES = Object.freeze( + Object.fromEntries( + Object.entries(COLORS).map(([key, value]) => [key, value.label]) + ) +); + /** * Spell ranges (legacy - to be replaced with Prism system) */ diff --git a/module/config/system.mjs b/module/config/system.mjs index 6b17ae1..3bde296 100644 --- a/module/config/system.mjs +++ b/module/config/system.mjs @@ -7,6 +7,8 @@ import * as SKILL from "./skill.mjs" import * as EQUIPMENT from "./equipment.mjs" import * as CHARACTERISTICS from "./characteristic-tables.mjs" import * as MONSTER from "./monster.mjs" +import * as RACE from "./race.mjs" +import * as CLASS from "./class.mjs" export const SYSTEM_ID = "fvtt-prism-rpg" export const DEV_MODE = false @@ -220,15 +222,6 @@ export const MIRACLE_TYPES = { "ritualfaith": "Ritual of Faith" } -export const SPELL_CRITICAL = { - "none": "None", - "electric": "Electric", - "fire": "Fire", - "cold": "Cold", - "force": "Force", - "acid": "Acid" -} - export const CHOICE_MODIFIERS = { "-9": "-9", "-8": "-8", @@ -296,6 +289,7 @@ export const SYSTEM = { CHALLENGES: CHARACTER.CHALLENGES, SKILL_CATEGORY: SKILL.CATEGORY, CORE_SKILLS: SKILL.CORE_SKILLS, + CORE_SKILLS_CHOICES: SKILL.CORE_SKILLS_CHOICES, CORE_SKILL_BONUS: SKILL.CORE_SKILL_BONUS, ARMOR_TYPE: ARMOR.TYPE, ARMOR_BASE_AC: ARMOR.BASE_AC, @@ -303,16 +297,19 @@ export const SYSTEM = { ARMOR_WITHSTAND_APC: ARMOR.WITHSTAND_APC, ARMOR_SET_REQUIREMENTS: ARMOR.SET_REQUIREMENTS, SHIELD_TYPE: SHIELD.TYPE, + SHIELD_TYPE_CHOICES: SHIELD.TYPE_CHOICES, SHIELD_BLOCK_AUGMENTS: SHIELD.BLOCK_AUGMENTS, EQUIPMENT_CATEGORY: EQUIPMENT.CATEGORY, SPELL_RANGE: SPELL.RANGE, SPELL_COLORS: SPELL.COLORS, + SPELL_COLORS_CHOICES: SPELL.COLORS_CHOICES, WEAPON_TYPE: WEAPON.TYPE, + WEAPON_TYPE_CHOICES: WEAPON.TYPE_CHOICES, WEAPON_GROUP: WEAPON.WEAPON_GROUP, + WEAPON_GROUP_CHOICES: WEAPON.WEAPON_GROUP_CHOICES, WEAPON_DAMAGE_TYPE: WEAPON.DAMAGE_TYPE, WEAPON_CLASS: WEAPON.WEAPON_CLASS, COMBAT_PROGRESSION_DICE: DICE_VALUES, - SHIELD_DEFENSE_DICE: DEFENSE_DICE_VALUES, WEAPON_CATEGORIES: WEAPON.WEAPON_CATEGORIES, CHARACTERISTIC_ATTACK, CHARACTERISTIC_RANGED_ATTACK, @@ -333,8 +330,12 @@ export const SYSTEM = { FAVOR_CHOICES, ATTACKER_AIM_CHOICES, MORTAL_CHOICES, - SPELL_CRITICAL, MIRACLE_TYPES, SPELL_LETHARGY_DICE, - GRANTED_DICE_CHOICES + GRANTED_DICE_CHOICES, + RACE_SIZE: RACE.SIZE, + RACE_AGE_CATEGORY: RACE.AGE_CATEGORY, + CLASS_ARCHETYPE: CLASS.ARCHETYPE, + CLASS_TYPE: CLASS.CLASS_TYPE, + CLASS_SPELLCASTING_TYPE: CLASS.SPELLCASTING_TYPE } diff --git a/module/config/weapon.mjs b/module/config/weapon.mjs index f1ce285..21e96a1 100644 --- a/module/config/weapon.mjs +++ b/module/config/weapon.mjs @@ -29,6 +29,15 @@ export const TYPE = Object.freeze({ } }); +/** + * Simplified Weapon Types object for form choices (label-only format) + */ +export const TYPE_CHOICES = Object.freeze( + Object.fromEntries( + Object.entries(TYPE).map(([key, value]) => [key, value.label]) + ) +); + /** * Weapon groups and their associated passives * Each weapon belongs to a group and possesses its passive while wielded @@ -36,48 +45,57 @@ export const TYPE = Object.freeze({ export const WEAPON_GROUP = Object.freeze({ longsword: { id: "longsword", - label: "PRISMRPG.Weapon.WeaponGroup.longsword", + label: "PRISMRPG.WeaponGroup.longsword", passive: "turningEdge", passiveLabel: "PRISMRPG.Weapon.Passive.turningEdge", passiveDescription: "PRISMRPG.Weapon.PassiveDescription.turningEdge" }, warhammer: { id: "warhammer", - label: "PRISMRPG.Weapon.WeaponGroup.warhammer", + label: "PRISMRPG.WeaponGroup.warhammer", passive: "puncturingBlows", passiveLabel: "PRISMRPG.Weapon.Passive.puncturingBlows", passiveDescription: "PRISMRPG.Weapon.PassiveDescription.puncturingBlows" }, battleaxe: { id: "battleaxe", - label: "PRISMRPG.Weapon.WeaponGroup.battleaxe", + label: "PRISMRPG.WeaponGroup.battleaxe", passive: "shieldEater", passiveLabel: "PRISMRPG.Weapon.Passive.shieldEater", passiveDescription: "PRISMRPG.Weapon.PassiveDescription.shieldEater" }, dagger: { id: "dagger", - label: "PRISMRPG.Weapon.WeaponGroup.dagger", + label: "PRISMRPG.WeaponGroup.dagger", passive: "balancingStance", passiveLabel: "PRISMRPG.Weapon.Passive.balancingStance", passiveDescription: "PRISMRPG.Weapon.PassiveDescription.balancingStance" }, crossbow: { id: "crossbow", - label: "PRISMRPG.Weapon.WeaponGroup.crossbow", + label: "PRISMRPG.WeaponGroup.crossbow", passive: "boltlock", passiveLabel: "PRISMRPG.Weapon.Passive.boltlock", passiveDescription: "PRISMRPG.Weapon.PassiveDescription.boltlock" }, longbow: { id: "longbow", - label: "PRISMRPG.Weapon.WeaponGroup.longbow", + label: "PRISMRPG.WeaponGroup.longbow", passive: "volleyFire", passiveLabel: "PRISMRPG.Weapon.Passive.volleyFire", passiveDescription: "PRISMRPG.Weapon.PassiveDescription.volleyFire" } }); +/** + * Simplified Weapon Groups object for form choices (label-only format) + */ +export const WEAPON_GROUP_CHOICES = Object.freeze( + Object.fromEntries( + Object.entries(WEAPON_GROUP).map(([key, value]) => [key, value.label]) + ) +); + /** * Damage types for weapons */ diff --git a/module/documents/item.mjs b/module/documents/item.mjs index 7137711..b296c2f 100644 --- a/module/documents/item.mjs +++ b/module/documents/item.mjs @@ -3,11 +3,11 @@ export const defaultItemImg = { armor: "systems/fvtt-prism-rpg/assets/icons/icon_armor.webp", equipment: "systems/fvtt-prism-rpg/assets/icons/icon_equipment.webp", skill: "systems/fvtt-prism-rpg/assets/icons/icon_skill.webp", - gift: "systems/fvtt-prism-rpg/assets/icons/icon_gift.webp", - vulnerability: "systems/fvtt-prism-rpg/assets/icons/icon_vulnerability.webp", + "racial-ability": "systems/fvtt-prism-rpg/assets/icons/icon_racial-ability.webp", shield: "systems/fvtt-prism-rpg/assets/icons/icon_shield.webp", spell: "systems/fvtt-prism-rpg/assets/icons/icon_spell.webp", - miracle: "systems/fvtt-prism-rpg/assets/icons/icon_miracle.webp" + race: "systems/fvtt-prism-rpg/assets/icons/icon_race.webp", + class: "systems/fvtt-prism-rpg/assets/icons/icon_class.webp" } export default class PrismRPGItem extends Item { diff --git a/module/documents/roll.mjs b/module/documents/roll.mjs index ded145d..6a75b29 100644 --- a/module/documents/roll.mjs +++ b/module/documents/roll.mjs @@ -247,11 +247,13 @@ export default class PrismRPGRoll extends Roll { } } else if (options.rollType === "shield-roll") { + // Legacy Lethal Fantasy - Shield Defense Roll (not used in PRISM RPG) + // In PRISM, shields use Block action with Shield Rating (SR) hasD30 = false - options.rollName = "Shield Defense" - dice = options.rollTarget.system.defense.toUpperCase() + options.rollName = "Shield Block" + dice = "1d20" // Placeholder - actual Block mechanic handled elsewhere baseFormula = dice - hasModifier = true + hasModifier = false hasChangeDice = false hasMaxValue = false hasExplode = false @@ -261,7 +263,8 @@ export default class PrismRPGRoll extends Roll { options.rollName = options.rollTarget.name hasModifier = true hasChangeDice = false - let damageBonus = (options.rollTarget.weapon.system.applyStrengthDamageBonus) ? options.rollTarget.combat.damageModifier : 0 + // In PRISM, all weapons apply STR damage bonus + let damageBonus = options.rollTarget.combat.damageModifier options.rollTarget.value = damageBonus + options.rollTarget.weaponSkillModifier + options.rollTarget.weapon.system.bonuses.damageBonus options.rollTarget.charModifier = damageBonus if (options.rollType.includes("small")) { diff --git a/module/models/_module.mjs b/module/models/_module.mjs index b875374..bc74875 100644 --- a/module/models/_module.mjs +++ b/module/models/_module.mjs @@ -5,7 +5,9 @@ export { default as PrismRPGSpell } from "./spell.mjs" export { default as PrismRPGSkill } from "./skill.mjs" export { default as PrismRPGArmor } from "./armor.mjs" export { default as PrismRPGShield } from "./shield.mjs" -export { default as PrismRPGGift } from "./gift.mjs" +export { default as PrismRPGRacialAbility } from "./racial-ability.mjs" export { default as PrismRPGVulnerability } from "./vulnerability.mjs" export { default as PrismRPGEquipment } from "./equipment.mjs" export { default as PrismRPGMiracle } from "./miracle.mjs" +export { default as PrismRPGRace } from "./race.mjs" +export { default as PrismRPGClass } from "./class.mjs" \ No newline at end of file diff --git a/module/models/armor.mjs b/module/models/armor.mjs index 656ef44..4407f92 100644 --- a/module/models/armor.mjs +++ b/module/models/armor.mjs @@ -19,12 +19,6 @@ export default class PrismRPGArmor extends foundry.abstract.TypeDataModel { schema.augment = new fields.StringField({ required: false, initial: "", label: "Armor Augment" }) schema.augmentDescription = new fields.HTMLField({ required: false, textSearch: true, label: "Augment Description" }) - // Legacy fields for compatibility - schema.defense = new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: -50 }) - schema.maximumMovement = new fields.StringField({ required: false, initial: "" }) - schema.hp = new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }) - schema.damageReduction = new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }) - schema.encLoad = new fields.NumberField({ required: true, initial: 0, min: 0 }) schema.equipped = new fields.BooleanField({ required: true, initial: false }) schema.isHelmet = new fields.BooleanField({ required: true, initial: false }) diff --git a/module/models/character.mjs b/module/models/character.mjs index 71b3e44..e426c5c 100644 --- a/module/models/character.mjs +++ b/module/models/character.mjs @@ -173,7 +173,7 @@ export default class PrismRPGCharacter extends foundry.abstract.TypeDataModel { skill: new fields.StringField({ required: true, initial: "", - choices: Object.keys(SYSTEM.CORE_SKILLS || {}), + choices: SYSTEM.CORE_SKILLS_CHOICES, label: "Selected Core Skill" }), attributeChoice: new fields.StringField({ diff --git a/module/models/class.mjs b/module/models/class.mjs new file mode 100644 index 0000000..9c60726 --- /dev/null +++ b/module/models/class.mjs @@ -0,0 +1,159 @@ +/** + * Class data model for Prism RPG + * + * Classes in Prism provide: + * - Archetype classification (Faith, Mana, Wanderer, Warrior) + * - Class features gained at different levels + * - Proficiencies and abilities + * - Characters can have up to 3 classes simultaneously + */ +import { SYSTEM } from "../config/system.mjs" + +export default class PrismRPGClass extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields + const schema = {} + + schema.description = new fields.HTMLField({ + required: true, + textSearch: true, + initial: "" + }) + + // Archetype (Faith, Mana, Wanderer, Warrior) + schema.archetype = new fields.StringField({ + required: true, + initial: "wanderer", + choices: SYSTEM.CLASS_ARCHETYPE, + label: "Archetype" + }) + + // Is this a Core Class or Continental Class? + schema.classType = new fields.StringField({ + required: true, + initial: "core", + choices: SYSTEM.CLASS_TYPE, + label: "Class Type" + }) + + // For Continental Classes, specify the continent + schema.continent = new fields.StringField({ + required: false, + initial: "", + label: "Continent" + }) + + // Current level in this class (for tracking progression) + schema.level = new fields.NumberField({ + required: true, + nullable: false, + integer: true, + initial: 1, + min: 1, + max: 10, + label: "Class Level" + }) + + // Class Features (structured data for features gained at each level) + schema.features = new fields.SchemaField({ + level1: new fields.HTMLField({ initial: "" }), + level2: new fields.HTMLField({ initial: "" }), + level3: new fields.HTMLField({ initial: "" }), + level4: new fields.HTMLField({ initial: "" }), + level5: new fields.HTMLField({ initial: "" }), + level6: new fields.HTMLField({ initial: "" }), + level7: new fields.HTMLField({ initial: "" }), + level8: new fields.HTMLField({ initial: "" }), + level9: new fields.HTMLField({ initial: "" }), + level10: new fields.HTMLField({ initial: "" }) + }) + + // Proficiencies granted by this class + schema.weaponProficiencies = new fields.StringField({ + required: true, + initial: "", + label: "Weapon Proficiencies" + }) + + schema.armorProficiencies = new fields.StringField({ + required: true, + initial: "", + label: "Armor Proficiencies" + }) + + // Special abilities + schema.spellcasting = new fields.BooleanField({ + required: true, + initial: false, + label: "Has Spellcasting" + }) + + schema.spellcastingType = new fields.StringField({ + required: false, + nullable: true, + initial: null, + blank: true, + choices: SYSTEM.CLASS_SPELLCASTING_TYPE, + label: "Spellcasting Type" + }) + + // Attribute bonuses + schema.attributeBonuses = new fields.HTMLField({ + required: true, + initial: "", + label: "Attribute Bonuses" + }) + + // Additional notes + schema.notes = new fields.HTMLField({ + required: true, + initial: "", + label: "Notes" + }) + + return schema + } + + /** @override */ + static LOCALIZATION_PREFIXES = ["PRISMRPG.Class"] + + /** + * Clean up data before validation + * @override + */ + static cleanData(source = {}, options = {}) { + // Convert empty string to null for spellcastingType + if (source.spellcastingType === "") { + source.spellcastingType = null + } + return super.cleanData(source, options) + } + + /** + * Get the localized archetype label + */ + get archetypeLabel() { + return game.i18n.localize(`PRISMRPG.Class.Archetype.${this.archetype}`) + } + + /** + * Get the current level's features + */ + get currentLevelFeatures() { + return this.features[`level${this.level}`] || "" + } + + /** + * Get all features up to current level + */ + get allFeaturesUpToLevel() { + const features = [] + for (let i = 1; i <= this.level; i++) { + const feature = this.features[`level${i}`] + if (feature) { + features.push({ level: i, description: feature }) + } + } + return features + } +} diff --git a/module/models/equipment.mjs b/module/models/equipment.mjs index 0c5918c..6f1d335 100644 --- a/module/models/equipment.mjs +++ b/module/models/equipment.mjs @@ -10,9 +10,6 @@ export default class PrismRPGEquipment extends foundry.abstract.TypeDataModel { schema.category = new fields.StringField({ required: true, initial: "tinbit", choices: SYSTEM.EQUIPMENT_CATEGORIES }) schema.encLoad = new fields.NumberField({ required: true, initial: 0, min: 0 }) - schema.hi = new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }) - schema.medium = new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }) - schema.lo = new fields.NumberField({ ...requiredInteger, 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 }) diff --git a/module/models/gift.mjs b/module/models/gift.mjs deleted file mode 100644 index 3ab730e..0000000 --- a/module/models/gift.mjs +++ /dev/null @@ -1,16 +0,0 @@ -export default class PrismRPGGift extends foundry.abstract.TypeDataModel { - static defineSchema() { - const fields = foundry.data.fields - const requiredInteger = { required: true, nullable: false, integer: true } - const schema = {} - - schema.description = new fields.HTMLField({ required: true, textSearch: true }) - schema.cost = new fields.NumberField({ required: true, initial: 0, min: 0 }) - - return schema - } - - /** @override */ - static LOCALIZATION_PREFIXES = ["PRISMRPG.Gift"] - -} diff --git a/module/models/miracle.mjs b/module/models/miracle.mjs index 7c5f862..1eacb46 100644 --- a/module/models/miracle.mjs +++ b/module/models/miracle.mjs @@ -98,17 +98,6 @@ export default class PrismRPGMiracle extends foundry.abstract.TypeDataModel { initial: "" }) - // Attack and power - schema.attackRoll = new fields.StringField({ - required: true, - initial: "" - }) - - schema.powerRoll = new fields.StringField({ - required: true, - initial: "" - }) - // Keywords schema.keywords = new fields.ArrayField( new fields.StringField() diff --git a/module/models/race.mjs b/module/models/race.mjs new file mode 100644 index 0000000..ec910d2 --- /dev/null +++ b/module/models/race.mjs @@ -0,0 +1,107 @@ +/** + * Race data model for Prism RPG + * + * Races provide: + * - Racial Passive: Always-on ability + * - Sub-race selection: Specific racial ability based on sub-race + * - Basic information: Senses, size, age, language + */ +import { SYSTEM } from "../config/system.mjs" + +export default class PrismRPGRace extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields + const schema = {} + + schema.description = new fields.HTMLField({ + required: true, + textSearch: true, + initial: "" + }) + + // Basic Information + schema.senses = new fields.StringField({ + required: true, + initial: "standard", + label: "Senses" + }) + + schema.size = new fields.StringField({ + required: true, + initial: "medium", + choices: SYSTEM.RACE_SIZE, + label: "Size" + }) + + schema.ageCategory = new fields.StringField({ + required: true, + initial: "short", + choices: SYSTEM.RACE_AGE_CATEGORY, + label: "Age Category" + }) + + schema.language = new fields.StringField({ + required: true, + initial: "", + label: "Language" + }) + + // Racial Passive + schema.racialPassive = new fields.StringField({ + required: true, + initial: "", + label: "Racial Passive Name" + }) + + schema.racialPassiveDescription = new fields.HTMLField({ + required: true, + initial: "", + label: "Racial Passive Description" + }) + + // Sub-race + schema.subrace = new fields.StringField({ + required: true, + initial: "", + label: "Sub-race" + }) + + schema.subraceAbility = new fields.StringField({ + required: true, + initial: "", + label: "Sub-race Ability Name" + }) + + schema.subraceAbilityDescription = new fields.HTMLField({ + required: true, + initial: "", + label: "Sub-race Ability Description" + }) + + // Additional notes + schema.notes = new fields.HTMLField({ + required: true, + initial: "", + label: "Notes" + }) + + return schema + } + + /** @override */ + static LOCALIZATION_PREFIXES = ["PRISMRPG.Race"] + + /** + * Get the localized size label + */ + get sizeLabel() { + return game.i18n.localize(`PRISMRPG.Race.Size.${this.size}`) + } + + /** + * Get the localized age category label + */ + get ageCategoryLabel() { + return game.i18n.localize(`PRISMRPG.Race.AgeCategory.${this.ageCategory}`) + } +} diff --git a/module/models/racial-ability.mjs b/module/models/racial-ability.mjs new file mode 100644 index 0000000..c272464 --- /dev/null +++ b/module/models/racial-ability.mjs @@ -0,0 +1,14 @@ +export default class PrismRPGRacialAbility extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields + const schema = {} + + schema.description = new fields.HTMLField({ required: true, textSearch: true }) + + return schema + } + + /** @override */ + static LOCALIZATION_PREFIXES = ["PRISMRPG.RacialAbility"] + +} diff --git a/module/models/shield.mjs b/module/models/shield.mjs index 3e2bef0..64105ae 100644 --- a/module/models/shield.mjs +++ b/module/models/shield.mjs @@ -12,7 +12,7 @@ export default class PrismRPGShield extends foundry.abstract.TypeDataModel { schema.shieldType = new fields.StringField({ required: true, initial: "buckler", - choices: Object.keys(SYSTEM.SHIELD_TYPE || {}) + choices: SYSTEM.SHIELD_TYPE_CHOICES }) // APC (Action Point Cost) for Block action @@ -58,47 +58,7 @@ export default class PrismRPGShield extends foundry.abstract.TypeDataModel { label: "Augment Description" }) - // Legacy properties (kept for backward compatibility) - schema.defense = new fields.StringField({ - required: true, - initial: "d4", - choices: SYSTEM.SHIELD_DEFENSE_DICE - }) - - schema.movementreduction = new fields.NumberField({ - ...requiredInteger, - required: true, - initial: 0, - min: 0 - }) - - schema.hascover = new fields.BooleanField({ - required: true, - initial: false - }) - - schema.standing = new fields.SchemaField({ - min: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }), - max: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }) - }) - - schema.crouching = new fields.SchemaField({ - min: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }), - max: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }) - }) - - schema.destruction = new fields.SchemaField({ - bashing: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }), - slashing: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }), - piercing: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }) - }) - - schema.autodestruction = new fields.SchemaField({ - bashing: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }), - slashing: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }), - piercing: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }) - }) - + // 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 }) diff --git a/module/models/skill.mjs b/module/models/skill.mjs index 3b426a8..42d1672 100644 --- a/module/models/skill.mjs +++ b/module/models/skill.mjs @@ -1,4 +1,4 @@ -import { SYSTEM } from "../config/system.mjs" +import { CORE_SKILLS_CHOICES, CORE_SKILL_BONUS, CORE_SKILLS } from "../config/skill.mjs" /** * Core Skill data model for Prism RPG @@ -25,7 +25,7 @@ export default class PrismRPGSkill extends foundry.abstract.TypeDataModel { schema.coreSkill = new fields.StringField({ required: true, initial: "acrobatics", - choices: Object.keys(SYSTEM.CORE_SKILLS || {}), + choices: CORE_SKILLS_CHOICES, label: "Core Skill" }) @@ -82,7 +82,7 @@ export default class PrismRPGSkill extends foundry.abstract.TypeDataModel { * Get the Core Skill definition from SYSTEM */ get coreSkillDefinition() { - return SYSTEM.CORE_SKILLS?.[this.coreSkill] || null + return CORE_SKILLS?.[this.coreSkill] || null } /** @@ -109,7 +109,7 @@ export default class PrismRPGSkill extends foundry.abstract.TypeDataModel { // If this is the character's Core Skill, apply bonuses if (this.isCoreSkill) { - this.modifier = SYSTEM.CORE_SKILL_BONUS?.basic || 5 + this.modifier = CORE_SKILL_BONUS?.basic || 5 this.canAdvancedCheck = true } else { this.modifier = 0 diff --git a/module/models/spell.mjs b/module/models/spell.mjs index 274a6d4..e866413 100644 --- a/module/models/spell.mjs +++ b/module/models/spell.mjs @@ -52,7 +52,7 @@ export default class PrismRPGSpell extends foundry.abstract.TypeDataModel { schema.color = new fields.StringField({ required: true, initial: "violet", - choices: Object.keys(SYSTEM.SPELL_COLORS || {}), + choices: SYSTEM.SPELL_COLORS_CHOICES, label: "Spell Color" }) @@ -82,24 +82,6 @@ export default class PrismRPGSpell extends foundry.abstract.TypeDataModel { initial: false }) - // Components - schema.components = new fields.SchemaField({ - verbal: new fields.BooleanField({ initial: false }), - somatic: new fields.BooleanField({ initial: false }), - catalyst: new fields.BooleanField({ initial: false }), - material: new fields.BooleanField({ initial: false }), - }) - - schema.materialComponent = new fields.StringField({ - required: true, - initial: "" - }) - - schema.catalyst = new fields.StringField({ - required: true, - initial: "" - }) - // Casting parameters schema.castingTime = new fields.StringField({ required: true, @@ -126,39 +108,25 @@ export default class PrismRPGSpell extends foundry.abstract.TypeDataModel { initial: "" }) - // Attack and damage - schema.attackRoll = new fields.StringField({ + // Keywords (text field with comma-separated values) + schema.keywords = new fields.StringField({ required: true, - initial: "" + initial: "", + label: "Keywords" }) - schema.powerRoll = new fields.StringField({ + // Prism RPG: Targets + schema.targets = new fields.StringField({ required: true, - initial: "" + initial: "Single enemy", + label: "Targets" }) - // Keywords - schema.keywords = new fields.ArrayField( - new fields.StringField() - ) - - // Legacy fields - schema.cost = new fields.NumberField({ - ...requiredInteger, + // Prism RPG: Resolve method (Attack, Saving Throw, None) + schema.resolve = new fields.StringField({ required: true, - initial: 0, - min: 0 - }) - - schema.extraAetherPoints = new fields.StringField({ - required: true, - initial: "" - }) - - schema.criticalType = new fields.StringField({ - required: true, - initial: "electric", - choices: SYSTEM.SPELL_CRITICAL + initial: "Attack", + label: "Resolve" }) return schema diff --git a/module/models/weapon.mjs b/module/models/weapon.mjs index d077670..5f2ea8c 100644 --- a/module/models/weapon.mjs +++ b/module/models/weapon.mjs @@ -12,13 +12,13 @@ export default class PrismRPGWeapon extends foundry.abstract.TypeDataModel { schema.weaponType = new fields.StringField({ required: true, initial: "light", - choices: Object.keys(SYSTEM.WEAPON_TYPE || {}) + choices: SYSTEM.WEAPON_TYPE_CHOICES }) schema.weaponGroup = new fields.StringField({ required: true, initial: "longsword", - choices: Object.keys(SYSTEM.WEAPON_GROUP || {}) + choices: SYSTEM.WEAPON_GROUP_CHOICES }) // APC (Action Point Cost) - determined by weapon type @@ -105,37 +105,7 @@ export default class PrismRPGWeapon extends foundry.abstract.TypeDataModel { min: 0 }) - // Legacy properties (kept for backward compatibility) - schema.hands = new fields.StringField({ - required: true, - initial: "1", - choices: { "1": "1", "2": "2" } - }) - - schema.isAgile = new fields.BooleanField({ - required: true, - initial: false - }) - - schema.applyStrengthDamageBonus = new fields.BooleanField({ - required: true, - initial: true - }) - - schema.defenseMax = new fields.NumberField({ - ...requiredInteger, - required: true, - initial: 0, - min: 0 - }) - - schema.defense = new fields.NumberField({ - ...requiredInteger, - required: true, - initial: 0, - min: 0 - }) - + // Bonuses (from magical enhancements, etc.) schema.bonuses = new fields.SchemaField({ attackBonus: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }), damageBonus: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }), diff --git a/module/utils.mjs b/module/utils.mjs index 5946a43..7a316e5 100644 --- a/module/utils.mjs +++ b/module/utils.mjs @@ -22,43 +22,43 @@ export default class PrismRPGUtils { static setHookListeners() { Hooks.on('renderTokenHUD', async (hud, html, token) => { - const lossHPButton = await foundry.applications.handlebars.renderTemplate('systems/fvtt-prism-rpg/templates/loss-hp-hud.hbs', {} ) + const lossHPButton = await foundry.applications.handlebars.renderTemplate('systems/fvtt-prism-rpg/templates/loss-hp-hud.hbs', {}) $(html).find('div.left').append(lossHPButton); - $(html).find('img.prism-hp-loss-hud').click((event) => { - event.preventDefault(); - let hpMenu = $(html).find('.hp-loss-wrap')[0] - if (hpMenu.classList.contains("hp-loss-hud-disabled")) { - $(html).find('.hp-loss-wrap')[0].classList.add('hp-loss-hud-active'); - $(html).find('.hp-loss-wrap')[0].classList.remove('hp-loss-hud-disabled'); - $(html).find('.hp-loss-wrap')[1].classList.add('hp-loss-hud-active'); - $(html).find('.hp-loss-wrap')[1].classList.remove('hp-loss-hud-disabled'); - $(html).find('.hp-loss-wrap')[2].classList.add('hp-loss-hud-active'); - $(html).find('.hp-loss-wrap')[2].classList.remove('hp-loss-hud-disabled'); - } else { - $(html).find('.hp-loss-wrap')[0].classList.remove('hp-loss-hud-active'); - $(html).find('.hp-loss-wrap')[0].classList.add('hp-loss-hud-disabled'); - $(html).find('.hp-loss-wrap')[1].classList.remove('hp-loss-hud-active'); - $(html).find('.hp-loss-wrap')[1].classList.add('hp-loss-hud-disabled'); - $(html).find('.hp-loss-wrap')[2].classList.remove('hp-loss-hud-active'); - $(html).find('.hp-loss-wrap')[2].classList.add('hp-loss-hud-disabled'); - } - }) - $(html).find('.loss-hp-hud-click').click((event) => { - event.preventDefault(); - let hpLoss = event.currentTarget.dataset.hpValue; - if (token) { - let tokenFull = canvas.tokens.placeables.find( t => t.id === token._id); - console.log(tokenFull, token) - let actor = tokenFull.actor; - actor.applyDamage(Number(hpLoss)); - $(html).find('.hp-loss-wrap')[0].classList.remove('hp-loss-hud-active'); - $(html).find('.hp-loss-wrap')[0].classList.add('hp-loss-hud-disabled'); - $(html).find('.hp-loss-wrap')[1].classList.remove('hp-loss-hud-active'); - $(html).find('.hp-loss-wrap')[1].classList.add('hp-loss-hud-disabled'); - $(html).find('.hp-loss-wrap')[2].classList.remove('hp-loss-hud-active'); - $(html).find('.hp-loss-wrap')[2].classList.add('hp-loss-hud-disabled'); - } - }) + $(html).find('img.prism-hp-loss-hud').click((event) => { + event.preventDefault(); + let hpMenu = $(html).find('.hp-loss-wrap')[0] + if (hpMenu.classList.contains("hp-loss-hud-disabled")) { + $(html).find('.hp-loss-wrap')[0].classList.add('hp-loss-hud-active'); + $(html).find('.hp-loss-wrap')[0].classList.remove('hp-loss-hud-disabled'); + $(html).find('.hp-loss-wrap')[1].classList.add('hp-loss-hud-active'); + $(html).find('.hp-loss-wrap')[1].classList.remove('hp-loss-hud-disabled'); + $(html).find('.hp-loss-wrap')[2].classList.add('hp-loss-hud-active'); + $(html).find('.hp-loss-wrap')[2].classList.remove('hp-loss-hud-disabled'); + } else { + $(html).find('.hp-loss-wrap')[0].classList.remove('hp-loss-hud-active'); + $(html).find('.hp-loss-wrap')[0].classList.add('hp-loss-hud-disabled'); + $(html).find('.hp-loss-wrap')[1].classList.remove('hp-loss-hud-active'); + $(html).find('.hp-loss-wrap')[1].classList.add('hp-loss-hud-disabled'); + $(html).find('.hp-loss-wrap')[2].classList.remove('hp-loss-hud-active'); + $(html).find('.hp-loss-wrap')[2].classList.add('hp-loss-hud-disabled'); + } + }) + $(html).find('.loss-hp-hud-click').click((event) => { + event.preventDefault(); + let hpLoss = event.currentTarget.dataset.hpValue; + if (token) { + let tokenFull = canvas.tokens.placeables.find(t => t.id === token._id); + console.log(tokenFull, token) + let actor = tokenFull.actor; + actor.applyDamage(Number(hpLoss)); + $(html).find('.hp-loss-wrap')[0].classList.remove('hp-loss-hud-active'); + $(html).find('.hp-loss-wrap')[0].classList.add('hp-loss-hud-disabled'); + $(html).find('.hp-loss-wrap')[1].classList.remove('hp-loss-hud-active'); + $(html).find('.hp-loss-wrap')[1].classList.add('hp-loss-hud-disabled'); + $(html).find('.hp-loss-wrap')[2].classList.remove('hp-loss-hud-active'); + $(html).find('.hp-loss-wrap')[2].classList.add('hp-loss-hud-disabled'); + } + }) }) } @@ -159,6 +159,11 @@ export default class PrismRPGUtils { Handlebars.registerHelper('not', function (cond) { return !cond; }) + Handlebars.registerHelper('inc', function (value) { + // Extract number from string like "level1" or just parse number + const num = typeof value === 'string' ? parseInt(value.replace(/\D/g, '')) : parseInt(value); + return isNaN(num) ? value : num + 1; + }) Handlebars.registerHelper('count', function (list) { return list.length; }) diff --git a/packs-system/lf-equipment/000450.log b/packs-system/lf-equipment/000470.log similarity index 100% rename from packs-system/lf-equipment/000450.log rename to packs-system/lf-equipment/000470.log diff --git a/packs-system/lf-equipment/CURRENT b/packs-system/lf-equipment/CURRENT index cbf3119..f11dd62 100644 --- a/packs-system/lf-equipment/CURRENT +++ b/packs-system/lf-equipment/CURRENT @@ -1 +1 @@ -MANIFEST-000448 +MANIFEST-000468 diff --git a/packs-system/lf-equipment/LOG b/packs-system/lf-equipment/LOG index fd3ca62..51c447c 100644 --- a/packs-system/lf-equipment/LOG +++ b/packs-system/lf-equipment/LOG @@ -1,8 +1,8 @@ -2025/10/17-20:04:40.410646 7f7b74bf86c0 Recovering log #446 -2025/10/17-20:04:40.459394 7f7b74bf86c0 Delete type=3 #444 -2025/10/17-20:04:40.459535 7f7b74bf86c0 Delete type=0 #446 -2025/10/17-20:06:06.949461 7f7b6f3ff6c0 Level-0 table #451: started -2025/10/17-20:06:06.949513 7f7b6f3ff6c0 Level-0 table #451: 0 bytes OK -2025/10/17-20:06:06.981230 7f7b6f3ff6c0 Delete type=0 #449 -2025/10/17-20:06:06.981548 7f7b6f3ff6c0 Manual compaction at level-0 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zw9RQocTdz3HRjZK' @ 0 : 0; will stop at (end) -2025/10/17-20:06:07.038248 7f7b6f3ff6c0 Manual compaction at level-1 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zw9RQocTdz3HRjZK' @ 0 : 0; will stop at (end) +2025/11/06-22:23:29.041811 7f14b9ffb6c0 Recovering log #466 +2025/11/06-22:23:29.055418 7f14b9ffb6c0 Delete type=3 #464 +2025/11/06-22:23:29.055494 7f14b9ffb6c0 Delete type=0 #466 +2025/11/06-23:30:20.549081 7f14b8ff96c0 Level-0 table #471: started +2025/11/06-23:30:20.549163 7f14b8ff96c0 Level-0 table #471: 0 bytes OK +2025/11/06-23:30:20.583937 7f14b8ff96c0 Delete type=0 #469 +2025/11/06-23:30:20.699841 7f14b8ff96c0 Manual compaction at level-0 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zw9RQocTdz3HRjZK' @ 0 : 0; will stop at (end) +2025/11/06-23:30:20.699883 7f14b8ff96c0 Manual compaction at level-1 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zw9RQocTdz3HRjZK' @ 0 : 0; will stop at (end) diff --git a/packs-system/lf-equipment/LOG.old b/packs-system/lf-equipment/LOG.old index cd995b6..ad2d88f 100644 --- a/packs-system/lf-equipment/LOG.old +++ b/packs-system/lf-equipment/LOG.old @@ -1,8 +1,8 @@ -2025/10/17-17:16:55.022615 7f7b74bf86c0 Recovering log #442 -2025/10/17-17:16:55.032145 7f7b74bf86c0 Delete type=3 #440 -2025/10/17-17:16:55.032213 7f7b74bf86c0 Delete type=0 #442 -2025/10/17-17:19:51.857936 7f7b6f3ff6c0 Level-0 table #447: started -2025/10/17-17:19:51.857966 7f7b6f3ff6c0 Level-0 table #447: 0 bytes OK -2025/10/17-17:19:51.864468 7f7b6f3ff6c0 Delete type=0 #445 -2025/10/17-17:19:51.873932 7f7b6f3ff6c0 Manual compaction at level-0 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zw9RQocTdz3HRjZK' @ 0 : 0; will stop at (end) -2025/10/17-17:19:51.885633 7f7b6f3ff6c0 Manual compaction at level-1 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zw9RQocTdz3HRjZK' @ 0 : 0; will stop at (end) +2025/11/06-22:02:31.372569 7f14baffd6c0 Recovering log #462 +2025/11/06-22:02:31.382670 7f14baffd6c0 Delete type=3 #460 +2025/11/06-22:02:31.382741 7f14baffd6c0 Delete type=0 #462 +2025/11/06-22:07:01.938023 7f14b8ff96c0 Level-0 table #467: started +2025/11/06-22:07:01.938057 7f14b8ff96c0 Level-0 table #467: 0 bytes OK +2025/11/06-22:07:01.975385 7f14b8ff96c0 Delete type=0 #465 +2025/11/06-22:07:02.061915 7f14b8ff96c0 Manual compaction at level-0 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zw9RQocTdz3HRjZK' @ 0 : 0; will stop at (end) +2025/11/06-22:07:02.061954 7f14b8ff96c0 Manual compaction at level-1 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zw9RQocTdz3HRjZK' @ 0 : 0; will stop at (end) diff --git a/packs-system/lf-equipment/MANIFEST-000448 b/packs-system/lf-equipment/MANIFEST-000468 similarity index 71% rename from packs-system/lf-equipment/MANIFEST-000448 rename to packs-system/lf-equipment/MANIFEST-000468 index 4ef2154..548d6f6 100644 Binary files a/packs-system/lf-equipment/MANIFEST-000448 and b/packs-system/lf-equipment/MANIFEST-000468 differ diff --git a/packs-system/lf-gifts/CURRENT b/packs-system/lf-gifts/CURRENT deleted file mode 100644 index cbf3119..0000000 --- a/packs-system/lf-gifts/CURRENT +++ /dev/null @@ -1 +0,0 @@ -MANIFEST-000448 diff --git a/packs-system/lf-gifts/LOG b/packs-system/lf-gifts/LOG deleted file mode 100644 index 256d55d..0000000 --- a/packs-system/lf-gifts/LOG +++ /dev/null @@ -1,8 +0,0 @@ -2025/10/17-20:04:40.466635 7f7b753f96c0 Recovering log #446 -2025/10/17-20:04:40.515547 7f7b753f96c0 Delete type=3 #444 -2025/10/17-20:04:40.515653 7f7b753f96c0 Delete type=0 #446 -2025/10/17-20:06:06.880963 7f7b6f3ff6c0 Level-0 table #451: started -2025/10/17-20:06:06.881016 7f7b6f3ff6c0 Level-0 table #451: 0 bytes OK -2025/10/17-20:06:06.917770 7f7b6f3ff6c0 Delete type=0 #449 -2025/10/17-20:06:06.981510 7f7b6f3ff6c0 Manual compaction at level-0 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!x5gLtqlW4sdDmHTd' @ 0 : 0; will stop at (end) -2025/10/17-20:06:07.038270 7f7b6f3ff6c0 Manual compaction at level-1 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!x5gLtqlW4sdDmHTd' @ 0 : 0; will stop at (end) diff --git a/packs-system/lf-gifts/LOG.old b/packs-system/lf-gifts/LOG.old deleted file mode 100644 index 5bdf310..0000000 --- a/packs-system/lf-gifts/LOG.old +++ /dev/null @@ -1,8 +0,0 @@ -2025/10/17-17:16:55.037014 7f7b753f96c0 Recovering log #442 -2025/10/17-17:16:55.047876 7f7b753f96c0 Delete type=3 #440 -2025/10/17-17:16:55.047925 7f7b753f96c0 Delete type=0 #442 -2025/10/17-17:19:51.864578 7f7b6f3ff6c0 Level-0 table #447: started -2025/10/17-17:19:51.867676 7f7b6f3ff6c0 Level-0 table #447: 197 bytes OK -2025/10/17-17:19:51.873697 7f7b6f3ff6c0 Delete type=0 #445 -2025/10/17-17:19:51.873943 7f7b6f3ff6c0 Manual compaction at level-0 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!x5gLtqlW4sdDmHTd' @ 0 : 0; will stop at (end) -2025/10/17-17:19:51.885624 7f7b6f3ff6c0 Manual compaction at level-1 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!x5gLtqlW4sdDmHTd' @ 0 : 0; will stop at (end) diff --git a/packs-system/lf-gifts/000411.ldb b/packs-system/lf-racial-abilities/000411.ldb similarity index 100% rename from packs-system/lf-gifts/000411.ldb rename to packs-system/lf-racial-abilities/000411.ldb diff --git a/packs-system/lf-gifts/000447.ldb b/packs-system/lf-racial-abilities/000447.ldb similarity index 100% rename from packs-system/lf-gifts/000447.ldb rename to packs-system/lf-racial-abilities/000447.ldb diff --git a/packs-system/lf-gifts/000450.log b/packs-system/lf-racial-abilities/000468.log similarity index 100% rename from packs-system/lf-gifts/000450.log rename to packs-system/lf-racial-abilities/000468.log diff --git a/packs-system/lf-racial-abilities/CURRENT b/packs-system/lf-racial-abilities/CURRENT new file mode 100644 index 0000000..98d8b49 --- /dev/null +++ b/packs-system/lf-racial-abilities/CURRENT @@ -0,0 +1 @@ +MANIFEST-000466 diff --git a/packs-system/lf-gifts/LOCK b/packs-system/lf-racial-abilities/LOCK similarity index 100% rename from packs-system/lf-gifts/LOCK rename to packs-system/lf-racial-abilities/LOCK diff --git a/packs-system/lf-racial-abilities/LOG b/packs-system/lf-racial-abilities/LOG new file mode 100644 index 0000000..da6529e --- /dev/null +++ b/packs-system/lf-racial-abilities/LOG @@ -0,0 +1,8 @@ +2025/11/06-22:23:29.058630 7f14ba7fc6c0 Recovering log #464 +2025/11/06-22:23:29.069558 7f14ba7fc6c0 Delete type=3 #462 +2025/11/06-22:23:29.069634 7f14ba7fc6c0 Delete type=0 #464 +2025/11/06-23:30:20.584078 7f14b8ff96c0 Level-0 table #469: started +2025/11/06-23:30:20.584111 7f14b8ff96c0 Level-0 table #469: 0 bytes OK +2025/11/06-23:30:20.620952 7f14b8ff96c0 Delete type=0 #467 +2025/11/06-23:30:20.699855 7f14b8ff96c0 Manual compaction at level-0 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!x5gLtqlW4sdDmHTd' @ 0 : 0; will stop at (end) +2025/11/06-23:30:20.699903 7f14b8ff96c0 Manual compaction at level-1 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!x5gLtqlW4sdDmHTd' @ 0 : 0; will stop at (end) diff --git a/packs-system/lf-racial-abilities/LOG.old b/packs-system/lf-racial-abilities/LOG.old new file mode 100644 index 0000000..df4da7b --- /dev/null +++ b/packs-system/lf-racial-abilities/LOG.old @@ -0,0 +1,8 @@ +2025/11/06-22:02:31.386507 7f14ba7fc6c0 Recovering log #460 +2025/11/06-22:02:31.396339 7f14ba7fc6c0 Delete type=3 #458 +2025/11/06-22:02:31.396393 7f14ba7fc6c0 Delete type=0 #460 +2025/11/06-22:07:02.098070 7f14b8ff96c0 Level-0 table #465: started +2025/11/06-22:07:02.098098 7f14b8ff96c0 Level-0 table #465: 0 bytes OK +2025/11/06-22:07:02.135227 7f14b8ff96c0 Delete type=0 #463 +2025/11/06-22:07:02.214791 7f14b8ff96c0 Manual compaction at level-0 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!x5gLtqlW4sdDmHTd' @ 0 : 0; will stop at (end) +2025/11/06-22:07:02.214841 7f14b8ff96c0 Manual compaction at level-1 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!x5gLtqlW4sdDmHTd' @ 0 : 0; will stop at (end) diff --git a/packs-system/lf-gifts/MANIFEST-000448 b/packs-system/lf-racial-abilities/MANIFEST-000466 similarity index 77% rename from packs-system/lf-gifts/MANIFEST-000448 rename to packs-system/lf-racial-abilities/MANIFEST-000466 index 10b043d..a467997 100644 Binary files a/packs-system/lf-gifts/MANIFEST-000448 and b/packs-system/lf-racial-abilities/MANIFEST-000466 differ diff --git a/packs-system/lf-skills/000451.log b/packs-system/lf-skills/000472.log similarity index 100% rename from packs-system/lf-skills/000451.log rename to packs-system/lf-skills/000472.log diff --git a/packs-system/lf-skills/CURRENT b/packs-system/lf-skills/CURRENT index 6da9542..65eef60 100644 --- a/packs-system/lf-skills/CURRENT +++ b/packs-system/lf-skills/CURRENT @@ -1 +1 @@ -MANIFEST-000449 +MANIFEST-000470 diff --git a/packs-system/lf-skills/LOG b/packs-system/lf-skills/LOG index b55427c..86306c7 100644 --- a/packs-system/lf-skills/LOG +++ b/packs-system/lf-skills/LOG @@ -1,15 +1,8 @@ -2025/10/17-20:04:40.334536 7f7b75bfa6c0 Recovering log #446 -2025/10/17-20:04:40.405745 7f7b75bfa6c0 Delete type=3 #444 -2025/10/17-20:04:40.405910 7f7b75bfa6c0 Delete type=0 #446 -2025/10/17-20:06:06.834305 7f7b6f3ff6c0 Level-0 table #452: started -2025/10/17-20:06:06.848868 7f7b6f3ff6c0 Level-0 table #452: 2022 bytes OK -2025/10/17-20:06:06.880702 7f7b6f3ff6c0 Delete type=0 #450 -2025/10/17-20:06:06.981485 7f7b6f3ff6c0 Manual compaction at level-0 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end) -2025/10/17-20:06:06.981572 7f7b6f3ff6c0 Manual compaction at level-1 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at '!items!iu0NfEMvEsUW0FEx' @ 730 : 1 -2025/10/17-20:06:06.981587 7f7b6f3ff6c0 Compacting 1@1 + 1@2 files -2025/10/17-20:06:07.000371 7f7b6f3ff6c0 Generated table #453@1: 89 keys, 118004 bytes -2025/10/17-20:06:07.000414 7f7b6f3ff6c0 Compacted 1@1 + 1@2 files => 118004 bytes -2025/10/17-20:06:07.037470 7f7b6f3ff6c0 compacted to: files[ 0 0 1 0 0 0 0 ] -2025/10/17-20:06:07.037700 7f7b6f3ff6c0 Delete type=2 #448 -2025/10/17-20:06:07.038082 7f7b6f3ff6c0 Delete type=2 #452 -2025/10/17-20:06:07.038307 7f7b6f3ff6c0 Manual compaction at level-1 from '!items!iu0NfEMvEsUW0FEx' @ 730 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end) +2025/11/06-22:23:29.029187 7f14baffd6c0 Recovering log #468 +2025/11/06-22:23:29.039080 7f14baffd6c0 Delete type=3 #466 +2025/11/06-22:23:29.039138 7f14baffd6c0 Delete type=0 #468 +2025/11/06-23:30:20.621142 7f14b8ff96c0 Level-0 table #473: started +2025/11/06-23:30:20.621185 7f14b8ff96c0 Level-0 table #473: 0 bytes OK +2025/11/06-23:30:20.663601 7f14b8ff96c0 Delete type=0 #471 +2025/11/06-23:30:20.699871 7f14b8ff96c0 Manual compaction at level-0 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end) +2025/11/06-23:30:20.699913 7f14b8ff96c0 Manual compaction at level-1 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end) diff --git a/packs-system/lf-skills/LOG.old b/packs-system/lf-skills/LOG.old index daceab7..0d5c53e 100644 --- a/packs-system/lf-skills/LOG.old +++ b/packs-system/lf-skills/LOG.old @@ -1,15 +1,8 @@ -2025/10/17-17:16:55.008421 7f7b75bfa6c0 Recovering log #442 -2025/10/17-17:16:55.018287 7f7b75bfa6c0 Delete type=3 #440 -2025/10/17-17:16:55.018352 7f7b75bfa6c0 Delete type=0 #442 -2025/10/17-17:19:51.840745 7f7b6f3ff6c0 Level-0 table #447: started -2025/10/17-17:19:51.844779 7f7b6f3ff6c0 Level-0 table #447: 965 bytes OK -2025/10/17-17:19:51.851258 7f7b6f3ff6c0 Delete type=0 #445 -2025/10/17-17:19:51.873900 7f7b6f3ff6c0 Manual compaction at level-0 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end) -2025/10/17-17:19:51.873957 7f7b6f3ff6c0 Manual compaction at level-1 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at '!items!iu0NfEMvEsUW0FEx' @ 725 : 1 -2025/10/17-17:19:51.873962 7f7b6f3ff6c0 Compacting 1@1 + 1@2 files -2025/10/17-17:19:51.879155 7f7b6f3ff6c0 Generated table #448@1: 89 keys, 117699 bytes -2025/10/17-17:19:51.879178 7f7b6f3ff6c0 Compacted 1@1 + 1@2 files => 117699 bytes -2025/10/17-17:19:51.885277 7f7b6f3ff6c0 compacted to: files[ 0 0 1 0 0 0 0 ] -2025/10/17-17:19:51.885392 7f7b6f3ff6c0 Delete type=2 #411 -2025/10/17-17:19:51.885543 7f7b6f3ff6c0 Delete type=2 #447 -2025/10/17-17:19:51.885644 7f7b6f3ff6c0 Manual compaction at level-1 from '!items!iu0NfEMvEsUW0FEx' @ 725 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end) +2025/11/06-22:02:31.360508 7f14b97fa6c0 Recovering log #464 +2025/11/06-22:02:31.369829 7f14b97fa6c0 Delete type=3 #462 +2025/11/06-22:02:31.369896 7f14b97fa6c0 Delete type=0 #464 +2025/11/06-22:07:01.975536 7f14b8ff96c0 Level-0 table #469: started +2025/11/06-22:07:01.975585 7f14b8ff96c0 Level-0 table #469: 0 bytes OK +2025/11/06-22:07:02.017435 7f14b8ff96c0 Delete type=0 #467 +2025/11/06-22:07:02.061930 7f14b8ff96c0 Manual compaction at level-0 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end) +2025/11/06-22:07:02.061962 7f14b8ff96c0 Manual compaction at level-1 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end) diff --git a/packs-system/lf-skills/MANIFEST-000449 b/packs-system/lf-skills/MANIFEST-000449 deleted file mode 100644 index 383ba0b..0000000 Binary files a/packs-system/lf-skills/MANIFEST-000449 and /dev/null differ diff --git a/packs-system/lf-skills/MANIFEST-000470 b/packs-system/lf-skills/MANIFEST-000470 new file mode 100644 index 0000000..7a712b2 Binary files /dev/null and b/packs-system/lf-skills/MANIFEST-000470 differ diff --git a/packs-system/lf-spells-miracles/000150.log b/packs-system/lf-spells-miracles/000170.log similarity index 100% rename from packs-system/lf-spells-miracles/000150.log rename to packs-system/lf-spells-miracles/000170.log diff --git a/packs-system/lf-spells-miracles/CURRENT b/packs-system/lf-spells-miracles/CURRENT index 89e2564..57112f5 100644 --- a/packs-system/lf-spells-miracles/CURRENT +++ b/packs-system/lf-spells-miracles/CURRENT @@ -1 +1 @@ -MANIFEST-000148 +MANIFEST-000168 diff --git a/packs-system/lf-spells-miracles/LOG b/packs-system/lf-spells-miracles/LOG index a8d100f..dfdd1a7 100644 --- a/packs-system/lf-spells-miracles/LOG +++ b/packs-system/lf-spells-miracles/LOG @@ -1,8 +1,8 @@ -2025/10/17-20:04:40.563726 7f7b74bf86c0 Recovering log #146 -2025/10/17-20:04:40.603255 7f7b74bf86c0 Delete type=3 #144 -2025/10/17-20:04:40.603347 7f7b74bf86c0 Delete type=0 #146 -2025/10/17-20:06:07.107148 7f7b6f3ff6c0 Level-0 table #151: started -2025/10/17-20:06:07.107209 7f7b6f3ff6c0 Level-0 table #151: 0 bytes OK -2025/10/17-20:06:07.142401 7f7b6f3ff6c0 Delete type=0 #149 -2025/10/17-20:06:07.182630 7f7b6f3ff6c0 Manual compaction at level-0 from '!folders!37mu4dxsSuftlnmP' @ 72057594037927935 : 1 .. '!items!zKOpU34oLziGJW6y' @ 0 : 0; will stop at (end) -2025/10/17-20:06:07.182721 7f7b6f3ff6c0 Manual compaction at level-1 from '!folders!37mu4dxsSuftlnmP' @ 72057594037927935 : 1 .. '!items!zKOpU34oLziGJW6y' @ 0 : 0; will stop at (end) +2025/11/06-22:23:29.084326 7f14b97fa6c0 Recovering log #166 +2025/11/06-22:23:29.094282 7f14b97fa6c0 Delete type=3 #164 +2025/11/06-22:23:29.094350 7f14b97fa6c0 Delete type=0 #166 +2025/11/06-23:30:20.736863 7f14b8ff96c0 Level-0 table #171: started +2025/11/06-23:30:20.736903 7f14b8ff96c0 Level-0 table #171: 0 bytes OK +2025/11/06-23:30:20.773276 7f14b8ff96c0 Delete type=0 #169 +2025/11/06-23:30:20.843384 7f14b8ff96c0 Manual compaction at level-0 from '!folders!37mu4dxsSuftlnmP' @ 72057594037927935 : 1 .. '!items!zKOpU34oLziGJW6y' @ 0 : 0; will stop at (end) +2025/11/06-23:30:20.843468 7f14b8ff96c0 Manual compaction at level-1 from '!folders!37mu4dxsSuftlnmP' @ 72057594037927935 : 1 .. '!items!zKOpU34oLziGJW6y' @ 0 : 0; will stop at (end) diff --git a/packs-system/lf-spells-miracles/LOG.old b/packs-system/lf-spells-miracles/LOG.old index fc3369c..1a70dd0 100644 --- a/packs-system/lf-spells-miracles/LOG.old +++ b/packs-system/lf-spells-miracles/LOG.old @@ -1,8 +1,8 @@ -2025/10/17-17:16:55.063170 7f7b74bf86c0 Recovering log #142 -2025/10/17-17:16:55.073152 7f7b74bf86c0 Delete type=3 #140 -2025/10/17-17:16:55.073202 7f7b74bf86c0 Delete type=0 #142 -2025/10/17-17:19:51.909136 7f7b6f3ff6c0 Level-0 table #147: started -2025/10/17-17:19:51.909165 7f7b6f3ff6c0 Level-0 table #147: 0 bytes OK -2025/10/17-17:19:51.915284 7f7b6f3ff6c0 Delete type=0 #145 -2025/10/17-17:19:51.933498 7f7b6f3ff6c0 Manual compaction at level-0 from '!folders!37mu4dxsSuftlnmP' @ 72057594037927935 : 1 .. '!items!zKOpU34oLziGJW6y' @ 0 : 0; will stop at (end) -2025/10/17-17:19:51.939577 7f7b6f3ff6c0 Manual compaction at level-1 from '!folders!37mu4dxsSuftlnmP' @ 72057594037927935 : 1 .. '!items!zKOpU34oLziGJW6y' @ 0 : 0; will stop at (end) +2025/11/06-22:02:31.410218 7f14baffd6c0 Recovering log #162 +2025/11/06-22:02:31.420645 7f14baffd6c0 Delete type=3 #160 +2025/11/06-22:02:31.420716 7f14baffd6c0 Delete type=0 #162 +2025/11/06-22:07:02.062050 7f14b8ff96c0 Level-0 table #167: started +2025/11/06-22:07:02.062080 7f14b8ff96c0 Level-0 table #167: 0 bytes OK +2025/11/06-22:07:02.097947 7f14b8ff96c0 Delete type=0 #165 +2025/11/06-22:07:02.214774 7f14b8ff96c0 Manual compaction at level-0 from '!folders!37mu4dxsSuftlnmP' @ 72057594037927935 : 1 .. '!items!zKOpU34oLziGJW6y' @ 0 : 0; will stop at (end) +2025/11/06-22:07:02.214817 7f14b8ff96c0 Manual compaction at level-1 from '!folders!37mu4dxsSuftlnmP' @ 72057594037927935 : 1 .. '!items!zKOpU34oLziGJW6y' @ 0 : 0; will stop at (end) diff --git a/packs-system/lf-spells-miracles/MANIFEST-000148 b/packs-system/lf-spells-miracles/MANIFEST-000168 similarity index 72% rename from packs-system/lf-spells-miracles/MANIFEST-000148 rename to packs-system/lf-spells-miracles/MANIFEST-000168 index 0961f89..d7baf50 100644 Binary files a/packs-system/lf-spells-miracles/MANIFEST-000148 and b/packs-system/lf-spells-miracles/MANIFEST-000168 differ diff --git a/packs-system/lf-vulnerabilities/000449.log b/packs-system/lf-vulnerabilities/000469.log similarity index 100% rename from packs-system/lf-vulnerabilities/000449.log rename to packs-system/lf-vulnerabilities/000469.log diff --git a/packs-system/lf-vulnerabilities/CURRENT b/packs-system/lf-vulnerabilities/CURRENT index d173ab7..cc78e12 100644 --- a/packs-system/lf-vulnerabilities/CURRENT +++ b/packs-system/lf-vulnerabilities/CURRENT @@ -1 +1 @@ -MANIFEST-000447 +MANIFEST-000467 diff --git a/packs-system/lf-vulnerabilities/LOG b/packs-system/lf-vulnerabilities/LOG index 613d10e..ad10823 100644 --- a/packs-system/lf-vulnerabilities/LOG +++ b/packs-system/lf-vulnerabilities/LOG @@ -1,8 +1,8 @@ -2025/10/17-20:04:40.518960 7f7b75bfa6c0 Recovering log #445 -2025/10/17-20:04:40.559683 7f7b75bfa6c0 Delete type=3 #443 -2025/10/17-20:04:40.559810 7f7b75bfa6c0 Delete type=0 #445 -2025/10/17-20:06:06.918106 7f7b6f3ff6c0 Level-0 table #450: started -2025/10/17-20:06:06.918166 7f7b6f3ff6c0 Level-0 table #450: 0 bytes OK -2025/10/17-20:06:06.949207 7f7b6f3ff6c0 Delete type=0 #448 -2025/10/17-20:06:06.981529 7f7b6f3ff6c0 Manual compaction at level-0 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end) -2025/10/17-20:06:07.038289 7f7b6f3ff6c0 Manual compaction at level-1 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end) +2025/11/06-22:23:29.072490 7f14baffd6c0 Recovering log #465 +2025/11/06-22:23:29.081800 7f14baffd6c0 Delete type=3 #463 +2025/11/06-22:23:29.081874 7f14baffd6c0 Delete type=0 #465 +2025/11/06-23:30:20.663745 7f14b8ff96c0 Level-0 table #470: started +2025/11/06-23:30:20.663783 7f14b8ff96c0 Level-0 table #470: 0 bytes OK +2025/11/06-23:30:20.699688 7f14b8ff96c0 Delete type=0 #468 +2025/11/06-23:30:20.699892 7f14b8ff96c0 Manual compaction at level-0 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end) +2025/11/06-23:30:20.699942 7f14b8ff96c0 Manual compaction at level-1 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end) diff --git a/packs-system/lf-vulnerabilities/LOG.old b/packs-system/lf-vulnerabilities/LOG.old index df49b7f..78931b3 100644 --- a/packs-system/lf-vulnerabilities/LOG.old +++ b/packs-system/lf-vulnerabilities/LOG.old @@ -1,8 +1,8 @@ -2025/10/17-17:16:55.050630 7f7b75bfa6c0 Recovering log #441 -2025/10/17-17:16:55.059896 7f7b75bfa6c0 Delete type=3 #439 -2025/10/17-17:16:55.059946 7f7b75bfa6c0 Delete type=0 #441 -2025/10/17-17:19:51.851372 7f7b6f3ff6c0 Level-0 table #446: started -2025/10/17-17:19:51.851400 7f7b6f3ff6c0 Level-0 table #446: 0 bytes OK -2025/10/17-17:19:51.857689 7f7b6f3ff6c0 Delete type=0 #444 -2025/10/17-17:19:51.873917 7f7b6f3ff6c0 Manual compaction at level-0 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end) -2025/10/17-17:19:51.885612 7f7b6f3ff6c0 Manual compaction at level-1 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end) +2025/11/06-22:02:31.398571 7f14b97fa6c0 Recovering log #461 +2025/11/06-22:02:31.407995 7f14b97fa6c0 Delete type=3 #459 +2025/11/06-22:02:31.408047 7f14b97fa6c0 Delete type=0 #461 +2025/11/06-22:07:02.017574 7f14b8ff96c0 Level-0 table #466: started +2025/11/06-22:07:02.017607 7f14b8ff96c0 Level-0 table #466: 0 bytes OK +2025/11/06-22:07:02.061758 7f14b8ff96c0 Delete type=0 #464 +2025/11/06-22:07:02.061944 7f14b8ff96c0 Manual compaction at level-0 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end) +2025/11/06-22:07:02.061971 7f14b8ff96c0 Manual compaction at level-1 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end) diff --git a/packs-system/lf-vulnerabilities/MANIFEST-000447 b/packs-system/lf-vulnerabilities/MANIFEST-000467 similarity index 72% rename from packs-system/lf-vulnerabilities/MANIFEST-000447 rename to packs-system/lf-vulnerabilities/MANIFEST-000467 index b6dc4e1..efba7ed 100644 Binary files a/packs-system/lf-vulnerabilities/MANIFEST-000447 and b/packs-system/lf-vulnerabilities/MANIFEST-000467 differ diff --git a/packs/lf-gifts/000005.ldb b/packs/lf-racial-abilities/000005.ldb similarity index 100% rename from packs/lf-gifts/000005.ldb rename to packs/lf-racial-abilities/000005.ldb diff --git a/packs/lf-gifts/000088.log b/packs/lf-racial-abilities/000088.log similarity index 100% rename from packs/lf-gifts/000088.log rename to packs/lf-racial-abilities/000088.log diff --git a/packs/lf-gifts/CURRENT b/packs/lf-racial-abilities/CURRENT similarity index 100% rename from packs/lf-gifts/CURRENT rename to packs/lf-racial-abilities/CURRENT diff --git a/packs/lf-gifts/LOCK b/packs/lf-racial-abilities/LOCK similarity index 100% rename from packs/lf-gifts/LOCK rename to packs/lf-racial-abilities/LOCK diff --git a/packs/lf-gifts/LOG b/packs/lf-racial-abilities/LOG similarity index 100% rename from packs/lf-gifts/LOG rename to packs/lf-racial-abilities/LOG diff --git a/packs/lf-gifts/LOG.old b/packs/lf-racial-abilities/LOG.old similarity index 100% rename from packs/lf-gifts/LOG.old rename to packs/lf-racial-abilities/LOG.old diff --git a/packs/lf-gifts/MANIFEST-000086 b/packs/lf-racial-abilities/MANIFEST-000086 similarity index 100% rename from packs/lf-gifts/MANIFEST-000086 rename to packs/lf-racial-abilities/MANIFEST-000086 diff --git a/prism-rpg.mjs b/prism-rpg.mjs index 111e553..511c804 100644 --- a/prism-rpg.mjs +++ b/prism-rpg.mjs @@ -25,6 +25,9 @@ Hooks.once("init", function () { globalThis.prismRPG = game.system game.system.CONST = SYSTEM + // Expose system configuration to CONFIG + CONFIG.PRISMRPG = SYSTEM + // Expose the system API game.system.api = { applications, @@ -44,14 +47,16 @@ Hooks.once("init", function () { CONFIG.Item.documentClass = documents.PrismRPGItem CONFIG.Item.dataModels = { skill: models.PrismRPGSkill, - gift: models.PrismRPGGift, + "racial-ability": models.PrismRPGRacialAbility, weapon: models.PrismRPGWeapon, armor: models.PrismRPGArmor, shield: models.PrismRPGShield, spell: models.PrismRPGSpell, - vulnerability: models.PrismRPGVulnerability, + // Vulnerability: models.PrismRPGVulnerability, // Disabled - Legacy from Lethal Fantasy equipment: models.PrismRPGEquipment, - miracle: models.PrismRPGMiracle + // Miracle: models.PrismRPGMiracle // Disabled - Legacy from Lethal Fantasy, PRISM uses Divine class features instead + race: models.PrismRPGRace, + class: models.PrismRPGClass, } // Register sheet application classes @@ -61,14 +66,16 @@ Hooks.once("init", function () { foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ActorSheet) foundry.documents.collections.Items.registerSheet("prismRPG", applications.PrismRPGSkillSheet, { types: ["skill"], makeDefault: true }) - foundry.documents.collections.Items.registerSheet("prismRPG", applications.PrismRPGGiftSheet, { types: ["gift"], makeDefault: true }) - foundry.documents.collections.Items.registerSheet("prismRPG", applications.PrismRPGVulnerabilitySheet, { types: ["vulnerability"], makeDefault: true }) + foundry.documents.collections.Items.registerSheet("prismRPG", applications.PrismRPGRacialAbilitySheet, { types: ["racial-ability"], makeDefault: true }) + // Foundry.documents.collections.Items.registerSheet("prismRPG", applications.PrismRPGVulnerabilitySheet, { types: ["vulnerability"], makeDefault: true }) // Disabled - Legacy from Lethal Fantasy foundry.documents.collections.Items.registerSheet("prismRPG", applications.PrismRPGWeaponSheet, { types: ["weapon"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("prismRPG", applications.PrismRPGSpellSheet, { types: ["spell"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("prismRPG", applications.PrismRPGArmorSheet, { types: ["armor"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("prismRPG", applications.PrismRPGShieldSheet, { types: ["shield"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("prismRPG", applications.PrismRPGEquipmentSheet, { types: ["equipment"], makeDefault: true }) - foundry.documents.collections.Items.registerSheet("prismRPG", applications.PrismRPGMiracleSheet, { types: ["miracle"], makeDefault: true }) + foundry.documents.collections.Items.registerSheet("prismRPG", applications.PrismRPGRaceSheet, { types: ["race"], makeDefault: true }) + foundry.documents.collections.Items.registerSheet("prismRPG", applications.PrismRPGClassSheet, { types: ["class"], makeDefault: true }) + // Foundry.documents.collections.Items.registerSheet("prismRPG", applications.PrismRPGMiracleSheet, { types: ["miracle"], makeDefault: true }) // Disabled - Legacy from Lethal Fantasy // Other Document Configuration CONFIG.ChatMessage.documentClass = documents.PrismRPGChatMessage @@ -95,18 +102,42 @@ Hooks.once("init", function () { }) /** - * Perform one-time configuration of system configuration objects.f + * Perform one-time pre-localization of system configuration objects. */ function preLocalizeConfig() { const localizeConfigObject = (obj, keys) => { for (let o of Object.values(obj)) { for (let k of keys) { - o[k] = game.i18n.localize(o[k]) + if (typeof o[k] === "string") { + o[k] = game.i18n.localize(o[k]) + } + } + } + } + + // Pre-localize choice objects that are displayed in forms + const choicesToLocalize = [ + "CORE_SKILLS_CHOICES", + "SPELL_COLORS_CHOICES", + "SHIELD_TYPE_CHOICES", + "WEAPON_TYPE_CHOICES", + "WEAPON_GROUP_CHOICES" + ] + + for (const choice of choicesToLocalize) { + if (CONFIG.PRISMRPG[choice]) { + for (const [key, label] of Object.entries(CONFIG.PRISMRPG[choice])) { + CONFIG.PRISMRPG[choice][key] = game.i18n.localize(label) } } } } +Hooks.once("i18nInit", function () { + console.info("PRISM RPG | Localizing configuration") + preLocalizeConfig() +}) + Hooks.once("ready", function () { console.info("PRISM RPG | Ready") diff --git a/styles/character.less b/styles/character.less index 0d0e8ff..f541880 100644 --- a/styles/character.less +++ b/styles/character.less @@ -278,11 +278,11 @@ } } } - .gifts { + .racial-abilities { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; - .gift { + .racial-ability { display: flex; align-items: center; gap: 4px; diff --git a/styles/class.less b/styles/class.less new file mode 100644 index 0000000..91bdbd4 --- /dev/null +++ b/styles/class.less @@ -0,0 +1,16 @@ +.class-content { + .sheet-common(); + .item-sheet-common(); + + .header { + display: flex; + img { + width: 50px; + height: 50px; + } + } + + label { + flex: 10%; + } +} diff --git a/styles/fvtt-prism-rpg.less b/styles/fvtt-prism-rpg.less index a60e119..d01c219 100644 --- a/styles/fvtt-prism-rpg.less +++ b/styles/fvtt-prism-rpg.less @@ -6,7 +6,7 @@ @import "character.less"; @import "monster.less"; @import "skill.less"; - @import "gift.less"; + @import "racial-ability.less"; @import "weapon.less"; @import "armor.less"; @import "spell.less"; @@ -15,6 +15,8 @@ @import "equipment.less"; @import "shield.less"; @import "miracle.less"; + @import "race.less"; + @import "class.less"; } @import "roll.less"; diff --git a/styles/global.less b/styles/global.less index f4328d1..a72e30a 100644 --- a/styles/global.less +++ b/styles/global.less @@ -3,7 +3,7 @@ --font-size-standard: 0.8rem; --background-image-base: url("../assets/ui/prism_rpg_background.webp"); --font-secondary: "BaskervilleBold", serif; - --logo-standard: url("../assets/ui/lf_logo_small_02.webp"); + --logo-standard: url("../assets/ui/prism-rpg-logo-01.webp"); } .initiative-area { @@ -47,7 +47,7 @@ i.prismrpg { .application.dialog.prismrpg { font-family: var(--font-primary); - font-size: calc(var(--font-size-standard) * 1.0); + font-size: calc(var(--font-size-standard) * 1); background-image: var(--background-image-base); button:hover { background: var(--color-dark-6); @@ -70,13 +70,13 @@ i.prismrpg { background-size: 100% 100%; } -.combat-sidebar li.combatant .token-initiative .initiative{ +.combat-sidebar li.combatant .token-initiative .initiative { margin-right: 16px; } .combat-sidebar li.combatant .token-initiative { - flex:none; + flex: none; } .initiative-minus { margin-right: 8px; -} \ No newline at end of file +} diff --git a/styles/monster.less b/styles/monster.less index 3320188..e6c6222 100644 --- a/styles/monster.less +++ b/styles/monster.less @@ -25,7 +25,6 @@ gap: 10px; flex: 1; - .monster-hp { display: flex; gap: 4px; @@ -46,7 +45,7 @@ min-width: 2.2rem; max-width: 2.2rem; margin-left: 4px; - font-size: calc(var(--font-size-standard) * 1.0); + font-size: calc(var(--font-size-standard) * 1); } .character-hp-max { clear: both; @@ -58,7 +57,7 @@ input { width: 3.2rem; text-align: center; - font-size: calc(var(--font-size-standard) * 1.0); + font-size: calc(var(--font-size-standard) * 1); } } } @@ -252,7 +251,7 @@ } } -.tab.monster-skills .main-div{ +.tab.monster-skills .main-div { display: grid; grid-template-columns: 1fr; legend { @@ -278,11 +277,11 @@ } } } - .gifts { + .racial-abilities { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; - .gift { + .racial-ability { display: flex; align-items: center; gap: 4px; diff --git a/styles/race.less b/styles/race.less new file mode 100644 index 0000000..ca54be3 --- /dev/null +++ b/styles/race.less @@ -0,0 +1,16 @@ +.race-content { + .sheet-common(); + .item-sheet-common(); + + .header { + display: flex; + img { + width: 50px; + height: 50px; + } + } + + label { + flex: 10%; + } +} diff --git a/styles/gift.less b/styles/racial-ability.less similarity index 93% rename from styles/gift.less rename to styles/racial-ability.less index c40ad31..b3267d4 100644 --- a/styles/gift.less +++ b/styles/racial-ability.less @@ -1,4 +1,4 @@ -.gift-content { +.racial-ability-content { .sheet-common(); .item-sheet-common(); @@ -19,7 +19,7 @@ input[type="checkbox"]:checked { background-color: rgba(0, 0, 0, 0.1); } - + input[type="checkbox"]:checked::after { color: rgba(0, 0, 0, 0.1); } diff --git a/system.json b/system.json index 062d497..4358d0e 100644 --- a/system.json +++ b/system.json @@ -33,14 +33,14 @@ }, "Item": { "skill": { "htmlFields": ["description"] }, - "gift": { "htmlFields": ["description"] }, - "vulnerability": { "htmlFields": ["description"] }, + "racial-ability": { "htmlFields": ["description"] }, "weapon": { "htmlFields": ["description"] }, "armor": { "htmlFields": ["description"] }, "shield": { "htmlFields": ["description"] }, "spell": { "htmlFields": ["description"] }, "equipment": { "htmlFields": ["description"] }, - "miracle": { "htmlFields": ["miracle"] } + "race": { "htmlFields": ["description", "racialPassiveDescription", "subraceAbilityDescription", "notes"] }, + "class": { "htmlFields": ["description", "attributeBonuses", "notes", "features.level1", "features.level2", "features.level3", "features.level4", "features.level5", "features.level6", "features.level7", "features.level8", "features.level9", "features.level10"] } } }, "grid": { @@ -68,11 +68,11 @@ "type": "Item" }, { - "name": "lf-gifts", + "name": "lf-racial-abilities", "banner": "", - "label": "Gifts", + "label": "Racial Abilities", "system": "fvtt-prism-rpg", - "path": "packs-system/lf-gifts", + "path": "packs-system/lf-racial-abilities", "type": "Item" }, { diff --git a/templates/armor.hbs b/templates/armor.hbs index 463a4f7..45e7403 100644 --- a/templates/armor.hbs +++ b/templates/armor.hbs @@ -18,37 +18,19 @@ label="PRISMRPG.Label.armorType" }} - {{! Armor Class (AC) }} - {{formField - systemFields.defense - value=system.defense - label="PRISMRPG.Label.armorClass" - }} - {{! Maximum Reduction Rating (MRR) }} - {{formField systemFields.mrr value=system.mrr label="PRISMRPG.Label.mrr"}} - - {{! Movement Penalty }} {{formField - systemFields.maximumMovement - value=system.maximumMovement - label="PRISMRPG.Label.movementPenalty" - }} - - {{! Armor Hit Points }} - {{formField systemFields.hp value=system.hp label="PRISMRPG.Label.armorHP"}} - - {{! Damage Reduction }} - {{formField - systemFields.damageReduction - value=system.damageReduction - label="PRISMRPG.Label.damageReduction" + systemFields.mrr + value=system.mrr + localize=true + label="PRISMRPG.Label.mrr" }} {{! Encumbrance Load }} {{formField systemFields.encLoad value=system.encLoad + localize=true label="PRISMRPG.Label.encumbranceLoad" }} @@ -56,11 +38,13 @@ {{formField systemFields.isHelmet value=system.isHelmet + localize=true label="PRISMRPG.Label.isHelmet" }} {{formField systemFields.equipped value=system.equipped + localize=true label="PRISMRPG.Label.equipped" }} @@ -70,18 +54,17 @@ {{formField systemFields.passive value=system.passive + localize=true label="PRISMRPG.Label.passiveName" }} -