powergrid-viewer 1.9.3 → 1.9.5
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.9.
|
|
3
|
+
"version": "1.9.5",
|
|
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.13.
|
|
21
|
+
"powergrid-engine": "1.13.4"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@types/assert": "^1.4.7",
|
package/src/components/Game.vue
CHANGED
|
@@ -59,6 +59,40 @@
|
|
|
59
59
|
@build="build($event)"
|
|
60
60
|
/>
|
|
61
61
|
|
|
62
|
+
<!-- Japan: Free Jump indicator -->
|
|
63
|
+
<g v-if="G.map.name === 'Japan'">
|
|
64
|
+
<text x="330" y="93" font-size="20" font-weight="bold" fill="black">Free Jump:</text>
|
|
65
|
+
<template v-for="(fjPlayer, i) in G.players">
|
|
66
|
+
<g
|
|
67
|
+
:key="'fj_' + i"
|
|
68
|
+
:transform="`translate(${480 + i * 30}, 80) scale(0.045)`"
|
|
69
|
+
:opacity="playerHasUsedFreeJump(i) ? 0.2 : 1"
|
|
70
|
+
>
|
|
71
|
+
<path
|
|
72
|
+
d="M187.698 263.636V456.017L3 341.204V169.522L80.8579 108.141L187.698 263.636Z"
|
|
73
|
+
:fill="playerColors[i]"
|
|
74
|
+
stroke="#010101"
|
|
75
|
+
stroke-width="12"
|
|
76
|
+
stroke-miterlimit="10"
|
|
77
|
+
/>
|
|
78
|
+
<path
|
|
79
|
+
d="M395.724 136.361V300.164L187.698 456.017V263.636L395.724 136.361Z"
|
|
80
|
+
:fill="playerColors[i]"
|
|
81
|
+
stroke="#010101"
|
|
82
|
+
stroke-width="12"
|
|
83
|
+
stroke-miterlimit="10"
|
|
84
|
+
/>
|
|
85
|
+
<path
|
|
86
|
+
d="M395.724 136.361L187.698 263.636L80.8579 108.141L304.771 4L395.724 136.361Z"
|
|
87
|
+
:fill="playerColors[i]"
|
|
88
|
+
stroke="#010101"
|
|
89
|
+
stroke-width="12"
|
|
90
|
+
stroke-miterlimit="10"
|
|
91
|
+
/>
|
|
92
|
+
</g>
|
|
93
|
+
</template>
|
|
94
|
+
</g>
|
|
95
|
+
|
|
62
96
|
<Resources
|
|
63
97
|
ref="resources"
|
|
64
98
|
:transform="`translate(${G.map.supplyPosition[0]}, ${G.map.supplyPosition[1]})`"
|
|
@@ -168,6 +202,45 @@
|
|
|
168
202
|
</div>
|
|
169
203
|
</div>
|
|
170
204
|
|
|
205
|
+
<div v-if="G && freeJumpCity" :class="['modal', { visible: freeJumpVisible }]">
|
|
206
|
+
<div class="modal-content">
|
|
207
|
+
<span
|
|
208
|
+
class="close"
|
|
209
|
+
@click="
|
|
210
|
+
freeJumpVisible = false;
|
|
211
|
+
freeJumpCity = null;
|
|
212
|
+
"
|
|
213
|
+
>×</span
|
|
214
|
+
>
|
|
215
|
+
<div class="modal-title">Free Jump — {{ freeJumpCity.name }}</div>
|
|
216
|
+
<div class="confirm-message" v-if="freeJumpNormalPrice !== null">
|
|
217
|
+
Use your <b>Free Jump</b> to build here for ${{ freeJumpSlotPrice }} (slot cost only), or pay the
|
|
218
|
+
full connection price of ${{ freeJumpNormalPrice }} and save the jump for later.
|
|
219
|
+
</div>
|
|
220
|
+
<div class="confirm-message" v-else>
|
|
221
|
+
Use your <b>Free Jump</b> to build here for ${{ freeJumpSlotPrice }} (slot cost only)? This city is
|
|
222
|
+
not reachable from your network otherwise.
|
|
223
|
+
</div>
|
|
224
|
+
<div class="confirm-buttons">
|
|
225
|
+
<button class="confirm-button" @click="confirmFreeJump(true)">
|
|
226
|
+
Use Free Jump (${{ freeJumpSlotPrice }})
|
|
227
|
+
</button>
|
|
228
|
+
<button v-if="freeJumpNormalPrice !== null" class="confirm-button" @click="confirmFreeJump(false)">
|
|
229
|
+
Pay Full Price (${{ freeJumpNormalPrice }})
|
|
230
|
+
</button>
|
|
231
|
+
<button
|
|
232
|
+
class="confirm-button"
|
|
233
|
+
@click="
|
|
234
|
+
freeJumpVisible = false;
|
|
235
|
+
freeJumpCity = null;
|
|
236
|
+
"
|
|
237
|
+
>
|
|
238
|
+
Cancel
|
|
239
|
+
</button>
|
|
240
|
+
</div>
|
|
241
|
+
</div>
|
|
242
|
+
</div>
|
|
243
|
+
|
|
171
244
|
<div v-if="G && discardedPowerPlant" :class="['modal', { visible: discardVisible }]">
|
|
172
245
|
<div class="modal-content">
|
|
173
246
|
<div class="modal-title">Discard Resources</div>
|
|
@@ -488,6 +561,11 @@ export default class Game extends Vue {
|
|
|
488
561
|
discardVisible: boolean = false;
|
|
489
562
|
resourcesToDiscard: { name: string, max: number, value: string }[] = [];
|
|
490
563
|
|
|
564
|
+
freeJumpCity: City | null = null;
|
|
565
|
+
freeJumpNormalPrice: number | null = null;
|
|
566
|
+
freeJumpSlotPrice: number = 0;
|
|
567
|
+
freeJumpVisible: boolean = false;
|
|
568
|
+
|
|
491
569
|
disablePass: boolean = false;
|
|
492
570
|
|
|
493
571
|
@Ref() powerPlantMarket!: PowerPlantMarket;
|
|
@@ -651,8 +729,41 @@ export default class Game extends Vue {
|
|
|
651
729
|
build(city: City) {
|
|
652
730
|
const currentPlayer = this.G!.players[this.player!];
|
|
653
731
|
const availableMoves = currentPlayer.availableMoves!;
|
|
654
|
-
const
|
|
655
|
-
|
|
732
|
+
const buildMoves = availableMoves[MoveName.Build]!;
|
|
733
|
+
const freeJumpMove = buildMoves.find((c) => c.name === city.name && c.freeJump);
|
|
734
|
+
const normalMove = buildMoves.find((c) => c.name === city.name && !c.freeJump);
|
|
735
|
+
|
|
736
|
+
if (freeJumpMove && normalMove) {
|
|
737
|
+
// Player can choose: use the free jump or pay full price
|
|
738
|
+
this.freeJumpCity = city;
|
|
739
|
+
this.freeJumpSlotPrice = freeJumpMove.price;
|
|
740
|
+
this.freeJumpNormalPrice = normalMove.price;
|
|
741
|
+
this.freeJumpVisible = true;
|
|
742
|
+
} else if (freeJumpMove && !normalMove) {
|
|
743
|
+
// Only reachable via free jump — confirm before using it
|
|
744
|
+
this.freeJumpCity = city;
|
|
745
|
+
this.freeJumpSlotPrice = freeJumpMove.price;
|
|
746
|
+
this.freeJumpNormalPrice = null;
|
|
747
|
+
this.freeJumpVisible = true;
|
|
748
|
+
} else {
|
|
749
|
+
// Normal build, no free jump involved
|
|
750
|
+
this.sendMove({ name: MoveName.Build, data: { name: city.name, price: normalMove!.price } });
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
confirmFreeJump(useJump: boolean) {
|
|
755
|
+
const city = this.freeJumpCity!;
|
|
756
|
+
const currentPlayer = this.G!.players[this.player!];
|
|
757
|
+
const buildMoves = currentPlayer.availableMoves![MoveName.Build]!;
|
|
758
|
+
this.freeJumpVisible = false;
|
|
759
|
+
this.freeJumpCity = null;
|
|
760
|
+
if (useJump) {
|
|
761
|
+
const freeJumpMove = buildMoves.find((c) => c.name === city.name && c.freeJump)!;
|
|
762
|
+
this.sendMove({ name: MoveName.Build, data: { name: city.name, price: freeJumpMove.price, freeJump: true } });
|
|
763
|
+
} else {
|
|
764
|
+
const normalMove = buildMoves.find((c) => c.name === city.name && !c.freeJump)!;
|
|
765
|
+
this.sendMove({ name: MoveName.Build, data: { name: city.name, price: normalMove.price } });
|
|
766
|
+
}
|
|
656
767
|
}
|
|
657
768
|
|
|
658
769
|
confirmDiscard() {
|
|
@@ -924,6 +1035,10 @@ export default class Game extends Vue {
|
|
|
924
1035
|
return availableMoves[MoveName.Build] && availableMoves[MoveName.Build]!.map((c) => c.name) || [];
|
|
925
1036
|
}
|
|
926
1037
|
|
|
1038
|
+
playerHasUsedFreeJump(playerIndex: number): boolean {
|
|
1039
|
+
return !!this.G?.players[playerIndex]?.usedFreeJump;
|
|
1040
|
+
}
|
|
1041
|
+
|
|
927
1042
|
canBuild(city: City) {
|
|
928
1043
|
if (!this.canMove()) return false;
|
|
929
1044
|
|
|
@@ -152,6 +152,23 @@
|
|
|
152
152
|
stroke-linecap="round"
|
|
153
153
|
/>
|
|
154
154
|
</template>
|
|
155
|
+
<!-- [10,10,20] city: "10" label at bottom-left (two 10-Elektro slots) -->
|
|
156
|
+
<text
|
|
157
|
+
v-if="
|
|
158
|
+
city.slotCosts &&
|
|
159
|
+
city.slotCosts.length === 3 &&
|
|
160
|
+
city.slotCosts[0] === 10 &&
|
|
161
|
+
city.slotCosts[1] === 10
|
|
162
|
+
"
|
|
163
|
+
:key="city.name + '_10label'"
|
|
164
|
+
:x="city.x - 20"
|
|
165
|
+
:y="city.y + 19"
|
|
166
|
+
font-size="17"
|
|
167
|
+
font-weight="bold"
|
|
168
|
+
fill="black"
|
|
169
|
+
text-anchor="middle"
|
|
170
|
+
>10</text
|
|
171
|
+
>
|
|
155
172
|
<!-- [15,20] city: X at top-middle -->
|
|
156
173
|
<template v-if="city.slotCosts && city.slotCosts.length === 2 && city.slotCosts[0] === 15">
|
|
157
174
|
<line
|