From e43fa37fe8fb5a875d81aca49d7e50cd998370ee Mon Sep 17 00:00:00 2001 From: Lurkars Date: Tue, 18 Apr 2023 21:05:56 +0200 Subject: [PATCH] address #237, #239, #240, #90/#160, change Confederated to Allied, improve ally/allied marker, small fixes + improvements --- data/fh/scenarios/028.json | 2 +- data/fh/scenarios/061.json | 14 ++++---- data/fh/scenarios/062.json | 11 +++--- data/fh/scenarios/086.json | 12 ++++--- data/fh/scenarios/114.json | 8 +++-- data/fh/scenarios/116.json | 12 ++++--- data/fh/sections/105-1.json | 12 ++++--- data/fh/sections/146-3.json | 36 +++++++++++++------ data/fh/sections/86-1.json | 9 +++++ package-lock.json | 4 +-- package.json | 2 +- scripts/sort/sorter/scenario.mjs | 2 +- .../businesslogic/AttackModifierManager.ts | 8 ++--- src/app/game/businesslogic/LootManager.ts | 4 +-- src/app/game/businesslogic/MonsterManager.ts | 4 +-- src/app/game/businesslogic/ScenarioManager.ts | 20 ++++++++--- src/app/game/businesslogic/SettingsManager.ts | 22 +++++++++--- src/app/game/businesslogic/StateManager.ts | 1 + src/app/game/businesslogic/StorageManager.ts | 4 ++- src/app/game/model/Monster.ts | 12 +++---- src/app/game/model/Settings.ts | 1 + src/app/game/model/data/ScenarioData.ts | 4 +-- src/app/game/model/data/ScenarioRule.ts | 2 ++ src/app/ui/figures/actions/action.ts | 2 +- .../figures/actions/summon/action-summon.ts | 2 +- .../entities-menu/entities-menu-dialog.html | 6 ++-- .../entity-menu/entity-menu-dialog.html | 14 ++++---- .../figures/entity-menu/entity-menu-dialog.ts | 6 ++-- .../figures/monster/dialogs/level-dialog.html | 8 ++--- .../figures/monster/dialogs/level-dialog.ts | 6 ++-- .../ui/figures/monster/stats/stat-dialog.ts | 2 +- .../figures/monster/stats/stats-dialog.html | 4 +-- .../ui/figures/monster/stats/stats-dialog.ts | 2 +- src/app/ui/figures/monster/stats/stats.html | 8 ++--- src/app/ui/figures/monster/stats/stats.ts | 18 ++++++++-- src/app/ui/figures/objective/objective.html | 2 +- src/app/ui/figures/objective/objective.scss | 10 ++---- src/app/ui/footer/footer.ts | 4 +-- .../footer/scenario-rules/scenario-rules.ts | 4 +-- .../scenario/dialog/abilities/stats-list.ts | 2 +- .../scenario/summary/scenario-summary.html | 16 ++++++++- src/app/ui/header/menu/server/server.html | 4 +-- src/app/ui/header/menu/settings/settings.html | 28 +++++++++++---- src/app/ui/main.ts | 28 ++++++++++++++- src/app/ui/tools/feedback/feedback-dialog.ts | 2 +- src/assets/locales/de.json | 16 ++++++--- src/assets/locales/en.json | 18 +++++++--- src/styles.scss | 22 ++++++++++++ 48 files changed, 305 insertions(+), 135 deletions(-) create mode 100644 data/fh/sections/86-1.json diff --git a/data/fh/scenarios/028.json b/data/fh/scenarios/028.json index cf97e9fe0..5c28980fb 100644 --- a/data/fh/scenarios/028.json +++ b/data/fh/scenarios/028.json @@ -17,7 +17,7 @@ "algox-icespeaker", "algox-snowspeaker" ], - "confederates": [ + "allied": [ "algox-archer", "algox-icespeaker" ], diff --git a/data/fh/scenarios/061.json b/data/fh/scenarios/061.json index a04ec9c19..7ad013db0 100644 --- a/data/fh/scenarios/061.json +++ b/data/fh/scenarios/061.json @@ -24,12 +24,14 @@ }, { "type": "attack", - "value": "L+1" - }, - { - "type": "custom", - "small": true, - "value": "Attacks are unaffected by %game.action.retaliate%" + "value": "L+1", + "subActions": [ + { + "type": "custom", + "small": true, + "value": "Attacks are unaffected by %game.action.retaliate%" + } + ] } ] } diff --git a/data/fh/scenarios/062.json b/data/fh/scenarios/062.json index 2f37ab844..97cdb79af 100644 --- a/data/fh/scenarios/062.json +++ b/data/fh/scenarios/062.json @@ -20,10 +20,13 @@ "actions": [ { "type": "move", - "value": 3 - }, - { - "type": "jump" + "value": 3, + "subActions": [ + { + "type": "jump", + "small": true + } + ] } ] } diff --git a/data/fh/scenarios/086.json b/data/fh/scenarios/086.json index 213e69236..54d888da9 100644 --- a/data/fh/scenarios/086.json +++ b/data/fh/scenarios/086.json @@ -15,11 +15,13 @@ "actions": [ { "type": "custom", - "value": "When suffering damage but not destroyed:" - }, - { - "type": "summon", - "value": "black-imp:normal" + "value": "When suffering damage but not destroyed:", + "subActions": [ + { + "type": "summon", + "value": "black-imp:normal" + } + ] } ] } diff --git a/data/fh/scenarios/114.json b/data/fh/scenarios/114.json index 9a247c4da..93394b396 100644 --- a/data/fh/scenarios/114.json +++ b/data/fh/scenarios/114.json @@ -2,9 +2,11 @@ "index": "114", "name": "Work Freeze", "edition": "fh", - "unlocks": [ - "115" - ], + "rewards": { + "calenderSection": [ + "86.1-4" + ] + }, "monsters": [ "hound", "polar-bear", diff --git a/data/fh/scenarios/116.json b/data/fh/scenarios/116.json index d14548e37..3ed7212a9 100644 --- a/data/fh/scenarios/116.json +++ b/data/fh/scenarios/116.json @@ -21,11 +21,13 @@ "actions": [ { "type": "move", - "value": "3" - }, - { - "type": "custom", - "value": "Focus on moving towards %game.mapMarker.b%" + "value": "3", + "subActions": [ + { + "type": "custom", + "value": "Focus on moving towards %game.mapMarker.b%" + } + ] } ] } diff --git a/data/fh/sections/105-1.json b/data/fh/sections/105-1.json index e7826fa81..b1358a876 100644 --- a/data/fh/sections/105-1.json +++ b/data/fh/sections/105-1.json @@ -22,11 +22,13 @@ }, { "type": "attack", - "value": "L+2" - }, - { - "type": "custom", - "value": "Attacks are unaffected by %game.action.retaliate%" + "value": "L+2", + "subActions": [ + { + "type": "custom", + "value": "Attacks are unaffected by %game.action.retaliate%" + } + ] } ] } diff --git a/data/fh/sections/146-3.json b/data/fh/sections/146-3.json index cecd82d22..6fc5e85a6 100644 --- a/data/fh/sections/146-3.json +++ b/data/fh/sections/146-3.json @@ -29,16 +29,32 @@ }, { "type": "attack", - "value": "3+L" - }, - { - "type": "condition", - "value": "brittle" - }, - { - "type": "custom", - "value": "When this attack is performed, on the next round at initiative 99 instead perform: %game.action.heal%2 self", - "small": true + "value": "3+L", + "subActions": [ + { + "type": "condition", + "value": "brittle", + "small": true + }, + { + "type": "custom", + "value": "When this attack is performed, on the next round at initiative 99 instead perform:", + "small": true, + "subActions": [ + { + "type": "heal", + "value": 2, + "subActions": [ + { + "type": "specialTarget", + "value": "self", + "small": true + } + ] + } + ] + } + ] } ] } diff --git a/data/fh/sections/86-1.json b/data/fh/sections/86-1.json new file mode 100644 index 000000000..0dd1eb13d --- /dev/null +++ b/data/fh/sections/86-1.json @@ -0,0 +1,9 @@ +{ + "index": "86.1", + "name": "Protect the Pass", + "edition": "fh", + "conclusion": true, + "unlocks": [ + "115" + ] +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 0fd4888d9..51ae2073a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "gloomhavensecretariat", - "version": "0.60.0", + "version": "0.60.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "gloomhavensecretariat", - "version": "0.60.0", + "version": "0.60.1", "license": "AGPL3", "dependencies": { "@angular/animations": "^15.2.7", diff --git a/package.json b/package.json index 4e6c31c36..71af53b5b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gloomhavensecretariat", - "version": "0.60.0", + "version": "0.60.1", "license": "AGPL3", "description": "Gloomhaven Secretariat is a Gloomhaven Companion app.", "homepage": "https://gloomhaven-secretariat.de", diff --git a/scripts/sort/sorter/scenario.mjs b/scripts/sort/sorter/scenario.mjs index 5c163524d..84eb8b3fc 100644 --- a/scripts/sort/sorter/scenario.mjs +++ b/scripts/sort/sorter/scenario.mjs @@ -40,5 +40,5 @@ export const sortScenario = function (scenario) { scenario.requiredAchievements = scenario.requiredAchievements.map((requiredAchievements) => sortObjectKeys(requiredAchievements, 'global', 'party')); } - return sortObjectKeys(scenario, 'index', 'group', 'name', 'gridLocation', 'edition', 'parent', 'parentSections', 'conclusion', 'blockedSections', 'marker', 'spoiler', 'initial', 'random', 'solo', 'allyDeck', 'resetRound', 'unlocks', 'requires', 'requiredAchievements', 'blocks', 'links', "forcedLinks", "rewards", 'monsters', 'allies', 'confederates', 'drawExtra', 'objectives', 'lootDeckConfig', 'rules', 'rooms'); + return sortObjectKeys(scenario, 'index', 'group', 'name', 'gridLocation', 'edition', 'parent', 'parentSections', 'conclusion', 'blockedSections', 'marker', 'spoiler', 'initial', 'random', 'solo', 'allyDeck', 'resetRound', 'unlocks', 'requires', 'requiredAchievements', 'blocks', 'links', "forcedLinks", "rewards", 'monsters', 'allies', 'allied', 'drawExtra', 'objectives', 'lootDeckConfig', 'rules', 'rooms'); } \ No newline at end of file diff --git a/src/app/game/businesslogic/AttackModifierManager.ts b/src/app/game/businesslogic/AttackModifierManager.ts index c4001c8eb..3cbfdfd97 100644 --- a/src/app/game/businesslogic/AttackModifierManager.ts +++ b/src/app/game/businesslogic/AttackModifierManager.ts @@ -21,7 +21,7 @@ export class AttackModifierManager { if (figure instanceof Character) { return figure.attackModifierDeck; } else if (figure instanceof Monster) { - return (settingsManager.settings.alwaysAllyAttackModifierDeck || gameManager.fhRules()) && (figure.isAlly || figure.isConfederated) ? this.game.allyAttackModifierDeck : this.game.monsterAttackModifierDeck; + return (settingsManager.settings.alwaysAllyAttackModifierDeck || gameManager.fhRules()) && (figure.isAlly || figure.isAllied) ? this.game.allyAttackModifierDeck : this.game.monsterAttackModifierDeck; } return new AttackModifierDeck(); @@ -29,7 +29,7 @@ export class AttackModifierManager { countUpcomingBlesses(): number { let count = 0; - if (settingsManager.settings.alwaysAllyAttackModifierDeck || gameManager.fhRules() && gameManager.game.figures.some((figure) => figure instanceof Monster && (figure.isAlly || figure.isConfederated))) { + if (settingsManager.settings.alwaysAllyAttackModifierDeck || gameManager.fhRules() && gameManager.game.figures.some((figure) => figure instanceof Monster && (figure.isAlly || figure.isAllied))) { count += gameManager.game.allyAttackModifierDeck.cards.filter((attackModifier, index) => { return attackModifier.type == AttackModifierType.bless && index > gameManager.game.allyAttackModifierDeck.current; }).length; @@ -55,7 +55,7 @@ export class AttackModifierManager { } let count = 0; - if (settingsManager.settings.alwaysAllyAttackModifierDeck || gameManager.fhRules() && gameManager.game.figures.some((figure) => figure instanceof Monster && (figure.isAlly || figure.isConfederated))) { + if (settingsManager.settings.alwaysAllyAttackModifierDeck || gameManager.fhRules() && gameManager.game.figures.some((figure) => figure instanceof Monster && (figure.isAlly || figure.isAllied))) { count += gameManager.game.allyAttackModifierDeck.cards.filter((attackModifier, index) => { return attackModifier.type == AttackModifierType.curse && index > gameManager.game.allyAttackModifierDeck.current; }).length; @@ -71,7 +71,7 @@ export class AttackModifierManager { countExtraMinus1(): number { let count = 0; - if (settingsManager.settings.alwaysAllyAttackModifierDeck || gameManager.fhRules() && gameManager.game.figures.some((figure) => figure instanceof Monster && (figure.isAlly || figure.isConfederated))) { + if (settingsManager.settings.alwaysAllyAttackModifierDeck || gameManager.fhRules() && gameManager.game.figures.some((figure) => figure instanceof Monster && (figure.isAlly || figure.isAllied))) { count += gameManager.game.allyAttackModifierDeck.cards.filter((attackModifier) => { return attackModifier.type == AttackModifierType.minus1extra; }).length; diff --git a/src/app/game/businesslogic/LootManager.ts b/src/app/game/businesslogic/LootManager.ts index fb255667f..cbf6572db 100644 --- a/src/app/game/businesslogic/LootManager.ts +++ b/src/app/game/businesslogic/LootManager.ts @@ -229,8 +229,8 @@ export class LootManager { break; case TreasureRewardType.calenderSection: if (reward.value && typeof reward.value === 'string' && reward.value.split('-').length > 1) { - const section = reward.value[0]; - const week = gameManager.game.party.weeks + (+reward.value[1]); + const section = reward.value.split('-')[0]; + const week = gameManager.game.party.weeks + (+reward.value.split('-')[1]); if (!gameManager.game.party.weekSections[week]) { gameManager.game.party.weekSections[week] = []; } diff --git a/src/app/game/businesslogic/MonsterManager.ts b/src/app/game/businesslogic/MonsterManager.ts index 33604ec10..641335dbc 100644 --- a/src/app/game/businesslogic/MonsterManager.ts +++ b/src/app/game/businesslogic/MonsterManager.ts @@ -315,9 +315,9 @@ export class MonsterManager { return monsterEntity; } - spawnMonsterEntity(monster: Monster, type: MonsterType, isAlly: boolean = false, isConfederated: boolean = false, drawExtra: boolean = false, summon: boolean = false): MonsterEntity | undefined { + spawnMonsterEntity(monster: Monster, type: MonsterType, isAlly: boolean = false, isAllied: boolean = false, drawExtra: boolean = false, summon: boolean = false): MonsterEntity | undefined { monster.isAlly = isAlly; - monster.isConfederated = isConfederated; + monster.isAllied = isAllied; monster.drawExtra = drawExtra; const monsterCount = this.monsterStandeeMax(monster); if (settingsManager.settings.automaticStandees && this.monsterStandeeCount(monster) < monsterCount) { diff --git a/src/app/game/businesslogic/ScenarioManager.ts b/src/app/game/businesslogic/ScenarioManager.ts index c5a91f555..acb7f1088 100644 --- a/src/app/game/businesslogic/ScenarioManager.ts +++ b/src/app/game/businesslogic/ScenarioManager.ts @@ -158,6 +158,18 @@ export class ScenarioManager { } }) } + + if (rewards.calenderSection) + rewards.calenderSection.forEach((calenderSection) => { + if (calenderSection.split('-').length > 1) { + const section = calenderSection.split('-')[0]; + const week = gameManager.game.party.weeks + (+calenderSection.split('-')[1]) + ((!casual && scenario && gameManager.fhRules() && !linkedScenario) ? 1 : 0); + if (!gameManager.game.party.weekSections[week]) { + gameManager.game.party.weekSections[week] = []; + } + gameManager.game.party.weekSections[week]?.push(section); + } + }) } if (conclusionSection) { @@ -221,7 +233,7 @@ export class ScenarioManager { let monster = gameManager.monsterManager.addMonsterByName(name, scenarioData.edition); if (monster) { monster.isAlly = scenarioData.allies && scenarioData.allies.indexOf(monsterName) != -1 || section && gameManager.game.scenario && gameManager.game.scenario.allies && gameManager.game.scenario.allies.indexOf(monsterName) != -1 || false; - monster.isConfederated = scenarioData.confederates && scenarioData.confederates.indexOf(monsterName) != -1 || section && gameManager.game.scenario && gameManager.game.scenario.confederates && gameManager.game.scenario.confederates.indexOf(monsterName) != -1 || false; + monster.isAllied = scenarioData.allied && scenarioData.allied.indexOf(monsterName) != -1 || section && gameManager.game.scenario && gameManager.game.scenario.allied && gameManager.game.scenario.allied.indexOf(monsterName) != -1 || false; monster.drawExtra = scenarioData.drawExtra && scenarioData.drawExtra.indexOf(monsterName) != -1 || section && gameManager.game.scenario && gameManager.game.scenario.drawExtra && gameManager.game.scenario.drawExtra.indexOf(monsterName) != -1 || false; } }); @@ -256,7 +268,7 @@ export class ScenarioManager { let monster = gameManager.monsterManager.addMonsterByName(name, scenarioData.edition); if (monster) { monster.isAlly = scenarioData.allies && scenarioData.allies.indexOf(monsterName) != -1 || section && gameManager.game.scenario && gameManager.game.scenario.allies && gameManager.game.scenario.allies.indexOf(monsterName) != -1 || false; - monster.isConfederated = scenarioData.confederates && scenarioData.confederates.indexOf(monsterName) != -1 || section && gameManager.game.scenario && gameManager.game.scenario.confederates && gameManager.game.scenario.confederates.indexOf(monsterName) != -1 || false; + monster.isAllied = scenarioData.allied && scenarioData.allied.indexOf(monsterName) != -1 || section && gameManager.game.scenario && gameManager.game.scenario.allied && gameManager.game.scenario.allied.indexOf(monsterName) != -1 || false; monster.drawExtra = scenarioData.drawExtra && scenarioData.drawExtra.indexOf(monsterName) != -1 || section && gameManager.game.scenario && gameManager.game.scenario.drawExtra && gameManager.game.scenario.drawExtra.indexOf(monsterName) != -1 || false; } } @@ -331,12 +343,12 @@ export class ScenarioManager { } else { const monsterName = monsterStandeeData.name.split(':')[0]; const isAlly = scenarioData.allies && scenarioData.allies.indexOf(monsterName) != -1 || section && gameManager.game.scenario && gameManager.game.scenario.allies && gameManager.game.scenario.allies.indexOf(monsterName) != -1 || false; - const isConfederated = scenarioData.confederates && scenarioData.confederates.indexOf(monsterName) != -1 || section && gameManager.game.scenario && gameManager.game.scenario.confederates && gameManager.game.scenario.confederates.indexOf(monsterName) != -1 || false; + const isAllied = scenarioData.allied && scenarioData.allied.indexOf(monsterName) != -1 || section && gameManager.game.scenario && gameManager.game.scenario.allied && gameManager.game.scenario.allied.indexOf(monsterName) != -1 || false; const drawExtra = scenarioData.drawExtra && scenarioData.drawExtra.indexOf(monsterName) != -1 || section && gameManager.game.scenario && gameManager.game.scenario.drawExtra && gameManager.game.scenario.drawExtra.indexOf(monsterName) != -1 || false; const monster = gameManager.monsterManager.addMonsterByName(monsterStandeeData.name, scenarioData.edition); if (monster) { - const entity = gameManager.monsterManager.spawnMonsterEntity(monster, type, isAlly, isConfederated, drawExtra); + const entity = gameManager.monsterManager.spawnMonsterEntity(monster, type, isAlly, isAllied, drawExtra); if (entity) { if (monsterStandeeData.marker) { entity.marker = monsterStandeeData.marker; diff --git a/src/app/game/businesslogic/SettingsManager.ts b/src/app/game/businesslogic/SettingsManager.ts index 269329bf1..990b32b09 100644 --- a/src/app/game/businesslogic/SettingsManager.ts +++ b/src/app/game/businesslogic/SettingsManager.ts @@ -33,10 +33,19 @@ export class SettingsManager { } async loadSettings() { + let loadDefault = false; try { - const settings = await storageManager.read('settings', 'default'); - this.setSettings(settings); + let settings = await storageManager.read('settings', 'default'); + if (settings) { + this.setSettings(settings); + } else { + loadDefault = true; + } } catch { + loadDefault = true; + } + + if (loadDefault) { try { await fetch('./ghs-settings-default.json') .then(response => { @@ -47,7 +56,7 @@ export class SettingsManager { }).then((value: Settings) => { this.setSettings(Object.assign(new Settings(), value)); }); - } catch (error) { + } catch { this.setSettings(new Settings()); } } @@ -84,7 +93,7 @@ export class SettingsManager { } storeSettings(): void { - storageManager.write('settings','default', this.settings); + storageManager.write('settings', 'default', this.settings); if (this.settings.serverSettings) { gameManager.stateManager.saveSettings(); } @@ -274,6 +283,11 @@ export class SettingsManager { this.storeSettings(); } + setDisableStatAnimations(disableStatAnimations: boolean) { + this.settings.disableStatAnimations = disableStatAnimations; + this.storeSettings(); + } + async setDisableWakeLock(disableWakeLock: boolean) { this.settings.disableWakeLock = disableWakeLock; if (disableWakeLock && gameManager.stateManager.wakeLock) { diff --git a/src/app/game/businesslogic/StateManager.ts b/src/app/game/businesslogic/StateManager.ts index 2b89a562c..d2e2014d8 100644 --- a/src/app/game/businesslogic/StateManager.ts +++ b/src/app/game/businesslogic/StateManager.ts @@ -251,6 +251,7 @@ export class StateManager { settings.browserNavigation = settingsManager.settings.browserNavigation; settings.debugRightClick = settingsManager.settings.debugRightClick; settings.disableAnimations = settingsManager.settings.disableAnimations; + settings.disableStatAnimations = settingsManager.settings.disableStatAnimations; settings.disableColumns = settingsManager.settings.disableColumns; settings.disableWakeLock = settingsManager.settings.disableWakeLock; settings.dragValues = settingsManager.settings.dragValues; diff --git a/src/app/game/businesslogic/StorageManager.ts b/src/app/game/businesslogic/StorageManager.ts index b19f08ccd..4816f529d 100644 --- a/src/app/game/businesslogic/StorageManager.ts +++ b/src/app/game/businesslogic/StorageManager.ts @@ -198,7 +198,9 @@ export class StorageManager { datadump['undo-infos'] = await this.readAll('undo-infos'); datadump['game-backup'] = await this.readAll('game-backup'); } else { - console.warn("No IndexedDB, fallback to Local Storage"); + if (!migrate) { + console.warn("No IndexedDB, fallback to Local Storage"); + } for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i); if (key) { diff --git a/src/app/game/model/Monster.ts b/src/app/game/model/Monster.ts index dcdcc90ba..21c53eb59 100644 --- a/src/app/game/model/Monster.ts +++ b/src/app/game/model/Monster.ts @@ -26,7 +26,7 @@ export class Monster extends MonsterData implements Figure { abilities: number[] = []; entities: MonsterEntity[] = []; isAlly: boolean = false; - isConfederated: boolean = false; + isAllied: boolean = false; constructor(monsterData: MonsterData, level: number = 1) { super(monsterData.name, monsterData.count, monsterData.standeeCount, monsterData.standeeShare, monsterData.standeeShareEdition, monsterData.baseStat, monsterData.stats, monsterData.edition, monsterData.deck, monsterData.boss, monsterData.flying, monsterData.immortal, monsterData.thumbnail, monsterData.thumbnailUrl, monsterData.spoiler, monsterData.catching); @@ -71,7 +71,7 @@ export class Monster extends MonsterData implements Figure { } toModel(): GameMonsterModel { - return new GameMonsterModel(this.name, this.edition, this.level, this.off, this.active, this.drawExtra, this.lastDraw, this.ability, this.abilities, this.entities.map((value) => value.toModel()), this.isAlly, this.isConfederated) + return new GameMonsterModel(this.name, this.edition, this.level, this.off, this.active, this.drawExtra, this.lastDraw, this.ability, this.abilities, this.entities.map((value) => value.toModel()), this.isAlly, this.isAllied) } @@ -105,7 +105,7 @@ export class Monster extends MonsterData implements Figure { entity.fromModel(value); }) this.isAlly = model.isAlly; - this.isConfederated = model.isConfederated; + this.isAllied = model.isAllied; } } @@ -121,7 +121,7 @@ export class GameMonsterModel { abilities: number[]; entities: GameMonsterEntityModel[]; isAlly: boolean; - isConfederated: boolean; + isAllied: boolean; constructor(name: string, edition: string, @@ -134,7 +134,7 @@ export class GameMonsterModel { abilities: number[], entities: GameMonsterEntityModel[], isAlly: boolean, - isConfederated: boolean) { + isAllied: boolean) { this.name = name; this.edition = edition; this.level = level; @@ -146,6 +146,6 @@ export class GameMonsterModel { this.abilities = JSON.parse(JSON.stringify(abilities)); this.entities = JSON.parse(JSON.stringify(entities)); this.isAlly = isAlly; - this.isConfederated = isConfederated; + this.isAllied = isAllied; } } \ No newline at end of file diff --git a/src/app/game/model/Settings.ts b/src/app/game/model/Settings.ts index 04808f4d9..b971c81d2 100644 --- a/src/app/game/model/Settings.ts +++ b/src/app/game/model/Settings.ts @@ -35,6 +35,7 @@ export class Settings { disabledTurnConfirmation: boolean = false; disableSortFigures: boolean = false; disableStandees: boolean = false; + disableStatAnimations: boolean = false; disableWakeLock: boolean = false; dragValues: boolean = true; editionDataUrls: string[] = []; diff --git a/src/app/game/model/data/ScenarioData.ts b/src/app/game/model/data/ScenarioData.ts index 6eeba3fcc..ea35e214c 100644 --- a/src/app/game/model/data/ScenarioData.ts +++ b/src/app/game/model/data/ScenarioData.ts @@ -19,7 +19,7 @@ export class ScenarioData implements Editional, Spoilable { group: string | undefined; monsters: string[] = []; allies: string[] = []; - confederates: string[] = []; + allied: string[] = []; drawExtra: string[] = []; objectives: ObjectiveData[] = []; rooms: RoomData[] = [] = []; @@ -57,7 +57,7 @@ export class ScenarioData implements Editional, Spoilable { this.group = scenarioData.group; this.monsters = scenarioData.monsters; this.allies = scenarioData.allies; - this.confederates = scenarioData.confederates; + this.allied = scenarioData.allied; this.drawExtra = scenarioData.drawExtra; this.objectives = scenarioData.objectives; this.rooms = scenarioData.rooms; diff --git a/src/app/game/model/data/ScenarioRule.ts b/src/app/game/model/data/ScenarioRule.ts index 35754045f..f3f49197e 100644 --- a/src/app/game/model/data/ScenarioRule.ts +++ b/src/app/game/model/data/ScenarioRule.ts @@ -105,6 +105,7 @@ export class ScenarioRewards { chooseItem: string[] = []; itemDesigns: string[] = []; events: string[] = []; + calenderSection: string[] = []; custom: string = ""; ignoredBonus: string[] = []; hints: ScenarioRewardHints | undefined = undefined; @@ -129,6 +130,7 @@ export class ScenarioRewardHints { chooseItem: string[] = []; itemDesigns: string[] = []; events: string[] = []; + calenderSection: string[] = []; } export class ScenarioRuleIdentifier { diff --git a/src/app/ui/figures/actions/action.ts b/src/app/ui/figures/actions/action.ts index dc20894dc..b6a34ced4 100644 --- a/src/app/ui/figures/actions/action.ts +++ b/src/app/ui/figures/actions/action.ts @@ -187,7 +187,7 @@ export class ActionComponent implements OnInit { break; } - if (sign && (typeof this.action.value === 'number' || this.action.value.match(EntityExpressionRegex) || this.action.value.match(EntityValueRegex))) { + if (sign && this.action.value && (typeof this.action.value === 'number' || this.action.value.match(EntityExpressionRegex) || this.action.value.match(EntityValueRegex))) { if (this.action.valueType == ActionValueType.plus) { return statValue + EntityValueFunction(this.action.value); } else if (this.action.valueType == ActionValueType.minus) { diff --git a/src/app/ui/figures/actions/summon/action-summon.ts b/src/app/ui/figures/actions/summon/action-summon.ts index a3bb65a31..c0c11d961 100644 --- a/src/app/ui/figures/actions/summon/action-summon.ts +++ b/src/app/ui/figures/actions/summon/action-summon.ts @@ -199,7 +199,7 @@ export class ActionSummonComponent implements OnChanges { const monster = gameManager.monsterManager.addMonsterByName(spawn.monster.name, this.monster && this.monster.edition || gameManager.currentEdition()); if (monster) { for (let i = 0; i < count; i++) { - const entity = gameManager.monsterManager.spawnMonsterEntity(monster, spawn.monster.type, monster.isAlly, monster.isConfederated, monster.drawExtra, !this.isSpawn); + const entity = gameManager.monsterManager.spawnMonsterEntity(monster, spawn.monster.type, monster.isAlly, monster.isAllied, monster.drawExtra, !this.isSpawn); if (entity) { const tag = this.getTag(index); entity.tags = entity.tags || []; diff --git a/src/app/ui/figures/entities-menu/entities-menu-dialog.html b/src/app/ui/figures/entities-menu/entities-menu-dialog.html index c310d2236..ca6c4d464 100644 --- a/src/app/ui/figures/entities-menu/entities-menu-dialog.html +++ b/src/app/ui/figures/entities-menu/entities-menu-dialog.html @@ -3,10 +3,8 @@
{{'data.monster.' + data.monster.name | ghsLabel}}  - ({{'game.ally' | - ghsLabel}})  - ({{'game.confederated' | - ghsLabel}})  + {{'game.ally' | ghsLabel}}  + {{'game.allied' | ghsLabel}} 
diff --git a/src/app/ui/figures/entity-menu/entity-menu-dialog.html b/src/app/ui/figures/entity-menu/entity-menu-dialog.html index 16257e4e7..4d7adbc1c 100644 --- a/src/app/ui/figures/entity-menu/entity-menu-dialog.html +++ b/src/app/ui/figures/entity-menu/entity-menu-dialog.html @@ -27,8 +27,8 @@ {{'data.monster.' + data.figure.name | ghsLabel}}  - ({{'game.ally' | ghsLabel}})  - ({{'game.confederated' | ghsLabel}})  + {{'game.ally' | ghsLabel}}  + {{'game.allied' | ghsLabel}} 
- +
- +
@@ -172,13 +174,13 @@ {{countUpcomingAttackModifier(AttackModifierType.curse) + this.curse}} + *ngIf="gameManager.attackModifierManager.countUpcomingCurses(gameManager.isMonster(data.figure) && !gameManager.toMonster(data.figure).isAlly && !gameManager.toMonster(data.figure).isAllied) + this.curse > 10"> diff --git a/src/app/ui/figures/entity-menu/entity-menu-dialog.ts b/src/app/ui/figures/entity-menu/entity-menu-dialog.ts index a0f5ac664..7e6a893d8 100644 --- a/src/app/ui/figures/entity-menu/entity-menu-dialog.ts +++ b/src/app/ui/figures/entity-menu/entity-menu-dialog.ts @@ -120,7 +120,7 @@ export class EntityMenuDialogComponent { } beforeAttackModifierDeck(change: AttackModiferDeckChange) { - gameManager.stateManager.before("updateAttackModifierDeck." + change.type, this.data.figure instanceof Character ? "data.character." + this.data.figure.name : (this.data.figure instanceof Monster && (this.data.figure.isAlly || this.data.figure.isConfederated) ? 'ally' : 'monster'), ...change.values); + gameManager.stateManager.before("updateAttackModifierDeck." + change.type, this.data.figure instanceof Character ? "data.character." + this.data.figure.name : (this.data.figure instanceof Monster && (this.data.figure.isAlly || this.data.figure.isAllied) ? 'ally' : 'monster'), ...change.values); } afterAttackModifierDeck(change: AttackModiferDeckChange) { @@ -150,7 +150,7 @@ export class EntityMenuDialogComponent { if (value > 0) { if (type == AttackModifierType.bless && gameManager.attackModifierManager.countUpcomingBlesses() >= 10) { return; - } else if (type == AttackModifierType.curse && gameManager.attackModifierManager.countUpcomingCurses(this.data.figure instanceof Monster && !this.data.figure.isAlly && !this.data.figure.isConfederated) >= 10) { + } else if (type == AttackModifierType.curse && gameManager.attackModifierManager.countUpcomingCurses(this.data.figure instanceof Monster && !this.data.figure.isAlly && !this.data.figure.isAllied) >= 10) { return; } for (let i = 0; i < value; i++) { @@ -185,7 +185,7 @@ export class EntityMenuDialogComponent { changeCurse(value: number) { if (this.data.figure instanceof Character || this.data.figure instanceof Monster) { this.curse += value; - const existing = gameManager.attackModifierManager.countUpcomingCurses(this.data.figure instanceof Monster && !this.data.figure.isAlly && !this.data.figure.isConfederated); + const existing = gameManager.attackModifierManager.countUpcomingCurses(this.data.figure instanceof Monster && !this.data.figure.isAlly && !this.data.figure.isAllied); if (this.curse + existing >= 10) { this.curse = 10 - existing; } else if (this.curse + existing < 0) { diff --git a/src/app/ui/figures/monster/dialogs/level-dialog.html b/src/app/ui/figures/monster/dialogs/level-dialog.html index 7a9ff4b58..f03b6c42c 100644 --- a/src/app/ui/figures/monster/dialogs/level-dialog.html +++ b/src/app/ui/figures/monster/dialogs/level-dialog.html @@ -1,8 +1,8 @@
\ No newline at end of file diff --git a/src/app/ui/figures/monster/dialogs/level-dialog.ts b/src/app/ui/figures/monster/dialogs/level-dialog.ts index 434235aeb..00d007176 100644 --- a/src/app/ui/figures/monster/dialogs/level-dialog.ts +++ b/src/app/ui/figures/monster/dialogs/level-dialog.ts @@ -29,9 +29,9 @@ export class MonsterLevelDialogComponent { gameManager.stateManager.after(); } - toggleConfederated() { - gameManager.stateManager.before(this.monster.isConfederated ? "unsetConfederated" : "setConfederated", "data.monster." + this.monster.name); - this.monster.isConfederated = !this.monster.isConfederated; + toggleallied() { + gameManager.stateManager.before(this.monster.isAllied ? "unsetallied" : "setallied", "data.monster." + this.monster.name); + this.monster.isAllied = !this.monster.isAllied; gameManager.stateManager.after(); } diff --git a/src/app/ui/figures/monster/stats/stat-dialog.ts b/src/app/ui/figures/monster/stats/stat-dialog.ts index 1fa527550..ed2364403 100644 --- a/src/app/ui/figures/monster/stats/stat-dialog.ts +++ b/src/app/ui/figures/monster/stats/stat-dialog.ts @@ -35,7 +35,7 @@ export class MonsterStatDialogComponent implements OnInit { gameManager.monsterManager.addMonsterEntity(monster, 1, MonsterType.elite); } monster.isAlly = this.monster.isAlly; - monster.isConfederated = this.monster.isConfederated; + monster.isAllied = this.monster.isAllied; monster.level = this.monster.level < 4 ? this.monster.level + 4 : this.monster.level - 4; monster.errors = this.monster.errors; return monster; diff --git a/src/app/ui/figures/monster/stats/stats-dialog.html b/src/app/ui/figures/monster/stats/stats-dialog.html index feeb32036..de5a59be6 100644 --- a/src/app/ui/figures/monster/stats/stats-dialog.html +++ b/src/app/ui/figures/monster/stats/stats-dialog.html @@ -1,8 +1,8 @@
{{'data.monster.' + monster.name | ghsLabel}} - ({{'game.ally' | ghsLabel}}) - ({{'game.confederated' | ghsLabel}}) + {{'game.ally' | ghsLabel}} + {{'game.allied' | ghsLabel}} [{{'data.edition.' + getEdition()| ghsLabel}}]
diff --git a/src/app/ui/figures/monster/stats/stats-dialog.ts b/src/app/ui/figures/monster/stats/stats-dialog.ts index 48378fee7..607354129 100644 --- a/src/app/ui/figures/monster/stats/stats-dialog.ts +++ b/src/app/ui/figures/monster/stats/stats-dialog.ts @@ -31,7 +31,7 @@ export class MonsterStatsDialogComponent { gameManager.monsterManager.addMonsterEntity(monster, level, MonsterType.elite); } monster.isAlly = this.monster.isAlly; - monster.isConfederated = this.monster.isConfederated; + monster.isAllied = this.monster.isAllied; monster.level = level; monster.errors = this.monster.errors; return monster; diff --git a/src/app/ui/figures/monster/stats/stats.html b/src/app/ui/figures/monster/stats/stats.html index ee658b5d8..c246284ac 100644 --- a/src/app/ui/figures/monster/stats/stats.html +++ b/src/app/ui/figures/monster/stats/stats.html @@ -8,8 +8,8 @@ [disabled]="noClick"> {{'data.monster.' + monster.name | ghsLabel}} - ({{'game.ally' | ghsLabel}}) - ({{'game.confederated' | ghsLabel}}) + {{'game.ally' | ghsLabel}} + {{'game.allied' | ghsLabel}} @@ -17,8 +17,8 @@
-
{ + if (settingsManager.settings.disableStatAnimations) { + this.highlightActions = []; + } else { + this.highlightActions = [ActionType.shield, ActionType.retaliate]; + } + } + }) } hideStats(type: MonsterType) { @@ -86,9 +98,9 @@ export class MonsterStatsComponent implements OnInit { gameManager.stateManager.after(); } - toggleConfederated() { - gameManager.stateManager.before(this.monster.isConfederated ? "unsetConfederated" : "setConfederated", "data.monster." + this.monster.name); - this.monster.isConfederated = !this.monster.isConfederated; + toggleallied() { + gameManager.stateManager.before(this.monster.isAllied ? "unsetallied" : "setallied", "data.monster." + this.monster.name); + this.monster.isAllied = !this.monster.isAllied; gameManager.stateManager.after(); } diff --git a/src/app/ui/figures/objective/objective.html b/src/app/ui/figures/objective/objective.html index 09bdd97ba..848b719fa 100644 --- a/src/app/ui/figures/objective/objective.html +++ b/src/app/ui/figures/objective/objective.html @@ -72,7 +72,7 @@
- +
diff --git a/src/app/ui/figures/objective/objective.scss b/src/app/ui/figures/objective/objective.scss index c2d62f3b4..913b11a13 100644 --- a/src/app/ui/figures/objective/objective.scss +++ b/src/app/ui/figures/objective/objective.scss @@ -160,16 +160,12 @@ .actions { width: calc(var(--ghs-unit) * 30); + height: calc(var(--ghs-unit) * 11); + margin: calc(var(--ghs-unit) * 1.5) 0; margin-left: calc(var(--ghs-unit) * 1); - padding-top: calc(var(--ghs-unit) * 2.5); display: flex; - flex-wrap: wrap; - font-family: var(--ghs-font-normal); font-size: calc(var(--ghs-unit) * 2.5); - - ghs-action { - margin: 0 calc(var(--ghs-unit) * 0.5); - } + overflow: auto; } .markers { diff --git a/src/app/ui/footer/footer.ts b/src/app/ui/footer/footer.ts index f8a1f675e..147de1a20 100644 --- a/src/app/ui/footer/footer.ts +++ b/src/app/ui/footer/footer.ts @@ -36,13 +36,13 @@ export class FooterComponent implements OnInit { constructor(private dialog: Dialog, private overlay: Overlay) { } ngOnInit(): void { - this.hasAllyAttackModifierDeck = settingsManager.settings.allyAttackModifierDeck && (settingsManager.settings.alwaysAllyAttackModifierDeck || gameManager.fhRules() && gameManager.game.figures.some((figure) => figure instanceof Monster && (figure.isAlly || figure.isConfederated) || figure instanceof Objective && figure.objectiveId && gameManager.objectiveDataByScenarioObjectiveIdentifier(figure.objectiveId)?.allyDeck) || gameManager.game.scenario && gameManager.game.scenario.allyDeck) || false; + this.hasAllyAttackModifierDeck = settingsManager.settings.allyAttackModifierDeck && (settingsManager.settings.alwaysAllyAttackModifierDeck || gameManager.fhRules() && gameManager.game.figures.some((figure) => figure instanceof Monster && (figure.isAlly || figure.isAllied) || figure instanceof Objective && figure.objectiveId && gameManager.objectiveDataByScenarioObjectiveIdentifier(figure.objectiveId)?.allyDeck) || gameManager.game.scenario && gameManager.game.scenario.allyDeck) || false; this.lootDeck = settingsManager.settings.lootDeck && Object.keys(gameManager.game.lootDeck.cards).length > 0; gameManager.uiChange.subscribe({ next: () => { - this.hasAllyAttackModifierDeck = settingsManager.settings.allyAttackModifierDeck && (settingsManager.settings.alwaysAllyAttackModifierDeck || gameManager.fhRules() && gameManager.game.figures.some((figure) => figure instanceof Monster && (figure.isAlly || figure.isConfederated) || figure instanceof Objective && figure.objectiveId && gameManager.objectiveDataByScenarioObjectiveIdentifier(figure.objectiveId)?.allyDeck) || gameManager.game.scenario && gameManager.game.scenario.allyDeck) || false; + this.hasAllyAttackModifierDeck = settingsManager.settings.allyAttackModifierDeck && (settingsManager.settings.alwaysAllyAttackModifierDeck || gameManager.fhRules() && gameManager.game.figures.some((figure) => figure instanceof Monster && (figure.isAlly || figure.isAllied) || figure instanceof Objective && figure.objectiveId && gameManager.objectiveDataByScenarioObjectiveIdentifier(figure.objectiveId)?.allyDeck) || gameManager.game.scenario && gameManager.game.scenario.allyDeck) || false; this.lootDeck = settingsManager.settings.lootDeck && Object.keys(gameManager.game.lootDeck.cards).length > 0; } }) diff --git a/src/app/ui/footer/scenario-rules/scenario-rules.ts b/src/app/ui/footer/scenario-rules/scenario-rules.ts index 67063c7f5..3ed0c10f4 100644 --- a/src/app/ui/footer/scenario-rules/scenario-rules.ts +++ b/src/app/ui/footer/scenario-rules/scenario-rules.ts @@ -242,7 +242,7 @@ export class ScenarioRulesComponent { const monster = gameManager.monsterManager.addMonsterByName(spawn.monster.name, scenario.edition); if (monster) { for (let i = 0; i < this.spawnCount(rule, spawn); i++) { - let entity = gameManager.monsterManager.spawnMonsterEntity(monster, type, scenario.allies && scenario.allies.indexOf(spawn.monster.name) != -1, scenario.confederates && scenario.confederates.indexOf(spawn.monster.name) != -1, scenario.drawExtra && scenario.drawExtra.indexOf(spawn.monster.name) != -1, spawn.summon); + let entity = gameManager.monsterManager.spawnMonsterEntity(monster, type, scenario.allies && scenario.allies.indexOf(spawn.monster.name) != -1, scenario.allied && scenario.allied.indexOf(spawn.monster.name) != -1, scenario.drawExtra && scenario.drawExtra.indexOf(spawn.monster.name) != -1, spawn.summon); if (entity) { if (spawn.monster.marker) { entity.marker = spawn.monster.marker; @@ -422,7 +422,7 @@ export class ScenarioRulesComponent { monster.ability = figure.ability; monster.isAlly = figure.isAlly; - monster.isConfederated = figure.isConfederated; + monster.isAllied = figure.isAllied; monster.entities = figure.entities; monster.entities.forEach((entity) => { diff --git a/src/app/ui/footer/scenario/dialog/abilities/stats-list.ts b/src/app/ui/footer/scenario/dialog/abilities/stats-list.ts index 5075ffaad..3cfc8ec2f 100644 --- a/src/app/ui/footer/scenario/dialog/abilities/stats-list.ts +++ b/src/app/ui/footer/scenario/dialog/abilities/stats-list.ts @@ -39,7 +39,7 @@ export class StatsListComponent { gameManager.monsterManager.addMonsterEntity(monster, level, MonsterType.elite); } monster.isAlly = this.monster.isAlly; - monster.isConfederated = this.monster.isConfederated; + monster.isAllied = this.monster.isAllied; monster.level = level; monster.errors = this.monster.errors; return monster; diff --git a/src/app/ui/footer/scenario/summary/scenario-summary.html b/src/app/ui/footer/scenario/summary/scenario-summary.html index f31164ed2..f865aac44 100644 --- a/src/app/ui/footer/scenario/summary/scenario-summary.html +++ b/src/app/ui/footer/scenario/summary/scenario-summary.html @@ -185,7 +185,8 @@ ? 'ignore' : 'reapply') | ghsLabel}}
- +
+ +
+
+ + +
+
+
diff --git a/src/app/ui/header/menu/server/server.html b/src/app/ui/header/menu/server/server.html index f87237921..add036f1b 100644 --- a/src/app/ui/header/menu/server/server.html +++ b/src/app/ui/header/menu/server/server.html @@ -219,8 +219,8 @@ diff --git a/src/app/ui/header/menu/settings/settings.html b/src/app/ui/header/menu/settings/settings.html index a408a062e..496bdfa70 100644 --- a/src/app/ui/header/menu/settings/settings.html +++ b/src/app/ui/header/menu/settings/settings.html @@ -293,6 +293,20 @@
+ +
+
+ + + + + +
+
@@ -507,11 +521,11 @@ -
+
-