powergrid-viewer 1.11.13 → 1.11.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "powergrid-viewer",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.15",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/boardgamers/powergrid.git",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"vue": "^2.6.11",
|
|
19
19
|
"vue-class-component": "^7.2.3",
|
|
20
20
|
"vue-property-decorator": "^8.4.2",
|
|
21
|
-
"powergrid-engine": "1.15.
|
|
21
|
+
"powergrid-engine": "1.15.15"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@types/assert": "^1.4.7",
|
package/src/components/Game.vue
CHANGED
|
@@ -380,31 +380,10 @@
|
|
|
380
380
|
<div :style="'background-color: ' + playerColors[player.id]">{{ player.name }}</div>
|
|
381
381
|
</th>
|
|
382
382
|
</tr>
|
|
383
|
-
<tr
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
'Spending: Connections',
|
|
388
|
-
'Spending: Plants',
|
|
389
|
-
'Spending: Resources',
|
|
390
|
-
]"
|
|
391
|
-
:key="'FC_' + cat"
|
|
392
|
-
>
|
|
393
|
-
<td>{{ cat }}</td>
|
|
394
|
-
<td v-for="player in sortedPlayers" :key="'FS' + player.id + i">
|
|
395
|
-
<div>
|
|
396
|
-
{{
|
|
397
|
-
i == 0
|
|
398
|
-
? player.totalIncome
|
|
399
|
-
: i == 1
|
|
400
|
-
? player.totalSpentCities
|
|
401
|
-
: i == 2
|
|
402
|
-
? player.totalSpentConnections
|
|
403
|
-
: i == 3
|
|
404
|
-
? player.totalSpentPlants
|
|
405
|
-
: player.totalSpentResources
|
|
406
|
-
}}
|
|
407
|
-
</div>
|
|
383
|
+
<tr v-for="row in spendingRows" :key="'FC_' + row.label">
|
|
384
|
+
<td>{{ row.label }}</td>
|
|
385
|
+
<td v-for="player in sortedPlayers" :key="'FS' + player.id + row.label">
|
|
386
|
+
<div>{{ row.value(player) }}</div>
|
|
408
387
|
</td>
|
|
409
388
|
</tr>
|
|
410
389
|
</table>
|
|
@@ -562,8 +541,9 @@ import CityCount from './boards/CityCount.vue';
|
|
|
562
541
|
import Map from './boards/Map.vue';
|
|
563
542
|
import Resources from './boards/Resources.vue';
|
|
564
543
|
import { LogMove } from 'powergrid-engine/src/log';
|
|
565
|
-
import { Phase, PowerPlant, PowerPlantType, ResourceType } from 'powergrid-engine/src/gamestate';
|
|
544
|
+
import { Phase, playerTimeUsed, PowerPlant, PowerPlantType, ResourceType } from 'powergrid-engine/src/gamestate';
|
|
566
545
|
import { City } from 'powergrid-engine/src/maps';
|
|
546
|
+
import { formatDuration } from '../util/time';
|
|
567
547
|
|
|
568
548
|
@Component({
|
|
569
549
|
created(this: Game) {
|
|
@@ -1054,7 +1034,10 @@ export default class Game extends Vue {
|
|
|
1054
1034
|
|
|
1055
1035
|
sendMove(move) {
|
|
1056
1036
|
if (!this.paused) {
|
|
1057
|
-
|
|
1037
|
+
// Stamp the move so the engine can advance the per-player clocks. The
|
|
1038
|
+
// engine never reads the system clock itself — the timestamp lives in the
|
|
1039
|
+
// log so replaying a game reproduces the same times.
|
|
1040
|
+
this.emitter.emit('move', { ...move, time: Date.now() });
|
|
1058
1041
|
}
|
|
1059
1042
|
}
|
|
1060
1043
|
|
|
@@ -1405,6 +1388,26 @@ export default class Game extends Vue {
|
|
|
1405
1388
|
return playersSortedByScore(this.G!);
|
|
1406
1389
|
}
|
|
1407
1390
|
|
|
1391
|
+
// Rows of the end-of-game Spending table, in display order.
|
|
1392
|
+
get spendingRows(): { label: string; value: (player: Player) => string | number }[] {
|
|
1393
|
+
return [
|
|
1394
|
+
{ label: 'Income', value: (p) => p.totalIncome },
|
|
1395
|
+
{ label: 'Spending: Cities', value: (p) => p.totalSpentCities },
|
|
1396
|
+
{ label: 'Spending: Connections', value: (p) => p.totalSpentConnections },
|
|
1397
|
+
{
|
|
1398
|
+
// What each city on the board effectively cost: the house price plus
|
|
1399
|
+
// the connection cost paid to reach it, averaged over cities built.
|
|
1400
|
+
label: 'Cost per City',
|
|
1401
|
+
value: (p) =>
|
|
1402
|
+
p.cities.length ? ((p.totalSpentCities + p.totalSpentConnections) / p.cities.length).toFixed(1) : '-',
|
|
1403
|
+
},
|
|
1404
|
+
{ label: 'Spending: Plants', value: (p) => p.totalSpentPlants },
|
|
1405
|
+
{ label: 'Spending: Resources', value: (p) => p.totalSpentResources },
|
|
1406
|
+
// Every clock is stopped once the game ends, so the banked total is final.
|
|
1407
|
+
{ label: 'Time Used', value: (p) => formatDuration(playerTimeUsed(p)) },
|
|
1408
|
+
];
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1408
1411
|
get mapTransform() {
|
|
1409
1412
|
if (!this.G?.map) return '';
|
|
1410
1413
|
const [mx, my] = this.G.map.mapPosition!;
|
|
@@ -96,13 +96,27 @@
|
|
|
96
96
|
|
|
97
97
|
<Uranium :pieceId="'Uranium' + player.id" :targetState="{ x: 215, y: 76 }" />
|
|
98
98
|
<text text-anchor="middle" x="250" y="85" fill="black">{{ player.uraniumLeft }}</text>
|
|
99
|
+
|
|
100
|
+
<!-- Time this player has spent on the clock. Ticks live while it is their
|
|
101
|
+
turn; sits in the free space right of the resource counters. -->
|
|
102
|
+
<text
|
|
103
|
+
text-anchor="end"
|
|
104
|
+
x="345"
|
|
105
|
+
y="85"
|
|
106
|
+
fill="black"
|
|
107
|
+
:font-weight="isCurrentPlayer ? 700 : 400"
|
|
108
|
+
style="font-size: 13px"
|
|
109
|
+
>
|
|
110
|
+
{{ timeUsed }}
|
|
111
|
+
</text>
|
|
99
112
|
</g>
|
|
100
113
|
</template>
|
|
101
114
|
<script lang="ts">
|
|
102
115
|
import { MoveName, Player } from 'powergrid-engine';
|
|
103
|
-
import { Phase, PowerPlant, PowerPlantType, ResourceType } from 'powergrid-engine/src/gamestate';
|
|
116
|
+
import { Phase, playerTimeUsed, PowerPlant, PowerPlantType, ResourceType } from 'powergrid-engine/src/gamestate';
|
|
104
117
|
import { Vue, Component, Prop, Inject } from 'vue-property-decorator';
|
|
105
118
|
import { Preferences } from '../types/ui-data';
|
|
119
|
+
import { formatDuration } from '../util/time';
|
|
106
120
|
import { Coal, Oil, Garbage, Uranium, Card } from './pieces';
|
|
107
121
|
|
|
108
122
|
@Component({
|
|
@@ -133,6 +147,27 @@ export default class PlayerBoard extends Vue {
|
|
|
133
147
|
|
|
134
148
|
powerPlantClicked?: PowerPlant;
|
|
135
149
|
|
|
150
|
+
// Ticks the live clock. Kept in this component rather than in Game so the
|
|
151
|
+
// per-second update only re-renders the player boards, not the whole board SVG.
|
|
152
|
+
now = Date.now();
|
|
153
|
+
private clockTimer?: number;
|
|
154
|
+
|
|
155
|
+
mounted() {
|
|
156
|
+
this.clockTimer = window.setInterval(() => (this.now = Date.now()), 1000);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
beforeDestroy() {
|
|
160
|
+
if (this.clockTimer != undefined) {
|
|
161
|
+
window.clearInterval(this.clockTimer);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Total time this player has been on the clock, counting the stretch currently
|
|
166
|
+
// running so the active player's timer visibly ticks up.
|
|
167
|
+
get timeUsed(): string {
|
|
168
|
+
return formatDuration(playerTimeUsed(this.player, this.now));
|
|
169
|
+
}
|
|
170
|
+
|
|
136
171
|
// Horizontal position of the i-th power-plant card. Spacing compresses as the
|
|
137
172
|
// hand grows so Australia's mines (which don't count toward the 3-plant limit,
|
|
138
173
|
// so a player can hold many cards) stay on the board instead of overflowing
|
package/src/util/time.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Formats a duration in milliseconds compactly, at a precision that suits the
|
|
2
|
+
// magnitude. Games range from a few minutes per player to correspondence games
|
|
3
|
+
// running for days, so the unit pair shifts with the size:
|
|
4
|
+
// 45s | 12m 34s | 3h 22m | 5d 3h
|
|
5
|
+
export function formatDuration(ms: number): string {
|
|
6
|
+
if (!ms || ms < 0) {
|
|
7
|
+
return '0s';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const totalSeconds = Math.floor(ms / 1000);
|
|
11
|
+
const totalMinutes = Math.floor(totalSeconds / 60);
|
|
12
|
+
const totalHours = Math.floor(totalMinutes / 60);
|
|
13
|
+
const days = Math.floor(totalHours / 24);
|
|
14
|
+
|
|
15
|
+
if (days > 0) {
|
|
16
|
+
return `${days}d ${totalHours % 24}h`;
|
|
17
|
+
}
|
|
18
|
+
if (totalHours > 0) {
|
|
19
|
+
return `${totalHours}h ${totalMinutes % 60}m`;
|
|
20
|
+
}
|
|
21
|
+
if (totalMinutes > 0) {
|
|
22
|
+
return `${totalMinutes}m ${totalSeconds % 60}s`;
|
|
23
|
+
}
|
|
24
|
+
return `${totalSeconds}s`;
|
|
25
|
+
}
|