diff --git a/lang/de.json b/lang/de.json index 2bf3be49..d1a9e186 100644 --- a/lang/de.json +++ b/lang/de.json @@ -114,10 +114,12 @@ "DS4.ArmorMaterialTypeNaturalAbbr": "Natürlich", "DS4.SpellType": "Zauberspruchtyp", "DS4.SpellTypeAbbr": "T", + "DS4.SpellTypeDescription": "Der Typ des Zauberspruchs.", "DS4.SortBySpellType": "Nach Zauberspruchtyp sortieren", "DS4.SpellTypeSpellcasting": "Zaubern", "DS4.SpellTypeTargetedSpellcasting": "Zielzaubern", "DS4.SpellCategory": "Kategorie", + "DS4.SpellCategoryDescription": "Eine Kategorie, der der Zauberspruch zugehörig ist.", "DS4.SpellCategoryHealing": "Heilung", "DS4.SpellCategoryFire": "Feuer", "DS4.SpellCategoryIce": "Eis", @@ -127,18 +129,33 @@ "DS4.SpellCategoryElectricity": "Elektrizität", "DS4.SpellCategoryNone": "Keine", "DS4.SpellCategoryUnset": "Nicht gesetzt", - "DS4.SpellBonus": "Zauberbonus", - "DS4.SpellBonusAbbr": "ZB", - "DS4.SortBySpellBonus": "Nach Zauberbonus sortieren", - "DS4.SpellMaxDistance": "Reichweite", - "DS4.SpellEffectRadius": "Effektradius", - "DS4.SpellDuration": "Wirkdauer", - "DS4.SpellCooldownDuration": "Abklingzeit", + "DS4.SpellModifier": "Zauberbonus", + "DS4.SpellModifierAbbr": "ZB", + "DS4.SpellModifierDescription": "Der Zauberbonus auf die Probe.", + "DS4.SortBySpellModifier": "Nach Zauberbonus sortieren", + "DS4.SpellDistance": "Distanz", + "DS4.SpellDistanceDescription": "Die maximale Entfernung zum Ziel. „Selbst“ bedeutet, dass nur der Zauberwirker selbst das Ziel des Zaubers sein kann.", + "DS4.SpellEffectRadius": "Wirkungsradius", + "DS4.SpellEffectRadiusDescription": "Der Wirkungsradius des Zaubers.", + "DS4.SpellDuration": "Dauer", + "DS4.SpellDurationDescription": "Die Wirkungszeit des Zaubers.", + "DS4.CooldownDuration": "Abklingzeit", + "DS4.CooldownDurationDescription": "Die Dauer, die der Zauber nach erfolgreichem Wirken nicht einsetzbar ist.", + "DS4.CooldownDuration0R": "0 Kampfrunden", + "DS4.CooldownDuration1R": "1 Kampfrunde", + "DS4.CooldownDuration2R": "2 Kampfrunden", + "DS4.CooldownDuration5R": "5 Kampfrunden", + "DS4.CooldownDuration10R": "10 Kampfrunden", + "DS4.CooldownDuration100R": "100 Kampfrunden", + "DS4.CooldownDuration1D": "1 Tag", + "DS4.CooldownDurationD20D": "W20 Tage", "DS4.SpellMinimumLevel": "Zugangsstufe", + "DS4.SpellMinimumLevelDescription": "Die minimale Stufe, ab der ein Zauberwirker den Zauberspruch erlernen kann.", "DS4.SpellCasterClassHealer": "Heiler", "DS4.SpellCasterClassSorcerer": "Schwarzmagier", "DS4.SpellCasterClassWizard": "Zauberer", "DS4.SpellPrice": "Preis (Gold)", + "DS4.SpellPriceDescription": "Der Kaufpreis des Zauberspruchs.", "DS4.EffectEnabled": "Aktiv", "DS4.EffectEnabledAbbr": "A", "DS4.EffectEffectivelyEnabled": "Effektiv Aktiv (unter Betrachtung, ob ein eventuelles Quellen-Item ausgerüstet ist usw.)", @@ -240,6 +257,7 @@ "DS4.ErrorSlayingDiceRecursionLimitExceeded": "Die maximale Rekursionstiefe für slayende Würfelwürfe wurde überschritten.", "DS4.ErrorInvalidNumberOfDice": "Ungültige Anzahl an Würfeln.", "DS4.ErrorDuringMigration": "Fehler während der Aktualisierung des DS4 Systems von Migrationsversion {currentVersion} auf {targetVersion}. Der Fehler trat während der Ausführung des Migrationsskripts mit der Version {migrationVersion} auf. Spätere Migrationsskripte wurden nicht ausgeführt. Mehr Details finden Sie in der Entwicklerkonsole (F12).", + "DS4.ErrorDuringCompendiumMigration": "Fehler während der Aktualisierung Kompendiums '{pack}' für DS4 von Migrationsversion {currentVersion} auf {targetVersion}. Der Fehler trat während der Ausführung des Migrationsskripts mit der Version {migrationVersion} auf. Spätere Migrationsskripte wurden nicht ausgeführt. Mehr Details finden Sie in der Entwicklerkonsole (F12).", "DS4.ErrorCannotRollUnownedItem": "Für das Item '{name}' ({id}) kann nicht gewürfelt werden, da es keinem Aktor gehört.", "DS4.ErrorRollingForItemTypeNotPossible": "Würfeln ist für Items vom Typ '{type}' nicht möglich.", "DS4.ErrorWrongItemType": "Ein Item vom Type '{expectedType}' wurde erwartet aber das Item '{name}' ({id}) ist vom Typ '{actualType}'.", @@ -255,9 +273,11 @@ "DS4.WarningItemIsNotRollable": "Für das Item '{name}' ({id}) vom Typ '{type}' kann nicht gewürfelt werden.", "DS4.WarningMacrosCanOnlyBeCreatedForOwnedItems": "Makros können nur für besessene Items angelegt werden.", "DS4.WarningInvalidCheckDropped": "Eine ungültige Probe wurde auf die Hotbar gezogen.", - "DS4.InfoManuallyEnterSpellBonus": "Der korrekte Wert für den Zauberbonus '{spellBonus}' des Zaubers '{name}' muss manuell angegeben werden.", + "DS4.InfoManuallyEnterSpellModifier": "Der korrekte Wert für den Zauberbonus '{spellModifier}' des Zaubers '{name}' muss manuell angegeben werden.", "DS4.InfoSystemUpdateStart": "Aktualisiere DS4 System von Migrationsversion {currentVersion} auf {targetVersion}. Bitte haben Sie etwas Geduld, schließen Sie nicht das Spiel und fahren Sie nicht den Server herunter.", "DS4.InfoSystemUpdateCompleted": "Aktualisierung des DS4 Systems von Migrationsversion {currentVersion} auf {targetVersion} erfolgreich!", + "DS4.InfoCompendiumMigrationStart": "Aktualisiere Kompendium '{pack}' für DS4 von Migrationsversion {currentVersion} auf {targetVersion}. Bitte haben Sie etwas Geduld, schließen Sie nicht das Spiel und fahren Sie nicht den Server herunter.", + "DS4.InfoCompendiumMigrationCompleted": "Aktualisierung des Kompendiums '{pack}' für DS4 von Migrationsversion {currentVersion} auf {targetVersion} erfolgreich!", "DS4.UnitRounds": "Runden", "DS4.UnitRoundsAbbr": "Rnd", "DS4.UnitMinutes": "Minuten", diff --git a/lang/en.json b/lang/en.json index f6d6d59f..38640607 100644 --- a/lang/en.json +++ b/lang/en.json @@ -114,10 +114,12 @@ "DS4.ArmorMaterialTypeNaturalAbbr": "Natural", "DS4.SpellType": "Spell Type", "DS4.SpellTypeAbbr": "T", + "DS4.SpellTypeDescription": "The type of the spell.", "DS4.SortBySpellType": "Sort by Spell Type", "DS4.SpellTypeSpellcasting": "Spellcasting", "DS4.SpellTypeTargetedSpellcasting": "Targeted Spellcasting", "DS4.SpellCategory": "Category", + "DS4.SpellCategoryDescription": "A category which the spell belongs to.", "DS4.SpellCategoryHealing": "Healing", "DS4.SpellCategoryFire": "Fire", "DS4.SpellCategoryIce": "Ice", @@ -127,18 +129,33 @@ "DS4.SpellCategoryElectricity": "Electricity", "DS4.SpellCategoryNone": "None", "DS4.SpellCategoryUnset": "Unset", - "DS4.SpellBonus": "Spell Bonus", - "DS4.SpellBonusAbbr": "SB", - "DS4.SortBySpellBonus": "Sort by Spell Bonus", - "DS4.SpellMaxDistance": "Range", - "DS4.SpellEffectRadius": "Radius", + "DS4.SpellModifier": "Spell Modifier", + "DS4.SpellModifierAbbr": "SM", + "DS4.SpellModifierDescription": "The spell modifier for the corresponding check.", + "DS4.SortBySpellModifier": "Sort by Spell Modifier", + "DS4.SpellDistance": "Distance", + "DS4.SpellDistanceDescription": "The maximum distance to the target, “Self” meaning that only the caster can be the target of this spell.", + "DS4.SpellEffectRadius": "Area of Effect Radius", + "DS4.SpellEffectRadiusDescription": "The radius of the area of effect of the spell.", "DS4.SpellDuration": "Duration", - "DS4.SpellCooldownDuration": "Cooldown", + "DS4.SpellDurationDescription": "The spell’s duration.", + "DS4.CooldownDuration": "Cooldown Period", + "DS4.CooldownDurationDescription": "The length of time to wait after a successful casting before the spell can be cast again.", + "DS4.CooldownDuration0R": "0 Rounds", + "DS4.CooldownDuration1R": "1 Round", + "DS4.CooldownDuration2R": "2 Rounds", + "DS4.CooldownDuration5R": "5 Rounds", + "DS4.CooldownDuration10R": "10 Rounds", + "DS4.CooldownDuration100R": "100 Rounds", + "DS4.CooldownDuration1D": "1 Day", + "DS4.CooldownDurationD20D": "D20 Days", "DS4.SpellMinimumLevel": "Minimum Level", + "DS4.SpellMinimumLevelDescription": "The minimum level at which a spell caster may learn the spell.", "DS4.SpellCasterClassHealer": "Healer", "DS4.SpellCasterClassSorcerer": "Sorcerer", "DS4.SpellCasterClassWizard": "Wizard", "DS4.SpellPrice": "Price (Gold)", + "DS4.SpellPriceDescription": "The price to purchase the spell.", "DS4.EffectEnabled": "Enabled", "DS4.EffectEnabledAbbr": "E", "DS4.EffectEffectivelyEnabled": "Effectively Enabled (taking into account whether a potential source item is equipped etc.)", @@ -240,6 +257,7 @@ "DS4.ErrorSlayingDiceRecursionLimitExceeded": "Maximum recursion depth for slaying dice roll exceeded.", "DS4.ErrorInvalidNumberOfDice": "Invalid number of dice.", "DS4.ErrorDuringMigration": "Error while migrating DS4 system from migration version {currentVersion} to {targetVersion}. The error occurred during execution of migration script with version {migrationVersion}. Later migrations have not been executed. For more details, please look at the development console (F12).", + "DS4.ErrorDuringCompendiumMigration": "Error while migrating compendium '{pack}' for DS4 from migration version {currentVersion} to {targetVersion}. The error occurred during execution of migration script with version {migrationVersion}. Later migrations have not been executed. For more details, please look at the development console (F12).", "DS4.ErrorCannotRollUnownedItem": "Rolling for item '{name}' ({id})is not possible because it is not owned.", "DS4.ErrorRollingForItemTypeNotPossible": "Rolling is not possible for items of type '{type}'.", "DS4.ErrorWrongItemType": "Expected an item of type '{expectedType}' but item '{name}' ({id}) is of type '{actualType}'.", @@ -255,9 +273,11 @@ "DS4.WarningItemIsNotRollable": "Item '{name}' ({id}) of type '{type}' is not rollable.", "DS4.WarningMacrosCanOnlyBeCreatedForOwnedItems": "Macros can only be created for owned items.", "DS4.WarningInvalidCheckDropped": "An invalid check was dropped on the Hotbar.", - "DS4.InfoManuallyEnterSpellBonus": "The correct value of the spell bonus '{spellBonus}' of the spell '{name}' needs to be entered by manually.", + "DS4.InfoManuallyEnterSpellModifier": "The correct value of the spell modifier '{spellModifier}' of the spell '{name}' needs to be entered by manually.", "DS4.InfoSystemUpdateStart": "Migrating DS4 system from migration version {currentVersion} to {targetVersion}. Please be patient and do not close your game or shut down your server.", "DS4.InfoSystemUpdateCompleted": "Migration of DS4 system from migration version {currentVersion} to {targetVersion} successful!", + "DS4.InfoCompendiumMigrationStart": "Migrating compendium '{pack}' for DS4 from migration version {currentVersion} to {targetVersion}. Please be patient and do not close your game or shut down your server.", + "DS4.InfoCompendiumMigrationCompleted": "Migration of compendium '{pack}' for DS4 from migration version {currentVersion} to {targetVersion} successful!", "DS4.UnitRounds": "Rounds", "DS4.UnitRoundsAbbr": "rnd", "DS4.UnitMinutes": "Minutes", diff --git a/packs/creatures.json b/packs/creatures.json index fe7a9565..47ceb694 100644 --- a/packs/creatures.json +++ b/packs/creatures.json @@ -1881,10 +1881,7 @@ "value": "", "unit": "custom" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": null, "wizard": null, @@ -3584,10 +3581,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": 2, "wizard": 5, @@ -3629,10 +3623,7 @@ "value": "VE / 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": 12, @@ -3674,10 +3665,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "5", - "unit": "rounds" - }, + "cooldownDuration": "5r", "minimumLevels": { "healer": 16, "wizard": 10, @@ -3719,10 +3707,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": 16, "wizard": 12, @@ -3764,10 +3749,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 4, "wizard": 8, @@ -3809,10 +3791,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 4, "wizard": 8, @@ -3854,10 +3833,7 @@ "value": "Konzentration", "unit": "custom" }, - "cooldownDuration": { - "value": "0", - "unit": "rounds" - }, + "cooldownDuration": "0r", "minimumLevels": { "healer": null, "wizard": 6, @@ -3899,10 +3875,7 @@ "value": "Prb.", "unit": "minutes" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 20, "wizard": 12, @@ -3944,10 +3917,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": 8, "wizard": 5, @@ -3990,10 +3960,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "5", - "unit": "rounds" - }, + "cooldownDuration": "5r", "minimumLevels": { "healer": 1, "wizard": 5, @@ -16049,10 +16016,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 7, "wizard": 7, @@ -20114,10 +20078,7 @@ "value": "VE", "unit": "minutes" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 5, "wizard": 9, @@ -21132,7 +21093,7 @@ "name": "Gedankenzehrerstrahl", "type": "spell", "data": { - "description": "

Gedankenzehrerstrahl (nicht sichtbar; verursacht mental Schaden und führt zu Werteverlust)

", + "description": "

Nicht sichtbar; verursacht mental Schaden und führt zu Werteverlust

", "equipped": true, "spellType": "targetedSpellcasting", "bonus": "", @@ -21149,10 +21110,7 @@ "value": "", "unit": "custom" }, - "cooldownDuration": { - "value": "", - "unit": "rounds" - }, + "cooldownDuration": "0r", "minimumLevels": { "healer": null, "wizard": null, @@ -25446,10 +25404,7 @@ "value": "VE x 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": 10, @@ -25491,10 +25446,7 @@ "value": "VE", "unit": "minutes" }, - "cooldownDuration": { - "value": "W20", - "unit": "days" - }, + "cooldownDuration": "d20d", "minimumLevels": { "healer": null, "wizard": 18, @@ -25536,10 +25488,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": 2, "wizard": 5, @@ -25581,10 +25530,7 @@ "value": "VE", "unit": "rounds" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": 15, @@ -25626,10 +25572,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": null, "wizard": 12, @@ -25671,10 +25614,7 @@ "value": "Prb. x 5", "unit": "rounds" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": 15, @@ -25716,10 +25656,7 @@ "value": "VE / 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": 12, @@ -25761,10 +25698,7 @@ "value": "Bis erlöst", "unit": "custom" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": null, "wizard": 8, @@ -25806,10 +25740,7 @@ "value": "Bis Schloss geöffnet", "unit": "custom" }, - "cooldownDuration": { - "value": "5", - "unit": "rounds" - }, + "cooldownDuration": "5r", "minimumLevels": { "healer": 3, "wizard": 1, @@ -25851,10 +25782,7 @@ "value": "Prb. / 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": 4, "wizard": 9, @@ -25896,10 +25824,7 @@ "value": "Prb. / 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "5", - "unit": "rounds" - }, + "cooldownDuration": "5r", "minimumLevels": { "healer": null, "wizard": 6, @@ -25941,10 +25866,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": null, @@ -25986,10 +25908,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "0", - "unit": "rounds" - }, + "cooldownDuration": "0r", "minimumLevels": { "healer": null, "wizard": 15, @@ -26031,10 +25950,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": 5, "wizard": 2, @@ -26076,10 +25992,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": null, "wizard": 4, @@ -26121,10 +26034,7 @@ "value": "VE / 2", "unit": "hours" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": null, "wizard": 5, @@ -26166,10 +26076,7 @@ "value": "Prb.", "unit": "minutes" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 20, "wizard": 12, @@ -26211,10 +26118,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": 8, "wizard": 5, @@ -26256,10 +26160,7 @@ "value": "Prb. / 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": null, "wizard": 6, @@ -26301,10 +26202,7 @@ "value": "Prb. x 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": null, "wizard": null, @@ -26346,10 +26244,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "W20", - "unit": "days" - }, + "cooldownDuration": "d20d", "minimumLevels": { "healer": null, "wizard": 15, @@ -28333,10 +28228,7 @@ "value": "VE / 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": null, "wizard": null, @@ -28882,10 +28774,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "1", - "unit": "rounds" - }, + "cooldownDuration": "1r", "minimumLevels": { "healer": 10, "wizard": 7, diff --git a/packs/spells.json b/packs/spells.json index 2de37c0f..344870f4 100644 --- a/packs/spells.json +++ b/packs/spells.json @@ -22,10 +22,7 @@ "value": "1", "unit": "rounds" }, - "cooldownDuration": { - "value": "0", - "unit": "rounds" - }, + "cooldownDuration": "0r", "minimumLevels": { "healer": 1, "wizard": 4, @@ -63,10 +60,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 4, "wizard": null, @@ -104,10 +98,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "1", - "unit": "rounds" - }, + "cooldownDuration": "1r", "minimumLevels": { "healer": 10, "wizard": 12, @@ -145,10 +136,7 @@ "value": "VE", "unit": "rounds" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": 2, "wizard": 6, @@ -186,10 +174,7 @@ "value": "VE", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 10, "wizard": 10, @@ -227,10 +212,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "2", - "unit": "rounds" - }, + "cooldownDuration": "2r", "minimumLevels": { "healer": 12, "wizard": null, @@ -268,10 +250,7 @@ "value": "Prb. / 2", "unit": "hours" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": 5, @@ -309,10 +288,7 @@ "value": "Prb. x 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 2, "wizard": 4, @@ -350,10 +326,7 @@ "value": "Prb. / 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "5", - "unit": "rounds" - }, + "cooldownDuration": "5r", "minimumLevels": { "healer": null, "wizard": 6, @@ -391,10 +364,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "1", - "unit": "rounds" - }, + "cooldownDuration": "1r", "minimumLevels": { "healer": 16, "wizard": 19, @@ -432,10 +402,7 @@ "value": "Prb. / 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": 4, "wizard": 9, @@ -473,10 +440,7 @@ "value": "VE", "unit": "hours" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 4, "wizard": 6, @@ -514,10 +478,7 @@ "value": "Prb. / 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": null, "wizard": 6, @@ -555,10 +516,7 @@ "value": "VE", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": null, "wizard": 8, @@ -596,10 +554,7 @@ "value": "VE", "unit": "rounds" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": 15, @@ -637,10 +592,7 @@ "value": "Prb.", "unit": "hours" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": 5, @@ -678,10 +630,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 6, "wizard": null, @@ -719,10 +668,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "2", - "unit": "rounds" - }, + "cooldownDuration": "2r", "minimumLevels": { "healer": 4, "wizard": null, @@ -760,10 +706,7 @@ "value": "Bis erlöst", "unit": "custom" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": null, "wizard": 8, @@ -801,10 +744,7 @@ "value": "Prb.", "unit": "minutes" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 1, "wizard": 1, @@ -842,10 +782,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 20, "wizard": 10, @@ -883,10 +820,7 @@ "value": "VE", "unit": "minutes" }, - "cooldownDuration": { - "value": "1", - "unit": "rounds" - }, + "cooldownDuration": "1r", "minimumLevels": { "healer": 1, "wizard": 1, @@ -924,10 +858,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": null, "wizard": 10, @@ -965,10 +896,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "W20", - "unit": "days" - }, + "cooldownDuration": "d20d", "minimumLevels": { "healer": null, "wizard": 15, @@ -1006,10 +934,7 @@ "value": "VE x 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": null, "wizard": 4, @@ -1047,10 +972,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": 2, "wizard": 5, @@ -1088,10 +1010,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 12, "wizard": 10, @@ -1129,10 +1048,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 5, "wizard": null, @@ -1170,10 +1086,7 @@ "value": "Prb.", "unit": "days" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": 6, @@ -1211,10 +1124,7 @@ "value": "Prb.", "unit": "minutes" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 20, "wizard": 12, @@ -1252,10 +1162,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "0", - "unit": "rounds" - }, + "cooldownDuration": "0r", "minimumLevels": { "healer": 1, "wizard": null, @@ -1293,10 +1200,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": 17, @@ -1334,10 +1238,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": null, "wizard": 4, @@ -1375,10 +1276,7 @@ "value": "VE", "unit": "hours" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 1, "wizard": 7, @@ -1416,10 +1314,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 18, "wizard": null, @@ -1457,10 +1352,7 @@ "value": "Prb.", "unit": "minutes" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": 10, @@ -1498,10 +1390,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "5", - "unit": "rounds" - }, + "cooldownDuration": "5r", "minimumLevels": { "healer": 1, "wizard": 5, @@ -1539,10 +1428,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": 5, @@ -1580,10 +1466,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": null, "wizard": 4, @@ -1621,10 +1504,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 7, "wizard": 7, @@ -1662,10 +1542,7 @@ "value": "VE min oder Konzentration", "unit": "minutes" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 14, "wizard": 10, @@ -1703,10 +1580,7 @@ "value": "Prb.", "unit": "minutes" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": 1, "wizard": 1, @@ -1744,10 +1618,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": 5, "wizard": 2, @@ -1785,10 +1656,7 @@ "value": "VE", "unit": "minutes" }, - "cooldownDuration": { - "value": "W20", - "unit": "days" - }, + "cooldownDuration": "d20d", "minimumLevels": { "healer": null, "wizard": 18, @@ -1826,10 +1694,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "5", - "unit": "rounds" - }, + "cooldownDuration": "5r", "minimumLevels": { "healer": 4, "wizard": null, @@ -1867,10 +1732,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": 10, @@ -1908,10 +1770,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 4, "wizard": 8, @@ -1949,10 +1808,7 @@ "value": "VE", "unit": "minutes" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 6, "wizard": 7, @@ -1990,10 +1846,7 @@ "value": "Prb. x 5", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 20, "wizard": 10, @@ -2031,10 +1884,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": 3, "wizard": 6, @@ -2072,10 +1922,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "W20", - "unit": "days" - }, + "cooldownDuration": "d20d", "minimumLevels": { "healer": null, "wizard": null, @@ -2113,10 +1960,7 @@ "value": "Prb. / 2", "unit": "minutes" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 1, "wizard": null, @@ -2154,10 +1998,7 @@ "value": "Bis Strecke zurückgelegt", "unit": "custom" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": 2, "wizard": 3, @@ -2195,10 +2036,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "0", - "unit": "rounds" - }, + "cooldownDuration": "0r", "minimumLevels": { "healer": null, "wizard": 5, @@ -2236,10 +2074,7 @@ "value": "VE", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 10, "wizard": null, @@ -2277,10 +2112,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": null, "wizard": 8, @@ -2318,10 +2150,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "0", - "unit": "rounds" - }, + "cooldownDuration": "0r", "minimumLevels": { "healer": 7, "wizard": 5, @@ -2359,10 +2188,7 @@ "value": "VE x 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": null, "wizard": 2, @@ -2400,10 +2226,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "1", - "unit": "rounds" - }, + "cooldownDuration": "1r", "minimumLevels": { "healer": 10, "wizard": 7, @@ -2441,10 +2264,7 @@ "value": "VE", "unit": "minutes" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 5, "wizard": 9, @@ -2482,10 +2302,7 @@ "value": "VE", "unit": "hours" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 1, "wizard": null, @@ -2523,10 +2340,7 @@ "value": "Konzentration", "unit": "custom" }, - "cooldownDuration": { - "value": "W20", - "unit": "days" - }, + "cooldownDuration": "d20d", "minimumLevels": { "healer": 8, "wizard": 12, @@ -2564,10 +2378,7 @@ "value": "VE", "unit": "hours" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": null, "wizard": 9, @@ -2605,10 +2416,7 @@ "value": "Konzentration", "unit": "custom" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 8, "wizard": 4, @@ -2646,10 +2454,7 @@ "value": "Konzentration", "unit": "custom" }, - "cooldownDuration": { - "value": "0", - "unit": "rounds" - }, + "cooldownDuration": "0r", "minimumLevels": { "healer": null, "wizard": 6, @@ -2687,10 +2492,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 8, "wizard": 18, @@ -2728,10 +2530,7 @@ "value": "VE x 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": 10, @@ -2769,10 +2568,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": 10, "wizard": 6, @@ -2810,10 +2606,7 @@ "value": "VE x 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 6, "wizard": 2, @@ -2851,10 +2644,7 @@ "value": "VE", "unit": "hours" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 2, "wizard": null, @@ -2892,10 +2682,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "0", - "unit": "rounds" - }, + "cooldownDuration": "0r", "minimumLevels": { "healer": 3, "wizard": 7, @@ -2933,10 +2720,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 4, "wizard": 8, @@ -2974,10 +2758,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 1, "wizard": 6, @@ -3015,10 +2796,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "W20", - "unit": "days" - }, + "cooldownDuration": "d20d", "minimumLevels": { "healer": null, "wizard": null, @@ -3056,10 +2834,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "0", - "unit": "rounds" - }, + "cooldownDuration": "0r", "minimumLevels": { "healer": null, "wizard": 15, @@ -3097,10 +2872,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": null, @@ -3138,10 +2910,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": 16, "wizard": 12, @@ -3179,10 +2948,7 @@ "value": "1", "unit": "rounds" }, - "cooldownDuration": { - "value": "0", - "unit": "rounds" - }, + "cooldownDuration": "0r", "minimumLevels": { "healer": 1, "wizard": 3, @@ -3220,10 +2986,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 7, "wizard": 8, @@ -3261,10 +3024,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": 1, "wizard": 1, @@ -3302,10 +3062,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": null, @@ -3343,10 +3100,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 4, "wizard": 8, @@ -3384,10 +3138,7 @@ "value": "VE", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 2, "wizard": 6, @@ -3425,10 +3176,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 10, "wizard": null, @@ -3466,10 +3214,7 @@ "value": "Bis Schloss geöffnet", "unit": "custom" }, - "cooldownDuration": { - "value": "5", - "unit": "rounds" - }, + "cooldownDuration": "5r", "minimumLevels": { "healer": 3, "wizard": 1, @@ -3507,10 +3252,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": 5, "wizard": 7, @@ -3548,10 +3290,7 @@ "value": "VE / 2", "unit": "hours" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": null, "wizard": 5, @@ -3589,10 +3328,7 @@ "value": "VE", "unit": "rounds" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 7, "wizard": 3, @@ -3630,10 +3366,7 @@ "value": "1 Min & bis Distanz gefallen", "unit": "custom" }, - "cooldownDuration": { - "value": "0", - "unit": "rounds" - }, + "cooldownDuration": "0r", "minimumLevels": { "healer": 5, "wizard": 3, @@ -3671,10 +3404,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": null, "wizard": 4, @@ -3712,10 +3442,7 @@ "value": "bis zu VE / 2", "unit": "hours" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": 5, @@ -3753,10 +3480,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "5", - "unit": "rounds" - }, + "cooldownDuration": "5r", "minimumLevels": { "healer": 16, "wizard": 10, @@ -3794,10 +3518,7 @@ "value": "VE", "unit": "hours" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": 10, @@ -3835,10 +3556,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 1, "wizard": 10, @@ -3876,10 +3594,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": null, "wizard": 12, @@ -3917,10 +3632,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": null, "wizard": 10, @@ -3958,10 +3670,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": 2, "wizard": 1, @@ -3999,10 +3708,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": null, "wizard": 1, @@ -4040,10 +3746,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "0", - "unit": "rounds" - }, + "cooldownDuration": "0r", "minimumLevels": { "healer": null, "wizard": 1, @@ -4081,10 +3784,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 2, "wizard": 7, @@ -4122,10 +3822,7 @@ "value": "VE / 2", "unit": "minutes" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": null, "wizard": 8, @@ -4163,10 +3860,7 @@ "value": "VE", "unit": "hours" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": 1, "wizard": 2, @@ -4204,10 +3898,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "1", - "unit": "rounds" - }, + "cooldownDuration": "1r", "minimumLevels": { "healer": 2, "wizard": 5, @@ -4245,10 +3936,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": null, @@ -4286,10 +3974,7 @@ "value": "VE", "unit": "hours" }, - "cooldownDuration": { - "value": "0", - "unit": "rounds" - }, + "cooldownDuration": "0r", "minimumLevels": { "healer": 5, "wizard": 9, @@ -4327,10 +4012,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "1", - "unit": "rounds" - }, + "cooldownDuration": "1r", "minimumLevels": { "healer": null, "wizard": 20, @@ -4368,10 +4050,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 10, "wizard": 12, @@ -4409,10 +4088,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": 8, "wizard": 5, @@ -4450,10 +4126,7 @@ "value": "Prb x 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 1, "wizard": null, @@ -4491,10 +4164,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "1", - "unit": "rounds" - }, + "cooldownDuration": "1r", "minimumLevels": { "healer": 5, "wizard": 1, @@ -4532,10 +4202,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 10, "wizard": null, @@ -4573,10 +4240,7 @@ "value": "VE / 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 12, "wizard": 10, @@ -4614,10 +4278,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 4, "wizard": null, @@ -4655,10 +4316,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": 20, @@ -4696,10 +4354,7 @@ "value": "VE Fragen, bzw. VE Minuten", "unit": "custom" }, - "cooldownDuration": { - "value": "W20", - "unit": "days" - }, + "cooldownDuration": "d20d", "minimumLevels": { "healer": null, "wizard": null, @@ -4737,10 +4392,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 12, "wizard": 7, @@ -4778,10 +4430,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "0", - "unit": "rounds" - }, + "cooldownDuration": "0r", "minimumLevels": { "healer": null, "wizard": 6, @@ -4819,10 +4468,7 @@ "value": "Prb. x 5", "unit": "rounds" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": 15, @@ -4860,10 +4506,7 @@ "value": "VE", "unit": "rounds" }, - "cooldownDuration": { - "value": "10", - "unit": "rounds" - }, + "cooldownDuration": "10r", "minimumLevels": { "healer": 3, "wizard": 8, @@ -4901,10 +4544,7 @@ "value": "Sofort", "unit": "custom" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 10, "wizard": 5, @@ -4942,10 +4582,7 @@ "value": "Prb. / 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": 10, @@ -4983,10 +4620,7 @@ "value": "VE / 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": 12, @@ -5024,10 +4658,7 @@ "value": "Bis auformuliert", "unit": "custom" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 8, "wizard": 6, @@ -5065,10 +4696,7 @@ "value": "VE x 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": 8, "wizard": 6, @@ -5106,10 +4734,7 @@ "value": "Prb. x 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "100", - "unit": "rounds" - }, + "cooldownDuration": "100r", "minimumLevels": { "healer": null, "wizard": null, @@ -5147,10 +4772,7 @@ "value": "VE / 2", "unit": "rounds" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": 10, @@ -5188,10 +4810,7 @@ "value": "VE x 2", "unit": "hours" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": null, "wizard": 17, @@ -5229,10 +4848,7 @@ "value": "Prb.", "unit": "rounds" }, - "cooldownDuration": { - "value": "24", - "unit": "hours" - }, + "cooldownDuration": "1d", "minimumLevels": { "healer": 8, "wizard": 8, @@ -5270,10 +4886,7 @@ "value": "Konzentration", "unit": "custom" }, - "cooldownDuration": { - "value": "W20", - "unit": "days" - }, + "cooldownDuration": "d20d", "minimumLevels": { "healer": 12, "wizard": null, diff --git a/spec/item/type-specific-helpers/spell.spec.ts b/spec/item/type-specific-helpers/spell.spec.ts index 9b520e5f..e454c959 100644 --- a/spec/item/type-specific-helpers/spell.spec.ts +++ b/spec/item/type-specific-helpers/spell.spec.ts @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: MIT -import { DS4SpellDataSourceData, TemporalUnit, UnitData } from "../../../src/item/item-data-source"; +import { CooldownDuration, DS4SpellDataSourceData } from "../../../src/item/item-data-source"; import { calculateSpellPrice } from "../../../src/item/type-specific-helpers/spell"; const defaultData: DS4SpellDataSourceData = { @@ -23,10 +23,7 @@ const defaultData: DS4SpellDataSourceData = { value: "", unit: "custom", }, - cooldownDuration: { - value: "", - unit: "rounds", - }, + cooldownDuration: "0r", minimumLevels: { healer: null, wizard: null, @@ -167,65 +164,41 @@ function buildCombinedTestCases(): CombinedTestCase[] { } describe("calculateSpellPrice", () => { - const cooldownDurations: (UnitData & { factor: number })[] = [ - { value: "", unit: "rounds", factor: 1 }, - { value: "foo", unit: "rounds", factor: 1 }, - { value: "0", unit: "rounds", factor: 1 }, - { value: "1", unit: "rounds", factor: 1 }, - { value: "17279", unit: "rounds", factor: 1 }, - { value: "17280", unit: "rounds", factor: 2 }, - { value: "34559", unit: "rounds", factor: 2 }, - { value: "34560", unit: "rounds", factor: 3 }, - - { value: "", unit: "minutes", factor: 1 }, - { value: "foo", unit: "minutes", factor: 1 }, - { value: "0", unit: "minutes", factor: 1 }, - { value: "1", unit: "minutes", factor: 1 }, - { value: "1439", unit: "minutes", factor: 1 }, - { value: "1440", unit: "minutes", factor: 2 }, - { value: "2879", unit: "minutes", factor: 2 }, - { value: "2880", unit: "minutes", factor: 3 }, - - { value: "", unit: "hours", factor: 1 }, - { value: "foo", unit: "hours", factor: 1 }, - { value: "0", unit: "hours", factor: 1 }, - { value: "1", unit: "hours", factor: 1 }, - { value: "23", unit: "hours", factor: 1 }, - { value: "24", unit: "hours", factor: 2 }, - { value: "47", unit: "hours", factor: 2 }, - { value: "48", unit: "hours", factor: 3 }, - - { value: "", unit: "days", factor: 3 }, - { value: "foo", unit: "days", factor: 3 }, - { value: "0", unit: "days", factor: 1 }, - { value: "1", unit: "days", factor: 2 }, - { value: "2", unit: "days", factor: 3 }, + const cooldownDurations: { cooldownDuration: CooldownDuration; factor: number }[] = [ + { cooldownDuration: "0r", factor: 1 }, + { cooldownDuration: "1r", factor: 1 }, + { cooldownDuration: "2r", factor: 1 }, + { cooldownDuration: "5r", factor: 1 }, + { cooldownDuration: "10r", factor: 1 }, + { cooldownDuration: "100r", factor: 1 }, + { cooldownDuration: "1d", factor: 2 }, + { cooldownDuration: "d20d", factor: 3 }, ]; - describe.each(cooldownDurations)("with cooldown duration set to $value $unit", ({ value, unit, factor }) => { - const dataWithCooldownDuration = { - ...defaultData, - cooldownDuration: { - value, - unit, - }, - }; + describe.each(cooldownDurations)( + "with cooldown duration set to $cooldownDuration", + ({ cooldownDuration, factor }) => { + const dataWithCooldownDuration = { + ...defaultData, + cooldownDuration, + }; - it.each(buildCombinedTestCases())( - `returns ${factor} × $expected if the minimum leves are $minimumLevels`, - ({ minimumLevels, expected }) => { - // given - const data: DS4SpellDataSourceData = { - ...dataWithCooldownDuration, - minimumLevels, - }; + it.each(buildCombinedTestCases())( + `returns ${factor} × $expected if the minimum leves are $minimumLevels`, + ({ minimumLevels, expected }) => { + // given + const data: DS4SpellDataSourceData = { + ...dataWithCooldownDuration, + minimumLevels, + }; - // when - const spellPrice = calculateSpellPrice(data); + // when + const spellPrice = calculateSpellPrice(data); - // then - expect(spellPrice).toBe(expected !== null ? expected * factor : expected); - }, - ); - }); + // then + expect(spellPrice).toBe(expected !== null ? expected * factor : expected); + }, + ); + }, + ); }); diff --git a/src/common/time-helpers.ts b/src/common/time-helpers.ts deleted file mode 100644 index fb32ae6f..00000000 --- a/src/common/time-helpers.ts +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Johannes Loher -// -// SPDX-License-Identifier: MIT - -export const secondsPerRound = 5; -export const secondsPerMinute = 60; -export const minutesPerHour = 60; -export const hoursPerDay = 24; diff --git a/src/config.ts b/src/config.ts index 2c79cf54..731744d8 100644 --- a/src/config.ts +++ b/src/config.ts @@ -106,6 +106,17 @@ const i18nKeys = { unset: "DS4.SpellCategoryUnset", }, + cooldownDurations: { + "0r": "DS4.CooldownDuration0R", + "1r": "DS4.CooldownDuration1R", + "2r": "DS4.CooldownDuration2R", + "5r": "DS4.CooldownDuration5R", + "10r": "DS4.CooldownDuration10R", + "100r": "DS4.CooldownDuration100R", + "1d": "DS4.CooldownDuration1D", + d20d: "DS4.CooldownDurationD20D", + }, + /** * Define the set of actor types */ @@ -276,16 +287,6 @@ const i18nKeys = { minutes: "DS4.UnitMinutes", hours: "DS4.UnitHours", days: "DS4.UnitDays", - }, - - /** - * Define translations for available duration units including "custom" - */ - customTemporalUnits: { - rounds: "DS4.UnitRounds", - minutes: "DS4.UnitMinutes", - hours: "DS4.UnitHours", - days: "DS4.UnitDays", custom: "DS4.UnitCustom", }, @@ -297,16 +298,6 @@ const i18nKeys = { minutes: "DS4.UnitMinutesAbbr", hours: "DS4.UnitHoursAbbr", days: "DS4.UnitDaysAbbr", - }, - - /** - * Define abbreviations for available duration units including "custom" - */ - customTemporalUnitsAbbr: { - rounds: "DS4.UnitRoundsAbbr", - minutes: "DS4.UnitMinutesAbbr", - hours: "DS4.UnitHoursAbbr", - days: "DS4.UnitDaysAbbr", custom: "DS4.UnitCustomAbbr", }, diff --git a/src/hooks/setup.ts b/src/hooks/setup.ts index d9105954..0a548f2c 100644 --- a/src/hooks/setup.ts +++ b/src/hooks/setup.ts @@ -18,7 +18,14 @@ export default function registerForSetupHooks(): void { * Localizes all objects in {@link DS4.i18n} and sorts them unless they are explicitly excluded. */ function localizeAndSortConfigObjects() { - const noSort = ["attributes", "traits", "combatValues", "creatureSizeCategories"]; + const noSort = [ + "attributes", + "combatValues", + "cooldownDurations", + "creatureSizeCategories", + "spellCategories", + "traits", + ]; const localizeObject = (obj: T, sort = true): T => { const localized = Object.entries(obj).map(([key, value]): [string, string] => { diff --git a/src/item/item-data-source.ts b/src/item/item-data-source.ts index dc7f4c4c..f75dafa5 100644 --- a/src/item/item-data-source.ts +++ b/src/item/item-data-source.ts @@ -136,14 +136,16 @@ export interface DS4ShieldDataSourceData DS4ItemDataSourceDataEquipable, DS4ItemDataSourceDataProtective {} +export type CooldownDuration = keyof typeof DS4.i18n.cooldownDurations; + export interface DS4SpellDataSourceData extends DS4ItemDataSourceDataBase, DS4ItemDataSourceDataEquipable { spellType: keyof typeof DS4.i18n.spellTypes; bonus: string; spellCategory: keyof typeof DS4.i18n.spellCategories; maxDistance: UnitData; effectRadius: UnitData; - duration: UnitData; - cooldownDuration: UnitData; + duration: UnitData; + cooldownDuration: CooldownDuration; minimumLevels: { healer: number | null; wizard: number | null; @@ -158,9 +160,7 @@ export interface UnitData { type DistanceUnit = keyof typeof DS4.i18n.distanceUnits; -type CustomTemporalUnit = keyof typeof DS4.i18n.customTemporalUnits; - -export type TemporalUnit = keyof typeof DS4.i18n.temporalUnits; +type TemporalUnit = keyof typeof DS4.i18n.temporalUnits; export interface DS4EquipmentDataSourceData extends DS4ItemDataSourceDataBase, diff --git a/src/item/item.ts b/src/item/item.ts index 822a68e7..ed875897 100644 --- a/src/item/item.ts +++ b/src/item/item.ts @@ -148,17 +148,17 @@ export class DS4Item extends Item { } const ownerDataData = this.actor.data.data; - const spellBonus = Number.isNumeric(this.data.data.bonus) ? parseInt(this.data.data.bonus) : undefined; - if (spellBonus === undefined) { + const spellModifier = Number.isNumeric(this.data.data.bonus) ? parseInt(this.data.data.bonus) : undefined; + if (spellModifier === undefined) { notifications.info( - getGame().i18n.format("DS4.InfoManuallyEnterSpellBonus", { + getGame().i18n.format("DS4.InfoManuallyEnterSpellModifier", { name: this.name, - spellBonus: this.data.data.bonus, + spellModifier: this.data.data.bonus, }), ); } const spellType = this.data.data.spellType; - const checkTargetNumber = ownerDataData.combatValues[spellType].total + (spellBonus ?? 0); + const checkTargetNumber = ownerDataData.combatValues[spellType].total + (spellModifier ?? 0); const speaker = ChatMessage.getSpeaker({ actor: this.actor, ...options.speaker }); await createCheckRoll(checkTargetNumber, { diff --git a/src/item/type-specific-helpers/spell.ts b/src/item/type-specific-helpers/spell.ts index 5af27f20..c9949996 100644 --- a/src/item/type-specific-helpers/spell.ts +++ b/src/item/type-specific-helpers/spell.ts @@ -2,8 +2,7 @@ // // SPDX-License-Identifier: MIT -import { hoursPerDay, minutesPerHour, secondsPerMinute, secondsPerRound } from "../../common/time-helpers"; -import { DS4SpellDataSourceData, TemporalUnit, UnitData } from "../item-data-source"; +import { CooldownDuration, DS4SpellDataSourceData } from "../item-data-source"; export function calculateSpellPrice(data: DS4SpellDataSourceData): number | null { const spellPriceFactor = calculateSpellPriceFactor(data.cooldownDuration); @@ -16,39 +15,18 @@ export function calculateSpellPrice(data: DS4SpellDataSourceData): number | null return baseSpellPrice === Infinity ? null : baseSpellPrice * spellPriceFactor; } -function calculateSpellPriceFactor(temporalData: UnitData): number { - let days: number; - if (Number.isNumeric(temporalData.value)) { - const value = Number.fromString(temporalData.value); - switch (temporalData.unit) { - case "days": { - days = value; - break; - } - case "hours": { - days = value / hoursPerDay; - break; - } - case "minutes": { - days = value / (hoursPerDay * minutesPerHour); - break; - } - case "rounds": { - days = (value * secondsPerRound) / (hoursPerDay * minutesPerHour * secondsPerMinute); - break; - } - } - } else { - switch (temporalData.unit) { - case "days": { - days = 2; - break; - } - default: { - days = 0; - break; - } - } +function calculateSpellPriceFactor(cooldownDuration: CooldownDuration): number { + switch (cooldownDuration) { + case "0r": + case "1r": + case "2r": + case "5r": + case "10r": + case "100r": + return 1; + case "1d": + return 2; + case "d20d": + return 3; } - return Math.clamped(Math.floor(days), 0, 2) + 1; } diff --git a/src/migrations.ts b/src/migrations.ts index 63d97697..4731e803 100644 --- a/src/migrations.ts +++ b/src/migrations.ts @@ -4,10 +4,11 @@ import { getGame } from "./helpers"; import logger from "./logger"; -import { migrate as migrate001 } from "./migrations/001"; -import { migrate as migrate002 } from "./migrations/002"; -import { migrate as migrate003 } from "./migrations/003"; -import { migrate as migrate004 } from "./migrations/004"; +import { migration as migration001 } from "./migrations/001"; +import { migration as migration002 } from "./migrations/002"; +import { migration as migration003 } from "./migrations/003"; +import { migration as migration004 } from "./migrations/004"; +import { migration as migration005 } from "./migrations/005"; import notifications from "./ui/notifications"; async function migrate(): Promise { @@ -43,11 +44,11 @@ async function migrateFromTo(oldMigrationVersion: number, targetMigrationVersion { permanent: true }, ); - for (const [i, migration] of migrationsToExecute.entries()) { + for (const [i, { migrate }] of migrationsToExecute.entries()) { const currentMigrationVersion = oldMigrationVersion + i + 1; logger.info("executing migration script ", currentMigrationVersion); try { - await migration(); + await migrate(); getGame().settings.set("ds4", "systemMigrationVersion", currentMigrationVersion); } catch (err) { notifications.error( @@ -73,18 +74,76 @@ async function migrateFromTo(oldMigrationVersion: number, targetMigrationVersion } } +async function migrateCompendiumFromTo( + pack: CompendiumCollection, + oldMigrationVersion: number, + targetMigrationVersion: number, +): Promise { + if (!getGame().user?.isGM) { + return; + } + + const migrationsToExecute = migrations.slice(oldMigrationVersion, targetMigrationVersion); + + if (migrationsToExecute.length > 0) { + notifications.info( + getGame().i18n.format("DS4.InfoCompendiumMigrationStart", { + pack: pack.title, + currentVersion: oldMigrationVersion, + targetVersion: targetMigrationVersion, + }), + { permanent: true }, + ); + + for (const [i, { migrateCompendium }] of migrationsToExecute.entries()) { + const currentMigrationVersion = oldMigrationVersion + i + 1; + logger.info("executing compendium migration ", currentMigrationVersion); + try { + await migrateCompendium(pack); + } catch (err) { + notifications.error( + getGame().i18n.format("DS4.ErrorDuringCompendiumMigration", { + pack: pack.title, + currentVersion: oldMigrationVersion, + targetVersion: targetMigrationVersion, + migrationVersion: currentMigrationVersion, + }), + { permanent: true }, + ); + logger.error("Failed ds4 compendium migration:", err); + return; + } + } + + notifications.info( + getGame().i18n.format("DS4.InfoCompendiumMigrationCompleted", { + pack: pack.title, + currentVersion: oldMigrationVersion, + targetVersion: targetMigrationVersion, + }), + { permanent: true }, + ); + } +} + function getTargetMigrationVersion(): number { return migrations.length; } -const migrations: Array<() => Promise> = [migrate001, migrate002, migrate003, migrate004]; +interface Migration { + migrate: () => Promise; + migrateCompendium: (pack: CompendiumCollection) => Promise; +} + +const migrations: Migration[] = [migration001, migration002, migration003, migration004, migration005]; function isFirstWorldStart(migrationVersion: number): boolean { return migrationVersion < 0; } export const migration = { - migrate: migrate, - migrateFromTo: migrateFromTo, - getTargetMigrationVersion: getTargetMigrationVersion, + migrate, + migrateFromTo, + getTargetMigrationVersion, + migrateCompendiumFromTo, }; diff --git a/src/migrations/001.ts b/src/migrations/001.ts index c8e2f7b3..c01252fa 100644 --- a/src/migrations/001.ts +++ b/src/migrations/001.ts @@ -10,7 +10,7 @@ import { migrateScenes, } from "./migrationHelpers"; -export async function migrate(): Promise { +async function migrate(): Promise { await migrateActors(getActorUpdateData); await migrateScenes(getSceneUpdateData); await migrateCompendiums(migrateCompendium); @@ -39,3 +39,8 @@ function getActorUpdateData(): Record { const getSceneUpdateData = getSceneUpdateDataGetter(getActorUpdateData); const migrateCompendium = getCompendiumMigrator({ getActorUpdateData, getSceneUpdateData }); + +export const migration = { + migrate, + migrateCompendium, +}; diff --git a/src/migrations/002.ts b/src/migrations/002.ts index 93ac4063..0c1ccb53 100644 --- a/src/migrations/002.ts +++ b/src/migrations/002.ts @@ -12,7 +12,7 @@ import { migrateScenes, } from "./migrationHelpers"; -export async function migrate(): Promise { +async function migrate(): Promise { await migrateItems(getItemUpdateData); await migrateActors(getActorUpdateData); await migrateScenes(getSceneUpdateData); @@ -32,3 +32,8 @@ const migrateCompendium = getCompendiumMigrator( { getItemUpdateData, getActorUpdateData, getSceneUpdateData }, { migrateToTemplateEarly: false }, ); + +export const migration = { + migrate, + migrateCompendium, +}; diff --git a/src/migrations/003.ts b/src/migrations/003.ts index 1ebc46f8..a2870ad5 100644 --- a/src/migrations/003.ts +++ b/src/migrations/003.ts @@ -12,7 +12,7 @@ import { migrateScenes, } from "./migrationHelpers"; -export async function migrate(): Promise { +async function migrate(): Promise { await migrateItems(getItemUpdateData); await migrateActors(getActorUpdateData); await migrateScenes(getSceneUpdateData); @@ -34,3 +34,8 @@ const migrateCompendium = getCompendiumMigrator( { getItemUpdateData, getActorUpdateData }, { migrateToTemplateEarly: false }, ); + +export const migration = { + migrate, + migrateCompendium, +}; diff --git a/src/migrations/004.ts b/src/migrations/004.ts index 97f3d155..e0483376 100644 --- a/src/migrations/004.ts +++ b/src/migrations/004.ts @@ -12,7 +12,7 @@ import { migrateScenes, } from "./migrationHelpers"; -export async function migrate(): Promise { +async function migrate(): Promise { await migrateItems(getItemUpdateData); await migrateActors(getActorUpdateData); await migrateScenes(getSceneUpdateData); @@ -21,6 +21,7 @@ export async function migrate(): Promise { function getItemUpdateData(itemData: Partial) { if (itemData.type !== "spell") return; + // @ts-expect-error the type of cooldownDuration was UnitData at the point for this migration, but it changed later on const cooldownDurationUnit: string | undefined = itemData.data?.cooldownDuration.unit; const updateData: Record = { @@ -38,3 +39,8 @@ function getItemUpdateData(itemData: Partial) const getActorUpdateData = getActorUpdateDataGetter(getItemUpdateData); const getSceneUpdateData = getSceneUpdateDataGetter(getActorUpdateData); const migrateCompendium = getCompendiumMigrator({ getItemUpdateData, getActorUpdateData, getSceneUpdateData }); + +export const migration = { + migrate, + migrateCompendium, +}; diff --git a/src/migrations/005.ts b/src/migrations/005.ts new file mode 100644 index 00000000..80d0fc8f --- /dev/null +++ b/src/migrations/005.ts @@ -0,0 +1,119 @@ +// SPDX-FileCopyrightText: 2021 Johannes Loher +// +// SPDX-License-Identifier: MIT + +import { CooldownDuration } from "../item/item-data-source"; +import { + getActorUpdateDataGetter, + getCompendiumMigrator, + getSceneUpdateDataGetter, + migrateActors, + migrateCompendiums, + migrateItems, + migrateScenes, +} from "./migrationHelpers"; + +const secondsPerRound = 5; +const secondsPerMinute = 60; +const roundsPerMinute = secondsPerMinute / secondsPerRound; +const minutesPerHour = 60; +const roundsPerHour = minutesPerHour / roundsPerMinute; +const hoursPerDay = 24; +const roundsPerDay = hoursPerDay / roundsPerHour; +const secondsPerDay = secondsPerMinute * minutesPerHour * hoursPerDay; + +async function migrate(): Promise { + await migrateItems(getItemUpdateData); + await migrateActors(getActorUpdateData); + await migrateScenes(getSceneUpdateData); + await migrateCompendiums(migrateCompendium); +} + +function getItemUpdateData(itemData: Partial) { + if (itemData.type !== "spell") return; + // @ts-expect-error the type of cooldownDuration is changed from UnitData to CooldownDuation with this migration + const cooldownDurationUnit: string | undefined = itemData.data?.cooldownDuration.unit; + // @ts-expect-error the type of cooldownDuration is changed from UnitData to CooldownDuation with this migration + const cooldownDurationValue: string | undefined = itemData.data?.cooldownDuration.value; + const cooldownDuration = migrateCooldownDuration(cooldownDurationValue, cooldownDurationUnit); + + const updateData: Record = { + data: { + cooldownDuration, + }, + }; + return updateData; +} + +function migrateCooldownDuration(cooldownDurationValue?: string, cooldownDurationUnit?: string) { + if (Number.isNumeric(cooldownDurationValue)) { + const value = Number.fromString(cooldownDurationValue!); + const rounds = getRounds(cooldownDurationUnit ?? "", value); + + if (rounds * secondsPerRound > secondsPerDay) { + return "d20d"; + } else if (rounds > 100) { + return "1d"; + } else if (rounds > 10) { + return "100r"; + } else if (rounds > 5) { + return "10r"; + } else if (rounds > 2) { + return "5r"; + } else if (rounds > 1) { + return "2r"; + } else if (rounds > 0) { + return "1r"; + } else { + return "0r"; + } + } else { + // if the value is not numeric, we can only make a best guess + switch (cooldownDurationUnit) { + case "rounds": { + return "10r"; + } + case "minutes": { + return "100r"; + } + case "hours": { + return "1d"; + } + case "days": { + return "d20d"; + } + default: { + return "0r"; + } + } + } +} + +function getRounds(unit: string, value: number): number { + switch (unit) { + case "rounds": { + return value; + } + case "minutes": { + return value * roundsPerMinute; + } + case "hours": { + return value * roundsPerHour; + } + case "days": { + return value * roundsPerDay; + } + default: { + return 0; + } + } +} + +const getActorUpdateData = getActorUpdateDataGetter(getItemUpdateData); +const getSceneUpdateData = getSceneUpdateDataGetter(getActorUpdateData); +const migrateCompendium = getCompendiumMigrator({ getItemUpdateData, getActorUpdateData, getSceneUpdateData }); + +export const migration = { + migrate, + migrateCompendium, +}; diff --git a/template.json b/template.json index b7378316..d4ec6bc3 100644 --- a/template.json +++ b/template.json @@ -187,10 +187,7 @@ "value": "", "unit": "custom" }, - "cooldownDuration": { - "value": "", - "unit": "rounds" - }, + "cooldownDuration": "0r", "minimumLevels": { "healer": null, "wizard": null, diff --git a/templates/sheets/actor/tabs/spells.hbs b/templates/sheets/actor/tabs/spells.hbs index 54ce2a0d..3f0df03c 100644 --- a/templates/sheets/actor/tabs/spells.hbs +++ b/templates/sheets/actor/tabs/spells.hbs @@ -25,7 +25,7 @@ SPDX-License-Identifier: MIT {{/inline}} {{!-- -!-- Three templates based on the "unit" template for displaying values with unit. +!-- Two templates based on the "unit" template for displaying values with unit. !-- Both accept a `config` object holding the unitNames and unitAbbr instead of !-- directly handing over the latter two. !-- @param titleKey: The key of the localized title to use. @@ -35,11 +35,6 @@ SPDX-License-Identifier: MIT titleKey=titleKey}} {{/inline}} -{{#*inline "customTemporalUnit"}} -{{> unit unitNames=config.i18n.customTemporalUnits unitAbbrs=config.i18n.customTemporalUnitsAbbr unitDatum=unitDatum -titleKey=titleKey}} -{{/inline}} - {{#*inline "distanceUnit"}} {{> unit unitNames=config.i18n.distanceUnits unitAbbrs=config.i18n.distanceUnitsAbbr unitDatum=unitDatum titleKey=titleKey}} @@ -60,16 +55,16 @@ titleKey=titleKey}} {{!-- spell bonus --}}
{{localize 'DS4.SpellBonusAbbr'}}
+ title="{{localize 'DS4.SortBySpellModifier'}}">{{localize 'DS4.SpellModifierAbbr'}} {{!-- max. distance --}} -
+
{{!-- duration --}}
{{!-- cooldown duration --}} -
+
{{/systems/ds4/templates/sheets/actor/components/item-list-header.hbs}} {{#each itemsByType.spell as |itemData id|}} @@ -77,23 +72,24 @@ titleKey=titleKey}} hideDescription=true}} {{!-- spell type --}} + src="{{lookup @root/config.icons.spellTypes itemData.data.spellType}}" + title="{{lookup @root/config.i18n.spellTypes itemData.data.spellType}}" /> {{!-- spell bonus --}} + data-property="data.bonus" value="{{itemData.data.bonus}}" title="{{localize 'DS4.SpellModifier'}}" /> {{!-- max. distance --}} - {{> distanceUnit titleKey='DS4.SpellMaxDistance' unitDatum=itemData.data.maxDistance - config=../../config}} + {{> distanceUnit titleKey='DS4.SpellDistance' unitDatum=itemData.data.maxDistance + config=@root/config}} {{!-- duration --}} - {{> customTemporalUnit titleKey='DS4.SpellDuration' unitDatum=itemData.data.duration config=../../config}} + {{> temporalUnit titleKey='DS4.SpellDuration' unitDatum=itemData.data.duration config=@root/config}} {{!-- cooldown duration --}} - {{> temporalUnit titleKey='DS4.SpellCooldownDuration' unitDatum=itemData.data.cooldownDuration - config=../../config}} +
{{lookup @root/config.i18n.cooldownDurations + itemData.data.cooldownDuration}}
+ {{/systems/ds4/templates/sheets/actor/components/item-list-entry.hbs}} {{/each}} diff --git a/templates/sheets/item/components/properties/spell.hbs b/templates/sheets/item/components/properties/spell.hbs index ea788cd9..eb48d9f2 100644 --- a/templates/sheets/item/components/properties/spell.hbs +++ b/templates/sheets/item/components/properties/spell.hbs @@ -7,12 +7,16 @@ SPDX-License-Identifier: MIT

{{localize 'DS4.ItemPropertiesSpell'}}

- - + +
+ +
- +
{{#select data.data.spellCategory}} @@ -36,7 +41,7 @@ SPDX-License-Identifier: MIT
- +
@@ -50,7 +55,7 @@ SPDX-License-Identifier: MIT
- +
@@ -64,25 +69,11 @@ SPDX-License-Identifier: MIT
- +
-
-
-
- -
- -
+
+ +
+ +
+
- +
- - {{data.data.price}} + +
+ {{data.data.price}} +