Commit | Line | Data |
---|---|---|
ccd4a2b7 BA |
1 | <template lang="pug"> |
2 | div | |
5b020e73 BA |
3 | input#modalNewgame.modal(type="checkbox") |
4 | div(role="dialog" aria-labelledby="titleFenedit") | |
5 | .card.smallpad | |
6 | label#closeNewgame.modal-close(for="modalNewgame") | |
7 | fieldset | |
8 | label(for="selectVariant") {{ st.tr["Variant"] }} | |
9 | select#selectVariant(v-model="newgameInfo.vid") | |
10 | option(v-for="v in variants" :value="v.id") {{ v.name }} | |
11 | fieldset | |
12 | label(for="selectNbPlayers") {{ st.tr["Number of players"] }} | |
13 | select#selectNbPlayers(v-model="newgameInfo.nbPlayers") | |
14 | option(v-show="possibleNbplayers(2)" value="2") 2 | |
15 | option(v-show="possibleNbplayers(3)" value="3") 3 | |
16 | option(v-show="possibleNbplayers(4)" value="4") 4 | |
17 | fieldset | |
18 | label(for="timeControl") Time control (in days) | |
19 | #timeControl | |
20 | input(type="number" v-model="newgameInfo.mainTime" | |
21 | placeholder="Main time") | |
22 | input(type="number" v-model="newgameInfo.increment" | |
23 | placeholder="Increment") | |
24 | fieldset | |
25 | label(for="selectPlayers") {{ st.tr["Play with?"] }} | |
26 | #selectPlayers | |
27 | input(type="text" v-model="newgameInfo.players[0].name") | |
28 | input(v-show="newgameInfo.nbPlayers>=3" type="text" | |
29 | v-model="newgameInfo.players[1].name") | |
30 | input(v-show="newgameInfo.nbPlayers==4" type="text" | |
31 | v-model="newgameInfo.players[2].name") | |
32 | fieldset | |
33 | label(for="inputFen") | |
34 | {{ st.tr["FEN (ignored if players fields are blank)"] }} | |
35 | input#inputFen(type="text" v-model="newgameInfo.fen") | |
36 | button(@click="newGame") Launch game | |
37 | p TODO: cadence, adversaire (pre-filled if click on name) | |
38 | p cadence 2m+12s ou 7d+1d (m,s ou d,d) --> main, increment | |
39 | p Note: leave FEN blank for random; FEN only for targeted challenge | |
40 | div | |
41 | my-challenge-list(:challenges="challenges" @click-challenge="clickChallenge") | |
42 | div(style="border:1px solid black") | |
43 | h3 Online players | |
44 | div(v-for="p in players" @click="challenge(p)") {{ p.name }} | |
45 | button(onClick="doClick('modalNewgame')") New game | |
46 | div | |
47 | .button-group | |
48 | button(@click="gdisplay='live'") Live games | |
49 | button(@click="gdisplay='corr'") Correspondance games | |
50 | my-game-list(v-show="gdisplay=='live'" :games="liveGames" | |
51 | @show-game="showGame") | |
52 | my-game-list(v-show="gdisplay=='corr'" :games="corrGames" | |
53 | @show-game="showGame") | |
625022fd BA |
54 | </template> |
55 | ||
56 | <script> | |
5b020e73 BA |
57 | // main playing hall: online players + current challenges + button "new game" |
58 | // TODO: si on est en train de jouer une partie, le notifier aux nouveaux connectés | |
59 | /* | |
60 | TODO: surligner si nouveau défi perso et pas affichage courant | |
61 | (cadences base + incrément, corr == incr >= 1jour ou base >= 7j) | |
62 | --> correspondance: stocker sur serveur lastMove + uid + color + movesCount + gameId + variant + timeleft | |
63 | fin de partie corr: supprimer partie du serveur au bout de 7 jours (arbitraire) | |
64 | */ | |
65 | // TODO: au moins l'échange des coups en P2P ? et game chat ? | |
66 | // TODO: objet game, objet challenge ? et player ? | |
67 | import { store } from "@/store"; | |
68 | import GameList from "@/components/GameList.vue"; | |
69 | import ChallengeList from "@/components/ChallengeList.vue"; | |
625022fd BA |
70 | export default { |
71 | name: "home", | |
5b020e73 BA |
72 | components: { |
73 | GameList, | |
74 | ChallengeList, | |
75 | }, | |
76 | data: function () { | |
77 | return { | |
78 | st: store.state, | |
79 | gdisplay: "live", | |
80 | liveGames: [], | |
81 | corrGames: [], | |
82 | players: [], //online players | |
83 | challenges: [], //live challenges | |
84 | willPlay: [], //IDs of challenges in which I decide to play (>= 3 players) | |
85 | newgameInfo: { | |
86 | fen: "", | |
87 | vid: 0, | |
88 | nbPlayers: 0, | |
89 | players: [{id:0,name:""},{id:0,name:""},{id:0,name:""}], | |
90 | mainTime: 0, | |
91 | increment: 0, | |
92 | }, | |
93 | }; | |
8d61fc4a | 94 | }, |
ccd4a2b7 | 95 | created: function() { |
5b020e73 | 96 | // TODO: ask server for current corr games (all but mines: names, ID, time control) |
ccd4a2b7 BA |
97 | const socketMessageListener = msg => { |
98 | const data = JSON.parse(msg.data); | |
5b020e73 BA |
99 | switch (data.code) |
100 | { | |
101 | case "newgame": | |
102 | // TODO: new game just started: data contain all informations | |
103 | // (id, players, time control, fenStart ...) | |
104 | break; | |
105 | // TODO: also receive live games summaries (update) | |
106 | // (just players names, time control, and ID + player ID) | |
107 | case "acceptchallenge": | |
108 | // oppid: opponent socket ID (or DB id if registered) | |
109 | if (true) //TODO: if challenge is full | |
110 | this.newGame(data.challenge, data.user); //user.id et user.name | |
111 | break; | |
112 | case "withdrawchallenge": | |
113 | // TODO | |
114 | break; | |
115 | case "cancelchallenge": | |
116 | // TODO | |
117 | break; | |
118 | // TODO: distinguish these (dis)connect events from their analogs in game.js | |
119 | case "connect": | |
120 | this.players.push({name:data.name, id:data.uid}); | |
121 | break; | |
122 | case "disconnect": | |
123 | const pIdx = this.players.findIndex(p => p.id == data.uid); | |
124 | this.players.splice(pIdx); | |
125 | break; | |
126 | } | |
ccd4a2b7 BA |
127 | }; |
128 | const socketCloseListener = () => { | |
5b020e73 BA |
129 | this.st.conn.addEventListener('message', socketMessageListener); |
130 | this.st.conn.addEventListener('close', socketCloseListener); | |
ccd4a2b7 | 131 | }; |
5b020e73 BA |
132 | this.st.conn.onmessage = socketMessageListener; |
133 | this.st.conn.onclose = socketCloseListener; | |
134 | }, | |
135 | methods: { | |
136 | showGame: function(game) { | |
137 | // NOTE: if we are an observer, the game will be found in main games list | |
138 | // (sent by connected remote players) | |
139 | this.$router.push("/" + game.id) | |
140 | }, | |
141 | challenge: function(player) { | |
142 | this.st.conn.send(JSON.stringify({code:"sendchallenge", oppid:p.id, | |
143 | user:{name:this.st.user.name,id:this.st.user.id}})); | |
144 | }, | |
145 | clickChallenge: function(challenge) { | |
146 | const index = this.challenges.findIndex(c => c.id == challenge.id); | |
147 | const toIdx = challenge.to.findIndex(p => p.id == user.id); | |
148 | const me = {name:user.name,id:user.id}; | |
149 | if (toIdx >= 0) | |
150 | { | |
151 | // It's a multiplayer challenge I accepted: withdraw | |
152 | this.st.conn.send(JSON.stringify({code:"withdrawchallenge", | |
153 | cid:challenge.id, user:me})); | |
154 | this.challenges.to.splice(toIdx, 1); | |
155 | } | |
156 | else if (challenge.from.id == user.id) //it's my challenge: cancel it | |
157 | { | |
158 | this.st.conn.send(JSON.stringify({code:"cancelchallenge", cid:challenge.id})); | |
159 | this.challenges.splice(index, 1); | |
160 | } | |
161 | else //accept a challenge | |
162 | { | |
163 | this.st.conn.send(JSON.stringify({code:"acceptchallenge", | |
164 | cid:challenge.id, user:me})); | |
165 | this.challenges[index].to.push(me); | |
166 | } | |
167 | // TODO: accepter un challenge peut lancer une partie, il | |
168 | // faut alors supprimer challenge + creer partie + la retourner et l'ajouter ici | |
169 | // autres actions: | |
170 | // supprime mon défi | |
171 | // accepte un défi | |
172 | // annule l'acceptation d'un défi (si >= 3 joueurs) | |
173 | // | |
174 | // si pas le mien et FEN speciale :: (charger code variante et) | |
175 | // montrer diagramme + couleur (orienté) | |
176 | }, | |
177 | // user: last person to accept the challenge | |
178 | newGameLive: function(chall, user) { | |
179 | const fen = chall.fen || V.GenRandInitFen(); | |
180 | const game = {}; //TODO: fen, players, time ... | |
181 | //setStorage(game); //TODO | |
182 | game.players.forEach(p => { | |
183 | this.conn.send( | |
184 | JSON.stringify({code:"newgame", oppid:p.id, game:game})); | |
185 | }); | |
186 | if (this.settings.sound >= 1) | |
187 | new Audio("/sounds/newgame.mp3").play().catch(err => {}); | |
188 | }, | |
189 | newGame: function() { | |
190 | const afterRulesAreLoaded = () => { | |
191 | // NOTE: side-effect = set FEN | |
192 | // TODO: (to avoid any cheating option) separate the GenRandInitFen() functions | |
193 | // in separate files, load on server and generate FEN on server. | |
194 | const error = checkChallenge(this.newgameInfo, vname); | |
195 | if (!!error) | |
196 | return alert(error); | |
197 | // Possible (server) error if filled player does not exist | |
198 | ajax( | |
199 | "/challenges/" + this.newgameInfo.vid, | |
200 | "POST", | |
201 | this.newgameInfo, | |
202 | response => { | |
203 | const chall = Object.assign({}, | |
204 | this.newgameInfo, | |
205 | { | |
206 | id: response.cid, | |
207 | uid: user.id, | |
208 | added: Date.now(), | |
209 | vname: vname, | |
210 | }, | |
211 | this.challenges.push(response.challenge); | |
212 | } | |
213 | ); | |
214 | // TODO: else, if live game: send infos (socket), and... | |
215 | }; | |
216 | const idxInVariants = | |
217 | variantArray.findIndex(v => v.id == this.newgameInfo.vid); | |
218 | const vname = variantArray[idxInVariants].name; | |
219 | const scriptId = vname + "RulesScript"; | |
220 | if (!document.getElementById(scriptId)) | |
221 | { | |
222 | // Load variant rules (only once) | |
223 | var script = document.createElement("script"); | |
224 | script.id = scriptId; | |
225 | script.onload = afterRulesAreLoaded; | |
226 | //script.addEventListener ("load", afterRulesAreLoaded, false); | |
227 | script.src = "/javascripts/variants/" + vname + ".js"; | |
228 | document.body.appendChild(script); | |
229 | } | |
230 | else | |
231 | afterRulesAreLoaded(); | |
232 | }, | |
233 | possibleNbplayers: function(nbp) { | |
234 | if (this.newgameInfo.vid == 0) | |
235 | return false; | |
236 | const idxInVariants = | |
237 | variantArray.findIndex(v => v.id == this.newgameInfo.vid); | |
238 | return NbPlayers[variantArray[idxInVariants].name].includes(nbp); | |
239 | }, | |
8d61fc4a | 240 | }, |
5b020e73 | 241 | }); |
ccd4a2b7 | 242 | </script> |