diff --git a/Das_Schwarze_Auge_4-1/dsa4_1_character_sheet_roll20.css b/Das_Schwarze_Auge_4-1/dsa4_1_character_sheet_roll20.css index 11aff49cff..7aa36c5257 100644 --- a/Das_Schwarze_Auge_4-1/dsa4_1_character_sheet_roll20.css +++ b/Das_Schwarze_Auge_4-1/dsa4_1_character_sheet_roll20.css @@ -482,6 +482,14 @@ The solution: convert the s to type="text" and make them look like normal } /*----------------------------------------------Combat--------------------------------------*/ +.charsheet p { + font-family: serif; + font-size: 1em; +} +.charsheet .not-implemented { + font-style: italic; +} + .charsheet table.table-armour-zones td { text-align: left; } @@ -528,13 +536,16 @@ The solution: convert the s to type="text" and make them look like normal display: none; } -.charsheet table.hideable-melee-weapons input[type="text"]:disabled.stat-immutable, -.charsheet table.hideable-melee-weapons td, .charsheet table.hideable-ranged-weapons input[type="text"]:disabled.stat-immutable, .charsheet table.hideable-ranged-weapons td { text-align: center; } +.charsheet .active-melee input.be-at-mod-hint:checked ~ div span.be-at-mod-hint, +.charsheet .active-melee input.be-pa-mod-hint:checked ~ div span.be-pa-mod-hint { + display: inline; +} + .charsheet input.input-weapon-name, .charsheet input[type="text"]:disabled.input-weapon-name { width: 11em; @@ -802,11 +813,14 @@ The solution: convert the s to type="text" and make them look like normal .charsheet .verstecke-myranor:checked ~ table tr.myranor, .charsheet .verstecke-myranor:checked ~ input.myranor, .charsheet .verstecke-myranor:checked ~ div.myranor, -.charsheet .verstecke-myranor:checked ~ span.myranor { +.charsheet .verstecke-myranor:checked ~ span.myranor, +.charsheet .verstecke-myranor:checked ~ select > option.myranor { display: none; } -.charsheet .verstecke-myranor:not(:checked) ~ div.myranor-hide { +.charsheet .verstecke-myranor:not(:checked) ~ div.myranor-hide, +.charsheet .verstecke-myranor:not(:checked) ~ table tr.myranor-hide, +.charsheet .verstecke-myranor:not(:checked) ~ select > option.myranor-hide { display: none; } diff --git a/Das_Schwarze_Auge_4-1/dsa4_1_character_sheet_roll20.html b/Das_Schwarze_Auge_4-1/dsa4_1_character_sheet_roll20.html index e869373134..c15f137c01 100644 --- a/Das_Schwarze_Auge_4-1/dsa4_1_character_sheet_roll20.html +++ b/Das_Schwarze_Auge_4-1/dsa4_1_character_sheet_roll20.html @@ -891,6 +891,7 @@
PA
TaW
+
Anderthalbhänder
@@ -903,7 +904,7 @@
-
+
Armbrust
C
BE−5
@@ -913,6 +914,28 @@
+ +
+
Bastardstäbe
+
D
+
BE−2
+ + + + +
+
+ +
+
Bela (Armbrust)
+
C
+
BE−5
+ + + + +
+
Belagerungswaffen
@@ -979,6 +1002,17 @@
+ +
+
Feuerwaffen
+
C
+
BE−5
+ + + + +
+
Hiebwaffen
@@ -1200,19 +1234,23 @@
+ - +
+ +
+
-
+ @@ -1396,6 +1434,56 @@
+ +
+ + +
+ +
+ + + + + +
+ +
+ + + +
+
@@ -1893,7 +1981,7 @@
- +
- +
@@ -2193,6 +2281,7 @@
+ @@ -6693,6 +6782,51 @@
+ +
+ + +
+ +
+ + + + + + +
+
@@ -8245,6 +8379,7 @@ +
@@ -8262,9 +8397,9 @@ + - @@ -8302,7 +8437,7 @@
- @@ -14131,11 +14266,11 @@ ℹ️

- ℹ️ + ℹ️

- ℹ️ + ℹ️

ℹ️

- ℹ️ + ℹ️

@@ -14364,6 +14499,7 @@ + @@ -14460,6 +14597,7 @@ + @@ -14556,6 +14695,7 @@ + @@ -14652,6 +14793,7 @@ + @@ -14766,13 +14909,16 @@ + + + + + Waffe
-
AT:
-
PA:
+
AT: 🪨
+
PA: 🪨
TP: W6 +
TP/KK:
DK:
@@ -15377,8 +15535,8 @@
-
AT:
-
PA:
+
AT: 🪨
+
PA: 🪨
TP: W6 +
TP/KK:
DK:
@@ -15388,8 +15546,8 @@
-
AT:
-
PA:
+
AT: 🪨
+
PA: 🪨
TP: W6 +
TP/KK:
DK:
@@ -15399,8 +15557,8 @@
-
AT:
-
PA:
+
AT: 🪨
+
PA: 🪨
TP: W6 +
TP/KK:
DK:
@@ -15413,7 +15571,7 @@
AT:
-
PA:
+
PA: 🪨
TP(A):
TP/KK:
DK: H
@@ -15424,8 +15582,8 @@ Parierwaffe
-
AT:
-
PA:
+
AT: 🪨
+
PA: 🪨
TP:
TP/KK:
DK: H
@@ -15467,7 +15625,7 @@ - + @@ -15807,7 +15965,8 @@ - + + @@ -16176,15 +16335,6 @@
- - - - - - - -
Relevante Vor- und Nachteile (?)
Dieser Abschnitt ist umgezogen. Sie finden sich im „Fertigkeiten“-Tab (zwischen dem „Grundwerte“- und dem „Inventar“-Tab) unter dem neuen Namen „berücksichtigte Vor- und Nachteile“.
-

Kampfsonderfertigkeiten

@@ -16192,12 +16342,12 @@ @@ -16222,12 +16372,12 @@ @@ -16237,27 +16387,27 @@ @@ -16272,7 +16422,7 @@ @@ -16282,12 +16432,12 @@ @@ -16297,17 +16447,17 @@ @@ -16317,17 +16467,17 @@ @@ -16337,12 +16487,12 @@ @@ -16389,84 +16539,90 @@
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +

Fernkampf

+ - + + + + + + + - + + + + + + + - + + + + + + +
- +
- +
+ +
@@ -16477,6 +16633,11 @@
+ +
@@ -16497,11 +16658,16 @@
+ +
@@ -16512,6 +16678,11 @@
+ +
@@ -16532,19 +16703,29 @@
- + +
+
- + +
+
- +
@@ -16554,32 +16735,32 @@
- +
- +
- +
- +
- +
- +
@@ -16589,158 +16770,165 @@
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
+

Legende: +

    +
  • kursiver Text: Sonderfertigkeit wird vom Charakterbogen nicht berücksichtigt
  • +
  • normaler Text mit Info: Sonderfertigkeit wird vom Charakterbogen teilweise berücksichtigt (Info enthält Details)
  • +
  • normaler Text ohne Info: Sonderfertigkeit wird vom Charakterbogen voll berücksichtigt
  • +
+

Wundeffekte

@@ -17002,9 +17190,44 @@
-

Update auf Version 20240901

+

Update auf Version 20241002

-

Video: noch in Bearbeitung, Link wird in einer zukünftigen Version nachgereicht

+
Neue Features
+

+

    +
  • + Automatischer Abzug von Projektilen bei Fernkampfproben + + +
  • +
  • Neue Talente hinzugefügt: „Freies Fliegen“ (Körper) und „Fluggerätesteuern“ (Handwerk)
  • +
  • Neue Kampftechniken hinzugefügt: „Bastardstäbe“ (Myranor, Dunkle Zeiten; immer sichtbar) und „Feuerwaffen“ (nur Myranor)
  • +
+

+
Design
+

+

    +
  • Abzüge auf AT/PA durch hohe BE werden jetzt durch ein Fels-Emoji (🪨) angezeigt
  • +
  • Myranischen Alias „Bela“ für Armbrüste hinzugefügt
  • +
  • Tab „Kampf“, Untertab „V/N & SF“: Hinweis auf „neuen“ Ort der vom Charakterbogen unterstützten Vor- und Nachteile entfernt
  • +
  • Tab „Kampf“, Untertab „V/N & SF“: Überschrift entfernt
  • +
  • Tab „Kampf“, Untertab „V/N & SF“: Hinweise auf Grad der charakterbogenseitigen Berücksichtigung der aufgelisteten Kampfsonderfertigkeiten hinzugefügt
  • +
+

+
Fehlerbehebungen
+

+

    +
  • Texte der Infoboxen in ausgeklappten Myranorbeschwörungszaubern an die realen Verhältnisse angeglichen
  • +
  • Konsistente Verwendung von „Sinnenschärfe“
  • +
+

+
+ +
+ +

🎬 Update auf Version 20240901

+
+

Video:

Neues Feature: Myranische Beschwörungszauber

    @@ -17433,7 +17656,7 @@ - + @@ -18244,7 +18467,7 @@
- „Das Schwarze Auge“-Heldenbogen für Roll20.net, Version + „Das Schwarze Auge“-Heldenbogen für Roll20.net, Version
@@ -20128,6 +20351,21 @@ {{/rollWasFumble() wurf}} {{/^rollLess() eff_wert 0}} +{{#rollTotal() ammohint 0}} + + Verbleibende Munition: {{ammoRemaining}}. + +{{/rollTotal() ammohint 0}} +{{#rollTotal() ammohint 1}} + + Hinweis: Wurf wurde ausgeführt, ohne dass Munition vorhanden war. + +{{/rollTotal() ammohint 1}} +{{#rollTotal() ammohint 2}} + + Hinweis: Munitionswert ungültig. ℹ️ + +{{/rollTotal() ammohint 2}}
@@ -20507,12 +20745,14 @@ const statAttrs = [ const combatTechniques = { "anderthalbhander": { type: "melee", ebe: -2, "at-only": false }, "armbrust": { type: "ranged", ebe: -5, "at-only": true }, + "bastardstaebe": { type: "melee", ebe: -2, "at-only": false }, "belagerungswaffen": { type: "ranged", ebe: undefined, "at-only": true }, "blasrohr": { type: "ranged", ebe: -5, "at-only": true }, "bogen": { type: "ranged", ebe: -3, "at-only": true }, "diskus": { type: "ranged", ebe: -2, "at-only": true }, "dolche": { type: "melee", ebe: -1, "at-only": false }, "fechtwaffen": { type: "melee", ebe: -1, "at-only": false }, + "feuerwaffen": { type: "ranged", ebe: -5, "at-only": true }, "hiebwaffen": { type: "melee", ebe: -4, "at-only": false }, "infanteriewaffen": { type: "melee", ebe: -3, "at-only": false }, "kettenstabe": { type: "melee", ebe: -1, "at-only": false }, @@ -20609,6 +20849,7 @@ const defaultValues = { "atbasis": 5, "AT_Anderthalbhander": 5, + "AT_bastardstaebe": 5, "AT_dolche": 5, "AT_fechtwaffen": 5, "AT_hiebwaffen": 5, @@ -20633,6 +20874,7 @@ const defaultValues = { "pabasis": 5, "PA_Anderthalbhander": 5, + "PA_bastardstaebe": 5, "PA_dolche": 5, "PA_fechtwaffen": 5, "PA_hiebwaffen": 5, @@ -20675,7 +20917,7 @@ const defaultValues = { "AT_Blasrohr": 5, "AT_Bogen": 5, "AT_Diskus": 5, - "AT_peitsche": 5, + "AT_feuerwaffen": 5, "AT_Schleuder": 5, "AT_Wurfbeile": 5, "AT_Wurfmesser": 5, @@ -20757,6 +20999,8 @@ const defaultValues = { "BE": 0, "be_at_mod": 0, "be_pa_mod": 0, + "be_at_mod_hint": 0, + "be_pa_mod_hint": 0, "BE_RG": 0, "BE_RG_INI": 0, @@ -20846,12 +21090,14 @@ Individual spell names are generally based on a/the short name. One of the excep const talents = [ 't_ka_anderthalbhaender', 't_ka_armbrust', + 't_ka_bastardstaebe', 't_ka_belagerungswaffen', 't_ka_blasrohr', 't_ka_bogen', 't_ka_diskus', 't_ka_dolche', 't_ka_fechtwaffen', + 't_ka_feuerwaffen', 't_ka_hiebwaffen', 't_ka_infanteriewaffen', 't_ka_kettenstaebe', @@ -20874,6 +21120,7 @@ const talents = [ 't_ko_akrobatik', 't_ko_athletik', 't_ko_fliegen', + 't_ko_freiesfliegen', 't_ko_gaukeleien', 't_ko_immanspiel', 't_ko_klettern', @@ -21004,6 +21251,7 @@ const talents = [ 't_h_feinmechanik', 't_h_feuersteinbearbeitung', 't_h_fleischer', + 't_h_fluggeraetesteuern', 't_h_gerber', 't_h_glaskunst', 't_h_grobschmied', @@ -21123,6 +21371,7 @@ const talents_ebe = [ 't_ko_akrobatik', 't_ko_athletik', 't_ko_fliegen', + 't_ko_freiesfliegen', 't_ko_gaukeleien', 't_ko_klettern', 't_ko_koerperbeherrschung', @@ -21546,12 +21795,14 @@ In the long run, all attributes should be migrated to the new ones. const talentsData = { 't_ka_anderthalbhaender': {'internal': "Anderthalbhander", 'ui': "Anderthalbhänder"}, 't_ka_armbrust': {'internal': "armbrust", 'ui': "Armbrust"}, + 't_ka_bastardstaebe': {'internal': "bastardstaebe", 'ui': "Bastardstäbe"}, 't_ka_belagerungswaffen': {'internal': "belagerungswaffen", 'ui': "Belagerungswaffen"}, 't_ka_blasrohr': {'internal': "blasrohr", 'ui': "Blasrohr"}, 't_ka_bogen': {'internal': "bogen", 'ui': "Bogen"}, 't_ka_diskus': {'internal': "diskus", 'ui': "Diskus"}, 't_ka_dolche': {'internal': "dolche", 'ui': "Dolche"}, 't_ka_fechtwaffen': {'internal': "fechtwaffen", 'ui': "Fechtwaffen"}, + 't_ka_feuerwaffen': {'internal': "feuerwaffen", 'ui': "Feuerwaffen"}, 't_ka_hiebwaffen': {'internal': "hiebwaffen", 'ui': "Hiebwaffen"}, 't_ka_infanteriewaffen': {'internal': "infanteriewaffen", 'ui': "Infanteriewaffen"}, 't_ka_kettenstaebe': {'internal': "kettenstabe", 'ui': "Kettenstäbe"}, @@ -21574,6 +21825,7 @@ const talentsData = { 't_ko_akrobatik': {'internal': "akrobatik", 'ui': "Akrobatik"}, 't_ko_athletik': {'internal': "athletik", 'ui': "Athletik"}, 't_ko_fliegen': {'internal': "fliegen", 'ui': "Fliegen"}, + 't_ko_freiesfliegen': {'internal': "freiesfliegen", 'ui': "Freies Fliegen"}, 't_ko_gaukeleien': {'internal': "gaukeleien", 'ui': "Gaukeleien"}, 't_ko_immanspiel': {'internal': "immanspiel", 'ui': "Immanspiel"}, 't_ko_klettern': {'internal': "klettern", 'ui': "Klettern"}, @@ -21704,6 +21956,7 @@ const talentsData = { 't_h_feinmechanik': {'internal': "feinmechanik", 'ui': "Feinmechanik"}, 't_h_feuersteinbearbeitung': {'internal': "feuersteinbearbeitung", 'ui': "Feuersteinbearbeitung"}, 't_h_fleischer': {'internal': "fleischer", 'ui': "Fleischer"}, + 't_h_fluggeraetesteuern': {'internal': "fluggeraetesteuern", 'ui': "Fluggerätesteuern"}, 't_h_gerber': {'internal': "gerber", 'ui': "Gerber"}, 't_h_glaskunst': {'internal': "glaskunst", 'ui': "Glaskunst"}, 't_h_grobschmied': {'internal': "grobschmied", 'ui': "Grobschmied"}, @@ -22214,6 +22467,7 @@ const effectiveEncumbrance = { "t_ko_akrobatik": { "value": 2, "type": "factor" }, "t_ko_athletik": { "value": 2, "type": "factor" }, "t_ko_fliegen": { "value": 1, "type": "factor" }, + "t_ko_freiesfliegen": { "value": 2, "type": "factor" }, "t_ko_gaukeleien": { "value": 2, "type": "factor" }, "t_ko_klettern": { "value": 2, "type": "factor" }, "t_ko_koerperbeherrschung": { "value": 2, "type": "factor" }, @@ -22823,7 +23077,7 @@ const meleeData = { */ }, 'k_meisterliches_entwaffnen_parade_parierwaffe': { - 'ui': 'Meisterliches Entwaffnen (Pairerwaffenparade)', + 'ui': 'Meisterliches Entwaffnen (Parierwaffenparade)', 'typ': 'pa-parierwaffe', 'rollCount': 1, 'mod': '0', @@ -23402,7 +23656,7 @@ function safeGetAttrs( attrsToGet, callback ) { var badDef = []; var errors = [0, 0]; - for (req of attrsToGet) { + for (let req of attrsToGet) { // Check for missing attributes and try setting a default value if (!Object.hasOwn(attrs, req)) { errors[0] += 1; @@ -23440,7 +23694,7 @@ function safeSetAttrs( attrsToSet, options = "", callback = function() {}) { var badDef = []; var errors = 0; - for (req in attrsToSet) { + for (let req in attrsToSet) { // Check existing attributes for undefined or NaN if ( typeof attrsToSet[req] === 'undefined' || @@ -23653,7 +23907,7 @@ function generateShortRollTag (integer) { var result = []; var rest = integer; - for (n = digits; n >= 0; n--) { + for (let n = digits; n >= 0; n--) { result.push(charset[Math.trunc(rest/Math.pow(base, n))]); rest = rest % Math.pow(base, n); } @@ -23682,6 +23936,24 @@ function DSAsane (value, type) { } switch(type) { + case "int": + // General + // Must be number of parseInt()-able number + // integer + if (!limitedIntValid(value, -Infinity, Infinity)) { + debugLog(func, "Value '" + value + "' check against type '" + type + "' failed."); + sane = false; + } + break; + case "non-negative int": + // General + // Must be number of parseInt()-able number + // Non-negative integer + if (!limitedIntValid(value, 0, Infinity)) { + debugLog(func, "Value '" + value + "' check against type '" + type + "' failed."); + sane = false; + } + break; case "stat": // MU, KL, IN, ... // Must be number or parseInt()-able number @@ -23722,7 +23994,8 @@ function DSAsane (value, type) { // Limited set of combat techniques to choose from // Must be within the set const meleeCombatTechniques = [ - "anderthalbhander", "dolche", "fechtwaffen", + "anderthalbhander", "bastardstaebe", "dolche", + "fechtwaffen", "hiebwaffen", "infanteriewaffen", "kettenstabe", "kettenwaffen", "lanzenreiten", "peitsche", "raufen", "ringen", "sabel", @@ -23761,7 +24034,7 @@ function countStats (statsArray) { debugLog(caller, "Array is empty."); } - for (stat of statsArray) + for (let stat of statsArray) { if (validStats.has(stat)) { @@ -23790,7 +24063,7 @@ function extractStats (statsArray) { debugLog(caller, "Array is empty."); } - for (entry of statsArray) + for (let entry of statsArray) { let result = entry.match(statPattern); if (result) @@ -23915,7 +24188,7 @@ function migrationCheck() { if not and it is the first migration, than the function name is saved as "firstFunction" if it is not the first migration to apply it is added to "functionsToCall" array */ - for (version of versionsWithMigrations) { + for (let version of versionsWithMigrations) { if (dataVersion < version) { var functionName = "migrateTo" + version; debugLog(caller, "dataVersion " + dataVersion + " is older than version " + version + " which needs a migration. Invoking migration function: " + functionName); @@ -23976,11 +24249,11 @@ function initializeSheet(migrationChain) { // Combat /// Melee AT Values "AT_Aktiv", "AT_Aktiv_TaW", "atbasis", - "AT_Anderthalbhander", "AT_dolche", "AT_fechtwaffen", "AT_hiebwaffen", "AT_infanteriewaffen", "AT_kettenstabe", "AT_kettenwaffen", "AT_lanzenreiten", "AT_peitsche", "AT_raufen", "AT_ringen", "AT_sabel", "AT_schwerter", "AT_speere", "AT_stabe", "AT_zweihandflegel", "AT_zweihand-hiebwaffen", "AT_zweihandschwerter", + "AT_Anderthalbhander", "AT_bastardstaebe", "AT_dolche", "AT_fechtwaffen", "AT_hiebwaffen", "AT_infanteriewaffen", "AT_kettenstabe", "AT_kettenwaffen", "AT_lanzenreiten", "AT_peitsche", "AT_raufen", "AT_ringen", "AT_sabel", "AT_schwerter", "AT_speere", "AT_stabe", "AT_zweihandflegel", "AT_zweihand-hiebwaffen", "AT_zweihandschwerter", /// Melee PA Values "PA_Aktiv", "PA_Aktiv_TaW", "pabasis", - "PA_Anderthalbhander", "PA_dolche", "PA_fechtwaffen", "PA_hiebwaffen", "PA_infanteriewaffen", "PA_kettenstabe", "PA_kettenwaffen", "PA_lanzenreiten", "PA_peitsche", "PA_raufen", "PA_ringen", "PA_sabel", "PA_schwerter", "PA_speere", "PA_stabe", "PA_zweihandflegel", "PA_zweihand-hiebwaffen", "PA_zweihandschwerter", + "PA_Anderthalbhander", "PA_bastardstaebe", "PA_dolche", "PA_fechtwaffen", "PA_hiebwaffen", "PA_infanteriewaffen", "PA_kettenstabe", "PA_kettenwaffen", "PA_lanzenreiten", "PA_peitsche", "PA_raufen", "PA_ringen", "PA_sabel", "PA_schwerter", "PA_speere", "PA_stabe", "PA_zweihandflegel", "PA_zweihand-hiebwaffen", "PA_zweihandschwerter", /// Melee other "NKW_Aktiv1", "NKW_Aktiv2", "NKW_Aktiv3", "NKW_Aktiv4", @@ -23990,7 +24263,7 @@ function initializeSheet(migrationChain) { /// Ranged Combat "FK_Aktiv", "fkbasis", - "AT_Armbrust", "AT_Belagerungswaffen", "AT_Blasrohr", "AT_Bogen", "AT_Diskus", "AT_peitsche", "AT_Schleuder", "AT_Wurfbeile", "AT_Wurfmesser", "AT_Wurfspeere", + "AT_Armbrust", "AT_Belagerungswaffen", "AT_Blasrohr", "AT_Bogen", "AT_Diskus", "AT_feuerwaffen", "AT_Schleuder", "AT_Wurfbeile", "AT_Wurfmesser", "AT_Wurfspeere", "FKWFK1", "FKWFK2", "FKWFK3", "FKWFK4", "FKWtyp1", "FKWtyp2", "FKWtyp3", "FKWtyp4", @@ -24035,9 +24308,9 @@ function initializeSheet(migrationChain) { defaults = { "Basis": 8, "Mod": 0 }; safeguardAttrs = []; - for ( stem of attrStems ) + for ( let stem of attrStems ) { - for ( ext of attrExtensions ) + for ( let ext of attrExtensions ) { safeguardAttrs.push(stem + "_" + ext); } @@ -24048,7 +24321,7 @@ function initializeSheet(migrationChain) { safeguardAttrs.concat(["data_version"]), function(v, missing, badDef) { - debugLog(caller, "Safeguard attributes:", v); + debugLog(caller, "Safeguard attributes:", v); var attrs = { "sheet_initialized": false }; var dataVersionSet = true; @@ -24059,7 +24332,7 @@ function initializeSheet(migrationChain) { } if ( dataVersionSet === false ) { - for ( attr of safeguardAttrs ) + for ( let attr of safeguardAttrs ) { // None of the safeguard attributes should be undefined (missing) or have a bad value (NaN, undefined) if ( @@ -24075,9 +24348,9 @@ function initializeSheet(migrationChain) { { // The safeguard attributes should all be at their default values debugLog(caller, "Checking safeguard attributes ..."); - for ( attr of safeguardAttrs ) + for ( let attr of safeguardAttrs ) { - for ( ext of attrExtensions ) + for ( let ext of attrExtensions ) { if ( attr.search(ext) > -1 ) { @@ -24097,7 +24370,7 @@ function initializeSheet(migrationChain) { } if ( attrs["sheet_initialized"] === false ) { - for ( attr of attrsToInit ) + for ( let attr of attrsToInit ) { attrs[attr] = getDefaultValue(attr); } @@ -24131,7 +24404,8 @@ var versionsWithMigrations = [ 20230618, 20240414, 20240510, - 20240519 + 20240519, + 20241002 ]; /* @@ -24215,7 +24489,7 @@ function migrateTo20190427 (migrationChain) { debugLog(caller, "Migration: No gifts found, nothing to migrate."); } else { debugLog(caller, "Migration: Found old gifts, continuing ..."); - for(var i=0; i < gabenIDs.length; i++) { + for(let i=0; i < gabenIDs.length; i++) { attrsToGet.push("repeating_GabenTalente_" + gabenIDs[i] + "_TalentName"); attrsToGet.push("repeating_GabenTalente_" + gabenIDs[i] + "_Eigenschaft1"); attrsToGet.push("repeating_GabenTalente_" + gabenIDs[i] + "_Eigenschaft2"); @@ -24230,7 +24504,7 @@ function migrateTo20190427 (migrationChain) { debugLog(caller, "Migration: No meta-talents found, nothing to migrate."); } else { debugLog(caller, "Migration: Found old meta-talents, continuing ..."); - for(var i=0; i < metatalenteIDs.length; i++) { + for(let i=0; i < metatalenteIDs.length; i++) { attrsToGet.push("repeating_MetaTalente_" + metatalenteIDs[i] + "_TalentName"); attrsToGet.push("repeating_MetaTalente_" + metatalenteIDs[i] + "_Eigenschaft1"); attrsToGet.push("repeating_MetaTalente_" + metatalenteIDs[i] + "_Eigenschaft2"); @@ -24247,7 +24521,7 @@ function migrateTo20190427 (migrationChain) { let defaultGiftTaW = 3; let defaultMetaTaW = 0; let update = {}; - for(var i=0; i < gabenIDs.length; i++) { + for(let i=0; i < gabenIDs.length; i++) { let newrow = generateRowID(); let current = gabenIDs[i]; let prefixNew = "repeating_Gaben_" + newrow; @@ -24288,7 +24562,7 @@ function migrateTo20190427 (migrationChain) { } debugLog(caller, update); - for(var i=0; i < metatalenteIDs.length; i++) { + for(let i=0; i < metatalenteIDs.length; i++) { let newrow = generateRowID(); let current = metatalenteIDs[i]; let prefixNew = "repeating_Metatalente201904_" + newrow; @@ -24362,7 +24636,7 @@ function migrateTo20200809(migrationChain) { var attrsToChange = {}; var activeCount = 0; - for (var i = 1; i <= 4; i++) { + for (let i = 1; i <= 4; i++) { if (v["NKW_Aktiv" + i] === "1") { activeCount += 1; } @@ -24466,7 +24740,7 @@ function migrateTo20210413(migrationChain) { values["KK"] = Math.max(0, parseInt(values["KK_Basis"]) + parseInt(values["KK_mod"])); let attrsToChange = {}; - for (var i = 1; i <= 4; i++) { + for (let i = 1; i <= 4; i++) { attrsToChange["NKW" + i + "_SB"] = calculateTpKKModFromValuesAndWeaponNumber(values, i); } @@ -24497,7 +24771,7 @@ function migrateTo20210413(migrationChain) { // Updates for INI modifiers // Set INI modifier from (main) weapon var weaponini = 0; - for (weapon = 1; weapon <= 4; weapon++) { + for (let weapon = 1; weapon <= 4; weapon++) { if (DSAsane(values["INIModNKW" + weapon], "ini-mod-weapon")) { debugLog(caller, "INIModNKW" + weapon, "is", values["INIModNKW" + weapon]); weaponini = parseInt(values["INIModNKW" + weapon]); @@ -24586,7 +24860,7 @@ function migrateTo20210718 (migrationChain) { results = checkRequiredProperties(requirements, values); if (results["errors"] >= 1) { debugLog(caller, "Missing properties: '" + results["missing"].toString() + "'. Using default values. 0 for 'Ges_BE', 'BE_Last', 'BE_TaW' and 'sf_rustungsgewohnungIII'."); - for (req of requirements) { + for (let req of requirements) { if (!Object.hasOwn(values, req)) { values[req] = defaultValue; } @@ -24594,7 +24868,7 @@ function migrateTo20210718 (migrationChain) { } // Check sanity var reqsToCheck = requirements.slice(0,3); - for (req of reqsToCheck) { + for (let req of reqsToCheck) { if (!DSAsane(values[req], "encumbrance")) { debugLog(caller, "'" + req + "' not sane, set to default value (" + defaultValue + ")."); values[req] = defaultValue; @@ -24664,16 +24938,16 @@ function migrateTo20220116(migrationChain) { // Build list of attributes var attrsToGet = ["character_name"]; var ebeTalents = [] - for(talent of talents_ebe) + for(let talent of talents_ebe) { ebeTalents.push(talent + "-ebe"); } - for(attr of [].concat(talents, ebeTalents, spells)) + for(let attr of [].concat(talents, ebeTalents, spells)) { attrsToGet.push(attr + "_action"); } safeGetAttrs(attrsToGet, function(v) { - for (attr of attrsToGet) + for (let attr of attrsToGet) { // No action buttons for character name and combat techniques required if (attr.match("t_ka_") || attr === "character_name") continue; @@ -24707,7 +24981,7 @@ function migrateTo20220604(migrationChain) { var attrsToChange = {}; safeGetAttrs(attrsToGet, function(v) { - for (attr of attrsToGet) + for (let attr of attrsToGet) { if (attr.match("visibli")) { @@ -25235,7 +25509,7 @@ function migrateTo20240519(migrationChain) { safeGetAttrs(attrsToGet, function (v) { var attrsToChange = {}; - for (property in attrMap) + for (let property in attrMap) { let oldAttr = attrMap[property]; if (v[oldAttr] === 0) @@ -25250,6 +25524,46 @@ function migrateTo20240519(migrationChain) { }); }); } + +/* + Migration steps: + - Initialize newly added attributes (Bastardstäbe, Feuerwaffen, hints for mods from encumbrance) +*/ +function migrateTo20241002(migrationChain) { + const caller = "migrateTo20241002"; + debugLog(caller, "Invoked."); + + const attrsToGet = [ "be_at_mod", "be_pa_mod"]; + safeGetAttrs(attrsToGet, function(values) { + let attrsToInit = { + "AT_bastardstaebe": 5, + "PA_bastardstaebe": 5, + "AT_feuerwaffen": 5, + "be_at_mod_hint": 0, + "be_pa_mod_hint": 0 + }; + + for (let attr of attrsToGet) + { + if (DSAsane(values[attr], "int")) + { + let value = values[attr]; + let hintAttr = attr + "_hint"; + if (value > 0) + { + attrsToInit[hintAttr] = 1; + } else { + attrsToInit[hintAttr] = 0; + } + } + } + + debugLog(caller, "attrsToInit", attrsToInit); + safeSetAttrs(attrsToInit, {}, function () { + callNextMigration(migrationChain); + }); + }); +} /* migration end */ /* base values begin */ on( @@ -25647,7 +25961,7 @@ function getTalentRollResults(results) { { let successes = 0; let failures = 0; - for (roll of rolls) + for (let roll of rolls) { if (roll <= success) { @@ -25679,7 +25993,7 @@ function getTalentRollResults(results) { } else { if (effTaW < 0) { - for (roll in rolls) + for (let roll in rolls) { effRolls[roll] = rolls[roll] + Math.abs(effTaW); } @@ -25687,7 +26001,7 @@ function getTalentRollResults(results) { } // TaP-Verbrauch für jeden Wurf - for (roll in effRolls) + for (let roll in effRolls) { TaPstar -= Math.max(0, effRolls[roll] - stats[roll]); } @@ -25977,7 +26291,7 @@ function replaceSpellStats(spellData, stats) { const spellStatFreq = countStats(spellData["stats"]); // Determine whether spell has potentially beneficial stat situation - for (stat of relevantStats){ + for (let stat of relevantStats) { if (spellStatFreq[stat] >= 2) { multiStat = stat; @@ -25995,7 +26309,7 @@ function replaceSpellStats(spellData, stats) { // Act only if the other stat is also better than the multi stat if (otherStat === betterStat) { - for (i in spellData["stats"]) + for (let i in spellData["stats"]) { if (spellData["stats"][i] === multiStat) { @@ -26042,7 +26356,7 @@ function replaceSpellStats(spellData, stats) { } // Replacement - for (stat in spellData["stats"]) + for (let stat in spellData["stats"]) { if (spellData["stats"][stat] === replacement["replaceable"]) { @@ -26078,7 +26392,7 @@ function replaceSpellStats(spellData, stats) { // Replacement // Up to three stats might match, but only one can be replaced -> determine index to replace after iterating over all stats let lowestStat = { "value": Infinity, "index": null }; - for (stat in spellData["stats"]) + for (let stat in spellData["stats"]) { // Get values of replaceable stats at the index of the replaceable stat if (replacement["replaceable"].includes(spellData["stats"][stat])) @@ -26235,7 +26549,7 @@ on(spells.map(spell => "clicked:" + spell + "-action").join(" "), (info) => { let festeMatrix = v["v_festematrix"] === "0" ? false : true; let spruchhemmung = v["n_spruchhemmung"] === "0" ? false : true; - for (roll of rolls) + for (let roll of rolls) { if (roll <= success) { @@ -26256,7 +26570,7 @@ on(spells.map(spell => "clicked:" + spell + "-action").join(" "), (info) => { criticality = -1; festeMatrixSave = true; - for (roll of rolls) + for (let roll of rolls) { if ( (roll > success) && @@ -26302,7 +26616,7 @@ on(spells.map(spell => "clicked:" + spell + "-action").join(" "), (info) => { } else { if (effTaW < 0) { - for (roll in rolls) + for (let roll in rolls) { effRolls[roll] = rolls[roll] + Math.abs(effTaW); } @@ -26310,7 +26624,7 @@ on(spells.map(spell => "clicked:" + spell + "-action").join(" "), (info) => { } // TaP-Verbrauch für jeden Wurf - for (roll in effRolls) + for (let roll in effRolls) { TaPstar -= Math.max(0, effRolls[roll] - stats[roll]); } @@ -26453,7 +26767,7 @@ on("change:repeating_conjuration-spells-myranor", function(info) { ]; var prefix = "repeating_conjuration-spells-myranor_" + trigger["rowID"] + "_"; - for (attr of repeatingAttrs) + for (let attr of repeatingAttrs) { attrsToGet.push(prefix + attr); } @@ -26541,7 +26855,7 @@ on("change:repeating_conjuration-spells-myranor", function(info) { if (doNothing === false) { - for (statIndex in stats) + for (let statIndex in stats) { attrsToChange[prefix + "stat" + statIndex] = stats[statIndex]; } @@ -26612,7 +26926,7 @@ on("clicked:repeating_conjuration-spells-myranor:spell-action", (info) => { "v_festematrix", "n_spruchhemmung" ]; - for (attr of rowAttrs) + for (let attr of rowAttrs) { attrsToGet.push( [ @@ -26627,7 +26941,7 @@ on("clicked:repeating_conjuration-spells-myranor:spell-action", (info) => { // Shortening of result properties const repeatingRegex = new RegExp(`${attrPrefix}_${triggerRow}_`); var shortResults = {}; - for (attr of attrsToGet) + for (let attr of attrsToGet) { // attrs from outside the repeating section are already short if (!attr.match(repeatingRegex)) @@ -26737,7 +27051,7 @@ on("clicked:repeating_conjuration-spells-myranor:spell-action", (info) => { let festeMatrix = v["v_festematrix"] === "0" ? false : true; let spruchhemmung = v["n_spruchhemmung"] === "0" ? false : true; - for (roll of rolls) + for (let roll of rolls) { if (roll <= success) { @@ -26758,7 +27072,7 @@ on("clicked:repeating_conjuration-spells-myranor:spell-action", (info) => { criticality = -1; festeMatrixSave = true; - for (roll of rolls) + for (let roll of rolls) { if ( (roll > success) && @@ -26804,7 +27118,7 @@ on("clicked:repeating_conjuration-spells-myranor:spell-action", (info) => { } else { if (effTaW < 0) { - for (roll in rolls) + for (let roll in rolls) { effRolls[roll] = rolls[roll] + Math.abs(effTaW); } @@ -26812,7 +27126,7 @@ on("clicked:repeating_conjuration-spells-myranor:spell-action", (info) => { } // TaP-Verbrauch für jeden Wurf - for (roll in effRolls) + for (let roll in effRolls) { TaPstar -= Math.max(0, effRolls[roll] - stats[roll]); } @@ -26888,7 +27202,7 @@ on('clicked:eidsegen-action', async (info) => { // Negativer TaW: |effTaW| zu Teilwürfen addieren if (effTaW < 0) { - for (roll in rolls) + for (let roll in rolls) { effRolls[roll] = rolls[roll] + Math.abs(effTaW); } @@ -26896,7 +27210,7 @@ on('clicked:eidsegen-action', async (info) => { } // TaP-Verbrauch für jeden Wurf - for (roll in effRolls) + for (let roll in effRolls) { TaPstar -= Math.max(0, effRolls[roll] - stats[roll]); } @@ -26925,68 +27239,68 @@ There are two possible results: one and only one active shield; no active shield We need to make sure that the right thing™ is done */ on("change:repeating_shields:shield_active", function(eventInfo) { - var caller = "???"; - // Get the source shield, its row ID and whether it was turned on or off - var sourceShield = eventInfo.sourceAttribute; - var sourceShieldId = extractRowId(sourceShield); - var mode = eventInfo.newValue; + var caller = "Action Listener for Active Shields"; + // Get the source shield, its row ID and whether it was turned on or off + var sourceShield = eventInfo.sourceAttribute; + var sourceShieldId = extractRowId(sourceShield); + var mode = eventInfo.newValue; - // Get all the shields - getSectionIDs("shields", function(idarray) { - var prefix = "repeating_shields_"; - var suffix = "_shield_active"; + // Get all the shields + getSectionIDs("shields", function(idarray) { + var prefix = "repeating_shields_"; + var suffix = "_shield_active"; - // Gather all the shield_active states (as attribute names) - var attrsToGet = []; - for(id of idarray) { - attrsToGet.push(prefix + id + suffix); + // Gather all the shield_active states (as attribute names) + var attrsToGet = []; + for(let id of idarray) { + attrsToGet.push(prefix + id + suffix); + } + + // Get the attributes + safeGetAttrs( attrsToGet, function(shieldActiveStates) { + var activeShields = []; + var activeShieldRowId = ""; + + for (let attr of attrsToGet) { + if (shieldActiveStates[ attr ] === "on") { + activeShields.push(attr); } + } - // Get the attributes - safeGetAttrs( attrsToGet, function(shieldActiveStates) { - var activeShields = []; - var activeShieldRowId = ""; - - for (attr of attrsToGet) { - if (shieldActiveStates[ attr ] === "on") { - activeShields.push(attr); - } + var attrsToChange = {}; + // 0 active shields? Deactivate shields, nothing to do. + if (activeShields.length === 0) { + // do something for deactivation + debugLog(caller, "Deactivating shields/parry weapons ..."); + activeShieldRowId = ""; + } else if (activeShields.length === 1) { + // this is the active shield + var activeShield = activeShields[0]; + debugLog(caller, "Setting active shields/parry weapons to \"" + activeShield + "\""); + activeShieldRowId = extractRowId(activeShield); + } else { + // If one shield got activated, deactivate all others. + if (mode === "on") { + activeShieldRowId = sourceShieldId; + debugLog(caller, "Setting active shields/parry weapons to \"" + sourceShield + "\" and deactivating all others ..."); + for (let activeShield of activeShields) { + if (activeShield !== sourceShield) { + attrsToChange[ activeShield ] = 0; } - - var attrsToChange = {}; - // 0 active shields? Deactivate shields, nothing to do. - if (activeShields.length === 0) { - // do something for deactivation - debugLog(caller, "Deactivating shields/parry weapons ..."); - activeShieldRowId = ""; - } else if (activeShields.length === 1) { - // this is the active shield - var activeShield = activeShields[0]; - debugLog(caller, "Setting active shields/parry weapons to \"" + activeShield + "\""); - activeShieldRowId = extractRowId(activeShield); - } else { - // If one shield got activated, deactivate all others. - if (mode === "on") { - activeShieldRowId = sourceShieldId; - debugLog(caller, "Setting active shields/parry weapons to \"" + sourceShield + "\" and deactivating all others ..."); - for (activeShield of activeShields) { - if (activeShield !== sourceShield) { - attrsToChange[ activeShield ] = 0; - } - } - } else { - // If one shield got deactivated and there is another active shield, keep one and only one shield. (This case should not happen.) - debugLog(caller, "Impossible case triggered: One shield deactivated and more than one active shield remaining. Deactivating all but the first active shield."); - activeShieldRowId = extractRowId(activeShields[0]); - for (var i = 1; i < activeShields.length; i++) { - attrsToChange[ activeShields[i] ] = 0; - } - } - } - attrsToChange[ "activeShieldRowId" ] = activeShieldRowId; - safeSetAttrs( attrsToChange, { silent: true }, () => { calculateCombatValues() } ); - }); + } + } else { + // If one shield got deactivated and there is another active shield, keep one and only one shield. (This case should not happen.) + debugLog(caller, "Impossible case triggered: One shield deactivated and more than one active shield remaining. Deactivating all but the first active shield."); + activeShieldRowId = extractRowId(activeShields[0]); + for (let i = 1; i < activeShields.length; i++) { + attrsToChange[ activeShields[i] ] = 0; + } + } + } + attrsToChange[ "activeShieldRowId" ] = activeShieldRowId; + safeSetAttrs( attrsToChange, { silent: true }, () => { calculateCombatValues() } ); }); + }); }); /* Helper attributes "TP_W_Aktiv" and "TP_Bonus_Aktiv" for combat calculations @@ -27081,19 +27395,22 @@ function(eventInfos) { // Not working: Peitsche on( "change:kk change:kk_basis change:kk_mod "+ -"change:taw_anderthalbhander change:taw_dolche change:taw_fechtwaffen " + +"change:taw_anderthalbhander change:taw_bastardstaebe change:taw_dolche " + +"change:taw_fechtwaffen " + "change:taw_hiebwaffen change:taw_infanteriewaffen change:taw_kettenstabe " + "change:taw_kettenwaffen change:taw_lanzenreiten change:taw_peitsche " + "change:taw_raufen change:taw_ringen change:taw_sabel change:taw_schwerter " + "change:taw_speere change:taw_stabe change:taw_zweihandflegel " + "change:taw_zweihand-hiebwaffen change:taw_zweihandschwerter " + -"change:at_anderthalbhander change:at_dolche change:at_fechtwaffen change:at_hiebwaffen " + +"change:at_anderthalbhander change:at_bastardstaebe change:at_dolche change:at_fechtwaffen " + +"change:at_hiebwaffen " + "change:at_infanteriewaffen change:at_kettenstabe change:at_kettenwaffen " + "change:at_lanzenreiten change:at_peitsche change:at_raufen change:at_ringen change:at_sabel " + "change:at_schwerter change:at_speere change:at_stabe change:at_zweihandflegel " + "change:at_zweihand-hiebwaffen change:at_zweihandschwerter " + "change:pabasis " + -"change:pa_anderthalbhander change:pa_dolche change:pa_fechtwaffen change:pa_hiebwaffen " + +"change:pa_anderthalbhander change: pa_bastardstaebe change:pa_dolche change:pa_fechtwaffen " + +"change:pa_hiebwaffen " + "change:pa_infanteriewaffen change:pa_kettenstabe change:pa_kettenwaffen " + "change:pa_lanzenreiten change:pa_peitsche change:pa_raufen change:pa_ringen change:pa_sabel " + "change:pa_schwerter change:pa_speere change:pa_stabe change:pa_zweihandflegel " + @@ -27113,87 +27430,87 @@ function(eventInfos) { function calculateCombatValues() { var caller = "calculateCombatValues"; - debugLog(caller, "calculating combat values"); - // Zunächst sammeln wir Infos über die aktiven Waffen und Schilde - // "activeShieldRowId" can be the id of either a shield or a parry weapon - safeGetAttrs([ "activeShieldRowId", "NKW_Aktiv1", "NKW_Aktiv2", "NKW_Aktiv3", "NKW_Aktiv4" ], function(rowIdValues) { - var weapon = 0; - if (rowIdValues["NKW_Aktiv1"] === "1") { - weapon = 1; - } else if (rowIdValues["NKW_Aktiv2"] === "1") { - weapon = 2; - } else if (rowIdValues["NKW_Aktiv3"] === "1") { - weapon = 3; - } else if (rowIdValues["NKW_Aktiv4"] === "1") { - weapon = 4; - } else { - // didn't find an active weapon. setting values to 0; - attrsToChange = { - "AT_Aktiv": 0, - "AT_Aktiv_TaW": "0", - "PA_Aktiv": 0, - "PA_Aktiv_TaW": "0", - "shield_pa": 0, - "parryweapon_at": 0, - "parryweapon_pa": 0, - "shield_pa_available": "0", - "parryweapon_pa_available": "0" - } - safeSetAttrs(attrsToChange); - return; - } - var variablesToGet = [ - "KK", "KK_Basis", "KK_mod", - "NKW_AT_typ" + weapon, "NKW" + weapon + "ATMod", - "NKW_PA_typ" + weapon, "NKW" + weapon + "PAMod", - "INIModNKW" + weapon, - "NKW" + weapon + "_Spez", "NKW" + weapon + "_SB", - "TaW_anderthalbhander", "TaW_dolche", "TaW_fechtwaffen", "TaW_hiebwaffen", - "TaW_infanteriewaffen", "TaW_kettenstabe", "TaW_kettenwaffen", "TaW_lanzenreiten", "TaW_peitsche", "TaW_raufen", "TaW_ringen", "TaW_sabel", - "TaW_schwerter", "TaW_speere", "TaW_stabe", "TaW_zweihandflegel", "TaW_zweihand-hiebwaffen", "TaW_zweihandschwerter", - "AT_anderthalbhander", "AT_dolche", "AT_fechtwaffen", "AT_hiebwaffen", - "AT_infanteriewaffen", "AT_kettenstabe", "AT_kettenwaffen", "AT_lanzenreiten", "AT_peitsche", "AT_raufen", "AT_ringen", "AT_sabel", - "AT_schwerter", "AT_speere", "AT_stabe", "AT_zweihandflegel", "AT_zweihand-hiebwaffen", "AT_zweihandschwerter", - "AT_mod_wounds", - "PA_anderthalbhander", "PA_dolche", "PA_fechtwaffen", "PA_hiebwaffen", - "PA_infanteriewaffen", "PA_kettenstabe", "PA_kettenwaffen", "PA_lanzenreiten", "PA_peitsche", "PA_raufen", "PA_ringen", "PA_sabel", - "PA_schwerter", "PA_speere", "PA_stabe", "PA_zweihandflegel", "PA_zweihand-hiebwaffen", "PA_zweihandschwerter", - "PA_mod_wounds", - "PABasis", "sf_schildkampfI", "sf_schildkampfII", "sf_linkhand", "sf_parierwaffenI", "sf_parierwaffenII", "be_at_mod", "be_pa_mod", - "sf_beidhandigerkampfI", "sf_beidhandigerkampfII", "vorteil_beidhaendig" - ]; + debugLog(caller, "calculating combat values"); + // Zunächst sammeln wir Infos über die aktiven Waffen und Schilde + // "activeShieldRowId" can be the id of either a shield or a parry weapon + safeGetAttrs([ "activeShieldRowId", "NKW_Aktiv1", "NKW_Aktiv2", "NKW_Aktiv3", "NKW_Aktiv4" ], function(rowIdValues) { + var weapon = 0; + if (rowIdValues["NKW_Aktiv1"] === "1") { + weapon = 1; + } else if (rowIdValues["NKW_Aktiv2"] === "1") { + weapon = 2; + } else if (rowIdValues["NKW_Aktiv3"] === "1") { + weapon = 3; + } else if (rowIdValues["NKW_Aktiv4"] === "1") { + weapon = 4; + } else { + // didn't find an active weapon. setting values to 0; + attrsToChange = { + "AT_Aktiv": 0, + "AT_Aktiv_TaW": "0", + "PA_Aktiv": 0, + "PA_Aktiv_TaW": "0", + "shield_pa": 0, + "parryweapon_at": 0, + "parryweapon_pa": 0, + "shield_pa_available": "0", + "parryweapon_pa_available": "0" + } + safeSetAttrs(attrsToChange); + return; + } + var variablesToGet = [ + "KK", "KK_Basis", "KK_mod", + "NKW_AT_typ" + weapon, "NKW" + weapon + "ATMod", + "NKW_PA_typ" + weapon, "NKW" + weapon + "PAMod", + "INIModNKW" + weapon, + "NKW" + weapon + "_Spez", "NKW" + weapon + "_SB", + "TaW_anderthalbhander", "TaW_bastardstaebe", "TaW_dolche", "TaW_fechtwaffen", "TaW_hiebwaffen", + "TaW_infanteriewaffen", "TaW_kettenstabe", "TaW_kettenwaffen", "TaW_lanzenreiten", "TaW_peitsche", "TaW_raufen", "TaW_ringen", "TaW_sabel", + "TaW_schwerter", "TaW_speere", "TaW_stabe", "TaW_zweihandflegel", "TaW_zweihand-hiebwaffen", "TaW_zweihandschwerter", + "AT_anderthalbhander", "AT_bastardstaebe", "AT_dolche", "AT_fechtwaffen", "AT_hiebwaffen", + "AT_infanteriewaffen", "AT_kettenstabe", "AT_kettenwaffen", "AT_lanzenreiten", "AT_peitsche", "AT_raufen", "AT_ringen", "AT_sabel", + "AT_schwerter", "AT_speere", "AT_stabe", "AT_zweihandflegel", "AT_zweihand-hiebwaffen", "AT_zweihandschwerter", + "AT_mod_wounds", + "PA_anderthalbhander", "PA_bastardstaebe", "PA_dolche", "PA_fechtwaffen", "PA_hiebwaffen", + "PA_infanteriewaffen", "PA_kettenstabe", "PA_kettenwaffen", "PA_lanzenreiten", "PA_peitsche", "PA_raufen", "PA_ringen", "PA_sabel", + "PA_schwerter", "PA_speere", "PA_stabe", "PA_zweihandflegel", "PA_zweihand-hiebwaffen", "PA_zweihandschwerter", + "PA_mod_wounds", + "PABasis", "sf_schildkampfI", "sf_schildkampfII", "sf_linkhand", "sf_parierwaffenI", "sf_parierwaffenII", "be_at_mod", "be_pa_mod", + "sf_beidhandigerkampfI", "sf_beidhandigerkampfII", "vorteil_beidhaendig" + ]; - // Wurde dieses Event dadurch ausgelöst, dass sich die Aktivität eines Schildes geändert hat, dann müssen wir die activeShieldRowId noch manuell bearbeiten, da diese eventuell noch nicht korrekt gesetzt wurde - var activeShieldRowId = rowIdValues["activeShieldRowId"]; + // Wurde dieses Event dadurch ausgelöst, dass sich die Aktivität eines Schildes geändert hat, dann müssen wir die activeShieldRowId noch manuell bearbeiten, da diese eventuell noch nicht korrekt gesetzt wurde + var activeShieldRowId = rowIdValues["activeShieldRowId"]; - // Wenn es ein aktives Schild (oder Parierwaffe) gibt, möchten wir auch dessen Werte mit laden - if (activeShieldRowId) { - variablesToGet.push("repeating_shields_" + activeShieldRowId + "_shield_at_mod"); - variablesToGet.push("repeating_shields_" + activeShieldRowId + "_shield_pa_mod"); - variablesToGet.push("repeating_shields_" + activeShieldRowId + "_shield_bf"); - variablesToGet.push("repeating_shields_" + activeShieldRowId + "_shield_ini_mod"); - variablesToGet.push("repeating_shields_" + activeShieldRowId + "_shield_name"); - variablesToGet.push("repeating_shields_" + activeShieldRowId + "_shield_tp"); - variablesToGet.push("repeating_shields_" + activeShieldRowId + "_shield_tpkk"); - variablesToGet.push("repeating_shields_" + activeShieldRowId + "_shield_type"); - variablesToGet.push("repeating_shields_" + activeShieldRowId + "_combat_technique"); - } + // Wenn es ein aktives Schild (oder Parierwaffe) gibt, möchten wir auch dessen Werte mit laden + if (activeShieldRowId) { + variablesToGet.push("repeating_shields_" + activeShieldRowId + "_shield_at_mod"); + variablesToGet.push("repeating_shields_" + activeShieldRowId + "_shield_pa_mod"); + variablesToGet.push("repeating_shields_" + activeShieldRowId + "_shield_bf"); + variablesToGet.push("repeating_shields_" + activeShieldRowId + "_shield_ini_mod"); + variablesToGet.push("repeating_shields_" + activeShieldRowId + "_shield_name"); + variablesToGet.push("repeating_shields_" + activeShieldRowId + "_shield_tp"); + variablesToGet.push("repeating_shields_" + activeShieldRowId + "_shield_tpkk"); + variablesToGet.push("repeating_shields_" + activeShieldRowId + "_shield_type"); + variablesToGet.push("repeating_shields_" + activeShieldRowId + "_combat_technique"); + } - safeGetAttrs(variablesToGet, function(values) { - var attrsToChange = {}; + safeGetAttrs(variablesToGet, function(values) { + var attrsToChange = {}; // Prepare against NaN KK if (isNaN(values["KK"])) { values["KK"] = Math.max(0, parseInt(values["KK_Basis"]) + parseInt(values["KK_mod"])); } - // Used for AT, PA and TP calc - let tpkkMod = parseInt(values["NKW" + weapon + "_SB"]); + // Used for AT, PA and TP calc + let tpkkMod = parseInt(values["NKW" + weapon + "_SB"]); - // Berechne Waffen-AT - var ATkampftechnikRaw = values["NKW_AT_typ" + weapon]; - // AT-Wert nur berechenbar, wenn dahinterstehende Kampftechnik bekannt - if (ATkampftechnikRaw && ATkampftechnikRaw !== "0") { + // Berechne Waffen-AT + var ATkampftechnikRaw = values["NKW_AT_typ" + weapon]; + // AT-Wert nur berechenbar, wenn dahinterstehende Kampftechnik bekannt + if (ATkampftechnikRaw && ATkampftechnikRaw !== "0") { var AT = 0; var taw = 0; var ATkampftechnik = ATkampftechnikRaw.match("@{AT_(.*)}"); @@ -27211,30 +27528,30 @@ function calculateCombatValues() { AT = parseInt(values["AT_" + ATkampftechnik[1].toLowerCase()]); } - var atMod = parseInt(values["NKW" + weapon +"ATMod"]); - var spec = parseInt(values["NKW" + weapon + "_Spez"]); - var atValue = AT + atMod + spec + (values.AT_mod_wounds || 0); - // bei aktivem Schild (nicht bei Parierwaffen), wird der AT Wert der Hauptwaffe um den AT-Mod des Schildes verändert - if (activeShieldRowId && values["repeating_shields_" + activeShieldRowId + "_shield_type"] === "shield") { - atValue = atValue + parseInt(values["repeating_shields_" + activeShieldRowId + "_shield_at_mod"]); - } - if (values["be_at_mod"]) { - atValue -= parseInt(values["be_at_mod"]); - } + var atMod = parseInt(values["NKW" + weapon +"ATMod"]); + var spec = parseInt(values["NKW" + weapon + "_Spez"]); + var atValue = AT + atMod + spec + (values.AT_mod_wounds || 0); + // bei aktivem Schild (nicht bei Parierwaffen), wird der AT Wert der Hauptwaffe um den AT-Mod des Schildes verändert + if (activeShieldRowId && values["repeating_shields_" + activeShieldRowId + "_shield_type"] === "shield") { + atValue = atValue + parseInt(values["repeating_shields_" + activeShieldRowId + "_shield_at_mod"]); + } + if (values["be_at_mod"]) { + atValue -= parseInt(values["be_at_mod"]); + } // Negative TP/KK reduziert auch AT - if (tpkkMod && tpkkMod < 0) { - atValue += tpkkMod; - } - attrsToChange["AT_Aktiv"] = Math.max(0, atValue); - attrsToChange["AT_Aktiv_TaW"] = taw; - } + if (tpkkMod && tpkkMod < 0) { + atValue += tpkkMod; + } + attrsToChange["AT_Aktiv"] = Math.max(0, atValue); + attrsToChange["AT_Aktiv_TaW"] = taw; + } - // Berechne Waffen-PA - var PAkampftechnikRaw = values["NKW_PA_typ" + weapon]; - var paValue = 0; - // Wir berechnen den PA Wert nur, wenn ein Talenttyp für den PA Wert der Waffe ausgewählt ist - if (PAkampftechnikRaw && PAkampftechnikRaw !== "0" ) { + // Berechne Waffen-PA + var PAkampftechnikRaw = values["NKW_PA_typ" + weapon]; + var paValue = 0; + // Wir berechnen den PA Wert nur, wenn ein Talenttyp für den PA Wert der Waffe ausgewählt ist + if (PAkampftechnikRaw && PAkampftechnikRaw !== "0" ) { var PA = 0; var taw = 0; var PAkampftechnik = PAkampftechnikRaw.match("@{PA_(.*)}"); @@ -27252,120 +27569,120 @@ function calculateCombatValues() { PA = parseInt(values["PA_" + PAkampftechnik[1].toLowerCase()]); } - var paMod = parseInt(values["NKW" + weapon +"PAMod"]); - var spec = parseInt(values["NKW" + weapon + "_Spez"]); - var wounds = isNaN(values['PA_mod_wounds']) ? 0 : values['PA_mod_wounds']; - paValue = PA + paMod + spec + wounds; + var paMod = parseInt(values["NKW" + weapon +"PAMod"]); + var spec = parseInt(values["NKW" + weapon + "_Spez"]); + var wounds = isNaN(values['PA_mod_wounds']) ? 0 : values['PA_mod_wounds']; + paValue = PA + paMod + spec + wounds; - if (values["be_pa_mod"]) { - paValue -= parseInt(values["be_pa_mod"]); - } - - if (Number.isNaN(paValue) || paValue < 0) { - paValue = 0; - } - if (tpkkMod && tpkkMod < 0) { - paValue += tpkkMod; - } - attrsToChange["PA_Aktiv"] = Math.max(0, paValue); - attrsToChange["PA_Aktiv_TaW"] = taw; + if (values["be_pa_mod"]) { + paValue -= parseInt(values["be_pa_mod"]); + } + + if (Number.isNaN(paValue) || paValue < 0) { + paValue = 0; + } + if (tpkkMod && tpkkMod < 0) { + paValue += tpkkMod; + } + attrsToChange["PA_Aktiv"] = Math.max(0, paValue); + attrsToChange["PA_Aktiv_TaW"] = taw; + } + + // Berechne Schild-PA und Parierwaffen-AT (Annahme: Kampf mit "falscher" Hand) + var shieldPa = 0; + var parryweaponAT = 0; + var parryweaponPa = 0; + // natürlich nur, wenn ein Schild aktiv ist (Siehe WdS S. 70) + if (activeShieldRowId) { + var linkhand = values["sf_linkhand"]; + if (values["repeating_shields_" + activeShieldRowId + "_shield_type"] === "shield") { + // Lade die Werte der für Schildparaden relevanten SF + var schildkampf1 = values["sf_schildkampfI"]; + var schildkampf2 = values["sf_schildkampfII"]; + // Wir starten mit dem PA Basiswert des Charakters + shieldPa = parseInt(values["PABasis"]); + // Für Schildkampf 2 werden 5 Punkte, für Schildkampf 1 3 Punkte und für Linkhand 1 Punkt addiert + if (schildkampf2 === "1") { + shieldPa += 5; + } else if (schildkampf1 === "1") { + shieldPa += 3; + } else if (linkhand === "1") { + shieldPa += 1; + } + + // Ist der PA Wert der Waffe >= 21 werden 3 Punkte, >= 18 2 Punkte und >= 15 1 Punkt addiert + if (paValue >= 21) { + shieldPa += 3; + } else if (paValue >= 18) { + shieldPa += 2; + } else if (paValue >= 15) { + shieldPa += 1; + } + + // berechne BE modifikator mit ein + if (values["be_pa_mod"]) { + shieldPa -= parseInt(values["be_pa_mod"]); + } + + // Zuletzt: Addiere den PA-Modifikator des Schildes + shieldPa += parseInt(values["repeating_shields_" + activeShieldRowId + "_shield_pa_mod"]); + } else if (values["repeating_shields_" + activeShieldRowId + "_shield_type"] === "parryweapon") { + // Parierwaffen-AT besteht aus: AT der Kampftechnik + AT-WM der Waffe + Wundmod. + BE-Mod + // TODO: Spezialisierungen beachten + var parryWeaponCombatTechnique = values["repeating_shields_" + activeShieldRowId + "_combat_technique"]; + if (DSAsane(parryWeaponCombatTechnique, "melee-combat-technique")) { + var AT = 0; + + // Suche nach der richtigen Schreibweise des Attributnamens ... + AT = parseInt(values["AT_" + parryWeaponCombatTechnique]); + if (isNaN(AT)) { + AT = parseInt(values["AT_" + parryWeaponCombatTechnique.toLowerCase()]) } - // Berechne Schild-PA und Parierwaffen-AT (Annahme: Kampf mit "falscher" Hand) - var shieldPa = 0; - var parryweaponAT = 0; - var parryweaponPa = 0; - // natürlich nur, wenn ein Schild aktiv ist (Siehe WdS S. 70) - if (activeShieldRowId) { - var linkhand = values["sf_linkhand"]; - if (values["repeating_shields_" + activeShieldRowId + "_shield_type"] === "shield") { - // Lade die Werte der für Schildparaden relevanten SF - var schildkampf1 = values["sf_schildkampfI"]; - var schildkampf2 = values["sf_schildkampfII"]; - // Wir starten mit dem PA Basiswert des Charakters - shieldPa = parseInt(values["PABasis"]); - // Für Schildkampf 2 werden 5 Punkte, für Schildkampf 1 3 Punkte und für Linkhand 1 Punkt addiert - if (schildkampf2 === "1") { - shieldPa += 5; - } else if (schildkampf1 === "1") { - shieldPa += 3; - } else if (linkhand === "1") { - shieldPa += 1; - } + var atMod = parseInt(values["repeating_shields_" + activeShieldRowId + "_shield_at_mod"]); - // Ist der PA Wert der Waffe >= 21 werden 3 Punkte, >= 18 2 Punkte und >= 15 1 Punkt addiert - if (paValue >= 21) { - shieldPa += 3; - } else if (paValue >= 18) { - shieldPa += 2; - } else if (paValue >= 15) { - shieldPa += 1; - } + var atValue = + AT + atMod + + values["AT_mod_wounds"] + - parseInt(values["be_at_mod"]); + attrsToChange["parryweapon_at"] = atValue; + } - // berechne BE modifikator mit ein - if (values["be_pa_mod"]) { - shieldPa -= parseInt(values["be_pa_mod"]); - } + var parierwaffen1 = values["sf_parierwaffenI"]; + var parierwaffen2 = values["sf_parierwaffenII"]; + // Basis für Parierwaffen-PA ist die PA der Hauptwaffe + parryweaponPa = Math.max(0, paValue); - // Zuletzt: Addiere den PA-Modifikator des Schildes - shieldPa += parseInt(values["repeating_shields_" + activeShieldRowId + "_shield_pa_mod"]); - } else if (values["repeating_shields_" + activeShieldRowId + "_shield_type"] === "parryweapon") { - // Parierwaffen-AT besteht aus: AT der Kampftechnik + AT-WM der Waffe + Wundmod. + BE-Mod - // TODO: Spezialisierungen beachten - var parryWeaponCombatTechnique = values["repeating_shields_" + activeShieldRowId + "_combat_technique"]; - if (DSAsane(parryWeaponCombatTechnique, "melee-combat-technique")) { - var AT = 0; + // Dazu wird der PA-Mod der Parierwaffe addiert + parryweaponPa += parseInt(values["repeating_shields_" + activeShieldRowId + "_shield_pa_mod"]); - // Suche nach der richtigen Schreibweise des Attributnamens ... - AT = parseInt(values["AT_" + parryWeaponCombatTechnique]); - if (isNaN(AT)) { - AT = parseInt(values["AT_" + parryWeaponCombatTechnique.toLowerCase()]) - } + if (parierwaffen2 === "1") { + parryweaponPa += 2; + } else if (parierwaffen1 === "1") { + parryweaponPa += -1; + } else if (linkhand === "1") { + parryweaponPa += -4; + } else { + // Ohne die SF Linkhand können Parierwaffen nicht verwendet werden + parryweaponPa = 0; + } + } + // Wundeinfluss (bei Parierwaffe über PA-Wert der Hauptwaffe bereits drin) + shieldPa = Math.max(0, shieldPa + (isNaN(values['PA_mod_wounds']) ? 0 : values['PA_mod_wounds'])); + } - var atMod = parseInt(values["repeating_shields_" + activeShieldRowId + "_shield_at_mod"]); - - var atValue = - AT + atMod - + values["AT_mod_wounds"] - - parseInt(values["be_at_mod"]); - attrsToChange["parryweapon_at"] = atValue; - } - - var parierwaffen1 = values["sf_parierwaffenI"]; - var parierwaffen2 = values["sf_parierwaffenII"]; - // Basis für Parierwaffen-PA ist die PA der Hauptwaffe - parryweaponPa = Math.max(0, paValue); - - // Dazu wird der PA-Mod der Parierwaffe addiert - parryweaponPa += parseInt(values["repeating_shields_" + activeShieldRowId + "_shield_pa_mod"]); - - if (parierwaffen2 === "1") { - parryweaponPa += 2; - } else if (parierwaffen1 === "1") { - parryweaponPa += -1; - } else if (linkhand === "1") { - parryweaponPa += -4; - } else { - // Ohne die SF Linkhand können Parierwaffen nicht verwendet werden - parryweaponPa = 0; - } - } - // Wundeinfluss (bei Parierwaffe über PA-Wert der Hauptwaffe bereits drin) - shieldPa = Math.max(0, shieldPa + (isNaN(values['PA_mod_wounds']) ? 0 : values['PA_mod_wounds'])); - } - - if (shieldPa > 0) { - attrsToChange["shield_pa_available"] = "on"; - } else { - attrsToChange["shield_pa_available"] = "0"; - } - if (parryweaponPa > 0) { - attrsToChange["parryweapon_pa_available"] = "on"; - } else { - attrsToChange["parryweapon_pa_available"] = "0"; - } - attrsToChange["shield_pa"] = shieldPa; - attrsToChange["parryweapon_pa"] = parryweaponPa; + if (shieldPa > 0) { + attrsToChange["shield_pa_available"] = "on"; + } else { + attrsToChange["shield_pa_available"] = "0"; + } + if (parryweaponPa > 0) { + attrsToChange["parryweapon_pa_available"] = "on"; + } else { + attrsToChange["parryweapon_pa_available"] = "0"; + } + attrsToChange["shield_pa"] = shieldPa; + attrsToChange["parryweapon_pa"] = parryweaponPa; // Set INI modifier from (main) weapon var weaponini = 0; @@ -27375,28 +27692,28 @@ function calculateCombatValues() { } attrsToChange["INI_mod_hauptwaffe"] = weaponini; - // Set INI modifier from shields/parry weapons - var shieldparryini = 0; - if (activeShieldRowId) { - shieldparryini = parseInt(values["repeating_shields_" + activeShieldRowId + "_shield_ini_mod"]); - } - attrsToChange["ShieldParryINI"] = shieldparryini; + // Set INI modifier from shields/parry weapons + var shieldparryini = 0; + if (activeShieldRowId) { + shieldparryini = parseInt(values["repeating_shields_" + activeShieldRowId + "_shield_ini_mod"]); + } + attrsToChange["ShieldParryINI"] = shieldparryini; - // Set shield parry weapon BF (Bruchfaktor; lit. breaking factor -> fragility) - var shieldparrybf = 0; - if (activeShieldRowId) { - shieldparrybf = values["repeating_shields_" + activeShieldRowId + "_shield_bf"]; - if (shieldparrybf === undefined || isNaN(parseInt(shieldparrybf))) { - shieldparrybf = 0; - } - } - attrsToChange["shield_bf"] = shieldparrybf; + // Set shield parry weapon BF (Bruchfaktor; lit. breaking factor -> fragility) + var shieldparrybf = 0; + if (activeShieldRowId) { + shieldparrybf = values["repeating_shields_" + activeShieldRowId + "_shield_bf"]; + if (shieldparrybf === undefined || isNaN(parseInt(shieldparrybf))) { + shieldparrybf = 0; + } + } + attrsToChange["shield_bf"] = shieldparrybf; - // Set shield parry weapon TP/KK (damage modifier based on low/high strength) - var shieldparrytpkkdefault = "13/3"; - var shieldparrytpkk = shieldparrytpkkdefault; - if (activeShieldRowId) { - shieldparrytpkk = values["repeating_shields_" + activeShieldRowId + "_shield_tpkk"]; + // Set shield parry weapon TP/KK (damage modifier based on low/high strength) + var shieldparrytpkkdefault = "13/3"; + var shieldparrytpkk = shieldparrytpkkdefault; + if (activeShieldRowId) { + shieldparrytpkk = values["repeating_shields_" + activeShieldRowId + "_shield_tpkk"]; // Check for correct TP/KK { @@ -27415,87 +27732,115 @@ function calculateCombatValues() { shieldparrytpkk = shieldparrytpkkdefault; } } - // We are misusing the TP/KK function a bit ... - var TPKK = new Object(); - TPKK["Schwellenwert"] = parseInt(shieldparrytpkk.match(/([^/]+)\/([^/]+)/)[1]); - TPKK["Schritt"] = parseInt(shieldparrytpkk.match(/([^/]+)\/([^/]+)/)[2]); - shieldparrytpkk = calculateTpKKModFromValuesAndWeaponNumber( - { - "KK": values["KK"], - "NKW-schild_SchwellenwertKK": TPKK["Schwellenwert"], - "NKW-schild_Schwellenwert": TPKK["Schritt"] - }, - "-schild" - ); - } - attrsToChange["shield_tpkk"] = shieldparrytpkk; + // We are misusing the TP/KK function a bit ... + var TPKK = new Object(); + TPKK["Schwellenwert"] = parseInt(shieldparrytpkk.match(/([^/]+)\/([^/]+)/)[1]); + TPKK["Schritt"] = parseInt(shieldparrytpkk.match(/([^/]+)\/([^/]+)/)[2]); + shieldparrytpkk = calculateTpKKModFromValuesAndWeaponNumber( + { + "KK": values["KK"], + "NKW-schild_SchwellenwertKK": TPKK["Schwellenwert"], + "NKW-schild_Schwellenwert": TPKK["Schritt"] + }, + "-schild" + ); + } + attrsToChange["shield_tpkk"] = shieldparrytpkk; - // Set shield parry weapon TP (damage) - // For now no calculations, just showing text - var shieldparrytp = ""; - var shieldparrytproll = ""; - if (activeShieldRowId) { - shieldparrytp = values["repeating_shields_" + activeShieldRowId + "_shield_tp"]; - if (shieldparrytp === undefined || shieldparrytp === "") { - shieldparrytp = " "; - } else { - shieldparrytproll = shieldparrytp.replace("W", "d"); - } - } - attrsToChange["shield_tp"] = shieldparrytp; - attrsToChange["shield_tp_roll"] = shieldparrytproll; + // Set shield parry weapon TP (damage) + // For now no calculations, just showing text + var shieldparrytp = ""; + var shieldparrytproll = ""; + if (activeShieldRowId) { + shieldparrytp = values["repeating_shields_" + activeShieldRowId + "_shield_tp"]; + if (shieldparrytp === undefined || shieldparrytp === "") { + shieldparrytp = " "; + } else { + shieldparrytproll = shieldparrytp.replace("W", "d"); + } + } + attrsToChange["shield_tp"] = shieldparrytp; + attrsToChange["shield_tp_roll"] = shieldparrytproll; - // Set shield parry weapon name - var shieldparryname = ""; - if (activeShieldRowId) { - shieldparryname = values["repeating_shields_" + activeShieldRowId + "_shield_name"]; - if (shieldparryname === undefined || shieldparryname === "") { - shieldparryname = " "; - } - } - attrsToChange["shield_name"] = shieldparryname; + // Set shield parry weapon name + var shieldparryname = ""; + if (activeShieldRowId) { + shieldparryname = values["repeating_shields_" + activeShieldRowId + "_shield_name"]; + if (shieldparryname === undefined || shieldparryname === "") { + shieldparryname = " "; + } + } + attrsToChange["shield_name"] = shieldparryname; - safeSetAttrs(attrsToChange); - }); + safeSetAttrs(attrsToChange); }); + }); } -// Wird eine Nahkampfwaffe aktiviert, werden alle anderen deaktiviert. Auf diese Weise wird sichergestellt, dass immer maximal eine Nahkampfwaffe aktiv ist. -// Funktionsweise siehe Methode unten zum deaktivieren der Schilde -on("change:nkw_aktiv1 change:nkw_aktiv2 change:nkw_aktiv3 change:nkw_aktiv4", function(eventInfo) { - if (eventInfo.newValue !== "1") { - return; - } - var attrsToChange = {}; - for (var i = 1; i <= 4; i++) { - if (eventInfo.sourceAttribute !== "nkw_aktiv" + i) { - attrsToChange["NKW_Aktiv" + i] = 0; +// Toggling hints for encumbrance affecting AT/PA +on([ + "be_at_mod", + "be_pa_mod", + ].map(attr => `change:${attr}`).join(" "), function(eventInfo) { + const caller = "Action Listener for Toggling Hints for Encumbrance Affecting AT/PA"; + const sourceAttr = eventInfo["sourceAttribute"]; + const hintAttr = sourceAttr + "_hint"; + let attrsToChange = {}; + + switch (sourceAttr) + { + case "be_at_mod": + case "be_pa_mod": + if (eventInfo["newValue"] > 0) + { + attrsToChange[hintAttr] = 1; + } else { + attrsToChange[hintAttr] = 0; } + break; + default: + debugLog(caller, "sourceAttribute not be_at_mod or be_pa_mod."); + break; } safeSetAttrs(attrsToChange); }); -on("change:atbasis change:taw_peitsche change:at_peitsche", function(eventInfo) { - // do prevent infinite loop - if (eventInfo.sourceType === "sheetworker" && eventInfo.sourceAttribute === "AT_peitsche") { - return; +// Wird eine Nahkampfwaffe aktiviert, werden alle anderen deaktiviert. Auf diese Weise wird sichergestellt, dass immer maximal eine Nahkampfwaffe aktiv ist. +// Funktionsweise siehe Methode unten zum deaktivieren der Schilde +on("change:nkw_aktiv1 change:nkw_aktiv2 change:nkw_aktiv3 change:nkw_aktiv4", function(eventInfo) { + if (eventInfo.newValue !== "1") { + return; + } + var attrsToChange = {}; + for (let i = 1; i <= 4; i++) { + if (eventInfo.sourceAttribute !== "nkw_aktiv" + i) { + attrsToChange["NKW_Aktiv" + i] = 0; } - safeGetAttrs([ "ATbasis", "TaW_peitsche" ], function(values) { - var peitscheAT = 0; - if (values["TaW_peitsche"]) { - peitscheAT = parseInt(values["ATbasis"]) + parseInt(values["TaW_peitsche"]); - } - safeSetAttrs({ "AT_peitsche": peitscheAT }); - }); + } + safeSetAttrs(attrsToChange); +}); + +on("change:atbasis change:taw_peitsche change:at_peitsche", function(eventInfo) { + // do prevent infinite loop + if (eventInfo.sourceType === "sheetworker" && eventInfo.sourceAttribute === "AT_peitsche") { + return; + } + safeGetAttrs([ "ATbasis", "TaW_peitsche" ], function(values) { + var peitscheAT = 0; + if (values["TaW_peitsche"]) { + peitscheAT = parseInt(values["ATbasis"]) + parseInt(values["TaW_peitsche"]); + } + safeSetAttrs({ "AT_peitsche": peitscheAT }); + }); }); on( "change:sf_linkhand change:sf_beidhandigerkampfI change:sf_beidhandigerkampfII change:vorteil_beidhaendig " + "change:sf_parierwaffeni change:sf_parierwaffenii " + "change:sf_schildkampfi change:sf_schildkampfii ", function(eventInfo) { - safeGetAttrs(["sf_linkhand", "sf_beidhandigerkampfI", "sf_beidhandigerkampfII", "vorteil_beidhaendig", "sf_parierwaffenI", "sf_parierwaffenII", "sf_schildkampfI", "sf_schildkampfII"], function(values) { - var caller = "???"; - var attrsToChange = {}; + safeGetAttrs(["sf_linkhand", "sf_beidhandigerkampfI", "sf_beidhandigerkampfII", "vorteil_beidhaendig", "sf_parierwaffenI", "sf_parierwaffenII", "sf_schildkampfI", "sf_schildkampfII"], function(values) { + var caller = "???"; + var attrsToChange = {}; // Caution: This might cause trouble if some function other than this one changed these attributes. if (eventInfo.sourceType === "sheetworker") @@ -27563,10 +27908,10 @@ on( } break; } - safeSetAttrs(attrsToChange, () => { + safeSetAttrs(attrsToChange, () => { calculateCombatValues(eventInfo); - }); }); + }); }); on( @@ -27576,39 +27921,39 @@ on( "change:nkw3_schwellenwertkk change:nkw3_schwellenwert " + "change:nkw4_schwellenwertkk change:nkw4_schwellenwert", function(eventInfo) { - var weaponsToCalculate = []; - let attrsToGet = [ "KK", "KK_Basis", "KK_mod" ]; + var weaponsToCalculate = []; + let attrsToGet = [ "KK", "KK_Basis", "KK_mod" ]; - // Gather all affected melee weapons (NKW) - // Changes to KK (strength) can affect all weapons - // Compare with lowercase as all attribute names are lowercase in eventInfo - if (eventInfo.sourceAttribute === "kk") { - for (var weapon = 1; weapon <= 4; weapon++) { - weaponsToCalculate.push(weapon); - attrsToGet.push("NKW" + weapon + "_Schwellenwert"); - attrsToGet.push("NKW" + weapon + "_SchwellenwertKK"); - } - // Use the slot (number) of the weapon which just got changed - } else { - let matchResult = eventInfo.sourceAttribute.match(/nkw(\d)_.*/i); - let weapon = matchResult[1]; - weaponsToCalculate.push(weapon); - attrsToGet.push("NKW" + weapon + "_Schwellenwert"); - attrsToGet.push("NKW" + weapon + "_SchwellenwertKK"); + // Gather all affected melee weapons (NKW) + // Changes to KK (strength) can affect all weapons + // Compare with lowercase as all attribute names are lowercase in eventInfo + if (eventInfo.sourceAttribute === "kk") { + for (let weapon = 1; weapon <= 4; weapon++) { + weaponsToCalculate.push(weapon); + attrsToGet.push("NKW" + weapon + "_Schwellenwert"); + attrsToGet.push("NKW" + weapon + "_SchwellenwertKK"); } + // Use the slot (number) of the weapon which just got changed + } else { + let matchResult = eventInfo.sourceAttribute.match(/nkw(\d)_.*/i); + let weapon = matchResult[1]; + weaponsToCalculate.push(weapon); + attrsToGet.push("NKW" + weapon + "_Schwellenwert"); + attrsToGet.push("NKW" + weapon + "_SchwellenwertKK"); + } - safeGetAttrs(attrsToGet, function(values) { + safeGetAttrs(attrsToGet, function(values) { // Prepare against NaN KK if (isNaN(values["KK"])) { values["KK"] = Math.max(0, parseInt(values["KK_Basis"]) + parseInt(values["KK_mod"])); } - let attrsToChange = {}; - for (var i = 0; i < weaponsToCalculate.length; i++) { - let weapon = weaponsToCalculate[i]; - attrsToChange["NKW" + weapon + "_SB"] = calculateTpKKModFromValuesAndWeaponNumber(values, weapon); - } - safeSetAttrs(attrsToChange); - }) + let attrsToChange = {}; + for (let i = 0; i < weaponsToCalculate.length; i++) { + let weapon = weaponsToCalculate[i]; + attrsToChange["NKW" + weapon + "_SB"] = calculateTpKKModFromValuesAndWeaponNumber(values, weapon); + } + safeSetAttrs(attrsToChange); + }); }); /* TP/KK modifies (usually only) TP, but sometimes also AT and PA @@ -27664,13 +28009,13 @@ Str. Dif. Flo. Res. // Special version function calculateTpKKModFromValuesAndWeaponNumber(values, weapon) { - const func = "calculateTpKKModFromValuesAndWeaponNumber"; - let KK = parseInt(values["KK"]); - let threshold = parseInt(values["NKW" + weapon + "_SchwellenwertKK"]); - let step = parseInt(values["NKW" + weapon + "_Schwellenwert"]); + const func = "calculateTpKKModFromValuesAndWeaponNumber"; + let KK = parseInt(values["KK"]); + let threshold = parseInt(values["NKW" + weapon + "_SchwellenwertKK"]); + let step = parseInt(values["NKW" + weapon + "_Schwellenwert"]); - var tpkkMod = calculateTpKKMod(KK, threshold, step); - return tpkkMod; + var tpkkMod = calculateTpKKMod(KK, threshold, step); + return tpkkMod; } // General version @@ -27702,43 +28047,42 @@ function calculateTpKKMod(KK, threshold, step) { // calculate shield attack modifier on("change:repeating_shields change:sf_schildkampfI change:sf_schildkampfII change:sf_knaufschlag change:sf_schmutzigetricks change:at_raufen change:at_mod_wounds", function(eventInfos) { - safeGetAttrs(["activeShieldRowId"], function(rowIdValues) { - var caller = "???"; - var activeShieldRowId = rowIdValues["activeShieldRowId"]; - if (eventInfos.sourceAttribute && eventInfos.sourceAttribute.endsWith("_shield_active")) { - if (eventInfos.newValue === "on") { - activeShieldRowId = extractRowId(eventInfos.sourceAttribute); - } else if (eventInfos.sourceType === "player") { - activeShieldRowId = undefined; - } + safeGetAttrs(["activeShieldRowId"], function(rowIdValues) { + var caller = "???"; + var activeShieldRowId = rowIdValues["activeShieldRowId"]; + if (eventInfos.sourceAttribute && eventInfos.sourceAttribute.endsWith("_shield_active")) { + if (eventInfos.newValue === "on") { + activeShieldRowId = extractRowId(eventInfos.sourceAttribute); + } else if (eventInfos.sourceType === "player") { + activeShieldRowId = undefined; } + } - let variablesToGet = [ "sf_schildkampfI", "sf_schildkampfII", "sf_schmutzigetricks", "sf_knaufschlag", "AT_raufen", "AT_mod_wounds"] + let variablesToGet = [ "sf_schildkampfI", "sf_schildkampfII", "sf_schmutzigetricks", "sf_knaufschlag", "AT_raufen", "AT_mod_wounds"] - // Wenn es ein aktives Schild (oder Parierwaffe) gibt, möchten wir auch dessen Werte mit laden - if (activeShieldRowId) { - variablesToGet.push("repeating_shields_" + activeShieldRowId + "_shield_at_mod"); - variablesToGet.push("repeating_shields_" + activeShieldRowId + "_shield_pa_mod"); - variablesToGet.push("repeating_shields_" + activeShieldRowId + "_shield_type"); - variablesToGet.push("repeating_shields_" + activeShieldRowId + "_combat_technique"); - } else { - debugLog(caller, "no active shield found"); - safeSetAttrs({ + // Wenn es ein aktives Schild (oder Parierwaffe) gibt, möchten wir auch dessen Werte mit laden + if (activeShieldRowId) { + variablesToGet.push("repeating_shields_" + activeShieldRowId + "_shield_at_mod"); + variablesToGet.push("repeating_shields_" + activeShieldRowId + "_shield_pa_mod"); + variablesToGet.push("repeating_shields_" + activeShieldRowId + "_shield_type"); + variablesToGet.push("repeating_shields_" + activeShieldRowId + "_combat_technique"); + } else { + debugLog(caller, "no active shield found"); + safeSetAttrs({ "shield_at": 0, "shield_at_available": "0", "shield_at_mod": 0 }); - return; - } - - safeGetAttrs(variablesToGet, function(values) { - let result = calculateShieldAttack(values, activeShieldRowId); - debugLog(caller, 'calculated shield attack'); - debugLog(caller, result); - safeSetAttrs(result); - }); + return; + } + safeGetAttrs(variablesToGet, function(values) { + let result = calculateShieldAttack(values, activeShieldRowId); + debugLog(caller, 'calculated shield attack'); + debugLog(caller, result); + safeSetAttrs(result); }); + }); }); function calculateShieldAttack(values, activeShieldRowId) { @@ -28060,7 +28404,7 @@ on( }; // Add contents to the results data structure - for (macro of elements) { + for (let macro of elements) { if (Object.hasOwn(macro, "prefix")) { transformed["common"]["prefix"] += macro["prefix"] + " "; } else if (Object.hasOwn(macro, "suffix")) { @@ -28261,17 +28605,17 @@ on( passthrough["rollTime"] = Date.now(); passthrough["rollTag"] = generateShortRollTag(passthrough["rollTime"]); passthrough["rollMacro"] = - "@{gm_roll_opt} " + - "&{template:DSA-Nahkampf-Patzer} " + - "{{name=Nahkampfpatzer}} " + - "{{wurf=[[2d6cs1cf6]]}} " + - "{{isOriginalRoll=[[0]]}} " + - "{{showRollTag=[[@{show_roll_tags}]]}} " + - "{{rollTag=[[0]]}} " + - "{{rollTime=[[0]]}} " + - "{{rollExpired=[[0]]}} " + - "{{rollTimeHuman=[[0]]}} " + - "{{passthrough=[[0]]}}"; + "@{gm_roll_opt} " + + "&{template:DSA-Nahkampf-Patzer} " + + "{{name=Nahkampfpatzer}} " + + "{{wurf=[[2d6cs1cf6]]}} " + + "{{isOriginalRoll=[[0]]}} " + + "{{showRollTag=[[@{show_roll_tags}]]}} " + + "{{rollTag=[[0]]}} " + + "{{rollTime=[[0]]}} " + + "{{rollExpired=[[0]]}} " + + "{{rollTimeHuman=[[0]]}} " + + "{{passthrough=[[0]]}}"; console.log(passthrough); } } else { @@ -28400,17 +28744,17 @@ on('clicked:combat_reaction', async (info) => { passthrough["rollTime"] = received["rollTime"]; passthrough["rollTag"] = received["rollTag"]; passthrough["rollMacro"] = - "@{gm_roll_opt} " + - "&{template:DSA-Nahkampf-Patzer} " + - "{{name=Nahkampfpatzer}} " + - "{{wurf=[[2d6cs1cf6]]}} " + - "{{isOriginalRoll=[[0]]}} " + - "{{showRollTag=[[@{show_roll_tags}]]}} " + - "{{rollTag=[[0]]}} " + - "{{rollTime=[[0]]}} " + - "{{rollExpired=[[0]]}} " + - "{{rollTimeHuman=[[0]]}} " + - "{{passthrough=[[0]]}}"; + "@{gm_roll_opt} " + + "&{template:DSA-Nahkampf-Patzer} " + + "{{name=Nahkampfpatzer}} " + + "{{wurf=[[2d6cs1cf6]]}} " + + "{{isOriginalRoll=[[0]]}} " + + "{{showRollTag=[[@{show_roll_tags}]]}} " + + "{{rollTag=[[0]]}} " + + "{{rollTime=[[0]]}} " + + "{{rollExpired=[[0]]}} " + + "{{rollTimeHuman=[[0]]}} " + + "{{passthrough=[[0]]}}"; console.log(passthrough); } else { result = -2; @@ -28452,6 +28796,9 @@ function FKWgetType(typeRaw) case '@{AT_Bogen}': FKWtype = 'Bogen'; break; + case '@{AT_feuerwaffen}': + FKWtype = 'Feuerwaffen'; + break; case '@{AT_Schleuder}': FKWtype = 'Schleuder'; break; @@ -28590,6 +28937,7 @@ on( "change:fkw_aktiv_schuetzentyp change:sf_scharfschutze_armbrust change:sf_meisterschutze_armbrust " + "change:sf_scharfschutze_blasrohr change:sf_meisterschutze_blasrohr " + "change:sf_scharfschutze_bogen change:sf_meisterschutze_bogen " + + "change:sf_scharfschutze_feuerwaffen change:sf_meisterschutze_feuerwaffen " + "change:sf_scharfschutze_wurfbeile change:sf_meisterschutze_wurfbeile " + "change:sf_scharfschutze_wurfmesser change:sf_meisterschutze_wurfmesser " + "change:sf_scharfschutze_wurfspeere change:sf_meisterschutze_wurfspeere " + @@ -28672,6 +29020,8 @@ on( 'sf_meisterschutze_blasrohr', 'sf_scharfschutze_bogen', 'sf_meisterschutze_bogen', + 'sf_scharfschutze_feuerwaffen', + 'sf_meisterschutze_feuerwaffen', 'sf_scharfschutze_schleuder', 'sf_meisterschutze_schleuder', 'sf_scharfschutze_wurfbeile', @@ -28888,6 +29238,10 @@ on( if(v.sf_scharfschutze_bogen == "1") {FKW.schuetze = 1;} if(v.sf_meisterschutze_bogen == "1") {FKW.schuetze = 2;} break; + case "Feuerwaffen": + if(v.sf_scharfschutze_feuerwaffen == "1") {FKW.schuetze = 1;} + if(v.sf_meisterschutze_feuerwaffen == "1") {FKW.schuetze = 2;} + break; case "Schleuder": if(v.sf_scharfschutze_schleuder == "1") {FKW.schuetze = 1;} if(v.sf_meisterschutze_schleuder == "1") {FKW.schuetze = 2;} @@ -29049,7 +29403,7 @@ on( // Helligkeit // absolute Dunkelheit immer "finsternis" - + if(FKR.licht != "nd") { var finsternis = 8; @@ -29357,6 +29711,7 @@ on( case "Belagerungswaffen": case "Blasrohr": case "Bogen": + case "Feuerwaffen": case "Schleuder": mods = 4; break; @@ -29392,6 +29747,7 @@ on( case "Belagerungswaffen": case "Blasrohr": case "Bogen": + case "Feuerwaffen": case "Schleuder": mods = 4; break; @@ -29657,13 +30013,101 @@ on( ); } ); + +/* CRP for projectile subtraction */ +on("clicked:rc_attack-action", async (info) => { + var func = "Action Listener for Ranged Combat Roll Button"; + var trigger = info["triggerName"].replace(/clicked:([^-]+)-action/, '$1'); + + let rollMacro = [ + '@{gm_roll_opt}', + '&{template:DSA-Fernkampf-AT}', + '{{name=Fernkampfangriff}}', + '{{mod=[[(@{fkr_erschwernis_gesamt}) - (@{fkr_erschwernis_ansage_gesamt})]]}}', + '{{ansage=[[@{fkr_erschwernis_ansage_gesamt}]]}}', + '{{modansage=[[@{fkr_erschwernis_gesamt}]]}} {{wert=[[(@{FK_Aktiv})]]}}', + '{{eff_wert=[[(@{FK_Aktiv}) - (@{fkr_erschwernis_gesamt})]]}}', + '{{eff_wert_ohne_kampfgetuemmel=[[(@{FK_Aktiv}) - (@{fkr_erschwernis_ohne_kampfgetuemmel})]]}}', + '{{ZieleKampfgetuemmel=[[@{fkr_kampfgetuemmel_ziele}]]}}', + '{{wurf=[[1d20cs<@{cs_kampf_fk}cf>@{cf_kampf_fk}]]}}', + '{{pruefwurf=[[1d20cs<@{cs_kampf_fk}cf>@{cf_kampf_fk}]]}}' + ]; + + safeGetAttrs( + [ + 'FKW_Aktiv1', 'FKWMunition1Anzahl', + 'FKW_Aktiv2', 'FKWMunition2Anzahl', + 'FKW_Aktiv3', 'FKWMunition3Anzahl', + 'FKW_Aktiv4', 'FKWMunition4Anzahl' + ], async function(values) { + let attrsToChange = {}; + + // Projectile subtraction + // rcw: ranged combat weapon + let rcwActive = 0; + let rcwAmmo = 0; + + // Get active ranged combat weapon + if(values.FKW_Aktiv1 == "1") { rcwActive = 1; } + else if (values.FKW_Aktiv2 == "1") { rcwActive = 2; } + else if (values.FKW_Aktiv3 == "1") { rcwActive = 3; } + else if (values.FKW_Aktiv4 == "1") { rcwActive = 4; } + + // Get ammo of active ranged combat weapon + switch(rcwActive) + { + case 0: + debugLog(func, 'Keine aktive Fernkampfwaffe gefunden, automatischer Munitionsverbrauch nicht möglich.'); + break; + case 1: + case 2: + case 3: + case 4: + rcwAmmo = parseInt(values[`FKWMunition${rcwActive}Anzahl`]); + break; + } + + if (DSAsane(rcwAmmo, "non-negative int")) + { + if (rcwAmmo > 0) + { + rollMacro.push(`{{ammoRemaining=[[${rcwAmmo - 1}]]}}`); + rollMacro.push(`{{ammohint=[[0]]}}`); + attrsToChange[`FKWMunition${rcwActive}Anzahl`] = rcwAmmo - 1; + } else { + rollMacro.push(`{{ammoRemaining=[[0]]}}`); + rollMacro.push(`{{ammohint=[[1]]}}`); + } + } else { + debugLog(func, `'FKWMunition${rcwActive}Anzahl' enthält keinen gültigen Wert.`); + rollMacro.push(`{{ammohint=[[2]]}}`); + } + + debugLog(func, rollMacro, attrsToChange); + safeSetAttrs(attrsToChange); + + // Execute Roll + results = await startRoll(rollMacro.join(" ")); + debugLog(func, "test: info:", info, "results:", results); + + // Process Roll + let rollID = results.rollId; + + finishRoll( + rollID, + {} + ); + }); +}); + /* ranged combat calculator end */ /* ranged combat other begin */ on( "change:safe-sheet-open " + "change:FKBasis " + "change:TaW_Armbrust change:TaW_Belagerungswaffen change:TaW_Blasrohr " + - "change:TaW_Bogen change:TaW_Diskus change:TaW_Schleuder " + + "change:TaW_Bogen change:TaW_Diskus change:TaW_feuerwaffen " + + "change:TaW_Schleuder " + "change:TaW_Wurfbeile change:TaW_Wurfmesser change:TaW_Wurfspeere " + "change:FKWFK1 change:FKW_Aktiv1 change:FKW1_Spez change:FKWtyp1 " + "change:FKWFK2 change:FKW_Aktiv2 change:FKW2_Spez change:FKWtyp2 " + @@ -29674,7 +30118,8 @@ on( safeGetAttrs([ "FKBasis", "TaW_Armbrust", "TaW_Belagerungswaffen", "TaW_Blasrohr", - "TaW_Bogen", "TaW_Diskus", "TaW_Schleuder", + "TaW_Bogen", "TaW_Diskus", "TaW_feuerwaffen", + "TaW_Schleuder", "TaW_Wurfbeile", "TaW_Wurfmesser", "TaW_Wurfspeere", "FKWFK1", "FKW_Aktiv1", "FKW1_Spez", "FKWtyp1", "FKWFK2", "FKW_Aktiv2", "FKW2_Spez", "FKWtyp2", @@ -29685,7 +30130,8 @@ on( var attrsToChange = {"FK_Aktiv": 0}; var FKTalente = [ "Armbrust", "Belagerungswaffen", "Blasrohr", - "Bogen", "Diskus", "Schleuder", + "Bogen", "Diskus", "feuerwaffen", + "Schleuder", "Wurfbeile", "Wurfmesser", "Wurfspeere" ]; // Todo: Proper sanity checking of input data @@ -29698,7 +30144,7 @@ on( } // Calculation of FK values - for (FKTalent of FKTalente) { + for (let FKTalent of FKTalente) { var TaW = "TaW_" + FKTalent; if (isNaN(v[TaW])) { v[TaW] = 0; @@ -29706,7 +30152,7 @@ on( attrsToChange["AT_" + FKTalent] = parseInt(v["FKBasis"]) + parseInt(v[TaW]); } - for (var i = 1; i <= 4; i++) { + for (let i = 1; i <= 4; i++) { v["FKWtyp" + i] = v["FKWtyp" + i].replace(/[^_a-zA-ZäöüÄÖÜß|]/g, ""); if (v["FKWtyp" + i] === "") { v["FKWtyp" + i] = "--"; @@ -29816,7 +30262,7 @@ function calculateRuestungBE(values, eventInfo) { // Get armour names var armours = []; - for (name of [ + for (let name of [ [ values["RSName1"], values["RSAktiv1"] ], [ values["RSName2"], values["RSAktiv2"] ], [ values["RSName3"], values["RSAktiv3"] ], @@ -29826,7 +30272,7 @@ function calculateRuestungBE(values, eventInfo) { armours.push(name[0]); } } - for (name in armours) { + for (let name in armours) { armours[name] = armours[name] .replace(/[^a-zA-ZäöüÄÖÜß|]/g, "") .toLowerCase(); @@ -29848,7 +30294,7 @@ function calculateRuestungBE(values, eventInfo) { if (RGarmours.length === 0) debugLog(caller, "Warnung: Kein gültiger Rüstungsnamen für Rüstungsgewöhnung I gefunden, da kein Zeichen aus dem folgenden Zeichenvorrat stammt: a-z, A-Z, ä, ö, ü, Ä, Ö, Ü, ß."); // Find the first match and stop - for (armour of armours) { + for (let armour of armours) { if (RGarmours.indexOf(armour) > -1) { RGBonus = 1; debugLog(caller, "Rüstungsgewöhnung I: \"" + armour + "\" erhält den Bonus."); @@ -29865,7 +30311,7 @@ function calculateRuestungBE(values, eventInfo) { // Encumbrance calculation var totalBe = 0; - for (var i = 1; i <= 4; i++) { + for (let i = 1; i <= 4; i++) { if (values["RSAktiv" + i] === "1") { totalBe += parseFloat(values["RS_gBE" + i]); } @@ -30048,7 +30494,7 @@ function calculateWoundModifiers(values) { // Input Sanitation // Part 2: Check Values var errors = 0; - for (property of requiredProperties) { + for (let property of requiredProperties) { if (!DSAsane(values[property], "wound-box")) { errors += 1; } @@ -30080,16 +30526,16 @@ function calculateWoundModifiers(values) { var affectedParameters = ["AT", "PA", "FK", "IB", "MU", "IN", "KL", "FF", "GE", "KO", "KK", "GS"]; var wounds = {}; - for (zone of zones) { + for (let zone of zones) { wounds[zone] = 0; - for (woundCount of [1, 2, 3]) { + for (let woundCount of [1, 2, 3]) { wounds[zone] += parseInt(values["wound_" + zone + woundCount]); } } // Calculate final wound modifiers - for (param of affectedParameters) { - for (zone of zones) { + for (let param of affectedParameters) { + for (let zone of zones) { woundModifiers[param] += wounds[zone] * woundEffects[param][zone]; } } @@ -31081,7 +31527,7 @@ on('clicked:reg_sleep-action', async (info) => { { let successes = 0; let failures = 0; - for (roll of rolls) + for (let roll of rolls) { if (roll <= success) { @@ -31113,7 +31559,7 @@ on('clicked:reg_sleep-action', async (info) => { } else { if (effTaW < 0) { - for (roll in rolls) + for (let roll in rolls) { effRolls[roll] = rolls[roll] + Math.abs(effTaW); } @@ -31121,7 +31567,7 @@ on('clicked:reg_sleep-action', async (info) => { } // TaP-Verbrauch für jeden Wurf - for (roll in effRolls) + for (let roll in effRolls) { TaPstar -= Math.max(0, effRolls[roll] - stats[roll]); } @@ -31478,7 +31924,7 @@ function buildMacros(macros, reuse, resultType) { if (answer["val"].length < 1) { valResult = false; } else { - for (item of answer["val"]) { + for (let item of answer["val"]) { if ( ["string", "object"].includes(typeof(item)) ) { valResult = true; } else { @@ -31505,7 +31951,7 @@ function buildMacros(macros, reuse, resultType) { result = true; } else if (a.length > 0) { var numValidObjs = 0; - for (answer of a) { + for (let answer of a) { if (answerIsValid(answer) === true) { numValidObjs += 1; } @@ -31532,8 +31978,8 @@ function buildMacros(macros, reuse, resultType) { ) { if (answersIsValid(obj["macro"]["a"])) { // Arrays need to be iterated and each item checked (could be an object) - for (answer of obj["macro"]["a"]) { - for (item of answer["val"]) { + for (let answer of obj["macro"]["a"]) { + for (let item of answer["val"]) { if (typeof(item) === "object") { console.log("nestedEntry:", item); macroCalls = [...macroCalls, ...analyseObject(item, macro)]; @@ -31549,7 +31995,7 @@ function buildMacros(macros, reuse, resultType) { } function buildCalledMacrosList(macros) { var calledMacrosList = {}; - for (macro in macros) { + for (let macro in macros) { // Add empty entry for new reuse macro calledMacrosList[macro] = []; @@ -31564,8 +32010,8 @@ function buildMacros(macros, reuse, resultType) { // Objects are only allowed within the answers array if (answersIsValid(macros[macro]["a"])) { // Arrays need to be iterated and each item checked (could be an object) - for (answer of macros[macro]["a"]) { - for (item of answer["val"]) { + for (let answer of macros[macro]["a"]) { + for (let item of answer["val"]) { if (typeof(item) === "object") { // Expand the calledMacrosList using a recursive function. // If analyseObject() does not return anything, that means that the current top-level reuse macro does not reference any other reuse macros. @@ -31581,7 +32027,7 @@ function buildMacros(macros, reuse, resultType) { } function buildReuseNamesList(macros) { var reuseNamesList = []; - for (macro in macros) { + for (let macro in macros) { // Add reuse name to the list of known reuse names reuseNamesList.push(macro); } @@ -31594,20 +32040,20 @@ function buildMacros(macros, reuse, resultType) { var paths = []; // Create starting points from the reuse names list - for (name of reuseNamesList) { - for (edge of edges) { + for (let name of reuseNamesList) { + for (let edge of edges) { if (name === edge[0]) { paths.push([ name, edge[1] ]); } } } // Iterate over all paths, including new ones added on the way - for (path of paths) { + for (let path of paths) { // Next macro to call is the last macro of the path var nextRef = path.slice(-1)[0]; // Iterate over all edges to find matching macros - for (edge of edges) { + for (let edge of edges) { if (nextRef === edge[0]) { // Matches lead to new paths // Optimizing this to create new paths only if there is more than one matching edge will give headaches for keeping the outer loop running; it's not worth the hassle @@ -31646,10 +32092,10 @@ function buildMacros(macros, reuse, resultType) { console.log("reuseNamesList:", reuseNamesList, "calledMacrosList:", calledMacrosList); // Remove references to undefined reuse names - for (macro in calledMacrosList) { + for (let macro in calledMacrosList) { var toBeRemoved = []; if (calledMacrosList[macro].length > 0) { - for (entry in calledMacrosList[macro]) { + for (let entry in calledMacrosList[macro]) { if (reuseNamesList.includes(calledMacrosList[macro][entry]) === false) { console.log("Reuse not found:", calledMacrosList[macro][entry]); toBeRemoved.push(entry); @@ -31659,7 +32105,7 @@ function buildMacros(macros, reuse, resultType) { } console.log("calledMacrosList[macro]:", calledMacrosList[macro], "toBeRemoved:", toBeRemoved); if (toBeRemoved.length > 0) { - for (entry in toBeRemoved.reverse()) { + for (let entry in toBeRemoved.reverse()) { calledMacrosList[macro].splice(toBeRemoved[entry], 1); } } @@ -31669,9 +32115,9 @@ function buildMacros(macros, reuse, resultType) { // Build tree // Start: Create edges var edges = []; - for (macro in calledMacrosList) { + for (let macro in calledMacrosList) { if (calledMacrosList[macro].length > 0) { - for (entry in calledMacrosList[macro]) { + for (let entry in calledMacrosList[macro]) { edges.push([ macro, calledMacrosList[macro][entry] ]); } } @@ -31681,14 +32127,14 @@ function buildMacros(macros, reuse, resultType) { // Check edges to self { var toBeRemoved = []; - for (edge in edges) { + for (let edge in edges) { if (edges[edge][0] === edges[edge][1]) { console.log("Loop detected:", edges[edge].join(' -> ')); results["noLoopedEdges"] = false; toBeRemoved.push(edge); } } - for (entry in toBeRemoved.reverse()) { + for (let entry in toBeRemoved.reverse()) { edges.splice(toBeRemoved[entry], 1); } if (toBeRemoved.length === 0) { @@ -31881,7 +32327,7 @@ function buildMacros(macros, reuse, resultType) { var result = ""; var lastAnswerIndex = answers.length - 1; console.log("answers:", answers); - for (answer in answers) { + for (let answer in answers) { console.log("answer:", answer, "currentAnswer:", answers[answer]); answer = parseInt(answer); var currentAnswer = answers[answer]; @@ -31904,7 +32350,7 @@ function buildMacros(macros, reuse, resultType) { // Description: Array, only string elements are considered if (Array.isArray(currentAnswer["desc"]) === true) { - for (part of currentAnswer["desc"]) { + for (let part of currentAnswer["desc"]) { if (typeof(part) === "string") { desc += part; } else { @@ -31919,7 +32365,7 @@ function buildMacros(macros, reuse, resultType) { // Value: Array, strings or objects; objects are not checked for validity if (Array.isArray(currentAnswer["val"]) === true) { - for (part of currentAnswer["val"]) { + for (let part of currentAnswer["val"]) { if (typeof(part) === "string") { val += part; } else if (typeof(part) === "object") { @@ -31987,11 +32433,11 @@ function buildMacros(macros, reuse, resultType) { console.log(protectCount, protectParts, protectSplit); var macroEscaped = []; - for (part of protectSplit) { + for (let part of protectSplit) { macroEscaped.push(escaper(part)); } - for (part in protectParts) { + for (let part in protectParts) { macroComplete += macroEscaped[part] + protectParts[part]; } macroComplete += macroEscaped[macroEscaped.length -1]; @@ -32002,12 +32448,12 @@ function buildMacros(macros, reuse, resultType) { // Build the macros var result = []; - for (macro of macros) { + for (let macro of macros) { result.push(buildMacro(macro, 0, reuse)); } var structuredResult = []; - for (macro of result) { + for (let macro of result) { // Get the name of the roll variable var rollVarName = macro.slice(2, macro.search('=')); @@ -32153,7 +32599,7 @@ function calcCritLevels (effects) { if (propertyCheck['errors'] >= 1) { debugLog(caller, 'Missing properties:', propertyCheck['missing'], '. Missing values added with default value 0.'); - for (property of propertyCheck['missing']) + for (let property of propertyCheck['missing']) { effects[property] = 0; } @@ -32161,7 +32607,7 @@ function calcCritLevels (effects) { // Assumption: safeGetAttrs() used, so no undefined or NaN // Correct values: 0 or 1 - for (property of effectList) + for (let property of effectList) { if (isNaN(parseInt(effects[property]))) { @@ -32179,11 +32625,11 @@ function calcCritLevels (effects) { debugLog(caller, 'Inputs sanitized: effects:', effects); /* Calculations */ - for (type of types) + for (let type of types) { - for (effect of effectList) + for (let effect of effectList) { - for (crit of ['success', 'failure']) + for (let crit of ['success', 'failure']) result[type][crit] += effects[effect] * effectMatrix[type][effect][crit]; } } @@ -32200,28 +32646,29 @@ on("sheet:opened change:character_name", function(eventInfo) { var repeatingTalents = []; getSectionIDs("conjuration-spells-myranor", function(ids) { - for (id of ids) + for (let id of ids) { repeatingTalents.push("repeating_conjuration-spells-myranor_" + id + "_spell"); } - for(talent of talents_ebe) + for (let talent of talents_ebe) { ebeTalents.push(talent + "-ebe"); } - for(attr of [].concat(talents, ebeTalents, spells, melee, reg, repeatingTalents)) + for (let attr of [].concat(talents, ebeTalents, spells, melee, reg, repeatingTalents)) { attrsToGet.push(attr + "_action"); } safeGetAttrs(attrsToGet, function(v) { var attrsToChange = {}; - for (attr of attrsToGet) + for (let attr of attrsToGet) { // No action buttons for character name and combat techniques required if (attr.match("t_ka_") || attr === "character_name") continue; attrsToChange[attr] = "%{" + v["character_name"] + "|" + attr.replace(/_action$/gm, "") + "-action}"; } + attrsToChange["rc_attack_action"] = "%{" + v["character_name"] + "|rc_attack-action}"; attrsToChange["eidsegen_action"] = "%{" + v["character_name"] + "|eidsegen-action}"; debugLog(func, attrsToChange);