Skip to content

Commit

Permalink
address #612
Browse files Browse the repository at this point in the history
  • Loading branch information
Lurkars committed Oct 28, 2024
1 parent 5d6bbab commit 38a7a62
Show file tree
Hide file tree
Showing 10 changed files with 223 additions and 24 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "gloomhavensecretariat",
"version": "0.102.3",
"version": "0.102.4",
"license": "AGPL3",
"description": "Gloomhaven Secretariat is a Gloomhaven/Frosthaven Companion app.",
"homepage": "https://gloomhaven-secretariat.de",
Expand Down Expand Up @@ -101,7 +101,7 @@
"ng-in-viewport": "^16.1.0",
"rxjs": "~7.8.1",
"tslib": "^2.8.0",
"uuid": "^10.0.0",
"uuid": "^11.0.1",
"zone.js": "~0.14.10"
},
"devDependencies": {
Expand All @@ -114,7 +114,7 @@
"@types/jasmine": "~5.1.4",
"@types/leaflet": "^1.9.14",
"@types/uuid": "^10.0.0",
"electron": "^32.2.0",
"electron": "^33.0.2",
"electron-builder": "^25.1.8",
"http-server": "^14.1.1",
"husky": "^9.1.6",
Expand Down
6 changes: 4 additions & 2 deletions src/app/game/model/data/Loot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ export enum LootType {
special2 = "special2"
}

export const enhancableLootTypes: LootType[] = [LootType.lumber, LootType.metal, LootType.hide, LootType.arrowvine, LootType.axenut, LootType.corpsecap, LootType.flamefruit, LootType.rockroot, LootType.snowthistle, LootType.money];
export const resourceLootTypes: LootType[] = [LootType.lumber, LootType.metal, LootType.hide, LootType.arrowvine, LootType.axenut, LootType.corpsecap, LootType.flamefruit, LootType.rockroot, LootType.snowthistle];

export const appliableLootTypes: LootType[] = [LootType.money, LootType.lumber, LootType.metal, LootType.hide, LootType.arrowvine, LootType.axenut, LootType.corpsecap, LootType.flamefruit, LootType.rockroot, LootType.snowthistle, LootType.special1, LootType.special2, LootType.random_item];
export const enhancableLootTypes: LootType[] = [...resourceLootTypes, LootType.money];

export const appliableLootTypes: LootType[] = [...enhancableLootTypes, LootType.special1, LootType.special2, LootType.random_item];


export function getLootClass(type: LootType): LootClass {
Expand Down
2 changes: 1 addition & 1 deletion src/app/ui/figures/party/party-sheet-dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1045,7 +1045,7 @@ export class PartySheetDialogComponent implements OnInit, OnDestroy {

openResources() {
this.dialog.open(PartyResourcesDialogComponent, {
panelClass: ['dialog-invert'],
panelClass: ['dialog'],
});
}

Expand Down
49 changes: 45 additions & 4 deletions src/app/ui/figures/party/resources/resources.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
<table>
<thead>
<tr>
<th></th>
<th><label>
<span [ghs-label]="'party.campaign.sheet.supply.edit'"></span>
<input type="checkbox" [(ngModel)]="edit"></label></th>
<th><span [ghs-label]="'party.campaign.sheet.supply'"></span></th>
<th *ngFor="let character of characters">
<span class="character">
Expand All @@ -19,11 +21,45 @@
</tr>
</thead>
<tbody>
<tr>
<th [ghs-tooltip]="'character.progress.gold'"><img class="ghs-svg"
[src]="'./assets/images/loot.svg'">
</th>
<td><span class="loot">-</span></td>
<td *ngFor="let character of characters">
<span *ngIf="!edit" class="loot">{{character.progress.gold || '-'}}</span>
<input *ngIf="edit" [(ngModel)]="character.progress.gold" type="number" min="0"
(change)="changeGold(character, $event)">
</td>
<td>
<span class="loot" [ngClass]="{'total' : totalGold}">{{totalGold || '-'}}</span>
</td>
</tr>
<tr>
<th [ghs-tooltip]="'game.experience'"><img class="ghs-svg" [src]="'./assets/images/experience.svg'">
</th>
<td><span class="loot">-</span></td>
<td *ngFor="let character of characters">
<span *ngIf="!edit" class="loot">{{character.progress.experience || '-'}}</span>
<input *ngIf="edit" [(ngModel)]="character.progress.experience" type="number" min="0"
(change)="changeXP(character, $event)">
</td>
<td>
<span class="loot" [ngClass]="{'total' : totalXP}">{{totalXP || '-'}}</span>
</td>
</tr>
<tr *ngFor="let lootType of lootColumns; let i = index">
<th><img class="ghs-svg" [src]="'./assets/images/fh/loot/' + lootType + '.svg'"></th>
<td><span class="loot">{{(gameManager.game.party.loot[lootType] || '-')}}</span></td>
<th [ghs-tooltip]="'game.loot.' + lootType"><img class="ghs-svg"
[src]="'./assets/images/fh/loot/' + lootType + '.svg'"></th>
<td>
<span *ngIf="!edit" class="loot">{{(party.loot[lootType] || '-')}}</span>
<input *ngIf="edit" [(ngModel)]="party.loot[lootType]" type="number" min="0"
(change)="changeLoot(undefined, lootType, $event)">
</td>
<td *ngFor="let character of characters">
<span class="loot">{{(character.progress.loot[lootType] || '-')}}</span>
<span *ngIf="!edit" class="loot">{{(character.progress.loot[lootType] || '-')}}</span>
<input *ngIf="edit" [(ngModel)]="character.progress.loot[lootType]" type="number" min="0"
(change)="changeLoot(character, lootType, $event)">
</td>
<td>
<span class="loot" [ngClass]="{'total' : total[lootType]}">{{(total[lootType] || '-')}}</span>
Expand All @@ -32,4 +68,9 @@
</tbody>
</table>
</div>

<div class="buttons" *ngIf="edit || edited">
<a class="cancel" (click)="close()"><span [ghs-label]="'cancel'"></span></a>
<a class="apply" (click)="apply()"><span [ghs-label]="'party.campaign.sheet.supply.apply'"></span></a>
</div>
</div>
94 changes: 91 additions & 3 deletions src/app/ui/figures/party/resources/resources.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.resources-dialog {

position: relative;
color: var(--ghs-color-white);

table {
border-collapse: collapse;
Expand All @@ -15,14 +16,72 @@
border-bottom: calc(var(--ghs-unit) * 0.2 * var(--ghs-dialog-factor)) solid var(--ghs-color-darkgray);
}

th {
label {
cursor: pointer;
font-size: calc(var(--ghs-unit) * 2 * var(--ghs-text-factor));
display: flex;
justify-content: flex-end;
align-items: center;
}
}

tbody tr {

td,
th {
position: relative;
z-index: 1;

span,
input {
position: relative;
z-index: 2;
}

input {
width: calc(var(--ghs-unit) * 4 * var(--ghs-dialog-factor));
max-width: 100%;
text-align: center;
border: none;
outline: none;
}
}

&:nth-child(odd) {
background-color: var(--ghs-color-lightgray);

td,
th {
&::before {
content: ' ';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--ghs-color-darkgray);
opacity: 0.3;
z-index: 0;
}
}
}

&:hover {
background-color: var(--ghs-color-yellow);
opacity: 0.5;

td,
th {
&::before {
content: ' ';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--ghs-color-yellow);
opacity: 0.5;
z-index: 0;
}
}
}
}

Expand Down Expand Up @@ -58,6 +117,35 @@
.ghs-svg {
width: calc(var(--ghs-unit) * 3 * var(--ghs-dialog-factor));
height: auto;
filter: var(--ghs-filter-white)
}
}

.buttons {
display: flex;
margin-top: calc(var(--ghs-unit) * 2 * var(--ghs-dialog-factor));
font-family: var(--ghs-font-title);
font-size: calc(var(--ghs-unit) * 3 * var(--ghs-dialog-factor));
justify-content: space-between;
align-items: center;

a {
cursor: pointer;
min-width: 33%;
display: flex;
justify-content: center;

&:hover {
opacity: 0.6;
}
}

.cancel {
color: var(--ghs-color-red);
}

.apply {
color: var(--ghs-color-green);
}
}
}
57 changes: 54 additions & 3 deletions src/app/ui/figures/party/resources/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { DialogRef } from "@angular/cdk/dialog";
import { Component, OnInit } from "@angular/core";
import { gameManager, GameManager } from "src/app/game/businesslogic/GameManager";
import { Character } from "src/app/game/model/Character";
import { LootType } from "src/app/game/model/data/Loot";
import { LootType, resourceLootTypes } from "src/app/game/model/data/Loot";
import { Party } from "src/app/game/model/Party";
import { ghsDialogClosingHelper } from "src/app/ui/helper/Static";

@Component({
Expand All @@ -15,20 +16,70 @@ export class PartyResourcesDialogComponent implements OnInit {

gameManager: GameManager = gameManager;

party: Party = new Party();
characters: Character[] = [];
total: Partial<Record<LootType, number>> = {};
lootColumns: LootType[] = [LootType.lumber, LootType.metal, LootType.hide, LootType.arrowvine, LootType.axenut, LootType.corpsecap, LootType.flamefruit, LootType.rockroot, LootType.snowthistle];;
totalGold: number = 0;
totalXP: number = 0;
lootColumns: LootType[] = resourceLootTypes;

edit: boolean = false;
edited: boolean = false;

constructor(private dialogRef: DialogRef) { }

ngOnInit(): void {
this.characters = gameManager.game.figures.filter((figure) => figure instanceof Character).map((figure) => figure as Character);
this.party = JSON.parse(JSON.stringify(gameManager.game.party));
this.characters = gameManager.game.figures.filter((figure) => figure instanceof Character).map((figure) => JSON.parse(JSON.stringify(figure)));
this.update();
}

update() {
this.lootColumns.forEach((type) => {
this.total[type] = (gameManager.game.party.loot[type] || 0);
if (this.characters.length > 0) {
this.total[type] = (this.total[type] || 0) + this.characters.map((character) => character.progress.loot[type] || 0).reduce((a, b) => a + b);
}
})
if (this.characters.length) {
this.totalGold = this.characters.map((character) => character.progress.gold || 0).reduce((a, b) => a + b);
this.totalXP = this.characters.map((character) => character.progress.experience || 0).reduce((a, b) => a + b);
}
}

changeLoot(character: Character | undefined, type: LootType, event: any) {
if (character) {
character.progress.loot[type] = +event.target.value || undefined;
} else {
this.party.loot[type] = +event.target.value || undefined;
}
this.update();
this.edited = true;
}

changeGold(character: Character, event: any) {
character.progress.gold = +event.target.value;
this.update();
this.edited = true;
}

changeXP(character: Character, event: any) {
character.progress.experience = +event.target.value;
this.update();
this.edited = true;
}

apply() {
gameManager.stateManager.before("applyResourceChange");
gameManager.game.party.loot = this.party.loot;
gameManager.game.figures.filter((figure) => figure instanceof Character).forEach((figure) => {
const character = this.characters.find((character) => character.edition == figure.edition && character.name == figure.name);
if (character) {
figure.progress = character.progress;
}
})
gameManager.stateManager.after();
ghsDialogClosingHelper(this.dialogRef);
}

close() {
Expand Down
20 changes: 12 additions & 8 deletions src/app/ui/header/menu/campaign/campaign.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,27 @@
<label><span [ghs-label]="'campaign'"></span></label>
</div>

<div class="line span" *ngIf="settingsManager.settings.partySheet && !gameManager.bbRules()">
<div class="line" *ngIf="settingsManager.settings.partySheet && !gameManager.bbRules()">
<a tabclick (click)="openPartySheet()" [ghs-label]="'campaign.party'"></a>
</div>

<div class="line span" *ngIf="settingsManager.settings.partySheet && !gameManager.bbRules()">
<div class="line" *ngIf="settingsManager.settings.partySheet && gameManager.fhRules()">
<a tabclick (click)="openResources()" [ghs-label]="'campaign.resources'"></a>
</div>

<div class="line" *ngIf="settingsManager.settings.partySheet && !gameManager.bbRules()">
<a tabclick (click)="openCampaignSheet()" [ghs-label]="'campaign.sheet'"></a>
</div>

<div class="line span" *ngIf="worldMap">
<div class="line" *ngIf="worldMap">
<a tabclick (click)="openMap()" [ghs-label]="'campaign.map'"></a>
</div>

<div class="line span" *ngIf="(settingsManager.settings.characterSheet || settingsManager.settings.characterItems)">
<div class="line">
<a tabclick (click)="openFlowChart()" [ghs-label]="'scenario.chart'"></a>
</div>

<div class="line" *ngIf="(settingsManager.settings.characterSheet || settingsManager.settings.characterItems)">
<a tabclick (click)="openItems()" [ghs-label]="'campaign.items'"></a>
</div>

Expand All @@ -50,10 +58,6 @@
<a tabclick (click)="openBattleGoalsSetup()" [ghs-label]="'campaign.battleGoals'"></a>
</div>

<div class="line span">
<a tabclick (click)="openFlowChart()" [ghs-label]="'scenario.chart'"></a>
</div>

<div class="line title span"
*ngIf="characters.length > 0 && settingsManager.settings.characterSheet && !gameManager.bbRules()">
<label><span [ghs-label]="'campaign.character'"></span></label>
Expand Down
7 changes: 7 additions & 0 deletions src/app/ui/header/menu/campaign/campaign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { ItemsDialogComponent } from "src/app/ui/figures/items/dialog/items-dial
import { PartySheetDialogComponent } from "src/app/ui/figures/party/party-sheet-dialog";
import { WorldMapComponent } from "src/app/ui/figures/party/world-map/world-map";
import { ScenarioChartDialogComponent } from "../../../figures/party/scenario-chart/scenario-chart";
import { PartyResourcesDialogComponent } from "src/app/ui/figures/party/resources/resources";


@Component({
Expand Down Expand Up @@ -159,6 +160,12 @@ export class CampaignMenuComponent implements OnInit {
this.close.emit();
}

openResources() {
this.dialog.open(PartyResourcesDialogComponent, {
panelClass: ['dialog'],
});
this.close.emit();
}

addParty() {
let party = new Party();
Expand Down
Loading

0 comments on commit 38a7a62

Please sign in to comment.