|
|
| Zeile 1: |
Zeile 1: |
| <html> | | <!DOCTYPE html> |
| <style> | | <html lang="de"> |
| .creator-form { | | <head> |
| max-width: 800px;
| | <meta charset="UTF-8"> |
| margin: auto;
| | <title>Charakter Creator</title> |
| font-family: sans-serif; | | <style> |
| } | | label, select, input, button { |
| | display: block; |
| | margin: 5px 0; |
| | } |
| | </style> |
| | </head> |
| | <body> |
| | <h1>Charakter Creator</h1> |
|
| |
|
| .creator-form label { | | <label for="name">Name:</label> |
| font-weight: bold;
| | <input type="text" id="name"> |
| display: block;
| |
| margin-top: 10px;
| |
| } | |
|
| |
|
| .creator-form input, | | <label for="rasse">Rasse:</label> |
| .creator-form select {
| | <select id="rasse"> |
| width: 100%;
| | <option value="">Keine</option> |
| padding: 5px;
| | <option value="Mensch">Mensch</option> |
| margin-bottom: 10px;
| | <option value="Mutant">Mutant</option> |
| }
| | <option value="Android">Android</option> |
| | | <option value="Bestie">Bestie</option> |
| .creator-form button {
| | </select> |
| margin-top: 15px;
| |
| padding: 10px;
| |
| width: 100%;
| |
| }
| |
| | |
| .attribute-inputs {
| |
| display: grid;
| |
| grid-template-columns: 1fr 1fr;
| |
| gap: 10px;
| |
| }
| |
| | |
| .output {
| |
| margin-top: 20px;
| |
| padding: 10px;
| |
| background: #f8f8f8;
| |
| border: 1px solid #ccc;
| |
| white-space: pre-wrap;
| |
| }
| |
| | |
| .points-remaining {
| |
| font-weight: bold;
| |
| color: #b00;
| |
| margin-top: 10px;
| |
| }
| |
| </style> | |
| | |
| <div class="creator-form"> | |
| <h2>Charakter Creator</h2>
| |
| | |
| <label for="name">Name:</label>
| |
| <input type="text" id="name" placeholder="Name des Charakters">
| |
|
| |
|
| <label for="klasse">Klasse:</label> | | <label for="klasse">Klasse:</label> |
| Zeile 73: |
Zeile 46: |
| <label for="subklasse">Subklasse:</label> | | <label for="subklasse">Subklasse:</label> |
| <select id="subklasse"> | | <select id="subklasse"> |
| <option value="">Keine (+15 GP Ausgleich)</option> | | <option value="">Keine</option> |
| <option value="Auserwählter">Auserwählter</option> | | <option value="Auserwählter">Auserwählter</option> |
| <option value="Diener">Diener</option> | | <option value="Diener">Diener</option> |
| Zeile 94: |
Zeile 67: |
| </select> | | </select> |
|
| |
|
| <label for="rasse">Rasse:</label> | | <button onclick="zeigeCharakter()">Charakter anzeigen</button> |
| <select id="rasse">
| |
| <option value="">Keine</option>
| |
| <option value="Mensch">Mensch</option>
| |
| <option value="Elf">Elf</option>
| |
| </select>
| |
|
| |
|
| <label for="subspezies">Subspezies:</label> | | <pre id="ausgabe"></pre> |
| <select id="subspezies">
| |
| <option value="">Keine (+20 GP Ausgleich)</option>
| |
| <option value="Waldelf">Waldelf</option>
| |
| <option value="Stadelf">Stadelf</option>
| |
| </select>
| |
|
| |
|
| <label for="gegenstaende">Gegenstände wählen:</label> | | <script> |
| <select id="gegenstaende">
| | const attributeListe = [ |
| <option value="0">Keine</option>
| | "Agilität", "Ausdauer", "Charisma", "Geschick", |
| <option value="1">1 Gegenstand (-10 GP)</option>
| | "Intelligenz", "Konstitution", "Resistenz", |
| <option value="2">2 Gegenstände (-20 GP)</option>
| | "Stärke", "Wahrnehmung" |
| <option value="3">3 Gegenstände (-30 GP)</option>
| | ]; |
| </select>
| |
|
| |
|
| <div class="points-remaining" id="punkteInfo"></div>
| | const basisPunkte = 160; |
|
| |
|
| <label>Attribute:</label>
| | const klassenBoni = { |
| <div class="attribute-inputs" id="attributeInputs"></div>
| | "Arbeiter": {}, "Barde": {}, "Bote": {}, "Gelehrter": {}, "Gläubiger": {}, |
| | "Kind": {}, "Krieger": {}, "Schurke": {}, "Schütze": {}, "Seelenkünstler": {}, |
| | "Soldat": {}, "Techniker": {}, "Vagabunde": {} |
| | }; |
|
| |
|
| <button onclick="berechneCharakter()">Charakter berechnen</button>
| | const subklassenBoni = { |
| <button onclick="exportiereCharakter()">Exportieren</button>
| | "Auserwählter": {}, "Diener": {}, "Drogenjunkie": {}, "Dummkopf": {}, |
| | "Dunkler Künstler": {}, "Gesetzloser": {}, "Glücksspieler": {}, "Händler": {}, |
| | "Koch": {}, "Kopfgeldjäger": {}, "Ödländer": {}, "Okkultist": {}, |
| | "Pazifist": {}, "Politiker": {}, "Revolutionär": {}, "Seefahrer": {}, |
| | "Spion": {}, "Mutant": {} |
| | }; |
|
| |
|
| <div class="output" id="ausgabe"></div>
| | // Initialisiere alle Attribute mit 0 für jede Klasse und Subklasse |
| </div>
| | for (const klasse in klassenBoni) { |
| | attributeListe.forEach(attr => klassenBoni[klasse][attr] = 0); |
| | } |
|
| |
|
| <script>
| | for (const subklasse in subklassenBoni) { |
| const attributeListe = [
| | attributeListe.forEach(attr => subklassenBoni[subklasse][attr] = 0); |
| "Agilität", "Ausdauer", "Charisma", "Geschick", | | } |
| "Intelligenz", "Konstitution", "Resistenz",
| |
| "Stärke", "Wahrnehmung"
| |
| ];
| |
|
| |
|
| const basisPunkte = 160;
| | function zeigeCharakter() { |
| | const name = document.getElementById("name").value; |
| | const rasse = document.getElementById("rasse").value; |
| | const klasse = document.getElementById("klasse").value; |
| | const subklasse = document.getElementById("subklasse").value; |
|
| |
|
| const klassenBoni = Object.fromEntries([
| | const werte = {}; |
| "Arbeiter", "Barde", "Bote", "Gelehrter", "Gläubiger", "Kind", "Krieger", "Schurke",
| | attributeListe.forEach(attr => { |
| "Schütze", "Seelenkünstler", "Soldat", "Techniker", "Vagabunde"
| | werte[attr] = basisPunkte + |
| ].map(name => [name, Object.fromEntries(attributeListe.map(attr => [attr, 0]))]));
| | (klassenBoni[klasse]?.[attr] || 0) + |
| | (subklassenBoni[subklasse]?.[attr] || 0); |
| | }); |
|
| |
|
| const subklassenBoni = Object.fromEntries([
| | const ausgabe = { |
| "Auserwählter", "Diener", "Drogenjunkie", "Dummkopf", "Dunkler Künstler", "Gesetzloser",
| | Name: name, |
| "Glücksspieler", "Händler", "Koch", "Kopfgeldjäger", "Ödländer", "Okkultist",
| | Rasse: rasse, |
| "Pazifist", "Politiker", "Revolutionär", "Seefahrer", "Spion", "Mutant"
| | Klasse: klasse, |
| ].map(name => [name, Object.fromEntries(attributeListe.map(attr => [attr, 0]))]));
| | Subklasse: subklasse, |
| | Attribute: werte |
| | }; |
|
| |
|
| const rassenBoni = {
| | document.getElementById("ausgabe").textContent = JSON.stringify(ausgabe, null, 2); |
| "Mensch": { "Agilität": 0, "Ausdauer": 0, "Charisma": 1, "Geschick": 0, "Intelligenz": 0, "Konstitution": 0, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 },
| |
| "Elf": { "Agilität": 1, "Ausdauer": 0, "Charisma": 0, "Geschick": 1, "Intelligenz": 0, "Konstitution": 0, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 }
| |
| };
| |
| | |
| const subspeziesBoni = {
| |
| "Waldelf": { "Agilität": 0, "Ausdauer": 0, "Charisma": 0, "Geschick": 1, "Intelligenz": 0, "Konstitution": 0, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 1 },
| |
| "Stadelf": { "Agilität": 0, "Ausdauer": 0, "Charisma": 1, "Geschick": 0, "Intelligenz": 1, "Konstitution": 0, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 }
| |
| };
| |
| | |
| const attributeInputs = document.getElementById("attributeInputs");
| |
| attributeListe.forEach(attr => {
| |
| const input = document.createElement("input");
| |
| input.type = "number";
| |
| input.min = "0";
| |
| input.value = "0";
| |
| input.id = `attr_${attr}`;
| |
| input.oninput = updateRemainingPoints;
| |
| const label = document.createElement("label");
| |
| label.textContent = attr;
| |
| label.htmlFor = input.id;
| |
| attributeInputs.appendChild(label);
| |
| attributeInputs.appendChild(input);
| |
| });
| |
| | |
| function getBonus(boni, key) {
| |
| return boni[key] || Object.fromEntries(attributeListe.map(attr => [attr, 0]));
| |
| }
| |
| | |
| function sumUserInput() {
| |
| return attributeListe.reduce((sum, attr) => {
| |
| const val = parseInt(document.getElementById(`attr_${attr}`).value) || 0;
| |
| return sum + val;
| |
| }, 0);
| |
| }
| |
| | |
| function updateRemainingPoints() {
| |
| let total = basisPunkte;
| |
| if (!document.getElementById("subspezies").value) total += 20;
| |
| if (!document.getElementById("subklasse").value) total += 15;
| |
| | |
| const gegenstaende = parseInt(document.getElementById("gegenstaende").value) || 0;
| |
| total -= gegenstaende * 10;
| |
| | |
| const used = sumUserInput();
| |
| const remaining = total - used;
| |
| | |
| document.getElementById("punkteInfo").textContent = `Verbleibende Punkte: ${remaining} / ${total}`;
| |
| }
| |
| | |
| function berechneCharakter() {
| |
| const name = document.getElementById("name").value;
| |
| const klasse = document.getElementById("klasse").value;
| |
| const subklasse = document.getElementById("subklasse").value;
| |
| const rasse = document.getElementById("rasse").value;
| |
| const subspezies = document.getElementById("subspezies").value;
| |
| const gegenstaende = parseInt(document.getElementById("gegenstaende").value) || 0;
| |
| | |
| const basisAttribute = {};
| |
| attributeListe.forEach(attr => {
| |
| basisAttribute[attr] = parseInt(document.getElementById(`attr_${attr}`).value) || 0;
| |
| });
| |
| | |
| const gesamt = {};
| |
| attributeListe.forEach(attr => {
| |
| gesamt[attr] =
| |
| basisAttribute[attr] +
| |
| getBonus(klassenBoni, klasse)[attr] +
| |
| getBonus(subklassenBoni, subklasse)[attr] +
| |
| getBonus(rassenBoni, rasse)[attr] +
| |
| getBonus(subspeziesBoni, subspezies)[attr];
| |
| });
| |
| | |
| const daten = {
| |
| Name: name,
| |
| Klasse: klasse,
| |
| Subklasse: subklasse || "Keine (15 Punkte erhalten)",
| |
| Rasse: rasse,
| |
| Subspezies: subspezies || "Keine (20 Punkte erhalten)",
| |
| Gegenstände: `${gegenstaende} (${gegenstaende * 10} Punkte abgezogen)`,
| |
| Verwendete_Punkte: sumUserInput(),
| |
| Gesamt_Punkte: basisPunkte + (subklasse ? 0 : 15) + (subspezies ? 0 : 20) - (gegenstaende * 10),
| |
| Attribute: gesamt | |
| };
| |
| | |
| document.getElementById("ausgabe").textContent = JSON.stringify(daten, null, 2);
| |
| }
| |
| | |
| function exportiereCharakter() {
| |
| const daten = document.getElementById("ausgabe").textContent;
| |
| if (!daten) {
| |
| alert("Bitte zuerst berechnen!");
| |
| return;
| |
| } | | } |
| const blob = new Blob([daten], { type: "application/json" });
| | </script> |
| const url = URL.createObjectURL(blob);
| | </body> |
| const a = document.createElement("a");
| |
| a.href = url;
| |
| a.download = "charakter.json";
| |
| a.click();
| |
| URL.revokeObjectURL(url);
| |
| }
| |
| | |
| document.addEventListener("DOMContentLoaded", function () {
| |
| const inputs = document.querySelectorAll("select, input[type='number']");
| |
| inputs.forEach(el => {
| |
| el.addEventListener("input", updateRemainingPoints);
| |
| el.addEventListener("change", updateRemainingPoints);
| |
| });
| |
| updateRemainingPoints();
| |
| });
| |
| </script> | |
| </html> | | </html> |