diff --git a/frosthaven_assistant/assets/data/editions/Forgotten Circles.json b/frosthaven_assistant/assets/data/editions/Forgotten Circles.json index 7ebc585f..6866bb62 100644 --- a/frosthaven_assistant/assets/data/editions/Forgotten Circles.json +++ b/frosthaven_assistant/assets/data/editions/Forgotten Circles.json @@ -1662,6 +1662,12 @@ }, "scenarios": { + "#Random Dungeon": { + "special": [ + { + "type": "RandomSections" + }] + }, "#96 Unexpected Visitors": { "monsters": [ "Earth Demon", "Flame Demon", "Frost Demon", "Wind Demon" ], "special": [ @@ -1959,6 +1965,9 @@ "#103 Where It Is Needed": { "monsters": [], "special": [ + { + "type": "RandomSections" + }, { "type": "Escort", "name": "Caravan", diff --git a/frosthaven_assistant/assets/data/editions/Frosthaven.json b/frosthaven_assistant/assets/data/editions/Frosthaven.json index f9aa72e9..b8a37c83 100644 --- a/frosthaven_assistant/assets/data/editions/Frosthaven.json +++ b/frosthaven_assistant/assets/data/editions/Frosthaven.json @@ -6240,6 +6240,12 @@ }, "scenarios": { + "#Random Dungeon": { + "special": [ + { + "type": "RandomSections" + }] + }, "#0 Howling in the Snow": { "monsters": [ "Hound Scenario 0" ], "lootDeck": {"coin":8,"lumber": 2,"metal":2,"hide": 2} diff --git a/frosthaven_assistant/assets/data/editions/Gloomhaven.json b/frosthaven_assistant/assets/data/editions/Gloomhaven.json index dd3ba158..0d55f70f 100644 --- a/frosthaven_assistant/assets/data/editions/Gloomhaven.json +++ b/frosthaven_assistant/assets/data/editions/Gloomhaven.json @@ -4197,6 +4197,12 @@ }, "scenarios": { + "#Random Dungeon": { + "special": [ + { + "type": "RandomSections" + }] + }, "#1 Black Barrow": { "monsters": [ "Bandit Guard", "Bandit Archer", "Living Bones" ] }, @@ -4732,7 +4738,11 @@ "monsters": [ "Cave Bear (54)", "Living Spirit", "Frost Demon", "Harrower Infester" ] }, "#55 Foggy Thicket": { - "monsters": [] + "monsters": [], + "special": [ + { + "type": "RandomSections" + }] }, "#56 Bandit's Wood": { "monsters": [ "Hound", "Bandit Archer", "Rending Drake", "Bandit Guard" ], diff --git a/frosthaven_assistant/assets/data/rooms/Forgotten Circles.json b/frosthaven_assistant/assets/data/rooms/Forgotten Circles.json index 3194a4be..0da5aeac 100644 --- a/frosthaven_assistant/assets/data/rooms/Forgotten Circles.json +++ b/frosthaven_assistant/assets/data/rooms/Forgotten Circles.json @@ -1,12 +1,15 @@ { - "96": [ + "Random": [ { - "I2b": { - "Earth Demon": { + "start": {} + }, + { + "554 Mangy": { + "Cave Bear": { "normal": [ 1, - 2, - 1 + 1, + 0 ], "elite": [ 0, @@ -14,36 +17,52 @@ 1 ] }, - "Flame Demon": { + "Vermling Scout": { "normal": [ - 1, - 0, - 1 + 3, + 6, + 4 ], "elite": [ 0, 1, - 1 + 3 ] }, - "Frost Demon": { + "Vermling Shaman": { "normal": [ 0, 0, - 1 + 0 ], "elite": [ 1, 1, 1 ] - }, - "Wind Demon": { + } + } + }, + { + "555 Drowned": { + "Living Spirit": { "normal": [ - 0, 1, + 2, 1 ], + "elite": [ + 0, + 0, + 2 + ] + }, + "Lurker": { + "normal": [ + 1, + 2, + 2 + ], "elite": [ 1, 1, @@ -53,124 +72,146 @@ } }, { - "1": { - "Flame Demon": { + "556 Hopeless": { + "Black Imp": { "normal": [ - 0, + 4, 3, - 2 + 3 ], "elite": [ - 1, 0, - 1 + 2, + 3 + ] + }, + "Night Demon": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 ] } } }, { - "24": { - "Earth Demon": { + "557 Defiled": { + "Forest Imp": { "normal": [ - 0, 1, - 2 + 4, + 1 ], "elite": [ 1, 1, + 4 + ] + }, + "Sun Demon": { + "normal": [ + 1, + 0, 1 + ], + "elite": [ + 1, + 2, + 2 ] } } }, { - "34": { - "Frost Demon": { + "558 Wild": { + "Cave Bear": { + "normal": [ + 1, + 0, + 1 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Forest Imp": { "normal": [ 2, 3, 2 ], + "elite": [ + 1, + 1, + 2 + ] + }, + "Hound": { + "normal": [ + 1, + 1, + 1 + ], "elite": [ 0, 0, - 1 + 0 ] } } }, { - "spawn 1": { - "Frost Demon": { - "normal": [1, 1, 0], - "elite": [0, 0, 1] - } - } - }, - { - "spawn 2": { - "Flame Demon": { - "normal": [1, 1, 0], - "elite": [0, 0, 1] - } - } - }, - { - "spawn 3": { - "Earth Demon": { - "normal": [1, 0, 0], - "elite": [0, 1, 1] - } - } - } - ], - "97": [ - { - "N1b": { - "Black Imp": { + "559 Fortified": { + "Ancient Artillery": { "normal": [ - 2, 1, - 2 + 2, + 1 ], "elite": [ 0, - 2, + 0, 1 ] }, - "Living Bones": { + "City Archer": { "normal": [ 2, - 1, + 2, 2 ], "elite": [ 0, - 1, + 0, 1 ] }, - "Living Corpse": { + "City Guard": { "normal": [ 0, - 2, - 0 + 1, + 1 ], "elite": [ 1, - 0, - 2 + 1, + 1 ] } } }, { - "23": { - "Living Bones": { + "560 Cutthroat": { + "Bandit Archer": { "normal": [ - 1, + 2, 1, 2 ], @@ -180,51 +221,59 @@ 1 ] }, - "Living Corpse": { + "Bandit Guard": { "normal": [ 0, 1, - 0 + 1 ], "elite": [ 1, - 0, + 1, 1 ] + }, + "Hound": { + "normal": [ + 1, + 2, + 0 + ], + "elite": [ + 0, + 0, + 2 + ] } } }, { - "40": { + "561 Rotting": { "Living Bones": { "normal": [ - 0, 2, - 1 + 1, + 0 ], "elite": [ - 1, 0, - 1 + 1, + 2 ] }, "Living Corpse": { "normal": [ + 0, 1, - 1, - 1 + 0 ], "elite": [ - 0, 1, - 1 + 1, + 2 ] - } - } - }, - { - "112": { - "Aesther Scout": { + }, + "Living Spirit": { "normal": [ 0, 1, @@ -239,114 +288,128 @@ } }, { - "119": { - "Black Imp": { + "562 Foggy": { + "Flame Demon": { "normal": [ 0, - 3, - 4 + 1, + 2 ], "elite": [ - 2, - 0, - 0 + 1, + 1, + 1 ] }, - "Deep Terror": { + "Frost Demon": { "normal": [ - 1, + 0, 1, 2 ], "elite": [ - 0, + 1, 1, 1 ] } } - } - ], - "98": [ + }, { - "H3b": { - "Ancient Artillery": { + "563 Crushing": { + "Earth Demon": { "normal": [ - 1, 0, + 1, 0 ], "elite": [ - 0, 1, - 1 + 1, + 2 ] }, - "Bandit Archer": { + "Wind Demon": { "normal": [ - 1, - 1, - 0 + 2, + 3, + 4 ], "elite": [ 0, 0, - 2 + 0 ] - }, - "Bandit Guard": { + } + } + }, + { + "564 Tribal": { + "Inox Archer": { "normal": [ - 3, - 3, - 4 + 0, + 0, + 1 ], "elite": [ - 0, + 1, 1, 1 ] }, - "Spitting Drake": { + "Inox Guard": { "normal": [ + 2, 1, + 0 + ], + "elite": [ + 0, 1, 2 + ] + }, + "Inox Shaman": { + "normal": [ + 1, + 2, + 1 ], "elite": [ 0, - 1, - 0 + 0, + 1 ] } } }, { - "4": { - "Bandit Archer": { + "565 Horrific": { + "Black Imp": { "normal": [ - 1, 2, - 1 + 5, + 2 ], "elite": [ 0, 0, - 1 + 3 ] }, - "Bandit Guard": { + "Deep Terror": { "normal": [ + 1, 0, - 0, - 2 + 0 ], "elite": [ 1, - 1, - 0 + 2, + 2 ] }, - "Spitting Drake": { + "Lurker": { "normal": [ 1, 1, @@ -361,134 +424,278 @@ } }, { - "32": { - "Bandit Archer": { + "566 Archaic": { + "Ancient Artillery": { "normal": [ + 2, + 3, + 2 + ], + "elite": [ 0, 0, 1 + ] + }, + "Stone Golem": { + "normal": [ + 0, + 1, + 0 ], "elite": [ 1, 1, + 2 + ] + } + } + }, + { + "567 Scaled": { + "Giant Viper": { + "normal": [ + 2, + 0, 0 + ], + "elite": [ + 0, + 2, + 2 ] }, - "Bandit Guard": { + "Rending Drake": { "normal": [ 1, 2, - 0 + 1 ], "elite": [ 0, 0, - 2 + 1 ] }, "Spitting Drake": { "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "568 Venomous": { + "Black Imp": { + "normal": [ + 2, 1, + 2 + ], + "elite": [ + 0, 1, + 1 + ] + }, + "Giant Viper": { + "normal": [ + 3, + 4, 2 ], "elite": [ 0, 0, + 2 + ] + }, + "Harrower Infester": { + "normal": [ + 0, + 1, 0 + ], + "elite": [ + 1, + 1, + 2 ] } } - } - ], - "99": [ + }, { - "N1b": { - "Black Imp": { + "569 Unstable": { + "Earth Demon": { "normal": [ + 1, 0, - 2, - 0 + 1 ], "elite": [ + 0, + 1, + 1 + ] + }, + "Flame Demon": { + "normal": [ + 1, 2, - 2, - 4 + 1 + ], + "elite": [ + 0, + 0, + 1 ] }, - "Cultist (FC99)": { + "Savvas Lavaflow": { "normal": [ 1, 1, - 3 + 1 ], "elite": [ + 0, + 0, + 0 + ] + } + } + }, + { + "570 Corrupted": { + "Cultist": { + "normal": [ 1, 2, 2 + ], + "elite": [ + 1, + 1, + 1 ] }, - "Deep Terror": { + "Living Bones": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Night Demon": { "normal": [ + 1, 2, - 3, 1 ], "elite": [ 0, 0, - 2 + 1 ] } } }, { - "100": { - "Black Imp": { + "571 Infected": { + "Giant Viper": { "normal": [ 3, - 2, - 3 + 4, + 2 ], "elite": [ - 0, + 1, 2, - 2 + 5 ] }, - "Cultist (FC99)": { + "Ooze": { "normal": [ 1, - 1, - 3 + 2, + 1 ], "elite": [ 1, - 2, + 1, 2 ] + } + } + }, + { + "572 Putrid": { + "Living Corpse": { + "normal": [ + 1, + 2, + 4 + ], + "elite": [ + 1, + 1, + 1 + ] }, - "Deep Terror": { + "Ooze": { "normal": [ 2, - 3, + 2, 1 ], "elite": [ 0, - 0, + 1, 2 ] } } - } - ], - "100": [ + }, { - "F1a": { - "Stone Golem": { + "573 Frigid": { + "Frost Demon": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Savvas Icestorm": { "normal": [ + 0, + 0, + 0 + ], + "elite": [ + 1, 1, + 1 + ] + }, + "Wind Demon": { + "normal": [ + 0, 2, 1 ], @@ -501,43 +708,945 @@ } }, { - "14": { - "Living Spirit": { + "622 Arid": { + "Valrath Savage": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Valrath Tracker": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + }, + { + "623 Ethereal": { + "Aesther Ashblade": { + "normal": [ + 0, + 0, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Aesther Scout": { + "normal": [ + 1, + 2, + 3 + ], + "elite": [ + 0, + 0, + 0 + ] + }, + "Ooze": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + } + ], + "96": [ + { + "I2b": { + "Earth Demon": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Flame Demon": { + "normal": [ + 1, + 0, + 1 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Frost Demon": { + "normal": [ + 0, + 0, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Wind Demon": { + "normal": [ + 0, + 1, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + }, + { + "1": { + "Flame Demon": { + "normal": [ + 0, + 3, + 2 + ], + "elite": [ + 1, + 0, + 1 + ] + } + } + }, + { + "24": { + "Earth Demon": { + "normal": [ + 0, + 1, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + }, + { + "34": { + "Frost Demon": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "spawn 1": { + "Frost Demon": { + "normal": [1, 1, 0], + "elite": [0, 0, 1] + } + } + }, + { + "spawn 2": { + "Flame Demon": { + "normal": [1, 1, 0], + "elite": [0, 0, 1] + } + } + }, + { + "spawn 3": { + "Earth Demon": { + "normal": [1, 0, 0], + "elite": [0, 1, 1] + } + } + } + ], + "97": [ + { + "N1b": { + "Black Imp": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 2, + 1 + ] + }, + "Living Bones": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Living Corpse": { + "normal": [ + 0, + 2, + 0 + ], + "elite": [ + 1, + 0, + 2 + ] + } + } + }, + { + "23": { + "Living Bones": { + "normal": [ + 1, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Living Corpse": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 0, + 1 + ] + } + } + }, + { + "40": { + "Living Bones": { + "normal": [ + 0, + 2, + 1 + ], + "elite": [ + 1, + 0, + 1 + ] + }, + "Living Corpse": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 1, + 1 + ] + } + } + }, + { + "112": { + "Aesther Scout": { + "normal": [ + 0, + 1, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + }, + { + "119": { + "Black Imp": { + "normal": [ + 0, + 3, + 4 + ], + "elite": [ + 2, + 0, + 0 + ] + }, + "Deep Terror": { + "normal": [ + 1, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + } + } + } + ], + "98": [ + { + "H3b": { + "Ancient Artillery": { + "normal": [ + 1, + 0, + 0 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Bandit Archer": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 0, + 2 + ] + }, + "Bandit Guard": { + "normal": [ + 3, + 3, + 4 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Spitting Drake": { + "normal": [ + 1, + 1, + 2 + ], + "elite": [ + 0, + 1, + 0 + ] + } + } + }, + { + "4": { + "Bandit Archer": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Bandit Guard": { + "normal": [ + 0, + 0, + 2 + ], + "elite": [ + 1, + 1, + 0 + ] + }, + "Spitting Drake": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "32": { + "Bandit Archer": { + "normal": [ + 0, + 0, + 1 + ], + "elite": [ + 1, + 1, + 0 + ] + }, + "Bandit Guard": { + "normal": [ + 1, + 2, + 0 + ], + "elite": [ + 0, + 0, + 2 + ] + }, + "Spitting Drake": { + "normal": [ + 1, + 1, + 2 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + } + ], + "99": [ + { + "N1b": { + "Black Imp": { + "normal": [ + 0, + 2, + 0 + ], + "elite": [ + 2, + 2, + 4 + ] + }, + "Cultist (FC99)": { + "normal": [ + 1, + 1, + 3 + ], + "elite": [ + 1, + 2, + 2 + ] + }, + "Deep Terror": { + "normal": [ + 2, + 3, + 1 + ], + "elite": [ + 0, + 0, + 2 + ] + } + } + }, + { + "100": { + "Black Imp": { + "normal": [ + 3, + 2, + 3 + ], + "elite": [ + 0, + 2, + 2 + ] + }, + "Cultist (FC99)": { + "normal": [ + 1, + 1, + 3 + ], + "elite": [ + 1, + 2, + 2 + ] + }, + "Deep Terror": { + "normal": [ + 2, + 3, + 1 + ], + "elite": [ + 0, + 0, + 2 + ] + } + } + } + ], + "100": [ + { + "F1a": { + "Stone Golem": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "14": { + "Living Spirit": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 0, + 0 + ] + }, + "Stone Golem": { + "normal": [ + 1, + 0, + 0 + ], + "elite": [ + 0, + 1, + 1 + ] + } + } + }, + { + "22": { + "Living Spirit": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + } + } + }, + { + "26": { + "Ancient Artillery": { + "normal": [ + 2, + 2, + 4 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + }, + { + "39": { + "Ancient Artillery": { + "normal": [ + 0, + 3, + 2 + ], + "elite": [ + 1, + 0, + 1 + ] + } + } + }, + { + "46": { + "Living Spirit": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + } + } + }, + { + "50": { + "Living Spirit": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + } + } + }, + { + "71": { + "Living Spirit": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 0, + 0 + ] + }, + "Stone Golem": { + "normal": [ + 1, + 0, + 0 + ], + "elite": [ + 0, + 1, + 1 + ] + } + } + } + ], + "101": [ + { + "D1b": { + "Rending Drake": { + "normal": [ + 1, + 2, + 3 + ], + "elite": [ + 0, + 0, + 0 + ] + }, + "Spitting Drake": { + "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 1, + 2 + ] + } + } + }, + { + "41": { + "Living Spirit": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Night Demon": { + "normal": [ + 0, + 0, + 0 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + }, + { + "64": { + "Living Bones": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 0, + 0, + 0 + ] + }, + "Living Corpse": { + "normal": [ + 0, + 1, + 1 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + }, + { + "72": { + "Living Spirit": { + "normal": [ + 2, + 1, + 1 + ], + "elite": [ + 0, + 1, + 0 + ] + }, + "Night Demon": { + "normal": [ + 0, + 0, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "93": { + "Living Spirit": { + "normal": [ + 0, + 2, + 1 + ], + "elite": [ + 0, + 0, + 0 + ] + }, + "Night Demon": { + "normal": [ + 1, + 0, + 1 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + }, + { + "123": { + "Living Spirit": { + "normal": [ + 0, + 2, + 1 + ], + "elite": [ + 0, + 0, + 0 + ] + }, + "Night Demon": { + "normal": [ + 1, + 0, + 1 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + }, + { + "spawn 1": { + "Night Demon": { + "normal": [1, 1, 0], + "elite": [0, 0, 1] + } + } + }, + { + "spawn 2": { + "Night Demon": { + "normal": [1, 0, 0], + "elite": [0, 1, 1] + } + } + }, + { + "spawn 3": { + "Night Demon": { + "normal": [1, 0, 0], + "elite": [0, 1, 1] + } + } + } + ], + "102": [], + "103": [ + { + "start": {} + }, + { + "554 Mangy": { + "Cave Bear": { "normal": [ - 2, 1, - 2 + 1, + 0 ], "elite": [ 0, 0, - 0 + 1 ] }, - "Stone Golem": { + "Vermling Scout": { "normal": [ - 1, - 0, - 0 + 3, + 6, + 4 ], "elite": [ 0, 1, - 1 + 3 ] - } - } - }, - { - "22": { - "Living Spirit": { + }, + "Vermling Shaman": { "normal": [ - 2, - 1, - 2 + 0, + 0, + 0 ], "elite": [ - 0, + 1, 1, 1 ] @@ -545,72 +1654,76 @@ } }, { - "26": { - "Ancient Artillery": { + "555 Drowned": { + "Living Spirit": { "normal": [ + 1, 2, - 2, - 4 + 1 ], "elite": [ 0, 0, - 0 + 2 ] - } - } - }, - { - "39": { - "Ancient Artillery": { + }, + "Lurker": { "normal": [ - 0, - 3, + 1, + 2, 2 ], "elite": [ 1, - 0, + 1, 1 ] } } }, { - "46": { - "Living Spirit": { + "558 Wild": { + "Cave Bear": { "normal": [ - 2, 1, - 2 + 0, + 1 ], "elite": [ 0, 1, 1 ] - } - } - }, - { - "50": { - "Living Spirit": { + }, + "Forest Imp": { "normal": [ 2, - 1, + 3, 2 ], "elite": [ - 0, + 1, + 1, + 2 + ] + }, + "Hound": { + "normal": [ + 1, 1, 1 + ], + "elite": [ + 0, + 0, + 0 ] } } }, { - "71": { - "Living Spirit": { + "560 Cutthroat": { + "Bandit Archer": { "normal": [ 2, 1, @@ -618,41 +1731,39 @@ ], "elite": [ 0, - 0, - 0 + 1, + 1 ] }, - "Stone Golem": { + "Bandit Guard": { "normal": [ - 1, 0, - 0 + 1, + 1 ], "elite": [ - 0, + 1, 1, 1 ] - } - } - } - ], - "101": [ - { - "D1b": { - "Rending Drake": { + }, + "Hound": { "normal": [ 1, 2, - 3 + 0 ], "elite": [ 0, 0, - 0 + 2 ] - }, - "Spitting Drake": { + } + } + }, + { + "561 Rotting": { + "Living Bones": { "normal": [ 2, 1, @@ -663,28 +1774,24 @@ 1, 2 ] - } - } - }, - { - "41": { - "Living Spirit": { + }, + "Living Corpse": { "normal": [ 0, 1, 0 ], "elite": [ - 0, - 0, - 1 + 1, + 1, + 2 ] }, - "Night Demon": { + "Living Spirit": { "normal": [ 0, - 0, - 0 + 1, + 2 ], "elite": [ 1, @@ -695,52 +1802,36 @@ } }, { - "64": { - "Living Bones": { + "564 Tribal": { + "Inox Archer": { "normal": [ - 1, - 2, - 2 - ], - "elite": [ 0, 0, - 0 - ] - }, - "Living Corpse": { - "normal": [ - 0, - 1, 1 ], "elite": [ 1, 1, - 2 + 1 ] - } - } - }, - { - "72": { - "Living Spirit": { + }, + "Inox Guard": { "normal": [ 2, 1, - 1 + 0 ], "elite": [ 0, 1, - 0 + 2 ] }, - "Night Demon": { + "Inox Shaman": { "normal": [ - 0, - 0, - 0 + 1, + 2, + 1 ], "elite": [ 0, @@ -751,88 +1842,86 @@ } }, { - "93": { - "Living Spirit": { + "568 Venomous": { + "Black Imp": { "normal": [ - 0, 2, - 1 + 1, + 2 ], "elite": [ 0, - 0, - 0 + 1, + 1 ] }, - "Night Demon": { + "Giant Viper": { "normal": [ - 1, - 0, - 1 + 3, + 4, + 2 ], "elite": [ 0, 0, + 2 + ] + }, + "Harrower Infester": { + "normal": [ + 0, + 1, 0 + ], + "elite": [ + 1, + 1, + 2 ] } } }, { - "123": { - "Living Spirit": { + "570 Corrupted": { + "Cultist": { "normal": [ - 0, + 1, 2, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Living Bones": { + "normal": [ + 1, + 1, 1 ], "elite": [ 0, 0, - 0 + 1 ] }, "Night Demon": { "normal": [ 1, - 0, + 2, 1 ], "elite": [ 0, 0, - 0 + 1 ] } } - }, - { - "spawn 1": { - "Night Demon": { - "normal": [1, 1, 0], - "elite": [0, 0, 1] - } - } - }, - { - "spawn 2": { - "Night Demon": { - "normal": [1, 0, 0], - "elite": [0, 1, 1] - } - } - }, - { - "spawn 3": { - "Night Demon": { - "normal": [1, 0, 0], - "elite": [0, 1, 1] - } - } } ], - "102": [], - "103": [], "104": [ { "D2b": { diff --git a/frosthaven_assistant/assets/data/rooms/Frosthaven.json b/frosthaven_assistant/assets/data/rooms/Frosthaven.json index a965dff3..7196acea 100644 --- a/frosthaven_assistant/assets/data/rooms/Frosthaven.json +++ b/frosthaven_assistant/assets/data/rooms/Frosthaven.json @@ -1,5 +1,826 @@ { - "0": [ + "Random": [ + { + "start": {} + }, + { + "891 Smashing": { + "Algox Archer": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Algox Icespeaker": { + "normal": [ + 2, + 1, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "893 Territorial": { + "Algox Priest": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Algox Scout": { + "normal": [ + 0, + 1, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + }, + { + "892 Stormy": { + "Algox Guard": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Algox Snowspeaker": { + "normal": [ + 2, + 1, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "894 Feral": { + "Hound": { + "normal": [ + 0, + 1, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Polar Bear": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Snow Imp": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + }, + { + "895 Tamed": { + "Polar Bear": { + "normal": [ + 1, + 0, + 0 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Vermling Priest": { + "normal": [ + 2, + 2, + 0 + ], + "elite": [ + 0, + 0, + 2 + ] + }, + "Vermling Scout": { + "normal": [ + 1, + 3, + 1 + ], + "elite": [ + 1, + 1, + 3 + ] + } + } + }, + { + "896 Swarming": { + "Forest Imp": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 2 + ] + }, + "Harrower Infester": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 0, + 0, + 0 + ] + }, + "Shrike Fiend": { + "normal": [ + 0, + 0, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + }, + { + "897 Traitorous": { + "Chaos Demon": { + "normal": [ + 2, + 2, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "City Guard": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 1, + 2, + 2 + ] + } + } + }, + { + "898 Bleak": { + "Living Bones": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Living Doom": { + "normal": [ + 0, + 1, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Living Spirit": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "899 Sapping": { + "Frost Demon": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Ice Wraith": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Snow Imp": { + "normal": [ + 0, + 1, + 1 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + }, + { + "900 Decayed": { + "Frozen Corpse": { + "normal": [ + 3, + 2, + 2 + ], + "elite": [ + 0, + 1, + 2 + ] + }, + "Living Bones": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + }, + { + "901 Deomesticated": { + "Abael Herder": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 1, + 2 + ] + }, + "Abael Scout": { + "normal": [ + 0, + 0, + 0 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Piranha Pig": { + "normal": [ + 2, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "903 Daunting": { + "Lurker Clawcrusher": { + "normal": [ + 2, + 1, + 1 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Lurker Mindsnipper": { + "normal": [ + 1, + 1, + 2 + ], + "elite": [ + 0, + 0, + 0 + ] + }, + "Lurker Wavethrower": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "902 Trashing": { + "Lurker Soldier": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 0, + 0, + 0 + ] + }, + "Lurker Wavethrower": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + }, + "Piranha Pig": { + "normal": [ + 2, + 2, + 0 + ], + "elite": [ + 0, + 0, + 2 + ] + } + } + }, + { + "904 Abandoned": { + "Ancient Artillery": { + "normal": [ + 3, + 2, + 0 + ], + "elite": [ + 0, + 1, + 3 + ] + }, + "Ruined Machine": { + "normal": [ + 3, + 4, + 2 + ], + "elite": [ + 1, + 2, + 4 + ] + } + } + }, + { + "905 Reinforced": { + "Robotic Boltshooter": { + "normal": [ + 3, + 3, + 2 + ], + "elite": [ + 0, + 0, + 2 + ] + }, + "Steel Automaton": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + }, + { + "906 Rusted": { + "Flaming Bladespinner": { + "normal": [ + 1, + 1, + 2 + ], + "elite": [ + 0, + 0, + 0 + ] + }, + "Ruined Machine": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Steel Automaton": { + "normal": [ + 1, + 0, + 0 + ], + "elite": [ + 0, + 1, + 1 + ] + } + } + }, + { + "907 Unsettling": { + "Black Imp": { + "normal": [ + 1, + 2, + 0 + ], + "elite": [ + 0, + 0, + 2 + ] + }, + "Chaos Demon": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Ooze": { + "normal": [ + 0, + 1, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + }, + { + "908 Taloned": { + "Rending Drake": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Shrike Fiend": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "909 Segmented": { + "Burrowing Blade": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Spitting Drake": { + "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 1, + 2 + ] + } + } + }, + { + "910 Dirty": { + "Earth Demon": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Forest Imp": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 0, + 0, + 0 + ] + }, + "Ooze": { + "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 1, + 2 + ] + } + } + }, + { + "911 Grave": { + "Deep Terror": { + "normal": [ + 1, + 1, + 2 + ], + "elite": [ + 0, + 0, + 0 + ] + }, + "Ice Wraith": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Night Demon": { + "normal": [ + 2, + 2, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + } + } + }, + { + "912 Luminous": { + "Lurker Wavethrower": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 1, + 1, + 3 + ] + }, + "Sun Demon": { + "normal": [ + 2, + 2, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + } + } + }, + { + "913 Scorching": { + "Flame Demon": { + "normal": [ + 1, + 1, + 2 + ], + "elite": [ + 0, + 1, + 0 + ] + }, + "Flaming Bladespinner": { + "normal": [ + 2, + 2, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "914 Swift": { + "Algox Scout": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + }, + "Wind Demon": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + } + ], + "0": [ { "13 A": { "Hound Scenario 0": { diff --git a/frosthaven_assistant/assets/data/rooms/Gloomhaven.json b/frosthaven_assistant/assets/data/rooms/Gloomhaven.json index b9bda87f..03991ca6 100644 --- a/frosthaven_assistant/assets/data/rooms/Gloomhaven.json +++ b/frosthaven_assistant/assets/data/rooms/Gloomhaven.json @@ -1,4 +1,713 @@ { + "Random": [ + { + "start": {} + }, + { + "554 Mangy": { + "Cave Bear": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Vermling Scout": { + "normal": [ + 3, + 6, + 4 + ], + "elite": [ + 0, + 1, + 3 + ] + }, + "Vermling Shaman": { + "normal": [ + 0, + 0, + 0 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + }, + { + "555 Drowned": { + "Living Spirit": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 2 + ] + }, + "Lurker": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + }, + { + "556 Hopeless": { + "Black Imp": { + "normal": [ + 4, + 3, + 3 + ], + "elite": [ + 0, + 2, + 3 + ] + }, + "Night Demon": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + }, + { + "557 Defiled": { + "Forest Imp": { + "normal": [ + 1, + 4, + 1 + ], + "elite": [ + 1, + 1, + 4 + ] + }, + "Sun Demon": { + "normal": [ + 1, + 0, + 1 + ], + "elite": [ + 1, + 2, + 2 + ] + } + } + }, + { + "558 Wild": { + "Cave Bear": { + "normal": [ + 1, + 0, + 1 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Forest Imp": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 1, + 1, + 2 + ] + }, + "Hound": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + }, + { + "559 Fortified": { + "Ancient Artillery": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "City Archer": { + "normal": [ + 2, + 2, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "City Guard": { + "normal": [ + 0, + 1, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + }, + { + "560 Cutthroat": { + "Bandit Archer": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Bandit Guard": { + "normal": [ + 0, + 1, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Hound": { + "normal": [ + 1, + 2, + 0 + ], + "elite": [ + 0, + 0, + 2 + ] + } + } + }, + { + "561 Rotting": { + "Living Bones": { + "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 1, + 2 + ] + }, + "Living Corpse": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + }, + "Living Spirit": { + "normal": [ + 0, + 1, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + }, + { + "562 Foggy": { + "Flame Demon": { + "normal": [ + 0, + 1, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Frost Demon": { + "normal": [ + 0, + 1, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + }, + { + "563 Crushing": { + "Earth Demon": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + }, + "Wind Demon": { + "normal": [ + 2, + 3, + 4 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + }, + { + "564 Tribal": { + "Inox Archer": { + "normal": [ + 0, + 0, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Inox Guard": { + "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 1, + 2 + ] + }, + "Inox Shaman": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "565 Horrific": { + "Black Imp": { + "normal": [ + 2, + 5, + 2 + ], + "elite": [ + 0, + 0, + 3 + ] + }, + "Deep Terror": { + "normal": [ + 1, + 0, + 0 + ], + "elite": [ + 1, + 2, + 2 + ] + }, + "Lurker": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "566 Archaic": { + "Ancient Artillery": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Stone Golem": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + }, + { + "567 Scaled": { + "Giant Viper": { + "normal": [ + 2, + 0, + 0 + ], + "elite": [ + 0, + 2, + 2 + ] + }, + "Rending Drake": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Spitting Drake": { + "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "568 Venomous": { + "Black Imp": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Giant Viper": { + "normal": [ + 3, + 4, + 2 + ], + "elite": [ + 0, + 0, + 2 + ] + }, + "Harrower Infester": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + }, + { + "569 Unstable": { + "Earth Demon": { + "normal": [ + 1, + 0, + 1 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Flame Demon": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Savvas Lavaflow": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + }, + { + "570 Corrupted": { + "Cultist": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Living Bones": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Night Demon": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "571 Infected": { + "Giant Viper": { + "normal": [ + 3, + 4, + 2 + ], + "elite": [ + 1, + 2, + 5 + ] + }, + "Ooze": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + }, + { + "572 Putrid": { + "Living Corpse": { + "normal": [ + 1, + 2, + 4 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Ooze": { + "normal": [ + 2, + 2, + 1 + ], + "elite": [ + 0, + 1, + 2 + ] + } + } + }, + { + "573 Frigid": { + "Frost Demon": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Savvas Icestorm": { + "normal": [ + 0, + 0, + 0 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Wind Demon": { + "normal": [ + 0, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + } + ], "1": [ { "L1a": { @@ -5971,7 +6680,239 @@ } } ], - "55": [], + "55": [ + { + "start": {} + }, + { + "554 Mangy": { + "Cave Bear": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Vermling Scout": { + "normal": [ + 3, + 6, + 4 + ], + "elite": [ + 0, + 1, + 3 + ] + }, + "Vermling Shaman": { + "normal": [ + 0, + 0, + 0 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + }, + { + "558 Wild": { + "Cave Bear": { + "normal": [ + 1, + 0, + 1 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Forest Imp": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 1, + 1, + 2 + ] + }, + "Hound": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + }, + { + "560 Cutthroat": { + "Bandit Archer": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Bandit Guard": { + "normal": [ + 0, + 1, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Hound": { + "normal": [ + 1, + 2, + 0 + ], + "elite": [ + 0, + 0, + 2 + ] + } + } + }, + { + "564 Tribal": { + "Inox Archer": { + "normal": [ + 0, + 0, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Inox Guard": { + "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 1, + 2 + ] + }, + "Inox Shaman": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "567 Scaled": { + "Giant Viper": { + "normal": [ + 2, + 0, + 0 + ], + "elite": [ + 0, + 2, + 2 + ] + }, + "Rending Drake": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Spitting Drake": { + "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "571 Infected": { + "Giant Viper": { + "normal": [ + 3, + 4, + 2 + ], + "elite": [ + 1, + 2, + 5 + ] + }, + "Ooze": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + } + ], "57": [ { "C1a(1)": { diff --git a/frosthaven_assistant/lib/Layout/menus/add_section_menu.dart b/frosthaven_assistant/lib/Layout/menus/add_section_menu.dart index 835bf927..a4d19042 100644 --- a/frosthaven_assistant/lib/Layout/menus/add_section_menu.dart +++ b/frosthaven_assistant/lib/Layout/menus/add_section_menu.dart @@ -27,11 +27,11 @@ class AddSectionMenuState extends State { @override initState() { // at the beginning, all items are shown - var scenarios = _gameData.modelData.value[_gameState.currentCampaign.value] + var scenarios = _gameData.modelData.value[_gameState.currentCampaign.value] ?.scenarios[_gameState.scenario.value]?.sections .map((e) => e.name) .toList(); - if(scenarios != null) { + if (scenarios != null) { _foundScenarios = scenarios; } _foundScenarios = _foundScenarios.where((element) => !element.contains("spawn")).toList(); @@ -87,8 +87,6 @@ class AddSectionMenuState extends State { return Container( constraints: const BoxConstraints(maxWidth: 400), child: Card( - //color: Colors.transparent, - // shadowColor: Colors.transparent, margin: const EdgeInsets.all(2), child: Stack(children: [ Column( @@ -117,8 +115,11 @@ class AddSectionMenuState extends State { })); } }, - decoration: const InputDecoration( - labelText: 'Add Section', suffixIcon: Icon(Icons.search)), + decoration: InputDecoration( + labelText: _gameState.scenario.value == "#Random Dungeon" + ? 'Add Random Dungeon Card' + : 'Add Section', + suffixIcon: const Icon(Icons.search)), ), ), const SizedBox( @@ -134,13 +135,17 @@ class AddSectionMenuState extends State { itemBuilder: (context, index) => ListTile( title: Text(_foundScenarios[index], style: TextStyle( - color: _gameState.scenarioSectionsAdded.contains(_foundScenarios[index]) ? Colors.blueGrey : Colors.black, - fontSize: 18 - )), + color: _gameState.scenarioSectionsAdded + .contains(_foundScenarios[index]) + ? Colors.blueGrey + : Colors.black, + fontSize: 18)), onTap: () { - if(!_gameState.scenarioSectionsAdded.contains(_foundScenarios[index])) { + if (!_gameState.scenarioSectionsAdded + .contains(_foundScenarios[index])) { Navigator.pop(context); - _gameState.action(SetScenarioCommand(_foundScenarios[index], true)); + _gameState + .action(SetScenarioCommand(_foundScenarios[index], true)); } }, ), diff --git a/frosthaven_assistant/lib/Layout/menus/main_menu.dart b/frosthaven_assistant/lib/Layout/menus/main_menu.dart index e42a54e0..96c25388 100644 --- a/frosthaven_assistant/lib/Layout/menus/main_menu.dart +++ b/frosthaven_assistant/lib/Layout/menus/main_menu.dart @@ -121,7 +121,10 @@ Drawer createMainMenu(BuildContext context) { }, ), ListTile( - title: const Text('Add Section'), + title: Text( + getIt().scenario.value == "#Random Dungeon" + ? 'Add Random Dungeon Card' + : 'Add Section'), enabled: true, onTap: () { Navigator.pop(context); diff --git a/frosthaven_assistant/lib/Layout/menus/select_scenario_menu.dart b/frosthaven_assistant/lib/Layout/menus/select_scenario_menu.dart index 4d3791d4..af81d223 100644 --- a/frosthaven_assistant/lib/Layout/menus/select_scenario_menu.dart +++ b/frosthaven_assistant/lib/Layout/menus/select_scenario_menu.dart @@ -48,7 +48,7 @@ class SelectScenarioMenuState extends State { } void setCampaign(String campaign) { - //TODO:clear search + //TODO: clear search //check value ok if (_gameData.modelData.value[campaign] == null) { @@ -105,6 +105,12 @@ class SelectScenarioMenuState extends State { return a.compareTo(b); }); + //sort random dungeon first for visibility of special feature + if(_foundScenarios.last == "#Random Dungeon") { + _foundScenarios.insert(0, _foundScenarios.last); + _foundScenarios.removeAt(_foundScenarios.length-1); + } + if (campaign != "Solo") { _foundScenarios.insert(0, "custom"); } diff --git a/frosthaven_assistant/lib/Layout/monster_box.dart b/frosthaven_assistant/lib/Layout/monster_box.dart index 70ca9605..0c237978 100644 --- a/frosthaven_assistant/lib/Layout/monster_box.dart +++ b/frosthaven_assistant/lib/Layout/monster_box.dart @@ -266,10 +266,10 @@ class MonsterBox extends StatelessWidget { } return Material( - color: Colors.amberAccent, + color: Colors.transparent, child:InkWell( - splashColor: Colors.brown, - focusColor: Colors.amber, + //splashColor: Colors.brown, + //focusColor: Colors.amber, onTap: () { //open stats menu if (!blockInput) { diff --git a/frosthaven_assistant/lib/Layout/section_list.dart b/frosthaven_assistant/lib/Layout/section_list.dart index f385eb5f..c994d6e3 100644 --- a/frosthaven_assistant/lib/Layout/section_list.dart +++ b/frosthaven_assistant/lib/Layout/section_list.dart @@ -1,3 +1,4 @@ +import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:frosthaven_assistant/Layout/section_button.dart'; import 'package:frosthaven_assistant/Resource/state/game_state.dart'; @@ -12,14 +13,16 @@ class SectionList extends StatelessWidget { List generateList(List inputList) { List list = []; - for (int index = 0; index < inputList.length; index++) { - var item = inputList[index]; - if (!item.name.contains("spawn")) { - SectionButton value = - SectionButton(key: Key(item.name), data: item.name); - list.add(value); + // if(inputList.length <=20) { //arbitrary limit, so view is not filled up with extra buttons + for (int index = 0; index < inputList.length; index++) { + var item = inputList[index]; + if (!item.name.contains("spawn")) { + SectionButton value = + SectionButton(key: Key(item.name), data: item.name); + list.add(value); + } } - } + //} return list; } @@ -41,6 +44,19 @@ class SectionList extends StatelessWidget { ?.sections .toList(); + //handle random list + var randomSections = gameState.scenarioSpecialRules.firstWhereOrNull((element) => element.type == "RandomSections"); + if(randomSections != null && list != null) { + List newList = []; + for(var item in randomSections.list) { + var section = list.firstWhereOrNull((element) => element.name == item); + if(section != null) { + newList.add(section); + } + } + list = newList; + } + if (getIt().autoAddStandees.value == false) { //filter out all sections with only room data list = list?.where((element) { @@ -62,6 +78,7 @@ class SectionList extends StatelessWidget { list = []; } list ??= []; + return Wrap( alignment: WrapAlignment.center, spacing: 4 * scale, diff --git a/frosthaven_assistant/lib/Resource/game_methods.dart b/frosthaven_assistant/lib/Resource/game_methods.dart index 8cf4128a..5e343e66 100644 --- a/frosthaven_assistant/lib/Resource/game_methods.dart +++ b/frosthaven_assistant/lib/Resource/game_methods.dart @@ -85,7 +85,8 @@ class GameMethods { if (item is Monster) { if (item.type.deck == deck.name) { if (item.monsterInstances.isNotEmpty || item.isActive) { - if (deck.lastRoundDrawn != _gameState.totalRounds.value) { //do not draw new card in case drawn already this round + if (deck.lastRoundDrawn != _gameState.totalRounds.value) { + //do not draw new card in case drawn already this round deck.draw(stateModifier); break; } @@ -233,7 +234,7 @@ class GameMethods { //in case initiative is earlier than current turn, ignore anything current turn, and earlier and place later int insertIndex = currentTurnItemIndex + 1; for (int j = currentTurnItemIndex + 1; j < newList.length; j++) { - if( getInitiative(newList[j]) >= initiative) { + if (getInitiative(newList[j]) >= initiative) { insertIndex = j; break; } @@ -341,8 +342,7 @@ class GameMethods { int res = 0; for (ListItemData data in _gameState.currentList) { if (data is Character) { - if (data.characterClass.name != "Escort" && - data.characterClass.name != "Objective") { + if (data.characterClass.name != "Escort" && data.characterClass.name != "Objective") { res++; } } @@ -378,13 +378,11 @@ class GameMethods { List newList = []; for (var item in _gameState.currentList) { if (item is Character) { - if (item.characterClass.name != "Objective" && - item.characterClass.name != "Escort") { + if (item.characterClass.name != "Objective" && item.characterClass.name != "Escort") { item.characterState._initiative.value = 0; - item.characterState._health.value = item.characterClass - .healthByLevel[item.characterState.level.value - 1]; - item.characterState._maxHealth.value = - item.characterState.health.value; + item.characterState._health.value = + item.characterClass.healthByLevel[item.characterState.level.value - 1]; + item.characterState._maxHealth.value = item.characterState.health.value; item.characterState._xp.value = 0; item.characterState.conditions.value.clear(); item.characterState._chill.value = 0; @@ -410,16 +408,14 @@ class GameMethods { //loot deck init if (scenario != "custom") { LootDeckModel? lootDeckModel = _gameData - .modelData - .value[_gameState.currentCampaign.value]! - .scenarios[scenario]! - .lootDeck; + .modelData.value[_gameState.currentCampaign.value]!.scenarios[scenario]!.lootDeck; if (lootDeckModel != null) { _gameState._lootDeck = LootDeck(lootDeckModel, _gameState.lootDeck); } else { _gameState._lootDeck = LootDeck.from(_gameState.lootDeck); } } else { + //todo: remove. no need for custom loot deck if (_gameState.currentCampaign.value == "Frosthaven") { //add loot deck for random scenarios LootDeckModel? lootDeckModel = const LootDeckModel(2, 2, 2, 12, 1, 1, 1, 1, 1, 1, 0); @@ -436,34 +432,34 @@ class GameMethods { List monsters = []; List specialRules = []; List roomMonsterData = []; + List subSections = []; String initMessage = ""; if (section) { - var sectionData = _gameData - .modelData - .value[_gameState.currentCampaign.value] - ?.scenarios[_gameState.scenario.value] - ?.sections + var sectionData = _gameData.modelData.value[_gameState.currentCampaign.value] + ?.scenarios[_gameState.scenario.value]?.sections .firstWhere((element) => element.name == scenario); if (sectionData != null) { monsters = sectionData.monsters; specialRules = sectionData.specialRules.toList(); initMessage = sectionData.initMessage; - roomMonsterData = sectionData.monsterStandees != null - ? sectionData.monsterStandees!.toList() - : []; + roomMonsterData = + sectionData.monsterStandees != null ? sectionData.monsterStandees!.toList() : []; } - } else { + } + else { if (scenario != "custom") { - var scenarioData = _gameData.modelData - .value[_gameState.currentCampaign.value]?.scenarios[scenario]; + var scenarioData = + _gameData.modelData.value[_gameState.currentCampaign.value]?.scenarios[scenario]; if (scenarioData != null) { monsters = scenarioData.monsters; specialRules = scenarioData.specialRules.toList(); initMessage = scenarioData.initMessage; - roomMonsterData = scenarioData.monsterStandees != null - ? scenarioData.monsterStandees!.toList() - : []; + roomMonsterData = + scenarioData.monsterStandees != null ? scenarioData.monsterStandees!.toList() : []; + for(var item in scenarioData.sections) { + subSections.add(item.name); + } } } } @@ -479,8 +475,8 @@ class GameMethods { //hack for banner spear solo special rule if (scenario.contains("Banner Spear: Scouting Ambush")) { - MonsterAbilityState deck = _gameState.currentAbilityDecks - .firstWhere((element) => element.name.contains("Scout")); + MonsterAbilityState deck = + _gameState.currentAbilityDecks.firstWhere((element) => element.name.contains("Scout")); for (int i = 0; i < deck.drawPile.getList().length; i++) { if (deck.drawPile.getList()[i].title == "Rancid Arrow") { deck.drawPile.add(deck.drawPile.removeAt(i)); @@ -492,20 +488,17 @@ class GameMethods { //add objectives and escorts for (var item in specialRules) { if (item.type == "Objective") { - if (item.condition == "" || - StatCalculator.evaluateCondition(item.condition)) { - Character objective = GameMethods.createCharacter(_, - "Objective", item.name, _gameState.level.value + 1)!; + if (item.condition == "" || StatCalculator.evaluateCondition(item.condition)) { + Character objective = + GameMethods.createCharacter(_, "Objective", item.name, _gameState.level.value + 1)!; objective.characterState._maxHealth.value = StatCalculator.calculateFormula(item.health.toString())!; - objective.characterState._health.value = - objective.characterState.maxHealth.value; + objective.characterState._health.value = objective.characterState.maxHealth.value; objective.characterState._initiative.value = item.init; bool add = true; for (var item2 in _gameState.currentList) { //don't add duplicates - if (item2 is Character && - (item2).characterState.display.value == item.name) { + if (item2 is Character && (item2).characterState.display.value == item.name) { add = false; break; } @@ -516,20 +509,17 @@ class GameMethods { } } if (item.type == "Escort") { - if (item.condition == "" || - StatCalculator.evaluateCondition(item.condition)) { - Character objective = GameMethods.createCharacter(_, - "Escort", item.name, _gameState.level.value + 1)!; + if (item.condition == "" || StatCalculator.evaluateCondition(item.condition)) { + Character objective = + GameMethods.createCharacter(_, "Escort", item.name, _gameState.level.value + 1)!; objective.characterState._maxHealth.value = StatCalculator.calculateFormula(item.health.toString())!; - objective.characterState._health.value = - objective.characterState.maxHealth.value; + objective.characterState._health.value = objective.characterState.maxHealth.value; objective.characterState._initiative.value = item.init; bool add = true; for (var item2 in _gameState.currentList) { //don't add duplicates - if (item2 is Character && - (item2).characterState.display.value == item.name) { + if (item2 is Character && (item2).characterState.display.value == item.name) { add = false; break; } @@ -571,18 +561,14 @@ class GameMethods { if (rule.name.isNotEmpty) { //get room data and deal with spawns ScenarioModel? scenarioModel = _gameData - .modelData - .value[_gameState.currentCampaign.value] - ?.scenarios[scenario]; + .modelData.value[_gameState.currentCampaign.value]?.scenarios[scenario]; if (scenarioModel != null) { ScenarioModel? spawnSection = scenarioModel.sections - .firstWhereOrNull( - (element) => element.name.substring(1) == rule.name); - if (spawnSection != null && - spawnSection.monsterStandees != null) { + .firstWhereOrNull((element) => element.name.substring(1) == rule.name); + if (spawnSection != null && spawnSection.monsterStandees != null) { for (var spawnItem in spawnSection.monsterStandees!) { - var item = roomMonsterData.firstWhereOrNull( - (element) => element.name == spawnItem.name); + var item = roomMonsterData + .firstWhereOrNull((element) => element.name == spawnItem.name); if (item != null) { //merge List normal = [ @@ -595,8 +581,7 @@ class GameMethods { item.elite[1] + spawnItem.elite[1], item.elite[2] + spawnItem.elite[2] ]; - RoomMonsterData mergedItem = - RoomMonsterData(item.name, normal, elite); + RoomMonsterData mergedItem = RoomMonsterData(item.name, normal, elite); for (int i = 0; i < roomMonsterData.length; i++) { if (roomMonsterData[i].name == item.name) { roomMonsterData[i] = mergedItem; @@ -630,9 +615,7 @@ class GameMethods { _gameState._scenarioSectionsAdded = []; } else { //remove earlier times if has "ResetRound" - if (specialRules - .firstWhereOrNull((element) => element.type == "ResetRound") != - null) { + if (specialRules.firstWhereOrNull((element) => element.type == "ResetRound") != null) { _gameState._scenarioSpecialRules.removeWhere((oldItem) { if (oldItem.type == "Timer") { return true; @@ -645,8 +628,7 @@ class GameMethods { for (var item in specialRules) { if (item.type == "Timer") { _gameState._scenarioSpecialRules.removeWhere((oldItem) { - if (oldItem.type == "Timer" && - item.startOfRound == oldItem.startOfRound) { + if (oldItem.type == "Timer" && item.startOfRound == oldItem.startOfRound) { if (item.list.contains(-1) || oldItem.list.contains(-1)) { return true; } @@ -661,6 +643,16 @@ class GameMethods { _gameState._scenarioSectionsAdded.add(scenario); } + //handle random sections + var rule = specialRules.firstWhereOrNull((element) => element.type == "RandomSections"); + if(rule != null) { + subSections.shuffle(); + //add the random selected to rule.list + SpecialRule newRule = SpecialRule("RandomSections", "", 0, 0, 0, "", subSections.sublist(0,3), false, ""); + specialRules.remove(rule); + specialRules.add(newRule); + } + _gameState.updateList.value++; if (!section) { @@ -668,11 +660,11 @@ class GameMethods { } //show init message if exists: - if (initMessage.isNotEmpty && - getIt().showReminders.value == true) { + if (initMessage.isNotEmpty && getIt().showReminders.value == true) { _gameState._toastMessage.value += initMessage; - } else { - if(getIt.isRegistered()) { + } + else { + if (getIt.isRegistered()) { ScaffoldMessenger.of(getIt()).hideCurrentSnackBar(); } } @@ -680,11 +672,11 @@ class GameMethods { static void returnLootCard(bool top) { var card = _gameState._lootDeck._discardPile.pop(); - card.owner = ""; - if(top) { - _gameState._lootDeck._drawPile.push(card); - } else { - _gameState._lootDeck._drawPile.insert(0, card); + card.owner = ""; + if (top) { + _gameState._lootDeck._drawPile.push(card); + } else { + _gameState._lootDeck._drawPile.insert(0, card); } } @@ -694,8 +686,7 @@ class GameMethods { if (item is Character) { bool remove = false; for (var name in characters) { - if (item.characterState.display.value == - name.characterState.display.value) { + if (item.characterState.display.value == name.characterState.display.value) { remove = true; break; } @@ -758,8 +749,7 @@ class GameMethods { } static void reorderMainList(_StateModifier _, int newIndex, int oldIndex) { - _gameState._currentList - .insert(newIndex, _gameState._currentList.removeAt(oldIndex)); + _gameState._currentList.insert(newIndex, _gameState._currentList.removeAt(oldIndex)); } static void addToMainList(_StateModifier _, int? index, ListItemData item) { @@ -854,16 +844,8 @@ class GameMethods { } instance = MonsterInstance(nr, type, addAsSummon, monster!); } else { - instance = MonsterInstance.summon( - summon.standeeNr, - type, - summon.name, - summon.health, - summon.move, - summon.attack, - summon.range, - summon.gfx, - getIt().round.value); + instance = MonsterInstance.summon(summon.standeeNr, type, summon.name, summon.health, + summon.move, summon.attack, summon.range, summon.gfx, getIt().round.value); } List? monsterList; @@ -915,19 +897,15 @@ class GameMethods { GameMethods.sortCharactersFirst(_); } else if (getIt().roundState.value == RoundState.playTurns) { GameMethods.drawAbilityCardFromInactiveDeck(_); - GameMethods.sortItemToPlace(_, - monster.id, - GameMethods.getInitiative( - monster)); //need to only sort this one item to place + GameMethods.sortItemToPlace(_, monster.id, + GameMethods.getInitiative(monster)); //need to only sort this one item to place } } } - static void addStandee( - int? nr, Monster data, MonsterType type, bool addAsSummon) { + static void addStandee(int? nr, Monster data, MonsterType type, bool addAsSummon) { if (nr != null) { - _gameState - .action(AddStandeeCommand(nr, null, data.id, type, addAsSummon)); + _gameState.action(AddStandeeCommand(nr, null, data.id, type, addAsSummon)); } else { //add first un added nr for (int i = 1; i <= data.type.count; i++) { @@ -939,8 +917,7 @@ class GameMethods { } } if (!added) { - _gameState - .action(AddStandeeCommand(i, null, data.id, type, addAsSummon)); + _gameState.action(AddStandeeCommand(i, null, data.id, type, addAsSummon)); return; } } @@ -976,16 +953,15 @@ class GameMethods { if (alliedMonsters.contains(monster)) { isAlly = true; } - _gameState._currentList.add(GameMethods.createMonster(_, monster, - (_gameState.level.value + levelAdjust).clamp(0, 7), isAlly)!); + _gameState._currentList.add(GameMethods.createMonster( + _, monster, (_gameState.level.value + levelAdjust).clamp(0, 7), isAlly)!); } } - static String autoAddStandees(_StateModifier stateModifier, - List roomMonsterData, String initMessage) { + static String autoAddStandees( + _StateModifier stateModifier, List roomMonsterData, String initMessage) { //handle room data - int characterIndex = - GameMethods.getCurrentCharacterAmount().clamp(2, 4) - 2; + int characterIndex = GameMethods.getCurrentCharacterAmount().clamp(2, 4) - 2; for (int i = 0; i < roomMonsterData.length; i++) { var roomMonsters = roomMonsterData[i]; addMonster(stateModifier, roomMonsters.name, _gameState._scenarioSpecialRules); @@ -1000,8 +976,8 @@ class GameMethods { List normals = []; List elites = []; var roomMonsters = roomMonsterData[i]; - Monster data = _gameState.currentList.firstWhereOrNull( - (element) => element.id == roomMonsters.name) as Monster; + Monster data = _gameState.currentList + .firstWhereOrNull((element) => element.id == roomMonsters.name) as Monster; int eliteAmount = roomMonsters.elite[characterIndex]; int normalAmount = roomMonsters.normal[characterIndex]; @@ -1015,8 +991,8 @@ class GameMethods { int randomNr = GameMethods.getRandomStandee(data); if (randomNr != 0) { elites.add(randomNr); - GameMethods.executeAddStandee(stateModifier, - randomNr, null, MonsterType.elite, data.id, false); + GameMethods.executeAddStandee( + stateModifier, randomNr, null, MonsterType.elite, data.id, false); } } @@ -1024,12 +1000,8 @@ class GameMethods { int randomNr = GameMethods.getRandomStandee(data); if (randomNr != 0) { normals.add(randomNr); - GameMethods.executeAddStandee(stateModifier, - randomNr, - null, - isBoss ? MonsterType.boss : MonsterType.normal, - data.id, - false); + GameMethods.executeAddStandee(stateModifier, randomNr, null, + isBoss ? MonsterType.boss : MonsterType.normal, data.id, false); } } @@ -1046,8 +1018,7 @@ class GameMethods { for (int i = 0; i < elites.length; i++) { initMessage += "${elites[i]}, "; if (i == elites.length - 1) { - initMessage = - initMessage.substring(0, initMessage.length - 2); + initMessage = initMessage.substring(0, initMessage.length - 2); } } } @@ -1063,8 +1034,7 @@ class GameMethods { for (int i = 0; i < normals.length; i++) { initMessage += "${normals[i]}, "; if (i == normals.length - 1) { - initMessage = - initMessage.substring(0, initMessage.length - 2); + initMessage = initMessage.substring(0, initMessage.length - 2); } } } @@ -1072,7 +1042,7 @@ class GameMethods { } } else { if (roomMonsterData.isNotEmpty) { - if(getIt.isRegistered()) { + if (getIt.isRegistered()) { openDialogWithDismissOption( getIt(), AutoAddStandeeMenu( @@ -1094,16 +1064,14 @@ class GameMethods { if (item.id == ownerId) { if (item is Monster) { for (var instance in item.monsterInstances) { - String id = - instance.name + instance.gfx + instance.standeeNr.toString(); + String id = instance.name + instance.gfx + instance.standeeNr.toString(); if (id == figureId) { return instance; } } } else if (item is Character) { for (var instance in item.characterState.summonList) { - String id = - instance.name + instance.gfx + instance.standeeNr.toString(); + String id = instance.name + instance.gfx + instance.standeeNr.toString(); if (id == figureId) { return instance; } @@ -1120,9 +1088,7 @@ class GameMethods { if (item is Monster) { for (var instance in item.monsterInstances) { if (instance.standeeNr == nr) { - return instance.name + - instance.gfx + - instance.standeeNr.toString(); + return instance.name + instance.gfx + instance.standeeNr.toString(); } } } @@ -1158,8 +1124,8 @@ class GameMethods { //create the bear summon final int bearHp = 8 + characterState.level.value * 2; - MonsterInstance bear = MonsterInstance.summon( - 0, MonsterType.summon, "Bear", bearHp, 3, 2, 0, "beast", -1); + MonsterInstance bear = + MonsterInstance.summon(0, MonsterType.summon, "Bear", bearHp, 3, 2, 0, "beast", -1); character.characterState._summonList.add(bear); } @@ -1185,10 +1151,10 @@ class GameMethods { } static bool shouldShowAlliesDeck() { - if (!getIt().showAmdDeck.value ) { + if (!getIt().showAmdDeck.value) { return false; } - if (_gameState.showAllyDeck.value ) { + if (_gameState.showAllyDeck.value) { return true; } for (var item in _gameState.currentList) { @@ -1201,12 +1167,11 @@ class GameMethods { return false; } - static void clearTurnStateConditions(_StateModifier _, - FigureState figure, bool clearLastTurnToo) { + static void clearTurnStateConditions( + _StateModifier _, FigureState figure, bool clearLastTurnToo) { if (!clearLastTurnToo) { figure._conditionsAddedPreviousTurn.clear(); - figure._conditionsAddedPreviousTurn.addAll( - figure.conditionsAddedThisTurn.toSet()); + figure._conditionsAddedPreviousTurn.addAll(figure.conditionsAddedThisTurn.toSet()); } else { figure._conditionsAddedPreviousTurn.clear(); } @@ -1295,8 +1260,7 @@ class GameMethods { static void reapplyConditions(_StateModifier _, FigureState figure) { for (var condition in figure.conditionsAddedPreviousTurn) { - if (!figure.conditions.value.contains(condition) || - condition == Condition.chill) { + if (!figure.conditions.value.contains(condition) || condition == Condition.chill) { figure.conditions.value.add(condition); figure._conditionsAddedThisTurn.remove(condition); } @@ -1394,20 +1358,15 @@ class GameMethods { } static void updateForSpecialRules(_StateModifier _) { - List? rules = _gameData - .modelData - .value[_gameState.currentCampaign.value] - ?.scenarios[_gameState.scenario.value] - ?.specialRules; + List? rules = _gameData.modelData.value[_gameState.currentCampaign.value] + ?.scenarios[_gameState.scenario.value]?.specialRules; if (rules != null) { for (SpecialRule rule in rules) { if (rule.type == "Objective" || rule.type == "Escort") { Character? character = _gameState.currentList - .firstWhereOrNull((element) => element.id == rule.name) - as Character?; + .firstWhereOrNull((element) => element.id == rule.name) as Character?; if (character != null) { - int newHealth = - StatCalculator.calculateFormula(rule.health.toString())!; + int newHealth = StatCalculator.calculateFormula(rule.health.toString())!; if (newHealth != character.characterState.maxHealth.value) { character.characterState._maxHealth.value = newHealth; character.characterState._health.value = newHealth; @@ -1415,8 +1374,7 @@ class GameMethods { } } else if (rule.type == "LevelAdjust") { Monster? monster = _gameState.currentList - .firstWhereOrNull((element) => element.id == rule.name) - as Monster?; + .firstWhereOrNull((element) => element.id == rule.name) as Monster?; if (monster != null) { if (_gameState.level.value == monster.level.value) { int newLevel = (monster.level.value + rule.level).clamp(0, 7); @@ -1446,7 +1404,7 @@ class GameMethods { static void setRound(_StateModifier _, int round, bool resetTotal) { _gameState._round.value = round; - if(resetTotal) { + if (resetTotal) { _gameState._totalRounds.value = round; } else { _gameState._totalRounds.value++; diff --git a/frosthaven_assistant/lib/Resource/state/game_state.dart b/frosthaven_assistant/lib/Resource/state/game_state.dart index 6f8e3a21..44adc952 100644 --- a/frosthaven_assistant/lib/Resource/state/game_state.dart +++ b/frosthaven_assistant/lib/Resource/state/game_state.dart @@ -104,7 +104,7 @@ class GameState extends ActionHandler { BuiltList get scenarioSpecialRules => BuiltList.of(_scenarioSpecialRules); List _scenarioSpecialRules = - []; //has both monsters and characters + []; LootDeck get lootDeck => _lootDeck; //todo: still mutable late LootDeck _lootDeck = LootDeck.empty(); //loot deck for current scenario diff --git a/room-data-converter/Frosthaven.json b/room-data-converter/Frosthaven.json index ccd42350..77adb567 100644 --- a/room-data-converter/Frosthaven.json +++ b/room-data-converter/Frosthaven.json @@ -1200,3 +1200,3067 @@ } } ], +{ + "5": [ + { + "Unknown": { + "Cave Bear": { + "normal": [ + 1, + 0, + 1 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Forest Imp": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 1, + 1, + 2 + ] + }, + "Hound": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + } + ], + "9": [ + { + "Unknown": { + "Flame Demon": { + "normal": [ + 0, + 1, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Frost Demon": { + "normal": [ + 0, + 1, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + } + ], + "3": [ + { + "Unknown": { + "Black Imp": { + "normal": [ + 4, + 3, + 3 + ], + "elite": [ + 0, + 2, + 3 + ] + }, + "Night Demon": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + } + ], + "6": [ + { + "Unknown": { + "Ancient Artillery": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "City Archer": { + "normal": [ + 2, + 2, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "City Guard": { + "normal": [ + 0, + 1, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + } + ], + "2": [ + { + "Unknown": { + "Living Spirit": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 2 + ] + }, + "Lurker": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + } + ], + "7": [ + { + "Unknown": { + "Bandit Archer": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Bandit Guard": { + "normal": [ + 0, + 1, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Hound": { + "normal": [ + 1, + 2, + 0 + ], + "elite": [ + 0, + 0, + 2 + ] + } + } + } + ], + "1": [ + { + "Unknown": { + "Cave Bear": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Vermling Scout": { + "normal": [ + 3, + 6, + 4 + ], + "elite": [ + 0, + 1, + 3 + ] + }, + "Vermling Shaman": { + "normal": [ + 0, + 0, + 0 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + } + ], + "12": [ + { + "Unknown": { + "Black Imp": { + "normal": [ + 2, + 5, + 2 + ], + "elite": [ + 0, + 0, + 3 + ] + }, + "Deep Terror": { + "normal": [ + 1, + 0, + 0 + ], + "elite": [ + 1, + 2, + 2 + ] + }, + "Lurker": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + } + ], + "13": [ + { + "Unknown": { + "Ancient Artillery": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Stone Golem": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + } + ], + "14": [ + { + "Unknown": { + "Giant Viper": { + "normal": [ + 2, + 0, + 0 + ], + "elite": [ + 0, + 2, + 2 + ] + }, + "Rending Drake": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Spitting Drake": { + "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + } + ], + "4": [ + { + "Unknown": { + "Forest Imp": { + "normal": [ + 1, + 4, + 1 + ], + "elite": [ + 1, + 1, + 4 + ] + }, + "Sun Demon": { + "normal": [ + 1, + 0, + 1 + ], + "elite": [ + 1, + 2, + 2 + ] + } + } + } + ], + "15": [ + { + "Unknown": { + "Black Imp": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Giant Viper": { + "normal": [ + 3, + 4, + 2 + ], + "elite": [ + 0, + 0, + 2 + ] + }, + "Harrower Infester": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + } + ], + "11": [ + { + "Unknown": { + "Inox Archer": { + "normal": [ + 0, + 0, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Inox Guard": { + "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 1, + 2 + ] + }, + "Inox Shaman": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + } + ], + "10": [ + { + "Unknown": { + "Earth Demon": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + }, + "Wind Demon": { + "normal": [ + 2, + 3, + 4 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + } + ], + "8": [ + { + "Unknown": { + "Living Bones": { + "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 1, + 2 + ] + }, + "Living Corpse": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + }, + "Living Spirit": { + "normal": [ + 0, + 1, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + } + ], + "18": [ + { + "Unknown": { + "Giant Viper": { + "normal": [ + 3, + 4, + 2 + ], + "elite": [ + 1, + 2, + 5 + ] + }, + "Ooze": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + } + ], + "17": [ + { + "Unknown": { + "Cultist": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Living Bones": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Night Demon": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + } + ], + "20": [ + { + "Unknown": { + "Frost Demon": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Savvas Icestorm": { + "normal": [ + 0, + 0, + 0 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Wind Demon": { + "normal": [ + 0, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + } + ], + "16": [ + { + "Unknown": { + "Earth Demon": { + "normal": [ + 1, + 0, + 1 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Flame Demon": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Savvas Lavaflow": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + } + ], +{ + "5": [ + { + "Unknown": { + "Cave Bear": { + "normal": [ + 1, + 0, + 1 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Forest Imp": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 1, + 1, + 2 + ] + }, + "Hound": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + } + ], + "9": [ + { + "Unknown": { + "Flame Demon": { + "normal": [ + 0, + 1, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Frost Demon": { + "normal": [ + 0, + 1, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + } + ], + "3": [ + { + "Unknown": { + "Black Imp": { + "normal": [ + 4, + 3, + 3 + ], + "elite": [ + 0, + 2, + 3 + ] + }, + "Night Demon": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + } + ], + "6": [ + { + "Unknown": { + "Ancient Artillery": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "City Archer": { + "normal": [ + 2, + 2, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "City Guard": { + "normal": [ + 0, + 1, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + } + ], + "2": [ + { + "Unknown": { + "Living Spirit": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 2 + ] + }, + "Lurker": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + } + ], + "7": [ + { + "Unknown": { + "Bandit Archer": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Bandit Guard": { + "normal": [ + 0, + 1, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Hound": { + "normal": [ + 1, + 2, + 0 + ], + "elite": [ + 0, + 0, + 2 + ] + } + } + } + ], + "1": [ + { + "Unknown": { + "Cave Bear": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Vermling Scout": { + "normal": [ + 3, + 6, + 4 + ], + "elite": [ + 0, + 1, + 3 + ] + }, + "Vermling Shaman": { + "normal": [ + 0, + 0, + 0 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + } + ], + "12": [ + { + "Unknown": { + "Black Imp": { + "normal": [ + 2, + 5, + 2 + ], + "elite": [ + 0, + 0, + 3 + ] + }, + "Deep Terror": { + "normal": [ + 1, + 0, + 0 + ], + "elite": [ + 1, + 2, + 2 + ] + }, + "Lurker": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + } + ], + "13": [ + { + "Unknown": { + "Ancient Artillery": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Stone Golem": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + } + ], + "14": [ + { + "Unknown": { + "Giant Viper": { + "normal": [ + 2, + 0, + 0 + ], + "elite": [ + 0, + 2, + 2 + ] + }, + "Rending Drake": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Spitting Drake": { + "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + } + ], + "4": [ + { + "Unknown": { + "Forest Imp": { + "normal": [ + 1, + 4, + 1 + ], + "elite": [ + 1, + 1, + 4 + ] + }, + "Sun Demon": { + "normal": [ + 1, + 0, + 1 + ], + "elite": [ + 1, + 2, + 2 + ] + } + } + } + ], + "15": [ + { + "Unknown": { + "Black Imp": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Giant Viper": { + "normal": [ + 3, + 4, + 2 + ], + "elite": [ + 0, + 0, + 2 + ] + }, + "Harrower Infester": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + } + ], + "11": [ + { + "Unknown": { + "Inox Archer": { + "normal": [ + 0, + 0, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Inox Guard": { + "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 1, + 2 + ] + }, + "Inox Shaman": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + } + ], + "10": [ + { + "Unknown": { + "Earth Demon": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + }, + "Wind Demon": { + "normal": [ + 2, + 3, + 4 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + } + ], + "8": [ + { + "Unknown": { + "Living Bones": { + "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 1, + 2 + ] + }, + "Living Corpse": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + }, + "Living Spirit": { + "normal": [ + 0, + 1, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + } + ], + "18": [ + { + "Unknown": { + "Giant Viper": { + "normal": [ + 3, + 4, + 2 + ], + "elite": [ + 1, + 2, + 5 + ] + }, + "Ooze": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + } + ], + "17": [ + { + "Unknown": { + "Cultist": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Living Bones": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Night Demon": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + } + ], + "20": [ + { + "Unknown": { + "Frost Demon": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Savvas Icestorm": { + "normal": [ + 0, + 0, + 0 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Wind Demon": { + "normal": [ + 0, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + } + ], + "16": [ + { + "Unknown": { + "Earth Demon": { + "normal": [ + 1, + 0, + 1 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Flame Demon": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Savvas Lavaflow": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + } + ], + "21": [ + { + "Unknown": { + "Valrath Savage": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Valrath Tracker": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + } + ], +{ + "5": [ + { + "Unknown": { + "Cave Bear": { + "normal": [ + 1, + 0, + 1 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Forest Imp": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 1, + 1, + 2 + ] + }, + "Hound": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + } + ], + "9": [ + { + "Unknown": { + "Flame Demon": { + "normal": [ + 0, + 1, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Frost Demon": { + "normal": [ + 0, + 1, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + } + ], + "3": [ + { + "Unknown": { + "Black Imp": { + "normal": [ + 4, + 3, + 3 + ], + "elite": [ + 0, + 2, + 3 + ] + }, + "Night Demon": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + } + ], + "6": [ + { + "Unknown": { + "Ancient Artillery": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "City Archer": { + "normal": [ + 2, + 2, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "City Guard": { + "normal": [ + 0, + 1, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + } + ], + "2": [ + { + "Unknown": { + "Living Spirit": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 2 + ] + }, + "Lurker": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + } + ], + "7": [ + { + "Unknown": { + "Bandit Archer": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Bandit Guard": { + "normal": [ + 0, + 1, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Hound": { + "normal": [ + 1, + 2, + 0 + ], + "elite": [ + 0, + 0, + 2 + ] + } + } + } + ], + "1": [ + { + "Unknown": { + "Cave Bear": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Vermling Scout": { + "normal": [ + 3, + 6, + 4 + ], + "elite": [ + 0, + 1, + 3 + ] + }, + "Vermling Shaman": { + "normal": [ + 0, + 0, + 0 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + } + ], + "12": [ + { + "Unknown": { + "Black Imp": { + "normal": [ + 2, + 5, + 2 + ], + "elite": [ + 0, + 0, + 3 + ] + }, + "Deep Terror": { + "normal": [ + 1, + 0, + 0 + ], + "elite": [ + 1, + 2, + 2 + ] + }, + "Lurker": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + } + ], + "13": [ + { + "Unknown": { + "Ancient Artillery": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Stone Golem": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + } + ], + "14": [ + { + "Unknown": { + "Giant Viper": { + "normal": [ + 2, + 0, + 0 + ], + "elite": [ + 0, + 2, + 2 + ] + }, + "Rending Drake": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Spitting Drake": { + "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + } + ], + "4": [ + { + "Unknown": { + "Forest Imp": { + "normal": [ + 1, + 4, + 1 + ], + "elite": [ + 1, + 1, + 4 + ] + }, + "Sun Demon": { + "normal": [ + 1, + 0, + 1 + ], + "elite": [ + 1, + 2, + 2 + ] + } + } + } + ], + "15": [ + { + "Unknown": { + "Black Imp": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Giant Viper": { + "normal": [ + 3, + 4, + 2 + ], + "elite": [ + 0, + 0, + 2 + ] + }, + "Harrower Infester": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + } + ], + "11": [ + { + "Unknown": { + "Inox Archer": { + "normal": [ + 0, + 0, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Inox Guard": { + "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 1, + 2 + ] + }, + "Inox Shaman": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + } + ], + "10": [ + { + "Unknown": { + "Earth Demon": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + }, + "Wind Demon": { + "normal": [ + 2, + 3, + 4 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + } + ], + "8": [ + { + "Unknown": { + "Living Bones": { + "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 1, + 2 + ] + }, + "Living Corpse": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + }, + "Living Spirit": { + "normal": [ + 0, + 1, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + } + ], + "18": [ + { + "Unknown": { + "Giant Viper": { + "normal": [ + 3, + 4, + 2 + ], + "elite": [ + 1, + 2, + 5 + ] + }, + "Ooze": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + } + ], + "17": [ + { + "Unknown": { + "Cultist": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Living Bones": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Night Demon": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + } + ], + "20": [ + { + "Unknown": { + "Frost Demon": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Savvas Icestorm": { + "normal": [ + 0, + 0, + 0 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Wind Demon": { + "normal": [ + 0, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + } + ], + "16": [ + { + "Unknown": { + "Earth Demon": { + "normal": [ + 1, + 0, + 1 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Flame Demon": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Savvas Lavaflow": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + } + ], + "21": [ + { + "Unknown": { + "Valrath Savage": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Valrath Tracker": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + } + ], + "22": [ + { + "Unknown": { + "Aesther Ashblade": { + "normal": [ + 0, + 0, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Aesther Scout": { + "normal": [ + 1, + 2, + 3 + ], + "elite": [ + 0, + 0, + 0 + ] + }, + "Ooze": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + } + ], + "19": [ + { + "Unknown": { + "Living Corpse": { + "normal": [ + 1, + 2, + 4 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Ooze": { + "normal": [ + 2, + 2, + 1 + ], + "elite": [ + 0, + 1, + 2 + ] + } + } + } + ], +{ + "5": [ + { + "Unknown": { + "Cave Bear": { + "normal": [ + 1, + 0, + 1 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Forest Imp": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 1, + 1, + 2 + ] + }, + "Hound": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + } + ], + "9": [ + { + "Unknown": { + "Flame Demon": { + "normal": [ + 0, + 1, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Frost Demon": { + "normal": [ + 0, + 1, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + } + ], + "3": [ + { + "Unknown": { + "Black Imp": { + "normal": [ + 4, + 3, + 3 + ], + "elite": [ + 0, + 2, + 3 + ] + }, + "Night Demon": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + } + ], + "6": [ + { + "Unknown": { + "Ancient Artillery": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "City Archer": { + "normal": [ + 2, + 2, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "City Guard": { + "normal": [ + 0, + 1, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + } + ], + "2": [ + { + "Unknown": { + "Living Spirit": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 2 + ] + }, + "Lurker": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + } + ], + "7": [ + { + "Unknown": { + "Bandit Archer": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Bandit Guard": { + "normal": [ + 0, + 1, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Hound": { + "normal": [ + 1, + 2, + 0 + ], + "elite": [ + 0, + 0, + 2 + ] + } + } + } + ], + "1": [ + { + "Unknown": { + "Cave Bear": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Vermling Scout": { + "normal": [ + 3, + 6, + 4 + ], + "elite": [ + 0, + 1, + 3 + ] + }, + "Vermling Shaman": { + "normal": [ + 0, + 0, + 0 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + } + ], + "12": [ + { + "Unknown": { + "Black Imp": { + "normal": [ + 2, + 5, + 2 + ], + "elite": [ + 0, + 0, + 3 + ] + }, + "Deep Terror": { + "normal": [ + 1, + 0, + 0 + ], + "elite": [ + 1, + 2, + 2 + ] + }, + "Lurker": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + } + ], + "13": [ + { + "Unknown": { + "Ancient Artillery": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Stone Golem": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + } + ], + "14": [ + { + "Unknown": { + "Giant Viper": { + "normal": [ + 2, + 0, + 0 + ], + "elite": [ + 0, + 2, + 2 + ] + }, + "Rending Drake": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Spitting Drake": { + "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + } + ], + "4": [ + { + "Unknown": { + "Forest Imp": { + "normal": [ + 1, + 4, + 1 + ], + "elite": [ + 1, + 1, + 4 + ] + }, + "Sun Demon": { + "normal": [ + 1, + 0, + 1 + ], + "elite": [ + 1, + 2, + 2 + ] + } + } + } + ], + "15": [ + { + "Unknown": { + "Black Imp": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Giant Viper": { + "normal": [ + 3, + 4, + 2 + ], + "elite": [ + 0, + 0, + 2 + ] + }, + "Harrower Infester": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + } + ], + "11": [ + { + "Unknown": { + "Inox Archer": { + "normal": [ + 0, + 0, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Inox Guard": { + "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 1, + 2 + ] + }, + "Inox Shaman": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + } + ], + "10": [ + { + "Unknown": { + "Earth Demon": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + }, + "Wind Demon": { + "normal": [ + 2, + 3, + 4 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + } + ], + "8": [ + { + "Unknown": { + "Living Bones": { + "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 1, + 2 + ] + }, + "Living Corpse": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + }, + "Living Spirit": { + "normal": [ + 0, + 1, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + } + ], + "18": [ + { + "Unknown": { + "Giant Viper": { + "normal": [ + 3, + 4, + 2 + ], + "elite": [ + 1, + 2, + 5 + ] + }, + "Ooze": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + } + ], + "17": [ + { + "Unknown": { + "Cultist": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Living Bones": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Night Demon": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + } + ], + "20": [ + { + "Unknown": { + "Frost Demon": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Savvas Icestorm": { + "normal": [ + 0, + 0, + 0 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Wind Demon": { + "normal": [ + 0, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + } + ], + "16": [ + { + "Unknown": { + "Earth Demon": { + "normal": [ + 1, + 0, + 1 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Flame Demon": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Savvas Lavaflow": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + } + ], + "21": [ + { + "Unknown": { + "Valrath Savage": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Valrath Tracker": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + } + ], + "22": [ + { + "Unknown": { + "Aesther Ashblade": { + "normal": [ + 0, + 0, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Aesther Scout": { + "normal": [ + 1, + 2, + 3 + ], + "elite": [ + 0, + 0, + 0 + ] + }, + "Ooze": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + } + ], diff --git a/room-data-converter/README.md b/room-data-converter/README.md deleted file mode 100644 index 3816eca3..00000000 --- a/room-data-converter/README.md +++ /dev/null @@ -1,2 +0,0 @@ -A sample command-line application with an entrypoint in `bin/`, library code -in `lib/`, and example unit test in `test/`. diff --git a/room-data-converter/assets/data/1.json b/room-data-converter/assets/data/1.json new file mode 100644 index 00000000..95d54ad4 --- /dev/null +++ b/room-data-converter/assets/data/1.json @@ -0,0 +1,54 @@ +{ + "index": "891", + "group": "randomMonsterCard", + "name": "Smashing", + "edition": "fh", + "rules": [ + { + "round": "true", + "always": true, + "once": true, + "elements": [ + { + "type": "earth", + "state": "new" + } + ] + } + ], + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "algox-archer", + "player2": "normal", + "player3": "elite", + "player4": "elite" + }, + { + "name": "algox-archer", + "player3": "normal", + "player4": "normal" + }, + { + "name": "algox-archer", + "player3": "normal" + }, + { + "name": "algox-icespeaker", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "algox-icespeaker", + "player2": "normal", + "player4": "normal" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/10.json b/room-data-converter/assets/data/10.json new file mode 100644 index 00000000..e80b1e4b --- /dev/null +++ b/room-data-converter/assets/data/10.json @@ -0,0 +1,57 @@ +{ + "index": "900", + "group": "randomMonsterCard", + "name": "Decayed", + "edition": "fh", + "rules": [ + { + "round": "true", + "always": true, + "once": true, + "elements": [ + { + "type": "ice", + "state": "new" + } + ] + } + ], + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "frozen-corpse", + "type": "normal" + }, + { + "name": "frozen-corpse", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "frozen-corpse", + "player2": "normal", + "player3": "elite", + "player4": "elite" + }, + { + "name": "frozen-corpse", + "player4": "normal" + }, + { + "name": "living-bones", + "type": "normal" + }, + { + "name": "living-bones", + "player3": "normal", + "player4": "normal" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/11.json b/room-data-converter/assets/data/11.json new file mode 100644 index 00000000..bc5fe042 --- /dev/null +++ b/room-data-converter/assets/data/11.json @@ -0,0 +1,40 @@ +{ + "index": "901", + "group": "randomMonsterCard", + "name": "Deomesticated", + "edition": "fh", + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "abael-herder", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "abael-herder", + "player3": "elite", + "player4": "elite" + }, + { + "name": "abael-scout", + "type": "elite" + }, + { + "name": "piranha-pig", + "type": "normal" + }, + { + "name": "piranha-pig", + "player2": "normal", + "player3": "normal", + "player4": "elite" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/12.json b/room-data-converter/assets/data/12.json new file mode 100644 index 00000000..714338c7 --- /dev/null +++ b/room-data-converter/assets/data/12.json @@ -0,0 +1,58 @@ +{ + "index": "902", + "group": "randomMonsterCard", + "name": "Trashing", + "edition": "fh", + "rules": [ + { + "round": "true", + "always": true, + "once": true, + "elements": [ + { + "type": "ice", + "state": "new" + } + ] + } + ], + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "lurker-soldier", + "type": "normal" + }, + { + "name": "lurker-soldier", + "player3": "normal", + "player4": "normal" + }, + { + "name": "lurker-wavethrower", + "type": "elite" + }, + { + "name": "lurker-wavethrower", + "player3": "normal", + "player4": "elite" + }, + { + "name": "piranha-pig", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "piranha-pig", + "player2": "normal", + "player3": "normal", + "player4": "elite" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/13.json b/room-data-converter/assets/data/13.json new file mode 100644 index 00000000..aa7515b1 --- /dev/null +++ b/room-data-converter/assets/data/13.json @@ -0,0 +1,51 @@ +{ + "index": "903", + "group": "randomMonsterCard", + "name": "Daunting", + "edition": "fh", + "rules": [ + { + "round": "true", + "always": true, + "once": true, + "elements": [ + { + "type": "earth", + "state": "new" + } + ] + } + ], + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "lurker-clawcrusher", + "type": "normal" + }, + { + "name": "lurker-clawcrusher", + "player2": "normal", + "player3": "elite", + "player4": "elite" + }, + { + "name": "lurker-mindsnipper", + "type": "normal" + }, + { + "name": "lurker-mindsnipper", + "player4": "normal" + }, + { + "name": "lurker-wavethrower", + "player3": "normal", + "player4": "elite" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/14.json b/room-data-converter/assets/data/14.json new file mode 100644 index 00000000..146934ea --- /dev/null +++ b/room-data-converter/assets/data/14.json @@ -0,0 +1,65 @@ +{ + "index": "904", + "group": "randomMonsterCard", + "name": "Abandoned", + "edition": "fh", + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "ancient-artillery", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "ancient-artillery", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "ancient-artillery", + "player2": "normal", + "player3": "elite", + "player4": "elite" + }, + { + "name": "ruined-machine", + "type": "elite" + }, + { + "name": "ruined-machine", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "ruined-machine", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "ruined-machine", + "player2": "normal", + "player3": "elite", + "player4": "elite" + }, + { + "name": "ruined-machine", + "player3": "normal", + "player4": "normal" + }, + { + "name": "ruined-machine", + "player3": "normal", + "player4": "normal" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/15.json b/room-data-converter/assets/data/15.json new file mode 100644 index 00000000..4d163af1 --- /dev/null +++ b/room-data-converter/assets/data/15.json @@ -0,0 +1,44 @@ +{ + "index": "905", + "group": "randomMonsterCard", + "name": "Reinforced", + "edition": "fh", + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "robotic-boltshooter", + "type": "normal" + }, + { + "name": "robotic-boltshooter", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "robotic-boltshooter", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "robotic-boltshooter", + "player4": "normal" + }, + { + "name": "steel-automaton", + "type": "normal" + }, + { + "name": "steel-automaton", + "player3": "normal", + "player4": "normal" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/16.json b/room-data-converter/assets/data/16.json new file mode 100644 index 00000000..42ef9df8 --- /dev/null +++ b/room-data-converter/assets/data/16.json @@ -0,0 +1,48 @@ +{ + "index": "906", + "group": "randomMonsterCard", + "name": "Rusted", + "edition": "fh", + "rules": [ + { + "round": "true", + "always": true, + "once": true, + "elements": [ + { + "type": "fire", + "state": "new" + } + ] + } + ], + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "flaming-bladespinner", + "type": "normal" + }, + { + "name": "flaming-bladespinner", + "player4": "normal" + }, + { + "name": "ruined-machine", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "steel-automaton", + "player2": "normal", + "player3": "elite", + "player4": "elite" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/17.json b/room-data-converter/assets/data/17.json new file mode 100644 index 00000000..82f42955 --- /dev/null +++ b/room-data-converter/assets/data/17.json @@ -0,0 +1,63 @@ +{ + "index": "907", + "group": "randomMonsterCard", + "name": "Unsettling", + "edition": "fh", + "rules": [ + { + "round": "true", + "always": true, + "once": true, + "elements": [ + { + "type": "dark", + "state": "new" + } + ] + } + ], + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "black-imp", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "black-imp", + "player3": "normal", + "player4": "elite" + }, + { + "name": "chaos-demon", + "type": "normal" + }, + { + "name": "chaos-demon", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "chaos-demon", + "player3": "normal", + "player4": "normal" + }, + { + "name": "ooze", + "type": "elite" + }, + { + "name": "ooze", + "player3": "normal", + "player4": "normal" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/18.json b/room-data-converter/assets/data/18.json new file mode 100644 index 00000000..05c06f7d --- /dev/null +++ b/room-data-converter/assets/data/18.json @@ -0,0 +1,57 @@ +{ + "index": "908", + "group": "randomMonsterCard", + "name": "Taloned", + "edition": "fh", + "rules": [ + { + "round": "true", + "always": true, + "once": true, + "elements": [ + { + "type": "dark", + "state": "new" + } + ] + } + ], + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "rending-drake", + "type": "normal" + }, + { + "name": "rending-drake", + "player2": "normal", + "player3": "elite", + "player4": "elite" + }, + { + "name": "rending-drake", + "player4": "normal" + }, + { + "name": "shrike-fiend", + "type": "normal" + }, + { + "name": "shrike-fiend", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "shrike-fiend", + "player3": "normal", + "player4": "normal" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/19.json b/room-data-converter/assets/data/19.json new file mode 100644 index 00000000..0bba0096 --- /dev/null +++ b/room-data-converter/assets/data/19.json @@ -0,0 +1,55 @@ +{ + "index": "909", + "group": "randomMonsterCard", + "name": "Segmented", + "edition": "fh", + "rules": [ + { + "round": "true", + "always": true, + "once": true, + "elements": [ + { + "type": "earth", + "state": "new" + } + ] + } + ], + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "burrowing-blade", + "type": "normal" + }, + { + "name": "burrowing-blade", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "burrowing-blade", + "player3": "normal", + "player4": "normal" + }, + { + "name": "spitting-drake", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "spitting-drake", + "player2": "normal", + "player3": "elite", + "player4": "elite" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/2.json b/room-data-converter/assets/data/2.json new file mode 100644 index 00000000..e9a38b47 --- /dev/null +++ b/room-data-converter/assets/data/2.json @@ -0,0 +1,54 @@ +{ + "index": "892", + "group": "randomMonsterCard", + "name": "Stormy", + "edition": "fh", + "rules": [ + { + "round": "true", + "always": true, + "once": true, + "elements": [ + { + "type": "air", + "state": "new" + } + ] + } + ], + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "algox-guard", + "player2": "normal", + "player3": "elite", + "player4": "elite" + }, + { + "name": "algox-guard", + "player3": "normal", + "player4": "normal" + }, + { + "name": "algox-guard", + "player3": "normal" + }, + { + "name": "algox-snowspeaker", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "algox-snowspeaker", + "player2": "normal", + "player4": "normal" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/20.json b/room-data-converter/assets/data/20.json new file mode 100644 index 00000000..830906c7 --- /dev/null +++ b/room-data-converter/assets/data/20.json @@ -0,0 +1,63 @@ +{ + "index": "910", + "group": "randomMonsterCard", + "name": "Dirty", + "edition": "fh", + "rules": [ + { + "round": "true", + "always": true, + "once": true, + "elements": [ + { + "type": "earth", + "state": "new" + } + ] + } + ], + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "earth-demon", + "type": "normal" + }, + { + "name": "earth-demon", + "player2": "normal", + "player3": "elite", + "player4": "elite" + }, + { + "name": "earth-demon", + "player4": "normal" + }, + { + "name": "forest-imp", + "type": "normal" + }, + { + "name": "forest-imp", + "player3": "normal", + "player4": "normal" + }, + { + "name": "ooze", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "ooze", + "player2": "normal", + "player3": "elite", + "player4": "elite" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/21.json b/room-data-converter/assets/data/21.json new file mode 100644 index 00000000..7c0458bc --- /dev/null +++ b/room-data-converter/assets/data/21.json @@ -0,0 +1,59 @@ +{ + "index": "911", + "group": "randomMonsterCard", + "name": "Grave", + "edition": "fh", + "rules": [ + { + "round": "true", + "always": true, + "once": true, + "elements": [ + { + "type": "dark", + "state": "new" + } + ] + } + ], + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "deep-terror", + "type": "normal" + }, + { + "name": "deep-terror", + "player4": "normal" + }, + { + "name": "ice-wraith", + "type": "normal" + }, + { + "name": "ice-wraith", + "player4": "elite" + }, + { + "name": "night-demon", + "type": "normal" + }, + { + "name": "night-demon", + "player2": "normal", + "player3": "elite", + "player4": "elite" + }, + { + "name": "night-demon", + "player3": "normal", + "player4": "normal" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/22.json b/room-data-converter/assets/data/22.json new file mode 100644 index 00000000..59db601f --- /dev/null +++ b/room-data-converter/assets/data/22.json @@ -0,0 +1,57 @@ +{ + "index": "912", + "group": "randomMonsterCard", + "name": "Luminous", + "edition": "fh", + "rules": [ + { + "round": "true", + "always": true, + "once": true, + "elements": [ + { + "type": "light", + "state": "new" + } + ] + } + ], + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "lurker-wavethrower", + "type": "elite" + }, + { + "name": "lurker-wavethrower", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "lurker-wavethrower", + "player4": "elite" + }, + { + "name": "sun-demon", + "type": "normal" + }, + { + "name": "sun-demon", + "player2": "normal", + "player3": "elite", + "player4": "elite" + }, + { + "name": "sun-demon", + "player3": "normal", + "player4": "normal" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/23.json b/room-data-converter/assets/data/23.json new file mode 100644 index 00000000..2af73262 --- /dev/null +++ b/room-data-converter/assets/data/23.json @@ -0,0 +1,53 @@ +{ + "index": "913", + "group": "randomMonsterCard", + "name": "Scorching", + "edition": "fh", + "rules": [ + { + "round": "true", + "always": true, + "once": true, + "elements": [ + { + "type": "fire", + "state": "new" + } + ] + } + ], + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "flame-demon", + "player2": "normal", + "player3": "elite", + "player4": "normal" + }, + { + "name": "flame-demon", + "player3": "normal", + "player4": "normal" + }, + { + "name": "flaming-bladespinner", + "type": "normal" + }, + { + "name": "flaming-bladespinner", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "flaming-bladespinner", + "player4": "normal" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/24.json b/room-data-converter/assets/data/24.json new file mode 100644 index 00000000..4ee10b34 --- /dev/null +++ b/room-data-converter/assets/data/24.json @@ -0,0 +1,52 @@ +{ + "index": "914", + "group": "randomMonsterCard", + "name": "Swift", + "edition": "fh", + "rules": [ + { + "round": "true", + "always": true, + "once": true, + "elements": [ + { + "type": "air", + "state": "new" + } + ] + } + ], + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "algox-scout", + "type": "elite" + }, + { + "name": "algox-scout", + "player3": "normal", + "player4": "elite" + }, + { + "name": "wind-demon", + "type": "normal" + }, + { + "name": "wind-demon", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "wind-demon", + "player3": "normal", + "player4": "normal" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/3.json b/room-data-converter/assets/data/3.json new file mode 100644 index 00000000..ad509b74 --- /dev/null +++ b/room-data-converter/assets/data/3.json @@ -0,0 +1,42 @@ +{ + "index": "893", + "group": "randomMonsterCard", + "name": "Territorial", + "edition": "fh", + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "algox-priest", + "type": "normal" + }, + { + "name": "algox-priest", + "player2": "normal", + "player3": "elite", + "player4": "elite" + }, + { + "name": "algox-priest", + "player4": "normal" + }, + { + "name": "algox-scout", + "type": "elite" + }, + { + "name": "algox-scout", + "player3": "normal", + "player4": "normal" + }, + { + "name": "algox-scout", + "player4": "normal" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/4.json b/room-data-converter/assets/data/4.json new file mode 100644 index 00000000..efe71f89 --- /dev/null +++ b/room-data-converter/assets/data/4.json @@ -0,0 +1,45 @@ +{ + "index": "894", + "group": "randomMonsterCard", + "name": "Feral", + "edition": "fh", + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "hound", + "type": "elite" + }, + { + "name": "hound", + "player3": "normal", + "player4": "normal" + }, + { + "name": "polar-bear", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "polar-bear", + "player3": "normal", + "player4": "normal" + }, + { + "name": "snow-imp", + "type": "elite" + }, + { + "name": "snow-imp", + "player2": "normal", + "player3": "normal", + "player4": "elite" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/5.json b/room-data-converter/assets/data/5.json new file mode 100644 index 00000000..5a27d9ab --- /dev/null +++ b/room-data-converter/assets/data/5.json @@ -0,0 +1,53 @@ +{ + "index": "895", + "group": "randomMonsterCard", + "name": "Tamed", + "edition": "fh", + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "polar-bear", + "player2": "normal", + "player3": "elite", + "player4": "elite" + }, + { + "name": "vermling-priest", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "vermling-priest", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "vermling-scout", + "type": "elite" + }, + { + "name": "vermling-scout", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "vermling-scout", + "player3": "normal", + "player4": "normal" + }, + { + "name": "vermling-scout", + "player3": "normal", + "player4": "elite" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/6.json b/room-data-converter/assets/data/6.json new file mode 100644 index 00000000..24a09391 --- /dev/null +++ b/room-data-converter/assets/data/6.json @@ -0,0 +1,60 @@ +{ + "index": "896", + "group": "randomMonsterCard", + "name": "Swarming", + "edition": "fh", + "rules": [ + { + "round": "true", + "always": true, + "once": true, + "elements": [ + { + "type": "dark", + "state": "new" + } + ] + } + ], + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "forest-imp", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "forest-imp", + "player3": "normal", + "player4": "elite" + }, + { + "name": "forest-imp", + "player4": "normal" + }, + { + "name": "harrower-infester", + "type": "normal" + }, + { + "name": "harrower-infester", + "player3": "normal", + "player4": "normal" + }, + { + "name": "shrike-fiend", + "type": "elite" + }, + { + "name": "shrike-fiend", + "player4": "normal" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/7.json b/room-data-converter/assets/data/7.json new file mode 100644 index 00000000..9b3138f2 --- /dev/null +++ b/room-data-converter/assets/data/7.json @@ -0,0 +1,62 @@ +{ + "index": "897", + "group": "randomMonsterCard", + "name": "Traitorous", + "edition": "fh", + "rules": [ + { + "round": "true", + "always": true, + "once": true, + "elements": [ + { + "type": "light", + "state": "new" + } + ] + } + ], + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "chaos-demon", + "type": "normal" + }, + { + "name": "chaos-demon", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "chaos-demon", + "player4": "normal" + }, + { + "name": "city-guard", + "type": "elite" + }, + { + "name": "city-guard", + "player2": "normal", + "player3": "elite", + "player4": "elite" + }, + { + "name": "city-guard", + "player3": "normal", + "player4": "normal" + }, + { + "name": "city-guard", + "player3": "normal", + "player4": "normal" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/8.json b/room-data-converter/assets/data/8.json new file mode 100644 index 00000000..75679498 --- /dev/null +++ b/room-data-converter/assets/data/8.json @@ -0,0 +1,58 @@ +{ + "index": "898", + "group": "randomMonsterCard", + "name": "Bleak", + "edition": "fh", + "rules": [ + { + "round": "true", + "always": true, + "once": true, + "elements": [ + { + "type": "ice", + "state": "new" + } + ] + } + ], + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "living-bones", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "living-bones", + "player3": "normal", + "player4": "normal" + }, + { + "name": "living-doom", + "type": "elite" + }, + { + "name": "living-doom", + "player3": "normal", + "player4": "normal" + }, + { + "name": "living-spirit", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "living-spirit", + "player4": "normal" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/assets/data/9.json b/room-data-converter/assets/data/9.json new file mode 100644 index 00000000..c35db2da --- /dev/null +++ b/room-data-converter/assets/data/9.json @@ -0,0 +1,56 @@ +{ + "index": "899", + "group": "randomMonsterCard", + "name": "Sapping", + "edition": "fh", + "rules": [ + { + "round": "true", + "always": true, + "once": true, + "elements": [ + { + "type": "ice", + "state": "new" + } + ] + } + ], + "rooms": [ + { + "roomNumber": 1, + "initial": true, + "treasures": [], + "monster": [ + { + "name": "frost-demon", + "player2": "normal", + "player3": "normal", + "player4": "elite" + }, + { + "name": "frost-demon", + "player4": "normal" + }, + { + "name": "ice-wraith", + "type": "normal" + }, + { + "name": "ice-wraith", + "type": "elite" + }, + { + "name": "ice-wraith", + "player3": "normal", + "player4": "normal" + }, + { + "name": "snow-imp", + "player3": "normal", + "player4": "normal" + } + ] + } + ] +} \ No newline at end of file diff --git a/room-data-converter/lib/room_data_converter.dart b/room-data-converter/lib/room_data_converter.dart index e2ae2070..e032bb67 100644 --- a/room-data-converter/lib/room_data_converter.dart +++ b/room-data-converter/lib/room_data_converter.dart @@ -8,7 +8,7 @@ Future calculate() async { bool ttsData = false; //await File('Gloomhaven.json').writeAsString(""); String res = "{\n"; - for (int scenarioNumber = 0; scenarioNumber <= 19; scenarioNumber++) { + for (int scenarioNumber = 1; scenarioNumber <= 24; scenarioNumber++) { File file = File('./assets/data/$scenarioNumber.json'); Future futureContent = file.readAsString(); futureContent.then((c) async { @@ -23,6 +23,9 @@ Future calculate() async { final rooms = data['rooms'] as List; for (var room in rooms) { String roomName = "unknown"; + if(data.containsKey("name") && data.containsKey("index")) { + roomName = data['index'] + " " + data['name']; + } if (room.containsKey('ref')) { roomName = room['ref']; } @@ -146,7 +149,7 @@ Future calculate() async { scenarioJson = scenarioJson.substring(2, scenarioJson.length - 2); res += "$scenarioJson,\n"; }).then((value) async { - await File('Frosthaven.json').writeAsString(res, mode: FileMode.append); + await File('random.json').writeAsString(res, mode: FileMode.append); }); } diff --git a/room-data-converter/random.json b/room-data-converter/random.json new file mode 100644 index 00000000..3310ba95 --- /dev/null +++ b/room-data-converter/random.json @@ -0,0 +1,820 @@ + "Random": [ + { + "start": {} + }, + { + "891 Smashing": { + "Algox Archer": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Algox Icespeaker": { + "normal": [ + 2, + 1, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "893 Territorial": { + "Algox Priest": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Algox Scout": { + "normal": [ + 0, + 1, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + }, + { + "892 Stormy": { + "Algox Guard": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Algox Snowspeaker": { + "normal": [ + 2, + 1, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "894 Feral": { + "Hound": { + "normal": [ + 0, + 1, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Polar Bear": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Snow Imp": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + } + } + }, + { + "895 Tamed": { + "Polar Bear": { + "normal": [ + 1, + 0, + 0 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Vermling Priest": { + "normal": [ + 2, + 2, + 0 + ], + "elite": [ + 0, + 0, + 2 + ] + }, + "Vermling Scout": { + "normal": [ + 1, + 3, + 1 + ], + "elite": [ + 1, + 1, + 3 + ] + } + } + }, + { + "896 Swarming": { + "Forest Imp": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 2 + ] + }, + "Harrower Infester": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 0, + 0, + 0 + ] + }, + "Shrike Fiend": { + "normal": [ + 0, + 0, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + }, + { + "897 Traitorous": { + "Chaos Demon": { + "normal": [ + 2, + 2, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "City Guard": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 1, + 2, + 2 + ] + } + } + }, + { + "898 Bleak": { + "Living Bones": { + "normal": [ + 1, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Living Doom": { + "normal": [ + 0, + 1, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Living Spirit": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "899 Sapping": { + "Frost Demon": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Ice Wraith": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Snow Imp": { + "normal": [ + 0, + 1, + 1 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + }, + { + "900 Decayed": { + "Frozen Corpse": { + "normal": [ + 3, + 2, + 2 + ], + "elite": [ + 0, + 1, + 2 + ] + }, + "Living Bones": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + }, + { + "901 Deomesticated": { + "Abael Herder": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 1, + 2 + ] + }, + "Abael Scout": { + "normal": [ + 0, + 0, + 0 + ], + "elite": [ + 1, + 1, + 1 + ] + }, + "Piranha Pig": { + "normal": [ + 2, + 2, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "903 Daunting": { + "Lurker Clawcrusher": { + "normal": [ + 2, + 1, + 1 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Lurker Mindsnipper": { + "normal": [ + 1, + 1, + 2 + ], + "elite": [ + 0, + 0, + 0 + ] + }, + "Lurker Wavethrower": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "902 Trashing": { + "Lurker Soldier": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 0, + 0, + 0 + ] + }, + "Lurker Wavethrower": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + }, + "Piranha Pig": { + "normal": [ + 2, + 2, + 0 + ], + "elite": [ + 0, + 0, + 2 + ] + } + } + }, + { + "904 Abandoned": { + "Ancient Artillery": { + "normal": [ + 3, + 2, + 0 + ], + "elite": [ + 0, + 1, + 3 + ] + }, + "Ruined Machine": { + "normal": [ + 3, + 4, + 2 + ], + "elite": [ + 1, + 2, + 4 + ] + } + } + }, + { + "905 Reinforced": { + "Robotic Boltshooter": { + "normal": [ + 3, + 3, + 2 + ], + "elite": [ + 0, + 0, + 2 + ] + }, + "Steel Automaton": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 0, + 0, + 0 + ] + } + } + }, + { + "906 Rusted": { + "Flaming Bladespinner": { + "normal": [ + 1, + 1, + 2 + ], + "elite": [ + 0, + 0, + 0 + ] + }, + "Ruined Machine": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Steel Automaton": { + "normal": [ + 1, + 0, + 0 + ], + "elite": [ + 0, + 1, + 1 + ] + } + } + }, + { + "907 Unsettling": { + "Black Imp": { + "normal": [ + 1, + 2, + 0 + ], + "elite": [ + 0, + 0, + 2 + ] + }, + "Chaos Demon": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Ooze": { + "normal": [ + 0, + 1, + 1 + ], + "elite": [ + 1, + 1, + 1 + ] + } + } + }, + { + "908 Taloned": { + "Rending Drake": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Shrike Fiend": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "909 Segmented": { + "Burrowing Blade": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Spitting Drake": { + "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 1, + 2 + ] + } + } + }, + { + "910 Dirty": { + "Earth Demon": { + "normal": [ + 2, + 1, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + }, + "Forest Imp": { + "normal": [ + 1, + 2, + 2 + ], + "elite": [ + 0, + 0, + 0 + ] + }, + "Ooze": { + "normal": [ + 2, + 1, + 0 + ], + "elite": [ + 0, + 1, + 2 + ] + } + } + }, + { + "911 Grave": { + "Deep Terror": { + "normal": [ + 1, + 1, + 2 + ], + "elite": [ + 0, + 0, + 0 + ] + }, + "Ice Wraith": { + "normal": [ + 1, + 1, + 1 + ], + "elite": [ + 0, + 0, + 1 + ] + }, + "Night Demon": { + "normal": [ + 2, + 2, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + } + } + }, + { + "912 Luminous": { + "Lurker Wavethrower": { + "normal": [ + 1, + 1, + 0 + ], + "elite": [ + 1, + 1, + 3 + ] + }, + "Sun Demon": { + "normal": [ + 2, + 2, + 2 + ], + "elite": [ + 0, + 1, + 1 + ] + } + } + }, + { + "913 Scorching": { + "Flame Demon": { + "normal": [ + 1, + 1, + 2 + ], + "elite": [ + 0, + 1, + 0 + ] + }, + "Flaming Bladespinner": { + "normal": [ + 2, + 2, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }, + { + "914 Swift": { + "Algox Scout": { + "normal": [ + 0, + 1, + 0 + ], + "elite": [ + 1, + 1, + 2 + ] + }, + "Wind Demon": { + "normal": [ + 2, + 3, + 2 + ], + "elite": [ + 0, + 0, + 1 + ] + } + } + }