]> git.sesse.net Git - ultimatescore/blob - score.js
Add code for computing the best thirds.
[ultimatescore] / score.js
1 'use strict';
2
3 let num_clocks = 2;
4 let clocks = [
5         { 'running': false, 'elapsed': 0, 'origin': undefined, 'id': 'clock' },
6         { 'running': false, 'elapsed': 0, 'origin': undefined, 'id': 'clock2' }
7 ];
8
9 let clock_visible = false;
10 let comment_visible = false;
11 let lowerthird_visible = false;
12 let clock_limit = 30 * 60;
13 let scoreA = 0;
14 let scoreB = 0;
15 let state = {};
16
17 function setteams()
18 {
19         document.getElementById('team1').innerHTML = state['team1'];
20         document.getElementById('team2').innerHTML = state['team2'];
21
22         let sheets = { 'A': state['team1'], 'B': state['team2'] };
23         loadquickl3s(sheets);
24 }
25
26 function setteams2()
27 {
28         document.getElementById('score2_team1').innerHTML = state['team1'];
29         document.getElementById('score2_team2').innerHTML = state['team2'];
30 }
31
32 function setcolors()
33 {
34         document.getElementById('team1color').style.backgroundColor = state['team1color'];
35         document.getElementById('team2color').style.backgroundColor = state['team2color'];
36 }
37
38 function setscore()
39 {
40         scoreA = state['score1'];
41         scoreB = state['score2'];
42         update_score();
43 }
44
45 function setscore2()
46 {
47         scoreA = state['score1'];
48         scoreB = state['score2'];
49         document.getElementById('score2_score').innerHTML = scoreA + " – " + scoreB;
50 }
51
52 function startclock(num)
53 {
54         if (!clocks[num].running) {
55                 clocks[num].origin = Date.now();
56                 clocks[num].running = true;
57         }
58         if (num == 0) {
59                 showclock();
60         }
61 }
62
63 function stopclock(num)
64 {
65         if (!clocks[num].running) return;
66         clocks[num].elapsed = time_elapsed(num);
67         clocks[num].origin = Date.now();
68         clocks[num].running = false;
69 }
70
71 function setclock(num, amount)
72 {
73         clocks[num].elapsed = amount;
74         clocks[num].origin = Date.now();
75         update_clock(num);
76 }
77
78 function setclockfromstate()
79 {
80         let amount = parseInt(state['clock_min']) * 60 + parseInt(state['clock_sec']);
81         setclock(0, amount);
82 }
83
84 // No setclock2fromstate.
85
86 function adjustclockfromstate(num)
87 {
88         let amount = parseInt(state['clock_min']) * 60 + parseInt(state['clock_sec']);
89         let elapsed = time_elapsed_raw(num);
90         if (Math.abs(amount - elapsed) >= 2.0) {
91                 setclock(num, amount);
92         }
93 }
94
95 function setclocklimitfromstate()
96 {
97         let amount = parseInt(state['clock_limit_min']) * 60 + parseInt(state['clock_limit_sec']);
98         clock_limit = amount;
99 }
100
101 function showclock()
102 {
103         if (clock_visible) return;
104         let clockbug = document.getElementById('clockbug');
105         clockbug.className = 'clockbug clockbug-animate-in';
106         clock_visible = true;
107 }
108
109 function hideclock()
110 {
111         if (!clock_visible) return;
112         let clockbug = document.getElementById('clockbug');
113         clockbug.className = 'clockbug clockbug-animate-out';
114         clock_visible = false;
115 }
116
117 function setcomment()
118 {
119         document.getElementById('comment').innerHTML = state['comment'];
120 }
121
122 function showcomment()
123 {
124         if (comment_visible) return;
125         let commentbug = document.getElementById('commentbug');
126         commentbug.className = 'commentbug commentbug-animate-in';
127         comment_visible = true;
128 }
129
130 function hidecomment()
131 {
132         if (!comment_visible) return;
133         let commentbug = document.getElementById('commentbug');
134         commentbug.className = 'commentbug commentbug-animate-out';
135         comment_visible = false;
136 }
137
138 function showlowerthird()
139 {
140         if (lowerthird_visible) return;
141
142         document.getElementById('lowerthird-headline').className = 'lowerthird-headline lowerthird-headline-animate-in';
143         document.getElementById('lowerthird-headline-content').className = 'lowerthird-headline-content lowerthird-headline-content-animate-in';
144         document.getElementById('lowerthird-subheading').className = 'lowerthird-subheading lowerthird-subheading-animate-in';
145         document.getElementById('lowerthird-subheading-content').className = 'lowerthird-subheading-content lowerthird-subheading-content-animate-in';
146         document.getElementById('lowerthird-picture').className = 'lowerthird-picture lowerthird-picture-animate-in';
147         document.getElementById('lowerthird-picture-content').className = 'lowerthird-picture-content lowerthird-picture-content-animate-in';
148         lowerthird_visible = true;
149 }
150
151 function setandshowlowerthird()
152 {
153         document.getElementById('lowerthird-headline-content').innerHTML = state['text1'];
154         document.getElementById('lowerthird-subheading-content').innerHTML = state['text2'];
155         let img = document.getElementById('lowerthird-img');
156         if (state['image'] === undefined) {
157                 img.style.display = 'none';
158         } else {
159                 img.src = state['image'];
160                 img.style.display = 'inline';
161         }
162         showlowerthird();
163 }
164
165 function hidelowerthird()
166 {
167         if (!lowerthird_visible) return;
168         document.getElementById('lowerthird-headline').className = 'lowerthird-headline lowerthird-headline-hidden lowerthird-headline-animate-out';
169         document.getElementById('lowerthird-headline-content').className = 'lowerthird-headline-content lowerthird-headline-content-animate-out';
170         document.getElementById('lowerthird-subheading').className = 'lowerthird-subheading lowerthird-subheading-animate-out';
171         document.getElementById('lowerthird-subheading-content').className = 'lowerthird-subheading-content lowerthird-subheading-content-animate-out';
172         document.getElementById('lowerthird-picture').className = 'lowerthird-picture lowerthird-picture-animate-out';
173         document.getElementById('lowerthird-picture-content').className = 'lowerthird-picture-content lowerthird-picture-content-animate-out';
174         lowerthird_visible = false;
175 }
176
177 function time_elapsed_raw(num)
178 {
179         let elapsed = (Date.now() - clocks[num].origin) * 1e-3;
180         if (clocks[num].elapsed + elapsed >= clock_limit) {
181                 console.log("limit for", num);
182                 if (num == 0) {
183                         clocks[num].elapsed = clock_limit;
184                         clocks[num].origin = Date.now();
185                         clocks[num].running = false;
186
187                         if (state['autocomment_on_clock_limit'] == '1' && !comment_visible) {
188                                 state['comment'] = state['autocomment'];
189                                 setcomment();
190                                 showcomment();
191                         }
192                 }
193
194                 return clock_limit;
195         }
196         return clocks[num].elapsed + elapsed;
197 }
198
199 function time_elapsed(num)
200 {
201         return Math.floor(time_elapsed_raw(num));
202 }
203
204 function update_given_clock(elapsed, id)
205 {
206         let min = Math.floor(elapsed / 60);
207         let sec = elapsed % 60;
208
209         if (sec < 10) sec = "0" + sec;
210         let text = min + ":" + sec;
211
212         if (ultimateconfig['exohack']) {
213                 // This is a hack around the fact that Exo has variable-width numerals.
214                 // It doesn't look fantastic, but for the clock, it's better not to have
215                 // the text jumping around.
216                 let html = "";
217                 for (let i = 0; i < text.length; ++i) {
218                         if (text.charAt(i) === ':') {
219                                 html += ':';
220                         } else {
221                                 html += "<div style='display: inline-block; width: 15px'>" + text.charAt(i) + "</div>";
222                         }
223                 }
224                 document.getElementById(id).innerHTML = html;
225         } else {
226                 document.getElementById(id).innerHTML = text;
227         }
228 }
229
230 function update_clock(num)
231 {
232         update_given_clock(time_elapsed(num), clocks[num].id);
233 }
234
235 function goalA()
236 {
237         ++scoreA;
238         update_score();
239 }
240
241 function goalB()
242 {
243         ++scoreB;
244         update_score();
245 }
246
247 function ungoalA()
248 {
249         if (scoreA > 0) --scoreA;
250         update_score();
251 }
252
253 function ungoalB()
254 {
255         if (scoreB > 0) --scoreB;
256         update_score();
257 }
258
259 function resetscore()
260 {
261         scoreA = scoreB = 0;
262         update_score();
263 }
264
265 function update_score()
266 {
267         document.getElementById('score').innerHTML = scoreA + "&nbsp;–&nbsp;" + scoreB;
268 }
269
270 /* called by the Nageru theme only */
271 function play()
272 {
273         document.getElementById('manualcontrols').style.display = 'none';
274         document.getElementById('area').style.display = 'none';
275 }
276
277 function update(v)
278 {
279         console.log('[[[' + v + ']]]');
280         let j = JSON.parse(v);
281         for(let key in j) state[key] = j[key];
282 }
283
284 setInterval(function() {
285         for (let i = 0; i < num_clocks; ++i) {
286                 if (clocks[i].running) {
287                         update_clock(i);
288                 }
289         }
290 }, 100);
291 update_score();
292
293 //play();
294 //startclock();
295
296 let websocket = null;
297
298 function open_ws()
299 {
300         console.log("Connecting...");
301         try {
302                 if (websocket)
303                         websocket.close();
304                 websocket = new WebSocket("ws://127.0.0.1:5250/");
305                 websocket.onopen = function(evt) {
306                         console.log("Connected to client.");
307                 };
308                 websocket.onclose = function(evt) {
309                         console.log("Disconnected from client.");
310                         setTimeout(open_ws, 100);
311                 };
312                 websocket.onmessage = function(evt) {
313                         let msg = evt.data;
314                         let m = msg.match(/^update (.*)/);
315                         if (m !== null) {
316                                 update(m[1]);
317                         }
318                         m = msg.match(/^eval (.*)/);
319                         if (m !== null) {
320                                 eval(m[1]);
321                         }
322                 };
323                 websocket.onerror = function(evt) {
324                         console.log('Error: ' + evt.data);
325                 };
326         } catch (exception) {
327                 console.log('Error: ' + exception);
328                 setTimeout(open_ws, 100);
329         }
330 };
331 open_ws();