diff --git a/data/fh/scenarios/093B.json b/data/fh/scenarios/093B.json index a73fa87a8..d3947dc1c 100644 --- a/data/fh/scenarios/093B.json +++ b/data/fh/scenarios/093B.json @@ -4,8 +4,8 @@ "edition": "fh", "complexity": 2, "rewards": { - "items": [ - "235" + "itemBlueprints": [ + "79" ] }, "monsters": [ diff --git a/package-lock.json b/package-lock.json index e9ede4772..6b7ca2409 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "gloomhavensecretariat", - "version": "0.83.6", + "version": "0.83.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "gloomhavensecretariat", - "version": "0.83.6", + "version": "0.83.7", "license": "AGPL3", "dependencies": { "@angular/animations": "^17.0.6", diff --git a/package.json b/package.json index 5773cefc3..563bdb5dd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gloomhavensecretariat", - "version": "0.83.6", + "version": "0.83.7", "license": "AGPL3", "description": "Gloomhaven Secretariat is a Gloomhaven Companion app.", "homepage": "https://gloomhaven-secretariat.de", diff --git a/src/app/ui/figures/actions/action.ts b/src/app/ui/figures/actions/action.ts index 25a97f1df..914d00ce3 100644 --- a/src/app/ui/figures/actions/action.ts +++ b/src/app/ui/figures/actions/action.ts @@ -235,6 +235,9 @@ export class ActionComponent implements OnInit, OnDestroy { if (this.action.valueType == ActionValueType.plus) { return statValue + EntityValueFunction(this.action.value); } else if (this.action.valueType == ActionValueType.minus) { + if (!statValue) { + return "-"; + } return statValue - EntityValueFunction(this.action.value); } } diff --git a/src/app/ui/footer/scenario/summary/scenario-summary.ts b/src/app/ui/footer/scenario/summary/scenario-summary.ts index 8ff14b4f6..362a691c4 100644 --- a/src/app/ui/footer/scenario/summary/scenario-summary.ts +++ b/src/app/ui/footer/scenario/summary/scenario-summary.ts @@ -534,18 +534,42 @@ export class ScenarioSummaryComponent { } changeCollectiveGold(event: any, index: number) { - gameManager.stateManager.before("finishScenario.dialog.collectiveGold", '' + index, event.target.value); - this.collectiveGold[index] = +event.target.value; - this.updateFinish(); - gameManager.stateManager.after(); + let value = +event.target.value; + const old = this.collectiveGold[index] || 0; + this.collectiveGold[index] = 0; + if (value < 0) { + value = 0; + } else if (value > this.availableCollectiveGold()) { + value = this.availableCollectiveGold(); + } + this.collectiveGold[index] = old; + if (value != (this.collectiveGold[index] || 0)) { + gameManager.stateManager.before("finishScenario.dialog.collectiveGold", '' + index, event.target.value); + this.collectiveGold[index] = +event.target.value; + this.updateFinish(); + gameManager.stateManager.after(); + } + event.target.value = value; } changeCollectiveResource(event: any, index: number, type: LootType) { - gameManager.stateManager.before("finishScenario.dialog.collectiveResource", type, '' + index, event.target.value); - this.collectiveResources[index] = this.collectiveResources[index] || {}; - this.collectiveResources[index][type] = +event.target.value; - this.updateFinish(); - gameManager.stateManager.after(); + let value = +event.target.value; + const old = this.collectiveResources[index][type] || 0; + this.collectiveResources[index][type] = 0; + if (value < 0) { + value = 0; + } else if (value > this.availableCollectiveResource(type)) { + value = this.availableCollectiveResource(type); + } + this.collectiveResources[index][type] = old; + if (value != (this.collectiveResources[index][type] || 0)) { + gameManager.stateManager.before("finishScenario.dialog.collectiveResource", type, '' + index, event.target.value); + this.collectiveResources[index] = this.collectiveResources[index] || {}; + this.collectiveResources[index][type] = value; + this.updateFinish(); + gameManager.stateManager.after(); + } + event.target.value = value; } changeCalendarSectionManual(event: any, index: number) { diff --git a/src/app/ui/header/element/element.scss b/src/app/ui/header/element/element.scss index 25e4dd423..14111fd6c 100644 --- a/src/app/ui/header/element/element.scss +++ b/src/app/ui/header/element/element.scss @@ -67,9 +67,10 @@ ghs-element { } } - &.new #outline { - display: none; + &.new #outline path { + fill: var(--ghs-color-gray) !important; } + } &:hover .element-svg { @@ -78,6 +79,10 @@ ghs-element { #bg { opacity: 1 !important; } + + &.new #outline path { + fill: var(--ghs-color-white) !important; + } } &.consume { diff --git a/src/app/ui/header/menu/settings/settings.html b/src/app/ui/header/menu/settings/settings.html index ade639b70..a3365d038 100644 --- a/src/app/ui/header/menu/settings/settings.html +++ b/src/app/ui/header/menu/settings/settings.html @@ -659,14 +659,15 @@
+ [ngClass]="{'immunity': settingsManager.settings.applyConditionsExcludes.indexOf(condition.name) != -1}" + (click)="toggleApplyConditionsExclude(condition.name)"> + [src]="'./assets/images' + (settingsManager.settings.fhStyle ? '/fh' : '') + '/condition/' + condition.name + '.svg'" /> + X
- +
@@ -710,14 +711,15 @@
+ [ngClass]="{'immunity': settingsManager.settings.activeApplyConditionsExcludes.indexOf(condition.name) != -1}" + (click)="toggleActiveApplyConditionsExclude(condition.name)"> + [src]="'./assets/images' + (settingsManager.settings.fhStyle ? '/fh' : '') + '/condition/' + condition.name + '.svg'" /> + X
- +
diff --git a/src/app/ui/header/menu/settings/settings.scss b/src/app/ui/header/menu/settings/settings.scss index cdd8f32dc..d1ab39789 100644 --- a/src/app/ui/header/menu/settings/settings.scss +++ b/src/app/ui/header/menu/settings/settings.scss @@ -26,6 +26,8 @@ cursor: pointer; width: calc(var(--ghs-unit) * 3.5 * var(--ghs-dialog-factor)); height: calc(var(--ghs-unit) * 3.5 * var(--ghs-dialog-factor)); + position: relative; + display: flex; &.immunity { opacity: 0.7; @@ -41,6 +43,16 @@ width: 100%; height: auto; } + + .value { + font-family: var(--ghs-font-title); + font-size: calc(var(--ghs-unit) * 1.3 * var(--ghs-dialog-factor)); + color: var(--ghs-color-white); + position: absolute; + bottom: 0; + left: calc(var(--ghs-unit) * 1.8 * var(--ghs-dialog-factor)); + transform: translateX(-50%); + } } .hint-trigger { diff --git a/src/app/ui/header/menu/settings/settings.ts b/src/app/ui/header/menu/settings/settings.ts index 3aaafc077..333865aba 100644 --- a/src/app/ui/header/menu/settings/settings.ts +++ b/src/app/ui/header/menu/settings/settings.ts @@ -22,19 +22,22 @@ export class SettingsMenuComponent { GameState = GameState; SubMenu = SubMenu; wakeLock: boolean; - applyConditionsExcludes: ConditionName[] = []; - activeApplyConditionsExcludes: ConditionName[] = []; + applyConditionsExcludes: Condition[] = []; + activeApplyConditionsExcludes: Condition[] = []; WebSocket = WebSocket; + ConditionType = ConditionType; constructor(public platform: Platform) { this.wakeLock = 'wakeLock' in navigator; Object.keys(ConditionName).forEach((conditionName) => { const condition = new Condition(conditionName); - if (condition.types.indexOf(ConditionType.turn) != -1 || condition.types.indexOf(ConditionType.afterTurn) != -1) { - this.applyConditionsExcludes.push(condition.name); - } if (condition.types.indexOf(ConditionType.apply) != -1) { - this.activeApplyConditionsExcludes.push(condition.name); + if (!gameManager.game.edition || gameManager.conditions(gameManager.game.edition).map((condition) => condition.name).indexOf(condition.name) != -1 || condition.types.indexOf(ConditionType.hidden) != -1) { + if (condition.types.indexOf(ConditionType.turn) != -1 || condition.types.indexOf(ConditionType.afterTurn) != -1) { + this.applyConditionsExcludes.push(condition); + } if (condition.types.indexOf(ConditionType.apply) != -1) { + this.activeApplyConditionsExcludes.push(condition); + } } }) } diff --git a/src/app/ui/helper/label.ts b/src/app/ui/helper/label.ts index 5629f53ff..311bc4a23 100644 --- a/src/app/ui/helper/label.ts +++ b/src/app/ui/helper/label.ts @@ -36,16 +36,15 @@ export const applyPlaceholder = function (value: string, placeholder: string[] = let replace: string = match; let image: string = ''; if (type == "condition") { - image = ''; + image = ''; + image += ''; if (value) { image += '' + value + ''; } - replace = '' + (fh ? ' ' : settingsManager.getLabel('game.condition.' + split[2])) + image + ''; + image += ''; + replace = '' + (fh ? ' ' : settingsManager.getLabel('game.condition.' + split[2], [value ? value : ''])) + image + ''; } else if (type == "immunity") { - image = ''; - if (value) { - image += '' + value + ''; - } + image = '' + (value ? '' + value + '' : '') + ''; replace = '' + (fh ? ' ' : settingsManager.getLabel('game.condition.' + split[2])) + image + ''; } else if (type == "action" && split.length == 3 && !split[2].startsWith('specialTarget') && !split[2].startsWith('summon') && !split[2].startsWith('area')) { split.splice(0, 1); diff --git a/src/assets/locales/de.json b/src/assets/locales/de.json index ccea2483a..cb67d8869 100644 --- a/src/assets/locales/de.json +++ b/src/assets/locales/de.json @@ -1411,7 +1411,7 @@ "brittle": "Nachfragen ob nach erhaltenden Schaden %game.condition.brittle% angewendet werden soll um den Schaden zu erhöhen.", "heal": "Kein Zustand, aber eine Hilfe ob %game.action.heal% angwendet werden soll wenn die Trefferpunkte erhöht werden.", "poison": "Nachfragen ob nach erhaltenden Schaden %game.action.attack% +1 von %game.condition.poison% angewendet werden soll (inklusive %game.attackmodifier.double%).", - "poison_x": "Nachfragen ob nach erhaltenden Schaden %game.action.attack% +1 von %game.condition.poison_x% angewendet werden soll (inklusive %game.attackmodifier.double%).", + "poison_x": "Nachfragen ob nach erhaltenden Schaden %game.action.attack% +X von %game.condition.poison_x:X% angewendet werden soll (inklusive %game.attackmodifier.double%).", "shield": "Kein Zustand, aber eine Hilfe ob nach erhaltenden Schaden %game.action.shield% angwendet werden soll.", "ward": "Nachfragen ob nach erhaltenden Schaden %game.condition.ward% angewendet werden soll um den erhaltenden Schaden zu reduzieren." } @@ -1468,7 +1468,7 @@ "bane": "Am Ende des Zuges automatisch %game.condition.bane% Schaden hinzufügen.", "regenerate": "Am Anfang des Zuges automatisch %game.condition.regenerate% anwenden.", "wound": "Am Anfang des Zuges automatisch %game.condition.wound% Schaden hinzufügen.", - "wound_x": "Am Anfang des Zuges automatisch %game.condition.wound_x% Schaden hinzufügen." + "wound_x": "Am Anfang des Zuges automatisch %game.condition.wound_x:X% Schaden hinzufügen." } }, "applyLongRest": { diff --git a/src/assets/locales/en.json b/src/assets/locales/en.json index 9c7cefe3f..ab1d6c8bf 100644 --- a/src/assets/locales/en.json +++ b/src/assets/locales/en.json @@ -1560,7 +1560,7 @@ "brittle": "On suffering damage, ask to apply %game.condition.brittle% and increase damage.", "heal": "No condition, but helper if %game.action.heal% should be applied when increasing hitpoints.", "poison": "On suffering damage, ask to apply %game.action.attack% +1 from %game.condition.poison% (including %game.attackmodifier.double%).", - "poison_x": "On suffering damage, ask to apply %game.action.attack% +1 from %game.condition.poison_x% (including %game.attackmodifier.double%).", + "poison_x": "On suffering damage, ask to apply %game.action.attack% +X from %game.condition.poison_x:X% (including %game.attackmodifier.double%).", "shield": "No condition, but helper if %game.action.shield% should be applied when taking damage.", "ward": "On suffering damage, ask to apply %game.condition.ward% and lowering damage." } @@ -1617,7 +1617,7 @@ "bane": "Automatic apply %game.condition.bane% damage at end of turn.", "regenerate": "Automatic apply %game.condition.regenerate% at start of turn.", "wound": "Automatic apply %game.condition.wound% damage at end of turn.", - "wound_x": "Automatic apply %game.condition.wound_x% damage at end of turn." + "wound_x": "Automatic apply %game.condition.wound_x:X% damage at end of turn." } }, "applyLongRest": { diff --git a/src/styles.scss b/src/styles.scss index 3991ac343..feeca1de6 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -1063,6 +1063,16 @@ input[type="radio"] { .icon { margin: 0; } + + .value { + font-family: var(--ghs-font-title); + font-size: 0.6em; + color: var(--ghs-color-white); + position: absolute; + bottom: -0.2em; + left: 1.1em; + transform: translateX(-50%); + } } }