CharakterCreator: Unterschied zwischen den Versionen

Aus Dunkelherzen Wiki
Keine Bearbeitungszusammenfassung
Markierung: Zurückgesetzt
Keine Bearbeitungszusammenfassung
 
(17 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
<!DOCTYPE html>
<html>
<html lang="de">
<head>
<head>
   <meta charset="UTF-8">
   <meta charset="UTF-8" />
  <title>Charakter Creator</title>
   <style>
   <style>
     body {
     .creator-form {
      font-family: sans-serif;
       max-width: 800px;
       max-width: 800px;
       margin: auto;
       margin: auto;
       padding: 20px;
       font-family: sans-serif;
     }
     }
 
     .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;
      padding: 10px;
       width: 100%;
       width: 100%;
      border-collapse: collapse;
      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;
       white-space: pre-wrap;
       padding: 10px;
       background: #f8f8f8;
       background: #f8f8f8;
      padding: 10px;
       border: 1px solid #ccc;
       border: 1px solid #ccc;
      white-space: pre-wrap;
     }
     }
 
     .points-remaining {
     .button {
       font-weight: bold;
       margin-top: 15px;
       color: #b00;
       padding: 10px;
       margin-top: 10px;
       width: 100%;
     }
     }
   </style>
   </style>
</head>
</head>
<body>
<body>
  <div class="creator-form">
    <h2>Charakter Creator</h2>


  <h2>Charakter Creator</h2>
    <label for="name">Name:</label>
    <input type="text" id="name" placeholder="Name des Charakters">


  <label for="name">Name:</label>
    <label for="speziestyp">Speziestyp:</label>
  <input type="text" id="name" placeholder="Name des Charakters">
    <select id="speziestyp">
      <option value="">Keine</option>
      <option value="Humanoid">Humanoid</option>
      <option value="Ätherer">Ätherer</option>
      <option value="Mensch-Ätherer">Mensch-Ätherer</option>
      <option value="Andere Ätherer">Andere Ätherer</option>
      <option value="Non-Humanoide / Andere">Non-Humanoide / Andere</option>
      <option value="Xeutano">Xeutano</option>
      <option value="Androidenartige">Androidenartige</option>
  <option value="Androidenartige">Androiden</option>
    </select>


  <label for="klasse">Klasse:</label>
    <label for="rasse">Spezies:</label>
  <select id="klasse">
    <select id="rasse">
    <option value="">Wähle...</option>
      <option value="">Keine</option>
    <option value="Arbeiter">Arbeiter</option>
     </select>
    <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="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>


  <label for="subklasse">Subklasse:</label>
    <label for="subspezies">Subspezies:</label>
  <select id="subklasse">
    <select id="subspezies">
    <option value="">Keine Subklasse</option>
      <option value="">Keine (+20 GP Ausgleich)</option>
    <option value="Auserwählter">Auserwählter</option>
      <option value="Waldelf">Waldelf</option>
    <option value="Diener">Diener</option>
      <option value="Stadelf">Stadelf</option>
    <option value="Drogenjunkie">Drogenjunkie</option>
     </select>
    <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>


  <label for="rasse">Rasse:</label>
    <label for="klasse">Klasse:</label>
  <select id="rasse">
    <select id="klasse">
    <option value="">Wähle...</option>
      <option value="">Keine</option>
    <option value="Mensch">Mensch</option>
      <option value="Arbeiter">Arbeiter</option>
    <option value="Elf">Elf</option>
      <option value="Barde">Barde</option>
  </select>
      <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="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>


  <label for="subrasse">Subrasse:</label>
    <label for="subklasse">Subklasse:</label>
  <select id="subrasse">
    <select id="subklasse">
    <option value="">Keine Subrasse</option>
      <option value="">Keine (+15 GP Ausgleich)</option>
    <option value="Hochelf">Hochelf</option>
      <option value="Auserwählter">Auserwählter</option>
    <option value="Wüstenmensch">Wüstenmensch</option>
      <option value="Diener">Diener</option>
  </select>
      <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>


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


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


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


  <button class="button" onclick="berechneWerte()">Charakterdaten anzeigen</button>
    <button onclick="berechneCharakter()">Charakter berechnen</button>
  <button class="button" onclick="exportiereDaten()">Charakterdaten exportieren</button>
    <button onclick="exportiereCharakter()">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", "Intelligenz",
       "Agilität", "Ausdauer", "Charisma", "Geschick",
      "Konstitution", "Resistenz", "Stärke", "Wahrnehmung"
      "Intelligenz", "Konstitution", "Resistenz",
      "Stärke", "Wahrnehmung"
     ];
     ];
    const basisPunkte = 160;
    const zeroBoni = () =>
      Object.fromEntries(attributeListe.map(attr => [attr, 0]));
    const klassenBoni = Object.fromEntries([
      "Arbeiter", "Barde", "Bote", "Gelehrter", "Gläubiger", "Kind", "Krieger", "Schurke",
      "Schütze", "Seelenkünstler", "Soldat", "Techniker", "Vagabunde"
    ].map(name => [name, zeroBoni()]));


     const MAX_PUNKTE = 160;
     const subklassenBoni = Object.fromEntries([
      "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"
    ].map(name => [name, zeroBoni()]));


     const basisBoni = () => {
     const speziestypBoni = Object.fromEntries([
       const boni = {};
       "Humanoid", "Ätherer", "Mensch-Ätherer", "Andere Ätherer",
       attributeListe.forEach(attr => boni[attr] = 0);
       "Non-Humanoide / Andere", "Xeutano", "Androidenartige", "Androiden"
      return boni;
    ].map(name => [name, zeroBoni()]));
    };


     // Alle Klassen/Subklassen/Rassen/Subrassen starten mit 0 für alle Attribute
     Object.assign(speziestypBoni, {
    const klassenBoni = {
       "Humanoid":         { "Agilität": 0, "Ausdauer": 0, "Charisma": 1, "Geschick": 0, "Intelligenz": 0, "Konstitution": 0, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 },
       "Arbeiter": basisBoni(),
       "Ätherer":          { "Agilität": 0, "Ausdauer": 0, "Charisma": 0, "Geschick": 0, "Intelligenz": 1, "Konstitution": 0, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 },
       "Barde": basisBoni(),
       "Mensch-Ätherer":  { "Agilität": 0, "Ausdauer": 0, "Charisma": 0, "Geschick": 0, "Intelligenz": 1, "Konstitution": 0, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 },
       "Bote": basisBoni(),
       "Andere Ätherer":  { "Agilität": 0, "Ausdauer": 0, "Charisma": 0, "Geschick": 0, "Intelligenz": 0, "Konstitution": 1, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 },
       "Gelehrter": basisBoni(),
  "Andere":    { "Agilität": 0, "Ausdauer": 0, "Charisma": 0, "Geschick": 0, "Intelligenz": 0, "Konstitution": 1, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 },
      "Gläubiger": basisBoni(),
  "Xeutano":          { "Agilität": 0, "Ausdauer": 0, "Charisma": 0, "Geschick": 0, "Intelligenz": 0, "Konstitution": 1, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 },
      "Kind": basisBoni(),
  "Androidenartige":  { "Agilität": 0, "Ausdauer": 0, "Charisma": 0, "Geschick": 0, "Intelligenz": 0, "Konstitution": 1, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 },
      "Krieger": basisBoni(),
  "Androiden":    { "Agilität": 0, "Ausdauer": 0, "Charisma": 0, "Geschick": 0, "Intelligenz": 0, "Konstitution": 1, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 }
      "Schurke": basisBoni(),
     });
      "Schütze": basisBoni(),
      "Seelenkünstler": basisBoni(),
      "Soldat": basisBoni(),
      "Techniker": basisBoni(),
      "Vagabunde": basisBoni()
     };


     const subklassenBoni = {
     const speziesNachTyp = {
       "Auserwählter": basisBoni(),
       "Humanoid": [
      "Diener": basisBoni(),
        "Arcadier / Byzantone", "Astroma", "Caesaren", "Fijen", "Floratia",
      "Drogenjunkie": basisBoni(),
        "Kalani", "Lugier", "Nore", "Pendräa", "Rubinnia", "Sowi", "Varene", "Zarcore"
      "Dummkopf": basisBoni(),
       ],
      "Dunkler Künstler": basisBoni(),
       "Ätherer": ["Maggarn", "Sapiée"],
      "Gesetzloser": basisBoni(),
       "Mensch-Ätherer": ["Cilina", "Gaimane"],
      "Glücksspieler": basisBoni(),
       "Andere Ätherer": ["Matari"],
      "Händler": basisBoni(),
       "Non-Humanoide / Andere": [],
       "Koch": basisBoni(),
       "Xeutano": [],
       "Kopfgeldjäger": basisBoni(),
       "Androidenartige": [],
      "Ödländer": basisBoni(),
  "Androiden": []
       "Okkultist": basisBoni(),
      "Pazifist": basisBoni(),
       "Politiker": basisBoni(),
       "Revolutionär": basisBoni(),
       "Seefahrer": basisBoni(),
       "Spion": basisBoni(),
      "Mutant": basisBoni()
     };
     };


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


     const subrassenBoni = {
     const subspeziesBoni = {
       "Hochelf": basisBoni(),
       "Waldelf": { "Agilität": 0, "Ausdauer": 0, "Charisma": 0, "Geschick": 1, "Intelligenz": 0, "Konstitution": 0, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 1 },
       "Wüstenmensch": basisBoni()
       "Stadelf": { "Agilität": 0, "Ausdauer": 0, "Charisma": 1, "Geschick": 0, "Intelligenz": 1, "Konstitution": 0, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 }
     };
     };


     function erstelleTabelle() {
     attributeListe.forEach(attr => {
       const tbody = document.getElementById("attributeTabelle");
       const input = document.createElement("input");
       tbody.innerHTML = "";
       input.type = "number";
       attributeListe.forEach(attr => {
       input.min = "0";
        const tr = document.createElement("tr");
      input.value = "0";
        tr.innerHTML = `<td>${attr}</td>
      input.id = `attr_${attr}`;
                        <td><input type="number" id="attr_${attr}" value="0" min="0" onchange="updateRemainingPoints()"></td>`;
      input.oninput = updateRemainingPoints;
         tbody.appendChild(tr);
      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] || zeroBoni();
    }
 
    function sumUserInput() {
      return attributeListe.reduce((sum, attr) => {
        const val = parseInt(document.getElementById(`attr_${attr}`).value) || 0;
         return sum + val;
       }, 0);
     }
     }


     function getBoni() {
     function updateRemainingPoints() {
       let bonus = {};
       let total = basisPunkte;
       attributeListe.forEach(attr => bonus[attr] = 0);
      if (!document.getElementById("subspezies").value) total += 20;
       if (!document.getElementById("subklasse").value) total += 15;
      total -= parseInt(document.getElementById("gegenstaende").value || "0") * 10;
      const used = sumUserInput();
      document.getElementById("punkteInfo").textContent = `Verbleibende Punkte: ${total - used} / ${total}`;
    }


    function berechneCharakter() {
      const name = document.getElementById("name").value;
      const speziestyp = document.getElementById("speziestyp").value;
      const rasse = document.getElementById("rasse").value;
      const subspezies = document.getElementById("subspezies").value;
       const klasse = document.getElementById("klasse").value;
       const klasse = document.getElementById("klasse").value;
       const subklasse = document.getElementById("subklasse").value;
       const subklasse = document.getElementById("subklasse").value;
       const rasse = document.getElementById("rasse").value;
       const gegenstaende = parseInt(document.getElementById("gegenstaende").value) || 0;
      const subrasse = document.getElementById("subrasse").value;


       [klassenBoni[klasse], subklassenBoni[subklasse], rassenBoni[rasse], subrassenBoni[subrasse]].forEach(obj => {
       const basisAttribute = {};
         if (obj) {
      attributeListe.forEach(attr => {
          for (let key in obj) {
         basisAttribute[attr] = parseInt(document.getElementById(`attr_${attr}`).value) || 0;
            bonus[key] += obj[key] || 0;
          }
        }
       });
       });


      return bonus;
       const gesamt = {};
    }
 
    function berechnePunkteBonus() {
      let bonus = 0;
      if (!document.getElementById("subklasse").value) bonus += 15;
      if (!document.getElementById("subrasse").value) bonus += 20;
 
       const gegenstände = parseInt(document.getElementById("items").value);
      bonus -= (gegenstände * 10);
 
      return bonus;
    }
 
    function updateRemainingPoints() {
      let summe = 0;
       attributeListe.forEach(attr => {
       attributeListe.forEach(attr => {
         summe += parseInt(document.getElementById("attr_" + attr).value) || 0;
         gesamt[attr] =
          basisAttribute[attr] +
          getBonus(speziestypBoni, speziestyp)[attr] +
          getBonus(rassenBoni, rasse)[attr] +
          getBonus(subspeziesBoni, subspezies)[attr] +
          getBonus(klassenBoni, klasse)[attr] +
          getBonus(subklassenBoni, subklasse)[attr];
       });
       });


      const verbleibend = MAX_PUNKTE + berechnePunkteBonus() - summe;
      document.getElementById("remainingPoints").textContent = verbleibend;
    }
    function berechneWerte() {
      const name = document.getElementById("name").value;
       const daten = {
       const daten = {
         Name: name,
         Name: name,
         Klasse: document.getElementById("klasse").value,
         Speziestyp: speziestyp,
         Subklasse: document.getElementById("subklasse").value,
        Spezies: rasse,
         Rasse: document.getElementById("rasse").value,
        Subspezies: subspezies || "Keine (20 Punkte erhalten)",
         Subrasse: document.getElementById("subrasse").value,
        Klasse: klasse,
         Gegenstände: document.getElementById("items").value,
         Subklasse: subklasse || "Keine (15 Punkte erhalten)",
         Attribute: {}
         Gegenstände: `${gegenstaende} (${gegenstaende * 10} Punkte abgezogen)`,
         Verwendete_Punkte: sumUserInput(),
         Gesamt_Punkte: basisPunkte + (subklasse ? 0 : 15) + (subspezies ? 0 : 20) - (gegenstaende * 10),
         Attribute: gesamt
       };
       };
      attributeListe.forEach(attr => {
        daten.Attribute[attr] = parseInt(document.getElementById("attr_" + attr).value) || 0;
      });


       document.getElementById("ausgabe").textContent = JSON.stringify(daten, null, 2);
       document.getElementById("ausgabe").textContent = JSON.stringify(daten, null, 2);
     }
     }


     function exportiereDaten() {
     function exportiereCharakter() {
       const ausgabe = document.getElementById("ausgabe").textContent;
       const daten = document.getElementById("ausgabe").textContent;
       if (!ausgabe) return alert("Bitte erst Charakter berechnen!");
       if (!daten) {
       const blob = new Blob([ausgabe], { type: "application/json" });
        alert("Bitte zuerst berechnen!");
        return;
      }
       const blob = new Blob([daten], { type: "application/json" });
       const url = URL.createObjectURL(blob);
       const url = URL.createObjectURL(blob);
       const a = document.createElement("a");
       const a = document.createElement("a");
Zeile 282: Zeile 286:
       URL.revokeObjectURL(url);
       URL.revokeObjectURL(url);
     }
     }
    document.getElementById("speziestyp").addEventListener("change", function () {
      const typ = this.value;
      const rasseSelect = document.getElementById("rasse");
      rasseSelect.innerHTML = '<option value="">Keine</option>';
      if (speziesNachTyp[typ]) {
        speziesNachTyp[typ].forEach(spezies => {
          const opt = document.createElement("option");
          opt.value = spezies;
          opt.textContent = spezies;
          rasseSelect.appendChild(opt);
        });
      }
      updateRemainingPoints();
    });


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

Aktuelle Version vom 29. Juli 2025, 19:59 Uhr

Charakter Creator