powergrid-viewer 1.5.4
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/README.md +35 -0
- package/dist/img/help.ba7779cc.svg +1 -0
- package/dist/img/log.04ef6981.svg +1 -0
- package/dist/img/pass.da9065dc.svg +3 -0
- package/dist/img/rules.64f9aae5.svg +28 -0
- package/dist/img/sound-off.72ada995.svg +3 -0
- package/dist/img/sound-on.c55edd90.svg +3 -0
- package/dist/img/undo.208666d2.svg +3 -0
- package/dist/media/notification.55fa47dd.ogg +0 -0
- package/dist/media/notification.ac905963.mp3 +0 -0
- package/dist/media/piece-drop.eef5f607.mp3 +0 -0
- package/dist/powergrid-viewer.css +1 -0
- package/dist/powergrid-viewer.umd.min.js +35 -0
- package/package.json +49 -0
- package/src/audio/notification.mp3 +0 -0
- package/src/audio/notification.ogg +0 -0
- package/src/audio/piece-drop.mp3 +0 -0
- package/src/components/Calculator.vue +62 -0
- package/src/components/Game.vue +1354 -0
- package/src/components/PlayerBoard.vue +230 -0
- package/src/components/boards/CityCount.vue +82 -0
- package/src/components/boards/Map.vue +196 -0
- package/src/components/boards/PlayerOrder.vue +68 -0
- package/src/components/boards/PowerPlantMarket.vue +184 -0
- package/src/components/boards/Resources.vue +446 -0
- package/src/components/buttons/Button.vue +26 -0
- package/src/components/buttons/HelpButton.vue +18 -0
- package/src/components/buttons/LogButton.vue +15 -0
- package/src/components/buttons/PassButton.vue +18 -0
- package/src/components/buttons/RulesButton.vue +14 -0
- package/src/components/buttons/SoundButton.vue +18 -0
- package/src/components/buttons/UndoButton.vue +17 -0
- package/src/components/buttons/index.js +9 -0
- package/src/components/pieces/Card.vue +131 -0
- package/src/components/pieces/Coal.vue +40 -0
- package/src/components/pieces/Garbage.vue +40 -0
- package/src/components/pieces/House.vue +51 -0
- package/src/components/pieces/Hybrid.vue +37 -0
- package/src/components/pieces/Oil.vue +40 -0
- package/src/components/pieces/Piece.vue +104 -0
- package/src/components/pieces/Uranium.vue +32 -0
- package/src/components/pieces/index.js +10 -0
- package/src/icons/help.svg +1 -0
- package/src/icons/log.svg +1 -0
- package/src/icons/pass.svg +3 -0
- package/src/icons/rules.svg +28 -0
- package/src/icons/sound-off.svg +3 -0
- package/src/icons/sound-on.svg +3 -0
- package/src/icons/undo.svg +3 -0
- package/src/launch.ts +87 -0
- package/src/main.ts +3 -0
- package/src/self-contained.ts +97 -0
- package/src/shims-tsx.d.ts +13 -0
- package/src/shims-vue.d.ts +4 -0
- package/src/types/ui-data.ts +34 -0
- package/src/wrapper.ts +8 -0
- package/tsconfig.json +23 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<g class="button enabled" @click="$emit('click')">
|
|
3
|
+
<rect width="80" height="26" fill="gainsboro" stroke="black" rx="2" />
|
|
4
|
+
<image x="11" y="5" width="16" height="16" href="../../icons/log.svg" />
|
|
5
|
+
<text text-anchor="middle" fill="black" x="47" y="13">Log</text>
|
|
6
|
+
<title>Show log</title>
|
|
7
|
+
</g>
|
|
8
|
+
</template>
|
|
9
|
+
<script lang="ts">
|
|
10
|
+
import { Vue, Component } from 'vue-property-decorator';
|
|
11
|
+
|
|
12
|
+
@Component
|
|
13
|
+
export default class LogButton extends Vue {
|
|
14
|
+
}
|
|
15
|
+
</script>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<g :class="['button', { enabled, highlightButton }]" @click="enabled && $emit('click')">
|
|
3
|
+
<rect width="80" height="26" fill="gainsboro" stroke="black" rx="2" />
|
|
4
|
+
<image x="15" y="8" width="10" height="10" href="../../icons/pass.svg" />
|
|
5
|
+
<text text-anchor="middle" fill="black" x="47" y="13">{{ text }}</text>
|
|
6
|
+
<title>Pass turn</title>
|
|
7
|
+
</g>
|
|
8
|
+
</template>
|
|
9
|
+
<script lang="ts">
|
|
10
|
+
import { Vue, Component, Prop, Inject } from 'vue-property-decorator';
|
|
11
|
+
|
|
12
|
+
@Component
|
|
13
|
+
export default class PassButton extends Vue {
|
|
14
|
+
@Prop() enabled!: boolean;
|
|
15
|
+
@Prop() highlightButton!: boolean;
|
|
16
|
+
@Prop() text!: string;
|
|
17
|
+
}
|
|
18
|
+
</script>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<g class="button enabled" @click="$emit('click')">
|
|
3
|
+
<circle cx="15" cy="15" r="15" fill="gainsboro" stroke="black" stroke-width="2px" />
|
|
4
|
+
<image x="5" y="5" width="20" height="20" href="../../icons/rules.svg" />
|
|
5
|
+
<title>Rules</title>
|
|
6
|
+
</g>
|
|
7
|
+
</template>
|
|
8
|
+
<script lang="ts">
|
|
9
|
+
import { Vue, Component, Prop } from 'vue-property-decorator';
|
|
10
|
+
|
|
11
|
+
@Component
|
|
12
|
+
export default class RulesButton extends Vue {
|
|
13
|
+
}
|
|
14
|
+
</script>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<g class="button enabled" @click="$emit('click')">
|
|
3
|
+
<circle cx="15" cy="15" r="15" fill="gainsboro" stroke="black" stroke-width="2px" />
|
|
4
|
+
<image v-if="isOn" x="5" y="5" width="20" height="20" href="../../icons/sound-on.svg" />
|
|
5
|
+
<image v-else x="5" y="5" width="20" height="20" href="../../icons/sound-off.svg" />
|
|
6
|
+
<title v-if="isOn">Sound off</title>
|
|
7
|
+
<title v-else>Sound on</title>
|
|
8
|
+
</g>
|
|
9
|
+
</template>
|
|
10
|
+
<script lang="ts">
|
|
11
|
+
import { Vue, Component, Prop } from 'vue-property-decorator';
|
|
12
|
+
|
|
13
|
+
@Component
|
|
14
|
+
export default class SoundButton extends Vue {
|
|
15
|
+
@Prop()
|
|
16
|
+
isOn?: boolean;
|
|
17
|
+
}
|
|
18
|
+
</script>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<g :class="['button', { enabled, highlightButton }]" @click="enabled && $emit('click')">
|
|
3
|
+
<rect width="80" height="26" fill="gainsboro" stroke="black" rx="2" />
|
|
4
|
+
<image x="11" y="4" width="16" height="16" href="../../icons/undo.svg" />
|
|
5
|
+
<text text-anchor="middle" fill="black" x="47" y="13">Undo</text>
|
|
6
|
+
<title>Undo last move</title>
|
|
7
|
+
</g>
|
|
8
|
+
</template>
|
|
9
|
+
<script lang="ts">
|
|
10
|
+
import { Vue, Component, Prop } from 'vue-property-decorator';
|
|
11
|
+
|
|
12
|
+
@Component
|
|
13
|
+
export default class UndoButton extends Vue {
|
|
14
|
+
@Prop() enabled!: boolean;
|
|
15
|
+
@Prop() highlightButton!: boolean;
|
|
16
|
+
}
|
|
17
|
+
</script>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import Button from './Button.vue';
|
|
2
|
+
import HelpButton from './HelpButton.vue';
|
|
3
|
+
import LogButton from './LogButton.vue';
|
|
4
|
+
import PassButton from './PassButton.vue';
|
|
5
|
+
import SoundButton from './SoundButton.vue';
|
|
6
|
+
import RulesButton from './RulesButton.vue';
|
|
7
|
+
import UndoButton from './UndoButton.vue';
|
|
8
|
+
|
|
9
|
+
export { Button, HelpButton, LogButton, PassButton, SoundButton, RulesButton, UndoButton };
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<g v-if="powerPlant.number == 99" :id="elId" :transform="`translate(${currentX}, ${currentY})`">
|
|
3
|
+
<rect width="60" height="40" :fill="getColor()" stroke="black" stroke-width="2" rx="4" />
|
|
4
|
+
<text text-anchor="middle" x="30" y="20" fill="black">Step 3</text>
|
|
5
|
+
</g>
|
|
6
|
+
<g
|
|
7
|
+
v-else
|
|
8
|
+
:id="elId"
|
|
9
|
+
:class="[{ canClick: canClick }]"
|
|
10
|
+
:transform="`translate(${currentX}, ${currentY})`"
|
|
11
|
+
@click="canClick && $emit('click')"
|
|
12
|
+
>
|
|
13
|
+
<rect
|
|
14
|
+
width="60"
|
|
15
|
+
height="40"
|
|
16
|
+
:fill="getColor()"
|
|
17
|
+
:stroke="hasDiscount ? 'palegreen' : 'black'"
|
|
18
|
+
stroke-width="2"
|
|
19
|
+
rx="4"
|
|
20
|
+
/>
|
|
21
|
+
<g v-if="hasDiscount">
|
|
22
|
+
<rect width="12" height="12" rx="4" fill="palegreen" />
|
|
23
|
+
<text text-anchor="middle" x="6" y="6" style="font-size: 12px" fill="black">$</text>
|
|
24
|
+
</g>
|
|
25
|
+
<g transform="translate(30, 10)">
|
|
26
|
+
<text text-anchor="middle" x="1" y="1" fill="gray">{{ powerPlant.number }}</text>
|
|
27
|
+
<text text-anchor="middle" fill="white">{{ powerPlant.number }}</text>
|
|
28
|
+
</g>
|
|
29
|
+
|
|
30
|
+
<g :id="elId" :class="['piece']" transform="translate(40, 20) scale(0.035)">
|
|
31
|
+
<path
|
|
32
|
+
d="M187.698 263.636V456.017L3 341.204V169.522L80.8579 108.141L187.698 263.636Z"
|
|
33
|
+
fill="white"
|
|
34
|
+
stroke="white"
|
|
35
|
+
stroke-width="12"
|
|
36
|
+
stroke-miterlimit="10"
|
|
37
|
+
/>
|
|
38
|
+
<path
|
|
39
|
+
d="M395.724 136.361V300.164L187.698 456.017V263.636L395.724 136.361Z"
|
|
40
|
+
fill="white"
|
|
41
|
+
stroke="white"
|
|
42
|
+
stroke-width="12"
|
|
43
|
+
stroke-miterlimit="10"
|
|
44
|
+
/>
|
|
45
|
+
<path
|
|
46
|
+
d="M395.724 136.361L187.698 263.636L80.8579 108.141L304.771 4L395.724 136.361Z"
|
|
47
|
+
fill="white"
|
|
48
|
+
stroke="white"
|
|
49
|
+
stroke-width="12"
|
|
50
|
+
stroke-miterlimit="10"
|
|
51
|
+
/>
|
|
52
|
+
</g>
|
|
53
|
+
<text text-anchor="middle" x="47" y="28" style="font-size: 12px" fill="black">
|
|
54
|
+
{{ powerPlant.citiesPowered }}
|
|
55
|
+
</text>
|
|
56
|
+
|
|
57
|
+
<g transform="translate(5, 20)">
|
|
58
|
+
<path :d="getResourcePath()" fill="white" />
|
|
59
|
+
</g>
|
|
60
|
+
<text v-if="powerPlant.cost > 0" text-anchor="middle" x="12.5" y="27.5" style="font-size: 12px" fill="black">
|
|
61
|
+
{{ powerPlant.cost }}
|
|
62
|
+
</text>
|
|
63
|
+
|
|
64
|
+
<g transform="translate(24, 22)">
|
|
65
|
+
<path d="M0,3 L8,3 L8,0 L14,6 L8,12 L8,9 L0,9Z" fill="white" />
|
|
66
|
+
</g>
|
|
67
|
+
|
|
68
|
+
<defs>
|
|
69
|
+
<linearGradient id="hybrid" x1="0" y1="0" x2="100%" y2="100%">
|
|
70
|
+
<stop offset="50%" stop-color="#8b4513" />
|
|
71
|
+
<stop offset="50%" stop-color="#445" />
|
|
72
|
+
</linearGradient>
|
|
73
|
+
</defs>
|
|
74
|
+
</g>
|
|
75
|
+
</template>
|
|
76
|
+
<script lang="ts">
|
|
77
|
+
import { PieceType } from './../../types/ui-data';
|
|
78
|
+
import { PowerPlant, PowerPlantType } from 'powergrid-engine/src/gamestate';
|
|
79
|
+
import { Component, Mixins, Prop } from 'vue-property-decorator';
|
|
80
|
+
import Piece from './Piece.vue';
|
|
81
|
+
|
|
82
|
+
@Component({
|
|
83
|
+
created(this: Card) {
|
|
84
|
+
this.pieceType = PieceType.Card;
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
export default class Card extends Mixins(Piece) {
|
|
88
|
+
@Prop()
|
|
89
|
+
owner?: number;
|
|
90
|
+
|
|
91
|
+
@Prop()
|
|
92
|
+
powerPlant?: PowerPlant;
|
|
93
|
+
|
|
94
|
+
@Prop()
|
|
95
|
+
canClick?: boolean;
|
|
96
|
+
|
|
97
|
+
@Prop({ default: false })
|
|
98
|
+
hasDiscount?: boolean;
|
|
99
|
+
|
|
100
|
+
getColor() {
|
|
101
|
+
switch (this.powerPlant?.type) {
|
|
102
|
+
case PowerPlantType.Coal: return '#8b4513';
|
|
103
|
+
case PowerPlantType.Oil: return '#445';
|
|
104
|
+
case PowerPlantType.Garbage: return 'goldenrod';
|
|
105
|
+
case PowerPlantType.Uranium: return 'red';
|
|
106
|
+
case PowerPlantType.Hybrid: return 'url(#hybrid)';
|
|
107
|
+
case PowerPlantType.Wind: return 'limegreen';
|
|
108
|
+
case PowerPlantType.Nuclear: return 'dodgerblue';
|
|
109
|
+
case PowerPlantType.Step3: return 'dodgerblue';
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
getResourcePath() {
|
|
114
|
+
switch (this.powerPlant?.type) {
|
|
115
|
+
case PowerPlantType.Coal: return 'M0,3 L7.5,0 L15,3 L15,12 L7.5,15 L0,12Z';
|
|
116
|
+
case PowerPlantType.Oil: return 'M3,2 A6,3 0 0,1 12,2 L12,12 A6,3 0 0,1 3,12Z';
|
|
117
|
+
case PowerPlantType.Garbage: return 'M0,3 A7.5,3 0 0,1 15,3 L15,12 A7.5,3 0 0,1 0,12Z';
|
|
118
|
+
case PowerPlantType.Uranium: return 'M1,2 l4,-2 l6,0 l4,2 l0,11 l-4,2 l-6,0 l-4,-2Z';
|
|
119
|
+
case PowerPlantType.Hybrid: return 'M0,3 L7.5,0 L15,3 L15,12 L7.5,15 L0,12Z M9,1 A6,3 0 0,1 18,1 L18,10 A6,3 0 0,1 10,10Z';
|
|
120
|
+
case PowerPlantType.Wind: return '';
|
|
121
|
+
case PowerPlantType.Nuclear: return '';
|
|
122
|
+
case PowerPlantType.Step3: return '';
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
</script>
|
|
127
|
+
<style lang="scss">
|
|
128
|
+
.canClick {
|
|
129
|
+
cursor: pointer;
|
|
130
|
+
}
|
|
131
|
+
</style>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<g
|
|
3
|
+
:id="elId"
|
|
4
|
+
:class="[{ canClick: canClick }]"
|
|
5
|
+
:transform="`translate(${currentX}, ${currentY}) scale(${scale})`"
|
|
6
|
+
:opacity="transparent ? 0.3 : 1"
|
|
7
|
+
@click="canClick && $emit('click')"
|
|
8
|
+
>
|
|
9
|
+
<path
|
|
10
|
+
d="M136.8 21.2L43.1001 48.9L43.2001 167.2L135.2 210.3L228.8 174V55.7L136.8 21.2Z"
|
|
11
|
+
fill="#5a2d0c"
|
|
12
|
+
stroke="black"
|
|
13
|
+
stroke-width="20"
|
|
14
|
+
stroke-miterlimit="10"
|
|
15
|
+
/>
|
|
16
|
+
<path d="M135.2 210.3L43.2001 167.2L43.1001 48.8999L135.1 83.4999L135.2 210.3Z" fill="#70380f" />
|
|
17
|
+
<path d="M135.1 83.5L43.1001 48.9L136.8 21.2L228.8 55.7L135.1 83.5Z" fill="#8b4513" />
|
|
18
|
+
<path d="M228.8 55.7V174L135.2 210.3L135.1 83.5L228.8 55.7Z" fill="#5a2d0c" />
|
|
19
|
+
|
|
20
|
+
<title>Coal</title>
|
|
21
|
+
</g>
|
|
22
|
+
</template>
|
|
23
|
+
<script lang="ts">
|
|
24
|
+
import { PieceType } from './../../types/ui-data';
|
|
25
|
+
import { Component, Mixins, Prop } from 'vue-property-decorator';
|
|
26
|
+
import Piece from './Piece.vue';
|
|
27
|
+
|
|
28
|
+
@Component({
|
|
29
|
+
created(this: Coal) {
|
|
30
|
+
this.pieceType = PieceType.Coal;
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
export default class Coal extends Mixins(Piece) {
|
|
34
|
+
@Prop()
|
|
35
|
+
canClick?: boolean;
|
|
36
|
+
|
|
37
|
+
@Prop({ default: 0.08 })
|
|
38
|
+
scale?: number;
|
|
39
|
+
}
|
|
40
|
+
</script>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<g
|
|
3
|
+
:id="elId"
|
|
4
|
+
:class="[{ canClick: canClick }]"
|
|
5
|
+
:transform="`translate(${currentX}, ${currentY}) scale(${scale})`"
|
|
6
|
+
:opacity="transparent ? 0.3 : 1"
|
|
7
|
+
@click="canClick && $emit('click')"
|
|
8
|
+
>
|
|
9
|
+
<path d="M2,5 A9,5,0 0,1 18,5 L18,15 A9,5 0 0,1 2,15Z" fill="none" stroke="black" stroke-miterlimit="0" />
|
|
10
|
+
<path d="M2,5 A9,5 0 0,0 18,5 A9,5 0 0,0 2,5" fill="#FF0" />
|
|
11
|
+
<path d="M2,5 A9,5 0 0,0 2,5 L2,15 A9,5,0 0,0 18,15 L18,5 A9,5 0 0,1 2,5" fill="url(#garbage-linear)" />
|
|
12
|
+
|
|
13
|
+
<title>Garbage</title>
|
|
14
|
+
|
|
15
|
+
<defs>
|
|
16
|
+
<linearGradient id="garbage-linear" x1="0" y1="10" x2="20" y2="10" gradientUnits="userSpaceOnUse">
|
|
17
|
+
<stop stop-color="#DD0" />
|
|
18
|
+
<stop offset="1" stop-color="#AA0" />
|
|
19
|
+
</linearGradient>
|
|
20
|
+
</defs>
|
|
21
|
+
</g>
|
|
22
|
+
</template>
|
|
23
|
+
<script lang="ts">
|
|
24
|
+
import { PieceType } from './../../types/ui-data';
|
|
25
|
+
import { Component, Mixins, Prop } from 'vue-property-decorator';
|
|
26
|
+
import Piece from './Piece.vue';
|
|
27
|
+
|
|
28
|
+
@Component({
|
|
29
|
+
created(this: Garbage) {
|
|
30
|
+
this.pieceType = PieceType.Garbage;
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
export default class Garbage extends Mixins(Piece) {
|
|
34
|
+
@Prop()
|
|
35
|
+
canClick?: boolean;
|
|
36
|
+
|
|
37
|
+
@Prop({ default: 1 })
|
|
38
|
+
scale?: number;
|
|
39
|
+
}
|
|
40
|
+
</script>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<g :id="elId" :class="['piece']" :transform="`translate(${currentX}, ${currentY}) scale(0.035)`">
|
|
3
|
+
<!-- <path d="M15 0 L30 10 L30 30 L0 30 L0 10Z" :fill="color" stroke="black" /> -->
|
|
4
|
+
<path
|
|
5
|
+
d="M187.698 263.636V456.017L3 341.204V169.522L80.8579 108.141L187.698 263.636Z"
|
|
6
|
+
:fill="color"
|
|
7
|
+
stroke="#010101"
|
|
8
|
+
stroke-width="12"
|
|
9
|
+
stroke-miterlimit="10"
|
|
10
|
+
/>
|
|
11
|
+
<path
|
|
12
|
+
d="M395.724 136.361V300.164L187.698 456.017V263.636L395.724 136.361Z"
|
|
13
|
+
:fill="color"
|
|
14
|
+
stroke="#010101"
|
|
15
|
+
stroke-width="12"
|
|
16
|
+
stroke-miterlimit="10"
|
|
17
|
+
/>
|
|
18
|
+
<path
|
|
19
|
+
d="M395.724 136.361L187.698 263.636L80.8579 108.141L304.771 4L395.724 136.361Z"
|
|
20
|
+
:fill="color"
|
|
21
|
+
stroke="#010101"
|
|
22
|
+
stroke-width="12"
|
|
23
|
+
stroke-miterlimit="10"
|
|
24
|
+
/>
|
|
25
|
+
<title>{{ ownerName }}'s House</title>
|
|
26
|
+
</g>
|
|
27
|
+
</template>
|
|
28
|
+
<script lang="ts">
|
|
29
|
+
import { PieceType } from './../../types/ui-data';
|
|
30
|
+
import { Component, InjectReactive, Mixins, Prop } from 'vue-property-decorator';
|
|
31
|
+
import Piece from './Piece.vue';
|
|
32
|
+
|
|
33
|
+
@Component({
|
|
34
|
+
created(this: House) {
|
|
35
|
+
this.pieceType = PieceType.House;
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
export default class House extends Mixins(Piece) {
|
|
39
|
+
@InjectReactive()
|
|
40
|
+
readonly player!: number;
|
|
41
|
+
|
|
42
|
+
@Prop()
|
|
43
|
+
color?: string;
|
|
44
|
+
|
|
45
|
+
@Prop()
|
|
46
|
+
owner?: number;
|
|
47
|
+
|
|
48
|
+
@Prop()
|
|
49
|
+
ownerName?: string;
|
|
50
|
+
}
|
|
51
|
+
</script>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<g :id="elId" :class="['piece']" :transform="`translate(${currentX}, ${currentY})`">
|
|
3
|
+
<g transform="scale(0.08)">
|
|
4
|
+
<path
|
|
5
|
+
d="M136.8 21.2L43.1001 48.9L43.2001 167.2L135.2 210.3L228.8 174V55.7L136.8 21.2Z"
|
|
6
|
+
fill="#5a2d0c"
|
|
7
|
+
stroke="black"
|
|
8
|
+
stroke-width="20"
|
|
9
|
+
stroke-miterlimit="10"
|
|
10
|
+
/>
|
|
11
|
+
<path d="M135.2 210.3L43.2001 167.2L43.1001 48.8999L135.1 83.4999L135.2 210.3Z" fill="#70380f" />
|
|
12
|
+
<path d="M135.1 83.5L43.1001 48.9L136.8 21.2L228.8 55.7L135.1 83.5Z" fill="#8b4513" />
|
|
13
|
+
<path d="M228.8 55.7V174L135.2 210.3L135.1 83.5L228.8 55.7Z" fill="#5a2d0c" />
|
|
14
|
+
</g>
|
|
15
|
+
|
|
16
|
+
<g transform="translate(5, 0)">
|
|
17
|
+
<path d="M6,4 A6,4,0 0,1 14,4 L14,16 A6,4 0 0,1 6,16Z" fill="none" stroke="black" />
|
|
18
|
+
<path d="M6,4 A6,4 0 0,0 14,4 A6,4 0 0,0 6,4" fill="#556" />
|
|
19
|
+
<path d="M6,4 A6,4 0 0,0 6,4 L6,16 A6,4,0 0,0 14,16 L14,4 A6,4 0 0,1 6,4" fill="url(#oil-linear)" />
|
|
20
|
+
</g>
|
|
21
|
+
|
|
22
|
+
<title>Coal/Oil</title>
|
|
23
|
+
</g>
|
|
24
|
+
</template>
|
|
25
|
+
<script lang="ts">
|
|
26
|
+
import { PieceType } from './../../types/ui-data';
|
|
27
|
+
import { Component, Mixins } from 'vue-property-decorator';
|
|
28
|
+
import Piece from './Piece.vue';
|
|
29
|
+
|
|
30
|
+
@Component({
|
|
31
|
+
created(this: Hybrid) {
|
|
32
|
+
this.pieceType = PieceType.Hybrid;
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
export default class Hybrid extends Mixins(Piece) {
|
|
36
|
+
}
|
|
37
|
+
</script>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<g
|
|
3
|
+
:id="elId"
|
|
4
|
+
:class="[{ canClick: canClick }]"
|
|
5
|
+
:transform="`translate(${currentX}, ${currentY}) scale(${scale})`"
|
|
6
|
+
:opacity="transparent ? 0.3 : 1"
|
|
7
|
+
@click="canClick && $emit('click')"
|
|
8
|
+
>
|
|
9
|
+
<path d="M6,4 A6,4,0 0,1 14,4 L14,16 A6,4 0 0,1 6,16Z" fill="none" stroke="black" />
|
|
10
|
+
<path d="M6,4 A6,4 0 0,0 14,4 A6,4 0 0,0 6,4" fill="#556" />
|
|
11
|
+
<path d="M6,4 A6,4 0 0,0 6,4 L6,16 A6,4,0 0,0 14,16 L14,4 A6,4 0 0,1 6,4" fill="url(#oil-linear)" />
|
|
12
|
+
|
|
13
|
+
<title>Oil</title>
|
|
14
|
+
|
|
15
|
+
<defs>
|
|
16
|
+
<linearGradient id="oil-linear" x1="0" y1="10" x2="20" y2="10" gradientUnits="userSpaceOnUse">
|
|
17
|
+
<stop stop-color="#445" />
|
|
18
|
+
<stop offset="1" stop-color="#223" />
|
|
19
|
+
</linearGradient>
|
|
20
|
+
</defs>
|
|
21
|
+
</g>
|
|
22
|
+
</template>
|
|
23
|
+
<script lang="ts">
|
|
24
|
+
import { PieceType } from './../../types/ui-data';
|
|
25
|
+
import { Component, Mixins, Prop } from 'vue-property-decorator';
|
|
26
|
+
import Piece from './Piece.vue';
|
|
27
|
+
|
|
28
|
+
@Component({
|
|
29
|
+
created(this: Oil) {
|
|
30
|
+
this.pieceType = PieceType.Oil;
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
export default class Oil extends Mixins(Piece) {
|
|
34
|
+
@Prop()
|
|
35
|
+
canClick?: boolean;
|
|
36
|
+
|
|
37
|
+
@Prop({ default: 1 })
|
|
38
|
+
scale?: number;
|
|
39
|
+
}
|
|
40
|
+
</script>
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Vue, Component, Inject, Prop, Watch } from 'vue-property-decorator';
|
|
3
|
+
import { EventEmitter } from 'events';
|
|
4
|
+
import { PieceType, UIData } from './../../types/ui-data';
|
|
5
|
+
|
|
6
|
+
@Component({
|
|
7
|
+
created(this: Piece) {
|
|
8
|
+
},
|
|
9
|
+
mounted(this: Piece) {
|
|
10
|
+
this.mounted = true;
|
|
11
|
+
},
|
|
12
|
+
beforeDestroy(this: Piece) {
|
|
13
|
+
this.onTransitionEnd();
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
export default class Piece extends Vue {
|
|
17
|
+
@Prop({ default: () => ({ x: 0, y: 0, rotate: 0 }) })
|
|
18
|
+
targetState!: {
|
|
19
|
+
x: number,
|
|
20
|
+
y: number,
|
|
21
|
+
rotate: number,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
@Prop()
|
|
25
|
+
pieceId!: string;
|
|
26
|
+
|
|
27
|
+
@Prop()
|
|
28
|
+
transparent?: boolean;
|
|
29
|
+
|
|
30
|
+
@Inject()
|
|
31
|
+
readonly communicator!: EventEmitter;
|
|
32
|
+
|
|
33
|
+
@Inject()
|
|
34
|
+
readonly ui!: UIData;
|
|
35
|
+
|
|
36
|
+
public pieceType!: PieceType;
|
|
37
|
+
|
|
38
|
+
currentX = 0;
|
|
39
|
+
currentY = 0;
|
|
40
|
+
mounted = false;
|
|
41
|
+
transitioning = false;
|
|
42
|
+
transitionCount = 0;
|
|
43
|
+
|
|
44
|
+
moving = false;
|
|
45
|
+
|
|
46
|
+
startTransitioning() {
|
|
47
|
+
if (this.transitioning) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
this.ui.waitingAnimations += 1;
|
|
52
|
+
this.transitioning = true;
|
|
53
|
+
this.transitionCount += 1;
|
|
54
|
+
|
|
55
|
+
const count = this.transitionCount;
|
|
56
|
+
|
|
57
|
+
// Safeguard to make sure even if we don't catch the transition end event, we stop the transition
|
|
58
|
+
setTimeout(() => {
|
|
59
|
+
if (count === this.transitionCount) {
|
|
60
|
+
this.onTransitionEnd();
|
|
61
|
+
}
|
|
62
|
+
}, 1000);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@Watch('dragging')
|
|
66
|
+
@Watch('targetState', { immediate: true })
|
|
67
|
+
onTargetChanged(newVal: boolean, oldVal: boolean) {
|
|
68
|
+
if (this.targetState.x === this.currentX && this.targetState.y === this.currentY) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!this.transitioning && this.mounted) {
|
|
73
|
+
if (!(oldVal && !newVal)) {
|
|
74
|
+
this.startTransitioning();
|
|
75
|
+
} else {
|
|
76
|
+
this.moving = true;
|
|
77
|
+
setTimeout(() => this.moving = false, 800);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (!this.mounted) {
|
|
82
|
+
this.currentX = this.targetState.x;
|
|
83
|
+
this.currentY = this.targetState.y;
|
|
84
|
+
} else {
|
|
85
|
+
// Make sure the animation plays by waiting until the class "dragging" is removed for sure from the element
|
|
86
|
+
setTimeout(() => {
|
|
87
|
+
this.currentX = this.targetState.x;
|
|
88
|
+
this.currentY = this.targetState.y;
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
onTransitionEnd() {
|
|
94
|
+
if (this.transitioning) {
|
|
95
|
+
this.transitioning = false;
|
|
96
|
+
this.ui.waitingAnimations = Math.max(this.ui.waitingAnimations - 1, 0);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
get elId() {
|
|
101
|
+
return this.transitioning || this.moving ? 'moving' : undefined;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
</script>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<g
|
|
3
|
+
:id="elId"
|
|
4
|
+
:class="[{ canClick: canClick }]"
|
|
5
|
+
:transform="`translate(${currentX}, ${currentY})`"
|
|
6
|
+
:opacity="transparent ? 0.3 : 1"
|
|
7
|
+
@click="canClick && $emit('click')"
|
|
8
|
+
>
|
|
9
|
+
<path d="M3,3 l4,-2 l6,0 l4,2 l0,11 l-4,2 l-6,0 l-4,-2Z" fill="#F00" stroke="black" />
|
|
10
|
+
<path d="M3,3 l4,-2 l6,0 l4,2 l0,2.1 l-4,2 l-6,0 l-4,-2 l0,-2.1" fill="#F00" />
|
|
11
|
+
<path d="M3,5 l0,9 l4.1,2 l0,-9 l-4.1,-2" fill="#e60000" />
|
|
12
|
+
<path d="M7,7 l6.1,0 l0,9 l-6.1,0 l0,-9" fill="#cc0000" />
|
|
13
|
+
<path d="M13,7 l4.1,-2 l0,9 l-4.1,2 l0,-9" fill="#b30000" />
|
|
14
|
+
|
|
15
|
+
<title>Uranium</title>
|
|
16
|
+
</g>
|
|
17
|
+
</template>
|
|
18
|
+
<script lang="ts">
|
|
19
|
+
import { PieceType } from './../../types/ui-data';
|
|
20
|
+
import { Component, Mixins, Prop } from 'vue-property-decorator';
|
|
21
|
+
import Piece from './Piece.vue';
|
|
22
|
+
|
|
23
|
+
@Component({
|
|
24
|
+
created(this: Uranium) {
|
|
25
|
+
this.pieceType = PieceType.Uranium;
|
|
26
|
+
}
|
|
27
|
+
})
|
|
28
|
+
export default class Uranium extends Mixins(Piece) {
|
|
29
|
+
@Prop()
|
|
30
|
+
canClick?: boolean;
|
|
31
|
+
}
|
|
32
|
+
</script>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import Card from './Card.vue';
|
|
2
|
+
import Coal from './Coal.vue';
|
|
3
|
+
import Garbage from './Garbage.vue';
|
|
4
|
+
import House from './House.vue';
|
|
5
|
+
import Hybrid from './Hybrid.vue';
|
|
6
|
+
import Oil from './Oil.vue';
|
|
7
|
+
import Piece from './Piece.vue';
|
|
8
|
+
import Uranium from './Uranium.vue';
|
|
9
|
+
|
|
10
|
+
export { Card, House, Coal, Oil, Garbage, Uranium, Hybrid, Piece };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M14.601 21.5c0 1.38-1.116 2.5-2.499 2.5-1.378 0-2.499-1.12-2.499-2.5s1.121-2.5 2.499-2.5c1.383 0 2.499 1.119 2.499 2.5zm-2.42-21.5c-4.029 0-7.06 2.693-7.06 8h3.955c0-2.304.906-4.189 3.024-4.189 1.247 0 2.57.828 2.684 2.411.123 1.666-.767 2.511-1.892 3.582-2.924 2.78-2.816 4.049-2.816 7.196h3.943c0-1.452-.157-2.508 1.838-4.659 1.331-1.436 2.986-3.222 3.021-5.943.047-3.963-2.751-6.398-6.697-6.398z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M24 12c0 6.627-5.373 12-12 12s-12-5.373-12-12h2c0 5.514 4.486 10 10 10s10-4.486 10-10-4.486-10-10-10c-2.777 0-5.287 1.141-7.099 2.977l2.061 2.061-6.962 1.354 1.305-7.013 2.179 2.18c2.172-2.196 5.182-3.559 8.516-3.559 6.627 0 12 5.373 12 12zm-13-6v8h7v-2h-5v-6h-2z"/></svg>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="475.452px" height="475.451px" viewBox="0 0 475.452 475.451">
|
|
2
|
+
<g>
|
|
3
|
+
<path d="M468.083,118.385c-3.99-5.33-9.61-9.419-16.854-12.275c0.387,6.665-0.086,12.09-1.42,16.281l-85.65,281.789
|
|
4
|
+
c-1.526,4.948-4.859,8.897-9.992,11.848c-5.141,2.953-10.469,4.428-15.989,4.428H74.66c-22.84,0-36.542-6.652-41.112-19.985
|
|
5
|
+
c-1.903-5.14-1.807-9.229,0.288-12.275c2.092-2.857,5.708-4.288,10.85-4.288h248.102c17.702,0,29.93-3.285,36.688-9.852
|
|
6
|
+
c6.763-6.567,13.565-21.177,20.413-43.824l78.228-258.669c4.186-14.084,2.474-26.457-5.141-37.113s-18.462-15.987-32.548-15.987
|
|
7
|
+
H173.163c-2.474,0-7.329,0.854-14.562,2.568l0.284-0.859c-5.33-1.14-9.851-1.662-13.562-1.571
|
|
8
|
+
c-3.71,0.099-7.137,1.192-10.277,3.289c-3.14,2.094-5.664,4.328-7.566,6.706c-1.903,2.38-3.761,5.426-5.568,9.136
|
|
9
|
+
c-1.805,3.715-3.33,7.142-4.567,10.282c-1.237,3.14-2.666,6.473-4.281,9.998c-1.62,3.521-3.186,6.423-4.71,8.706
|
|
10
|
+
c-1.143,1.523-2.758,3.521-4.854,5.996c-2.091,2.474-3.805,4.664-5.137,6.567c-1.331,1.903-2.19,3.616-2.568,5.14
|
|
11
|
+
c-0.378,1.711-0.19,4.233,0.571,7.566c0.76,3.328,1.047,5.753,0.854,7.277c-0.76,7.232-3.378,16.414-7.849,27.552
|
|
12
|
+
c-4.471,11.136-8.52,19.18-12.135,24.126c-0.761,0.95-2.853,3.092-6.28,6.424c-3.427,3.33-5.52,6.23-6.279,8.704
|
|
13
|
+
c-0.762,0.951-0.81,3.617-0.144,7.994c0.666,4.38,0.907,7.423,0.715,9.136c-0.765,6.473-3.14,15.037-7.139,25.697
|
|
14
|
+
c-3.999,10.657-7.994,19.414-11.993,26.265c-0.569,1.141-2.185,3.328-4.853,6.567c-2.662,3.237-4.283,5.902-4.853,7.99
|
|
15
|
+
c-0.38,1.523-0.33,4.188,0.144,7.994c0.473,3.806,0.426,6.66-0.144,8.562c-1.521,7.228-4.377,15.94-8.565,26.125
|
|
16
|
+
c-4.187,10.178-8.47,18.896-12.851,26.121c-1.138,1.906-2.712,4.145-4.708,6.711c-1.999,2.566-3.568,4.805-4.711,6.707
|
|
17
|
+
c-1.141,1.903-1.903,3.901-2.284,5.996c-0.19,1.143,0.098,2.998,0.859,5.571c0.76,2.566,1.047,4.612,0.854,6.14
|
|
18
|
+
c-0.192,2.662-0.57,6.187-1.141,10.567c-0.572,4.373-0.859,6.939-0.859,7.699c-4.187,11.424-3.999,23.511,0.572,36.269
|
|
19
|
+
c5.33,14.838,14.797,27.36,28.406,37.541c13.61,10.185,27.74,15.27,42.398,15.27h263.521c12.367,0,24.026-4.141,34.971-12.416
|
|
20
|
+
c10.944-8.281,18.227-18.507,21.837-30.696l78.511-258.662C477.412,141.51,475.701,129.234,468.083,118.385z M164.31,118.956
|
|
21
|
+
l5.997-18.274c0.76-2.474,2.329-4.615,4.709-6.423c2.38-1.805,4.808-2.712,7.282-2.712h173.589c2.663,0,4.565,0.903,5.708,2.712
|
|
22
|
+
c1.14,1.809,1.335,3.949,0.575,6.423l-6.002,18.274c-0.764,2.475-2.327,4.611-4.713,6.424c-2.382,1.805-4.805,2.708-7.278,2.708
|
|
23
|
+
H170.593c-2.666,0-4.568-0.9-5.711-2.708C163.74,123.567,163.55,121.431,164.31,118.956z M140.615,192.045l5.996-18.271
|
|
24
|
+
c0.76-2.474,2.331-4.615,4.709-6.423c2.38-1.809,4.805-2.712,7.282-2.712h173.583c2.666,0,4.572,0.9,5.712,2.712
|
|
25
|
+
c1.14,1.809,1.331,3.949,0.568,6.423l-5.996,18.271c-0.759,2.474-2.33,4.617-4.708,6.423c-2.383,1.809-4.805,2.712-7.283,2.712
|
|
26
|
+
H146.895c-2.664,0-4.567-0.9-5.708-2.712C140.043,196.662,139.854,194.519,140.615,192.045z"/>
|
|
27
|
+
</g>
|
|
28
|
+
</svg>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
|
2
|
+
<path d="M5 17h-5v-10h5v10zm2-10v10l9 5v-20l-9 5zm15.324 4.993l1.646-1.659-1.324-1.324-1.651 1.67-1.665-1.648-1.316 1.318 1.67 1.657-1.65 1.669 1.318 1.317 1.658-1.672 1.666 1.653 1.324-1.325-1.676-1.656z"/>
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="497.25px" height="497.25px" viewBox="0 0 497.25 497.25" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path fill="black" d="M248.625,89.25 V0 l-127.5,127.5 l127.5,127.5 V140.25 c84.15,0,153,68.85,153,153 c0,84.15-68.85,153-153,153 c-84.15,0-153-68.85-153-153 h-51 c0,112.2,91.8,204,204,204 s204-91.8,204-204 S360.825,89.25,248.625,89.25z"/>
|
|
3
|
+
</svg>
|