Compare commits

...

6 Commits

Author SHA1 Message Date
Sven Balzer
98dcb0749d add dialog to attributes for custom modifier 2024-11-12 01:04:03 +01:00
Sven Balzer
3946a8116c add dialog to attacke for custom modifier 2024-11-12 00:45:58 +01:00
Sven Balzer
7384e6cdcf add parade dialog for parrying crits 2024-11-12 00:25:47 +01:00
Sven Balzer
5179ecba91 add crits to nahkampfwaffe damage 2024-11-12 00:05:53 +01:00
Sven Balzer
d9e1721459 add crits to fernkampf damage 2024-11-11 23:47:41 +01:00
Sven Balzer
998951bafc add fernkampf attack and damage rolls 2024-11-11 23:24:32 +01:00
18 changed files with 537 additions and 33 deletions

View File

@ -13,7 +13,7 @@
{{/inline}}
<div class="actor-sheet ActorSheet">
<div class="row">
<div class="grid4 gap">
{{>editable-input type="text" name="name" value=actor.name placeholder=(localize "DSA41.name")}}
{{>editable-input type="text" name="system.race" value=actor.system.race placeholder=(localize "DSA41.race")}}
{{>editable-input type="text" name="system.culture" value=actor.system.culture placeholder=(localize "DSA41.culture")}}
@ -141,7 +141,7 @@
</div>
{{#each actor.itemTypes.Bewaffnung}}
<div class="list-item" data-item-id="{{this._id}}">
<div class="item-name row" data-action="item-open">
<div class="row" data-action="item-open">
<img class="item-image" src="{{this.img}}" title="{{this.name}}">
<div class="col">
<span>{{this.name}}</span>
@ -168,7 +168,7 @@
</div>
{{#each actor.itemTypes.Ruestung}}
<div class="list-item" data-item-id="{{this._id}}">
<div class="item-name row" data-action="item-open">
<div class="row" data-action="item-open">
<img class="item-image" src="{{this.img}}" title="{{this.name}}">
<span class="center">{{this.name}}</span>
</div>
@ -187,7 +187,7 @@
</div>
{{#each actor.itemTypes.Gegenstand}}
<div class="list-item" data-item-id="{{this._id}}">
<div class="item-name row" data-action="item-open">
<div class="row" data-action="item-open">
<img class="item-image" src="{{this.img}}" title="{{this.name}}">
<span class="center">{{this.name}}</span>
</div>
@ -210,7 +210,7 @@
{{#each actor.system.computed.kampf.waffen}}
<div class="list-item" data-item-id="{{item._id}}">
<div class="item-name row" data-action="item-open">
<div class="row" data-action="item-open">
<img class="item-image" src="{{item.img}}" title="{{item.name}}">
<div class="col">
<span>{{item.name}}</span>
@ -221,6 +221,19 @@
<div class="center">{{>die-value type="trefferpunkte" data-roll=trefferpunkte value=trefferpunkte_display data-tooltip="trefferpunkte_tooltip"}}</div>
</div>
{{/each}}
{{#each actor.system.computed.kampf.fernkampf_waffen}}
<div class="list-item" data-item-id="{{item._id}}">
<div class="row" data-action="item-open">
<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="fernkampf-attacke" data-roll="1d20" value=attacke data-tooltip="fernkampf_attacke_tooltip"}}</div>
<div class="center"></div>
<div class="center">{{>die-value type="fernkampf-trefferpunkte" data-roll=trefferpunkte value=trefferpunkte_display data-tooltip="fernkampf_trefferpunkte_tooltip"}}</div>
</div>
{{/each}}
</div>
<div class="list Ruestung">
@ -249,7 +262,7 @@
{{#each actor.system.computed.kampf.ruestungen}}
<div class="list-item" data-item-id="{{item._id}}">
<div class="row item-name" data-action="item-open">
<div class="row" data-action="item-open">
<img class="item-image" src="{{item.img}}" title="{{item.name}}">
<span class="center">{{item.name}}</span>
</div>

28
src/Dialogs/Attacke.hbs Normal file
View File

@ -0,0 +1,28 @@
<div class="parade_dialog">
<span class="colspan2">{{localize "DSA41.kampf.modifikator"}}</span>
{{>editable-input type="number" name="modifikator" class="colspan2" value=(lookup formData "modifikator") }}
<div class="dsa41-calculation colspan4 center">
<ruby>{{options.item.basis_attacke}}<rt>{{localize "DSA41.bewaffnung.nahkampfwaffe.basis"}}</rt></ruby>
+ <ruby>{{options.item.talent_attacke}}<rt>{{localize "DSA41.talente.label"}}</rt></ruby>
{{#if (ne options.item.modifikator_attacke 0)}}
+ <ruby>{{options.item.modifikator_attacke}}<rt>{{localize "DSA41.bewaffnung.nahkampfwaffe.modifikator"}}</rt></ruby>
{{/if}}
{{#if (ne options.item.parierwaffe_attacke 0)}}
+ <ruby>{{options.item.parierwaffe_attacke}}<rt>{{localize "DSA41.bewaffnung.parierwaffe.label"}}</rt></ruby>
{{/if}}
{{#if (ne options.item.schild_attacke 0)}}
+ <ruby>{{options.item.schild_attacke}}<rt>{{localize "DSA41.bewaffnung.schild.label"}}</rt></ruby>
{{/if}}
{{#if (lt options.item.tp_kk 0)}}
+ <ruby>{{options.item.tp_kk}}<rt>{{localize "DSA41.attributes.long.strength"}}</rt></ruby>
{{/if}}
+ <ruby>{{formData.modifikator}}<rt>{{localize "DSA41.kampf.modifikator"}}</rt></ruby>
</div>
</div>

16
src/Dialogs/Attribute.hbs Normal file
View File

@ -0,0 +1,16 @@
<div class="parade_dialog">
<span class="colspan2">{{localize "DSA41.kampf.modifikator"}}</span>
{{>editable-input type="number" name="modifikator" class="colspan2" value=(lookup formData "modifikator") }}
<div class="dsa41-calculation colspan4 center">
<ruby>{{options.attribute.initial}}<rt>{{localize "DSA41.attributes.initial"}}</rt></ruby>
{{#if (ne options.attribute.advancement 0)}}
+ <ruby>{{options.attribute.advancement}}<rt>{{localize "DSA41.attributes.advancement"}}</rt></ruby>
{{/if}}
{{#if (ne options.attribute.modifier 0)}}
+ <ruby>{{options.attribute.modifier}}<rt>{{localize "DSA41.attributes.modifier"}}</rt></ruby>
{{/if}}
+ <ruby>{{formData.modifikator}}<rt>{{localize "DSA41.kampf.modifikator"}}</rt></ruby>
</div>
</div>

View File

@ -0,0 +1,59 @@
<div class="fernkampf_angriff_dialog">
<span>{{localize "DSA41.kampf.zielgroesse.label"}}</span>
<select name="ziel_groesse">
<option value="-2" {{#if (eq formData.ziel_groesse -2)}}selected{{/if}}>{{localize "DSA41.kampf.zielgroesse.sehr_gross"}}</option>
<option value="0" {{#if (eq formData.ziel_groesse 0)}}selected{{/if}}>{{localize "DSA41.kampf.zielgroesse.gross"}} </option>
<option value="2" {{#if (eq formData.ziel_groesse 2)}}selected{{/if}}>{{localize "DSA41.kampf.zielgroesse.mittel"}} </option>
<option value="4" {{#if (eq formData.ziel_groesse 4)}}selected{{/if}}>{{localize "DSA41.kampf.zielgroesse.klein"}} </option>
<option value="6" {{#if (eq formData.ziel_groesse 6)}}selected{{/if}}>{{localize "DSA41.kampf.zielgroesse.sehr_klein"}}</option>
<option value="8" {{#if (eq formData.ziel_groesse 8)}}selected{{/if}}>{{localize "DSA41.kampf.zielgroesse.winzig"}} </option>
</select>
<span>{{localize "DSA41.kampf.deckung.label"}}</span>
<select name="deckung">
<option value="0" {{#if (eq formData.deckung 0)}}selected{{/if}}>{{localize "DSA41.kampf.deckung.keine"}} </option>
<option value="2" {{#if (eq formData.deckung 2)}}selected{{/if}}>{{localize "DSA41.kampf.deckung.halb"}} </option>
<option value="4" {{#if (eq formData.deckung 4)}}selected{{/if}}>{{localize "DSA41.kampf.deckung.drei_viertel"}}</option>
</select>
<span>{{localize "DSA41.kampf.entfernung.label"}}</span>
<select name="entfernung">
<option value="-2" {{#if (eq formData.entfernung -2)}}selected{{/if}}>{{localize "DSA41.kampf.entfernung.sehr_nah"}} </option>
<option value="0" {{#if (eq formData.entfernung 0)}}selected{{/if}}>{{localize "DSA41.kampf.entfernung.nah"}} </option>
<option value="4" {{#if (eq formData.entfernung 4)}}selected{{/if}}>{{localize "DSA41.kampf.entfernung.mittel"}} </option>
<option value="8" {{#if (eq formData.entfernung 8)}}selected{{/if}}>{{localize "DSA41.kampf.entfernung.weit"}} </option>
<option value="12" {{#if (eq formData.entfernung 12)}}selected{{/if}}>{{localize "DSA41.kampf.entfernung.extrem_weit"}}</option>
</select>
<span>{{localize "DSA41.kampf.zielbewegung.label"}}</span>
<select name="ziel_bewegung">
<option value="-4" {{#if (eq formData.ziel_bewegung -4)}}selected{{/if}}>{{localize "DSA41.kampf.zielbewegung.unbeweglich"}} </option>
<option value="-2" {{#if (eq formData.ziel_bewegung -2)}}selected{{/if}}>{{localize "DSA41.kampf.zielbewegung.stillstehend"}}</option>
<option value="0" {{#if (eq formData.ziel_bewegung 0)}}selected{{/if}}>{{localize "DSA41.kampf.zielbewegung.leicht"}} </option>
<option value="2" {{#if (eq formData.ziel_bewegung 2)}}selected{{/if}}>{{localize "DSA41.kampf.zielbewegung.schnell"}} </option>
<option value="4" {{#if (eq formData.ziel_bewegung 4)}}selected{{/if}}>{{localize "DSA41.kampf.zielbewegung.sehr_schnell"}}</option>
</select>
<span>{{localize "DSA41.kampf.wind.label"}}</span>
<select name="wind">
<option value="0" {{#if (eq formData.wind 0)}}selected{{/if}}>{{localize "DSA41.kampf.wind.still"}} </option>
<option value="4" {{#if (eq formData.wind 4)}}selected{{/if}}>{{localize "DSA41.kampf.wind.seitenwind"}} </option>
<option value="8" {{#if (eq formData.wind 8)}}selected{{/if}}>{{localize "DSA41.kampf.wind.starker_seitenwind"}}</option>
</select>
<span>{{localize "DSA41.kampf.modifikator"}}</span>
{{>editable-input type="number" name="modifikator" value=(lookup formData "modifikator")}}
<div class="dsa41-calculation colspan4 center">
max(-2,
<ruby>{{formData.ziel_groesse}}<rt>{{localize "DSA41.kampf.zielgroesse.label"}}</rt></ruby>
+ <ruby>{{formData.deckung}}<rt>{{localize "DSA41.kampf.deckung.label"}}</rt></ruby>
+ <ruby>{{formData.ziel_bewegung}}<rt>{{localize "DSA41.kampf.zielbewegung.label"}}</rt></ruby>
)
+ <ruby>{{formData.entfernung}}<rt>{{localize "DSA41.kampf.entfernung.label"}}</rt></ruby>
+ <ruby>{{formData.wind}}<rt>{{localize "DSA41.kampf.wind.label"}}</rt></ruby>
+ <ruby>{{formData.modifikator}}<rt>{{localize "DSA41.kampf.modifikator"}}</rt></ruby>
</div>
</div>

View File

@ -0,0 +1,24 @@
<div class="fernkampf_trefferpunkte_dialog">
<span>{{localize "DSA41.kampf.entfernung.label"}}</span>
<select name="entfernung">
<option value="modifikator1" {{#if (eq formData.entfernung "modifikator1")}}selected{{/if}}>{{localize "DSA41.kampf.entfernung.sehr_nah"}} </option>
<option value="modifikator2" {{#if (eq formData.entfernung "modifikator2")}}selected{{/if}}>{{localize "DSA41.kampf.entfernung.nah"}} </option>
<option value="modifikator3" {{#if (eq formData.entfernung "modifikator3")}}selected{{/if}}>{{localize "DSA41.kampf.entfernung.mittel"}} </option>
<option value="modifikator4" {{#if (eq formData.entfernung "modifikator4")}}selected{{/if}}>{{localize "DSA41.kampf.entfernung.weit"}} </option>
<option value="modifikator5" {{#if (eq formData.entfernung "modifikator5")}}selected{{/if}}>{{localize "DSA41.kampf.entfernung.extrem_weit"}}</option>
</select>
<span>{{localize "DSA41.kampf.modifikator"}}</span>
{{>editable-input type="number" name="modifikator" value=(lookup formData "modifikator") }}
<span>{{localize "DSA41.kampf.crit"}}</span>
{{>editable-input type="checkbox" name="crit" class="center" value=(lookup formData "crit")}}
<div class="dsa41-calculation colspan4 center">
{{#if formData.crit}}<ruby>2 * <rt>{{localize "DSA41.kampf.crit"}}</rt></ruby>({{/if}}
<ruby>{{options.item.item.system.fernkampfwaffe.basis}}<rt>{{localize "DSA41.bewaffnung.fernkampfwaffe.basis"}}</rt></ruby>
{{#if formData.crit}}){{/if}}
+ <ruby>{{lookup options.item.item.system.fernkampfwaffe formData.entfernung}}<rt>{{localize "DSA41.kampf.entfernung.label"}}</rt></ruby>
+ <ruby>{{formData.modifikator}}<rt>{{localize "DSA41.kampf.modifikator"}}</rt></ruby>
</div>
</div>

34
src/Dialogs/Parade.hbs Normal file
View File

@ -0,0 +1,34 @@
<div class="parade_dialog">
<span>{{localize "DSA41.kampf.modifikator"}}</span>
{{>editable-input type="number" name="modifikator" value=(lookup formData "modifikator") }}
<span>{{localize "DSA41.kampf.crit"}}</span>
{{>editable-input type="checkbox" name="crit" class="center" value=(lookup formData "crit")}}
<div class="dsa41-calculation colspan4 center">
{{#if formData.crit}}({{/if}}
<ruby>{{options.item.basis_parade}}<rt>{{localize "DSA41.bewaffnung.nahkampfwaffe.basis"}}</rt></ruby>
+ <ruby>{{options.item.talent_parade}}<rt>{{localize "DSA41.talente.label"}}</rt></ruby>
{{#if (ne options.item.modifikator_parade 0)}}
+ <ruby>{{options.item.modifikator_parade}}<rt>{{localize "DSA41.bewaffnung.nahkampfwaffe.modifikator"}}</rt></ruby>
{{/if}}
{{#if (ne options.item.parierwaffe_parade 0)}}
+ <ruby>{{options.item.parierwaffe_parade}}<rt>{{localize "DSA41.bewaffnung.parierwaffe.label"}}</rt></ruby>
{{/if}}
{{#if (ne options.item.schild_parade 0)}}
+ <ruby>{{options.item.schild_parade}}<rt>{{localize "DSA41.bewaffnung.schild.label"}}</rt></ruby>
{{/if}}
{{#if (lt options.item.tp_kk 0)}}
+ <ruby>{{options.item.tp_kk}}<rt>{{localize "DSA41.attributes.long.strength"}}</rt></ruby>
{{/if}}
{{#if formData.crit}})<ruby> / 2<rt>{{localize "DSA41.kampf.crit"}}</rt></ruby>{{/if}}
+ <ruby>{{formData.modifikator}}<rt>{{localize "DSA41.kampf.modifikator"}}</rt></ruby>
</div>
</div>

View File

@ -0,0 +1,19 @@
<div class="trefferpunkte_dialog">
<span>{{localize "DSA41.kampf.modifikator"}}</span>
{{>editable-input type="number" name="modifikator" value=(lookup formData "modifikator") }}
<span>{{localize "DSA41.kampf.crit"}}</span>
{{>editable-input type="checkbox" name="crit" class="center" value=(lookup formData "crit")}}
<div class="dsa41-calculation colspan4 center">
{{#if formData.crit}}<ruby>2 * <rt>{{localize "DSA41.kampf.crit"}}</rt></ruby>({{/if}}
<ruby>{{options.item.item.system.nahkampfwaffe.basis}}<rt>{{localize "DSA41.bewaffnung.nahkampfwaffe.basis"}}</rt></ruby>
{{#if formData.crit}}){{/if}}
{{#if (ne options.item.tp_kk 0)}}
+ <ruby>{{options.item.tp_kk}}<rt>{{localize "DSA41.attributes.long.strength"}}</rt></ruby>
{{/if}}
+ <ruby>{{formData.modifikator}}<rt>{{localize "DSA41.kampf.modifikator"}}</rt></ruby>
</div>
</div>

View File

@ -1,4 +1,4 @@
<div class="editable-input editable-{{type}}">
<div class="editable-input editable-{{type}} {{class}}">
{{#if (eq type "checkbox")}}
<input type="checkbox" name="{{name}}" {{checked value}}>
{{else}}

View File

@ -3,7 +3,7 @@
<img class="item-image" src="{{ item.img }}" title="{{ item.name }}" {{#if editable}}data-edit="img"{{/if}}>
<div class="col">
{{>editable-input type="text" name="name" value=item.name placeholder=(localize "DSA41.name")}}
<div class="row">
<div class="row gap">
{{>editable-input type="number" name="system.gewicht" value=item.system.gewicht placeholder=(localize "DSA41.weight")}}
{{>editable-input type="number" name="system.preis" value=item.system.preis placeholder=(localize "DSA41.price")}}
</div>

View File

@ -3,7 +3,7 @@
<img class="item-image" src="{{ item.img }}" title="{{ item.name }}" {{#if editable}}data-edit="img"{{/if}}>
<div class="col">
{{>editable-input type="text" name="name" value=item.name placeholder=(localize "DSA41.name")}}
<div class="row">
<div class="row gap">
{{>editable-input type="number" name="system.gewicht" value=item.system.gewicht placeholder=(localize "DSA41.weight")}}
{{>editable-input type="number" name="system.preis" value=item.system.preis placeholder=(localize "DSA41.price")}}
</div>

View File

@ -3,7 +3,7 @@
<img class="item-image" src="{{ item.img }}" title="{{ item.name }}" {{#if editable}}data-edit="img"{{/if}}>
<div class="col">
{{>editable-input type="text" name="name" value=item.name placeholder=(localize "DSA41.name")}}
<div class="row">
<div class="row gap">
{{>editable-input type="number" name="system.gewicht" value=item.system.gewicht placeholder=(localize "DSA41.weight")}}
{{>editable-input type="number" name="system.preis" value=item.system.preis placeholder=(localize "DSA41.price")}}
</div>

View File

@ -1,5 +1,7 @@
<div class="dsa41-tooltip">
<ruby>{{talent_attacke}}<rt>{{localize "DSA41.talente.label"}}</rt></ruby>
<ruby>{{basis_attacke}}<rt>{{localize "DSA41.bewaffnung.nahkampfwaffe.basis"}}</rt></ruby>
+ <ruby>{{talent_attacke}}<rt>{{localize "DSA41.talente.label"}}</rt></ruby>
{{#if (ne modifikator_attacke 0)}}
+ <ruby>{{modifikator_attacke}}<rt>{{localize "DSA41.bewaffnung.nahkampfwaffe.modifikator"}}</rt></ruby>

View File

@ -0,0 +1,4 @@
<div class="dsa41-tooltip">
<ruby>{{basis_attacke}}<rt>{{localize "DSA41.bewaffnung.fernkampfwaffe.basis"}}</rt></ruby>
+ <ruby>{{talent_attacke}}<rt>{{localize "DSA41.talente.label"}}</rt></ruby>
</div>

View File

@ -0,0 +1,3 @@
<div class="dsa41-tooltip">
<ruby>{{item.system.fernkampfwaffe.basis}}<rt>{{localize "DSA41.bewaffnung.fernkampfwaffe.basis"}}</rt></ruby>
</div>

View File

@ -1,5 +1,7 @@
<div class="dsa41-tooltip">
<ruby>{{talent_parade}}<rt>{{localize "DSA41.talente.label"}}</rt></ruby>
<ruby>{{basis_parade}}<rt>{{localize "DSA41.bewaffnung.nahkampfwaffe.basis"}}</rt></ruby>
+ <ruby>{{talent_parade}}<rt>{{localize "DSA41.talente.label"}}</rt></ruby>
{{#if (ne modifikator_parade 0)}}
+ <ruby>{{modifikator_parade}}<rt>{{localize "DSA41.bewaffnung.nahkampfwaffe.modifikator"}}</rt></ruby>

View File

@ -27,7 +27,10 @@
"attacke": "Attacke",
"parade": "Parade",
"trefferpunkte": "Trefferpunkte"
"trefferpunkte": "Trefferpunkte",
"fernkampf-attacke": "Attacke",
"fernkampf-trefferpunkte": "Trefferpunkte"
},
"character": {
@ -354,11 +357,60 @@
},
"kampf": {
"bewaffnung": "Bewaffnung",
"bewaffnung": "Bewaffnung",
"attacke": "Attacke",
"parade": "Parade",
"trefferpunkte": "Trefferpunkte",
"ruestungen": "Rüstungen"
"ruestungen": "Rüstungen",
"modifikator": "Modifikator",
"crit": "Glückliche Attacke",
"zielgroesse": {
"label": "Zielgröße",
"winzig": "Winzig",
"sehr_klein": "Sehr Klein",
"klein": "Klein",
"mittel": "Mittel",
"gross": "Groß",
"sehr_gross": "Sehr Groß"
},
"deckung": {
"label": "Deckung",
"keine": "Keine",
"halb": "Halb",
"drei_viertel": "Drei Viertel"
},
"entfernung": {
"label": "Entfernung",
"sehr_nah": "Sehr Nah",
"nah": "Nah",
"mittel": "Mittel",
"weit": "Weit",
"extrem_weit": "Extrem Weit"
},
"zielbewegung": {
"label": "Bewegung des Ziels",
"unbeweglich": "Unbeweglich",
"stillstehend": "Stillstehend",
"leicht": "Leicht",
"schnell": "Schnell",
"sehr_schnell": "Sehr Schnell"
},
"wind": {
"label": "Wind",
"still": "Still",
"seitenwind": "Böiger Seitenwind",
"starker_seitenwind": "Starker Seitenwind"
}
}
}
}

View File

@ -14,7 +14,7 @@
& [data-action] {
cursor: pointer;
&:hover {
&:not(button):hover {
transform: scale(1.05);
}
}
@ -58,6 +58,10 @@
flex: 0;
}
& .gap {
gap: 0.5rem;
}
& .subgrid {
display: grid;
grid-template-rows: subgrid;
@ -105,7 +109,6 @@
& .editable-input {
flex: 1;
padding: 0px 3px;
& input {
border: none;
@ -132,6 +135,7 @@
& .item-image {
width: 80px;
height: 80px;
margin-right: 0.5rem;
}
& .die {
@ -161,6 +165,9 @@
&.die-attacke { fill: #b22319; }
&.die-parade { fill: #388834; }
&.die-trefferpunkte { fill: #0c0c0c; }
&.die-fernkampf-attacke { fill: #388834; }
&.die-fernkampf-trefferpunkte { fill: #0c0c0c; }
}
& .tabs {
@ -194,10 +201,6 @@
width: 40px;
height: 40px;
}
& .item-name {
gap: 0.5rem;
}
}
& .list-header {
@ -231,6 +234,17 @@
}
}
&.Dialog > .window-content {
gap: 1rem;
& > :first-child {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 0.5rem;
align-items: center;
}
}
& [data-application-part="Bewaffnung"] {
& .tab {
grid-template-columns: minmax(0, max-content) minmax(0, 1fr) minmax(0, max-content) minmax(0, 1fr);
@ -302,4 +316,9 @@
}
}
}
& .dsa41-calculation {
font-size: 18px;
padding-top: 0.5rem;
}
}

View File

@ -1,10 +1,10 @@
const { TypeDataModel } = foundry.abstract;
const { SchemaField, NumberField, StringField, BooleanField } = foundry.data.fields;
const { ActorSheetV2, ItemSheetV2 } = foundry.applications.sheets;
const { HandlebarsApplicationMixin } = foundry.applications.api;
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
const { OperatorTerm, NumericTerm } = foundry.dice.terms;
Hooks.once("init", function() {
Hooks.once("init", async function() {
CONFIG.Combat.initiative.formula = "1d6 + @computed.ini_basiswert[INI-Basiswert]";
CONFIG.Actor.dataModels.Player = DSA41_CharacterData;
@ -32,7 +32,7 @@ Hooks.once("init", function() {
]
});
loadTemplates({
await loadTemplates({
"editable-input": "systems/dsa-4th-edition/src/EditableInput.hbs",
"attribute_tooltip": "systems/dsa-4th-edition/src/Tooltips/Attribute.hbs",
@ -40,6 +40,14 @@ Hooks.once("init", function() {
"attacke_tooltip": "systems/dsa-4th-edition/src/Tooltips/Attacke.hbs",
"parade_tooltip": "systems/dsa-4th-edition/src/Tooltips/Parade.hbs",
"trefferpunkte_tooltip": "systems/dsa-4th-edition/src/Tooltips/Trefferpunkte.hbs",
"fernkampf_attacke_tooltip": "systems/dsa-4th-edition/src/Tooltips/FernkampfAttacke.hbs",
"fernkampf_trefferpunkte_tooltip": "systems/dsa-4th-edition/src/Tooltips/FernkampfTrefferpunkte.hbs",
"trefferpunkte_dialog": "systems/dsa-4th-edition/src/Dialog/Trefferpunkte.hbs",
"fernkampf_angriff_dialog": "systems/dsa-4th-edition/src/Dialogs/FernkampfAngriff.hbs",
"fernkampf_trefferpunkte_dialog": "systems/dsa-4th-edition/src/Dialogs/FernkampfTrefferpunkte.hbs",
});
});
@ -300,9 +308,10 @@ class DSA41_CharacterData extends TypeDataModel {
attributes_without_modifiers: {},
kampf: {
talente: {},
waffen: {},
ruestungen: {},
talente: {},
waffen: {},
fernkampf_waffen: {},
ruestungen: {},
ruestungen_gesamt: {
kopf: 0,
brust: 0,
@ -375,6 +384,9 @@ class DSA41_CharacterData extends TypeDataModel {
trefferpunkte: "",
trefferpunkte_display: "",
basis_attacke: 0,
basis_parade: 0,
talent_attacke: 0,
talent_parade: 0,
@ -390,10 +402,13 @@ class DSA41_CharacterData extends TypeDataModel {
schild_parade: 0,
};
computed.basis_attacke = this.computed.at_basiswert;
computed.basis_parade = this.computed.pa_basiswert;
const talent = item.system.nahkampfwaffe.kampftalente;
computed.talent_attacke = this.computed.kampf.talente[talent].attacke;
computed.talent_parade = this.computed.kampf.talente[talent].parade;
computed.talent_attacke = this.kampf_talente[talent]?.attacke ?? 0;
computed.talent_parade = this.kampf_talente[talent]?.parade ?? 0;
computed.modifikator_attacke = item.system.nahkampfwaffe.modifikator_attacke;
computed.modifikator_parade = item.system.nahkampfwaffe.modifikator_parade;
@ -416,13 +431,35 @@ class DSA41_CharacterData extends TypeDataModel {
computed.schild_parade += schild.system.schild.modifikator_parade;
}
computed.attacke = computed.talent_attacke + computed.modifikator_attacke + computed.parierwaffe_attacke + computed.schild_attacke + Math.min(computed.tp_kk, 0);
computed.parade = computed.talent_parade + computed.modifikator_parade + computed.parierwaffe_parade + computed.schild_parade + Math.min(computed.tp_kk, 0);
computed.attacke = computed.basis_attacke + computed.talent_attacke + computed.modifikator_attacke + computed.parierwaffe_attacke + computed.schild_attacke + Math.min(computed.tp_kk, 0);
computed.parade = computed.basis_parade + computed.talent_parade + computed.modifikator_parade + computed.parierwaffe_parade + computed.schild_parade + Math.min(computed.tp_kk, 0);
computed.trefferpunkte = get_minified_formula(item.system.nahkampfwaffe.basis + (computed.tp_kk != 0 ? " + " + computed.tp_kk : ""));
computed.trefferpunkte_display = computed.trefferpunkte.replace(/[\+\-]/, (op) => "<br>" + op);
}
}
for (const item of equipped_fernkampfwaffen) {
let computed = this.computed.kampf.fernkampf_waffen[item._id] = {
item: item,
attacke: 0,
trefferpunkte: "",
trefferpunkte_display: "",
basis_attacke: 0,
talent_attacke: 0,
};
computed.basis_attacke = this.computed.fk_basiswert;
const talent = item.system.nahkampfwaffe.kampftalente;
computed.talent_attacke = this.kampf_talente[talent]?.attacke ?? 0;
computed.attacke = computed.basis_attacke + computed.talent_attacke;
computed.trefferpunkte = get_minified_formula(item.system.fernkampfwaffe.basis);
computed.trefferpunkte_display = computed.trefferpunkte.replace(/[\+\-]/, (op) => "<br>" + op);
}
}
}
@ -551,6 +588,81 @@ function DSA41_ApplicationMixin(BaseApplication) {
return DSA41_Application;
}
class DSA41_Dialog extends DSA41_ApplicationMixin(ApplicationV2) {
static PARTS = {
Eigenschaft: { template: "systems/dsa-4th-edition/src/Dialogs/Attribute.hbs" },
Attacke: { template: "systems/dsa-4th-edition/src/Dialogs/Attacke.hbs" },
Parade: { template: "systems/dsa-4th-edition/src/Dialogs/Parade.hbs" },
Trefferpunkte: { template: "systems/dsa-4th-edition/src/Dialogs/Trefferpunkte.hbs" },
FernkampfAttacke: { template: "systems/dsa-4th-edition/src/Dialogs/FernkampfAttacke.hbs" },
FernkampfTrefferpunkte: { template: "systems/dsa-4th-edition/src/Dialogs/FernkampfTrefferpunkte.hbs" },
footer: { template: "templates/generic/form-footer.hbs" },
};
static DEFAULT_OPTIONS = {
classes: [ "DSA41", "Dialog" ],
window: {
title: "Dialog",
minimizable: false,
resizable: false
},
tag: "form",
form: {
closeOnSubmit: false,
submitOnChange: true,
}
};
get formData() {
const data = Object.fromEntries(
new FormData(this.element).entries().map(([key, value])=>{
if (typeof value != "string") return [key, value];
return isNaN(value) ? [key, value] : [key, Number(value)];
})
);
return data;
}
buttons = [{
type: "submit",
label: "Confirm"
}];
static async wait(dialog_type, options) {
return new Promise((resolve, reject) => {
const dialog = new this({
dialog_type: dialog_type,
form: {
handler: (event, form, formData) => {
if (event.type != "submit") {
dialog.render({ force: false });
return;
}
dialog.close();
resolve(dialog.formData);
}
},
...options,
});
dialog.render({ force: true });
});
}
_configureRenderOptions(options) {
super._configureRenderOptions(options);
options.parts = [ this.options.dialog_type, "footer" ];
}
_onFirstRender(context, options) {
this.render(options)
}
}
class DSA41_ActorSheet extends DSA41_ApplicationMixin(ActorSheetV2) {
static PARTS = {
ActorSheet: { template: "systems/dsa-4th-edition/src/ActorSheet.hbs" },
@ -560,15 +672,132 @@ class DSA41_ActorSheet extends DSA41_ApplicationMixin(ActorSheetV2) {
position: { width: "800", height: "650" },
actions: {
"roll": async function(event, target) {
const roll_formula = event.target.closest("[data-roll]").dataset.roll;
var roll_formula = event.target.closest("[data-roll]").dataset.roll;
const roll_type = event.target.closest("[data-roll-type]").dataset.rollType;
const success_value = event.target.closest("[data-success-value]")?.dataset.successValue;
const item_id = event.target.closest("[data-item-id]")?.dataset.itemId;
const item = this.document.items.get(item_id);
let flavor = game.i18n.localize("DSA41.roll_types." + roll_type);
if (typeof success_value !== 'undefined') {
flavor += " <= " + success_value;
}
if (roll_type == "courage" || roll_type == "cleverness" || roll_type == "intuition" || roll_type == "charisma" ||
roll_type == "dexterity" || roll_type == "agility" || roll_type == "constitution" || roll_type == "strength") {
const title = game.i18n.localize("DSA41.roll_types." + roll_type) + ": " + this.document.name;
const data = await DSA41_Dialog.wait("Eigenschaft", { window: { title: title }, attribute: this.document.system.attributes[roll_type] });
let flavor = game.i18n.localize("DSA41.roll_types." + roll_type);
if (typeof success_value !== 'undefined') {
flavor += " <= " + (Number(success_value) + data.modifikator);
}
let roll = new Roll(roll_formula, this.document.system);
roll.toMessage({
speaker: ChatMessage.getSpeaker({ actor: this.document }),
flavor: flavor,
});
return;
}
if (roll_type == "attacke") {
const item = this.document.system.computed.kampf.waffen[item_id];
const title = game.i18n.localize("DSA41.roll_types." + roll_type) + ": " + item.name;
const data = await DSA41_Dialog.wait("Attacke", { window: { title: title }, item: item });
let flavor = game.i18n.localize("DSA41.roll_types." + roll_type);
if (typeof success_value !== 'undefined') {
flavor += " <= " + (Number(success_value) + data.modifikator);
}
let roll = new Roll(roll_formula, this.document.system);
roll.toMessage({
speaker: ChatMessage.getSpeaker({ actor: this.document }),
flavor: flavor,
});
return;
}
if (roll_type == "parade") {
const item = this.document.system.computed.kampf.waffen[item_id];
const title = game.i18n.localize("DSA41.roll_types." + roll_type) + ": " + item.name;
const data = await DSA41_Dialog.wait("Parade", { window: { title: title }, item: item });
let flavor = game.i18n.localize("DSA41.roll_types." + roll_type);
if (typeof success_value !== 'undefined') {
flavor += " <= " + (Number(success_value) + data.modifikator);
}
if (data.crit == "on") {
roll_formula = "round((" + roll_formula + ") / 2)";
}
let roll = new Roll(roll_formula, this.document.system);
roll.toMessage({
speaker: ChatMessage.getSpeaker({ actor: this.document }),
flavor: flavor,
});
return;
}
if (roll_type == "trefferpunkte") {
const item = this.document.system.computed.kampf.waffen[item_id];
const title = game.i18n.localize("DSA41.roll_types." + roll_type) + ": " + item.name;
const data = await DSA41_Dialog.wait("Trefferpunkte", { window: { title: title }, item: item });
if (data.crit == "on") {
roll_formula = "2 * (" + item.item.system.nahkampfwaffe.basis + ")" + " + " + item.tp_kk;
}
let roll = new Roll(roll_formula + " + " + data.modifikator, this.document.system);
roll.toMessage({
speaker: ChatMessage.getSpeaker({ actor: this.document }),
flavor: flavor,
});
return;
}
if (roll_type == "fernkampf-attacke") {
const title = game.i18n.localize("DSA41.roll_types." + roll_type) + ": " + item.name;
const data = await DSA41_Dialog.wait("FernkampfAttacke", { window: { title: title }, item: this.document.system.computed.kampf.fernkampf_waffen[item_id] });
const groessen_modifikator = Math.max(data.ziel_groesse + data.deckung + data.ziel_bewegung, -2);
const andere_modifikator = data.entfernung + data.wind + data.modifikator;
const total_modifikator = groessen_modifikator + andere_modifikator;
let roll = new Roll(roll_formula + " + " + total_modifikator, this.document.system);
roll.toMessage({
speaker: ChatMessage.getSpeaker({ actor: this.document }),
flavor: game.i18n.localize("DSA41.roll_types." + roll_type),
});
return;
}
if (roll_type == "fernkampf-trefferpunkte") {
const title = game.i18n.localize("DSA41.roll_types." + roll_type) + ": " + item.name;
const data = await DSA41_Dialog.wait("FernkampfTrefferpunkte", { window: { title: title }, item: this.document.system.computed.kampf.fernkampf_waffen[item_id] });
const entfernung = item.system.fernkampfwaffe[data.entfernung];
if (data.crit == "on") {
roll_formula = "2 * (" + roll_formula + ")";
}
let roll = new Roll(roll_formula + " + " + (entfernung + data.modifikator), this.document.system);
roll.toMessage({
speaker: ChatMessage.getSpeaker({ actor: this.document }),
flavor: game.i18n.localize("DSA41.roll_types." + roll_type),
});
return;
}
let roll = new Roll(roll_formula, this.document.system);
roll.toMessage({
speaker: ChatMessage.getSpeaker({ actor: this.document }),