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
5 const int QTO_SF_PLAYERSCORE = MINIG_SF_CUSTOM;
7 const int QTO_LET_CNT = 5;
8 const int QTO_NUM_CNT = 5;
10 const int QTO_TILE_SIZE = 8;
14 // find same game piece given its tile name
15 entity qto_find_piece(entity minig, string tile)
18 while ( ( e = findentity(e,owner,minig) ) )
19 if ( e.classname == "minigame_board_piece" && e.netname == tile )
24 // Checks if the given piece completes a row
25 bool qto_winning_piece(entity minigame)
27 //int number = minigame_tile_number(piece.netname);
28 //int letter = minigame_tile_letter(piece.netname);
31 while ( ( e = findentity(e,owner,minigame) ) )
32 if ( e.classname == "minigame_board_piece" )
41 // check if the tile name is valid (5x5 grid)
42 bool qto_valid_tile(string tile)
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;
51 void qto_setup_pieces(entity minigame)
54 for(i = 0; i < QTO_NUM_CNT; ++i)
55 for(t = 0; t < QTO_LET_CNT; ++t)
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);
64 minigame_server_sendflags(minigame,MINIG_SF_UPDATE);
67 void qto_add_score(entity minigame, int thescore)
72 if(minigame.minigame_players)
74 minigame.minigame_players.qto_moves += thescore;
75 minigame.minigame_players.SendFlags |= QTO_SF_PLAYERSCORE;
81 void qto_move(entity minigame, entity player, string pos )
83 if ( minigame.minigame_flags & QTO_TURN_MOVE )
86 if ( qto_valid_tile(pos) )
87 if ( qto_find_piece(minigame, pos) )
93 piece.cnt = (piece.cnt) ? 0 : 1; \
94 minigame_server_sendflags(piece,MINIG_SF_UPDATE); \
97 int number = minigame_tile_number(pos);
98 int letter = minigame_tile_letter(pos);
99 piece = qto_find_piece(minigame, pos);
101 piece = qto_find_piece(minigame, minigame_tile_buildname(letter-1,number));
103 piece = qto_find_piece(minigame, minigame_tile_buildname(letter+1,number));
105 piece = qto_find_piece(minigame, minigame_tile_buildname(letter,number-1));
107 piece = qto_find_piece(minigame, minigame_tile_buildname(letter,number+1));
110 qto_add_score(minigame,1); // add 1 move score
112 minigame_server_sendflags(minigame,MINIG_SF_UPDATE);
114 if ( qto_winning_piece(minigame) )
116 minigame.minigame_flags = QTO_TURN_WIN;
119 minigame.minigame_flags = QTO_TURN_MOVE;
125 void qto_restart_match(entity minigame, entity player)
127 minigame.minigame_flags = QTO_TURN_MOVE;
128 minigame_server_sendflags(minigame,MINIG_SF_UPDATE);
130 while ( ( e = findentity(e,owner,minigame) ) )
131 if ( e.classname == "minigame_board_piece" )
134 qto_setup_pieces(minigame);
136 if(minigame.minigame_players)
138 minigame.minigame_players.qto_moves = 0;
139 minigame.minigame_players.SendFlags |= QTO_SF_PLAYERSCORE;
147 // required function, handle server side events
148 int qto_server_event(entity minigame, string event, ...)
154 qto_setup_pieces(minigame);
155 minigame.minigame_flags = QTO_TURN_MOVE;
161 while( (e = findentity(e, owner, minigame)) )
162 if(e.classname == "minigame_board_piece")
164 if(e.netname) { strunzone(e.netname); }
171 int pl_num = minigame_count_players(minigame);
173 // Don't allow more than 1 player
174 if(pl_num >= 1) { return false; }
184 qto_move(minigame, ...(0,entity), ...(1,int) == 2 ? argv(1) : string_null );
187 qto_restart_match(minigame,...(0,entity));
195 entity sent = ...(0,entity);
197 if ( sent.classname == "minigame_board_piece" && (sf & MINIG_SF_UPDATE) )
199 WriteByte(MSG_ENTITY,sent.cnt);
201 else if ( sent.classname == "minigame_player" && (sf & QTO_SF_PLAYERSCORE ) )
203 WriteLong(MSG_ENTITY,sent.qto_moves);
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
219 // Required function, draw the game board
220 void qto_hud_board(vector pos, vector mySize)
222 minigame_hud_fitsqare(pos, mySize);
224 qto_boardsize = mySize;
226 minigame_hud_simpleboard(pos,mySize,minigame_texture("qto/board"));
228 vector tile_size = minigame_hud_denormalize_size('1 1 0' / QTO_TILE_SIZE,pos,mySize);
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);
240 FOREACH_MINIGAME_ENTITY(e)
242 if ( e.classname == "minigame_board_piece" )
244 tile_pos = minigame_tile_pos(e.netname,QTO_NUM_CNT,QTO_LET_CNT);
245 tile_pos = minigame_hud_denormalize(tile_pos,pos,mySize);
247 vector tile_color = '0.4 0.4 0.4';
253 case pos1: case pos2: case pos3: case pos4:
254 tile_color = '0.8 0.8 0.8';
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 );
266 // Required function, draw the game status panel
267 void qto_hud_status(vector pos, vector mySize)
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);
277 vector player_fontsize = hud_fontsize * 1.75;
278 ts_y = ( mySize_y - 2*player_fontsize_y ) / 2;
281 vector tile_size = '48 48 0';
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);
289 FOREACH_MINIGAME_ENTITY(e)
291 if ( e.classname == "minigame_player" )
294 minigame_drawcolorcodedstring_trunc(mySize_x,mypos,
295 GetPlayerName(e.minigame_playerslot-1),
296 player_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
298 mypos_y += player_fontsize_y;
300 // minigame_texture("qto/piece"),
301 // tile_size, '1 0 0', panel_fg_alpha, DRAWFLAG_NORMAL );
303 //mypos_x += tile_size_x;
305 drawstring(mypos,sprintf(_("Moves: %s"), ftos(e.qto_moves)),'32 32 0',
306 '0.7 0.84 1', panel_fg_alpha, DRAWFLAG_NORMAL);
311 // Turn a set of flags into a help message
312 string qto_turn_to_string(int turnflags)
314 if ( turnflags & QTO_TURN_WIN )
315 return _("Well done, you win!");
317 if ( turnflags & QTO_TURN_MOVE )
318 return _("Turn all the angry faces into happy faces");
323 // Make the correct move
324 void qto_make_move(entity minigame)
326 if ( minigame.minigame_flags == QTO_TURN_MOVE )
328 minigame_cmd("move ",qto_curr_pos);
332 void qto_set_curr_pos(string s)
335 strunzone(qto_curr_pos);
341 // Required function, handle client events
342 int qto_client_event(entity minigame, string event, ...)
348 qto_set_curr_pos("");
349 minigame.message = qto_turn_to_string(minigame.minigame_flags);
354 //if((minigame.minigame_flags & QTO_TURN_TEAM) == minigame_self.team)
356 switch ( ...(0,int) )
359 case K_KP_RIGHTARROW:
360 if ( ! qto_curr_pos )
361 qto_set_curr_pos("a3");
363 qto_set_curr_pos( minigame_relative_tile(qto_curr_pos,1,0,QTO_NUM_CNT,QTO_LET_CNT));
367 if ( ! qto_curr_pos )
368 qto_set_curr_pos("c3");
370 qto_set_curr_pos(minigame_relative_tile(qto_curr_pos,-1,0,QTO_NUM_CNT,QTO_LET_CNT));
374 if ( ! qto_curr_pos )
375 qto_set_curr_pos("a1");
377 qto_set_curr_pos(minigame_relative_tile(qto_curr_pos,0,1,QTO_NUM_CNT,QTO_LET_CNT));
381 if ( ! qto_curr_pos )
382 qto_set_curr_pos("a3");
384 qto_set_curr_pos(minigame_relative_tile(qto_curr_pos,0,-1,QTO_NUM_CNT,QTO_LET_CNT));
389 qto_make_move(minigame);
396 case "mouse_pressed":
398 if(...(0,int) == K_MOUSE1)
400 qto_make_move(minigame);
408 vector mouse_pos = minigame_hud_normalize(mousepos,qto_boardpos,qto_boardsize);
409 if ( minigame.minigame_flags == QTO_TURN_MOVE )
411 qto_set_curr_pos(minigame_tile_name(mouse_pos,QTO_NUM_CNT,QTO_LET_CNT));
413 if ( ! qto_valid_tile(qto_curr_pos) )
414 qto_set_curr_pos("");
418 case "network_receive":
420 entity sent = ...(0,entity);
422 if ( sent.classname == "minigame" )
424 if ( sf & MINIG_SF_UPDATE )
426 sent.message = qto_turn_to_string(sent.minigame_flags);
427 if ( sent.minigame_flags & minigame_self.team )
431 else if(sent.classname == "minigame_board_piece")
433 if(sf & MINIG_SF_UPDATE)
435 sent.cnt = ReadByte();
438 else if ( sent.classname == "minigame_player" && (sf & QTO_SF_PLAYERSCORE ) )
440 sent.qto_moves = ReadLong();
447 HUD_MinigameMenu_CustomEntry(...(0,entity),_("Restart"),"restart");
452 if(...(0,string) == "restart")
453 minigame_cmd("restart");