diff --git a/package-lock.json b/package-lock.json index 6eb04817d..b7966788e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "gloomhavensecretariat", - "version": "0.80.4", + "version": "0.80.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "gloomhavensecretariat", - "version": "0.80.4", + "version": "0.80.5", "license": "AGPL3", "dependencies": { "@angular/animations": "^16.2.11", diff --git a/package.json b/package.json index ef409a9fb..8747f2655 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gloomhavensecretariat", - "version": "0.80.4", + "version": "0.80.5", "license": "AGPL3", "description": "Gloomhaven Secretariat is a Gloomhaven Companion app.", "homepage": "https://gloomhaven-secretariat.de", diff --git a/src/app/game/model/ObjectiveEntity.ts b/src/app/game/model/ObjectiveEntity.ts index 4300dcfff..5392d2736 100644 --- a/src/app/game/model/ObjectiveEntity.ts +++ b/src/app/game/model/ObjectiveEntity.ts @@ -10,10 +10,6 @@ export class ObjectiveEntity implements Entity { dormant: boolean = false; revealed: boolean = false; - // workaround - type: "" = ""; - summon: "" = ""; - // from entity active: boolean = false; off: boolean = false; diff --git a/src/app/ui/figures/character/character.html b/src/app/ui/figures/character/character.html index ed127ee0b..1ba80b116 100644 --- a/src/app/ui/figures/character/character.html +++ b/src/app/ui/figures/character/character.html @@ -183,7 +183,8 @@
+ (singleClick)="openItems()" (doubleClick)="openItems(true)" [ghs-label]="'game.items'" + [ghs-label-attribute]="'title'">
diff --git a/src/app/ui/figures/character/summon/summon.html b/src/app/ui/figures/character/summon/summon.html index 16b869352..90fbbbfb0 100644 --- a/src/app/ui/figures/character/summon/summon.html +++ b/src/app/ui/figures/character/summon/summon.html @@ -38,7 +38,7 @@
- + diff --git a/src/app/ui/figures/character/summon/summon.ts b/src/app/ui/figures/character/summon/summon.ts index f4760e209..4570ca687 100644 --- a/src/app/ui/figures/character/summon/summon.ts +++ b/src/app/ui/figures/character/summon/summon.ts @@ -163,4 +163,9 @@ export class SummonEntityComponent implements OnInit, OnDestroy { } } + removeCondition(entityCondition: EntityCondition) { + gameManager.stateManager.before(...gameManager.entityManager.undoInfos(this.summon, this.character, "removeCondition"), entityCondition.name); + gameManager.entityManager.removeCondition(this.summon, entityCondition, entityCondition.permanent); + gameManager.stateManager.after(); + } } \ No newline at end of file diff --git a/src/app/ui/figures/standee/standee.html b/src/app/ui/figures/standee/standee.html index ce35c6ccd..b7f891d02 100644 --- a/src/app/ui/figures/standee/standee.html +++ b/src/app/ui/figures/standee/standee.html @@ -1,20 +1,36 @@
-
-
+
+
+ + +
+ [style.background-image]="figure.noThumbnail || settingsManager.settings.disableArtwork || !gameManager.isMonster(figure) ? '': 'url(' + gameManager.monsterManager.monsterThumbnail(gameManager.toMonster(figure)) + ')'">
{{entity.number < 0 ? '?' : entity.number}} - - {{EntityValueFunction(entity.maxHealth) > 0 ? ((entity.health + health) | ghsMinZero) : '-'}} - - + + + + + + - + {{gameManager.toSummon(entity).number}} + + + + {{EntityValueFunction(entity.maxHealth) > 0 ? ((entity.health + health) | + ghsMinZero) : '-'}} + +
@@ -45,7 +61,7 @@
+ [ngClass]="{'center' : (gameManager.isMonsterEntity(entity) && gameManager.toMonsterEntity(entity).summon == SummonState.false || gameManager.isSummon(entity) || gameManager.isObjectiveEntity(entity)) && ((activeConditions).length % 2) == 1 && (activeConditions).length == index + 1, 'expired' : entityCondition.expired}"> - + - + [ngClass]="{'active' : gameManager.isMonsterEntity(entity) && gameManager.toMonsterEntity(entity).summon == SummonState.true, 'new' : gameManager.isMonsterEntity(entity) && gameManager.toMonsterEntity(entity).summon == SummonState.new}"> +
diff --git a/src/app/ui/figures/standee/standee.scss b/src/app/ui/figures/standee/standee.scss index 58031f689..dd8db517d 100644 --- a/src/app/ui/figures/standee/standee.scss +++ b/src/app/ui/figures/standee/standee.scss @@ -52,12 +52,15 @@ } &.active-focus { - .standee { + + .monster-standee, + .objective-standee { animation: monster-entity-active-focus 1000ms ease-in-out infinite; } } - .standee { + .monster-standee, + .objective-standee { box-shadow: 0px 0px calc(var(--ghs-unit) * 1) calc(var(--ghs-unit) * 0.5) var(--ghs-color-red); } } @@ -110,20 +113,22 @@ } .entity { - .standee { + + .monster-standee, + .objective-standee { box-shadow: 0px 0px calc(var(--ghs-unit) * 0.6) calc(var(--ghs-unit) * 0.3) var(--ghs-color-white); animation: monster-entity-revealed 1000ms ease-in-out infinite; } &.elite { - .standee { + .monster-standee { box-shadow: 0px 0px calc(var(--ghs-unit) * 0.6) calc(var(--ghs-unit) * 0.3) var(--ghs-color-yellow); animation: monster-entity-revealed-elite 1000ms ease-in-out infinite; } } &.boss { - .standee { + .monster-standee { box-shadow: 0px 0px calc(var(--ghs-unit) * 0.6) calc(var(--ghs-unit) * 0.3) var(--ghs-color-red); animation: monster-entity-revealed-boss 1000ms ease-in-out infinite; } @@ -178,76 +183,141 @@ filter: brightness(70%); } } - } - .number, - .health { - display: flex; - width: calc(var(--ghs-unit) * 4 * var(--ghs-text-factor)); - height: calc(var(--ghs-unit) * 4 * var(--ghs-text-factor)); - justify-content: center; - align-items: center; - font-family: "ghs-normal"; - flex-shrink: 0; - z-index: 1; - } - @keyframes number-pulse { - 0% { - transform: scale(0.9); + .number, + .health { + display: flex; + width: calc(var(--ghs-unit) * 4 * var(--ghs-text-factor)); + height: calc(var(--ghs-unit) * 4 * var(--ghs-text-factor)); + justify-content: center; + align-items: center; + font-family: "ghs-normal"; + flex-shrink: 0; + z-index: 1; } - 50% { - transform: scale(1.1); - } + @keyframes number-pulse { + 0% { + transform: scale(0.9); + } - 100% { - transform: scale(0.9); + 50% { + transform: scale(1.1); + } + + 100% { + transform: scale(0.9); + } } - } - .number { - color: var(--ghs-color-darkgray); - background-color: var(--ghs-color-white); - border-bottom-right-radius: 50%; - border-top-left-radius: 35%; - height: calc(var(--ghs-unit) * 4 * var(--ghs-text-factor)); - font-size: calc(var(--ghs-unit) * 4 * var(--ghs-text-factor)); - text-shadow: none; + .number { + color: var(--ghs-color-darkgray); + background-color: var(--ghs-color-white); + border-bottom-right-radius: 50%; + border-top-left-radius: 35%; + height: calc(var(--ghs-unit) * 4 * var(--ghs-text-factor)); + font-size: calc(var(--ghs-unit) * 4 * var(--ghs-text-factor)); + text-shadow: none; - &.highlight .value { - animation: number-pulse 2000ms ease-in-out infinite; + &.highlight .value { + animation: number-pulse 2000ms ease-in-out infinite; + } } - } - .health { - font-size: calc(var(--ghs-unit) * 4.5 * var(--ghs-text-factor)); - position: relative; - top: calc(var(--ghs-unit) * 1.2 * var(--ghs-text-factor)); - left: 0; - height: calc(var(--ghs-unit) * 5 * var(--ghs-text-factor)); - &::before { - content: " "; - position: absolute; - left: 50%; - top: calc(var(--ghs-unit) * -0.9 * var(--ghs-text-factor)); - width: calc(var(--ghs-unit) * 1 * var(--ghs-text-factor)); - height: calc(var(--ghs-unit) * 1.5 * var(--ghs-text-factor)); - background-image: url('~/src/assets/images/status/health.svg'); - background-size: contain; - background-repeat: no-repeat; - transform: translateX(-50%); + .health { + font-size: calc(var(--ghs-unit) * 4.5 * var(--ghs-text-factor)); + position: relative; + top: calc(var(--ghs-unit) * 1.2 * var(--ghs-text-factor)); + left: 0; + height: calc(var(--ghs-unit) * 5 * var(--ghs-text-factor)); + + &::before { + content: " "; + position: absolute; + left: 50%; + top: calc(var(--ghs-unit) * -0.9 * var(--ghs-text-factor)); + width: calc(var(--ghs-unit) * 1 * var(--ghs-text-factor)); + height: calc(var(--ghs-unit) * 1.5 * var(--ghs-text-factor)); + background-image: url('~/src/assets/images/status/health.svg'); + background-size: contain; + background-repeat: no-repeat; + transform: translateX(-50%); + } + + .value-overlay { + position: absolute; + left: calc(var(--ghs-unit) * -1 * var(--ghs-text-factor)); + top: calc(var(--ghs-unit) * -4.5 * var(--ghs-text-factor)); + font-size: calc(var(--ghs-unit) * 4 * var(--ghs-text-factor)); + width: calc(var(--ghs-unit) * 5 * var(--ghs-text-factor)); + height: calc(var(--ghs-unit) * 4.5 * var(--ghs-text-factor)); + z-index: 1000; + } } - .value-overlay { - position: absolute; - left: calc(var(--ghs-unit) * -1 * var(--ghs-text-factor)); - top: calc(var(--ghs-unit) * -4.5 * var(--ghs-text-factor)); - font-size: calc(var(--ghs-unit) * 4 * var(--ghs-text-factor)); - width: calc(var(--ghs-unit) * 5 * var(--ghs-text-factor)); - height: calc(var(--ghs-unit) * 4.5 * var(--ghs-text-factor)); - z-index: 1000; + + + &.summon-standee { + + .number { + display: none; + } + + .summon-state { + position: absolute; + top: calc(var(--ghs-unit) * 0.5); + left: 0; + width: calc(var(--ghs-unit) * 4); + height: calc(var(--ghs-unit) * 4); + transition: top 500ms ease-out, left 500ms ease-out; + + &.new::before { + content: " "; + display: block; + position: absolute; + width: calc(var(--ghs-unit) * 4); + height: calc(var(--ghs-unit) * 4); + background-image: url('~/src/assets/images/summons/minus.svg'); + background-size: cover; + z-index: 2; + } + + img { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 1; + } + + .summon-number { + position: absolute; + display: flex; + justify-content: center; + align-items: center; + top: 0; + left: calc(var(--ghs-unit) * -0.1); + height: calc(var(--ghs-unit) * 4); + width: calc(var(--ghs-unit) * 2); + font-family: var(--ghs-font-title); + font-size: calc(var(--ghs-unit) * 2.5); + color: var(--ghs-color-white); + background-color: var(--ghs-color-darkgray); + border-top-left-radius: calc(var(--ghs-unit) * 4); + border-bottom-left-radius: calc(var(--ghs-unit) * 4); + z-index: 3; + opacity: 0.9; + } + } + + .health { + position: absolute; + top: calc(var(--ghs-unit) * 1.2 * var(--ghs-text-factor)); + left: calc(var(--ghs-unit) * 4 * var(--ghs-text-factor)); + } } } @@ -527,8 +597,91 @@ z-index: 4; } + &.active.summon { + + z-index: 15; + + .entity { + height: calc(var(--ghs-unit) * 12 * var(--ghs-text-factor)); + + .summon-standee { + position: relative; + width: calc(var(--ghs-unit) * 30 * var(--ghs-text-factor)); + height: calc(var(--ghs-unit) * 12 * var(--ghs-text-factor)); + font-size: calc(var(--ghs-unit) * 2 * var(--ghs-text-factor)); + + .sheet { + height: calc(var(--ghs-unit) * 11 * var(--ghs-text-factor)); + } + + .background-image-container { + top: 5%; + left: 0; + height: 75%; + width: calc(var(--ghs-unit) * 4.5 * var(--ghs-text-factor)); + + .background-image { + top: 8%; + left: -35%; + width: calc(var(--ghs-unit) * 6 * var(--ghs-text-factor)); + } + + } + + ghs-summon-sheet { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + } + + .summon-state { + top: calc(var(--ghs-unit) * -1); + left: calc(var(--ghs-unit) * -2); + } + + .health { + top: calc(var(--ghs-unit) * 6.5 * var(--ghs-text-factor)); + left: calc(var(--ghs-unit) * 1); + + .value-overlay { + left: 100%; + bottom: calc(var(--ghs-unit) * 0.6); + z-index: 1000; + } + } + } + } + + ghs-healthbar { + left: calc(var(--ghs-unit) * 0.4 * var(--ghs-text-factor)); + width: calc(var(--ghs-unit) * 29.2 * var(--ghs-text-factor)); + } + + &.fh { + .entity .summon-standee { + + .background-image-container { + top: 25%; + height: 85%; + width: calc(var(--ghs-unit) * 9.5 * var(--ghs-text-factor)); + + .background-image { + top: 0; + left: -10%; + width: calc(var(--ghs-unit) * 9.5 * var(--ghs-text-factor)); + } + } + .health { + left: calc(var(--ghs-unit) * 2); + } + } + } + } + &.fh { &.active { @keyframes monster-entity-active-focus-fh { diff --git a/src/app/ui/figures/standee/standee.ts b/src/app/ui/figures/standee/standee.ts index b244cad5f..4d7aa6282 100644 --- a/src/app/ui/figures/standee/standee.ts +++ b/src/app/ui/figures/standee/standee.ts @@ -16,6 +16,7 @@ import { Subscription } from 'rxjs'; import { ObjectiveEntity } from 'src/app/game/model/ObjectiveEntity'; import { ObjectiveContainer } from 'src/app/game/model/ObjectiveContainer'; import { ActionHint } from 'src/app/game/model/data/Action'; +import { Character } from 'src/app/game/model/Character'; @Component({ selector: 'ghs-standee', @@ -28,8 +29,8 @@ export class StandeeComponent implements OnInit, OnDestroy { gameManager: GameManager = gameManager; settingsManager: SettingsManager = settingsManager; - @Input() figure!: Monster | ObjectiveContainer; - @Input() entity!: MonsterEntity | ObjectiveEntity; + @Input() figure!: Monster | Character | ObjectiveContainer; + @Input() entity!: MonsterEntity | Summon | ObjectiveEntity; Conditions = Condition; AttackModifierType = AttackModifierType; SummonState = SummonState; @@ -90,7 +91,7 @@ export class StandeeComponent implements OnInit, OnDestroy { } } } - this.marker = this.entity.marker; + this.marker = (this.entity instanceof MonsterEntity || this.entity instanceof ObjectiveEntity) ? this.entity.marker : ""; if (this.figure instanceof ObjectiveContainer && this.figure.entities.flatMap((entity) => entity.marker).every((marker, index, self) => self.indexOf(marker) == 0)) { this.marker = ""; }