updated the character form

This commit is contained in:
Lukas Forsberg 2025-11-30 22:32:40 +01:00
parent 3c10555577
commit 0339054f73
3 changed files with 219 additions and 77 deletions

View File

@ -16,8 +16,14 @@
characterData.Connections ??= []; characterData.Connections ??= [];
characterData.RangedWeapons ??= []; characterData.RangedWeapons ??= [];
characterData.MeleeWeapons ??= []; characterData.MeleeWeapons ??= [];
characterData.Armor ??= [];
characterData.Cyberware ??= []; characterData.Cyberware ??= [];
characterData.Bioware ??= []; characterData.Bioware ??= [];
characterData.PositiveQualities ??= [];
characterData.NegativeQualities ??= [];
characterData.PysicalCondition ??= Defaults.PysicalCondition
characterData.StunCondition ??= Defaults.StunCondition
characterData.Notes ??= ""
const characterInfoTypes = { const characterInfoTypes = {
Metatype: "text", Metatype: "text",
@ -60,10 +66,10 @@
let inventory = currentCharacter?.inventory || []; let inventory = currentCharacter?.inventory || [];
</script> </script>
<h1>Name: {currentCharacter.name}</h1> <h1>Name: {currentCharacter.name}</h1>
<h2>Character Info</h2> <h2>Character Info</h2>
<div class="info-container">
{#each Object.entries(characterData.Info) as [key, value], i} {#each Object.entries(characterData.Info) as [key, value], i}
<div class="input-row"> <div class="input-row">
<label for={"field-" + i}>{key}</label> <label for={"field-" + i}>{key}</label>
@ -71,11 +77,14 @@
id={"field-" + i} id={"field-" + i}
type={characterInfoTypes[key]} type={characterInfoTypes[key]}
bind:value={characterData.Info[key]} bind:value={characterData.Info[key]}
min={characterInfoTypes[key] === "number" ? 0 : null} /> min={characterInfoTypes[key] === "number" ? 0 : null}
max={characterInfoTypes[key] === "number" ? 100 : null} />
</div> </div>
{/each} {/each}
</div>
<h2>Attributes</h2> <h2>Attributes</h2>
<div class="info-container">
{#each Object.entries(characterData.Attributes) as [key, value], i} {#each Object.entries(characterData.Attributes) as [key, value], i}
<div class="input-row"> <div class="input-row">
<label for={"field-" + i}>{key}</label> <label for={"field-" + i}>{key}</label>
@ -83,11 +92,12 @@
id={"field-" + i} id={"field-" + i}
type="number" type="number"
bind:value={characterData["Attributes"][key]} bind:value={characterData["Attributes"][key]}
min=0 /> min=0
max=100 />
</div> </div>
{/each} {/each}
</div>
<div class="skill-form-container">
<h2>Skills</h2> <h2>Skills</h2>
<table> <table>
<thead> <thead>
@ -122,7 +132,6 @@
</table> </table>
<button on:click={() => add("Skills")}>+</button> <button on:click={() => add("Skills")}>+</button>
<h2>Contacts</h2> <h2>Contacts</h2>
<table> <table>
<thead> <thead>
@ -218,93 +227,203 @@
</table> </table>
<button on:click={() => add("MeleeWeapons")}>+</button> <button on:click={() => add("MeleeWeapons")}>+</button>
<h2>Cyberware</h2> <h2>Armor</h2>
<div class="skill-headers"> <table>
<span class="col-name">Cyberware</span> <thead>
<span class="col-value">Rating</span> <tr>
<span class="col-value">Essence</span> <th>Armor</th>
<span class="col-value">Notes</span> <th>Ballistic</th>
<span></span> <!-- for remove button --> <th>Impact</th>
</div> <th>Page</th>
{#each characterData.Cyberware as Cyberware, i} <th></th>
<div class="skill-entry"> <th></th>
<input class="col-name" placeholder="Cyberware" bind:value={characterData.Cyberware[i].Implant} /> </tr>
<input class="col-value" type="number" min="0" bind:value={characterData.Cyberware[i].Rating} /> </thead>
<input class="col-value" type="number" min="0" bind:value={characterData.Cyberware[i].Essence} /> <tbody>
<input class="col-value" placeholder="Notes" bind:value={characterData.Cyberware[i].Notes} /> {#each characterData.Armor as armor, i}
<button on:click={() => remove("Cyberware", i)}>X</button> <tr>
</div> <td><input placeholder="Armor" bind:value={characterData.Armor[i].Armor} /></td>
{/each} <td><input type="number" min=0 max=100 bind:value={characterData.Armor[i].Ballistic} /></td>
<button on:click={() => add("Cyberware")}>Add Cyberware</button> <td><input type="number" min=0 max=100 bind:value={characterData.Armor[i].Impact} /></td>
<td><input type="number" min=1 max=354 bind:value={characterData.Armor[i].Page} /></td>
<td><button on:click={() => viewPage(characterData.Armor[i].Page)}>View</button></td>
<td><button on:click={() => remove("Armor", i)}>X</button></td>
</tr>
{/each}
</tbody>
</table>
<button on:click={() => add("Armor")}>+</button>
<h2>Cyberware</h2>
<table>
<thead>
<tr>
<th>Cyberware</th>
<th>Rating</th>
<th>Essence</th>
<th>Notes</th>
<th>Page</th>
<th></th>
<th></th> <!-- for remove button -->
</tr>
</thead>
<tbody>
{#each characterData.Cyberware as Cyberware, i}
<tr>
<td><input placeholder="Cyberware" bind:value={characterData.Cyberware[i].Implant} /></td>
<td><input type="number" min=0 max=100 bind:value={characterData.Cyberware[i].Rating} /></td>
<td><input type="number" min=0 max=100 bind:value={characterData.Cyberware[i].Essence} /></td>
<td><input placeholder="Notes" bind:value={characterData.Cyberware[i].Notes} /></td>
<td><input type="number" min=1 max=354 bind:value={characterData.Connections[i].Page} /></td>
<td><button on:click={() => viewPage(characterData.Connections[i].Page)}>View</button></td>
<td><button on:click={() => remove("Cyberware", i)}>X</button></td>
</tr>
{/each}
</tbody>
</table>
<button on:click={() => add("Cyberware")}>+</button>
<h2>Bioware</h2> <h2>Bioware</h2>
<div class="skill-headers"> <table>
<span class="col-name">Bioware</span> <thead>
<span class="col-value">Rating</span> <tr>
<span class="col-value">Essence</span> <th>Bioware</th>
<span class="col-name">Notes</span> <th>Rating</th>
<span></span> <!-- for remove button --> <th>Essence</th>
</div> <th>Notes</th>
{#each characterData.Bioware as Bioware, i} <th>Page</th>
<div class="skill-entry"> <th></th>
<input class="col-name" placeholder="Bioware" bind:value={characterData.Bioware[i].Implant} /> <th></th> <!-- for remove button -->
<input class="col-value" type="number" min="0" bind:value={characterData.Bioware[i].Rating} /> </tr>
<input class="col-value" type="number" min="0" bind:value={characterData.Bioware[i].Essence} /> </thead>
<input class="col-name" placeholder="Notes" bind:value={characterData.Bioware[i].Notes} /> <tbody>
<button on:click={() => remove("Bioware", i)}>X</button> {#each characterData.Bioware as Bioware, i}
</div> <tr>
{/each} <td><input placeholder="Bioware" bind:value={characterData.Bioware[i].Implant} /></td>
<button on:click={() => add("Bioware")}>Add Bioware</button> <td><input type="number" min="0" bind:value={characterData.Bioware[i].Rating} /></td>
<td><input type="number" min="0" bind:value={characterData.Bioware[i].Essence} /></td>
<td><input placeholder="Notes" bind:value={characterData.Bioware[i].Notes} /></td>
<td><input type="number" min=1 max=354 bind:value={characterData.Connections[i].Page} /></td>
<td><button on:click={() => viewPage(characterData.Connections[i].Page)}>View</button></td>
<td><button on:click={() => remove("Bioware", i)}>X</button></td>
</tr>
{/each}
</tbody>
</table>
<button on:click={() => add("Bioware")}>+</button>
<h2>Qualities</h2>
<h3>Positive</h3>
<table>
<thead>
<tr>
<th>Quality</th>
<th>Page</th>
<th></th>
<th></th> <!-- for remove button -->
</tr>
</thead>
<tbody>
{#each characterData.PositiveQualities as qualitiy, i}
<tr>
<td><input placeholder="Qualitiy" bind:value={characterData.PositiveQualities[i].Qualitiy} /></td>
<td><input type="number" min=1 max=354 bind:value={characterData.PositiveQualities[i].Page} /></td>
<td><button on:click={() => viewPage(characterData.PositiveQualities[i].Page)}>View</button></td>
<td><button on:click={() => remove("PositiveQualities", i)}>X</button></td>
</tr>
{/each}
</tbody>
</table>
<button on:click={() => add("PositiveQualities")}>+</button>
<h3>Negative</h3>
<table>
<thead>
<tr>
<th>Quality</th>
<th>Page</th>
<th></th>
<th></th> <!-- for remove button -->
</tr>
</thead>
<tbody>
{#each characterData.NegativeQualities as qualitiy, i}
<tr>
<td><input placeholder="Qualitiy" bind:value={characterData.NegativeQualities[i].Qualitiy} /></td>
<td><input type="number" min=1 max=354 bind:value={characterData.NegativeQualities[i].Page} /></td>
<td><button on:click={() => viewPage(characterData.NegativeQualities[i].Page)}>View</button></td>
<td><button on:click={() => remove("NegativeQualities", i)}>X</button></td>
</tr>
{/each}
</tbody>
</table>
<button on:click={() => add("NegativeQualities")}>+</button>
<h2>Pysical Condition</h2>
<table>
<tbody>
{#each characterData.PysicalCondition as row, rowIndex}
<tr>
{#each row as cell, colIndex}
<td>
<input
type="checkbox"
bind:checked={characterData.PysicalCondition[rowIndex][colIndex]}
/>
</td>
{/each}
</tr>
{/each}
</tbody>
</table>
<h2>Stun Condition</h2>
<table>
<tbody>
{#each characterData.StunCondition as row, rowIndex}
<tr>
{#each row as cell, colIndex}
<td>
<input
type="checkbox"
bind:checked={characterData.StunCondition[rowIndex][colIndex]}
/>
</td>
{/each}
</tr>
{/each}
</tbody>
</table>
<h2>Notes</h2>
<div>
<textarea
id="notes"
bind:value={characterData.Notes}
rows="10"
cols="100"
placeholder="Write your character notes here..."
></textarea>
</div> </div>
<button on:click={saveCharacterData}>Save</button> <button on:click={saveCharacterData}>Save</button>
<style> <style>
.skill-form-container { .info-container {
width: 100%; /* 100% of the screen */ display: flex;
max-width: 1200px; /* optional, limits width on large screens */ flex-wrap: wrap; /* allows items to go to next line if needed */
} gap: 0.5em; /* space between each input-row */
}
.skill-headers, .skill-entry {
.input-row {
display: flex; display: flex;
gap: 0.3rem;
align-items: center; align-items: center;
flex-wrap: wrap; /* allow wrapping on small screens */ gap: 0.5em; /* space between label and input */
}
.skill-headers {
font-weight: bold;
margin-bottom: 0.3rem;
}
.skill-headers span {
padding: 0;
margin: 0;
}
.skill-headers span,
.skill-entry input,
.skill-entry select,
.skill-entry span {
box-sizing: border-box;
}
.col-name {
flex: 2;
min-width: 80px;
}
.col-value {
flex: 1;
min-width: 40px;
} }
th { th {
text-align: left; text-align: left;
} }
.col-remove {
flex: 0;
}
</style> </style>

View File

@ -65,6 +65,22 @@ const Implant = {
Notes: "", Notes: "",
} }
const Qualitiy = {
Qualitiy : ""
}
const PysicalCondition = Array.from({ length: 6 }, () =>
Array.from({ length: 3 }, () => false))
const StunCondition = Array.from({ length: 4 }, () =>
Array.from({ length: 3 }, () => false))
const Armor = {
Armor: "",
Ballistic: 0,
Impact: 0
}
export const Defaults = { export const Defaults = {
Info: Info, Info: Info,
Attributes: Attributes, Attributes: Attributes,
@ -74,6 +90,11 @@ export const Defaults = {
MeleeWeapons : MeleeWeapon, MeleeWeapons : MeleeWeapon,
Cyberware : Implant, Cyberware : Implant,
Bioware : Implant, Bioware : Implant,
PositiveQualities : Qualitiy,
NegativeQualities : Qualitiy,
PysicalCondition : PysicalCondition,
StunCondition : StunCondition,
Armor : Armor,
} }

View File

@ -21,6 +21,8 @@ namespace shadowrun {
MeleeWeapons = 6, MeleeWeapons = 6,
Cyberware = 7, Cyberware = 7,
Bioware = 8, Bioware = 8,
PositiveQualities = 9,
NegativeQualities = 10,
}; };
struct ShadowrunCharacter { struct ShadowrunCharacter {