powergrid-viewer 2.0.12 → 2.0.14
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": "2.0.
|
|
3
|
+
"version": "2.0.14",
|
|
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": "2.0.
|
|
21
|
+
"powergrid-engine": "2.0.6"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@types/assert": "^1.4.7",
|
package/src/components/Game.vue
CHANGED
|
@@ -98,6 +98,7 @@
|
|
|
98
98
|
:connections="G.map.connections"
|
|
99
99
|
:polygons="G.map.polygons"
|
|
100
100
|
:buildableCities="getBuildableCities()"
|
|
101
|
+
:buildPrices="getBuildableCityPrices()"
|
|
101
102
|
:blockedCities="G.blockedCities"
|
|
102
103
|
:pickableRegions="getPickableRegions()"
|
|
103
104
|
:noUraniumRegions="G.map.noUraniumRegions"
|
|
@@ -1080,7 +1081,11 @@ export default class Game extends Vue {
|
|
|
1080
1081
|
// scrubber renders reconstructed MID-game states, whose own `ended()` is
|
|
1081
1082
|
// false however long ago the game finished, so it cannot be asked. See
|
|
1082
1083
|
// `moneyIsPublic`.
|
|
1083
|
-
|
|
1084
|
+
// `state` is null until the platform posts the first one: launch() mounts
|
|
1085
|
+
// the viewer with `state: null` and the immediate `@Watch('state')` fires
|
|
1086
|
+
// at mount, so this runs once with null (hard refresh / first load) and
|
|
1087
|
+
// must not dereference it.
|
|
1088
|
+
if (replaceState && state && ended(state)) {
|
|
1084
1089
|
this.gameIsOver = true;
|
|
1085
1090
|
}
|
|
1086
1091
|
|
|
@@ -1743,6 +1748,39 @@ export default class Game extends Vue {
|
|
|
1743
1748
|
return availableMoves[MoveName.Build] && availableMoves[MoveName.Build]!.map((c) => c.name) || [];
|
|
1744
1749
|
}
|
|
1745
1750
|
|
|
1751
|
+
/**
|
|
1752
|
+
* What each buildable city would cost this player, keyed by city name (#148).
|
|
1753
|
+
*
|
|
1754
|
+
* The total is not computed here: `available-moves` already sums the shortest-path
|
|
1755
|
+
* connection cost and the slot cost for the number of players ALREADY in the city
|
|
1756
|
+
* (10/15/20 in the standard build, per-map `slotCosts` otherwise), then drops every
|
|
1757
|
+
* city the player cannot afford. That per-city occupancy is exactly what #148 asks
|
|
1758
|
+
* about in Step 3, so the number only needed surfacing — the viewer was discarding
|
|
1759
|
+
* it and keeping the names.
|
|
1760
|
+
*
|
|
1761
|
+
* A map with a free jump (Japan) offers the same city twice at two prices, so both
|
|
1762
|
+
* are kept; a city reachable ONLY by jump has no `price`.
|
|
1763
|
+
*/
|
|
1764
|
+
getBuildableCityPrices(): Record<string, { price?: number; jumpPrice?: number }> {
|
|
1765
|
+
if (!this.canMove()) return {};
|
|
1766
|
+
|
|
1767
|
+
const moves = this.G!.players[this.player!].availableMoves![MoveName.Build];
|
|
1768
|
+
if (!moves) return {};
|
|
1769
|
+
|
|
1770
|
+
const prices: Record<string, { price?: number; jumpPrice?: number }> = {};
|
|
1771
|
+
for (const move of moves) {
|
|
1772
|
+
if (!prices[move.name]) {
|
|
1773
|
+
prices[move.name] = {};
|
|
1774
|
+
}
|
|
1775
|
+
if (move.freeJump) {
|
|
1776
|
+
prices[move.name].jumpPrice = move.price;
|
|
1777
|
+
} else {
|
|
1778
|
+
prices[move.name].price = move.price;
|
|
1779
|
+
}
|
|
1780
|
+
}
|
|
1781
|
+
return prices;
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1746
1784
|
getPickableRegions(): string[] {
|
|
1747
1785
|
if (!this.canMove()) return [];
|
|
1748
1786
|
|
|
@@ -171,8 +171,8 @@
|
|
|
171
171
|
>
|
|
172
172
|
<title>
|
|
173
173
|
{{ city.name }}<template v-if="isBlocked(city)"> — blocked for this player count (transit
|
|
174
|
-
only)</template ><template v-else>
|
|
175
|
-
space)</template>
|
|
174
|
+
only)</template ><template v-else-if="buildCostLabel(city)">{{ buildCostLabel(city) }}</template
|
|
175
|
+
><template v-else> — build for {{ city.slotCosts[0] }} (+ flat 5 per transited space)</template>
|
|
176
176
|
</title>
|
|
177
177
|
</rect>
|
|
178
178
|
<text
|
|
@@ -411,7 +411,7 @@
|
|
|
411
411
|
pointer-events="all"
|
|
412
412
|
@click="onCityClick(city)"
|
|
413
413
|
>
|
|
414
|
-
<title>{{ city.name }}</title>
|
|
414
|
+
<title>{{ city.name }}{{ buildCostLabel(city) }}</title>
|
|
415
415
|
</circle>
|
|
416
416
|
<!-- Node-weighted tiles (Bremen) get the same treatment at the tile's own
|
|
417
417
|
size — their houses sit in slots inside the diamond. Manhattan's spaces
|
|
@@ -431,7 +431,7 @@
|
|
|
431
431
|
:transform="`rotate(45, ${city.x}, ${city.y})`"
|
|
432
432
|
@click="onCityClick(city)"
|
|
433
433
|
>
|
|
434
|
-
<title>{{ city.name }}</title>
|
|
434
|
+
<title>{{ city.name }}{{ buildCostLabel(city) }}</title>
|
|
435
435
|
</rect>
|
|
436
436
|
</template>
|
|
437
437
|
|
|
@@ -486,6 +486,8 @@ export default class Map extends Vue {
|
|
|
486
486
|
@Prop() connections?: Connection[];
|
|
487
487
|
@Prop() playerColors?: string[];
|
|
488
488
|
@Prop() buildableCities?: string[];
|
|
489
|
+
// #148: what each of those cities would cost this player, from available-moves.
|
|
490
|
+
@Prop() buildPrices?: Record<string, { price?: number; jumpPrice?: number }>;
|
|
489
491
|
// Manhattan: spaces blocked for this player count — transitable but never buildable.
|
|
490
492
|
@Prop() blockedCities?: string[];
|
|
491
493
|
// chooseRegions draft: region names the current player may pick this turn.
|
|
@@ -699,6 +701,34 @@ export default class Map extends Vue {
|
|
|
699
701
|
return !!this.buildableCities!.find((cityName) => cityName == city.name);
|
|
700
702
|
}
|
|
701
703
|
|
|
704
|
+
/**
|
|
705
|
+
* The " — build for N" tail appended to a buildable city's tooltip (#148).
|
|
706
|
+
*
|
|
707
|
+
* coyotte508 asked for this because in Step 3 the cost varies city by city with how
|
|
708
|
+
* many players are already there, and the board alone does not say what YOU would
|
|
709
|
+
* pay. It is a tooltip rather than a printed label on purpose: measured across every
|
|
710
|
+
* recharged map, a Step-3 build turn offers a median 26–52% of the cities in play
|
|
711
|
+
* and up to all of them, so labelling each one would bury the board it is meant to
|
|
712
|
+
* explain — and there is nowhere to put such a label in portrait.
|
|
713
|
+
*
|
|
714
|
+
* Empty while the city is only region-pickable, so the draft tooltip is untouched.
|
|
715
|
+
*/
|
|
716
|
+
buildCostLabel(city: City): string {
|
|
717
|
+
const entry = this.buildPrices && this.buildPrices[city.name];
|
|
718
|
+
if (!entry) return '';
|
|
719
|
+
|
|
720
|
+
if (entry.price != null && entry.jumpPrice != null) {
|
|
721
|
+
return ` — build for ${entry.price}, or ${entry.jumpPrice} using your free jump`;
|
|
722
|
+
}
|
|
723
|
+
if (entry.price != null) {
|
|
724
|
+
return ` — build for ${entry.price}`;
|
|
725
|
+
}
|
|
726
|
+
if (entry.jumpPrice != null) {
|
|
727
|
+
return ` — build for ${entry.jumpPrice}, using your free jump`;
|
|
728
|
+
}
|
|
729
|
+
return '';
|
|
730
|
+
}
|
|
731
|
+
|
|
702
732
|
isBlocked(city: City) {
|
|
703
733
|
return !!this.blockedCities && this.blockedCities.includes(city.name);
|
|
704
734
|
}
|