add basic attribute and combat rolls

This commit is contained in:
Sven Balzer 2024-10-17 19:59:31 +02:00
parent e2ffb67d35
commit 00fb647f0f
4 changed files with 289 additions and 27 deletions

View File

@ -38,8 +38,8 @@
{{#*inline "die-value"}} {{#*inline "die-value"}}
<div class="col noflex"> <div class="col noflex">
<div class="center">{{localize (concat "DSA41.attributes.short." type)}}</div> {{#if header}}<div class="center">{{header}}</div>{{/if}}
<div class="die die-{{type}}">{{lookup @root.actor.system.computed.attributes.with_modifiers type}}</div> <div class="die die-{{type}} roll" data-roll-type="{{type}}" {{#if value}}data-success-value="{{value}}"{{/if}} {{#if data-roll}}data-roll="{{data-roll}}"{{/if}}>{{value}}</div>
</div> </div>
{{/inline}} {{/inline}}
@ -54,7 +54,7 @@
<div class="row"> <div class="row">
<img class="character-image" src="{{ actor.img }}" title="{{ actor.name }}" {{#if editable}}data-edit="img"{{/if}}> <img class="character-image" src="{{ actor.img }}" title="{{ actor.name }}" {{#if editable}}data-edit="img"{{/if}}>
{{#each actor.system.attributes}} {{#each actor.system.attributes}}
{{>die-value type=@key}} {{>die-value type=@key header=(localize (concat "DSA41.attributes.short." @key)) value=(lookup @root.actor.system.computed.attributes.with_modifiers @key) data-roll="1d20"}}
{{/each}} {{/each}}
</div> </div>
@ -68,6 +68,9 @@
<div class="row noflex"> <div class="row noflex">
<a data-tab="tab3">{{localize "DSA41.character.inventar"}}</a> <a data-tab="tab3">{{localize "DSA41.character.inventar"}}</a>
</div> </div>
<div class="row noflex">
<a data-tab="tab4">{{localize "DSA41.character.kampf"}}</a>
</div>
</nav> </nav>
<section class="content"> <section class="content">
@ -134,7 +137,7 @@
<div class="tab" data-group="primary" data-tab="tab2"> <div class="tab" data-group="primary" data-tab="tab2">
<div class="row"> <div class="row">
<fieldset> <fieldset>
<legend>{{localize "DSA41.talente.kampf_talente.label"}}</legend> <legend>{{localize "DSA41.talente.kampf.label"}}</legend>
<table> <table>
<tr> <tr>
<th>{{localize "DSA41.talente.label"}}</th> <th>{{localize "DSA41.talente.label"}}</th>
@ -150,8 +153,8 @@
<td>{{>editable-input type="number" name=(concat "system.kampf_talente." @key ".talentwert") value=(lookup this "talentwert")}}</td> <td>{{>editable-input type="number" name=(concat "system.kampf_talente." @key ".talentwert") value=(lookup this "talentwert")}}</td>
<td>{{>editable-input type="number" name=(concat "system.kampf_talente." @key ".attacke") value=(lookup this "attacke")}}</td> <td>{{>editable-input type="number" name=(concat "system.kampf_talente." @key ".attacke") value=(lookup this "attacke")}}</td>
<td>{{>editable-input type="number" name=(concat "system.kampf_talente." @key ".parade") value=(lookup this "parade")}}</td> <td>{{>editable-input type="number" name=(concat "system.kampf_talente." @key ".parade") value=(lookup this "parade")}}</td>
<td class="center">0</td> <td class="center">{{lookup (lookup @root.actor.system.computed.kampf.talente @key) "attacke"}}</td>
<td class="center">0</td> <td class="center">{{lookup (lookup @root.actor.system.computed.kampf.talente @key) "parade"}}</td>
</tr> </tr>
{{/each}} {{/each}}
</table> </table>
@ -190,7 +193,7 @@
</div> </div>
{{#each actor.itemTypes.Bewaffnung}} {{#each actor.itemTypes.Bewaffnung}}
<div class="row list-item" data-item-id="{{this._id}}"> <div class="row list-item" data-item-id="{{this._id}}">
<div class="row item-name"> <div class="row item-name item-open">
<img class="item-image" src="{{this.img}}" title="{{this.name}}"> <img class="item-image" src="{{this.img}}" title="{{this.name}}">
<div class="col"> <div class="col">
<span>{{this.name}}</span> <span>{{this.name}}</span>
@ -202,8 +205,9 @@
</span> </span>
</div> </div>
</div> </div>
<div class="row"></div>
<div class="center">{{this.system.gewicht}}</div> <div class="center">{{this.system.gewicht}}</div>
<div class="center">{{>editable-checkbox value=this.system.angelegt}}</div> <div class="center fas fa-trash item-delete"></div>
</div> </div>
{{/each}} {{/each}}
</div> </div>
@ -243,5 +247,48 @@
</div> </div>
</div> </div>
</div> </div>
<div class="tab" data-group="primary" data-tab="tab4">
<div class="col kampf">
<div class="col list">
<div class="row list-header">
<div class="row">{{localize "DSA41.kampf.bewaffnung"}}</div>
<div>{{localize "DSA41.kampf.attacke"}}</div>
<div>{{localize "DSA41.kampf.parade"}}</div>
<div>{{localize "DSA41.kampf.trefferpunkte"}}</div>
</div>
{{#each actor.system.computed.kampf.waffen}}
<div class="row list-item" data-item-id="{{item._id}}">
<div class="row item-name">
<img class="item-image" src="{{item.img}}" title="{{item.name}}">
<div class="col">
<span>{{item.name}}</span>
</div>
</div>
<div class="center">{{>die-value type="attacke" data-roll="1d20" value=attacke}}</div>
<div class="center">{{>die-value type="parade" data-roll="1d20" value=parade}}</div>
<div class="center">{{>die-value type="trefferpunkte" data-roll=trefferpunkte}}</div>
</div>
{{/each}}
</div>
<div class="col list">
<div class="row list-header">
<div class="row">{{localize "DSA41.kampf.ruestungen"}}</div>
<div>{{localize "DSA41.weight"}}</div>
</div>
{{#each actor.itemTypes.Ruestung}}
<div class="row list-item" data-item-id="{{this._id}}">
<div class="row item-name">
<img class="item-image" src="{{this.img}}" title="{{this.name}}">
<span class="center">{{this.name}}</span>
</div>
<div class="center">{{this.system.gewicht}}</div>
<div class="center">{{>editable-checkbox value=this.system.angelegt}}</div>
</div>
{{/each}}
</div>
</div>
</div>
</section> </section>
</form> </form>

View File

@ -15,10 +15,26 @@
"weight": "Gewicht", "weight": "Gewicht",
"price": "Preis", "price": "Preis",
"roll_types": {
"courage": "Mut",
"cleverness": "Klugheit",
"intuition": "Intuition",
"charisma": "Charisma",
"dexterity": "Fingerfertigkeit",
"agility": "Gewandheit",
"constitution": "Konstitution",
"strength": "Körperkraft",
"attacke": "Attacke",
"parade": "Parade",
"trefferpunkte": "Trefferpunkte"
},
"character": { "character": {
"eigenschaften": "Eigenschaften", "eigenschaften": "Eigenschaften",
"talente": "Talente", "talente": "Talente",
"inventar": "Inventar" "inventar": "Inventar",
"kampf": "Kampf"
}, },
"attributes": { "attributes": {
@ -64,7 +80,32 @@
"name": { "name": {
"anderthalbhaender": "Anderthalbhänder", "anderthalbhaender": "Anderthalbhänder",
"armbrust": "Armbrust" "armbrust": "Armbrust",
"belagerungswaffen": "Belagerungswaffen",
"blasrohr": "Blasrohr",
"bogen": "Bogen",
"diskus": "Diskus",
"dolche": "Dolche",
"fechtwaffen": "Fechtwaffen",
"hiebwaffen": "Hiebwaffen",
"infanteriewaffen": "Infanteriewaffen",
"kettenstaebe": "Kettenstäbe",
"kettenwaffen": "Kettenwaffen",
"lanzenreiten": "Lanzenreiten",
"peitsche": "Peitsche",
"raufen": "Raufen",
"ringen": "Ringen",
"saebel": "Saebel",
"schleuder": "Schleuder",
"schwerter": "Schwerter",
"speere": "Speere",
"staebe": "Stäbe",
"wurfbeile": "Wurfbeile",
"wurfmesser": "Wurfmesser",
"wurfspeere": "Wurfspeere",
"zweihandflegel": "Zweihandflegel",
"zweihand_hiebwaffen": "Zweihand-Hiebwaffen",
"zweihandschwerter": "Zweihandschwerter/-säbel"
} }
}, },
@ -129,7 +170,28 @@
"name": { "name": {
"anatomie": "Anatomie", "anatomie": "Anatomie",
"baukunst": "Baukunst" "baukunst": "Baukunst",
"brett_kartenspiel": "Brett-/Kartenspiel",
"geographie": "Geographie",
"geschichtswissen": "Geschichtswissen",
"gesteinskunde": "Gesteinskunde",
"goetter_kulte": "Götter/Kulte",
"heraldik": "Heraldik",
"huettenkunde": "Hüttenkunde",
"kriegskunst": "Kriegskunst",
"kryptographie": "Kryptographie",
"magiekunde": "Magiekunde",
"mechanik": "Mechanik",
"pflanzenkunde": "Pflanzenkunde",
"philosophie": "Philosophie",
"rechnen": "Rechnen",
"rechtskunde": "Rechtskunde",
"sagen_legenden": "Sagen/Legenden",
"schaetzen": "Schätzen",
"sprachenkunde": "Sprachenkunde",
"staatskunst": "Staatskunst",
"sternkunde": "Sternenkunde",
"tierkunde": "Tierkunde"
} }
}, },
@ -148,7 +210,52 @@
"name": { "name": {
"abrichten": "Abrichten", "abrichten": "Abrichten",
"ackerbau": "Ackerbau" "ackerbau": "Ackerbau",
"alchimie": "Alchimie",
"bergbau": "Bergbau",
"bogenbau": "Bogenbau",
"boote_fahren": "Boote Fahren",
"brauer": "Brauer",
"drucker": "Drucker",
"fahrzeug_lenken": "Fahrzeug Lenken",
"falschspiel": "Falschspiel",
"feinmechanik": "Feinmechanik",
"feuersteinbearbeitung": "Feuersteinbearbeitung",
"fleischer": "Fleischer",
"gerber": "Gerber/Kürschner",
"glaskunst": "Glaskunst",
"grobschmied": "Grobschmied",
"handel": "Handel",
"hauswirtschaft": "Hauswirtschaft",
"heilkunde_gift": "Heilkunde Gift",
"heilkunde_krankheiten": "Heilkunde Krankheiten",
"heilkunde_seele": "Heilkunde Seele",
"heilkunde_wunden": "Heilkunde Wunden",
"holzbearbeitung": "Holzbearbeitung",
"instrumentenbauer": "Instrumentenbauer",
"kartographie": "Kartographie",
"kochen": "Kochen",
"kristallzucht": "Kristallzucht",
"lederarbeiten": "Lederarbeiten",
"malen_zeichnen": "Malen/Zeichnen",
"maurer": "Maurer",
"metallguss": "Metallguss",
"musizieren": "Musizieren",
"schloesser_knacken": "Schlösser Knacken",
"schnapps_brennen": "Schnapps Brennen",
"schneidern": "Schneidern",
"seefahrt": "Seefahrt",
"seiler": "Seiler",
"steinmetz": "Steinmetz",
"juwelier": "Steinschneider/Juwelier",
"stellmacher": "Stellmacher",
"stoffe_faerben": "Stoffe Faerben",
"taetowieren": "Tätowieren",
"toepfern": "Töpfern",
"viehzucht": "Viehzucht",
"webkunst": "Webkunst",
"winzer": "Winzer",
"zimmermann": "Zimmermann"
} }
} }
}, },
@ -233,6 +340,14 @@
"bewaffnung": "Bewaffnung", "bewaffnung": "Bewaffnung",
"ruestungen": "Rüstungen", "ruestungen": "Rüstungen",
"gegenstaende": "Gegenstände" "gegenstaende": "Gegenstände"
},
"kampf": {
"bewaffnung": "Bewaffnung",
"attacke": "Attacke",
"parade": "Parade",
"trefferpunkte": "Trefferpunkte",
"ruestungen": "Rüstungen"
} }
} }
} }

View File

@ -49,7 +49,7 @@
.die { .sheet .die {
width: 48px; width: 48px;
height: 48px; height: 48px;
line-height: 48px; line-height: 48px;
@ -62,14 +62,30 @@
color: #fff; color: #fff;
} }
.die-courage { background-color: #b22319; } .sheet .die-courage { background-color: #b22319; }
.die-cleverness { background-color: #8158a3; } .sheet .die-cleverness { background-color: #8158a3; }
.die-intuition { background-color: #388834; } .sheet .die-intuition { background-color: #388834; }
.die-charisma { background-color: #0c0c0c; } .sheet .die-charisma { background-color: #0c0c0c; }
.die-dexterity { background-color: #d4b366; } .sheet .die-dexterity { background-color: #d4b366; }
.die-agility { background-color: #678ec3; } .sheet .die-agility { background-color: #678ec3; }
.die-constitution { background-color: #a3a3a3; } .sheet .die-constitution { background-color: #a3a3a3; }
.die-strength { background-color: #d5a877; } .sheet .die-strength { background-color: #d5a877; }
.sheet .die-attacke { background-color: #b22319; }
.sheet .die-parade { background-color: #388834; }
.sheet .die-trefferpunkte { background-color: #0c0c0c; }
.sheet .item-open,
.sheet .item-delete,
.sheet .roll {
cursor: pointer;
}
.sheet .item-open:hover,
.sheet .item-delete:hover,
.sheet .roll:hover {
transform: scale(1.05);
}
.character-image { .character-image {
@ -101,6 +117,7 @@
.item-name { .item-name {
gap: 0.5rem; gap: 0.5rem;
flex: 0 1 auto;
} }
.item-sub { .item-sub {

View File

@ -1,6 +1,4 @@
Hooks.once("init", function() { Hooks.once("init", function() {
console.log("INIT");
CONFIG.Combat.initiative.formula = "1d6 + @computed.ini_basiswert[INI-Basiswert]"; CONFIG.Combat.initiative.formula = "1d6 + @computed.ini_basiswert[INI-Basiswert]";
CONFIG.Actor.dataModels.Player = DSA41_CharacterData; CONFIG.Actor.dataModels.Player = DSA41_CharacterData;
@ -240,6 +238,11 @@ class DSA41_CharacterData extends foundry.abstract.TypeDataModel {
without_modifiers: {}, without_modifiers: {},
with_modifiers: {}, with_modifiers: {},
}, },
kampf: {
talente: {},
waffen: {},
},
}; };
for (const [attribute, values] of Object.entries(this.attributes)) { for (const [attribute, values] of Object.entries(this.attributes)) {
@ -257,7 +260,54 @@ class DSA41_CharacterData extends foundry.abstract.TypeDataModel {
this.computed.pa_basiswert = Math.round((this.computed.attributes.without_modifiers.intuition + this.computed.attributes.without_modifiers.agility + this.computed.attributes.without_modifiers.strength) / 5);; this.computed.pa_basiswert = Math.round((this.computed.attributes.without_modifiers.intuition + this.computed.attributes.without_modifiers.agility + this.computed.attributes.without_modifiers.strength) / 5);;
this.computed.fk_basiswert = Math.round((this.computed.attributes.without_modifiers.intuition + this.computed.attributes.without_modifiers.dexterity + this.computed.attributes.without_modifiers.strength) / 5);; this.computed.fk_basiswert = Math.round((this.computed.attributes.without_modifiers.intuition + this.computed.attributes.without_modifiers.dexterity + this.computed.attributes.without_modifiers.strength) / 5);;
for(const [name, values] of Object.entries(this.kampf_talente)) {
this.computed.kampf.talente[name] = {};
this.computed.kampf.talente[name].attacke = this.computed.at_basiswert + values.attacke;
this.computed.kampf.talente[name].parade = this.computed.pa_basiswert + values.parade;
}
let equipped_bewaffnung = this.parent.items.filter((x) => x.type === "Bewaffnung");
let equipped_nahkampfwaffen = equipped_bewaffnung.filter((x) => x.system.nahkampfwaffe.aktiv);
let equipped_parierwaffen = equipped_bewaffnung.filter((x) => x.system.parierwaffe.aktiv);
let equipped_schilde = equipped_bewaffnung.filter((x) => x.system.schild.aktiv);
let equipped_fernkampfwaffen = equipped_bewaffnung.filter((x) => x.system.fernkampfwaffe.aktiv);
for(const item of equipped_nahkampfwaffen) {
this.computed.kampf.waffen[item._id] = {};
this.computed.kampf.waffen[item._id].item = item;
if (item.system.nahkampfwaffe.aktiv) {
const talent = item.system.nahkampfwaffe.kampftalente;
this.computed.kampf.waffen[item._id].attacke = this.computed.kampf.talente[talent].attacke + item.system.nahkampfwaffe.modifikator_attacke;
this.computed.kampf.waffen[item._id].parade = this.computed.kampf.talente[talent].parade + item.system.nahkampfwaffe.modifikator_attacke;
const tp_kk = Math.trunc((this.computed.attributes.with_modifiers.strength - item.system.nahkampfwaffe.schwellenwert) / item.system.nahkampfwaffe.schadensschritte);
if (tp_kk >= 0) {
this.computed.kampf.waffen[item._id].trefferpunkte = item.system.nahkampfwaffe.basis + " + " + tp_kk;
} else {
this.computed.kampf.waffen[item._id].trefferpunkte = item.system.nahkampfwaffe.basis + "" + tp_kk;
this.computed.kampf.waffen[item._id].attacke += tp_kk;
this.computed.kampf.waffen[item._id].parade += tp_kk;
}
for (const parierwaffe of equipped_parierwaffen) {
if (parierwaffe._id === item._id) continue;
this.computed.kampf.waffen[item._id].attacke += parierwaffe.system.parierwaffe.modifikator_attacke;
this.computed.kampf.waffen[item._id].parade += parierwaffe.system.parierwaffe.modifikator_parade;
}
for (const schild of equipped_schilde) {
if (schild._id === item._id) continue;
this.computed.kampf.waffen[item._id].attacke += schild.system.schild.modifikator_attacke;
this.computed.kampf.waffen[item._id].parade += schild.system.schild.modifikator_parade;
}
}
}
} }
} }
@ -380,6 +430,39 @@ class DSA41_ActorSheet extends ActorSheet {
get template() { get template() {
return "systems/dsa-4th-edition/src/ActorSheet.html"; return "systems/dsa-4th-edition/src/ActorSheet.html";
} }
activateListeners(html) {
super.activateListeners(html);
html.on("click", ".item-open", async (event) => {
const item_id = event.currentTarget.closest("[data-item-id]").dataset.itemId;
const item = this.object.items.get(item_id);
item.sheet.render(true)
});
html.on("click", ".item-delete", async (event) => {
const item_id = event.currentTarget.closest("[data-item-id]").dataset.itemId;
const item = this.object.items.get(item_id);
item.delete();
});
html.on("click", ".roll", async (event) => {
const roll_formula = event.currentTarget.closest("[data-roll]").dataset.roll;
const roll_type = event.currentTarget.closest("[data-roll]").dataset.rollType;
const success_value = event.currentTarget.closest("[data-roll]").dataset.successValue;
let flavor = game.i18n.localize("DSA41.roll_types." + roll_type);
if (typeof success_value !== 'undefined') {
flavor += " <= " + success_value;
}
let roll = new Roll(roll_formula, this.object.system);
roll.toMessage({
speaker: ChatMessage.getSpeaker({ actor: this.object }),
flavor: flavor,
});
});
}
} }
class DSA41_ItemSheet extends ItemSheet { class DSA41_ItemSheet extends ItemSheet {