CharakterCreator: Unterschied zwischen den Versionen
Aus Dunkelherzen Wiki
DRP (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung |
DRP (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung |
||
| (15 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
| Zeile 1: | Zeile 1: | ||
<html> | <html> | ||
<style> | <head> | ||
<meta charset="UTF-8" /> | |||
<style> | |||
.creator-form { | |||
max-width: 800px; | |||
margin: auto; | |||
font-family: sans-serif; | |||
} | |||
.creator-form label { | |||
font-weight: bold; | |||
display: block; | |||
margin-top: 10px; | |||
} | |||
.creator-form input, | |||
.creator-form select { | |||
width: 100%; | |||
padding: 5px; | |||
margin-bottom: 10px; | |||
} | |||
.creator-form button { | |||
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> | |||
</head> | |||
<body> | |||
<div class="creator-form"> | |||
<h2>Charakter Creator</h2> | |||
<label for="name">Name:</label> | |||
<input type="text" id="name" placeholder="Name des Charakters"> | |||
<label for="speziestyp">Speziestyp:</label> | |||
<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="rasse">Spezies:</label> | |||
<select id="rasse"> | |||
<option value="">Keine</option> | |||
</select> | |||
<label for="subspezies">Subspezies:</label> | |||
<select id="subspezies"> | |||
<option value="">Keine (+20 GP Ausgleich)</option> | |||
<option value="Waldelf">Waldelf</option> | |||
<option value="Stadelf">Stadelf</option> | |||
</select> | |||
<label for="klasse">Klasse:</label> | |||
<select id="klasse"> | |||
<option value="">Keine</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="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> | |||
<select id="subklasse"> | |||
<option value="">Keine (+15 GP Ausgleich)</option> | |||
<option value="Auserwählter">Auserwählter</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> | |||
< | <label for="gegenstaende">Gegenstände wählen:</label> | ||
<select id="gegenstaende"> | |||
<option value="0">Keine</option> | |||
<option value="1">1 Gegenstand (-10 GP)</option> | |||
<option value="2">2 Gegenstände (-20 GP)</option> | |||
<option value="3">3 Gegenstände (-30 GP)</option> | |||
</select> | |||
<div class="points-remaining" id="punkteInfo"></div> | |||
<label>Attribute:</label> | |||
<div class="attribute-inputs" id="attributeInputs"></div> | |||
< | |||
<button onclick="berechneCharakter()">Charakter berechnen</button> | |||
<button onclick="exportiereCharakter()">Exportieren</button> | |||
< | |||
< | |||
<div class="output" id="ausgabe"></div> | |||
</div> | |||
</ | |||
< | <script> | ||
const attributeListe = [ | |||
"Agilität", "Ausdauer", "Charisma", "Geschick", | |||
"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 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 speziestypBoni = Object.fromEntries([ | |||
"Humanoid", "Ätherer", "Mensch-Ätherer", "Andere Ätherer", | |||
"Non-Humanoide / Andere", "Xeutano", "Androidenartige", "Androiden" | |||
].map(name => [name, zeroBoni()])); | |||
Object.assign(speziestypBoni, { | |||
"Humanoid": { "Agilität": 0, "Ausdauer": 0, "Charisma": 1, "Geschick": 0, "Intelligenz": 0, "Konstitution": 0, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 }, | |||
"Ätherer": { "Agilität": 0, "Ausdauer": 0, "Charisma": 0, "Geschick": 0, "Intelligenz": 1, "Konstitution": 0, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 }, | |||
"Mensch-Ätherer": { "Agilität": 0, "Ausdauer": 0, "Charisma": 0, "Geschick": 0, "Intelligenz": 1, "Konstitution": 0, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 }, | |||
"Andere Ätherer": { "Agilität": 0, "Ausdauer": 0, "Charisma": 0, "Geschick": 0, "Intelligenz": 0, "Konstitution": 1, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 }, | |||
"Andere": { "Agilität": 0, "Ausdauer": 0, "Charisma": 0, "Geschick": 0, "Intelligenz": 0, "Konstitution": 1, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 }, | |||
"Xeutano": { "Agilität": 0, "Ausdauer": 0, "Charisma": 0, "Geschick": 0, "Intelligenz": 0, "Konstitution": 1, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 }, | |||
"Androidenartige": { "Agilität": 0, "Ausdauer": 0, "Charisma": 0, "Geschick": 0, "Intelligenz": 0, "Konstitution": 1, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 }, | |||
"Androiden": { "Agilität": 0, "Ausdauer": 0, "Charisma": 0, "Geschick": 0, "Intelligenz": 0, "Konstitution": 1, "Resistenz": 0, "Stärke": 0, "Wahrnehmung": 0 } | |||
}); | |||
const speziesNachTyp = { | |||
"Humanoid": [ | |||
"Arcadier / Byzantone", "Astroma", "Caesaren", "Fijen", "Floratia", | |||
"Kalani", "Lugier", "Nore", "Pendräa", "Rubinnia", "Sowi", "Varene", "Zarcore" | |||
], | |||
"Ätherer": ["Maggarn", "Sapiée"], | |||
"Mensch-Ätherer": ["Cilina", "Gaimane"], | |||
"Andere Ätherer": ["Matari"], | |||
"Non-Humanoide / Andere": [], | |||
"Xeutano": [], | |||
"Androidenartige": [], | |||
"Androiden": [] | |||
}; | |||
const rassenBoni = { | |||
"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 } | |||
}; | |||
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] || zeroBoni(); | |||
} | |||
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; | |||
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 subklasse = document.getElementById("subklasse").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(speziestypBoni, speziestyp)[attr] + | |||
getBonus(rassenBoni, rasse)[attr] + | |||
getBonus(subspeziesBoni, subspezies)[attr] + | |||
getBonus(klassenBoni, klasse)[attr] + | |||
getBonus(subklassenBoni, subklasse)[attr]; | |||
}); | |||
const daten = { | |||
Name: name, | |||
Speziestyp: speziestyp, | |||
Spezies: rasse, | |||
Subspezies: subspezies || "Keine (20 Punkte erhalten)", | |||
Klasse: klasse, | |||
Subklasse: subklasse || "Keine (15 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); | |||
} | |||
document.getElementById(" | function exportiereCharakter() { | ||
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); | |||
} | |||
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(); | |||
}); | }); | ||
const | document.addEventListener("DOMContentLoaded", () => { | ||
const inputs = document.querySelectorAll("select, input[type='number']"); | |||
inputs.forEach(el => { | |||
el.addEventListener("input", updateRemainingPoints); | |||
el.addEventListener("change", updateRemainingPoints); | |||
}); | |||
updateRemainingPoints(); | |||
}); | }); | ||
</script> | |||
</body> | |||
</ | |||
</html> | </html> | ||
Aktuelle Version vom 29. Juli 2025, 19:59 Uhr
