From bc0d0ec1a0122b34b04aec3248178577d35ccbea Mon Sep 17 00:00:00 2001 From: Davis Ford Date: Tue, 28 Jun 2022 08:48:50 -0600 Subject: [PATCH 1/5] Add Gallet to realms, add basic rules --- src/generic_rules/realmscapes.ts | 51 ++++++++++++++++++++++++++++++-- src/meta/rule_sources.ts | 4 +++ src/types/realmscapes.ts | 12 +++----- 3 files changed, 57 insertions(+), 10 deletions(-) diff --git a/src/generic_rules/realmscapes.ts b/src/generic_rules/realmscapes.ts index 23b8063ad..d5479f37d 100644 --- a/src/generic_rules/realmscapes.ts +++ b/src/generic_rules/realmscapes.ts @@ -1,7 +1,16 @@ import meta_rule_sources from 'meta/rule_sources' import { TEntry } from 'types/data' -import { END_OF_ROUND, HERO_PHASE, START_OF_COMBAT_PHASE, TURN_THREE_START_OF_ROUND } from 'types/phases' -import { GHUR } from 'types/realmscapes' +import { + COMBAT_PHASE, + DURING_GAME, + END_OF_CHARGE_PHASE, + END_OF_ROUND, + HERO_PHASE, + START_OF_COMBAT_PHASE, + START_OF_ROUND, + TURN_THREE_START_OF_ROUND, +} from 'types/phases' +import { GALLET, GHUR } from 'types/realmscapes' // Realmscapes and their various effects/spells etc. const Realmscapes: TEntry[] = [ @@ -36,6 +45,44 @@ const Realmscapes: TEntry[] = [ }, ], }, + + { + name: GALLET, + effects: [ + { + name: `Masters of the Splintered Land`, + desc: `Friendly Battleline units that have a Wounds characteristic of 4 or less and do not have mounts gain the GALLETIAN VETERANS keyword.`, + when: [DURING_GAME], + rule_sources: [meta_rule_sources.GHB_2022], + }, + { + name: `Proving Grounds`, + desc: `At the start of each battle round, after the players have determined who will take the first turn, the player who will take the second turn can pick 1 objective on the battlefield to be the proving ground until the end of that battle round. The same objective cannot be picked as the proving ground more than once per battle, and only 1 objective can be marked as the proving ground at any one time. Only models in units with the GALLETIAN VETERANS keyword can contest an objective marked as the proving ground.`, + when: [START_OF_ROUND], + rule_sources: [meta_rule_sources.GHB_2022], + }, + { + name: `The Bonds of Battle`, + desc: `When a model in a GALLETIAN VETERANS unit makes an attack with a melee weapon, you can target an enemy unit within 1/2" of another model from that GALLETIAN VETERANS unit instead of using the weapon's Range characteristic for that attack. If you do so, the attacking model must be within 1/2" of another model from its own unit that is within 1/2" of the target.`, + when: [COMBAT_PHASE], + rule_sources: [meta_rule_sources.GHB_2022], + }, + { + name: `Gaze of Ghur`, + desc: `Casting value of 7 and a range of 12". Pick 1 enemy unit within range and visible to the caster. When determining the number of models in that enemy unit that are contesting an objective, your opponent must halve that number, rounding down. All WIZARDS know the Gaze of Ghur in addition to any others that they know.`, + when: [HERO_PHASE], + rule_sources: [meta_rule_sources.GHB_2022], + spell: true, + }, + { + name: `Overwhelming Assault`, + desc: `You can use this command ability at the end of your charge phase. The unit that receives the command must be a GALLETIAN VETERANS that has 10 or more models. Pick 1 enemy unit within 1" of that unit that has a Wounds characteristic of 4 or less and roll a dice. If the roll is greater than the number of models in that enemy unit, the strike-last effect applies to that enemy unit in the following combat phase.`, + when: [END_OF_CHARGE_PHASE], + rule_sources: [meta_rule_sources.GHB_2022], + command_ability: true, + }, + ], + }, ] export default Realmscapes diff --git a/src/meta/rule_sources.ts b/src/meta/rule_sources.ts index a8430967e..a96cba0ce 100644 --- a/src/meta/rule_sources.ts +++ b/src/meta/rule_sources.ts @@ -98,6 +98,10 @@ const meta_rule_sources = { name: "General's Handbook (2021)", type: 'ghb', }, + GHB_2022: { + name: "General's Handbook (2022)", + type: 'ghb', + }, ERRATA_GHB_SEPTEMBER_2021: { name: "General's Handbook Errata (September 2021)", type: 'ghb', diff --git a/src/types/realmscapes.ts b/src/types/realmscapes.ts index a1034ec86..6a8dc1ff3 100644 --- a/src/types/realmscapes.ts +++ b/src/types/realmscapes.ts @@ -5,6 +5,7 @@ // type TDolorum = `Dolorum` // type TEightpoints = `Eightpoints` // type TGenesisGate = `Genesis Gate` +type TGallet = `Gallet` type TGhur = `Ghur` // type TGhyran = `Ghyran` // type THelleflux = `Helleflux` @@ -19,14 +20,7 @@ type TGhur = `Ghur` // type TVaranthax = `Varanthax's Maw` // type TYmetrica = `Ymetrica` -export type TOriginRealms = - // | TAqshy - // | TChamon - TGhur -// | TGhyran -// | THysh -// | TShyish -// | TUlgu +export type TOriginRealms = TGallet | TGhur export type TBattleRealms = TOriginRealms // | TStygxx @@ -50,6 +44,7 @@ export type TBattleRealms = TOriginRealms // export const DOLORUM: TDolorum = `Dolorum` // export const EIGHTPOINTS: TEightpoints = `Eightpoints` // export const GENESISGATE: TGenesisGate = `Genesis Gate` +export const GALLET: TGallet = `Gallet` export const GHUR: TGhur = `Ghur` // export const GHYRAN: TGhyran = `Ghyran` // export const HELLEFlUX: THelleflux = `Helleflux` @@ -72,6 +67,7 @@ export const SUPPORTED_BATTLE_REALMS: TBattleRealms[] = [ // DOLORUM, // EIGHTPOINTS, // GENESISGATE, + GALLET, GHUR, // GHYRAN, // HELLEFlUX, From 4bc9279601dcdb8ea303208be243145a48b37a1a Mon Sep 17 00:00:00 2001 From: Davis Ford Date: Tue, 28 Jun 2022 08:51:06 -0600 Subject: [PATCH 2/5] Update core_battalions.ts --- src/generic_rules/core_battalions.ts | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/generic_rules/core_battalions.ts b/src/generic_rules/core_battalions.ts index d0a99f82e..b39edb0b9 100644 --- a/src/generic_rules/core_battalions.ts +++ b/src/generic_rules/core_battalions.ts @@ -3,6 +3,7 @@ import { TEntry } from 'types/data' import { CHARGE_PHASE, COMBAT_PHASE, + DURING_GAME, END_OF_CHARGE_PHASE, END_OF_SETUP, MOVEMENT_PHASE, @@ -82,6 +83,8 @@ const CoreBattalions: TEntry[] = [ name: 'Command Entourage - Strategists', effects: [StrategistsBattalionEffect], }, + + // GHB 2021 Battalions { name: 'Alpha-Beast Pack', effects: [ @@ -104,6 +107,30 @@ const CoreBattalions: TEntry[] = [ }, ], }, + + // GHB 2022 Battalions + { + name: 'Expert Conquerors', + effects: [ + { + name: `Dominant Force`, + desc: `GALLETIAN VETERANS units only. Each model in this battalion counts as 3 models for the purposes of contesting objectives.`, + when: [DURING_GAME], + rule_sources: [meta_rule_sources.GHB_2022], + }, + ], + }, + { + name: 'Bounty Hunters', + effects: [ + { + name: `Headhunters`, + desc: `If the target of an attack made with a melee weapon by a model in this battalion is a GALLETIAN VETERANS unit, add 1 to the Damage characteristic of that weapon for that attack.`, + when: [COMBAT_PHASE], + rule_sources: [meta_rule_sources.GHB_2022], + }, + ], + }, ] export default CoreBattalions From 4cf0b4878b7a91150ba2b838f856a46dc825ff1b Mon Sep 17 00:00:00 2001 From: Davis Ford Date: Tue, 28 Jun 2022 08:55:44 -0600 Subject: [PATCH 3/5] Update grand_strategies.ts --- src/generic_rules/grand_strategies.ts | 68 +++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/generic_rules/grand_strategies.ts b/src/generic_rules/grand_strategies.ts index a70b86809..357c125e8 100644 --- a/src/generic_rules/grand_strategies.ts +++ b/src/generic_rules/grand_strategies.ts @@ -92,6 +92,74 @@ const GenericGrandStrategies: TEntry[] = [ }, ], }, + + // GHB 2022 Grand Strategies + { + name: `No Place for the Weak`, + effects: [ + { + name: `No Place for the Weak`, + desc: `When the battle ends, you complete this grand strategy if there are no Battleline units from your opponent's starting army on the battlefield.`, + when: [END_OF_GAME], + rule_sources: [meta_rule_sources.GHB_2022], + }, + ], + }, + { + name: `Tame the Land`, + effects: [ + { + name: `Tame the Land`, + desc: `When the battle ends, you complete this grand strategy if you control all of the objectives on the battlefield that are wholly outside your territory.`, + when: [END_OF_GAME], + rule_sources: [meta_rule_sources.GHB_2022], + }, + ], + }, + { + name: `Defend What's Ours`, + effects: [ + { + name: `Defend What's Ours`, + desc: `When the battle ends, you complete this grand strategy if there are no enemy units wholly within your territory.`, + when: [END_OF_GAME], + rule_sources: [meta_rule_sources.GHB_2022], + }, + ], + }, + { + name: `Take What's Theirs`, + effects: [ + { + name: `Take What's Theirs`, + desc: `When the battle ends, you complete this grand strategy if there are more friendly units than enemy units wholly within your opponent's territory.`, + when: [END_OF_GAME], + rule_sources: [meta_rule_sources.GHB_2022], + }, + ], + }, + { + name: `Demonstration of Strength`, + effects: [ + { + name: `Demonstration of Strength`, + desc: `When the battle ends, you complete this grand strategy if there are 3 or more GALLETIAN VETERANS units from your starting army on the battlefield.`, + when: [END_OF_GAME], + rule_sources: [meta_rule_sources.GHB_2022], + }, + ], + }, + { + name: `Show of Dominance`, + effects: [ + { + name: `Show of Dominance`, + desc: `When the battle ends, you complete this grand strategy if there are any friendly GALLETIAN VETERANS units in each quarter of the battlefield.`, + when: [END_OF_GAME], + rule_sources: [meta_rule_sources.GHB_2022], + }, + ], + }, ] export default GenericGrandStrategies From f11c7d7778b157d4353393ecba70ccda54adf7ab Mon Sep 17 00:00:00 2001 From: Davis Ford Date: Tue, 28 Jun 2022 09:05:06 -0600 Subject: [PATCH 4/5] Remove Ghur --- src/components/info/banners/app_banner.tsx | 4 +- src/components/routes/Home.tsx | 6 +- src/generic_rules/core_rules.ts | 113 +++++++++---- src/generic_rules/grand_strategies.ts | 178 ++++++++++----------- src/generic_rules/realmscapes.ts | 77 ++++----- src/types/realmscapes.ts | 21 +-- 6 files changed, 214 insertions(+), 185 deletions(-) diff --git a/src/components/info/banners/app_banner.tsx b/src/components/info/banners/app_banner.tsx index dff057c73..c90ea5654 100644 --- a/src/components/info/banners/app_banner.tsx +++ b/src/components/info/banners/app_banner.tsx @@ -3,7 +3,7 @@ import { useTheme } from 'context/useTheme' const AppBanner = () => { const { isDark } = useTheme() - const name = 'aos-3-idoneth-deepkin-fyreslayers-battletome-release' + const name = 'aos-3-ghb-2022-release' return ( { variant={isDark ? `info` : `info`} > - NEW: The newly-released Idoneth Deepkin and Fyreslayers battletomes have been added! + NEW: General's Handbook (2022) has been added. Sylvaneth and Skaven are coming soon! ) diff --git a/src/components/routes/Home.tsx b/src/components/routes/Home.tsx index 4e2643980..3cf6c691f 100644 --- a/src/components/routes/Home.tsx +++ b/src/components/routes/Home.tsx @@ -7,7 +7,7 @@ import { lazy, Suspense, useEffect } from 'react' import { logPageView } from 'utils/analytics' const AlliedArmies = lazy(() => import('components/input/ally_armies')) -// const AppBanner = lazy(() => import('components/info/banners/app_banner')) +const AppBanner = lazy(() => import('components/info/banners/app_banner')) const ArmyBuilder = lazy(() => import('components/input/army_builder')) const FooterComponent = lazy(() => import('components/page/footer')) const LoadedArmyHeader = lazy(() => import('components/input/savedArmies/loaded_army_header')) @@ -34,9 +34,9 @@ const Home = () => {
- {/* }> + }> - */} + }> diff --git a/src/generic_rules/core_rules.ts b/src/generic_rules/core_rules.ts index c43b55b55..04be1e4f3 100644 --- a/src/generic_rules/core_rules.ts +++ b/src/generic_rules/core_rules.ts @@ -370,59 +370,110 @@ const CoreRules: TEntry[] = [ { name: 'Battle Tactics', effects: [ - { - name: `Battle Tactics`, - desc: `At the start of your hero phase, you must pick 1 battle tactic. You must reveal your choice to your opponent, and if your battle tactics instructs you to pick something, you must tell your opponent what you pick. You have until the end of that turn to complete the battle tactic. You cannot pick the same battle tactic more than once per battle.`, - when: [START_OF_HERO_PHASE], - rule_sources: [meta_rule_sources.GHB_2021], - }, - { - name: `Broken Ranks`, - desc: `When you reveal this battle tactic, pick 1 Battleline unit from your opponent's starting army on the battlefield. You complete this battle tactic if that unit is destroyed during this turn. If that unit was destroyed by an attack made by a friendly MONSTER or an ability of a friendly MONSTER, score 1 additional victory point.`, + // TODO: These should be enabled when GHUR is selected + // { + // name: `Battle Tactics`, + // desc: `At the start of your hero phase, you must pick 1 battle tactic. You must reveal your choice to your opponent, and if your battle tactics instructs you to pick something, you must tell your opponent what you pick. You have until the end of that turn to complete the battle tactic. You cannot pick the same battle tactic more than once per battle.`, + // when: [START_OF_HERO_PHASE], + // rule_sources: [meta_rule_sources.GHB_2021], + // }, + // { + // name: `Broken Ranks`, + // desc: `When you reveal this battle tactic, pick 1 Battleline unit from your opponent's starting army on the battlefield. You complete this battle tactic if that unit is destroyed during this turn. If that unit was destroyed by an attack made by a friendly MONSTER or an ability of a friendly MONSTER, score 1 additional victory point.`, + // when: [START_OF_HERO_PHASE], + // rule_sources: [meta_rule_sources.GHB_2021], + // }, + // { + // name: `Conquer`, + // desc: `When you reveal this battle tactic, pick 1 objective marker on the battlefield that your opponent controls. You complete this battle tactic if you control that objective marker at the end of this turn.`, + // when: [START_OF_HERO_PHASE], + // rule_sources: [meta_rule_sources.GHB_2021], + // }, + // { + // name: `Slay the Warlord`, + // desc: `You complete this battle tactic if the model chosen to be your opponent's general is slain during this turn. If that model was destroyed by an attack made by a friendly MONSTER or an ability of a friendly MONSTER, score 1 additional victory point.`, + // when: [START_OF_HERO_PHASE], + // rule_sources: [meta_rule_sources.GHB_2021], + // }, + // { + // name: `Ferocious Advance`, + // desc: `When you reveal this battle tactic, pick 3 different units from your starting army on the battlefield. You complete this battle tactic if all of the units your picked run in the following movement phase and finish that run within 3" of each other. If all 3 of those units are MONSTERS, score 1 additional victory point.`, + // when: [START_OF_HERO_PHASE], + // rule_sources: [meta_rule_sources.GHB_2021], + // }, + // { + // name: `Bring It Down!`, + // desc: `When you reveal this battle tactic, pick 1 enemy MONSTER on the battlefield. You complete this battle tactic if that unit is destroyed during this turn. If that enemy MONSTER was destroyed by an attack made by a friendly MONSTER or an ability of a friendly MONSTER, score 1 additional victory point.`, + // when: [START_OF_HERO_PHASE], + // rule_sources: [meta_rule_sources.GHB_2021], + // }, + // { + // name: `Aggressive Expansion`, + // desc: `When you reveal this battle tactic, pick 2 objective markers on the battlefield that are not wholly within your territory. You complete this battle tactic if you control both objective markers at the end of this turn.`, + // when: [START_OF_HERO_PHASE], + // rule_sources: [meta_rule_sources.GHB_2021], + // }, + // { + // name: `Monstrous Takeover`, + // desc: `When you reveal this battle tactic, pick 1 MONSTER from your starting army on the battlefield. You complete this battle tactic if that MONSTER is contesting an objective marker that you control at the end of this turn, and that objective marker is not contested by an enemy MONSTER.`, + // when: [START_OF_HERO_PHASE], + // rule_sources: [meta_rule_sources.GHB_2021], + // }, + // { + // name: `Savage Spearhead`, + // desc: `You complete this battle tactic if there are 2 or more units from your starting army wholly within your opponent's territory at the end of this turn. If 2 or more of those units are MONSTERS, score 1 additional victory point.`, + // when: [START_OF_HERO_PHASE], + // rule_sources: [meta_rule_sources.GHB_2021], + // }, + + // TODO: These should only be enabled when Gallet is selected + { + name: `Gaining Momentum`, + desc: `Pick 1 enemy unit on the battlefield. You complete this battle tactic if that unit is destroyed during this turn and you control more objectives than your opponent at the end of this turn.`, when: [START_OF_HERO_PHASE], - rule_sources: [meta_rule_sources.GHB_2021], + rule_sources: [meta_rule_sources.GHB_2022], }, { - name: `Conquer`, - desc: `When you reveal this battle tactic, pick 1 objective marker on the battlefield that your opponent controls. You complete this battle tactic if you control that objective marker at the end of this turn.`, + name: `An Eye for an Eye`, + desc: `You complete this battle tactic if 1 or more friendly units were destroyed in the previous turn and 1 or more enemy units are destroyed during this turn.`, when: [START_OF_HERO_PHASE], - rule_sources: [meta_rule_sources.GHB_2021], + rule_sources: [meta_rule_sources.GHB_2022], }, { - name: `Slay the Warlord`, - desc: `You complete this battle tactic if the model chosen to be your opponent's general is slain during this turn. If that model was destroyed by an attack made by a friendly MONSTER or an ability of a friendly MONSTER, score 1 additional victory point.`, + name: `Desecrate their Lands`, + desc: `Pick 1 terrain feature or faction terrain feature that is partially or wholly within your opponent's territory. You complete this battle tactic if you control that terrain feature at the end of this turn.`, when: [START_OF_HERO_PHASE], - rule_sources: [meta_rule_sources.GHB_2021], + rule_sources: [meta_rule_sources.GHB_2022], }, { - name: `Ferocious Advance`, - desc: `When you reveal this battle tactic, pick 3 different units from your starting army on the battlefield. You complete this battle tactic if all of the units your picked run in the following movement phase and finish that run within 3" of each other. If all 3 of those units are MONSTERS, score 1 additional victory point.`, + name: `This One's Mine!`, + desc: `Pick 1 enemy unit on the battlefield. You complete this battle tactic if that unit is destroyed during this turn by an attack made by the model picked to be your general.`, when: [START_OF_HERO_PHASE], - rule_sources: [meta_rule_sources.GHB_2021], + rule_sources: [meta_rule_sources.GHB_2022], }, { - name: `Bring It Down!`, - desc: `When you reveal this battle tactic, pick 1 enemy MONSTER on the battlefield. You complete this battle tactic if that unit is destroyed during this turn. If that enemy MONSTER was destroyed by an attack made by a friendly MONSTER or an ability of a friendly MONSTER, score 1 additional victory point.`, + name: `Head-to-Head`, + desc: `Pick 1 enemy GALLETIAN VETERANS unit on the battlefield. You complete this battle tactic if that unit is destroyed during this turn by an attack made by a friendly GALLETIAN VETERANS unit or an ability of a friendly GALLETIAN VETERANS unit.`, when: [START_OF_HERO_PHASE], - rule_sources: [meta_rule_sources.GHB_2021], + rule_sources: [meta_rule_sources.GHB_2022], }, { - name: `Aggressive Expansion`, - desc: `When you reveal this battle tactic, pick 2 objective markers on the battlefield that are not wholly within your territory. You complete this battle tactic if you control both objective markers at the end of this turn.`, + name: `Outmuscle`, + desc: `Pick 1 enemy GALLETIAN VETERANS unit that has any models contesting an objective marked as the proving ground (pg 12). You complete this battle tactic if no models from that enemy unit are contesting the proving ground at the end of this turn.`, when: [START_OF_HERO_PHASE], - rule_sources: [meta_rule_sources.GHB_2021], + rule_sources: [meta_rule_sources.GHB_2022], }, { - name: `Monstrous Takeover`, - desc: `When you reveal this battle tactic, pick 1 MONSTER from your starting army on the battlefield. You complete this battle tactic if that MONSTER is contesting an objective marker that you control at the end of this turn, and that objective marker is not contested by an enemy MONSTER.`, + name: `Against the Odds`, + desc: `Pick 1 unit from your starting army on the battlefield. You complete this battle tactic if, at the end of this turn, any models from that unit are contesting an objective you control and that objective is not being contested by any enemy GALLETIAN VETERANS models.`, when: [START_OF_HERO_PHASE], - rule_sources: [meta_rule_sources.GHB_2021], + rule_sources: [meta_rule_sources.GHB_2022], }, { - name: `Savage Spearhead`, - desc: `You complete this battle tactic if there are 2 or more units from your starting army wholly within your opponent's territory at the end of this turn. If 2 or more of those units are MONSTERS, score 1 additional victory point.`, + name: `Barge Through Enemy Lines`, + desc: `You complete this battle tactic if there are 2 or more units from your starting army wholly within your opponent's territory at the end of this turn. If 2 or more of those units are GALLETIAN VETERANS units, score 1 additional victory point.`, when: [START_OF_HERO_PHASE], - rule_sources: [meta_rule_sources.GHB_2021], + rule_sources: [meta_rule_sources.GHB_2022], }, ], }, diff --git a/src/generic_rules/grand_strategies.ts b/src/generic_rules/grand_strategies.ts index 357c125e8..72d8060d8 100644 --- a/src/generic_rules/grand_strategies.ts +++ b/src/generic_rules/grand_strategies.ts @@ -2,96 +2,96 @@ import meta_rule_sources from 'meta/rule_sources' import { TEntry } from 'types/data' import { END_OF_GAME } from 'types/phases' -// General grand strategies available from GHB 2021 +// General grand strategies const GenericGrandStrategies: TEntry[] = [ - { - name: `Sever the Head`, - effects: [ - { - name: `Sever the Head`, - desc: `When the battle ends, you complete this grand strategy if there are no HEROES from your opponent's starting army on the battlefield.`, - when: [END_OF_GAME], - rule_sources: [meta_rule_sources.GHB_2021], - }, - ], - }, - { - name: `Hold the Line`, - effects: [ - { - name: `Hold the Line`, - desc: `When the battle ends, you complete this grand strategy if there are any Battleline units from your starting army on the battlefield.`, - when: [END_OF_GAME], - rule_sources: [meta_rule_sources.GHB_2021], - }, - ], - }, - { - name: `Vendetta`, - effects: [ - { - name: `Vendetta`, - desc: `When the battle ends, you complete this grand strategy if the model chosen to be your opponent's general has been slain and the model chosen to be your general has not been slain.`, - when: [END_OF_GAME], - rule_sources: [meta_rule_sources.GHB_2021], - }, - ], - }, - { - name: `Dominating Presence`, - effects: [ - { - name: `Dominating Presence`, - desc: `When the battle ends, you complete this grand strategy if there are more units from your starting army on the battlefield than there are units from your opponent's starting army on the battlefield.`, - when: [END_OF_GAME], - rule_sources: [meta_rule_sources.GHB_2021], - }, - ], - }, - { - name: `Beast Master`, - effects: [ - { - name: `Beast Master`, - desc: `When the battle ends, you complete this grand strategy if there are any MONSTERS from your starting army on the battlefield.`, - when: [END_OF_GAME], - rule_sources: [meta_rule_sources.GHB_2021], - }, - ], - }, - { - name: `Prized Sorcery`, - effects: [ - { - name: `Prized Sorcery`, - desc: `When the battle ends, you complete this grand strategy if there are any WIZARDS from your starting army on the battlefield.`, - when: [END_OF_GAME], - rule_sources: [meta_rule_sources.GHB_2021], - }, - ], - }, - { - name: `Pillars of Belief`, - effects: [ - { - name: `Pillars of Belief`, - desc: `When the battle ends, you complete this grand strategy if there are any PRIESTS from your starting army on the battlefield.`, - when: [END_OF_GAME], - rule_sources: [meta_rule_sources.GHB_2021], - }, - ], - }, - { - name: `Predator's Domain`, - effects: [ - { - name: `Predator's Domain`, - desc: `When the battle ends, you complete this grand strategy if you control more terrain features than your opponent.`, - when: [END_OF_GAME], - rule_sources: [meta_rule_sources.GHB_2021], - }, - ], - }, + // { + // name: `Sever the Head`, + // effects: [ + // { + // name: `Sever the Head`, + // desc: `When the battle ends, you complete this grand strategy if there are no HEROES from your opponent's starting army on the battlefield.`, + // when: [END_OF_GAME], + // rule_sources: [meta_rule_sources.GHB_2021], + // }, + // ], + // }, + // { + // name: `Hold the Line`, + // effects: [ + // { + // name: `Hold the Line`, + // desc: `When the battle ends, you complete this grand strategy if there are any Battleline units from your starting army on the battlefield.`, + // when: [END_OF_GAME], + // rule_sources: [meta_rule_sources.GHB_2021], + // }, + // ], + // }, + // { + // name: `Vendetta`, + // effects: [ + // { + // name: `Vendetta`, + // desc: `When the battle ends, you complete this grand strategy if the model chosen to be your opponent's general has been slain and the model chosen to be your general has not been slain.`, + // when: [END_OF_GAME], + // rule_sources: [meta_rule_sources.GHB_2021], + // }, + // ], + // }, + // { + // name: `Dominating Presence`, + // effects: [ + // { + // name: `Dominating Presence`, + // desc: `When the battle ends, you complete this grand strategy if there are more units from your starting army on the battlefield than there are units from your opponent's starting army on the battlefield.`, + // when: [END_OF_GAME], + // rule_sources: [meta_rule_sources.GHB_2021], + // }, + // ], + // }, + // { + // name: `Beast Master`, + // effects: [ + // { + // name: `Beast Master`, + // desc: `When the battle ends, you complete this grand strategy if there are any MONSTERS from your starting army on the battlefield.`, + // when: [END_OF_GAME], + // rule_sources: [meta_rule_sources.GHB_2021], + // }, + // ], + // }, + // { + // name: `Prized Sorcery`, + // effects: [ + // { + // name: `Prized Sorcery`, + // desc: `When the battle ends, you complete this grand strategy if there are any WIZARDS from your starting army on the battlefield.`, + // when: [END_OF_GAME], + // rule_sources: [meta_rule_sources.GHB_2021], + // }, + // ], + // }, + // { + // name: `Pillars of Belief`, + // effects: [ + // { + // name: `Pillars of Belief`, + // desc: `When the battle ends, you complete this grand strategy if there are any PRIESTS from your starting army on the battlefield.`, + // when: [END_OF_GAME], + // rule_sources: [meta_rule_sources.GHB_2021], + // }, + // ], + // }, + // { + // name: `Predator's Domain`, + // effects: [ + // { + // name: `Predator's Domain`, + // desc: `When the battle ends, you complete this grand strategy if you control more terrain features than your opponent.`, + // when: [END_OF_GAME], + // rule_sources: [meta_rule_sources.GHB_2021], + // }, + // ], + // }, // GHB 2022 Grand Strategies { diff --git a/src/generic_rules/realmscapes.ts b/src/generic_rules/realmscapes.ts index d5479f37d..2d19a0a69 100644 --- a/src/generic_rules/realmscapes.ts +++ b/src/generic_rules/realmscapes.ts @@ -1,50 +1,41 @@ import meta_rule_sources from 'meta/rule_sources' import { TEntry } from 'types/data' -import { - COMBAT_PHASE, - DURING_GAME, - END_OF_CHARGE_PHASE, - END_OF_ROUND, - HERO_PHASE, - START_OF_COMBAT_PHASE, - START_OF_ROUND, - TURN_THREE_START_OF_ROUND, -} from 'types/phases' -import { GALLET, GHUR } from 'types/realmscapes' +import { COMBAT_PHASE, DURING_GAME, END_OF_CHARGE_PHASE, HERO_PHASE, START_OF_ROUND } from 'types/phases' +import { GALLET } from 'types/realmscapes' // Realmscapes and their various effects/spells etc. const Realmscapes: TEntry[] = [ - { - name: GHUR, - effects: [ - { - name: `Predators and Prey`, - desc: `Once per battle round, you score 1 additional victory point if any enemy MONSTERS were slain in that battle round.`, - when: [END_OF_ROUND], - rule_sources: [meta_rule_sources.GHB_2021], - }, - { - name: `Seismic Shift`, - desc: `At the start of the third battle round, after the players roll off to determine who has the first turn, the player taking the second turn in that battle round can pick 1 objective marker on the battlefield and remove it from play.`, - when: [TURN_THREE_START_OF_ROUND], - rule_sources: [meta_rule_sources.GHB_2021], - }, - { - name: `Feral Roar`, - desc: `You can use this command ability at the start of the combat phase. The unit that receives that command must be a MONSTER. Until the end of that phase, when you look up a value on that unit's damage table, it is treated as if it has suffered 0 wounds.`, - when: [START_OF_COMBAT_PHASE], - rule_sources: [meta_rule_sources.GHB_2021], - command_ability: true, - }, - { - name: `Metamorphosis`, - desc: `Casting value of 5 and range of 12". Pick 1 friendly HERO that is not a MONSTER and that is within range and visible to the caster. That HERO gains the MONSTER keyword until your next hero phase.`, - when: [HERO_PHASE], - rule_sources: [meta_rule_sources.GHB_2021], - spell: true, - }, - ], - }, + // { + // name: GHUR, + // effects: [ + // { + // name: `Predators and Prey`, + // desc: `Once per battle round, you score 1 additional victory point if any enemy MONSTERS were slain in that battle round.`, + // when: [END_OF_ROUND], + // rule_sources: [meta_rule_sources.GHB_2021], + // }, + // { + // name: `Seismic Shift`, + // desc: `At the start of the third battle round, after the players roll off to determine who has the first turn, the player taking the second turn in that battle round can pick 1 objective marker on the battlefield and remove it from play.`, + // when: [TURN_THREE_START_OF_ROUND], + // rule_sources: [meta_rule_sources.GHB_2021], + // }, + // { + // name: `Feral Roar`, + // desc: `You can use this command ability at the start of the combat phase. The unit that receives that command must be a MONSTER. Until the end of that phase, when you look up a value on that unit's damage table, it is treated as if it has suffered 0 wounds.`, + // when: [START_OF_COMBAT_PHASE], + // rule_sources: [meta_rule_sources.GHB_2021], + // command_ability: true, + // }, + // { + // name: `Metamorphosis`, + // desc: `Casting value of 5 and range of 12". Pick 1 friendly HERO that is not a MONSTER and that is within range and visible to the caster. That HERO gains the MONSTER keyword until your next hero phase.`, + // when: [HERO_PHASE], + // rule_sources: [meta_rule_sources.GHB_2021], + // spell: true, + // }, + // ], + // }, { name: GALLET, @@ -72,7 +63,7 @@ const Realmscapes: TEntry[] = [ desc: `Casting value of 7 and a range of 12". Pick 1 enemy unit within range and visible to the caster. When determining the number of models in that enemy unit that are contesting an objective, your opponent must halve that number, rounding down. All WIZARDS know the Gaze of Ghur in addition to any others that they know.`, when: [HERO_PHASE], rule_sources: [meta_rule_sources.GHB_2022], - spell: true, + spell: true, // TODO: This doesn't appear in dropdowns }, { name: `Overwhelming Assault`, diff --git a/src/types/realmscapes.ts b/src/types/realmscapes.ts index 6a8dc1ff3..2ba7591c9 100644 --- a/src/types/realmscapes.ts +++ b/src/types/realmscapes.ts @@ -6,7 +6,7 @@ // type TEightpoints = `Eightpoints` // type TGenesisGate = `Genesis Gate` type TGallet = `Gallet` -type TGhur = `Ghur` +// type TGhur = `Ghur` // type TGhyran = `Ghyran` // type THelleflux = `Helleflux` // type THysh = `Hysh` @@ -20,22 +20,9 @@ type TGhur = `Ghur` // type TVaranthax = `Varanthax's Maw` // type TYmetrica = `Ymetrica` -export type TOriginRealms = TGallet | TGhur +export type TOriginRealms = TGallet export type TBattleRealms = TOriginRealms -// | TStygxx -// | TEightpoints -// | TUmbral -// | THelleflux -// | TCharrwind -// | TVaranthax -// | TInvidia -// | TPraetoris -// | TYmetrica -// | TGenesisGate -// | TDolorum -// | TProsperis -// | TCoastOfTusks // export const AQSHY: TAqshy = `Aqshy` // export const CHAMON: TChamon = `Chamon` @@ -45,7 +32,7 @@ export type TBattleRealms = TOriginRealms // export const EIGHTPOINTS: TEightpoints = `Eightpoints` // export const GENESISGATE: TGenesisGate = `Genesis Gate` export const GALLET: TGallet = `Gallet` -export const GHUR: TGhur = `Ghur` +// export const GHUR: TGhur = `Ghur` // export const GHYRAN: TGhyran = `Ghyran` // export const HELLEFlUX: THelleflux = `Helleflux` // export const INVIDA: TInvidia = `Invidia` @@ -68,7 +55,7 @@ export const SUPPORTED_BATTLE_REALMS: TBattleRealms[] = [ // EIGHTPOINTS, // GENESISGATE, GALLET, - GHUR, + // GHUR, // GHYRAN, // HELLEFlUX, // HYSH, From ab41d95e792d63e310dc7997890a619449f1cbc8 Mon Sep 17 00:00:00 2001 From: Davis Ford Date: Tue, 28 Jun 2022 09:37:35 -0600 Subject: [PATCH 5/5] Move battle tactics to realmscapes --- src/components/input/army_builder.tsx | 4 +- src/ducks/realmscape.ts | 10 +- src/generic_rules/core_rules.ts | 111 -- src/generic_rules/grand_strategies.ts | 176 +- src/generic_rules/realmscapes.ts | 190 +- .../html/1625911854492-Battlescribe.html | 1608 ----------------- src/tests/warscroll/warscrollJson.test.ts | 4 +- src/types/army.ts | 6 +- src/types/import.ts | 6 +- src/types/realmscapes.ts | 75 +- src/types/store.ts | 6 +- src/utils/azyr/getAzyrArmy.ts | 6 +- src/utils/battlescribe/getters.ts | 10 +- src/utils/battlescribe/parseHTML.ts | 10 +- src/utils/getArmy/getArmy.ts | 10 +- src/utils/hooks/useGetArmyBuilderCards.tsx | 4 +- src/utils/processReminders.ts | 4 +- 17 files changed, 289 insertions(+), 1951 deletions(-) delete mode 100644 src/tests/fixtures/battlescribe/html/1625911854492-Battlescribe.html diff --git a/src/components/input/army_builder.tsx b/src/components/input/army_builder.tsx index 116910502..92e6f0c02 100644 --- a/src/components/input/army_builder.tsx +++ b/src/components/input/army_builder.tsx @@ -2,7 +2,7 @@ import { CardMultiSelect, CardSingleSelect } from 'components/info/card' import { armyActions, selectors } from 'ducks' import { Fragment, useEffect, useMemo } from 'react' import { useDispatch, useSelector } from 'react-redux' -import { TOriginRealms } from 'types/realmscapes' +import { RealmscapesEnum } from 'types/realmscapes' import useGetArmy from 'utils/hooks/useGetArmy' import useGetArmyBuilderCards from 'utils/hooks/useGetArmyBuilderCards' import useWindowSize from 'utils/hooks/useWindowSize' @@ -48,7 +48,7 @@ const ArmyBuilder = () => { key={card.title} label={factionName} mobileTitle={card.mobileTitle || null} - setValue={withSelectOne(value => dispatch(card.setValue(value as TOriginRealms | null)))} + setValue={withSelectOne(value => dispatch(card.setValue(value as RealmscapesEnum | null)))} title={card.title} value={card.value} selectionCount={0} diff --git a/src/ducks/realmscape.ts b/src/ducks/realmscape.ts index a328f9ddf..022e2ff7b 100644 --- a/src/ducks/realmscape.ts +++ b/src/ducks/realmscape.ts @@ -1,9 +1,9 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit' import DefaultAppState from 'store/initialAppState' -import { SUPPORTED_BATTLE_REALMS, TBattleRealms, TOriginRealms } from 'types/realmscapes' +import { RealmscapesEnum, SUPPORTED_REALMSCAPES } from 'types/realmscapes' -const getRealmscapeFromFeature = (feature: string): TBattleRealms | null => { - return SUPPORTED_BATTLE_REALMS.find(realm => feature.includes(realm)) || null +const getRealmscapeFromFeature = (feature: string): RealmscapesEnum | null => { + return SUPPORTED_REALMSCAPES.find(realm => feature.includes(realm)) || null } const realmscape = createSlice({ @@ -12,11 +12,11 @@ const realmscape = createSlice({ reducers: { resetRealmscapeStore: () => DefaultAppState.realmscape, - setOriginRealm: (state, action: PayloadAction) => { + setOriginRealm: (state, action: PayloadAction) => { state.origin_realm = action.payload }, - setRealmscape: (state, action: PayloadAction) => { + setRealmscape: (state, action: PayloadAction) => { const realmscape = action.payload let realmscape_feature = state.realmscape_feature if (realmscape && realmscape_feature && !realmscape_feature.includes(realmscape)) { diff --git a/src/generic_rules/core_rules.ts b/src/generic_rules/core_rules.ts index 04be1e4f3..bfcfa7832 100644 --- a/src/generic_rules/core_rules.ts +++ b/src/generic_rules/core_rules.ts @@ -367,117 +367,6 @@ const CoreRules: TEntry[] = [ effects: [OneDropDeploymentEffect], }, - { - name: 'Battle Tactics', - effects: [ - // TODO: These should be enabled when GHUR is selected - // { - // name: `Battle Tactics`, - // desc: `At the start of your hero phase, you must pick 1 battle tactic. You must reveal your choice to your opponent, and if your battle tactics instructs you to pick something, you must tell your opponent what you pick. You have until the end of that turn to complete the battle tactic. You cannot pick the same battle tactic more than once per battle.`, - // when: [START_OF_HERO_PHASE], - // rule_sources: [meta_rule_sources.GHB_2021], - // }, - // { - // name: `Broken Ranks`, - // desc: `When you reveal this battle tactic, pick 1 Battleline unit from your opponent's starting army on the battlefield. You complete this battle tactic if that unit is destroyed during this turn. If that unit was destroyed by an attack made by a friendly MONSTER or an ability of a friendly MONSTER, score 1 additional victory point.`, - // when: [START_OF_HERO_PHASE], - // rule_sources: [meta_rule_sources.GHB_2021], - // }, - // { - // name: `Conquer`, - // desc: `When you reveal this battle tactic, pick 1 objective marker on the battlefield that your opponent controls. You complete this battle tactic if you control that objective marker at the end of this turn.`, - // when: [START_OF_HERO_PHASE], - // rule_sources: [meta_rule_sources.GHB_2021], - // }, - // { - // name: `Slay the Warlord`, - // desc: `You complete this battle tactic if the model chosen to be your opponent's general is slain during this turn. If that model was destroyed by an attack made by a friendly MONSTER or an ability of a friendly MONSTER, score 1 additional victory point.`, - // when: [START_OF_HERO_PHASE], - // rule_sources: [meta_rule_sources.GHB_2021], - // }, - // { - // name: `Ferocious Advance`, - // desc: `When you reveal this battle tactic, pick 3 different units from your starting army on the battlefield. You complete this battle tactic if all of the units your picked run in the following movement phase and finish that run within 3" of each other. If all 3 of those units are MONSTERS, score 1 additional victory point.`, - // when: [START_OF_HERO_PHASE], - // rule_sources: [meta_rule_sources.GHB_2021], - // }, - // { - // name: `Bring It Down!`, - // desc: `When you reveal this battle tactic, pick 1 enemy MONSTER on the battlefield. You complete this battle tactic if that unit is destroyed during this turn. If that enemy MONSTER was destroyed by an attack made by a friendly MONSTER or an ability of a friendly MONSTER, score 1 additional victory point.`, - // when: [START_OF_HERO_PHASE], - // rule_sources: [meta_rule_sources.GHB_2021], - // }, - // { - // name: `Aggressive Expansion`, - // desc: `When you reveal this battle tactic, pick 2 objective markers on the battlefield that are not wholly within your territory. You complete this battle tactic if you control both objective markers at the end of this turn.`, - // when: [START_OF_HERO_PHASE], - // rule_sources: [meta_rule_sources.GHB_2021], - // }, - // { - // name: `Monstrous Takeover`, - // desc: `When you reveal this battle tactic, pick 1 MONSTER from your starting army on the battlefield. You complete this battle tactic if that MONSTER is contesting an objective marker that you control at the end of this turn, and that objective marker is not contested by an enemy MONSTER.`, - // when: [START_OF_HERO_PHASE], - // rule_sources: [meta_rule_sources.GHB_2021], - // }, - // { - // name: `Savage Spearhead`, - // desc: `You complete this battle tactic if there are 2 or more units from your starting army wholly within your opponent's territory at the end of this turn. If 2 or more of those units are MONSTERS, score 1 additional victory point.`, - // when: [START_OF_HERO_PHASE], - // rule_sources: [meta_rule_sources.GHB_2021], - // }, - - // TODO: These should only be enabled when Gallet is selected - { - name: `Gaining Momentum`, - desc: `Pick 1 enemy unit on the battlefield. You complete this battle tactic if that unit is destroyed during this turn and you control more objectives than your opponent at the end of this turn.`, - when: [START_OF_HERO_PHASE], - rule_sources: [meta_rule_sources.GHB_2022], - }, - { - name: `An Eye for an Eye`, - desc: `You complete this battle tactic if 1 or more friendly units were destroyed in the previous turn and 1 or more enemy units are destroyed during this turn.`, - when: [START_OF_HERO_PHASE], - rule_sources: [meta_rule_sources.GHB_2022], - }, - { - name: `Desecrate their Lands`, - desc: `Pick 1 terrain feature or faction terrain feature that is partially or wholly within your opponent's territory. You complete this battle tactic if you control that terrain feature at the end of this turn.`, - when: [START_OF_HERO_PHASE], - rule_sources: [meta_rule_sources.GHB_2022], - }, - { - name: `This One's Mine!`, - desc: `Pick 1 enemy unit on the battlefield. You complete this battle tactic if that unit is destroyed during this turn by an attack made by the model picked to be your general.`, - when: [START_OF_HERO_PHASE], - rule_sources: [meta_rule_sources.GHB_2022], - }, - { - name: `Head-to-Head`, - desc: `Pick 1 enemy GALLETIAN VETERANS unit on the battlefield. You complete this battle tactic if that unit is destroyed during this turn by an attack made by a friendly GALLETIAN VETERANS unit or an ability of a friendly GALLETIAN VETERANS unit.`, - when: [START_OF_HERO_PHASE], - rule_sources: [meta_rule_sources.GHB_2022], - }, - { - name: `Outmuscle`, - desc: `Pick 1 enemy GALLETIAN VETERANS unit that has any models contesting an objective marked as the proving ground (pg 12). You complete this battle tactic if no models from that enemy unit are contesting the proving ground at the end of this turn.`, - when: [START_OF_HERO_PHASE], - rule_sources: [meta_rule_sources.GHB_2022], - }, - { - name: `Against the Odds`, - desc: `Pick 1 unit from your starting army on the battlefield. You complete this battle tactic if, at the end of this turn, any models from that unit are contesting an objective you control and that objective is not being contested by any enemy GALLETIAN VETERANS models.`, - when: [START_OF_HERO_PHASE], - rule_sources: [meta_rule_sources.GHB_2022], - }, - { - name: `Barge Through Enemy Lines`, - desc: `You complete this battle tactic if there are 2 or more units from your starting army wholly within your opponent's territory at the end of this turn. If 2 or more of those units are GALLETIAN VETERANS units, score 1 additional victory point.`, - when: [START_OF_HERO_PHASE], - rule_sources: [meta_rule_sources.GHB_2022], - }, - ], - }, - { name: 'Wandering Endless Spells', effects: [ diff --git a/src/generic_rules/grand_strategies.ts b/src/generic_rules/grand_strategies.ts index 72d8060d8..438a12508 100644 --- a/src/generic_rules/grand_strategies.ts +++ b/src/generic_rules/grand_strategies.ts @@ -4,94 +4,94 @@ import { END_OF_GAME } from 'types/phases' // General grand strategies const GenericGrandStrategies: TEntry[] = [ - // { - // name: `Sever the Head`, - // effects: [ - // { - // name: `Sever the Head`, - // desc: `When the battle ends, you complete this grand strategy if there are no HEROES from your opponent's starting army on the battlefield.`, - // when: [END_OF_GAME], - // rule_sources: [meta_rule_sources.GHB_2021], - // }, - // ], - // }, - // { - // name: `Hold the Line`, - // effects: [ - // { - // name: `Hold the Line`, - // desc: `When the battle ends, you complete this grand strategy if there are any Battleline units from your starting army on the battlefield.`, - // when: [END_OF_GAME], - // rule_sources: [meta_rule_sources.GHB_2021], - // }, - // ], - // }, - // { - // name: `Vendetta`, - // effects: [ - // { - // name: `Vendetta`, - // desc: `When the battle ends, you complete this grand strategy if the model chosen to be your opponent's general has been slain and the model chosen to be your general has not been slain.`, - // when: [END_OF_GAME], - // rule_sources: [meta_rule_sources.GHB_2021], - // }, - // ], - // }, - // { - // name: `Dominating Presence`, - // effects: [ - // { - // name: `Dominating Presence`, - // desc: `When the battle ends, you complete this grand strategy if there are more units from your starting army on the battlefield than there are units from your opponent's starting army on the battlefield.`, - // when: [END_OF_GAME], - // rule_sources: [meta_rule_sources.GHB_2021], - // }, - // ], - // }, - // { - // name: `Beast Master`, - // effects: [ - // { - // name: `Beast Master`, - // desc: `When the battle ends, you complete this grand strategy if there are any MONSTERS from your starting army on the battlefield.`, - // when: [END_OF_GAME], - // rule_sources: [meta_rule_sources.GHB_2021], - // }, - // ], - // }, - // { - // name: `Prized Sorcery`, - // effects: [ - // { - // name: `Prized Sorcery`, - // desc: `When the battle ends, you complete this grand strategy if there are any WIZARDS from your starting army on the battlefield.`, - // when: [END_OF_GAME], - // rule_sources: [meta_rule_sources.GHB_2021], - // }, - // ], - // }, - // { - // name: `Pillars of Belief`, - // effects: [ - // { - // name: `Pillars of Belief`, - // desc: `When the battle ends, you complete this grand strategy if there are any PRIESTS from your starting army on the battlefield.`, - // when: [END_OF_GAME], - // rule_sources: [meta_rule_sources.GHB_2021], - // }, - // ], - // }, - // { - // name: `Predator's Domain`, - // effects: [ - // { - // name: `Predator's Domain`, - // desc: `When the battle ends, you complete this grand strategy if you control more terrain features than your opponent.`, - // when: [END_OF_GAME], - // rule_sources: [meta_rule_sources.GHB_2021], - // }, - // ], - // }, + { + name: `Sever the Head`, + effects: [ + { + name: `Sever the Head`, + desc: `When the battle ends, you complete this grand strategy if there are no HEROES from your opponent's starting army on the battlefield.`, + when: [END_OF_GAME], + rule_sources: [meta_rule_sources.GHB_2021], + }, + ], + }, + { + name: `Hold the Line`, + effects: [ + { + name: `Hold the Line`, + desc: `When the battle ends, you complete this grand strategy if there are any Battleline units from your starting army on the battlefield.`, + when: [END_OF_GAME], + rule_sources: [meta_rule_sources.GHB_2021], + }, + ], + }, + { + name: `Vendetta`, + effects: [ + { + name: `Vendetta`, + desc: `When the battle ends, you complete this grand strategy if the model chosen to be your opponent's general has been slain and the model chosen to be your general has not been slain.`, + when: [END_OF_GAME], + rule_sources: [meta_rule_sources.GHB_2021], + }, + ], + }, + { + name: `Dominating Presence`, + effects: [ + { + name: `Dominating Presence`, + desc: `When the battle ends, you complete this grand strategy if there are more units from your starting army on the battlefield than there are units from your opponent's starting army on the battlefield.`, + when: [END_OF_GAME], + rule_sources: [meta_rule_sources.GHB_2021], + }, + ], + }, + { + name: `Beast Master`, + effects: [ + { + name: `Beast Master`, + desc: `When the battle ends, you complete this grand strategy if there are any MONSTERS from your starting army on the battlefield.`, + when: [END_OF_GAME], + rule_sources: [meta_rule_sources.GHB_2021], + }, + ], + }, + { + name: `Prized Sorcery`, + effects: [ + { + name: `Prized Sorcery`, + desc: `When the battle ends, you complete this grand strategy if there are any WIZARDS from your starting army on the battlefield.`, + when: [END_OF_GAME], + rule_sources: [meta_rule_sources.GHB_2021], + }, + ], + }, + { + name: `Pillars of Belief`, + effects: [ + { + name: `Pillars of Belief`, + desc: `When the battle ends, you complete this grand strategy if there are any PRIESTS from your starting army on the battlefield.`, + when: [END_OF_GAME], + rule_sources: [meta_rule_sources.GHB_2021], + }, + ], + }, + { + name: `Predator's Domain`, + effects: [ + { + name: `Predator's Domain`, + desc: `When the battle ends, you complete this grand strategy if you control more terrain features than your opponent.`, + when: [END_OF_GAME], + rule_sources: [meta_rule_sources.GHB_2021], + }, + ], + }, // GHB 2022 Grand Strategies { diff --git a/src/generic_rules/realmscapes.ts b/src/generic_rules/realmscapes.ts index 2d19a0a69..ce1500868 100644 --- a/src/generic_rules/realmscapes.ts +++ b/src/generic_rules/realmscapes.ts @@ -1,44 +1,110 @@ import meta_rule_sources from 'meta/rule_sources' import { TEntry } from 'types/data' -import { COMBAT_PHASE, DURING_GAME, END_OF_CHARGE_PHASE, HERO_PHASE, START_OF_ROUND } from 'types/phases' -import { GALLET } from 'types/realmscapes' +import { + COMBAT_PHASE, + DURING_GAME, + END_OF_CHARGE_PHASE, + END_OF_ROUND, + HERO_PHASE, + START_OF_COMBAT_PHASE, + START_OF_HERO_PHASE, + START_OF_ROUND, + TURN_THREE_START_OF_ROUND, +} from 'types/phases' +import { RealmscapesEnum } from 'types/realmscapes' // Realmscapes and their various effects/spells etc. const Realmscapes: TEntry[] = [ - // { - // name: GHUR, - // effects: [ - // { - // name: `Predators and Prey`, - // desc: `Once per battle round, you score 1 additional victory point if any enemy MONSTERS were slain in that battle round.`, - // when: [END_OF_ROUND], - // rule_sources: [meta_rule_sources.GHB_2021], - // }, - // { - // name: `Seismic Shift`, - // desc: `At the start of the third battle round, after the players roll off to determine who has the first turn, the player taking the second turn in that battle round can pick 1 objective marker on the battlefield and remove it from play.`, - // when: [TURN_THREE_START_OF_ROUND], - // rule_sources: [meta_rule_sources.GHB_2021], - // }, - // { - // name: `Feral Roar`, - // desc: `You can use this command ability at the start of the combat phase. The unit that receives that command must be a MONSTER. Until the end of that phase, when you look up a value on that unit's damage table, it is treated as if it has suffered 0 wounds.`, - // when: [START_OF_COMBAT_PHASE], - // rule_sources: [meta_rule_sources.GHB_2021], - // command_ability: true, - // }, - // { - // name: `Metamorphosis`, - // desc: `Casting value of 5 and range of 12". Pick 1 friendly HERO that is not a MONSTER and that is within range and visible to the caster. That HERO gains the MONSTER keyword until your next hero phase.`, - // when: [HERO_PHASE], - // rule_sources: [meta_rule_sources.GHB_2021], - // spell: true, - // }, - // ], - // }, + { + name: RealmscapesEnum.GHUR, + effects: [ + { + name: `Predators and Prey`, + desc: `Once per battle round, you score 1 additional victory point if any enemy MONSTERS were slain in that battle round.`, + when: [END_OF_ROUND], + rule_sources: [meta_rule_sources.GHB_2021], + }, + { + name: `Seismic Shift`, + desc: `At the start of the third battle round, after the players roll off to determine who has the first turn, the player taking the second turn in that battle round can pick 1 objective marker on the battlefield and remove it from play.`, + when: [TURN_THREE_START_OF_ROUND], + rule_sources: [meta_rule_sources.GHB_2021], + }, + { + name: `Feral Roar`, + desc: `You can use this command ability at the start of the combat phase. The unit that receives that command must be a MONSTER. Until the end of that phase, when you look up a value on that unit's damage table, it is treated as if it has suffered 0 wounds.`, + when: [START_OF_COMBAT_PHASE], + rule_sources: [meta_rule_sources.GHB_2021], + command_ability: true, + }, + { + name: `Metamorphosis`, + desc: `Casting value of 5 and range of 12". Pick 1 friendly HERO that is not a MONSTER and that is within range and visible to the caster. That HERO gains the MONSTER keyword until your next hero phase.`, + when: [HERO_PHASE], + rule_sources: [meta_rule_sources.GHB_2021], + spell: true, + }, + + // Battle Tactics + { + name: `Battle Tactics`, + desc: `At the start of your hero phase, you must pick 1 battle tactic. You must reveal your choice to your opponent, and if your battle tactics instructs you to pick something, you must tell your opponent what you pick. You have until the end of that turn to complete the battle tactic. You cannot pick the same battle tactic more than once per battle.`, + when: [START_OF_HERO_PHASE], + rule_sources: [meta_rule_sources.GHB_2021], + }, + { + name: `Battle Tactic: Broken Ranks`, + desc: `When you reveal this battle tactic, pick 1 Battleline unit from your opponent's starting army on the battlefield. You complete this battle tactic if that unit is destroyed during this turn. If that unit was destroyed by an attack made by a friendly MONSTER or an ability of a friendly MONSTER, score 1 additional victory point.`, + when: [START_OF_HERO_PHASE], + rule_sources: [meta_rule_sources.GHB_2021], + }, + { + name: `Battle Tactic: Conquer`, + desc: `When you reveal this battle tactic, pick 1 objective marker on the battlefield that your opponent controls. You complete this battle tactic if you control that objective marker at the end of this turn.`, + when: [START_OF_HERO_PHASE], + rule_sources: [meta_rule_sources.GHB_2021], + }, + { + name: `Battle Tactic: Slay the Warlord`, + desc: `You complete this battle tactic if the model chosen to be your opponent's general is slain during this turn. If that model was destroyed by an attack made by a friendly MONSTER or an ability of a friendly MONSTER, score 1 additional victory point.`, + when: [START_OF_HERO_PHASE], + rule_sources: [meta_rule_sources.GHB_2021], + }, + { + name: `Battle Tactic: Ferocious Advance`, + desc: `When you reveal this battle tactic, pick 3 different units from your starting army on the battlefield. You complete this battle tactic if all of the units your picked run in the following movement phase and finish that run within 3" of each other. If all 3 of those units are MONSTERS, score 1 additional victory point.`, + when: [START_OF_HERO_PHASE], + rule_sources: [meta_rule_sources.GHB_2021], + }, + { + name: `Battle Tactic: Bring It Down!`, + desc: `When you reveal this battle tactic, pick 1 enemy MONSTER on the battlefield. You complete this battle tactic if that unit is destroyed during this turn. If that enemy MONSTER was destroyed by an attack made by a friendly MONSTER or an ability of a friendly MONSTER, score 1 additional victory point.`, + when: [START_OF_HERO_PHASE], + rule_sources: [meta_rule_sources.GHB_2021], + }, + { + name: `Battle Tactic: Aggressive Expansion`, + desc: `When you reveal this battle tactic, pick 2 objective markers on the battlefield that are not wholly within your territory. You complete this battle tactic if you control both objective markers at the end of this turn.`, + when: [START_OF_HERO_PHASE], + rule_sources: [meta_rule_sources.GHB_2021], + }, + { + name: `Battle Tactic: Monstrous Takeover`, + desc: `When you reveal this battle tactic, pick 1 MONSTER from your starting army on the battlefield. You complete this battle tactic if that MONSTER is contesting an objective marker that you control at the end of this turn, and that objective marker is not contested by an enemy MONSTER.`, + when: [START_OF_HERO_PHASE], + rule_sources: [meta_rule_sources.GHB_2021], + }, + { + name: `Battle Tactic: Savage Spearhead`, + desc: `You complete this battle tactic if there are 2 or more units from your starting army wholly within your opponent's territory at the end of this turn. If 2 or more of those units are MONSTERS, score 1 additional victory point.`, + when: [START_OF_HERO_PHASE], + rule_sources: [meta_rule_sources.GHB_2021], + }, + ], + }, { - name: GALLET, + name: RealmscapesEnum.GALLET, effects: [ { name: `Masters of the Splintered Land`, @@ -72,6 +138,62 @@ const Realmscapes: TEntry[] = [ rule_sources: [meta_rule_sources.GHB_2022], command_ability: true, }, + + // Battle tactics + { + name: `Battle Tactics`, + desc: `At the start of your hero phase, you must pick 1 battle tactic. You must reveal your choice to your opponent, and if your battle tactics instructs you to pick something, you must tell your opponent what you pick. You have until the end of that turn to complete the battle tactic. You cannot pick the same battle tactic more than once per battle.`, + when: [START_OF_HERO_PHASE], + rule_sources: [meta_rule_sources.GHB_2022], + }, + { + name: `Battle Tactic: Gaining Momentum`, + desc: `Pick 1 enemy unit on the battlefield. You complete this battle tactic if that unit is destroyed during this turn and you control more objectives than your opponent at the end of this turn.`, + when: [START_OF_HERO_PHASE], + rule_sources: [meta_rule_sources.GHB_2022], + }, + { + name: `Battle Tactic: An Eye for an Eye`, + desc: `You complete this battle tactic if 1 or more friendly units were destroyed in the previous turn and 1 or more enemy units are destroyed during this turn.`, + when: [START_OF_HERO_PHASE], + rule_sources: [meta_rule_sources.GHB_2022], + }, + { + name: `Battle Tactic: Desecrate their Lands`, + desc: `Pick 1 terrain feature or faction terrain feature that is partially or wholly within your opponent's territory. You complete this battle tactic if you control that terrain feature at the end of this turn.`, + when: [START_OF_HERO_PHASE], + rule_sources: [meta_rule_sources.GHB_2022], + }, + { + name: `Battle Tactic: This One's Mine!`, + desc: `Pick 1 enemy unit on the battlefield. You complete this battle tactic if that unit is destroyed during this turn by an attack made by the model picked to be your general.`, + when: [START_OF_HERO_PHASE], + rule_sources: [meta_rule_sources.GHB_2022], + }, + { + name: `Battle Tactic: Head-to-Head`, + desc: `Pick 1 enemy GALLETIAN VETERANS unit on the battlefield. You complete this battle tactic if that unit is destroyed during this turn by an attack made by a friendly GALLETIAN VETERANS unit or an ability of a friendly GALLETIAN VETERANS unit.`, + when: [START_OF_HERO_PHASE], + rule_sources: [meta_rule_sources.GHB_2022], + }, + { + name: `Battle Tactic: Outmuscle`, + desc: `Pick 1 enemy GALLETIAN VETERANS unit that has any models contesting an objective marked as the proving ground (pg 12). You complete this battle tactic if no models from that enemy unit are contesting the proving ground at the end of this turn.`, + when: [START_OF_HERO_PHASE], + rule_sources: [meta_rule_sources.GHB_2022], + }, + { + name: `Battle Tactic: Against the Odds`, + desc: `Pick 1 unit from your starting army on the battlefield. You complete this battle tactic if, at the end of this turn, any models from that unit are contesting an objective you control and that objective is not being contested by any enemy GALLETIAN VETERANS models.`, + when: [START_OF_HERO_PHASE], + rule_sources: [meta_rule_sources.GHB_2022], + }, + { + name: `Battle Tactic: Barge Through Enemy Lines`, + desc: `You complete this battle tactic if there are 2 or more units from your starting army wholly within your opponent's territory at the end of this turn. If 2 or more of those units are GALLETIAN VETERANS units, score 1 additional victory point.`, + when: [START_OF_HERO_PHASE], + rule_sources: [meta_rule_sources.GHB_2022], + }, ], }, ] diff --git a/src/tests/fixtures/battlescribe/html/1625911854492-Battlescribe.html b/src/tests/fixtures/battlescribe/html/1625911854492-Battlescribe.html deleted file mode 100644 index 18aff94ca..000000000 --- a/src/tests/fixtures/battlescribe/html/1625911854492-Battlescribe.html +++ /dev/null @@ -1,1608 +0,0 @@ - - - - - - - -
-

New Nh 3.0 (Age of Sigmar) [2,000pts]

-
    -
  • -

    **Pitched Battle** 2,000 (Death - Nighthaunt) [2,000pts]

    -
      -
    • -

      Core Battalion

      -
        -
      • -

        Core Battalion: Battle Regiment

        -

        - Categories: Core Battalion -

        -

        - Battalion Abilities: Unified, Battalion Organisation: Core Battalion: Battle Regiment -

        -
        - - - - - - - - - -
        Battalion AbilitiesBattalion Ability Details
        UnifiedOne-drop Deployment (see 26.2.1).
        - - - - - - - - - -
        Battalion OrganisationRequired
        Core Battalion: Battle Regiment1 Commander
        - 0-2 Sub-commanders
        - 2-5 Troops
        - 0-1 Monster or Artillery
        - -
      • -
      -
    • -
    • -

      Leader [415pts]

      -
        -
      • -

        The Briar Queen [175pts]

        -

        - Selections: Briar Whip, Howling Vortex, Rending Scream -

        -

        - Categories: DEATH, MALIGNANT, NIGHTHAUNT, HERO, MIRRORGHAST BANSHEE, WIZARD, THORNS OF THE BRIAR QUEEN, Leader, 9 or less wounds Leader -

        -

        - Spell: Arcane Bolt, Howling Vortex, Mystic Shield, Unit: The Briar Queen, Unit Abilities: Ethereal, Fly, Weapon: Briar Whip, Rending Scream -

        -
        - - - - - - - - - - - - - - - - - -
        SpellCasting ValueRangeDescription
        Arcane Bolt512"If successfully cast, at the start of any 1 phase before your next hero phase, you can pick 1 enemy unit within range and visible to the caster. That unit suffers 1 mortal wound. If that unit is within 3" of the caster, it suffers D3 mortal wounds instead of 1.
        Howling Vortex718"If successfully cast, pick a point on the battlefield within 18" of the caster that is visible to them, and roll 2D6 for each enemy unit within 6" of that point. If the roll is greater than the value of that unit’s Move characteristic, or that roll is a double, that unit suffers 1 mortal wound and its Move characteristic is halved until the caster’s next hero phase.
        Mystic Shield512"If successfully cast, pick 1 friendly unit wholly within range and visible to the caster. Add 1 to save rolls for attacks that target that unit until your next hero phase.
        - - - - - - - - - -
        UnitMoveWoundsBraverySave
        The Briar Queen6"5104+
        - - - - - - - - - - - - - -
        Unit AbilitiesAbility Details
        EtherealIgnore modifiers (positive or negative) when making save rolls for this unit.
        FlyThis unit can fly.
        - - - - - - - - - - - - - -
        WeaponTypeRangeAttacksTo HitTo WoundRendDamage
        Briar WhipMelee3"13+3+-2D3
        Rending ScreamMissile10"33+3+-31
        - -
      • -
      • -

        Tomb Banshee [80pts]

        -

        - Selections: 6. Ruler of the Spirit Host, Battle Regiment - 1 Commander, Chill Dagger, General, Ghostly Howl -

        -

        - Categories: DEATH, MALIGNANT, NIGHTHAUNT, HERO, TOMB BANSHEE, Leader, 9 or less wounds Leader, General -

        -

        - Command Trait: Ruler of the Spirit Host, Unit: Tomb Banshee, Unit Abilities: Ethereal, Fly, Frightful Touch, Ghostly Howl, Weapon: Chill Dagger, Ghostly Howl -

        -
        - - - - - - - - - -
        Command TraitCommand Trait Details
        Ruler of the Spirit HostAt the start of your hero phase, you can pick a friendly SUMMONABLE NIGHTHAUNT unit within 9" of this general and return D3 slain models to that unit The returning models must be setup within 9" of this general.
        - - - - - - - - - -
        UnitMoveWoundsBraverySave
        Tomb Banshee6"4104+
        - - - - - - - - - - - - - - - - - - - - - -
        Unit AbilitiesAbility Details
        EtherealIgnore modifiers (positive or negative) when making save rolls for this unit.
        FlyThis unit can fly.
        Frightful TouchIf the unmodified roll for an attack made with the <Banshee Mandmaidens' Spectral Claws>, <Wraith Herald's Spectral Claws>, <Fellreaper>, <Reaper Scythe> <Chill Dagger> <Spectral Scythe> <Cairn Wraith's Reaper Scythe> <Spectral Claws and Daggers> <Spectral Host's Ethereal Weapons>, <Mourngul's Nightmarish Claws and Fangs> is 6, that attack inflicts <the weapon damage as a> mortal wound and the attack sequence ends (do not make a wound or save roll).
        Ghostly HowlAt the start of your shooting phase, pick an enemy unit within 10" of this model and roll 2D6. If the roll is higher than the unit's Bravery characteristic, it suffers a number of mortal wounds equal to the difference between its Bravery characteristic and the roll.
        - - - - - - - - - - - - - -
        WeaponTypeRangeAttacksTo HitTo WoundRendDamage
        Chill DaggerMelee1"14+3+-2D3
        Ghostly HowlMissile10"*****
        - -
      • -
      • -

        Tomb Banshee [80pts]

        -

        - Selections: Battle Regiment - 0-2 Sub-Commander, Chill Dagger, Ghostly Howl -

        -

        - Categories: DEATH, MALIGNANT, NIGHTHAUNT, HERO, TOMB BANSHEE, Leader, 9 or less wounds Leader -

        -

        - Unit: Tomb Banshee, Unit Abilities: Ethereal, Fly, Frightful Touch, Ghostly Howl, Weapon: Chill Dagger, Ghostly Howl -

        -
        - - - - - - - - - -
        UnitMoveWoundsBraverySave
        Tomb Banshee6"4104+
        - - - - - - - - - - - - - - - - - - - - - -
        Unit AbilitiesAbility Details
        EtherealIgnore modifiers (positive or negative) when making save rolls for this unit.
        FlyThis unit can fly.
        Frightful TouchIf the unmodified roll for an attack made with the <Banshee Mandmaidens' Spectral Claws>, <Wraith Herald's Spectral Claws>, <Fellreaper>, <Reaper Scythe> <Chill Dagger> <Spectral Scythe> <Cairn Wraith's Reaper Scythe> <Spectral Claws and Daggers> <Spectral Host's Ethereal Weapons>, <Mourngul's Nightmarish Claws and Fangs> is 6, that attack inflicts <the weapon damage as a> mortal wound and the attack sequence ends (do not make a wound or save roll).
        Ghostly HowlAt the start of your shooting phase, pick an enemy unit within 10" of this model and roll 2D6. If the roll is higher than the unit's Bravery characteristic, it suffers a number of mortal wounds equal to the difference between its Bravery characteristic and the roll.
        - - - - - - - - - - - - - -
        WeaponTypeRangeAttacksTo HitTo WoundRendDamage
        Chill DaggerMelee1"14+3+-2D3
        Ghostly HowlMissile10"*****
        - -
      • -
      • -

        Tomb Banshee [80pts]

        -

        - Selections: Battle Regiment - 0-2 Sub-Commander, Chill Dagger, Ghostly Howl -

        -

        - Categories: DEATH, MALIGNANT, NIGHTHAUNT, HERO, TOMB BANSHEE, Leader, 9 or less wounds Leader -

        -

        - Unit: Tomb Banshee, Unit Abilities: Ethereal, Fly, Frightful Touch, Ghostly Howl, Weapon: Chill Dagger, Ghostly Howl -

        -
        - - - - - - - - - -
        UnitMoveWoundsBraverySave
        Tomb Banshee6"4104+
        - - - - - - - - - - - - - - - - - - - - - -
        Unit AbilitiesAbility Details
        EtherealIgnore modifiers (positive or negative) when making save rolls for this unit.
        FlyThis unit can fly.
        Frightful TouchIf the unmodified roll for an attack made with the <Banshee Mandmaidens' Spectral Claws>, <Wraith Herald's Spectral Claws>, <Fellreaper>, <Reaper Scythe> <Chill Dagger> <Spectral Scythe> <Cairn Wraith's Reaper Scythe> <Spectral Claws and Daggers> <Spectral Host's Ethereal Weapons>, <Mourngul's Nightmarish Claws and Fangs> is 6, that attack inflicts <the weapon damage as a> mortal wound and the attack sequence ends (do not make a wound or save roll).
        Ghostly HowlAt the start of your shooting phase, pick an enemy unit within 10" of this model and roll 2D6. If the roll is higher than the unit's Bravery characteristic, it suffers a number of mortal wounds equal to the difference between its Bravery characteristic and the roll.
        - - - - - - - - - - - - - -
        WeaponTypeRangeAttacksTo HitTo WoundRendDamage
        Chill DaggerMelee1"14+3+-2D3
        Ghostly HowlMissile10"*****
        - -
      • -
      -
    • -
    • -

      Battleline [625pts]

      -
        -
      • -

        Chainrasp Horde [95pts]

        -

        - Selections: 10 Chainrasps [95pts], Malignant Weapon -

        -

        - Categories: DEATH, MALIGNANT, NIGHTHAUNT, SUMMONABLE, CHAINRASP HORDE, Battleline -

        -

        - Unit: Chainrasp, Unit Abilities: Chilling Horde, Dreadwarden, Ethereal, Fly, Weapon: Malignant Weapon -

        -
        - - - - - - - - - -
        UnitMoveWoundsBraverySave
        Chainrasp6"165+
        - - - - - - - - - - - - - - - - - - - - - -
        Unit AbilitiesAbility Details
        Chilling HordeRe-roll wound rolls of 1 for this unit while it has more than 10 models.
        DreadwardenThe leader of this unit is a Dreadwarden. Add 1 to the Attacks characteristic of a Dreadwarden's Malignant Weapon. In addition, a Chainrasp Horde has a Bravery characteristic of 10 instead of 6 while it includes a Dreadwarden.
        EtherealIgnore modifiers (positive or negative) when making save rolls for this unit.
        FlyThis unit can fly.
        - - - - - - - - - -
        WeaponTypeRangeAttacksTo HitTo WoundRendDamage
        Malignant WeaponMelee1"24+4+-1
        - -
      • -
      • -

        Chainrasp Horde [95pts]

        -

        - Selections: 10 Chainrasps [95pts], Malignant Weapon -

        -

        - Categories: DEATH, MALIGNANT, NIGHTHAUNT, SUMMONABLE, CHAINRASP HORDE, Battleline -

        -

        - Unit: Chainrasp, Unit Abilities: Chilling Horde, Dreadwarden, Ethereal, Fly, Weapon: Malignant Weapon -

        -
        - - - - - - - - - -
        UnitMoveWoundsBraverySave
        Chainrasp6"165+
        - - - - - - - - - - - - - - - - - - - - - -
        Unit AbilitiesAbility Details
        Chilling HordeRe-roll wound rolls of 1 for this unit while it has more than 10 models.
        DreadwardenThe leader of this unit is a Dreadwarden. Add 1 to the Attacks characteristic of a Dreadwarden's Malignant Weapon. In addition, a Chainrasp Horde has a Bravery characteristic of 10 instead of 6 while it includes a Dreadwarden.
        EtherealIgnore modifiers (positive or negative) when making save rolls for this unit.
        FlyThis unit can fly.
        - - - - - - - - - -
        WeaponTypeRangeAttacksTo HitTo WoundRendDamage
        Malignant WeaponMelee1"24+4+-1
        - -
      • -
      • -

        Chainrasp Horde [95pts]

        -

        - Selections: 10 Chainrasps [95pts], Malignant Weapon -

        -

        - Categories: DEATH, MALIGNANT, NIGHTHAUNT, SUMMONABLE, CHAINRASP HORDE, Battleline -

        -

        - Unit: Chainrasp, Unit Abilities: Chilling Horde, Dreadwarden, Ethereal, Fly, Weapon: Malignant Weapon -

        -
        - - - - - - - - - -
        UnitMoveWoundsBraverySave
        Chainrasp6"165+
        - - - - - - - - - - - - - - - - - - - - - -
        Unit AbilitiesAbility Details
        Chilling HordeRe-roll wound rolls of 1 for this unit while it has more than 10 models.
        DreadwardenThe leader of this unit is a Dreadwarden. Add 1 to the Attacks characteristic of a Dreadwarden's Malignant Weapon. In addition, a Chainrasp Horde has a Bravery characteristic of 10 instead of 6 while it includes a Dreadwarden.
        EtherealIgnore modifiers (positive or negative) when making save rolls for this unit.
        FlyThis unit can fly.
        - - - - - - - - - -
        WeaponTypeRangeAttacksTo HitTo WoundRendDamage
        Malignant WeaponMelee1"24+4+-1
        - -
      • -
      • -

        Chainrasp Horde [95pts]

        -

        - Selections: 10 Chainrasps [95pts], Malignant Weapon -

        -

        - Categories: DEATH, MALIGNANT, NIGHTHAUNT, SUMMONABLE, CHAINRASP HORDE, Battleline -

        -

        - Unit: Chainrasp, Unit Abilities: Chilling Horde, Dreadwarden, Ethereal, Fly, Weapon: Malignant Weapon -

        -
        - - - - - - - - - -
        UnitMoveWoundsBraverySave
        Chainrasp6"165+
        - - - - - - - - - - - - - - - - - - - - - -
        Unit AbilitiesAbility Details
        Chilling HordeRe-roll wound rolls of 1 for this unit while it has more than 10 models.
        DreadwardenThe leader of this unit is a Dreadwarden. Add 1 to the Attacks characteristic of a Dreadwarden's Malignant Weapon. In addition, a Chainrasp Horde has a Bravery characteristic of 10 instead of 6 while it includes a Dreadwarden.
        EtherealIgnore modifiers (positive or negative) when making save rolls for this unit.
        FlyThis unit can fly.
        - - - - - - - - - -
        WeaponTypeRangeAttacksTo HitTo WoundRendDamage
        Malignant WeaponMelee1"24+4+-1
        - -
      • -
      • -

        Chainrasp Horde [95pts]

        -

        - Selections: 10 Chainrasps [95pts], Malignant Weapon -

        -

        - Categories: DEATH, MALIGNANT, NIGHTHAUNT, SUMMONABLE, CHAINRASP HORDE, Battleline -

        -

        - Unit: Chainrasp, Unit Abilities: Chilling Horde, Dreadwarden, Ethereal, Fly, Weapon: Malignant Weapon -

        -
        - - - - - - - - - -
        UnitMoveWoundsBraverySave
        Chainrasp6"165+
        - - - - - - - - - - - - - - - - - - - - - -
        Unit AbilitiesAbility Details
        Chilling HordeRe-roll wound rolls of 1 for this unit while it has more than 10 models.
        DreadwardenThe leader of this unit is a Dreadwarden. Add 1 to the Attacks characteristic of a Dreadwarden's Malignant Weapon. In addition, a Chainrasp Horde has a Bravery characteristic of 10 instead of 6 while it includes a Dreadwarden.
        EtherealIgnore modifiers (positive or negative) when making save rolls for this unit.
        FlyThis unit can fly.
        - - - - - - - - - -
        WeaponTypeRangeAttacksTo HitTo WoundRendDamage
        Malignant WeaponMelee1"24+4+-1
        - -
      • -
      • -

        Hexwraiths [150pts]

        -

        - Selections: 5 Hexwraiths [150pts], Battle Regiment - 2-5 Troops, Spectral Scythe -

        -

        - Categories: DEATH, HEXWRAITHS, MALIGNANT, NIGHTHAUNT, SUMMONABLE, Other, Battleline -

        -

        - Unit: Hexwraith, Unit Abilities: Ethereal, Fly, Frightful Touch, Hellwraith, Spectral Hunters, Weapon: Spectral Scythe -

        -
          -
        • -

          MOUNT

          -

          - Selections: Skeletal Steed's Hooves and Teeth -

          -

          - Weapon: Hooves and Teeth -

          - -
        • -
        -
        - - - - - - - - - -
        UnitMoveWoundsBraverySave
        Hexwraith12"2104+
        - - - - - - - - - - - - - - - - - - - - - - - - - -
        Unit AbilitiesAbility Details
        EtherealIgnore modifiers (positive or negative) when making save rolls for this unit.
        FlyThis unit can fly.
        Frightful TouchIf the unmodified roll for an attack made with the <Banshee Mandmaidens' Spectral Claws>, <Wraith Herald's Spectral Claws>, <Fellreaper>, <Reaper Scythe> <Chill Dagger> <Spectral Scythe> <Cairn Wraith's Reaper Scythe> <Spectral Claws and Daggers> <Spectral Host's Ethereal Weapons>, <Mourngul's Nightmarish Claws and Fangs> is 6, that attack inflicts <the weapon damage as a> mortal wound and the attack sequence ends (do not make a wound or save roll).
        HellwraithThe leader of this unit is a Hellwraith. Add 1 to the Attacks characteristic of a Hellwraith’s Spectral Scythe.
        Spectral HuntersIn your movement phase, immediately after this unit has moved, you can pick an enemy unit that has any models that a model from this unit passed across. If you do so, roll a dice for each model from this unit that passed across the enemy unit. For each roll of 5+, that enemy unit suffers 1 mortal wound.
        - - - - - - - - - - - - - -
        WeaponTypeRangeAttacksTo HitTo WoundRendDamage
        Hooves and TeethMelee1"24+5+-1
        Spectral ScytheMelee1"24+3+-11
        - -
      • -
      -
    • -
    • -

      Other [960pts]

      -
        -
      • -

        Bladegheist Revenants [190pts]

        -

        - Selections: 10 Bladegheist Revenants [190pts], Battle Regiment - 2-5 Troops, Tomb Greatblade -

        -

        - Categories: DEATH, MALIGNANT, NIGHTHAUNT, SUMMONABLE, BLADEGHEIST REVENANTS, Other -

        -

        - Unit: Bladegheist Revenant, Unit Abilities: Elite, Ethereal, Fearful Frenzy, Fly, Whirling Death, Weapon: Tomb Greatblade -

        -
        - - - - - - - - - -
        UnitMoveWoundsBraverySave
        Bladegheist Revenant8"1104+
        - - - - - - - - - - - - - - - - - - - - - - - - - -
        Unit AbilitiesAbility Details
        EliteModels in this unit can issue commands to their own unit.
        EtherealIgnore modifiers (positive or negative) when making save rolls for this unit.
        Fearful FrenzyYou can re-roll failed hit rolls for attacks made by this unit if it is wholly within 12" of any friendly SPIRIT TORMENTS or CHAINGHASTS
        FlyThis unit can fly.
        Whirling DeathThis unit can retreat and charge in the same turn. In addition, add 1 to the Attacks characteristic of this unit's Tomb Greatblades if it made a charge move in the same turn.
        - - - - - - - - - -
        WeaponTypeRangeAttacksTo HitTo WoundRendDamage
        Tomb GreatbladeMelee1"23+3+-11
        - -
      • -
      • -

        Bladegheist Revenants [190pts]

        -

        - Selections: 10 Bladegheist Revenants [190pts], Battle Regiment - 2-5 Troops, Tomb Greatblade -

        -

        - Categories: DEATH, MALIGNANT, NIGHTHAUNT, SUMMONABLE, BLADEGHEIST REVENANTS, Other -

        -

        - Unit: Bladegheist Revenant, Unit Abilities: Elite, Ethereal, Fearful Frenzy, Fly, Whirling Death, Weapon: Tomb Greatblade -

        -
        - - - - - - - - - -
        UnitMoveWoundsBraverySave
        Bladegheist Revenant8"1104+
        - - - - - - - - - - - - - - - - - - - - - - - - - -
        Unit AbilitiesAbility Details
        EliteModels in this unit can issue commands to their own unit.
        EtherealIgnore modifiers (positive or negative) when making save rolls for this unit.
        Fearful FrenzyYou can re-roll failed hit rolls for attacks made by this unit if it is wholly within 12" of any friendly SPIRIT TORMENTS or CHAINGHASTS
        FlyThis unit can fly.
        Whirling DeathThis unit can retreat and charge in the same turn. In addition, add 1 to the Attacks characteristic of this unit's Tomb Greatblades if it made a charge move in the same turn.
        - - - - - - - - - -
        WeaponTypeRangeAttacksTo HitTo WoundRendDamage
        Tomb GreatbladeMelee1"23+3+-11
        - -
      • -
      • -

        Chainghasts [75pts]

        -

        - Selections: 2 Chainghasts [75pts], Battle Regiment - 2-5 Troops, Ghastflails -

        -

        - Categories: DEATH, MALIGNANT, NIGHTHAUNT, SUMMONABLE, CHAINGHASTS, Other -

        -

        - Unit: Chainghast, Unit Abilities: Another Link in the Chain, Ethereal, Sweeping Blows, Weapon: Ghastflails (Melee), Ghastflails (Missile) -

        -
        - - - - - - - - - -
        UnitMoveWoundsBraverySave
        Chainghast6"2104+
        - - - - - - - - - - - - - - - - - -
        Unit AbilitiesAbility Details
        Another Link in the ChainWhile this unit is wholly within 12" of a friendly Spirit Torment, you can re-roll hit rolls of 1 for friendly Nighthaunt units while they are wholly within 12" of this unit.
        EtherealIgnore modifiers (positive or negative) when making save rolls for this unit.
        Sweeping BlowsThe Attacks characteristic of the Ghastflails melee weapon is equal to the number of enemy models within 2" of the attacking model when the number of attacks made with the weapon is determined.
        - - - - - - - - - - - - - -
        WeaponTypeRangeAttacksTo HitTo WoundRendDamage
        Ghastflails (Melee)Melee2"See Sweeping Blow4+3+-11
        Ghastflails (Missile)Missile15"D34+3+-21
        - -
      • -
      • -

        Chainghasts [75pts]

        -

        - Selections: 2 Chainghasts [75pts], Battle Regiment - 2-5 Troops, Ghastflails -

        -

        - Categories: DEATH, MALIGNANT, NIGHTHAUNT, SUMMONABLE, CHAINGHASTS, Other -

        -

        - Unit: Chainghast, Unit Abilities: Another Link in the Chain, Ethereal, Sweeping Blows, Weapon: Ghastflails (Melee), Ghastflails (Missile) -

        -
        - - - - - - - - - -
        UnitMoveWoundsBraverySave
        Chainghast6"2104+
        - - - - - - - - - - - - - - - - - -
        Unit AbilitiesAbility Details
        Another Link in the ChainWhile this unit is wholly within 12" of a friendly Spirit Torment, you can re-roll hit rolls of 1 for friendly Nighthaunt units while they are wholly within 12" of this unit.
        EtherealIgnore modifiers (positive or negative) when making save rolls for this unit.
        Sweeping BlowsThe Attacks characteristic of the Ghastflails melee weapon is equal to the number of enemy models within 2" of the attacking model when the number of attacks made with the weapon is determined.
        - - - - - - - - - - - - - -
        WeaponTypeRangeAttacksTo HitTo WoundRendDamage
        Ghastflails (Melee)Melee2"See Sweeping Blow4+3+-11
        Ghastflails (Missile)Missile15"D34+3+-21
        - -
      • -
      • -

        Chainghasts [75pts]

        -

        - Selections: 2 Chainghasts [75pts], Ghastflails -

        -

        - Categories: DEATH, MALIGNANT, NIGHTHAUNT, SUMMONABLE, CHAINGHASTS, Other -

        -

        - Unit: Chainghast, Unit Abilities: Another Link in the Chain, Ethereal, Sweeping Blows, Weapon: Ghastflails (Melee), Ghastflails (Missile) -

        -
        - - - - - - - - - -
        UnitMoveWoundsBraverySave
        Chainghast6"2104+
        - - - - - - - - - - - - - - - - - -
        Unit AbilitiesAbility Details
        Another Link in the ChainWhile this unit is wholly within 12" of a friendly Spirit Torment, you can re-roll hit rolls of 1 for friendly Nighthaunt units while they are wholly within 12" of this unit.
        EtherealIgnore modifiers (positive or negative) when making save rolls for this unit.
        Sweeping BlowsThe Attacks characteristic of the Ghastflails melee weapon is equal to the number of enemy models within 2" of the attacking model when the number of attacks made with the weapon is determined.
        - - - - - - - - - - - - - -
        WeaponTypeRangeAttacksTo HitTo WoundRendDamage
        Ghastflails (Melee)Melee2"See Sweeping Blow4+3+-11
        Ghastflails (Missile)Missile15"D34+3+-21
        - -
      • -
      • -

        Glaivewraith Stalkers [65pts]

        -

        - Selections: 4 Glaivewraith Stalkers [65pts], Hunter's Glaive -

        -

        - Categories: DEATH, MALIGNANT, NIGHTHAUNT, SUMMONABLE, GLAIVEWRAITH STALKERS, Other -

        -

        - Unit: Glaivewraith Stalker, Unit Abilities: Ethereal, Fly, The Point of Death, Weapon: Hunter's Glaive -

        -
        - - - - - - - - - -
        UnitMoveWoundsBraverySave
        Glaivewraith Stalker6"1104+
        - - - - - - - - - - - - - - - - - -
        Unit AbilitiesAbility Details
        EtherealIgnore modifiers (positive or negative) when making save rolls for this unit.
        FlyThis unit can fly.
        The Point of DeathYou can re-roll failed hit rolls for attacks made with this unit’s Hunter’s Glaives if this unit or the target unit made a charge move in the same turn.
        - - - - - - - - - -
        WeaponTypeRangeAttacksTo HitTo WoundRendDamage
        Hunter's GlaiveMelee2"24+3+-1
        - -
      • -
      • -

        Glaivewraith Stalkers [65pts]

        -

        - Selections: 4 Glaivewraith Stalkers [65pts], Hunter's Glaive -

        -

        - Categories: DEATH, MALIGNANT, NIGHTHAUNT, SUMMONABLE, GLAIVEWRAITH STALKERS, Other -

        -

        - Unit: Glaivewraith Stalker, Unit Abilities: Ethereal, Fly, The Point of Death, Weapon: Hunter's Glaive -

        -
        - - - - - - - - - -
        UnitMoveWoundsBraverySave
        Glaivewraith Stalker6"1104+
        - - - - - - - - - - - - - - - - - -
        Unit AbilitiesAbility Details
        EtherealIgnore modifiers (positive or negative) when making save rolls for this unit.
        FlyThis unit can fly.
        The Point of DeathYou can re-roll failed hit rolls for attacks made with this unit’s Hunter’s Glaives if this unit or the target unit made a charge move in the same turn.
        - - - - - - - - - -
        WeaponTypeRangeAttacksTo HitTo WoundRendDamage
        Hunter's GlaiveMelee2"24+3+-1
        - -
      • -
      • -

        Myrmourn Banshees [75pts]

        -

        - Selections: 4 Myrmourn Banshees [75pts], Chill Dagger -

        -

        - Categories: DEATH, MALIGNANT, NIGHTHAUNT, SUMMONABLE, MYRNMOURN BANSHEES, Other -

        -

        - Unit: Myrmourn Banshees, Unit Abilities: Ethereal, Fly, Spell-eaters, Weapon: Chill Dagger -

        -
        - - - - - - - - - -
        UnitMoveWoundsBraverySave
        Myrmourn Banshees8"1104+
        - - - - - - - - - - - - - - - - - -
        Unit AbilitiesAbility Details
        EtherealIgnore modifiers (positive or negative) when making save rolls for this unit.
        FlyThis unit can fly.
        Spell-eatersOnce in each enemy hero phase, if this unit is within 18" of an enemy WIZARD that successfully casts a spell, this unit can attempt to unbind the spell in the same manner as a Wizard. If it does so, add 1 to the unbinding roll for every 4 models in this unit. In addition, if this unit unbinds an enemy spell, add 1 to the Attacks characteristic of this unit’s Chill Daggers until the next enemy hero phase. Once in each of your hero phases, if this unit is within 6" of an ENDLESS SPELL, this unit can attempt to dispel the endless spell in the same manner as a WIZARD. If this unit dispels an endless spell, it suffers D3 mortal wounds, but add 1 to the Attacks characteristic of this unit’s Chill Daggers until your next hero phase.
        - - - - - - - - - -
        WeaponTypeRangeAttacksTo HitTo WoundRendDamage
        Chill DaggerMelee1"14+3+-2D3
        - -
      • -
      • -

        Myrmourn Banshees [75pts]

        -

        - Selections: 4 Myrmourn Banshees [75pts], Chill Dagger -

        -

        - Categories: DEATH, MALIGNANT, NIGHTHAUNT, SUMMONABLE, MYRNMOURN BANSHEES, Other -

        -

        - Unit: Myrmourn Banshees, Unit Abilities: Ethereal, Fly, Spell-eaters, Weapon: Chill Dagger -

        -
        - - - - - - - - - -
        UnitMoveWoundsBraverySave
        Myrmourn Banshees8"1104+
        - - - - - - - - - - - - - - - - - -
        Unit AbilitiesAbility Details
        EtherealIgnore modifiers (positive or negative) when making save rolls for this unit.
        FlyThis unit can fly.
        Spell-eatersOnce in each enemy hero phase, if this unit is within 18" of an enemy WIZARD that successfully casts a spell, this unit can attempt to unbind the spell in the same manner as a Wizard. If it does so, add 1 to the unbinding roll for every 4 models in this unit. In addition, if this unit unbinds an enemy spell, add 1 to the Attacks characteristic of this unit’s Chill Daggers until the next enemy hero phase. Once in each of your hero phases, if this unit is within 6" of an ENDLESS SPELL, this unit can attempt to dispel the endless spell in the same manner as a WIZARD. If this unit dispels an endless spell, it suffers D3 mortal wounds, but add 1 to the Attacks characteristic of this unit’s Chill Daggers until your next hero phase.
        - - - - - - - - - -
        WeaponTypeRangeAttacksTo HitTo WoundRendDamage
        Chill DaggerMelee1"14+3+-2D3
        - -
      • -
      • -

        Myrmourn Banshees [75pts]

        -

        - Selections: 4 Myrmourn Banshees [75pts], Chill Dagger -

        -

        - Categories: DEATH, MALIGNANT, NIGHTHAUNT, SUMMONABLE, MYRNMOURN BANSHEES, Other -

        -

        - Unit: Myrmourn Banshees, Unit Abilities: Ethereal, Fly, Spell-eaters, Weapon: Chill Dagger -

        -
        - - - - - - - - - -
        UnitMoveWoundsBraverySave
        Myrmourn Banshees8"1104+
        - - - - - - - - - - - - - - - - - -
        Unit AbilitiesAbility Details
        EtherealIgnore modifiers (positive or negative) when making save rolls for this unit.
        FlyThis unit can fly.
        Spell-eatersOnce in each enemy hero phase, if this unit is within 18" of an enemy WIZARD that successfully casts a spell, this unit can attempt to unbind the spell in the same manner as a Wizard. If it does so, add 1 to the unbinding roll for every 4 models in this unit. In addition, if this unit unbinds an enemy spell, add 1 to the Attacks characteristic of this unit’s Chill Daggers until the next enemy hero phase. Once in each of your hero phases, if this unit is within 6" of an ENDLESS SPELL, this unit can attempt to dispel the endless spell in the same manner as a WIZARD. If this unit dispels an endless spell, it suffers D3 mortal wounds, but add 1 to the Attacks characteristic of this unit’s Chill Daggers until your next hero phase.
        - - - - - - - - - -
        WeaponTypeRangeAttacksTo HitTo WoundRendDamage
        Chill DaggerMelee1"14+3+-2D3
        - -
      • -
      • -

        Thorns of the Briar Queen

        -

        - Selections: 6x Malignant Weapon, 5x Thorns of the Briar Queen , Varclav the Cruel -

        -

        - Categories: DEATH, MALIGNANT, NIGHTHAUNT, SUMMONABLE, CHAINRASP HORDE, THORNS OF THE BRIAR QUEEN, Other -

        -

        - Unit: Thorns of the Briar Queen, Unit Abilities: Ethereal, Fly, Grasping Chains, Varclav the Cruel, Weapon: Malignant Weapon -

        -
        - - - - - - - - - -
        UnitMoveWoundsBraverySave
        Thorns of the Briar Queen6"165+
        - - - - - - - - - - - - - - - - - - - - - -
        Unit AbilitiesAbility Details
        EtherealIgnore modifiers (positive or negative) when making save rolls for this unit.
        FlyThis unit can fly.
        Grasping ChainsYou can re-roll wound rolls of 1 for attacks made by this unit that target an enemy unit that is within 3" of two or more models from this unit.
        Varclav the CruelThe leader of this unit is Varclav the Cruel. Add 1 to the Attacks characteristic of Varclav the Cruel’s Malignant Weapon. In addition, this unit has a Bravery characteristic of 10 instead of 6 while it includes Varclav the Cruel.
        - - - - - - - - - -
        WeaponTypeRangeAttacksTo HitTo WoundRendDamage
        Malignant WeaponMelee1"24+4+-1
        - -
      • -
      -
    • -
    • -

      Allegiance

      -
        -
      • -

        Allegiance

        -

        - Categories: Allegiance -

        -
          -
        • -

          Allegiance: Nighthaunt

          -

          - Selections: The Emerald Host -

          -

          - Categories: Allegiance -

          -

          - Battle Trait: Aura of Dread, Deathless Spirits, Feed on Terror, From the Underworlds They Come, Knights of Regret, The Emerald Curse, Wave of Terror, Command Abilities: Spectral Summons -

          - -
        • -
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        Battle TraitBattle Trait Details
        Aura of DreadSubtract 1 from the Bravery characteristic of enemy units while they are within 6" of any friendly NIGHTHAUNT units.
        Deathless SpiritsRoll a dice for each wound or mortal wound inflicted on a friendly NIGHTHAUNT unit wholly within 12" of your general or a friendly NIGHTHAUNT HERO from your army. On a 6+ the wound is negated.
        Feed on TerrorEach time an enemy unit fails a battleshock test, pick one friendly NIGHTHAUNT HERO within 6" of that enemy unit. Heal 1 wound that has been allocated to that HERO.
        From the Underworlds They ComeInstead of setting up a NIGHTHAUNT unit on the battlefield, you can place it to one side and say that it is in the underworlds as a reserve unit. You can set up one unit in the underworlds for each unit you set up on the battlefield. At the end of your movement phase you can set up any of these models ore than 9" from any enemy models. This counts as their move for that turn. Any units which are not set up on the battlefield before the start of the fourth battle round are slain.
        Knights of RegretAdd 1 to the Attacks characteristic of melee weapons used by EMERALD HOST HEXWRAITHS units that have made a charge move in the same turn. In addition, roll a dice before you allocate a wound or mortal wound to your general if they are within 3" of any friendly EMERALD HOST HEXWRAITHS units. On a 2+, you must allocate that wound or mortal wound to one of those units instead.
        The Emerald CurseAfter armies are set up but before the first battle round begins, you can pick 1 enemy HERO. For the duration of the battle, subtract 1 from save rolls for attacks that target that HERO.
        Wave of TerrorIf you make an unmodified charge roll of 10+ for a friendly NIGHTHAUNT unit, it can fight immediately after you complete the charge move. This does not stop the unit from being picked to fight in the combat phase of the same turn.
        - - - - - - - - - -
        Command AbilitiesCommand Ability Details
        Spectral SummonsYou can use this command ability at the start of your movement phase. If you do so, pick a friendly NIGHTHAUNT unit that is on the battlefield. Remove that unit from the battlefield, and then set it up wholly within 12' of your general and more than 9" from any enemy models. This counts as their move for that movement phase.
        - -
      • -
      -
    • -
    • -

      Game Options

      -
        -
      • -

        Game Type

        -

        - Selections: 2000 Points - Battlehost -

        -

        - Categories: Game Options, Battlehost -

        - -
      • -
      • -

        Grand Strategy

        -

        - Selections: Hold the Line -

        -

        - Categories: Game Options -

        -

        - Grand Strategy: Hold the Line -

        -
        - - - - - - - - - -
        Grand StrategyDescription
        Hold the LineWhen the battle ends, you complete this grand strategy if there are any Battleline units from your starting army on the battlefield.
        - -
      • -
      -
    • - -
    -
  • - -
- - - -
-

Created with BattleScribe

-
- - \ No newline at end of file diff --git a/src/tests/warscroll/warscrollJson.test.ts b/src/tests/warscroll/warscrollJson.test.ts index cff1c7fd0..5945205f3 100644 --- a/src/tests/warscroll/warscrollJson.test.ts +++ b/src/tests/warscroll/warscrollJson.test.ts @@ -28,7 +28,7 @@ import { TZEENTCH, } from 'meta/factions' import path from 'path' -import { GHUR } from 'types/realmscapes' +import { RealmscapesEnum } from 'types/realmscapes' import { DEPRECATED_AOS_3, DEPRECATED_MALIGN_SORCERY } from 'utils/import/options' import { getWarscrollArmyFromPdf } from 'utils/warscroll/getWarscrollArmy' @@ -726,7 +726,7 @@ describe('getWarscrollArmyFromJson', () => { const res = getWarscrollArmyFromPdf(parsedText) expect(res.factionName).toEqual(OGOR_MAWTRIBES) - expect(res.origin_realm).toEqual(GHUR) + expect(res.origin_realm).toEqual(RealmscapesEnum.GHUR) }) it('should work with The Brazen Rune', () => { diff --git a/src/types/army.ts b/src/types/army.ts index f6c6330fb..a43a894b5 100644 --- a/src/types/army.ts +++ b/src/types/army.ts @@ -1,7 +1,7 @@ import { TSupportedFaction } from 'meta/factions' import { TGameStructure } from 'meta/game_structure' import { TEffects, TEntry } from 'types/data' -import { TBattleRealms, TOriginRealms } from 'types/realmscapes' +import { RealmscapesEnum } from 'types/realmscapes' import { TSelections } from 'types/selections' import { TAllySelectionStore } from 'types/store' @@ -42,8 +42,8 @@ export interface ICurrentArmy { allySelections: TAllySelectionStore factionName: TSupportedFaction subFactionName: string - origin_realm: TOriginRealms | null + origin_realm: RealmscapesEnum | null realmscape_feature: string | null - realmscape: TBattleRealms | null + realmscape: RealmscapesEnum | null selections: TSelections } diff --git a/src/types/import.ts b/src/types/import.ts index c5b45f5f6..6fe240a10 100644 --- a/src/types/import.ts +++ b/src/types/import.ts @@ -1,6 +1,6 @@ import { TSupportedFaction } from 'meta/factions' import { ICurrentArmy } from 'types/army' -import { TBattleRealms, TOriginRealms } from 'types/realmscapes' +import { RealmscapesEnum } from 'types/realmscapes' import { ILinkedArmy, ISavedArmyFromApi } from 'types/savedArmy' import { TSelections } from 'types/selections' import { TAllySelectionStore } from 'types/store' @@ -13,9 +13,9 @@ export interface IImportedArmy { factionName: TSupportedFaction subFactionName: string hiddenReminders?: undefined - origin_realm: TOriginRealms | null + origin_realm: RealmscapesEnum | null realmscape_feature: string | null - realmscape: TBattleRealms | null + realmscape: RealmscapesEnum | null selections: TSelections unknownSelections: string[] } diff --git a/src/types/realmscapes.ts b/src/types/realmscapes.ts index 2ba7591c9..4201e1fc2 100644 --- a/src/types/realmscapes.ts +++ b/src/types/realmscapes.ts @@ -1,71 +1,6 @@ -// type TAqshy = `Aqshy` -// type TChamon = `Chamon` -// type TCharrwind = `Charrwind Coast` -// type TCoastOfTusks = `Coast of Tusks` -// type TDolorum = `Dolorum` -// type TEightpoints = `Eightpoints` -// type TGenesisGate = `Genesis Gate` -type TGallet = `Gallet` -// type TGhur = `Ghur` -// type TGhyran = `Ghyran` -// type THelleflux = `Helleflux` -// type THysh = `Hysh` -// type TInvidia = `Invidia` -// type TPraetoris = `Praetoris` -// type TProsperis = `Prosperis` -// type TShyish = `Shyish` -// type TStygxx = `Stygxx` -// type TUlgu = `Ulgu` -// type TUmbral = `Umbral Veil` -// type TVaranthax = `Varanthax's Maw` -// type TYmetrica = `Ymetrica` +export enum RealmscapesEnum { + GALLET = 'Gallet', + GHUR = 'Ghur', +} -export type TOriginRealms = TGallet - -export type TBattleRealms = TOriginRealms - -// export const AQSHY: TAqshy = `Aqshy` -// export const CHAMON: TChamon = `Chamon` -// export const CHARRWIND: TCharrwind = `Charrwind Coast` -// export const COASTOFTUSKS: TCoastOfTusks = `Coast of Tusks` -// export const DOLORUM: TDolorum = `Dolorum` -// export const EIGHTPOINTS: TEightpoints = `Eightpoints` -// export const GENESISGATE: TGenesisGate = `Genesis Gate` -export const GALLET: TGallet = `Gallet` -// export const GHUR: TGhur = `Ghur` -// export const GHYRAN: TGhyran = `Ghyran` -// export const HELLEFlUX: THelleflux = `Helleflux` -// export const INVIDA: TInvidia = `Invidia` -// export const HYSH: THysh = `Hysh` -// export const PRAETORIS: TPraetoris = `Praetoris` -// export const PROSPERIS: TProsperis = `Prosperis` -// export const SHYISH: TShyish = `Shyish` -// export const STYGXX: TStygxx = `Stygxx` -// export const ULGU: TUlgu = `Ulgu` -// export const UMBRAL: TUmbral = `Umbral Veil` -// export const VARANTHAX: TVaranthax = `Varanthax's Maw` -// export const YMETRICA: TYmetrica = `Ymetrica` - -export const SUPPORTED_BATTLE_REALMS: TBattleRealms[] = [ - // AQSHY, - // CHAMON, - // CHARRWIND, - // COASTOFTUSKS, - // DOLORUM, - // EIGHTPOINTS, - // GENESISGATE, - GALLET, - // GHUR, - // GHYRAN, - // HELLEFlUX, - // HYSH, - // INVIDA, - // PRAETORIS, - // PROSPERIS, - // SHYISH, - // STYGXX, - // ULGU, - // UMBRAL, - // VARANTHAX, - // YMETRICA, -] +export const SUPPORTED_REALMSCAPES: RealmscapesEnum[] = [RealmscapesEnum.GALLET, RealmscapesEnum.GHUR] diff --git a/src/types/store.ts b/src/types/store.ts index 5f3a1e91b..9ff4b167e 100644 --- a/src/types/store.ts +++ b/src/types/store.ts @@ -1,7 +1,7 @@ import { TSupportedFaction } from 'meta/factions' import { IArmy, TAllyArmies } from 'types/army' import { INote } from 'types/notes' -import { TBattleRealms, TOriginRealms } from 'types/realmscapes' +import { RealmscapesEnum } from 'types/realmscapes' import { IAllySelections, TSelections, TSelectionTypes } from 'types/selections' export interface IArmyStore { @@ -19,8 +19,8 @@ export interface INotesStore { } export interface IRealmscapeStore { - origin_realm: TOriginRealms | null - realmscape: TBattleRealms | null + origin_realm: RealmscapesEnum | null + realmscape: RealmscapesEnum | null realmscape_feature: string | null } diff --git a/src/utils/azyr/getAzyrArmy.ts b/src/utils/azyr/getAzyrArmy.ts index 689631afb..5647dc54f 100644 --- a/src/utils/azyr/getAzyrArmy.ts +++ b/src/utils/azyr/getAzyrArmy.ts @@ -3,7 +3,7 @@ import { uniq } from 'lodash' import { SLAANESH, TSupportedFaction } from 'meta/factions' import { getFactionFromList } from 'meta/faction_list' import { AZYR, IImportedArmy } from 'types/import' -import { TBattleRealms } from 'types/realmscapes' +import { RealmscapesEnum } from 'types/realmscapes' import { TSelections, TSelectionTypes } from 'types/selections' import { isValidFactionName } from 'utils/armyUtils' import { importErrorChecker } from 'utils/import' @@ -33,7 +33,7 @@ const selectorLookup: Record = { const getInitialAzyrArmy = (pages: string[]): IImportedArmy => { let factionName = '' let subFactionName = '' - let realmscape: TBattleRealms | null = null + let realmscape: RealmscapesEnum | null = null let allyUnits: string[] = [] let unknownSelections: string[] = [] @@ -48,7 +48,7 @@ const getInitialAzyrArmy = (pages: string[]): IImportedArmy => { } if (name.startsWith('REALMSCAPE:')) { - realmscape = titleCase(name.replace('REALMSCAPE: ', '')) as TBattleRealms + realmscape = titleCase(name.replace('REALMSCAPE: ', '')) as RealmscapesEnum return accum } diff --git a/src/utils/battlescribe/getters.ts b/src/utils/battlescribe/getters.ts index b707d100c..2a6775c63 100644 --- a/src/utils/battlescribe/getters.ts +++ b/src/utils/battlescribe/getters.ts @@ -9,7 +9,7 @@ import { TSupportedFaction, } from 'meta/factions' import { getFactionFromList } from 'meta/faction_list' -import { TBattleRealms, TOriginRealms } from 'types/realmscapes' +import { RealmscapesEnum } from 'types/realmscapes' import { TSelections } from 'types/selections' import { isValidFactionName } from 'utils/armyUtils' import { cleanText, fixKeys, ignoredValues } from 'utils/battlescribe/battlescribeUtils' @@ -91,21 +91,21 @@ export const getFactionAndFlavors = ( } } -export const parseBattleRealmObj = (obj: IParentNode): TBattleRealms | null => { +export const parseBattleRealmObj = (obj: IParentNode): RealmscapesEnum | null => { try { //@ts-ignore const text = obj.childNodes[1].childNodes[1].value - return text.split(': ')[1].trim() as TBattleRealms + return text.split(': ')[1].trim() as RealmscapesEnum } catch (err) { return null } } -export const parseOriginRealmObj = (obj: IParentNode): TOriginRealms | null => { +export const parseOriginRealmObj = (obj: IParentNode): RealmscapesEnum | null => { try { //@ts-ignore const text = obj.childNodes[1].childNodes[1].value - return text.split(': ')[1].trim() as TOriginRealms + return text.split(': ')[1].trim() as RealmscapesEnum } catch (err) { return null } diff --git a/src/utils/battlescribe/parseHTML.ts b/src/utils/battlescribe/parseHTML.ts index 9224cc221..5c82cc9cd 100644 --- a/src/utils/battlescribe/parseHTML.ts +++ b/src/utils/battlescribe/parseHTML.ts @@ -1,5 +1,5 @@ import parse5 from 'parse5' -import { TBattleRealms, TOriginRealms } from 'types/realmscapes' +import { RealmscapesEnum } from 'types/realmscapes' import { cleanText, fixKeys } from 'utils/battlescribe/battlescribeUtils' import { isAllegianceObj, @@ -21,8 +21,8 @@ import { type TTraverseDoc = (docObj: IParentNode | IChildNode) => { allegianceInfo: IFlavorInfo[] factionInfo: IFactionInfo - origin_realm: TOriginRealms | null - realmscape: TBattleRealms | null + origin_realm: RealmscapesEnum | null + realmscape: RealmscapesEnum | null rootSelections: IParentNode[] } @@ -30,8 +30,8 @@ export const traverseDoc: TTraverseDoc = docObj => { const results = { allegianceInfo: [] as IFlavorInfo[], factionInfo: { factionName: null, grandAlliance: null } as IFactionInfo, - origin_realm: null as TOriginRealms | null, - realmscape: null as TBattleRealms | null, + origin_realm: null as RealmscapesEnum | null, + realmscape: null as RealmscapesEnum | null, rootSelections: [] as IParentNode[], } diff --git a/src/utils/getArmy/getArmy.ts b/src/utils/getArmy/getArmy.ts index 4852a77cc..eb22aa2f5 100644 --- a/src/utils/getArmy/getArmy.ts +++ b/src/utils/getArmy/getArmy.ts @@ -4,7 +4,7 @@ import { GRAND_ALLIANCE_FACTIONS, TGrandAllianceFactions, TGrandAlliances } from import { TSupportedFaction } from 'meta/factions' import { getFactionFromList } from 'meta/faction_list' import { IArmy, TCollection, TSubfactionArmy } from 'types/army' -import { TBattleRealms, TOriginRealms } from 'types/realmscapes' +import { RealmscapesEnum } from 'types/realmscapes' import { isValidFactionName } from 'utils/armyUtils' import { isDev } from 'utils/env' import { getAllianceItems, getGrandAllianceEndlessSpells } from 'utils/getArmy/getAllianceItems' @@ -22,8 +22,8 @@ import { processGame } from 'utils/processGame' export const getArmy = ( factionName: TSupportedFaction | null, subFactionName: string | null = null, - originRealm: TOriginRealms | null = null, - realmscape: TBattleRealms | null = null + originRealm: RealmscapesEnum | null = null, + realmscape: RealmscapesEnum | null = null ): IArmy | null => { if (!isValidFactionName(factionName)) return null @@ -53,8 +53,8 @@ interface IModifyArmyMeta { Collection: TCollection factionName: TSupportedFaction GrandAlliance: TGrandAlliances - originRealm: TOriginRealms | null - realmscape: TBattleRealms | null + originRealm: RealmscapesEnum | null + realmscape: RealmscapesEnum | null } const modifyArmy = produce((Army: TSubfactionArmy, meta: IModifyArmyMeta) => { diff --git a/src/utils/hooks/useGetArmyBuilderCards.tsx b/src/utils/hooks/useGetArmyBuilderCards.tsx index 9af1ae5f9..411aa9dc7 100644 --- a/src/utils/hooks/useGetArmyBuilderCards.tsx +++ b/src/utils/hooks/useGetArmyBuilderCards.tsx @@ -3,7 +3,7 @@ import { selectRealmscapeSlice, selectSelections } from 'ducks/selectors' import { useMemo } from 'react' import { useSelector } from 'react-redux' import { IArmy } from 'types/army' -import { SUPPORTED_BATTLE_REALMS } from 'types/realmscapes' +import { SUPPORTED_REALMSCAPES } from 'types/realmscapes' import { TSelectionTypes } from 'types/selections' import { getSideEffects } from 'utils/getSideEffects' @@ -167,7 +167,7 @@ const useGetArmyBuilderCards = (army: IArmy) => { // type: 'single', // }, { - items: SUPPORTED_BATTLE_REALMS, + items: SUPPORTED_REALMSCAPES, setValue: realmscapeActions.setRealmscape, title: `Realm of Battle`, mobileTitle: `Battle Realm`, diff --git a/src/utils/processReminders.ts b/src/utils/processReminders.ts index efe74c691..46980aa45 100644 --- a/src/utils/processReminders.ts +++ b/src/utils/processReminders.ts @@ -15,7 +15,7 @@ import { TEntryProperties, TTurnAction, } from 'types/data' -import { TBattleRealms } from 'types/realmscapes' +import { RealmscapesEnum } from 'types/realmscapes' import { IAllySelections, TSelections, TSelectionTypes } from 'types/selections' import { TAllySelectionStore } from 'types/store' import { hashReminder } from 'utils/reminderUtils' @@ -28,7 +28,7 @@ type TProcessReminders = ( factionName: TSupportedFaction, subFactionName: string, selections: TSelections, - realmscape: TBattleRealms | null, + realmscape: RealmscapesEnum | null, allyFactionNames: TSupportedFaction[], allyArmies: TAllyArmies, allySelections: TAllySelectionStore