CharakterCreator: Unterschied zwischen den Versionen

Aus Dunkelherzen Wiki
Keine Bearbeitungszusammenfassung
Keine Bearbeitungszusammenfassung
Markierung: Zurückgesetzt
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>
  }
    body {
      font-family: sans-serif;
      max-width: 800px;
      margin: auto;
      padding: 20px;
    }


  .creator-form label {
    label {
    font-weight: bold;
      font-weight: bold;
    display: block;
      display: block;
    margin-top: 10px;
      margin-top: 10px;
  }
    }


  .creator-form input,
    input, select {
  .creator-form select {
      width: 100%;
    width: 100%;
      padding: 5px;
    padding: 5px;
      margin-bottom: 10px;
    margin-bottom: 10px;
    }
  }


  .creator-form button {
    table {
    margin-top: 15px;
      width: 100%;
    padding: 10px;
      border-collapse: collapse;
    width: 100%;
      margin-top: 20px;
  }
    }


  .attribute-inputs {
    th, td {
    display: grid;
      border: 1px solid #ccc;
    grid-template-columns: 1fr 1fr;
      padding: 5px;
    gap: 10px;
      text-align: center;
  }
    }


  .output {
    .output {
    margin-top: 20px;
      margin-top: 20px;
    padding: 10px;
      white-space: pre-wrap;
    background: #f8f8f8;
      background: #f8f8f8;
    border: 1px solid #ccc;
      padding: 10px;
     white-space: pre-wrap;
      border: 1px solid #ccc;
  }
     }


  .points-remaining {
    .button {
    font-weight: bold;
      margin-top: 15px;
    color: #b00;
      padding: 10px;
    margin-top: 10px;
      width: 100%;
  }
    }
</style>
  </style>
</head>
<body>


<div class="creator-form">
   <h2>Charakter Creator</h2>
   <h2>Charakter Creator</h2>


Zeile 55: Zeile 60:
   <label for="klasse">Klasse:</label>
   <label for="klasse">Klasse:</label>
   <select id="klasse">
   <select id="klasse">
     <option value="">Keine</option>
     <option value="">Wähle...</option>
    <option value="Arbeiter">Arbeiter</option>
    <option value="Barde">Barde</option>
    <option value="Bote">Bote</option>
    <option value="Gelehrter">Gelehrter</option>
    <option value="Gläubiger">Gläubiger</option>
    <option value="Kind">Kind</option>
     <option value="Krieger">Krieger</option>
     <option value="Krieger">Krieger</option>
     <option value="Magier">Magier</option>
     <option value="Schurke">Schurke</option>
    <option value="Schütze">Schütze</option>
    <option value="Seelenkünstler">Seelenkünstler</option>
    <option value="Soldat">Soldat</option>
    <option value="Techniker">Techniker</option>
    <option value="Vagabunde">Vagabunde</option>
   </select>
   </select>


   <label for="subklasse">Subklasse:</label>
   <label for="subklasse">Subklasse:</label>
   <select id="subklasse">
   <select id="subklasse">
     <option value="">Keine (+20 GP ausgleich)</option>
     <option value="">Keine Subklasse</option>
     <option value="Berserker">Berserker</option>
     <option value="Auserwählter">Auserwählter</option>
     <option value="Hexenmeister">Hexenmeister</option>
     <option value="Diener">Diener</option>
    <option value="Drogenjunkie">Drogenjunkie</option>
    <option value="Dummkopf">Dummkopf</option>
    <option value="Dunkler Künstler">Dunkler Künstler</option>
    <option value="Gesetzloser">Gesetzloser</option>
    <option value="Glücksspieler">Glücksspieler</option>
    <option value="Händler">Händler</option>
    <option value="Koch">Koch</option>
    <option value="Kopfgeldjäger">Kopfgeldjäger</option>
    <option value="Ödländer">Ödländer</option>
    <option value="Okkultist">Okkultist</option>
    <option value="Pazifist">Pazifist</option>
    <option value="Politiker">Politiker</option>
    <option value="Revolutionär">Revolutionär</option>
    <option value="Seefahrer">Seefahrer</option>
    <option value="Spion">Spion</option>
    <option value="Mutant">Mutant</option>
   </select>
   </select>


   <label for="rasse">Rasse:</label>
   <label for="rasse">Rasse:</label>
   <select id="rasse">
   <select id="rasse">
     <option value="">Keine</option>
     <option value="">Wähle...</option>
     <option value="Mensch">Mensch</option>
     <option value="Mensch">Mensch</option>
     <option value="Elf">Elf</option>
     <option value="Elf">Elf</option>
   </select>
   </select>


   <label for="subspezies">Subspezies:</label>
   <label for="subrasse">Subrasse:</label>
   <select id="subspezies">
   <select id="subrasse">
     <option value="">Keine (+15 GP ausgleich)</option>
     <option value="">Keine Subrasse</option>
     <option value="Waldelf">Waldelf</option>
     <option value="Hochelf">Hochelf</option>
     <option value="Stadelf">Stadelf</option>
     <option value="Wüstenmensch">Wüstenmensch</option>
   </select>
   </select>


   <label for="gegenstaende">Gegenstände wählen:</label>
   <label for="items">Anzahl gewählter Gegenstände:</label>
   <select id="gegenstaende" onchange="updateRemainingPoints()">
   <select id="items">
     <option value="0">Keine</option>
     <option value="0">0 Gegenstände (+0 Punkte)</option>
     <option value="1">1 Gegenstand (-10 GP ausgleich)</option>
     <option value="1">1 Gegenstand (−10 Punkte)</option>
     <option value="2">2 Gegenstände (-20 GP ausgleich)</option>
     <option value="2">2 Gegenstände (−20 Punkte)</option>
     <option value="3">3 Gegenstände (-30 GP ausgleich)</option>
     <option value="3">3 Gegenstände (−30 Punkte)</option>
   </select>
   </select>


   <div class="points-remaining" id="punkteInfo"></div>
   <table>
    <thead>
      <tr>
        <th>Attribut</th>
        <th>Wert</th>
      </tr>
    </thead>
    <tbody id="attributeTabelle"></tbody>
  </table>


   <label>Attribute:</label>
   <p><strong>Verbleibende Punkte:</strong> <span id="remainingPoints">160</span></p>
  <div class="attribute-inputs" id="attributeInputs"></div>


   <button onclick="berechneCharakter()">Charakter berechnen</button>
   <button class="button" onclick="berechneWerte()">Charakterdaten anzeigen</button>
   <button onclick="exportiereCharakter()">Exportieren</button>
   <button class="button" onclick="exportiereDaten()">Charakterdaten exportieren</button>


   <div class="output" id="ausgabe"></div>
   <div class="output" id="ausgabe"></div>
</div>


<script>
  <script>
  const attributeListe = [
    const attributeListe = [
    "Agilität", "Ausdauer", "Charisma", "Geschick",
      "Agilität", "Ausdauer", "Charisma", "Geschick", "Intelligenz",
    "Intelligenz", "Konstitution", "Resistenz",
      "Konstitution", "Resistenz", "Stärke", "Wahrnehmung"
    "Stärke", "Wahrnehmung"
    ];
  ];


  const basisPunkte = 160;
    const MAX_PUNKTE = 160;


  const klassenBoni = {
    const basisBoni = () => {
    "Krieger": { "Agilität": 0, "Ausdauer": 1, "Charisma": 0, "Geschick": 0, "Intelligenz": 0, "Konstitution": 0, "Resistenz": 0, "Stärke": 2, "Wahrnehmung": 0 },
      const boni = {};
    "Magier":  { "Agilität": 0, "Ausdauer": 0, "Charisma": 0, "Geschick": 0, "Intelligenz": 2, "Konstitution": 0, "Resistenz": 1, "Stärke": 0, "Wahrnehmung": 0 }
      attributeListe.forEach(attr => boni[attr] = 0);
  };
      return boni;
    };


  const subklassenBoni = {
    // Alle Klassen/Subklassen/Rassen/Subrassen starten mit 0 für alle Attribute
    "Berserker":     { "Agilität": 1, "Ausdauer": 1, "Charisma": 0, "Geschick": 0, "Intelligenz": 0, "Konstitution": 0, "Resistenz": 0, "Stärke": 1, "Wahrnehmung": 0 },
    const klassenBoni = {
    "Hexenmeister":  { "Agilität": 0, "Ausdauer": 0, "Charisma": 2, "Geschick": 0, "Intelligenz": 1, "Konstitution": 0, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 }
      "Arbeiter": basisBoni(),
  };
      "Barde": basisBoni(),
      "Bote": basisBoni(),
      "Gelehrter": basisBoni(),
      "Gläubiger": basisBoni(),
      "Kind": basisBoni(),
      "Krieger": basisBoni(),
      "Schurke": basisBoni(),
      "Schütze": basisBoni(),
      "Seelenkünstler": basisBoni(),
      "Soldat": basisBoni(),
      "Techniker": basisBoni(),
      "Vagabunde": basisBoni()
    };


  const rassenBoni = {
    const subklassenBoni = {
    "Mensch": { "Agilität": 0, "Ausdauer": 0, "Charisma": 1, "Geschick": 0, "Intelligenz": 0, "Konstitution": 0, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 },
      "Auserwählter": basisBoni(),
    "Elf":   { "Agilität": 1, "Ausdauer": 0, "Charisma": 0, "Geschick": 1, "Intelligenz": 0, "Konstitution": 0, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 }
      "Diener": basisBoni(),
  };
      "Drogenjunkie": basisBoni(),
      "Dummkopf": basisBoni(),
      "Dunkler Künstler": basisBoni(),
      "Gesetzloser": basisBoni(),
      "Glücksspieler": basisBoni(),
      "Händler": basisBoni(),
      "Koch": basisBoni(),
      "Kopfgeldjäger": basisBoni(),
      "Ödländer": basisBoni(),
      "Okkultist": basisBoni(),
      "Pazifist": basisBoni(),
      "Politiker": basisBoni(),
      "Revolutionär": basisBoni(),
      "Seefahrer": basisBoni(),
      "Spion": basisBoni(),
      "Mutant": basisBoni()
    };


  const subspeziesBoni = {
    const rassenBoni = {
    "Waldelf":  { "Agilität": 0, "Ausdauer": 0, "Charisma": 0, "Geschick": 1, "Intelligenz": 0, "Konstitution": 0, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 1 },
      "Mensch": basisBoni(),
     "Stadelf":  { "Agilität": 0, "Ausdauer": 0, "Charisma": 1, "Geschick": 0, "Intelligenz": 1, "Konstitution": 0, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 }
      "Elf": basisBoni()
  };
     };


  const attributeInputs = document.getElementById("attributeInputs");
    const subrassenBoni = {
  attributeListe.forEach(attr => {
      "Hochelf": basisBoni(),
    const input = document.createElement("input");
      "Wüstenmensch": basisBoni()
    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) {
    function erstelleTabelle() {
    return boni[key] || attributeListe.reduce((acc, attr) => (acc[attr] = 0, acc), {});
      const tbody = document.getElementById("attributeTabelle");
  }
      tbody.innerHTML = "";
      attributeListe.forEach(attr => {
        const tr = document.createElement("tr");
        tr.innerHTML = `<td>${attr}</td>
                        <td><input type="number" id="attr_${attr}" value="0" min="0" onchange="updateRemainingPoints()"></td>`;
        tbody.appendChild(tr);
      });
    }


  function sumUserInput() {
    function getBoni() {
    return attributeListe.reduce((sum, attr) => {
      let bonus = {};
      const val = parseInt(document.getElementById(`attr_${attr}`).value) || 0;
      attributeListe.forEach(attr => bonus[attr] = 0);
      return sum + val;
    }, 0);
  }


  function updateRemainingPoints() {
      const klasse = document.getElementById("klasse").value;
    let total = basisPunkte;
      const subklasse = document.getElementById("subklasse").value;
    if (!document.getElementById("subspezies").value) total += 20;
      const rasse = document.getElementById("rasse").value;
    if (!document.getElementById("subklasse").value) total += 15;
      const subrasse = document.getElementById("subrasse").value;


    const gegenstaende = parseInt(document.getElementById("gegenstaende").value) || 0;
      [klassenBoni[klasse], subklassenBoni[subklasse], rassenBoni[rasse], subrassenBoni[subrasse]].forEach(obj => {
     total -= gegenstaende * 10;
        if (obj) {
          for (let key in obj) {
            bonus[key] += obj[key] || 0;
          }
        }
      });
 
      return bonus;
     }


     const used = sumUserInput();
     function berechnePunkteBonus() {
    const remaining = total - used;
      let bonus = 0;
      if (!document.getElementById("subklasse").value) bonus += 15;
      if (!document.getElementById("subrasse").value) bonus += 20;


    document.getElementById("punkteInfo").textContent = `Verbleibende Punkte: ${remaining} / ${total}`;
      const gegenstände = parseInt(document.getElementById("items").value);
  }
      bonus -= (gegenstände * 10);


  function berechneCharakter() {
      return bonus;
    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 = {};
     function updateRemainingPoints() {
    attributeListe.forEach(attr => {
      let summe = 0;
      basisAttribute[attr] = parseInt(document.getElementById(`attr_${attr}`).value) || 0;
      attributeListe.forEach(attr => {
    });
        summe += parseInt(document.getElementById("attr_" + attr).value) || 0;
      });


    const gesamt = {};
      const verbleibend = MAX_PUNKTE + berechnePunkteBonus() - summe;
    attributeListe.forEach(attr => {
      document.getElementById("remainingPoints").textContent = verbleibend;
      gesamt[attr] =
     }
        basisAttribute[attr] +
        getBonus(klassenBoni, klasse)[attr] +
        getBonus(subklassenBoni, subklasse)[attr] +
        getBonus(rassenBoni, rasse)[attr] +
        getBonus(subspeziesBoni, subspezies)[attr];
     });


     const daten = {
     function berechneWerte() {
      Name: name,
      const name = document.getElementById("name").value;
      Klasse: klasse,
      const daten = {
      Subklasse: subklasse || "Keine (15 Punkte erhalten)",
        Name: name,
      Rasse: rasse,
        Klasse: document.getElementById("klasse").value,
      Subspezies: subspezies || "Keine (20 Punkte erhalten)",
        Subklasse: document.getElementById("subklasse").value,
      Gegenstände: `${gegenstaende} (${gegenstaende * 10} Punkte erhalten)`,
        Rasse: document.getElementById("rasse").value,
      Verwendete_Punkte: sumUserInput(),
        Subrasse: document.getElementById("subrasse").value,
      Gesamt_Punkte: basisPunkte + (subklasse ? 0 : 15) + (subspezies ? 0 : 20) + (gegenstaende * 10),
        Gegenstände: document.getElementById("items").value,
       Attribute: gesamt
        Attribute: {}
    };
       };


    document.getElementById("ausgabe").textContent = JSON.stringify(daten, null, 2);
      attributeListe.forEach(attr => {
  }
        daten.Attribute[attr] = parseInt(document.getElementById("attr_" + attr).value) || 0;
      });


  function exportiereCharakter() {
      document.getElementById("ausgabe").textContent = JSON.stringify(daten, null, 2);
    const daten = document.getElementById("ausgabe").textContent;
    if (!daten) {
      alert("Bitte zuerst berechnen!");
      return;
     }
     }
    const blob = new Blob([daten], { type: "application/json" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = "charakter.json";
    a.click();
    URL.revokeObjectURL(url);
  }


  updateRemainingPoints();
    function exportiereDaten() {
      const ausgabe = document.getElementById("ausgabe").textContent;
      if (!ausgabe) return alert("Bitte erst Charakter berechnen!");
      const blob = new Blob([ausgabe], { type: "application/json" });
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = "charakter.json";
      a.click();
      URL.revokeObjectURL(url);
    }


// Automatische Aktualisierung bei jeder Eingabe
    document.addEventListener("DOMContentLoaded", () => {
document.addEventListener("DOMContentLoaded", function () {
      erstelleTabelle();
  const inputs = document.querySelectorAll("select, input[type='number']");
      document.querySelectorAll("select").forEach(el => {
  inputs.forEach(el => {
        el.addEventListener("change", updateRemainingPoints);
    el.addEventListener("input", updateRemainingPoints);
      });
    el.addEventListener("change", updateRemainingPoints);
    });
  });
  </script>
});
</body>
 
</script>
</html>
</html>

Version vom 26. Juli 2025, 11:32 Uhr

<!DOCTYPE html> Charakter Creator

Charakter Creator

Attribut Wert

Verbleibende Punkte: 160