Import initial
This commit is contained in:
@@ -0,0 +1,757 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'Cinzel';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://fonts.gstatic.com/s/cinzel/v26/8vIU7ww63mVu7gtR-kwKxNvkNOjw-tbnTYo.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cinzel';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://fonts.gstatic.com/s/cinzel/v26/8vIU7ww63mVu7gtR-kwKxNvkNOjw-gjgTYo.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cinzel';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://fonts.gstatic.com/s/cinzel/v26/8vIU7ww63mVu7gtR-kwKxNvkNOjw-jHgTYo.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cormorant Garamond';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://fonts.gstatic.com/s/cormorantgaramond/v21/co3umX5slCNuHLi8bLeY9MK7whWMhyjypVO7abI26QOD_v86GnM.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cormorant Garamond';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://fonts.gstatic.com/s/cormorantgaramond/v21/co3umX5slCNuHLi8bLeY9MK7whWMhyjypVO7abI26QOD_s06GnM.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cormorant Garamond';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://fonts.gstatic.com/s/cormorantgaramond/v21/co3umX5slCNuHLi8bLeY9MK7whWMhyjypVO7abI26QOD_iE9GnM.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cormorant Garamond';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://fonts.gstatic.com/s/cormorantgaramond/v21/co3umX5slCNuHLi8bLeY9MK7whWMhyjypVO7abI26QOD_hg9GnM.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'IM Fell English SC';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://fonts.gstatic.com/s/imfellenglishsc/v16/a8IENpD3CDX-4zrWfr1VY879qFF05pZLOw.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies.sheet,
|
||||||
|
.fvtt-les-oublies.sheet .window-content {
|
||||||
|
--lo-bg-deep: #0f1714;
|
||||||
|
--lo-bg-moss: #1a2820;
|
||||||
|
--lo-bg-night: #18211b;
|
||||||
|
--lo-panel: rgba(247, 237, 218, 0.92);
|
||||||
|
--lo-panel-heavy: rgba(236, 222, 196, 0.94);
|
||||||
|
--lo-panel-soft: rgba(255, 250, 241, 0.76);
|
||||||
|
--lo-ink: #221610;
|
||||||
|
--lo-ink-soft: #584336;
|
||||||
|
--lo-gold: #cfb06a;
|
||||||
|
--lo-copper: #8d5c3b;
|
||||||
|
--lo-blood: #6d2922;
|
||||||
|
--lo-shadow: rgba(0, 0, 0, 0.42);
|
||||||
|
--lo-line: rgba(110, 77, 53, 0.4);
|
||||||
|
--lo-glow: rgba(207, 176, 106, 0.22);
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies.sheet {
|
||||||
|
color: var(--lo-ink);
|
||||||
|
font-family: "Cormorant Garamond", Georgia, serif;
|
||||||
|
background: radial-gradient(circle at top left, rgba(120, 103, 63, 0.22), transparent 28%), radial-gradient(circle at top right, rgba(78, 107, 76, 0.18), transparent 24%), linear-gradient(180deg, rgba(14, 22, 18, 0.95), rgba(23, 31, 26, 0.96));
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies.sheet .window-content {
|
||||||
|
background: linear-gradient(180deg, rgba(12, 19, 16, 0.92), rgba(22, 29, 25, 0.96)), radial-gradient(circle at 20% 10%, rgba(207, 176, 106, 0.08), transparent 26%);
|
||||||
|
color: var(--lo-ink);
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies {
|
||||||
|
color: var(--lo-ink);
|
||||||
|
padding: 0.4rem;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .les-oublies-sheet {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .les-oublies-sheet::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: -0.35rem;
|
||||||
|
border: 1px solid rgba(207, 176, 106, 0.18);
|
||||||
|
border-radius: 18px;
|
||||||
|
pointer-events: none;
|
||||||
|
box-shadow: 0 0 0 1px rgba(36, 23, 14, 0.5), inset 0 0 40px rgba(0, 0, 0, 0.12);
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .hero-banner {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 110px 1fr;
|
||||||
|
gap: 1.2rem;
|
||||||
|
align-items: stretch;
|
||||||
|
margin-bottom: 1.1rem;
|
||||||
|
padding: 1rem 1.1rem 1.1rem;
|
||||||
|
border-radius: 18px;
|
||||||
|
background: linear-gradient(135deg, rgba(250, 240, 217, 0.98), rgba(232, 214, 182, 0.92)), linear-gradient(180deg, rgba(207, 176, 106, 0.18), rgba(109, 41, 34, 0.08));
|
||||||
|
border: 1px solid rgba(207, 176, 106, 0.4);
|
||||||
|
box-shadow: 0 18px 40px var(--lo-shadow), inset 0 1px 0 rgba(255, 250, 242, 0.7), inset 0 0 0 1px rgba(121, 80, 51, 0.08);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .hero-banner::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.16), transparent), radial-gradient(circle at 85% 15%, rgba(78, 107, 76, 0.16), transparent 18%);
|
||||||
|
mix-blend-mode: soft-light;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .profile-img {
|
||||||
|
width: 110px;
|
||||||
|
height: 132px;
|
||||||
|
object-fit: cover;
|
||||||
|
border: 2px solid rgba(85, 55, 34, 0.7);
|
||||||
|
border-radius: 14px;
|
||||||
|
background: linear-gradient(180deg, #291e17, #5f4435);
|
||||||
|
box-shadow: 0 14px 24px rgba(27, 14, 9, 0.35), 0 0 0 3px rgba(255, 246, 226, 0.35);
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .hero-copy,
|
||||||
|
.fvtt-les-oublies .header-fields {
|
||||||
|
flex: 1;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .sheet-kicker {
|
||||||
|
margin: 0 0 0.18rem;
|
||||||
|
color: var(--lo-blood);
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
font-size: 0.78rem;
|
||||||
|
letter-spacing: 0.24em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .sheet-title {
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .sheet-title input,
|
||||||
|
.fvtt-les-oublies .header-fields h1 input {
|
||||||
|
font-family: "IM Fell English SC", "Cinzel", serif;
|
||||||
|
font-size: clamp(2rem, 2.6vw, 2.8rem);
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
color: #2b1b14;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
box-shadow: none;
|
||||||
|
padding: 0;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .sheet-subtitle {
|
||||||
|
margin: 0.35rem 0 0;
|
||||||
|
color: var(--lo-ink-soft);
|
||||||
|
font-size: 1.05rem;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .sheet-grid {
|
||||||
|
display: grid;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .sheet-grid-2 {
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .sheet-card {
|
||||||
|
background: linear-gradient(180deg, var(--lo-panel), var(--lo-panel-heavy)), linear-gradient(135deg, rgba(255, 255, 255, 0.24), transparent);
|
||||||
|
border: 1px solid rgba(133, 99, 74, 0.5);
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 1rem 1rem 0.95rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
box-shadow: 0 12px 28px rgba(0, 0, 0, 0.18), inset 0 1px 0 rgba(255, 251, 243, 0.6), inset 0 0 0 1px rgba(255, 243, 218, 0.18);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .sheet-card::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: linear-gradient(180deg, rgba(255, 255, 255, 0.14), transparent 22%), radial-gradient(circle at 100% 0, rgba(207, 176, 106, 0.1), transparent 26%);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .sheet-card h2,
|
||||||
|
.fvtt-les-oublies .sheet-card h3 {
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #3a251a;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .sheet-card h2 {
|
||||||
|
margin: 0 0 0.75rem;
|
||||||
|
padding-bottom: 0.35rem;
|
||||||
|
border-bottom: 1px solid rgba(109, 41, 34, 0.18);
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .sheet-card h3 {
|
||||||
|
margin: 0 0 0.55rem;
|
||||||
|
font-size: 0.84rem;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .summary-card {
|
||||||
|
background: linear-gradient(180deg, rgba(246, 235, 210, 0.94), rgba(228, 213, 179, 0.95)), linear-gradient(135deg, rgba(207, 176, 106, 0.16), transparent 60%);
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .profiles-card {
|
||||||
|
background: linear-gradient(180deg, rgba(245, 238, 223, 0.95), rgba(232, 223, 201, 0.92));
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .ledger-card {
|
||||||
|
background: linear-gradient(180deg, rgba(251, 244, 232, 0.95), rgba(236, 224, 198, 0.92));
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .notes-card {
|
||||||
|
background: linear-gradient(180deg, rgba(240, 229, 207, 0.98), rgba(223, 207, 177, 0.95));
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .sheet-actions,
|
||||||
|
.fvtt-les-oublies .embed-buttons,
|
||||||
|
.fvtt-les-oublies .item-controls,
|
||||||
|
.fvtt-les-oublies .section-title-row {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .field-row,
|
||||||
|
.fvtt-les-oublies .profile-cell {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.65rem;
|
||||||
|
margin-bottom: 0.65rem;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .field-row label,
|
||||||
|
.fvtt-les-oublies .profile-cell label {
|
||||||
|
min-width: 10rem;
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
font-size: 0.74rem;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #51392b;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .field-row span {
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
font-size: 0.84rem;
|
||||||
|
color: var(--lo-blood);
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .profile-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
gap: 0.75rem 1rem;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .profile-cell {
|
||||||
|
padding: 0.7rem 0.8rem;
|
||||||
|
border-radius: 14px;
|
||||||
|
background: linear-gradient(180deg, rgba(255, 250, 243, 0.7), rgba(230, 214, 185, 0.6));
|
||||||
|
border: 1px solid rgba(130, 98, 71, 0.2);
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5);
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .group-block + .group-block {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .item-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.65rem;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .item-card {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 1rem;
|
||||||
|
padding: 0.8rem 0.9rem;
|
||||||
|
border: 1px solid rgba(118, 85, 58, 0.22);
|
||||||
|
border-radius: 14px;
|
||||||
|
background: linear-gradient(180deg, rgba(255, 252, 246, 0.78), rgba(239, 229, 206, 0.78)), linear-gradient(135deg, rgba(207, 176, 106, 0.08), transparent);
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.56), 0 6px 14px rgba(0, 0, 0, 0.08);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .item-card::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
left: 0.55rem;
|
||||||
|
top: 0.6rem;
|
||||||
|
bottom: 0.6rem;
|
||||||
|
width: 3px;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: linear-gradient(180deg, var(--lo-gold), var(--lo-blood));
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .item-card > div:first-child {
|
||||||
|
padding-left: 0.6rem;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .item-card strong,
|
||||||
|
.fvtt-les-oublies .reference-list strong {
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
color: #3d281d;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .reference-list {
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 1.2rem;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .reference-list li + li {
|
||||||
|
margin-top: 0.35rem;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .help-text {
|
||||||
|
color: var(--lo-ink-soft);
|
||||||
|
font-size: 0.96rem;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .mode-button,
|
||||||
|
.fvtt-les-oublies button {
|
||||||
|
cursor: pointer;
|
||||||
|
border: 1px solid rgba(99, 61, 40, 0.45);
|
||||||
|
border-radius: 999px;
|
||||||
|
background: linear-gradient(180deg, #2e3f34, #18231d);
|
||||||
|
color: #f2e5c8;
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
font-size: 0.72rem;
|
||||||
|
letter-spacing: 0.12em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
padding: 0.5rem 0.9rem;
|
||||||
|
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.18), inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
||||||
|
transition: transform 120ms ease, box-shadow 120ms ease, border-color 120ms ease;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .les-oublies-roll-dialog {
|
||||||
|
color: var(--lo-ink);
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .les-oublies-roll-dialog .sheet-card {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .les-oublies-roll-dialog .field-row input,
|
||||||
|
.fvtt-les-oublies .les-oublies-roll-dialog .field-row select {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies button:hover,
|
||||||
|
.fvtt-les-oublies button:focus {
|
||||||
|
transform: translateY(-1px);
|
||||||
|
border-color: rgba(207, 176, 106, 0.75);
|
||||||
|
box-shadow: 0 12px 22px rgba(0, 0, 0, 0.22), 0 0 0 1px rgba(207, 176, 106, 0.24);
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies input[type="text"],
|
||||||
|
.fvtt-les-oublies input[type="number"],
|
||||||
|
.fvtt-les-oublies select,
|
||||||
|
.fvtt-les-oublies textarea {
|
||||||
|
background: linear-gradient(180deg, rgba(255, 251, 244, 0.96), rgba(238, 226, 201, 0.96));
|
||||||
|
border: 1px solid rgba(113, 79, 56, 0.42);
|
||||||
|
border-radius: 10px;
|
||||||
|
color: #2e1f18;
|
||||||
|
font-family: "Cormorant Garamond", Georgia, serif;
|
||||||
|
font-size: 1rem;
|
||||||
|
min-height: 2.1rem;
|
||||||
|
padding: 0.2rem 0.65rem;
|
||||||
|
box-shadow: inset 0 1px 3px rgba(72, 46, 30, 0.08);
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies input[type="checkbox"] {
|
||||||
|
accent-color: #6d2922;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .sheet-card .editor,
|
||||||
|
.fvtt-les-oublies .sheet-card .editor-content,
|
||||||
|
.fvtt-les-oublies .sheet-card .editor-container,
|
||||||
|
.fvtt-les-oublies prose-mirror {
|
||||||
|
background: rgba(255, 252, 246, 0.62);
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .prosemirror,
|
||||||
|
.fvtt-les-oublies prose-mirror {
|
||||||
|
border: 1px solid rgba(111, 84, 55, 0.18);
|
||||||
|
padding: 0.6rem 0.7rem;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies a,
|
||||||
|
.fvtt-les-oublies button[data-action="rollProfile"],
|
||||||
|
.fvtt-les-oublies button[data-action="rollSkill"] {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies button[data-action="rollProfile"],
|
||||||
|
.fvtt-les-oublies button[data-action="rollSkill"] {
|
||||||
|
background: linear-gradient(180deg, #6a2f29, #421914);
|
||||||
|
color: #f8ead3;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .compagnie-sheet .hero-banner {
|
||||||
|
background: linear-gradient(135deg, rgba(245, 235, 210, 0.98), rgba(224, 205, 173, 0.93)), linear-gradient(180deg, rgba(207, 176, 106, 0.18), rgba(58, 37, 26, 0.08));
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .creature-sheet .hero-banner {
|
||||||
|
background: linear-gradient(135deg, rgba(236, 226, 206, 0.96), rgba(213, 196, 166, 0.92)), radial-gradient(circle at 90% 15%, rgba(109, 41, 34, 0.14), transparent 28%);
|
||||||
|
}
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
.fvtt-les-oublies .sheet-grid-2,
|
||||||
|
.fvtt-les-oublies .profile-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .hero-banner {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
.fvtt-les-oublies .profile-img {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 110px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.chat-message .les-oublies-chat-card,
|
||||||
|
.chat-popout .les-oublies-chat-card,
|
||||||
|
#chat-log .les-oublies-chat-card {
|
||||||
|
--lo-chat-bg-top: rgba(249, 241, 227, 0.98);
|
||||||
|
--lo-chat-bg-bottom: rgba(226, 209, 178, 0.96);
|
||||||
|
--lo-chat-line: rgba(114, 80, 55, 0.26);
|
||||||
|
--lo-chat-ink: #2f1f17;
|
||||||
|
--lo-chat-soft: #6a5142;
|
||||||
|
--lo-chat-gold: #cfb06a;
|
||||||
|
--lo-chat-blood: #6d2922;
|
||||||
|
color: var(--lo-chat-ink);
|
||||||
|
background: linear-gradient(180deg, var(--lo-chat-bg-top), var(--lo-chat-bg-bottom)), linear-gradient(135deg, rgba(207, 176, 106, 0.18), transparent 72%);
|
||||||
|
border: 1px solid rgba(133, 99, 74, 0.45);
|
||||||
|
border-radius: 18px;
|
||||||
|
padding: 0.9rem 1rem;
|
||||||
|
margin: 0.2rem 0;
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.56), 0 10px 28px rgba(0, 0, 0, 0.14);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.chat-message .les-oublies-chat-card::before,
|
||||||
|
.chat-popout .les-oublies-chat-card::before,
|
||||||
|
#chat-log .les-oublies-chat-card::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
background: linear-gradient(180deg, rgba(255, 255, 255, 0.16), transparent 24%), radial-gradient(circle at 100% 0, rgba(207, 176, 106, 0.14), transparent 28%);
|
||||||
|
}
|
||||||
|
.chat-message .les-oublies-chat-card.is-success,
|
||||||
|
.chat-popout .les-oublies-chat-card.is-success,
|
||||||
|
#chat-log .les-oublies-chat-card.is-success {
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.56), 0 10px 28px rgba(0, 0, 0, 0.14), 0 0 0 1px rgba(65, 107, 72, 0.18);
|
||||||
|
}
|
||||||
|
.chat-message .les-oublies-chat-card.is-failure,
|
||||||
|
.chat-popout .les-oublies-chat-card.is-failure,
|
||||||
|
#chat-log .les-oublies-chat-card.is-failure {
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.56), 0 10px 28px rgba(0, 0, 0, 0.14), 0 0 0 1px rgba(109, 41, 34, 0.18);
|
||||||
|
}
|
||||||
|
.chat-message .chat-card-banner,
|
||||||
|
.chat-popout .chat-card-banner,
|
||||||
|
#chat-log .chat-card-banner {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 3rem 1fr auto;
|
||||||
|
gap: 0.8rem;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
.chat-message .chat-card-portrait,
|
||||||
|
.chat-popout .chat-card-portrait,
|
||||||
|
#chat-log .chat-card-portrait {
|
||||||
|
width: 3rem;
|
||||||
|
height: 3rem;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 14px;
|
||||||
|
border: 1px solid rgba(91, 60, 39, 0.5);
|
||||||
|
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.16);
|
||||||
|
background: linear-gradient(180deg, #2c1d16, #6b4a37);
|
||||||
|
}
|
||||||
|
.chat-message .chat-card-kicker,
|
||||||
|
.chat-popout .chat-card-kicker,
|
||||||
|
#chat-log .chat-card-kicker {
|
||||||
|
margin: 0;
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
font-size: 0.66rem;
|
||||||
|
letter-spacing: 0.18em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--lo-chat-blood);
|
||||||
|
}
|
||||||
|
.chat-message .chat-card-header h3,
|
||||||
|
.chat-popout .chat-card-header h3,
|
||||||
|
#chat-log .chat-card-header h3 {
|
||||||
|
margin: 0.08rem 0 0;
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
font-size: 1rem;
|
||||||
|
letter-spacing: 0.06em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #3a251a;
|
||||||
|
}
|
||||||
|
.chat-message .chat-card-subtitle,
|
||||||
|
.chat-popout .chat-card-subtitle,
|
||||||
|
#chat-log .chat-card-subtitle {
|
||||||
|
margin: 0.2rem 0 0;
|
||||||
|
color: var(--lo-chat-soft);
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
.chat-message .chat-card-badge,
|
||||||
|
.chat-popout .chat-card-badge,
|
||||||
|
#chat-log .chat-card-badge {
|
||||||
|
align-self: start;
|
||||||
|
padding: 0.38rem 0.65rem;
|
||||||
|
border-radius: 999px;
|
||||||
|
border: 1px solid var(--lo-chat-line);
|
||||||
|
background: rgba(255, 249, 239, 0.7);
|
||||||
|
color: #3a251a;
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
font-size: 0.72rem;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-align: center;
|
||||||
|
max-width: 13rem;
|
||||||
|
}
|
||||||
|
.chat-message .chat-card-badge.success,
|
||||||
|
.chat-popout .chat-card-badge.success,
|
||||||
|
#chat-log .chat-card-badge.success {
|
||||||
|
background: rgba(226, 243, 225, 0.74);
|
||||||
|
color: #29422d;
|
||||||
|
}
|
||||||
|
.chat-message .chat-card-badge.failure,
|
||||||
|
.chat-popout .chat-card-badge.failure,
|
||||||
|
#chat-log .chat-card-badge.failure {
|
||||||
|
background: rgba(245, 223, 220, 0.74);
|
||||||
|
color: #6d2922;
|
||||||
|
}
|
||||||
|
.chat-message .chat-card-badge.neutral,
|
||||||
|
.chat-popout .chat-card-badge.neutral,
|
||||||
|
#chat-log .chat-card-badge.neutral {
|
||||||
|
background: rgba(242, 233, 212, 0.78);
|
||||||
|
}
|
||||||
|
.chat-message .chat-card-body,
|
||||||
|
.chat-popout .chat-card-body,
|
||||||
|
#chat-log .chat-card-body {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
.chat-message .chat-card-body p,
|
||||||
|
.chat-popout .chat-card-body p,
|
||||||
|
#chat-log .chat-card-body p {
|
||||||
|
margin: 0.45rem 0 0;
|
||||||
|
}
|
||||||
|
.chat-message .roll-summary-grid,
|
||||||
|
.chat-popout .roll-summary-grid,
|
||||||
|
#chat-log .roll-summary-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
gap: 0.55rem;
|
||||||
|
margin: 0.85rem 0 0.8rem;
|
||||||
|
}
|
||||||
|
.chat-message .roll-summary-grid div,
|
||||||
|
.chat-popout .roll-summary-grid div,
|
||||||
|
#chat-log .roll-summary-grid div {
|
||||||
|
padding: 0.58rem 0.68rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: rgba(255, 250, 241, 0.68);
|
||||||
|
border: 1px solid var(--lo-chat-line);
|
||||||
|
}
|
||||||
|
.chat-message .roll-summary-grid span,
|
||||||
|
.chat-popout .roll-summary-grid span,
|
||||||
|
#chat-log .roll-summary-grid span {
|
||||||
|
display: block;
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
font-size: 0.66rem;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--lo-chat-blood);
|
||||||
|
}
|
||||||
|
.chat-message .roll-summary-grid strong,
|
||||||
|
.chat-popout .roll-summary-grid strong,
|
||||||
|
#chat-log .roll-summary-grid strong {
|
||||||
|
font-size: 1.08rem;
|
||||||
|
color: var(--lo-chat-ink);
|
||||||
|
}
|
||||||
|
.chat-message .roll-formula,
|
||||||
|
.chat-popout .roll-formula,
|
||||||
|
#chat-log .roll-formula {
|
||||||
|
margin-top: 0.2rem;
|
||||||
|
padding: 0.55rem 0.7rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: rgba(255, 249, 239, 0.52);
|
||||||
|
border: 1px solid rgba(118, 85, 58, 0.14);
|
||||||
|
}
|
||||||
|
.chat-message .dice-strip,
|
||||||
|
.chat-popout .dice-strip,
|
||||||
|
#chat-log .dice-strip {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.55rem;
|
||||||
|
margin-top: 0.8rem;
|
||||||
|
}
|
||||||
|
.chat-message .die-chip,
|
||||||
|
.chat-popout .die-chip,
|
||||||
|
#chat-log .die-chip {
|
||||||
|
min-width: 8.4rem;
|
||||||
|
padding: 0.62rem 0.72rem;
|
||||||
|
border-radius: 13px;
|
||||||
|
background: rgba(247, 238, 221, 0.8);
|
||||||
|
border: 1px solid rgba(118, 85, 58, 0.18);
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.52);
|
||||||
|
}
|
||||||
|
.chat-message .die-chip.selected,
|
||||||
|
.chat-popout .die-chip.selected,
|
||||||
|
#chat-log .die-chip.selected {
|
||||||
|
border-color: rgba(207, 176, 106, 0.86);
|
||||||
|
background: rgba(255, 247, 228, 0.92);
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.52), 0 0 0 1px rgba(207, 176, 106, 0.28);
|
||||||
|
}
|
||||||
|
.chat-message .die-chip strong,
|
||||||
|
.chat-popout .die-chip strong,
|
||||||
|
#chat-log .die-chip strong,
|
||||||
|
.chat-message .die-chip em,
|
||||||
|
.chat-popout .die-chip em,
|
||||||
|
#chat-log .die-chip em,
|
||||||
|
.chat-message .die-chip span,
|
||||||
|
.chat-popout .die-chip span,
|
||||||
|
#chat-log .die-chip span {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.chat-message .die-chip span,
|
||||||
|
.chat-popout .die-chip span,
|
||||||
|
#chat-log .die-chip span {
|
||||||
|
color: var(--lo-chat-ink);
|
||||||
|
}
|
||||||
|
.chat-message .die-chip em,
|
||||||
|
.chat-popout .die-chip em,
|
||||||
|
#chat-log .die-chip em {
|
||||||
|
color: var(--lo-chat-blood);
|
||||||
|
font-size: 0.82rem;
|
||||||
|
}
|
||||||
|
.chat-message .chat-callouts,
|
||||||
|
.chat-popout .chat-callouts,
|
||||||
|
#chat-log .chat-callouts {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.6rem;
|
||||||
|
margin-top: 0.8rem;
|
||||||
|
}
|
||||||
|
.chat-message .chat-callout,
|
||||||
|
.chat-popout .chat-callout,
|
||||||
|
#chat-log .chat-callout {
|
||||||
|
min-width: 10rem;
|
||||||
|
flex: 1 1 10rem;
|
||||||
|
padding: 0.62rem 0.75rem;
|
||||||
|
border-radius: 13px;
|
||||||
|
background: rgba(255, 250, 241, 0.62);
|
||||||
|
border: 1px solid var(--lo-chat-line);
|
||||||
|
}
|
||||||
|
.chat-message .chat-callout span,
|
||||||
|
.chat-popout .chat-callout span,
|
||||||
|
#chat-log .chat-callout span,
|
||||||
|
.chat-message .chat-callout strong,
|
||||||
|
.chat-popout .chat-callout strong,
|
||||||
|
#chat-log .chat-callout strong,
|
||||||
|
.chat-message .chat-callout em,
|
||||||
|
.chat-popout .chat-callout em,
|
||||||
|
#chat-log .chat-callout em {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.chat-message .chat-callout span,
|
||||||
|
.chat-popout .chat-callout span,
|
||||||
|
#chat-log .chat-callout span {
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
font-size: 0.66rem;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--lo-chat-blood);
|
||||||
|
}
|
||||||
|
.chat-message .chat-callout strong,
|
||||||
|
.chat-popout .chat-callout strong,
|
||||||
|
#chat-log .chat-callout strong {
|
||||||
|
color: var(--lo-chat-ink);
|
||||||
|
}
|
||||||
|
.chat-message .chat-callout em,
|
||||||
|
.chat-popout .chat-callout em,
|
||||||
|
#chat-log .chat-callout em {
|
||||||
|
color: var(--lo-chat-soft);
|
||||||
|
font-size: 0.88rem;
|
||||||
|
}
|
||||||
|
.chat-message .chat-callout.warning,
|
||||||
|
.chat-popout .chat-callout.warning,
|
||||||
|
#chat-log .chat-callout.warning {
|
||||||
|
background: rgba(245, 223, 220, 0.72);
|
||||||
|
}
|
||||||
|
.chat-message .confrontation-body,
|
||||||
|
.chat-popout .confrontation-body,
|
||||||
|
#chat-log .confrontation-body {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
gap: 0.85rem;
|
||||||
|
margin-top: 0.8rem;
|
||||||
|
}
|
||||||
|
.chat-message .chat-side-card,
|
||||||
|
.chat-popout .chat-side-card,
|
||||||
|
#chat-log .chat-side-card {
|
||||||
|
padding: 0.82rem 0.88rem;
|
||||||
|
border-radius: 15px;
|
||||||
|
border: 1px solid var(--lo-chat-line);
|
||||||
|
background: rgba(255, 251, 245, 0.58);
|
||||||
|
}
|
||||||
|
.chat-message .chat-side-card.is-success,
|
||||||
|
.chat-popout .chat-side-card.is-success,
|
||||||
|
#chat-log .chat-side-card.is-success {
|
||||||
|
box-shadow: inset 3px 0 0 rgba(65, 107, 72, 0.6);
|
||||||
|
}
|
||||||
|
.chat-message .chat-side-card.is-failure,
|
||||||
|
.chat-popout .chat-side-card.is-failure,
|
||||||
|
#chat-log .chat-side-card.is-failure {
|
||||||
|
box-shadow: inset 3px 0 0 rgba(109, 41, 34, 0.6);
|
||||||
|
}
|
||||||
|
.chat-message .chat-side-head,
|
||||||
|
.chat-popout .chat-side-head,
|
||||||
|
#chat-log .chat-side-head {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 0.5rem;
|
||||||
|
align-items: baseline;
|
||||||
|
margin-bottom: 0.2rem;
|
||||||
|
}
|
||||||
|
.chat-message .chat-side-head h2,
|
||||||
|
.chat-popout .chat-side-head h2,
|
||||||
|
#chat-log .chat-side-head h2 {
|
||||||
|
margin: 0;
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
font-size: 0.92rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.06em;
|
||||||
|
color: #3a251a;
|
||||||
|
}
|
||||||
|
.chat-message .chat-side-mode,
|
||||||
|
.chat-popout .chat-side-mode,
|
||||||
|
#chat-log .chat-side-mode {
|
||||||
|
color: var(--lo-chat-soft);
|
||||||
|
font-size: 0.86rem;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
@media (max-width: 720px) {
|
||||||
|
.chat-message .chat-card-banner,
|
||||||
|
.chat-popout .chat-card-banner,
|
||||||
|
#chat-log .chat-card-banner {
|
||||||
|
grid-template-columns: 3rem 1fr;
|
||||||
|
}
|
||||||
|
.chat-message .chat-card-badge,
|
||||||
|
.chat-popout .chat-card-badge,
|
||||||
|
#chat-log .chat-card-badge {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
justify-self: start;
|
||||||
|
}
|
||||||
|
.chat-message .roll-summary-grid,
|
||||||
|
.chat-popout .roll-summary-grid,
|
||||||
|
#chat-log .roll-summary-grid,
|
||||||
|
.chat-message .confrontation-body,
|
||||||
|
.chat-popout .confrontation-body,
|
||||||
|
#chat-log .confrontation-body {
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*# sourceMappingURL=les-oublies.css.map */
|
||||||
|
/*# sourceMappingURL=les-oublies.css.map */
|
||||||
File diff suppressed because one or more lines are too long
+26
@@ -0,0 +1,26 @@
|
|||||||
|
import gulp from "gulp"
|
||||||
|
import less from "gulp-less"
|
||||||
|
import sourcemaps from "gulp-sourcemaps"
|
||||||
|
|
||||||
|
const paths = {
|
||||||
|
styles: {
|
||||||
|
src: "less/**/*.less",
|
||||||
|
entry: "less/les-oublies.less",
|
||||||
|
dest: "css/",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export function styles() {
|
||||||
|
return gulp.src(paths.styles.entry)
|
||||||
|
.pipe(sourcemaps.init())
|
||||||
|
.pipe(less())
|
||||||
|
.pipe(sourcemaps.write("."))
|
||||||
|
.pipe(gulp.dest(paths.styles.dest))
|
||||||
|
}
|
||||||
|
|
||||||
|
export function watch() {
|
||||||
|
gulp.watch(paths.styles.src, styles)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const build = gulp.series(styles)
|
||||||
|
export default gulp.series(build, watch)
|
||||||
+191
@@ -0,0 +1,191 @@
|
|||||||
|
{
|
||||||
|
"TYPES": {
|
||||||
|
"Actor": {
|
||||||
|
"personnage": "Personnage",
|
||||||
|
"compagnie": "Compagnie",
|
||||||
|
"creature": "Créature"
|
||||||
|
},
|
||||||
|
"Item": {
|
||||||
|
"race": "Race",
|
||||||
|
"tribu": "Tribu",
|
||||||
|
"metier": "Métier",
|
||||||
|
"competence": "Compétence",
|
||||||
|
"sortilege": "Sortilège",
|
||||||
|
"arme": "Arme",
|
||||||
|
"armure": "Armure",
|
||||||
|
"equipement": "Équipement",
|
||||||
|
"pouvoircompagnie": "Pouvoir de compagnie"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"LESOUBLIES": {
|
||||||
|
"ui": {
|
||||||
|
"editMode": "Mode édition",
|
||||||
|
"playMode": "Mode lecture",
|
||||||
|
"newItem": "Nouvel élément",
|
||||||
|
"newActor": "Nouvel acteur",
|
||||||
|
"roll": "Jet",
|
||||||
|
"creation": "Création",
|
||||||
|
"competences": "Compétences",
|
||||||
|
"magie": "Magie",
|
||||||
|
"equipement": "Équipement",
|
||||||
|
"notes": "Notes",
|
||||||
|
"membres": "Membres",
|
||||||
|
"combat": "Combat",
|
||||||
|
"pouvoir": "Pouvoir",
|
||||||
|
"liens": "Liens",
|
||||||
|
"vie": "Points de vie",
|
||||||
|
"songes": "Songes",
|
||||||
|
"cauchemar": "Cauchemar",
|
||||||
|
"profils": "Profils",
|
||||||
|
"derivedOverview": "Synthèse",
|
||||||
|
"embeddedItems": "Objets embarqués",
|
||||||
|
"sourceData": "Données source",
|
||||||
|
"readOnlyCollection": "Cette liste est fournie par les données de référence du système."
|
||||||
|
},
|
||||||
|
"rolls": {
|
||||||
|
"roll": "Lancer",
|
||||||
|
"test": "Test",
|
||||||
|
"confrontation": "Confrontation",
|
||||||
|
"initiative": "Initiative",
|
||||||
|
"attacker": "Acteur",
|
||||||
|
"defender": "Adversaire",
|
||||||
|
"label": "Libellé",
|
||||||
|
"score": "Valeur",
|
||||||
|
"difficulty": "Difficulté",
|
||||||
|
"rollMode": "Mode de jet",
|
||||||
|
"extraDie": "Dé supplémentaire",
|
||||||
|
"selectedDie": "Dé retenu",
|
||||||
|
"natural": "Résultat naturel",
|
||||||
|
"final": "Résultat final",
|
||||||
|
"threshold": "Seuil",
|
||||||
|
"margin": "Marge",
|
||||||
|
"resolution": "Résolution",
|
||||||
|
"result": "Verdict",
|
||||||
|
"resourceState": "Réserves",
|
||||||
|
"debt": "Dette",
|
||||||
|
"breakdown": "Détail",
|
||||||
|
"success": "Succès",
|
||||||
|
"failure": "Échec",
|
||||||
|
"safeChoice": "Choix prudent",
|
||||||
|
"riskyChoice": "Choix risqué",
|
||||||
|
"noDebt": "Aucune dette",
|
||||||
|
"debtGain": "+1 dette de {type}",
|
||||||
|
"notEnoughResource": "{actor} n'a pas assez de {resource}.",
|
||||||
|
"exploded": "12 explosif",
|
||||||
|
"naturalOne": "1 naturel : échec automatique.",
|
||||||
|
"initiativeHint": "L'initiative utilise Rapidité / 0 puis arrondit le résultat final à la moitié supérieure, avec un plafond à 12.",
|
||||||
|
"testHint": "Le jet lance les dés nécessaires puis vous laisse choisir le dé retenu quand Songes et Cauchemar sont en concurrence.",
|
||||||
|
"confrontationHint": "Saisissez les deux valeurs à opposer. Chaque camp résout son jet avec ses propres dés et sa propre difficulté.",
|
||||||
|
"choiceHint": "Choisissez le dé retenu après avoir vu les résultats naturels.",
|
||||||
|
"confrontationType": "Type de confrontation",
|
||||||
|
"confrontationTypes": {
|
||||||
|
"directe": "Directe",
|
||||||
|
"differee": "Différée"
|
||||||
|
},
|
||||||
|
"rollModes": {
|
||||||
|
"dual": "2d12 Songes / Cauchemar",
|
||||||
|
"songes": "2d12 Songes",
|
||||||
|
"cauchemar": "2d12 Cauchemar",
|
||||||
|
"single": "1d12"
|
||||||
|
},
|
||||||
|
"extraDice": {
|
||||||
|
"none": "Aucun",
|
||||||
|
"songes": "1 dé de Songes",
|
||||||
|
"cauchemar": "1 dé de Cauchemar"
|
||||||
|
},
|
||||||
|
"dice": {
|
||||||
|
"songes": "Songes",
|
||||||
|
"cauchemar": "Cauchemar",
|
||||||
|
"neutral": "Neutre"
|
||||||
|
},
|
||||||
|
"dialogs": {
|
||||||
|
"testTitle": "Jet de test",
|
||||||
|
"initiativeTitle": "Jet d'initiative",
|
||||||
|
"confrontationTitle": "Jet de confrontation",
|
||||||
|
"choiceTitle": "Choisir le dé retenu"
|
||||||
|
},
|
||||||
|
"outcomes": {
|
||||||
|
"attacker-success": "L'acteur passe, l'adversaire rate.",
|
||||||
|
"defender-success": "L'adversaire l'emporte seul.",
|
||||||
|
"attacker-advantage": "L'acteur prend l'avantage.",
|
||||||
|
"defender-advantage": "L'adversaire prend l'avantage.",
|
||||||
|
"tie": "Égalité : la fiction tranche."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"labels": {
|
||||||
|
"race": "Race",
|
||||||
|
"tribu": "Tribu",
|
||||||
|
"metier": "Métier",
|
||||||
|
"taille": "Taille",
|
||||||
|
"esperanceVie": "Espérance de vie",
|
||||||
|
"motsCles": "Mots-clés",
|
||||||
|
"langue": "Langue",
|
||||||
|
"territoire": "Territoire",
|
||||||
|
"philosophie": "Philosophie",
|
||||||
|
"fierte": "Fierté",
|
||||||
|
"mytheNature": "Mythe de Dame Nature",
|
||||||
|
"mytheEdenia": "Mythes d'Edenia",
|
||||||
|
"reglesSpeciales": "Règles spéciales",
|
||||||
|
"domaines": "Domaines",
|
||||||
|
"profil": "Profil",
|
||||||
|
"base": "Base",
|
||||||
|
"valeurFinale": "Valeur finale",
|
||||||
|
"cout": "Coût",
|
||||||
|
"preparation": "Préparation",
|
||||||
|
"duree": "Durée",
|
||||||
|
"portee": "Portée",
|
||||||
|
"aire": "Aire d'effet",
|
||||||
|
"cumul": "Cumul",
|
||||||
|
"proprietes": "Propriétés",
|
||||||
|
"prix": "Prix",
|
||||||
|
"quantite": "Quantité",
|
||||||
|
"equipe": "Équipé",
|
||||||
|
"categorie": "Catégorie",
|
||||||
|
"origine": "Origine",
|
||||||
|
"description": "Description",
|
||||||
|
"notes": "Notes",
|
||||||
|
"gmnotes": "Notes MJ",
|
||||||
|
"compagnie": "Compagnie",
|
||||||
|
"capitaine": "Capitaine",
|
||||||
|
"pouvoir": "Pouvoir",
|
||||||
|
"ombreDuTourment": "Ombre du Tourment",
|
||||||
|
"identite": "Identité",
|
||||||
|
"age": "Âge",
|
||||||
|
"sexe": "Sexe",
|
||||||
|
"xp": "Expérience",
|
||||||
|
"ecorces": "Écorces",
|
||||||
|
"hpMax": "PV max",
|
||||||
|
"hpAffichage": "PV affichés",
|
||||||
|
"powerName": "Nom du pouvoir",
|
||||||
|
"powerEffect": "Effet",
|
||||||
|
"membresIds": "Identifiants des membres",
|
||||||
|
"liensNarratifs": "Liens narratifs",
|
||||||
|
"detteSonges": "Dette de Songes",
|
||||||
|
"detteCauchemar": "Dette de Cauchemar",
|
||||||
|
"creditSonges": "Crédits Songes",
|
||||||
|
"creditCauchemar": "Crédits Cauchemar",
|
||||||
|
"pointsSonges": "Points de Songes",
|
||||||
|
"pointsCauchemar": "Points de Cauchemar",
|
||||||
|
"degats": "Dégâts",
|
||||||
|
"sortilegesSonges": "Sortilèges de Songes",
|
||||||
|
"sortilegesCauchemar": "Sortilèges de Cauchemar",
|
||||||
|
"profilsOptionnels": "Profils (optionnels)",
|
||||||
|
"reserveSongesCompagnie": "Réserve de Songes",
|
||||||
|
"activation": "Activation",
|
||||||
|
"capitaineVisible": "Vue du capitaine requise",
|
||||||
|
"capitaineTemoin": "Capitaine avec témoin",
|
||||||
|
"pouvoirCompagnieActif": "Pouvoir de compagnie actif"
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"artiste": "Artiste",
|
||||||
|
"athlete": "Athlète",
|
||||||
|
"chasseur": "Chasseur",
|
||||||
|
"faiseur": "Faiseur",
|
||||||
|
"forceNature": "Force de la nature",
|
||||||
|
"guerrier": "Guerrier",
|
||||||
|
"mystique": "Mystique",
|
||||||
|
"ombre": "Ombre",
|
||||||
|
"savant": "Savant"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,760 @@
|
|||||||
|
@import url("https://fonts.googleapis.com/css2?family=Cinzel:wght@400;600;700&family=Cormorant+Garamond:wght@400;500;600;700&family=IM+Fell+English+SC&display=swap");
|
||||||
|
|
||||||
|
.fvtt-les-oublies.sheet,
|
||||||
|
.fvtt-les-oublies.sheet .window-content {
|
||||||
|
--lo-bg-deep: #0f1714;
|
||||||
|
--lo-bg-moss: #1a2820;
|
||||||
|
--lo-bg-night: #18211b;
|
||||||
|
--lo-panel: rgba(247, 237, 218, 0.92);
|
||||||
|
--lo-panel-heavy: rgba(236, 222, 196, 0.94);
|
||||||
|
--lo-panel-soft: rgba(255, 250, 241, 0.76);
|
||||||
|
--lo-ink: #221610;
|
||||||
|
--lo-ink-soft: #584336;
|
||||||
|
--lo-gold: #cfb06a;
|
||||||
|
--lo-copper: #8d5c3b;
|
||||||
|
--lo-blood: #6d2922;
|
||||||
|
--lo-shadow: rgba(0, 0, 0, 0.42);
|
||||||
|
--lo-line: rgba(110, 77, 53, 0.4);
|
||||||
|
--lo-glow: rgba(207, 176, 106, 0.22);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fvtt-les-oublies.sheet {
|
||||||
|
color: var(--lo-ink);
|
||||||
|
font-family: "Cormorant Garamond", Georgia, serif;
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at top left, rgba(120, 103, 63, 0.22), transparent 28%),
|
||||||
|
radial-gradient(circle at top right, rgba(78, 107, 76, 0.18), transparent 24%),
|
||||||
|
linear-gradient(180deg, rgba(14, 22, 18, 0.95), rgba(23, 31, 26, 0.96));
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fvtt-les-oublies.sheet .window-content {
|
||||||
|
background:
|
||||||
|
linear-gradient(180deg, rgba(12, 19, 16, 0.92), rgba(22, 29, 25, 0.96)),
|
||||||
|
radial-gradient(circle at 20% 10%, rgba(207, 176, 106, 0.08), transparent 26%);
|
||||||
|
color: var(--lo-ink);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fvtt-les-oublies {
|
||||||
|
color: var(--lo-ink);
|
||||||
|
padding: 0.4rem;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.les-oublies-sheet {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.les-oublies-sheet::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: -0.35rem;
|
||||||
|
border: 1px solid rgba(207, 176, 106, 0.18);
|
||||||
|
border-radius: 18px;
|
||||||
|
pointer-events: none;
|
||||||
|
box-shadow: 0 0 0 1px rgba(36, 23, 14, 0.5), inset 0 0 40px rgba(0, 0, 0, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-banner {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 110px 1fr;
|
||||||
|
gap: 1.2rem;
|
||||||
|
align-items: stretch;
|
||||||
|
margin-bottom: 1.1rem;
|
||||||
|
padding: 1rem 1.1rem 1.1rem;
|
||||||
|
border-radius: 18px;
|
||||||
|
background:
|
||||||
|
linear-gradient(135deg, rgba(250, 240, 217, 0.98), rgba(232, 214, 182, 0.92)),
|
||||||
|
linear-gradient(180deg, rgba(207, 176, 106, 0.18), rgba(109, 41, 34, 0.08));
|
||||||
|
border: 1px solid rgba(207, 176, 106, 0.4);
|
||||||
|
box-shadow:
|
||||||
|
0 18px 40px var(--lo-shadow),
|
||||||
|
inset 0 1px 0 rgba(255, 250, 242, 0.7),
|
||||||
|
inset 0 0 0 1px rgba(121, 80, 51, 0.08);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-banner::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background:
|
||||||
|
linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.16), transparent),
|
||||||
|
radial-gradient(circle at 85% 15%, rgba(78, 107, 76, 0.16), transparent 18%);
|
||||||
|
mix-blend-mode: soft-light;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-img {
|
||||||
|
width: 110px;
|
||||||
|
height: 132px;
|
||||||
|
object-fit: cover;
|
||||||
|
border: 2px solid rgba(85, 55, 34, 0.7);
|
||||||
|
border-radius: 14px;
|
||||||
|
background: linear-gradient(180deg, #291e17, #5f4435);
|
||||||
|
box-shadow:
|
||||||
|
0 14px 24px rgba(27, 14, 9, 0.35),
|
||||||
|
0 0 0 3px rgba(255, 246, 226, 0.35);
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-copy,
|
||||||
|
.header-fields {
|
||||||
|
flex: 1;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheet-kicker {
|
||||||
|
margin: 0 0 0.18rem;
|
||||||
|
color: var(--lo-blood);
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
font-size: 0.78rem;
|
||||||
|
letter-spacing: 0.24em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheet-title {
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheet-title input,
|
||||||
|
.header-fields h1 input {
|
||||||
|
font-family: "IM Fell English SC", "Cinzel", serif;
|
||||||
|
font-size: clamp(2rem, 2.6vw, 2.8rem);
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
color: #2b1b14;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
box-shadow: none;
|
||||||
|
padding: 0;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheet-subtitle {
|
||||||
|
margin: 0.35rem 0 0;
|
||||||
|
color: var(--lo-ink-soft);
|
||||||
|
font-size: 1.05rem;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheet-grid {
|
||||||
|
display: grid;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheet-grid-2 {
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheet-card {
|
||||||
|
background:
|
||||||
|
linear-gradient(180deg, var(--lo-panel), var(--lo-panel-heavy)),
|
||||||
|
linear-gradient(135deg, rgba(255, 255, 255, 0.24), transparent);
|
||||||
|
border: 1px solid rgba(133, 99, 74, 0.5);
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 1rem 1rem 0.95rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
box-shadow:
|
||||||
|
0 12px 28px rgba(0, 0, 0, 0.18),
|
||||||
|
inset 0 1px 0 rgba(255, 251, 243, 0.6),
|
||||||
|
inset 0 0 0 1px rgba(255, 243, 218, 0.18);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheet-card::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background:
|
||||||
|
linear-gradient(180deg, rgba(255, 255, 255, 0.14), transparent 22%),
|
||||||
|
radial-gradient(circle at 100% 0, rgba(207, 176, 106, 0.1), transparent 26%);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheet-card h2,
|
||||||
|
.sheet-card h3 {
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #3a251a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheet-card h2 {
|
||||||
|
margin: 0 0 0.75rem;
|
||||||
|
padding-bottom: 0.35rem;
|
||||||
|
border-bottom: 1px solid rgba(109, 41, 34, 0.18);
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheet-card h3 {
|
||||||
|
margin: 0 0 0.55rem;
|
||||||
|
font-size: 0.84rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-card {
|
||||||
|
background:
|
||||||
|
linear-gradient(180deg, rgba(246, 235, 210, 0.94), rgba(228, 213, 179, 0.95)),
|
||||||
|
linear-gradient(135deg, rgba(207, 176, 106, 0.16), transparent 60%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.profiles-card {
|
||||||
|
background:
|
||||||
|
linear-gradient(180deg, rgba(245, 238, 223, 0.95), rgba(232, 223, 201, 0.92));
|
||||||
|
}
|
||||||
|
|
||||||
|
.ledger-card {
|
||||||
|
background:
|
||||||
|
linear-gradient(180deg, rgba(251, 244, 232, 0.95), rgba(236, 224, 198, 0.92));
|
||||||
|
}
|
||||||
|
|
||||||
|
.notes-card {
|
||||||
|
background:
|
||||||
|
linear-gradient(180deg, rgba(240, 229, 207, 0.98), rgba(223, 207, 177, 0.95));
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheet-actions,
|
||||||
|
.embed-buttons,
|
||||||
|
.item-controls,
|
||||||
|
.section-title-row {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-row,
|
||||||
|
.profile-cell {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.65rem;
|
||||||
|
margin-bottom: 0.65rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-row label,
|
||||||
|
.profile-cell label {
|
||||||
|
min-width: 10rem;
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
font-size: 0.74rem;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #51392b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-row span {
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
font-size: 0.84rem;
|
||||||
|
color: var(--lo-blood);
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
gap: 0.75rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-cell {
|
||||||
|
padding: 0.7rem 0.8rem;
|
||||||
|
border-radius: 14px;
|
||||||
|
background: linear-gradient(180deg, rgba(255, 250, 243, 0.7), rgba(230, 214, 185, 0.6));
|
||||||
|
border: 1px solid rgba(130, 98, 71, 0.2);
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5);
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-block + .group-block {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.65rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-card {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 1rem;
|
||||||
|
padding: 0.8rem 0.9rem;
|
||||||
|
border: 1px solid rgba(118, 85, 58, 0.22);
|
||||||
|
border-radius: 14px;
|
||||||
|
background:
|
||||||
|
linear-gradient(180deg, rgba(255, 252, 246, 0.78), rgba(239, 229, 206, 0.78)),
|
||||||
|
linear-gradient(135deg, rgba(207, 176, 106, 0.08), transparent);
|
||||||
|
box-shadow:
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.56),
|
||||||
|
0 6px 14px rgba(0, 0, 0, 0.08);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-card::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
left: 0.55rem;
|
||||||
|
top: 0.6rem;
|
||||||
|
bottom: 0.6rem;
|
||||||
|
width: 3px;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: linear-gradient(180deg, var(--lo-gold), var(--lo-blood));
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-card > div:first-child {
|
||||||
|
padding-left: 0.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-card strong,
|
||||||
|
.reference-list strong {
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
color: #3d281d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reference-list {
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reference-list li + li {
|
||||||
|
margin-top: 0.35rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.help-text {
|
||||||
|
color: var(--lo-ink-soft);
|
||||||
|
font-size: 0.96rem;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode-button,
|
||||||
|
button {
|
||||||
|
cursor: pointer;
|
||||||
|
border: 1px solid rgba(99, 61, 40, 0.45);
|
||||||
|
border-radius: 999px;
|
||||||
|
background:
|
||||||
|
linear-gradient(180deg, #2e3f34, #18231d);
|
||||||
|
color: #f2e5c8;
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
font-size: 0.72rem;
|
||||||
|
letter-spacing: 0.12em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
padding: 0.5rem 0.9rem;
|
||||||
|
box-shadow:
|
||||||
|
0 8px 18px rgba(0, 0, 0, 0.18),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
||||||
|
transition: transform 120ms ease, box-shadow 120ms ease, border-color 120ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.les-oublies-roll-dialog {
|
||||||
|
color: var(--lo-ink);
|
||||||
|
|
||||||
|
.sheet-card {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-row input,
|
||||||
|
.field-row select {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover,
|
||||||
|
button:focus {
|
||||||
|
transform: translateY(-1px);
|
||||||
|
border-color: rgba(207, 176, 106, 0.75);
|
||||||
|
box-shadow:
|
||||||
|
0 12px 22px rgba(0, 0, 0, 0.22),
|
||||||
|
0 0 0 1px rgba(207, 176, 106, 0.24);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"],
|
||||||
|
input[type="number"],
|
||||||
|
select,
|
||||||
|
textarea {
|
||||||
|
background: linear-gradient(180deg, rgba(255, 251, 244, 0.96), rgba(238, 226, 201, 0.96));
|
||||||
|
border: 1px solid rgba(113, 79, 56, 0.42);
|
||||||
|
border-radius: 10px;
|
||||||
|
color: #2e1f18;
|
||||||
|
font-family: "Cormorant Garamond", Georgia, serif;
|
||||||
|
font-size: 1rem;
|
||||||
|
min-height: 2.1rem;
|
||||||
|
padding: 0.2rem 0.65rem;
|
||||||
|
box-shadow: inset 0 1px 3px rgba(72, 46, 30, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="checkbox"] {
|
||||||
|
accent-color: #6d2922;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheet-card .editor,
|
||||||
|
.sheet-card .editor-content,
|
||||||
|
.sheet-card .editor-container,
|
||||||
|
prose-mirror {
|
||||||
|
background: rgba(255, 252, 246, 0.62);
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prosemirror,
|
||||||
|
prose-mirror {
|
||||||
|
border: 1px solid rgba(111, 84, 55, 0.18);
|
||||||
|
padding: 0.6rem 0.7rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
a,
|
||||||
|
button[data-action="rollProfile"],
|
||||||
|
button[data-action="rollSkill"] {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button[data-action="rollProfile"],
|
||||||
|
button[data-action="rollSkill"] {
|
||||||
|
background: linear-gradient(180deg, #6a2f29, #421914);
|
||||||
|
color: #f8ead3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.compagnie-sheet .hero-banner {
|
||||||
|
background:
|
||||||
|
linear-gradient(135deg, rgba(245, 235, 210, 0.98), rgba(224, 205, 173, 0.93)),
|
||||||
|
linear-gradient(180deg, rgba(207, 176, 106, 0.18), rgba(58, 37, 26, 0.08));
|
||||||
|
}
|
||||||
|
|
||||||
|
.creature-sheet .hero-banner {
|
||||||
|
background:
|
||||||
|
linear-gradient(135deg, rgba(236, 226, 206, 0.96), rgba(213, 196, 166, 0.92)),
|
||||||
|
radial-gradient(circle at 90% 15%, rgba(109, 41, 34, 0.14), transparent 28%);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
.sheet-grid-2,
|
||||||
|
.profile-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-banner {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-img {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 110px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-message,
|
||||||
|
.chat-popout,
|
||||||
|
#chat-log {
|
||||||
|
.les-oublies-chat-card {
|
||||||
|
--lo-chat-bg-top: rgba(249, 241, 227, 0.98);
|
||||||
|
--lo-chat-bg-bottom: rgba(226, 209, 178, 0.96);
|
||||||
|
--lo-chat-line: rgba(114, 80, 55, 0.26);
|
||||||
|
--lo-chat-ink: #2f1f17;
|
||||||
|
--lo-chat-soft: #6a5142;
|
||||||
|
--lo-chat-gold: #cfb06a;
|
||||||
|
--lo-chat-blood: #6d2922;
|
||||||
|
color: var(--lo-chat-ink);
|
||||||
|
background:
|
||||||
|
linear-gradient(180deg, var(--lo-chat-bg-top), var(--lo-chat-bg-bottom)),
|
||||||
|
linear-gradient(135deg, rgba(207, 176, 106, 0.18), transparent 72%);
|
||||||
|
border: 1px solid rgba(133, 99, 74, 0.45);
|
||||||
|
border-radius: 18px;
|
||||||
|
padding: 0.9rem 1rem;
|
||||||
|
margin: 0.2rem 0;
|
||||||
|
box-shadow:
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.56),
|
||||||
|
0 10px 28px rgba(0, 0, 0, 0.14);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.les-oublies-chat-card::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
background:
|
||||||
|
linear-gradient(180deg, rgba(255, 255, 255, 0.16), transparent 24%),
|
||||||
|
radial-gradient(circle at 100% 0, rgba(207, 176, 106, 0.14), transparent 28%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.les-oublies-chat-card.is-success {
|
||||||
|
box-shadow:
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.56),
|
||||||
|
0 10px 28px rgba(0, 0, 0, 0.14),
|
||||||
|
0 0 0 1px rgba(65, 107, 72, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
.les-oublies-chat-card.is-failure {
|
||||||
|
box-shadow:
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.56),
|
||||||
|
0 10px 28px rgba(0, 0, 0, 0.14),
|
||||||
|
0 0 0 1px rgba(109, 41, 34, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-card-banner {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 3rem 1fr auto;
|
||||||
|
gap: 0.8rem;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-card-portrait {
|
||||||
|
width: 3rem;
|
||||||
|
height: 3rem;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 14px;
|
||||||
|
border: 1px solid rgba(91, 60, 39, 0.5);
|
||||||
|
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.16);
|
||||||
|
background: linear-gradient(180deg, #2c1d16, #6b4a37);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-card-kicker {
|
||||||
|
margin: 0;
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
font-size: 0.66rem;
|
||||||
|
letter-spacing: 0.18em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--lo-chat-blood);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-card-header h3 {
|
||||||
|
margin: 0.08rem 0 0;
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
font-size: 1rem;
|
||||||
|
letter-spacing: 0.06em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #3a251a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-card-subtitle {
|
||||||
|
margin: 0.2rem 0 0;
|
||||||
|
color: var(--lo-chat-soft);
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-card-badge {
|
||||||
|
align-self: start;
|
||||||
|
padding: 0.38rem 0.65rem;
|
||||||
|
border-radius: 999px;
|
||||||
|
border: 1px solid var(--lo-chat-line);
|
||||||
|
background: rgba(255, 249, 239, 0.7);
|
||||||
|
color: #3a251a;
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
font-size: 0.72rem;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-align: center;
|
||||||
|
max-width: 13rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-card-badge.success {
|
||||||
|
background: rgba(226, 243, 225, 0.74);
|
||||||
|
color: #29422d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-card-badge.failure {
|
||||||
|
background: rgba(245, 223, 220, 0.74);
|
||||||
|
color: #6d2922;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-card-badge.neutral {
|
||||||
|
background: rgba(242, 233, 212, 0.78);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-card-body {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-card-body p {
|
||||||
|
margin: 0.45rem 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.roll-summary-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
gap: 0.55rem;
|
||||||
|
margin: 0.85rem 0 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.roll-summary-grid div {
|
||||||
|
padding: 0.58rem 0.68rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: rgba(255, 250, 241, 0.68);
|
||||||
|
border: 1px solid var(--lo-chat-line);
|
||||||
|
}
|
||||||
|
|
||||||
|
.roll-summary-grid span {
|
||||||
|
display: block;
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
font-size: 0.66rem;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--lo-chat-blood);
|
||||||
|
}
|
||||||
|
|
||||||
|
.roll-summary-grid strong {
|
||||||
|
font-size: 1.08rem;
|
||||||
|
color: var(--lo-chat-ink);
|
||||||
|
}
|
||||||
|
|
||||||
|
.roll-formula {
|
||||||
|
margin-top: 0.2rem;
|
||||||
|
padding: 0.55rem 0.7rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: rgba(255, 249, 239, 0.52);
|
||||||
|
border: 1px solid rgba(118, 85, 58, 0.14);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dice-strip {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.55rem;
|
||||||
|
margin-top: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.die-chip {
|
||||||
|
min-width: 8.4rem;
|
||||||
|
padding: 0.62rem 0.72rem;
|
||||||
|
border-radius: 13px;
|
||||||
|
background: rgba(247, 238, 221, 0.8);
|
||||||
|
border: 1px solid rgba(118, 85, 58, 0.18);
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.52);
|
||||||
|
}
|
||||||
|
|
||||||
|
.die-chip.selected {
|
||||||
|
border-color: rgba(207, 176, 106, 0.86);
|
||||||
|
background: rgba(255, 247, 228, 0.92);
|
||||||
|
box-shadow:
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.52),
|
||||||
|
0 0 0 1px rgba(207, 176, 106, 0.28);
|
||||||
|
}
|
||||||
|
|
||||||
|
.die-chip strong,
|
||||||
|
.die-chip em,
|
||||||
|
.die-chip span {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.die-chip span {
|
||||||
|
color: var(--lo-chat-ink);
|
||||||
|
}
|
||||||
|
|
||||||
|
.die-chip em {
|
||||||
|
color: var(--lo-chat-blood);
|
||||||
|
font-size: 0.82rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-callouts {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.6rem;
|
||||||
|
margin-top: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-callout {
|
||||||
|
min-width: 10rem;
|
||||||
|
flex: 1 1 10rem;
|
||||||
|
padding: 0.62rem 0.75rem;
|
||||||
|
border-radius: 13px;
|
||||||
|
background: rgba(255, 250, 241, 0.62);
|
||||||
|
border: 1px solid var(--lo-chat-line);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-callout span,
|
||||||
|
.chat-callout strong,
|
||||||
|
.chat-callout em {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-callout span {
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
font-size: 0.66rem;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--lo-chat-blood);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-callout strong {
|
||||||
|
color: var(--lo-chat-ink);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-callout em {
|
||||||
|
color: var(--lo-chat-soft);
|
||||||
|
font-size: 0.88rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-callout.warning {
|
||||||
|
background: rgba(245, 223, 220, 0.72);
|
||||||
|
}
|
||||||
|
|
||||||
|
.confrontation-body {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
gap: 0.85rem;
|
||||||
|
margin-top: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-side-card {
|
||||||
|
padding: 0.82rem 0.88rem;
|
||||||
|
border-radius: 15px;
|
||||||
|
border: 1px solid var(--lo-chat-line);
|
||||||
|
background: rgba(255, 251, 245, 0.58);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-side-card.is-success {
|
||||||
|
box-shadow: inset 3px 0 0 rgba(65, 107, 72, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-side-card.is-failure {
|
||||||
|
box-shadow: inset 3px 0 0 rgba(109, 41, 34, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-side-head {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 0.5rem;
|
||||||
|
align-items: baseline;
|
||||||
|
margin-bottom: 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-side-head h2 {
|
||||||
|
margin: 0;
|
||||||
|
font-family: "Cinzel", serif;
|
||||||
|
font-size: 0.92rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.06em;
|
||||||
|
color: #3a251a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-side-mode {
|
||||||
|
color: var(--lo-chat-soft);
|
||||||
|
font-size: 0.86rem;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 720px) {
|
||||||
|
.chat-card-banner {
|
||||||
|
grid-template-columns: 3rem 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-card-badge {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
justify-self: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.roll-summary-grid,
|
||||||
|
.confrontation-body {
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
@import "components/sheets.less";
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
export { default as LesOubliesPersonnageSheet } from "./personnage-sheet.mjs"
|
||||||
|
export { default as LesOubliesCompagnieSheet } from "./compagnie-sheet.mjs"
|
||||||
|
export { default as LesOubliesCreatureSheet } from "./creature-sheet.mjs"
|
||||||
|
export { default as LesOubliesReferenceItemSheet } from "./reference-item-sheet.mjs"
|
||||||
|
export { default as LesOubliesCompetenceSheet } from "./competence-sheet.mjs"
|
||||||
|
export { default as LesOubliesSortilegeSheet } from "./sortilege-sheet.mjs"
|
||||||
|
export { default as LesOubliesArmeSheet } from "./arme-sheet.mjs"
|
||||||
|
export { default as LesOubliesArmureSheet } from "./armure-sheet.mjs"
|
||||||
|
export { default as LesOubliesEquipementSheet } from "./equipement-sheet.mjs"
|
||||||
|
export { default as LesOubliesPouvoirCompagnieSheet } from "./pouvoir-compagnie-sheet.mjs"
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import LesOubliesItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class LesOubliesArmeSheet extends LesOubliesItemSheet {
|
||||||
|
static PARTS = {
|
||||||
|
sheet: {
|
||||||
|
template: "systems/fvtt-les-oublies/templates/item-arme-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import LesOubliesItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class LesOubliesArmureSheet extends LesOubliesItemSheet {
|
||||||
|
static PARTS = {
|
||||||
|
sheet: {
|
||||||
|
template: "systems/fvtt-les-oublies/templates/item-armure-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,186 @@
|
|||||||
|
const { HandlebarsApplicationMixin } = foundry.applications.api
|
||||||
|
|
||||||
|
import { LesOubliesUtility } from "../../les-oublies-utility.js"
|
||||||
|
|
||||||
|
export default class LesOubliesActorSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ActorSheetV2) {
|
||||||
|
static SHEET_MODES = { EDIT: 0, PLAY: 1 }
|
||||||
|
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["fvtt-les-oublies", "sheet", "actor"],
|
||||||
|
position: {
|
||||||
|
width: 980,
|
||||||
|
height: 860,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
resizable: true,
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
submitOnChange: true,
|
||||||
|
closeOnSubmit: false,
|
||||||
|
},
|
||||||
|
dragDrop: [{ dragSelector: ".item-card", dropSelector: "form" }],
|
||||||
|
actions: {
|
||||||
|
toggleSheet: LesOubliesActorSheet.#onToggleSheet,
|
||||||
|
editImage: LesOubliesActorSheet.#onEditImage,
|
||||||
|
createItem: LesOubliesActorSheet.#onCreateItem,
|
||||||
|
editItem: LesOubliesActorSheet.#onEditItem,
|
||||||
|
deleteItem: LesOubliesActorSheet.#onDeleteItem,
|
||||||
|
openRoll: LesOubliesActorSheet.#onOpenRoll,
|
||||||
|
openConfrontation: LesOubliesActorSheet.#onOpenConfrontation,
|
||||||
|
openInitiative: LesOubliesActorSheet.#onOpenInitiative,
|
||||||
|
rollProfile: LesOubliesActorSheet.#onRollProfile,
|
||||||
|
rollSkill: LesOubliesActorSheet.#onRollSkill,
|
||||||
|
useWeapon: LesOubliesActorSheet.#onUseWeapon,
|
||||||
|
resolveWeaponDamage: LesOubliesActorSheet.#onResolveWeaponDamage,
|
||||||
|
useSpell: LesOubliesActorSheet.#onUseSpell,
|
||||||
|
openCombatPreset: LesOubliesActorSheet.#onOpenCombatPreset,
|
||||||
|
openThreadHarvest: LesOubliesActorSheet.#onOpenThreadHarvest,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
_sheetMode = this.constructor.SHEET_MODES.EDIT
|
||||||
|
|
||||||
|
get isEditMode() {
|
||||||
|
return this._sheetMode === this.constructor.SHEET_MODES.EDIT
|
||||||
|
}
|
||||||
|
|
||||||
|
get isPlayMode() {
|
||||||
|
return this._sheetMode === this.constructor.SHEET_MODES.PLAY
|
||||||
|
}
|
||||||
|
|
||||||
|
async _prepareContext() {
|
||||||
|
return {
|
||||||
|
actor: this.document,
|
||||||
|
system: this.document.system,
|
||||||
|
source: this.document.toObject(),
|
||||||
|
fields: this.document.schema.fields,
|
||||||
|
systemFields: this.document.system.schema.fields,
|
||||||
|
isEditable: this.isEditable,
|
||||||
|
isEditMode: this.isEditMode,
|
||||||
|
isPlayMode: this.isPlayMode,
|
||||||
|
isGM: game.user.isGM,
|
||||||
|
config: CONFIG.LESOUBLIES,
|
||||||
|
enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.biodata?.description ?? this.document.system.description ?? "", { async: true }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_onRender(context, options) {
|
||||||
|
super._onRender(context, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
_canDragStart() {
|
||||||
|
return this.isEditable
|
||||||
|
}
|
||||||
|
|
||||||
|
_canDragDrop() {
|
||||||
|
return this.isEditable
|
||||||
|
}
|
||||||
|
|
||||||
|
async _onDrop(event) {
|
||||||
|
const data = TextEditor.getDragEventData(event)
|
||||||
|
if (data.type !== "Item" || !data.uuid) return
|
||||||
|
const item = await fromUuid(data.uuid)
|
||||||
|
if (!item) return
|
||||||
|
return this._onDropItem(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
async _onDropItem(item) {
|
||||||
|
const itemData = item.toObject()
|
||||||
|
delete itemData._id
|
||||||
|
return this.document.createEmbeddedDocuments("Item", [itemData], { renderSheet: false })
|
||||||
|
}
|
||||||
|
|
||||||
|
static #onToggleSheet() {
|
||||||
|
const modes = this.constructor.SHEET_MODES
|
||||||
|
this._sheetMode = this.isEditMode ? modes.PLAY : modes.EDIT
|
||||||
|
this.render()
|
||||||
|
}
|
||||||
|
|
||||||
|
static async #onEditImage(event, target) {
|
||||||
|
const attr = target.dataset.edit
|
||||||
|
const current = foundry.utils.getProperty(this.document, attr)
|
||||||
|
const fp = new FilePicker({
|
||||||
|
current,
|
||||||
|
type: "image",
|
||||||
|
callback: (path) => this.document.update({ [attr]: path }),
|
||||||
|
top: this.position.top + 40,
|
||||||
|
left: this.position.left + 10,
|
||||||
|
})
|
||||||
|
return fp.browse()
|
||||||
|
}
|
||||||
|
|
||||||
|
static async #onCreateItem(event, target) {
|
||||||
|
const type = target.dataset.type
|
||||||
|
if (!type) return
|
||||||
|
const label = game.i18n.localize(`TYPES.Item.${type}`)
|
||||||
|
return this.document.createEmbeddedDocuments("Item", [{
|
||||||
|
name: label,
|
||||||
|
type,
|
||||||
|
img: LesOubliesUtility.getDefaultItemImage(type),
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
|
||||||
|
static async #onEditItem(event, target) {
|
||||||
|
const itemId = target.dataset.itemId
|
||||||
|
const item = this.document.items.get(itemId)
|
||||||
|
if (item) item.sheet.render(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
static async #onDeleteItem(event, target) {
|
||||||
|
const itemId = target.dataset.itemId
|
||||||
|
const item = this.document.items.get(itemId)
|
||||||
|
if (item) await item.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
static async #onOpenRoll() {
|
||||||
|
await this.document.openTestRollDialog()
|
||||||
|
}
|
||||||
|
|
||||||
|
static async #onOpenConfrontation() {
|
||||||
|
await this.document.openConfrontationRollDialog()
|
||||||
|
}
|
||||||
|
|
||||||
|
static async #onOpenInitiative() {
|
||||||
|
await this.document.openInitiativeRollDialog()
|
||||||
|
}
|
||||||
|
|
||||||
|
static async #onRollProfile(event, target) {
|
||||||
|
const profileKey = target.dataset.profileKey
|
||||||
|
if (!profileKey) return
|
||||||
|
await this.document.rollProfile(profileKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
static async #onRollSkill(event, target) {
|
||||||
|
const itemId = target.dataset.itemId
|
||||||
|
if (!itemId) return
|
||||||
|
await this.document.rollCompetence(itemId)
|
||||||
|
}
|
||||||
|
|
||||||
|
static async #onUseWeapon(event, target) {
|
||||||
|
const itemId = target.dataset.itemId
|
||||||
|
if (!itemId) return
|
||||||
|
await this.document.openAttackRollDialog({ itemId })
|
||||||
|
}
|
||||||
|
|
||||||
|
static async #onResolveWeaponDamage(event, target) {
|
||||||
|
const itemId = target.dataset.itemId
|
||||||
|
if (!itemId) return
|
||||||
|
await this.document.openDamageDialog({ itemId })
|
||||||
|
}
|
||||||
|
|
||||||
|
static async #onUseSpell(event, target) {
|
||||||
|
const itemId = target.dataset.itemId
|
||||||
|
if (!itemId) return
|
||||||
|
await this.document.openSpellActivationDialog(itemId)
|
||||||
|
}
|
||||||
|
|
||||||
|
static async #onOpenCombatPreset(event, target) {
|
||||||
|
const actionKey = target.dataset.preset
|
||||||
|
if (!actionKey) return
|
||||||
|
await this.document.openCombatPresetDialog(actionKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
static async #onOpenThreadHarvest() {
|
||||||
|
await this.document.openThreadHarvestDialog()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
const { HandlebarsApplicationMixin } = foundry.applications.api
|
||||||
|
|
||||||
|
export default class LesOubliesItemSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ItemSheetV2) {
|
||||||
|
static SHEET_MODES = { EDIT: 0, PLAY: 1 }
|
||||||
|
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["fvtt-les-oublies", "sheet", "item"],
|
||||||
|
position: {
|
||||||
|
width: 760,
|
||||||
|
height: 720,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
resizable: true,
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
submitOnChange: true,
|
||||||
|
closeOnSubmit: false,
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
toggleSheet: LesOubliesItemSheet.#onToggleSheet,
|
||||||
|
editImage: LesOubliesItemSheet.#onEditImage,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
_sheetMode = this.constructor.SHEET_MODES.EDIT
|
||||||
|
|
||||||
|
get isEditMode() {
|
||||||
|
return this._sheetMode === this.constructor.SHEET_MODES.EDIT
|
||||||
|
}
|
||||||
|
|
||||||
|
get isPlayMode() {
|
||||||
|
return this._sheetMode === this.constructor.SHEET_MODES.PLAY
|
||||||
|
}
|
||||||
|
|
||||||
|
async _prepareContext() {
|
||||||
|
return {
|
||||||
|
item: this.document,
|
||||||
|
system: this.document.system,
|
||||||
|
source: this.document.toObject(),
|
||||||
|
fields: this.document.schema.fields,
|
||||||
|
systemFields: this.document.system.schema.fields,
|
||||||
|
isEditable: this.isEditable,
|
||||||
|
isEditMode: this.isEditMode,
|
||||||
|
isPlayMode: this.isPlayMode,
|
||||||
|
isGM: game.user.isGM,
|
||||||
|
config: CONFIG.LESOUBLIES,
|
||||||
|
enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description ?? "", { async: true }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static #onToggleSheet() {
|
||||||
|
const modes = this.constructor.SHEET_MODES
|
||||||
|
this._sheetMode = this.isEditMode ? modes.PLAY : modes.EDIT
|
||||||
|
this.render()
|
||||||
|
}
|
||||||
|
|
||||||
|
static async #onEditImage(event, target) {
|
||||||
|
const attr = target.dataset.edit
|
||||||
|
const current = foundry.utils.getProperty(this.document, attr)
|
||||||
|
const fp = new FilePicker({
|
||||||
|
current,
|
||||||
|
type: "image",
|
||||||
|
callback: (path) => this.document.update({ [attr]: path }),
|
||||||
|
top: this.position.top + 40,
|
||||||
|
left: this.position.left + 10,
|
||||||
|
})
|
||||||
|
return fp.browse()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import LesOubliesActorSheet from "./base-actor-sheet.mjs"
|
||||||
|
|
||||||
|
export default class LesOubliesCompagnieSheet extends LesOubliesActorSheet {
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
...super.DEFAULT_OPTIONS,
|
||||||
|
classes: [...super.DEFAULT_OPTIONS.classes, "compagnie"],
|
||||||
|
window: {
|
||||||
|
...super.DEFAULT_OPTIONS.window,
|
||||||
|
title: "TYPES.Actor.compagnie",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
static PARTS = {
|
||||||
|
sheet: {
|
||||||
|
template: "systems/fvtt-les-oublies/templates/actor-compagnie-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.members = (this.document.system.memberIds ?? []).map((id) => game.actors.get(id)).filter(Boolean)
|
||||||
|
context.captain = this.document.system.captainId ? game.actors.get(this.document.system.captainId) : null
|
||||||
|
context.shadow = this.document.system.ombreDuTourmentId ? game.actors.get(this.document.system.ombreDuTourmentId) : null
|
||||||
|
context.powers = this.document.getEmbeddedItems("pouvoircompagnie")
|
||||||
|
context.primaryPower = context.powers[0] ?? null
|
||||||
|
context.links = (this.document.system.links ?? []).map((link) => ({
|
||||||
|
...link,
|
||||||
|
sourceLabel: game.actors.get(link.sourceId)?.name ?? link.sourceId,
|
||||||
|
targetLabel: game.actors.get(link.targetId)?.name ?? link.targetId,
|
||||||
|
}))
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import LesOubliesItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class LesOubliesCompetenceSheet extends LesOubliesItemSheet {
|
||||||
|
static PARTS = {
|
||||||
|
sheet: {
|
||||||
|
template: "systems/fvtt-les-oublies/templates/item-competence-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import LesOubliesActorSheet from "./base-actor-sheet.mjs"
|
||||||
|
|
||||||
|
export default class LesOubliesCreatureSheet extends LesOubliesActorSheet {
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
...super.DEFAULT_OPTIONS,
|
||||||
|
classes: [...super.DEFAULT_OPTIONS.classes, "creature"],
|
||||||
|
window: {
|
||||||
|
...super.DEFAULT_OPTIONS.window,
|
||||||
|
title: "TYPES.Actor.creature",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
static PARTS = {
|
||||||
|
sheet: {
|
||||||
|
template: "systems/fvtt-les-oublies/templates/actor-creature-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.derived = this.document.getDerivedOverview()
|
||||||
|
context.skillGroups = this.document.getGroupedCompetences()
|
||||||
|
context.spells = this.document.getEmbeddedItems("sortilege")
|
||||||
|
context.weapons = this.document.getEmbeddedItems("arme")
|
||||||
|
context.armors = this.document.getEmbeddedItems("armure")
|
||||||
|
context.equipment = this.document.getEmbeddedItems("equipement")
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import LesOubliesItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class LesOubliesEquipementSheet extends LesOubliesItemSheet {
|
||||||
|
static PARTS = {
|
||||||
|
sheet: {
|
||||||
|
template: "systems/fvtt-les-oublies/templates/item-equipement-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import LesOubliesActorSheet from "./base-actor-sheet.mjs"
|
||||||
|
|
||||||
|
export default class LesOubliesPersonnageSheet extends LesOubliesActorSheet {
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
...super.DEFAULT_OPTIONS,
|
||||||
|
classes: [...super.DEFAULT_OPTIONS.classes, "personnage"],
|
||||||
|
window: {
|
||||||
|
...super.DEFAULT_OPTIONS.window,
|
||||||
|
title: "TYPES.Actor.personnage",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
static PARTS = {
|
||||||
|
sheet: {
|
||||||
|
template: "systems/fvtt-les-oublies/templates/actor-personnage-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.derived = this.document.getDerivedOverview()
|
||||||
|
context.creation = {
|
||||||
|
race: this.document.getCreationItem("race"),
|
||||||
|
tribu: this.document.getCreationItem("tribu"),
|
||||||
|
metier: this.document.getCreationItem("metier"),
|
||||||
|
}
|
||||||
|
context.profileEntries = this.document.system.profils
|
||||||
|
context.skillGroups = this.document.getGroupedCompetences()
|
||||||
|
context.spells = this.document.getEmbeddedItems("sortilege")
|
||||||
|
context.weapons = this.document.getEmbeddedItems("arme")
|
||||||
|
context.armors = this.document.getEmbeddedItems("armure")
|
||||||
|
context.equipment = this.document.getEmbeddedItems("equipement")
|
||||||
|
context.companyPowers = this.document.getEmbeddedItems("pouvoircompagnie")
|
||||||
|
context.activeCompanyPower = context.derived.compagnie?.getEmbeddedItems?.("pouvoircompagnie")?.[0] ?? null
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import LesOubliesItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class LesOubliesPouvoirCompagnieSheet extends LesOubliesItemSheet {
|
||||||
|
static PARTS = {
|
||||||
|
sheet: {
|
||||||
|
template: "systems/fvtt-les-oublies/templates/item-pouvoir-compagnie-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import LesOubliesItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class LesOubliesReferenceItemSheet extends LesOubliesItemSheet {
|
||||||
|
static PARTS = {
|
||||||
|
sheet: {
|
||||||
|
template: "systems/fvtt-les-oublies/templates/item-reference-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.isRace = this.document.type === "race"
|
||||||
|
context.isTribu = this.document.type === "tribu"
|
||||||
|
context.isMetier = this.document.type === "metier"
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import LesOubliesItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class LesOubliesSortilegeSheet extends LesOubliesItemSheet {
|
||||||
|
static PARTS = {
|
||||||
|
sheet: {
|
||||||
|
template: "systems/fvtt-les-oublies/templates/item-sortilege-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
import { LESOUBLIES_CONFIG } from "./les-oublies-config.js"
|
||||||
|
import { LesOubliesUtility } from "./les-oublies-utility.js"
|
||||||
|
import { LesOubliesRolls } from "./les-oublies-rolls.js"
|
||||||
|
|
||||||
|
export class LesOubliesActor extends Actor {
|
||||||
|
prepareDerivedData() {
|
||||||
|
super.prepareDerivedData()
|
||||||
|
|
||||||
|
if (this.type === "personnage") {
|
||||||
|
const system = this.system
|
||||||
|
const sizeValue = Math.clamp(Number(system.size?.value ?? 1), 1, 4)
|
||||||
|
const hpMax = Math.max(sizeValue * 4 + Number(system.hp?.bonus ?? 0), 0)
|
||||||
|
system.hp.max = hpMax
|
||||||
|
system.hp.value = Math.min(Number(system.hp.value ?? hpMax), hpMax)
|
||||||
|
|
||||||
|
const songesValue = Number(system.songes?.value ?? 0)
|
||||||
|
const cauchemarValue = Number(system.cauchemar?.value ?? 0)
|
||||||
|
const totals = LesOubliesUtility.computeDreamPointTotals(songesValue, cauchemarValue)
|
||||||
|
system.songes.max = totals.songesPoints
|
||||||
|
system.cauchemar.max = totals.cauchemarPoints
|
||||||
|
system.songes.points = Math.clamp(Number(system.songes.points ?? totals.songesPoints), 0, totals.songesPoints)
|
||||||
|
system.cauchemar.points = Math.clamp(Number(system.cauchemar.points ?? totals.cauchemarPoints), 0, totals.cauchemarPoints)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.type !== "creature") return
|
||||||
|
|
||||||
|
const system = this.system
|
||||||
|
const hpValue = Math.max(Number(system.hp?.value ?? 0), 0)
|
||||||
|
const hpMax = Math.max(Number(system.hp?.max ?? hpValue), hpValue, 0)
|
||||||
|
system.hp.max = hpMax
|
||||||
|
system.hp.value = Math.min(hpValue, hpMax)
|
||||||
|
const songesPoints = Math.max(Number(system.songes?.points ?? 0), 0)
|
||||||
|
const cauchemarPoints = Math.max(Number(system.cauchemar?.points ?? 0), 0)
|
||||||
|
system.songes.max = Math.max(Number(system.songes?.max ?? songesPoints), songesPoints)
|
||||||
|
system.cauchemar.max = Math.max(Number(system.cauchemar?.max ?? cauchemarPoints), cauchemarPoints)
|
||||||
|
system.songes.points = Math.min(songesPoints, system.songes.max)
|
||||||
|
system.cauchemar.points = Math.min(cauchemarPoints, system.cauchemar.max)
|
||||||
|
}
|
||||||
|
|
||||||
|
getProfileValue(profileKey) {
|
||||||
|
return Number(this.system.profils?.[profileKey] ?? 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
getCreationItem(type) {
|
||||||
|
return this.items.find((item) => item.type === type) ?? null
|
||||||
|
}
|
||||||
|
|
||||||
|
getEmbeddedItems(type) {
|
||||||
|
const items = this.itemTypes?.[type] ?? this.items.filter((item) => item.type === type)
|
||||||
|
return LesOubliesUtility.sortByName(items)
|
||||||
|
}
|
||||||
|
|
||||||
|
getCompagnie() {
|
||||||
|
const compagnieId = this.system.references?.compagnieId
|
||||||
|
return compagnieId ? game.actors.get(compagnieId) ?? null : null
|
||||||
|
}
|
||||||
|
|
||||||
|
getCompetenceByKey(skillKey) {
|
||||||
|
return this.getEmbeddedItems("competence").find((item) => item.system.key === skillKey) ?? null
|
||||||
|
}
|
||||||
|
|
||||||
|
getSkillScoreByKey(skillKey) {
|
||||||
|
const competence = this.getCompetenceByKey(skillKey)
|
||||||
|
return competence ? this.computeSkillValue(competence) : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
computeSkillValue(item) {
|
||||||
|
const base = Number(item.system.base ?? 0)
|
||||||
|
const profileValue = this.getProfileValue(item.system.profileKey)
|
||||||
|
if (item.system.closed && base === 0) return 0
|
||||||
|
return base + profileValue
|
||||||
|
}
|
||||||
|
|
||||||
|
getCompetences() {
|
||||||
|
return this.getEmbeddedItems("competence").map((item) => ({
|
||||||
|
item,
|
||||||
|
finalValue: this.computeSkillValue(item),
|
||||||
|
profileLabel: LESOUBLIES_CONFIG.profileLabels[item.system.profileKey] ?? item.system.profileKey,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
getGroupedCompetences() {
|
||||||
|
return LESOUBLIES_CONFIG.profiles.map((profile) => ({
|
||||||
|
...profile,
|
||||||
|
items: this.getCompetences().filter((entry) => entry.item.system.profileKey === profile.id),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
getDerivedOverview() {
|
||||||
|
const hpValue = Number(this.system.hp?.value ?? 0)
|
||||||
|
const hpMax = Number(this.system.hp?.max ?? 0)
|
||||||
|
const hpDisplay = this.type === "creature"
|
||||||
|
? (this.system.hp?.display || (hpValue === hpMax ? String(hpValue) : `${hpValue}/${hpMax}`))
|
||||||
|
: `${hpValue}/${hpMax}`
|
||||||
|
|
||||||
|
return {
|
||||||
|
sizeLabel: LESOUBLIES_CONFIG.sizes[this.system.size?.value] ?? this.system.size?.value,
|
||||||
|
hpMax,
|
||||||
|
hpValue,
|
||||||
|
hpDisplay,
|
||||||
|
songesMax: this.system.songes?.max ?? this.system.songes?.points ?? 0,
|
||||||
|
cauchemarMax: this.system.cauchemar?.max ?? this.system.cauchemar?.points ?? 0,
|
||||||
|
songesPoints: this.system.songes?.points ?? 0,
|
||||||
|
cauchemarPoints: this.system.cauchemar?.points ?? 0,
|
||||||
|
race: this.getCreationItem("race"),
|
||||||
|
tribu: this.getCreationItem("tribu"),
|
||||||
|
metier: this.getCreationItem("metier"),
|
||||||
|
compagnie: this.getCompagnie(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async openTestRollDialog(preset = {}) {
|
||||||
|
return LesOubliesRolls.openTestDialog(this, preset)
|
||||||
|
}
|
||||||
|
|
||||||
|
async openConfrontationRollDialog() {
|
||||||
|
return LesOubliesRolls.openConfrontationDialog(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
async openInitiativeRollDialog() {
|
||||||
|
return LesOubliesRolls.openInitiativeDialog(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
async openAttackRollDialog({ itemId = null, mode = null } = {}) {
|
||||||
|
return LesOubliesRolls.openAttackDialog(this, { itemId, mode })
|
||||||
|
}
|
||||||
|
|
||||||
|
async openDamageDialog({ itemId = null } = {}) {
|
||||||
|
return LesOubliesRolls.openDamageDialog(this, { itemId })
|
||||||
|
}
|
||||||
|
|
||||||
|
async openSpellActivationDialog(itemId) {
|
||||||
|
return LesOubliesRolls.openSpellDialog(this, itemId)
|
||||||
|
}
|
||||||
|
|
||||||
|
async openCombatPresetDialog(actionKey) {
|
||||||
|
return LesOubliesRolls.openCombatPresetDialog(this, actionKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
async openThreadHarvestDialog() {
|
||||||
|
return LesOubliesRolls.openThreadHarvestDialog(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
async rollProfile(profileKey) {
|
||||||
|
return this.openTestRollDialog({
|
||||||
|
label: LESOUBLIES_CONFIG.profileLabels[profileKey] ?? profileKey,
|
||||||
|
score: this.getProfileValue(profileKey),
|
||||||
|
difficulty: 0,
|
||||||
|
rollMode: LesOubliesRolls.getDefaultRollMode(this),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async rollCompetence(itemId) {
|
||||||
|
const item = this.items.get(itemId)
|
||||||
|
if (!item) return null
|
||||||
|
return this.openTestRollDialog({
|
||||||
|
label: item.name,
|
||||||
|
score: this.computeSkillValue(item),
|
||||||
|
difficulty: 0,
|
||||||
|
rollMode: LesOubliesRolls.getDefaultRollMode(this),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
export const PROFILE_KEYS = [
|
||||||
|
"artiste",
|
||||||
|
"athlete",
|
||||||
|
"chasseur",
|
||||||
|
"faiseur",
|
||||||
|
"forceNature",
|
||||||
|
"guerrier",
|
||||||
|
"mystique",
|
||||||
|
"ombre",
|
||||||
|
"savant",
|
||||||
|
]
|
||||||
|
|
||||||
|
export const PROFILE_LABELS = {
|
||||||
|
artiste: "Artiste",
|
||||||
|
athlete: "Athlète",
|
||||||
|
chasseur: "Chasseur",
|
||||||
|
faiseur: "Faiseur",
|
||||||
|
forceNature: "Force de la nature",
|
||||||
|
guerrier: "Guerrier",
|
||||||
|
mystique: "Mystique",
|
||||||
|
ombre: "Ombre",
|
||||||
|
savant: "Savant",
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SKILLS = {
|
||||||
|
arts: { label: "Arts", profileKey: "artiste", closed: false, domainSkill: true },
|
||||||
|
empathie: { label: "Empathie", profileKey: "artiste", closed: false, domainSkill: false },
|
||||||
|
seduction: { label: "Séduction", profileKey: "artiste", closed: false, domainSkill: false },
|
||||||
|
athletisme: { label: "Athlétisme", profileKey: "athlete", closed: false, domainSkill: false },
|
||||||
|
rapidite: { label: "Rapidité", profileKey: "athlete", closed: false, domainSkill: false },
|
||||||
|
volonte: { label: "Volonté", profileKey: "athlete", closed: false, domainSkill: false },
|
||||||
|
sens: { label: "Sens", profileKey: "chasseur", closed: false, domainSkill: false },
|
||||||
|
survie: { label: "Survie", profileKey: "chasseur", closed: false, domainSkill: false },
|
||||||
|
tir: { label: "Tir", profileKey: "chasseur", closed: false, domainSkill: false },
|
||||||
|
artisanat: { label: "Artisanat", profileKey: "faiseur", closed: false, domainSkill: true },
|
||||||
|
intellect: { label: "Intellect", profileKey: "faiseur", closed: false, domainSkill: false },
|
||||||
|
soins: { label: "Soins", profileKey: "faiseur", closed: false, domainSkill: false },
|
||||||
|
commandement: { label: "Commandement", profileKey: "forceNature", closed: false, domainSkill: false },
|
||||||
|
endurance: { label: "Endurance", profileKey: "forceNature", closed: false, domainSkill: false },
|
||||||
|
force: { label: "Force", profileKey: "forceNature", closed: false, domainSkill: false },
|
||||||
|
corpsacorps: { label: "Corps à corps", profileKey: "guerrier", closed: false, domainSkill: false },
|
||||||
|
melee: { label: "Mêlée", profileKey: "guerrier", closed: false, domainSkill: false },
|
||||||
|
montures: { label: "Montures", profileKey: "guerrier", closed: false, domainSkill: false },
|
||||||
|
chimerisme: { label: "Chimérisme", profileKey: "mystique", closed: true, domainSkill: false },
|
||||||
|
magie: { label: "Magie", profileKey: "mystique", closed: true, domainSkill: false },
|
||||||
|
onirologie: { label: "Onirologie", profileKey: "mystique", closed: true, domainSkill: false },
|
||||||
|
discretion: { label: "Discrétion", profileKey: "ombre", closed: false, domainSkill: false },
|
||||||
|
esquive: { label: "Esquive", profileKey: "ombre", closed: false, domainSkill: false },
|
||||||
|
subterfuge: { label: "Subterfuge", profileKey: "ombre", closed: false, domainSkill: false },
|
||||||
|
erudition: { label: "Érudition", profileKey: "savant", closed: true, domainSkill: true },
|
||||||
|
langues: { label: "Langues", profileKey: "savant", closed: true, domainSkill: true },
|
||||||
|
strategie: { label: "Stratégie", profileKey: "savant", closed: false, domainSkill: false },
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SIZE_LABELS = {
|
||||||
|
1: "Minuscule",
|
||||||
|
2: "Petite",
|
||||||
|
3: "Moyenne",
|
||||||
|
4: "Grande",
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ACTOR_IMAGES = {
|
||||||
|
personnage: "icons/svg/mystery-man.svg",
|
||||||
|
compagnie: "icons/svg/book.svg",
|
||||||
|
creature: "icons/svg/eye.svg",
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ITEM_IMAGES = {
|
||||||
|
race: "icons/svg/mystery-man.svg",
|
||||||
|
tribu: "icons/svg/ruins.svg",
|
||||||
|
metier: "icons/svg/upgrade.svg",
|
||||||
|
competence: "icons/svg/book.svg",
|
||||||
|
sortilege: "icons/svg/daze.svg",
|
||||||
|
arme: "icons/svg/sword.svg",
|
||||||
|
armure: "icons/svg/shield.svg",
|
||||||
|
equipement: "icons/svg/chest.svg",
|
||||||
|
pouvoircompagnie: "icons/svg/aura.svg",
|
||||||
|
}
|
||||||
|
|
||||||
|
export const LESOUBLIES_CONFIG = {
|
||||||
|
id: "fvtt-les-oublies",
|
||||||
|
title: "Les Oubliés",
|
||||||
|
profiles: PROFILE_KEYS.map((key) => ({ id: key, label: PROFILE_LABELS[key] })),
|
||||||
|
profileLabels: PROFILE_LABELS,
|
||||||
|
skills: SKILLS,
|
||||||
|
sizes: SIZE_LABELS,
|
||||||
|
actorImages: ACTOR_IMAGES,
|
||||||
|
itemImages: ITEM_IMAGES,
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
export class LesOubliesItem extends Item {
|
||||||
|
getChatData() {
|
||||||
|
const data = super.getChatData()
|
||||||
|
return {
|
||||||
|
...data,
|
||||||
|
description: this.system.description,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import { LESOUBLIES_CONFIG } from "./les-oublies-config.js"
|
||||||
|
import { LesOubliesUtility } from "./les-oublies-utility.js"
|
||||||
|
import { LesOubliesActor } from "./les-oublies-actor.js"
|
||||||
|
import { LesOubliesItem } from "./les-oublies-item.js"
|
||||||
|
import { LesOubliesRolls } from "./les-oublies-rolls.js"
|
||||||
|
import * as models from "./models/index.mjs"
|
||||||
|
import * as sheets from "./applications/sheets/_module.mjs"
|
||||||
|
|
||||||
|
Hooks.once("init", function () {
|
||||||
|
console.info("Les Oubliés | Initialisation du système")
|
||||||
|
|
||||||
|
CONFIG.Actor.documentClass = LesOubliesActor
|
||||||
|
CONFIG.Actor.dataModels = {
|
||||||
|
personnage: models.PersonnageDataModel,
|
||||||
|
compagnie: models.CompagnieDataModel,
|
||||||
|
creature: models.CreatureDataModel,
|
||||||
|
}
|
||||||
|
|
||||||
|
CONFIG.Item.documentClass = LesOubliesItem
|
||||||
|
CONFIG.Item.dataModels = {
|
||||||
|
race: models.RaceDataModel,
|
||||||
|
tribu: models.TribuDataModel,
|
||||||
|
metier: models.MetierDataModel,
|
||||||
|
competence: models.CompetenceDataModel,
|
||||||
|
sortilege: models.SortilegeDataModel,
|
||||||
|
arme: models.ArmeDataModel,
|
||||||
|
armure: models.ArmureDataModel,
|
||||||
|
equipement: models.EquipementDataModel,
|
||||||
|
pouvoircompagnie: models.PouvoirCompagnieDataModel,
|
||||||
|
}
|
||||||
|
|
||||||
|
CONFIG.LESOUBLIES = LESOUBLIES_CONFIG
|
||||||
|
|
||||||
|
game.system.lesOublies = {
|
||||||
|
config: LESOUBLIES_CONFIG,
|
||||||
|
models,
|
||||||
|
sheets,
|
||||||
|
rolls: LesOubliesRolls,
|
||||||
|
utility: LesOubliesUtility,
|
||||||
|
}
|
||||||
|
|
||||||
|
foundry.documents.collections.Actors.registerSheet("fvtt-les-oublies", sheets.LesOubliesPersonnageSheet, { types: ["personnage"], makeDefault: true })
|
||||||
|
foundry.documents.collections.Actors.registerSheet("fvtt-les-oublies", sheets.LesOubliesCompagnieSheet, { types: ["compagnie"], makeDefault: true })
|
||||||
|
foundry.documents.collections.Actors.registerSheet("fvtt-les-oublies", sheets.LesOubliesCreatureSheet, { types: ["creature"], makeDefault: true })
|
||||||
|
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-les-oublies", sheets.LesOubliesReferenceItemSheet, { types: ["race", "tribu", "metier"], makeDefault: true })
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-les-oublies", sheets.LesOubliesCompetenceSheet, { types: ["competence"], makeDefault: true })
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-les-oublies", sheets.LesOubliesSortilegeSheet, { types: ["sortilege"], makeDefault: true })
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-les-oublies", sheets.LesOubliesArmeSheet, { types: ["arme"], makeDefault: true })
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-les-oublies", sheets.LesOubliesArmureSheet, { types: ["armure"], makeDefault: true })
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-les-oublies", sheets.LesOubliesEquipementSheet, { types: ["equipement"], makeDefault: true })
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-les-oublies", sheets.LesOubliesPouvoirCompagnieSheet, { types: ["pouvoircompagnie"], makeDefault: true })
|
||||||
|
|
||||||
|
LesOubliesUtility.registerHandlebarsHelpers()
|
||||||
|
})
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,76 @@
|
|||||||
|
import { ACTOR_IMAGES, ITEM_IMAGES, LESOUBLIES_CONFIG, PROFILE_KEYS } from "./les-oublies-config.js"
|
||||||
|
|
||||||
|
export class LesOubliesUtility {
|
||||||
|
static registerHandlebarsHelpers() {
|
||||||
|
Handlebars.registerHelper("eq", (left, right) => left === right)
|
||||||
|
Handlebars.registerHelper("join", (values, separator = ", ") => Array.isArray(values) ? values.filter(Boolean).join(separator) : "")
|
||||||
|
Handlebars.registerHelper("count", (values) => Array.isArray(values) ? values.length : 0)
|
||||||
|
Handlebars.registerHelper("concat", (...parts) => parts.slice(0, -1).join(""))
|
||||||
|
Handlebars.registerHelper("profileLabel", (key) => LESOUBLIES_CONFIG.profileLabels[key] ?? key)
|
||||||
|
Handlebars.registerHelper("skillLabel", (key) => LESOUBLIES_CONFIG.skills[key]?.label ?? key)
|
||||||
|
Handlebars.registerHelper("formatPrice", (value) => Number(value) > 0 ? `${value} e` : "—")
|
||||||
|
Handlebars.registerHelper("formatSkillBonus", (bonus) => {
|
||||||
|
const keys = [bonus.key, ...(bonus.alternativeKeys ?? [])]
|
||||||
|
.filter(Boolean)
|
||||||
|
.map((key) => LESOUBLIES_CONFIG.skills[key]?.label ?? key)
|
||||||
|
const label = keys.join(" ou ")
|
||||||
|
const domains = []
|
||||||
|
if (Array.isArray(bonus.domainsGranted) && bonus.domainsGranted.length) domains.push(bonus.domainsGranted.join(", "))
|
||||||
|
if (Number(bonus.domainsToChoose ?? 0) > 0) {
|
||||||
|
const prefix = bonus.domainsToChoose > 1 ? `${bonus.domainsToChoose} choix` : "1 choix"
|
||||||
|
domains.push(bonus.domainsChoiceText ? `${prefix} : ${bonus.domainsChoiceText}` : prefix)
|
||||||
|
}
|
||||||
|
return domains.length ? `${label} +${bonus.base} — ${domains.join(" ; ")}` : `${label} +${bonus.base}`
|
||||||
|
})
|
||||||
|
Handlebars.registerHelper("formatEquipmentEntry", (entry) => {
|
||||||
|
const baseLabel = entry.choiceText || entry.name || ""
|
||||||
|
const quantity = Number(entry.quantity ?? 0) > 1 ? ` x${entry.quantity}` : ""
|
||||||
|
const extras = []
|
||||||
|
if (entry.details) extras.push(entry.details)
|
||||||
|
if (Number(entry.ecorces ?? 0) > 0) extras.push(`${entry.ecorces} écorces`)
|
||||||
|
return extras.length ? `${baseLabel}${quantity} — ${extras.join(", ")}` : `${baseLabel}${quantity}`
|
||||||
|
})
|
||||||
|
Handlebars.registerHelper("formatSpellGrant", (grant) => {
|
||||||
|
const discipline = LESOUBLIES_CONFIG.skills[grant.skillKey]?.label ?? grant.skillKey ?? grant.tradition
|
||||||
|
return `${grant.tradition} (${discipline}) / ${grant.polarity} : ${grant.amount}`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
static getDefaultActorImage(type) {
|
||||||
|
return ACTOR_IMAGES[type] ?? "icons/svg/mystery-man.svg"
|
||||||
|
}
|
||||||
|
|
||||||
|
static getDefaultItemImage(type) {
|
||||||
|
return ITEM_IMAGES[type] ?? "icons/svg/item-bag.svg"
|
||||||
|
}
|
||||||
|
|
||||||
|
static createEmptyProfiles() {
|
||||||
|
return PROFILE_KEYS.reduce((profiles, key) => {
|
||||||
|
profiles[key] = 0
|
||||||
|
return profiles
|
||||||
|
}, {})
|
||||||
|
}
|
||||||
|
|
||||||
|
static computeDreamPointTotals(songesValue, cauchemarValue) {
|
||||||
|
if (songesValue > cauchemarValue) {
|
||||||
|
return {
|
||||||
|
songesPoints: songesValue * 2 - cauchemarValue,
|
||||||
|
cauchemarPoints: cauchemarValue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (songesValue === cauchemarValue) {
|
||||||
|
return {
|
||||||
|
songesPoints: songesValue,
|
||||||
|
cauchemarPoints: cauchemarValue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
songesPoints: songesValue,
|
||||||
|
cauchemarPoints: cauchemarValue * 3 - songesValue * 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static sortByName(documents = []) {
|
||||||
|
return [...documents].sort((left, right) => left.name.localeCompare(right.name, "fr"))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { BaseItemDataModel } from "./base-item.mjs"
|
||||||
|
|
||||||
|
export default class ArmeDataModel extends BaseItemDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields
|
||||||
|
return {
|
||||||
|
...this.defineBaseSchema(),
|
||||||
|
category: new fields.StringField({ initial: "melee" }),
|
||||||
|
origin: new fields.StringField({ initial: "petitPeuple" }),
|
||||||
|
sizeMode: new fields.StringField({ initial: "variable" }),
|
||||||
|
sizeValue: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
sizeModifier: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
damage: new fields.StringField({ initial: "" }),
|
||||||
|
range: new fields.StringField({ initial: "" }),
|
||||||
|
properties: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
restrictedRace: new fields.StringField({ initial: "" }),
|
||||||
|
quantity: new fields.NumberField({ initial: 1, integer: true, min: 0 }),
|
||||||
|
price: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
equipped: new fields.BooleanField({ initial: false }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { BaseItemDataModel } from "./base-item.mjs"
|
||||||
|
|
||||||
|
export default class ArmureDataModel extends BaseItemDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields
|
||||||
|
return {
|
||||||
|
...this.defineBaseSchema(),
|
||||||
|
state: new fields.StringField({ initial: "protege" }),
|
||||||
|
protection: new fields.NumberField({ initial: 1, integer: true, min: 0 }),
|
||||||
|
physicalPenalty: new fields.NumberField({ initial: 1, integer: true, min: 0 }),
|
||||||
|
initiativePenalty: new fields.NumberField({ initial: 1, integer: true, min: 0 }),
|
||||||
|
quantity: new fields.NumberField({ initial: 1, integer: true, min: 0 }),
|
||||||
|
price: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
equipped: new fields.BooleanField({ initial: false }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
export class BaseItemDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineBaseSchema() {
|
||||||
|
const fields = foundry.data.fields
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
notes: new fields.HTMLField({ initial: "" }),
|
||||||
|
source: new fields.StringField({ initial: "Livre de règles Les Oubliés" }),
|
||||||
|
tags: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
export default class CompagnieDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
notes: new fields.HTMLField({ initial: "" }),
|
||||||
|
captainId: new fields.StringField({ initial: "" }),
|
||||||
|
memberIds: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
ombreDuTourmentId: new fields.StringField({ initial: "" }),
|
||||||
|
power: new fields.SchemaField({
|
||||||
|
name: new fields.StringField({ initial: "" }),
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
sharedDreamPoints: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
activationCondition: new fields.StringField({ initial: "À portée de vue du capitaine" }),
|
||||||
|
captainVisible: new fields.BooleanField({ initial: true }),
|
||||||
|
captainNeedsWitness: new fields.BooleanField({ initial: true }),
|
||||||
|
}),
|
||||||
|
links: new fields.ArrayField(new fields.SchemaField({
|
||||||
|
sourceId: new fields.StringField({ initial: "" }),
|
||||||
|
targetId: new fields.StringField({ initial: "" }),
|
||||||
|
label: new fields.StringField({ initial: "" }),
|
||||||
|
details: new fields.StringField({ initial: "" }),
|
||||||
|
}), { initial: [] }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { BaseItemDataModel } from "./base-item.mjs"
|
||||||
|
|
||||||
|
export default class CompetenceDataModel extends BaseItemDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields
|
||||||
|
return {
|
||||||
|
...this.defineBaseSchema(),
|
||||||
|
key: new fields.StringField({ initial: "" }),
|
||||||
|
profileKey: new fields.StringField({ initial: "" }),
|
||||||
|
base: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
closed: new fields.BooleanField({ initial: false }),
|
||||||
|
domainSkill: new fields.BooleanField({ initial: false }),
|
||||||
|
domains: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
fixedDomains: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
exampleDomains: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
export default class CreatureDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields
|
||||||
|
return {
|
||||||
|
biodata: new fields.SchemaField({
|
||||||
|
categorie: new fields.StringField({ initial: "autre" }),
|
||||||
|
habitat: new fields.HTMLField({ initial: "" }),
|
||||||
|
motscles: new fields.StringField({ initial: "" }),
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
notes: new fields.HTMLField({ initial: "" }),
|
||||||
|
gmnotes: new fields.HTMLField({ initial: "" }),
|
||||||
|
}),
|
||||||
|
size: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({ initial: 2, integer: true, min: 1, max: 8 }),
|
||||||
|
label: new fields.StringField({ initial: "" }),
|
||||||
|
}),
|
||||||
|
profils: new fields.SchemaField({
|
||||||
|
artiste: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
athlete: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
chasseur: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
faiseur: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
forceNature: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
guerrier: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
mystique: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
ombre: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
savant: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
}),
|
||||||
|
songes: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
points: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
max: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
}),
|
||||||
|
cauchemar: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
points: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
max: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
}),
|
||||||
|
hp: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({ initial: 8, integer: true, min: 0 }),
|
||||||
|
max: new fields.NumberField({ initial: 8, integer: true, min: 0 }),
|
||||||
|
display: new fields.StringField({ initial: "" }),
|
||||||
|
}),
|
||||||
|
protection: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
statblock: new fields.SchemaField({
|
||||||
|
damage: new fields.HTMLField({ initial: "" }),
|
||||||
|
special: new fields.HTMLField({ initial: "" }),
|
||||||
|
spellSonges: new fields.HTMLField({ initial: "" }),
|
||||||
|
spellCauchemar: new fields.HTMLField({ initial: "" }),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { BaseItemDataModel } from "./base-item.mjs"
|
||||||
|
|
||||||
|
export default class EquipementDataModel extends BaseItemDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields
|
||||||
|
return {
|
||||||
|
...this.defineBaseSchema(),
|
||||||
|
category: new fields.StringField({ initial: "survie" }),
|
||||||
|
quantity: new fields.NumberField({ initial: 1, integer: true, min: 0 }),
|
||||||
|
price: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
bonus: new fields.StringField({ initial: "" }),
|
||||||
|
usage: new fields.StringField({ initial: "" }),
|
||||||
|
lifespan: new fields.StringField({ initial: "" }),
|
||||||
|
equipped: new fields.BooleanField({ initial: false }),
|
||||||
|
consumable: new fields.BooleanField({ initial: false }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
export { BaseItemDataModel } from "./base-item.mjs"
|
||||||
|
export { default as PersonnageDataModel } from "./personnage.mjs"
|
||||||
|
export { default as CompagnieDataModel } from "./compagnie.mjs"
|
||||||
|
export { default as CreatureDataModel } from "./creature.mjs"
|
||||||
|
export { default as RaceDataModel } from "./race.mjs"
|
||||||
|
export { default as TribuDataModel } from "./tribu.mjs"
|
||||||
|
export { default as MetierDataModel } from "./metier.mjs"
|
||||||
|
export { default as CompetenceDataModel } from "./competence.mjs"
|
||||||
|
export { default as SortilegeDataModel } from "./sortilege.mjs"
|
||||||
|
export { default as ArmeDataModel } from "./arme.mjs"
|
||||||
|
export { default as ArmureDataModel } from "./armure.mjs"
|
||||||
|
export { default as EquipementDataModel } from "./equipement.mjs"
|
||||||
|
export { default as PouvoirCompagnieDataModel } from "./pouvoir-compagnie.mjs"
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import { BaseItemDataModel } from "./base-item.mjs"
|
||||||
|
|
||||||
|
export default class MetierDataModel extends BaseItemDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields
|
||||||
|
return {
|
||||||
|
...this.defineBaseSchema(),
|
||||||
|
specialRules: new fields.HTMLField({ initial: "" }),
|
||||||
|
roleplayNotes: new fields.HTMLField({ initial: "" }),
|
||||||
|
skillBonuses: new fields.ArrayField(new fields.SchemaField({
|
||||||
|
key: new fields.StringField({ initial: "" }),
|
||||||
|
alternativeKeys: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
base: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
domainsGranted: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
domainsToChoose: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
domainsChoiceText: new fields.StringField({ initial: "" }),
|
||||||
|
}), { initial: [] }),
|
||||||
|
startingEquipment: new fields.ArrayField(new fields.SchemaField({
|
||||||
|
name: new fields.StringField({ initial: "" }),
|
||||||
|
type: new fields.StringField({ initial: "equipement" }),
|
||||||
|
quantity: new fields.NumberField({ initial: 1, integer: true, min: 0 }),
|
||||||
|
details: new fields.StringField({ initial: "" }),
|
||||||
|
choiceText: new fields.StringField({ initial: "" }),
|
||||||
|
ecorces: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
}), { initial: [] }),
|
||||||
|
spellGrants: new fields.ArrayField(new fields.SchemaField({
|
||||||
|
tradition: new fields.StringField({ initial: "" }),
|
||||||
|
skillKey: new fields.StringField({ initial: "" }),
|
||||||
|
polarity: new fields.StringField({ initial: "" }),
|
||||||
|
amount: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
}), { initial: [] }),
|
||||||
|
revenues: new fields.SchemaField({
|
||||||
|
beginner: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
intermediate: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
expert: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
export default class PersonnageDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields
|
||||||
|
return {
|
||||||
|
biodata: new fields.SchemaField({
|
||||||
|
age: new fields.NumberField({ initial: 20, integer: true, min: 0 }),
|
||||||
|
sexe: new fields.StringField({ initial: "" }),
|
||||||
|
motscles: new fields.StringField({ initial: "" }),
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
notes: new fields.HTMLField({ initial: "" }),
|
||||||
|
gmnotes: new fields.HTMLField({ initial: "" }),
|
||||||
|
}),
|
||||||
|
references: new fields.SchemaField({
|
||||||
|
raceId: new fields.StringField({ initial: "" }),
|
||||||
|
tribuId: new fields.StringField({ initial: "" }),
|
||||||
|
metierId: new fields.StringField({ initial: "" }),
|
||||||
|
compagnieId: new fields.StringField({ initial: "" }),
|
||||||
|
}),
|
||||||
|
size: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({ initial: 2, integer: true, min: 1, max: 4 }),
|
||||||
|
label: new fields.StringField({ initial: "" }),
|
||||||
|
}),
|
||||||
|
profils: new fields.SchemaField({
|
||||||
|
artiste: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
athlete: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
chasseur: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
faiseur: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
forceNature: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
guerrier: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
mystique: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
ombre: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
savant: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
}),
|
||||||
|
songes: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({ initial: 1, integer: true, min: 0 }),
|
||||||
|
points: new fields.NumberField({ initial: 2, integer: true, min: 0 }),
|
||||||
|
max: new fields.NumberField({ initial: 2, integer: true, min: 0 }),
|
||||||
|
debt: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
xpCredit: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
}),
|
||||||
|
cauchemar: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
points: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
max: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
debt: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
xpCredit: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
}),
|
||||||
|
hp: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({ initial: 8, integer: true, min: 0 }),
|
||||||
|
max: new fields.NumberField({ initial: 8, integer: true, min: 0 }),
|
||||||
|
bonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
}),
|
||||||
|
experience: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
}),
|
||||||
|
money: new fields.SchemaField({
|
||||||
|
ecorces: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
}),
|
||||||
|
flagsNarratifs: new fields.SchemaField({
|
||||||
|
ombreDuTourment: new fields.BooleanField({ initial: false }),
|
||||||
|
isCaptain: new fields.BooleanField({ initial: false }),
|
||||||
|
}),
|
||||||
|
visions: new fields.HTMLField({ initial: "" }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { BaseItemDataModel } from "./base-item.mjs"
|
||||||
|
|
||||||
|
export default class PouvoirCompagnieDataModel extends BaseItemDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields
|
||||||
|
return {
|
||||||
|
...this.defineBaseSchema(),
|
||||||
|
scope: new fields.StringField({ initial: "compagnie" }),
|
||||||
|
effectMode: new fields.StringField({ initial: "" }),
|
||||||
|
ruleText: new fields.HTMLField({ initial: "" }),
|
||||||
|
limitedUses: new fields.StringField({ initial: "" }),
|
||||||
|
resourceImpact: new fields.StringField({ initial: "" }),
|
||||||
|
activationCondition: new fields.StringField({ initial: "À portée de vue du capitaine" }),
|
||||||
|
captainVisible: new fields.BooleanField({ initial: true }),
|
||||||
|
captainNeedsWitness: new fields.BooleanField({ initial: true }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import { BaseItemDataModel } from "./base-item.mjs"
|
||||||
|
|
||||||
|
export default class RaceDataModel extends BaseItemDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields
|
||||||
|
return {
|
||||||
|
...this.defineBaseSchema(),
|
||||||
|
size: new fields.NumberField({ initial: 2, integer: true, min: 1, max: 4 }),
|
||||||
|
lifeExpectancy: new fields.NumberField({ initial: 50, integer: true, min: 0 }),
|
||||||
|
keywords: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
mainTribes: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
language: new fields.StringField({ initial: "" }),
|
||||||
|
languageDomains: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
specialRules: new fields.HTMLField({ initial: "" }),
|
||||||
|
appearance: new fields.HTMLField({ initial: "" }),
|
||||||
|
roleplayHints: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
profiles: new fields.SchemaField({
|
||||||
|
artiste: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
athlete: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
chasseur: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
faiseur: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
forceNature: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
guerrier: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
mystique: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
ombre: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
savant: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { BaseItemDataModel } from "./base-item.mjs"
|
||||||
|
|
||||||
|
export default class SortilegeDataModel extends BaseItemDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields
|
||||||
|
return {
|
||||||
|
...this.defineBaseSchema(),
|
||||||
|
tradition: new fields.StringField({ initial: "" }),
|
||||||
|
skillKey: new fields.StringField({ initial: "" }),
|
||||||
|
polarity: new fields.StringField({ initial: "songes" }),
|
||||||
|
cost: new fields.NumberField({ initial: 1, integer: true, min: 0 }),
|
||||||
|
costFormula: new fields.StringField({ initial: "" }),
|
||||||
|
variableCost: new fields.BooleanField({ initial: false }),
|
||||||
|
preparation: new fields.StringField({ initial: "" }),
|
||||||
|
duration: new fields.StringField({ initial: "" }),
|
||||||
|
range: new fields.StringField({ initial: "" }),
|
||||||
|
area: new fields.StringField({ initial: "" }),
|
||||||
|
stacking: new fields.StringField({ initial: "" }),
|
||||||
|
requiredDomains: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
artsDomains: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
effectsText: new fields.HTMLField({ initial: "" }),
|
||||||
|
ruleTags: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import { BaseItemDataModel } from "./base-item.mjs"
|
||||||
|
|
||||||
|
export default class TribuDataModel extends BaseItemDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields
|
||||||
|
return {
|
||||||
|
...this.defineBaseSchema(),
|
||||||
|
keywords: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
mainRace: new fields.StringField({ initial: "" }),
|
||||||
|
spokenLanguage: new fields.StringField({ initial: "" }),
|
||||||
|
philosophy: new fields.StringField({ initial: "" }),
|
||||||
|
pride: new fields.StringField({ initial: "" }),
|
||||||
|
mythNature: new fields.StringField({ initial: "" }),
|
||||||
|
mythEdenia: new fields.StringField({ initial: "" }),
|
||||||
|
territory: new fields.StringField({ initial: "" }),
|
||||||
|
specialRules: new fields.HTMLField({ initial: "" }),
|
||||||
|
roleplayNotes: new fields.HTMLField({ initial: "" }),
|
||||||
|
restrictedJobs: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
allowedJobs: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
skillBonuses: new fields.ArrayField(new fields.SchemaField({
|
||||||
|
key: new fields.StringField({ initial: "" }),
|
||||||
|
alternativeKeys: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
base: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
domainsGranted: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
domainsToChoose: new fields.NumberField({ initial: 0, integer: true, min: 0 }),
|
||||||
|
domainsChoiceText: new fields.StringField({ initial: "" }),
|
||||||
|
}), { initial: [] }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
+2687
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "fvtt-les-oublies",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"description": "Systeme FoundryVTT AppV2 pour le JDR Les Oublies",
|
||||||
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"build": "gulp build",
|
||||||
|
"watch": "gulp watch"
|
||||||
|
},
|
||||||
|
"author": "Copilot",
|
||||||
|
"license": "UNLICENSED",
|
||||||
|
"devDependencies": {
|
||||||
|
"gulp": "^5.0.0",
|
||||||
|
"gulp-less": "^5.0.0",
|
||||||
|
"gulp-sourcemaps": "^3.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
[
|
||||||
|
{ "name": "Akinakas", "type": "arme", "img": "icons/svg/sword.svg", "system": { "description": "<p>Lance belgfolk à pique traversant les alliages.</p>", "category": "melee", "origin": "petitPeuple", "sizeMode": "variable", "sizeValue": 0, "sizeModifier": 0, "damage": "Taille +0", "range": "", "properties": ["Blessure précise"], "restrictedRace": "", "quantity": 1, "price": 900, "equipped": false } },
|
||||||
|
{ "name": "Arc", "type": "arme", "img": "icons/svg/sword.svg", "system": { "description": "", "category": "tir", "origin": "petitPeuple", "sizeMode": "variable", "sizeValue": 0, "sizeModifier": 0, "damage": "Taille +0", "range": "75", "properties": ["Encocher une nouvelle flèche est une action libre"], "restrictedRace": "", "quantity": 1, "price": 360, "equipped": false } },
|
||||||
|
{ "name": "Arbalète", "type": "arme", "img": "icons/svg/sword.svg", "system": { "description": "<p>Arme de tir du Petit Peuple listée dans le tableau des armes, sans prix explicite dans les tables de tarifs du livre.</p>", "category": "tir", "origin": "petitPeuple", "sizeMode": "variable", "sizeValue": 0, "sizeModifier": 1, "damage": "Taille +1", "range": "100", "properties": ["Encocher un nouveau carreau est une action unique"], "restrictedRace": "", "quantity": 1, "price": 0, "equipped": false } },
|
||||||
|
{ "name": "Dague de Songiam", "type": "arme", "img": "icons/svg/sword.svg", "system": { "description": "<p>Dague kobolde fine et discrète.</p>", "category": "melee", "origin": "petitPeuple", "sizeMode": "variable", "sizeValue": 0, "sizeModifier": -1, "damage": "Taille -1", "range": "", "properties": ["Discrétion +3 en cas de fouille", "Blessure précise"], "restrictedRace": "", "quantity": 1, "price": 270, "equipped": false } },
|
||||||
|
{ "name": "Espadon huvon", "type": "arme", "img": "icons/svg/sword.svg", "system": { "description": "<p>Grande épée forgée pour la musculature des korrigans.</p>", "category": "melee", "origin": "petitPeuple", "sizeMode": "fixe", "sizeValue": 4, "sizeModifier": 0, "damage": "4", "range": "", "properties": ["Korrigans", "Force 1"], "restrictedRace": "Korrigan", "quantity": 1, "price": 900, "equipped": false } },
|
||||||
|
{ "name": "Grifdrachat", "type": "arme", "img": "icons/svg/sword.svg", "system": { "description": "<p>Pointe de métal recourbée capable de se glisser dans les interstices des armures.</p>", "category": "melee", "origin": "geant", "sizeMode": "fixe", "sizeValue": 3, "sizeModifier": 0, "damage": "3", "range": "", "properties": ["Blessure précise"], "restrictedRace": "", "quantity": 1, "price": 540, "equipped": false } },
|
||||||
|
{ "name": "Lance plume", "type": "arme", "img": "icons/svg/sword.svg", "system": { "description": "<p>Lance incrustée d'une plume taillée, conçue pour les charges.</p>", "category": "melee", "origin": "petitPeuple", "sizeMode": "variable", "sizeValue": 0, "sizeModifier": 1, "damage": "Taille +1", "range": "", "properties": ["Charge"], "restrictedRace": "", "quantity": 1, "price": 270, "equipped": false } },
|
||||||
|
{ "name": "Poignard", "type": "arme", "img": "icons/svg/sword.svg", "system": { "description": "", "category": "jet", "origin": "petitPeuple", "sizeMode": "variable", "sizeValue": 0, "sizeModifier": -1, "damage": "Taille -1", "range": "Taille x 5", "properties": [], "restrictedRace": "", "quantity": 1, "price": 90, "equipped": false } }
|
||||||
|
]
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
[
|
||||||
|
{ "name": "Protégé", "type": "armure", "img": "icons/svg/shield.svg", "system": { "description": "<p>État d'équipement léger : bouclier simple, quelques pièces de défense ou protection souple.</p>", "state": "protégé", "protection": 1, "physicalPenalty": 1, "initiativePenalty": 1, "quantity": 1, "price": 0, "equipped": false } },
|
||||||
|
{ "name": "Harnaché", "type": "armure", "img": "icons/svg/shield.svg", "system": { "description": "<p>État d'équipement intermédiaire combinant plusieurs pièces d'armure.</p>", "state": "harnaché", "protection": 2, "physicalPenalty": 2, "initiativePenalty": 2, "quantity": 1, "price": 0, "equipped": false } },
|
||||||
|
{ "name": "Bardé", "type": "armure", "img": "icons/svg/shield.svg", "system": { "description": "<p>État d'équipement lourd et très encombrant, correspondant au niveau maximal du livre de base.</p>", "state": "bardé", "protection": 3, "physicalPenalty": 3, "initiativePenalty": 3, "quantity": 1, "price": 0, "equipped": false } }
|
||||||
|
]
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
[
|
||||||
|
{ "name": "Arts", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "<p>Compétence à domaines artistiques.</p>", "key": "arts", "profileKey": "artiste", "base": 0, "closed": false, "domainSkill": true, "domains": [], "fixedDomains": [], "exampleDomains": ["Danse", "Musique", "Peinture", "Poésie", "Sculpture"] } },
|
||||||
|
{ "name": "Empathie", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "empathie", "profileKey": "artiste", "base": 0, "closed": false, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } },
|
||||||
|
{ "name": "Séduction", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "seduction", "profileKey": "artiste", "base": 0, "closed": false, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } },
|
||||||
|
{ "name": "Athlétisme", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "athletisme", "profileKey": "athlete", "base": 0, "closed": false, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } },
|
||||||
|
{ "name": "Rapidité", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "rapidite", "profileKey": "athlete", "base": 0, "closed": false, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } },
|
||||||
|
{ "name": "Volonté", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "volonte", "profileKey": "athlete", "base": 0, "closed": false, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } },
|
||||||
|
{ "name": "Sens", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "sens", "profileKey": "chasseur", "base": 0, "closed": false, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } },
|
||||||
|
{ "name": "Survie", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "survie", "profileKey": "chasseur", "base": 0, "closed": false, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } },
|
||||||
|
{ "name": "Tir", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "tir", "profileKey": "chasseur", "base": 0, "closed": false, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } },
|
||||||
|
{ "name": "Artisanat", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "<p>Compétence à domaines techniques.</p>", "key": "artisanat", "profileKey": "faiseur", "base": 0, "closed": false, "domainSkill": true, "domains": [], "fixedDomains": [], "exampleDomains": ["Construction", "Forge", "Mécanique", "Menuiserie", "Taille de pierre"] } },
|
||||||
|
{ "name": "Intellect", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "intellect", "profileKey": "faiseur", "base": 0, "closed": false, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } },
|
||||||
|
{ "name": "Soins", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "soins", "profileKey": "faiseur", "base": 0, "closed": false, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } },
|
||||||
|
{ "name": "Commandement", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "commandement", "profileKey": "forceNature", "base": 0, "closed": false, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } },
|
||||||
|
{ "name": "Endurance", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "endurance", "profileKey": "forceNature", "base": 0, "closed": false, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } },
|
||||||
|
{ "name": "Force", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "force", "profileKey": "forceNature", "base": 0, "closed": false, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } },
|
||||||
|
{ "name": "Corps à corps", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "corpsacorps", "profileKey": "guerrier", "base": 0, "closed": false, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } },
|
||||||
|
{ "name": "Mêlée", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "melee", "profileKey": "guerrier", "base": 0, "closed": false, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } },
|
||||||
|
{ "name": "Montures", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "montures", "profileKey": "guerrier", "base": 0, "closed": false, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } },
|
||||||
|
{ "name": "Chimérisme", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "chimerisme", "profileKey": "mystique", "base": 0, "closed": true, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } },
|
||||||
|
{ "name": "Magie", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "magie", "profileKey": "mystique", "base": 0, "closed": true, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } },
|
||||||
|
{ "name": "Onirologie", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "onirologie", "profileKey": "mystique", "base": 0, "closed": true, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } },
|
||||||
|
{ "name": "Discrétion", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "discretion", "profileKey": "ombre", "base": 0, "closed": false, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } },
|
||||||
|
{ "name": "Esquive", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "esquive", "profileKey": "ombre", "base": 0, "closed": false, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } },
|
||||||
|
{ "name": "Subterfuge", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "subterfuge", "profileKey": "ombre", "base": 0, "closed": false, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } },
|
||||||
|
{ "name": "Érudition", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "<p>Compétence fermée à domaines de savoir.</p>", "key": "erudition", "profileKey": "savant", "base": 0, "closed": true, "domainSkill": true, "domains": [], "fixedDomains": [], "exampleDomains": ["Edenia", "Histoire", "Légendes", "Lettres", "Terra Incognita"] } },
|
||||||
|
{ "name": "Langues", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "<p>Compétence fermée à domaines linguistiques.</p>", "key": "langues", "profileKey": "savant", "base": 0, "closed": true, "domainSkill": true, "domains": [], "fixedDomains": [], "exampleDomains": ["Chimérique", "Jargon des likias", "Latin", "Oc", "Vieux lutin"] } },
|
||||||
|
{ "name": "Stratégie", "type": "competence", "img": "icons/svg/book.svg", "system": { "description": "", "key": "strategie", "profileKey": "savant", "base": 0, "closed": false, "domainSkill": false, "domains": [], "fixedDomains": [], "exampleDomains": [] } }
|
||||||
|
]
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
[
|
||||||
|
{ "name": "Bougie de géant", "type": "equipement", "img": "icons/svg/chest.svg", "system": { "description": "<p>Source de lumière simple à planter sur une pique.</p>", "category": "voyage", "quantity": 1, "price": 180, "bonus": "", "usage": "Éclairage", "lifespan": "", "equipped": false, "consumable": true } },
|
||||||
|
{ "name": "Dé à coudre en acier", "type": "equipement", "img": "icons/svg/chest.svg", "system": { "description": "<p>Brasero miniature portable utilisé sans laisser de trace de campement.</p>", "category": "voyage", "quantity": 1, "price": 15, "bonus": "", "usage": "Campement", "lifespan": "", "equipped": false, "consumable": false } },
|
||||||
|
{ "name": "Lampe à fée des nuits", "type": "equipement", "img": "icons/svg/chest.svg", "system": { "description": "<p>Lampe froide alimentée par une ou plusieurs fées des nuits captives.</p>", "category": "voyage", "quantity": 1, "price": 360, "bonus": "", "usage": "Éclairage", "lifespan": "Quelques mois", "equipped": false, "consumable": true } },
|
||||||
|
{ "name": "Corde", "type": "equipement", "img": "icons/svg/chest.svg", "system": { "description": "<p>Segment de corde de 50 à 70 cm prélevé sur les cordages des géants.</p>", "category": "voyage", "quantity": 1, "price": 3, "bonus": "", "usage": "Escalade", "lifespan": "", "equipped": false, "consumable": false } },
|
||||||
|
{ "name": "Grappin", "type": "equipement", "img": "icons/svg/chest.svg", "system": { "description": "<p>Souvent façonné dans un hameçon ou une broche de géant. Peut aussi servir d'arme de corps à corps.</p>", "category": "voyage", "quantity": 1, "price": 6, "bonus": "", "usage": "Escalade", "lifespan": "", "equipped": false, "consumable": false } },
|
||||||
|
{ "name": "Nécessaire d'entretien d'armes", "type": "equipement", "img": "icons/svg/chest.svg", "system": { "description": "<p>Sert à l'affûtage et à la prévention de la corrosion des armes.</p>", "category": "outil", "quantity": 1, "price": 0, "bonus": "", "usage": "Maintenance", "lifespan": "", "equipped": false, "consumable": false } },
|
||||||
|
{ "name": "Nécessaire à écriture / dessins", "type": "equipement", "img": "icons/svg/chest.svg", "system": { "description": "<p>Encre, plume et supports de fortune pour écrire, dessiner ou cartographier.</p>", "category": "outil", "quantity": 1, "price": 0, "bonus": "", "usage": "Écriture", "lifespan": "", "equipped": false, "consumable": false } },
|
||||||
|
{ "name": "Piolet", "type": "equipement", "img": "icons/svg/chest.svg", "system": { "description": "<p>Outil d'ascension accordant un bonus de +3 aux escalades adaptées.</p>", "category": "voyage", "quantity": 1, "price": 60, "bonus": "+3 escalade", "usage": "Ascension", "lifespan": "", "equipped": false, "consumable": false } },
|
||||||
|
{ "name": "Rikilin", "type": "equipement", "img": "icons/svg/chest.svg", "system": { "description": "<p>Chaussures de marche munies de crampons métalliques pour l'escalade.</p>", "category": "voyage", "quantity": 1, "price": 0, "bonus": "+3 escalade", "usage": "Ascension", "lifespan": "", "equipped": false, "consumable": false } },
|
||||||
|
{ "name": "Trousse de premiers soins", "type": "equipement", "img": "icons/svg/chest.svg", "system": { "description": "<p>Bandages, plantes désinfectantes et fioles de soins pour les premiers secours.</p>", "category": "voyage", "quantity": 1, "price": 0, "bonus": "", "usage": "Soins", "lifespan": "", "equipped": false, "consumable": true } }
|
||||||
|
]
|
||||||
@@ -0,0 +1,198 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "Mage des Songes",
|
||||||
|
"type": "metier",
|
||||||
|
"img": "icons/svg/upgrade.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Puissant magicien du Petit Peuple et acteur majeur de sa survie en Terra Incognita.</p>",
|
||||||
|
"specialRules": "<p>Possède 3 sortilèges de magie de Songes et 3 de Cauchemar à la création.</p>",
|
||||||
|
"roleplayNotes": "<p>Le mage des Songes est une figure importante et souvent respectée, dépositaire d'une magie utile à la survie collective.</p>",
|
||||||
|
"skillBonuses": [
|
||||||
|
{ "key": "magie", "alternativeKeys": [], "base": 3, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "intellect", "alternativeKeys": [], "base": 3, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "erudition", "alternativeKeys": [], "base": 1, "domainsGranted": ["Lettres"], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "volonte", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" }
|
||||||
|
],
|
||||||
|
"startingEquipment": [
|
||||||
|
{ "name": "Sphère de verre contenant 1 fil de Songes", "type": "equipement", "quantity": 3, "details": "", "choiceText": "", "ecorces": 0 },
|
||||||
|
{ "name": "Arme", "type": "arme", "quantity": 1, "details": "", "choiceText": "Arme au choix", "ecorces": 0 },
|
||||||
|
{ "name": "Bourse", "type": "equipement", "quantity": 1, "details": "", "choiceText": "", "ecorces": 180 }
|
||||||
|
],
|
||||||
|
"spellGrants": [
|
||||||
|
{ "tradition": "magie", "skillKey": "magie", "polarity": "songes", "amount": 3 },
|
||||||
|
{ "tradition": "magie", "skillKey": "magie", "polarity": "cauchemar", "amount": 3 }
|
||||||
|
],
|
||||||
|
"revenues": { "beginner": 30, "intermediate": 90, "expert": 450 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Rêvirine",
|
||||||
|
"type": "metier",
|
||||||
|
"img": "icons/svg/upgrade.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Guerrier des Songes chargé de récolter les rêves des géants.</p>",
|
||||||
|
"specialRules": "<p>Connaît 1 sortilège d'Onirologie de Songes et 1 de Cauchemar.</p>",
|
||||||
|
"roleplayNotes": "<p>Les rêvirines sont des spécialistes des dormeurs géants et des filaments de Songe, à la fois magiciens et prédateurs de rêves.</p>",
|
||||||
|
"skillBonuses": [
|
||||||
|
{ "key": "onirologie", "alternativeKeys": [], "base": 3, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "volonte", "alternativeKeys": [], "base": 3, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "magie", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "endurance", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" }
|
||||||
|
],
|
||||||
|
"startingEquipment": [
|
||||||
|
{ "name": "Sphère de verre contenant 1 fil de Songes", "type": "equipement", "quantity": 1, "details": "", "choiceText": "", "ecorces": 0 },
|
||||||
|
{ "name": "Arme", "type": "arme", "quantity": 1, "details": "", "choiceText": "Arme au choix", "ecorces": 0 },
|
||||||
|
{ "name": "Corde solide et très fine", "type": "equipement", "quantity": 1, "details": "Environ 3 mètres", "choiceText": "", "ecorces": 0 },
|
||||||
|
{ "name": "Bourse", "type": "equipement", "quantity": 1, "details": "", "choiceText": "", "ecorces": 180 }
|
||||||
|
],
|
||||||
|
"spellGrants": [
|
||||||
|
{ "tradition": "onirologie", "skillKey": "onirologie", "polarity": "songes", "amount": 1 },
|
||||||
|
{ "tradition": "onirologie", "skillKey": "onirologie", "polarity": "cauchemar", "amount": 1 }
|
||||||
|
],
|
||||||
|
"revenues": { "beginner": 30, "intermediate": 100, "expert": 300 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Chevalier errant",
|
||||||
|
"type": "metier",
|
||||||
|
"img": "icons/svg/upgrade.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Dernier représentant d'un code d'honneur hérité d'Edenia.</p>",
|
||||||
|
"specialRules": "",
|
||||||
|
"roleplayNotes": "<p>Les chevaliers errants vivent selon un idéal ancien, souvent moqué mais encore redoutable au combat.</p>",
|
||||||
|
"skillBonuses": [
|
||||||
|
{ "key": "melee", "alternativeKeys": [], "base": 3, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "montures", "alternativeKeys": [], "base": 3, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "commandement", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "volonte", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" }
|
||||||
|
],
|
||||||
|
"startingEquipment": [
|
||||||
|
{ "name": "Arme", "type": "arme", "quantity": 2, "details": "", "choiceText": "2 armes au choix", "ecorces": 0 },
|
||||||
|
{ "name": "Armure", "type": "armure", "quantity": 1, "details": "", "choiceText": "Armure au choix", "ecorces": 0 },
|
||||||
|
{ "name": "Monture", "type": "equipement", "quantity": 1, "details": "", "choiceText": "Monture au choix", "ecorces": 0 },
|
||||||
|
{ "name": "Bourse", "type": "equipement", "quantity": 1, "details": "", "choiceText": "", "ecorces": 6 }
|
||||||
|
],
|
||||||
|
"spellGrants": [],
|
||||||
|
"revenues": { "beginner": 3, "intermediate": 12, "expert": 30 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Mercenaire",
|
||||||
|
"type": "metier",
|
||||||
|
"img": "icons/svg/upgrade.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Combattant de métier, formé à l'obéissance et aux conflits permanents de la Terra.</p>",
|
||||||
|
"specialRules": "",
|
||||||
|
"roleplayNotes": "<p>Les mercenaires servent dans les grinides et vivent dans une logique de guerre, de hiérarchie et de solde.</p>",
|
||||||
|
"skillBonuses": [
|
||||||
|
{ "key": "melee", "alternativeKeys": [], "base": 3, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "rapidite", "alternativeKeys": [], "base": 3, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "athletisme", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "soins", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" }
|
||||||
|
],
|
||||||
|
"startingEquipment": [
|
||||||
|
{ "name": "Arme", "type": "arme", "quantity": 2, "details": "", "choiceText": "2 armes au choix", "ecorces": 0 },
|
||||||
|
{ "name": "Armure", "type": "armure", "quantity": 1, "details": "", "choiceText": "Armure au choix", "ecorces": 0 },
|
||||||
|
{ "name": "Bourse", "type": "equipement", "quantity": 1, "details": "", "choiceText": "", "ecorces": 18 }
|
||||||
|
],
|
||||||
|
"spellGrants": [],
|
||||||
|
"revenues": { "beginner": 9, "intermediate": 30, "expert": 180 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Explorateur-marchand",
|
||||||
|
"type": "metier",
|
||||||
|
"img": "icons/svg/upgrade.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Voyageur, négociant et éclaireur des routes de la Terra Incognita.</p>",
|
||||||
|
"specialRules": "",
|
||||||
|
"roleplayNotes": "<p>Les explorateurs-marchands parcourent sans cesse les routes dangereuses pour ravitailler le Petit Peuple.</p>",
|
||||||
|
"skillBonuses": [
|
||||||
|
{ "key": "survie", "alternativeKeys": [], "base": 3, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "seduction", "alternativeKeys": [], "base": 3, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "artisanat", "alternativeKeys": ["arts"], "base": 1, "domainsGranted": [], "domainsToChoose": 1, "domainsChoiceText": "domaine au choix dans la compétence retenue" },
|
||||||
|
{ "key": "montures", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" }
|
||||||
|
],
|
||||||
|
"startingEquipment": [
|
||||||
|
{ "name": "Arme", "type": "arme", "quantity": 1, "details": "", "choiceText": "Arme au choix", "ecorces": 0 },
|
||||||
|
{ "name": "Bel objet", "type": "equipement", "quantity": 1, "details": "", "choiceText": "Bel objet au choix", "ecorces": 0 },
|
||||||
|
{ "name": "Bourse", "type": "equipement", "quantity": 1, "details": "", "choiceText": "", "ecorces": 72 }
|
||||||
|
],
|
||||||
|
"spellGrants": [],
|
||||||
|
"revenues": { "beginner": 18, "intermediate": 60, "expert": 360 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Cartographe",
|
||||||
|
"type": "metier",
|
||||||
|
"img": "icons/svg/upgrade.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Observateur curieux, collectionneur de cartes et d'usages des géants.</p>",
|
||||||
|
"specialRules": "",
|
||||||
|
"roleplayNotes": "<p>Le cartographe observe les géants, leurs lieux et leurs bibliothèques avec une curiosité méthodique.</p>",
|
||||||
|
"skillBonuses": [
|
||||||
|
{ "key": "erudition", "alternativeKeys": [], "base": 3, "domainsGranted": ["Géants", "Lettres", "Terra Incognita"], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "survie", "alternativeKeys": [], "base": 3, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "artisanat", "alternativeKeys": [], "base": 1, "domainsGranted": ["Cartographie"], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "endurance", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" }
|
||||||
|
],
|
||||||
|
"startingEquipment": [
|
||||||
|
{ "name": "Boîte de cartographe", "type": "equipement", "quantity": 1, "details": "2 plumes, 2 fioles d'encre, 1 fil mesureur et 5 parchemins vierges", "choiceText": "", "ecorces": 0 },
|
||||||
|
{ "name": "Arme", "type": "arme", "quantity": 1, "details": "", "choiceText": "Arme au choix", "ecorces": 0 },
|
||||||
|
{ "name": "Objet géant", "type": "equipement", "quantity": 1, "details": "", "choiceText": "Objet géant au choix", "ecorces": 0 },
|
||||||
|
{ "name": "Bourse", "type": "equipement", "quantity": 1, "details": "", "choiceText": "", "ecorces": 18 }
|
||||||
|
],
|
||||||
|
"spellGrants": [],
|
||||||
|
"revenues": { "beginner": 9, "intermediate": 30, "expert": 180 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Doux rêveur",
|
||||||
|
"type": "metier",
|
||||||
|
"img": "icons/svg/upgrade.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Conteur, comédien ou ménestrel qui entretient le mythe d'Edenia.</p>",
|
||||||
|
"specialRules": "<p>Connaît 3 sortilèges de Chimérisme de Songes et 3 de Cauchemar.</p>",
|
||||||
|
"roleplayNotes": "<p>Les doux rêveurs font vivre le récit de l'Exil, de Syllistine et des exploits des compagnies dans l'imaginaire du Petit Peuple.</p>",
|
||||||
|
"skillBonuses": [
|
||||||
|
{ "key": "chimerisme", "alternativeKeys": [], "base": 3, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "seduction", "alternativeKeys": [], "base": 3, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "arts", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 1, "domainsChoiceText": "domaine d'Arts au choix" },
|
||||||
|
{ "key": "magie", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" }
|
||||||
|
],
|
||||||
|
"startingEquipment": [
|
||||||
|
{ "name": "Instrument de musique", "type": "equipement", "quantity": 1, "details": "", "choiceText": "", "ecorces": 0 },
|
||||||
|
{ "name": "Arme", "type": "arme", "quantity": 1, "details": "", "choiceText": "Arme au choix", "ecorces": 0 },
|
||||||
|
{ "name": "Bourse", "type": "equipement", "quantity": 1, "details": "", "choiceText": "", "ecorces": 12 }
|
||||||
|
],
|
||||||
|
"spellGrants": [
|
||||||
|
{ "tradition": "chimerisme", "skillKey": "chimerisme", "polarity": "songes", "amount": 3 },
|
||||||
|
{ "tradition": "chimerisme", "skillKey": "chimerisme", "polarity": "cauchemar", "amount": 3 }
|
||||||
|
],
|
||||||
|
"revenues": { "beginner": 6, "intermediate": 30, "expert": 180 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Trouvetout",
|
||||||
|
"type": "metier",
|
||||||
|
"img": "icons/svg/upgrade.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Récupérateur audacieux des biens des géants.</p>",
|
||||||
|
"specialRules": "",
|
||||||
|
"roleplayNotes": "<p>Les trouvetouts vivent du risque, de l'intrusion et du pillage utile des demeures géantes.</p>",
|
||||||
|
"skillBonuses": [
|
||||||
|
{ "key": "discretion", "alternativeKeys": [], "base": 3, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "athletisme", "alternativeKeys": [], "base": 3, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "force", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "rapidite", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" }
|
||||||
|
],
|
||||||
|
"startingEquipment": [
|
||||||
|
{ "name": "Arme", "type": "arme", "quantity": 1, "details": "", "choiceText": "Arme au choix", "ecorces": 0 },
|
||||||
|
{ "name": "Objet de survie", "type": "equipement", "quantity": 1, "details": "", "choiceText": "Objet de survie au choix", "ecorces": 0 },
|
||||||
|
{ "name": "Bourse", "type": "equipement", "quantity": 1, "details": "", "choiceText": "", "ecorces": 60 }
|
||||||
|
],
|
||||||
|
"spellGrants": [],
|
||||||
|
"revenues": { "beginner": 30, "intermediate": 90, "expert": 180 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
[
|
||||||
|
{ "name": "Ardeur belliqueuse", "type": "pouvoircompagnie", "img": "icons/svg/aura.svg", "system": { "description": "<p>Les attaques au corps à corps et en mêlée infligent 1 point de dégâts supplémentaire.</p>", "scope": "compagnie", "effectMode": "passif", "ruleText": "<p>Les dégâts des attaques au corps à corps et en mêlée augmentent de 1 point.</p>", "limitedUses": "Permanent", "resourceImpact": "", "activationCondition": "À portée de vue du capitaine ; le capitaine doit lui-même voir au moins un autre membre", "captainVisible": true, "captainNeedsWitness": true } },
|
||||||
|
{ "name": "Aube flamboyante", "type": "pouvoircompagnie", "img": "icons/svg/aura.svg", "system": { "description": "<p>La compagnie récupère plus vite ses Songes à l'aube.</p>", "scope": "compagnie", "effectMode": "passif", "ruleText": "<p>À l'aube, les Oubliés récupèrent 2 points de Songes au lieu de 1.</p>", "limitedUses": "À chaque aube", "resourceImpact": "Songes", "activationCondition": "À portée de vue du capitaine ; le capitaine doit lui-même voir au moins un autre membre", "captainVisible": true, "captainNeedsWitness": true } },
|
||||||
|
{ "name": "Levier", "type": "pouvoircompagnie", "img": "icons/svg/aura.svg", "system": { "description": "<p>Permet des réussites spectaculaires quand les deux dés montrent le même nombre.</p>", "scope": "compagnie", "effectMode": "passif", "ruleText": "<p>Si les deux d12 montrent le même nombre, le résultat naturel s'obtient en les additionnant, sauf sur double 1.</p>", "limitedUses": "Permanent", "resourceImpact": "", "activationCondition": "À portée de vue du capitaine ; le capitaine doit lui-même voir au moins un autre membre", "captainVisible": true, "captainNeedsWitness": true } },
|
||||||
|
{ "name": "Patience", "type": "pouvoircompagnie", "img": "icons/svg/aura.svg", "system": { "description": "<p>Concentration avant test pour améliorer le résultat.</p>", "scope": "compagnie", "effectMode": "action", "ruleText": "<p>Passer un round à se concentrer avant un test permet d'augmenter de 1 le résultat final.</p>", "limitedUses": "À volonté", "resourceImpact": "", "activationCondition": "À portée de vue du capitaine ; le capitaine doit lui-même voir au moins un autre membre", "captainVisible": true, "captainNeedsWitness": true } },
|
||||||
|
{ "name": "Protection", "type": "pouvoircompagnie", "img": "icons/svg/aura.svg", "system": { "description": "<p>La compagnie bénéficie d'une armure naturelle.</p>", "scope": "compagnie", "effectMode": "passif", "ruleText": "<p>Le pouvoir accorde une armure naturelle de 2 points.</p>", "limitedUses": "Permanent", "resourceImpact": "", "activationCondition": "À portée de vue du capitaine ; le capitaine doit lui-même voir au moins un autre membre", "captainVisible": true, "captainNeedsWitness": true } },
|
||||||
|
{ "name": "Resplendissance", "type": "pouvoircompagnie", "img": "icons/svg/aura.svg", "system": { "description": "<p>Transforme les réussites parfaites en succès éblouissants.</p>", "scope": "compagnie", "effectMode": "passif", "ruleText": "<p>Sur un 12, le dé est relancé mais le 12 remplace le nouveau résultat pour le calcul du résultat naturel.</p>", "limitedUses": "Permanent", "resourceImpact": "", "activationCondition": "À portée de vue du capitaine ; le capitaine doit lui-même voir au moins un autre membre", "captainVisible": true, "captainNeedsWitness": true } },
|
||||||
|
{ "name": "Sauvegarde", "type": "pouvoircompagnie", "img": "icons/svg/aura.svg", "system": { "description": "<p>Permet de relancer un 1 naturel sur un test de compétence.</p>", "scope": "compagnie", "effectMode": "réaction", "ruleText": "<p>Un 1 naturel peut être relancé une fois. Si un nouveau 1 est obtenu, il doit être conservé.</p>", "limitedUses": "Permanent", "resourceImpact": "", "activationCondition": "À portée de vue du capitaine ; le capitaine doit lui-même voir au moins un autre membre", "captainVisible": true, "captainNeedsWitness": true } },
|
||||||
|
{ "name": "Songes immanents", "type": "pouvoircompagnie", "img": "icons/svg/aura.svg", "system": { "description": "<p>La compagnie possède un point de Songes partagé.</p>", "scope": "compagnie", "effectMode": "ressource", "ruleText": "<p>La compagnie possède 1 point de Songes utilisable par un membre, régénéré à l'aube.</p>", "limitedUses": "1 par aube", "resourceImpact": "1 point de Songes partagé", "activationCondition": "À portée de vue du capitaine ; le capitaine doit lui-même voir au moins un autre membre", "captainVisible": true, "captainNeedsWitness": true } }
|
||||||
|
]
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "Belgfolk",
|
||||||
|
"type": "race",
|
||||||
|
"img": "icons/svg/mystery-man.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Race trapue, robuste et ingénieuse du Petit Peuple.</p>",
|
||||||
|
"size": 2,
|
||||||
|
"lifeExpectancy": 60,
|
||||||
|
"keywords": ["intelligent", "ingénieux", "curieux", "calculateur", "égoïste", "têtu", "bourru", "nostalgique", "costaud"],
|
||||||
|
"mainTribes": ["Frinios", "Margouts"],
|
||||||
|
"language": "Belgfolk",
|
||||||
|
"languageDomains": ["Chimérique", "Jargon des likias", "Belgfolk"],
|
||||||
|
"specialRules": "",
|
||||||
|
"appearance": "<p>Les belgfolks sont massifs, poilus et courts sur patte, avec un long nez, une haute stature pour leur taille et une barbe ou une longue natte soigneusement portée.</p>",
|
||||||
|
"roleplayHints": ["Garant d'une époque glorieuse passée", "Inspirations slaves et vikings", "Endurant face aux éléments"],
|
||||||
|
"profiles": { "artiste": 0, "athlete": 0, "chasseur": 1, "faiseur": 5, "forceNature": 5, "guerrier": 0, "mystique": 0, "ombre": 1, "savant": 3 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Farfadet",
|
||||||
|
"type": "race",
|
||||||
|
"img": "icons/svg/mystery-man.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Race mystique, longévive et liée aux sortilèges.</p>",
|
||||||
|
"size": 3,
|
||||||
|
"lifeExpectancy": 100,
|
||||||
|
"keywords": ["calme", "silencieux", "paisible", "résigné", "pessimiste", "généreux", "mystique", "solitaire", "enchanteur"],
|
||||||
|
"mainTribes": ["Siccomores", "Margouts"],
|
||||||
|
"language": "Farfadet",
|
||||||
|
"languageDomains": ["Chimérique", "Jargon des likias", "Farfadet"],
|
||||||
|
"specialRules": "",
|
||||||
|
"appearance": "<p>Les farfadets sont voûtés, rabougris, aux cheveux noirs, à la peau abîmée et aux longs ongles. Les femmes se distinguent souvent par leurs bijoux et boucles d'oreilles.</p>",
|
||||||
|
"roleplayHints": ["Fier d'une race autrefois influente", "Inspirations d'enchanteurs et de vieilles sorcières médiévales", "Présence inquiétante et ancienne"],
|
||||||
|
"profiles": { "artiste": 1, "athlete": 0, "chasseur": 0, "faiseur": 1, "forceNature": 3, "guerrier": 0, "mystique": 5, "ombre": 0, "savant": 4 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Gnome",
|
||||||
|
"type": "race",
|
||||||
|
"img": "icons/svg/mystery-man.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Race très petite, acrobatique, bruyante et farceuse.</p>",
|
||||||
|
"size": 2,
|
||||||
|
"lifeExpectancy": 50,
|
||||||
|
"keywords": ["agile", "acrobate", "chétif", "comédien", "espiègle", "farceur", "bruyant", "bagarreur", "cavalier", "tireur"],
|
||||||
|
"mainTribes": ["Pataches", "Banshises", "Margouts"],
|
||||||
|
"language": "Gnome",
|
||||||
|
"languageDomains": ["Chimérique", "Jargon des likias", "Gnome"],
|
||||||
|
"specialRules": "",
|
||||||
|
"appearance": "<p>Les gnomes ont un visage d'enfant, aucune pilosité et une allure malingre. Leur petite taille contraste avec leur énergie débordante.</p>",
|
||||||
|
"roleplayHints": ["Déclenche facilement les bagarres", "Grandes variations culturelles", "Inspirations nomades et tsiganes"],
|
||||||
|
"profiles": { "artiste": 3, "athlete": 5, "chasseur": 3, "faiseur": 0, "forceNature": 0, "guerrier": 1, "mystique": 0, "ombre": 3, "savant": 0 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Kobold",
|
||||||
|
"type": "race",
|
||||||
|
"img": "icons/svg/mystery-man.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Race gracile et macabre, proche des morts et de la nuit.</p>",
|
||||||
|
"size": 3,
|
||||||
|
"lifeExpectancy": 65,
|
||||||
|
"keywords": ["calme", "froid", "taciturne", "solitaire", "macabre", "gracieux", "agile", "orgueilleux", "élancé"],
|
||||||
|
"mainTribes": ["Sixts", "Vivitins", "Margouts"],
|
||||||
|
"language": "Kobold",
|
||||||
|
"languageDomains": ["Chimérique", "Jargon des likias", "Kobold"],
|
||||||
|
"specialRules": "<p>Les kobolds voient et entendent les esprits des morts qui les entourent.</p>",
|
||||||
|
"appearance": "<p>Les kobolds ont la peau pâle, les cheveux argentés et une beauté glaciale. Certains sont d'un bleu sombre presque noir et sont promis à un grand destin magique.</p>",
|
||||||
|
"roleplayHints": ["Chevaliers noirs et noblesse décadente", "Affinité naturelle avec les morts", "Souvent tenus pour suspects"],
|
||||||
|
"profiles": { "artiste": 0, "athlete": 5, "chasseur": 0, "faiseur": 0, "forceNature": 0, "guerrier": 3, "mystique": 3, "ombre": 1, "savant": 1 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Korrigan",
|
||||||
|
"type": "race",
|
||||||
|
"img": "icons/svg/mystery-man.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Race violente, puissante et exubérante, peu sensible au Songe.</p>",
|
||||||
|
"size": 2,
|
||||||
|
"lifeExpectancy": 45,
|
||||||
|
"keywords": ["agressif", "violent", "bruyant", "impulsif", "épicurien", "farceur", "tolérant", "force prodigieuse", "guerrier"],
|
||||||
|
"mainTribes": ["Huvons", "Margouts"],
|
||||||
|
"language": "Korrigan",
|
||||||
|
"languageDomains": ["Chimérique", "Jargon des likias", "Korrigan"],
|
||||||
|
"specialRules": "",
|
||||||
|
"appearance": "<p>Très trapus, souvent sombres et extrêmement velus, les korrigans ressemblent à des cubes de muscle taillés pour la bagarre.</p>",
|
||||||
|
"roleplayHints": ["Guerrier craint", "Adore la compagnie et les conflits", "Inspirations barbares et celtes"],
|
||||||
|
"profiles": { "artiste": 0, "athlete": 3, "chasseur": 1, "faiseur": 0, "forceNature": 5, "guerrier": 5, "mystique": 0, "ombre": 1, "savant": 0 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Lutin",
|
||||||
|
"type": "race",
|
||||||
|
"img": "icons/svg/mystery-man.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Race noble, charismatique et très polyvalente.</p>",
|
||||||
|
"size": 3,
|
||||||
|
"lifeExpectancy": 60,
|
||||||
|
"keywords": ["agile", "sensuel", "élancé", "orgueilleux", "autoritaire", "arrogant", "charismatique", "polyvalent"],
|
||||||
|
"mainTribes": ["Krograines", "Karius", "Margouts"],
|
||||||
|
"language": "Lutin",
|
||||||
|
"languageDomains": ["Chimérique", "Jargon des likias", "Lutin"],
|
||||||
|
"specialRules": "",
|
||||||
|
"appearance": "<p>Les lutins sont minces, élégants, d'une grande beauté et portent de longues chevelures aux reflets d'or ou de rouille. Leur regard froid impressionne les autres races.</p>",
|
||||||
|
"roleplayHints": ["Respecté des autres races", "Gardien des mythes d'Edenia", "Inspirations arthuriennes et féodales"],
|
||||||
|
"profiles": { "artiste": 4, "athlete": 0, "chasseur": 1, "faiseur": 0, "forceNature": 0, "guerrier": 5, "mystique": 3, "ombre": 1, "savant": 0 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Velu nuton",
|
||||||
|
"type": "race",
|
||||||
|
"img": "icons/svg/mystery-man.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Les plus grands et les plus robustes du Petit Peuple.</p>",
|
||||||
|
"size": 4,
|
||||||
|
"lifeExpectancy": 50,
|
||||||
|
"keywords": ["force de la nature", "brute", "cavalier", "amoureux de la nature", "conteur", "sauvage", "primitif"],
|
||||||
|
"mainTribes": ["Ventrus", "Margouts"],
|
||||||
|
"language": "Velu nuton",
|
||||||
|
"languageDomains": ["Chimérique", "Jargon des likias", "Velu nuton"],
|
||||||
|
"specialRules": "",
|
||||||
|
"appearance": "<p>Les velus nutons mesurent souvent de 10 à 13 cm, voire davantage. Puissants mais peu agiles, ils sont prisés comme gardes du corps.</p>",
|
||||||
|
"roleplayHints": ["Individu craint et sous-estimé", "Ogre poétique et nomade", "Inspirations barbares primitives"],
|
||||||
|
"profiles": { "artiste": 1, "athlete": 1, "chasseur": 3, "faiseur": 0, "forceNature": 5, "guerrier": 3, "mystique": 0, "ombre": 0, "savant": 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
[
|
||||||
|
{ "name": "Chevelure de sirène", "type": "sortilege", "img": "icons/svg/daze.svg", "system": { "description": "<p>Fouet scintillant qui gêne les adversaires touchés.</p>", "tradition": "magie", "skillKey": "magie", "polarity": "songes", "cost": 1, "costFormula": "", "variableCost": false, "preparation": "1 action libre", "duration": "1 combat", "range": "personnelle", "area": "-", "stacking": "non", "requiredDomains": [], "artsDomains": [], "effectsText": "<p>Confère la prime Facilité à chaque attaque ; n'inflige pas de dégâts mais applique Difficulté.</p>", "ruleTags": ["combat", "altération"] } },
|
||||||
|
{ "name": "Dôme scintillant", "type": "sortilege", "img": "icons/svg/daze.svg", "system": { "description": "<p>Dôme protecteur rendant les attaques à distance plus difficiles.</p>", "tradition": "magie", "skillKey": "magie", "polarity": "songes", "cost": 1, "costFormula": "", "variableCost": false, "preparation": "1 action gratuite", "duration": "1 combat", "range": "personnelle", "area": "10 cm", "stacking": "non", "requiredDomains": [], "artsDomains": [], "effectsText": "<p>Les attaques à distance visant l'intérieur subissent un malus de -3.</p>", "ruleTags": ["protection", "zone"] } },
|
||||||
|
{ "name": "Liens de Songes", "type": "sortilege", "img": "icons/svg/daze.svg", "system": { "description": "<p>Entrave lumineuse qui immobilise une cible.</p>", "tradition": "magie", "skillKey": "magie", "polarity": "songes", "cost": 2, "costFormula": "", "variableCost": false, "preparation": "1 action libre", "duration": "1 round", "range": "vue", "area": "cible", "stacking": "non", "requiredDomains": [], "artsDomains": [], "effectsText": "<p>La cible ne peut plus agir physiquement sauf test de Force / -6.</p>", "ruleTags": ["contrôle"] } },
|
||||||
|
{ "name": "Pluie d'étoiles", "type": "sortilege", "img": "icons/svg/daze.svg", "system": { "description": "<p>Nuée d'éclats infligeant des dégâts autour du mage.</p>", "tradition": "magie", "skillKey": "magie", "polarity": "songes", "cost": 1, "costFormula": "", "variableCost": false, "preparation": "1 action unique", "duration": "instantanée", "range": "personnelle", "area": "adversaires engagés", "stacking": "-", "requiredDomains": [], "artsDomains": [], "effectsText": "<p>Inflige 2 points de dégâts à tous les adversaires engagés, sans protection d'armure.</p>", "ruleTags": ["dégâts", "zone"] } },
|
||||||
|
{ "name": "Armure obscurine", "type": "sortilege", "img": "icons/svg/daze.svg", "system": { "description": "<p>L'ombre du mage absorbe les dégâts.</p>", "tradition": "magie", "skillKey": "magie", "polarity": "cauchemar", "cost": 1, "costFormula": "X", "variableCost": true, "preparation": "1 action unique", "duration": "1 combat", "range": "personnelle", "area": "-", "stacking": "oui", "requiredDomains": [], "artsDomains": [], "effectsText": "<p>Absorbe X points de dégâts jusqu'à dissipation de l'ombre.</p>", "ruleTags": ["protection", "cauchemar"] } },
|
||||||
|
{ "name": "Aspect cauchemardesque", "type": "sortilege", "img": "icons/svg/daze.svg", "system": { "description": "<p>Altère le visage pour intimider.</p>", "tradition": "magie", "skillKey": "magie", "polarity": "cauchemar", "cost": 1, "costFormula": "", "variableCost": false, "preparation": "1 action gratuite", "duration": "1 h", "range": "personnelle", "area": "-", "stacking": "non", "requiredDomains": [], "artsDomains": [], "effectsText": "<p>Octroie +3 aux tests de Commandement pour intimider.</p>", "ruleTags": ["social", "cauchemar"] } },
|
||||||
|
{ "name": "Hirond'ailes", "type": "sortilege", "img": "icons/svg/daze.svg", "system": { "description": "<p>Sortilège farfadet de vol personnel.</p>", "tradition": "farfadet", "skillKey": "magie", "polarity": "songes", "cost": 1, "costFormula": "", "variableCost": false, "preparation": "1 action unique", "duration": "utilisation", "range": "personnelle", "area": "-", "stacking": "non", "requiredDomains": [], "artsDomains": [], "effectsText": "<p>Fait apparaître des ailes permettant de voler avec un équipement léger.</p>", "ruleTags": ["déplacement", "farfadet"] } },
|
||||||
|
{ "name": "Seconde peau", "type": "sortilege", "img": "icons/svg/daze.svg", "system": { "description": "<p>Tatouage protecteur absorbant les blessures.</p>", "tradition": "farfadet", "skillKey": "magie", "polarity": "songes", "cost": 1, "costFormula": "X", "variableCost": true, "preparation": "1 action unique", "duration": "spéciale", "range": "toucher", "area": "1 être vivant", "stacking": "non", "requiredDomains": [], "artsDomains": [], "effectsText": "<p>Absorbe les 2X prochains dégâts jusqu'à disparition du tatouage.</p>", "ruleTags": ["protection", "farfadet"] } }
|
||||||
|
]
|
||||||
@@ -0,0 +1,309 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "Krograines",
|
||||||
|
"type": "tribu",
|
||||||
|
"img": "icons/svg/ruins.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Tribu lutine traditionaliste, gardienne de la mémoire d'Edenia.</p>",
|
||||||
|
"keywords": ["riche", "traditionaliste", "hautain", "méfiant", "conquérant", "expansionniste", "intolérant"],
|
||||||
|
"mainRace": "Lutin",
|
||||||
|
"spokenLanguage": "Vieux lutin",
|
||||||
|
"philosophy": "Gardiens de la mémoire d'Edenia",
|
||||||
|
"pride": "Pureté de la race lutine",
|
||||||
|
"mythNature": "faible",
|
||||||
|
"mythEdenia": "moyen",
|
||||||
|
"territory": "Cloître bénédictin et environs",
|
||||||
|
"specialRules": "",
|
||||||
|
"roleplayNotes": "<p>Les Krograines sont naturellement fermés à la discussion et convaincus d'appartenir à une tribu supérieure.</p>",
|
||||||
|
"restrictedJobs": [],
|
||||||
|
"allowedJobs": [],
|
||||||
|
"skillBonuses": [
|
||||||
|
{ "key": "commandement", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "erudition", "alternativeKeys": [], "base": 2, "domainsGranted": ["Catholicisme", "Histoire"], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "langues", "alternativeKeys": [], "base": 1, "domainsGranted": ["Vieux lutin"], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "melee", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "montures", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "volonte", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Karius",
|
||||||
|
"type": "tribu",
|
||||||
|
"img": "icons/svg/ruins.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Tribu repliée sur elle-même, méfiante et excellente chevaucheuse d'oiseaux.</p>",
|
||||||
|
"keywords": ["pauvre", "solitaire", "méfiant", "reclus", "prétentieux", "habile chevaucheur d'oiseaux"],
|
||||||
|
"mainRace": "Lutin",
|
||||||
|
"spokenLanguage": "Lutin",
|
||||||
|
"philosophy": "Crainte et suspicion envers l'étranger",
|
||||||
|
"pride": "Adresse des guerriers en vol et cité du Pic d'Azur",
|
||||||
|
"mythNature": "faible",
|
||||||
|
"mythEdenia": "inexistant",
|
||||||
|
"territory": "Clocher de la vieille église de la Trinité",
|
||||||
|
"specialRules": "<p>Chaque Karius est accompagné d'une fée rousse à laquelle il est émotionnellement lié.</p>",
|
||||||
|
"roleplayNotes": "<p>Un Karius jouable est nécessairement un banni, peu expansif et façonné par la peur du monde extérieur.</p>",
|
||||||
|
"restrictedJobs": [],
|
||||||
|
"allowedJobs": [],
|
||||||
|
"skillBonuses": [
|
||||||
|
{ "key": "athletisme", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "discretion", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "esquive", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "langues", "alternativeKeys": [], "base": 1, "domainsGranted": ["Lutin"], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "montures", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ventrus",
|
||||||
|
"type": "tribu",
|
||||||
|
"img": "icons/svg/ruins.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Nomades sauvages, fidèles à Dame Nature et aux voyages.</p>",
|
||||||
|
"keywords": ["pauvre", "violent", "méfiant", "bruyant", "bagarreur", "sauvage", "primitif", "voyageur", "solitaire"],
|
||||||
|
"mainRace": "Velu nuton",
|
||||||
|
"spokenLanguage": "Velu nuton",
|
||||||
|
"philosophy": "Rendre hommage à Dame Nature",
|
||||||
|
"pride": "Doux rêveurs et puissants guerriers",
|
||||||
|
"mythNature": "fort",
|
||||||
|
"mythEdenia": "faible",
|
||||||
|
"territory": "Nomades",
|
||||||
|
"specialRules": "",
|
||||||
|
"roleplayNotes": "<p>Les Ventrus ont grandi sur les routes et voient la Terra comme un monde rude mais familier.</p>",
|
||||||
|
"restrictedJobs": [],
|
||||||
|
"allowedJobs": [],
|
||||||
|
"skillBonuses": [
|
||||||
|
{ "key": "corpsacorps", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "endurance", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "force", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "langues", "alternativeKeys": [], "base": 1, "domainsGranted": ["Velu nuton"], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "montures", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "survie", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Sixts",
|
||||||
|
"type": "tribu",
|
||||||
|
"img": "icons/svg/ruins.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Noblesse kobolde morbide et pilleuse de tombes.</p>",
|
||||||
|
"keywords": ["mystérieux", "manipulateur", "déchu", "pilleur de tombes", "sombre", "morbide", "ennemi des Vivitins"],
|
||||||
|
"mainRace": "Kobold",
|
||||||
|
"spokenLanguage": "Kobold",
|
||||||
|
"philosophy": "Restaurer leur grandeur passée",
|
||||||
|
"pride": "Leur richesse",
|
||||||
|
"mythNature": "inexistant",
|
||||||
|
"mythEdenia": "moyen",
|
||||||
|
"territory": "Cimetières et charniers",
|
||||||
|
"specialRules": "",
|
||||||
|
"roleplayNotes": "<p>Les Sixts sont solitaires, peu loquaces et liés à la noblesse décadente de leur tribu.</p>",
|
||||||
|
"restrictedJobs": [],
|
||||||
|
"allowedJobs": [],
|
||||||
|
"skillBonuses": [
|
||||||
|
{ "key": "arts", "alternativeKeys": [], "base": 1, "domainsGranted": ["Conte"], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "chimerisme", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "discretion", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "erudition", "alternativeKeys": [], "base": 1, "domainsGranted": ["Légendes"], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "langues", "alternativeKeys": [], "base": 1, "domainsGranted": ["Kobold"], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "subterfuge", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Frinios",
|
||||||
|
"type": "tribu",
|
||||||
|
"img": "icons/svg/ruins.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Belgfolks inventifs, fascinés par les géants et les secrets.</p>",
|
||||||
|
"keywords": ["fasciné par les géants", "inventif", "curieux", "bourru", "observateur", "rigoureux", "habile", "tenace", "têtu", "matérialiste"],
|
||||||
|
"mainRace": "Belgfolk",
|
||||||
|
"spokenLanguage": "Belgfolk",
|
||||||
|
"philosophy": "Recherche et découverte de secrets",
|
||||||
|
"pride": "La Frivolution et les inventions",
|
||||||
|
"mythNature": "faible",
|
||||||
|
"mythEdenia": "faible",
|
||||||
|
"territory": "Chantier naval",
|
||||||
|
"specialRules": "",
|
||||||
|
"roleplayNotes": "<p>Les Frinios sont instruits, avides de connaissances et peu nombreux à quitter leur colonie pour devenir Oubliés.</p>",
|
||||||
|
"restrictedJobs": [],
|
||||||
|
"allowedJobs": [],
|
||||||
|
"skillBonuses": [
|
||||||
|
{ "key": "artisanat", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 2, "domainsChoiceText": "domaines d'Artisanat au choix" },
|
||||||
|
{ "key": "erudition", "alternativeKeys": [], "base": 1, "domainsGranted": ["Lettres"], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "intellect", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "langues", "alternativeKeys": [], "base": 2, "domainsGranted": ["Belgfolk"], "domainsToChoose": 1, "domainsChoiceText": "autre langue au choix" },
|
||||||
|
{ "key": "strategie", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "survie", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Pataches",
|
||||||
|
"type": "tribu",
|
||||||
|
"img": "icons/svg/ruins.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Gnomes nomades, chaleureux et dresseurs réputés.</p>",
|
||||||
|
"keywords": ["haine des géants", "nomade", "insouciant", "familial", "ouvert", "enjoué", "bonimenteur", "sensible", "dresseur réputé"],
|
||||||
|
"mainRace": "Gnome",
|
||||||
|
"spokenLanguage": "Gnome",
|
||||||
|
"philosophy": "Protéger sa famille et la quête d'Edenia",
|
||||||
|
"pride": "Leurs caravanes",
|
||||||
|
"mythNature": "fort",
|
||||||
|
"mythEdenia": "fort",
|
||||||
|
"territory": "Nomades",
|
||||||
|
"specialRules": "",
|
||||||
|
"roleplayNotes": "<p>Les Pataches font du rire et de la bonne humeur un rempart contre la dureté de l'Exil.</p>",
|
||||||
|
"restrictedJobs": [],
|
||||||
|
"allowedJobs": [],
|
||||||
|
"skillBonuses": [
|
||||||
|
{ "key": "artisanat", "alternativeKeys": [], "base": 1, "domainsGranted": ["Apothicaire"], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "erudition", "alternativeKeys": [], "base": 2, "domainsGranted": ["Faune", "Flore"], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "langues", "alternativeKeys": [], "base": 1, "domainsGranted": ["Gnome"], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "montures", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "survie", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "tir", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Banshises",
|
||||||
|
"type": "tribu",
|
||||||
|
"img": "icons/svg/ruins.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Gnomes teigneux et indépendants, très liés à leurs clans.</p>",
|
||||||
|
"keywords": ["individualiste", "indépendant", "insoumis", "bagarreur", "teigneux", "voleur", "guerrier dans l'âme"],
|
||||||
|
"mainRace": "Gnome",
|
||||||
|
"spokenLanguage": "Gnome",
|
||||||
|
"philosophy": "Préserver clan et famille",
|
||||||
|
"pride": "Leur indépendance",
|
||||||
|
"mythNature": "moyen",
|
||||||
|
"mythEdenia": "inexistant",
|
||||||
|
"territory": "Le Labrus",
|
||||||
|
"specialRules": "",
|
||||||
|
"roleplayNotes": "<p>Les Banshises sont élevés dans le conflit et le chapardage ; devenir Oublié est pour eux une rupture profonde.</p>",
|
||||||
|
"restrictedJobs": [],
|
||||||
|
"allowedJobs": [],
|
||||||
|
"skillBonuses": [
|
||||||
|
{ "key": "discretion", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "esquive", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "langues", "alternativeKeys": [], "base": 1, "domainsGranted": ["Gnome"], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "melee", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "subterfuge", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "survie", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Vivitins",
|
||||||
|
"type": "tribu",
|
||||||
|
"img": "icons/svg/ruins.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Kobolds navigateurs, fiers guerriers et ennemis des Sixts.</p>",
|
||||||
|
"keywords": ["navigateur", "ingénieux", "guerrier", "courageux", "sinistre", "aigri", "hait les Sixts"],
|
||||||
|
"mainRace": "Kobold",
|
||||||
|
"spokenLanguage": "Kobold",
|
||||||
|
"philosophy": "Accroître la puissance des Vivitins",
|
||||||
|
"pride": "Le nouveau destin de leur tribu",
|
||||||
|
"mythNature": "inexistant",
|
||||||
|
"mythEdenia": "inexistant",
|
||||||
|
"territory": "Marches brumeuses",
|
||||||
|
"specialRules": "",
|
||||||
|
"roleplayNotes": "<p>Les Vivitins veulent prouver leur valeur, portent une forte rancœur envers les Sixts et se vivent comme un peuple renaissant.</p>",
|
||||||
|
"restrictedJobs": [],
|
||||||
|
"allowedJobs": [],
|
||||||
|
"skillBonuses": [
|
||||||
|
{ "key": "artisanat", "alternativeKeys": [], "base": 2, "domainsGranted": ["Construction", "Navigation"], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "athletisme", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "langues", "alternativeKeys": [], "base": 1, "domainsGranted": ["Kobold"], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "sens", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "survie", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "volonte", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Margouts",
|
||||||
|
"type": "tribu",
|
||||||
|
"img": "icons/svg/ruins.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Tribu marchande, multiculturelle et cosmopolite.</p>",
|
||||||
|
"keywords": ["navigateur multiculturel", "baratineur", "marchand", "épicurien", "exubérant", "raffiné", "cupide", "riche", "tolérant"],
|
||||||
|
"mainRace": "Toutes",
|
||||||
|
"spokenLanguage": "Chimérique",
|
||||||
|
"philosophy": "Tout se revend avec bénéfice",
|
||||||
|
"pride": "Leur richesse",
|
||||||
|
"mythNature": "inexistant",
|
||||||
|
"mythEdenia": "inexistant",
|
||||||
|
"territory": "Place du marché",
|
||||||
|
"specialRules": "",
|
||||||
|
"roleplayNotes": "<p>Les Margouts vivent pour l'échange, l'apparat et l'avenir ; ils aiment la Terra bien plus que les vieux mythes.</p>",
|
||||||
|
"restrictedJobs": [],
|
||||||
|
"allowedJobs": [],
|
||||||
|
"skillBonuses": [
|
||||||
|
{ "key": "artisanat", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 1, "domainsChoiceText": "domaine d'Artisanat au choix" },
|
||||||
|
{ "key": "empathie", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "intellect", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "langues", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 1, "domainsChoiceText": "langue du Petit Peuple autre que celle de la race" },
|
||||||
|
{ "key": "seduction", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "subterfuge", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Siccomores",
|
||||||
|
"type": "tribu",
|
||||||
|
"img": "icons/svg/ruins.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Farfadets particulièrement doués en magie et fabricants d'objets enchantés.</p>",
|
||||||
|
"keywords": ["ancien conseiller", "doué en magie", "en voie de disparition", "sage", "introverti", "pessimiste", "hait le Cauchemar", "fabricant d'objets enchantés"],
|
||||||
|
"mainRace": "Farfadet",
|
||||||
|
"spokenLanguage": "Farfadet",
|
||||||
|
"philosophy": "Responsables de l'Exil du Petit Peuple",
|
||||||
|
"pride": "Leur influence",
|
||||||
|
"mythNature": "faible",
|
||||||
|
"mythEdenia": "fort",
|
||||||
|
"territory": "Ghetto juif",
|
||||||
|
"specialRules": "<p>Le seul métier possible à la création est mage des Songes.</p>",
|
||||||
|
"roleplayNotes": "<p>Les Siccomores sont austères, peu loquaces et vivent dans la conscience lourde de l'Exil.</p>",
|
||||||
|
"restrictedJobs": ["Rêvirine", "Chevalier errant", "Mercenaire", "Explorateur-marchand", "Cartographe", "Doux rêveur", "Trouvetout"],
|
||||||
|
"allowedJobs": ["Mage des Songes"],
|
||||||
|
"skillBonuses": [
|
||||||
|
{ "key": "erudition", "alternativeKeys": [], "base": 2, "domainsGranted": ["Judaïsme", "Lettres"], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "intellect", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "langues", "alternativeKeys": [], "base": 1, "domainsGranted": ["Farfadet"], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "magie", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "seduction", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "volonte", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Huvons",
|
||||||
|
"type": "tribu",
|
||||||
|
"img": "icons/svg/ruins.svg",
|
||||||
|
"system": {
|
||||||
|
"description": "<p>Korrigans violents, maîtres artisans et grands buveurs.</p>",
|
||||||
|
"keywords": ["mauvaise réputation", "guerrier", "violent", "maître artisan", "grand buveur", "grande gueule", "dur", "brutal", "vulgaire", "opportuniste"],
|
||||||
|
"mainRace": "Korrigan",
|
||||||
|
"spokenLanguage": "Korrigan",
|
||||||
|
"philosophy": "Être au cœur du combat comme de la vie",
|
||||||
|
"pride": "Leur vie dans les conflits du Petit Peuple",
|
||||||
|
"mythNature": "faible",
|
||||||
|
"mythEdenia": "inexistant",
|
||||||
|
"territory": "La forge",
|
||||||
|
"specialRules": "",
|
||||||
|
"roleplayNotes": "<p>Les Huvons valorisent la brutalité, les arènes et les compagnies de mercenaires plus que les Oubliés.</p>",
|
||||||
|
"restrictedJobs": [],
|
||||||
|
"allowedJobs": [],
|
||||||
|
"skillBonuses": [
|
||||||
|
{ "key": "commandement", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "corpsacorps", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "endurance", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "langues", "alternativeKeys": [], "base": 1, "domainsGranted": ["Korrigan"], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "melee", "alternativeKeys": [], "base": 2, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" },
|
||||||
|
{ "key": "strategie", "alternativeKeys": [], "base": 1, "domainsGranted": [], "domainsToChoose": 0, "domainsChoiceText": "" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
+124
@@ -0,0 +1,124 @@
|
|||||||
|
{
|
||||||
|
"id": "fvtt-les-oublies",
|
||||||
|
"title": "Les Oubliés",
|
||||||
|
"description": "Système FoundryVTT AppV2 pour le jeu de role Les Oubliés.",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Copilot",
|
||||||
|
"flags": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"compatibility": {
|
||||||
|
"minimum": "13",
|
||||||
|
"verified": "14"
|
||||||
|
},
|
||||||
|
"esmodules": [
|
||||||
|
"modules/les-oublies-main.js"
|
||||||
|
],
|
||||||
|
"styles": [
|
||||||
|
"css/les-oublies.css"
|
||||||
|
],
|
||||||
|
"languages": [
|
||||||
|
{
|
||||||
|
"lang": "fr",
|
||||||
|
"name": "Français",
|
||||||
|
"path": "lang/fr.json",
|
||||||
|
"flags": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"documentTypes": {
|
||||||
|
"Actor": {
|
||||||
|
"personnage": {
|
||||||
|
"htmlFields": [
|
||||||
|
"biodata.description",
|
||||||
|
"biodata.notes",
|
||||||
|
"biodata.gmnotes",
|
||||||
|
"visions"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"compagnie": {
|
||||||
|
"htmlFields": [
|
||||||
|
"description",
|
||||||
|
"notes",
|
||||||
|
"power.description"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"creature": {
|
||||||
|
"htmlFields": [
|
||||||
|
"biodata.description",
|
||||||
|
"biodata.habitat",
|
||||||
|
"biodata.notes",
|
||||||
|
"biodata.gmnotes",
|
||||||
|
"statblock.damage",
|
||||||
|
"statblock.special",
|
||||||
|
"statblock.spellSonges",
|
||||||
|
"statblock.spellCauchemar"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Item": {
|
||||||
|
"race": {
|
||||||
|
"htmlFields": [
|
||||||
|
"description",
|
||||||
|
"specialRules",
|
||||||
|
"notes"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"tribu": {
|
||||||
|
"htmlFields": [
|
||||||
|
"description",
|
||||||
|
"specialRules",
|
||||||
|
"notes"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"metier": {
|
||||||
|
"htmlFields": [
|
||||||
|
"description",
|
||||||
|
"specialRules",
|
||||||
|
"notes"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"competence": {
|
||||||
|
"htmlFields": [
|
||||||
|
"description",
|
||||||
|
"notes"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"sortilege": {
|
||||||
|
"htmlFields": [
|
||||||
|
"description",
|
||||||
|
"effectsText",
|
||||||
|
"notes"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"arme": {
|
||||||
|
"htmlFields": [
|
||||||
|
"description",
|
||||||
|
"notes"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"armure": {
|
||||||
|
"htmlFields": [
|
||||||
|
"description",
|
||||||
|
"notes"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"equipement": {
|
||||||
|
"htmlFields": [
|
||||||
|
"description",
|
||||||
|
"notes"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"pouvoircompagnie": {
|
||||||
|
"htmlFields": [
|
||||||
|
"description",
|
||||||
|
"ruleText",
|
||||||
|
"notes"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"primaryTokenAttribute": "system.hp.value",
|
||||||
|
"flags": {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
<section class="{{cssClass}} les-oublies-sheet compagnie-sheet" autocomplete="off">
|
||||||
|
<header class="sheet-header hero-banner">
|
||||||
|
<img class="profile-img" data-edit="img" data-action="editImage" src="{{actor.img}}" title="{{actor.name}}" />
|
||||||
|
<div class="header-fields hero-copy">
|
||||||
|
<p class="sheet-kicker">Blason de la compagnie</p>
|
||||||
|
<h1 class="sheet-title"><input name="name" type="text" value="{{actor.name}}" placeholder="Nom de compagnie" {{#if isPlayMode}}disabled{{/if}} /></h1>
|
||||||
|
<p class="sheet-subtitle">Capitaine, pouvoir partagé et liens forgés dans l'Exil</p>
|
||||||
|
<button class="mode-button" type="button" data-action="toggleSheet">{{#if isEditMode}}{{localize "LESOUBLIES.ui.playMode"}}{{else}}{{localize "LESOUBLIES.ui.editMode"}}{{/if}}</button>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section class="sheet-card summary-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.pouvoir"}}</h2>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.powerName"}}</label>
|
||||||
|
<input name="system.power.name" type="text" value="{{system.power.name}}" {{#if isPlayMode}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.reserveSongesCompagnie"}}</label>
|
||||||
|
<input name="system.power.sharedDreamPoints" type="number" value="{{system.power.sharedDreamPoints}}" {{#if isPlayMode}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.activation"}}</label>
|
||||||
|
<input name="system.power.activationCondition" type="text" value="{{system.power.activationCondition}}" {{#if isPlayMode}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.capitaineVisible"}}</label>
|
||||||
|
<input name="system.power.captainVisible" type="checkbox" {{checked system.power.captainVisible}} {{#if isPlayMode}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.capitaineTemoin"}}</label>
|
||||||
|
<input name="system.power.captainNeedsWitness" type="checkbox" {{checked system.power.captainNeedsWitness}} {{#if isPlayMode}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
{{editor system.power.description target="system.power.description" button=true editable=isEditMode}}
|
||||||
|
<div class="section-title-row">
|
||||||
|
<h3>Items de pouvoir</h3>
|
||||||
|
<button type="button" data-action="createItem" data-type="pouvoircompagnie">+ {{localize "TYPES.Item.pouvoircompagnie"}}</button>
|
||||||
|
</div>
|
||||||
|
<div class="item-list">
|
||||||
|
{{#each powers as |item|}}
|
||||||
|
<article class="item-card">
|
||||||
|
<div><strong>{{item.name}}</strong><div>{{item.system.activationCondition}}</div></div>
|
||||||
|
<div class="item-controls"><button type="button" data-action="editItem" data-item-id="{{item.id}}">Edit</button><button type="button" data-action="deleteItem" data-item-id="{{item.id}}">Delete</button></div>
|
||||||
|
</article>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
{{#if primaryPower}}
|
||||||
|
<div class="help-text">{{primaryPower.name}} — {{primaryPower.system.activationCondition}}</div>
|
||||||
|
{{/if}}
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="sheet-grid sheet-grid-2">
|
||||||
|
<section class="sheet-card ledger-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.ui.membres"}}</h2>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.capitaine"}}</label>
|
||||||
|
<input name="system.captainId" type="text" value="{{system.captainId}}" {{#if isPlayMode}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.ombreDuTourment"}}</label>
|
||||||
|
<input name="system.ombreDuTourmentId" type="text" value="{{system.ombreDuTourmentId}}" {{#if isPlayMode}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<p class="help-text">{{localize "LESOUBLIES.labels.membresIds"}}</p>
|
||||||
|
{{#if captain}}<p><strong>Capitaine :</strong> {{captain.name}}</p>{{/if}}
|
||||||
|
{{#if shadow}}<p><strong>Ombre :</strong> {{shadow.name}}</p>{{/if}}
|
||||||
|
<ul class="reference-list">
|
||||||
|
{{#each members as |member|}}
|
||||||
|
<li>{{member.name}}</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="sheet-card ledger-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.liensNarratifs"}}</h2>
|
||||||
|
<p class="help-text">{{localize "LESOUBLIES.ui.readOnlyCollection"}}</p>
|
||||||
|
<ul class="reference-list">
|
||||||
|
{{#each links as |link|}}
|
||||||
|
<li><strong>{{link.label}}</strong> — {{link.sourceLabel}} -> {{link.targetLabel}} {{link.details}}</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section class="sheet-card notes-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.description"}}</h2>
|
||||||
|
{{editor system.description target="system.description" button=true editable=isEditMode}}
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.notes"}}</h2>
|
||||||
|
{{editor system.notes target="system.notes" button=true editable=isEditMode}}
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
<section class="{{cssClass}} les-oublies-sheet creature-sheet" autocomplete="off">
|
||||||
|
<header class="sheet-header hero-banner">
|
||||||
|
<img class="profile-img" data-edit="img" data-action="editImage" src="{{actor.img}}" title="{{actor.name}}" />
|
||||||
|
<div class="header-fields hero-copy">
|
||||||
|
<p class="sheet-kicker">Bestiaire de la Terra</p>
|
||||||
|
<h1 class="sheet-title"><input name="name" type="text" value="{{actor.name}}" placeholder="Nom" {{#if isPlayMode}}disabled{{/if}} /></h1>
|
||||||
|
<p class="sheet-subtitle">Créatures du Petit Peuple, du Cauchemar et des frontières</p>
|
||||||
|
<div class="sheet-actions">
|
||||||
|
<button type="button" data-action="openRoll">{{localize "LESOUBLIES.rolls.test"}}</button>
|
||||||
|
<button type="button" data-action="openConfrontation">{{localize "LESOUBLIES.rolls.confrontation"}}</button>
|
||||||
|
<button type="button" data-action="openInitiative">{{localize "LESOUBLIES.rolls.initiative"}}</button>
|
||||||
|
<button type="button" data-action="openThreadHarvest">Récolte de fils</button>
|
||||||
|
<button class="mode-button" type="button" data-action="toggleSheet">{{#if isEditMode}}{{localize "LESOUBLIES.ui.playMode"}}{{else}}{{localize "LESOUBLIES.ui.editMode"}}{{/if}}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="sheet-grid sheet-grid-2">
|
||||||
|
<section class="sheet-card summary-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.ui.derivedOverview"}}</h2>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.categorie"}}</label><input name="system.biodata.categorie" type="text" value="{{system.biodata.categorie}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.taille"}}</label><input name="system.size.value" type="number" value="{{system.size.value}}" {{#if isPlayMode}}disabled{{/if}} /><span>{{derived.sizeLabel}}</span></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.ui.vie"}}</label><input name="system.hp.value" type="number" value="{{system.hp.value}}" {{#if isPlayMode}}disabled{{/if}} /><span>/ {{derived.hpMax}}</span></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.hpAffichage"}}</label><input name="system.hp.display" type="text" value="{{system.hp.display}}" {{#if isPlayMode}}disabled{{/if}} /><span>{{derived.hpDisplay}}</span></div>
|
||||||
|
<div class="field-row"><label>Protection</label><input name="system.protection" type="number" value="{{system.protection}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.ui.songes"}}</label><input name="system.songes.value" type="number" value="{{system.songes.value}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.pointsSonges"}}</label><input name="system.songes.points" type="number" value="{{system.songes.points}}" {{#if isPlayMode}}disabled{{/if}} /><span>/ {{system.songes.max}}</span></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.ui.cauchemar"}}</label><input name="system.cauchemar.value" type="number" value="{{system.cauchemar.value}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.pointsCauchemar"}}</label><input name="system.cauchemar.points" type="number" value="{{system.cauchemar.points}}" {{#if isPlayMode}}disabled{{/if}} /><span>/ {{system.cauchemar.max}}</span></div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="sheet-card profiles-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.profilsOptionnels"}}</h2>
|
||||||
|
<div class="profile-grid">
|
||||||
|
{{#each system.profils as |value key|}}
|
||||||
|
<div class="profile-cell">
|
||||||
|
<button type="button" data-action="rollProfile" data-profile-key="{{key}}">{{profileLabel key}}</button>
|
||||||
|
<input name="system.profils.{{key}}" type="number" value="{{value}}" {{#if @root.isPlayMode}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section class="sheet-card ledger-card">
|
||||||
|
<div class="section-title-row">
|
||||||
|
<h2>{{localize "LESOUBLIES.ui.competences"}}</h2>
|
||||||
|
<button type="button" data-action="createItem" data-type="competence">+ {{localize "TYPES.Item.competence"}}</button>
|
||||||
|
</div>
|
||||||
|
{{#each skillGroups as |group|}}
|
||||||
|
{{#if (count group.items)}}
|
||||||
|
<div class="group-block">
|
||||||
|
<h3>{{group.label}}</h3>
|
||||||
|
<div class="item-list">
|
||||||
|
{{#each group.items as |entry|}}
|
||||||
|
<article class="item-card">
|
||||||
|
<div><strong>{{entry.item.name}}</strong><div>{{localize "LESOUBLIES.labels.valeurFinale"}} {{entry.finalValue}}</div></div>
|
||||||
|
<div class="item-controls"><button type="button" data-action="rollSkill" data-item-id="{{entry.item.id}}">{{localize "LESOUBLIES.ui.roll"}}</button><button type="button" data-action="editItem" data-item-id="{{entry.item.id}}">Edit</button><button type="button" data-action="deleteItem" data-item-id="{{entry.item.id}}">Delete</button></div>
|
||||||
|
</article>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{/each}}
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="sheet-grid sheet-grid-2">
|
||||||
|
<section class="sheet-card ledger-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.degats"}}</h2>
|
||||||
|
{{editor system.statblock.damage target="system.statblock.damage" button=true editable=isEditMode}}
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.reglesSpeciales"}}</h2>
|
||||||
|
{{editor system.statblock.special target="system.statblock.special" button=true editable=isEditMode}}
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="sheet-card ledger-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.sortilegesSonges"}}</h2>
|
||||||
|
{{editor system.statblock.spellSonges target="system.statblock.spellSonges" button=true editable=isEditMode}}
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.sortilegesCauchemar"}}</h2>
|
||||||
|
{{editor system.statblock.spellCauchemar target="system.statblock.spellCauchemar" button=true editable=isEditMode}}
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section class="sheet-card ledger-card">
|
||||||
|
<div class="section-title-row">
|
||||||
|
<h2>{{localize "LESOUBLIES.ui.combat"}}</h2>
|
||||||
|
<div class="embed-buttons">
|
||||||
|
<button type="button" data-action="openCombatPreset" data-preset="encourager">Encourager</button>
|
||||||
|
<button type="button" data-action="openCombatPreset" data-preset="intimider">Intimider</button>
|
||||||
|
<button type="button" data-action="openCombatPreset" data-preset="evaluer">Évaluer</button>
|
||||||
|
<button type="button" data-action="openCombatPreset" data-preset="maitriser">Maîtriser</button>
|
||||||
|
<button type="button" data-action="openCombatPreset" data-preset="seDeplacer">Se déplacer</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="sheet-card ledger-card">
|
||||||
|
<div class="section-title-row">
|
||||||
|
<h2>{{localize "LESOUBLIES.ui.equipement"}}</h2>
|
||||||
|
<div class="embed-buttons">
|
||||||
|
<button type="button" data-action="createItem" data-type="arme">+ {{localize "TYPES.Item.arme"}}</button>
|
||||||
|
<button type="button" data-action="createItem" data-type="armure">+ {{localize "TYPES.Item.armure"}}</button>
|
||||||
|
<button type="button" data-action="createItem" data-type="equipement">+ {{localize "TYPES.Item.equipement"}}</button>
|
||||||
|
<button type="button" data-action="createItem" data-type="sortilege">+ {{localize "TYPES.Item.sortilege"}}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-list">
|
||||||
|
{{#each weapons as |item|}}
|
||||||
|
<article class="item-card">
|
||||||
|
<div><strong>{{item.name}}</strong><div>{{item.system.damage}}</div></div>
|
||||||
|
<div class="item-controls"><button type="button" data-action="useWeapon" data-item-id="{{item.id}}">Attaque</button><button type="button" data-action="resolveWeaponDamage" data-item-id="{{item.id}}">Dégâts</button><button type="button" data-action="editItem" data-item-id="{{item.id}}">Edit</button><button type="button" data-action="deleteItem" data-item-id="{{item.id}}">Delete</button></div>
|
||||||
|
</article>
|
||||||
|
{{/each}}
|
||||||
|
{{#each armors as |item|}}
|
||||||
|
<article class="item-card">
|
||||||
|
<div><strong>{{item.name}}</strong><div>Prot {{item.system.protection}}</div></div>
|
||||||
|
<div class="item-controls"><button type="button" data-action="editItem" data-item-id="{{item.id}}">Edit</button><button type="button" data-action="deleteItem" data-item-id="{{item.id}}">Delete</button></div>
|
||||||
|
</article>
|
||||||
|
{{/each}}
|
||||||
|
{{#each equipment as |item|}}
|
||||||
|
<article class="item-card">
|
||||||
|
<div><strong>{{item.name}}</strong><div>{{localize "TYPES.Item.equipement"}} - {{item.system.category}}</div></div>
|
||||||
|
<div class="item-controls"><button type="button" data-action="editItem" data-item-id="{{item.id}}">Edit</button><button type="button" data-action="deleteItem" data-item-id="{{item.id}}">Delete</button></div>
|
||||||
|
</article>
|
||||||
|
{{/each}}
|
||||||
|
{{#each spells as |item|}}
|
||||||
|
<article class="item-card">
|
||||||
|
<div><strong>{{item.name}}</strong><div>{{item.system.tradition}} / {{item.system.polarity}}</div></div>
|
||||||
|
<div class="item-controls"><button type="button" data-action="useSpell" data-item-id="{{item.id}}">Activer</button><button type="button" data-action="editItem" data-item-id="{{item.id}}">Edit</button><button type="button" data-action="deleteItem" data-item-id="{{item.id}}">Delete</button></div>
|
||||||
|
</article>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="sheet-card notes-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.description"}}</h2>
|
||||||
|
{{editor system.biodata.description target="system.biodata.description" button=true editable=isEditMode}}
|
||||||
|
<h2>Habitat</h2>
|
||||||
|
{{editor system.biodata.habitat target="system.biodata.habitat" button=true editable=isEditMode}}
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.notes"}}</h2>
|
||||||
|
{{editor system.biodata.notes target="system.biodata.notes" button=true editable=isEditMode}}
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.gmnotes"}}</h2>
|
||||||
|
{{editor system.biodata.gmnotes target="system.biodata.gmnotes" button=true editable=isEditMode owner=isGM}}
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
@@ -0,0 +1,228 @@
|
|||||||
|
<section class="{{cssClass}} les-oublies-sheet personnage-sheet" autocomplete="off">
|
||||||
|
<header class="sheet-header hero-banner">
|
||||||
|
<img class="profile-img" data-edit="img" data-action="editImage" src="{{actor.img}}" title="{{actor.name}}" />
|
||||||
|
<div class="header-fields hero-copy">
|
||||||
|
<p class="sheet-kicker">Chronique d'un Oublié</p>
|
||||||
|
<h1 class="sheet-title"><input name="name" type="text" value="{{actor.name}}" placeholder="Nom" {{#if isPlayMode}}disabled{{/if}} /></h1>
|
||||||
|
<p class="sheet-subtitle">Petit Peuple, Songes, Cauchemar et destin de compagnie</p>
|
||||||
|
<div class="sheet-actions">
|
||||||
|
<button type="button" data-action="openRoll">{{localize "LESOUBLIES.rolls.test"}}</button>
|
||||||
|
<button type="button" data-action="openConfrontation">{{localize "LESOUBLIES.rolls.confrontation"}}</button>
|
||||||
|
<button type="button" data-action="openInitiative">{{localize "LESOUBLIES.rolls.initiative"}}</button>
|
||||||
|
<button type="button" data-action="openThreadHarvest">Récolte de fils</button>
|
||||||
|
<button class="mode-button" type="button" data-action="toggleSheet">{{#if isEditMode}}{{localize "LESOUBLIES.ui.playMode"}}{{else}}{{localize "LESOUBLIES.ui.editMode"}}{{/if}}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="sheet-grid sheet-grid-2">
|
||||||
|
<section class="sheet-card summary-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.ui.derivedOverview"}}</h2>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.taille"}}</label>
|
||||||
|
<input name="system.size.value" type="number" value="{{system.size.value}}" {{#if isPlayMode}}disabled{{/if}} />
|
||||||
|
<span>{{derived.sizeLabel}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.ui.vie"}}</label>
|
||||||
|
<input name="system.hp.value" type="number" value="{{system.hp.value}}" {{#if isPlayMode}}disabled{{/if}} />
|
||||||
|
<span>/ {{derived.hpMax}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.ui.songes"}}</label>
|
||||||
|
<input name="system.songes.value" type="number" value="{{system.songes.value}}" {{#if isPlayMode}}disabled{{/if}} />
|
||||||
|
<span>{{system.songes.points}} / {{system.songes.max}} pts</span>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.detteSonges"}}</label>
|
||||||
|
<input name="system.songes.debt" type="number" value="{{system.songes.debt}}" {{#if isPlayMode}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.creditSonges"}}</label>
|
||||||
|
<input name="system.songes.xpCredit" type="number" value="{{system.songes.xpCredit}}" {{#if isPlayMode}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.ui.cauchemar"}}</label>
|
||||||
|
<input name="system.cauchemar.value" type="number" value="{{system.cauchemar.value}}" {{#if isPlayMode}}disabled{{/if}} />
|
||||||
|
<span>{{system.cauchemar.points}} / {{system.cauchemar.max}} pts</span>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.detteCauchemar"}}</label>
|
||||||
|
<input name="system.cauchemar.debt" type="number" value="{{system.cauchemar.debt}}" {{#if isPlayMode}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.creditCauchemar"}}</label>
|
||||||
|
<input name="system.cauchemar.xpCredit" type="number" value="{{system.cauchemar.xpCredit}}" {{#if isPlayMode}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.xp"}}</label>
|
||||||
|
<input name="system.experience.value" type="number" value="{{system.experience.value}}" {{#if isPlayMode}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.ecorces"}}</label>
|
||||||
|
<input name="system.money.ecorces" type="number" value="{{system.money.ecorces}}" {{#if isPlayMode}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.ombreDuTourment"}}</label>
|
||||||
|
<input name="system.flagsNarratifs.ombreDuTourment" type="checkbox" {{checked system.flagsNarratifs.ombreDuTourment}} {{#if isPlayMode}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="sheet-card creation-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.identite"}}</h2>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.age"}}</label>
|
||||||
|
<input name="system.biodata.age" type="number" value="{{system.biodata.age}}" {{#if isPlayMode}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.sexe"}}</label>
|
||||||
|
<input name="system.biodata.sexe" type="text" value="{{system.biodata.sexe}}" {{#if isPlayMode}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.motsCles"}}</label>
|
||||||
|
<input name="system.biodata.motscles" type="text" value="{{system.biodata.motscles}}" {{#if isPlayMode}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.capitaine"}}</label>
|
||||||
|
<input name="system.flagsNarratifs.isCaptain" type="checkbox" {{checked system.flagsNarratifs.isCaptain}} {{#if isPlayMode}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="sheet-card creation-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.ui.creation"}}</h2>
|
||||||
|
<ul class="reference-list">
|
||||||
|
<li><strong>{{localize "LESOUBLIES.labels.race"}} :</strong> {{#if creation.race}}{{creation.race.name}}{{else}}—{{/if}}</li>
|
||||||
|
<li><strong>{{localize "LESOUBLIES.labels.tribu"}} :</strong> {{#if creation.tribu}}{{creation.tribu.name}}{{else}}—{{/if}}</li>
|
||||||
|
<li><strong>{{localize "LESOUBLIES.labels.metier"}} :</strong> {{#if creation.metier}}{{creation.metier.name}}{{else}}—{{/if}}</li>
|
||||||
|
<li><strong>{{localize "LESOUBLIES.labels.compagnie"}} :</strong> {{#if derived.compagnie}}{{derived.compagnie.name}}{{else}}—{{/if}}</li>
|
||||||
|
</ul>
|
||||||
|
<div class="embed-buttons">
|
||||||
|
<button type="button" data-action="createItem" data-type="race">+ {{localize "TYPES.Item.race"}}</button>
|
||||||
|
<button type="button" data-action="createItem" data-type="tribu">+ {{localize "TYPES.Item.tribu"}}</button>
|
||||||
|
<button type="button" data-action="createItem" data-type="metier">+ {{localize "TYPES.Item.metier"}}</button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section class="sheet-card profiles-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.ui.profils"}}</h2>
|
||||||
|
<div class="profile-grid">
|
||||||
|
{{#each system.profils as |value key|}}
|
||||||
|
<div class="profile-cell">
|
||||||
|
<button type="button" data-action="rollProfile" data-profile-key="{{key}}">{{profileLabel key}}</button>
|
||||||
|
<input name="system.profils.{{key}}" type="number" value="{{value}}" {{#if @root.isPlayMode}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="sheet-card ledger-card">
|
||||||
|
<div class="section-title-row">
|
||||||
|
<h2>{{localize "LESOUBLIES.ui.competences"}}</h2>
|
||||||
|
<button type="button" data-action="createItem" data-type="competence">+ {{localize "TYPES.Item.competence"}}</button>
|
||||||
|
</div>
|
||||||
|
{{#each skillGroups as |group|}}
|
||||||
|
<div class="group-block">
|
||||||
|
<h3>{{group.label}}</h3>
|
||||||
|
<div class="item-list">
|
||||||
|
{{#each group.items as |entry|}}
|
||||||
|
<article class="item-card">
|
||||||
|
<div>
|
||||||
|
<strong>{{entry.item.name}}</strong>
|
||||||
|
<div>Base {{entry.item.system.base}} - {{localize "LESOUBLIES.labels.valeurFinale"}} {{entry.finalValue}}</div>
|
||||||
|
{{#if (count entry.item.system.domains)}}<div>{{localize "LESOUBLIES.labels.domaines}} : {{join entry.item.system.domains}}</div>{{/if}}
|
||||||
|
</div>
|
||||||
|
<div class="item-controls">
|
||||||
|
<button type="button" data-action="rollSkill" data-item-id="{{entry.item.id}}">{{localize "LESOUBLIES.ui.roll"}}</button>
|
||||||
|
<button type="button" data-action="editItem" data-item-id="{{entry.item.id}}">Edit</button>
|
||||||
|
<button type="button" data-action="deleteItem" data-item-id="{{entry.item.id}}">Delete</button>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="sheet-card ledger-card">
|
||||||
|
<div class="section-title-row">
|
||||||
|
<h2>{{localize "LESOUBLIES.ui.combat"}}</h2>
|
||||||
|
<div class="embed-buttons">
|
||||||
|
<button type="button" data-action="openCombatPreset" data-preset="encourager">Encourager</button>
|
||||||
|
<button type="button" data-action="openCombatPreset" data-preset="intimider">Intimider</button>
|
||||||
|
<button type="button" data-action="openCombatPreset" data-preset="evaluer">Évaluer</button>
|
||||||
|
<button type="button" data-action="openCombatPreset" data-preset="maitriser">Maîtriser</button>
|
||||||
|
<button type="button" data-action="openCombatPreset" data-preset="seDeplacer">Se déplacer</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="sheet-card ledger-card">
|
||||||
|
<div class="section-title-row">
|
||||||
|
<h2>{{localize "LESOUBLIES.ui.magie"}}</h2>
|
||||||
|
<button type="button" data-action="createItem" data-type="sortilege">+ {{localize "TYPES.Item.sortilege"}}</button>
|
||||||
|
</div>
|
||||||
|
<div class="item-list">
|
||||||
|
{{#each spells as |item|}}
|
||||||
|
<article class="item-card">
|
||||||
|
<div>
|
||||||
|
<strong>{{item.name}}</strong>
|
||||||
|
<div>{{item.system.tradition}} / {{item.system.polarity}} / coût {{item.system.cost}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-controls">
|
||||||
|
<button type="button" data-action="useSpell" data-item-id="{{item.id}}">Activer</button>
|
||||||
|
<button type="button" data-action="editItem" data-item-id="{{item.id}}">Edit</button>
|
||||||
|
<button type="button" data-action="deleteItem" data-item-id="{{item.id}}">Delete</button>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="sheet-card ledger-card">
|
||||||
|
<div class="section-title-row">
|
||||||
|
<h2>{{localize "LESOUBLIES.ui.equipement"}}</h2>
|
||||||
|
<div class="embed-buttons">
|
||||||
|
<button type="button" data-action="createItem" data-type="arme">+ {{localize "TYPES.Item.arme"}}</button>
|
||||||
|
<button type="button" data-action="createItem" data-type="armure">+ {{localize "TYPES.Item.armure"}}</button>
|
||||||
|
<button type="button" data-action="createItem" data-type="equipement">+ {{localize "TYPES.Item.equipement"}}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-list">
|
||||||
|
{{#each weapons as |item|}}
|
||||||
|
<article class="item-card">
|
||||||
|
<div><strong>{{item.name}}</strong><div>{{localize "TYPES.Item.arme"}} - {{item.system.damage}}</div></div>
|
||||||
|
<div class="item-controls"><button type="button" data-action="useWeapon" data-item-id="{{item.id}}">Attaque</button><button type="button" data-action="resolveWeaponDamage" data-item-id="{{item.id}}">Dégâts</button><button type="button" data-action="editItem" data-item-id="{{item.id}}">Edit</button><button type="button" data-action="deleteItem" data-item-id="{{item.id}}">Delete</button></div>
|
||||||
|
</article>
|
||||||
|
{{/each}}
|
||||||
|
{{#each armors as |item|}}
|
||||||
|
<article class="item-card">
|
||||||
|
<div><strong>{{item.name}}</strong><div>{{localize "TYPES.Item.armure"}} - Prot {{item.system.protection}}</div></div>
|
||||||
|
<div class="item-controls"><button type="button" data-action="editItem" data-item-id="{{item.id}}">Edit</button><button type="button" data-action="deleteItem" data-item-id="{{item.id}}">Delete</button></div>
|
||||||
|
</article>
|
||||||
|
{{/each}}
|
||||||
|
{{#each equipment as |item|}}
|
||||||
|
<article class="item-card">
|
||||||
|
<div><strong>{{item.name}}</strong><div>{{localize "TYPES.Item.equipement"}} - {{item.system.category}}</div></div>
|
||||||
|
<div class="item-controls"><button type="button" data-action="editItem" data-item-id="{{item.id}}">Edit</button><button type="button" data-action="deleteItem" data-item-id="{{item.id}}">Delete</button></div>
|
||||||
|
</article>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="sheet-card notes-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.ui.notes"}}</h2>
|
||||||
|
<label>{{localize "LESOUBLIES.labels.description"}}</label>
|
||||||
|
{{editor system.biodata.description target="system.biodata.description" button=true editable=isEditMode}}
|
||||||
|
<label>{{localize "LESOUBLIES.labels.notes"}}</label>
|
||||||
|
{{editor system.biodata.notes target="system.biodata.notes" button=true editable=isEditMode}}
|
||||||
|
<label>{{localize "LESOUBLIES.labels.gmnotes"}}</label>
|
||||||
|
{{editor system.biodata.gmnotes target="system.biodata.gmnotes" button=true editable=isEditMode owner=isGM}}
|
||||||
|
<label>{{localize "LESOUBLIES.labels.liensNarratifs"}}</label>
|
||||||
|
{{editor system.visions target="system.visions" button=true editable=isEditMode}}
|
||||||
|
{{#if activeCompanyPower}}
|
||||||
|
<label>{{localize "LESOUBLIES.labels.pouvoirCompagnieActif"}}</label>
|
||||||
|
<div class="help-text">{{activeCompanyPower.name}} — {{activeCompanyPower.system.activationCondition}}</div>
|
||||||
|
{{/if}}
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
<div class="les-oublies-chat-card {{#if result}}{{#if result.success}}is-success{{else}}is-failure{{/if}}{{/if}}">
|
||||||
|
<header class="chat-card-header">
|
||||||
|
<div class="chat-card-banner">
|
||||||
|
<img class="chat-card-portrait" src="{{actor.img}}" alt="{{actor.name}}" />
|
||||||
|
<div class="chat-card-heading">
|
||||||
|
<p class="chat-card-kicker">{{#if result}}Action{{else}}Résolution{{/if}}</p>
|
||||||
|
<h3>{{#if action}}{{action.title}}{{else}}{{result.label}}{{/if}}</h3>
|
||||||
|
<p class="chat-card-subtitle"><strong>{{actor.name}}</strong>{{#if action.subtitle}} · {{action.subtitle}}{{/if}}</p>
|
||||||
|
</div>
|
||||||
|
{{#if result}}
|
||||||
|
<div class="chat-card-badge {{#if result.success}}success{{else}}failure{{/if}}">{{result.successLabel}}</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section class="chat-card-body">
|
||||||
|
{{#if result}}
|
||||||
|
<div class="roll-summary-grid">
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.score"}}</span><strong>{{result.score}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.difficulty"}}</span><strong>{{numberFormat result.difficulty sign=true}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.natural"}}</span><strong>{{result.natural}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.final"}}</span><strong>{{result.final}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.threshold"}}</span><strong>{{result.threshold}}+</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.margin"}}</span><strong>{{numberFormat result.margin sign=true}}</strong></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="roll-formula"><strong>{{localize "LESOUBLIES.rolls.resolution"}}</strong> : {{result.natural}} + {{result.score}} {{numberFormat result.difficulty sign=true}}{{#if result.finalModifier}} {{numberFormat result.finalModifier sign=true}}{{/if}} = {{result.final}}</p>
|
||||||
|
|
||||||
|
<div class="dice-strip">
|
||||||
|
{{#each result.dice as |die|}}
|
||||||
|
<div class="die-chip {{#if (eq die.index @root.result.selectedDie.index)}}selected{{/if}}">
|
||||||
|
<strong>{{die.typeLabel}}</strong>
|
||||||
|
<span>{{die.breakdown}}</span>
|
||||||
|
{{#if die.exploded}}<em>{{localize "LESOUBLIES.rolls.exploded"}}</em>{{/if}}
|
||||||
|
{{#if die.sourceLabel}}<em>{{die.sourceLabel}}</em>{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if action.hint}}
|
||||||
|
<p class="roll-formula"><strong>Rappel</strong> : {{action.hint}}</p>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if action.modifiers.labels.length}}
|
||||||
|
<div class="chat-callouts">
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>Modificateurs</span>
|
||||||
|
<strong>{{join action.modifiers.labels}}</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if action.outcome}}
|
||||||
|
{{#if result}}
|
||||||
|
{{#if result.success}}
|
||||||
|
<div class="chat-callouts">
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>{{action.outcome.label}}</span>
|
||||||
|
<strong>{{action.outcome.description}}</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{else}}
|
||||||
|
<div class="chat-callouts">
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>{{action.outcome.label}}</span>
|
||||||
|
<strong>{{action.outcome.description}}</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if action.damage}}
|
||||||
|
<div class="chat-callouts">
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>Dégâts de base</span>
|
||||||
|
<strong>{{action.damage.baseLabel}}</strong>
|
||||||
|
</div>
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>Protection</span>
|
||||||
|
<strong>{{action.damage.effectiveProtection}}</strong>
|
||||||
|
<em>{{action.damage.targetLabel}}</em>
|
||||||
|
</div>
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>Dégâts finaux</span>
|
||||||
|
<strong>{{action.damage.finalDamage}}</strong>
|
||||||
|
{{#if action.damage.nonLethal}}<em>Non létal</em>{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if action.harvest}}
|
||||||
|
<div class="chat-callouts">
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>Récolte</span>
|
||||||
|
<strong>{{action.harvest.threadCount}} fil{{#unless (eq action.harvest.threadCount 1)}}s{{/unless}} de {{action.harvest.threadType}}</strong>
|
||||||
|
<em>{{action.harvest.sleeperLabel}}</em>
|
||||||
|
</div>
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>Dégâts subis</span>
|
||||||
|
<strong>{{action.harvest.damageTaken}}</strong>
|
||||||
|
</div>
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>Après le Néphertine</span>
|
||||||
|
<strong>{{action.harvest.durationHours}} h</strong>
|
||||||
|
<em>{{action.harvest.sideEffectText}}</em>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if action.notes}}
|
||||||
|
<p class="roll-formula"><strong>Notes</strong> : {{action.notes}}</p>
|
||||||
|
{{/if}}
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
<div class="les-oublies-chat-card confrontation-card">
|
||||||
|
<header class="chat-card-header">
|
||||||
|
<div class="chat-card-banner">
|
||||||
|
<img class="chat-card-portrait" src="{{actor.img}}" alt="{{actor.name}}" />
|
||||||
|
<div class="chat-card-heading">
|
||||||
|
<p class="chat-card-kicker">{{localize "LESOUBLIES.rolls.confrontation"}}</p>
|
||||||
|
<h3>{{attacker.label}} · {{defender.label}}</h3>
|
||||||
|
<p class="chat-card-subtitle">{{localize "LESOUBLIES.rolls.confrontationType"}} · {{confrontationType}}</p>
|
||||||
|
</div>
|
||||||
|
<div class="chat-card-badge neutral">{{outcomeLabel}}</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section class="chat-card-body confrontation-body">
|
||||||
|
{{#if action}}
|
||||||
|
<article class="chat-side-card">
|
||||||
|
<div class="chat-side-head">
|
||||||
|
<h2>{{action.title}}</h2>
|
||||||
|
{{#if action.subtitle}}<span class="chat-side-mode">{{action.subtitle}}</span>{{/if}}
|
||||||
|
</div>
|
||||||
|
{{#if action.hint}}<p class="roll-formula"><strong>Rappel</strong> : {{action.hint}}</p>{{/if}}
|
||||||
|
{{#if action.modifiers.labels.length}}
|
||||||
|
<div class="chat-callouts">
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>Modificateurs</span>
|
||||||
|
<strong>{{join action.modifiers.labels}}</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{#if action.outcome}}
|
||||||
|
{{#if action.outcome.success}}
|
||||||
|
<div class="chat-callouts">
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>{{action.outcome.label}}</span>
|
||||||
|
<strong>{{action.outcome.description}}</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
{{#if action.damage}}
|
||||||
|
<div class="chat-callouts">
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>Dégâts</span>
|
||||||
|
<strong>{{action.damage.finalDamage}}</strong>
|
||||||
|
{{#if action.damage.nonLethal}}<em>Non létal</em>{{/if}}
|
||||||
|
</div>
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>Protection</span>
|
||||||
|
<strong>{{action.damage.effectiveProtection}}</strong>
|
||||||
|
<em>{{action.damage.targetLabel}}</em>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{#if action.notes}}<p class="roll-formula"><strong>Notes</strong> : {{action.notes}}</p>{{/if}}
|
||||||
|
</article>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<article class="chat-side-card {{#if attacker.success}}is-success{{else}}is-failure{{/if}}">
|
||||||
|
<div class="chat-side-head">
|
||||||
|
<h2>{{attacker.label}}</h2>
|
||||||
|
<span class="chat-side-mode">{{attacker.rollModeLabel}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="roll-summary-grid">
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.score"}}</span><strong>{{attacker.score}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.difficulty"}}</span><strong>{{numberFormat attacker.difficulty sign=true}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.natural"}}</span><strong>{{attacker.natural}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.final"}}</span><strong>{{attacker.final}}</strong></div>
|
||||||
|
</div>
|
||||||
|
<p class="roll-formula"><strong>{{localize "LESOUBLIES.rolls.resolution"}}</strong> : {{attacker.natural}} + {{attacker.score}} {{numberFormat attacker.difficulty sign=true}}{{#if attacker.finalModifier}} {{numberFormat attacker.finalModifier sign=true}}{{/if}} = {{attacker.final}}</p>
|
||||||
|
<div class="dice-strip">
|
||||||
|
{{#each attacker.dice as |die|}}
|
||||||
|
<div class="die-chip {{#if (eq die.index @root.attacker.selectedDie.index)}}selected{{/if}}">
|
||||||
|
<strong>{{die.typeLabel}}</strong>
|
||||||
|
<span>{{die.breakdown}}</span>
|
||||||
|
{{#if die.exploded}}<em>{{localize "LESOUBLIES.rolls.exploded"}}</em>{{/if}}
|
||||||
|
{{#if die.sourceLabel}}<em>{{die.sourceLabel}}</em>{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
<div class="chat-callouts">
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>{{localize "LESOUBLIES.rolls.result"}}</span>
|
||||||
|
<strong>{{attacker.successLabel}}</strong>
|
||||||
|
<em>{{attacker.selectedSummary}}</em>
|
||||||
|
</div>
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>{{localize "LESOUBLIES.rolls.debt"}}</span>
|
||||||
|
<strong>{{attacker.debt.label}}</strong>
|
||||||
|
</div>
|
||||||
|
{{#if attacker.spentResource}}
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>{{localize "LESOUBLIES.rolls.extraDie"}}</span>
|
||||||
|
<strong>{{attacker.spentResource.label}}</strong>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{#if attacker.automaticFailure}}
|
||||||
|
<div class="chat-callout warning">
|
||||||
|
<span>{{localize "LESOUBLIES.rolls.result"}}</span>
|
||||||
|
<strong>{{localize "LESOUBLIES.rolls.naturalOne"}}</strong>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="chat-side-card {{#if defender.success}}is-success{{else}}is-failure{{/if}}">
|
||||||
|
<div class="chat-side-head">
|
||||||
|
<h2>{{defender.label}}</h2>
|
||||||
|
<span class="chat-side-mode">{{defender.rollModeLabel}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="roll-summary-grid">
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.score"}}</span><strong>{{defender.score}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.difficulty"}}</span><strong>{{numberFormat defender.difficulty sign=true}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.natural"}}</span><strong>{{defender.natural}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.final"}}</span><strong>{{defender.final}}</strong></div>
|
||||||
|
</div>
|
||||||
|
<p class="roll-formula"><strong>{{localize "LESOUBLIES.rolls.resolution"}}</strong> : {{defender.natural}} + {{defender.score}} {{numberFormat defender.difficulty sign=true}}{{#if defender.finalModifier}} {{numberFormat defender.finalModifier sign=true}}{{/if}} = {{defender.final}}</p>
|
||||||
|
<div class="dice-strip">
|
||||||
|
{{#each defender.dice as |die|}}
|
||||||
|
<div class="die-chip {{#if (eq die.index @root.defender.selectedDie.index)}}selected{{/if}}">
|
||||||
|
<strong>{{die.typeLabel}}</strong>
|
||||||
|
<span>{{die.breakdown}}</span>
|
||||||
|
{{#if die.exploded}}<em>{{localize "LESOUBLIES.rolls.exploded"}}</em>{{/if}}
|
||||||
|
{{#if die.sourceLabel}}<em>{{die.sourceLabel}}</em>{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
<div class="chat-callouts">
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>{{localize "LESOUBLIES.rolls.result"}}</span>
|
||||||
|
<strong>{{defender.successLabel}}</strong>
|
||||||
|
<em>{{defender.selectedSummary}}</em>
|
||||||
|
</div>
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>{{localize "LESOUBLIES.rolls.debt"}}</span>
|
||||||
|
<strong>{{defender.debt.label}}</strong>
|
||||||
|
</div>
|
||||||
|
{{#if defender.spentResource}}
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>{{localize "LESOUBLIES.rolls.extraDie"}}</span>
|
||||||
|
<strong>{{defender.spentResource.label}}</strong>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{#if defender.automaticFailure}}
|
||||||
|
<div class="chat-callout warning">
|
||||||
|
<span>{{localize "LESOUBLIES.rolls.result"}}</span>
|
||||||
|
<strong>{{localize "LESOUBLIES.rolls.naturalOne"}}</strong>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<div class="les-oublies-chat">
|
||||||
|
<h3>{{label}}</h3>
|
||||||
|
<p><strong>{{actor.name}}</strong> lance les dés de Songes et de Cauchemar.</p>
|
||||||
|
<p>Songes : <strong>{{songesDie}}</strong> | Cauchemar : <strong>{{cauchemarDie}}</strong></p>
|
||||||
|
<p>Cible : <strong>{{target}}</strong> | Résultat retenu : <strong>{{selected}}</strong></p>
|
||||||
|
<p>{{#if success}}Succès{{else}}Échec{{/if}}</p>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
<div class="les-oublies-chat-card is-initiative">
|
||||||
|
<header class="chat-card-header">
|
||||||
|
<div class="chat-card-banner">
|
||||||
|
<img class="chat-card-portrait" src="{{actor.img}}" alt="{{actor.name}}" />
|
||||||
|
<div class="chat-card-heading">
|
||||||
|
<p class="chat-card-kicker">{{localize "LESOUBLIES.rolls.test"}}</p>
|
||||||
|
<h3>{{localize "LESOUBLIES.rolls.initiative"}}</h3>
|
||||||
|
<p class="chat-card-subtitle"><strong>{{actor.name}}</strong> · {{result.rollModeLabel}}</p>
|
||||||
|
</div>
|
||||||
|
<div class="chat-card-badge neutral">{{result.initiativeScore}}</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section class="chat-card-body">
|
||||||
|
<div class="roll-summary-grid">
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.score"}}</span><strong>{{result.score}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.natural"}}</span><strong>{{result.natural}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.final"}}</span><strong>{{result.final}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.initiative"}}</span><strong>{{result.initiativeScore}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.threshold"}}</span><strong>{{result.threshold}}+</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.margin"}}</span><strong>{{numberFormat result.margin sign=true}}</strong></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="roll-formula"><strong>{{localize "LESOUBLIES.rolls.resolution"}}</strong> : {{result.natural}} + {{result.score}} = {{result.final}}, puis initiative = {{result.initiativeScore}}</p>
|
||||||
|
|
||||||
|
<div class="dice-strip">
|
||||||
|
{{#each result.dice as |die|}}
|
||||||
|
<div class="die-chip {{#if (eq die.index @root.result.selectedDie.index)}}selected{{/if}}">
|
||||||
|
<strong>{{die.typeLabel}}</strong>
|
||||||
|
<span>{{die.breakdown}}</span>
|
||||||
|
{{#if die.exploded}}<em>{{localize "LESOUBLIES.rolls.exploded"}}</em>{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="chat-callouts">
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>{{localize "LESOUBLIES.rolls.selectedDie"}}</span>
|
||||||
|
<strong>{{result.selectedSummary}}</strong>
|
||||||
|
<em>{{result.choiceLabel}}</em>
|
||||||
|
</div>
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>{{localize "LESOUBLIES.rolls.debt"}}</span>
|
||||||
|
<strong>{{result.debt.label}}</strong>
|
||||||
|
</div>
|
||||||
|
{{#if result.spentResource}}
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>{{localize "LESOUBLIES.rolls.extraDie"}}</span>
|
||||||
|
<strong>{{result.spentResource.label}}</strong>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
<div class="les-oublies-chat-card is-success">
|
||||||
|
<header class="chat-card-header">
|
||||||
|
<div class="chat-card-banner">
|
||||||
|
<img class="chat-card-portrait" src="{{actor.img}}" alt="{{actor.name}}" />
|
||||||
|
<div class="chat-card-heading">
|
||||||
|
<p class="chat-card-kicker">Sortilège</p>
|
||||||
|
<h3>{{spell.name}}</h3>
|
||||||
|
<p class="chat-card-subtitle"><strong>{{actor.name}}</strong> · {{spell.system.tradition}} / {{spell.system.polarity}}</p>
|
||||||
|
</div>
|
||||||
|
<div class="chat-card-badge success">Activation</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section class="chat-card-body">
|
||||||
|
<div class="roll-summary-grid">
|
||||||
|
<div><span>Compétence</span><strong>{{skillLabel spell.system.skillKey}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.labels.preparation"}}</span><strong>{{spell.system.preparation}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.labels.duree"}}</span><strong>{{spell.system.duration}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.labels.portee"}}</span><strong>{{spell.system.range}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.labels.aire"}}</span><strong>{{spell.system.area}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.labels.cumul"}}</span><strong>{{spell.system.stacking}}</strong></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="chat-callouts">
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>Ressource</span>
|
||||||
|
<strong>{{activation.costLabel}}</strong>
|
||||||
|
</div>
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>Métier</span>
|
||||||
|
<strong>{{#if activation.metierMatch}}Couvert{{else}}Hors métier{{/if}}</strong>
|
||||||
|
{{#if activation.surcharge}}<em>Surcoût appliqué</em>{{/if}}
|
||||||
|
</div>
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>Cible / scène</span>
|
||||||
|
<strong>{{activation.targetLabel}}</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#if activation.notes}}
|
||||||
|
<p class="roll-formula"><strong>Notes</strong> : {{activation.notes}}</p>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if spell.system.effectsText}}
|
||||||
|
<p class="roll-formula"><strong>Effets</strong> : {{{spell.system.effectsText}}}</p>
|
||||||
|
{{/if}}
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
<div class="les-oublies-chat-card {{#if result.success}}is-success{{else}}is-failure{{/if}}">
|
||||||
|
<header class="chat-card-header">
|
||||||
|
<div class="chat-card-banner">
|
||||||
|
<img class="chat-card-portrait" src="{{actor.img}}" alt="{{actor.name}}" />
|
||||||
|
<div class="chat-card-heading">
|
||||||
|
<p class="chat-card-kicker">{{localize "LESOUBLIES.rolls.test"}}</p>
|
||||||
|
<h3>{{result.label}}</h3>
|
||||||
|
<p class="chat-card-subtitle"><strong>{{actor.name}}</strong> · {{result.rollModeLabel}}</p>
|
||||||
|
</div>
|
||||||
|
<div class="chat-card-badge {{#if result.success}}success{{else}}failure{{/if}}">{{result.successLabel}}</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section class="chat-card-body">
|
||||||
|
<div class="roll-summary-grid">
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.score"}}</span><strong>{{result.score}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.difficulty"}}</span><strong>{{numberFormat result.difficulty sign=true}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.natural"}}</span><strong>{{result.natural}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.final"}}</span><strong>{{result.final}}</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.threshold"}}</span><strong>{{result.threshold}}+</strong></div>
|
||||||
|
<div><span>{{localize "LESOUBLIES.rolls.margin"}}</span><strong>{{numberFormat result.margin sign=true}}</strong></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="roll-formula"><strong>{{localize "LESOUBLIES.rolls.resolution"}}</strong> : {{result.natural}} + {{result.score}} {{numberFormat result.difficulty sign=true}} = {{result.final}}</p>
|
||||||
|
|
||||||
|
<div class="dice-strip">
|
||||||
|
{{#each result.dice as |die|}}
|
||||||
|
<div class="die-chip {{#if (eq die.index @root.result.selectedDie.index)}}selected{{/if}}">
|
||||||
|
<strong>{{die.typeLabel}}</strong>
|
||||||
|
<span>{{die.breakdown}}</span>
|
||||||
|
{{#if die.exploded}}<em>{{localize "LESOUBLIES.rolls.exploded"}}</em>{{/if}}
|
||||||
|
{{#if die.sourceLabel}}<em>{{die.sourceLabel}}</em>{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="chat-callouts">
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>{{localize "LESOUBLIES.rolls.selectedDie"}}</span>
|
||||||
|
<strong>{{result.selectedSummary}}</strong>
|
||||||
|
<em>{{result.choiceLabel}}</em>
|
||||||
|
</div>
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>{{localize "LESOUBLIES.rolls.debt"}}</span>
|
||||||
|
<strong>{{result.debt.label}}</strong>
|
||||||
|
</div>
|
||||||
|
{{#if result.spentResource}}
|
||||||
|
<div class="chat-callout">
|
||||||
|
<span>{{localize "LESOUBLIES.rolls.extraDie"}}</span>
|
||||||
|
<strong>{{result.spentResource.label}}</strong>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{#if result.automaticFailure}}
|
||||||
|
<div class="chat-callout warning">
|
||||||
|
<span>{{localize "LESOUBLIES.rolls.result"}}</span>
|
||||||
|
<strong>{{localize "LESOUBLIES.rolls.naturalOne"}}</strong>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<form class="les-oublies-roll-dialog">
|
||||||
|
<section class="sheet-card">
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Source</label>
|
||||||
|
<input type="text" value="{{#if weapon}}{{weapon.name}}{{else}}Dégâts{{/if}}" disabled />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Cible</label>
|
||||||
|
<input name="targetLabel" type="text" value="{{values.targetLabel}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Dégâts de base</label>
|
||||||
|
<input name="baseDamage" type="number" value="{{values.baseDamage}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Libellé dégâts</label>
|
||||||
|
<input name="baseDamageLabel" type="text" value="{{values.baseDamageLabel}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Protection</label>
|
||||||
|
<input name="targetProtection" type="number" value="{{values.targetProtection}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Prime</label>
|
||||||
|
<select name="primeId">
|
||||||
|
{{#each primeOptions as |option|}}
|
||||||
|
<option value="{{option.value}}" {{#if (eq option.value @root.values.primeId)}}selected{{/if}}>{{option.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Pénalité</label>
|
||||||
|
<select name="penaltyId">
|
||||||
|
{{#each penaltyOptions as |option|}}
|
||||||
|
<option value="{{option.value}}" {{#if (eq option.value @root.values.penaltyId)}}selected{{/if}}>{{option.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Appliquer à la cible</label>
|
||||||
|
<input name="applyToTarget" type="checkbox" {{checked values.applyToTarget}} {{#unless targetActor}}disabled{{/unless}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Notes</label>
|
||||||
|
<input name="notes" type="text" value="{{values.notes}}" />
|
||||||
|
</div>
|
||||||
|
<p class="help-text">Les dégâts standards ne se lancent pas aux dés : ils se résolvent à partir de l'arme, de la protection et des modificateurs choisis.</p>
|
||||||
|
</section>
|
||||||
|
</form>
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
<form class="les-oublies-roll-dialog">
|
||||||
|
<section class="sheet-card">
|
||||||
|
<h2>{{title}}</h2>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.rollMode"}}</label>
|
||||||
|
<select name="rollMode">
|
||||||
|
{{#each rollModes as |mode|}}
|
||||||
|
<option value="{{mode.value}}" {{#if (eq mode.value @root.values.rollMode)}}selected{{/if}}>{{mode.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.extraDie"}}</label>
|
||||||
|
<select name="extraDie">
|
||||||
|
{{#each extraDieModes as |mode|}}
|
||||||
|
<option value="{{mode.value}}" {{#if (eq mode.value @root.values.extraDie)}}selected{{/if}}>{{mode.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{{#if showMovementOptions}}
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Circonstance</label>
|
||||||
|
<select name="difficultyPreset">
|
||||||
|
<option value="0">Aucune (0)</option>
|
||||||
|
{{#each difficultyOptions as |entry|}}
|
||||||
|
<option value="{{entry.value}}">{{entry.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Destination</label>
|
||||||
|
<input name="targetLabel" type="text" value="{{values.targetLabel}}" />
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{#if showEncourageOptions}}
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Allié</label>
|
||||||
|
<input name="targetLabel" type="text" value="{{values.targetLabel}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Effet</label>
|
||||||
|
<select name="outcomeChoice">
|
||||||
|
<option value="initiative" {{#if (eq values.outcomeChoice "initiative")}}selected{{/if}}>+4 initiative</option>
|
||||||
|
<option value="action" {{#if (eq values.outcomeChoice "action")}}selected{{/if}}>+3 prochaine action</option>
|
||||||
|
<option value="reaction" {{#if (eq values.outcomeChoice "reaction")}}selected{{/if}}>+3 prochaine réaction</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Ajustement libre</label>
|
||||||
|
<input name="customDifficulty" type="number" value="{{values.customDifficulty}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Prime</label>
|
||||||
|
<select name="primeId">
|
||||||
|
{{#each primeOptions as |option|}}
|
||||||
|
<option value="{{option.value}}" {{#if (eq option.value @root.values.primeId)}}selected{{/if}}>{{option.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Pénalité</label>
|
||||||
|
<select name="penaltyId">
|
||||||
|
{{#each penaltyOptions as |option|}}
|
||||||
|
<option value="{{option.value}}" {{#if (eq option.value @root.values.penaltyId)}}selected{{/if}}>{{option.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Notes</label>
|
||||||
|
<input name="notes" type="text" value="{{values.notes}}" />
|
||||||
|
</div>
|
||||||
|
<p class="help-text">{{hint}}</p>
|
||||||
|
<p class="help-text">{{localize "LESOUBLIES.rolls.resourceState"}} : Songes {{resources.songesPoints}} / {{resources.songesValue}} · Cauchemar {{resources.cauchemarPoints}} / {{resources.cauchemarValue}}</p>
|
||||||
|
</section>
|
||||||
|
</form>
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
<form class="les-oublies-roll-dialog">
|
||||||
|
<div class="sheet-grid sheet-grid-2">
|
||||||
|
<section class="sheet-card">
|
||||||
|
<h2>{{attackTitle}}</h2>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Arme</label>
|
||||||
|
<input type="text" value="{{#if weapon}}{{weapon.name}}{{else}}Arme improvisée{{/if}}" disabled />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Compétence</label>
|
||||||
|
<select name="attackerSkill">
|
||||||
|
{{#each attackSkills as |skill|}}
|
||||||
|
<option value="{{skill.value}}" {{#if (eq skill.value @root.values.attackerSkill)}}selected{{/if}}>{{skill.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Circonstance</label>
|
||||||
|
<select name="difficultyPreset">
|
||||||
|
<option value="0">Aucune (0)</option>
|
||||||
|
{{#each difficultyOptions as |entry|}}
|
||||||
|
<option value="{{entry.value}}">{{entry.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Ajustement libre</label>
|
||||||
|
<input name="customDifficulty" type="number" value="{{values.customDifficulty}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.rollMode"}}</label>
|
||||||
|
<select name="attackerRollMode">
|
||||||
|
{{#each rollModes as |mode|}}
|
||||||
|
<option value="{{mode.value}}" {{#if (eq mode.value @root.values.attackerRollMode)}}selected{{/if}}>{{mode.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.extraDie"}}</label>
|
||||||
|
<select name="attackerExtraDie">
|
||||||
|
{{#each extraDieModes as |mode|}}
|
||||||
|
<option value="{{mode.value}}" {{#if (eq mode.value @root.values.attackerExtraDie)}}selected{{/if}}>{{mode.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Prime</label>
|
||||||
|
<select name="primeId">
|
||||||
|
{{#each primeOptions as |option|}}
|
||||||
|
<option value="{{option.value}}" {{#if (eq option.value @root.values.primeId)}}selected{{/if}}>{{option.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Pénalité</label>
|
||||||
|
<select name="penaltyId">
|
||||||
|
{{#each penaltyOptions as |option|}}
|
||||||
|
<option value="{{option.value}}" {{#if (eq option.value @root.values.penaltyId)}}selected{{/if}}>{{option.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<p class="help-text">{{localize "LESOUBLIES.rolls.resourceState"}} : Songes {{attackerResources.songesPoints}} / {{attackerResources.songesValue}} · Cauchemar {{attackerResources.cauchemarPoints}} / {{attackerResources.cauchemarValue}}</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="sheet-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.rolls.defender"}}</h2>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Cible</label>
|
||||||
|
<input name="defenderLabel" type="text" value="{{values.defenderLabel}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Réaction</label>
|
||||||
|
<select name="defenderSkill">
|
||||||
|
{{#each reactionSkills as |skill|}}
|
||||||
|
<option value="{{skill.value}}" {{#if (eq skill.value @root.values.defenderSkill)}}selected{{/if}}>{{skill.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Score défense</label>
|
||||||
|
<input name="defenderScore" type="number" value="{{values.defenderScore}}" {{#if targetActor}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Difficulté défense</label>
|
||||||
|
<input name="defenderDifficulty" type="number" value="{{values.defenderDifficulty}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.rollMode"}}</label>
|
||||||
|
<select name="defenderRollMode">
|
||||||
|
{{#each rollModes as |mode|}}
|
||||||
|
<option value="{{mode.value}}" {{#if (eq mode.value @root.values.defenderRollMode)}}selected{{/if}}>{{mode.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.extraDie"}}</label>
|
||||||
|
<select name="defenderExtraDie">
|
||||||
|
{{#each extraDieModes as |mode|}}
|
||||||
|
<option value="{{mode.value}}" {{#if (eq mode.value @root.values.defenderExtraDie)}}selected{{/if}}>{{mode.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Protection</label>
|
||||||
|
<input name="targetProtection" type="number" value="{{values.targetProtection}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Dégâts de base</label>
|
||||||
|
<input name="baseDamage" type="number" value="{{values.baseDamage}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Libellé dégâts</label>
|
||||||
|
<input name="baseDamageLabel" type="text" value="{{values.baseDamageLabel}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Appliquer à la cible</label>
|
||||||
|
<input name="applyToTarget" type="checkbox" {{checked values.applyToTarget}} {{#unless targetActor}}disabled{{/unless}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Notes</label>
|
||||||
|
<input name="notes" type="text" value="{{values.notes}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.ui.songes"}}</label>
|
||||||
|
<input name="defenderSongesValue" type="number" value="{{defenderResources.songesValue}}" {{#if targetActor}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.pointsSonges"}}</label>
|
||||||
|
<input name="defenderSongesPoints" type="number" value="{{defenderResources.songesPoints}}" {{#if targetActor}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.ui.cauchemar"}}</label>
|
||||||
|
<input name="defenderCauchemarValue" type="number" value="{{defenderResources.cauchemarValue}}" {{#if targetActor}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.pointsCauchemar"}}</label>
|
||||||
|
<input name="defenderCauchemarPoints" type="number" value="{{defenderResources.cauchemarPoints}}" {{#if targetActor}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<div class="les-oublies-roll-dialog">
|
||||||
|
<section class="sheet-card">
|
||||||
|
<h2>{{label}}</h2>
|
||||||
|
<p class="help-text">{{localize "LESOUBLIES.rolls.choiceHint"}}</p>
|
||||||
|
<div class="item-list">
|
||||||
|
{{#each dice as |die|}}
|
||||||
|
<article class="item-card">
|
||||||
|
<div>
|
||||||
|
<strong>{{die.typeLabel}}</strong>
|
||||||
|
<div>{{localize "LESOUBLIES.rolls.natural"}} : {{die.total}}</div>
|
||||||
|
<div>{{localize "LESOUBLIES.rolls.breakdown"}} : {{die.breakdown}}</div>
|
||||||
|
{{#if die.sourceLabel}}<div>{{die.sourceLabel}}</div>{{/if}}
|
||||||
|
<div>{{localize "LESOUBLIES.rolls.debt"}} : {{die.debtLabel}}</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
<form class="les-oublies-roll-dialog">
|
||||||
|
<div class="sheet-grid sheet-grid-2">
|
||||||
|
<section class="sheet-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.rolls.attacker"}}</h2>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.label"}}</label>
|
||||||
|
<input name="attackerLabel" type="text" value="{{actor.name}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.score"}}</label>
|
||||||
|
<input name="attackerScore" type="number" value="0" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.difficulty"}}</label>
|
||||||
|
<input name="attackerDifficulty" type="number" value="0" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.rollMode"}}</label>
|
||||||
|
<select name="attackerRollMode">
|
||||||
|
{{#each rollModes as |mode|}}
|
||||||
|
<option value="{{mode.value}}" {{#if (eq mode.value @root.defaultRollMode)}}selected{{/if}}>{{mode.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.extraDie"}}</label>
|
||||||
|
<select name="attackerExtraDie">
|
||||||
|
{{#each extraDieModes as |mode|}}
|
||||||
|
<option value="{{mode.value}}">{{mode.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<p class="help-text">{{localize "LESOUBLIES.rolls.resourceState"}} : Songes {{attackerResources.songesPoints}} / {{attackerResources.songesValue}} · Cauchemar {{attackerResources.cauchemarPoints}} / {{attackerResources.cauchemarValue}}</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="sheet-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.rolls.defender"}}</h2>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.label"}}</label>
|
||||||
|
<input name="defenderLabel" type="text" value="{{localize "LESOUBLIES.rolls.defender"}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.score"}}</label>
|
||||||
|
<input name="defenderScore" type="number" value="0" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.difficulty"}}</label>
|
||||||
|
<input name="defenderDifficulty" type="number" value="0" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.rollMode"}}</label>
|
||||||
|
<select name="defenderRollMode">
|
||||||
|
{{#each rollModes as |mode|}}
|
||||||
|
<option value="{{mode.value}}" {{#if (eq mode.value @root.defaultRollMode)}}selected{{/if}}>{{mode.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.extraDie"}}</label>
|
||||||
|
<select name="defenderExtraDie">
|
||||||
|
{{#each extraDieModes as |mode|}}
|
||||||
|
<option value="{{mode.value}}">{{mode.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.ui.songes"}}</label>
|
||||||
|
<input name="defenderSongesValue" type="number" value="{{defenderResources.songesValue}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.pointsSonges"}}</label>
|
||||||
|
<input name="defenderSongesPoints" type="number" value="{{defenderResources.songesPoints}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.ui.cauchemar"}}</label>
|
||||||
|
<input name="defenderCauchemarValue" type="number" value="{{defenderResources.cauchemarValue}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.pointsCauchemar"}}</label>
|
||||||
|
<input name="defenderCauchemarPoints" type="number" value="{{defenderResources.cauchemarPoints}}" />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section class="sheet-card">
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.confrontationType"}}</label>
|
||||||
|
<select name="confrontationType">
|
||||||
|
<option value="directe">{{localize "LESOUBLIES.rolls.confrontationTypes.directe"}}</option>
|
||||||
|
<option value="differee">{{localize "LESOUBLIES.rolls.confrontationTypes.differee"}}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<p class="help-text">{{localize "LESOUBLIES.rolls.confrontationHint"}}</p>
|
||||||
|
</section>
|
||||||
|
</form>
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
<form class="les-oublies-roll-dialog">
|
||||||
|
<div class="sheet-grid sheet-grid-2">
|
||||||
|
<section class="sheet-card">
|
||||||
|
<h2>{{title}}</h2>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Difficulté attaquant</label>
|
||||||
|
<input name="attackerDifficulty" type="number" value="{{values.attackerDifficulty}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.rollMode"}}</label>
|
||||||
|
<select name="attackerRollMode">
|
||||||
|
{{#each rollModes as |mode|}}
|
||||||
|
<option value="{{mode.value}}" {{#if (eq mode.value @root.values.attackerRollMode)}}selected{{/if}}>{{mode.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.extraDie"}}</label>
|
||||||
|
<select name="attackerExtraDie">
|
||||||
|
{{#each extraDieModes as |mode|}}
|
||||||
|
<option value="{{mode.value}}" {{#if (eq mode.value @root.values.attackerExtraDie)}}selected{{/if}}>{{mode.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Prime</label>
|
||||||
|
<select name="primeId">
|
||||||
|
{{#each primeOptions as |option|}}
|
||||||
|
<option value="{{option.value}}" {{#if (eq option.value @root.values.primeId)}}selected{{/if}}>{{option.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Pénalité</label>
|
||||||
|
<select name="penaltyId">
|
||||||
|
{{#each penaltyOptions as |option|}}
|
||||||
|
<option value="{{option.value}}" {{#if (eq option.value @root.values.penaltyId)}}selected{{/if}}>{{option.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{{#if showIntimidateOptions}}
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Effet</label>
|
||||||
|
<select name="outcomeChoice">
|
||||||
|
<option value="initiative">-4 initiative</option>
|
||||||
|
<option value="action">-3 prochaine action</option>
|
||||||
|
<option value="reaction">-3 prochaine réaction</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{#if showEvaluateOptions}}
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Paramètre visé</label>
|
||||||
|
<input name="targetLabel" type="text" value="{{values.targetLabel}}" />
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{#if showGrappleOptions}}
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Suite</label>
|
||||||
|
<select name="outcomeChoice">
|
||||||
|
<option value="silence">Réduire au silence</option>
|
||||||
|
<option value="otage">Prendre en otage</option>
|
||||||
|
<option value="conforter">Conforter sa prise</option>
|
||||||
|
<option value="etouffer">Étouffer</option>
|
||||||
|
<option value="attacher">Attacher</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Notes</label>
|
||||||
|
<input name="notes" type="text" value="{{values.notes}}" />
|
||||||
|
</div>
|
||||||
|
<p class="help-text">{{hint}}</p>
|
||||||
|
<p class="help-text">{{localize "LESOUBLIES.rolls.resourceState"}} : Songes {{attackerResources.songesPoints}} / {{attackerResources.songesValue}} · Cauchemar {{attackerResources.cauchemarPoints}} / {{attackerResources.cauchemarValue}}</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="sheet-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.rolls.defender"}}</h2>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Cible</label>
|
||||||
|
<input name="defenderLabel" type="text" value="{{values.defenderLabel}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Score défense</label>
|
||||||
|
<input name="defenderScore" type="number" value="{{values.defenderScore}}" {{#if targetActor}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Difficulté défense</label>
|
||||||
|
<input name="defenderDifficulty" type="number" value="{{values.defenderDifficulty}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.rollMode"}}</label>
|
||||||
|
<select name="defenderRollMode">
|
||||||
|
{{#each rollModes as |mode|}}
|
||||||
|
<option value="{{mode.value}}" {{#if (eq mode.value @root.values.defenderRollMode)}}selected{{/if}}>{{mode.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.extraDie"}}</label>
|
||||||
|
<select name="defenderExtraDie">
|
||||||
|
{{#each extraDieModes as |mode|}}
|
||||||
|
<option value="{{mode.value}}" {{#if (eq mode.value @root.values.defenderExtraDie)}}selected{{/if}}>{{mode.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.ui.songes"}}</label>
|
||||||
|
<input name="defenderSongesValue" type="number" value="{{defenderResources.songesValue}}" {{#if targetActor}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.pointsSonges"}}</label>
|
||||||
|
<input name="defenderSongesPoints" type="number" value="{{defenderResources.songesPoints}}" {{#if targetActor}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.ui.cauchemar"}}</label>
|
||||||
|
<input name="defenderCauchemarValue" type="number" value="{{defenderResources.cauchemarValue}}" {{#if targetActor}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.labels.pointsCauchemar"}}</label>
|
||||||
|
<input name="defenderCauchemarPoints" type="number" value="{{defenderResources.cauchemarPoints}}" {{#if targetActor}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<form class="les-oublies-roll-dialog">
|
||||||
|
<div class="sheet-card">
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.label"}}</label>
|
||||||
|
<input name="label" type="text" value="{{values.label}}" {{#if lockLabel}}disabled{{/if}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.score"}}</label>
|
||||||
|
<input name="score" type="number" value="{{values.score}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.difficulty"}}</label>
|
||||||
|
<input name="difficulty" type="number" value="{{values.difficulty}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.rollMode"}}</label>
|
||||||
|
<select name="rollMode">
|
||||||
|
{{#each rollModes as |mode|}}
|
||||||
|
<option value="{{mode.value}}" {{#if (eq mode.value @root.values.rollMode)}}selected{{/if}}>{{mode.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.extraDie"}}</label>
|
||||||
|
<select name="extraDie">
|
||||||
|
{{#each extraDieModes as |mode|}}
|
||||||
|
<option value="{{mode.value}}" {{#if (eq mode.value @root.values.extraDie)}}selected{{/if}}>{{mode.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<p class="help-text">{{localize "LESOUBLIES.rolls.resourceState"}} : Songes {{resources.songesPoints}} / {{resources.songesValue}} · Cauchemar {{resources.cauchemarPoints}} / {{resources.cauchemarValue}}</p>
|
||||||
|
{{#if isInitiative}}
|
||||||
|
<p class="help-text">{{localize "LESOUBLIES.rolls.initiativeHint"}}</p>
|
||||||
|
{{else}}
|
||||||
|
<p class="help-text">{{localize "LESOUBLIES.rolls.testHint"}}</p>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<form class="les-oublies-roll-dialog">
|
||||||
|
<div class="sheet-grid sheet-grid-2">
|
||||||
|
<section class="sheet-card">
|
||||||
|
<h2>{{spell.name}}</h2>
|
||||||
|
<div class="field-row"><label>Tradition</label><input type="text" value="{{spell.system.tradition}}" disabled /></div>
|
||||||
|
<div class="field-row"><label>Compétence</label><input type="text" value="{{skillLabel spell.system.skillKey}}" disabled /></div>
|
||||||
|
<div class="field-row"><label>Polarité</label><input type="text" value="{{spell.system.polarity}}" disabled /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.preparation"}}</label><input type="text" value="{{spell.system.preparation}}" disabled /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.duree"}}</label><input type="text" value="{{spell.system.duration}}" disabled /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.portee"}}</label><input type="text" value="{{spell.system.range}}" disabled /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.aire"}}</label><input type="text" value="{{spell.system.area}}" disabled /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.cumul"}}</label><input type="text" value="{{spell.system.stacking}}" disabled /></div>
|
||||||
|
<p class="help-text">{{#if isMetierMatch}}Le métier de l'acteur couvre ce sortilège.{{else}}Le métier ne couvre pas ce sortilège : le surcoût peut être appliqué ci-dessous.{{/if}}</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="sheet-card">
|
||||||
|
<h2>Activation</h2>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Coût réglé</label>
|
||||||
|
<input name="actualCost" type="number" value="{{values.actualCost}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Type de ressource</label>
|
||||||
|
<select name="paymentMode">
|
||||||
|
<option value="points" {{#if (eq values.paymentMode "points")}}selected{{/if}}>Points</option>
|
||||||
|
<option value="fils" {{#if (eq values.paymentMode "fils")}}selected{{/if}}>Fils</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Appliquer le surcoût</label>
|
||||||
|
<input name="applyMetierSurcharge" type="checkbox" {{checked values.applyMetierSurcharge}} />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Cible / scène</label>
|
||||||
|
<input name="targetLabel" type="text" value="{{values.targetLabel}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Notes</label>
|
||||||
|
<input name="notes" type="text" value="{{values.notes}}" />
|
||||||
|
</div>
|
||||||
|
<p class="help-text">{{localize "LESOUBLIES.rolls.resourceState"}} : Songes {{resources.songesPoints}} / {{resources.songesValue}} · Cauchemar {{resources.cauchemarPoints}} / {{resources.cauchemarValue}}</p>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
<form class="les-oublies-roll-dialog">
|
||||||
|
<section class="sheet-card">
|
||||||
|
<h2>Récolte de fils</h2>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Type de fil</label>
|
||||||
|
<select name="threadType">
|
||||||
|
<option value="songes" {{#if (eq values.threadType "songes")}}selected{{/if}}>Songes</option>
|
||||||
|
<option value="cauchemar" {{#if (eq values.threadType "cauchemar")}}selected{{/if}}>Cauchemar</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Nombre de fils</label>
|
||||||
|
<input name="threadCount" type="number" min="1" value="{{values.threadCount}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.rollMode"}}</label>
|
||||||
|
<select name="rollMode">
|
||||||
|
{{#each rollModes as |mode|}}
|
||||||
|
<option value="{{mode.value}}" {{#if (eq mode.value @root.values.rollMode)}}selected{{/if}}>{{mode.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>{{localize "LESOUBLIES.rolls.extraDie"}}</label>
|
||||||
|
<select name="extraDie">
|
||||||
|
{{#each extraDieModes as |mode|}}
|
||||||
|
<option value="{{mode.value}}" {{#if (eq mode.value @root.values.extraDie)}}selected{{/if}}>{{mode.label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Dormeur</label>
|
||||||
|
<input name="sleeperLabel" type="text" value="{{values.sleeperLabel}}" />
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<label>Notes</label>
|
||||||
|
<input name="notes" type="text" value="{{values.notes}}" />
|
||||||
|
</div>
|
||||||
|
<p class="help-text">Difficulté : -3 par fil supplémentaire. Dégâts subis : 1 par fil souhaité. En cas d'échec, plus aucune récolte possible sur ce dormeur cette nuit.</p>
|
||||||
|
<p class="help-text">{{localize "LESOUBLIES.rolls.resourceState"}} : Songes {{resources.songesPoints}} / {{resources.songesValue}} · Cauchemar {{resources.cauchemarPoints}} / {{resources.cauchemarValue}}</p>
|
||||||
|
</section>
|
||||||
|
</form>
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<section class="{{cssClass}} les-oublies-sheet item-sheet" autocomplete="off">
|
||||||
|
<header class="sheet-header hero-banner">
|
||||||
|
<img class="profile-img" data-edit="img" data-action="editImage" src="{{item.img}}" title="{{item.name}}" />
|
||||||
|
<div class="header-fields hero-copy">
|
||||||
|
<p class="sheet-kicker">Arsenal</p>
|
||||||
|
<h1 class="sheet-title"><input name="name" type="text" value="{{item.name}}" placeholder="Nom" {{#if isPlayMode}}disabled{{/if}} /></h1>
|
||||||
|
<button class="mode-button" type="button" data-action="toggleSheet">{{#if isEditMode}}{{localize "LESOUBLIES.ui.playMode"}}{{else}}{{localize "LESOUBLIES.ui.editMode"}}{{/if}}</button>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<section class="sheet-card summary-card">
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.categorie"}}</label><input name="system.category" type="text" value="{{system.category}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.origine"}}</label><input name="system.origin" type="text" value="{{system.origin}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>Dégâts</label><input name="system.damage" type="text" value="{{system.damage}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.portee"}}</label><input name="system.range" type="text" value="{{system.range}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.prix"}}</label><input name="system.price" type="number" value="{{system.price}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.quantite"}}</label><input name="system.quantity" type="number" value="{{system.quantity}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.equipe"}}</label><input name="system.equipped" type="checkbox" {{checked system.equipped}} {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<p><strong>Race restreinte :</strong> {{system.restrictedRace}}</p>
|
||||||
|
<p><strong>{{localize "LESOUBLIES.labels.proprietes}} :</strong> {{join system.properties}}</p>
|
||||||
|
</section>
|
||||||
|
<section class="sheet-card notes-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.description"}}</h2>
|
||||||
|
{{editor system.description target="system.description" button=true editable=isEditMode}}
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.notes"}}</h2>
|
||||||
|
{{editor system.notes target="system.notes" button=true editable=isEditMode}}
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
<section class="{{cssClass}} les-oublies-sheet item-sheet" autocomplete="off">
|
||||||
|
<header class="sheet-header hero-banner">
|
||||||
|
<img class="profile-img" data-edit="img" data-action="editImage" src="{{item.img}}" title="{{item.name}}" />
|
||||||
|
<div class="header-fields hero-copy">
|
||||||
|
<p class="sheet-kicker">Protection</p>
|
||||||
|
<h1 class="sheet-title"><input name="name" type="text" value="{{item.name}}" placeholder="Nom" {{#if isPlayMode}}disabled{{/if}} /></h1>
|
||||||
|
<button class="mode-button" type="button" data-action="toggleSheet">{{#if isEditMode}}{{localize "LESOUBLIES.ui.playMode"}}{{else}}{{localize "LESOUBLIES.ui.editMode"}}{{/if}}</button>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<section class="sheet-card summary-card">
|
||||||
|
<div class="field-row"><label>État</label><input name="system.state" type="text" value="{{system.state}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>Protection</label><input name="system.protection" type="number" value="{{system.protection}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>Malus physique</label><input name="system.physicalPenalty" type="number" value="{{system.physicalPenalty}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>Malus initiative</label><input name="system.initiativePenalty" type="number" value="{{system.initiativePenalty}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.prix"}}</label><input name="system.price" type="number" value="{{system.price}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.equipe"}}</label><input name="system.equipped" type="checkbox" {{checked system.equipped}} {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
</section>
|
||||||
|
<section class="sheet-card notes-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.description"}}</h2>
|
||||||
|
{{editor system.description target="system.description" button=true editable=isEditMode}}
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.notes"}}</h2>
|
||||||
|
{{editor system.notes target="system.notes" button=true editable=isEditMode}}
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<section class="{{cssClass}} les-oublies-sheet item-sheet" autocomplete="off">
|
||||||
|
<header class="sheet-header hero-banner">
|
||||||
|
<img class="profile-img" data-edit="img" data-action="editImage" src="{{item.img}}" title="{{item.name}}" />
|
||||||
|
<div class="header-fields hero-copy">
|
||||||
|
<p class="sheet-kicker">Savoir-faire</p>
|
||||||
|
<h1 class="sheet-title"><input name="name" type="text" value="{{item.name}}" placeholder="Nom" {{#if isPlayMode}}disabled{{/if}} /></h1>
|
||||||
|
<button class="mode-button" type="button" data-action="toggleSheet">{{#if isEditMode}}{{localize "LESOUBLIES.ui.playMode"}}{{else}}{{localize "LESOUBLIES.ui.editMode"}}{{/if}}</button>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<section class="sheet-card summary-card">
|
||||||
|
<div class="field-row"><label>Key</label><input name="system.key" type="text" value="{{system.key}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.profil"}}</label><input name="system.profileKey" type="text" value="{{system.profileKey}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.base"}}</label><input name="system.base" type="number" value="{{system.base}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>Fermée</label><input name="system.closed" type="checkbox" {{checked system.closed}} {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>À domaines</label><input name="system.domainSkill" type="checkbox" {{checked system.domainSkill}} {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<p><strong>{{localize "LESOUBLIES.labels.domaines}} :</strong> {{join system.domains}}</p>
|
||||||
|
<p><strong>Domaines fixes :</strong> {{join system.fixedDomains}}</p>
|
||||||
|
<p><strong>Exemples :</strong> {{join system.exampleDomains}}</p>
|
||||||
|
</section>
|
||||||
|
<section class="sheet-card notes-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.description"}}</h2>
|
||||||
|
{{editor system.description target="system.description" button=true editable=isEditMode}}
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.notes"}}</h2>
|
||||||
|
{{editor system.notes target="system.notes" button=true editable=isEditMode}}
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<section class="{{cssClass}} les-oublies-sheet item-sheet" autocomplete="off">
|
||||||
|
<header class="sheet-header hero-banner">
|
||||||
|
<img class="profile-img" data-edit="img" data-action="editImage" src="{{item.img}}" title="{{item.name}}" />
|
||||||
|
<div class="header-fields hero-copy">
|
||||||
|
<p class="sheet-kicker">Nécessaire de voyage</p>
|
||||||
|
<h1 class="sheet-title"><input name="name" type="text" value="{{item.name}}" placeholder="Nom" {{#if isPlayMode}}disabled{{/if}} /></h1>
|
||||||
|
<button class="mode-button" type="button" data-action="toggleSheet">{{#if isEditMode}}{{localize "LESOUBLIES.ui.playMode"}}{{else}}{{localize "LESOUBLIES.ui.editMode"}}{{/if}}</button>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<section class="sheet-card summary-card">
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.categorie"}}</label><input name="system.category" type="text" value="{{system.category}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.quantite"}}</label><input name="system.quantity" type="number" value="{{system.quantity}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.prix"}}</label><input name="system.price" type="number" value="{{system.price}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>Bonus</label><input name="system.bonus" type="text" value="{{system.bonus}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>Usage</label><input name="system.usage" type="text" value="{{system.usage}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>Durée de vie</label><input name="system.lifespan" type="text" value="{{system.lifespan}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.equipe"}}</label><input name="system.equipped" type="checkbox" {{checked system.equipped}} {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>Consumable</label><input name="system.consumable" type="checkbox" {{checked system.consumable}} {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
</section>
|
||||||
|
<section class="sheet-card notes-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.description"}}</h2>
|
||||||
|
{{editor system.description target="system.description" button=true editable=isEditMode}}
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.notes"}}</h2>
|
||||||
|
{{editor system.notes target="system.notes" button=true editable=isEditMode}}
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<section class="{{cssClass}} les-oublies-sheet item-sheet" autocomplete="off">
|
||||||
|
<header class="sheet-header hero-banner">
|
||||||
|
<img class="profile-img" data-edit="img" data-action="editImage" src="{{item.img}}" title="{{item.name}}" />
|
||||||
|
<div class="header-fields hero-copy">
|
||||||
|
<p class="sheet-kicker">Souffle collectif</p>
|
||||||
|
<h1 class="sheet-title"><input name="name" type="text" value="{{item.name}}" placeholder="Nom" {{#if isPlayMode}}disabled{{/if}} /></h1>
|
||||||
|
<button class="mode-button" type="button" data-action="toggleSheet">{{#if isEditMode}}{{localize "LESOUBLIES.ui.playMode"}}{{else}}{{localize "LESOUBLIES.ui.editMode"}}{{/if}}</button>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<section class="sheet-card summary-card">
|
||||||
|
<div class="field-row"><label>Scope</label><input name="system.scope" type="text" value="{{system.scope}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>Mode</label><input name="system.effectMode" type="text" value="{{system.effectMode}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>Usages</label><input name="system.limitedUses" type="text" value="{{system.limitedUses}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>Impact ressource</label><input name="system.resourceImpact" type="text" value="{{system.resourceImpact}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>Activation</label><input name="system.activationCondition" type="text" value="{{system.activationCondition}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>Vue du capitaine requise</label><input name="system.captainVisible" type="checkbox" {{checked system.captainVisible}} {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>Capitaine avec témoin</label><input name="system.captainNeedsWitness" type="checkbox" {{checked system.captainNeedsWitness}} {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
</section>
|
||||||
|
<section class="sheet-card notes-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.description"}}</h2>
|
||||||
|
{{editor system.description target="system.description" button=true editable=isEditMode}}
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.pouvoir"}}</h2>
|
||||||
|
{{editor system.ruleText target="system.ruleText" button=true editable=isEditMode}}
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.notes"}}</h2>
|
||||||
|
{{editor system.notes target="system.notes" button=true editable=isEditMode}}
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
<section class="{{cssClass}} les-oublies-sheet item-sheet" autocomplete="off">
|
||||||
|
<header class="sheet-header hero-banner">
|
||||||
|
<img class="profile-img" data-edit="img" data-action="editImage" src="{{item.img}}" title="{{item.name}}" />
|
||||||
|
<div class="header-fields hero-copy">
|
||||||
|
<p class="sheet-kicker">Référence de création</p>
|
||||||
|
<h1 class="sheet-title"><input name="name" type="text" value="{{item.name}}" placeholder="Nom" {{#if isPlayMode}}disabled{{/if}} /></h1>
|
||||||
|
<p class="sheet-subtitle">{{localize (concat "TYPES.Item." item.type)}}</p>
|
||||||
|
<button class="mode-button" type="button" data-action="toggleSheet">{{#if isEditMode}}{{localize "LESOUBLIES.ui.playMode"}}{{else}}{{localize "LESOUBLIES.ui.editMode"}}{{/if}}</button>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{{#if isRace}}
|
||||||
|
<section class="sheet-card summary-card">
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.taille"}}</label><input name="system.size" type="number" value="{{system.size}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.esperanceVie"}}</label><input name="system.lifeExpectancy" type="number" value="{{system.lifeExpectancy}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.langue"}}</label><input name="system.language" type="text" value="{{system.language}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<p><strong>{{localize "LESOUBLIES.labels.motsCles"}} :</strong> {{join system.keywords}}</p>
|
||||||
|
<p><strong>Domaines de langues :</strong> {{join system.languageDomains}}</p>
|
||||||
|
<h2>{{localize "LESOUBLIES.ui.profils"}}</h2>
|
||||||
|
<div class="profile-grid">
|
||||||
|
{{#each system.profiles as |value key|}}
|
||||||
|
<div class="profile-cell"><label>{{profileLabel key}}</label><input name="system.profiles.{{key}}" type="number" value="{{value}}" {{#if @root.isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
<p><strong>Tribus principales :</strong> {{join system.mainTribes}}</p>
|
||||||
|
</section>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if isTribu}}
|
||||||
|
<section class="sheet-card summary-card">
|
||||||
|
<p><strong>{{localize "LESOUBLIES.labels.motsCles"}} :</strong> {{join system.keywords}}</p>
|
||||||
|
<div class="field-row"><label>Race principale</label><input name="system.mainRace" type="text" value="{{system.mainRace}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.langue"}}</label><input name="system.spokenLanguage" type="text" value="{{system.spokenLanguage}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.territoire"}}</label><input name="system.territory" type="text" value="{{system.territory}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.philosophie"}}</label><input name="system.philosophy" type="text" value="{{system.philosophy}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.fierte"}}</label><input name="system.pride" type="text" value="{{system.pride}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.mytheNature"}}</label><input name="system.mythNature" type="text" value="{{system.mythNature}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.mytheEdenia"}}</label><input name="system.mythEdenia" type="text" value="{{system.mythEdenia}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<h2>Bonus de compétences</h2>
|
||||||
|
<ul class="reference-list">
|
||||||
|
{{#each system.skillBonuses as |bonus|}}
|
||||||
|
<li>{{formatSkillBonus bonus}}</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if isMetier}}
|
||||||
|
<section class="sheet-card summary-card">
|
||||||
|
<h2>Bonus de compétences</h2>
|
||||||
|
<ul class="reference-list">
|
||||||
|
{{#each system.skillBonuses as |bonus|}}
|
||||||
|
<li>{{formatSkillBonus bonus}}</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
<h2>Équipement de départ</h2>
|
||||||
|
<ul class="reference-list">
|
||||||
|
{{#each system.startingEquipment as |entry|}}
|
||||||
|
<li>{{formatEquipmentEntry entry}}</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
<h2>Sortilèges octroyés</h2>
|
||||||
|
<ul class="reference-list">
|
||||||
|
{{#each system.spellGrants as |grant|}}
|
||||||
|
<li>{{formatSpellGrant grant}}</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
<p><strong>Revenus :</strong> débutant {{formatPrice system.revenues.beginner}}, intermédiaire {{formatPrice system.revenues.intermediate}}, expert {{formatPrice system.revenues.expert}}</p>
|
||||||
|
</section>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<section class="sheet-card notes-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.description"}}</h2>
|
||||||
|
{{editor system.description target="system.description" button=true editable=isEditMode}}
|
||||||
|
{{#if isRace}}
|
||||||
|
<h2>Apparence et interprétation</h2>
|
||||||
|
{{editor system.appearance target="system.appearance" button=true editable=isEditMode}}
|
||||||
|
{{/if}}
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.reglesSpeciales"}}</h2>
|
||||||
|
{{#if isRace}}
|
||||||
|
{{editor system.specialRules target="system.specialRules" button=true editable=isEditMode}}
|
||||||
|
{{/if}}
|
||||||
|
{{#if isTribu}}
|
||||||
|
{{editor system.specialRules target="system.specialRules" button=true editable=isEditMode}}
|
||||||
|
<h2>Interprétation</h2>
|
||||||
|
{{editor system.roleplayNotes target="system.roleplayNotes" button=true editable=isEditMode}}
|
||||||
|
{{/if}}
|
||||||
|
{{#if isMetier}}
|
||||||
|
{{editor system.specialRules target="system.specialRules" button=true editable=isEditMode}}
|
||||||
|
<h2>Interprétation</h2>
|
||||||
|
{{editor system.roleplayNotes target="system.roleplayNotes" button=true editable=isEditMode}}
|
||||||
|
{{/if}}
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.notes"}}</h2>
|
||||||
|
{{editor system.notes target="system.notes" button=true editable=isEditMode}}
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<section class="{{cssClass}} les-oublies-sheet item-sheet" autocomplete="off">
|
||||||
|
<header class="sheet-header hero-banner">
|
||||||
|
<img class="profile-img" data-edit="img" data-action="editImage" src="{{item.img}}" title="{{item.name}}" />
|
||||||
|
<div class="header-fields hero-copy">
|
||||||
|
<p class="sheet-kicker">Art occulte</p>
|
||||||
|
<h1 class="sheet-title"><input name="name" type="text" value="{{item.name}}" placeholder="Nom" {{#if isPlayMode}}disabled{{/if}} /></h1>
|
||||||
|
<button class="mode-button" type="button" data-action="toggleSheet">{{#if isEditMode}}{{localize "LESOUBLIES.ui.playMode"}}{{else}}{{localize "LESOUBLIES.ui.editMode"}}{{/if}}</button>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<section class="sheet-card summary-card">
|
||||||
|
<div class="field-row"><label>Tradition</label><input name="system.tradition" type="text" value="{{system.tradition}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>Compétence</label><input name="system.skillKey" type="text" value="{{system.skillKey}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>Polarité</label><input name="system.polarity" type="text" value="{{system.polarity}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.cout"}}</label><input name="system.cost" type="number" value="{{system.cost}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.preparation"}}</label><input name="system.preparation" type="text" value="{{system.preparation}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.duree"}}</label><input name="system.duration" type="text" value="{{system.duration}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.portee"}}</label><input name="system.range" type="text" value="{{system.range}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.aire"}}</label><input name="system.area" type="text" value="{{system.area}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<div class="field-row"><label>{{localize "LESOUBLIES.labels.cumul"}}</label><input name="system.stacking" type="text" value="{{system.stacking}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||||
|
<p><strong>{{localize "LESOUBLIES.labels.domaines}} :</strong> {{join system.requiredDomains}}</p>
|
||||||
|
<p><strong>Arts requis :</strong> {{join system.artsDomains}}</p>
|
||||||
|
<p><strong>Tags :</strong> {{join system.ruleTags}}</p>
|
||||||
|
</section>
|
||||||
|
<section class="sheet-card notes-card">
|
||||||
|
<h2>{{localize "LESOUBLIES.labels.description"}}</h2>
|
||||||
|
{{editor system.description target="system.description" button=true editable=isEditMode}}
|
||||||
|
<h2>Effets</h2>
|
||||||
|
{{editor system.effectsText target="system.effectsText" button=true editable=isEditMode}}
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
Reference in New Issue
Block a user