8 Commits
13.2.2 ... main

Author SHA1 Message Date
8d9cc1045c Fix licence 2025-10-01 15:14:58 +02:00
4af277d8a2 Fight helper ! 2025-10-01 11:24:41 +02:00
bc9f397755 Fix initiative 2025-09-30 17:44:39 +02:00
264a5c7a4c Fix HP and other derivated values not computed anymore
All checks were successful
Release Creation / build (release) Successful in 2m57s
2025-08-10 19:33:28 +02:00
4edbc9b618 Translate weapons + skills in columns
All checks were successful
Release Creation / build (release) Successful in 3m43s
2025-07-29 18:29:02 +02:00
47c2aea941 New weapon management, including shotgun
All checks were successful
Release Creation / build (release) Successful in 1m14s
2025-07-14 21:36:08 +02:00
cdefecdeba New weapon management, including shotgun 2025-07-14 21:33:32 +02:00
61b8da8ccf Various CSS Enhancements
All checks were successful
Release Creation / build (release) Successful in 1m39s
2025-07-09 17:19:09 +02:00
50 changed files with 1448 additions and 279 deletions

View File

@@ -0,0 +1,6 @@
Code license :
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
This license requires that reusers give credit to the creator. It allows reusers to distribute, remix, adapt, and build upon the material in any medium or format, for noncommercial purposes only. If others modify or adapt the material, they must license the modified material under identical terms.

View File

@@ -20,7 +20,7 @@
"entries": { "entries": {
"Pilot (Type)": { "Pilot (Type)": {
"name": "Pilotage (Type)", "name": "Pilotage (Type)",
"description": "<pPiloter, naviguer et diriger des véhicules nautiques ou aériens. Utilisez cette compétence pour assurer la sécurité d'un navire en cas de danger, par exemple lors d'une tempête ou d'une poursuite dangereuse. Chaque type de véhicule requiert une compétence distincte : Avion, Drone, Hélicoptère, Dirigeable, Petite embarcation, Navire, etc.</p>" "description": "<p>Piloter, naviguer et diriger des véhicules nautiques ou aériens. Utilisez cette compétence pour assurer la sécurité d'un navire en cas de danger, par exemple lors d'une tempête ou d'une poursuite dangereuse. Chaque type de véhicule requiert une compétence distincte : Avion, Drone, Hélicoptère, Dirigeable, Petite embarcation, Navire, etc.</p>"
}, },
"Anthropology": { "Anthropology": {
"name": "Anthropologie", "name": "Anthropologie",

View File

@@ -0,0 +1,389 @@
{
"label": "Armes",
"folders": {
"Automatic and Heavy Weapons": "Automatiques et armes lourdes",
"Firearms": "Armes à feu",
"Melee Weapons": "Armes de mêlée",
"Ranged Weapons": "Armes à distance",
"Ranged weapons": "Armes à distance",
"Thermal Weapons": "Armes thermiques",
"Weapons - Age Of Revolutions": "Armes - Âge des Révolutions",
"Weapons - Age Of Sails": "Armes - Âge de la Voile",
"Weapons - Classical Era": "Armes - Époque Classique",
"Weapons - Cold War": "Armes - Guerre Froide",
"Weapons - Future": "Armes - Futur",
"Weapons - Jazz": "Armes - Jazz/Années folles",
"Weapons - Medieval": "Armes - Médiévales",
"Weapons - Modern": "Armes - Modernes",
"Weapons - Post Apocalyptic": "Armes - Post-apocalyptiques",
"Weapons - Victorian": "Armes - Victoriennes",
"Weapons - World War I": "Armes - Première Guerre mondiale",
"Weapons - World War II": "Armes - Seconde Guerre mondiale"
},
"mapping": {
"rangeUnit": {
"path": "system.rangeUnit",
"converter": "translateRangeUnit"
},
"baseRange": {
"path": "system.baseRange",
"converter": "translateRange"
}
},
"entries": {
"Anti-tank rifle": {
"name": "Arme antichar"
},
"Assault rifle": {
"name": "Fusil d'assaut"
},
"Axe": {
"name": "Hache"
},
"Bare hands and feet": {
"name": "Mains et pieds nus"
},
"Baseball Bat": {
"name": "Batte de baseball"
},
"Baseball bat": {
"name": "Batte de baseball"
},
"Battle laser": {
"name": "Laser de combat"
},
"Battle rifle": {
"name": "Fusil de combat"
},
"Bayonet": {
"name": "Baïonnette"
},
"Blackjack": {
"name": "Blackjack"
},
"Blunderbuss Pistol": {
"name": "Pistolet tromblon"
},
"Bow": {
"name": "Arc"
},
"Brass knuckles": {
"name": "Poings américains"
},
"Broad sword": {
"name": "Épée large"
},
"Buffalo Rifle": {
"name": "Fusil Buffalo"
},
"Cane Gun": {
"name": "Pistolet canne"
},
"Cannon Barrel Pistol": {
"name": "Pistolet canon"
},
"Carbine": {
"name": "Carabine"
},
"Cavalry lance": {
"name": "Lance de cavalerie"
},
"Cavalry sabre": {
"name": "Sabre de cavalerie"
},
"Ceramic Grenade": {
"name": "Grenade en céramique"
},
"Chainsaw": {
"name": "Tronçonneuse"
},
"Claymore": {
"name": "Claymore"
},
"Club": {
"name": "Gourdin"
},
"Combat knife": {
"name": "Couteau de combat"
},
"Cosh": {
"name": "Matraque"
},
"Cricket bat": {
"name": "Batte de cricket"
},
"Crossbow": {
"name": "Arbalète"
},
"Cutlass": {
"name": "Coutelas"
},
"Dagger": {
"name": "Dague"
},
"Derringer": {
"name": "Derringer"
},
"Dueling Pistol": {
"name": "Pistolet de duel"
},
"Dutch (long) Pistol": {
"name": "Pistolet néerlandais (long)"
},
"Elephant Gun": {
"name": "Fusil à éléphant"
},
"Flintlock Pistol": {
"name": "Pistolet à silex"
},
"Fowling Piece": {
"name": "Fusil de chasse"
},
"Garotte": {
"name": "Garrot"
},
"Gatling Gun": {
"name": "Gatling Gun"
},
"Guntō": {
"name": "Guntō"
},
"Hand Grenade": {
"name": "Grenade à main"
},
"Hand grenade": {
"name": "Grenade à main"
},
"Hatchet": {
"name": "Hachette"
},
"Heavy Pistol": {
"name": "Pistolet lourd"
},
"Heavy Spear": {
"name": "Lance lourde"
},
"Heavy axe": {
"name": "Hache lourde"
},
"Heavy hammer": {
"name": "Marteau lourd"
},
"Heavy pistol": {
"name": "Pistolet gros calibre"
},
"Heavy spear": {
"name": "Lance lourde"
},
"Incendiary Grenade": {
"name": "Grenade incendiaire"
},
"Javelin": {
"name": "Javelot"
},
"Katana": {
"name": "Katana"
},
"Knife": {
"name": "Couteau"
},
"Large Caliber Pistol": {
"name": "Pistolet gros calibre"
},
"Large sword": {
"name": "Grande épée"
},
"Laser carbine": {
"name": "Carabine laser"
},
"Life preserver": {
"name": "Gilet de sauvetage"
},
"Light Spear": {
"name": "Lance légère"
},
"Light axe": {
"name": "Hache légère"
},
"Light spear": {
"name": "Lance légère"
},
"Long spear": {
"name": "Lance longue"
},
"Long sword": {
"name": "Epée longue"
},
"Longrifle": {
"name": "Fusil long"
},
"Mace": {
"name": "Masse"
},
"Machete": {
"name": "Machette"
},
"Maxim": {
"name": "Maxime"
},
"Medium Pistol": {
"name": "Pistolet moyen"
},
"Musket": {
"name": "Mousquet"
},
"Nightstick": {
"name": "Matraque"
},
"Oil": {
"name": "Huile"
},
"Ordinary knife": {
"name": "Couteau ordinaire"
},
"Plasma rifle": {
"name": "Fusil à plasma"
},
"Polearm": {
"name": "Arme d'hast"
},
"Power sword": {
"name": "Epée énergétique"
},
"Rapier": {
"name": "Rapière"
},
"Rifle": {
"name": "Fusil"
},
"Sabre": {
"name": "Sabre"
},
"Scimitar": {
"name": "Cimeterre"
},
"Seax": {
"name": "Seax"
},
"Shield bash": {
"name": "Coup de bouclier"
},
"Shiv": {
"name": "Shiv"
},
"Short spear": {
"name": "Lance courte"
},
"Short sword": {
"name": "Epée courte"
},
"Shotgun": {
"name": "Shotgun"
},
"Shuriken": {
"name": "Shuriken"
},
"Sickle": {
"name": "Faucille"
},
"Sling": {
"name": "Fronde"
},
"Small-caliber pistol": {
"name": "Pistolet de petit calibre"
},
"Smallcaliber pistol": {
"name": "Pistolet de petit calibre"
},
"Staff": {
"name": "Bâton"
},
"Steel-toe boot": {
"name": "Botte à embout en acier"
},
"Steeltoe boot": {
"name": "Botte à embout en acier"
},
"Submachine gun": {
"name": "Pistolet-mitrailleur"
},
"Sulphur soaked cloth": {
"name": "Tissu imbibé de soufre"
},
"Switchblade": {
"name": "Couteau à cran d'arrêt"
},
"Sword cane": {
"name": "Canne épée"
},
"Taser": {
"name": "Taser"
},
"Thompson": {
"name": "Thompson"
},
"Thrown Axe": {
"name": "Hache de lancer"
},
"Thrown Hand Grenade": {
"name": "Grenade à main de lancer"
},
"Thrown Heavy Spear": {
"name": "Lance lourde lancée"
},
"Thrown Knife": {
"name": "Couteau de lancer"
},
"Thrown Light Spear": {
"name": "Lance légère lancée"
},
"Thrown Long Spear": {
"name": "Lance longue lancée"
},
"Thrown Net": {
"name": "Filet"
},
"Thrown Rock": {
"name": "Pierre lancée"
},
"Thrown Short Spear": {
"name": "Lance courte lancée"
},
"Thrown Spear": {
"name": "Lance lancée"
},
"Thrown Spear, Heavy": {
"name": "Lance lancée, lourde"
},
"Thrown Spear, Light": {
"name": "Lance lancée, légère"
},
"Tomahawk": {
"name": "Tomahawk"
},
"Trident": {
"name": "Trident"
},
"Two-Handed sword": {
"name": "Epée à deux mains"
},
"Two-handed sword": {
"name": "Epée à deux mains"
},
"Very heavy sniper laser": {
"name": "Laser lourd de sniper"
},
"Very heavy sniper rifle": {
"name": "Fusil lourd de sniper"
},
"Very large pistol": {
"name": "Pistolet très gros calibre"
},
"WW1 Machinegun": {
"name": "Mitrailleuse de la Première Guerre mondiale"
},
"War club": {
"name": "Massue de guerre"
}
}
}

View File

@@ -183,6 +183,25 @@ i.fvtt-cthulhu-eternal {
color: var(--color-critical-failure); color: var(--color-critical-failure);
font-family: var(--font-title); font-family: var(--font-title);
} }
.chat-san-request ul .san-type-buttons,
.chat-lethal-damage ul .san-type-buttons {
display: flex;
justify-content: center;
align-items: center;
margin: 10px 0;
}
.chat-san-request ul .san-type-buttons button,
.chat-lethal-damage ul .san-type-buttons button {
margin: 0 2px;
font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 0.9);
border: none;
padding: 2px 2px;
cursor: pointer;
transition: background-color 0.3s;
min-width: 6rem;
max-width: 6rem;
}
.chat-san-request ul .san-loose-buttons, .chat-san-request ul .san-loose-buttons,
.chat-lethal-damage ul .san-loose-buttons { .chat-lethal-damage ul .san-loose-buttons {
display: flex; display: flex;
@@ -275,9 +294,7 @@ i.fvtt-cthulhu-eternal {
font-family: var(--font-primary); font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1.05); font-size: calc(var(--font-size-standard) * 1.05);
color: var(--color-dark-1); color: var(--color-dark-1);
background-image: var(--background-image-base); background: var(--color-light-1);
background-repeat: no-repeat;
background-size: 100% 100%;
--input-height: 1.4rem; --input-height: 1.4rem;
overflow: scroll; overflow: scroll;
} }
@@ -400,7 +417,7 @@ i.fvtt-cthulhu-eternal {
} }
.fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-left .protagonist-hp input { .fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-left .protagonist-hp input {
flex: none; flex: none;
width: 2rem; width: 4rem;
margin-left: 4px; margin-left: 4px;
} }
.fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-left .protagonist-hp .hp-separator { .fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-left .protagonist-hp .hp-separator {
@@ -806,7 +823,7 @@ i.fvtt-cthulhu-eternal {
} }
.fvtt-cthulhu-eternal .tab.protagonist-equipment .main-div .weapons { .fvtt-cthulhu-eternal .tab.protagonist-equipment .main-div .weapons {
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(1, 1fr);
gap: 4px; gap: 4px;
} }
.fvtt-cthulhu-eternal .tab.protagonist-equipment .main-div .weapons .weapon { .fvtt-cthulhu-eternal .tab.protagonist-equipment .main-div .weapons .weapon {
@@ -826,10 +843,24 @@ i.fvtt-cthulhu-eternal {
min-width: 1.8rem; min-width: 1.8rem;
max-width: 1.8rem; max-width: 1.8rem;
} }
.fvtt-cthulhu-eternal .tab.protagonist-equipment .main-div .weapons .weapon .damage { .fvtt-cthulhu-eternal .tab.protagonist-equipment .main-div .weapons .weapon .range {
min-width: 6rem; min-width: 6rem;
max-width: 6rem; max-width: 6rem;
} }
.fvtt-cthulhu-eternal .tab.protagonist-equipment .main-div .weapons .weapon .ammo {
min-width: 4rem;
max-width: 4rem;
}
.fvtt-cthulhu-eternal .tab.protagonist-equipment .main-div .weapons .weapon .lethality {
display: flex;
min-width: 3.2rem;
max-width: 3.2rem;
}
.fvtt-cthulhu-eternal .tab.protagonist-equipment .main-div .weapons .weapon .damage {
display: flex;
min-width: 12rem;
max-width: 12rem;
}
.fvtt-cthulhu-eternal .tab.protagonist-equipment .main-div .weapons .weapon .name { .fvtt-cthulhu-eternal .tab.protagonist-equipment .main-div .weapons .weapon .name {
min-width: 10rem; min-width: 10rem;
max-width: 10rem; max-width: 10rem;
@@ -977,9 +1008,7 @@ i.fvtt-cthulhu-eternal {
font-family: var(--font-primary); font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1.05); font-size: calc(var(--font-size-standard) * 1.05);
color: var(--color-dark-1); color: var(--color-dark-1);
background-image: var(--background-image-base); background: var(--color-light-1);
background-repeat: no-repeat;
background-size: 100% 100%;
--input-height: 1.4rem; --input-height: 1.4rem;
overflow: scroll; overflow: scroll;
} }
@@ -1235,9 +1264,7 @@ i.fvtt-cthulhu-eternal {
font-family: var(--font-primary); font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1.05); font-size: calc(var(--font-size-standard) * 1.05);
color: var(--color-dark-1); color: var(--color-dark-1);
background-image: var(--background-image-base); background: var(--color-light-1);
background-repeat: no-repeat;
background-size: 100% 100%;
--input-height: 1.4rem; --input-height: 1.4rem;
overflow: scroll; overflow: scroll;
} }
@@ -1297,6 +1324,25 @@ i.fvtt-cthulhu-eternal {
.fvtt-cthulhu-eternal .sheet-tabs { .fvtt-cthulhu-eternal .sheet-tabs {
background-color: var(--color-light-1); background-color: var(--color-light-1);
} }
.fvtt-cthulhu-eternal .creature-hp {
gap: 2px;
align-items: center;
}
.fvtt-cthulhu-eternal .creature-hp .form-fields input {
flex: none;
min-width: 4rem;
max-width: 4rem;
margin-left: 4px;
}
.fvtt-cthulhu-eternal .creature-hp .damage-bonus {
font-size: calc(var(--font-size-standard) * 0.8);
}
.fvtt-cthulhu-eternal .creature-hp .hp-separator {
font-size: calc(var(--font-size-standard) * 1.2);
display: flex;
align-items: center;
justify-content: center;
}
.fvtt-cthulhu-eternal .creature-main { .fvtt-cthulhu-eternal .creature-main {
background-color: var(--color-light-1); background-color: var(--color-light-1);
display: flex; display: flex;
@@ -1322,24 +1368,6 @@ i.fvtt-cthulhu-eternal {
width: auto; width: auto;
border: none; border: none;
} }
.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-left .creature-hp {
gap: 2px;
align-items: center;
}
.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-left .creature-hp input {
flex: none;
width: 2rem;
margin-left: 4px;
}
.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-left .creature-hp .damage-bonus {
font-size: calc(var(--font-size-standard) * 0.8);
}
.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-left .creature-hp .hp-separator {
font-size: calc(var(--font-size-standard) * 1.2);
display: flex;
align-items: center;
justify-content: center;
}
.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-left .creature-dv .form-fields, .fvtt-cthulhu-eternal .creature-main .creature-pc .creature-left .creature-dv .form-fields,
.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-left .creature-dmax .form-fields { .fvtt-cthulhu-eternal .creature-main .creature-pc .creature-left .creature-dmax .form-fields {
flex: none; flex: none;
@@ -1894,9 +1922,7 @@ i.fvtt-cthulhu-eternal {
font-family: var(--font-primary); font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1.05); font-size: calc(var(--font-size-standard) * 1.05);
color: var(--color-dark-1); color: var(--color-dark-1);
background-image: var(--background-image-base); background: var(--color-light-1);
background-repeat: no-repeat;
background-size: 100% 100%;
--input-height: 1.4rem; --input-height: 1.4rem;
} }
.fvtt-cthulhu-eternal .skill-content .sheet-tabs a { .fvtt-cthulhu-eternal .skill-content .sheet-tabs a {
@@ -1989,9 +2015,7 @@ i.fvtt-cthulhu-eternal {
font-family: var(--font-primary); font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1.05); font-size: calc(var(--font-size-standard) * 1.05);
color: var(--color-dark-1); color: var(--color-dark-1);
background-image: var(--background-image-base); background: var(--color-light-1);
background-repeat: no-repeat;
background-size: 100% 100%;
--input-height: 1.4rem; --input-height: 1.4rem;
} }
.fvtt-cthulhu-eternal .injury-content .sheet-tabs a { .fvtt-cthulhu-eternal .injury-content .sheet-tabs a {
@@ -2084,9 +2108,7 @@ i.fvtt-cthulhu-eternal {
font-family: var(--font-primary); font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1.05); font-size: calc(var(--font-size-standard) * 1.05);
color: var(--color-dark-1); color: var(--color-dark-1);
background-image: var(--background-image-base); background: var(--color-light-1);
background-repeat: no-repeat;
background-size: 100% 100%;
--input-height: 1.4rem; --input-height: 1.4rem;
} }
.fvtt-cthulhu-eternal .weapon-content .sheet-tabs a { .fvtt-cthulhu-eternal .weapon-content .sheet-tabs a {
@@ -2164,6 +2186,24 @@ i.fvtt-cthulhu-eternal {
margin-top: 8px; margin-top: 8px;
background-color: var(--color-light-1); background-color: var(--color-light-1);
} }
.fvtt-cthulhu-eternal .weapon-content fieldset input {
max-width: 5rem;
min-width: 5rem;
}
.fvtt-cthulhu-eternal .weapon-content fieldset select {
max-width: 14rem;
min-width: 14rem;
}
.fvtt-cthulhu-eternal .weapon-content fieldset input[type="checkbox"] {
max-width: 1.5rem;
min-width: 1.5rem;
}
.fvtt-cthulhu-eternal .weapon-content fieldset .flexrow > *:not(:first-child) {
margin-left: 1rem;
}
.fvtt-cthulhu-eternal .weapon-content fieldset .damage-distance {
margin-left: 2rem;
}
.fvtt-cthulhu-eternal .weapon-content label { .fvtt-cthulhu-eternal .weapon-content label {
flex: 10%; flex: 10%;
} }
@@ -2171,9 +2211,7 @@ i.fvtt-cthulhu-eternal {
font-family: var(--font-primary); font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1.05); font-size: calc(var(--font-size-standard) * 1.05);
color: var(--color-dark-1); color: var(--color-dark-1);
background-image: var(--background-image-base); background: var(--color-light-1);
background-repeat: no-repeat;
background-size: 100% 100%;
--input-height: 1.4rem; --input-height: 1.4rem;
} }
.fvtt-cthulhu-eternal .armor-content .sheet-tabs a { .fvtt-cthulhu-eternal .armor-content .sheet-tabs a {
@@ -2258,9 +2296,7 @@ i.fvtt-cthulhu-eternal {
font-family: var(--font-primary); font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1.05); font-size: calc(var(--font-size-standard) * 1.05);
color: var(--color-dark-1); color: var(--color-dark-1);
background-image: var(--background-image-base); background: var(--color-light-1);
background-repeat: no-repeat;
background-size: 100% 100%;
--input-height: 1.4rem; --input-height: 1.4rem;
} }
.fvtt-cthulhu-eternal .motivation-content .sheet-tabs a { .fvtt-cthulhu-eternal .motivation-content .sheet-tabs a {
@@ -2345,9 +2381,7 @@ i.fvtt-cthulhu-eternal {
font-family: var(--font-primary); font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1.05); font-size: calc(var(--font-size-standard) * 1.05);
color: var(--color-dark-1); color: var(--color-dark-1);
background-image: var(--background-image-base); background: var(--color-light-1);
background-repeat: no-repeat;
background-size: 100% 100%;
--input-height: 1.4rem; --input-height: 1.4rem;
} }
.fvtt-cthulhu-eternal .mentaldisorder-content .sheet-tabs a { .fvtt-cthulhu-eternal .mentaldisorder-content .sheet-tabs a {
@@ -2432,9 +2466,7 @@ i.fvtt-cthulhu-eternal {
font-family: var(--font-primary); font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1.05); font-size: calc(var(--font-size-standard) * 1.05);
color: var(--color-dark-1); color: var(--color-dark-1);
background-image: var(--background-image-base); background: var(--color-light-1);
background-repeat: no-repeat;
background-size: 100% 100%;
--input-height: 1.4rem; --input-height: 1.4rem;
} }
.fvtt-cthulhu-eternal .bond-content .sheet-tabs a { .fvtt-cthulhu-eternal .bond-content .sheet-tabs a {
@@ -2535,9 +2567,7 @@ i.fvtt-cthulhu-eternal {
font-family: var(--font-primary); font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1.05); font-size: calc(var(--font-size-standard) * 1.05);
color: var(--color-dark-1); color: var(--color-dark-1);
background-image: var(--background-image-base); background: var(--color-light-1);
background-repeat: no-repeat;
background-size: 100% 100%;
--input-height: 1.4rem; --input-height: 1.4rem;
} }
.fvtt-cthulhu-eternal .gear-content .sheet-tabs a { .fvtt-cthulhu-eternal .gear-content .sheet-tabs a {
@@ -2622,9 +2652,7 @@ i.fvtt-cthulhu-eternal {
font-family: var(--font-primary); font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1.05); font-size: calc(var(--font-size-standard) * 1.05);
color: var(--color-dark-1); color: var(--color-dark-1);
background-image: var(--background-image-base); background: var(--color-light-1);
background-repeat: no-repeat;
background-size: 100% 100%;
--input-height: 1.4rem; --input-height: 1.4rem;
} }
.fvtt-cthulhu-eternal .arcane-content .sheet-tabs a { .fvtt-cthulhu-eternal .arcane-content .sheet-tabs a {
@@ -2709,9 +2737,7 @@ i.fvtt-cthulhu-eternal {
font-family: var(--font-primary); font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1.05); font-size: calc(var(--font-size-standard) * 1.05);
color: var(--color-dark-1); color: var(--color-dark-1);
background-image: var(--background-image-base); background: var(--color-light-1);
background-repeat: no-repeat;
background-size: 100% 100%;
--input-height: 1.4rem; --input-height: 1.4rem;
} }
.fvtt-cthulhu-eternal .archetype-content .sheet-tabs a { .fvtt-cthulhu-eternal .archetype-content .sheet-tabs a {
@@ -2796,9 +2822,7 @@ i.fvtt-cthulhu-eternal {
font-family: var(--font-primary); font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1.05); font-size: calc(var(--font-size-standard) * 1.05);
color: var(--color-dark-1); color: var(--color-dark-1);
background-image: var(--background-image-base); background: var(--color-light-1);
background-repeat: no-repeat;
background-size: 100% 100%;
--input-height: 1.4rem; --input-height: 1.4rem;
} }
.fvtt-cthulhu-eternal .ritual-content .sheet-tabs a { .fvtt-cthulhu-eternal .ritual-content .sheet-tabs a {
@@ -2891,9 +2915,7 @@ i.fvtt-cthulhu-eternal {
font-family: var(--font-primary); font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1.05); font-size: calc(var(--font-size-standard) * 1.05);
color: var(--color-dark-1); color: var(--color-dark-1);
background-image: var(--background-image-base); background: var(--color-light-1);
background-repeat: no-repeat;
background-size: 100% 100%;
--input-height: 1.4rem; --input-height: 1.4rem;
} }
.fvtt-cthulhu-eternal .tome-content .sheet-tabs a { .fvtt-cthulhu-eternal .tome-content .sheet-tabs a {
@@ -3019,6 +3041,9 @@ i.fvtt-cthulhu-eternal {
font-size: calc(var(--font-size-standard) * 2); font-size: calc(var(--font-size-standard) * 2);
color: var(--color-dark-1); color: var(--color-dark-1);
} }
.li-apply-wounds {
display: none;
}
.dice-roll { .dice-roll {
flex-direction: column; flex-direction: column;
} }

View File

@@ -29,6 +29,12 @@ Hooks.once("init", function () {
models, models,
documents, documents,
} }
// Set an initiative formula for the system
CONFIG.Combat.initiative = {
formula: "@characteristics.dex.value",
decimals: 1
};
CONFIG.Actor.documentClass = documents.CthulhuEternalActor CONFIG.Actor.documentClass = documents.CthulhuEternalActor
CONFIG.Actor.dataModels = { CONFIG.Actor.dataModels = {
@@ -93,13 +99,14 @@ Hooks.once("init", function () {
CthulhuEternalUtils.registerSettings() CthulhuEternalUtils.registerSettings()
CthulhuEternalUtils.registerHandlebarsHelpers() CthulhuEternalUtils.registerHandlebarsHelpers()
CthulhuEternalUtils.setupCSSRootVariables() CthulhuEternalUtils.setupCSSRootVariables()
CONFIG.debug.hooks = false;
console.info("CTHULHU ETERNAL | System Initialized") console.info("CTHULHU ETERNAL | System Initialized")
}) })
Hooks.once('babele.init', (babele) => { Hooks.once('babele.init', (babele) => {
babele.setSystemTranslationsDir("compendiums"); babele.setSystemTranslationsDir("compendiums");
CthulhuEternalUtils.registerBabeleTranslations(babele);
}); });
/** /**
@@ -151,7 +158,8 @@ Hooks.on("renderChatMessageHTML", (message, html, data) => {
CthulhuEternalUtils.nudgeRoll(message) CthulhuEternalUtils.nudgeRoll(message)
}) })
$(html).find(".damage-roll").click((event) => { $(html).find(".damage-roll").click((event) => {
CthulhuEternalUtils.damageRoll(message) let formula = $(event.currentTarget).data("roll-value")
CthulhuEternalUtils.damageRoll(message, formula)
}) })
$(html).find(".healing-roll").click((event) => { $(html).find(".healing-roll").click((event) => {
CthulhuEternalUtils.healingRoll(message) CthulhuEternalUtils.healingRoll(message)
@@ -163,6 +171,15 @@ Hooks.on("renderChatMessageHTML", (message, html, data) => {
CthulhuEternalUtils.applySANType(message, event) CthulhuEternalUtils.applySANType(message, event)
}) })
} }
if (game.user.isGM) {
$(html).find(".li-apply-wounds").each((i, btn) => {
btn.style.display = "inline"
})
$(html).find(".li-apply-wounds-select").click((event) => {
CthulhuEternalUtils.applyWounds(message, event)
})
}
}) })
/** /**

View File

@@ -212,6 +212,7 @@
"UnarmedCombat": "Unarmed Combat", "UnarmedCombat": "Unarmed Combat",
"RangedWeapons": "Ranged Weapons", "RangedWeapons": "Ranged Weapons",
"FirearmsBeams": "Firearms / Beam Weapons", "FirearmsBeams": "Firearms / Beam Weapons",
"MilitaryTrainingExplosive": "Military Training (Explosives)",
"FIELDS": { "FIELDS": {
"isHealing": { "isHealing": {
"label": "Healing skill" "label": "Healing skill"
@@ -268,7 +269,8 @@
"rangedprimitive": "Ranged Primitive", "rangedprimitive": "Ranged Primitive",
"rangedthrown": "Ranged Thrown", "rangedthrown": "Ranged Thrown",
"rangedfirearm": "Ranged Firearm", "rangedfirearm": "Ranged Firearm",
"unarmed": "Unarmed" "unarmed": "Unarmed",
"rangedexplosive": "Explosive"
}, },
"WeaponSubtype": { "WeaponSubtype": {
"basicfirearm": "Basic Firearm", "basicfirearm": "Basic Firearm",
@@ -283,7 +285,41 @@
"shortspray": "Short Spray", "shortspray": "Short Spray",
"longspray": "Long Spray" "longspray": "Long Spray"
}, },
"Target": {
"Normal": "Normal",
"Stationary": "Stationary",
"MovingRange": "Moving or on the ground",
"MovingFast": "Moving Fast (ie running)",
"MovingVeryFast": "Moving Very Fast",
"HalfCovered": "Half Covered",
"Covered": "Full Covered"
},
"Range": {
"PointBlank": "Point Blank",
"Normal": "Normal",
"Range2x": "Up to Range x2",
"Range5x": "Up to Range x5"
},
"Visibility": {
"Clear": "Clear",
"Obscured": "Obscured",
"Darkness": "Darkness"
},
"Attacker": {
"Normal": "Normal",
"Irritated": "Irritated/Annoyed",
"Corrosive": "Deeply Annoyed"
},
"FIELDS": { "FIELDS": {
"hasDamageDistance": {
"label": "Is damage distance based?"
},
"hasSight": {
"label": "Has sight"
},
"isStunning": {
"label": "Is Stunning"
},
"hasDirectSkill": { "hasDirectSkill": {
"label": "Has direct skill" "label": "Has direct skill"
}, },
@@ -526,11 +562,14 @@
"Unnatural": "Unnatural", "Unnatural": "Unnatural",
"sanLossViolence": "You suffered a SAN loss due to violence : violence progress path has evolved.", "sanLossViolence": "You suffered a SAN loss due to violence : violence progress path has evolved.",
"sanLossHelplessness": "You suffered a SAN loss due to helplessness : helplessness progress path has evolved.", "sanLossHelplessness": "You suffered a SAN loss due to helplessness : helplessness progress path has evolved.",
"SANLossUnnatural": "You suffered a SAN loss due to unnatural : you may gain an Unnatural skill, check with the GM.",
"SANLossNone": "You suffered a SAN loss, but no special consequences apply.",
"adaptedToViolence": "You are now : Adapted to Violence.", "adaptedToViolence": "You are now : Adapted to Violence.",
"adaptedToViolenceShort": "Adapted to Violence", "adaptedToViolenceShort": "Adapted to Violence",
"adaptedToHelplessness": "You are now : Adapted to Helplessness.", "adaptedToHelplessness": "You are now : Adapted to Helplessness.",
"adaptedToHelplessnessShort": "Adapted to Helplessness", "adaptedToHelplessnessShort": "Adapted to Helplessness",
"SANTest": "You just rolled a SAN test : please select the SAN loss with the buttons below.", "SANTestSuccess": "You just rolled a SAN test with success, but you may still loose SAN points. Select the value of SAN loss with the buttons below.",
"SANTestFailure": "You just rolled a SAN test with failure, you loose SAN points. Select the value of SAN loss with the buttons below.",
"breakingPointReached": "Your SAN has reached your Breaking Point : you suffer a disorder (to be discussed with the GM). Reset the BP to its new value.", "breakingPointReached": "Your SAN has reached your Breaking Point : you suffer a disorder (to be discussed with the GM). Reset the BP to its new value.",
"rollNudge": "Roll Nudge", "rollNudge": "Roll Nudge",
"rollDamage": "Roll Damage", "rollDamage": "Roll Damage",
@@ -613,6 +652,11 @@
"biography": "Biography", "biography": "Biography",
"notes": "Notes", "notes": "Notes",
"weapons": "Weapons", "weapons": "Weapons",
"melee": "Melee",
"Lethality": "Lethality",
"baseRange": "Base Range",
"Ammo": "Ammo",
"armorPiercing": "Armor Piercing",
"HP": "HP", "HP": "HP",
"SAN": "SAN", "SAN": "SAN",
"current": "Current", "current": "Current",
@@ -678,7 +722,16 @@
"killRadiusInfo": "All targets within the kill radius suffer the damage", "killRadiusInfo": "All targets within the kill radius suffer the damage",
"ammoUsed": "Ammo used", "ammoUsed": "Ammo used",
"lethalityLethal": "Lethal !!", "lethalityLethal": "Lethal !!",
"lethalityNotLethal": "Non-Lethal" "lethalityNotLethal": "Non-Lethal",
"WPSpent": "WP Spent",
"targetMove": "Target Move",
"attackerState": "Attacker State",
"targetSize": "Target Size",
"visibility": "Visibility",
"rangedRange": "Range",
"aimingLastRound": "Aiming Last Round (+20)",
"aimingWithSight": "Aiming with Sight (+20)",
"applyWounds": "Apply To"
}, },
"ChatMessage": { "ChatMessage": {
"exhausted": "Your protagonist is exhausted. He loses [[/r 1d6]] Willpower Points." "exhausted": "Your protagonist is exhausted. He loses [[/r 1d6]] Willpower Points."
@@ -699,9 +752,13 @@
"Tooltip": { "Tooltip": {
"sanBP": ">5 SAN lost in one roll, temporary insanity. If SAN less reaches BP = a Disorder unconscious Breaking and AND reset BP.", "sanBP": ">5 SAN lost in one roll, temporary insanity. If SAN less reaches BP = a Disorder unconscious Breaking and AND reset BP.",
"setBP": "Set the current Breaking Point based on the current SAN value", "setBP": "Set the current Breaking Point based on the current SAN value",
"addBond": "Add a new Bond" "addBond": "Add a new Bond",
"rollDamage": "Roll Damage"
}, },
"Chat": { "Chat": {
"noArmor": "No armor absorbed damage.",
"armorAbsorbed": "Armor absorbed {armor} damage.",
"woundsApplied": "Wounds applied to {name}: {effectiveWounds} (armor absorbed : {armorText})"
}, },
"Notifications": { "Notifications": {
"NoWeaponSkill": "No weapon skill found for this weapon. Check Weapon definition or available skills/era", "NoWeaponSkill": "No weapon skill found for this weapon. Check Weapon definition or available skills/era",

View File

@@ -224,6 +224,7 @@
"UnarmedCombat": "Combat à mains nues", "UnarmedCombat": "Combat à mains nues",
"RangedWeapons": "Armes de tir", "RangedWeapons": "Armes de tir",
"FirearmsBeams": "Armes à feu / à rayons", "FirearmsBeams": "Armes à feu / à rayons",
"MilitaryTrainingExplosive": "Entraînement militaire (Explosifs)",
"FIELDS": { "FIELDS": {
"isHealing": { "isHealing": {
"label": "Compétence de soin" "label": "Compétence de soin"
@@ -280,7 +281,8 @@
"rangedprimitive": "A distance - Primitive", "rangedprimitive": "A distance - Primitive",
"rangedthrown": "A distance - Lancer", "rangedthrown": "A distance - Lancer",
"rangedfirearm": "A distance - Arme à feu", "rangedfirearm": "A distance - Arme à feu",
"unarmed": "Non armé" "unarmed": "Non armé",
"rangedexplosive": "Explosif"
}, },
"WeaponSubtype": { "WeaponSubtype": {
"basicfirearm": "Arme à feu de base", "basicfirearm": "Arme à feu de base",
@@ -295,7 +297,41 @@
"shortspray": "Barrage court", "shortspray": "Barrage court",
"longspray": "Barrage long" "longspray": "Barrage long"
}, },
"Target": {
"Normal": "Normal",
"Stationary": "Immobile (+20)",
"MovingRange": "En mouvement ou au sol (-20)",
"MovingFast": "En mouvement rapide (ie course) (-20)",
"MovingVeryFast": "En mouvement très rapide (ie véhicule) (-40)",
"HalfCovered": "A moitié couvert (-20)",
"Covered": "A Couvert (-40)"
},
"Range": {
"PointBlank": "Bout portant (+20)",
"Normal": "Normal",
"Range2x": "de portée à portée x2 (-20)",
"Range5x": "de portéex2 à portée x5 (-40)"
},
"Visibility": {
"Clear": "Normale",
"Obscured": "Obscurci (-20)",
"Darkness": "Obscurité (-40)"
},
"Attacker": {
"Normal": "Normal",
"Irritated": "Irrité/Gêné (-20)",
"Corrosive": "Fortement gêné (-40)"
},
"FIELDS": { "FIELDS": {
"hasDamageDistance": {
"label": "Dégâts basés sur la distance ?"
},
"hasSight": {
"label": "Lunette de visée"
},
"isStunning": {
"label": "Etourdissante"
},
"ammo": { "ammo": {
"label": "Munitions", "label": "Munitions",
"value": { "value": {
@@ -528,20 +564,30 @@
} }
}, },
"Label": { "Label": {
"feet": "pieds (ie 30cm)",
"feets": "pieds (ie 30cm)",
"yard": "mètres",
"Yard": "mètres",
"yards": "mètres",
"Feet": "Pieds",
"Yards": "Mètres",
"sanLoss5": "Perte de SAN de 5+ ({value}) : vous souffrez d'une folie temporaire (Fuite, Soumission, Lutte ou compréhension de l'Inconcevable).", "sanLoss5": "Perte de SAN de 5+ ({value}) : vous souffrez d'une folie temporaire (Fuite, Soumission, Lutte ou compréhension de l'Inconcevable).",
"sanViolenceReset": "Le décompte des pertes de SAN de violence a été réinitialisé.", "sanViolenceReset": "Le décompte des pertes de SAN de violence a été réinitialisé.",
"sanHelplessnessReset": "Le décompte des pertes de SAN d'impuissance a été réinitialisé.", "sanHelplessnessReset": "Le décompte des pertes de SAN d'impuissance a été réinitialisé.",
"sanLoss": "Perte de SAN", "sanLoss": "Vous venez de perdre des points de SAN",
"noSanLoss": "Aucune perte de SAN", "noSanLoss": "Aucune perte de SAN",
"sanLossInfo": "Sélectionnez la perte de SAN à l'aide des boutons ci-dessous.", "sanLossInfo": "Sélectionnez la perte de SAN à l'aide des boutons ci-dessous.",
"selectSANType": "Sélectionnez le type de perte de SAN à l'aide des boutons ci-dessous.", "selectSANType": "Sélectionnez maintenant le type SAN perdue à l'aide des boutons ci-dessous.",
"sanLossViolence": "Vous avez subi une perte de SAN due à la violence : le chemin de progression de la violence a évolué.", "sanLossViolence": "Vous avez subi une perte de SAN due à la violence : le chemin de progression de la violence a évolué.",
"sanLossHelplessness": "Vous avez subi une perte de SAN due à l'impuissance : le chemin de progression de l'impuissance a évolué.", "sanLossHelplessness": "Vous avez subi une perte de SAN due à l'impuissance : le chemin de progression de l'impuissance a évolué.",
"SANLossUnnatural": "Vous avez subi une perte de SAN due à l'inconcevable : vous pouvez peut-être faire progresser la compétence Inconcevable, vérifiez avec le MJ.",
"SANLossNone": "Vous avez subi une perte de SAN, mais aucune conséquence spéciale n'est appliquée.",
"adaptedToViolence": "Vous êtes maintenant : Habitué à la violence", "adaptedToViolence": "Vous êtes maintenant : Habitué à la violence",
"adaptedToViolenceShort": "Habitué à la violence", "adaptedToViolenceShort": "Habitué à la violence",
"adaptedToHelplessness": "Vous êtes maintenant : Habitué à l'impuissance", "adaptedToHelplessness": "Vous êtes maintenant : Habitué à l'impuissance",
"adaptedToHelplessnessShort": "Habitué à l'impuissance", "adaptedToHelplessnessShort": "Habitué à l'impuissance",
"SANTest": "Vous venez de faire un jet de SAN : selectionnez la perte de SAN à l'aide des boutons ci-dessous.", "SANTestSuccess": "Vous venez de réussir votre jet de SAN, mais vous pouvez toujours perdre des points de SAN. Sélectionnez la valeur à l'aide des boutons ci-dessous.",
"SANTestFailure": "Vous venez d'échouer votre test de SAN, vous perdez des points de SAN. Sélectionnez la valeur à l'aide des boutons ci-dessous.",
"breakingPointReached": "Vous avez atteint votre Point de Rupture (PR) : vous souffrez d'un trouble mental. Vous devez re-initialiser votre PR à l'aide du bouton disponible dans la section SAN de la fiche de PJ.", "breakingPointReached": "Vous avez atteint votre Point de Rupture (PR) : vous souffrez d'un trouble mental. Vous devez re-initialiser votre PR à l'aide du bouton disponible dans la section SAN de la fiche de PJ.",
"Violence" : "Violence", "Violence" : "Violence",
"Helplessness": "Impuissance", "Helplessness": "Impuissance",
@@ -627,6 +673,11 @@
"biography": "Biographie", "biography": "Biographie",
"notes": "Notes", "notes": "Notes",
"weapons": "Armes", "weapons": "Armes",
"melee": "Mêlée",
"Lethality": "Létalité",
"baseRange": "Portée de base",
"Ammo": "Munitions",
"armorPiercing": "Pénétration d'armure",
"HP": "PV", "HP": "PV",
"SAN": "SAN", "SAN": "SAN",
"current": "Actuel", "current": "Actuel",
@@ -692,7 +743,16 @@
"killRadiusInfo": "Si la cible est dans le rayon de mortalité, elle subit les dommages.", "killRadiusInfo": "Si la cible est dans le rayon de mortalité, elle subit les dommages.",
"ammoUsed": "Munitions utilisées", "ammoUsed": "Munitions utilisées",
"lethalityLethal": "Létal !!", "lethalityLethal": "Létal !!",
"lethalityNotLethal": "Non létal" "lethalityNotLethal": "Non létal",
"WPSpent": "PVO dépensés",
"targetMove": "Mouvement de la cible",
"attackerState": "Etat de l'attaquant",
"targetSize": "Taille de la cible",
"visibility": "Visibilité",
"rangedRange": "Portée",
"aimingLastRound": "Visée lors du dernier round (+20)",
"aimingWithSight": "Visée avec lunette (+20)",
"applyWounds": "Appliquer à"
}, },
"ChatMessage": { "ChatMessage": {
"exhausted": "Votre protagoniste est épuisé. Il perd [[/r 1d6]] Points de Volonté." "exhausted": "Votre protagoniste est épuisé. Il perd [[/r 1d6]] Points de Volonté."
@@ -713,9 +773,13 @@
"Tooltip": { "Tooltip": {
"sanBP": "Perte de 5+ SAN en 1 jet : folie temporaire. SI la SAN atteint le PR : trouble mental, perte de conscience et reset du PR.", "sanBP": "Perte de 5+ SAN en 1 jet : folie temporaire. SI la SAN atteint le PR : trouble mental, perte de conscience et reset du PR.",
"setBP": "Positionner le Point de Rupture à la valeur courant de la SAN", "setBP": "Positionner le Point de Rupture à la valeur courant de la SAN",
"addBond": "Ajouter une Attache" "addBond": "Ajouter une Attache",
"rollDamage": "Lancer les dégâts"
}, },
"Chat": { "Chat": {
"armorAbsorbed": "L'armure a absorbé {armor} points de dégâts.",
"noArmor": "Pas d'armure.",
"woundsApplied": "Blessures appliquées à {name} : {effectiveWounds} (armure absorbée : {armorText})"
}, },
"Notifications": { "Notifications": {
"NoWeaponSkill": "Aucune compétence associée n'a été trouvé pour cette arme. Vérifier la définition de l'arme ainsi que l'époque configurée.", "NoWeaponSkill": "Aucune compétence associée n'a été trouvé pour cette arme. Vérifier la définition de l'arme ainsi que l'époque configurée.",

19
macro_roll.js Normal file
View File

@@ -0,0 +1,19 @@
let nb = 10000
let sum = 0
let results = []
for (let i = 0; i < nb; i++) {
let r = new Roll("1d100")
await r.evaluate()
sum += r.total
results.push(r.total)
}
let mean = sum / nb
let variance = results.reduce((acc, val) => acc + Math.pow(val - mean, 2), 0) / nb
let stddev = Math.sqrt(variance)
console.log("Average : ", mean)
console.log("Standard deviation : ", stddev)
console.log("Coefficient of variation : ", stddev / mean )
console.log("Min : ", Math.min(...results))
console.log("Max : ", Math.max(...results))

View File

@@ -98,10 +98,20 @@ export default class CthulhuEternalProtagonistSheet extends CthulhuEternalActorS
switch (partId) { switch (partId) {
case "main": case "main":
break break
case "skills": case "skills": {
context.tab = context.tabs.skills context.tab = context.tabs.skills
context.skills = doc.itemTypes.skill let tmpSkills = doc.itemTypes.skill
context.skills.sort((a, b) => a.name.localeCompare(b.name)) tmpSkills.sort((a, b) => a.name.localeCompare(b.name))
const nbCols = 3;
const nbRows = Math.ceil(tmpSkills.length / nbCols);
let skillsColumns = Array.from({ length: nbRows }, (_, rowIdx) =>
Array.from({ length: nbCols }, (_, colIdx) => tmpSkills[rowIdx + colIdx * nbRows]).filter(Boolean)
);
// Merge skillsColumns in a single flat array
skillsColumns = skillsColumns.flat().filter(Boolean);
//DEBUG : console.log("Skills columns:", skillsColumns);
context.skills = skillsColumns
}
break break
case "equipment": case "equipment":
context.tab = context.tabs.equipment context.tab = context.tabs.equipment
@@ -225,6 +235,7 @@ export default class CthulhuEternalProtagonistSheet extends CthulhuEternalActorS
case "damage": case "damage":
li = $(event.currentTarget).parents(".item"); li = $(event.currentTarget).parents(".item");
item = this.actor.items.get(li.data("item-id")); item = this.actor.items.get(li.data("item-id"));
item.damageFormula = $(event.currentTarget).data("roll-value") || item.system.damage
item.damageBonus = this.actor.system.damageBonus item.damageBonus = this.actor.system.damageBonus
break break
case "san": case "san":

View File

@@ -46,7 +46,7 @@ export const ERA_CSS = {
modern: { primaryFont: "Georama", secondaryFont: "Georama", titleFont: "Georama", baseFontSize: "1.0rem", titleFontSize: "1.2rem",imgFilter: "brightness(0) saturate(100%) invert(92%) sepia(11%) saturate(1214%) hue-rotate(51deg) brightness(93%) contrast(86%)" }, modern: { primaryFont: "Georama", secondaryFont: "Georama", titleFont: "Georama", baseFontSize: "1.0rem", titleFontSize: "1.2rem",imgFilter: "brightness(0) saturate(100%) invert(92%) sepia(11%) saturate(1214%) hue-rotate(51deg) brightness(93%) contrast(86%)" },
future: { primaryFont: "Georama", secondaryFont: "Georama", titleFont: "Seabreed", baseFontSize: "1.0rem", titleFontSize: "2.0rem",imgFilter: "invert(90%) sepia(6%) saturate(1818%) hue-rotate(152deg) brightness(91%) contrast(91%)" }, future: { primaryFont: "Georama", secondaryFont: "Georama", titleFont: "Seabreed", baseFontSize: "1.0rem", titleFontSize: "2.0rem",imgFilter: "invert(90%) sepia(6%) saturate(1818%) hue-rotate(152deg) brightness(91%) contrast(91%)" },
victorian: { primaryFont: "Volkhov", secondaryFont: "Volkhov", titleFont: "Excelsior", baseFontSize: "1.0rem", titleFontSize: "1.2rem",imgFilter: "brightness(0) saturate(100%) invert(100%) sepia(59%) saturate(1894%) hue-rotate(337deg) brightness(88%) contrast(98%)" }, victorian: { primaryFont: "Volkhov", secondaryFont: "Volkhov", titleFont: "Excelsior", baseFontSize: "1.0rem", titleFontSize: "1.2rem",imgFilter: "brightness(0) saturate(100%) invert(100%) sepia(59%) saturate(1894%) hue-rotate(337deg) brightness(88%) contrast(98%)" },
coldwar: { primaryFont: "Georama", secondaryFont: "Georama", titleFont: "TopSecret", baseFontSize: "1.0rem", titleFontSize: "1.2rem",imgFilter: "brightness(0) saturate(100%) invert(81%) sepia(14%) saturate(2508%) hue-rotate(202deg) brightness(99%) contrast(105%)"}, coldwar: { primaryFont: "Georama", secondaryFont: "Georama", titleFont: "TopSecret", baseFontSize: "0.9rem", titleFontSize: "1.2rem",imgFilter: "brightness(0) saturate(100%) invert(81%) sepia(14%) saturate(2508%) hue-rotate(202deg) brightness(99%) contrast(105%)"},
revolution: { primaryFont: "IMFell", secondaryFont: "IMFell", titleFont: "Dominican", baseFontSize: "1.0rem",titleFontSize: "1.3rem",imgFilter: "brightness(0) saturate(100%) invert(81%) sepia(25%) saturate(386%) hue-rotate(7deg) brightness(101%) contrast(84%)" }, revolution: { primaryFont: "IMFell", secondaryFont: "IMFell", titleFont: "Dominican", baseFontSize: "1.0rem",titleFontSize: "1.3rem",imgFilter: "brightness(0) saturate(100%) invert(81%) sepia(25%) saturate(386%) hue-rotate(7deg) brightness(101%) contrast(84%)" },
medieval: { primaryFont: "Skranji", secondaryFont: "UncialAntiqua", titleFont: "Luminari", baseFontSize: "0.9rem",titleFontSize: "1.2rem",imgFilter: "brightness(0) saturate(100%) invert(93%) sepia(46%) saturate(354%) hue-rotate(321deg) brightness(93%) contrast(87%)"}, medieval: { primaryFont: "Skranji", secondaryFont: "UncialAntiqua", titleFont: "Luminari", baseFontSize: "0.9rem",titleFontSize: "1.2rem",imgFilter: "brightness(0) saturate(100%) invert(93%) sepia(46%) saturate(354%) hue-rotate(321deg) brightness(93%) contrast(87%)"},
ww2: { primaryFont: "SairaStencilOne", secondaryFont: "SairaStencilOne", titleFont: "Armalite", baseFontSize: "0.9rem",titleFontSize: "1.2rem",imgFilter: "filter: invert(44%) sepia(8%) saturate(2657%) hue-rotate(40deg) brightness(96%) contrast(75%)"}, ww2: { primaryFont: "SairaStencilOne", secondaryFont: "SairaStencilOne", titleFont: "Armalite", baseFontSize: "0.9rem",titleFontSize: "1.2rem",imgFilter: "filter: invert(44%) sepia(8%) saturate(2657%) hue-rotate(40deg) brightness(96%) contrast(75%)"},
@@ -77,6 +77,96 @@ export const RESOURCE_RATING = {
19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichModern"}, 19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichModern"},
20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichModern"} 20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichModern"}
}, },
future: {
0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"},
4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorModern"},
8: {name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageModern"},
12: {name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageModern"},
16: {name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffModern"},
18: {name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 20000, assets: "CTHULHUETERNAL.Resource.RichModern"},
19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichModern"},
20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichModern"}
},
coldwar: {
0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"},
4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar"},
8: {name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar"},
12: {name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar"},
16: {name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar"},
18: {name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar"},
19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar"},
20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar"}
},
ww1: {
0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"},
4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar"},
8: {name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar"},
12: {name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar"},
16: {name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar"},
18: {name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar"},
19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar"},
20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar"}
},
ww2: {
0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"},
4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar"},
8: {name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar"},
12: {name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar"},
16: {name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar"},
18: {name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar"},
19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar"},
20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar"}
},
medieval: {
0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"},
4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar"},
8: {name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar"},
12: {name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar"},
16: {name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar"},
18: {name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar"},
19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar"},
20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar"}
},
revolution: {
0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"},
4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar"},
8: {name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar"},
12: {name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar"},
16: {name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar"},
18: {name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar"},
19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar"},
20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar"}
},
ageofsail: {
0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"},
4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar"},
8: {name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar"},
12: {name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar"},
16: {name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar"},
18: {name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar"},
19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar"},
20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar"}
},
classical: {
0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"},
4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar"},
8: {name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar"},
12: {name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar"},
16: {name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar"},
18: {name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar"},
19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar"},
20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar"}
},
postapo: {
0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"},
4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar"},
8: {name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar"},
12: {name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar"},
16: {name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar"},
18: {name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar"},
19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar"},
20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar"}
},
victorian: { victorian: {
0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"}, 0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"},
4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 30, assets: "CTHULHUETERNAL.Resource.PoorVictorian"}, 4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 30, assets: "CTHULHUETERNAL.Resource.PoorVictorian"},
@@ -154,7 +244,8 @@ export const WEAPON_SKILL_MAPPING = {
"rangedprimitive": "CTHULHUETERNAL.Skill.Firearms", "rangedprimitive": "CTHULHUETERNAL.Skill.Firearms",
"rangedthrown": "CTHULHUETERNAL.Skill.Athletics", "rangedthrown": "CTHULHUETERNAL.Skill.Athletics",
"rangedfirearm": "CTHULHUETERNAL.Skill.Firearms", "rangedfirearm": "CTHULHUETERNAL.Skill.Firearms",
"unarmed": "CTHULHUETERNAL.Skill.UnarmedCombat" "unarmed": "CTHULHUETERNAL.Skill.UnarmedCombat",
"rangedexplosive": "CTHULHUETERNAL.Skill.MilitaryTrainingExplosive"
}, },
victorian: { victorian: {
"melee": "CTHULHUETERNAL.Skill.Melee", "melee": "CTHULHUETERNAL.Skill.Melee",
@@ -245,6 +336,45 @@ export const WEAPON_SELECTIVE_FIRE_CHOICES = {
"longspray": { id: "longspray", label: "CTHULHUETERNAL.Weapon.SelectiveFire.longspray", ammoUsed: 20, lethality: 10, killRadius: 3}, "longspray": { id: "longspray", label: "CTHULHUETERNAL.Weapon.SelectiveFire.longspray", ammoUsed: 20, lethality: 10, killRadius: 3},
} }
// Melee stuff
export const WEAPON_MELEE_TARGET_MOVE = {
"normal": { id: "normal", label: "CTHULHUETERNAL.Weapon.Target.Normal", modifier: 0 },
"stationary": { id: "stationary", label: "CTHULHUETERNAL.Weapon.Target.Stationary", modifier: 20 },
"movingfast": { id: "movingfast", label: "CTHULHUETERNAL.Weapon.Target.MovingFast", modifier: -20 },
"movingveryfast": { id: "movingveryfast", label: "CTHULHUETERNAL.Weapon.Target.MovingVeryFast", modifier: -40 },
}
// Ranged stuff
export const WEAPON_RANGED_RANGE = {
"pointblank": { id: "pointblank", label: "CTHULHUETERNAL.Weapon.Range.PointBlank", modifier: +20 },
"normal": { id: "normal", label: "CTHULHUETERNAL.Weapon.Range.Normal", modifier: 0 },
"range2x": { id: "range2x", label: "CTHULHUETERNAL.Weapon.Range.Range2x", modifier: -20 },
"range5x": { id: "range5x", label: "CTHULHUETERNAL.Weapon.Range.Range5x", modifier: -40 }
}
export const WEAPON_RANGED_TARGET_MOVE = {
"normal": { id: "normal", label: "CTHULHUETERNAL.Weapon.Target.Normal", modifier: 0 },
"stationary": { id: "stationary", label: "CTHULHUETERNAL.Weapon.Target.Stationary", modifier: 20 },
"movingfast": { id: "movingfast", label: "CTHULHUETERNAL.Weapon.Target.MovingRange", modifier: -20 },
"movingveryfast": { id: "movingveryfast", label: "CTHULHUETERNAL.Weapon.Target.MovingVeryFast", modifier: -40 },
}
// Common stuff
export const WEAPON_ATTACKER_STATE = {
"normal": { id: "normal", label: "CTHULHUETERNAL.Weapon.Target.Normal", modifier: 0 },
"irritated": { id: "irritated", label: "CTHULHUETERNAL.Weapon.Attacker.Irritated", modifier: -20 },
"corrosive": { id: "corrosive", label: "CTHULHUETERNAL.Weapon.Attacker.Corrosive", modifier: -40 },
}
export const WEAPON_TARGET_SIZE = {
"normal": { id: "normal", label: "CTHULHUETERNAL.Weapon.Target.Normal", modifier: 0 },
"halfcovered": { id: "halfcovered", label: "CTHULHUETERNAL.Weapon.Target.HalfCovered", modifier: -20 },
"covered": { id: "covered", label: "CTHULHUETERNAL.Weapon.Target.Covered", modifier: -40 },
}
export const WEAPON_VISIBILITY = {
"clear": { id: "clear", label: "CTHULHUETERNAL.Weapon.Visibility.Clear", modifier: 0 },
"obscured": { id: "obscured", label: "CTHULHUETERNAL.Weapon.Visibility.Obscured", modifier: -20 },
"darkness": { id: "darkness", label: "CTHULHUETERNAL.Weapon.Visibility.Darkness", modifier: -40 },
}
export const RITUAL_TYPES = { export const RITUAL_TYPES = {
"simple": "CTHULHUETERNAL.Ritual.Simple", "simple": "CTHULHUETERNAL.Ritual.Simple",
"difficult": "CTHULHUETERNAL.Ritual.Difficult", "difficult": "CTHULHUETERNAL.Ritual.Difficult",
@@ -277,5 +407,11 @@ export const SYSTEM = {
MULTIPLIER_CHOICES, MULTIPLIER_CHOICES,
ASCII, ASCII,
DAMAGE_BONUS, DAMAGE_BONUS,
RITUAL_TYPES RITUAL_TYPES,
WEAPON_MELEE_TARGET_MOVE,
WEAPON_RANGED_RANGE,
WEAPON_RANGED_TARGET_MOVE,
WEAPON_ATTACKER_STATE,
WEAPON_TARGET_SIZE,
WEAPON_VISIBILITY
} }

View File

@@ -3,7 +3,8 @@ export const WEAPON_TYPE = {
"rangedprimitive": "CTHULHUETERNAL.Weapon.WeaponType.rangedprimitive", "rangedprimitive": "CTHULHUETERNAL.Weapon.WeaponType.rangedprimitive",
"rangedthrown": "CTHULHUETERNAL.Weapon.WeaponType.rangedthrown", "rangedthrown": "CTHULHUETERNAL.Weapon.WeaponType.rangedthrown",
"rangedfirearm": "CTHULHUETERNAL.Weapon.WeaponType.rangedfirearm", "rangedfirearm": "CTHULHUETERNAL.Weapon.WeaponType.rangedfirearm",
"unarmed": "CTHULHUETERNAL.Weapon.WeaponType.unarmed" "unarmed": "CTHULHUETERNAL.Weapon.WeaponType.unarmed",
"rangedexplosive": "CTHULHUETERNAL.Weapon.WeaponType.rangedexplosive",
} }
export const WEAPON_SUBTYPE = { export const WEAPON_SUBTYPE = {

View File

@@ -23,8 +23,10 @@ export default class CthulhuEternalActor extends Actor {
data.items.push(skill.toObject()) data.items.push(skill.toObject())
} }
} }
data.items.push({ type:"weapon", img: "systems/fvtt-cthulhu-eternal/assets/icons/icon_fist.svg", data.items.push({
name: game.i18n.localize("CTHULHUETERNAL.Label.Unarmed"), system: { damage: "1d4-1", weaponType: "unarmed" } }) type: "weapon", img: "systems/fvtt-cthulhu-eternal/assets/icons/icon_fist.svg",
name: game.i18n.localize("CTHULHUETERNAL.Label.Unarmed"), system: { damage: "1d4-1", weaponType: "unarmed" }
})
} }
return super.create(data, options); return super.create(data, options);
@@ -43,6 +45,39 @@ export default class CthulhuEternalActor extends Actor {
return super._onUpdate(changed, options, userId) return super._onUpdate(changed, options, userId)
} }
applyWounds(woundData) {
let updates = {}
// Get available armor
let armors = this.items.filter(i => i.type === "armor" && i.system.equipped)
let totalArmor = 0
for (let armor of armors) {
totalArmor += armor.system.protection
}
let effectiveWounds = Math.max(woundData.rollResult - totalArmor, 0)
if (woundData.isLethal) {
effectiveWounds = this.system.hp.value // Killed!
}
// Apply armor reduction
let hp = Math.max(this.system.hp.value - effectiveWounds, 0)
if (this.system.hp.value !== hp) {
updates[`system.hp.value`] = hp
}
if (Object.keys(updates).length > 0) {
this.update(updates)
}
// Chat message for GM only
if (game.user.isGM) {
let armorText = totalArmor > 0 ? game.i18n.format("CTHULHUETERNAL.Chat.armorAbsorbed", { armor: totalArmor }) : game.i18n.localize("CTHULHUETERNAL.Chat.noArmor")
ChatMessage.create({
user: game.user.id,
speaker: { alias: this.name },
rollMode: "gmroll",
content: game.i18n.format("CTHULHUETERNAL.Chat.woundsApplied", { name: this.name, effectiveWounds, armorText }),
})
}
}
async createEmbeddedDocuments(embeddedName, data, operation) { async createEmbeddedDocuments(embeddedName, data, operation) {
let newData = [] let newData = []
if (embeddedName === "Item") { if (embeddedName === "Item") {
@@ -71,18 +106,18 @@ export default class CthulhuEternalActor extends Actor {
} }
async _preCreate(data, options, user) { async _preCreate(data, options, user) {
await super._preCreate(data, options, user) await super._preCreate(data, options, user)
// Configure prototype token settings // Configure prototype token settings
const prototypeToken = {} const prototypeToken = {}
if (this.type === "protagonist") { if (this.type === "protagonist") {
Object.assign(prototypeToken, { Object.assign(prototypeToken, {
sight: { enabled: true }, sight: { enabled: true },
actorLink: true, actorLink: true,
disposition: CONST.TOKEN_DISPOSITIONS.FRIENDLY, disposition: CONST.TOKEN_DISPOSITIONS.FRIENDLY,
}) })
this.updateSource({ prototypeToken }) this.updateSource({ prototypeToken })
}
} }
}
} }

View File

@@ -106,7 +106,7 @@ export default class CthulhuEternalRoll extends Roll {
} }
static buildSelectiveFireChoices(actor, weapon) { static buildSelectiveFireChoices(actor, weapon) {
if (!weapon || !weapon?.system?.hasSelectiveFire) { if (!weapon?.system?.hasSelectiveFire) {
return {} return {}
} }
// Loop thru the selective fire choices and build the choices object when enough ammo in the weapon // Loop thru the selective fire choices and build the choices object when enough ammo in the weapon
@@ -144,6 +144,17 @@ export default class CthulhuEternalRoll extends Roll {
ammoUsed = choice.ammoUsed // Override ammo used ammoUsed = choice.ammoUsed // Override ammo used
} }
ammoUsed = Number(ammoUsed)
let combatants = []
if (game?.combat?.combatants) {
for (let c of game.combat.combatants) {
if (c.actor.id !== actor.id) {
combatants.push({ id: c.actor.id, name: c.name })
}
}
}
if (weapon.system.lethality > 0) { if (weapon.system.lethality > 0) {
let lethalityRoll = new Roll("1d100") let lethalityRoll = new Roll("1d100")
await lethalityRoll.evaluate() await lethalityRoll.evaluate()
@@ -157,27 +168,29 @@ export default class CthulhuEternalRoll extends Roll {
} }
let wounds = Math.floor(lethalityRoll.total / 10) + (lethalityRoll.total % 10) let wounds = Math.floor(lethalityRoll.total / 10) + (lethalityRoll.total % 10)
let msgData = { let msgData = {
actorId: actor.id,
weapon, weapon,
wounds, wounds,
lethalScore, lethalScore,
isLethal, isLethal,
ammoUsed, ammoUsed,
rollResult: lethalityRoll.total, rollResult: lethalityRoll.total,
combatants: combatants
} }
let flavor = await foundry.applications.handlebars.renderTemplate("systems/fvtt-cthulhu-eternal/templates/chat-lethal-damage.hbs", msgData) let flavor = await foundry.applications.handlebars.renderTemplate("systems/fvtt-cthulhu-eternal/templates/chat-lethal-damage.hbs", msgData)
ChatMessage.create({ let msg = await ChatMessage.create({
user: game.user.id, user: game.user.id,
content: flavor, content: flavor,
speaker: ChatMessage.getSpeaker({ actor: actor }), speaker: ChatMessage.getSpeaker({ actor: actor }),
}, { rollMode: options.rollMode, create: true }) }, { rollMode: options.rollMode, create: true })
await msg.setFlag("fvtt-cthulhu-eternal", "woundData", msgData)
return return
} }
// If the weapon is not lethal, we can proceed with the regular damage roll // If the weapon is not lethal, we can proceed with the regular damage roll
let formula = weapon.system.damage let formula = weapon?.damageFormula || weapon.system.damage || "0"
if (weapon.system.weaponType === "melee" || weapon.system.weaponType === "unarmed") { if (weapon.system.applyDamageBonus) {
formula += ` + ${weapon.damageBonus}` formula += ` + ${actor.system?.damageBonus}`
} }
if (options?.previousResultType === "successCritical") { if (options?.previousResultType === "successCritical") {
formula = `( ${formula} ) * 2` formula = `( ${formula} ) * 2`
@@ -188,20 +201,37 @@ export default class CthulhuEternalRoll extends Roll {
"system.ammo.value": Math.max(0, weapon.system.ammo.value - ammoUsed) "system.ammo.value": Math.max(0, weapon.system.ammo.value - ammoUsed)
}]) }])
} }
let damageRoll = new Roll(formula) let damageRoll = new Roll(formula)
await damageRoll.evaluate() await damageRoll.evaluate()
let msgData = { let msgData = {
weapon, actorId: actor.id,
formula, weapon,
ammoUsed, formula,
rollResult: damageRoll.total, ammoUsed,
} rollResult: damageRoll.total,
let flavor = await foundry.applications.handlebars.renderTemplate("systems/fvtt-cthulhu-eternal/templates/chat-regular-damage.hbs", msgData) combatants: combatants
ChatMessage.create({ }
user: game.user.id, let flavor = await foundry.applications.handlebars.renderTemplate("systems/fvtt-cthulhu-eternal/templates/chat-regular-damage.hbs", msgData)
content: flavor, let msg = await ChatMessage.create({
speaker: ChatMessage.getSpeaker({ actor: actor }), user: game.user.id,
}, { rollMode: options.rollMode, create: true }) content: flavor,
speaker: ChatMessage.getSpeaker({ actor: actor }),
}, { rollMode: options.rollMode, create: true })
await msg.setFlag("fvtt-cthulhu-eternal", "woundData", msgData)
}
static computeWeaponModifiers(rollData) {
let modifier = SYSTEM.WEAPON_MELEE_TARGET_MOVE[rollData.meleeTargetMoveChoice]?.modifier || 0
modifier += SYSTEM.WEAPON_RANGED_RANGE[rollData.rangedRangeChoice]?.modifier || 0
modifier += SYSTEM.WEAPON_RANGED_TARGET_MOVE[rollData.rangedTargetMoveChoice]?.modifier || 0
modifier += SYSTEM.WEAPON_VISIBILITY[rollData.visibilityChoice]?.modifier || 0
modifier += SYSTEM.WEAPON_ATTACKER_STATE[rollData.attackerStateChoice]?.modifier || 0
modifier += SYSTEM.WEAPON_TARGET_SIZE[rollData.targetSizeChoice]?.modifier || 0
modifier += (rollData.aimingLastRound) ? 20 : 0
modifier += (rollData.aimingWithSight) ? 20 : 0
return modifier
} }
/** /**
@@ -310,6 +340,7 @@ export default class CthulhuEternalRoll extends Roll {
rollType: options.rollType, rollType: options.rollType,
rollItem: foundry.utils.duplicate(options.rollItem), // Object only, no class rollItem: foundry.utils.duplicate(options.rollItem), // Object only, no class
weapon: options?.weapon, weapon: options?.weapon,
isRangedWeapon: options?.weapon?.system?.isRanged(),
initialScore: options.initialScore, initialScore: options.initialScore,
targetScore: options.initialScore, targetScore: options.initialScore,
isLowWP: options.isLowWP, isLowWP: options.isLowWP,
@@ -323,12 +354,26 @@ export default class CthulhuEternalRoll extends Roll {
choiceModifier, choiceModifier,
choiceMultiplier, choiceMultiplier,
choiceSelectiveFire, choiceSelectiveFire,
choiceMeleeTargetMove: SYSTEM.WEAPON_MELEE_TARGET_MOVE,
choiceRangedRange: SYSTEM.WEAPON_RANGED_RANGE,
choiceRangedTargetMove: SYSTEM.WEAPON_RANGED_TARGET_MOVE,
choiceVisibility: SYSTEM.WEAPON_VISIBILITY,
choiceAttackerState: SYSTEM.WEAPON_ATTACKER_STATE,
choiceTargetSize: SYSTEM.WEAPON_TARGET_SIZE,
selectiveFireChoice: "shortburst",
meleeTargetMoveChoice: "normal",
rangedRangeChoice: "normal",
rangedTargetMoveChoice: "normal",
visibilityChoice: "clear",
attackerStateChoice: "normal",
targetSizeChoice: "normal",
aimingLastRound: false,
aimingWithSight: false,
modifier,
formula, formula,
hasTarget: options.hasTarget, hasTarget: options.hasTarget,
hasModifier, hasModifier,
hasMultiplier, hasMultiplier,
modifier,
selectiveFireChoice: "shortburst",
multiplier multiplier
} }
const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-cthulhu-eternal/templates/roll-dialog.hbs", dialogContext) const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-cthulhu-eternal/templates/roll-dialog.hbs", dialogContext)
@@ -385,7 +430,9 @@ export default class CthulhuEternalRoll extends Roll {
if (options.rollType === "resource") { if (options.rollType === "resource") {
rollData.targetScore = options.initialScore * Number(rollContext.multiplier) rollData.targetScore = options.initialScore * Number(rollContext.multiplier)
} else { } else {
rollData.targetScore = Math.min(Math.max(options.initialScore + Number(rollData.modifier), 0), 100) let totalModifier = this.computeWeaponModifiers(rollData) + Number(rollData.modifier)
rollData.totalModifier = Math.min(totalModifier, 40)
rollData.targetScore = Math.min(Math.max(options.initialScore + Number(rollData.totalModifier), 0), 100)
if (rollData.isLowWP || rollData.isExhausted) { if (rollData.isLowWP || rollData.isExhausted) {
rollData.targetScore -= 20 rollData.targetScore -= 20
} }
@@ -394,7 +441,7 @@ export default class CthulhuEternalRoll extends Roll {
} }
rollData.targetScore = Math.min(Math.max(rollData.targetScore, 0), 100) rollData.targetScore = Math.min(Math.max(rollData.targetScore, 0), 100)
} }
if (!rollData.targetScore) { if (rollData.targetScore === undefined || rollData.targetScore === null) {
rollData.targetScore = options.initialScore rollData.targetScore = options.initialScore
rollData.modifier = "0" rollData.modifier = "0"
} }
@@ -455,6 +502,7 @@ export default class CthulhuEternalRoll extends Roll {
this.options.isCritical = resultType === "successCritical" || resultType === "failureCritical" this.options.isCritical = resultType === "successCritical" || resultType === "failureCritical"
} }
rollData.resultType = resultType rollData.resultType = resultType
this.options.isLowWP = rollData.isLowWP this.options.isLowWP = rollData.isLowWP
this.options.isZeroWP = rollData.isZeroWP this.options.isZeroWP = rollData.isZeroWP
this.options.isExhausted = rollData.isExhausted this.options.isExhausted = rollData.isExhausted
@@ -600,12 +648,14 @@ export default class CthulhuEternalRoll extends Roll {
rollItem: rollItem, rollItem: rollItem,
rollData: rollData rollData: rollData
} }
// Get array of gamemaster ID
let msg = await foundry.applications.handlebars.renderTemplate("systems/fvtt-cthulhu-eternal/templates/chat-san-request.hbs", msgData) let msg = await foundry.applications.handlebars.renderTemplate("systems/fvtt-cthulhu-eternal/templates/chat-san-request.hbs", msgData)
let chatMsg = await ChatMessage.create({ let chatMsg = await ChatMessage.create({
user: game.user.id, user: game.user.id,
content: msg, content: msg,
speaker: ChatMessage.getSpeaker({ actor: rollData.actor }) speaker: ChatMessage.getSpeaker({ actor: rollData.actor }),
}, { rollMode: rollData.rollMode, create: true }) whisper: game.users.filter(u => u.isGM).map(u => u.id),
})
await chatMsg.setFlag("fvtt-cthulhu-eternal", "rollData", rollData) await chatMsg.setFlag("fvtt-cthulhu-eternal", "rollData", rollData)
} }
} }

View File

@@ -90,6 +90,10 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData
prepareDerivedData() { prepareDerivedData() {
super.prepareDerivedData(); super.prepareDerivedData();
if (!game.user.isGM) {
return
}
let updates = {} let updates = {}
if (this.wp.max !== this.characteristics.pow.value) { if (this.wp.max !== this.characteristics.pow.value) {
updates[`system.wp.max`] = this.characteristics.pow.value updates[`system.wp.max`] = this.characteristics.pow.value
@@ -123,8 +127,6 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData
dmgBonus = -2 dmgBonus = -2
} else if (this.characteristics.str.value <= 8) { } else if (this.characteristics.str.value <= 8) {
dmgBonus = -1 dmgBonus = -1
} else if (this.characteristics.str.value <= 12) {
dmgBonus = 0
} else if (this.characteristics.str.value <= 16) { } else if (this.characteristics.str.value <= 16) {
dmgBonus = 1 dmgBonus = 1
} else if (this.characteristics.str.value <= 20) { } else if (this.characteristics.str.value <= 20) {
@@ -137,10 +139,16 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData
// BP (Breaking Point) management // BP (Breaking Point) management
if (!this.san.breakingPointReached && this.san.value <= this.san.breakingPoint) { if (!this.san.breakingPointReached && this.san.value <= this.san.breakingPoint) {
updates[`system.san.breakingPointReached`] = true updates[`system.san.breakingPointReached`] = true
ChatMessage.create({ this.san.breakingPointReached = true // Force local update to true
content: `<p>${game.i18n.format("CTHULHUETERNAL.Label.breakingPointReached", { bp: this.san.breakingPoint, san: this.san.value })}</p>`, let w = game.users.find(u => u.character?.name === this.parent?.name)
speaker: ChatMessage.getSpeaker({ actor: this.parent }) if (w) {
}) ChatMessage.create({
content: `<p>${game.i18n.format("CTHULHUETERNAL.Label.breakingPointReached", { bp: this.san.breakingPoint, san: this.san.value })}</p>`,
speaker: ChatMessage.getSpeaker({ actor: this.parent }),
// Get the user id of the actor owner
whisper: [w.id]
})
}
} }
// Unconsciousness management // Unconsciousness management
@@ -195,10 +203,6 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData
} }
async applySANConsequences(rollData) { async applySANConsequences(rollData) {
// If sanType is "non", do nothing
if (rollData.sanType === "none") {
return
}
let msgData = { let msgData = {
sanType: rollData.sanType, sanType: rollData.sanType,
sanLoss: rollData.sanLoss, sanLoss: rollData.sanLoss,
@@ -206,7 +210,7 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData
actorName: this.parent.name, actorName: this.parent.name,
adaptedToHelplessness: this.biodata.adaptedToHelplessness, adaptedToHelplessness: this.biodata.adaptedToHelplessness,
adaptedToViolence: this.biodata.adaptedToViolence, adaptedToViolence: this.biodata.adaptedToViolence,
... rollData ...rollData
} }
let updates = {} let updates = {}
let template = "" let template = ""
@@ -223,7 +227,7 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData
} }
template = "systems/fvtt-cthulhu-eternal/templates/chat-san-temp-insanity.hbs" template = "systems/fvtt-cthulhu-eternal/templates/chat-san-temp-insanity.hbs"
} else if (rollData.sanLoss === 0) { // Manage if sanLoss is 0 } else if (rollData.sanLoss === 0) { // Manage if sanLoss is 0
rollData.resetMsg = false rollData.resetMsg = false
if (rollData.sanType === "violence" && !this.biodata.adaptedToViolence) { if (rollData.sanType === "violence" && !this.biodata.adaptedToViolence) {
updates[`system.san.violence`] = [false, false, false] updates[`system.san.violence`] = [false, false, false]
@@ -235,7 +239,7 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData
} }
template = "systems/fvtt-cthulhu-eternal/templates/chat-san-loss-0.hbs" template = "systems/fvtt-cthulhu-eternal/templates/chat-san-loss-0.hbs"
} else if (rollData.sanType === "violence" ) { } else if (rollData.sanType === "violence") {
// Set the first false element of the violence array to true // Set the first false element of the violence array to true
let violence = this.san.violence.slice() let violence = this.san.violence.slice()
let index = violence.findIndex(v => !v) let index = violence.findIndex(v => !v)
@@ -250,7 +254,7 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData
updates[`system.san.violence`] = [false, false, false] updates[`system.san.violence`] = [false, false, false]
msgData.adaptedToViolence = true msgData.adaptedToViolence = true
} }
} else if (rollData.sanType === "helplessness" ) { } else if (rollData.sanType === "helplessness") {
// If sanType is "helplessness" and adapted to helplessness, set the first false element of the helplessness array to true // If sanType is "helplessness" and adapted to helplessness, set the first false element of the helplessness array to true
let helplessness = this.san.helplessness.slice() let helplessness = this.san.helplessness.slice()
let index = helplessness.findIndex(h => !h) let index = helplessness.findIndex(h => !h)
@@ -265,14 +269,21 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData
updates[`system.san.helplessness`] = [false, false, false] updates[`system.san.helplessness`] = [false, false, false]
msgData.adaptedToHelplessness = true msgData.adaptedToHelplessness = true
} }
} else if (rollData.sanType === "unnatural") {
template = "systems/fvtt-cthulhu-eternal/templates/chat-san-loss-unnatural.hbs"
} else {
template = "systems/fvtt-cthulhu-eternal/templates/chat-san-loss-none.hbs"
} }
console.log("CthulhuEternalProtagonist.applySANConsequences", rollData, updates, template)
let content = await foundry.applications.handlebars.renderTemplate(template, msgData) let content = await foundry.applications.handlebars.renderTemplate(template, msgData)
let msg = await ChatMessage.create({ let msg = await ChatMessage.create({
content: content, content: content,
speaker: ChatMessage.getSpeaker({ actor: this.parent }) speaker: ChatMessage.getSpeaker({ actor: this.parent }),
whisper: game.users.filter(u => u.isGM).map(u => u.id),
}) })
msg.setFlag("fvtt-cthulhu-eternal", "rollData", msgData) await msg.setFlag("fvtt-cthulhu-eternal", "rollData", msgData)
if (Object.keys(updates).length > 0) { if (Object.keys(updates).length > 0) {
this.parent.update(updates) this.parent.update(updates)
} }
@@ -284,12 +295,14 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData
let san = Math.max(Math.min(this.san.value + rollData.sanLoss, this.san.max), 0) let san = Math.max(Math.min(this.san.value + rollData.sanLoss, this.san.max), 0)
if (this.san.value !== san) { if (this.san.value !== san) {
updates[`system.san.value`] = san updates[`system.san.value`] = san
rollData.sanValue = san
const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-cthulhu-eternal/templates/chat-san-type-request.hbs", rollData) const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-cthulhu-eternal/templates/chat-san-type-request.hbs", rollData)
let msg = await ChatMessage.create({ let msg = await ChatMessage.create({
content: content, content: content,
speaker: ChatMessage.getSpeaker({ actor: this.parent }) speaker: ChatMessage.getSpeaker({ actor: this.parent }),
whisper: game.users.filter(u => u.isGM).map(u => u.id)
}) })
msg.setFlag("fvtt-cthulhu-eternal", "rollData", rollData) await msg.setFlag("fvtt-cthulhu-eternal", "rollData", rollData)
} }
if (Object.keys(updates).length > 0) { if (Object.keys(updates).length > 0) {
this.parent.update(updates) this.parent.update(updates)
@@ -344,15 +357,15 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData
*/ */
async roll(rollType, rollItem) { async roll(rollType, rollItem) {
if (this.hp.dead ) { if (this.hp.dead) {
// Warn with chat message // Warn with chat message
ChatMessage.create({ ChatMessage.create({
content: `<p>${game.i18n.format("CTHULHUETERNAL.Label.deadWarning", {con: this.characteristics.con.value} )}</p>`, content: `<p>${game.i18n.format("CTHULHUETERNAL.Label.deadWarning", { con: this.characteristics.con.value })}</p>`,
speaker: ChatMessage.getSpeaker({ actor: this.parent }) speaker: ChatMessage.getSpeaker({ actor: this.parent })
}) })
return null return null
} }
if (this.hp.unconscious ) { if (this.hp.unconscious) {
// Warn with chat message // Warn with chat message
ChatMessage.create({ ChatMessage.create({
content: `<p>${game.i18n.localize("CTHULHUETERNAL.Label.unconsciousWarning")}</p>`, content: `<p>${game.i18n.localize("CTHULHUETERNAL.Label.unconsciousWarning")}</p>`,

View File

@@ -13,12 +13,23 @@ export default class CthulhuEternalWeapon extends foundry.abstract.TypeDataModel
schema.weaponType = new fields.StringField({ required: true, initial: "melee", choices: SYSTEM.WEAPON_TYPE }) schema.weaponType = new fields.StringField({ required: true, initial: "melee", choices: SYSTEM.WEAPON_TYPE })
schema.hasDirectSkill = new fields.BooleanField({ required: true, initial: false }) schema.hasDirectSkill = new fields.BooleanField({ required: true, initial: false })
schema.directSkillValue = new fields.NumberField({ required: true, initial: 0, min: 0, max:99 }) schema.directSkillValue = new fields.NumberField({ required: true, initial: 0, min: 0, max: 99 })
schema.hasDamageDistance = new fields.BooleanField({ required: true, initial: false })
schema.damageDistance = new fields.SchemaField(Array.fromRange(6, 1).reduce((damageDistance, i) => {
damageDistance[`dist${i}`] = new fields.SchemaField({
damage: new fields.StringField({ required: true, initial: "1d6" }),
distance: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
})
return damageDistance
}, {}));
schema.hasSelectiveFire = new fields.BooleanField({ required: true, initial: false }) schema.hasSelectiveFire = new fields.BooleanField({ required: true, initial: false })
schema.damage = new fields.StringField({required: true, initial: "1d6"}) schema.hasSight = new fields.BooleanField({ required: true, initial: false })
schema.isStunning = new fields.BooleanField({ required: true, initial: false })
schema.damage = new fields.StringField({ required: true, initial: "1d6" })
schema.applyDamageBonus = new fields.BooleanField({ required: true, initial: false }) schema.applyDamageBonus = new fields.BooleanField({ required: true, initial: false })
schema.baseRange = new fields.StringField({required: true, initial: ""}) schema.baseRange = new fields.StringField({ required: true, initial: "" })
schema.rangeUnit = new fields.StringField({ required: true, initial: "yard", choices: SYSTEM.WEAPON_RANGE_UNIT }) schema.rangeUnit = new fields.StringField({ required: true, initial: "yard", choices: SYSTEM.WEAPON_RANGE_UNIT })
schema.lethality = new fields.NumberField({ required: true, initial: 0, min: 0 }) schema.lethality = new fields.NumberField({ required: true, initial: 0, min: 0 })
schema.killRadius = new fields.NumberField({ required: true, initial: 0, min: 0 }) schema.killRadius = new fields.NumberField({ required: true, initial: 0, min: 0 })
@@ -43,7 +54,8 @@ export default class CthulhuEternalWeapon extends foundry.abstract.TypeDataModel
} }
isRanged() { isRanged() {
return this.weaponType.includes("ranged") console.log("isRanged", this.weaponType, this)
return this.weaponType.match("ranged")
} }
isFireArm() { isFireArm() {

View File

@@ -196,11 +196,6 @@ export default class CthulhuEternalUtils {
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.noSanTypeFound")) ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.noSanTypeFound"))
return return
} }
// If the sanType is "none", we don't apply any SAN processing
if (sanType === "none") {
ui.notifications.info(game.i18n.localize("CTHULHUETERNAL.Notifications.noSanLossApplied"))
return
}
rollData.sanType = sanType rollData.sanType = sanType
await actor.system.applySANConsequences(rollData) await actor.system.applySANConsequences(rollData)
// Delete the roll message // Delete the roll message
@@ -234,7 +229,7 @@ export default class CthulhuEternalUtils {
let healingFormula = rollData.rollItem.system.healingFormula let healingFormula = rollData.rollItem.system.healingFormula
let healingMsg = "CTHULHUETERNAL.Label.healingRoll" let healingMsg = "CTHULHUETERNAL.Label.healingRoll"
if (rollData.resultType === "successCritical") { if (rollData.resultType === "successCritical") {
healingFormula += " * 2" healingFormula += " * 2"
} }
if (rollData.resultType === "failureCritical") { if (rollData.resultType === "failureCritical") {
healingMsg = "CTHULHUETERNAL.Label.healingRollFailure" healingMsg = "CTHULHUETERNAL.Label.healingRollFailure"
@@ -253,9 +248,39 @@ export default class CthulhuEternalUtils {
}) })
} }
static async damageRoll(rollMessage) { static translateRangeUnit(range) {
if (typeof range === 'string') {
return game.i18n.localize(`CTHULHUETERNAL.Label.${range}`)
} else if (typeof range === 'number') {
return range
} else {
console.warn("CTHULHU ETERNAL | translateRange called with an unknown type", range)
return range
}
}
static translateRange(range) {
// If the range is a string, replace STR with FOR
if (typeof range === 'string') {
return range.replace(/STR/g, "FOR").replace(/str/g, "for")
}
return range
}
static async registerBabeleTranslations(babele) {
babele.registerConverters({
'translateRangeUnit': (originalValue) => {
return CthulhuEternalUtils.translateRangeUnit(originalValue)
},
'translateRange': (originalValue) => {
return CthulhuEternalUtils.translateRange(originalValue)
}
})
}
static async damageRoll(rollMessage, formula = null) {
let rollData = rollMessage.rolls[0]?.options?.rollData let rollData = rollMessage.rolls[0]?.options?.rollData
let actor = game.actors.get(rollData.actorId) let actor = game.actors.get(rollData.actorId)
if (!actor) { if (!actor) {
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Label.noActorFound")) ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Label.noActorFound"))
return return
@@ -263,6 +288,7 @@ export default class CthulhuEternalUtils {
console.log("Damage roll data", rollData) console.log("Damage roll data", rollData)
rollData.weapon.resultType = rollData.resultType // Keep the result type from the roll message rollData.weapon.resultType = rollData.resultType // Keep the result type from the roll message
rollData.weapon.selectiveFireChoice = rollData.selectiveFireChoice // Keep the selected fire choice from the roll message rollData.weapon.selectiveFireChoice = rollData.selectiveFireChoice // Keep the selected fire choice from the roll message
rollData.weapon.damageFormula = formula || rollData.weapon.system.damage
actor.system.roll("damage", rollData.weapon) actor.system.roll("damage", rollData.weapon)
} }
@@ -310,8 +336,8 @@ export default class CthulhuEternalUtils {
rejectClose: false, // Click on Close button will not launch an error rejectClose: false, // Click on Close button will not launch an error
render: (event, dialog) => { render: (event, dialog) => {
$(".nudged-score-select").change(event => { $(".nudged-score-select").change(event => {
dialogContext.nudgedValue = Number(event.target.value)+1 dialogContext.nudgedValue = Number(event.target.value) + 1
dialogContext.wpCost = Math.ceil(Math.abs(rollMessage.rolls[0].total - dialogContext.nudgedValue) / 5) dialogContext.wpCost = Math.ceil(Math.abs(rollMessage.rolls[0].total - dialogContext.nudgedValue) / 5)
$("#nudged-wp-cost").val(dialogContext.wpCost) $("#nudged-wp-cost").val(dialogContext.wpCost)
}) })
} }
@@ -349,4 +375,24 @@ export default class CthulhuEternalUtils {
document.documentElement.style.setProperty('--background-image-base', `linear-gradient(rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.8)), url("../assets/ui/${era}_background_main.webp")`); document.documentElement.style.setProperty('--background-image-base', `linear-gradient(rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.8)), url("../assets/ui/${era}_background_main.webp")`);
} }
static applyWounds(message, event) {
let woundData = message.getFlag("fvtt-cthulhu-eternal", "woundData")
if (!woundData) {
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.noRollDataFound"))
return
}
let actor = game.actors.get(woundData.actorId)
if (!actor) {
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.noActorFound"))
return
}
// Get the targetted actorId from the HTML select event
let targetActorId = event.target.value
let targetActor = game.actors.get(targetActorId)
if (!targetActor) {
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.noTargetActorFound") + targetActorId)
return
}
targetActor.applyWounds(woundData)
}
} }

Binary file not shown.

View File

@@ -1 +1 @@
MANIFEST-000167 MANIFEST-000249

View File

@@ -1,7 +1,7 @@
2025/06/29-22:25:29.091880 7fda6d9f96c0 Recovering log #165 2025/10/01-10:24:47.689741 7fc4987f86c0 Recovering log #246
2025/06/29-22:25:29.103184 7fda6d9f96c0 Delete type=3 #163 2025/10/01-10:24:47.787870 7fc4987f86c0 Delete type=3 #244
2025/06/29-22:25:29.103305 7fda6d9f96c0 Delete type=0 #165 2025/10/01-10:24:47.787986 7fc4987f86c0 Delete type=0 #246
2025/06/29-22:26:56.370766 7fda5bbff6c0 Level-0 table #170: started 2025/10/01-11:24:12.555415 7fc497ff76c0 Level-0 table #252: started
2025/06/29-22:26:56.370832 7fda5bbff6c0 Level-0 table #170: 0 bytes OK 2025/10/01-11:24:12.555461 7fc497ff76c0 Level-0 table #252: 0 bytes OK
2025/06/29-22:26:56.379673 7fda5bbff6c0 Delete type=0 #168 2025/10/01-11:24:12.565317 7fc497ff76c0 Delete type=0 #250
2025/06/29-22:26:56.380010 7fda5bbff6c0 Manual compaction at level-0 from '!items!4oyPRBWPBWAChrJP' @ 72057594037927935 : 1 .. '!items!zVFfp3o0G0Zg3Ia4' @ 0 : 0; will stop at (end) 2025/10/01-11:24:12.577205 7fc497ff76c0 Manual compaction at level-0 from '!items!4oyPRBWPBWAChrJP' @ 72057594037927935 : 1 .. '!items!zVFfp3o0G0Zg3Ia4' @ 0 : 0; will stop at (end)

View File

@@ -1,7 +1,11 @@
2025/06/29-22:24:52.674663 7fda6c9f76c0 Recovering log #161 2025/10/01-09:23:25.493413 7fc499ffb6c0 Delete type=3 #1
2025/06/29-22:24:52.733389 7fda6c9f76c0 Delete type=3 #159 2025/10/01-09:24:30.037985 7fc497ff76c0 Level-0 table #247: started
2025/06/29-22:24:52.733531 7fda6c9f76c0 Delete type=0 #161 2025/10/01-09:24:30.038031 7fc497ff76c0 Level-0 table #247: 0 bytes OK
2025/06/29-22:25:23.612345 7fda5bbff6c0 Level-0 table #166: started 2025/10/01-09:24:30.044462 7fc497ff76c0 Delete type=0 #245
2025/06/29-22:25:23.612406 7fda5bbff6c0 Level-0 table #166: 0 bytes OK 2025/10/01-09:24:30.069660 7fc497ff76c0 Manual compaction at level-0 from '!items!4oyPRBWPBWAChrJP' @ 72057594037927935 : 1 .. '!items!zVFfp3o0G0Zg3Ia4' @ 0 : 0; will stop at '!items!zVFfp3o0G0Zg3Ia4' @ 52 : 1
2025/06/29-22:25:23.683484 7fda5bbff6c0 Delete type=0 #164 2025/10/01-09:24:30.069672 7fc497ff76c0 Compacting 1@0 + 0@1 files
2025/06/29-22:25:23.834365 7fda5bbff6c0 Manual compaction at level-0 from '!items!4oyPRBWPBWAChrJP' @ 72057594037927935 : 1 .. '!items!zVFfp3o0G0Zg3Ia4' @ 0 : 0; will stop at (end) 2025/10/01-09:24:30.073695 7fc497ff76c0 Generated table #248@0: 26 keys, 60964 bytes
2025/10/01-09:24:30.073722 7fc497ff76c0 Compacted 1@0 + 0@1 files => 60964 bytes
2025/10/01-09:24:30.080151 7fc497ff76c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2025/10/01-09:24:30.080234 7fc497ff76c0 Delete type=2 #242
2025/10/01-09:24:30.086925 7fc497ff76c0 Manual compaction at level-0 from '!items!zVFfp3o0G0Zg3Ia4' @ 52 : 1 .. '!items!zVFfp3o0G0Zg3Ia4' @ 0 : 0; will stop at (end)

Binary file not shown.

Binary file not shown.

View File

@@ -1 +1 @@
MANIFEST-000336 MANIFEST-000418

View File

@@ -1,7 +1,7 @@
2025/06/29-22:25:29.069935 7fda6d1f86c0 Recovering log #334 2025/10/01-10:24:47.499257 7fc4997fa6c0 Recovering log #415
2025/06/29-22:25:29.081064 7fda6d1f86c0 Delete type=3 #332 2025/10/01-10:24:47.596647 7fc4997fa6c0 Delete type=3 #413
2025/06/29-22:25:29.081192 7fda6d1f86c0 Delete type=0 #334 2025/10/01-10:24:47.596724 7fc4997fa6c0 Delete type=0 #415
2025/06/29-22:26:56.360514 7fda5bbff6c0 Level-0 table #339: started 2025/10/01-11:24:12.545465 7fc497ff76c0 Level-0 table #421: started
2025/06/29-22:26:56.360577 7fda5bbff6c0 Level-0 table #339: 0 bytes OK 2025/10/01-11:24:12.545499 7fc497ff76c0 Level-0 table #421: 0 bytes OK
2025/06/29-22:26:56.370559 7fda5bbff6c0 Delete type=0 #337 2025/10/01-11:24:12.555310 7fc497ff76c0 Delete type=0 #419
2025/06/29-22:26:56.379992 7fda5bbff6c0 Manual compaction at level-0 from '!folders!5PrT9QmN1cFPzDFP' @ 72057594037927935 : 1 .. '!items!zvoUByzWSWZ87fxA' @ 0 : 0; will stop at (end) 2025/10/01-11:24:12.577192 7fc497ff76c0 Manual compaction at level-0 from '!folders!5PrT9QmN1cFPzDFP' @ 72057594037927935 : 1 .. '!items!zvoUByzWSWZ87fxA' @ 0 : 0; will stop at (end)

View File

@@ -1,7 +1,11 @@
2025/06/29-22:24:52.606734 7fda6d9f96c0 Recovering log #330 2025/10/01-09:23:25.444068 7fc499ffb6c0 Delete type=3 #1
2025/06/29-22:24:52.662677 7fda6d9f96c0 Delete type=3 #328 2025/10/01-09:24:30.024822 7fc497ff76c0 Level-0 table #416: started
2025/06/29-22:24:52.662873 7fda6d9f96c0 Delete type=0 #330 2025/10/01-09:24:30.024870 7fc497ff76c0 Level-0 table #416: 0 bytes OK
2025/06/29-22:25:23.549590 7fda5bbff6c0 Level-0 table #335: started 2025/10/01-09:24:30.030665 7fc497ff76c0 Delete type=0 #414
2025/06/29-22:25:23.549651 7fda5bbff6c0 Level-0 table #335: 0 bytes OK 2025/10/01-09:24:30.044587 7fc497ff76c0 Manual compaction at level-0 from '!folders!5PrT9QmN1cFPzDFP' @ 72057594037927935 : 1 .. '!items!zvoUByzWSWZ87fxA' @ 0 : 0; will stop at '!items!zvoUByzWSWZ87fxA' @ 1281 : 1
2025/06/29-22:25:23.612061 7fda5bbff6c0 Delete type=0 #333 2025/10/01-09:24:30.044598 7fc497ff76c0 Compacting 1@0 + 0@1 files
2025/06/29-22:25:23.834320 7fda5bbff6c0 Manual compaction at level-0 from '!folders!5PrT9QmN1cFPzDFP' @ 72057594037927935 : 1 .. '!items!zvoUByzWSWZ87fxA' @ 0 : 0; will stop at (end) 2025/10/01-09:24:30.051264 7fc497ff76c0 Generated table #417@0: 556 keys, 320457 bytes
2025/10/01-09:24:30.051285 7fc497ff76c0 Compacted 1@0 + 0@1 files => 320457 bytes
2025/10/01-09:24:30.058278 7fc497ff76c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2025/10/01-09:24:30.058439 7fc497ff76c0 Delete type=2 #411
2025/10/01-09:24:30.086897 7fc497ff76c0 Manual compaction at level-0 from '!items!zvoUByzWSWZ87fxA' @ 1281 : 1 .. '!items!zvoUByzWSWZ87fxA' @ 0 : 0; will stop at (end)

Binary file not shown.

View File

@@ -0,0 +1 @@
MANIFEST-000064

View File

7
packs-system/weapons/LOG Normal file
View File

@@ -0,0 +1,7 @@
2025/10/01-10:24:47.601344 7fc499ffb6c0 Recovering log #61
2025/10/01-10:24:47.686801 7fc499ffb6c0 Delete type=3 #59
2025/10/01-10:24:47.686869 7fc499ffb6c0 Delete type=0 #61
2025/10/01-11:24:12.535658 7fc497ff76c0 Level-0 table #67: started
2025/10/01-11:24:12.535725 7fc497ff76c0 Level-0 table #67: 0 bytes OK
2025/10/01-11:24:12.545352 7fc497ff76c0 Delete type=0 #65
2025/10/01-11:24:12.577171 7fc497ff76c0 Manual compaction at level-0 from '!folders!0DI3T2jve3nsmsfZ' @ 72057594037927935 : 1 .. '!items!zyxA9DhO36t5OBDv' @ 0 : 0; will stop at (end)

View File

@@ -0,0 +1,11 @@
2025/10/01-09:23:25.469063 7fc499ffb6c0 Delete type=3 #1
2025/10/01-09:24:30.030754 7fc497ff76c0 Level-0 table #62: started
2025/10/01-09:24:30.030783 7fc497ff76c0 Level-0 table #62: 0 bytes OK
2025/10/01-09:24:30.037809 7fc497ff76c0 Delete type=0 #60
2025/10/01-09:24:30.058634 7fc497ff76c0 Manual compaction at level-0 from '!folders!0DI3T2jve3nsmsfZ' @ 72057594037927935 : 1 .. '!items!zyxA9DhO36t5OBDv' @ 0 : 0; will stop at '!items!zyxA9DhO36t5OBDv' @ 55 : 1
2025/10/01-09:24:30.058646 7fc497ff76c0 Compacting 1@0 + 0@1 files
2025/10/01-09:24:30.063565 7fc497ff76c0 Generated table #63@0: 362 keys, 93592 bytes
2025/10/01-09:24:30.063591 7fc497ff76c0 Compacted 1@0 + 0@1 files => 93592 bytes
2025/10/01-09:24:30.069446 7fc497ff76c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2025/10/01-09:24:30.069529 7fc497ff76c0 Delete type=2 #57
2025/10/01-09:24:30.086915 7fc497ff76c0 Manual compaction at level-0 from '!items!zyxA9DhO36t5OBDv' @ 55 : 1 .. '!items!zyxA9DhO36t5OBDv' @ 0 : 0; will stop at (end)

View File

View File

@@ -8,6 +8,28 @@
background-color: var(--color-light-1); background-color: var(--color-light-1);
} }
.creature-hp {
gap: 2px;
align-items: center;
.form-fields {
input {
flex: none;
min-width: 4rem;
max-width: 4rem;
margin-left: 4px;
}
}
.damage-bonus {
font-size: calc(var(--font-size-standard) * 0.8);
}
.hp-separator {
font-size: calc(var(--font-size-standard) * 1.2);
display: flex;
align-items: center;
justify-content: center;
}
}
.creature-main { .creature-main {
background-color: var(--color-light-1); background-color: var(--color-light-1);
display: flex; display: flex;
@@ -34,25 +56,6 @@
} }
} }
.creature-hp {
gap: 2px;
align-items: center;
input {
flex: none;
width: 2rem;
margin-left: 4px;
}
.damage-bonus {
font-size: calc(var(--font-size-standard) * 0.8);
}
.hp-separator {
font-size: calc(var(--font-size-standard) * 1.2);
display: flex;
align-items: center;
justify-content: center;
}
}
.creature-dv, .creature-dv,
.creature-dmax { .creature-dmax {
.form-fields { .form-fields {

View File

@@ -11,8 +11,8 @@
@import "weapon.less"; @import "weapon.less";
@import "armor.less"; @import "armor.less";
@import "motivation.less"; @import "motivation.less";
@import "mentaldisorder.less"; @import "mentaldisorder.less";
@import "bond.less"; @import "bond.less";
@import "chat.less"; @import "chat.less";
@import "gear.less"; @import "gear.less";
@import "arcane.less"; @import "arcane.less";
@@ -21,4 +21,4 @@
@import "tome.less"; @import "tome.less";
} }
@import "roll.less"; @import "roll.less";

View File

@@ -98,6 +98,23 @@ i.fvtt-cthulhu-eternal {
color: var(--color-critical-failure); color: var(--color-critical-failure);
font-family: var(--font-title); font-family: var(--font-title);
} }
.san-type-buttons {
display: flex;
justify-content: center;
align-items: center;
margin: 10px 0;
button {
margin: 0 2px;
font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 0.9);
border: none;
padding: 2px 2px;
cursor: pointer;
transition: background-color 0.3s;
min-width: 6.0rem;
max-width: 6.0rem;
}
}
.san-loose-buttons { .san-loose-buttons {
display: flex; display: flex;
justify-content: center; justify-content: center;

View File

@@ -2,9 +2,7 @@
font-family: var(--font-primary); font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1.05); font-size: calc(var(--font-size-standard) * 1.05);
color: var(--color-dark-1); color: var(--color-dark-1);
background-image: var(--background-image-base); background: var(--color-light-1);
background-repeat: no-repeat;
background-size: 100% 100%;
--input-height: 1.4rem; --input-height: 1.4rem;
.sheet-tabs { .sheet-tabs {

View File

@@ -39,7 +39,7 @@
align-items: center; align-items: center;
input { input {
flex: none; flex: none;
width: 2rem; width: 4rem;
margin-left: 4px; margin-left: 4px;
} }
.hp-separator { .hp-separator {
@@ -478,7 +478,7 @@
} }
.weapons { .weapons {
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(1, 1fr);
gap: 4px; gap: 4px;
.weapon { .weapon {
display: flex; display: flex;
@@ -496,10 +496,24 @@
min-width: 1.8rem; min-width: 1.8rem;
max-width: 1.8rem; max-width: 1.8rem;
} }
.damage { .range {
min-width: 6rem; min-width: 6rem;
max-width: 6rem; max-width: 6rem;
} }
.ammo {
min-width: 4rem;
max-width: 4rem;
}
.lethality {
display: flex;
min-width: 3.2rem;
max-width: 3.2rem;
}
.damage {
display: flex;
min-width: 12rem;
max-width: 12rem;
}
.name { .name {
min-width: 10rem; min-width: 10rem;
max-width: 10rem; max-width: 10rem;

View File

@@ -53,6 +53,10 @@
color: var(--color-dark-1); color: var(--color-dark-1);
} }
.li-apply-wounds {
display: none;
}
&.dice-roll { &.dice-roll {
flex-direction: column; flex-direction: column;
@@ -70,7 +74,7 @@
border: 0px; border: 0px;
} }
.intro-chat { .intro-chat {
color:var(--color-dark-1); color: var(--color-dark-1);
border-radius: 20px; border-radius: 20px;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@@ -91,20 +95,20 @@
li { li {
margin: 0 10px; margin: 0 10px;
font-family: var(--font-primary); font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1.0); font-size: calc(var(--font-size-standard) * 1);
} }
.nudge-roll { .nudge-roll {
font-size: calc(var(--font-size-standard) * 1.0); font-size: calc(var(--font-size-standard) * 1);
margin-left: 2rem; margin-left: 2rem;
display: none; display: none;
} }
.healing-roll { .healing-roll {
font-size: calc(var(--font-size-standard) * 1.0); font-size: calc(var(--font-size-standard) * 1);
margin-left: 2rem; margin-left: 2rem;
display: none; display: none;
} }
.roll-damage { .roll-damage {
font-size: calc(var(--font-size-standard) * 1.0); font-size: calc(var(--font-size-standard) * 1);
margin-left: 2rem; margin-left: 2rem;
display: none; display: none;
} }

View File

@@ -14,6 +14,24 @@
fieldset { fieldset {
margin-top: 8px; margin-top: 8px;
background-color: var(--color-light-1); background-color: var(--color-light-1);
input {
max-width: 5rem;
min-width: 5rem;
}
select {
max-width: 14rem;
min-width: 14rem;
}
input[type="checkbox"] {
max-width: 1.5rem;
min-width: 1.5rem;
}
.flexrow > *:not(:first-child) {
margin-left: 1rem;
}
.damage-distance {
margin-left: 2rem;
}
} }
label { label {

View File

@@ -152,6 +152,18 @@
}, },
"flags": {} "flags": {}
}, },
{
"name": "weapons",
"label": "Weapons",
"system": "fvtt-cthulhu-eternal",
"path": "packs-system/weapons",
"type": "Item",
"ownership": {
"PLAYER": "OBSERVER",
"ASSISTANT": "OWNER"
},
"flags": {}
},
{ {
"name": "rituals", "name": "rituals",
"label": "Rituals", "label": "Rituals",

View File

@@ -2,27 +2,39 @@
<div class="chat-lethal-damage"> <div class="chat-lethal-damage">
<ul> <ul>
<li><strong>{{weapon.name}} : {{localize "CTHULHUETERNAL.Label.lethalityRoll"}}</strong></li> <li><strong>{{weapon.name}} : {{localize "CTHULHUETERNAL.Label.lethalityRoll"}}</strong></li>
<li>{{localize "CTHULHUETERNAL.Label.result"}} :{{rollResult}} ({{lethalScore}})</li> <li>{{localize "CTHULHUETERNAL.Label.result"}} :{{rollResult}} ({{lethalScore}})</li>
{{#if weapon.system.selectiveFireChoice}} {{#if weapon.system.selectiveFireChoice}}
<li>{{weapon.system.selectiveFireChoiceLabel}}</li> <li>{{weapon.system.selectiveFireChoiceLabel}}</li>
{{/if}} {{/if}}
{{#if weapon.system.killRadius}} {{#if (gt weapon.system.killRadius 0)}}
<li>{{localize "CTHULHUETERNAL.Label.killRadius"}} : {{weapon.system.killRadius}} {{weapon.system.rangeUnit}}</li> <li>{{localize "CTHULHUETERNAL.Label.killRadius"}} : {{weapon.system.killRadius}} {{weapon.system.rangeUnit}}</li>
<li>{{localize "CTHULHUETERNAL.Label.killRadiusInfo"}}</li> <li>{{localize "CTHULHUETERNAL.Label.killRadiusInfo"}}</li>
{{/if}} {{/if}}
{{#if (gt weapon.system.armorPiercing 0)}}
<li>{{localize "CTHULHUETERNAL.Label.armorPiercing"}} : {{weapon.system.armorPiercing}}</li>
{{/if}}
{{#if ammoUsed}} {{#if ammoUsed}}
<li>{{localize "CTHULHUETERNAL.Label.ammoUsed"}}: {{ammoUsed}} / {{weapon.system.ammo.value}}</li> <li>{{localize "CTHULHUETERNAL.Label.ammoUsed"}}: {{ammoUsed}} / {{weapon.system.ammo.value}}</li>
{{/if}} {{/if}}
<li class="li-apply-wounds">
<button type="button" class="apply-wounds">{{localize "CTHULHUETERNAL.Label.applyWounds"}}</button>
<select name="combatant" class="roll-skill-modifier">
{{selectOptions combatants valueAttr="id" labelAttr="name"}}
</select>
</li>
{{#if isLethal}} {{#if isLethal}}
<li class="result-lethal">{{localize "CTHULHUETERNAL.Label.lethalityLethal"}}</li> <li class="result-lethal">{{localize "CTHULHUETERNAL.Label.lethalityLethal"}}</li>
<li class="result-lethal">{{localize "CTHULHUETERNAL.Label.lethalityWounded"}}</li> <li class="result-lethal">{{localize "CTHULHUETERNAL.Label.lethalityWounded"}}</li>
{{else}} {{else}}
<li class="result-non-lethal">{{localize "CTHULHUETERNAL.Label.lethalityNotLethal"}}</li> <li class="result-non-lethal">{{localize "CTHULHUETERNAL.Label.lethalityNotLethal"}}</li>
<li class="result-non-lethal">{{localize "CTHULHUETERNAL.Label.lethalityNotWounded"}}: <strong>{{wounds}}</strong></li> <li class="result-non-lethal">{{localize "CTHULHUETERNAL.Label.lethalityNotWounded"}}: <strong>{{wounds}}</strong>
</li>
{{/if}} {{/if}}
</ul> </ul>

View File

@@ -15,7 +15,7 @@
{{/if}} {{/if}}
{{#if isNudgedRoll}} {{#if isNudgedRoll}}
<li><strong>{{localize "CTHULHUETERNAL.Label.nudgedRoll"}} : {{wpCost}} WP spent</strong></li> <li><strong>{{localize "CTHULHUETERNAL.Label.nudgedRoll"}} : {{wpCost}} {{localize "CTHULHUETERNAL.Label.WPSpent"}}</strong></li>
{{/if}} {{/if}}
{{#if weapon}} {{#if weapon}}
@@ -43,26 +43,13 @@
{{#if (eq rollType "resource")}} {{#if (eq rollType "resource")}}
<li>{{localize "CTHULHUETERNAL.Label.multiplier"}} : {{multiplier}}</li> <li>{{localize "CTHULHUETERNAL.Label.multiplier"}} : {{multiplier}}</li>
{{else}} {{else}}
<li>{{localize "CTHULHUETERNAL.Label.modifier"}} : {{modifier}}%</li> <li>{{localize "CTHULHUETERNAL.Label.modifier"}} : {{totalModifier}}%</li>
{{/if}} {{/if}}
<li>{{localize "CTHULHUETERNAL.Label.targetScore"}} : {{targetScore}}%</li> <li>{{localize "CTHULHUETERNAL.Label.targetScore"}} : {{targetScore}}%</li>
{{#if isSuccess}} {{#if isSuccess}}
{{#if isCritical}} {{#if isCritical}}
<li class="result-critical-success">{{localize "CTHULHUETERNAL.Label.criticalSuccess"}} <li class="result-critical-success">{{localize "CTHULHUETERNAL.Label.criticalSuccess"}}
{{#if (eq rollType "weapon")}}
{{#if (eq weapon.system.weaponType "rangedfirearm")}}
<a class="damage-roll" data-tooltip="{{localize "CTHULHUETERNAL.Label.rollDamage"}}"><i class="fa-solid fa-gun"></i></a>
{{else}}
<a class="damage-roll" data-tooltip="{{localize "CTHULHUETERNAL.Label.rollDamage"}}"><i class="fa-solid fa-sword"></i></a>
{{/if}}
{{/if}}
{{#if (eq rollType "skill") }}
{{#if rollItem.system.isHealing}}
<a class="healing-roll" data-tooltip="{{localize "CTHULHUETERNAL.Label.rollHealing"}}"><i class="fa-solid fa-heart"></i></a>
{{/if}}
{{/if}}
</li> </li>
{{else}} {{else}}
<li class="result-success"> <li class="result-success">
@@ -70,38 +57,58 @@
{{#if isNudge}} {{#if isNudge}}
<a class="nudge-roll" data-tooltip="{{localize "CTHULHUETERNAL.Label.rollNudge"}}"><i class="fa-solid fa-circle-sort-down"></i></a> <a class="nudge-roll" data-tooltip="{{localize "CTHULHUETERNAL.Label.rollNudge"}}"><i class="fa-solid fa-circle-sort-down"></i></a>
{{/if}} {{/if}}
{{#if (eq weapon.system.weaponType "rangedfirearm")}}
<a class="damage-roll" data-tooltip="{{localize "CTHULHUETERNAL.Label.rollDamage"}}"><i class="fa-solid fa-gun"></i></a> </li>
{{/if}}
{{#if (eq rollType "weapon")}}
<li>
{{#if (eq weapon.system.weaponType "rangedfirearm")}}
{{#if weapon.system.hasDamageDistance}}
{{#each weapon.system.damageDistance as |damageDistance|}}
{{#if (gt damageDistance.distance 0)}}
<a class="damage-roll" data-item-id="{{weapon.id}}" data-action="roll" data-roll-type="damage"
data-roll-value="{{damageDistance.damage}}" >
<i class="fa-solid fa-gun"></i>
<span class="damage-distance">{{damageDistance.distance}}:{{damageDistance.damage}}&nbsp;&nbsp;</span>
</a>
{{/if}}
{{/each}}
{{else}} {{else}}
<a class="damage-roll" data-tooltip="{{localize "CTHULHUETERNAL.Label.rollDamage"}}"><i class="fa-solid fa-sword"></i></a> <a class="damage-roll" data-roll-value="{{weapon.system.damage}}" data-tooltip="{{localize "CTHULHUETERNAL.Label.rollDamage"}}"><i class="fa-solid fa-gun"></i></a>
{{/if}} {{/if}}
{{else}}
<a class="damage-roll" data-roll-value="{{weapon.system.damage}}" data-tooltip="{{localize "CTHULHUETERNAL.Label.rollDamage"}}"><i class="fa-solid fa-sword"></i></a>
{{/if}}
</li>
{{/if}}
{{#if (eq rollType "skill") }} {{#if (eq rollType "skill") }}
{{#if rollItem.system.isHealing}} {{#if rollItem.system.isHealing}}
<li>
<a class="healing-roll" data-tooltip="{{localize "CTHULHUETERNAL.Label.rollHealing"}}"><i class="fa-solid fa-heart"></i></a> <a class="healing-roll" data-tooltip="{{localize "CTHULHUETERNAL.Label.rollHealing"}}"><i class="fa-solid fa-heart"></i></a>
</li>
{{/if}} {{/if}}
{{/if}} {{/if}}
</li> </li>
{{/if}}
{{/if}} {{/if}}
{{#if isFailure}} {{#if isFailure}}
{{#if isCritical}} {{#if isCritical}}
<li class="result-critical-failure">{{localize "CTHULHUETERNAL.Label.criticalFailure"}} <li class="result-critical-failure">{{localize "CTHULHUETERNAL.Label.criticalFailure"}}
{{#if (eq rollType "skill") }} </li>
{{#if rollItem.system.isHealing}} {{else}}
<a class="healing-roll" data-tooltip="{{localize "CTHULHUETERNAL.Label.rollHealing"}}"><i class="fa-solid fa-heart"></i></a> <li class="result-failure">
{{/if}} {{localize "CTHULHUETERNAL.Label.failure"}}
{{/if}}
</li> </li>
{{else}}
<li class="result-failure">
{{localize "CTHULHUETERNAL.Label.failure"}}
{{#if isNudge}}
<a class="nudge-roll" data-tooltip="{{localize "CTHULHUETERNAL.Label.rollNudge"}}"><i class="fa-solid fa-circle-sort-down"></i></a>
{{/if}} {{/if}}
</li>
{{/if}} {{#if isNudge}}
<li>
<a class="nudge-roll" data-tooltip="{{localize "CTHULHUETERNAL.Label.rollNudge"}}"><i class="fa-solid fa-circle-sort-down"></i></a>
</li>
{{/if}}
{{/if}} {{/if}}
</ul> </ul>
</div> </div>

View File

@@ -2,17 +2,33 @@
<div class="chat-lethal-damage"> <div class="chat-lethal-damage">
<ul> <ul>
<li><strong>{{weapon.name}} : {{localize "CTHULHUETERNAL.Label.damageRoll"}}</strong></li> <li><strong>{{weapon.name}} : {{localize "CTHULHUETERNAL.Label.damageRoll"}}</strong></li>
<li>{{localize "CTHULHUETERNAL.Label.result"}} :{{rollResult}} ({{formula}})</li> <li>{{localize "CTHULHUETERNAL.Label.result"}} :{{rollResult}} ({{formula}})</li>
{{#if weapon.system.killRadius}} {{#if (gt weapon.system.killRadius 0)}}
<li>{{localize "CTHULHUETERNAL.Label.killRadius"}} : {{weapon.system.killRadius}} {{weapon.system.rangeUnit}}</li> <li>{{localize "CTHULHUETERNAL.Label.killRadius"}} : {{weapon.system.killRadius}} {{weapon.system.rangeUnit}}</li>
<li>{{localize "CTHULHUETERNAL.Label.killRadiusInfo"}}</li> <li>{{localize "CTHULHUETERNAL.Label.killRadiusInfo"}}</li>
{{/if}} {{/if}}
{{#if (gt weapon.system.armorPiercing 0)}}
<li>{{localize "CTHULHUETERNAL.Label.armorPiercing"}} : {{weapon.system.armorPiercing}}</li>
{{/if}}
{{#if (gt weapon.system.penetration 0)}}
<li>{{localize "CTHULHUETERNAL.Label.penetration"}} : {{weapon.system.penetration}}</li>
{{/if}}
{{#if ammoUsed}} {{#if ammoUsed}}
<li>{{localize "CTHULHUETERNAL.Label.ammoUsed"}}: {{ammoUsed}} / {{weapon.system.ammo.value}}</li> <li>{{localize "CTHULHUETERNAL.Label.ammoUsed"}}: {{ammoUsed}} / {{weapon.system.ammo.value}}</li>
{{/if}} {{/if}}
<li class="result-non-lethal">{{localize "CTHULHUETERNAL.Label.damageMessage"}}: <strong>{{rollResult}}</strong></li>
<li class="li-apply-wounds">
{{localize "CTHULHUETERNAL.Label.applyWounds"}}
<select name="combatant" class="li-apply-wounds-select">
{{selectOptions combatants valueAttr="id" labelAttr="name"}}
</select>
</li>
<li class="result-non-lethal">{{localize "CTHULHUETERNAL.Label.damageMessage"}}: <strong>{{rollResult}}</strong>
</li>
</ul> </ul>

View File

@@ -0,0 +1,8 @@
<div class="{{cssClass}}">
<div class="chat-san-request">
<ul>
<li><strong>{{localize "CTHULHUETERNAL.Label.SANLossNone"}}</strong></li>
</ul>
</div>
</div>

View File

@@ -0,0 +1,8 @@
<div class="{{cssClass}}">
<div class="chat-san-request">
<ul>
<li><strong>{{localize "CTHULHUETERNAL.Label.SANLossUnnatural"}}</strong></li>
</ul>
</div>
</div>

View File

@@ -1,7 +1,11 @@
<div class="{{cssClass}}"> <div class="{{cssClass}}">
<div class="chat-san-request"> <div class="chat-san-request">
<ul> <ul>
<li><strong>{{localize "CTHULHUETERNAL.Label.SANTest"}}</strong></li> {{#if rollData.isSuccess}}
<li><strong>{{localize "CTHULHUETERNAL.Label.SANTestSuccess"}}</strong></li>
{{else}}
<li><strong>{{localize "CTHULHUETERNAL.Label.SANTestFailure"}}</strong></li>
{{/if}}
<li class="san-loose-buttons"> <li class="san-loose-buttons">
<button class="san-loose" data-san-value="0">0</button> <button class="san-loose" data-san-value="0">0</button>

View File

@@ -16,11 +16,64 @@
{{item.name}} {{item.name}}
</div> </div>
<img src="systems/fvtt-cthulhu-eternal/assets/ui/d100.svg" class="d100" /> <div class="damage" data-tooltip="{{localize 'CTHULHUETERNAL.Tooltip.rollDamage'}}">
<a class="damage rollable" data-item-id="{{item.id}}" data-action="roll" data-roll-type="damage" {{#if (eq system.lethality 0)}}
data-roll-value="{{item.system.damage}}"> <img src="systems/fvtt-cthulhu-eternal/assets/ui/d100.svg" class="d100" />
{{localize "CTHULHUETERNAL.Label.damageShort"}} :
{{item.system.damage}}</a> {{#if item.system.hasDamageDistance}}
{{#each item.system.damageDistance as |damageDistance|}}
{{#if (gt damageDistance.distance 0)}}
<a class="rollable" data-item-id="{{item.id}}" data-action="roll" data-roll-type="damage"
data-roll-value="{{damageDistance.damage}}" >
<span class="damage-distance">{{damageDistance.distance}}:{{damageDistance.damage}}&nbsp;&nbsp;</span>
</a>
{{/if}}
{{/each}}
{{else}}
<a class="rollable" data-item-id="{{item.id}}" data-action="roll" data-roll-type="damage"
data-roll-value="{{item.system.damage}}" >
{{item.system.damage}}
</a>
{{/if}}
{{else}}
N/A
{{/if}}
</div>
{{#if (gt system.baseRange 0)}}
<span class="range" data-tooltip="CTHULHUETERNAL.Label.baseRange">{{item.system.baseRange}} {{item.system.rangeUnit}}</span>
{{else}}
<span class="range">{{localize "CTHULHUETERNAL.Label.melee"}}</span>
{{/if}}
{{#if (gt system.lethality 0)}}
<a class="lethality rollable" data-item-id="{{item.id}}" data-action="roll" data-roll-type="damage"
data-tooltip="CTHULHUETERNAL.Label.Lethality" >
<img src="systems/fvtt-cthulhu-eternal/assets/ui/d100.svg" class="d100" />
{{item.system.lethality}}%
</a>
{{else}}
<span class="lethality" data-tooltip="CTHULHUETERNAL.Label.Lethality">-</span>
{{/if}}
{{#if (gt system.killRadius 0)}}
<span class="lethality" data-tooltip="CTHULHUETERNAL.Label.killRadius" >{{item.system.killRadius}}</span>
{{else}}
<span class="lethality" data-tooltip="CTHULHUETERNAL.Label.killRadius">-</span>
{{/if}}
{{#if (gt system.armorPiercing 0)}}
<span class="lethality" data-tooltip="CTHULHUETERNAL.Label.armorPiercing" >{{item.system.armorPiercing}}</span>
{{else}}
<span class="lethality" data-tooltip="CTHULHUETERNAL.Label.armorPiercing">-</span>
{{/if}}
{{#if (eq system.weaponType "rangedfirearm")}}
<span class="ammo" data-tooltip="CTHULHUETERNAL.Label.Ammo" >{{item.system.ammo.value}}/{{item.system.ammo.max}}</span>
{{else}}
<span class="ammo" data-tooltip="CTHULHUETERNAL.Label.Ammo">N/A</span>
{{/if}}
<div class="controls"> <div class="controls">
<a data-tooltip="{{localize 'CTHULHUETERNAL.Edit'}}" data-action="edit" data-item-id="{{item.id}}" <a data-tooltip="{{localize 'CTHULHUETERNAL.Edit'}}" data-action="edit" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a> data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a>

View File

@@ -12,28 +12,87 @@
<div class="dialog-skill">{{rollItem.name}} : <span class="resource-score">{{initialScore}} ({{mul initialScore 5}}%)</span></div> <div class="dialog-skill">{{rollItem.name}} : <span class="resource-score">{{initialScore}} ({{mul initialScore 5}}%)</span></div>
<div class="dialog-skill">{{localize "CTHULHUETERNAL.Label.Hand"}} : {{rollItem.hand}} <input type="checkbox" data-action="selectHand" {{checked rollItem.enableHand}}></div> <div class="dialog-skill">{{localize "CTHULHUETERNAL.Label.Hand"}} : {{rollItem.hand}} <input type="checkbox" data-action="selectHand" {{checked rollItem.enableHand}}></div>
<div class="dialog-skill">{{localize "CTHULHUETERNAL.Label.Stowed"}} : {{rollItem.stowed}} <input type="checkbox" data-action="selectStowed" {{checked rollItem.enableStowed}}></div> <div class="dialog-skill">{{localize "CTHULHUETERNAL.Label.Stowed"}} : {{rollItem.stowed}} <input type="checkbox" data-action="selectStowed" {{checked rollItem.enableStowed}}></div>
<div class="dialog-skill">{{localize "CTHULHUETERNAL.Label.Storage"}} : {{rollItem.storage}} <input type="checkbox" data-action="selectStorage" {{checked rollItem.enableStorage}}></div> <div class="dialog-skill">
{{localize "CTHULHUETERNAL.Label.Storage"}} : {{rollItem.storage}}
<input type="checkbox" data-action="selectStorage" {{checked rollItem.enableStorage}}>
</div>
{{else}} {{else}}
<div class="dialog-skill">{{rollItem.name}} : {{initialScore}}%</div> <div class="dialog-skill">{{rollItem.name}} : {{initialScore}}%</div>
{{/if}} {{/if}}
{{#if weapon}} {{#if weapon}}
<div class="dialog-skill">{{localize "CTHULHUETERNAL.Label.Weapon"}} : {{weapon.name}}</div> <div class="dialog-skill">{{localize "CTHULHUETERNAL.Label.Weapon"}} : {{weapon.name}}</div>
{{#if (eq weapon.system.weaponType "melee")}}
<div class="dialog-skill">
{{localize "CTHULHUETERNAL.Label.targetMove"}}
<select name="meleeTargetMoveChoice" class="roll-skill-modifier">
{{selectOptions choiceMeleeTargetMove localize=true selected=meleeTargetMoveChoice valueAttr="id" labelAttr="label"}}
</select>
</div>
{{/if}}
{{#if isRangedWeapon}}
<div class="dialog-skill">
{{localize "CTHULHUETERNAL.Label.rangedRange"}}
<select name="rangedRangeChoice" class="roll-skill-modifier">
{{selectOptions choiceRangedRange localize=true selected=rangedRangeChoice valueAttr="id" labelAttr="label"}}
</select>
</div>
<div class="dialog-skill">
{{localize "CTHULHUETERNAL.Label.targetMove"}}
<select name="rangedTargetMoveChoice" class="roll-skill-modifier">
{{selectOptions choiceRangedTargetMove localize=true selected=rangedTargetMoveChoice valueAttr="id" labelAttr="label"}}
</select>
</div>
<div class="dialog-skill">
{{localize "CTHULHUETERNAL.Label.aimingLastRound"}}
<input type="checkbox" name="aimingLastRound">
</div>
{{#if weapon.system.hasSight}}
<div class="dialog-skill">
{{localize "CTHULHUETERNAL.Label.aimingWithSight"}}
<input type="checkbox" name="aimingWithSight">
</div>
{{/if}}
{{/if}}
<div class="dialog-skill">
{{localize "CTHULHUETERNAL.Label.visibility"}}
<select name="visibilityChoice" class="roll-skill-modifier">
{{selectOptions choiceVisibility localize=true selected=visibilityChoice valueAttr="id" labelAttr="label"}}
</select>
</div>
<div class="dialog-skill">
{{localize "CTHULHUETERNAL.Label.attackerState"}}
<select name="attackerStateChoice" class="roll-skill-modifier">
{{selectOptions choiceAttackerState localize=true selected=attackerStateChoice valueAttr="id" labelAttr="label"}}
</select>
</div>
<div class="dialog-skill">
{{localize "CTHULHUETERNAL.Label.targetSize"}}
<select name="targetSizeChoice" class="roll-skill-modifier">
{{selectOptions choiceTargetSize localize=true selected=targetSizeChoice valueAttr="id" labelAttr="label"}}
</select>
</div>
{{#if weapon.system.hasSelectiveFire}} {{#if weapon.system.hasSelectiveFire}}
<div class="dialog-skill">Selective Fire : <div class="dialog-skill">Selective Fire :
<select name="selectiveFireChoice" class="roll-skill-modifier"> <select name="selectiveFireChoice" class="roll-skill-modifier">
{{selectOptions choiceSelectiveFire localize=true selected=selectiveFireChoice nameAttr="id" labelAttr="label"}} {{selectOptions choiceSelectiveFire localize=true selected=selectiveFireChoice valueAttr="id" labelAttr="label"}}
</select> </select>
</div> </div>
{{/if}} {{/if}}
{{/if}} {{/if}}
{{#if isZeroWP}} {{#if isZeroWP}}
<div class="dialog-skill red-warning">{{localize "CTHULHUETERNAL.Label.ZeroWP"}}</div> <div class="dialog-skill red-warning">{{localize "CTHULHUETERNAL.Label.ZeroWP"}}</div>
{{else}} {{else}}
{{#if isLowWP}} {{#if isLowWP}}
<div class="dialog-skill orange-warning">{{localize "CTHULHUETERNAL.Label.LowWP"}} : -20%</div> <div class="dialog-skill orange-warning">{{localize "CTHULHUETERNAL.Label.LowWP"}} : -20%</div>
{{/if}} {{/if}}
{{/if}} {{/if}}
{{#if isExhausted}} {{#if isExhausted}}

View File

@@ -12,32 +12,60 @@
{{/if}} {{/if}}
{{formField systemFields.state value=system.state localize=true}} {{formField systemFields.state value=system.state localize=true}}
{{formField systemFields.isStunning value=system.isStunning localize=true}}
<div class="flexrow">
{{formField systemFields.hasDirectSkill value=system.hasDirectSkill }} {{formField systemFields.hasDirectSkill value=system.hasDirectSkill }}
{{#if system.hasDirectSkill}} {{#if system.hasDirectSkill}}
{{formField systemFields.directSkillValue value=system.directSkillValue }} {{formField systemFields.directSkillValue value=system.directSkillValue }}
{{/if}} {{/if}}
</div>
{{formField systemFields.applyDamageBonus value=system.applyDamageBonus}} <div class="flexrow">
{{formField systemFields.damage value=system.damage}} {{formField systemFields.hasDamageDistance value=system.hasDamageDistance localize=true}}
</div>
{{#if isRanged}} {{#if system.hasDamageDistance}}
{{formField systemFields.baseRange value=system.baseRange}} {{#each system.damageDistance as |damageDistance idx|}}
{{formField systemFields.rangeUnit value=system.rangeUnit localize=true}} <div class="flexrow">
<label class="damage-distance">Distance</label><input type="number" name="system.damageDistance.{{idx}}.distance" value="{{damageDistance.distance}}" min="0" />
<label>Damage</label><input type="text" name="system.damageDistance.{{idx}}.damage" value="{{damageDistance.damage}}" />
</div>
{{/each}}
{{else}}
<div class="flexrow">
{{formField systemFields.damage value=system.damage}}
{{formField systemFields.applyDamageBonus value=system.applyDamageBonus}}
</div>
{{#if isRanged}}
<div class="flexrow">
{{formField systemFields.baseRange value=system.baseRange}}
{{formField systemFields.rangeUnit value=system.rangeUnit localize=true}}
</div>
{{/if}}
{{/if}} {{/if}}
{{#if isFireArm}} {{#if isFireArm}}
<div class="flexrow">
{{formField systemFields.hasSelectiveFire value=system.hasSelectiveFire}} {{formField systemFields.hasSelectiveFire value=system.hasSelectiveFire}}
{{formField systemFields.hasSight value=system.hasSight}}
</div>
<div class="flexrow">
{{formField systemFields.ammo.fields.value value=system.ammo.value}} {{formField systemFields.ammo.fields.value value=system.ammo.value}}
{{formField systemFields.ammo.fields.max value=system.ammo.max}} {{formField systemFields.ammo.fields.max value=system.ammo.max}}
</div>
{{/if}} {{/if}}
{{formField systemFields.lethality value=system.lethality}} <div class="flexrow">
{{formField systemFields.killRadius value=system.killRadius}} {{formField systemFields.lethality value=system.lethality}}
{{formField systemFields.killRadius value=system.killRadius}}
</div>
<div class="flexrow">
{{formField systemFields.armorPiercing value=system.armorPiercing}} {{formField systemFields.armorPiercing value=system.armorPiercing}}
{{formField systemFields.resourceLevel value=system.resourceLevel}} {{formField systemFields.resourceLevel value=system.resourceLevel}}
</div>
</fieldset> </fieldset>
<fieldset> <fieldset>