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 @@
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 @@
0 && (actionHints.length % 2) == 1 && activeConditions.length == 0 && entity.summon == SummonState.false, 'fh': settingsManager.settings.theme == 'fh', 'modern': settingsManager.settings.theme == 'modern'}"
+ [ngClass]="{'dead' : entity.dead, 'off' : !entity.dormant && entity.off, 'dormant' : entity.dormant, 'revealed' : !entity.dormant && entity.revealed && settingsManager.settings.scenarioRooms, 'active' : !entity.dormant && entity.active && settingsManager.settings.activeStandees, 'active-focus': !entity.dormant && entity.active && settingsManager.settings.activeStandees && !figure.active,'monster' : gameManager.isMonsterEntity(entity), 'objective' : gameManager.isObjectiveEntity(entity), 'summon' : gameManager.isSummon(entity), 'denied' : gameManager.isMonster(figure) && !gameManager.stateManager.monsterPermissions[figure.name + '|' + figure.edition] || (gameManager.isObjective(figure) || gameManager.isObjectiveContainer(figure)) && gameManager.stateManager.permissions && !gameManager.stateManager.permissions.characters || gameManager.isCharacter(figure) && !gameManager.stateManager.characterPermissions[figure.name + '|' + figure.edition], 'action-hint-border' : actionHints.length > 0 && (actionHints.length % 2) == 1 && activeConditions.length == 0 && (gameManager.isObjectiveEntity(entity) && gameManager.isMonsterEntity(entity) && gameManager.toMonsterEntity(entity).summon == SummonState.false || gameManager.isSummon(entity) && gameManager.toSummon(entity).state == SummonState.false), 'fh': settingsManager.settings.theme == 'fh', 'modern': settingsManager.settings.theme == 'modern'}"
[entityAnimation]="entity.dead">
-
-
+
+
+
+
+
+ [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) : '-'}}
-
-
+
+
+
+
+
+ -
+ 0">{{gameManager.toSummon(entity).number}}
+
+
+
+
{{EntityValueFunction(entity.maxHealth) > 0 ? ((entity.health + health) |
+ ghsMinZero) : '-'}}
+
+
@@ -45,7 +61,7 @@
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 = "";
}