]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/minigames/minigame/qto.qc
Reduce spam of "x minutes" and "x fps" strings of a few sliders
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / minigames / minigame / qto.qc
1 const float QTO_TURN_MOVE  = 0x0100; // player has to click on a piece on the board
2 const float QTO_TURN_WIN   = 0x0200; // player has won
3 const float QTO_TURN_TYPE  = 0x0f00; // turn type mask
4
5 const int QTO_SF_PLAYERSCORE = MINIG_SF_CUSTOM;
6
7 const int QTO_LET_CNT = 5;
8 const int QTO_NUM_CNT = 5;
9
10 const int QTO_TILE_SIZE = 8;
11
12 .int qto_moves;
13
14 // find same game piece given its tile name
15 entity qto_find_piece(entity minig, string tile)
16 {
17         entity e = world;
18         while ( ( e = findentity(e,owner,minig) ) )
19                 if ( e.classname == "minigame_board_piece" && e.netname == tile )
20                         return e;
21         return world;
22 }
23
24 // Checks if the given piece completes a row
25 bool qto_winning_piece(entity minigame)
26 {
27         //int number = minigame_tile_number(piece.netname);
28         //int letter = minigame_tile_letter(piece.netname);
29
30         entity e = world;
31         while ( ( e = findentity(e,owner,minigame) ) )
32                 if ( e.classname == "minigame_board_piece" )
33                 {
34                         if(!e.cnt)
35                                 return false;
36                 }
37
38         return true;
39 }
40
41 // check if the tile name is valid (5x5 grid)
42 bool qto_valid_tile(string tile)
43 {
44         if ( !tile )
45                 return false;
46         float number = minigame_tile_number(tile);
47         float letter = minigame_tile_letter(tile);
48         return 0 <= number && number < QTO_NUM_CNT && 0 <= letter && letter < QTO_LET_CNT;
49 }
50
51 void qto_setup_pieces(entity minigame)
52 {
53         int i, t;
54         for(i = 0; i < QTO_NUM_CNT; ++i)
55         for(t = 0; t < QTO_LET_CNT; ++t)
56         {
57                 entity piece = msle_spawn(minigame,"minigame_board_piece");
58                 piece.team = 1; // init default team?
59                 piece.cnt = 0; // initialize cnt
60                 piece.netname = strzone(minigame_tile_buildname(t,i));
61                 minigame_server_sendflags(piece,MINIG_SF_ALL);
62         }
63
64         minigame_server_sendflags(minigame,MINIG_SF_UPDATE);
65 }
66
67 void qto_add_score(entity minigame, int thescore)
68 {
69 #ifdef SVQC
70         if(!minigame)
71                 return;
72         if(minigame.minigame_players)
73         {
74                 minigame.minigame_players.qto_moves += thescore;
75                 minigame.minigame_players.SendFlags |= QTO_SF_PLAYERSCORE;
76         }
77 #endif
78 }
79
80 // make a move
81 void qto_move(entity minigame, entity player, string pos )
82 {
83         if ( minigame.minigame_flags & QTO_TURN_MOVE )
84         if ( pos )
85         {
86                 if ( qto_valid_tile(pos) )
87                 if ( qto_find_piece(minigame, pos) )
88                 {
89                         entity piece;
90                 #define DO_JUNK \
91                         if(piece) \
92                         { \
93                                 piece.cnt = (piece.cnt) ? 0 : 1; \
94                                 minigame_server_sendflags(piece,MINIG_SF_UPDATE); \
95                         }
96
97                         int number = minigame_tile_number(pos);
98                         int letter = minigame_tile_letter(pos);
99                         piece = qto_find_piece(minigame, pos);
100                         DO_JUNK
101                         piece = qto_find_piece(minigame, minigame_tile_buildname(letter-1,number));
102                         DO_JUNK
103                         piece = qto_find_piece(minigame, minigame_tile_buildname(letter+1,number));
104                         DO_JUNK
105                         piece = qto_find_piece(minigame, minigame_tile_buildname(letter,number-1));
106                         DO_JUNK
107                         piece = qto_find_piece(minigame, minigame_tile_buildname(letter,number+1));
108                         DO_JUNK
109
110                         qto_add_score(minigame,1); // add 1 move score
111
112                         minigame_server_sendflags(minigame,MINIG_SF_UPDATE);
113
114                         if ( qto_winning_piece(minigame) )
115                         {
116                                 minigame.minigame_flags = QTO_TURN_WIN;
117                         }
118                         else
119                                 minigame.minigame_flags = QTO_TURN_MOVE;
120                 }
121         }
122 }
123
124 // restart match
125 void qto_restart_match(entity minigame, entity player)
126 {
127         minigame.minigame_flags = QTO_TURN_MOVE;
128         minigame_server_sendflags(minigame,MINIG_SF_UPDATE);
129         entity e = world;
130         while ( ( e = findentity(e,owner,minigame) ) )
131                 if ( e.classname == "minigame_board_piece" )
132                         remove(e);
133
134         qto_setup_pieces(minigame);
135 #ifdef SVQC
136         if(minigame.minigame_players)
137         {
138                 minigame.minigame_players.qto_moves = 0;
139                 minigame.minigame_players.SendFlags |= QTO_SF_PLAYERSCORE;
140         }
141 #endif
142 }
143
144 #ifdef SVQC
145
146
147 // required function, handle server side events
148 int qto_server_event(entity minigame, string event, ...)
149 {
150         switch(event)
151         {
152                 case "start":
153                 {
154                         qto_setup_pieces(minigame);
155                         minigame.minigame_flags = QTO_TURN_MOVE;
156                         return true;
157                 }
158                 case "end":
159                 {
160                         entity e = world;
161                         while( (e = findentity(e, owner, minigame)) )
162                         if(e.classname == "minigame_board_piece")
163                         {
164                                 if(e.netname) { strunzone(e.netname); }
165                                 remove(e);
166                         }
167                         return false;
168                 }
169                 case "join":
170                 {
171                         int pl_num = minigame_count_players(minigame);
172
173                         // Don't allow more than 1 player
174                         if(pl_num >= 1) { return false; }
175
176                         // Team 1 by default
177                         return 1;
178                 }
179                 case "cmd":
180                 {
181                         switch(argv(0))
182                         {
183                                 case "move":
184                                         qto_move(minigame, ...(0,entity), ...(1,int) == 2 ? argv(1) : string_null );
185                                         return true;
186                                 case "restart":
187                                         qto_restart_match(minigame,...(0,entity));
188                                         return true;
189                         }
190
191                         return false;
192                 }
193                 case "network_send":
194                 {
195                         entity sent = ...(0,entity);
196                         int sf = ...(1,int);
197                         if ( sent.classname == "minigame_board_piece" && (sf & MINIG_SF_UPDATE) )
198                         {
199                                 WriteByte(MSG_ENTITY,sent.cnt);
200                         }
201                         else if ( sent.classname == "minigame_player" && (sf & QTO_SF_PLAYERSCORE ) )
202                         {
203                                 WriteLong(MSG_ENTITY,sent.qto_moves);
204                         }
205                         return false;
206                 }
207         }
208
209         return false;
210 }
211
212
213 #elif defined(CSQC)
214
215 string qto_curr_pos; // identifier of the tile under the mouse
216 vector qto_boardpos; // HUD board position
217 vector qto_boardsize;// HUD board size
218
219 // Required function, draw the game board
220 void qto_hud_board(vector pos, vector mySize)
221 {
222         minigame_hud_fitsqare(pos, mySize);
223         qto_boardpos = pos;
224         qto_boardsize = mySize;
225
226         minigame_hud_simpleboard(pos,mySize,minigame_texture("qto/board"));
227
228         vector tile_size = minigame_hud_denormalize_size('1 1 0' / QTO_TILE_SIZE,pos,mySize);
229         vector tile_pos;
230
231         bool valid = qto_valid_tile(qto_curr_pos);
232         int number = minigame_tile_number(qto_curr_pos);
233         int letter = minigame_tile_letter(qto_curr_pos);
234         string pos1 = minigame_tile_buildname(letter-1,number);
235         string pos2 = minigame_tile_buildname(letter+1,number);
236         string pos3 = minigame_tile_buildname(letter,number-1);
237         string pos4 = minigame_tile_buildname(letter,number+1);
238
239         entity e;
240         FOREACH_MINIGAME_ENTITY(e)
241         {
242                 if ( e.classname == "minigame_board_piece" )
243                 {
244                         tile_pos = minigame_tile_pos(e.netname,QTO_NUM_CNT,QTO_LET_CNT);
245                         tile_pos = minigame_hud_denormalize(tile_pos,pos,mySize);
246
247                         vector tile_color = '0.4 0.4 0.4';
248
249                         if(valid)
250                         switch(e.netname)
251                         {
252                                 case qto_curr_pos:
253                                 case pos1: case pos2: case pos3: case pos4:
254                                         tile_color = '0.8 0.8 0.8';
255                                         break;
256                         }
257
258                         minigame_drawpic_centered( tile_pos,
259                                         minigame_texture(strcat("qto/piece", ftos(e.cnt))),
260                                         tile_size, tile_color, panel_fg_alpha, DRAWFLAG_NORMAL );
261                 }
262         }
263 }
264
265
266 // Required function, draw the game status panel
267 void qto_hud_status(vector pos, vector mySize)
268 {
269         HUD_Panel_DrawBg(1);
270         vector ts;
271         ts = minigame_drawstring_wrapped(mySize_x,pos,active_minigame.descriptor.message,
272                 hud_fontsize * 2, '0.25 0.47 0.72', panel_fg_alpha, DRAWFLAG_NORMAL,0.5);
273
274         pos_y += ts_y;
275         mySize_y -= ts_y;
276
277         vector player_fontsize = hud_fontsize * 1.75;
278         ts_y = ( mySize_y - 2*player_fontsize_y ) / 2;
279         ts_x = mySize_x;
280         vector mypos;
281         vector tile_size = '48 48 0';
282
283         mypos = pos;
284         drawfill(mypos,eX*mySize_x+eY*player_fontsize_y,'1 1 1',0.5,DRAWFLAG_ADDITIVE);
285         mypos_y += player_fontsize_y;
286         drawfill(mypos,eX*mySize_x+eY*tile_size_y,'1 1 1',0.25,DRAWFLAG_ADDITIVE);
287
288         entity e;
289         FOREACH_MINIGAME_ENTITY(e)
290         {
291                 if ( e.classname == "minigame_player" )
292                 {
293                         mypos = pos;
294                         minigame_drawcolorcodedstring_trunc(mySize_x,mypos,
295                                 GetPlayerName(e.minigame_playerslot-1),
296                                 player_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
297
298                         mypos_y += player_fontsize_y;
299                         //drawpic( mypos,
300                         //              minigame_texture("qto/piece"),
301                         //              tile_size, '1 0 0', panel_fg_alpha, DRAWFLAG_NORMAL );
302
303                         //mypos_x += tile_size_x;
304
305                         drawstring(mypos,sprintf(_("Moves: %s"), ftos(e.qto_moves)),'32 32 0',
306                                            '0.7 0.84 1', panel_fg_alpha, DRAWFLAG_NORMAL);
307                 }
308         }
309 }
310
311 // Turn a set of flags into a help message
312 string qto_turn_to_string(int turnflags)
313 {
314         if ( turnflags & QTO_TURN_WIN )
315                 return _("Well done, you win!");
316
317         if ( turnflags & QTO_TURN_MOVE )
318                 return _("Turn all the angry faces into happy faces");
319
320         return "";
321 }
322
323 // Make the correct move
324 void qto_make_move(entity minigame)
325 {
326         if ( minigame.minigame_flags == QTO_TURN_MOVE )
327         {
328                 minigame_cmd("move ",qto_curr_pos);
329         }
330 }
331
332 void qto_set_curr_pos(string s)
333 {
334         if ( qto_curr_pos )
335                 strunzone(qto_curr_pos);
336         if ( s )
337                 s = strzone(s);
338         qto_curr_pos = s;
339 }
340
341 // Required function, handle client events
342 int qto_client_event(entity minigame, string event, ...)
343 {
344         switch(event)
345         {
346                 case "activate":
347                 {
348                         qto_set_curr_pos("");
349                         minigame.message = qto_turn_to_string(minigame.minigame_flags);
350                         return false;
351                 }
352                 case "key_pressed":
353                 {
354                         //if((minigame.minigame_flags & QTO_TURN_TEAM) == minigame_self.team)
355                         {
356                                 switch ( ...(0,int) )
357                                 {
358                                         case K_RIGHTARROW:
359                                         case K_KP_RIGHTARROW:
360                                                 if ( ! qto_curr_pos )
361                                                         qto_set_curr_pos("a3");
362                                                 else
363                                                         qto_set_curr_pos( minigame_relative_tile(qto_curr_pos,1,0,QTO_NUM_CNT,QTO_LET_CNT));
364                                                 return true;
365                                         case K_LEFTARROW:
366                                         case K_KP_LEFTARROW:
367                                                 if ( ! qto_curr_pos )
368                                                         qto_set_curr_pos("c3");
369                                                 else
370                                                         qto_set_curr_pos(minigame_relative_tile(qto_curr_pos,-1,0,QTO_NUM_CNT,QTO_LET_CNT));
371                                                 return true;
372                                         case K_UPARROW:
373                                         case K_KP_UPARROW:
374                                                 if ( ! qto_curr_pos )
375                                                         qto_set_curr_pos("a1");
376                                                 else
377                                                         qto_set_curr_pos(minigame_relative_tile(qto_curr_pos,0,1,QTO_NUM_CNT,QTO_LET_CNT));
378                                                 return true;
379                                         case K_DOWNARROW:
380                                         case K_KP_DOWNARROW:
381                                                 if ( ! qto_curr_pos )
382                                                         qto_set_curr_pos("a3");
383                                                 else
384                                                         qto_set_curr_pos(minigame_relative_tile(qto_curr_pos,0,-1,QTO_NUM_CNT,QTO_LET_CNT));
385                                                 return true;
386                                         case K_ENTER:
387                                         case K_KP_ENTER:
388                                         case K_SPACE:
389                                                 qto_make_move(minigame);
390                                                 return true;
391                                 }
392                         }
393
394                         return false;
395                 }
396                 case "mouse_pressed":
397                 {
398                         if(...(0,int) == K_MOUSE1)
399                         {
400                                 qto_make_move(minigame);
401                                 return true;
402                         }
403
404                         return false;
405                 }
406                 case "mouse_moved":
407                 {
408                         vector mouse_pos = minigame_hud_normalize(mousepos,qto_boardpos,qto_boardsize);
409                         if ( minigame.minigame_flags == QTO_TURN_MOVE )
410                         {
411                                 qto_set_curr_pos(minigame_tile_name(mouse_pos,QTO_NUM_CNT,QTO_LET_CNT));
412                         }
413                         if ( ! qto_valid_tile(qto_curr_pos) )
414                                 qto_set_curr_pos("");
415
416                         return true;
417                 }
418                 case "network_receive":
419                 {
420                         entity sent = ...(0,entity);
421                         int sf = ...(1,int);
422                         if ( sent.classname == "minigame" )
423                         {
424                                 if ( sf & MINIG_SF_UPDATE )
425                                 {
426                                         sent.message = qto_turn_to_string(sent.minigame_flags);
427                                         if ( sent.minigame_flags & minigame_self.team )
428                                                 minigame_prompt();
429                                 }
430                         }
431                         else if(sent.classname == "minigame_board_piece")
432                         {
433                                 if(sf & MINIG_SF_UPDATE)
434                                 {
435                                         sent.cnt = ReadByte();
436                                 }
437                         }
438                         else if ( sent.classname == "minigame_player" && (sf & QTO_SF_PLAYERSCORE ) )
439                         {
440                                 sent.qto_moves = ReadLong();
441                         }
442
443                         return false;
444                 }
445                 case "menu_show":
446                 {
447                         HUD_MinigameMenu_CustomEntry(...(0,entity),_("Restart"),"restart");
448                         return false;
449                 }
450                 case "menu_click":
451                 {
452                         if(...(0,string) == "restart")
453                                 minigame_cmd("restart");
454                         return false;
455                 }
456         }
457
458         return false;
459 }
460
461 #endif