powergrid-viewer 2.0.13 → 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.13",
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.5"
21
+ "powergrid-engine": "2.0.6"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@types/assert": "^1.4.7",
@@ -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"
@@ -1747,6 +1748,39 @@ export default class Game extends Vue {
1747
1748
  return availableMoves[MoveName.Build] && availableMoves[MoveName.Build]!.map((c) => c.name) || [];
1748
1749
  }
1749
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
+
1750
1784
  getPickableRegions(): string[] {
1751
1785
  if (!this.canMove()) return [];
1752
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> — build for {{ city.slotCosts[0] }} (+ flat 5 per transited
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
  }